1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
6 #define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__
9 #include <linux/clk-provider.h>
10 #include <linux/regulator/consumer.h>
11 #include <linux/pm_opp.h>
15 struct dp_power_private {
16 struct dp_parser *parser;
17 struct platform_device *pdev;
19 struct drm_device *drm_dev;
20 struct clk *link_clk_src;
21 struct clk *pixel_provider;
22 struct clk *link_provider;
23 struct regulator_bulk_data supplies[DP_DEV_REGULATOR_MAX];
25 struct dp_power dp_power;
28 static void dp_power_regulator_disable(struct dp_power_private *power)
30 struct regulator_bulk_data *s = power->supplies;
31 const struct dp_reg_entry *regs = power->parser->regulator_cfg->regs;
32 int num = power->parser->regulator_cfg->num;
36 for (i = num - 1; i >= 0; i--)
37 if (regs[i].disable_load >= 0)
38 regulator_set_load(s[i].consumer,
39 regs[i].disable_load);
41 regulator_bulk_disable(num, s);
44 static int dp_power_regulator_enable(struct dp_power_private *power)
46 struct regulator_bulk_data *s = power->supplies;
47 const struct dp_reg_entry *regs = power->parser->regulator_cfg->regs;
48 int num = power->parser->regulator_cfg->num;
52 for (i = 0; i < num; i++) {
53 if (regs[i].enable_load >= 0) {
54 ret = regulator_set_load(s[i].consumer,
57 pr_err("regulator %d set op mode failed, %d\n",
64 ret = regulator_bulk_enable(num, s);
66 pr_err("regulator enable failed, %d\n", ret);
73 for (i--; i >= 0; i--)
74 regulator_set_load(s[i].consumer, regs[i].disable_load);
78 static int dp_power_regulator_init(struct dp_power_private *power)
80 struct regulator_bulk_data *s = power->supplies;
81 const struct dp_reg_entry *regs = power->parser->regulator_cfg->regs;
82 struct platform_device *pdev = power->pdev;
83 int num = power->parser->regulator_cfg->num;
86 for (i = 0; i < num; i++)
87 s[i].supply = regs[i].name;
89 ret = devm_regulator_bulk_get(&pdev->dev, num, s);
91 pr_err("%s: failed to init regulator, ret=%d\n",
99 static int dp_power_clk_init(struct dp_power_private *power)
102 struct dss_module_power *core, *ctrl, *stream;
103 struct device *dev = &power->pdev->dev;
105 core = &power->parser->mp[DP_CORE_PM];
106 ctrl = &power->parser->mp[DP_CTRL_PM];
107 stream = &power->parser->mp[DP_STREAM_PM];
109 rc = msm_dss_get_clk(dev, core->clk_config, core->num_clk);
111 DRM_ERROR("failed to get %s clk. err=%d\n",
112 dp_parser_pm_name(DP_CORE_PM), rc);
116 rc = msm_dss_get_clk(dev, ctrl->clk_config, ctrl->num_clk);
118 DRM_ERROR("failed to get %s clk. err=%d\n",
119 dp_parser_pm_name(DP_CTRL_PM), rc);
120 msm_dss_put_clk(core->clk_config, core->num_clk);
124 rc = msm_dss_get_clk(dev, stream->clk_config, stream->num_clk);
126 DRM_ERROR("failed to get %s clk. err=%d\n",
127 dp_parser_pm_name(DP_CTRL_PM), rc);
128 msm_dss_put_clk(core->clk_config, core->num_clk);
135 static int dp_power_clk_deinit(struct dp_power_private *power)
137 struct dss_module_power *core, *ctrl, *stream;
139 core = &power->parser->mp[DP_CORE_PM];
140 ctrl = &power->parser->mp[DP_CTRL_PM];
141 stream = &power->parser->mp[DP_STREAM_PM];
143 if (!core || !ctrl || !stream) {
144 DRM_ERROR("invalid power_data\n");
148 msm_dss_put_clk(ctrl->clk_config, ctrl->num_clk);
149 msm_dss_put_clk(core->clk_config, core->num_clk);
150 msm_dss_put_clk(stream->clk_config, stream->num_clk);
154 static int dp_power_clk_set_link_rate(struct dp_power_private *power,
155 struct dss_clk *clk_arry, int num_clk, int enable)
160 for (i = 0; i < num_clk; i++) {
161 if (clk_arry[i].clk) {
162 if (clk_arry[i].type == DSS_CLK_PCLK) {
164 rate = clk_arry[i].rate;
168 rc = dev_pm_opp_set_rate(power->dev, rate);
178 static int dp_power_clk_set_rate(struct dp_power_private *power,
179 enum dp_pm_type module, bool enable)
182 struct dss_module_power *mp = &power->parser->mp[module];
184 if (module == DP_CTRL_PM) {
185 rc = dp_power_clk_set_link_rate(power, mp->clk_config, mp->num_clk, enable);
187 DRM_ERROR("failed to set link clks rate\n");
193 rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
195 DRM_ERROR("failed to set clks rate\n");
201 rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);
203 DRM_ERROR("failed to %d clks, err: %d\n", enable, rc);
210 int dp_power_clk_status(struct dp_power *dp_power, enum dp_pm_type pm_type)
212 struct dp_power_private *power;
214 power = container_of(dp_power, struct dp_power_private, dp_power);
216 drm_dbg_dp(power->drm_dev,
217 "core_clk_on=%d link_clk_on=%d stream_clk_on=%d\n",
218 dp_power->core_clks_on, dp_power->link_clks_on, dp_power->stream_clks_on);
220 if (pm_type == DP_CORE_PM)
221 return dp_power->core_clks_on;
223 if (pm_type == DP_CTRL_PM)
224 return dp_power->link_clks_on;
226 if (pm_type == DP_STREAM_PM)
227 return dp_power->stream_clks_on;
232 int dp_power_clk_enable(struct dp_power *dp_power,
233 enum dp_pm_type pm_type, bool enable)
236 struct dp_power_private *power;
238 power = container_of(dp_power, struct dp_power_private, dp_power);
240 if (pm_type != DP_CORE_PM && pm_type != DP_CTRL_PM &&
241 pm_type != DP_STREAM_PM) {
242 DRM_ERROR("unsupported power module: %s\n",
243 dp_parser_pm_name(pm_type));
248 if (pm_type == DP_CORE_PM && dp_power->core_clks_on) {
249 drm_dbg_dp(power->drm_dev,
250 "core clks already enabled\n");
254 if (pm_type == DP_CTRL_PM && dp_power->link_clks_on) {
255 drm_dbg_dp(power->drm_dev,
256 "links clks already enabled\n");
260 if (pm_type == DP_STREAM_PM && dp_power->stream_clks_on) {
261 drm_dbg_dp(power->drm_dev,
262 "pixel clks already enabled\n");
266 if ((pm_type == DP_CTRL_PM) && (!dp_power->core_clks_on)) {
267 drm_dbg_dp(power->drm_dev,
268 "Enable core clks before link clks\n");
270 rc = dp_power_clk_set_rate(power, DP_CORE_PM, enable);
272 DRM_ERROR("fail to enable clks: %s. err=%d\n",
273 dp_parser_pm_name(DP_CORE_PM), rc);
276 dp_power->core_clks_on = true;
280 rc = dp_power_clk_set_rate(power, pm_type, enable);
282 DRM_ERROR("failed to '%s' clks for: %s. err=%d\n",
283 enable ? "enable" : "disable",
284 dp_parser_pm_name(pm_type), rc);
288 if (pm_type == DP_CORE_PM)
289 dp_power->core_clks_on = enable;
290 else if (pm_type == DP_STREAM_PM)
291 dp_power->stream_clks_on = enable;
293 dp_power->link_clks_on = enable;
295 drm_dbg_dp(power->drm_dev, "%s clocks for %s\n",
296 enable ? "enable" : "disable",
297 dp_parser_pm_name(pm_type));
298 drm_dbg_dp(power->drm_dev,
299 "strem_clks:%s link_clks:%s core_clks:%s\n",
300 dp_power->stream_clks_on ? "on" : "off",
301 dp_power->link_clks_on ? "on" : "off",
302 dp_power->core_clks_on ? "on" : "off");
307 int dp_power_client_init(struct dp_power *dp_power)
310 struct dp_power_private *power;
313 DRM_ERROR("invalid power data\n");
317 power = container_of(dp_power, struct dp_power_private, dp_power);
319 pm_runtime_enable(&power->pdev->dev);
321 rc = dp_power_regulator_init(power);
323 DRM_ERROR("failed to init regulators %d\n", rc);
327 rc = dp_power_clk_init(power);
329 DRM_ERROR("failed to init clocks %d\n", rc);
335 pm_runtime_disable(&power->pdev->dev);
339 void dp_power_client_deinit(struct dp_power *dp_power)
341 struct dp_power_private *power;
344 DRM_ERROR("invalid power data\n");
348 power = container_of(dp_power, struct dp_power_private, dp_power);
350 dp_power_clk_deinit(power);
351 pm_runtime_disable(&power->pdev->dev);
355 int dp_power_init(struct dp_power *dp_power, bool flip)
358 struct dp_power_private *power = NULL;
361 DRM_ERROR("invalid power data\n");
365 power = container_of(dp_power, struct dp_power_private, dp_power);
367 pm_runtime_get_sync(&power->pdev->dev);
368 rc = dp_power_regulator_enable(power);
370 DRM_ERROR("failed to enable regulators, %d\n", rc);
374 rc = dp_power_clk_enable(dp_power, DP_CORE_PM, true);
376 DRM_ERROR("failed to enable DP core clocks, %d\n", rc);
383 dp_power_regulator_disable(power);
385 pm_runtime_put_sync(&power->pdev->dev);
389 int dp_power_deinit(struct dp_power *dp_power)
391 struct dp_power_private *power;
393 power = container_of(dp_power, struct dp_power_private, dp_power);
395 dp_power_clk_enable(dp_power, DP_CORE_PM, false);
396 dp_power_regulator_disable(power);
397 pm_runtime_put_sync(&power->pdev->dev);
401 struct dp_power *dp_power_get(struct device *dev, struct dp_parser *parser)
403 struct dp_power_private *power;
404 struct dp_power *dp_power;
407 DRM_ERROR("invalid input\n");
408 return ERR_PTR(-EINVAL);
411 power = devm_kzalloc(&parser->pdev->dev, sizeof(*power), GFP_KERNEL);
413 return ERR_PTR(-ENOMEM);
415 power->parser = parser;
416 power->pdev = parser->pdev;
419 dp_power = &power->dp_power;