hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/pwm/pwm-rockchip.c
....@@ -1,16 +1,16 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * PWM driver for Rockchip SoCs
34 *
45 * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
56 * Copyright (C) 2014 ROCKCHIP, Inc.
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License
9
- * version 2 as published by the Free Software Foundation.
107 */
118
129 #include <linux/clk.h>
10
+#include <linux/interrupt.h>
1311 #include <linux/io.h>
12
+#include <linux/iopoll.h>
13
+#include <linux/irq.h>
1414 #include <linux/module.h>
1515 #include <linux/of.h>
1616 #include <linux/of_device.h>
....@@ -18,12 +18,19 @@
1818 #include <linux/platform_device.h>
1919 #include <linux/pwm.h>
2020 #include <linux/time.h>
21
+#include "pwm-rockchip.h"
22
+
23
+#define PWM_MAX_CHANNEL_NUM 4
2124
2225 #define PWM_CTRL_TIMER_EN (1 << 0)
2326 #define PWM_CTRL_OUTPUT_EN (1 << 3)
2427
2528 #define PWM_ENABLE (1 << 0)
26
-#define PWM_CONTINUOUS (1 << 1)
29
+#define PWM_MODE_SHIFT 1
30
+#define PWM_MODE_MASK (0x3 << PWM_MODE_SHIFT)
31
+#define PWM_ONESHOT (0 << PWM_MODE_SHIFT)
32
+#define PWM_CONTINUOUS (1 << PWM_MODE_SHIFT)
33
+#define PWM_CAPTURE (2 << PWM_MODE_SHIFT)
2734 #define PWM_DUTY_POSITIVE (1 << 3)
2835 #define PWM_DUTY_NEGATIVE (0 << 3)
2936 #define PWM_INACTIVE_NEGATIVE (0 << 4)
....@@ -33,9 +40,23 @@
3340 #define PWM_OUTPUT_CENTER (1 << 5)
3441 #define PWM_LOCK_EN (1 << 6)
3542 #define PWM_LP_DISABLE (0 << 8)
43
+#define PWM_CLK_SEL_SHIFT 9
44
+#define PWM_CLK_SEL_MASK (1 << PWM_CLK_SEL_SHIFT)
45
+#define PWM_SEL_NO_SCALED_CLOCK (0 << PWM_CLK_SEL_SHIFT)
46
+#define PWM_SEL_SCALED_CLOCK (1 << PWM_CLK_SEL_SHIFT)
47
+#define PWM_PRESCELE_SHIFT 12
48
+#define PWM_PRESCALE_MASK (0x3 << PWM_PRESCELE_SHIFT)
49
+#define PWM_SCALE_SHIFT 16
50
+#define PWM_SCALE_MASK (0xff << PWM_SCALE_SHIFT)
3651
3752 #define PWM_ONESHOT_COUNT_SHIFT 24
53
+#define PWM_ONESHOT_COUNT_MASK (0xff << PWM_ONESHOT_COUNT_SHIFT)
3854 #define PWM_ONESHOT_COUNT_MAX 256
55
+
56
+#define PWM_REG_INTSTS(n) ((3 - (n)) * 0x10 + 0x10)
57
+#define PWM_REG_INT_EN(n) ((3 - (n)) * 0x10 + 0x14)
58
+
59
+#define PWM_CH_INT(n) BIT(n)
3960
4061 struct rockchip_pwm_chip {
4162 struct pwm_chip chip;
....@@ -48,7 +69,9 @@
4869 unsigned long clk_rate;
4970 bool vop_pwm_en; /* indicate voppwm mirror register state */
5071 bool center_aligned;
51
- bool oneshot;
72
+ bool oneshot_en;
73
+ int channel_id;
74
+ int irq;
5275 };
5376
5477 struct rockchip_pwm_regs {
....@@ -81,44 +104,81 @@
81104 u32 enable_conf = pc->data->enable_conf;
82105 u64 tmp;
83106 u32 val;
107
+ u32 dclk_div;
84108 int ret;
85109
86
- ret = clk_enable(pc->pclk);
87
- if (ret)
88
- return;
110
+ if (!pc->oneshot_en) {
111
+ ret = clk_enable(pc->pclk);
112
+ if (ret)
113
+ return;
114
+ }
115
+
116
+ dclk_div = pc->oneshot_en ? 2 : 1;
89117
90118 tmp = readl_relaxed(pc->base + pc->data->regs.period);
91
- tmp *= pc->data->prescaler * NSEC_PER_SEC;
119
+ tmp *= dclk_div * pc->data->prescaler * NSEC_PER_SEC;
92120 state->period = DIV_ROUND_CLOSEST_ULL(tmp, pc->clk_rate);
93121
94122 tmp = readl_relaxed(pc->base + pc->data->regs.duty);
95
- tmp *= pc->data->prescaler * NSEC_PER_SEC;
123
+ tmp *= dclk_div * pc->data->prescaler * NSEC_PER_SEC;
96124 state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pc->clk_rate);
97125
98126 val = readl_relaxed(pc->base + pc->data->regs.ctrl);
99
- if (pc->data->supports_polarity)
100
- state->enabled = ((val & enable_conf) != enable_conf) ?
101
- false : true;
127
+ if (pc->oneshot_en)
128
+ enable_conf &= ~PWM_CONTINUOUS;
129
+ state->enabled = (val & enable_conf) == enable_conf;
130
+
131
+ if (pc->data->supports_polarity && !(val & PWM_DUTY_POSITIVE))
132
+ state->polarity = PWM_POLARITY_INVERSED;
102133 else
103
- state->enabled = ((val & enable_conf) == enable_conf) ?
104
- true : false;
134
+ state->polarity = PWM_POLARITY_NORMAL;
105135
106
- if (pc->data->supports_polarity) {
107
- if (!(val & PWM_DUTY_POSITIVE))
108
- state->polarity = PWM_POLARITY_INVERSED;
109
- }
136
+ if (!pc->oneshot_en)
137
+ clk_disable(pc->pclk);
138
+}
110139
111
- clk_disable(pc->pclk);
140
+static irqreturn_t rockchip_pwm_oneshot_irq(int irq, void *data)
141
+{
142
+ struct rockchip_pwm_chip *pc = data;
143
+ struct pwm_state state;
144
+ unsigned int id = pc->channel_id;
145
+ int val;
146
+
147
+ if (id > 3)
148
+ return IRQ_NONE;
149
+ val = readl_relaxed(pc->base + PWM_REG_INTSTS(id));
150
+
151
+ if ((val & PWM_CH_INT(id)) == 0)
152
+ return IRQ_NONE;
153
+
154
+ writel_relaxed(PWM_CH_INT(id), pc->base + PWM_REG_INTSTS(id));
155
+
156
+ /*
157
+ * Set pwm state to disabled when the oneshot mode finished.
158
+ */
159
+ pwm_get_state(&pc->chip.pwms[0], &state);
160
+ state.enabled = false;
161
+ pwm_apply_state(&pc->chip.pwms[0], &state);
162
+
163
+ rockchip_pwm_oneshot_callback(&pc->chip.pwms[0], &state);
164
+
165
+ return IRQ_HANDLED;
112166 }
113167
114168 static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
115
- struct pwm_state *state)
169
+ const struct pwm_state *state)
116170 {
117171 struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
118172 unsigned long period, duty;
119173 unsigned long flags;
120174 u64 div;
121175 u32 ctrl;
176
+ u8 dclk_div = 1;
177
+
178
+#ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
179
+ if (state->oneshot_count > 0 && state->oneshot_count <= PWM_ONESHOT_COUNT_MAX)
180
+ dclk_div = 2;
181
+#endif
122182
123183 /*
124184 * Since period and duty cycle registers have a width of 32
....@@ -126,11 +186,10 @@
126186 * default prescaler value for all practical clock rate values.
127187 */
128188 div = (u64)pc->clk_rate * state->period;
129
- period = DIV_ROUND_CLOSEST_ULL(div,
130
- pc->data->prescaler * NSEC_PER_SEC);
189
+ period = DIV_ROUND_CLOSEST_ULL(div, dclk_div * pc->data->prescaler * NSEC_PER_SEC);
131190
132191 div = (u64)pc->clk_rate * state->duty_cycle;
133
- duty = DIV_ROUND_CLOSEST_ULL(div, pc->data->prescaler * NSEC_PER_SEC);
192
+ duty = DIV_ROUND_CLOSEST_ULL(div, dclk_div * pc->data->prescaler * NSEC_PER_SEC);
134193
135194 local_irq_save(flags);
136195 /*
....@@ -146,15 +205,51 @@
146205 }
147206
148207 #ifdef CONFIG_PWM_ROCKCHIP_ONESHOT
149
- if (state->oneshot_count > PWM_ONESHOT_COUNT_MAX) {
150
- pc->oneshot = false;
151
- dev_err(chip->dev, "Oneshot_count value overflow.\n");
152
- } else if (state->oneshot_count > 0) {
153
- pc->oneshot = true;
208
+ if (state->oneshot_count > 0 && state->oneshot_count <= PWM_ONESHOT_COUNT_MAX) {
209
+ u32 int_ctrl;
210
+
211
+ /*
212
+ * This is a workaround, an uncertain waveform will be
213
+ * generated after oneshot ends. It is needed to enable
214
+ * the dclk scale function to resolve it. It doesn't
215
+ * matter what the scale factor is, just make sure the
216
+ * scale function is turned on, for which we set scale
217
+ * factor to 2.
218
+ */
219
+ ctrl &= ~PWM_SCALE_MASK;
220
+ ctrl |= (dclk_div / 2) << PWM_SCALE_SHIFT;
221
+ ctrl &= ~PWM_CLK_SEL_MASK;
222
+ ctrl |= PWM_SEL_SCALED_CLOCK;
223
+
224
+ pc->oneshot_en = true;
225
+ ctrl &= ~PWM_MODE_MASK;
226
+ ctrl |= PWM_ONESHOT;
227
+
228
+ ctrl &= ~PWM_ONESHOT_COUNT_MASK;
154229 ctrl |= (state->oneshot_count - 1) << PWM_ONESHOT_COUNT_SHIFT;
230
+
231
+ int_ctrl = readl_relaxed(pc->base + PWM_REG_INT_EN(pc->channel_id));
232
+ int_ctrl |= PWM_CH_INT(pc->channel_id);
233
+ writel_relaxed(int_ctrl, pc->base + PWM_REG_INT_EN(pc->channel_id));
155234 } else {
156
- pc->oneshot = false;
235
+ u32 int_ctrl;
236
+
237
+ ctrl &= ~PWM_SCALE_MASK;
238
+ ctrl &= ~PWM_CLK_SEL_MASK;
239
+ ctrl |= PWM_SEL_NO_SCALED_CLOCK;
240
+
241
+ if (state->oneshot_count)
242
+ dev_err(chip->dev, "Oneshot_count must be between 1 and 256.\n");
243
+
244
+ pc->oneshot_en = false;
245
+ ctrl &= ~PWM_MODE_MASK;
157246 ctrl |= PWM_CONTINUOUS;
247
+
248
+ ctrl &= ~PWM_ONESHOT_COUNT_MASK;
249
+
250
+ int_ctrl = readl_relaxed(pc->base + PWM_REG_INT_EN(pc->channel_id));
251
+ int_ctrl &= ~PWM_CH_INT(pc->channel_id);
252
+ writel_relaxed(int_ctrl, pc->base + PWM_REG_INT_EN(pc->channel_id));
158253 }
159254 #endif
160255
....@@ -211,7 +306,7 @@
211306
212307 if (enable) {
213308 val |= enable_conf;
214
- if (pc->oneshot)
309
+ if (pc->oneshot_en)
215310 val &= ~PWM_CONTINUOUS;
216311 } else {
217312 val &= ~enable_conf;
....@@ -228,16 +323,18 @@
228323 }
229324
230325 static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
231
- struct pwm_state *state)
326
+ const struct pwm_state *state)
232327 {
233328 struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
234329 struct pwm_state curstate;
235330 bool enabled;
236331 int ret = 0;
237332
238
- ret = clk_enable(pc->pclk);
239
- if (ret)
240
- return ret;
333
+ if (!pc->oneshot_en) {
334
+ ret = clk_enable(pc->pclk);
335
+ if (ret)
336
+ return ret;
337
+ }
241338
242339 pwm_get_state(pwm, &curstate);
243340 enabled = curstate.enabled;
....@@ -257,16 +354,11 @@
257354 goto out;
258355 }
259356
260
- /*
261
- * Update the state with the real hardware, which can differ a bit
262
- * because of period/duty_cycle approximation.
263
- */
264
- rockchip_pwm_get_state(chip, pwm, state);
265
-
266
- if (state->enabled || pc->oneshot)
357
+ if (state->enabled)
267358 ret = pinctrl_select_state(pc->pinctrl, pc->active_state);
268359 out:
269
- clk_disable(pc->pclk);
360
+ if (!pc->oneshot_en)
361
+ clk_disable(pc->pclk);
270362
271363 return ret;
272364 }
....@@ -349,11 +441,20 @@
349441 };
350442 MODULE_DEVICE_TABLE(of, rockchip_pwm_dt_ids);
351443
444
+static int rockchip_pwm_get_channel_id(const char *name)
445
+{
446
+ int len = strlen(name);
447
+
448
+ return name[len - 2] - '0';
449
+}
450
+
352451 static int rockchip_pwm_probe(struct platform_device *pdev)
353452 {
354453 const struct of_device_id *id;
355454 struct rockchip_pwm_chip *pc;
356455 struct resource *r;
456
+ u32 enable_conf, ctrl;
457
+ bool enabled;
357458 int ret, count;
358459
359460 id = of_match_device(rockchip_pwm_dt_ids, &pdev->dev);
....@@ -373,13 +474,9 @@
373474 pc->clk = devm_clk_get(&pdev->dev, "pwm");
374475 if (IS_ERR(pc->clk)) {
375476 pc->clk = devm_clk_get(&pdev->dev, NULL);
376
- if (IS_ERR(pc->clk)) {
377
- ret = PTR_ERR(pc->clk);
378
- if (ret != -EPROBE_DEFER)
379
- dev_err(&pdev->dev, "Can't get bus clk: %d\n",
380
- ret);
381
- return ret;
382
- }
477
+ if (IS_ERR(pc->clk))
478
+ return dev_err_probe(&pdev->dev, PTR_ERR(pc->clk),
479
+ "Can't get bus clk\n");
383480 }
384481
385482 count = of_count_phandle_with_args(pdev->dev.of_node,
....@@ -402,10 +499,34 @@
402499 return ret;
403500 }
404501
405
- ret = clk_prepare(pc->pclk);
502
+ ret = clk_prepare_enable(pc->pclk);
406503 if (ret) {
407
- dev_err(&pdev->dev, "Can't prepare APB clk: %d\n", ret);
504
+ dev_err(&pdev->dev, "Can't prepare enable APB clk: %d\n", ret);
408505 goto err_clk;
506
+ }
507
+
508
+ pc->channel_id = rockchip_pwm_get_channel_id(pdev->dev.of_node->full_name);
509
+ if (pc->channel_id < 0 || pc->channel_id >= PWM_MAX_CHANNEL_NUM) {
510
+ dev_err(&pdev->dev, "Channel id is out of range: %d\n", pc->channel_id);
511
+ ret = -EINVAL;
512
+ goto err_pclk;
513
+ }
514
+
515
+ if (IS_ENABLED(CONFIG_PWM_ROCKCHIP_ONESHOT)) {
516
+ pc->irq = platform_get_irq(pdev, 0);
517
+ if (pc->irq < 0) {
518
+ dev_err(&pdev->dev, "Get oneshot mode irq failed\n");
519
+ ret = pc->irq;
520
+ goto err_pclk;
521
+ }
522
+
523
+ ret = devm_request_irq(&pdev->dev, pc->irq, rockchip_pwm_oneshot_irq,
524
+ IRQF_NO_SUSPEND | IRQF_SHARED,
525
+ "rk_pwm_oneshot_irq", pc);
526
+ if (ret) {
527
+ dev_err(&pdev->dev, "Claim oneshot IRQ failed\n");
528
+ goto err_pclk;
529
+ }
409530 }
410531
411532 pc->pinctrl = devm_pinctrl_get(&pdev->dev);
....@@ -427,7 +548,7 @@
427548 pc->data = id->data;
428549 pc->chip.dev = &pdev->dev;
429550 pc->chip.ops = &rockchip_pwm_ops;
430
- pc->chip.base = -1;
551
+ pc->chip.base = of_alias_get_id(pdev->dev.of_node, "pwm");
431552 pc->chip.npwm = 1;
432553 pc->clk_rate = clk_get_rate(pc->clk);
433554
....@@ -435,6 +556,10 @@
435556 pc->chip.of_xlate = of_pwm_xlate_with_flags;
436557 pc->chip.of_pwm_n_cells = 3;
437558 }
559
+
560
+ enable_conf = pc->data->enable_conf;
561
+ ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
562
+ enabled = (ctrl & enable_conf) == enable_conf;
438563
439564 pc->center_aligned =
440565 device_property_read_bool(&pdev->dev, "center-aligned");
....@@ -446,13 +571,15 @@
446571 }
447572
448573 /* Keep the PWM clk enabled if the PWM appears to be up and running. */
449
- if (!pwm_is_enabled(pc->chip.pwms))
574
+ if (!enabled)
450575 clk_disable(pc->clk);
576
+
577
+ clk_disable(pc->pclk);
451578
452579 return 0;
453580
454581 err_pclk:
455
- clk_unprepare(pc->pclk);
582
+ clk_disable_unprepare(pc->pclk);
456583 err_clk:
457584 clk_disable_unprepare(pc->clk);
458585
....@@ -462,7 +589,27 @@
462589 static int rockchip_pwm_remove(struct platform_device *pdev)
463590 {
464591 struct rockchip_pwm_chip *pc = platform_get_drvdata(pdev);
592
+ struct pwm_state state;
593
+ u32 val;
465594
595
+ /*
596
+ * For oneshot mode, it is needed to wait for bit PWM_ENABLE
597
+ * to 0, which is automatic if all periods have been sent.
598
+ */
599
+ pwm_get_state(&pc->chip.pwms[0], &state);
600
+ if (state.enabled) {
601
+ if (pc->oneshot_en) {
602
+ if (readl_poll_timeout(pc->base + pc->data->regs.ctrl,
603
+ val, !(val & PWM_ENABLE), 1000, 10 * 1000))
604
+ dev_err(&pdev->dev, "Wait for oneshot to complete failed\n");
605
+ } else {
606
+ state.enabled = false;
607
+ pwm_apply_state(&pc->chip.pwms[0], &state);
608
+ }
609
+ }
610
+
611
+ if (pc->oneshot_en)
612
+ clk_disable(pc->pclk);
466613 clk_unprepare(pc->pclk);
467614 clk_unprepare(pc->clk);
468615