hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/pwm/pwm-mtk-disp.c
....@@ -1,16 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * MediaTek display pulse-width-modulation controller driver.
34 * Copyright (c) 2015 MediaTek Inc.
45 * Author: YH Huang <yh.huang@mediatek.com>
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License version 2 as
8
- * published by the Free Software Foundation.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
146 */
157
168 #include <linux/clk.h>
....@@ -82,6 +74,19 @@
8274 u64 div, rate;
8375 int err;
8476
77
+ err = clk_prepare_enable(mdp->clk_main);
78
+ if (err < 0) {
79
+ dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
80
+ return err;
81
+ }
82
+
83
+ err = clk_prepare_enable(mdp->clk_mm);
84
+ if (err < 0) {
85
+ dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
86
+ clk_disable_unprepare(mdp->clk_main);
87
+ return err;
88
+ }
89
+
8590 /*
8691 * Find period, high_width and clk_div to suit duty_ns and period_ns.
8792 * Calculate proper div value to keep period value in the bound.
....@@ -95,8 +100,11 @@
95100 rate = clk_get_rate(mdp->clk_main);
96101 clk_div = div_u64(rate * period_ns, NSEC_PER_SEC) >>
97102 PWM_PERIOD_BIT_WIDTH;
98
- if (clk_div > PWM_CLKDIV_MAX)
103
+ if (clk_div > PWM_CLKDIV_MAX) {
104
+ clk_disable_unprepare(mdp->clk_mm);
105
+ clk_disable_unprepare(mdp->clk_main);
99106 return -EINVAL;
107
+ }
100108
101109 div = NSEC_PER_SEC * (clk_div + 1);
102110 period = div64_u64(rate * period_ns, div);
....@@ -106,14 +114,17 @@
106114 high_width = div64_u64(rate * duty_ns, div);
107115 value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
108116
109
- err = clk_enable(mdp->clk_main);
110
- if (err < 0)
111
- return err;
112
-
113
- err = clk_enable(mdp->clk_mm);
114
- if (err < 0) {
115
- clk_disable(mdp->clk_main);
116
- return err;
117
+ if (mdp->data->bls_debug && !mdp->data->has_commit) {
118
+ /*
119
+ * For MT2701, disable double buffer before writing register
120
+ * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
121
+ */
122
+ mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
123
+ mdp->data->bls_debug_mask,
124
+ mdp->data->bls_debug_mask);
125
+ mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
126
+ mdp->data->con0_sel,
127
+ mdp->data->con0_sel);
117128 }
118129
119130 mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
....@@ -132,8 +143,8 @@
132143 0x0);
133144 }
134145
135
- clk_disable(mdp->clk_mm);
136
- clk_disable(mdp->clk_main);
146
+ clk_disable_unprepare(mdp->clk_mm);
147
+ clk_disable_unprepare(mdp->clk_main);
137148
138149 return 0;
139150 }
....@@ -143,13 +154,16 @@
143154 struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
144155 int err;
145156
146
- err = clk_enable(mdp->clk_main);
147
- if (err < 0)
148
- return err;
149
-
150
- err = clk_enable(mdp->clk_mm);
157
+ err = clk_prepare_enable(mdp->clk_main);
151158 if (err < 0) {
152
- clk_disable(mdp->clk_main);
159
+ dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
160
+ return err;
161
+ }
162
+
163
+ err = clk_prepare_enable(mdp->clk_mm);
164
+ if (err < 0) {
165
+ dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
166
+ clk_disable_unprepare(mdp->clk_main);
153167 return err;
154168 }
155169
....@@ -166,8 +180,8 @@
166180 mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
167181 0x0);
168182
169
- clk_disable(mdp->clk_mm);
170
- clk_disable(mdp->clk_main);
183
+ clk_disable_unprepare(mdp->clk_mm);
184
+ clk_disable_unprepare(mdp->clk_main);
171185 }
172186
173187 static const struct pwm_ops mtk_disp_pwm_ops = {
....@@ -202,14 +216,6 @@
202216 if (IS_ERR(mdp->clk_mm))
203217 return PTR_ERR(mdp->clk_mm);
204218
205
- ret = clk_prepare(mdp->clk_main);
206
- if (ret < 0)
207
- return ret;
208
-
209
- ret = clk_prepare(mdp->clk_mm);
210
- if (ret < 0)
211
- goto disable_clk_main;
212
-
213219 mdp->chip.dev = &pdev->dev;
214220 mdp->chip.ops = &mtk_disp_pwm_ops;
215221 mdp->chip.base = -1;
....@@ -217,44 +223,22 @@
217223
218224 ret = pwmchip_add(&mdp->chip);
219225 if (ret < 0) {
220
- dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
221
- goto disable_clk_mm;
226
+ dev_err(&pdev->dev, "pwmchip_add() failed: %pe\n", ERR_PTR(ret));
227
+ return ret;
222228 }
223229
224230 platform_set_drvdata(pdev, mdp);
225231
226
- /*
227
- * For MT2701, disable double buffer before writing register
228
- * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
229
- */
230
- if (!mdp->data->has_commit) {
231
- mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
232
- mdp->data->bls_debug_mask,
233
- mdp->data->bls_debug_mask);
234
- mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
235
- mdp->data->con0_sel,
236
- mdp->data->con0_sel);
237
- }
238
-
239232 return 0;
240
-
241
-disable_clk_mm:
242
- clk_unprepare(mdp->clk_mm);
243
-disable_clk_main:
244
- clk_unprepare(mdp->clk_main);
245
- return ret;
246233 }
247234
248235 static int mtk_disp_pwm_remove(struct platform_device *pdev)
249236 {
250237 struct mtk_disp_pwm *mdp = platform_get_drvdata(pdev);
251
- int ret;
252238
253
- ret = pwmchip_remove(&mdp->chip);
254
- clk_unprepare(mdp->clk_mm);
255
- clk_unprepare(mdp->clk_main);
239
+ pwmchip_remove(&mdp->chip);
256240
257
- return ret;
241
+ return 0;
258242 }
259243
260244 static const struct mtk_pwm_data mt2701_pwm_data = {
....@@ -277,10 +261,21 @@
277261 .commit_mask = 0x1,
278262 };
279263
264
+static const struct mtk_pwm_data mt8183_pwm_data = {
265
+ .enable_mask = BIT(0),
266
+ .con0 = 0x18,
267
+ .con0_sel = 0x0,
268
+ .con1 = 0x1c,
269
+ .has_commit = false,
270
+ .bls_debug = 0x80,
271
+ .bls_debug_mask = 0x3,
272
+};
273
+
280274 static const struct of_device_id mtk_disp_pwm_of_match[] = {
281275 { .compatible = "mediatek,mt2701-disp-pwm", .data = &mt2701_pwm_data},
282276 { .compatible = "mediatek,mt6595-disp-pwm", .data = &mt8173_pwm_data},
283277 { .compatible = "mediatek,mt8173-disp-pwm", .data = &mt8173_pwm_data},
278
+ { .compatible = "mediatek,mt8183-disp-pwm", .data = &mt8183_pwm_data},
284279 { }
285280 };
286281 MODULE_DEVICE_TABLE(of, mtk_disp_pwm_of_match);