pwm-dwc.c (7955B)
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");