diff options
Diffstat (limited to 'drivers/media/platform/coda/coda-common.c')
-rw-r--r-- | drivers/media/platform/coda/coda-common.c | 35 |
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) | |||
1950 | return video_register_device(vfd, VFL_TYPE_GRABBER, 0); | 1950 | return video_register_device(vfd, VFL_TYPE_GRABBER, 0); |
1951 | } | 1951 | } |
1952 | 1952 | ||
1953 | static void coda_copy_firmware(struct coda_dev *dev, const u8 * const buf, | ||
1954 | size_t size) | ||
1955 | { | ||
1956 | u32 *src = (u32 *)buf; | ||
1957 | |||
1958 | /* Check if the firmware has a 16-byte Freescale header, skip it */ | ||
1959 | if (buf[0] == 'M' && buf[1] == 'X') | ||
1960 | src += 4; | ||
1961 | /* | ||
1962 | * Check whether the firmware is in native order or pre-reordered for | ||
1963 | * memory access. The first instruction opcode always is 0xe40e. | ||
1964 | */ | ||
1965 | if (__le16_to_cpup((__le16 *)src) == 0xe40e) { | ||
1966 | u32 *dst = dev->codebuf.vaddr; | ||
1967 | int i; | ||
1968 | |||
1969 | /* Firmware in native order, reorder while copying */ | ||
1970 | if (dev->devtype->product == CODA_DX6) { | ||
1971 | for (i = 0; i < (size - 16) / 4; i++) | ||
1972 | dst[i] = (src[i] << 16) | (src[i] >> 16); | ||
1973 | } else { | ||
1974 | for (i = 0; i < (size - 16) / 4; i += 2) { | ||
1975 | dst[i] = (src[i + 1] << 16) | (src[i + 1] >> 16); | ||
1976 | dst[i + 1] = (src[i] << 16) | (src[i] >> 16); | ||
1977 | } | ||
1978 | } | ||
1979 | } else { | ||
1980 | /* Copy the already reordered firmware image */ | ||
1981 | memcpy(dev->codebuf.vaddr, src, size); | ||
1982 | } | ||
1983 | } | ||
1984 | |||
1953 | static void coda_fw_callback(const struct firmware *fw, void *context) | 1985 | static void coda_fw_callback(const struct firmware *fw, void *context) |
1954 | { | 1986 | { |
1955 | struct coda_dev *dev = context; | 1987 | struct coda_dev *dev = context; |
@@ -1967,8 +1999,7 @@ static void coda_fw_callback(const struct firmware *fw, void *context) | |||
1967 | if (ret < 0) | 1999 | if (ret < 0) |
1968 | goto put_pm; | 2000 | goto put_pm; |
1969 | 2001 | ||
1970 | /* Copy the whole firmware image to the code buffer */ | 2002 | coda_copy_firmware(dev, fw->data, fw->size); |
1971 | memcpy(dev->codebuf.vaddr, fw->data, fw->size); | ||
1972 | release_firmware(fw); | 2003 | release_firmware(fw); |
1973 | 2004 | ||
1974 | ret = coda_hw_init(dev); | 2005 | ret = coda_hw_init(dev); |