Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 293 lines 7.6 kB view raw
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Intel Low Power Subsystem PWM controller driver 4 * 5 * Copyright (C) 2014, Intel Corporation 6 * Author: Mika Westerberg <mika.westerberg@linux.intel.com> 7 * Author: Chew Kean Ho <kean.ho.chew@intel.com> 8 * Author: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com> 9 * Author: Chew Chiau Ee <chiau.ee.chew@intel.com> 10 * Author: Alan Cox <alan@linux.intel.com> 11 */ 12 13#define DEFAULT_SYMBOL_NAMESPACE "PWM_LPSS" 14 15#include <linux/bits.h> 16#include <linux/delay.h> 17#include <linux/io.h> 18#include <linux/iopoll.h> 19#include <linux/kernel.h> 20#include <linux/module.h> 21#include <linux/pm_runtime.h> 22#include <linux/pwm.h> 23#include <linux/time.h> 24 25#include "pwm-lpss.h" 26 27#define PWM 0x00000000 28#define PWM_ENABLE BIT(31) 29#define PWM_SW_UPDATE BIT(30) 30#define PWM_BASE_UNIT_SHIFT 8 31#define PWM_ON_TIME_DIV_MASK GENMASK(7, 0) 32 33/* Size of each PWM register space if multiple */ 34#define PWM_SIZE 0x400 35 36/* BayTrail */ 37const struct pwm_lpss_boardinfo pwm_lpss_byt_info = { 38 .clk_rate = 25000000, 39 .npwm = 1, 40 .base_unit_bits = 16, 41}; 42EXPORT_SYMBOL_GPL(pwm_lpss_byt_info); 43 44/* Braswell */ 45const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = { 46 .clk_rate = 19200000, 47 .npwm = 1, 48 .base_unit_bits = 16, 49 .other_devices_aml_touches_pwm_regs = true, 50}; 51EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info); 52 53/* Broxton */ 54const struct pwm_lpss_boardinfo pwm_lpss_bxt_info = { 55 .clk_rate = 19200000, 56 .npwm = 4, 57 .base_unit_bits = 22, 58 .bypass = true, 59}; 60EXPORT_SYMBOL_GPL(pwm_lpss_bxt_info); 61 62/* Tangier */ 63const struct pwm_lpss_boardinfo pwm_lpss_tng_info = { 64 .clk_rate = 19200000, 65 .npwm = 4, 66 .base_unit_bits = 22, 67}; 68EXPORT_SYMBOL_GPL(pwm_lpss_tng_info); 69 70static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip) 71{ 72 return pwmchip_get_drvdata(chip); 73} 74 75static inline u32 pwm_lpss_read(const struct pwm_device *pwm) 76{ 77 struct pwm_lpss_chip *lpwm = to_lpwm(pwm->chip); 78 79 return readl(lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM); 80} 81 82static inline void pwm_lpss_write(const struct pwm_device *pwm, u32 value) 83{ 84 struct pwm_lpss_chip *lpwm = to_lpwm(pwm->chip); 85 86 writel(value, lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM); 87} 88 89static int pwm_lpss_wait_for_update(struct pwm_device *pwm) 90{ 91 struct pwm_lpss_chip *lpwm = to_lpwm(pwm->chip); 92 const void __iomem *addr = lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM; 93 const unsigned int ms = 500 * USEC_PER_MSEC; 94 u32 val; 95 int err; 96 97 /* 98 * PWM Configuration register has SW_UPDATE bit that is set when a new 99 * configuration is written to the register. The bit is automatically 100 * cleared at the start of the next output cycle by the IP block. 101 * 102 * If one writes a new configuration to the register while it still has 103 * the bit enabled, PWM may freeze. That is, while one can still write 104 * to the register, it won't have an effect. Thus, we try to sleep long 105 * enough that the bit gets cleared and make sure the bit is not 106 * enabled while we update the configuration. 107 */ 108 err = readl_poll_timeout(addr, val, !(val & PWM_SW_UPDATE), 40, ms); 109 if (err) 110 dev_err(pwmchip_parent(pwm->chip), "PWM_SW_UPDATE was not cleared\n"); 111 112 return err; 113} 114 115static inline int pwm_lpss_is_updating(struct pwm_device *pwm) 116{ 117 if (pwm_lpss_read(pwm) & PWM_SW_UPDATE) { 118 dev_err(pwmchip_parent(pwm->chip), "PWM_SW_UPDATE is still set, skipping update\n"); 119 return -EBUSY; 120 } 121 122 return 0; 123} 124 125static void pwm_lpss_prepare(struct pwm_lpss_chip *lpwm, struct pwm_device *pwm, 126 int duty_ns, int period_ns) 127{ 128 unsigned long long on_time_div; 129 unsigned long c = lpwm->info->clk_rate, base_unit_range; 130 unsigned long long base_unit, freq = NSEC_PER_SEC; 131 u32 ctrl; 132 133 do_div(freq, period_ns); 134 135 /* 136 * The equation is: 137 * base_unit = round(base_unit_range * freq / c) 138 */ 139 base_unit_range = BIT(lpwm->info->base_unit_bits); 140 freq *= base_unit_range; 141 142 base_unit = DIV_ROUND_CLOSEST_ULL(freq, c); 143 /* base_unit must not be 0 and we also want to avoid overflowing it */ 144 base_unit = clamp_val(base_unit, 1, base_unit_range - 1); 145 146 on_time_div = 255ULL * duty_ns; 147 do_div(on_time_div, period_ns); 148 on_time_div = 255ULL - on_time_div; 149 150 ctrl = pwm_lpss_read(pwm); 151 ctrl &= ~PWM_ON_TIME_DIV_MASK; 152 ctrl &= ~((base_unit_range - 1) << PWM_BASE_UNIT_SHIFT); 153 ctrl |= (u32) base_unit << PWM_BASE_UNIT_SHIFT; 154 ctrl |= on_time_div; 155 156 pwm_lpss_write(pwm, ctrl); 157 pwm_lpss_write(pwm, ctrl | PWM_SW_UPDATE); 158} 159 160static inline void pwm_lpss_cond_enable(struct pwm_device *pwm, bool cond) 161{ 162 if (cond) 163 pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_ENABLE); 164} 165 166static int pwm_lpss_prepare_enable(struct pwm_lpss_chip *lpwm, 167 struct pwm_device *pwm, 168 const struct pwm_state *state) 169{ 170 int ret; 171 172 ret = pwm_lpss_is_updating(pwm); 173 if (ret) 174 return ret; 175 176 pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period); 177 pwm_lpss_cond_enable(pwm, lpwm->info->bypass == false); 178 ret = pwm_lpss_wait_for_update(pwm); 179 if (ret) 180 return ret; 181 182 pwm_lpss_cond_enable(pwm, lpwm->info->bypass == true); 183 return 0; 184} 185 186static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm, 187 const struct pwm_state *state) 188{ 189 struct pwm_lpss_chip *lpwm = to_lpwm(chip); 190 int ret = 0; 191 192 if (state->enabled) { 193 if (!pwm_is_enabled(pwm)) { 194 pm_runtime_get_sync(pwmchip_parent(chip)); 195 ret = pwm_lpss_prepare_enable(lpwm, pwm, state); 196 if (ret) 197 pm_runtime_put(pwmchip_parent(chip)); 198 } else { 199 ret = pwm_lpss_prepare_enable(lpwm, pwm, state); 200 } 201 } else if (pwm_is_enabled(pwm)) { 202 pwm_lpss_write(pwm, pwm_lpss_read(pwm) & ~PWM_ENABLE); 203 pm_runtime_put(pwmchip_parent(chip)); 204 } 205 206 return ret; 207} 208 209static int pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm, 210 struct pwm_state *state) 211{ 212 struct pwm_lpss_chip *lpwm = to_lpwm(chip); 213 unsigned long base_unit_range; 214 unsigned long long base_unit, freq, on_time_div; 215 u32 ctrl; 216 217 pm_runtime_get_sync(pwmchip_parent(chip)); 218 219 base_unit_range = BIT(lpwm->info->base_unit_bits); 220 221 ctrl = pwm_lpss_read(pwm); 222 on_time_div = 255 - (ctrl & PWM_ON_TIME_DIV_MASK); 223 base_unit = (ctrl >> PWM_BASE_UNIT_SHIFT) & (base_unit_range - 1); 224 225 freq = base_unit * lpwm->info->clk_rate; 226 do_div(freq, base_unit_range); 227 if (freq == 0) 228 state->period = NSEC_PER_SEC; 229 else 230 state->period = NSEC_PER_SEC / (unsigned long)freq; 231 232 on_time_div *= state->period; 233 do_div(on_time_div, 255); 234 state->duty_cycle = on_time_div; 235 236 state->polarity = PWM_POLARITY_NORMAL; 237 state->enabled = !!(ctrl & PWM_ENABLE); 238 239 pm_runtime_put(pwmchip_parent(chip)); 240 241 return 0; 242} 243 244static const struct pwm_ops pwm_lpss_ops = { 245 .apply = pwm_lpss_apply, 246 .get_state = pwm_lpss_get_state, 247}; 248 249struct pwm_chip *devm_pwm_lpss_probe(struct device *dev, void __iomem *base, 250 const struct pwm_lpss_boardinfo *info) 251{ 252 struct pwm_lpss_chip *lpwm; 253 struct pwm_chip *chip; 254 unsigned long c; 255 int i, ret; 256 u32 ctrl; 257 258 if (WARN_ON(info->npwm > LPSS_MAX_PWMS)) 259 return ERR_PTR(-ENODEV); 260 261 chip = devm_pwmchip_alloc(dev, info->npwm, sizeof(*lpwm)); 262 if (IS_ERR(chip)) 263 return chip; 264 lpwm = to_lpwm(chip); 265 266 lpwm->regs = base; 267 lpwm->info = info; 268 269 c = lpwm->info->clk_rate; 270 if (!c) 271 return ERR_PTR(-EINVAL); 272 273 chip->ops = &pwm_lpss_ops; 274 275 ret = devm_pwmchip_add(dev, chip); 276 if (ret) { 277 dev_err(dev, "failed to add PWM chip: %d\n", ret); 278 return ERR_PTR(ret); 279 } 280 281 for (i = 0; i < lpwm->info->npwm; i++) { 282 ctrl = pwm_lpss_read(&chip->pwms[i]); 283 if (ctrl & PWM_ENABLE) 284 pm_runtime_get(dev); 285 } 286 287 return chip; 288} 289EXPORT_SYMBOL_GPL(devm_pwm_lpss_probe); 290 291MODULE_DESCRIPTION("PWM driver for Intel LPSS"); 292MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); 293MODULE_LICENSE("GPL v2");