msm: camera: Add support for reset controller framework

The current api which performs the clock reset is moved to use the reset
framework, so support the changes in camera driver for the same. The reset
framework requires to get reset handle and perform assert/deassert of the
resets.

Change-Id: I5a809e464c90c29b6f69fc0bfba67bae9a9b6551
Signed-off-by: Amit Nischal <anischal@codeaurora.org>
This commit is contained in:
Amit Nischal 2016-06-08 18:34:48 +05:30 committed by Gerrit - the friendly Code Review server
parent 911e592fdc
commit 48c55694f1
8 changed files with 70 additions and 16 deletions

View file

@ -22,6 +22,10 @@ Required properties:
case dynamic clock scaling based on prevalent streams need lower clock rate.
- qcom,cpp-fw-payload-info: Child node for cpp node having infomration on
cpp firmware payload offsets. This is mandatory node.
- resets: reset specifier pair consists of phandle for the reset controller
and reset lines used by this controller.
- reset-names: reset signal name strings sorted in the same order as the resets
property.
Required properties of the child node:
- qcom,stripe-base = Base offset of stripes in cpp payload.
@ -120,6 +124,7 @@ Example:
qcom,ref-we-mmu-pf-ptr-off = <22>;
qcom,set-group-buffer-len = <135>;
qcom,dup-frame-indicator-off = <70>;
resets = <&clock_mmss MMSS_CAMSS_MICRO_BCR>;
reset-names = "micro_iface_reset";
};
};

View file

@ -623,6 +623,10 @@
"camss_cpp_axi_clk", "camss_cpp_clk",
"micro_iface_clk", "camss_ahb_clk",
"smmu_cpp_axi_clk", "cpp_vbif_ahb_clk";
resets = <&clock_mmss CAMSS_MICRO_BCR>;
reset-names = "micro_iface_reset";
qcom,clock-rates = <0 0 0 480000000 0 0 480000000 0 0 0 0>;
qcom,min-clock-rate = <200000000>;
qcom,bus-master = <1>;

View file

@ -405,6 +405,8 @@
<106 512 0 0>,
<106 512 0 0>;
qcom,msm-bus-vector-dyn-vote;
resets = <&clock_mmss CAMSS_MICRO_BCR>;
reset-names = "micro_iface_reset";
qcom,cpp-fw-payload-info {
qcom,stripe-base = <790>;
qcom,plane-base = <715>;

View file

@ -542,6 +542,28 @@ int msm_camera_put_clk_info_and_rates(struct platform_device *pdev,
}
EXPORT_SYMBOL(msm_camera_put_clk_info_and_rates);
/* Get reset info from DT */
int msm_camera_get_reset_info(struct platform_device *pdev,
struct reset_control **micro_iface_reset)
{
if (!pdev || !micro_iface_reset)
return -EINVAL;
if (of_property_match_string(pdev->dev.of_node, "reset-names",
"micro_iface_reset")) {
pr_err("err: Reset property not found\n");
return -EINVAL;
}
*micro_iface_reset = devm_reset_control_get
(&pdev->dev, "micro_iface_reset");
if (IS_ERR(*micro_iface_reset))
return PTR_ERR(*micro_iface_reset);
return 0;
}
EXPORT_SYMBOL(msm_camera_get_reset_info);
/* Get regulators from DT */
int msm_camera_get_regulator_info(struct platform_device *pdev,
struct msm_cam_regulator **vdd_info,

View file

@ -21,6 +21,7 @@
#include <linux/regulator/consumer.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/reset.h>
#include <soc/qcom/camera2.h>
enum cam_bus_client {
@ -187,6 +188,21 @@ int msm_camera_clk_enable(struct device *dev,
long msm_camera_clk_set_rate(struct device *dev,
struct clk *clk,
long clk_rate);
/**
* @brief : Gets reset info
*
* This function extracts the reset information for a specific
* platform device
*
* @param pdev : platform device to get reset information
* @param micro_iface_reset : Pointer to populate the reset names
*
* @return Status of operation. Negative in case of error. Zero otherwise.
*/
int msm_camera_get_reset_info(struct platform_device *pdev,
struct reset_control **micro_iface_reset);
/**
* @brief : Sets flags of a clock
*

View file

@ -4017,11 +4017,20 @@ static int cpp_probe(struct platform_device *pdev)
}
}
rc = msm_camera_get_reset_info(pdev,
&cpp_dev->micro_iface_reset);
if (rc < 0) {
cpp_dev->micro_iface_reset = NULL;
pr_err("%s: failed to get micro_iface_reset\n",
__func__);
goto get_reg_err;
}
rc = msm_camera_get_regulator_info(pdev, &cpp_dev->cpp_vdd,
&cpp_dev->num_reg);
if (rc < 0) {
pr_err("%s: failed to get the regulators\n", __func__);
goto get_reg_err;
goto get_reset_err;
}
msm_cpp_fetch_dt_params(cpp_dev);
@ -4104,6 +4113,8 @@ static int cpp_probe(struct platform_device *pdev)
cpp_probe_init_error:
media_entity_cleanup(&cpp_dev->msm_sd.sd.entity);
msm_sd_unregister(&cpp_dev->msm_sd);
get_reset_err:
reset_control_put(cpp_dev->micro_iface_reset);
get_reg_err:
msm_camera_put_clk_info(pdev, &cpp_dev->clk_info, &cpp_dev->cpp_clk,
cpp_dev->num_clks);
@ -4161,6 +4172,9 @@ static int cpp_device_remove(struct platform_device *dev)
msm_camera_unregister_bus_client(CAM_BUS_CLIENT_CPP);
mutex_destroy(&cpp_dev->mutex);
kfree(cpp_dev->work);
reset_control_put(cpp_dev->micro_iface_reset);
destroy_workqueue(cpp_dev->timer_wq);
kfree(cpp_dev->cpp_clk);
kfree(cpp_dev);

View file

@ -211,6 +211,7 @@ struct cpp_device {
struct clk **cpp_clk;
struct msm_cam_clk_info *clk_info;
size_t num_clks;
struct reset_control *micro_iface_reset;
struct msm_cam_regulator *cpp_vdd;
int num_reg;
struct mutex mutex;

View file

@ -103,20 +103,11 @@ static int cpp_get_clk_freq_tbl(struct clk *clk, struct cpp_hw_info *hw_info,
int msm_cpp_set_micro_clk(struct cpp_device *cpp_dev)
{
uint32_t msm_micro_iface_idx;
int rc;
msm_micro_iface_idx = msm_cpp_get_clock_index(cpp_dev,
"micro_iface_clk");
if (msm_micro_iface_idx < 0) {
pr_err("Fail to get clock index\n");
return -EINVAL;
}
rc = clk_reset(cpp_dev->cpp_clk[msm_micro_iface_idx],
CLK_RESET_ASSERT);
rc = reset_control_assert(cpp_dev->micro_iface_reset);
if (rc) {
pr_err("%s:micro_iface_clk assert failed\n",
pr_err("%s:micro_iface_reset assert failed\n",
__func__);
return -EINVAL;
}
@ -129,10 +120,9 @@ int msm_cpp_set_micro_clk(struct cpp_device *cpp_dev)
*/
usleep_range(1000, 1200);
rc = clk_reset(cpp_dev->cpp_clk[msm_micro_iface_idx],
CLK_RESET_DEASSERT);
rc = reset_control_deassert(cpp_dev->micro_iface_reset);
if (rc) {
pr_err("%s:micro_iface_clk de-assert failed\n", __func__);
pr_err("%s:micro_iface_reset de-assert failed\n", __func__);
return -EINVAL;
}