aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/coda
diff options
context:
space:
mode:
authorPhilipp Zabel <p.zabel@pengutronix.de>2016-02-17 11:21:10 -0200
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2016-03-03 07:31:44 -0300
commita1a87fa3a0cf8c9d3c5939c6311621ac3dbcb0da (patch)
tree7c34ac641c03430a2657eff80abe6311306b123d /drivers/media/platform/coda
parent[media] V4L: fix a confusing function name (diff)
downloadlinux-dev-a1a87fa3a0cf8c9d3c5939c6311621ac3dbcb0da.tar.xz
linux-dev-a1a87fa3a0cf8c9d3c5939c6311621ac3dbcb0da.zip
[media] coda: add support for native order firmware files with Freescale header
Freescale distribute their VPU firmware files with a 16 byte header in BIT processor native order. This patch allows to detect the header and to reorder the firmware on the fly. With this patch it should be possible to use the distributed vpu_fw_imx{53,6q,6d}.bin files directly after renaming them to v4l-coda*-imx{53,6q,6dl}.bin. Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/platform/coda')
-rw-r--r--drivers/media/platform/coda/coda-common.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
index 2d782ce94a67..0bc544d578e9 100644
--- a/drivers/media/platform/coda/coda-common.c
+++ b/drivers/media/platform/coda/coda-common.c
@@ -1950,6 +1950,38 @@ static int coda_register_device(struct coda_dev *dev, int i)
return video_register_device(vfd, VFL_TYPE_GRABBER, 0);
}
+static void coda_copy_firmware(struct coda_dev *dev, const u8 * const buf,
+ size_t size)
+{
+ u32 *src = (u32 *)buf;
+
+ /* Check if the firmware has a 16-byte Freescale header, skip it */
+ if (buf[0] == 'M' && buf[1] == 'X')
+ src += 4;
+ /*
+ * Check whether the firmware is in native order or pre-reordered for
+ * memory access. The first instruction opcode always is 0xe40e.
+ */
+ if (__le16_to_cpup((__le16 *)src) == 0xe40e) {
+ u32 *dst = dev->codebuf.vaddr;
+ int i;
+
+ /* Firmware in native order, reorder while copying */
+ if (dev->devtype->product == CODA_DX6) {
+ for (i = 0; i < (size - 16) / 4; i++)
+ dst[i] = (src[i] << 16) | (src[i] >> 16);
+ } else {
+ for (i = 0; i < (size - 16) / 4; i += 2) {
+ dst[i] = (src[i + 1] << 16) | (src[i + 1] >> 16);
+ dst[i + 1] = (src[i] << 16) | (src[i] >> 16);
+ }
+ }
+ } else {
+ /* Copy the already reordered firmware image */
+ memcpy(dev->codebuf.vaddr, src, size);
+ }
+}
+
static void coda_fw_callback(const struct firmware *fw, void *context)
{
struct coda_dev *dev = context;
@@ -1967,8 +1999,7 @@ static void coda_fw_callback(const struct firmware *fw, void *context)
if (ret < 0)
goto put_pm;
- /* Copy the whole firmware image to the code buffer */
- memcpy(dev->codebuf.vaddr, fw->data, fw->size);
+ coda_copy_firmware(dev, fw->data, fw->size);
release_firmware(fw);
ret = coda_hw_init(dev);