aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2008-11-08 15:14:22 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:38:04 -0500
commit2d1a1b055be8598dbcc8a7b905d07bcf05eaff3a (patch)
treead2cd2f583438e98e8e7c225d07c9248b061d0c2 /drivers
parent330c6ec8942765e81f237bd58020da1b161935ce (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.c21
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
137static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx) 137static 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);