From 8d9a297fc5f2eef6d528a7f204a82f9908c82273 Mon Sep 17 00:00:00 2001 From: Xu Han Date: Thu, 3 Dec 2015 11:35:16 -0800 Subject: [PATCH] msm: camera: Decouple CSIPHY 3phase clocks 3phase clock is required in CPHY mode but not in DPHY mode. Decouple 3phase clocks from other CSIPHY clocks in order to not enable 3phase clock when camera is in DPHY mode. Change-Id: I10f9a175ef937dab30afd9604cca3e870451b0c2 Signed-off-by: Xu Han --- .../msm/camera_v2/sensor/csiphy/msm_csiphy.c | 57 ++++++++++++++----- .../msm/camera_v2/sensor/csiphy/msm_csiphy.h | 2 + 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c index 5ecd6011df4f..380df2c18eea 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c +++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c @@ -517,6 +517,9 @@ static int msm_csiphy_lane_config(struct csiphy_device *csiphy_dev, if (csiphy_dev->csiphy_3phase == CSI_3PHASE_HW) { if (csiphy_params->csi_3phase == 1) { + msm_cam_clk_enable(&csiphy_dev->pdev->dev, + csiphy_dev->csiphy_3p_clk_info, + csiphy_dev->csiphy_3p_clk, 2, 1); rc = msm_csiphy_3phase_lane_config(csiphy_dev, csiphy_params); csiphy_dev->num_irq_registers = 20; @@ -1023,7 +1026,11 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg) msm_cam_clk_enable(&csiphy_dev->pdev->dev, csiphy_dev->csiphy_clk_info, csiphy_dev->csiphy_clk, csiphy_dev->num_clk, 0); - iounmap(csiphy_dev->clk_mux_base); + if (csiphy_dev->csiphy_3phase == CSI_3PHASE_HW) + msm_cam_clk_enable(&csiphy_dev->pdev->dev, + csiphy_dev->csiphy_3p_clk_info, + csiphy_dev->csiphy_3p_clk, 2, 0); + iounmap(csiphy_dev->clk_mux_base); } iounmap(csiphy_dev->base); csiphy_dev->base = NULL; @@ -1131,7 +1138,11 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg) msm_cam_clk_enable(&csiphy_dev->pdev->dev, csiphy_dev->csiphy_clk_info, csiphy_dev->csiphy_clk, csiphy_dev->num_clk, 0); - iounmap(csiphy_dev->clk_mux_base); + if (csiphy_dev->csiphy_3phase == CSI_3PHASE_HW) + msm_cam_clk_enable(&csiphy_dev->pdev->dev, + csiphy_dev->csiphy_3p_clk_info, + csiphy_dev->csiphy_3p_clk, 2, 0); + iounmap(csiphy_dev->clk_mux_base); } iounmap(csiphy_dev->base); @@ -1289,12 +1300,15 @@ static int msm_csiphy_get_clk_info(struct csiphy_device *csiphy_dev, uint32_t count; int i, rc; uint32_t rates[CSIPHY_NUM_CLK_MAX]; + const char *clk_name[CSIPHY_NUM_CLK_MAX]; + char *csi_3p_clk_name = "csi_phy_3p_clk"; + char *csi_3p_clk_src_name = "csiphy_3p_clk_src"; + uint32_t clk_cnt = 0; struct device_node *of_node; of_node = pdev->dev.of_node; count = of_property_count_strings(of_node, "clock-names"); - csiphy_dev->num_clk = count; CDBG("%s: count = %d\n", __func__, count); if (count == 0) { @@ -1311,9 +1325,8 @@ static int msm_csiphy_get_clk_info(struct csiphy_device *csiphy_dev, for (i = 0; i < count; i++) { rc = of_property_read_string_index(of_node, "clock-names", - i, &(csiphy_dev->csiphy_clk_info[i].clk_name)); - CDBG("%s: clock-names[%d] = %s\n", __func__, - i, csiphy_dev->csiphy_clk_info[i].clk_name); + i, &clk_name[i]); + CDBG("%s: clock-names[%d] = %s\n", __func__, i, clk_name[i]); if (rc < 0) { pr_err("%s:%d, failed\n", __func__, __LINE__); return rc; @@ -1326,18 +1339,37 @@ static int msm_csiphy_get_clk_info(struct csiphy_device *csiphy_dev, return rc; } for (i = 0; i < count; i++) { - csiphy_dev->csiphy_clk_info[i].clk_rate = (rates[i] == 0) ? - (long)-1 : rates[i]; - if (!strcmp(csiphy_dev->csiphy_clk_info[i].clk_name, + if (!strcmp(clk_name[i], csi_3p_clk_src_name)) { + csiphy_dev->csiphy_3p_clk_info[0].clk_name = + clk_name[i]; + csiphy_dev->csiphy_3p_clk_info[0].clk_rate = + (rates[i] == 0) ? (long)-1 : rates[i]; + continue; + } else if (!strcmp(clk_name[i], csi_3p_clk_name)) { + csiphy_dev->csiphy_3p_clk_info[1].clk_name = + clk_name[i]; + csiphy_dev->csiphy_3p_clk_info[1].clk_rate = + (rates[i] == 0) ? (long)-1 : rates[i]; + continue; + } + csiphy_dev->csiphy_clk_info[clk_cnt].clk_name = + clk_name[i]; + csiphy_dev->csiphy_clk_info[clk_cnt].clk_rate = + (rates[i] == 0) ? (long)-1 : rates[i]; + if (!strcmp(csiphy_dev->csiphy_clk_info[clk_cnt].clk_name, "csiphy_timer_src_clk")) { CDBG("%s:%d, copy csiphy_timer_src_clk", __func__, __LINE__); csiphy_dev->csiphy_max_clk = rates[i]; - csiphy_dev->csiphy_clk_index = i; + csiphy_dev->csiphy_clk_index = clk_cnt; } - CDBG("%s: clk_rate[%d] = %ld\n", __func__, i, - csiphy_dev->csiphy_clk_info[i].clk_rate); + CDBG("%s: clk_rate[%d] = %ld\n", __func__, clk_cnt, + csiphy_dev->csiphy_clk_info[clk_cnt].clk_rate); + clk_cnt++; } + + csiphy_dev->num_clk = clk_cnt; + return 0; } @@ -1371,7 +1403,6 @@ static int csiphy_probe(struct platform_device *pdev) CDBG("%s: device id = %d\n", __func__, pdev->id); } - /* ToDo: Enable 3phase clock for dynamic clock enable/disable */ rc = msm_csiphy_get_clk_info(new_csiphy_dev, pdev); if (rc < 0) { pr_err("%s: msm_csiphy_get_clk_info() failed", __func__); diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h index d0334b441131..1b2bddb94550 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h +++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h @@ -155,6 +155,8 @@ struct csiphy_device { uint32_t num_clk; struct clk *csiphy_clk[CSIPHY_NUM_CLK_MAX]; struct msm_cam_clk_info csiphy_clk_info[CSIPHY_NUM_CLK_MAX]; + struct clk *csiphy_3p_clk[2]; + struct msm_cam_clk_info csiphy_3p_clk_info[2]; int32_t ref_count; uint16_t lane_mask[MAX_CSIPHY]; uint32_t is_3_1_20nm_hw;