1 /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
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.
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.
14 #define pr_fmt(fmt) "[drm:%s:%d]: " fmt, __func__, __LINE__
16 #include <linux/clk.h>
17 #include <linux/kernel.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>
25 #include <linux/msm-bus.h>
26 #include <linux/msm-bus-board.h>
27 #include <linux/sde_io_util.h>
29 #include "sde_power_handle.h"
30 #include "sde_trace.h"
32 struct sde_power_client *sde_power_client_create(
33 struct sde_power_handle *phandle, char *client_name)
35 struct sde_power_client *client;
38 if (!client_name || !phandle) {
39 pr_err("client name is null or invalid power data\n");
40 return ERR_PTR(-EINVAL);
43 client = kzalloc(sizeof(struct sde_power_client), GFP_KERNEL);
45 return ERR_PTR(-ENOMEM);
47 mutex_lock(&phandle->phandle_lock);
48 strlcpy(client->name, client_name, MAX_CLIENT_NAME_LEN);
49 client->usecase_ndx = VOTE_INDEX_DISABLE;
51 pr_debug("client %s created:%pK id :%d\n", client_name,
54 list_add(&client->list, &phandle->power_client_clist);
55 mutex_unlock(&phandle->phandle_lock);
60 void sde_power_client_destroy(struct sde_power_handle *phandle,
61 struct sde_power_client *client)
63 if (!client || !phandle) {
64 pr_err("reg bus vote: invalid client handle\n");
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);
75 static int sde_power_parse_dt_supply(struct platform_device *pdev,
76 struct dss_module_power *mp)
80 struct device_node *of_node = NULL, *supply_root_node = NULL;
81 struct device_node *supply_node = NULL;
84 pr_err("invalid input param pdev:%pK mp:%pK\n", pdev, mp);
88 of_node = pdev->dev.of_node;
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");
98 for_each_child_of_node(supply_root_node, supply_node)
101 if (mp->num_vreg == 0) {
102 pr_debug("no vreg\n");
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) {
114 for_each_child_of_node(supply_root_node, supply_node) {
116 const char *st = NULL;
118 rc = of_property_read_string(supply_node,
119 "qcom,supply-name", &st);
121 pr_err("error reading name. rc=%d\n", rc);
125 strlcpy(mp->vreg_config[i].vreg_name, st,
126 sizeof(mp->vreg_config[i].vreg_name));
128 rc = of_property_read_u32(supply_node,
129 "qcom,supply-min-voltage", &tmp);
131 pr_err("error reading min volt. rc=%d\n", rc);
134 mp->vreg_config[i].min_voltage = tmp;
136 rc = of_property_read_u32(supply_node,
137 "qcom,supply-max-voltage", &tmp);
139 pr_err("error reading max volt. rc=%d\n", rc);
142 mp->vreg_config[i].max_voltage = tmp;
144 rc = of_property_read_u32(supply_node,
145 "qcom,supply-enable-load", &tmp);
147 pr_err("error reading enable load. rc=%d\n", rc);
150 mp->vreg_config[i].enable_load = tmp;
152 rc = of_property_read_u32(supply_node,
153 "qcom,supply-disable-load", &tmp);
155 pr_err("error reading disable load. rc=%d\n", rc);
158 mp->vreg_config[i].disable_load = tmp;
160 rc = of_property_read_u32(supply_node,
161 "qcom,supply-pre-on-sleep", &tmp);
163 pr_debug("error reading supply pre sleep value. rc=%d\n",
166 mp->vreg_config[i].pre_on_sleep = (!rc ? tmp : 0);
168 rc = of_property_read_u32(supply_node,
169 "qcom,supply-pre-off-sleep", &tmp);
171 pr_debug("error reading supply pre sleep value. rc=%d\n",
174 mp->vreg_config[i].pre_off_sleep = (!rc ? tmp : 0);
176 rc = of_property_read_u32(supply_node,
177 "qcom,supply-post-on-sleep", &tmp);
179 pr_debug("error reading supply post sleep value. rc=%d\n",
182 mp->vreg_config[i].post_on_sleep = (!rc ? tmp : 0);
184 rc = of_property_read_u32(supply_node,
185 "qcom,supply-post-off-sleep", &tmp);
187 pr_debug("error reading supply post sleep value. rc=%d\n",
190 mp->vreg_config[i].post_off_sleep = (!rc ? tmp : 0);
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);
210 if (mp->vreg_config) {
211 devm_kfree(&pdev->dev, mp->vreg_config);
212 mp->vreg_config = NULL;
219 static int sde_power_parse_dt_clock(struct platform_device *pdev,
220 struct dss_module_power *mp)
223 const char *clock_name;
225 u32 clock_max_rate = 0;
229 pr_err("invalid input param pdev:%pK mp:%pK\n", pdev, mp);
234 num_clk = of_property_count_strings(pdev->dev.of_node,
237 pr_debug("clocks are not defined\n");
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) {
250 for (i = 0; i < num_clk; i++) {
251 of_property_read_string_index(pdev->dev.of_node, "clock-names",
253 strlcpy(mp->clk_config[i].clk_name, clock_name,
254 sizeof(mp->clk_config[i].clk_name));
256 of_property_read_u32_index(pdev->dev.of_node, "clock-rate",
258 mp->clk_config[i].rate = clock_rate;
261 mp->clk_config[i].type = DSS_CLK_AHB;
263 mp->clk_config[i].type = DSS_CLK_PCLK;
266 of_property_read_u32_index(pdev->dev.of_node, "clock-max-rate",
268 mp->clk_config[i].max_rate = clock_max_rate;
275 #ifdef CONFIG_QCOM_BUS_SCALING
277 #define MAX_AXI_PORT_COUNT 3
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)
285 u64 ab_quota[MAX_AXI_PORT_COUNT] = {0, 0};
286 u64 ib_quota[MAX_AXI_PORT_COUNT] = {0, 0};
289 if (pdbus->data_bus_hdl < 1) {
290 pr_err("invalid bus handle %d\n", pdbus->data_bus_hdl);
294 if (!ab_quota_rt && !ab_quota_nrt && !ib_quota_rt && !ib_quota_nrt) {
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;
306 if (!bw_table || !total_axi_port_cnt ||
307 total_axi_port_cnt > MAX_AXI_PORT_COUNT) {
308 pr_err("invalid input\n");
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);
319 if (nrt_axi_port_cnt) {
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);
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;
329 ab_quota[i] = ab_quota_nrt;
330 ib_quota[i] = ib_quota_nrt;
334 ab_quota[0] = div_u64(ab_quota_rt + ab_quota_nrt,
336 ib_quota[0] = ib_quota_rt + ib_quota_nrt;
338 for (i = 1; i < total_axi_port_cnt; i++) {
339 ab_quota[i] = ab_quota[0];
340 ib_quota[i] = ib_quota[0];
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))
353 if (match_cnt == total_axi_port_cnt) {
354 pr_debug("skip BW vote\n");
358 new_uc_idx = (pdbus->curr_bw_uc_idx %
359 (bw_table->num_usecases - 1)) + 1;
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];
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);
371 pdbus->curr_bw_uc_idx = new_uc_idx;
372 pdbus->ao_bw_uc_idx = new_uc_idx;
374 if ((pdbus->bus_ref_cnt == 0) && pdbus->curr_bw_uc_idx) {
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,
380 SDE_ATRACE_END("msm_bus_scale_req");
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)
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;
395 if (!phandle || !pclient ||
396 bus_client >= SDE_POWER_HANDLE_DATA_BUS_CLIENT_MAX) {
397 pr_err("invalid parameters\n");
401 mutex_lock(&phandle->phandle_lock);
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);
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];
413 total_ab_rt += client->ab[i];
414 total_ib_rt = max(total_ib_rt, client->ib[i]);
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);
423 mutex_unlock(&phandle->phandle_lock);
428 static void sde_power_data_bus_unregister(
429 struct sde_power_data_bus_handle *pdbus)
431 if (pdbus->data_bus_hdl) {
432 msm_bus_scale_unregister_client(pdbus->data_bus_hdl);
433 pdbus->data_bus_hdl = 0;
437 static int sde_power_data_bus_parse(struct platform_device *pdev,
438 struct sde_power_data_bus_handle *pdbus)
440 struct device_node *node;
444 pdbus->bus_channels = 1;
445 rc = of_property_read_u32(pdev->dev.of_node,
446 "qcom,sde-dram-channels", &pdbus->bus_channels);
448 pr_debug("number of channels property not specified\n");
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);
457 pr_debug("number of axi port property not specified\n");
461 node = of_get_child_by_name(pdev->dev.of_node, "qcom,sde-data-bus");
463 rc = of_property_read_u32(node,
464 "qcom,msm-bus,num-paths", &paths);
466 pr_err("Error. qcom,msm-bus,num-paths not found\n");
469 pdbus->axi_port_cnt = paths;
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);
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");
485 pr_debug("register data_bus_hdl=%x\n", pdbus->data_bus_hdl);
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
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);
504 static int sde_power_reg_bus_parse(struct platform_device *pdev,
505 struct sde_power_handle *phandle)
507 struct device_node *node;
508 struct msm_bus_scale_pdata *bus_scale_table;
511 node = of_get_child_by_name(pdev->dev.of_node, "qcom,sde-reg-bus");
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);
519 phandle->reg_bus_hdl = msm_bus_scale_register_client(
521 if (!phandle->reg_bus_hdl) {
522 pr_err("reg_bus_client register failed\n");
526 pr_debug("register reg_bus_hdl=%x\n", phandle->reg_bus_hdl);
533 static void sde_power_reg_bus_unregister(u32 reg_bus_hdl)
536 msm_bus_scale_unregister_client(reg_bus_hdl);
539 static int sde_power_reg_bus_update(u32 reg_bus_hdl, u32 usecase_ndx)
544 rc = msm_bus_scale_client_update_request(reg_bus_hdl,
547 pr_err("failed to set reg bus vote rc=%d\n", rc);
552 static int sde_power_data_bus_parse(struct platform_device *pdev,
553 struct sde_power_data_bus_handle *pdbus)
558 static void sde_power_data_bus_unregister(
559 struct sde_power_data_bus_handle *pdbus)
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)
570 static int sde_power_reg_bus_parse(struct platform_device *pdev,
571 struct sde_power_handle *phandle)
576 static void sde_power_reg_bus_unregister(u32 reg_bus_hdl)
580 static int sde_power_reg_bus_update(u32 reg_bus_hdl, u32 usecase_ndx)
586 void sde_power_data_bus_bandwidth_ctrl(struct sde_power_handle *phandle,
587 struct sde_power_client *pclient, int enable)
589 struct sde_power_data_bus_handle *pdbus;
592 if (!phandle || !pclient) {
593 pr_err("invalid power/client handle\n");
597 pdbus = &phandle->data_bus_handle;
599 mutex_lock(&phandle->phandle_lock);
601 if (pdbus->bus_ref_cnt == 0)
603 pdbus->bus_ref_cnt++;
605 if (pdbus->bus_ref_cnt) {
606 pdbus->bus_ref_cnt--;
607 if (pdbus->bus_ref_cnt == 0)
610 pr_debug("Can not be turned off\n");
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);
619 SDE_ATRACE_INT("data_bus_ctrl", 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;
628 msm_bus_scale_client_update_request(
630 pdbus->curr_bw_uc_idx);
634 mutex_unlock(&phandle->phandle_lock);
637 int sde_power_resource_init(struct platform_device *pdev,
638 struct sde_power_handle *phandle)
641 struct dss_module_power *mp;
643 if (!phandle || !pdev) {
644 pr_err("invalid input param\n");
649 phandle->dev = &pdev->dev;
651 rc = sde_power_parse_dt_clock(pdev, mp);
653 pr_err("device clock parsing failed\n");
657 rc = sde_power_parse_dt_supply(pdev, mp);
659 pr_err("device vreg supply parsing failed\n");
663 rc = msm_dss_config_vreg(&pdev->dev,
664 mp->vreg_config, mp->num_vreg, 1);
666 pr_err("vreg config failed rc=%d\n", rc);
670 rc = msm_dss_get_clk(&pdev->dev, mp->clk_config, mp->num_clk);
672 pr_err("clock get failed rc=%d\n", rc);
676 rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
678 pr_err("clock set rate failed rc=%d\n", rc);
682 rc = sde_power_reg_bus_parse(pdev, phandle);
684 pr_err("register bus parse failed rc=%d\n", rc);
688 rc = sde_power_data_bus_parse(pdev, &phandle->data_bus_handle);
690 pr_err("register data bus parse failed rc=%d\n", rc);
694 INIT_LIST_HEAD(&phandle->power_client_clist);
695 mutex_init(&phandle->phandle_lock);
700 sde_power_reg_bus_unregister(phandle->reg_bus_hdl);
702 msm_dss_put_clk(mp->clk_config, mp->num_clk);
704 msm_dss_config_vreg(&pdev->dev, mp->vreg_config, mp->num_vreg, 0);
706 devm_kfree(&pdev->dev, mp->vreg_config);
709 devm_kfree(&pdev->dev, mp->clk_config);
715 void sde_power_resource_deinit(struct platform_device *pdev,
716 struct sde_power_handle *phandle)
718 struct dss_module_power *mp;
720 if (!phandle || !pdev) {
721 pr_err("invalid input param\n");
726 sde_power_data_bus_unregister(&phandle->data_bus_handle);
728 sde_power_reg_bus_unregister(phandle->reg_bus_hdl);
730 msm_dss_put_clk(mp->clk_config, mp->num_clk);
732 msm_dss_config_vreg(&pdev->dev, mp->vreg_config, mp->num_vreg, 0);
735 devm_kfree(&pdev->dev, mp->clk_config);
738 devm_kfree(&pdev->dev, mp->vreg_config);
744 int sde_power_resource_enable(struct sde_power_handle *phandle,
745 struct sde_power_client *pclient, bool enable)
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;
753 if (!phandle || !pclient) {
754 pr_err("invalid input argument\n");
760 mutex_lock(&phandle->phandle_lock);
763 else if (pclient->refcount)
766 if (pclient->refcount)
767 pclient->usecase_ndx = VOTE_INDEX_LOW;
769 pclient->usecase_ndx = VOTE_INDEX_DISABLE;
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;
777 if (phandle->current_usecase_ndx != max_usecase_ndx) {
779 prev_usecase_ndx = phandle->current_usecase_ndx;
780 phandle->current_usecase_ndx = max_usecase_ndx;
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);
791 rc = msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, enable);
793 pr_err("failed to enable vregs rc=%d\n", rc);
797 rc = sde_power_reg_bus_update(phandle->reg_bus_hdl,
800 pr_err("failed to set reg bus vote rc=%d\n", rc);
801 goto reg_bus_hdl_err;
804 rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);
806 pr_err("clock enable failed rc:%d\n", rc);
810 msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);
812 sde_power_reg_bus_update(phandle->reg_bus_hdl,
815 msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, enable);
819 mutex_unlock(&phandle->phandle_lock);
823 sde_power_reg_bus_update(phandle->reg_bus_hdl, prev_usecase_ndx);
825 msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, 0);
827 phandle->current_usecase_ndx = prev_usecase_ndx;
828 mutex_unlock(&phandle->phandle_lock);
832 int sde_power_clk_set_rate(struct sde_power_handle *phandle, char *clock_name,
836 struct dss_module_power *mp;
839 pr_err("invalid input power handle\n");
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;
850 mp->clk_config[i].rate = rate;
851 rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
859 u64 sde_power_clk_get_rate(struct sde_power_handle *phandle, char *clock_name)
862 struct dss_module_power *mp;
866 pr_err("invalid input power handle\n");
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);
881 u64 sde_power_clk_get_max_rate(struct sde_power_handle *phandle,
885 struct dss_module_power *mp;
889 pr_err("invalid input power handle\n");
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;
904 struct clk *sde_power_clk_get_clk(struct sde_power_handle *phandle,
908 struct dss_module_power *mp;
909 struct clk *clk = NULL;
912 pr_err("invalid input power handle\n");
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;