1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
4 */
5
6 #define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__
7
8 #include <linux/clk.h>
9 #include <linux/clk-provider.h>
10 #include <linux/regulator/consumer.h>
11 #include "dp_power.h"
12 #include "msm_drv.h"
13
14 struct dp_power_private {
15 struct dp_parser *parser;
16 struct platform_device *pdev;
17 struct clk *link_clk_src;
18 struct clk *pixel_provider;
19 struct clk *link_provider;
20 struct regulator_bulk_data supplies[DP_DEV_REGULATOR_MAX];
21
22 struct dp_power dp_power;
23 };
24
dp_power_regulator_disable(struct dp_power_private * power)25 static void dp_power_regulator_disable(struct dp_power_private *power)
26 {
27 struct regulator_bulk_data *s = power->supplies;
28 const struct dp_reg_entry *regs = power->parser->regulator_cfg->regs;
29 int num = power->parser->regulator_cfg->num;
30 int i;
31
32 DBG("");
33 for (i = num - 1; i >= 0; i--)
34 if (regs[i].disable_load >= 0)
35 regulator_set_load(s[i].consumer,
36 regs[i].disable_load);
37
38 regulator_bulk_disable(num, s);
39 }
40
dp_power_regulator_enable(struct dp_power_private * power)41 static int dp_power_regulator_enable(struct dp_power_private *power)
42 {
43 struct regulator_bulk_data *s = power->supplies;
44 const struct dp_reg_entry *regs = power->parser->regulator_cfg->regs;
45 int num = power->parser->regulator_cfg->num;
46 int ret, i;
47
48 DBG("");
49 for (i = 0; i < num; i++) {
50 if (regs[i].enable_load >= 0) {
51 ret = regulator_set_load(s[i].consumer,
52 regs[i].enable_load);
53 if (ret < 0) {
54 pr_err("regulator %d set op mode failed, %d\n",
55 i, ret);
56 goto fail;
57 }
58 }
59 }
60
61 ret = regulator_bulk_enable(num, s);
62 if (ret < 0) {
63 pr_err("regulator enable failed, %d\n", ret);
64 goto fail;
65 }
66
67 return 0;
68
69 fail:
70 for (i--; i >= 0; i--)
71 regulator_set_load(s[i].consumer, regs[i].disable_load);
72 return ret;
73 }
74
dp_power_regulator_init(struct dp_power_private * power)75 static int dp_power_regulator_init(struct dp_power_private *power)
76 {
77 struct regulator_bulk_data *s = power->supplies;
78 const struct dp_reg_entry *regs = power->parser->regulator_cfg->regs;
79 struct platform_device *pdev = power->pdev;
80 int num = power->parser->regulator_cfg->num;
81 int i, ret;
82
83 for (i = 0; i < num; i++)
84 s[i].supply = regs[i].name;
85
86 ret = devm_regulator_bulk_get(&pdev->dev, num, s);
87 if (ret < 0) {
88 pr_err("%s: failed to init regulator, ret=%d\n",
89 __func__, ret);
90 return ret;
91 }
92
93 return 0;
94 }
95
dp_power_clk_init(struct dp_power_private * power)96 static int dp_power_clk_init(struct dp_power_private *power)
97 {
98 int rc = 0;
99 struct dss_module_power *core, *ctrl, *stream;
100 struct device *dev = &power->pdev->dev;
101
102 core = &power->parser->mp[DP_CORE_PM];
103 ctrl = &power->parser->mp[DP_CTRL_PM];
104 stream = &power->parser->mp[DP_STREAM_PM];
105
106 rc = msm_dss_get_clk(dev, core->clk_config, core->num_clk);
107 if (rc) {
108 DRM_ERROR("failed to get %s clk. err=%d\n",
109 dp_parser_pm_name(DP_CORE_PM), rc);
110 return rc;
111 }
112
113 rc = msm_dss_get_clk(dev, ctrl->clk_config, ctrl->num_clk);
114 if (rc) {
115 DRM_ERROR("failed to get %s clk. err=%d\n",
116 dp_parser_pm_name(DP_CTRL_PM), rc);
117 msm_dss_put_clk(core->clk_config, core->num_clk);
118 return -ENODEV;
119 }
120
121 rc = msm_dss_get_clk(dev, stream->clk_config, stream->num_clk);
122 if (rc) {
123 DRM_ERROR("failed to get %s clk. err=%d\n",
124 dp_parser_pm_name(DP_CTRL_PM), rc);
125 msm_dss_put_clk(core->clk_config, core->num_clk);
126 return -ENODEV;
127 }
128
129 return 0;
130 }
131
dp_power_clk_deinit(struct dp_power_private * power)132 static int dp_power_clk_deinit(struct dp_power_private *power)
133 {
134 struct dss_module_power *core, *ctrl, *stream;
135
136 core = &power->parser->mp[DP_CORE_PM];
137 ctrl = &power->parser->mp[DP_CTRL_PM];
138 stream = &power->parser->mp[DP_STREAM_PM];
139
140 if (!core || !ctrl || !stream) {
141 DRM_ERROR("invalid power_data\n");
142 return -EINVAL;
143 }
144
145 msm_dss_put_clk(ctrl->clk_config, ctrl->num_clk);
146 msm_dss_put_clk(core->clk_config, core->num_clk);
147 msm_dss_put_clk(stream->clk_config, stream->num_clk);
148 return 0;
149 }
150
dp_power_clk_set_rate(struct dp_power_private * power,enum dp_pm_type module,bool enable)151 static int dp_power_clk_set_rate(struct dp_power_private *power,
152 enum dp_pm_type module, bool enable)
153 {
154 int rc = 0;
155 struct dss_module_power *mp = &power->parser->mp[module];
156
157 if (enable) {
158 rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
159 if (rc) {
160 DRM_ERROR("failed to set clks rate.\n");
161 return rc;
162 }
163 }
164
165 rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);
166 if (rc) {
167 DRM_ERROR("failed to %d clks, err: %d\n", enable, rc);
168 return rc;
169 }
170
171 return 0;
172 }
173
dp_power_clk_status(struct dp_power * dp_power,enum dp_pm_type pm_type)174 int dp_power_clk_status(struct dp_power *dp_power, enum dp_pm_type pm_type)
175 {
176 if (pm_type == DP_CORE_PM)
177 return dp_power->core_clks_on;
178
179 if (pm_type == DP_CTRL_PM)
180 return dp_power->link_clks_on;
181
182 if (pm_type == DP_STREAM_PM)
183 return dp_power->stream_clks_on;
184
185 return 0;
186 }
187
dp_power_clk_enable(struct dp_power * dp_power,enum dp_pm_type pm_type,bool enable)188 int dp_power_clk_enable(struct dp_power *dp_power,
189 enum dp_pm_type pm_type, bool enable)
190 {
191 int rc = 0;
192 struct dp_power_private *power;
193
194 power = container_of(dp_power, struct dp_power_private, dp_power);
195
196 if (pm_type != DP_CORE_PM && pm_type != DP_CTRL_PM &&
197 pm_type != DP_STREAM_PM) {
198 DRM_ERROR("unsupported power module: %s\n",
199 dp_parser_pm_name(pm_type));
200 return -EINVAL;
201 }
202
203 if (enable) {
204 if (pm_type == DP_CORE_PM && dp_power->core_clks_on) {
205 DRM_DEBUG_DP("core clks already enabled\n");
206 return 0;
207 }
208
209 if (pm_type == DP_CTRL_PM && dp_power->link_clks_on) {
210 DRM_DEBUG_DP("links clks already enabled\n");
211 return 0;
212 }
213
214 if (pm_type == DP_STREAM_PM && dp_power->stream_clks_on) {
215 DRM_DEBUG_DP("pixel clks already enabled\n");
216 return 0;
217 }
218
219 if ((pm_type == DP_CTRL_PM) && (!dp_power->core_clks_on)) {
220 DRM_DEBUG_DP("Enable core clks before link clks\n");
221
222 rc = dp_power_clk_set_rate(power, DP_CORE_PM, enable);
223 if (rc) {
224 DRM_ERROR("fail to enable clks: %s. err=%d\n",
225 dp_parser_pm_name(DP_CORE_PM), rc);
226 return rc;
227 }
228 dp_power->core_clks_on = true;
229 }
230 }
231
232 rc = dp_power_clk_set_rate(power, pm_type, enable);
233 if (rc) {
234 DRM_ERROR("failed to '%s' clks for: %s. err=%d\n",
235 enable ? "enable" : "disable",
236 dp_parser_pm_name(pm_type), rc);
237 return rc;
238 }
239
240 if (pm_type == DP_CORE_PM)
241 dp_power->core_clks_on = enable;
242 else if (pm_type == DP_STREAM_PM)
243 dp_power->stream_clks_on = enable;
244 else
245 dp_power->link_clks_on = enable;
246
247 DRM_DEBUG_DP("%s clocks for %s\n",
248 enable ? "enable" : "disable",
249 dp_parser_pm_name(pm_type));
250 DRM_DEBUG_DP("strem_clks:%s link_clks:%s core_clks:%s\n",
251 dp_power->stream_clks_on ? "on" : "off",
252 dp_power->link_clks_on ? "on" : "off",
253 dp_power->core_clks_on ? "on" : "off");
254
255 return 0;
256 }
257
dp_power_client_init(struct dp_power * dp_power)258 int dp_power_client_init(struct dp_power *dp_power)
259 {
260 int rc = 0;
261 struct dp_power_private *power;
262
263 if (!dp_power) {
264 DRM_ERROR("invalid power data\n");
265 return -EINVAL;
266 }
267
268 power = container_of(dp_power, struct dp_power_private, dp_power);
269
270 pm_runtime_enable(&power->pdev->dev);
271
272 rc = dp_power_regulator_init(power);
273 if (rc) {
274 DRM_ERROR("failed to init regulators %d\n", rc);
275 goto error;
276 }
277
278 rc = dp_power_clk_init(power);
279 if (rc) {
280 DRM_ERROR("failed to init clocks %d\n", rc);
281 goto error;
282 }
283 return 0;
284
285 error:
286 pm_runtime_disable(&power->pdev->dev);
287 return rc;
288 }
289
dp_power_client_deinit(struct dp_power * dp_power)290 void dp_power_client_deinit(struct dp_power *dp_power)
291 {
292 struct dp_power_private *power;
293
294 if (!dp_power) {
295 DRM_ERROR("invalid power data\n");
296 return;
297 }
298
299 power = container_of(dp_power, struct dp_power_private, dp_power);
300
301 dp_power_clk_deinit(power);
302 pm_runtime_disable(&power->pdev->dev);
303
304 }
305
dp_power_init(struct dp_power * dp_power,bool flip)306 int dp_power_init(struct dp_power *dp_power, bool flip)
307 {
308 int rc = 0;
309 struct dp_power_private *power = NULL;
310
311 if (!dp_power) {
312 DRM_ERROR("invalid power data\n");
313 return -EINVAL;
314 }
315
316 power = container_of(dp_power, struct dp_power_private, dp_power);
317
318 pm_runtime_get_sync(&power->pdev->dev);
319 rc = dp_power_regulator_enable(power);
320 if (rc) {
321 DRM_ERROR("failed to enable regulators, %d\n", rc);
322 goto exit;
323 }
324
325 rc = dp_power_clk_enable(dp_power, DP_CORE_PM, true);
326 if (rc) {
327 DRM_ERROR("failed to enable DP core clocks, %d\n", rc);
328 goto err_clk;
329 }
330
331 return 0;
332
333 err_clk:
334 dp_power_regulator_disable(power);
335 exit:
336 pm_runtime_put_sync(&power->pdev->dev);
337 return rc;
338 }
339
dp_power_deinit(struct dp_power * dp_power)340 int dp_power_deinit(struct dp_power *dp_power)
341 {
342 struct dp_power_private *power;
343
344 power = container_of(dp_power, struct dp_power_private, dp_power);
345
346 dp_power_clk_enable(dp_power, DP_CORE_PM, false);
347 dp_power_regulator_disable(power);
348 pm_runtime_put_sync(&power->pdev->dev);
349 return 0;
350 }
351
dp_power_get(struct dp_parser * parser)352 struct dp_power *dp_power_get(struct dp_parser *parser)
353 {
354 struct dp_power_private *power;
355 struct dp_power *dp_power;
356
357 if (!parser) {
358 DRM_ERROR("invalid input\n");
359 return ERR_PTR(-EINVAL);
360 }
361
362 power = devm_kzalloc(&parser->pdev->dev, sizeof(*power), GFP_KERNEL);
363 if (!power)
364 return ERR_PTR(-ENOMEM);
365
366 power->parser = parser;
367 power->pdev = parser->pdev;
368
369 dp_power = &power->dp_power;
370
371 return dp_power;
372 }
373