Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 124405
b: refs/heads/master
c: fd6b9c9
h: refs/heads/master
i:
  124403: 0eb8c23
v: v3
  • Loading branch information
Andy Walls authored and Mauro Carvalho Chehab committed Dec 30, 2008
1 parent 407d6af commit 9a1b677
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 53 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 50b86bac6ae6dda00faa14f7d73ae2412eacc240
refs/heads/master: fd6b9c978dc3447b9b4677d8949ef3ea7f946abc
1 change: 1 addition & 0 deletions trunk/drivers/media/video/cx18/cx18-driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
goto free_i2c;
}
cx18_init_memory(cx);
cx18_init_scb(cx);

/* Register IRQ */
retval = request_irq(cx->dev->irq, cx18_irq_handler,
Expand Down
101 changes: 51 additions & 50 deletions trunk/drivers/media/video/cx18/cx18-firmware.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,10 @@ void cx18_init_memory(struct cx18 *cx)

int cx18_firmware_init(struct cx18 *cx)
{
u32 fw_entry_addr;
int sz, retries;
u32 api_args[MAX_MB_ARGUMENTS];

/* Allow chip to control CLKRUN */
cx18_write_reg(cx, 0x5, CX18_DSP0_INTERRUPT_MASK);

Expand All @@ -341,65 +345,62 @@ int cx18_firmware_init(struct cx18 *cx)

cx18_msleep_timeout(1, 0);

/* If the CPU is still running */
if ((cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 8) == 0) {
CX18_ERR("%s: couldn't stop CPU to load firmware\n", __func__);
return -EIO;
}

cx18_sw1_irq_enable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
cx18_sw2_irq_enable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);

/* Only if the processor is not running */
if (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 8) {
u32 fw_entry_addr = 0;
int sz = load_apu_fw_direct("v4l-cx23418-apu.fw",
cx->enc_mem, cx, &fw_entry_addr);

if (sz <= 0)
return sz;

/* Clear bit0 for APU to start from 0 */
cx18_write_reg(cx, cx18_read_reg(cx, 0xc72030) & ~1, 0xc72030);

cx18_write_enc(cx, 0xE51FF004, 0); /* ldr pc, [pc, #-4] */
cx18_write_enc(cx, fw_entry_addr, 4);

/* Start APU */
cx18_write_reg_expect(cx, 0x00010000, CX18_PROC_SOFT_RESET,
0x00000000, 0x00010001);
cx18_msleep_timeout(500, 0);

sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw",
cx->enc_mem, cx);

if (sz > 0) {
int retries = 0;

/* start the CPU */
cx18_write_reg_expect(cx,
0x00080000, CX18_PROC_SOFT_RESET,
0x00000000, 0x00080008);
while (retries++ < 50) { /* Loop for max 500mS */
if ((cx18_read_reg(cx, CX18_PROC_SOFT_RESET)
& 1) == 0)
break;
cx18_msleep_timeout(10, 0);
}
cx18_msleep_timeout(200, 0);
if (retries == 51) {
CX18_ERR("Could not start the CPU\n");
return -EIO;
}
}
if (sz <= 0)
return -EIO;
sz = load_cpu_fw_direct("v4l-cx23418-cpu.fw", cx->enc_mem, cx);
if (sz <= 0)
return sz;

/* The SCB & IPC area *must* be correct before starting the firmwares */
cx18_init_scb(cx);

fw_entry_addr = 0;
sz = load_apu_fw_direct("v4l-cx23418-apu.fw", cx->enc_mem, cx,
&fw_entry_addr);
if (sz <= 0)
return sz;

/* Start the CPU. The CPU will take care of the APU for us. */
cx18_write_reg_expect(cx, 0x00080000, CX18_PROC_SOFT_RESET,
0x00000000, 0x00080008);

/* Wait up to 500 ms for the APU to come out of reset */
for (retries = 0;
retries < 50 && (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 1) == 1;
retries++)
cx18_msleep_timeout(10, 0);

cx18_msleep_timeout(200, 0);

if (retries == 50 &&
(cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 1) == 1) {
CX18_ERR("Could not start the CPU\n");
return -EIO;
}

/*
* The CPU firmware apparently sets up to receive an interrupt for it's
* outgoing IRQ_CPU_TO_EPU_ACK to us (*boggle*). We get an interrupt
* when it sends us an ack, but by the time we process it, that flag in
* the SW2 status register has been cleared by the CPU firmware.
* We'll prevent that not so useful behavior by clearing the CPU's
* interrupt enables for Ack IRQ's we want to process.
* The CPU had once before set up to receive an interrupt for it's
* outgoing IRQ_CPU_TO_EPU_ACK to us. If it ever does this, we get an
* interrupt when it sends us an ack, but by the time we process it,
* that flag in the SW2 status register has been cleared by the CPU
* firmware. We'll prevent that not so useful condition from happening
* by clearing the CPU's interrupt enables for Ack IRQ's we want to
* process.
*/
cx18_sw2_irq_disable_cpu(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);

/* Try a benign command to see if the CPU is alive and well */
sz = cx18_vapi_result(cx, api_args, CX18_CPU_DEBUG_PEEK32, 1, 0);
if (sz < 0)
return sz;

/* initialize GPIO */
cx18_write_reg_expect(cx, 0x14001400, 0xc78110, 0x00001400, 0x14001400);
return 0;
Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/media/video/cx18/cx18-mailbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,9 @@ static const struct cx18_api_info api_info[] = {
API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0),
API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0),
API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST),
API_ENTRY(CPU, CX18_APU_RESETAI, API_FAST),
API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW),
API_ENTRY(APU, CX18_APU_RESETAI, 0),
API_ENTRY(CPU, CX18_CPU_DEBUG_PEEK32, 0),
API_ENTRY(0, 0, 0),
};

Expand Down
1 change: 0 additions & 1 deletion trunk/drivers/media/video/cx18/cx18-scb.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,5 @@ void cx18_init_scb(struct cx18 *cx)
cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu_state),
&cx->scb->ipc_offset);

cx18_writel(cx, 1, &cx->scb->hpu_state);
cx18_writel(cx, 1, &cx->scb->epu_state);
}
6 changes: 6 additions & 0 deletions trunk/drivers/media/video/cx18/cx23418.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@

/* All commands for CPU have the following mask set */
#define CPU_CMD_MASK 0x20000000
#define CPU_CMD_MASK_DEBUG (CPU_CMD_MASK | 0x00000000)
#define CPU_CMD_MASK_ACK (CPU_CMD_MASK | 0x80000000)
#define CPU_CMD_MASK_CAPTURE (CPU_CMD_MASK | 0x00020000)
#define CPU_CMD_MASK_TS (CPU_CMD_MASK | 0x00040000)
Expand Down Expand Up @@ -71,6 +72,11 @@
0/zero/NULL means "I have nothing to say" */
#define CX18_EPU_DEBUG (EPU_CMD_MASK_DEBUG | 0x0003)

/* Reads memory/registers (32-bit)
IN[0] - Address
OUT[1] - Value */
#define CX18_CPU_DEBUG_PEEK32 (CPU_CMD_MASK_DEBUG | 0x0003)

/* Description: This command starts streaming with the set channel type
IN[0] - Task handle. Handle of the task to start
ReturnCode - One of the ERR_CAPTURE_... */
Expand Down

0 comments on commit 9a1b677

Please sign in to comment.