1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * simple driver for PWM (Pulse Width Modulator) controller 4 * 5 * Derived from pxa PWM driver by eric miao <eric.miao@marvell.com> 6 */ 7 8 #include <linux/bitfield.h> 9 #include <linux/bitops.h> 10 #include <linux/clk.h> 11 #include <linux/delay.h> 12 #include <linux/err.h> 13 #include <linux/io.h> 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/of.h> 17 #include <linux/of_device.h> 18 #include <linux/platform_device.h> 19 #include <linux/pwm.h> 20 #include <linux/slab.h> 21 22 #define MX3_PWMCR 0x00 /* PWM Control Register */ 23 #define MX3_PWMSR 0x04 /* PWM Status Register */ 24 #define MX3_PWMSAR 0x0C /* PWM Sample Register */ 25 #define MX3_PWMPR 0x10 /* PWM Period Register */ 26 27 #define MX3_PWMCR_FWM GENMASK(27, 26) 28 #define MX3_PWMCR_STOPEN BIT(25) 29 #define MX3_PWMCR_DOZEN BIT(24) 30 #define MX3_PWMCR_WAITEN BIT(23) 31 #define MX3_PWMCR_DBGEN BIT(22) 32 #define MX3_PWMCR_BCTR BIT(21) 33 #define MX3_PWMCR_HCTR BIT(20) 34 35 #define MX3_PWMCR_POUTC GENMASK(19, 18) 36 #define MX3_PWMCR_POUTC_NORMAL 0 37 #define MX3_PWMCR_POUTC_INVERTED 1 38 #define MX3_PWMCR_POUTC_OFF 2 39 40 #define MX3_PWMCR_CLKSRC GENMASK(17, 16) 41 #define MX3_PWMCR_CLKSRC_OFF 0 42 #define MX3_PWMCR_CLKSRC_IPG 1 43 #define MX3_PWMCR_CLKSRC_IPG_HIGH 2 44 #define MX3_PWMCR_CLKSRC_IPG_32K 3 45 46 #define MX3_PWMCR_PRESCALER GENMASK(15, 4) 47 48 #define MX3_PWMCR_SWR BIT(3) 49 50 #define MX3_PWMCR_REPEAT GENMASK(2, 1) 51 #define MX3_PWMCR_REPEAT_1X 0 52 #define MX3_PWMCR_REPEAT_2X 1 53 #define MX3_PWMCR_REPEAT_4X 2 54 #define MX3_PWMCR_REPEAT_8X 3 55 56 #define MX3_PWMCR_EN BIT(0) 57 58 #define MX3_PWMSR_FWE BIT(6) 59 #define MX3_PWMSR_CMP BIT(5) 60 #define MX3_PWMSR_ROV BIT(4) 61 #define MX3_PWMSR_FE BIT(3) 62 63 #define MX3_PWMSR_FIFOAV GENMASK(2, 0) 64 #define MX3_PWMSR_FIFOAV_EMPTY 0 65 #define MX3_PWMSR_FIFOAV_1WORD 1 66 #define MX3_PWMSR_FIFOAV_2WORDS 2 67 #define MX3_PWMSR_FIFOAV_3WORDS 3 68 #define MX3_PWMSR_FIFOAV_4WORDS 4 69 70 #define MX3_PWMCR_PRESCALER_SET(x) FIELD_PREP(MX3_PWMCR_PRESCALER, (x) - 1) 71 #define MX3_PWMCR_PRESCALER_GET(x) (FIELD_GET(MX3_PWMCR_PRESCALER, \ 72 (x)) + 1) 73 74 #define MX3_PWM_SWR_LOOP 5 75 76 /* PWMPR register value of 0xffff has the same effect as 0xfffe */ 77 #define MX3_PWMPR_MAX 0xfffe 78 79 struct pwm_imx27_chip { 80 struct clk *clk_ipg; 81 struct clk *clk_per; 82 void __iomem *mmio_base; 83 struct pwm_chip chip; 84 }; 85 86 #define to_pwm_imx27_chip(chip) container_of(chip, struct pwm_imx27_chip, chip) 87 88 static int pwm_imx27_clk_prepare_enable(struct pwm_chip *chip) 89 { 90 struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip); 91 int ret; 92 93 ret = clk_prepare_enable(imx->clk_ipg); 94 if (ret) 95 return ret; 96 97 ret = clk_prepare_enable(imx->clk_per); 98 if (ret) { 99 clk_disable_unprepare(imx->clk_ipg); 100 return ret; 101 } 102 103 return 0; 104 } 105 106 static void pwm_imx27_clk_disable_unprepare(struct pwm_chip *chip) 107 { 108 struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip); 109 110 clk_disable_unprepare(imx->clk_per); 111 clk_disable_unprepare(imx->clk_ipg); 112 } 113 114 static void pwm_imx27_get_state(struct pwm_chip *chip, 115 struct pwm_device *pwm, struct pwm_state *state) 116 { 117 struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip); 118 u32 period, prescaler, pwm_clk, val; 119 u64 tmp; 120 int ret; 121 122 ret = pwm_imx27_clk_prepare_enable(chip); 123 if (ret < 0) 124 return; 125 126 val = readl(imx->mmio_base + MX3_PWMCR); 127 128 if (val & MX3_PWMCR_EN) 129 state->enabled = true; 130 else 131 state->enabled = false; 132 133 switch (FIELD_GET(MX3_PWMCR_POUTC, val)) { 134 case MX3_PWMCR_POUTC_NORMAL: 135 state->polarity = PWM_POLARITY_NORMAL; 136 break; 137 case MX3_PWMCR_POUTC_INVERTED: 138 state->polarity = PWM_POLARITY_INVERSED; 139 break; 140 default: 141 dev_warn(chip->dev, "can't set polarity, output disconnected"); 142 } 143 144 prescaler = MX3_PWMCR_PRESCALER_GET(val); 145 pwm_clk = clk_get_rate(imx->clk_per); 146 pwm_clk = DIV_ROUND_CLOSEST_ULL(pwm_clk, prescaler); 147 val = readl(imx->mmio_base + MX3_PWMPR); 148 period = val >= MX3_PWMPR_MAX ? MX3_PWMPR_MAX : val; 149 150 /* PWMOUT (Hz) = PWMCLK / (PWMPR + 2) */ 151 tmp = NSEC_PER_SEC * (u64)(period + 2); 152 state->period = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk); 153 154 /* PWMSAR can be read only if PWM is enabled */ 155 if (state->enabled) { 156 val = readl(imx->mmio_base + MX3_PWMSAR); 157 tmp = NSEC_PER_SEC * (u64)(val); 158 state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk); 159 } else { 160 state->duty_cycle = 0; 161 } 162 163 if (!state->enabled) 164 pwm_imx27_clk_disable_unprepare(chip); 165 } 166 167 static void pwm_imx27_sw_reset(struct pwm_chip *chip) 168 { 169 struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip); 170 struct device *dev = chip->dev; 171 int wait_count = 0; 172 u32 cr; 173 174 writel(MX3_PWMCR_SWR, imx->mmio_base + MX3_PWMCR); 175 do { 176 usleep_range(200, 1000); 177 cr = readl(imx->mmio_base + MX3_PWMCR); 178 } while ((cr & MX3_PWMCR_SWR) && 179 (wait_count++ < MX3_PWM_SWR_LOOP)); 180 181 if (cr & MX3_PWMCR_SWR) 182 dev_warn(dev, "software reset timeout\n"); 183 } 184 185 static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip, 186 struct pwm_device *pwm) 187 { 188 struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip); 189 struct device *dev = chip->dev; 190 unsigned int period_ms; 191 int fifoav; 192 u32 sr; 193 194 sr = readl(imx->mmio_base + MX3_PWMSR); 195 fifoav = FIELD_GET(MX3_PWMSR_FIFOAV, sr); 196 if (fifoav == MX3_PWMSR_FIFOAV_4WORDS) { 197 period_ms = DIV_ROUND_UP(pwm_get_period(pwm), 198 NSEC_PER_MSEC); 199 msleep(period_ms); 200 201 sr = readl(imx->mmio_base + MX3_PWMSR); 202 if (fifoav == FIELD_GET(MX3_PWMSR_FIFOAV, sr)) 203 dev_warn(dev, "there is no free FIFO slot\n"); 204 } 205 } 206 207 static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, 208 struct pwm_state *state) 209 { 210 unsigned long period_cycles, duty_cycles, prescale; 211 struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip); 212 struct pwm_state cstate; 213 unsigned long long c; 214 int ret; 215 u32 cr; 216 217 pwm_get_state(pwm, &cstate); 218 219 if (state->enabled) { 220 c = clk_get_rate(imx->clk_per); 221 c *= state->period; 222 223 do_div(c, 1000000000); 224 period_cycles = c; 225 226 prescale = period_cycles / 0x10000 + 1; 227 228 period_cycles /= prescale; 229 c = (unsigned long long)period_cycles * state->duty_cycle; 230 do_div(c, state->period); 231 duty_cycles = c; 232 233 /* 234 * according to imx pwm RM, the real period value should be 235 * PERIOD value in PWMPR plus 2. 236 */ 237 if (period_cycles > 2) 238 period_cycles -= 2; 239 else 240 period_cycles = 0; 241 242 /* 243 * Wait for a free FIFO slot if the PWM is already enabled, and 244 * flush the FIFO if the PWM was disabled and is about to be 245 * enabled. 246 */ 247 if (cstate.enabled) { 248 pwm_imx27_wait_fifo_slot(chip, pwm); 249 } else { 250 ret = pwm_imx27_clk_prepare_enable(chip); 251 if (ret) 252 return ret; 253 254 pwm_imx27_sw_reset(chip); 255 } 256 257 writel(duty_cycles, imx->mmio_base + MX3_PWMSAR); 258 writel(period_cycles, imx->mmio_base + MX3_PWMPR); 259 260 cr = MX3_PWMCR_PRESCALER_SET(prescale) | 261 MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN | 262 FIELD_PREP(MX3_PWMCR_CLKSRC, MX3_PWMCR_CLKSRC_IPG_HIGH) | 263 MX3_PWMCR_DBGEN | MX3_PWMCR_EN; 264 265 if (state->polarity == PWM_POLARITY_INVERSED) 266 cr |= FIELD_PREP(MX3_PWMCR_POUTC, 267 MX3_PWMCR_POUTC_INVERTED); 268 269 writel(cr, imx->mmio_base + MX3_PWMCR); 270 } else if (cstate.enabled) { 271 writel(0, imx->mmio_base + MX3_PWMCR); 272 273 pwm_imx27_clk_disable_unprepare(chip); 274 } 275 276 return 0; 277 } 278 279 static const struct pwm_ops pwm_imx27_ops = { 280 .apply = pwm_imx27_apply, 281 .get_state = pwm_imx27_get_state, 282 .owner = THIS_MODULE, 283 }; 284 285 static const struct of_device_id pwm_imx27_dt_ids[] = { 286 { .compatible = "fsl,imx27-pwm", }, 287 { /* sentinel */ } 288 }; 289 MODULE_DEVICE_TABLE(of, pwm_imx27_dt_ids); 290 291 static int pwm_imx27_probe(struct platform_device *pdev) 292 { 293 struct pwm_imx27_chip *imx; 294 295 imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL); 296 if (imx == NULL) 297 return -ENOMEM; 298 299 platform_set_drvdata(pdev, imx); 300 301 imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); 302 if (IS_ERR(imx->clk_ipg)) { 303 dev_err(&pdev->dev, "getting ipg clock failed with %ld\n", 304 PTR_ERR(imx->clk_ipg)); 305 return PTR_ERR(imx->clk_ipg); 306 } 307 308 imx->clk_per = devm_clk_get(&pdev->dev, "per"); 309 if (IS_ERR(imx->clk_per)) { 310 int ret = PTR_ERR(imx->clk_per); 311 312 if (ret != -EPROBE_DEFER) 313 dev_err(&pdev->dev, 314 "failed to get peripheral clock: %d\n", 315 ret); 316 317 return ret; 318 } 319 320 imx->chip.ops = &pwm_imx27_ops; 321 imx->chip.dev = &pdev->dev; 322 imx->chip.base = -1; 323 imx->chip.npwm = 1; 324 325 imx->chip.of_xlate = of_pwm_xlate_with_flags; 326 imx->chip.of_pwm_n_cells = 3; 327 328 imx->mmio_base = devm_platform_ioremap_resource(pdev, 0); 329 if (IS_ERR(imx->mmio_base)) 330 return PTR_ERR(imx->mmio_base); 331 332 return pwmchip_add(&imx->chip); 333 } 334 335 static int pwm_imx27_remove(struct platform_device *pdev) 336 { 337 struct pwm_imx27_chip *imx; 338 339 imx = platform_get_drvdata(pdev); 340 341 pwm_imx27_clk_disable_unprepare(&imx->chip); 342 343 return pwmchip_remove(&imx->chip); 344 } 345 346 static struct platform_driver imx_pwm_driver = { 347 .driver = { 348 .name = "pwm-imx27", 349 .of_match_table = pwm_imx27_dt_ids, 350 }, 351 .probe = pwm_imx27_probe, 352 .remove = pwm_imx27_remove, 353 }; 354 module_platform_driver(imx_pwm_driver); 355 356 MODULE_LICENSE("GPL v2"); 357 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); 358