diff --git a/isp.c b/isp.c index 7101384..af1a29c 100644 --- a/isp.c +++ b/isp.c @@ -177,10 +177,12 @@ static int isp_load_firmware(struct bcwc_private *dev_priv) int isp_init(struct bcwc_private *dev_priv) { - struct isp_mem_obj *ipc_queue, *heap; + struct isp_mem_obj *ipc_queue, *heap, *fw_args; u32 num_channels, queue_size, heap_size; u32 reg; int i, retries, ret; + unsigned char *p; + struct isp_fw_args *fw_args_data; ret = isp_mem_init(dev_priv); if (ret) @@ -298,6 +300,36 @@ int isp_init(struct bcwc_private *dev_priv) BCWC_ISP_REG_WRITE(heap->size, ISP_FW_HEAP_SIZE2); + /* Set FW args */ + fw_args = isp_mem_create(dev_priv, FTHD_MEM_FW_ARGS, sizeof(struct isp_fw_args)); + if (!fw_args) + return -ENOMEM; + + fw_args_data = dev_priv->s2_mem + fw_args->offset; + + fw_args_data->__unknown = 2; + fw_args_data->fw_arg = 0; + fw_args_data->full_stats_mode = 0; + + BCWC_ISP_REG_WRITE(fw_args->offset, ISP_REG_C301C); + + BCWC_ISP_REG_WRITE(0x10, ISP_REG_41020); + + for (retries = 0; retries < 1000; retries++) { + reg = BCWC_ISP_REG_READ(ISP_REG_41000); + if ((reg & 0xf0) > 0) + break; + mdelay(10); + } + + if (retries >= 1000) { + dev_info(&dev_priv->pdev->dev, "Init failed! No second int\n"); + return -EIO; + } /* FIXME: free on error path */ + + dev_info(&dev_priv->pdev->dev, "ISP second int after %dms\n", + (retries - 1) * 10); + } return 0; diff --git a/isp.h b/isp.h index 3432735..aca15af 100644 --- a/isp.h +++ b/isp.h @@ -24,6 +24,7 @@ #define FTHD_MEM_FIRMWARE 1 #define FTHD_MEM_HEAP 2 #define FTHD_MEM_IPC_QUEUE 3 +#define FTHD_MEM_FW_ARGS 4 #define FTHD_MEM_SIZE 0x8000000 /* 128mb */ #define FTHD_MEM_FW_SIZE 0x800000 /* 8mb */ @@ -36,6 +37,11 @@ struct isp_mem_obj { unsigned long offset; }; +struct isp_fw_args { + u32 __unknown; + u32 fw_arg; + u32 full_stats_mode; +}; #define to_isp_mem_obj(x) container_of((x), struct isp_mem_obj, base) extern int isp_init(struct bcwc_private *dev_priv);