Commit 2d1a1b055be8598dbcc8a7b905d07bcf05eaff3a
Committed by
Mauro Carvalho Chehab
1 parent
330c6ec894
Exists in
master
and in
4 other branches
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); |