OSDN Git Service

Merge android-4.4.143 (7bbfac1) into msm-4.4
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / drivers / gpu / drm / msm / sde_power_handle.c
1 /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 and
5  * only version 2 as published by the Free Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  */
13
14 #define pr_fmt(fmt)     "[drm:%s:%d]: " fmt, __func__, __LINE__
15
16 #include <linux/clk.h>
17 #include <linux/kernel.h>
18 #include <linux/of.h>
19 #include <linux/string.h>
20 #include <linux/of_address.h>
21 #include <linux/slab.h>
22 #include <linux/mutex.h>
23 #include <linux/of_platform.h>
24
25 #include <linux/msm-bus.h>
26 #include <linux/msm-bus-board.h>
27 #include <linux/sde_io_util.h>
28
29 #include "sde_power_handle.h"
30 #include "sde_trace.h"
31
32 struct sde_power_client *sde_power_client_create(
33         struct sde_power_handle *phandle, char *client_name)
34 {
35         struct sde_power_client *client;
36         static u32 id;
37
38         if (!client_name || !phandle) {
39                 pr_err("client name is null or invalid power data\n");
40                 return ERR_PTR(-EINVAL);
41         }
42
43         client = kzalloc(sizeof(struct sde_power_client), GFP_KERNEL);
44         if (!client)
45                 return ERR_PTR(-ENOMEM);
46
47         mutex_lock(&phandle->phandle_lock);
48         strlcpy(client->name, client_name, MAX_CLIENT_NAME_LEN);
49         client->usecase_ndx = VOTE_INDEX_DISABLE;
50         client->id = id;
51         pr_debug("client %s created:%pK id :%d\n", client_name,
52                 client, id);
53         id++;
54         list_add(&client->list, &phandle->power_client_clist);
55         mutex_unlock(&phandle->phandle_lock);
56
57         return client;
58 }
59
60 void sde_power_client_destroy(struct sde_power_handle *phandle,
61         struct sde_power_client *client)
62 {
63         if (!client  || !phandle) {
64                 pr_err("reg bus vote: invalid client handle\n");
65         } else {
66                 pr_debug("bus vote client %s destroyed:%pK id:%u\n",
67                         client->name, client, client->id);
68                 mutex_lock(&phandle->phandle_lock);
69                 list_del_init(&client->list);
70                 mutex_unlock(&phandle->phandle_lock);
71                 kfree(client);
72         }
73 }
74
75 static int sde_power_parse_dt_supply(struct platform_device *pdev,
76                                 struct dss_module_power *mp)
77 {
78         int i = 0, rc = 0;
79         u32 tmp = 0;
80         struct device_node *of_node = NULL, *supply_root_node = NULL;
81         struct device_node *supply_node = NULL;
82
83         if (!pdev || !mp) {
84                 pr_err("invalid input param pdev:%pK mp:%pK\n", pdev, mp);
85                 return -EINVAL;
86         }
87
88         of_node = pdev->dev.of_node;
89
90         mp->num_vreg = 0;
91         supply_root_node = of_get_child_by_name(of_node,
92                                                 "qcom,platform-supply-entries");
93         if (!supply_root_node) {
94                 pr_debug("no supply entry present\n");
95                 return rc;
96         }
97
98         for_each_child_of_node(supply_root_node, supply_node)
99                 mp->num_vreg++;
100
101         if (mp->num_vreg == 0) {
102                 pr_debug("no vreg\n");
103                 return rc;
104         }
105
106         pr_debug("vreg found. count=%d\n", mp->num_vreg);
107         mp->vreg_config = devm_kzalloc(&pdev->dev, sizeof(struct dss_vreg) *
108                                                 mp->num_vreg, GFP_KERNEL);
109         if (!mp->vreg_config) {
110                 rc = -ENOMEM;
111                 return rc;
112         }
113
114         for_each_child_of_node(supply_root_node, supply_node) {
115
116                 const char *st = NULL;
117
118                 rc = of_property_read_string(supply_node,
119                                                 "qcom,supply-name", &st);
120                 if (rc) {
121                         pr_err("error reading name. rc=%d\n", rc);
122                         goto error;
123                 }
124
125                 strlcpy(mp->vreg_config[i].vreg_name, st,
126                                         sizeof(mp->vreg_config[i].vreg_name));
127
128                 rc = of_property_read_u32(supply_node,
129                                         "qcom,supply-min-voltage", &tmp);
130                 if (rc) {
131                         pr_err("error reading min volt. rc=%d\n", rc);
132                         goto error;
133                 }
134                 mp->vreg_config[i].min_voltage = tmp;
135
136                 rc = of_property_read_u32(supply_node,
137                                         "qcom,supply-max-voltage", &tmp);
138                 if (rc) {
139                         pr_err("error reading max volt. rc=%d\n", rc);
140                         goto error;
141                 }
142                 mp->vreg_config[i].max_voltage = tmp;
143
144                 rc = of_property_read_u32(supply_node,
145                                         "qcom,supply-enable-load", &tmp);
146                 if (rc) {
147                         pr_err("error reading enable load. rc=%d\n", rc);
148                         goto error;
149                 }
150                 mp->vreg_config[i].enable_load = tmp;
151
152                 rc = of_property_read_u32(supply_node,
153                                         "qcom,supply-disable-load", &tmp);
154                 if (rc) {
155                         pr_err("error reading disable load. rc=%d\n", rc);
156                         goto error;
157                 }
158                 mp->vreg_config[i].disable_load = tmp;
159
160                 rc = of_property_read_u32(supply_node,
161                                         "qcom,supply-pre-on-sleep", &tmp);
162                 if (rc)
163                         pr_debug("error reading supply pre sleep value. rc=%d\n",
164                                                         rc);
165
166                 mp->vreg_config[i].pre_on_sleep = (!rc ? tmp : 0);
167
168                 rc = of_property_read_u32(supply_node,
169                                         "qcom,supply-pre-off-sleep", &tmp);
170                 if (rc)
171                         pr_debug("error reading supply pre sleep value. rc=%d\n",
172                                                         rc);
173
174                 mp->vreg_config[i].pre_off_sleep = (!rc ? tmp : 0);
175
176                 rc = of_property_read_u32(supply_node,
177                                         "qcom,supply-post-on-sleep", &tmp);
178                 if (rc)
179                         pr_debug("error reading supply post sleep value. rc=%d\n",
180                                                         rc);
181
182                 mp->vreg_config[i].post_on_sleep = (!rc ? tmp : 0);
183
184                 rc = of_property_read_u32(supply_node,
185                                         "qcom,supply-post-off-sleep", &tmp);
186                 if (rc)
187                         pr_debug("error reading supply post sleep value. rc=%d\n",
188                                                         rc);
189
190                 mp->vreg_config[i].post_off_sleep = (!rc ? tmp : 0);
191
192                 pr_debug("%s min=%d, max=%d, enable=%d, disable=%d, preonsleep=%d, postonsleep=%d, preoffsleep=%d, postoffsleep=%d\n",
193                                         mp->vreg_config[i].vreg_name,
194                                         mp->vreg_config[i].min_voltage,
195                                         mp->vreg_config[i].max_voltage,
196                                         mp->vreg_config[i].enable_load,
197                                         mp->vreg_config[i].disable_load,
198                                         mp->vreg_config[i].pre_on_sleep,
199                                         mp->vreg_config[i].post_on_sleep,
200                                         mp->vreg_config[i].pre_off_sleep,
201                                         mp->vreg_config[i].post_off_sleep);
202                 ++i;
203
204                 rc = 0;
205         }
206
207         return rc;
208
209 error:
210         if (mp->vreg_config) {
211                 devm_kfree(&pdev->dev, mp->vreg_config);
212                 mp->vreg_config = NULL;
213                 mp->num_vreg = 0;
214         }
215
216         return rc;
217 }
218
219 static int sde_power_parse_dt_clock(struct platform_device *pdev,
220                                         struct dss_module_power *mp)
221 {
222         u32 i = 0, rc = 0;
223         const char *clock_name;
224         u32 clock_rate = 0;
225         u32 clock_max_rate = 0;
226         int num_clk = 0;
227
228         if (!pdev || !mp) {
229                 pr_err("invalid input param pdev:%pK mp:%pK\n", pdev, mp);
230                 return -EINVAL;
231         }
232
233         mp->num_clk = 0;
234         num_clk = of_property_count_strings(pdev->dev.of_node,
235                                                         "clock-names");
236         if (num_clk <= 0) {
237                 pr_debug("clocks are not defined\n");
238                 goto clk_err;
239         }
240
241         mp->num_clk = num_clk;
242         mp->clk_config = devm_kzalloc(&pdev->dev,
243                         sizeof(struct dss_clk) * num_clk, GFP_KERNEL);
244         if (!mp->clk_config) {
245                 rc = -ENOMEM;
246                 mp->num_clk = 0;
247                 goto clk_err;
248         }
249
250         for (i = 0; i < num_clk; i++) {
251                 of_property_read_string_index(pdev->dev.of_node, "clock-names",
252                                                         i, &clock_name);
253                 strlcpy(mp->clk_config[i].clk_name, clock_name,
254                                 sizeof(mp->clk_config[i].clk_name));
255
256                 of_property_read_u32_index(pdev->dev.of_node, "clock-rate",
257                                                         i, &clock_rate);
258                 mp->clk_config[i].rate = clock_rate;
259
260                 if (!clock_rate)
261                         mp->clk_config[i].type = DSS_CLK_AHB;
262                 else
263                         mp->clk_config[i].type = DSS_CLK_PCLK;
264
265                 clock_max_rate = 0;
266                 of_property_read_u32_index(pdev->dev.of_node, "clock-max-rate",
267                                                         i, &clock_max_rate);
268                 mp->clk_config[i].max_rate = clock_max_rate;
269         }
270
271 clk_err:
272         return rc;
273 }
274
275 #ifdef CONFIG_QCOM_BUS_SCALING
276
277 #define MAX_AXI_PORT_COUNT 3
278
279 static int _sde_power_data_bus_set_quota(
280                 struct sde_power_data_bus_handle *pdbus,
281                 u64 ab_quota_rt, u64 ab_quota_nrt,
282                 u64 ib_quota_rt, u64 ib_quota_nrt)
283 {
284         int new_uc_idx;
285         u64 ab_quota[MAX_AXI_PORT_COUNT] = {0, 0};
286         u64 ib_quota[MAX_AXI_PORT_COUNT] = {0, 0};
287         int rc;
288
289         if (pdbus->data_bus_hdl < 1) {
290                 pr_err("invalid bus handle %d\n", pdbus->data_bus_hdl);
291                 return -EINVAL;
292         }
293
294         if (!ab_quota_rt && !ab_quota_nrt && !ib_quota_rt && !ib_quota_nrt)  {
295                 new_uc_idx = 0;
296         } else {
297                 int i;
298                 struct msm_bus_vectors *vect = NULL;
299                 struct msm_bus_scale_pdata *bw_table =
300                         pdbus->data_bus_scale_table;
301                 u32 nrt_axi_port_cnt = pdbus->nrt_axi_port_cnt;
302                 u32 total_axi_port_cnt = pdbus->axi_port_cnt;
303                 u32 rt_axi_port_cnt = total_axi_port_cnt - nrt_axi_port_cnt;
304                 int match_cnt = 0;
305
306                 if (!bw_table || !total_axi_port_cnt ||
307                     total_axi_port_cnt > MAX_AXI_PORT_COUNT) {
308                         pr_err("invalid input\n");
309                         return -EINVAL;
310                 }
311
312                 if (pdbus->bus_channels) {
313                         ib_quota_rt = div_u64(ib_quota_rt,
314                                                 pdbus->bus_channels);
315                         ib_quota_nrt = div_u64(ib_quota_nrt,
316                                                 pdbus->bus_channels);
317                 }
318
319                 if (nrt_axi_port_cnt) {
320
321                         ab_quota_rt = div_u64(ab_quota_rt, rt_axi_port_cnt);
322                         ab_quota_nrt = div_u64(ab_quota_nrt, nrt_axi_port_cnt);
323
324                         for (i = 0; i < total_axi_port_cnt; i++) {
325                                 if (i < rt_axi_port_cnt) {
326                                         ab_quota[i] = ab_quota_rt;
327                                         ib_quota[i] = ib_quota_rt;
328                                 } else {
329                                         ab_quota[i] = ab_quota_nrt;
330                                         ib_quota[i] = ib_quota_nrt;
331                                 }
332                         }
333                 } else {
334                         ab_quota[0] = div_u64(ab_quota_rt + ab_quota_nrt,
335                                         total_axi_port_cnt);
336                         ib_quota[0] = ib_quota_rt + ib_quota_nrt;
337
338                         for (i = 1; i < total_axi_port_cnt; i++) {
339                                 ab_quota[i] = ab_quota[0];
340                                 ib_quota[i] = ib_quota[0];
341                         }
342                 }
343
344                 for (i = 0; i < total_axi_port_cnt; i++) {
345                         vect = &bw_table->usecase
346                                 [pdbus->curr_bw_uc_idx].vectors[i];
347                         /* avoid performing updates for small changes */
348                         if ((ab_quota[i] == vect->ab) &&
349                                 (ib_quota[i] == vect->ib))
350                                 match_cnt++;
351                 }
352
353                 if (match_cnt == total_axi_port_cnt) {
354                         pr_debug("skip BW vote\n");
355                         return 0;
356                 }
357
358                 new_uc_idx = (pdbus->curr_bw_uc_idx %
359                         (bw_table->num_usecases - 1)) + 1;
360
361                 for (i = 0; i < total_axi_port_cnt; i++) {
362                         vect = &bw_table->usecase[new_uc_idx].vectors[i];
363                         vect->ab = ab_quota[i];
364                         vect->ib = ib_quota[i];
365
366                         pr_debug("uc_idx=%d %s path idx=%d ab=%llu ib=%llu\n",
367                                 new_uc_idx, (i < rt_axi_port_cnt) ? "rt" : "nrt"
368                                 , i, vect->ab, vect->ib);
369                 }
370         }
371         pdbus->curr_bw_uc_idx = new_uc_idx;
372         pdbus->ao_bw_uc_idx = new_uc_idx;
373
374         if ((pdbus->bus_ref_cnt == 0) && pdbus->curr_bw_uc_idx) {
375                 rc = 0;
376         } else { /* vote BW if bus_bw_cnt > 0 or uc_idx is zero */
377                 SDE_ATRACE_BEGIN("msm_bus_scale_req");
378                 rc = msm_bus_scale_client_update_request(pdbus->data_bus_hdl,
379                         new_uc_idx);
380                 SDE_ATRACE_END("msm_bus_scale_req");
381         }
382         return rc;
383 }
384
385 int sde_power_data_bus_set_quota(struct sde_power_handle *phandle,
386                 struct sde_power_client *pclient,
387                 int bus_client, u64 ab_quota, u64 ib_quota)
388 {
389         int rc = 0;
390         int i;
391         u64 total_ab_rt = 0, total_ib_rt = 0;
392         u64 total_ab_nrt = 0, total_ib_nrt = 0;
393         struct sde_power_client *client;
394
395         if (!phandle || !pclient ||
396                         bus_client >= SDE_POWER_HANDLE_DATA_BUS_CLIENT_MAX) {
397                 pr_err("invalid parameters\n");
398                 return -EINVAL;
399         }
400
401         mutex_lock(&phandle->phandle_lock);
402
403         pclient->ab[bus_client] = ab_quota;
404         pclient->ib[bus_client] = ib_quota;
405         trace_sde_perf_update_bus(bus_client, ab_quota, ib_quota);
406
407         list_for_each_entry(client, &phandle->power_client_clist, list) {
408                 for (i = 0; i < SDE_POWER_HANDLE_DATA_BUS_CLIENT_MAX; i++) {
409                         if (i == SDE_POWER_HANDLE_DATA_BUS_CLIENT_NRT) {
410                                 total_ab_nrt += client->ab[i];
411                                 total_ib_nrt += client->ib[i];
412                         } else {
413                                 total_ab_rt += client->ab[i];
414                                 total_ib_rt = max(total_ib_rt, client->ib[i]);
415                         }
416                 }
417         }
418
419         rc = _sde_power_data_bus_set_quota(&phandle->data_bus_handle,
420                         total_ab_rt, total_ab_nrt,
421                         total_ib_rt, total_ib_nrt);
422
423         mutex_unlock(&phandle->phandle_lock);
424
425         return rc;
426 }
427
428 static void sde_power_data_bus_unregister(
429                 struct sde_power_data_bus_handle *pdbus)
430 {
431         if (pdbus->data_bus_hdl) {
432                 msm_bus_scale_unregister_client(pdbus->data_bus_hdl);
433                 pdbus->data_bus_hdl = 0;
434         }
435 }
436
437 static int sde_power_data_bus_parse(struct platform_device *pdev,
438         struct sde_power_data_bus_handle *pdbus)
439 {
440         struct device_node *node;
441         int rc = 0;
442         int paths;
443
444         pdbus->bus_channels = 1;
445         rc = of_property_read_u32(pdev->dev.of_node,
446                 "qcom,sde-dram-channels", &pdbus->bus_channels);
447         if (rc) {
448                 pr_debug("number of channels property not specified\n");
449                 rc = 0;
450         }
451
452         pdbus->nrt_axi_port_cnt = 0;
453         rc = of_property_read_u32(pdev->dev.of_node,
454                         "qcom,sde-num-nrt-paths",
455                         &pdbus->nrt_axi_port_cnt);
456         if (rc) {
457                 pr_debug("number of axi port property not specified\n");
458                 rc = 0;
459         }
460
461         node = of_get_child_by_name(pdev->dev.of_node, "qcom,sde-data-bus");
462         if (node) {
463                 rc = of_property_read_u32(node,
464                                 "qcom,msm-bus,num-paths", &paths);
465                 if (rc) {
466                         pr_err("Error. qcom,msm-bus,num-paths not found\n");
467                         return rc;
468                 }
469                 pdbus->axi_port_cnt = paths;
470
471                 pdbus->data_bus_scale_table =
472                                 msm_bus_pdata_from_node(pdev, node);
473                 if (IS_ERR_OR_NULL(pdbus->data_bus_scale_table)) {
474                         pr_err("reg bus handle parsing failed\n");
475                         rc = PTR_ERR(pdbus->data_bus_scale_table);
476                         goto end;
477                 }
478                 pdbus->data_bus_hdl = msm_bus_scale_register_client(
479                                 pdbus->data_bus_scale_table);
480                 if (!pdbus->data_bus_hdl) {
481                         pr_err("data_bus_client register failed\n");
482                         rc = -EINVAL;
483                         goto end;
484                 }
485                 pr_debug("register data_bus_hdl=%x\n", pdbus->data_bus_hdl);
486
487                 /*
488                  * Following call will not result in actual vote rather update
489                  * the current index and ab/ib value. When continuous splash
490                  * is enabled, actual vote will happen when splash handoff is
491                  * done.
492                  */
493                 return _sde_power_data_bus_set_quota(pdbus,
494                                 SDE_POWER_HANDLE_DATA_BUS_AB_QUOTA,
495                                 SDE_POWER_HANDLE_DATA_BUS_AB_QUOTA,
496                                 SDE_POWER_HANDLE_DATA_BUS_IB_QUOTA,
497                                 SDE_POWER_HANDLE_DATA_BUS_IB_QUOTA);
498         }
499
500 end:
501         return rc;
502 }
503
504 static int sde_power_reg_bus_parse(struct platform_device *pdev,
505         struct sde_power_handle *phandle)
506 {
507         struct device_node *node;
508         struct msm_bus_scale_pdata *bus_scale_table;
509         int rc = 0;
510
511         node = of_get_child_by_name(pdev->dev.of_node, "qcom,sde-reg-bus");
512         if (node) {
513                 bus_scale_table = msm_bus_pdata_from_node(pdev, node);
514                 if (IS_ERR_OR_NULL(bus_scale_table)) {
515                         pr_err("reg bus handle parsing failed\n");
516                         rc = PTR_ERR(bus_scale_table);
517                         goto end;
518                 }
519                 phandle->reg_bus_hdl = msm_bus_scale_register_client(
520                               bus_scale_table);
521                 if (!phandle->reg_bus_hdl) {
522                         pr_err("reg_bus_client register failed\n");
523                         rc = -EINVAL;
524                         goto end;
525                 }
526                 pr_debug("register reg_bus_hdl=%x\n", phandle->reg_bus_hdl);
527         }
528
529 end:
530         return rc;
531 }
532
533 static void sde_power_reg_bus_unregister(u32 reg_bus_hdl)
534 {
535         if (reg_bus_hdl)
536                 msm_bus_scale_unregister_client(reg_bus_hdl);
537 }
538
539 static int sde_power_reg_bus_update(u32 reg_bus_hdl, u32 usecase_ndx)
540 {
541         int rc = 0;
542
543         if (reg_bus_hdl)
544                 rc = msm_bus_scale_client_update_request(reg_bus_hdl,
545                                                                 usecase_ndx);
546         if (rc)
547                 pr_err("failed to set reg bus vote rc=%d\n", rc);
548
549         return rc;
550 }
551 #else
552 static int sde_power_data_bus_parse(struct platform_device *pdev,
553         struct sde_power_data_bus_handle *pdbus)
554 {
555         return 0;
556 }
557
558 static void sde_power_data_bus_unregister(
559                 struct sde_power_data_bus_handle *pdbus)
560 {
561 }
562
563 int sde_power_data_bus_set_quota(struct sde_power_handle *phandle,
564                 struct sde_power_client *pclient,
565                 int bus_client, u64 ab_quota, u64 ib_quota)
566 {
567         return 0;
568 }
569
570 static int sde_power_reg_bus_parse(struct platform_device *pdev,
571         struct sde_power_handle *phandle)
572 {
573         return 0;
574 }
575
576 static void sde_power_reg_bus_unregister(u32 reg_bus_hdl)
577 {
578 }
579
580 static int sde_power_reg_bus_update(u32 reg_bus_hdl, u32 usecase_ndx)
581 {
582         return 0;
583 }
584 #endif
585
586 void sde_power_data_bus_bandwidth_ctrl(struct sde_power_handle *phandle,
587                 struct sde_power_client *pclient, int enable)
588 {
589         struct sde_power_data_bus_handle *pdbus;
590         int changed = 0;
591
592         if (!phandle || !pclient) {
593                 pr_err("invalid power/client handle\n");
594                 return;
595         }
596
597         pdbus = &phandle->data_bus_handle;
598
599         mutex_lock(&phandle->phandle_lock);
600         if (enable) {
601                 if (pdbus->bus_ref_cnt == 0)
602                         changed++;
603                 pdbus->bus_ref_cnt++;
604         } else {
605                 if (pdbus->bus_ref_cnt) {
606                         pdbus->bus_ref_cnt--;
607                         if (pdbus->bus_ref_cnt == 0)
608                                 changed++;
609                 } else {
610                         pr_debug("Can not be turned off\n");
611                 }
612         }
613
614         pr_debug("%pS: task:%s bw_cnt=%d changed=%d enable=%d\n",
615                 __builtin_return_address(0), current->group_leader->comm,
616                 pdbus->bus_ref_cnt, changed, enable);
617
618         if (changed) {
619                 SDE_ATRACE_INT("data_bus_ctrl", enable);
620
621                 if (!enable) {
622                         if (!pdbus->handoff_pending) {
623                                 msm_bus_scale_client_update_request(
624                                                 pdbus->data_bus_hdl, 0);
625                                 pdbus->ao_bw_uc_idx = 0;
626                         }
627                 } else {
628                         msm_bus_scale_client_update_request(
629                                         pdbus->data_bus_hdl,
630                                         pdbus->curr_bw_uc_idx);
631                 }
632         }
633
634         mutex_unlock(&phandle->phandle_lock);
635 }
636
637 int sde_power_resource_init(struct platform_device *pdev,
638         struct sde_power_handle *phandle)
639 {
640         int rc = 0;
641         struct dss_module_power *mp;
642
643         if (!phandle || !pdev) {
644                 pr_err("invalid input param\n");
645                 rc = -EINVAL;
646                 goto end;
647         }
648         mp = &phandle->mp;
649         phandle->dev = &pdev->dev;
650
651         rc = sde_power_parse_dt_clock(pdev, mp);
652         if (rc) {
653                 pr_err("device clock parsing failed\n");
654                 goto end;
655         }
656
657         rc = sde_power_parse_dt_supply(pdev, mp);
658         if (rc) {
659                 pr_err("device vreg supply parsing failed\n");
660                 goto parse_vreg_err;
661         }
662
663         rc = msm_dss_config_vreg(&pdev->dev,
664                                 mp->vreg_config, mp->num_vreg, 1);
665         if (rc) {
666                 pr_err("vreg config failed rc=%d\n", rc);
667                 goto vreg_err;
668         }
669
670         rc = msm_dss_get_clk(&pdev->dev, mp->clk_config, mp->num_clk);
671         if (rc) {
672                 pr_err("clock get failed rc=%d\n", rc);
673                 goto clk_err;
674         }
675
676         rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
677         if (rc) {
678                 pr_err("clock set rate failed rc=%d\n", rc);
679                 goto bus_err;
680         }
681
682         rc = sde_power_reg_bus_parse(pdev, phandle);
683         if (rc) {
684                 pr_err("register bus parse failed rc=%d\n", rc);
685                 goto bus_err;
686         }
687
688         rc = sde_power_data_bus_parse(pdev, &phandle->data_bus_handle);
689         if (rc) {
690                 pr_err("register data bus parse failed rc=%d\n", rc);
691                 goto data_bus_err;
692         }
693
694         INIT_LIST_HEAD(&phandle->power_client_clist);
695         mutex_init(&phandle->phandle_lock);
696
697         return rc;
698
699 data_bus_err:
700         sde_power_reg_bus_unregister(phandle->reg_bus_hdl);
701 bus_err:
702         msm_dss_put_clk(mp->clk_config, mp->num_clk);
703 clk_err:
704         msm_dss_config_vreg(&pdev->dev, mp->vreg_config, mp->num_vreg, 0);
705 vreg_err:
706         devm_kfree(&pdev->dev, mp->vreg_config);
707         mp->num_vreg = 0;
708 parse_vreg_err:
709         devm_kfree(&pdev->dev, mp->clk_config);
710         mp->num_clk = 0;
711 end:
712         return rc;
713 }
714
715 void sde_power_resource_deinit(struct platform_device *pdev,
716         struct sde_power_handle *phandle)
717 {
718         struct dss_module_power *mp;
719
720         if (!phandle || !pdev) {
721                 pr_err("invalid input param\n");
722                 return;
723         }
724         mp = &phandle->mp;
725
726         sde_power_data_bus_unregister(&phandle->data_bus_handle);
727
728         sde_power_reg_bus_unregister(phandle->reg_bus_hdl);
729
730         msm_dss_put_clk(mp->clk_config, mp->num_clk);
731
732         msm_dss_config_vreg(&pdev->dev, mp->vreg_config, mp->num_vreg, 0);
733
734         if (mp->clk_config)
735                 devm_kfree(&pdev->dev, mp->clk_config);
736
737         if (mp->vreg_config)
738                 devm_kfree(&pdev->dev, mp->vreg_config);
739
740         mp->num_vreg = 0;
741         mp->num_clk = 0;
742 }
743
744 int sde_power_resource_enable(struct sde_power_handle *phandle,
745         struct sde_power_client *pclient, bool enable)
746 {
747         int rc = 0;
748         bool changed = false;
749         u32 max_usecase_ndx = VOTE_INDEX_DISABLE, prev_usecase_ndx;
750         struct sde_power_client *client;
751         struct dss_module_power *mp;
752
753         if (!phandle || !pclient) {
754                 pr_err("invalid input argument\n");
755                 return -EINVAL;
756         }
757
758         mp = &phandle->mp;
759
760         mutex_lock(&phandle->phandle_lock);
761         if (enable)
762                 pclient->refcount++;
763         else if (pclient->refcount)
764                 pclient->refcount--;
765
766         if (pclient->refcount)
767                 pclient->usecase_ndx = VOTE_INDEX_LOW;
768         else
769                 pclient->usecase_ndx = VOTE_INDEX_DISABLE;
770
771         list_for_each_entry(client, &phandle->power_client_clist, list) {
772                 if (client->usecase_ndx < VOTE_INDEX_MAX &&
773                     client->usecase_ndx > max_usecase_ndx)
774                         max_usecase_ndx = client->usecase_ndx;
775         }
776
777         if (phandle->current_usecase_ndx != max_usecase_ndx) {
778                 changed = true;
779                 prev_usecase_ndx = phandle->current_usecase_ndx;
780                 phandle->current_usecase_ndx = max_usecase_ndx;
781         }
782
783         pr_debug("%pS: changed=%d current idx=%d request client %s id:%u enable:%d refcount:%d\n",
784                 __builtin_return_address(0), changed, max_usecase_ndx,
785                 pclient->name, pclient->id, enable, pclient->refcount);
786
787         if (!changed)
788                 goto end;
789
790         if (enable) {
791                 rc = msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, enable);
792                 if (rc) {
793                         pr_err("failed to enable vregs rc=%d\n", rc);
794                         goto vreg_err;
795                 }
796
797                 rc = sde_power_reg_bus_update(phandle->reg_bus_hdl,
798                                                         max_usecase_ndx);
799                 if (rc) {
800                         pr_err("failed to set reg bus vote rc=%d\n", rc);
801                         goto reg_bus_hdl_err;
802                 }
803
804                 rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);
805                 if (rc) {
806                         pr_err("clock enable failed rc:%d\n", rc);
807                         goto clk_err;
808                 }
809         } else {
810                 msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);
811
812                 sde_power_reg_bus_update(phandle->reg_bus_hdl,
813                                                         max_usecase_ndx);
814
815                 msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, enable);
816         }
817
818 end:
819         mutex_unlock(&phandle->phandle_lock);
820         return rc;
821
822 clk_err:
823         sde_power_reg_bus_update(phandle->reg_bus_hdl, prev_usecase_ndx);
824 reg_bus_hdl_err:
825         msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, 0);
826 vreg_err:
827         phandle->current_usecase_ndx = prev_usecase_ndx;
828         mutex_unlock(&phandle->phandle_lock);
829         return rc;
830 }
831
832 int sde_power_clk_set_rate(struct sde_power_handle *phandle, char *clock_name,
833         u64 rate)
834 {
835         int i, rc = -EINVAL;
836         struct dss_module_power *mp;
837
838         if (!phandle) {
839                 pr_err("invalid input power handle\n");
840                 return -EINVAL;
841         }
842         mp = &phandle->mp;
843
844         for (i = 0; i < mp->num_clk; i++) {
845                 if (!strcmp(mp->clk_config[i].clk_name, clock_name)) {
846                         if (mp->clk_config[i].max_rate &&
847                                         (rate > mp->clk_config[i].max_rate))
848                                 rate = mp->clk_config[i].max_rate;
849
850                         mp->clk_config[i].rate = rate;
851                         rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
852                         break;
853                 }
854         }
855
856         return rc;
857 }
858
859 u64 sde_power_clk_get_rate(struct sde_power_handle *phandle, char *clock_name)
860 {
861         int i;
862         struct dss_module_power *mp;
863         u64 rate = -EINVAL;
864
865         if (!phandle) {
866                 pr_err("invalid input power handle\n");
867                 return -EINVAL;
868         }
869         mp = &phandle->mp;
870
871         for (i = 0; i < mp->num_clk; i++) {
872                 if (!strcmp(mp->clk_config[i].clk_name, clock_name)) {
873                         rate = clk_get_rate(mp->clk_config[i].clk);
874                         break;
875                 }
876         }
877
878         return rate;
879 }
880
881 u64 sde_power_clk_get_max_rate(struct sde_power_handle *phandle,
882                 char *clock_name)
883 {
884         int i;
885         struct dss_module_power *mp;
886         u64 rate = 0;
887
888         if (!phandle) {
889                 pr_err("invalid input power handle\n");
890                 return 0;
891         }
892         mp = &phandle->mp;
893
894         for (i = 0; i < mp->num_clk; i++) {
895                 if (!strcmp(mp->clk_config[i].clk_name, clock_name)) {
896                         rate = mp->clk_config[i].max_rate;
897                         break;
898                 }
899         }
900
901         return rate;
902 }
903
904 struct clk *sde_power_clk_get_clk(struct sde_power_handle *phandle,
905                 char *clock_name)
906 {
907         int i;
908         struct dss_module_power *mp;
909         struct clk *clk = NULL;
910
911         if (!phandle) {
912                 pr_err("invalid input power handle\n");
913                 return 0;
914         }
915         mp = &phandle->mp;
916
917         for (i = 0; i < mp->num_clk; i++) {
918                 if (!strcmp(mp->clk_config[i].clk_name, clock_name)) {
919                         clk = mp->clk_config[i].clk;
920                         break;
921                 }
922         }
923
924         return clk;
925 }