Merge branch 'CR_786_CAN_clivia.cai' into 'jh7110_fpga_dev_5.15'
[platform/kernel/linux-starfive.git] / drivers / pwm / pwm-starfive-ptc.c
1 /*
2  * Copyright (C) 2018 Starfive, Inc
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2, as published by
6  * the Free Software Foundation.
7  */
8
9 #include <dt-bindings/pwm/pwm.h>
10 #include <linux/module.h>
11 #include <linux/platform_device.h>
12 #include <linux/pwm.h>
13 #include <linux/slab.h>
14 #include <linux/clk.h>
15 #include <linux/io.h>
16
17 /* max channel of pwm */
18 #define MAX_PWM                                                 8
19
20 /* PTC Register offsets */
21 #define REG_RPTC_CNTR                                           0x0
22 #define REG_RPTC_HRC                                            0x4
23 #define REG_RPTC_LRC                                            0x8
24 #define REG_RPTC_CTRL                                           0xC
25
26 /* Bit for PWM clock */
27 #define BIT_PWM_CLOCK_EN                                        31
28
29 /* Bit for clock gen soft reset */
30 #define BIT_CLK_GEN_SOFT_RESET                                  13
31
32 #define NS_1                                                    1000000000
33
34 #define PTC_DEBUG                                               0
35
36 /* Access PTC register (cntr hrc lrc and ctrl) ,need to replace PWM_BASE_ADDR */
37 #define REG_PTC_BASE_ADDR_SUB(base, N)          ((base) + ((N>3)?((N%4)*0x10+(1<<15)):(N*0x10))) 
38 #define REG_PTC_RPTC_CNTR(base,N)               (REG_PTC_BASE_ADDR_SUB(base,N))
39 #define REG_PTC_RPTC_HRC(base,N)                (REG_PTC_BASE_ADDR_SUB(base,N) + 0x4)
40 #define REG_PTC_RPTC_LRC(base,N)                (REG_PTC_BASE_ADDR_SUB(base,N) + 0x8)
41 #define REG_PTC_RPTC_CTRL(base,N)               (REG_PTC_BASE_ADDR_SUB(base,N) + 0xC)
42
43 ///PTC_RPTC_CTRL
44 #define PTC_EN      (1<<0)
45 #define PTC_ECLK    (1<<1)  /* 1:ptc_ecgt signal increment RPTC_CNTR. 0:system clock increment RPTC_CNTR. */
46 #define PTC_NEC     (1<<2)  /* gate:system clock or ptc_ecgt input signal to increment RPTC_CNTR. If gate function is enabled, PWM periods can be automatically adjusted with the capture input. */
47 #define PTC_OE      (1<<3)  /* enbale PWM output */
48 #define PTC_SIGNLE  (1<<4)  /* 1:single operation; 0:continue operation */
49 #define PTC_INTE    (1<<5)  /* Timer/Counter interrput enable */
50 #define PTC_INT     (1<<6)  /* interrupt status, write 1 to clear */
51 #define PTC_CNTRRST (1<<7)  /* 0:clear reset */
52 #define PTC_CAPTE   (1<<8)  /* ptc_capt to increment RPTC_CNTR.*/
53
54
55 /* pwm ptc device */
56 struct starfive_pwm_ptc_device {
57         struct pwm_chip         chip;
58         struct clk              *clk;
59         void __iomem            *regs;
60         int                     irq;
61         /* apb clock frequency , from dts */
62         unsigned int            approx_period;
63 };
64
65 static inline struct starfive_pwm_ptc_device *chip_to_starfive_ptc(struct pwm_chip *c)
66 {
67         return container_of(c, struct starfive_pwm_ptc_device, chip);
68 }
69
70
71 static void starfive_pwm_ptc_get_state(struct pwm_chip *chip, struct pwm_device *dev, struct pwm_state *state)
72 {
73         struct starfive_pwm_ptc_device *pwm = chip_to_starfive_ptc(chip);
74         uint32_t data_lrc;
75         uint32_t data_hrc;
76         uint32_t period;        
77         uint32_t pwm_clk_ns = 0;
78
79         /* get lrc and hrc data from registe*/
80         data_lrc = ioread32(REG_PTC_RPTC_LRC(pwm->regs,dev->hwpwm));
81         data_hrc = ioread32(REG_PTC_RPTC_HRC(pwm->regs,dev->hwpwm));
82         //period = data_lrc + data_hrc;
83
84         /* how many ns does apb clock elapse */
85         pwm_clk_ns = NS_1 / pwm->approx_period;
86
87         /* pwm period(ns) */
88         state->period     = data_lrc*pwm_clk_ns;
89
90         /* duty cycle(ns) ,means high level eclapse ns if it is normal polarity */
91         state->duty_cycle = data_hrc*pwm_clk_ns;
92
93         /* polarity,we don't use it now because it is not in dts */
94         state->polarity   = PWM_POLARITY_NORMAL;
95
96         /* enabled or not */
97         state->enabled    = 1;
98 #if PTC_DEBUG   
99         printk("starfive_pwm_ptc_get_state in,no:%d....\r\n",dev->hwpwm);
100         printk("data_hrc:0x%x 0x%x \n", data_hrc, data_lrc);
101         printk("period:%d\r\n",state->period);
102         printk("duty_cycle:%d\r\n",state->duty_cycle);
103         printk("polarity:%d\r\n",state->polarity);
104         printk("enabled:%d\r\n",state->enabled);
105 #endif
106
107 }
108
109
110 static int starfive_pwm_ptc_apply(struct pwm_chip *chip, struct pwm_device *dev, struct pwm_state *state)
111 {
112         struct starfive_pwm_ptc_device *pwm = chip_to_starfive_ptc(chip);
113         uint32_t pwm_clk_ns = 0;
114         uint32_t data_hrc = 0;
115         uint32_t data_lrc = 0;
116         uint32_t period_data = 0;
117         uint32_t duty_data = 0;
118         void __iomem* reg_addr;
119
120 #if PTC_DEBUG   
121         printk("starfive_pwm_ptc_apply in,no:%d....\r\n",dev->hwpwm);
122         printk("set parameter......\r\n");
123         printk("period:%d\r\n",state->period);
124         printk("duty_cycle:%d\r\n",state->duty_cycle);  
125         printk("polarity:%d\r\n",state->polarity);
126         printk("enabled:%d\r\n",state->enabled);
127 #endif
128         /* duty_cycle should be less or equal than period */
129         if(state->duty_cycle > state->period)
130         {
131                 state->duty_cycle = state->period;
132         }       
133
134         /* calculate pwm real period (ns) */
135         pwm_clk_ns = NS_1 / pwm->approx_period;
136         
137 #if PTC_DEBUG
138         printk("approx_period,:%d,pwm_clk_ns:%d\r\n",pwm->approx_period,pwm_clk_ns);
139 #endif
140
141         /* calculate period count */
142         period_data = state->period / pwm_clk_ns;
143
144         if (!state->enabled) 
145         {
146                 /* if is unenable,just set duty_dat to 0 , means low level always */
147                 duty_data = 0;
148         }
149         else
150         {
151                 /* calculate duty count*/
152                 duty_data = state->duty_cycle / pwm_clk_ns;
153         }
154
155 #if PTC_DEBUG
156         printk("period_data:%d,duty_data:%d\r\n",period_data,duty_data);
157 #endif
158
159         if(state->polarity == PWM_POLARITY_NORMAL)
160         {
161                 /* calculate data_hrc */        
162                 data_hrc = period_data - duty_data;             
163         }
164         else
165         {
166                 /* calculate data_hrc */
167                 data_hrc = duty_data;   
168         }
169         data_lrc = period_data;
170
171         /* set hrc */
172         reg_addr = REG_PTC_RPTC_HRC(pwm->regs,dev->hwpwm);
173 #if PTC_DEBUG
174         printk("[starfive_pwm_ptc_config]reg_addr:0x%lx,HRC data:0x%x....\n",reg_addr,data_hrc);
175 #endif
176         iowrite32(data_hrc, reg_addr);
177
178
179         /* set lrc */
180         reg_addr = REG_PTC_RPTC_LRC(pwm->regs,dev->hwpwm);
181 #if PTC_DEBUG
182         printk("[starfive_pwm_ptc_config]reg_addr:0x%lx,LRC data:0x%x....\n",reg_addr,data_lrc);
183 #endif  
184         iowrite32(data_lrc, reg_addr);  
185
186         /* set REG_RPTC_CNTR*/
187         reg_addr = REG_PTC_RPTC_CNTR(pwm->regs, dev->hwpwm);
188         iowrite32(0, reg_addr);
189         
190         /* set REG_PTC_RPTC_CTRL*/
191         reg_addr = REG_PTC_RPTC_CTRL(pwm->regs, dev->hwpwm);
192         iowrite32(PTC_EN|PTC_OE, reg_addr);
193         
194         return 0;
195 }
196
197
198
199 static const struct pwm_ops starfive_pwm_ptc_ops = {
200         .get_state      = starfive_pwm_ptc_get_state,
201         .apply          = (void*)starfive_pwm_ptc_apply,
202         .owner          = THIS_MODULE,
203 };
204
205
206
207
208 static int starfive_pwm_ptc_probe(struct platform_device *pdev)
209 {
210         struct device *dev = &pdev->dev;
211         struct device_node *node = pdev->dev.of_node;
212         struct starfive_pwm_ptc_device *pwm;
213         struct pwm_chip *chip;
214         struct resource *res;
215         int ret;
216         
217 #if PTC_DEBUG
218         printk("starfive_pwm_ptc_probe in....\r\n");
219 #endif
220         pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL);
221         if (!pwm) {
222                 dev_err(dev, "Out of memory\n");
223                 return -ENOMEM;
224         }
225
226         chip = &pwm->chip;
227         chip->dev = dev;
228         chip->ops = &starfive_pwm_ptc_ops;
229
230         /* how many parameters can be transfered to ptc,need to fix */
231         chip->of_pwm_n_cells = 3;
232         chip->base = -1;
233
234         /* get pwm channels count, max value is 8 */
235         ret = of_property_read_u32(node, "starfive,npwm", &chip->npwm);
236         if (ret < 0 || chip->npwm > MAX_PWM) 
237         {
238                 chip->npwm = MAX_PWM;
239         }
240 #if PTC_DEBUG   
241         printk("[starfive_pwm_ptc_probe] npwm:0x%lx....\r\n",chip->npwm);
242 #endif
243         /* get apb clock frequency */
244         ret = of_property_read_u32(node, "starfive,approx-period", &pwm->approx_period);
245
246 #if PTC_DEBUG
247         printk("[starfive_pwm_ptc_probe] approx_period:%d....\r\n",pwm->approx_period);
248 #endif
249         /* get IO base address*/
250         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
251
252 #if PTC_DEBUG
253         printk("[starfive_pwm_ptc_probe] res start:0x%lx,end:0x%lx....\r\n",res->start,res->end);
254 #endif  
255         pwm->regs = devm_ioremap_resource(dev, res);
256         if (IS_ERR(pwm->regs)) 
257         {
258                 dev_err(dev, "Unable to map IO resources\n");
259                 return PTR_ERR(pwm->regs);
260         }
261
262 #if PTC_DEBUG
263         printk("[starfive_pwm_ptc_probe] regs:0x%lx....\r\n",pwm->regs);
264 #endif
265
266         pwm->clk = devm_clk_get(dev, NULL);
267         if (IS_ERR(pwm->clk)) {
268                 dev_err(dev, "Unable to find controller clock\n");
269                 return PTR_ERR(pwm->clk);
270         }
271
272         /* after add,it will display as /sys/class/pwm/pwmchip0,0 is chip->base 
273          * after execute echo 0 > export in  , pwm0 can be seen */
274         ret = pwmchip_add(chip);
275         if (ret < 0) {
276                 dev_err(dev, "cannot register PTC: %d\n", ret);
277                 return ret;
278         }
279
280         platform_set_drvdata(pdev, pwm);
281         
282 #if PTC_DEBUG
283         printk("starfive PWM PTC chip registered %d PWMs\n", chip->npwm);
284 #endif
285
286         return 0;
287 }
288
289 static int starfive_pwm_ptc_remove(struct platform_device *dev)
290 {
291         struct starfive_pwm_ptc_device *pwm = platform_get_drvdata(dev);
292         struct pwm_chip *chip = &pwm->chip;
293
294         pwmchip_remove(chip);
295
296         return 0;
297 }
298
299 static const struct of_device_id starfive_pwm_ptc_of_match[] = {
300         { .compatible = "starfive,pwm0" },
301         {},
302 };
303 MODULE_DEVICE_TABLE(of, starfive_pwm_ptc_of_match);
304
305 static struct platform_driver starfive_pwm_ptc_driver = {
306         .probe = starfive_pwm_ptc_probe,
307         .remove = starfive_pwm_ptc_remove,
308         .driver = {
309                 .name = "pwm-starfive-ptc",
310                 .of_match_table = of_match_ptr(starfive_pwm_ptc_of_match),
311         },
312 };
313 module_platform_driver(starfive_pwm_ptc_driver);
314
315 MODULE_DESCRIPTION("starfive PWM PTC driver");
316 MODULE_LICENSE("GPL v2");
317