forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 072de836f53be56a70cecf70b43ae43b7ce17376
kernel/drivers/pwm/pwm-hibvt.c
....@@ -1,20 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * PWM Controller Driver for HiSilicon BVT SoCs
34 *
45 * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
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 as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
186 */
197
208 #include <linux/bitops.h>
....@@ -49,15 +37,30 @@
4937 struct clk *clk;
5038 void __iomem *base;
5139 struct reset_control *rstc;
40
+ const struct hibvt_pwm_soc *soc;
5241 };
5342
5443 struct hibvt_pwm_soc {
5544 u32 num_pwms;
45
+ bool quirk_force_enable;
5646 };
5747
58
-static const struct hibvt_pwm_soc pwm_soc[2] = {
59
- { .num_pwms = 4 },
60
- { .num_pwms = 8 },
48
+static const struct hibvt_pwm_soc hi3516cv300_soc_info = {
49
+ .num_pwms = 4,
50
+};
51
+
52
+static const struct hibvt_pwm_soc hi3519v100_soc_info = {
53
+ .num_pwms = 8,
54
+};
55
+
56
+static const struct hibvt_pwm_soc hi3559v100_shub_soc_info = {
57
+ .num_pwms = 8,
58
+ .quirk_force_enable = true,
59
+};
60
+
61
+static const struct hibvt_pwm_soc hi3559v100_soc_info = {
62
+ .num_pwms = 2,
63
+ .quirk_force_enable = true,
6164 };
6265
6366 static inline struct hibvt_pwm_chip *to_hibvt_pwm_chip(struct pwm_chip *chip)
....@@ -146,14 +149,24 @@
146149 }
147150
148151 static int hibvt_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
149
- struct pwm_state *state)
152
+ const struct pwm_state *state)
150153 {
154
+ struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip);
155
+
151156 if (state->polarity != pwm->state.polarity)
152157 hibvt_pwm_set_polarity(chip, pwm, state->polarity);
153158
154159 if (state->period != pwm->state.period ||
155
- state->duty_cycle != pwm->state.duty_cycle)
160
+ state->duty_cycle != pwm->state.duty_cycle) {
156161 hibvt_pwm_config(chip, pwm, state->duty_cycle, state->period);
162
+
163
+ /*
164
+ * Some implementations require the PWM to be enabled twice
165
+ * each time the duty cycle is refreshed.
166
+ */
167
+ if (hi_pwm_chip->soc->quirk_force_enable && state->enabled)
168
+ hibvt_pwm_enable(chip, pwm);
169
+ }
157170
158171 if (state->enabled != pwm->state.enabled) {
159172 if (state->enabled)
....@@ -198,6 +211,7 @@
198211 pwm_chip->chip.npwm = soc->num_pwms;
199212 pwm_chip->chip.of_xlate = of_pwm_xlate_with_flags;
200213 pwm_chip->chip.of_pwm_n_cells = 3;
214
+ pwm_chip->soc = soc;
201215
202216 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
203217 pwm_chip->base = devm_ioremap_resource(&pdev->dev, res);
....@@ -250,8 +264,14 @@
250264 }
251265
252266 static const struct of_device_id hibvt_pwm_of_match[] = {
253
- { .compatible = "hisilicon,hi3516cv300-pwm", .data = &pwm_soc[0] },
254
- { .compatible = "hisilicon,hi3519v100-pwm", .data = &pwm_soc[1] },
267
+ { .compatible = "hisilicon,hi3516cv300-pwm",
268
+ .data = &hi3516cv300_soc_info },
269
+ { .compatible = "hisilicon,hi3519v100-pwm",
270
+ .data = &hi3519v100_soc_info },
271
+ { .compatible = "hisilicon,hi3559v100-shub-pwm",
272
+ .data = &hi3559v100_shub_soc_info },
273
+ { .compatible = "hisilicon,hi3559v100-pwm",
274
+ .data = &hi3559v100_soc_info },
255275 { }
256276 };
257277 MODULE_DEVICE_TABLE(of, hibvt_pwm_of_match);