summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pwm/pwm-berlin.c45
1 files changed, 25 insertions, 20 deletions
diff --git a/drivers/pwm/pwm-berlin.c b/drivers/pwm/pwm-berlin.c
index 771859aca4be..7c8d6a168ceb 100644
--- a/drivers/pwm/pwm-berlin.c
+++ b/drivers/pwm/pwm-berlin.c
@@ -21,8 +21,18 @@
21#define BERLIN_PWM_EN 0x0 21#define BERLIN_PWM_EN 0x0
22#define BERLIN_PWM_ENABLE BIT(0) 22#define BERLIN_PWM_ENABLE BIT(0)
23#define BERLIN_PWM_CONTROL 0x4 23#define BERLIN_PWM_CONTROL 0x4
24#define BERLIN_PWM_PRESCALE_MASK 0x7 24/*
25#define BERLIN_PWM_PRESCALE_MAX 4096 25 * The prescaler claims to support 8 different moduli, configured using the
26 * low three bits of PWM_CONTROL. (Sequentially, they are 1, 4, 8, 16, 64,
27 * 256, 1024, and 4096.) However, the moduli from 4 to 1024 appear to be
28 * implemented by internally shifting TCNT left without adding additional
29 * bits. So, the max TCNT that actually works for a modulus of 4 is 0x3fff;
30 * for 8, 0x1fff; and so on. This means that those moduli are entirely
31 * useless, as we could just do the shift ourselves. The 4096 modulus is
32 * implemented with a real prescaler, so we do use that, but we treat it
33 * as a flag instead of pretending the modulus is actually configurable.
34 */
35#define BERLIN_PWM_PRESCALE_4096 0x7
26#define BERLIN_PWM_INVERT_POLARITY BIT(3) 36#define BERLIN_PWM_INVERT_POLARITY BIT(3)
27#define BERLIN_PWM_DUTY 0x8 37#define BERLIN_PWM_DUTY 0x8
28#define BERLIN_PWM_TCNT 0xc 38#define BERLIN_PWM_TCNT 0xc
@@ -46,10 +56,6 @@ static inline struct berlin_pwm_chip *to_berlin_pwm_chip(struct pwm_chip *chip)
46 return container_of(chip, struct berlin_pwm_chip, chip); 56 return container_of(chip, struct berlin_pwm_chip, chip);
47} 57}
48 58
49static const u32 prescaler_table[] = {
50 1, 4, 8, 16, 64, 256, 1024, 4096
51};
52
53static inline u32 berlin_pwm_readl(struct berlin_pwm_chip *chip, 59static inline u32 berlin_pwm_readl(struct berlin_pwm_chip *chip,
54 unsigned int channel, unsigned long offset) 60 unsigned int channel, unsigned long offset)
55{ 61{
@@ -86,33 +92,32 @@ static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm_dev,
86 int duty_ns, int period_ns) 92 int duty_ns, int period_ns)
87{ 93{
88 struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip); 94 struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
89 unsigned int prescale; 95 bool prescale_4096 = false;
90 u32 value, duty, period; 96 u32 value, duty, period;
91 u64 cycles, tmp; 97 u64 cycles;
92 98
93 cycles = clk_get_rate(pwm->clk); 99 cycles = clk_get_rate(pwm->clk);
94 cycles *= period_ns; 100 cycles *= period_ns;
95 do_div(cycles, NSEC_PER_SEC); 101 do_div(cycles, NSEC_PER_SEC);
96 102
97 for (prescale = 0; prescale < ARRAY_SIZE(prescaler_table); prescale++) { 103 if (cycles > BERLIN_PWM_MAX_TCNT) {
98 tmp = cycles; 104 prescale_4096 = true;
99 do_div(tmp, prescaler_table[prescale]); 105 cycles >>= 12; // Prescaled by 4096
100 106
101 if (tmp <= BERLIN_PWM_MAX_TCNT) 107 if (cycles > BERLIN_PWM_MAX_TCNT)
102 break; 108 return -ERANGE;
103 } 109 }
104 110
105 if (tmp > BERLIN_PWM_MAX_TCNT) 111 period = cycles;
106 return -ERANGE; 112 cycles *= duty_ns;
107
108 period = tmp;
109 cycles = tmp * duty_ns;
110 do_div(cycles, period_ns); 113 do_div(cycles, period_ns);
111 duty = cycles; 114 duty = cycles;
112 115
113 value = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL); 116 value = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL);
114 value &= ~BERLIN_PWM_PRESCALE_MASK; 117 if (prescale_4096)
115 value |= prescale; 118 value |= BERLIN_PWM_PRESCALE_4096;
119 else
120 value &= ~BERLIN_PWM_PRESCALE_4096;
116 berlin_pwm_writel(pwm, pwm_dev->hwpwm, value, BERLIN_PWM_CONTROL); 121 berlin_pwm_writel(pwm, pwm_dev->hwpwm, value, BERLIN_PWM_CONTROL);
117 122
118 berlin_pwm_writel(pwm, pwm_dev->hwpwm, duty, BERLIN_PWM_DUTY); 123 berlin_pwm_writel(pwm, pwm_dev->hwpwm, duty, BERLIN_PWM_DUTY);