1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright 2018-2019 NXP. 4 * 5 * Limitations: 6 * - The TPM counter and period counter are shared between 7 * multiple channels, so all channels should use same period 8 * settings. 9 * - Changes to polarity cannot be latched at the time of the 10 * next period start. 11 * - Changing period and duty cycle together isn't atomic, 12 * with the wrong timing it might happen that a period is 13 * produced with old duty cycle but new period settings. 14 */ 15 16 #include <linux/bitfield.h> 17 #include <linux/bitops.h> 18 #include <linux/clk.h> 19 #include <linux/err.h> 20 #include <linux/io.h> 21 #include <linux/module.h> 22 #include <linux/of.h> 23 #include <linux/platform_device.h> 24 #include <linux/pwm.h> 25 #include <linux/slab.h> 26 27 #define PWM_IMX_TPM_PARAM 0x4 28 #define PWM_IMX_TPM_GLOBAL 0x8 29 #define PWM_IMX_TPM_SC 0x10 30 #define PWM_IMX_TPM_CNT 0x14 31 #define PWM_IMX_TPM_MOD 0x18 32 #define PWM_IMX_TPM_CnSC(n) (0x20 + (n) * 0x8) 33 #define PWM_IMX_TPM_CnV(n) (0x24 + (n) * 0x8) 34 35 #define PWM_IMX_TPM_PARAM_CHAN GENMASK(7, 0) 36 37 #define PWM_IMX_TPM_SC_PS GENMASK(2, 0) 38 #define PWM_IMX_TPM_SC_CMOD GENMASK(4, 3) 39 #define PWM_IMX_TPM_SC_CMOD_INC_EVERY_CLK FIELD_PREP(PWM_IMX_TPM_SC_CMOD, 1) 40 #define PWM_IMX_TPM_SC_CPWMS BIT(5) 41 42 #define PWM_IMX_TPM_CnSC_CHF BIT(7) 43 #define PWM_IMX_TPM_CnSC_MSB BIT(5) 44 #define PWM_IMX_TPM_CnSC_MSA BIT(4) 45 46 /* 47 * The reference manual describes this field as two separate bits. The 48 * semantic of the two bits isn't orthogonal though, so they are treated 49 * together as a 2-bit field here. 50 */ 51 #define PWM_IMX_TPM_CnSC_ELS GENMASK(3, 2) 52 #define PWM_IMX_TPM_CnSC_ELS_INVERSED FIELD_PREP(PWM_IMX_TPM_CnSC_ELS, 1) 53 #define PWM_IMX_TPM_CnSC_ELS_NORMAL FIELD_PREP(PWM_IMX_TPM_CnSC_ELS, 2) 54 55 56 #define PWM_IMX_TPM_MOD_WIDTH 16 57 #define PWM_IMX_TPM_MOD_MOD GENMASK(PWM_IMX_TPM_MOD_WIDTH - 1, 0) 58 59 struct imx_tpm_pwm_chip { 60 struct pwm_chip chip; 61 struct clk *clk; 62 void __iomem *base; 63 struct mutex lock; 64 u32 user_count; 65 u32 enable_count; 66 u32 real_period; 67 }; 68 69 struct imx_tpm_pwm_param { 70 u8 prescale; 71 u32 mod; 72 u32 val; 73 }; 74 75 static inline struct imx_tpm_pwm_chip * 76 to_imx_tpm_pwm_chip(struct pwm_chip *chip) 77 { 78 return container_of(chip, struct imx_tpm_pwm_chip, chip); 79 } 80 81 /* 82 * This function determines for a given pwm_state *state that a consumer 83 * might request the pwm_state *real_state that eventually is implemented 84 * by the hardware and the necessary register values (in *p) to achieve 85 * this. 86 */ 87 static int pwm_imx_tpm_round_state(struct pwm_chip *chip, 88 struct imx_tpm_pwm_param *p, 89 struct pwm_state *real_state, 90 const struct pwm_state *state) 91 { 92 struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip); 93 u32 rate, prescale, period_count, clock_unit; 94 u64 tmp; 95 96 rate = clk_get_rate(tpm->clk); 97 tmp = (u64)state->period * rate; 98 clock_unit = DIV_ROUND_CLOSEST_ULL(tmp, NSEC_PER_SEC); 99 if (clock_unit <= PWM_IMX_TPM_MOD_MOD) 100 prescale = 0; 101 else 102 prescale = ilog2(clock_unit) + 1 - PWM_IMX_TPM_MOD_WIDTH; 103 104 if ((!FIELD_FIT(PWM_IMX_TPM_SC_PS, prescale))) 105 return -ERANGE; 106 p->prescale = prescale; 107 108 period_count = (clock_unit + ((1 << prescale) >> 1)) >> prescale; 109 p->mod = period_count; 110 111 /* calculate real period HW can support */ 112 tmp = (u64)period_count << prescale; 113 tmp *= NSEC_PER_SEC; 114 real_state->period = DIV_ROUND_CLOSEST_ULL(tmp, rate); 115 116 /* 117 * if eventually the PWM output is inactive, either 118 * duty cycle is 0 or status is disabled, need to 119 * make sure the output pin is inactive. 120 */ 121 if (!state->enabled) 122 real_state->duty_cycle = 0; 123 else 124 real_state->duty_cycle = state->duty_cycle; 125 126 tmp = (u64)p->mod * real_state->duty_cycle; 127 p->val = DIV64_U64_ROUND_CLOSEST(tmp, real_state->period); 128 129 real_state->polarity = state->polarity; 130 real_state->enabled = state->enabled; 131 132 return 0; 133 } 134 135 static int pwm_imx_tpm_get_state(struct pwm_chip *chip, 136 struct pwm_device *pwm, 137 struct pwm_state *state) 138 { 139 struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip); 140 u32 rate, val, prescale; 141 u64 tmp; 142 143 /* get period */ 144 state->period = tpm->real_period; 145 146 /* get duty cycle */ 147 rate = clk_get_rate(tpm->clk); 148 val = readl(tpm->base + PWM_IMX_TPM_SC); 149 prescale = FIELD_GET(PWM_IMX_TPM_SC_PS, val); 150 tmp = readl(tpm->base + PWM_IMX_TPM_CnV(pwm->hwpwm)); 151 tmp = (tmp << prescale) * NSEC_PER_SEC; 152 state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, rate); 153 154 /* get polarity */ 155 val = readl(tpm->base + PWM_IMX_TPM_CnSC(pwm->hwpwm)); 156 if ((val & PWM_IMX_TPM_CnSC_ELS) == PWM_IMX_TPM_CnSC_ELS_INVERSED) 157 state->polarity = PWM_POLARITY_INVERSED; 158 else 159 /* 160 * Assume reserved values (2b00 and 2b11) to yield 161 * normal polarity. 162 */ 163 state->polarity = PWM_POLARITY_NORMAL; 164 165 /* get channel status */ 166 state->enabled = FIELD_GET(PWM_IMX_TPM_CnSC_ELS, val) ? true : false; 167 168 return 0; 169 } 170 171 /* this function is supposed to be called with mutex hold */ 172 static int pwm_imx_tpm_apply_hw(struct pwm_chip *chip, 173 struct imx_tpm_pwm_param *p, 174 struct pwm_state *state, 175 struct pwm_device *pwm) 176 { 177 struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip); 178 bool period_update = false; 179 bool duty_update = false; 180 u32 val, cmod, cur_prescale; 181 unsigned long timeout; 182 struct pwm_state c; 183 184 if (state->period != tpm->real_period) { 185 /* 186 * TPM counter is shared by multiple channels, so 187 * prescale and period can NOT be modified when 188 * there are multiple channels in use with different 189 * period settings. 190 */ 191 if (tpm->user_count > 1) 192 return -EBUSY; 193 194 val = readl(tpm->base + PWM_IMX_TPM_SC); 195 cmod = FIELD_GET(PWM_IMX_TPM_SC_CMOD, val); 196 cur_prescale = FIELD_GET(PWM_IMX_TPM_SC_PS, val); 197 if (cmod && cur_prescale != p->prescale) 198 return -EBUSY; 199 200 /* set TPM counter prescale */ 201 val &= ~PWM_IMX_TPM_SC_PS; 202 val |= FIELD_PREP(PWM_IMX_TPM_SC_PS, p->prescale); 203 writel(val, tpm->base + PWM_IMX_TPM_SC); 204 205 /* 206 * set period count: 207 * if the PWM is disabled (CMOD[1:0] = 2b00), then MOD register 208 * is updated when MOD register is written. 209 * 210 * if the PWM is enabled (CMOD[1:0] ≠ 2b00), the period length 211 * is latched into hardware when the next period starts. 212 */ 213 writel(p->mod, tpm->base + PWM_IMX_TPM_MOD); 214 tpm->real_period = state->period; 215 period_update = true; 216 } 217 218 pwm_imx_tpm_get_state(chip, pwm, &c); 219 220 /* polarity is NOT allowed to be changed if PWM is active */ 221 if (c.enabled && c.polarity != state->polarity) 222 return -EBUSY; 223 224 if (state->duty_cycle != c.duty_cycle) { 225 /* 226 * set channel value: 227 * if the PWM is disabled (CMOD[1:0] = 2b00), then CnV register 228 * is updated when CnV register is written. 229 * 230 * if the PWM is enabled (CMOD[1:0] ≠ 2b00), the duty length 231 * is latched into hardware when the next period starts. 232 */ 233 writel(p->val, tpm->base + PWM_IMX_TPM_CnV(pwm->hwpwm)); 234 duty_update = true; 235 } 236 237 /* make sure MOD & CnV registers are updated */ 238 if (period_update || duty_update) { 239 timeout = jiffies + msecs_to_jiffies(tpm->real_period / 240 NSEC_PER_MSEC + 1); 241 while (readl(tpm->base + PWM_IMX_TPM_MOD) != p->mod 242 || readl(tpm->base + PWM_IMX_TPM_CnV(pwm->hwpwm)) 243 != p->val) { 244 if (time_after(jiffies, timeout)) 245 return -ETIME; 246 cpu_relax(); 247 } 248 } 249 250 /* 251 * polarity settings will enabled/disable output status 252 * immediately, so if the channel is disabled, need to 253 * make sure MSA/MSB/ELS are set to 0 which means channel 254 * disabled. 255 */ 256 val = readl(tpm->base + PWM_IMX_TPM_CnSC(pwm->hwpwm)); 257 val &= ~(PWM_IMX_TPM_CnSC_ELS | PWM_IMX_TPM_CnSC_MSA | 258 PWM_IMX_TPM_CnSC_MSB); 259 if (state->enabled) { 260 /* 261 * set polarity (for edge-aligned PWM modes) 262 * 263 * ELS[1:0] = 2b10 yields normal polarity behaviour, 264 * ELS[1:0] = 2b01 yields inversed polarity. 265 * The other values are reserved. 266 */ 267 val |= PWM_IMX_TPM_CnSC_MSB; 268 val |= (state->polarity == PWM_POLARITY_NORMAL) ? 269 PWM_IMX_TPM_CnSC_ELS_NORMAL : 270 PWM_IMX_TPM_CnSC_ELS_INVERSED; 271 } 272 writel(val, tpm->base + PWM_IMX_TPM_CnSC(pwm->hwpwm)); 273 274 /* control the counter status */ 275 if (state->enabled != c.enabled) { 276 val = readl(tpm->base + PWM_IMX_TPM_SC); 277 if (state->enabled) { 278 if (++tpm->enable_count == 1) 279 val |= PWM_IMX_TPM_SC_CMOD_INC_EVERY_CLK; 280 } else { 281 if (--tpm->enable_count == 0) 282 val &= ~PWM_IMX_TPM_SC_CMOD; 283 } 284 writel(val, tpm->base + PWM_IMX_TPM_SC); 285 } 286 287 return 0; 288 } 289 290 static int pwm_imx_tpm_apply(struct pwm_chip *chip, 291 struct pwm_device *pwm, 292 const struct pwm_state *state) 293 { 294 struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip); 295 struct imx_tpm_pwm_param param; 296 struct pwm_state real_state; 297 int ret; 298 299 ret = pwm_imx_tpm_round_state(chip, ¶m, &real_state, state); 300 if (ret) 301 return ret; 302 303 mutex_lock(&tpm->lock); 304 ret = pwm_imx_tpm_apply_hw(chip, ¶m, &real_state, pwm); 305 mutex_unlock(&tpm->lock); 306 307 return ret; 308 } 309 310 static int pwm_imx_tpm_request(struct pwm_chip *chip, struct pwm_device *pwm) 311 { 312 struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip); 313 314 mutex_lock(&tpm->lock); 315 tpm->user_count++; 316 mutex_unlock(&tpm->lock); 317 318 return 0; 319 } 320 321 static void pwm_imx_tpm_free(struct pwm_chip *chip, struct pwm_device *pwm) 322 { 323 struct imx_tpm_pwm_chip *tpm = to_imx_tpm_pwm_chip(chip); 324 325 mutex_lock(&tpm->lock); 326 tpm->user_count--; 327 mutex_unlock(&tpm->lock); 328 } 329 330 static const struct pwm_ops imx_tpm_pwm_ops = { 331 .request = pwm_imx_tpm_request, 332 .free = pwm_imx_tpm_free, 333 .get_state = pwm_imx_tpm_get_state, 334 .apply = pwm_imx_tpm_apply, 335 }; 336 337 static int pwm_imx_tpm_probe(struct platform_device *pdev) 338 { 339 struct imx_tpm_pwm_chip *tpm; 340 int ret; 341 u32 val; 342 343 tpm = devm_kzalloc(&pdev->dev, sizeof(*tpm), GFP_KERNEL); 344 if (!tpm) 345 return -ENOMEM; 346 347 platform_set_drvdata(pdev, tpm); 348 349 tpm->base = devm_platform_ioremap_resource(pdev, 0); 350 if (IS_ERR(tpm->base)) 351 return PTR_ERR(tpm->base); 352 353 tpm->clk = devm_clk_get_enabled(&pdev->dev, NULL); 354 if (IS_ERR(tpm->clk)) 355 return dev_err_probe(&pdev->dev, PTR_ERR(tpm->clk), 356 "failed to get PWM clock\n"); 357 358 tpm->chip.dev = &pdev->dev; 359 tpm->chip.ops = &imx_tpm_pwm_ops; 360 361 /* get number of channels */ 362 val = readl(tpm->base + PWM_IMX_TPM_PARAM); 363 tpm->chip.npwm = FIELD_GET(PWM_IMX_TPM_PARAM_CHAN, val); 364 365 mutex_init(&tpm->lock); 366 367 ret = devm_pwmchip_add(&pdev->dev, &tpm->chip); 368 if (ret) 369 return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n"); 370 371 return 0; 372 } 373 374 static int __maybe_unused pwm_imx_tpm_suspend(struct device *dev) 375 { 376 struct imx_tpm_pwm_chip *tpm = dev_get_drvdata(dev); 377 378 if (tpm->enable_count > 0) 379 return -EBUSY; 380 381 /* 382 * Force 'real_period' to be zero to force period update code 383 * can be executed after system resume back, since suspend causes 384 * the period related registers to become their reset values. 385 */ 386 tpm->real_period = 0; 387 388 clk_disable_unprepare(tpm->clk); 389 390 return 0; 391 } 392 393 static int __maybe_unused pwm_imx_tpm_resume(struct device *dev) 394 { 395 struct imx_tpm_pwm_chip *tpm = dev_get_drvdata(dev); 396 int ret = 0; 397 398 ret = clk_prepare_enable(tpm->clk); 399 if (ret) 400 dev_err(dev, "failed to prepare or enable clock: %d\n", ret); 401 402 return ret; 403 } 404 405 static SIMPLE_DEV_PM_OPS(imx_tpm_pwm_pm, 406 pwm_imx_tpm_suspend, pwm_imx_tpm_resume); 407 408 static const struct of_device_id imx_tpm_pwm_dt_ids[] = { 409 { .compatible = "fsl,imx7ulp-pwm", }, 410 { /* sentinel */ } 411 }; 412 MODULE_DEVICE_TABLE(of, imx_tpm_pwm_dt_ids); 413 414 static struct platform_driver imx_tpm_pwm_driver = { 415 .driver = { 416 .name = "imx7ulp-tpm-pwm", 417 .of_match_table = imx_tpm_pwm_dt_ids, 418 .pm = &imx_tpm_pwm_pm, 419 }, 420 .probe = pwm_imx_tpm_probe, 421 }; 422 module_platform_driver(imx_tpm_pwm_driver); 423 424 MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>"); 425 MODULE_DESCRIPTION("i.MX TPM PWM Driver"); 426 MODULE_LICENSE("GPL v2"); 427