diff options
author | Andy Walls <awalls@radix.net> | 2008-11-08 15:14:22 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-30 06:38:04 -0500 |
commit | 2d1a1b055be8598dbcc8a7b905d07bcf05eaff3a (patch) | |
tree | ad2cd2f583438e98e8e7c225d07c9248b061d0c2 /drivers | |
parent | 330c6ec8942765e81f237bd58020da1b161935ce (diff) |
V4L/DVB (9597): cx18: Minor fixes to APU firmware load process
Use the APU fw start address from rom file instead of a hardcoded entry vector.
Fixed cx18_setup_page() calls to use the correct APU image load addresses.
Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/cx18/cx18-firmware.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c index 7a7c89032caa..ab02da727519 100644 --- a/drivers/media/video/cx18/cx18-firmware.c +++ b/drivers/media/video/cx18/cx18-firmware.c | |||
@@ -134,7 +134,8 @@ static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx) | |||
134 | return size; | 134 | return size; |
135 | } | 135 | } |
136 | 136 | ||
137 | static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx) | 137 | static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, |
138 | u32 *entry_addr) | ||
138 | { | 139 | { |
139 | const struct firmware *fw = NULL; | 140 | const struct firmware *fw = NULL; |
140 | int i, j; | 141 | int i, j; |
@@ -152,6 +153,7 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx) | |||
152 | return -ENOMEM; | 153 | return -ENOMEM; |
153 | } | 154 | } |
154 | 155 | ||
156 | *entry_addr = 0xffffffff; | ||
155 | src = (const u32 *)fw->data; | 157 | src = (const u32 *)fw->data; |
156 | vers = fw->data + sizeof(seghdr); | 158 | vers = fw->data + sizeof(seghdr); |
157 | sz = fw->size; | 159 | sz = fw->size; |
@@ -168,10 +170,12 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx) | |||
168 | } | 170 | } |
169 | CX18_DEBUG_INFO("load segment %x-%x\n", seghdr.addr, | 171 | CX18_DEBUG_INFO("load segment %x-%x\n", seghdr.addr, |
170 | seghdr.addr + seghdr.size - 1); | 172 | seghdr.addr + seghdr.size - 1); |
173 | if (*entry_addr == 0xffffffff) | ||
174 | *entry_addr = seghdr.addr; | ||
171 | if (offset + seghdr.size > sz) | 175 | if (offset + seghdr.size > sz) |
172 | break; | 176 | break; |
173 | for (i = 0; i < seghdr.size; i += 4096) { | 177 | for (i = 0; i < seghdr.size; i += 4096) { |
174 | cx18_setup_page(cx, offset + i); | 178 | cx18_setup_page(cx, seghdr.addr + i); |
175 | for (j = i; j < seghdr.size && j < i + 4096; j += 4) { | 179 | for (j = i; j < seghdr.size && j < i + 4096; j += 4) { |
176 | /* no need for endianness conversion on the ppc */ | 180 | /* no need for endianness conversion on the ppc */ |
177 | cx18_raw_writel(cx, src[(offset + j) / 4], | 181 | cx18_raw_writel(cx, src[(offset + j) / 4], |
@@ -192,8 +196,6 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx) | |||
192 | fn, apu_version, fw->size); | 196 | fn, apu_version, fw->size); |
193 | size = fw->size; | 197 | size = fw->size; |
194 | release_firmware(fw); | 198 | release_firmware(fw); |
195 | /* Clear bit0 for APU to start from 0 */ | ||
196 | cx18_write_reg(cx, cx18_read_reg(cx, 0xc72030) & ~1, 0xc72030); | ||
197 | return size; | 199 | return size; |
198 | } | 200 | } |
199 | 201 | ||
@@ -338,11 +340,16 @@ int cx18_firmware_init(struct cx18 *cx) | |||
338 | 340 | ||
339 | /* Only if the processor is not running */ | 341 | /* Only if the processor is not running */ |
340 | if (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 8) { | 342 | if (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 8) { |
343 | u32 fw_entry_addr; | ||
341 | int sz = load_apu_fw_direct("v4l-cx23418-apu.fw", | 344 | int sz = load_apu_fw_direct("v4l-cx23418-apu.fw", |
342 | cx->enc_mem, cx); | 345 | cx->enc_mem, cx, &fw_entry_addr); |
346 | |||
347 | /* Clear bit0 for APU to start from 0 */ | ||
348 | cx18_write_reg(cx, cx18_read_reg(cx, 0xc72030) & ~1, 0xc72030); | ||
349 | |||
350 | cx18_write_enc(cx, 0xE51FF004, 0); /* ldr pc, [pc, #-4] */ | ||
351 | cx18_write_enc(cx, fw_entry_addr, 4); | ||
343 | 352 | ||
344 | cx18_write_enc(cx, 0xE51FF004, 0); | ||
345 | cx18_write_enc(cx, 0xa00000, 4); /* todo: not hardcoded */ | ||
346 | /* Start APU */ | 353 | /* Start APU */ |
347 | cx18_write_reg_expect(cx, 0x00010000, CX18_PROC_SOFT_RESET, | 354 | cx18_write_reg_expect(cx, 0x00010000, CX18_PROC_SOFT_RESET, |
348 | 0x00000000, 0x00010001); | 355 | 0x00000000, 0x00010001); |