mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-15 01:01:56 -04:00
Merge "clk: qcom: lahaina: Add runtime_pm support"
This commit is contained in:
commit
65d212e2e0
9 changed files with 245 additions and 106 deletions
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include <dt-bindings/clock/qcom,camcc-lahaina.h>
|
||||
|
||||
|
|
@ -1931,24 +1932,6 @@ static struct clk_branch cam_cc_csiphy5_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch cam_cc_gdsc_clk = {
|
||||
.halt_reg = 0xc148,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0xc148,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cam_cc_gdsc_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &cam_cc_xo_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch cam_cc_icp_ahb_clk = {
|
||||
.halt_reg = 0xc094,
|
||||
.halt_check = BRANCH_HALT,
|
||||
|
|
@ -2866,7 +2849,6 @@ static struct clk_regmap *cam_cc_lahaina_clocks[] = {
|
|||
[CAM_CC_CSIPHY4_CLK] = &cam_cc_csiphy4_clk.clkr,
|
||||
[CAM_CC_CSIPHY5_CLK] = &cam_cc_csiphy5_clk.clkr,
|
||||
[CAM_CC_FAST_AHB_CLK_SRC] = &cam_cc_fast_ahb_clk_src.clkr,
|
||||
[CAM_CC_GDSC_CLK] = &cam_cc_gdsc_clk.clkr,
|
||||
[CAM_CC_ICP_AHB_CLK] = &cam_cc_icp_ahb_clk.clkr,
|
||||
[CAM_CC_ICP_CLK] = &cam_cc_icp_clk.clkr,
|
||||
[CAM_CC_ICP_CLK_SRC] = &cam_cc_icp_clk_src.clkr,
|
||||
|
|
@ -2972,7 +2954,7 @@ static const struct regmap_config cam_cc_lahaina_regmap_config = {
|
|||
.fast_io = true,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc cam_cc_lahaina_desc = {
|
||||
static struct qcom_cc_desc cam_cc_lahaina_desc = {
|
||||
.config = &cam_cc_lahaina_regmap_config,
|
||||
.clks = cam_cc_lahaina_clocks,
|
||||
.num_clks = ARRAY_SIZE(cam_cc_lahaina_clocks),
|
||||
|
|
@ -3014,23 +2996,22 @@ static int cam_cc_lahaina_fixup(struct platform_device *pdev,
|
|||
static int cam_cc_lahaina_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
clk = devm_clk_get(&pdev->dev, "cfg_ahb_clk");
|
||||
if (IS_ERR(clk)) {
|
||||
if (PTR_ERR(clk) != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev, "Unable to get ahb clock handle\n");
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
devm_clk_put(&pdev->dev, clk);
|
||||
|
||||
regmap = qcom_cc_map(pdev, &cam_cc_lahaina_desc);
|
||||
if (IS_ERR(regmap)) {
|
||||
dev_err(&pdev->dev, "Failed to map cam CC registers\n");
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
|
||||
ret = qcom_cc_runtime_init(pdev, &cam_cc_lahaina_desc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pm_runtime_get_sync(&pdev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clk_lucid_5lpe_pll_configure(&cam_cc_pll0, regmap, &cam_cc_pll0_config);
|
||||
clk_lucid_5lpe_pll_configure(&cam_cc_pll1, regmap, &cam_cc_pll1_config);
|
||||
clk_zonda_5lpe_pll_configure(&cam_cc_pll2, regmap, &cam_cc_pll2_config);
|
||||
|
|
@ -3043,12 +3024,19 @@ static int cam_cc_lahaina_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Keep clocks always enabled:
|
||||
* cam_cc_gdsc_clk
|
||||
*/
|
||||
regmap_update_bits(regmap, 0xc148, BIT(0), BIT(0));
|
||||
|
||||
ret = qcom_cc_really_probe(pdev, &cam_cc_lahaina_desc, regmap);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to register CAM CC clocks\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
dev_info(&pdev->dev, "Registered CAM CC clocks\n");
|
||||
|
||||
return ret;
|
||||
|
|
@ -3059,12 +3047,17 @@ static void cam_cc_lahaina_sync_state(struct device *dev)
|
|||
qcom_cc_sync_state(dev, &cam_cc_lahaina_desc);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops cam_cc_lahaina_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(qcom_cc_runtime_suspend, qcom_cc_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
static struct platform_driver cam_cc_lahaina_driver = {
|
||||
.probe = cam_cc_lahaina_probe,
|
||||
.driver = {
|
||||
.name = "lahaina-cam_cc",
|
||||
.of_match_table = cam_cc_lahaina_match_table,
|
||||
.sync_state = cam_cc_lahaina_sync_state,
|
||||
.pm = &cam_cc_lahaina_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -266,12 +266,22 @@ static u32 get_mux_divs(struct clk_hw *mux)
|
|||
|
||||
static int clk_debug_measure_get(void *data, u64 *val)
|
||||
{
|
||||
struct clk_regmap *rclk = NULL;
|
||||
struct clk_debug_mux *mux;
|
||||
struct clk_hw *hw = data;
|
||||
struct clk_hw *parent;
|
||||
int ret = 0;
|
||||
u32 regval;
|
||||
|
||||
if (clk_is_regmap_clk(hw))
|
||||
rclk = to_clk_regmap(hw);
|
||||
|
||||
if (rclk) {
|
||||
ret = clk_runtime_get_regmap(rclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
mutex_lock(&clk_debug_lock);
|
||||
|
||||
ret = clk_find_and_set_parent(measure, hw);
|
||||
|
|
@ -306,6 +316,8 @@ static int clk_debug_measure_get(void *data, u64 *val)
|
|||
}
|
||||
exit:
|
||||
mutex_unlock(&clk_debug_lock);
|
||||
if (rclk)
|
||||
clk_runtime_put_regmap(rclk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -501,8 +513,14 @@ static void clk_debug_print_hw(struct clk_hw *hw, struct seq_file *f)
|
|||
|
||||
if (clk_is_regmap_clk(hw)) {
|
||||
rclk = to_clk_regmap(hw);
|
||||
|
||||
if (clk_runtime_get_regmap(rclk))
|
||||
return;
|
||||
|
||||
if (rclk->ops && rclk->ops->list_registers)
|
||||
rclk->ops->list_registers(f, hw);
|
||||
|
||||
clk_runtime_put_regmap(rclk);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <linux/clk-provider.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include "clk-regmap.h"
|
||||
|
||||
|
|
@ -270,6 +271,8 @@ int devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk)
|
|||
{
|
||||
int ret;
|
||||
|
||||
rclk->dev = dev;
|
||||
|
||||
if (dev && dev_get_regmap(dev, NULL))
|
||||
rclk->regmap = dev_get_regmap(dev, NULL);
|
||||
else if (dev && dev->parent)
|
||||
|
|
@ -282,3 +285,24 @@ int devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk)
|
|||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_clk_register_regmap);
|
||||
|
||||
int clk_runtime_get_regmap(struct clk_regmap *rclk)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (pm_runtime_enabled(rclk->dev)) {
|
||||
ret = pm_runtime_get_sync(rclk->dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_runtime_get_regmap);
|
||||
|
||||
void clk_runtime_put_regmap(struct clk_regmap *rclk)
|
||||
{
|
||||
if (pm_runtime_enabled(rclk->dev))
|
||||
pm_runtime_put_sync(rclk->dev);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_runtime_put_regmap);
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ struct clk_regmap {
|
|||
struct clk_vdd_class_data vdd_data;
|
||||
struct clk_regmap_ops *ops;
|
||||
struct list_head list_node;
|
||||
struct device *dev;
|
||||
};
|
||||
#define to_clk_regmap(_hw) container_of(_hw, struct clk_regmap, hw)
|
||||
|
||||
|
|
@ -71,4 +72,7 @@ struct clk_register_data {
|
|||
u32 offset;
|
||||
};
|
||||
|
||||
int clk_runtime_get_regmap(struct clk_regmap *rclk);
|
||||
void clk_runtime_put_regmap(struct clk_regmap *rclk);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@
|
|||
#include <linux/reset-controller.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/clk/qcom.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/interconnect.h>
|
||||
#include <linux/pm_clock.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "clk-opp.h"
|
||||
|
|
@ -394,4 +398,123 @@ int qcom_clk_get_voltage(struct clk *clk, unsigned long rate)
|
|||
}
|
||||
EXPORT_SYMBOL(qcom_clk_get_voltage);
|
||||
|
||||
int qcom_cc_runtime_init(struct platform_device *pdev,
|
||||
struct qcom_cc_desc *desc)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
clk = clk_get_optional(dev, "iface");
|
||||
if (IS_ERR(clk)) {
|
||||
if (PTR_ERR(clk) != -EPROBE_DEFER)
|
||||
dev_err(dev, "unable to get iface clock\n");
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
clk_put(clk);
|
||||
|
||||
ret = clk_regulator_init(dev, desc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
desc->path = of_icc_get(dev, NULL);
|
||||
if (IS_ERR(desc->path)) {
|
||||
if (PTR_ERR(desc->path) != -EPROBE_DEFER)
|
||||
dev_err(dev, "error getting path\n");
|
||||
return PTR_ERR(desc->path);
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, desc);
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
ret = pm_clk_create(dev);
|
||||
if (ret)
|
||||
goto disable_pm_runtime;
|
||||
|
||||
ret = pm_clk_add(dev, "iface");
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to acquire iface clock\n");
|
||||
goto destroy_pm_clk;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
destroy_pm_clk:
|
||||
pm_clk_destroy(dev);
|
||||
|
||||
disable_pm_runtime:
|
||||
pm_runtime_disable(dev);
|
||||
icc_put(desc->path);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(qcom_cc_runtime_init);
|
||||
|
||||
int qcom_cc_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct qcom_cc_desc *desc = dev_get_drvdata(dev);
|
||||
struct clk_vdd_class_data vdd_data = {0};
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < desc->num_clk_regulators; i++) {
|
||||
vdd_data.vdd_class = desc->clk_regulators[i];
|
||||
if (!vdd_data.vdd_class)
|
||||
continue;
|
||||
|
||||
ret = clk_vote_vdd_level(&vdd_data, 1);
|
||||
if (ret) {
|
||||
dev_warn(dev, "%s: failed to vote voltage\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (desc->path) {
|
||||
ret = icc_set_bw(desc->path, 0, 1);
|
||||
if (ret) {
|
||||
dev_warn(dev, "%s: failed to vote bw\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = pm_clk_resume(dev);
|
||||
if (ret)
|
||||
dev_warn(dev, "%s: failed to enable clocks\n", __func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(qcom_cc_runtime_resume);
|
||||
|
||||
int qcom_cc_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct qcom_cc_desc *desc = dev_get_drvdata(dev);
|
||||
struct clk_vdd_class_data vdd_data = {0};
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
ret = pm_clk_suspend(dev);
|
||||
if (ret)
|
||||
dev_warn(dev, "%s: failed to disable clocks\n", __func__);
|
||||
|
||||
if (desc->path) {
|
||||
ret = icc_set_bw(desc->path, 0, 0);
|
||||
if (ret)
|
||||
dev_warn(dev, "%s: failed to unvote bw\n", __func__);
|
||||
}
|
||||
|
||||
for (i = 0; i < desc->num_clk_regulators; i++) {
|
||||
vdd_data.vdd_class = desc->clk_regulators[i];
|
||||
if (!vdd_data.vdd_class)
|
||||
continue;
|
||||
|
||||
ret = clk_unvote_vdd_level(&vdd_data, 1);
|
||||
if (ret)
|
||||
dev_warn(dev, "%s: failed to unvote voltage\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(qcom_cc_runtime_suspend);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ struct qcom_cc_desc {
|
|||
size_t num_clk_hws;
|
||||
struct clk_vdd_class **clk_regulators;
|
||||
size_t num_clk_regulators;
|
||||
struct icc_path *path;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -77,4 +78,10 @@ extern int qcom_cc_probe_by_index(struct platform_device *pdev, int index,
|
|||
const struct qcom_cc_desc *desc);
|
||||
extern const struct clk_ops clk_dummy_ops;
|
||||
void qcom_cc_sync_state(struct device *dev, const struct qcom_cc_desc *desc);
|
||||
|
||||
int qcom_cc_runtime_init(struct platform_device *pdev,
|
||||
struct qcom_cc_desc *desc);
|
||||
int qcom_cc_runtime_suspend(struct device *dev);
|
||||
int qcom_cc_runtime_resume(struct device *dev);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include <dt-bindings/clock/qcom,dispcc-lahaina.h>
|
||||
|
||||
|
|
@ -1422,24 +1423,6 @@ static struct clk_branch disp_cc_sleep_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_xo_clk = {
|
||||
.halt_reg = 0x605c,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x605c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_xo_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_xo_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap *disp_cc_lahaina_clocks[] = {
|
||||
[DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
|
||||
[DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
|
||||
|
|
@ -1502,7 +1485,6 @@ static struct clk_regmap *disp_cc_lahaina_clocks[] = {
|
|||
[DISP_CC_PLL1] = &disp_cc_pll1.clkr,
|
||||
[DISP_CC_SLEEP_CLK] = &disp_cc_sleep_clk.clkr,
|
||||
[DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr,
|
||||
[DISP_CC_XO_CLK] = &disp_cc_xo_clk.clkr,
|
||||
[DISP_CC_XO_CLK_SRC] = &disp_cc_xo_clk_src.clkr,
|
||||
};
|
||||
|
||||
|
|
@ -1519,7 +1501,7 @@ static const struct regmap_config disp_cc_lahaina_regmap_config = {
|
|||
.fast_io = true,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc disp_cc_lahaina_desc = {
|
||||
static struct qcom_cc_desc disp_cc_lahaina_desc = {
|
||||
.config = &disp_cc_lahaina_regmap_config,
|
||||
.clks = disp_cc_lahaina_clocks,
|
||||
.num_clks = ARRAY_SIZE(disp_cc_lahaina_clocks),
|
||||
|
|
@ -1538,20 +1520,19 @@ MODULE_DEVICE_TABLE(of, disp_cc_lahaina_match_table);
|
|||
static int disp_cc_lahaina_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
regmap = qcom_cc_map(pdev, &disp_cc_lahaina_desc);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
clk = devm_clk_get(&pdev->dev, "cfg_ahb_clk");
|
||||
if (IS_ERR(clk)) {
|
||||
if (PTR_ERR(clk) != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev, "Unable to get ahb clock handle\n");
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
devm_clk_put(&pdev->dev, clk);
|
||||
ret = qcom_cc_runtime_init(pdev, &disp_cc_lahaina_desc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pm_runtime_get_sync(&pdev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clk_lucid_5lpe_pll_configure(&disp_cc_pll0, regmap,
|
||||
&disp_cc_pll0_config);
|
||||
|
|
@ -1561,12 +1542,19 @@ static int disp_cc_lahaina_probe(struct platform_device *pdev)
|
|||
/* Enable clock gating for MDP clocks */
|
||||
regmap_update_bits(regmap, DISP_CC_MISC_CMD, 0x10, 0x10);
|
||||
|
||||
/*
|
||||
* Keep clocks always enabled:
|
||||
* disp_cc_xo_clk
|
||||
*/
|
||||
regmap_update_bits(regmap, 0x605c, BIT(0), BIT(0));
|
||||
|
||||
ret = qcom_cc_really_probe(pdev, &disp_cc_lahaina_desc, regmap);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to register DISP CC clocks\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
dev_info(&pdev->dev, "Registered DISP CC clocks\n");
|
||||
|
||||
return ret;
|
||||
|
|
@ -1577,12 +1565,17 @@ static void disp_cc_lahaina_sync_state(struct device *dev)
|
|||
qcom_cc_sync_state(dev, &disp_cc_lahaina_desc);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops disp_cc_lahaina_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(qcom_cc_runtime_suspend, qcom_cc_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
static struct platform_driver disp_cc_lahaina_driver = {
|
||||
.probe = disp_cc_lahaina_probe,
|
||||
.driver = {
|
||||
.name = "disp_cc-lahaina",
|
||||
.of_match_table = disp_cc_lahaina_match_table,
|
||||
.sync_state = disp_cc_lahaina_sync_state,
|
||||
.pm = &disp_cc_lahaina_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -197,6 +197,9 @@ int clk_regulator_init(struct device *dev, const struct qcom_cc_desc *desc)
|
|||
vdd_class = desc->clk_regulators[i];
|
||||
|
||||
for (cnt = 0; cnt < vdd_class->num_regulators; cnt++) {
|
||||
if (vdd_class->regulator[cnt])
|
||||
continue;
|
||||
|
||||
name = vdd_class->regulator_names[cnt];
|
||||
regulator = devm_regulator_get(dev, name);
|
||||
if (IS_ERR(regulator)) {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include <dt-bindings/clock/qcom,videocc-lahaina.h>
|
||||
|
||||
|
|
@ -361,26 +362,6 @@ static struct clk_regmap_div video_cc_mvs1c_div2_div_clk_src = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_ahb_clk = {
|
||||
.halt_reg = 0xe58,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.hwcg_reg = 0xe58,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0xe58,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "video_cc_ahb_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &video_cc_ahb_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_mvs0_clk = {
|
||||
.halt_reg = 0xd34,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
|
|
@ -495,26 +476,7 @@ static struct clk_branch video_cc_sleep_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_xo_clk = {
|
||||
.halt_reg = 0xeec,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0xeec,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "video_cc_xo_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &video_cc_xo_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap *video_cc_lahaina_clocks[] = {
|
||||
[VIDEO_CC_AHB_CLK] = &video_cc_ahb_clk.clkr,
|
||||
[VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr,
|
||||
[VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr,
|
||||
[VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr,
|
||||
|
|
@ -531,7 +493,6 @@ static struct clk_regmap *video_cc_lahaina_clocks[] = {
|
|||
&video_cc_mvs1c_div2_div_clk_src.clkr,
|
||||
[VIDEO_CC_SLEEP_CLK] = &video_cc_sleep_clk.clkr,
|
||||
[VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr,
|
||||
[VIDEO_CC_XO_CLK] = &video_cc_xo_clk.clkr,
|
||||
[VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr,
|
||||
[VIDEO_PLL0] = &video_pll0.clkr,
|
||||
[VIDEO_PLL1] = &video_pll1.clkr,
|
||||
|
|
@ -555,7 +516,7 @@ static const struct regmap_config video_cc_lahaina_regmap_config = {
|
|||
.fast_io = true,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc video_cc_lahaina_desc = {
|
||||
static struct qcom_cc_desc video_cc_lahaina_desc = {
|
||||
.config = &video_cc_lahaina_regmap_config,
|
||||
.clks = video_cc_lahaina_clocks,
|
||||
.num_clks = ARRAY_SIZE(video_cc_lahaina_clocks),
|
||||
|
|
@ -574,30 +535,38 @@ MODULE_DEVICE_TABLE(of, video_cc_lahaina_match_table);
|
|||
static int video_cc_lahaina_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
regmap = qcom_cc_map(pdev, &video_cc_lahaina_desc);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
clk = devm_clk_get(&pdev->dev, "cfg_ahb_clk");
|
||||
if (IS_ERR(clk)) {
|
||||
if (PTR_ERR(clk) != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev, "Unable to get ahb clock handle\n");
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
devm_clk_put(&pdev->dev, clk);
|
||||
ret = qcom_cc_runtime_init(pdev, &video_cc_lahaina_desc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pm_runtime_get_sync(&pdev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clk_lucid_5lpe_pll_configure(&video_pll0, regmap, &video_pll0_config);
|
||||
clk_lucid_5lpe_pll_configure(&video_pll1, regmap, &video_pll1_config);
|
||||
|
||||
/*
|
||||
* Keep clocks always enabled:
|
||||
* video_cc_ahb_clk
|
||||
* video_cc_xo_clk
|
||||
*/
|
||||
regmap_update_bits(regmap, 0xe58, BIT(0), BIT(0));
|
||||
regmap_update_bits(regmap, 0xeec, BIT(0), BIT(0));
|
||||
|
||||
ret = qcom_cc_really_probe(pdev, &video_cc_lahaina_desc, regmap);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to register VIDEO CC clocks\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
dev_info(&pdev->dev, "Registered VIDEO CC clocks\n");
|
||||
|
||||
return ret;
|
||||
|
|
@ -608,12 +577,17 @@ static void video_cc_lahaina_sync_state(struct device *dev)
|
|||
qcom_cc_sync_state(dev, &video_cc_lahaina_desc);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops video_cc_lahaina_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(qcom_cc_runtime_suspend, qcom_cc_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
static struct platform_driver video_cc_lahaina_driver = {
|
||||
.probe = video_cc_lahaina_probe,
|
||||
.driver = {
|
||||
.name = "video_cc-lahaina",
|
||||
.of_match_table = video_cc_lahaina_match_table,
|
||||
.sync_state = video_cc_lahaina_sync_state,
|
||||
.pm = &video_cc_lahaina_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue