Merge tag 'lsk-android-14.03' into develop-3.10
[firefly-linux-kernel-4.4.55.git] / drivers / pwm / pwm-rockchip.c
1
2 #include <linux/clk.h>
3 #include <linux/err.h>
4 #include <linux/io.h>
5 #include <linux/ioport.h>
6 #include <linux/kernel.h>
7 #include <linux/math64.h>
8 #include <linux/module.h>
9 #include <linux/of.h>
10 #include <linux/platform_device.h>
11 #include <linux/pwm.h>
12 #include <linux/slab.h>
13 #include <linux/types.h>
14 #include <linux/spinlock.h>
15
16 #define NUM_PWM         1
17
18 /* PWM registers  */
19 #if 0
20 #define PWM_REG_CNTR                  0x00  /* Counter Register */
21 #define PWM_REG_PERIOD                  0x04  /* Period Register */
22 #define PWM_REG_DUTY                    0x08  /* Duty Cycle Register */
23 #define PWM_REG_CTRL                   0x0c /* Control Register */
24
25 /*bits definitions*/
26
27 #define PWM_ENABLE                      (1 << 0)
28 #define PWM_DISABLE                     (0 << 0)
29
30 #define PWM_SHOT                        (0x00 << 1)
31 #define PWM_CONTINUMOUS         (0x01 << 1)
32 #define PWM_CAPTURE             (0x01 << 1)
33
34 #define PWM_DUTY_POSTIVE        (0x01 << 3)
35 #define PWM_DUTY_NEGATIVE       (0x00 << 3)
36
37 #define PWM_INACTIVE_POSTIVE            (0x01 << 4)
38 #define PWM_INACTIVE_NEGATIVE           (0x00 << 4)
39
40 #define PWM_OUTPUT_LEFT                 (0x00 << 5)
41 #define PWM_OUTPUT_ENTER                        (0x01 << 5)
42
43
44 #define PWM_LP_ENABLE           (1<<8)
45 #define PWM_LP_DISABLE          (0<<8)
46
47 #define PWM_CLK_SCALE           (1 << 9)
48 #define PWM_CLK_NON_SCALE       (0 << 9)
49
50
51
52 #define PWMCR_MIN_PRESCALE      0x00
53
54 #define PWMCR_MIN_PRESCALE      0x00
55 #define PWMCR_MAX_PRESCALE      0x07
56
57 #define PWMDCR_MIN_DUTY         0x0001
58 #define PWMDCR_MAX_DUTY         0xFFFF
59
60 #define PWMPCR_MIN_PERIOD               0x0001
61 #define PWMPCR_MAX_PERIOD               0xFFFF
62
63
64 enum pwm_div {
65         PWM_DIV1                 = (0x0 << 12),
66         PWM_DIV2                 = (0x1 << 12),
67         PWM_DIV4                 = (0x2 << 12),
68         PWM_DIV8                 = (0x3 << 12),
69         PWM_DIV16               = (0x4 << 12),
70         PWM_DIV32               = (0x5 << 12),
71         PWM_DIV64               = (0x6 << 12),
72         PWM_DIV128              = (0x7 << 12),
73 };
74 #endif
75 static int pwm_dbg_level = 0;
76 module_param_named(dbg_level, pwm_dbg_level, int, 0644);
77 #define DBG( args...) \
78         do { \
79                 if (pwm_dbg_level) { \
80                         pr_info(args); \
81                 } \
82         } while (0)
83
84 #define PWM_REG_CNTR    0x00
85 #define PWM_REG_HRC     0x04
86 #define PWM_REG_LRC     0x08
87 #define PWM_REG_CTRL    0x0c
88
89
90 #define PWM_REG_PERIOD                  PWM_REG_HRC  /* Period Register */
91 #define PWM_REG_DUTY                    PWM_REG_LRC  /* Duty Cycle Register */
92 //#define PWM_REG_CTRL                   0x0c /* Control Register */
93
94
95
96 #define PWM_DIV_MASK    (0xf << 9)
97 #define PWM_CAPTURE     (1 << 8)
98 #define PWM_RESET       (1 << 7)
99 #define PWM_INTCLR      (1 << 6)
100 #define PWM_INTEN       (1 << 5)
101 #define PWM_SINGLE      (1 << 4)
102
103 #define PWM_ENABLE      (1 << 3)
104 #define PWM_TIMER_EN    (1 << 0)
105
106 #define RK_PWM_DISABLE                     (0 << 0) 
107 #define RK_PWM_ENABLE                            (1 << 0)
108
109 #define PWM_SHOT                                (0 << 1)
110 #define PWM_CONTINUMOUS                 (1 << 1)
111 #define RK_PWM_CAPTURE                     (1 << 2)
112
113 #define PWM_DUTY_POSTIVE                (1 << 3)
114 #define PWM_DUTY_NEGATIVE               (0 << 3)
115
116 #define PWM_INACTIVE_POSTIVE            (1 << 4)
117 #define PWM_INACTIVE_NEGATIVE           (0 << 4)
118
119 #define PWM_OUTPUT_LEFT                 (0 << 5)
120 #define PWM_OUTPUT_ENTER                        (1 << 5)
121
122 #define PWM_LP_ENABLE                   (1<<8)
123 #define PWM_LP_DISABLE                  (0<<8)
124
125 #define DW_PWM_PRESCALE         9
126 #define RK_PWM_PRESCALE         16
127
128 #define PWM_TimeEN      PWM_TIMER_EN
129 #define PWMCR_MIN_PRESCALE      0x00
130
131 #define PWMCR_MIN_PRESCALE      0x00
132 #define PWMCR_MAX_PRESCALE      0x07
133
134 #define PWMDCR_MIN_DUTY         0x0001
135 #define PWMDCR_MAX_DUTY         0xFFFF
136
137 #define PWMPCR_MIN_PERIOD               0x0001
138 #define PWMPCR_MAX_PERIOD               0xFFFF
139
140 #define DW_PWM                                  0x00
141 #define RK_PWM                                  0x01
142
143 /**
144  * struct rk_pwm_chip - struct representing pwm chip
145  *
146  * @base: base address of pwm chip
147  * @clk: pointer to clk structure of pwm chip
148  * @chip: linux pwm chip representation
149  */
150
151 static spinlock_t pwm_lock[4] = {
152         __SPIN_LOCK_UNLOCKED(pwm_lock0),
153         __SPIN_LOCK_UNLOCKED(pwm_lock1),
154         __SPIN_LOCK_UNLOCKED(pwm_lock2),
155         __SPIN_LOCK_UNLOCKED(pwm_lock3),
156 };
157
158 struct rk_pwm_chip {
159         void __iomem *base;
160         struct clk *clk;
161         struct pwm_chip chip;
162         unsigned int pwm_id;
163 };
164
165 #define PWM_CLK 1
166 #if 0
167 static void __iomem *rk30_grf_base = NULL;
168 static void __iomem *rk30_cru_base = NULL;
169 static void __iomem *rk30_pwm_base = NULL;
170 //#define SZ_16K                         0x4000
171 //#define SZ_8K                         0x2000
172 #define RK30_GRF_PHYS           0x20008000
173 #define RK30_GRF_SIZE            SZ_8K
174 #define RK30_CRU_PHYS           0x20000000
175 #define RK30_CRU_SIZE            SZ_16K
176 #define RK30_PWM_PHYS           0x20050000
177 #define RK30_PWM_SIZE            SZ_16K
178
179 static void dump_register_of_pwm(void)
180 {
181         int off;
182 //rk30_grf_base =  ioremap(RK30_GRF_PHYS, RK30_GRF_SIZE);
183 // rk30_cru_base = ioremap(RK30_CRU_PHYS, RK30_CRU_SIZE);
184  //rk30_pwm_base = ioremap(RK30_PWM_PHYS, RK30_PWM_SIZE);
185
186 // DBG("GRF IOMUX GPIO3_D6 = 0x%08x\n",readl_relaxed(rk30_grf_base+ 0x9C) );
187  //DBG("CRU                            = 0x%08x\n",readl_relaxed(rk30_cru_base+ 0xeC) );
188 //writel_relaxed(0x10001000, rk30_grf_base+ 0x9C);
189  //DBG("GRF IOMUX GPIO3_D6 = 0x%08x\n",readl_relaxed(rk30_grf_base+ 0x9C) );
190  //DBG("CRU                            = 0x%08x\n",readl_relaxed(rk30_cru_base+ 0xeC) );
191
192 #if 0
193         barrier();
194         writel_relaxed(off, rk30_pwm_base+3*0x10+ PWM_REG_CTRL);
195
196         dsb();
197         writel_relaxed(0x1900, rk30_pwm_base+3*0x10+ PWM_REG_HRC);//rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_HRC,0x1900);// dc);
198         writel_relaxed(0x5dc0, rk30_pwm_base+3*0x10+ PWM_REG_LRC);//rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_LRC, 0x5dc0);//pv);
199         writel_relaxed(0, rk30_pwm_base+3*0x10+ PWM_REG_CNTR);//rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CNTR,0);
200         dsb();
201         writel_relaxed(0x09, rk30_pwm_base+3*0x10+ PWM_REG_CTRL);// rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CTRL,on);
202         dsb();
203 #endif
204 }
205 static void dump_pwm_register(struct rk_pwm_chip *chip)
206 {
207 DBG("dump pwm regitster start\n");
208 #if 1
209 DBG("PWM0\n");
210 DBG("PWM_REG_CTRL =0x%08x\n",rk_pwm_readl(chip, 0, PWM_REG_CTRL));
211 DBG("PWM_REG_HRC = 0x%08x\n",rk_pwm_readl(chip,0, PWM_REG_HRC));
212 DBG("PWM_REG_LRC = 0x%08x\n",rk_pwm_readl(chip,0, PWM_REG_LRC));
213 DBG("PWM_REG_CNTR = 0x%08x\n",rk_pwm_readl(chip,0, PWM_REG_CNTR));
214
215 DBG("PWM1\n");
216 DBG("PWM_REG_CTRL =0x%08x\n",rk_pwm_readl(chip, 1, PWM_REG_CTRL));
217 DBG("PWM_REG_HRC = 0x%08x\n",rk_pwm_readl(chip,1, PWM_REG_HRC));
218 DBG("PWM_REG_LRC = 0x%08x\n",rk_pwm_readl(chip,1, PWM_REG_LRC));
219 DBG("PWM_REG_CNTR = 0x%08x\n",rk_pwm_readl(chip,1, PWM_REG_CNTR));
220
221 DBG("PWM2\n");
222 DBG("PWM_REG_CTRL =0x%08x\n",rk_pwm_readl(chip, 2, PWM_REG_CTRL));
223 DBG("PWM_REG_HRC = 0x%08x\n",rk_pwm_readl(chip,2, PWM_REG_HRC));
224 DBG("PWM_REG_LRC = 0x%08x\n",rk_pwm_readl(chip,2, PWM_REG_LRC));
225 DBG("PWM_REG_CNTR = 0x%08x\n",rk_pwm_readl(chip,2, PWM_REG_CNTR));
226
227 DBG("PWM3\n");
228 DBG("PWM_REG_CTRL =0x%08x\n",rk_pwm_readl(chip,3, PWM_REG_CTRL));
229 DBG("PWM_REG_HRC = 0x%08x\n",rk_pwm_readl(chip,3, PWM_REG_HRC));
230 DBG("PWM_REG_LRC = 0x%08x\n",rk_pwm_readl(chip,3, PWM_REG_LRC));
231 DBG("PWM_REG_CNTR = 0x%08x\n",rk_pwm_readl(chip,3, PWM_REG_CNTR));
232 #endif
233 printk("dump pwm regitster end\n");
234
235 }
236
237 #endif
238 static inline struct rk_pwm_chip *to_rk_pwm_chip(struct pwm_chip *chip)
239 {
240         return container_of(chip, struct rk_pwm_chip, chip);
241 }
242
243 static inline u32 rk_pwm_readl(struct rk_pwm_chip *chip, unsigned int num,
244                                   unsigned long offset)
245 {
246         return readl_relaxed(chip->base + (num << 4) + offset);
247 }
248
249 static inline void rk_pwm_writel(struct rk_pwm_chip *chip,
250                                     unsigned int num, unsigned long offset,
251                                     unsigned long val)
252 {
253         writel_relaxed(val, chip->base + (num << 4) + offset);
254 }
255
256
257 #if 1
258 static int  rk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
259                             int duty_ns, int period_ns)
260 {
261         struct rk_pwm_chip *pc = to_rk_pwm_chip(chip);
262         u64 val, div, clk_rate;
263         unsigned long prescale = PWMCR_MIN_PRESCALE, pv, dc;
264         int ret;
265         u32 off, on;
266         int conf=0;
267        unsigned long flags;
268        spinlock_t *lock;
269
270        lock = &pwm_lock[pwm->hwpwm];
271         if(pc->pwm_id == DW_PWM){
272                 off =  PWM_RESET;
273                 on =  PWM_ENABLE | PWM_TIMER_EN;
274         }
275         if(pc->pwm_id == RK_PWM){
276                 on   =  RK_PWM_ENABLE ;
277                 conf = PWM_OUTPUT_LEFT|PWM_LP_DISABLE|
278                                     PWM_CONTINUMOUS|PWM_DUTY_POSTIVE|PWM_INACTIVE_NEGATIVE;
279         }
280         //dump_pwm_register(pc);
281
282         /*
283          * Find pv, dc and prescale to suit duty_ns and period_ns. This is done
284          * according to formulas described below:
285          *
286          * period_ns = 10^9 * (PRESCALE ) * PV / PWM_CLK_RATE
287          * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE
288          *
289          * PV = (PWM_CLK_RATE * period_ns) / (10^9 * (PRESCALE + 1))
290          * DC = (PWM_CLK_RATE * duty_ns) / (10^9 * (PRESCALE + 1))
291          */
292 #if PWM_CLK
293         clk_rate = clk_get_rate(pc->clk);
294 #else
295         clk_rate = 24000000;
296 #endif
297         while (1) {
298                 div = 1000000000;
299                 div *= 1 + prescale;
300                 val = clk_rate * period_ns;
301                 pv = div64_u64(val, div);
302                 val = clk_rate * duty_ns;
303                 dc = div64_u64(val, div);
304
305                 /* if duty_ns and period_ns are not achievable then return */
306                 if (pv < PWMPCR_MIN_PERIOD || dc < PWMDCR_MIN_DUTY)
307                         return -EINVAL;
308
309                 /*
310                  * if pv and dc have crossed their upper limit, then increase
311                  * prescale and recalculate pv and dc.
312                  */
313                 if (pv > PWMPCR_MAX_PERIOD || dc > PWMDCR_MAX_DUTY) {
314                         if (++prescale > PWMCR_MAX_PRESCALE)
315                                 return -EINVAL;
316                         continue;
317                 }
318                 break;
319         }
320
321         /*
322          * NOTE: the clock to PWM has to be enabled first before writing to the
323          * registers.
324          */
325
326 #if PWM_CLK
327         ret = clk_enable(pc->clk);
328         if (ret)
329                 return ret;
330 #endif
331         spin_lock_irqsave(lock, flags);
332         if(pc->pwm_id == DW_PWM){
333
334                 conf |= (prescale << DW_PWM_PRESCALE);
335                 barrier();
336                 rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CTRL,off);
337
338                 dsb();
339                 rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_HRC,dc);//0x1900);// dc);
340                 rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_LRC, pv);//0x5dc0);//pv);
341                 rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CNTR,0);
342                 dsb();
343                 rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CTRL,on|conf);
344         }
345         if(pc->pwm_id == RK_PWM){
346                 conf |= (prescale << RK_PWM_PRESCALE);
347                 
348                 barrier();
349                 rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CTRL,off);
350                 
351                 dsb();
352                 rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_DUTY,dc);//0x1900);// dc);
353                 rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_PERIOD,pv);//0x5dc0);//pv);
354                 rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CNTR,0);
355                 dsb();
356                 rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CTRL,on|conf);
357         }
358         spin_unlock_irqrestore(lock, flags);    
359
360 #if PWM_CLK
361         clk_disable(pc->clk);
362 #endif
363
364         return 0;
365 }
366 #endif
367
368 static int rk_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
369 {
370         struct rk_pwm_chip *pc = to_rk_pwm_chip(chip);
371         int rc = 0;
372         u32 val;
373 #if PWM_CLK
374         rc = clk_enable(pc->clk);
375         if (rc)
376                 return rc;
377 #endif
378         val = rk_pwm_readl(pc, pwm->hwpwm, PWM_REG_CTRL);
379         if(pc->pwm_id == DW_PWM){
380                 val |= PWM_ENABLE;
381         }
382         if(pc->pwm_id == RK_PWM){
383                 val |= RK_PWM_ENABLE;
384         }
385         
386         rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CTRL, val);
387
388         return 0;
389 }
390
391 static void rk_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
392 {
393         struct rk_pwm_chip *pc = to_rk_pwm_chip(chip);
394         u32 val;
395
396         val = rk_pwm_readl(pc, pwm->hwpwm, PWM_REG_CTRL);
397         if(pc->pwm_id == DW_PWM){
398                 val &= ~PWM_ENABLE;
399         }
400         if(pc->pwm_id == RK_PWM){
401                 val &= ~RK_PWM_ENABLE;
402         }
403
404         rk_pwm_writel(pc, pwm->hwpwm, PWM_REG_CTRL, val);
405 #if PWM_CLK
406         clk_disable(pc->clk);
407 #endif
408 }
409
410
411 static const struct pwm_ops rk_pwm_ops = {
412         .config = rk_pwm_config,
413         .enable = rk_pwm_enable,
414         .disable = rk_pwm_disable,
415         .owner = THIS_MODULE,
416 };
417
418
419
420 static int rk_pwm_probe(struct platform_device *pdev)
421 {
422         struct device_node *np = pdev->dev.of_node;
423         struct rk_pwm_chip *pc;
424         struct resource *r;
425         int ret;
426         DBG("%s start \n",__FUNCTION__);
427         r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
428         if (!r) {
429                 dev_err(&pdev->dev, "no memory resources defined\n");
430                 return -ENODEV;
431         }
432         pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
433         if (!pc) {
434                 dev_err(&pdev->dev, "failed to allocate memory\n");
435                 return -ENOMEM;
436         }
437         pc->base = devm_ioremap_resource(&pdev->dev, r);
438         if (IS_ERR(pc->base))
439                 return PTR_ERR(pc->base);
440
441 #if PWM_CLK
442         if (of_device_is_compatible(np, "rockchip,pwm")){
443                 pc->pwm_id = DW_PWM;
444         }else if (of_device_is_compatible(np, "rockchip,rk-pwm")){
445                 pc->pwm_id = RK_PWM;
446         }
447         //pc->clk = devm_clk_get(&pdev->dev, NULL);
448         pc->clk = devm_clk_get(&pdev->dev,"pclk_pwm");
449
450
451         if (IS_ERR(pc->clk))
452                 return PTR_ERR(pc->clk);
453 #endif
454
455         platform_set_drvdata(pdev, pc);
456
457         pc->chip.dev = &pdev->dev;
458         pc->chip.ops = &rk_pwm_ops;
459         pc->chip.base = -1;
460         pc->chip.npwm = NUM_PWM;
461
462 #if PWM_CLK
463         ret = clk_prepare(pc->clk);
464         if (ret)
465                 return ret;
466 #endif
467
468 #if PWM_CLK
469 //      if (of_device_is_compatible(np, "rockchip,pwm")) {
470         ret = clk_enable(pc->clk);
471         if (ret) {
472                 clk_unprepare(pc->clk);
473                 return ret;
474         }
475                 /*
476                  * Following enables PWM chip, channels would still be
477                  * enabled individually through their control register
478                  */
479 #if PWM_CLK
480 //              clk_disable(pc->clk);
481 #endif
482 #endif
483         DBG("npwm = %d, of_pwm_ncells =%d \n", pc->chip.npwm,pc->chip.of_pwm_n_cells);
484         ret = pwmchip_add(&pc->chip);
485         if (ret < 0) {
486                 clk_unprepare(pc->clk);
487                 dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
488         }
489         DBG("%s end \n",__FUNCTION__);
490
491         return ret;
492 }
493
494 static int rk_pwm_remove(struct platform_device *pdev)
495 {
496         return 0;//pwmchip_remove(&pc->chip);
497 }
498
499
500 static const struct of_device_id rk_pwm_of_match[] = {
501         { .compatible = "rockchip,pwm" },
502         { .compatible =  "rockchip,rk-pwm"},
503         { }
504 };
505
506 MODULE_DEVICE_TABLE(of, rk_pwm_of_match);
507
508 static struct platform_driver rk_pwm_driver = {
509         .driver = {
510                 .name = "rk-pwm",
511                 .of_match_table = rk_pwm_of_match,
512         },
513         .probe = rk_pwm_probe,
514         .remove = rk_pwm_remove,
515 };
516
517 module_platform_driver(rk_pwm_driver);
518
519 MODULE_LICENSE("GPL");
520 MODULE_AUTHOR("<xsf@rock-chips.com>");
521 MODULE_ALIAS("platform:rk-pwm");
522
523