drm:verisilicon:hdmi-audio:Adjust when to configure registers
[platform/kernel/linux-starfive.git] / drivers / pwm / pwm-starfive-ptc.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * PWM driver for the StarFive JH7110 SoC
4  *
5  * Copyright (C) 2018 StarFive Technology Co., Ltd.
6  */
7
8 #include <dt-bindings/pwm/pwm.h>
9 #include <linux/module.h>
10 #include <linux/platform_device.h>
11 #include <linux/pm_runtime.h>
12 #include <linux/pwm.h>
13 #include <linux/slab.h>
14 #include <linux/clk.h>
15 #include <linux/reset.h>
16 #include <linux/io.h>
17
18 /* how many parameters can be transferred to ptc */
19 #define OF_PWM_N_CELLS                  3
20
21 /* max channel of pwm */
22 #define MAX_PWM                         8
23
24 /* PTC Register offsets */
25 #define REG_RPTC_CNTR                   0x0
26 #define REG_RPTC_HRC                    0x4
27 #define REG_RPTC_LRC                    0x8
28 #define REG_RPTC_CTRL                   0xC
29
30 /* Bit for PWM clock */
31 #define BIT_PWM_CLOCK_EN                31
32
33 /* Bit for clock gen soft reset */
34 #define BIT_CLK_GEN_SOFT_RESET          13
35
36 #define NS_PER_SECOND                   1000000000
37 #define DEFAULT_FREQ_HZ                 2000000
38
39 /*
40  * Access PTC register (cntr hrc lrc and ctrl),
41  * need to replace PWM_BASE_ADDR
42  */
43 #define REG_PTC_BASE_ADDR_SUB(base, N)  \
44 ((base) + (((N) > 3) ? (((N) % 4) * 0x10 + (1 << 15)) : ((N) * 0x10)))
45 #define REG_PTC_RPTC_CNTR(base, N)      (REG_PTC_BASE_ADDR_SUB(base, N))
46 #define REG_PTC_RPTC_HRC(base, N)       (REG_PTC_BASE_ADDR_SUB(base, N) + 0x4)
47 #define REG_PTC_RPTC_LRC(base, N)       (REG_PTC_BASE_ADDR_SUB(base, N) + 0x8)
48 #define REG_PTC_RPTC_CTRL(base, N)      (REG_PTC_BASE_ADDR_SUB(base, N) + 0xC)
49
50 /* PTC_RPTC_CTRL */
51 #define PTC_EN      BIT(0)
52 #define PTC_ECLK    BIT(1)
53 #define PTC_NEC     BIT(2)
54 #define PTC_OE      BIT(3)
55 #define PTC_SIGNLE  BIT(4)
56 #define PTC_INTE    BIT(5)
57 #define PTC_INT     BIT(6)
58 #define PTC_CNTRRST BIT(7)
59 #define PTC_CAPTE   BIT(8)
60
61 struct starfive_pwm_ptc_device {
62         struct pwm_chip         chip;
63         struct clk              *clk;
64         struct reset_control    *rst;
65         void __iomem            *regs;
66         int                     irq;
67         /*pwm apb clock frequency*/
68         unsigned int            approx_freq;
69 };
70
71 static inline struct starfive_pwm_ptc_device *
72                 chip_to_starfive_ptc(struct pwm_chip *c)
73 {
74         return container_of(c, struct starfive_pwm_ptc_device, chip);
75 }
76
77 static void starfive_pwm_ptc_get_state(struct pwm_chip *chip,
78                                        struct pwm_device *dev,
79                                        struct pwm_state *state)
80 {
81         struct starfive_pwm_ptc_device *pwm = chip_to_starfive_ptc(chip);
82         u32 data_lrc, data_hrc, data_ctrl;
83         u32 pwm_clk_ns = 0;
84
85         pm_runtime_get_sync(chip->dev);
86
87         data_lrc = ioread32(REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm));
88         data_hrc = ioread32(REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm));
89         data_ctrl = ioread32(REG_PTC_RPTC_CTRL(pwm->regs, dev->hwpwm));
90
91         pwm_clk_ns = NS_PER_SECOND / pwm->approx_freq;
92
93         state->period = data_lrc * pwm_clk_ns;
94         state->duty_cycle = data_hrc * pwm_clk_ns;
95         state->polarity = PWM_POLARITY_NORMAL;
96         state->enabled = (data_ctrl & PTC_EN) ? true : false;
97
98         pm_runtime_put(chip->dev);
99 }
100
101 static int starfive_pwm_ptc_apply(struct pwm_chip *chip,
102                                   struct pwm_device *dev,
103                                   struct pwm_state *state)
104 {
105         struct starfive_pwm_ptc_device *pwm = chip_to_starfive_ptc(chip);
106         u32 data_hrc = 0;
107         u32 data_lrc = 0;
108         u32 period_data = 0;
109         u32 duty_data = 0;
110         s64 multi = pwm->approx_freq;
111         s64 div = NS_PER_SECOND;
112         void __iomem *reg_addr;
113         u32 val;
114
115         if (state->enabled) {
116                 if (!pwm_is_enabled(dev)) {
117                         pm_runtime_get_sync(chip->dev);
118                         reg_addr = REG_PTC_RPTC_CTRL(pwm->regs, dev->hwpwm);
119                         val = ioread32(reg_addr);
120                         iowrite32(val | PTC_EN | PTC_OE, reg_addr);
121                 }
122         } else if (pwm_is_enabled(dev)) {
123                 reg_addr = REG_PTC_RPTC_CTRL(pwm->regs, dev->hwpwm);
124                 val = ioread32(reg_addr);
125                 iowrite32(val & ~(PTC_EN | PTC_OE), reg_addr);
126                 pm_runtime_put(chip->dev);
127                 return 0;
128         } else {
129                 return 0;
130         }
131
132         if (state->duty_cycle > state->period)
133                 state->duty_cycle = state->period;
134
135         while (multi % 10 == 0 && div % 10 == 0 && multi > 0 && div > 0) {
136                 multi /= 10;
137                 div /= 10;
138         }
139
140         period_data = (u32)(state->period * multi / div);
141         if (abs(period_data * div / multi - state->period)
142             > abs((period_data + 1) * div / multi - state->period) ||
143             (state->period > 0 && period_data == 0))
144                 period_data += 1;
145
146         duty_data = (u32)(state->duty_cycle * multi / div);
147         if (abs(duty_data * div / multi - state->duty_cycle)
148             > abs((duty_data + 1) * div / multi - state->duty_cycle) ||
149             (state->duty_cycle > 0 && duty_data == 0))
150                 duty_data += 1;
151
152         if (state->polarity == PWM_POLARITY_NORMAL)
153                 data_hrc = period_data - duty_data;
154         else
155                 data_hrc = duty_data;
156
157         data_lrc = period_data;
158
159         reg_addr = REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm);
160         iowrite32(data_hrc, reg_addr);
161
162         reg_addr = REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm);
163         iowrite32(data_lrc, reg_addr);
164
165         reg_addr = REG_PTC_RPTC_CNTR(pwm->regs, dev->hwpwm);
166         iowrite32(0, reg_addr);
167
168         return 0;
169 }
170
171 static const struct pwm_ops starfive_pwm_ptc_ops = {
172         .get_state      = starfive_pwm_ptc_get_state,
173         .apply          = (void *)starfive_pwm_ptc_apply,
174         .owner          = THIS_MODULE,
175 };
176
177 static int starfive_pwm_ptc_probe(struct platform_device *pdev)
178 {
179         struct device *dev = &pdev->dev;
180         struct device_node *node = pdev->dev.of_node;
181         struct starfive_pwm_ptc_device *pwm;
182         struct pwm_chip *chip;
183         struct resource *res;
184         unsigned int clk_apb_freq;
185         int ret;
186
187         pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL);
188         if (!pwm)
189                 return -ENOMEM;
190
191         chip = &pwm->chip;
192         chip->dev = dev;
193         chip->ops = &starfive_pwm_ptc_ops;
194
195         chip->of_pwm_n_cells = OF_PWM_N_CELLS;
196         chip->base = -1;
197
198         ret = of_property_read_u32(node, "starfive,npwm", &chip->npwm);
199         if (ret < 0 || chip->npwm > MAX_PWM)
200                 chip->npwm = MAX_PWM;
201
202         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
203         pwm->regs = devm_ioremap_resource(dev, res);
204         if (IS_ERR(pwm->regs)) {
205                 dev_err(dev, "Unable to map IO resources\n");
206                 return PTR_ERR(pwm->regs);
207         }
208
209         pwm->clk = devm_clk_get(dev, NULL);
210         if (IS_ERR(pwm->clk)) {
211                 dev_err(dev, "Unable to get pwm clock\n");
212                 return PTR_ERR(pwm->clk);
213         }
214         pwm->rst = devm_reset_control_get_exclusive(dev, NULL);
215         if (IS_ERR(pwm->rst)) {
216                 dev_err(dev, "Unable to get pwm reset\n");
217                 return PTR_ERR(pwm->rst);
218         }
219
220         ret = of_property_read_u32(node, "starfive,approx-freq",
221                                    &clk_apb_freq);
222         if (!ret)
223                 pwm->approx_freq = clk_apb_freq;
224         else
225                 pwm->approx_freq = DEFAULT_FREQ_HZ;
226
227         clk_apb_freq = (unsigned int)clk_get_rate(pwm->clk);
228         if (!clk_apb_freq)
229                 dev_warn(dev,
230                          "get pwm apb clock rate failed.\n");
231         else
232                 pwm->approx_freq = clk_apb_freq;
233
234         ret = pwmchip_add(chip);
235         if (ret < 0) {
236                 dev_err(dev, "cannot register PTC: %d\n", ret);
237                 clk_disable_unprepare(pwm->clk);
238                 return ret;
239         }
240
241         platform_set_drvdata(pdev, pwm);
242
243         pm_runtime_enable(dev);
244
245         return 0;
246 }
247
248 static int starfive_pwm_ptc_remove(struct platform_device *dev)
249 {
250         struct starfive_pwm_ptc_device *pwm = platform_get_drvdata(dev);
251         struct pwm_chip *chip = &pwm->chip;
252
253         clk_disable_unprepare(pwm->clk);
254         pwmchip_remove(chip);
255
256         pm_runtime_disable(&dev->dev);
257
258         return 0;
259 }
260
261 #if defined(CONFIG_PM) || defined(CONFIG_PM_SLEEP)
262 static int __maybe_unused starfive_pwm_runtime_suspend(struct device *dev)
263 {
264         struct starfive_pwm_ptc_device *pwm = dev_get_drvdata(dev);
265
266         dev_dbg(dev, "starfive pwm runtime suspending..");
267         reset_control_assert(pwm->rst);
268         clk_disable_unprepare(pwm->clk);
269
270         return 0;
271 }
272
273 static int __maybe_unused starfive_pwm_runtime_resume(struct device *dev)
274 {
275         struct starfive_pwm_ptc_device *pwm = dev_get_drvdata(dev);
276         int ret;
277
278         dev_dbg(dev, "starfive pwm runtime resuming..");
279         ret = clk_prepare_enable(pwm->clk);
280         if (ret)
281                 dev_err(dev,
282                         "Failed to resume pwm clock, %d\n", ret);
283         reset_control_deassert(pwm->rst);
284         return ret;
285 }
286 #endif
287
288 static const struct dev_pm_ops starfive_pwm_pm_ops = {
289         SET_RUNTIME_PM_OPS(starfive_pwm_runtime_suspend,
290                            starfive_pwm_runtime_resume, NULL)
291         SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
292                                 pm_runtime_force_resume)
293 };
294
295 static const struct of_device_id starfive_pwm_ptc_of_match[] = {
296         { .compatible = "starfive,jh7110-pwm" },
297         {},
298 };
299 MODULE_DEVICE_TABLE(of, starfive_pwm_ptc_of_match);
300
301 static struct platform_driver starfive_pwm_ptc_driver = {
302         .probe = starfive_pwm_ptc_probe,
303         .remove = starfive_pwm_ptc_remove,
304         .driver = {
305                 .name = "pwm-starfive-ptc",
306                 .of_match_table = of_match_ptr(starfive_pwm_ptc_of_match),
307                 .pm = &starfive_pwm_pm_ops,
308         },
309 };
310 module_platform_driver(starfive_pwm_ptc_driver);
311
312 MODULE_AUTHOR("Jenny Zhang <jenny.zhang@starfivetech.com>");
313 MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
314 MODULE_DESCRIPTION("StarFive PWM PTC driver");
315 MODULE_LICENSE("GPL v2");