556 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Driver for Atmel Pulse Width Modulation Controller4 *5 * Copyright (C) 2013 Atmel Corporation6 * Bo Shen <voice.shen@atmel.com>7 *8 * Links to reference manuals for the supported PWM chips can be found in9 * Documentation/arch/arm/microchip.rst.10 *11 * Limitations:12 * - Periods start with the inactive level.13 * - Hardware has to be stopped in general to update settings.14 *15 * Software bugs/possible improvements:16 * - When atmel_pwm_apply() is called with state->enabled=false a change in17 * state->polarity isn't honored.18 * - Instead of sleeping to wait for a completed period, the interrupt19 * functionality could be used.20 */21 22#include <linux/clk.h>23#include <linux/delay.h>24#include <linux/err.h>25#include <linux/io.h>26#include <linux/module.h>27#include <linux/of.h>28#include <linux/platform_device.h>29#include <linux/pwm.h>30#include <linux/slab.h>31 32/* The following is global registers for PWM controller */33#define PWM_ENA 0x0434#define PWM_DIS 0x0835#define PWM_SR 0x0C36#define PWM_ISR 0x1C37/* Bit field in SR */38#define PWM_SR_ALL_CH_MASK 0x0F39 40/* The following register is PWM channel related registers */41#define PWM_CH_REG_OFFSET 0x20042#define PWM_CH_REG_SIZE 0x2043 44#define PWM_CMR 0x045/* Bit field in CMR */46#define PWM_CMR_CPOL (1 << 9)47#define PWM_CMR_UPD_CDTY (1 << 10)48#define PWM_CMR_CPRE_MSK 0xF49 50/* The following registers for PWM v1 */51#define PWMV1_CDTY 0x0452#define PWMV1_CPRD 0x0853#define PWMV1_CUPD 0x1054 55/* The following registers for PWM v2 */56#define PWMV2_CDTY 0x0457#define PWMV2_CDTYUPD 0x0858#define PWMV2_CPRD 0x0C59#define PWMV2_CPRDUPD 0x1060 61#define PWM_MAX_PRES 1062 63struct atmel_pwm_registers {64 u8 period;65 u8 period_upd;66 u8 duty;67 u8 duty_upd;68};69 70struct atmel_pwm_config {71 u32 period_bits;72};73 74struct atmel_pwm_data {75 struct atmel_pwm_registers regs;76 struct atmel_pwm_config cfg;77};78 79struct atmel_pwm_chip {80 struct clk *clk;81 void __iomem *base;82 const struct atmel_pwm_data *data;83 84 /*85 * The hardware supports a mechanism to update a channel's duty cycle at86 * the end of the currently running period. When such an update is87 * pending we delay disabling the PWM until the new configuration is88 * active because otherwise pmw_config(duty_cycle=0); pwm_disable();89 * might not result in an inactive output.90 * This bitmask tracks for which channels an update is pending in91 * hardware.92 */93 u32 update_pending;94 95 /* Protects .update_pending */96 spinlock_t lock;97};98 99static inline struct atmel_pwm_chip *to_atmel_pwm_chip(struct pwm_chip *chip)100{101 return pwmchip_get_drvdata(chip);102}103 104static inline u32 atmel_pwm_readl(struct atmel_pwm_chip *chip,105 unsigned long offset)106{107 return readl_relaxed(chip->base + offset);108}109 110static inline void atmel_pwm_writel(struct atmel_pwm_chip *chip,111 unsigned long offset, unsigned long val)112{113 writel_relaxed(val, chip->base + offset);114}115 116static inline u32 atmel_pwm_ch_readl(struct atmel_pwm_chip *chip,117 unsigned int ch, unsigned long offset)118{119 unsigned long base = PWM_CH_REG_OFFSET + ch * PWM_CH_REG_SIZE;120 121 return atmel_pwm_readl(chip, base + offset);122}123 124static inline void atmel_pwm_ch_writel(struct atmel_pwm_chip *chip,125 unsigned int ch, unsigned long offset,126 unsigned long val)127{128 unsigned long base = PWM_CH_REG_OFFSET + ch * PWM_CH_REG_SIZE;129 130 atmel_pwm_writel(chip, base + offset, val);131}132 133static void atmel_pwm_update_pending(struct atmel_pwm_chip *chip)134{135 /*136 * Each channel that has its bit in ISR set started a new period since137 * ISR was cleared and so there is no more update pending. Note that138 * reading ISR clears it, so this needs to handle all channels to not139 * loose information.140 */141 u32 isr = atmel_pwm_readl(chip, PWM_ISR);142 143 chip->update_pending &= ~isr;144}145 146static void atmel_pwm_set_pending(struct atmel_pwm_chip *chip, unsigned int ch)147{148 spin_lock(&chip->lock);149 150 /*151 * Clear pending flags in hardware because otherwise there might still152 * be a stale flag in ISR.153 */154 atmel_pwm_update_pending(chip);155 156 chip->update_pending |= (1 << ch);157 158 spin_unlock(&chip->lock);159}160 161static int atmel_pwm_test_pending(struct atmel_pwm_chip *chip, unsigned int ch)162{163 int ret = 0;164 165 spin_lock(&chip->lock);166 167 if (chip->update_pending & (1 << ch)) {168 atmel_pwm_update_pending(chip);169 170 if (chip->update_pending & (1 << ch))171 ret = 1;172 }173 174 spin_unlock(&chip->lock);175 176 return ret;177}178 179static int atmel_pwm_wait_nonpending(struct atmel_pwm_chip *chip, unsigned int ch)180{181 unsigned long timeout = jiffies + 2 * HZ;182 int ret;183 184 while ((ret = atmel_pwm_test_pending(chip, ch)) &&185 time_before(jiffies, timeout))186 usleep_range(10, 100);187 188 return ret ? -ETIMEDOUT : 0;189}190 191static int atmel_pwm_calculate_cprd_and_pres(struct pwm_chip *chip,192 unsigned long clkrate,193 const struct pwm_state *state,194 unsigned long *cprd, u32 *pres)195{196 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);197 unsigned long long cycles = state->period;198 int shift;199 200 /* Calculate the period cycles and prescale value */201 cycles *= clkrate;202 do_div(cycles, NSEC_PER_SEC);203 204 /*205 * The register for the period length is cfg.period_bits bits wide.206 * So for each bit the number of clock cycles is wider divide the input207 * clock frequency by two using pres and shift cprd accordingly.208 */209 shift = fls(cycles) - atmel_pwm->data->cfg.period_bits;210 211 if (shift > PWM_MAX_PRES) {212 dev_err(pwmchip_parent(chip), "pres exceeds the maximum value\n");213 return -EINVAL;214 } else if (shift > 0) {215 *pres = shift;216 cycles >>= *pres;217 } else {218 *pres = 0;219 }220 221 *cprd = cycles;222 223 return 0;224}225 226static void atmel_pwm_calculate_cdty(const struct pwm_state *state,227 unsigned long clkrate, unsigned long cprd,228 u32 pres, unsigned long *cdty)229{230 unsigned long long cycles = state->duty_cycle;231 232 cycles *= clkrate;233 do_div(cycles, NSEC_PER_SEC);234 cycles >>= pres;235 *cdty = cprd - cycles;236}237 238static void atmel_pwm_update_cdty(struct pwm_chip *chip, struct pwm_device *pwm,239 unsigned long cdty)240{241 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);242 u32 val;243 244 if (atmel_pwm->data->regs.duty_upd ==245 atmel_pwm->data->regs.period_upd) {246 val = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);247 val &= ~PWM_CMR_UPD_CDTY;248 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);249 }250 251 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm,252 atmel_pwm->data->regs.duty_upd, cdty);253 atmel_pwm_set_pending(atmel_pwm, pwm->hwpwm);254}255 256static void atmel_pwm_set_cprd_cdty(struct pwm_chip *chip,257 struct pwm_device *pwm,258 unsigned long cprd, unsigned long cdty)259{260 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);261 262 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm,263 atmel_pwm->data->regs.duty, cdty);264 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm,265 atmel_pwm->data->regs.period, cprd);266}267 268static void atmel_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm,269 bool disable_clk)270{271 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);272 unsigned long timeout;273 274 atmel_pwm_wait_nonpending(atmel_pwm, pwm->hwpwm);275 276 atmel_pwm_writel(atmel_pwm, PWM_DIS, 1 << pwm->hwpwm);277 278 /*279 * Wait for the PWM channel disable operation to be effective before280 * stopping the clock.281 */282 timeout = jiffies + 2 * HZ;283 284 while ((atmel_pwm_readl(atmel_pwm, PWM_SR) & (1 << pwm->hwpwm)) &&285 time_before(jiffies, timeout))286 usleep_range(10, 100);287 288 if (disable_clk)289 clk_disable(atmel_pwm->clk);290}291 292static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,293 const struct pwm_state *state)294{295 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);296 unsigned long cprd, cdty;297 u32 pres, val;298 int ret;299 300 if (state->enabled) {301 unsigned long clkrate = clk_get_rate(atmel_pwm->clk);302 303 if (pwm->state.enabled &&304 pwm->state.polarity == state->polarity &&305 pwm->state.period == state->period) {306 u32 cmr = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);307 308 cprd = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,309 atmel_pwm->data->regs.period);310 pres = cmr & PWM_CMR_CPRE_MSK;311 312 atmel_pwm_calculate_cdty(state, clkrate, cprd, pres, &cdty);313 atmel_pwm_update_cdty(chip, pwm, cdty);314 return 0;315 }316 317 ret = atmel_pwm_calculate_cprd_and_pres(chip, clkrate, state, &cprd,318 &pres);319 if (ret) {320 dev_err(pwmchip_parent(chip),321 "failed to calculate cprd and prescaler\n");322 return ret;323 }324 325 atmel_pwm_calculate_cdty(state, clkrate, cprd, pres, &cdty);326 327 if (pwm->state.enabled) {328 atmel_pwm_disable(chip, pwm, false);329 } else {330 ret = clk_enable(atmel_pwm->clk);331 if (ret) {332 dev_err(pwmchip_parent(chip), "failed to enable clock\n");333 return ret;334 }335 }336 337 /* It is necessary to preserve CPOL, inside CMR */338 val = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);339 val = (val & ~PWM_CMR_CPRE_MSK) | (pres & PWM_CMR_CPRE_MSK);340 if (state->polarity == PWM_POLARITY_NORMAL)341 val &= ~PWM_CMR_CPOL;342 else343 val |= PWM_CMR_CPOL;344 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);345 atmel_pwm_set_cprd_cdty(chip, pwm, cprd, cdty);346 atmel_pwm_writel(atmel_pwm, PWM_ENA, 1 << pwm->hwpwm);347 } else if (pwm->state.enabled) {348 atmel_pwm_disable(chip, pwm, true);349 }350 351 return 0;352}353 354static int atmel_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,355 struct pwm_state *state)356{357 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);358 u32 sr, cmr;359 360 sr = atmel_pwm_readl(atmel_pwm, PWM_SR);361 cmr = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);362 363 if (sr & (1 << pwm->hwpwm)) {364 unsigned long rate = clk_get_rate(atmel_pwm->clk);365 u32 cdty, cprd, pres;366 u64 tmp;367 368 pres = cmr & PWM_CMR_CPRE_MSK;369 370 cprd = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,371 atmel_pwm->data->regs.period);372 tmp = (u64)cprd * NSEC_PER_SEC;373 tmp <<= pres;374 state->period = DIV64_U64_ROUND_UP(tmp, rate);375 376 /* Wait for an updated duty_cycle queued in hardware */377 atmel_pwm_wait_nonpending(atmel_pwm, pwm->hwpwm);378 379 cdty = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,380 atmel_pwm->data->regs.duty);381 tmp = (u64)(cprd - cdty) * NSEC_PER_SEC;382 tmp <<= pres;383 state->duty_cycle = DIV64_U64_ROUND_UP(tmp, rate);384 385 state->enabled = true;386 } else {387 state->enabled = false;388 }389 390 if (cmr & PWM_CMR_CPOL)391 state->polarity = PWM_POLARITY_INVERSED;392 else393 state->polarity = PWM_POLARITY_NORMAL;394 395 return 0;396}397 398static const struct pwm_ops atmel_pwm_ops = {399 .apply = atmel_pwm_apply,400 .get_state = atmel_pwm_get_state,401};402 403static const struct atmel_pwm_data atmel_sam9rl_pwm_data = {404 .regs = {405 .period = PWMV1_CPRD,406 .period_upd = PWMV1_CUPD,407 .duty = PWMV1_CDTY,408 .duty_upd = PWMV1_CUPD,409 },410 .cfg = {411 /* 16 bits to keep period and duty. */412 .period_bits = 16,413 },414};415 416static const struct atmel_pwm_data atmel_sama5_pwm_data = {417 .regs = {418 .period = PWMV2_CPRD,419 .period_upd = PWMV2_CPRDUPD,420 .duty = PWMV2_CDTY,421 .duty_upd = PWMV2_CDTYUPD,422 },423 .cfg = {424 /* 16 bits to keep period and duty. */425 .period_bits = 16,426 },427};428 429static const struct atmel_pwm_data mchp_sam9x60_pwm_data = {430 .regs = {431 .period = PWMV1_CPRD,432 .period_upd = PWMV1_CUPD,433 .duty = PWMV1_CDTY,434 .duty_upd = PWMV1_CUPD,435 },436 .cfg = {437 /* 32 bits to keep period and duty. */438 .period_bits = 32,439 },440};441 442static const struct of_device_id atmel_pwm_dt_ids[] = {443 {444 .compatible = "atmel,at91sam9rl-pwm",445 .data = &atmel_sam9rl_pwm_data,446 }, {447 .compatible = "atmel,sama5d3-pwm",448 .data = &atmel_sama5_pwm_data,449 }, {450 .compatible = "atmel,sama5d2-pwm",451 .data = &atmel_sama5_pwm_data,452 }, {453 .compatible = "microchip,sam9x60-pwm",454 .data = &mchp_sam9x60_pwm_data,455 }, {456 /* sentinel */457 },458};459MODULE_DEVICE_TABLE(of, atmel_pwm_dt_ids);460 461static int atmel_pwm_enable_clk_if_on(struct pwm_chip *chip, bool on)462{463 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);464 unsigned int i, cnt = 0;465 unsigned long sr;466 int ret = 0;467 468 sr = atmel_pwm_readl(atmel_pwm, PWM_SR) & PWM_SR_ALL_CH_MASK;469 if (!sr)470 return 0;471 472 cnt = bitmap_weight(&sr, chip->npwm);473 474 if (!on)475 goto disable_clk;476 477 for (i = 0; i < cnt; i++) {478 ret = clk_enable(atmel_pwm->clk);479 if (ret) {480 dev_err(pwmchip_parent(chip),481 "failed to enable clock for pwm %pe\n",482 ERR_PTR(ret));483 484 cnt = i;485 goto disable_clk;486 }487 }488 489 return 0;490 491disable_clk:492 while (cnt--)493 clk_disable(atmel_pwm->clk);494 495 return ret;496}497 498static int atmel_pwm_probe(struct platform_device *pdev)499{500 struct atmel_pwm_chip *atmel_pwm;501 struct pwm_chip *chip;502 int ret;503 504 chip = devm_pwmchip_alloc(&pdev->dev, 4, sizeof(*atmel_pwm));505 if (IS_ERR(chip))506 return PTR_ERR(chip);507 508 atmel_pwm = to_atmel_pwm_chip(chip);509 atmel_pwm->data = of_device_get_match_data(&pdev->dev);510 511 atmel_pwm->update_pending = 0;512 spin_lock_init(&atmel_pwm->lock);513 514 atmel_pwm->base = devm_platform_ioremap_resource(pdev, 0);515 if (IS_ERR(atmel_pwm->base))516 return PTR_ERR(atmel_pwm->base);517 518 atmel_pwm->clk = devm_clk_get_prepared(&pdev->dev, NULL);519 if (IS_ERR(atmel_pwm->clk))520 return dev_err_probe(&pdev->dev, PTR_ERR(atmel_pwm->clk),521 "failed to get prepared PWM clock\n");522 523 chip->ops = &atmel_pwm_ops;524 525 ret = atmel_pwm_enable_clk_if_on(chip, true);526 if (ret < 0)527 return ret;528 529 ret = devm_pwmchip_add(&pdev->dev, chip);530 if (ret < 0) {531 dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");532 goto disable_clk;533 }534 535 return 0;536 537disable_clk:538 atmel_pwm_enable_clk_if_on(chip, false);539 540 return ret;541}542 543static struct platform_driver atmel_pwm_driver = {544 .driver = {545 .name = "atmel-pwm",546 .of_match_table = atmel_pwm_dt_ids,547 },548 .probe = atmel_pwm_probe,549};550module_platform_driver(atmel_pwm_driver);551 552MODULE_ALIAS("platform:atmel-pwm");553MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>");554MODULE_DESCRIPTION("Atmel PWM driver");555MODULE_LICENSE("GPL v2");556