aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pwm/pwm-mediatek.c24
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
55struct mtk_pwm_platform_data { 57struct 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
71static const unsigned int mtk_pwm_reg_offset[] = { 75static 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
252static const struct mtk_pwm_platform_data mt2712_pwm_data = { 267static 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
256static const struct mtk_pwm_platform_data mt7622_pwm_data = { 272static 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
260static const struct mtk_pwm_platform_data mt7623_pwm_data = { 277static 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
264static const struct of_device_id mtk_pwm_of_match[] = { 282static const struct of_device_id mtk_pwm_of_match[] = {