1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2012-2015, 2017-2018, The Linux Foundation.
7 #include <linux/clk/clk-conf.h>
9 #include <linux/delay.h>
12 #include <drm/drm_print.h>
14 #include "dpu_io_util.h"
16 void msm_dss_put_clk(struct dss_clk
*clk_arry
, int num_clk
)
20 for (i
= num_clk
- 1; i
>= 0; i
--) {
22 clk_put(clk_arry
[i
].clk
);
23 clk_arry
[i
].clk
= NULL
;
27 int msm_dss_get_clk(struct device
*dev
, struct dss_clk
*clk_arry
, int num_clk
)
31 for (i
= 0; i
< num_clk
; i
++) {
32 clk_arry
[i
].clk
= clk_get(dev
, clk_arry
[i
].clk_name
);
33 rc
= PTR_ERR_OR_ZERO(clk_arry
[i
].clk
);
35 DEV_ERR("%pS->%s: '%s' get failed. rc=%d\n",
36 __builtin_return_address(0), __func__
,
37 clk_arry
[i
].clk_name
, rc
);
45 for (i
--; i
>= 0; i
--) {
47 clk_put(clk_arry
[i
].clk
);
48 clk_arry
[i
].clk
= NULL
;
54 int msm_dss_clk_set_rate(struct dss_clk
*clk_arry
, int num_clk
)
58 for (i
= 0; i
< num_clk
; i
++) {
59 if (clk_arry
[i
].clk
) {
60 if (clk_arry
[i
].type
!= DSS_CLK_AHB
) {
61 DEV_DBG("%pS->%s: '%s' rate %ld\n",
62 __builtin_return_address(0), __func__
,
65 rc
= clk_set_rate(clk_arry
[i
].clk
,
68 DEV_ERR("%pS->%s: %s failed. rc=%d\n",
69 __builtin_return_address(0),
71 clk_arry
[i
].clk_name
, rc
);
76 DEV_ERR("%pS->%s: '%s' is not available\n",
77 __builtin_return_address(0), __func__
,
78 clk_arry
[i
].clk_name
);
87 int msm_dss_enable_clk(struct dss_clk
*clk_arry
, int num_clk
, int enable
)
92 for (i
= 0; i
< num_clk
; i
++) {
93 DEV_DBG("%pS->%s: enable '%s'\n",
94 __builtin_return_address(0), __func__
,
95 clk_arry
[i
].clk_name
);
96 rc
= clk_prepare_enable(clk_arry
[i
].clk
);
98 DEV_ERR("%pS->%s: %s en fail. rc=%d\n",
99 __builtin_return_address(0),
101 clk_arry
[i
].clk_name
, rc
);
104 msm_dss_enable_clk(&clk_arry
[i
- 1],
110 for (i
= num_clk
- 1; i
>= 0; i
--) {
111 DEV_DBG("%pS->%s: disable '%s'\n",
112 __builtin_return_address(0), __func__
,
113 clk_arry
[i
].clk_name
);
115 clk_disable_unprepare(clk_arry
[i
].clk
);
122 int msm_dss_parse_clock(struct platform_device
*pdev
,
123 struct dss_module_power
*mp
)
126 const char *clock_name
;
133 num_clk
= of_property_count_strings(pdev
->dev
.of_node
, "clock-names");
135 pr_debug("clocks are not defined\n");
139 mp
->clk_config
= devm_kcalloc(&pdev
->dev
,
140 num_clk
, sizeof(struct dss_clk
),
145 for (i
= 0; i
< num_clk
; i
++) {
146 rc
= of_property_read_string_index(pdev
->dev
.of_node
,
150 DRM_DEV_ERROR(&pdev
->dev
, "Failed to get clock name for %d\n",
154 strlcpy(mp
->clk_config
[i
].clk_name
, clock_name
,
155 sizeof(mp
->clk_config
[i
].clk_name
));
157 mp
->clk_config
[i
].type
= DSS_CLK_AHB
;
160 rc
= msm_dss_get_clk(&pdev
->dev
, mp
->clk_config
, num_clk
);
162 DRM_DEV_ERROR(&pdev
->dev
, "Failed to get clock refs %d\n", rc
);
166 rc
= of_clk_set_defaults(pdev
->dev
.of_node
, false);
168 DRM_DEV_ERROR(&pdev
->dev
, "Failed to set clock defaults %d\n", rc
);
172 for (i
= 0; i
< num_clk
; i
++) {
173 u32 rate
= clk_get_rate(mp
->clk_config
[i
].clk
);
176 mp
->clk_config
[i
].rate
= rate
;
177 mp
->clk_config
[i
].type
= DSS_CLK_PCLK
;
178 mp
->clk_config
[i
].max_rate
= rate
;
181 mp
->num_clk
= num_clk
;
185 msm_dss_put_clk(mp
->clk_config
, num_clk
);