Commit 2d1a1b055be8598dbcc8a7b905d07bcf05eaff3a

Authored by Andy Walls
Committed by Mauro Carvalho Chehab
1 parent 330c6ec894

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>

Showing 1 changed file with 14 additions and 7 deletions Side-by-side Diff

drivers/media/video/cx18/cx18-firmware.c
... ... @@ -134,7 +134,8 @@
134 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 140 const struct firmware *fw = NULL;
140 141 int i, j;
... ... @@ -152,6 +153,7 @@
152 153 return -ENOMEM;
153 154 }
154 155  
  156 + *entry_addr = 0xffffffff;
155 157 src = (const u32 *)fw->data;
156 158 vers = fw->data + sizeof(seghdr);
157 159 sz = fw->size;
158 160  
... ... @@ -168,10 +170,12 @@
168 170 }
169 171 CX18_DEBUG_INFO("load segment %x-%x\n", seghdr.addr,
170 172 seghdr.addr + seghdr.size - 1);
  173 + if (*entry_addr == 0xffffffff)
  174 + *entry_addr = seghdr.addr;
171 175 if (offset + seghdr.size > sz)
172 176 break;
173 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 179 for (j = i; j < seghdr.size && j < i + 4096; j += 4) {
176 180 /* no need for endianness conversion on the ppc */
177 181 cx18_raw_writel(cx, src[(offset + j) / 4],
... ... @@ -192,8 +196,6 @@
192 196 fn, apu_version, fw->size);
193 197 size = fw->size;
194 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 199 return size;
198 200 }
199 201  
200 202  
201 203  
... ... @@ -338,11 +340,16 @@
338 340  
339 341 /* Only if the processor is not running */
340 342 if (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 8) {
  343 + u32 fw_entry_addr;
341 344 int sz = load_apu_fw_direct("v4l-cx23418-apu.fw",
342   - cx->enc_mem, cx);
  345 + cx->enc_mem, cx, &fw_entry_addr);
343 346  
344   - cx18_write_enc(cx, 0xE51FF004, 0);
345   - cx18_write_enc(cx, 0xa00000, 4); /* todo: not hardcoded */
  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);
  352 +
346 353 /* Start APU */
347 354 cx18_write_reg_expect(cx, 0x00010000, CX18_PROC_SOFT_RESET,
348 355 0x00000000, 0x00010001);