linux/drivers/pwm/pwm-fsl-ftm.c
<<
>>
Prefs
   1/*
   2 *  Freescale FlexTimer Module (FTM) PWM Driver
   3 *
   4 *  Copyright 2012-2013 Freescale Semiconductor, Inc.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 */
  11
  12#include <linux/clk.h>
  13#include <linux/err.h>
  14#include <linux/io.h>
  15#include <linux/kernel.h>
  16#include <linux/module.h>
  17#include <linux/mutex.h>
  18#include <linux/of_address.h>
  19#include <linux/of_device.h>
  20#include <linux/platform_device.h>
  21#include <linux/pm.h>
  22#include <linux/pwm.h>
  23#include <linux/regmap.h>
  24#include <linux/slab.h>
  25
  26#define FTM_SC          0x00
  27#define FTM_SC_CLK_MASK_SHIFT   3
  28#define FTM_SC_CLK_MASK (3 << FTM_SC_CLK_MASK_SHIFT)
  29#define FTM_SC_CLK(c)   (((c) + 1) << FTM_SC_CLK_MASK_SHIFT)
  30#define FTM_SC_PS_MASK  0x7
  31
  32#define FTM_CNT         0x04
  33#define FTM_MOD         0x08
  34
  35#define FTM_CSC_BASE    0x0C
  36#define FTM_CSC_MSB     BIT(5)
  37#define FTM_CSC_MSA     BIT(4)
  38#define FTM_CSC_ELSB    BIT(3)
  39#define FTM_CSC_ELSA    BIT(2)
  40#define FTM_CSC(_channel)       (FTM_CSC_BASE + ((_channel) * 8))
  41
  42#define FTM_CV_BASE     0x10
  43#define FTM_CV(_channel)        (FTM_CV_BASE + ((_channel) * 8))
  44
  45#define FTM_CNTIN       0x4C
  46#define FTM_STATUS      0x50
  47
  48#define FTM_MODE        0x54
  49#define FTM_MODE_FTMEN  BIT(0)
  50#define FTM_MODE_INIT   BIT(2)
  51#define FTM_MODE_PWMSYNC        BIT(3)
  52
  53#define FTM_SYNC        0x58
  54#define FTM_OUTINIT     0x5C
  55#define FTM_OUTMASK     0x60
  56#define FTM_COMBINE     0x64
  57#define FTM_DEADTIME    0x68
  58#define FTM_EXTTRIG     0x6C
  59#define FTM_POL         0x70
  60#define FTM_FMS         0x74
  61#define FTM_FILTER      0x78
  62#define FTM_FLTCTRL     0x7C
  63#define FTM_QDCTRL      0x80
  64#define FTM_CONF        0x84
  65#define FTM_FLTPOL      0x88
  66#define FTM_SYNCONF     0x8C
  67#define FTM_INVCTRL     0x90
  68#define FTM_SWOCTRL     0x94
  69#define FTM_PWMLOAD     0x98
  70
  71enum fsl_pwm_clk {
  72        FSL_PWM_CLK_SYS,
  73        FSL_PWM_CLK_FIX,
  74        FSL_PWM_CLK_EXT,
  75        FSL_PWM_CLK_CNTEN,
  76        FSL_PWM_CLK_MAX
  77};
  78
  79struct fsl_ftm_soc {
  80        bool has_enable_bits;
  81};
  82
  83struct fsl_pwm_chip {
  84        struct pwm_chip chip;
  85
  86        struct mutex lock;
  87
  88        unsigned int cnt_select;
  89        unsigned int clk_ps;
  90
  91        struct regmap *regmap;
  92
  93        int period_ns;
  94
  95        struct clk *ipg_clk;
  96        struct clk *clk[FSL_PWM_CLK_MAX];
  97
  98        const struct fsl_ftm_soc *soc;
  99};
 100
 101static inline struct fsl_pwm_chip *to_fsl_chip(struct pwm_chip *chip)
 102{
 103        return container_of(chip, struct fsl_pwm_chip, chip);
 104}
 105
 106static int fsl_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
 107{
 108        int ret;
 109        struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
 110
 111        ret = clk_prepare_enable(fpc->ipg_clk);
 112        if (!ret && fpc->soc->has_enable_bits) {
 113                mutex_lock(&fpc->lock);
 114                regmap_update_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16),
 115                                   BIT(pwm->hwpwm + 16));
 116                mutex_unlock(&fpc->lock);
 117        }
 118
 119        return ret;
 120}
 121
 122static void fsl_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
 123{
 124        struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
 125
 126        if (fpc->soc->has_enable_bits) {
 127                mutex_lock(&fpc->lock);
 128                regmap_update_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16),
 129                                   0);
 130                mutex_unlock(&fpc->lock);
 131        }
 132
 133        clk_disable_unprepare(fpc->ipg_clk);
 134}
 135
 136static int fsl_pwm_calculate_default_ps(struct fsl_pwm_chip *fpc,
 137                                        enum fsl_pwm_clk index)
 138{
 139        unsigned long sys_rate, cnt_rate;
 140        unsigned long long ratio;
 141
 142        sys_rate = clk_get_rate(fpc->clk[FSL_PWM_CLK_SYS]);
 143        if (!sys_rate)
 144                return -EINVAL;
 145
 146        cnt_rate = clk_get_rate(fpc->clk[fpc->cnt_select]);
 147        if (!cnt_rate)
 148                return -EINVAL;
 149
 150        switch (index) {
 151        case FSL_PWM_CLK_SYS:
 152                fpc->clk_ps = 1;
 153                break;
 154        case FSL_PWM_CLK_FIX:
 155                ratio = 2 * cnt_rate - 1;
 156                do_div(ratio, sys_rate);
 157                fpc->clk_ps = ratio;
 158                break;
 159        case FSL_PWM_CLK_EXT:
 160                ratio = 4 * cnt_rate - 1;
 161                do_div(ratio, sys_rate);
 162                fpc->clk_ps = ratio;
 163                break;
 164        default:
 165                return -EINVAL;
 166        }
 167
 168        return 0;
 169}
 170
 171static unsigned long fsl_pwm_calculate_cycles(struct fsl_pwm_chip *fpc,
 172                                              unsigned long period_ns)
 173{
 174        unsigned long long c, c0;
 175
 176        c = clk_get_rate(fpc->clk[fpc->cnt_select]);
 177        c = c * period_ns;
 178        do_div(c, 1000000000UL);
 179
 180        do {
 181                c0 = c;
 182                do_div(c0, (1 << fpc->clk_ps));
 183                if (c0 <= 0xFFFF)
 184                        return (unsigned long)c0;
 185        } while (++fpc->clk_ps < 8);
 186
 187        return 0;
 188}
 189
 190static unsigned long fsl_pwm_calculate_period_cycles(struct fsl_pwm_chip *fpc,
 191                                                     unsigned long period_ns,
 192                                                     enum fsl_pwm_clk index)
 193{
 194        int ret;
 195
 196        ret = fsl_pwm_calculate_default_ps(fpc, index);
 197        if (ret) {
 198                dev_err(fpc->chip.dev,
 199                        "failed to calculate default prescaler: %d\n",
 200                        ret);
 201                return 0;
 202        }
 203
 204        return fsl_pwm_calculate_cycles(fpc, period_ns);
 205}
 206
 207static unsigned long fsl_pwm_calculate_period(struct fsl_pwm_chip *fpc,
 208                                              unsigned long period_ns)
 209{
 210        enum fsl_pwm_clk m0, m1;
 211        unsigned long fix_rate, ext_rate, cycles;
 212
 213        cycles = fsl_pwm_calculate_period_cycles(fpc, period_ns,
 214                        FSL_PWM_CLK_SYS);
 215        if (cycles) {
 216                fpc->cnt_select = FSL_PWM_CLK_SYS;
 217                return cycles;
 218        }
 219
 220        fix_rate = clk_get_rate(fpc->clk[FSL_PWM_CLK_FIX]);
 221        ext_rate = clk_get_rate(fpc->clk[FSL_PWM_CLK_EXT]);
 222
 223        if (fix_rate > ext_rate) {
 224                m0 = FSL_PWM_CLK_FIX;
 225                m1 = FSL_PWM_CLK_EXT;
 226        } else {
 227                m0 = FSL_PWM_CLK_EXT;
 228                m1 = FSL_PWM_CLK_FIX;
 229        }
 230
 231        cycles = fsl_pwm_calculate_period_cycles(fpc, period_ns, m0);
 232        if (cycles) {
 233                fpc->cnt_select = m0;
 234                return cycles;
 235        }
 236
 237        fpc->cnt_select = m1;
 238
 239        return fsl_pwm_calculate_period_cycles(fpc, period_ns, m1);
 240}
 241
 242static unsigned long fsl_pwm_calculate_duty(struct fsl_pwm_chip *fpc,
 243                                            unsigned long period_ns,
 244                                            unsigned long duty_ns)
 245{
 246        unsigned long long duty;
 247        u32 val;
 248
 249        regmap_read(fpc->regmap, FTM_MOD, &val);
 250        duty = (unsigned long long)duty_ns * (val + 1);
 251        do_div(duty, period_ns);
 252
 253        return (unsigned long)duty;
 254}
 255
 256static int fsl_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 257                          int duty_ns, int period_ns)
 258{
 259        struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
 260        u32 period, duty;
 261
 262        mutex_lock(&fpc->lock);
 263
 264        /*
 265         * The Freescale FTM controller supports only a single period for
 266         * all PWM channels, therefore incompatible changes need to be
 267         * refused.
 268         */
 269        if (fpc->period_ns && fpc->period_ns != period_ns) {
 270                dev_err(fpc->chip.dev,
 271                        "conflicting period requested for PWM %u\n",
 272                        pwm->hwpwm);
 273                mutex_unlock(&fpc->lock);
 274                return -EBUSY;
 275        }
 276
 277        if (!fpc->period_ns && duty_ns) {
 278                period = fsl_pwm_calculate_period(fpc, period_ns);
 279                if (!period) {
 280                        dev_err(fpc->chip.dev, "failed to calculate period\n");
 281                        mutex_unlock(&fpc->lock);
 282                        return -EINVAL;
 283                }
 284
 285                regmap_update_bits(fpc->regmap, FTM_SC, FTM_SC_PS_MASK,
 286                                   fpc->clk_ps);
 287                regmap_write(fpc->regmap, FTM_MOD, period - 1);
 288
 289                fpc->period_ns = period_ns;
 290        }
 291
 292        mutex_unlock(&fpc->lock);
 293
 294        duty = fsl_pwm_calculate_duty(fpc, period_ns, duty_ns);
 295
 296        regmap_write(fpc->regmap, FTM_CSC(pwm->hwpwm),
 297                     FTM_CSC_MSB | FTM_CSC_ELSB);
 298        regmap_write(fpc->regmap, FTM_CV(pwm->hwpwm), duty);
 299
 300        return 0;
 301}
 302
 303static int fsl_pwm_set_polarity(struct pwm_chip *chip,
 304                                struct pwm_device *pwm,
 305                                enum pwm_polarity polarity)
 306{
 307        struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
 308        u32 val;
 309
 310        regmap_read(fpc->regmap, FTM_POL, &val);
 311
 312        if (polarity == PWM_POLARITY_INVERSED)
 313                val |= BIT(pwm->hwpwm);
 314        else
 315                val &= ~BIT(pwm->hwpwm);
 316
 317        regmap_write(fpc->regmap, FTM_POL, val);
 318
 319        return 0;
 320}
 321
 322static int fsl_counter_clock_enable(struct fsl_pwm_chip *fpc)
 323{
 324        int ret;
 325
 326        /* select counter clock source */
 327        regmap_update_bits(fpc->regmap, FTM_SC, FTM_SC_CLK_MASK,
 328                           FTM_SC_CLK(fpc->cnt_select));
 329
 330        ret = clk_prepare_enable(fpc->clk[fpc->cnt_select]);
 331        if (ret)
 332                return ret;
 333
 334        ret = clk_prepare_enable(fpc->clk[FSL_PWM_CLK_CNTEN]);
 335        if (ret) {
 336                clk_disable_unprepare(fpc->clk[fpc->cnt_select]);
 337                return ret;
 338        }
 339
 340        return 0;
 341}
 342
 343static int fsl_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 344{
 345        struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
 346        int ret;
 347
 348        mutex_lock(&fpc->lock);
 349        regmap_update_bits(fpc->regmap, FTM_OUTMASK, BIT(pwm->hwpwm), 0);
 350
 351        ret = fsl_counter_clock_enable(fpc);
 352        mutex_unlock(&fpc->lock);
 353
 354        return ret;
 355}
 356
 357static void fsl_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 358{
 359        struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
 360        u32 val;
 361
 362        mutex_lock(&fpc->lock);
 363        regmap_update_bits(fpc->regmap, FTM_OUTMASK, BIT(pwm->hwpwm),
 364                           BIT(pwm->hwpwm));
 365
 366        clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]);
 367        clk_disable_unprepare(fpc->clk[fpc->cnt_select]);
 368
 369        regmap_read(fpc->regmap, FTM_OUTMASK, &val);
 370        if ((val & 0xFF) == 0xFF)
 371                fpc->period_ns = 0;
 372
 373        mutex_unlock(&fpc->lock);
 374}
 375
 376static const struct pwm_ops fsl_pwm_ops = {
 377        .request = fsl_pwm_request,
 378        .free = fsl_pwm_free,
 379        .config = fsl_pwm_config,
 380        .set_polarity = fsl_pwm_set_polarity,
 381        .enable = fsl_pwm_enable,
 382        .disable = fsl_pwm_disable,
 383        .owner = THIS_MODULE,
 384};
 385
 386static int fsl_pwm_init(struct fsl_pwm_chip *fpc)
 387{
 388        int ret;
 389
 390        ret = clk_prepare_enable(fpc->ipg_clk);
 391        if (ret)
 392                return ret;
 393
 394        regmap_write(fpc->regmap, FTM_CNTIN, 0x00);
 395        regmap_write(fpc->regmap, FTM_OUTINIT, 0x00);
 396        regmap_write(fpc->regmap, FTM_OUTMASK, 0xFF);
 397
 398        clk_disable_unprepare(fpc->ipg_clk);
 399
 400        return 0;
 401}
 402
 403static bool fsl_pwm_volatile_reg(struct device *dev, unsigned int reg)
 404{
 405        switch (reg) {
 406        case FTM_CNT:
 407                return true;
 408        }
 409        return false;
 410}
 411
 412static const struct regmap_config fsl_pwm_regmap_config = {
 413        .reg_bits = 32,
 414        .reg_stride = 4,
 415        .val_bits = 32,
 416
 417        .max_register = FTM_PWMLOAD,
 418        .volatile_reg = fsl_pwm_volatile_reg,
 419        .cache_type = REGCACHE_FLAT,
 420};
 421
 422static int fsl_pwm_probe(struct platform_device *pdev)
 423{
 424        struct fsl_pwm_chip *fpc;
 425        struct resource *res;
 426        void __iomem *base;
 427        int ret;
 428
 429        fpc = devm_kzalloc(&pdev->dev, sizeof(*fpc), GFP_KERNEL);
 430        if (!fpc)
 431                return -ENOMEM;
 432
 433        mutex_init(&fpc->lock);
 434
 435        fpc->soc = of_device_get_match_data(&pdev->dev);
 436        fpc->chip.dev = &pdev->dev;
 437
 438        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 439        base = devm_ioremap_resource(&pdev->dev, res);
 440        if (IS_ERR(base))
 441                return PTR_ERR(base);
 442
 443        fpc->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "ftm_sys", base,
 444                                                &fsl_pwm_regmap_config);
 445        if (IS_ERR(fpc->regmap)) {
 446                dev_err(&pdev->dev, "regmap init failed\n");
 447                return PTR_ERR(fpc->regmap);
 448        }
 449
 450        fpc->clk[FSL_PWM_CLK_SYS] = devm_clk_get(&pdev->dev, "ftm_sys");
 451        if (IS_ERR(fpc->clk[FSL_PWM_CLK_SYS])) {
 452                dev_err(&pdev->dev, "failed to get \"ftm_sys\" clock\n");
 453                return PTR_ERR(fpc->clk[FSL_PWM_CLK_SYS]);
 454        }
 455
 456        fpc->clk[FSL_PWM_CLK_FIX] = devm_clk_get(fpc->chip.dev, "ftm_fix");
 457        if (IS_ERR(fpc->clk[FSL_PWM_CLK_FIX]))
 458                return PTR_ERR(fpc->clk[FSL_PWM_CLK_FIX]);
 459
 460        fpc->clk[FSL_PWM_CLK_EXT] = devm_clk_get(fpc->chip.dev, "ftm_ext");
 461        if (IS_ERR(fpc->clk[FSL_PWM_CLK_EXT]))
 462                return PTR_ERR(fpc->clk[FSL_PWM_CLK_EXT]);
 463
 464        fpc->clk[FSL_PWM_CLK_CNTEN] =
 465                                devm_clk_get(fpc->chip.dev, "ftm_cnt_clk_en");
 466        if (IS_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]))
 467                return PTR_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]);
 468
 469        /*
 470         * ipg_clk is the interface clock for the IP. If not provided, use the
 471         * ftm_sys clock as the default.
 472         */
 473        fpc->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
 474        if (IS_ERR(fpc->ipg_clk))
 475                fpc->ipg_clk = fpc->clk[FSL_PWM_CLK_SYS];
 476
 477
 478        fpc->chip.ops = &fsl_pwm_ops;
 479        fpc->chip.of_xlate = of_pwm_xlate_with_flags;
 480        fpc->chip.of_pwm_n_cells = 3;
 481        fpc->chip.base = -1;
 482        fpc->chip.npwm = 8;
 483
 484        ret = pwmchip_add(&fpc->chip);
 485        if (ret < 0) {
 486                dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
 487                return ret;
 488        }
 489
 490        platform_set_drvdata(pdev, fpc);
 491
 492        return fsl_pwm_init(fpc);
 493}
 494
 495static int fsl_pwm_remove(struct platform_device *pdev)
 496{
 497        struct fsl_pwm_chip *fpc = platform_get_drvdata(pdev);
 498
 499        return pwmchip_remove(&fpc->chip);
 500}
 501
 502#ifdef CONFIG_PM_SLEEP
 503static int fsl_pwm_suspend(struct device *dev)
 504{
 505        struct fsl_pwm_chip *fpc = dev_get_drvdata(dev);
 506        int i;
 507
 508        regcache_cache_only(fpc->regmap, true);
 509        regcache_mark_dirty(fpc->regmap);
 510
 511        for (i = 0; i < fpc->chip.npwm; i++) {
 512                struct pwm_device *pwm = &fpc->chip.pwms[i];
 513
 514                if (!test_bit(PWMF_REQUESTED, &pwm->flags))
 515                        continue;
 516
 517                clk_disable_unprepare(fpc->ipg_clk);
 518
 519                if (!pwm_is_enabled(pwm))
 520                        continue;
 521
 522                clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]);
 523                clk_disable_unprepare(fpc->clk[fpc->cnt_select]);
 524        }
 525
 526        return 0;
 527}
 528
 529static int fsl_pwm_resume(struct device *dev)
 530{
 531        struct fsl_pwm_chip *fpc = dev_get_drvdata(dev);
 532        int i;
 533
 534        for (i = 0; i < fpc->chip.npwm; i++) {
 535                struct pwm_device *pwm = &fpc->chip.pwms[i];
 536
 537                if (!test_bit(PWMF_REQUESTED, &pwm->flags))
 538                        continue;
 539
 540                clk_prepare_enable(fpc->ipg_clk);
 541
 542                if (!pwm_is_enabled(pwm))
 543                        continue;
 544
 545                clk_prepare_enable(fpc->clk[fpc->cnt_select]);
 546                clk_prepare_enable(fpc->clk[FSL_PWM_CLK_CNTEN]);
 547        }
 548
 549        /* restore all registers from cache */
 550        regcache_cache_only(fpc->regmap, false);
 551        regcache_sync(fpc->regmap);
 552
 553        return 0;
 554}
 555#endif
 556
 557static const struct dev_pm_ops fsl_pwm_pm_ops = {
 558        SET_SYSTEM_SLEEP_PM_OPS(fsl_pwm_suspend, fsl_pwm_resume)
 559};
 560
 561static const struct fsl_ftm_soc vf610_ftm_pwm = {
 562        .has_enable_bits = false,
 563};
 564
 565static const struct fsl_ftm_soc imx8qm_ftm_pwm = {
 566        .has_enable_bits = true,
 567};
 568
 569static const struct of_device_id fsl_pwm_dt_ids[] = {
 570        { .compatible = "fsl,vf610-ftm-pwm", .data = &vf610_ftm_pwm },
 571        { .compatible = "fsl,imx8qm-ftm-pwm", .data = &imx8qm_ftm_pwm },
 572        { /* sentinel */ }
 573};
 574MODULE_DEVICE_TABLE(of, fsl_pwm_dt_ids);
 575
 576static struct platform_driver fsl_pwm_driver = {
 577        .driver = {
 578                .name = "fsl-ftm-pwm",
 579                .of_match_table = fsl_pwm_dt_ids,
 580                .pm = &fsl_pwm_pm_ops,
 581        },
 582        .probe = fsl_pwm_probe,
 583        .remove = fsl_pwm_remove,
 584};
 585module_platform_driver(fsl_pwm_driver);
 586
 587MODULE_DESCRIPTION("Freescale FlexTimer Module PWM Driver");
 588MODULE_AUTHOR("Xiubo Li <Li.Xiubo@freescale.com>");
 589MODULE_ALIAS("platform:fsl-ftm-pwm");
 590MODULE_LICENSE("GPL");
 591