From 53c6b89349730765a71722d274fc3fa41287d21f Mon Sep 17 00:00:00 2001 From: Ravi Kishore Tanuku Date: Wed, 22 Feb 2017 20:00:13 +0530 Subject: msm: camera: Add regulator enable and disable independent of CSID Regulator enable and disable of CSIPHY depends on the CSID module. Make the enable and disable of clk regulator independent of CSIPHY. CRs-Fixed: 1107702 Change-Id: Iabb5eb28d63b34a4c3201c53be17054a1907f4fe Signed-off-by: Ravi Kishore Tanuku --- arch/arm/boot/dts/qcom/msm8996-camera.dtsi | 38 ++++++--- .../msm/camera_v2/sensor/csiphy/msm_csiphy.c | 94 ++++++++++++++++++++-- .../msm/camera_v2/sensor/csiphy/msm_csiphy.h | 6 +- 3 files changed, 120 insertions(+), 18 deletions(-) diff --git a/arch/arm/boot/dts/qcom/msm8996-camera.dtsi b/arch/arm/boot/dts/qcom/msm8996-camera.dtsi index 3e1a889..e4960d0 100644 --- a/arch/arm/boot/dts/qcom/msm8996-camera.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-camera.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -28,18 +28,24 @@ reg-names = "csiphy", "csiphy_clk_mux"; interrupts = <0 78 0>; interrupt-names = "csiphy"; - clocks = <&clock_mmss clk_camss_top_ahb_clk>, + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + mmagic-supply = <&gdsc_mmagic_camss>; + gdscr-supply = <&gdsc_camss_top>; + qcom,cam-vreg-name = "mmagic", "gdscr"; + clocks = <&clock_mmss clk_mmss_mmagic_ahb_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, <&clock_mmss clk_camss_ispif_ahb_clk>, <&clock_mmss clk_csi0phytimer_clk_src>, <&clock_mmss clk_camss_csi0phytimer_clk>, <&clock_mmss clk_camss_ahb_clk>, <&clock_mmss clk_csiphy0_3p_clk_src>, <&clock_mmss clk_camss_csiphy0_3p_clk>; - clock-names = "camss_top_ahb_clk", + clock-names = "mmagic_ahb_clk", "camss_top_ahb_clk", "ispif_ahb_clk", "csiphy_timer_src_clk", "csiphy_timer_clk", "camss_ahb_clk", "csiphy_3p_clk_src", "csi_phy_3p_clk"; - qcom,clock-rates = <0 0 200000000 0 0 100000000 0>; + qcom,clock-rates = <0 0 0 200000000 0 0 100000000 0>; }; qcom,csiphy@a35000 { @@ -49,18 +55,24 @@ reg-names = "csiphy", "csiphy_clk_mux"; interrupts = <0 79 0>; interrupt-names = "csiphy"; - clocks = <&clock_mmss clk_camss_top_ahb_clk>, + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + mmagic-supply = <&gdsc_mmagic_camss>; + gdscr-supply = <&gdsc_camss_top>; + qcom,cam-vreg-name = "mmagic", "gdscr"; + clocks = <&clock_mmss clk_mmss_mmagic_ahb_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, <&clock_mmss clk_camss_ispif_ahb_clk>, <&clock_mmss clk_csi1phytimer_clk_src>, <&clock_mmss clk_camss_csi1phytimer_clk>, <&clock_mmss clk_camss_ahb_clk>, <&clock_mmss clk_csiphy1_3p_clk_src>, <&clock_mmss clk_camss_csiphy1_3p_clk>; - clock-names = "camss_top_ahb_clk", + clock-names = "mmagic_ahb_clk", "camss_top_ahb_clk", "ispif_ahb_clk", "csiphy_timer_src_clk", "csiphy_timer_clk", "camss_ahb_clk", "csiphy_3p_clk_src", "csi_phy_3p_clk"; - qcom,clock-rates = <0 0 200000000 0 0 100000000 0>; + qcom,clock-rates = <0 0 0 200000000 0 0 100000000 0>; }; qcom,csiphy@a36000 { @@ -70,18 +82,24 @@ reg-names = "csiphy", "csiphy_clk_mux"; interrupts = <0 80 0>; interrupt-names = "csiphy"; - clocks = <&clock_mmss clk_camss_top_ahb_clk>, + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + mmagic-supply = <&gdsc_mmagic_camss>; + gdscr-supply = <&gdsc_camss_top>; + qcom,cam-vreg-name = "mmagic", "gdscr"; + clocks = <&clock_mmss clk_mmss_mmagic_ahb_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, <&clock_mmss clk_camss_ispif_ahb_clk>, <&clock_mmss clk_csi2phytimer_clk_src>, <&clock_mmss clk_camss_csi2phytimer_clk>, <&clock_mmss clk_camss_ahb_clk>, <&clock_mmss clk_csiphy2_3p_clk_src>, <&clock_mmss clk_camss_csiphy2_3p_clk>; - clock-names = "camss_top_ahb_clk", + clock-names = "mmagic_ahb_clk", "camss_top_ahb_clk", "ispif_ahb_clk", "csiphy_timer_src_clk", "csiphy_timer_clk", "camss_ahb_clk", "csiphy_3p_clk_src", "csi_phy_3p_clk"; - qcom,clock-rates = <0 0 200000000 0 0 100000000 0>; + qcom,clock-rates = <0 0 0 200000000 0 0 100000000 0>; }; qcom,csid@a30000 { 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 9d6952ee..d1bb9af 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 @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -782,6 +782,25 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev) CDBG("%s:%d called\n", __func__, __LINE__); + rc = msm_camera_config_vreg(&csiphy_dev->pdev->dev, + csiphy_dev->csiphy_vreg, + csiphy_dev->regulator_count, NULL, 0, + &csiphy_dev->csiphy_reg_ptr[0], 1); + if (rc < 0) { + pr_err("%s:%d csiphy config_vreg failed\n", + __func__, __LINE__); + goto csiphy_vreg_config_fail; + } + rc = msm_camera_enable_vreg(&csiphy_dev->pdev->dev, + csiphy_dev->csiphy_vreg, + csiphy_dev->regulator_count, NULL, 0, + &csiphy_dev->csiphy_reg_ptr[0], 1); + if (rc < 0) { + pr_err("%s:%d csiphy enable_vreg failed\n", + __func__, __LINE__); + goto top_vreg_enable_failed; + } + rc = msm_camera_clk_enable(&csiphy_dev->pdev->dev, csiphy_dev->csiphy_clk_info, csiphy_dev->csiphy_clk, csiphy_dev->num_clk, true); @@ -790,7 +809,7 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev) if (rc < 0) { pr_err("%s: csiphy clk enable failed\n", __func__); csiphy_dev->ref_count--; - goto csiphy_resource_fail; + goto csiphy_enable_clk_fail; } CDBG("%s:%d called\n", __func__, __LINE__); @@ -818,7 +837,17 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev) csiphy_dev->csiphy_state = CSIPHY_POWER_UP; return 0; -csiphy_resource_fail: +csiphy_enable_clk_fail: + msm_camera_enable_vreg(&csiphy_dev->pdev->dev, + csiphy_dev->csiphy_vreg, + csiphy_dev->regulator_count, NULL, 0, + &csiphy_dev->csiphy_reg_ptr[0], 0); +top_vreg_enable_failed: + msm_camera_config_vreg(&csiphy_dev->pdev->dev, + csiphy_dev->csiphy_vreg, + csiphy_dev->regulator_count, NULL, 0, + &csiphy_dev->csiphy_reg_ptr[0], 0); +csiphy_vreg_config_fail: if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY, CAM_AHB_SUSPEND_VOTE) < 0) pr_err("%s: failed to vote for AHB\n", __func__); @@ -856,6 +885,24 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev) pr_err("%s: failed to vote for AHB\n", __func__); return rc; } + rc = msm_camera_config_vreg(&csiphy_dev->pdev->dev, + csiphy_dev->csiphy_vreg, + csiphy_dev->regulator_count, NULL, 0, + &csiphy_dev->csiphy_reg_ptr[0], 1); + if (rc < 0) { + pr_err("%s:%d csiphy config_vreg failed\n", + __func__, __LINE__); + goto csiphy_vreg_config_fail; + } + rc = msm_camera_enable_vreg(&csiphy_dev->pdev->dev, + csiphy_dev->csiphy_vreg, + csiphy_dev->regulator_count, NULL, 0, + &csiphy_dev->csiphy_reg_ptr[0], 1); + if (rc < 0) { + pr_err("%s:%d csiphy enable_vreg failed\n", + __func__, __LINE__); + goto top_vreg_enable_failed; + } rc = msm_camera_clk_enable(&csiphy_dev->pdev->dev, csiphy_dev->csiphy_clk_info, csiphy_dev->csiphy_clk, @@ -865,9 +912,9 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev) if (rc < 0) { pr_err("%s: csiphy clk enable failed\n", __func__); csiphy_dev->ref_count--; - goto csiphy_resource_fail; + goto csiphy_enable_clk_fail; } - CDBG("%s:%d called\n", __func__, __LINE__); + CDBG("%s:%d clk enable success\n", __func__, __LINE__); if (csiphy_dev->csiphy_3phase == CSI_3PHASE_HW) msm_csiphy_3ph_reset(csiphy_dev); @@ -890,7 +937,17 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev) csiphy_dev->csiphy_state = CSIPHY_POWER_UP; return 0; -csiphy_resource_fail: +csiphy_enable_clk_fail: + msm_camera_enable_vreg(&csiphy_dev->pdev->dev, + csiphy_dev->csiphy_vreg, + csiphy_dev->regulator_count, NULL, 0, + &csiphy_dev->csiphy_reg_ptr[0], 0); +top_vreg_enable_failed: + msm_camera_config_vreg(&csiphy_dev->pdev->dev, + csiphy_dev->csiphy_vreg, + csiphy_dev->regulator_count, NULL, 0, + &csiphy_dev->csiphy_reg_ptr[0], 0); +csiphy_vreg_config_fail: if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY, CAM_AHB_SUSPEND_VOTE) < 0) pr_err("%s: failed to vote for AHB\n", __func__); @@ -998,6 +1055,14 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg) csiphy_dev->csiphy_3p_clk, 2, false); } + msm_camera_enable_vreg(&csiphy_dev->pdev->dev, + csiphy_dev->csiphy_vreg, + csiphy_dev->regulator_count, NULL, 0, + &csiphy_dev->csiphy_reg_ptr[0], 0); + msm_camera_config_vreg(&csiphy_dev->pdev->dev, + csiphy_dev->csiphy_vreg, csiphy_dev->regulator_count, + NULL, 0, &csiphy_dev->csiphy_reg_ptr[0], 0); + csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN; if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY, @@ -1104,6 +1169,13 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg) csiphy_dev->csiphy_3p_clk, 2, false); } + msm_camera_enable_vreg(&csiphy_dev->pdev->dev, + csiphy_dev->csiphy_vreg, csiphy_dev->regulator_count, + NULL, 0, &csiphy_dev->csiphy_reg_ptr[0], 0); + msm_camera_config_vreg(&csiphy_dev->pdev->dev, + csiphy_dev->csiphy_vreg, csiphy_dev->regulator_count, + NULL, 0, &csiphy_dev->csiphy_reg_ptr[0], 0); + csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN; if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY, @@ -1419,6 +1491,14 @@ static int csiphy_probe(struct platform_device *pdev) goto csiphy_no_resource; } + rc = msm_camera_get_dt_vreg_data(pdev->dev.of_node, + &(new_csiphy_dev->csiphy_vreg), + &(new_csiphy_dev->regulator_count)); + if (rc < 0) { + pr_err("%s: get vreg data from dtsi fail\n", __func__); + rc = -EFAULT; + goto csiphy_no_resource; + } /* ToDo: Enable 3phase clock for dynamic clock enable/disable */ rc = msm_csiphy_get_clk_info(new_csiphy_dev, pdev); if (rc < 0) { @@ -1493,7 +1573,7 @@ static int msm_csiphy_exit(struct platform_device *pdev) &csiphy_dev->csiphy_all_clk, csiphy_dev->num_all_clk); - msm_camera_put_reg_base(pdev, csiphy_dev->base, "csid", true); + msm_camera_put_reg_base(pdev, csiphy_dev->base, "csiphy", true); if (csiphy_dev->hw_dts_version >= CSIPHY_VERSION_V30) { msm_camera_put_reg_base(pdev, csiphy_dev->clk_mux_base, "csiphy_clk_mux", true); 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 4b3c407..07a0811 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 @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -20,6 +20,7 @@ #include #include "msm_sd.h" #include "msm_camera_io_util.h" +#include "msm_camera_dt_util.h" #include "cam_soc_api.h" #define MAX_CSIPHY 3 @@ -168,6 +169,9 @@ struct csiphy_device { uint8_t num_irq_registers; uint32_t csiphy_sof_debug; uint32_t csiphy_sof_debug_count; + struct camera_vreg_t *csiphy_vreg; + struct regulator *csiphy_reg_ptr[MAX_REGULATOR]; + int32_t regulator_count; }; #define VIDIOC_MSM_CSIPHY_RELEASE \ -- cgit v1.1