diff options
-rw-r--r-- | drivers/pwm/pwm-mediatek.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c index f5d97e0ad52b..796baea7e8fe 100644 --- a/drivers/pwm/pwm-mediatek.c +++ b/drivers/pwm/pwm-mediatek.c | |||
@@ -29,7 +29,9 @@ | |||
29 | #define PWMGDUR 0x0c | 29 | #define PWMGDUR 0x0c |
30 | #define PWMWAVENUM 0x28 | 30 | #define PWMWAVENUM 0x28 |
31 | #define PWMDWIDTH 0x2c | 31 | #define PWMDWIDTH 0x2c |
32 | #define PWM45DWIDTH_FIXUP 0x30 | ||
32 | #define PWMTHRES 0x30 | 33 | #define PWMTHRES 0x30 |
34 | #define PWM45THRES_FIXUP 0x34 | ||
33 | 35 | ||
34 | #define PWM_CLK_DIV_MAX 7 | 36 | #define PWM_CLK_DIV_MAX 7 |
35 | 37 | ||
@@ -54,6 +56,7 @@ static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = { | |||
54 | 56 | ||
55 | struct mtk_pwm_platform_data { | 57 | struct mtk_pwm_platform_data { |
56 | unsigned int num_pwms; | 58 | unsigned int num_pwms; |
59 | bool pwm45_fixup; | ||
57 | }; | 60 | }; |
58 | 61 | ||
59 | /** | 62 | /** |
@@ -66,6 +69,7 @@ struct mtk_pwm_chip { | |||
66 | struct pwm_chip chip; | 69 | struct pwm_chip chip; |
67 | void __iomem *regs; | 70 | void __iomem *regs; |
68 | struct clk *clks[MTK_CLK_MAX]; | 71 | struct clk *clks[MTK_CLK_MAX]; |
72 | const struct mtk_pwm_platform_data *soc; | ||
69 | }; | 73 | }; |
70 | 74 | ||
71 | static const unsigned int mtk_pwm_reg_offset[] = { | 75 | static const unsigned int mtk_pwm_reg_offset[] = { |
@@ -131,7 +135,8 @@ static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
131 | { | 135 | { |
132 | struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); | 136 | struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); |
133 | struct clk *clk = pc->clks[MTK_CLK_PWM1 + pwm->hwpwm]; | 137 | struct clk *clk = pc->clks[MTK_CLK_PWM1 + pwm->hwpwm]; |
134 | u32 resolution, clkdiv = 0; | 138 | u32 resolution, clkdiv = 0, reg_width = PWMDWIDTH, |
139 | reg_thres = PWMTHRES; | ||
135 | int ret; | 140 | int ret; |
136 | 141 | ||
137 | ret = mtk_pwm_clk_enable(chip, pwm); | 142 | ret = mtk_pwm_clk_enable(chip, pwm); |
@@ -151,9 +156,18 @@ static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
151 | return -EINVAL; | 156 | return -EINVAL; |
152 | } | 157 | } |
153 | 158 | ||
159 | if (pc->soc->pwm45_fixup && pwm->hwpwm > 2) { | ||
160 | /* | ||
161 | * PWM[4,5] has distinct offset for PWMDWIDTH and PWMTHRES | ||
162 | * from the other PWMs on MT7623. | ||
163 | */ | ||
164 | reg_width = PWM45DWIDTH_FIXUP; | ||
165 | reg_thres = PWM45THRES_FIXUP; | ||
166 | } | ||
167 | |||
154 | mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | clkdiv); | 168 | mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | clkdiv); |
155 | mtk_pwm_writel(pc, pwm->hwpwm, PWMDWIDTH, period_ns / resolution); | 169 | mtk_pwm_writel(pc, pwm->hwpwm, reg_width, period_ns / resolution); |
156 | mtk_pwm_writel(pc, pwm->hwpwm, PWMTHRES, duty_ns / resolution); | 170 | mtk_pwm_writel(pc, pwm->hwpwm, reg_thres, duty_ns / resolution); |
157 | 171 | ||
158 | mtk_pwm_clk_disable(chip, pwm); | 172 | mtk_pwm_clk_disable(chip, pwm); |
159 | 173 | ||
@@ -211,6 +225,7 @@ static int mtk_pwm_probe(struct platform_device *pdev) | |||
211 | data = of_device_get_match_data(&pdev->dev); | 225 | data = of_device_get_match_data(&pdev->dev); |
212 | if (data == NULL) | 226 | if (data == NULL) |
213 | return -EINVAL; | 227 | return -EINVAL; |
228 | pc->soc = data; | ||
214 | 229 | ||
215 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 230 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
216 | pc->regs = devm_ioremap_resource(&pdev->dev, res); | 231 | pc->regs = devm_ioremap_resource(&pdev->dev, res); |
@@ -251,14 +266,17 @@ static int mtk_pwm_remove(struct platform_device *pdev) | |||
251 | 266 | ||
252 | static const struct mtk_pwm_platform_data mt2712_pwm_data = { | 267 | static const struct mtk_pwm_platform_data mt2712_pwm_data = { |
253 | .num_pwms = 8, | 268 | .num_pwms = 8, |
269 | .pwm45_fixup = false, | ||
254 | }; | 270 | }; |
255 | 271 | ||
256 | static const struct mtk_pwm_platform_data mt7622_pwm_data = { | 272 | static const struct mtk_pwm_platform_data mt7622_pwm_data = { |
257 | .num_pwms = 6, | 273 | .num_pwms = 6, |
274 | .pwm45_fixup = false, | ||
258 | }; | 275 | }; |
259 | 276 | ||
260 | static const struct mtk_pwm_platform_data mt7623_pwm_data = { | 277 | static const struct mtk_pwm_platform_data mt7623_pwm_data = { |
261 | .num_pwms = 5, | 278 | .num_pwms = 5, |
279 | .pwm45_fixup = true, | ||
262 | }; | 280 | }; |
263 | 281 | ||
264 | static const struct of_device_id mtk_pwm_of_match[] = { | 282 | static const struct of_device_id mtk_pwm_of_match[] = { |