mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-13 08:07:32 -04:00
clk: qcom: lahaina: Add runtime_pm support
Add runtime_pm support for clock providers which have register access requirements that aren't always satisfied. Stop registers clocks previously flagged as CLK_IS_CRITICAL, since doing so means the device is always active and suspend is never called. Instead, just enable these clocks by default in HW during probe. Change-Id: I34cf74080745b627b3978fafd9eb8bbde4bb655e Signed-off-by: Mike Tipton <mdtipton@codeaurora.org>
This commit is contained in:
parent
7c2b115d51
commit
5004b21405
3 changed files with 66 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,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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