linux/drivers/pwm/pwm-dwc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * DesignWare PWM Controller driver
   4 *
   5 * Copyright (C) 2018-2020 Intel Corporation
   6 *
   7 * Author: Felipe Balbi (Intel)
   8 * Author: Jarkko Nikula <jarkko.nikula@linux.intel.com>
   9 * Author: Raymond Tan <raymond.tan@intel.com>
  10 *
  11 * Limitations:
  12 * - The hardware cannot generate a 0 % or 100 % duty cycle. Both high and low
  13 *   periods are one or more input clock periods long.
  14 */
  15
  16#include <linux/bitops.h>
  17#include <linux/export.h>
  18#include <linux/kernel.h>
  19#include <linux/module.h>
  20#include <linux/pci.h>
  21#include <linux/pm_runtime.h>
  22#include <linux/pwm.h>
  23
  24#define DWC_TIM_LD_CNT(n)       ((n) * 0x14)
  25#define DWC_TIM_LD_CNT2(n)      (((n) * 4) + 0xb0)
  26#define DWC_TIM_CUR_VAL(n)      (((n) * 0x14) + 0x04)
  27#define DWC_TIM_CTRL(n)         (((n) * 0x14) + 0x08)
  28#define DWC_TIM_EOI(n)          (((n) * 0x14) + 0x0c)
  29#define DWC_TIM_INT_STS(n)      (((n) * 0x14) + 0x10)
  30
  31#define DWC_TIMERS_INT_STS      0xa0
  32#define DWC_TIMERS_EOI          0xa4
  33#define DWC_TIMERS_RAW_INT_STS  0xa8
  34#define DWC_TIMERS_COMP_VERSION 0xac
  35
  36#define DWC_TIMERS_TOTAL        8
  37#define DWC_CLK_PERIOD_NS       10
  38
  39/* Timer Control Register */
  40#define DWC_TIM_CTRL_EN         BIT(0)
  41#define DWC_TIM_CTRL_MODE       BIT(1)
  42#define DWC_TIM_CTRL_MODE_FREE  (0 << 1)
  43#define DWC_TIM_CTRL_MODE_USER  (1 << 1)
  44#define DWC_TIM_CTRL_INT_MASK   BIT(2)
  45#define DWC_TIM_CTRL_PWM        BIT(3)
  46
  47struct dwc_pwm_ctx {
  48        u32 cnt;
  49        u32 cnt2;
  50        u32 ctrl;
  51};
  52
  53struct dwc_pwm {
  54        struct pwm_chip chip;
  55        void __iomem *base;
  56        struct dwc_pwm_ctx ctx[DWC_TIMERS_TOTAL];
  57};
  58#define to_dwc_pwm(p)   (container_of((p), struct dwc_pwm, chip))
  59
  60static inline u32 dwc_pwm_readl(struct dwc_pwm *dwc, u32 offset)
  61{
  62        return readl(dwc->base + offset);
  63}
  64
  65static inline void dwc_pwm_writel(struct dwc_pwm *dwc, u32 value, u32 offset)
  66{
  67        writel(value, dwc->base + offset);
  68}
  69
  70static void __dwc_pwm_set_enable(struct dwc_pwm *dwc, int pwm, int enabled)
  71{
  72        u32 reg;
  73
  74        reg = dwc_pwm_readl(dwc, DWC_TIM_CTRL(pwm));
  75
  76        if (enabled)
  77                reg |= DWC_TIM_CTRL_EN;
  78        else
  79                reg &= ~DWC_TIM_CTRL_EN;
  80
  81        dwc_pwm_writel(dwc, reg, DWC_TIM_CTRL(pwm));
  82}
  83
  84static int __dwc_pwm_configure_timer(struct dwc_pwm *dwc,
  85                                     struct pwm_device *pwm,
  86                                     const struct pwm_state *state)
  87{
  88        u64 tmp;
  89        u32 ctrl;
  90        u32 high;
  91        u32 low;
  92
  93        /*
  94         * Calculate width of low and high period in terms of input clock
  95         * periods and check are the result within HW limits between 1 and
  96         * 2^32 periods.
  97         */
  98        tmp = DIV_ROUND_CLOSEST_ULL(state->duty_cycle, DWC_CLK_PERIOD_NS);
  99        if (tmp < 1 || tmp > (1ULL << 32))
 100                return -ERANGE;
 101        low = tmp - 1;
 102
 103        tmp = DIV_ROUND_CLOSEST_ULL(state->period - state->duty_cycle,
 104                                    DWC_CLK_PERIOD_NS);
 105        if (tmp < 1 || tmp > (1ULL << 32))
 106                return -ERANGE;
 107        high = tmp - 1;
 108
 109        /*
 110         * Specification says timer usage flow is to disable timer, then
 111         * program it followed by enable. It also says Load Count is loaded
 112         * into timer after it is enabled - either after a disable or
 113         * a reset. Based on measurements it happens also without disable
 114         * whenever Load Count is updated. But follow the specification.
 115         */
 116        __dwc_pwm_set_enable(dwc, pwm->hwpwm, false);
 117
 118        /*
 119         * Write Load Count and Load Count 2 registers. Former defines the
 120         * width of low period and latter the width of high period in terms
 121         * multiple of input clock periods:
 122         * Width = ((Count + 1) * input clock period).
 123         */
 124        dwc_pwm_writel(dwc, low, DWC_TIM_LD_CNT(pwm->hwpwm));
 125        dwc_pwm_writel(dwc, high, DWC_TIM_LD_CNT2(pwm->hwpwm));
 126
 127        /*
 128         * Set user-defined mode, timer reloads from Load Count registers
 129         * when it counts down to 0.
 130         * Set PWM mode, it makes output to toggle and width of low and high
 131         * periods are set by Load Count registers.
 132         */
 133        ctrl = DWC_TIM_CTRL_MODE_USER | DWC_TIM_CTRL_PWM;
 134        dwc_pwm_writel(dwc, ctrl, DWC_TIM_CTRL(pwm->hwpwm));
 135
 136        /*
 137         * Enable timer. Output starts from low period.
 138         */
 139        __dwc_pwm_set_enable(dwc, pwm->hwpwm, state->enabled);
 140
 141        return 0;
 142}
 143
 144static int dwc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 145                         const struct pwm_state *state)
 146{
 147        struct dwc_pwm *dwc = to_dwc_pwm(chip);
 148
 149        if (state->polarity != PWM_POLARITY_INVERSED)
 150                return -EINVAL;
 151
 152        if (state->enabled) {
 153                if (!pwm->state.enabled)
 154                        pm_runtime_get_sync(chip->dev);
 155                return __dwc_pwm_configure_timer(dwc, pwm, state);
 156        } else {
 157                if (pwm->state.enabled) {
 158                        __dwc_pwm_set_enable(dwc, pwm->hwpwm, false);
 159                        pm_runtime_put_sync(chip->dev);
 160                }
 161        }
 162
 163        return 0;
 164}
 165
 166static void dwc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
 167                              struct pwm_state *state)
 168{
 169        struct dwc_pwm *dwc = to_dwc_pwm(chip);
 170        u64 duty, period;
 171
 172        pm_runtime_get_sync(chip->dev);
 173
 174        state->enabled = !!(dwc_pwm_readl(dwc,
 175                                DWC_TIM_CTRL(pwm->hwpwm)) & DWC_TIM_CTRL_EN);
 176
 177        duty = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT(pwm->hwpwm));
 178        duty += 1;
 179        duty *= DWC_CLK_PERIOD_NS;
 180        state->duty_cycle = duty;
 181
 182        period = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT2(pwm->hwpwm));
 183        period += 1;
 184        period *= DWC_CLK_PERIOD_NS;
 185        period += duty;
 186        state->period = period;
 187
 188        state->polarity = PWM_POLARITY_INVERSED;
 189
 190        pm_runtime_put_sync(chip->dev);
 191}
 192
 193static const struct pwm_ops dwc_pwm_ops = {
 194        .apply = dwc_pwm_apply,
 195        .get_state = dwc_pwm_get_state,
 196        .owner = THIS_MODULE,
 197};
 198
 199static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id)
 200{
 201        struct device *dev = &pci->dev;
 202        struct dwc_pwm *dwc;
 203        int ret;
 204
 205        dwc = devm_kzalloc(&pci->dev, sizeof(*dwc), GFP_KERNEL);
 206        if (!dwc)
 207                return -ENOMEM;
 208
 209        ret = pcim_enable_device(pci);
 210        if (ret) {
 211                dev_err(&pci->dev,
 212                        "Failed to enable device (%pe)\n", ERR_PTR(ret));
 213                return ret;
 214        }
 215
 216        pci_set_master(pci);
 217
 218        ret = pcim_iomap_regions(pci, BIT(0), pci_name(pci));
 219        if (ret) {
 220                dev_err(&pci->dev,
 221                        "Failed to iomap PCI BAR (%pe)\n", ERR_PTR(ret));
 222                return ret;
 223        }
 224
 225        dwc->base = pcim_iomap_table(pci)[0];
 226        if (!dwc->base) {
 227                dev_err(&pci->dev, "Base address missing\n");
 228                return -ENOMEM;
 229        }
 230
 231        pci_set_drvdata(pci, dwc);
 232
 233        dwc->chip.dev = dev;
 234        dwc->chip.ops = &dwc_pwm_ops;
 235        dwc->chip.npwm = DWC_TIMERS_TOTAL;
 236
 237        ret = pwmchip_add(&dwc->chip);
 238        if (ret)
 239                return ret;
 240
 241        pm_runtime_put(dev);
 242        pm_runtime_allow(dev);
 243
 244        return 0;
 245}
 246
 247static void dwc_pwm_remove(struct pci_dev *pci)
 248{
 249        struct dwc_pwm *dwc = pci_get_drvdata(pci);
 250
 251        pm_runtime_forbid(&pci->dev);
 252        pm_runtime_get_noresume(&pci->dev);
 253
 254        pwmchip_remove(&dwc->chip);
 255}
 256
 257#ifdef CONFIG_PM_SLEEP
 258static int dwc_pwm_suspend(struct device *dev)
 259{
 260        struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
 261        struct dwc_pwm *dwc = pci_get_drvdata(pdev);
 262        int i;
 263
 264        for (i = 0; i < DWC_TIMERS_TOTAL; i++) {
 265                if (dwc->chip.pwms[i].state.enabled) {
 266                        dev_err(dev, "PWM %u in use by consumer (%s)\n",
 267                                i, dwc->chip.pwms[i].label);
 268                        return -EBUSY;
 269                }
 270                dwc->ctx[i].cnt = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT(i));
 271                dwc->ctx[i].cnt2 = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT2(i));
 272                dwc->ctx[i].ctrl = dwc_pwm_readl(dwc, DWC_TIM_CTRL(i));
 273        }
 274
 275        return 0;
 276}
 277
 278static int dwc_pwm_resume(struct device *dev)
 279{
 280        struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
 281        struct dwc_pwm *dwc = pci_get_drvdata(pdev);
 282        int i;
 283
 284        for (i = 0; i < DWC_TIMERS_TOTAL; i++) {
 285                dwc_pwm_writel(dwc, dwc->ctx[i].cnt, DWC_TIM_LD_CNT(i));
 286                dwc_pwm_writel(dwc, dwc->ctx[i].cnt2, DWC_TIM_LD_CNT2(i));
 287                dwc_pwm_writel(dwc, dwc->ctx[i].ctrl, DWC_TIM_CTRL(i));
 288        }
 289
 290        return 0;
 291}
 292#endif
 293
 294static SIMPLE_DEV_PM_OPS(dwc_pwm_pm_ops, dwc_pwm_suspend, dwc_pwm_resume);
 295
 296static const struct pci_device_id dwc_pwm_id_table[] = {
 297        { PCI_VDEVICE(INTEL, 0x4bb7) }, /* Elkhart Lake */
 298        {  }    /* Terminating Entry */
 299};
 300MODULE_DEVICE_TABLE(pci, dwc_pwm_id_table);
 301
 302static struct pci_driver dwc_pwm_driver = {
 303        .name = "pwm-dwc",
 304        .probe = dwc_pwm_probe,
 305        .remove = dwc_pwm_remove,
 306        .id_table = dwc_pwm_id_table,
 307        .driver = {
 308                .pm = &dwc_pwm_pm_ops,
 309        },
 310};
 311
 312module_pci_driver(dwc_pwm_driver);
 313
 314MODULE_AUTHOR("Felipe Balbi (Intel)");
 315MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@linux.intel.com>");
 316MODULE_AUTHOR("Raymond Tan <raymond.tan@intel.com>");
 317MODULE_DESCRIPTION("DesignWare PWM Controller");
 318MODULE_LICENSE("GPL");
 319