Merge "msm: camera: Add support for reset controller framework"
This commit is contained in:
commit
9e2d528dc4
8 changed files with 70 additions and 16 deletions
|
@ -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";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue