diff options
| -rw-r--r-- | drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c index 6339555bdf76..83abaea1fa44 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c @@ -1461,8 +1461,9 @@ static int cpp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) VBIF_CLIENT_CPP, cpp_vbif_error_handler); if (cpp_dev->cpp_open_cnt == 1) { - rc = cpp_init_hardware(cpp_dev); + rc = cpp_init_mem(cpp_dev); if (rc < 0) { + pr_err("Error: init memory fail\n"); cpp_dev->cpp_open_cnt--; cpp_dev->cpp_subscribe_list[i].active = 0; cpp_dev->cpp_subscribe_list[i].vfh = NULL; @@ -1470,16 +1471,14 @@ static int cpp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) return rc; } - rc = cpp_init_mem(cpp_dev); + rc = cpp_init_hardware(cpp_dev); if (rc < 0) { - pr_err("Error: init memory fail\n"); cpp_dev->cpp_open_cnt--; cpp_dev->cpp_subscribe_list[i].active = 0; cpp_dev->cpp_subscribe_list[i].vfh = NULL; mutex_unlock(&cpp_dev->mutex); return rc; } - cpp_dev->state = CPP_STATE_IDLE; CPP_DBG("Invoking msm_ion_client_create()\n"); @@ -1499,6 +1498,8 @@ static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { uint32_t i; int rc = -1; + int counter = 0; + u32 result = 0; struct cpp_device *cpp_dev = NULL; struct msm_device_queue *processing_q = NULL; struct msm_device_queue *eventData_q = NULL; @@ -1579,6 +1580,55 @@ static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) msm_camera_io_r(cpp_dev->cpp_hw_base + 0x88)); pr_debug("DEBUG_R1: 0x%x\n", msm_camera_io_r(cpp_dev->cpp_hw_base + 0x8C)); + + /* mask IRQ status */ + msm_camera_io_w(0xB, cpp_dev->cpp_hw_base + 0xC); + + /* clear IRQ status */ + msm_camera_io_w(0xFFFFF, cpp_dev->cpp_hw_base + 0x14); + + /* MMSS_A_CPP_AXI_CMD = 0x16C, reset 0x1*/ + msm_camera_io_w(0x1, cpp_dev->cpp_hw_base + 0x16C); + + while (counter < MSM_CPP_POLL_RETRIES) { + result = msm_camera_io_r(cpp_dev->cpp_hw_base + 0x10); + if (result & 0x2) + break; + /* + * Below usleep values are chosen based on experiments + * and this was the smallest number which works. This + * sleep is needed to leave enough time for hardware + * to update status register. + */ + usleep_range(200, 250); + counter++; + } + + pr_debug("CPP AXI done counter %d result 0x%x\n", + counter, result); + + /* clear IRQ status */ + msm_camera_io_w(0xFFFFF, cpp_dev->cpp_hw_base + 0x14); + counter = 0; + /* MMSS_A_CPP_RST_CMD_0 = 0x8, firmware reset = 0x3DF77 */ + msm_camera_io_w(0x3DF77, cpp_dev->cpp_hw_base + 0x8); + + while (counter < MSM_CPP_POLL_RETRIES) { + result = msm_camera_io_r(cpp_dev->cpp_hw_base + 0x10); + if (result & 0x1) + break; + /* + * Below usleep values are chosen based on experiments + * and this was the smallest number which works. This + * sleep is needed to leave enough time for hardware + * to update status register. + */ + usleep_range(200, 250); + counter++; + } + pr_debug("CPP reset done counter %d result 0x%x\n", + counter, result); + msm_camera_io_w(0x0, cpp_dev->base + MSM_CPP_MICRO_CLKEN_CTL); msm_cpp_clear_timer(cpp_dev); cpp_release_hardware(cpp_dev); |
