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 v3.7 467 lines 13 kB view raw
1/* 2 * EHRPWM PWM driver 3 * 4 * Copyright (C) 2012 Texas Instruments, Inc. - http://www.ti.com/ 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 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 */ 20 21#include <linux/module.h> 22#include <linux/platform_device.h> 23#include <linux/pwm.h> 24#include <linux/io.h> 25#include <linux/err.h> 26#include <linux/clk.h> 27#include <linux/pm_runtime.h> 28 29/* EHRPWM registers and bits definitions */ 30 31/* Time base module registers */ 32#define TBCTL 0x00 33#define TBPRD 0x0A 34 35#define TBCTL_RUN_MASK (BIT(15) | BIT(14)) 36#define TBCTL_STOP_NEXT 0 37#define TBCTL_STOP_ON_CYCLE BIT(14) 38#define TBCTL_FREE_RUN (BIT(15) | BIT(14)) 39#define TBCTL_PRDLD_MASK BIT(3) 40#define TBCTL_PRDLD_SHDW 0 41#define TBCTL_PRDLD_IMDT BIT(3) 42#define TBCTL_CLKDIV_MASK (BIT(12) | BIT(11) | BIT(10) | BIT(9) | \ 43 BIT(8) | BIT(7)) 44#define TBCTL_CTRMODE_MASK (BIT(1) | BIT(0)) 45#define TBCTL_CTRMODE_UP 0 46#define TBCTL_CTRMODE_DOWN BIT(0) 47#define TBCTL_CTRMODE_UPDOWN BIT(1) 48#define TBCTL_CTRMODE_FREEZE (BIT(1) | BIT(0)) 49 50#define TBCTL_HSPCLKDIV_SHIFT 7 51#define TBCTL_CLKDIV_SHIFT 10 52 53#define CLKDIV_MAX 7 54#define HSPCLKDIV_MAX 7 55#define PERIOD_MAX 0xFFFF 56 57/* compare module registers */ 58#define CMPA 0x12 59#define CMPB 0x14 60 61/* Action qualifier module registers */ 62#define AQCTLA 0x16 63#define AQCTLB 0x18 64#define AQSFRC 0x1A 65#define AQCSFRC 0x1C 66 67#define AQCTL_CBU_MASK (BIT(9) | BIT(8)) 68#define AQCTL_CBU_FRCLOW BIT(8) 69#define AQCTL_CBU_FRCHIGH BIT(9) 70#define AQCTL_CBU_FRCTOGGLE (BIT(9) | BIT(8)) 71#define AQCTL_CAU_MASK (BIT(5) | BIT(4)) 72#define AQCTL_CAU_FRCLOW BIT(4) 73#define AQCTL_CAU_FRCHIGH BIT(5) 74#define AQCTL_CAU_FRCTOGGLE (BIT(5) | BIT(4)) 75#define AQCTL_PRD_MASK (BIT(3) | BIT(2)) 76#define AQCTL_PRD_FRCLOW BIT(2) 77#define AQCTL_PRD_FRCHIGH BIT(3) 78#define AQCTL_PRD_FRCTOGGLE (BIT(3) | BIT(2)) 79#define AQCTL_ZRO_MASK (BIT(1) | BIT(0)) 80#define AQCTL_ZRO_FRCLOW BIT(0) 81#define AQCTL_ZRO_FRCHIGH BIT(1) 82#define AQCTL_ZRO_FRCTOGGLE (BIT(1) | BIT(0)) 83 84#define AQCTL_CHANA_POLNORMAL (AQCTL_CAU_FRCLOW | AQCTL_PRD_FRCHIGH | \ 85 AQCTL_ZRO_FRCHIGH) 86#define AQCTL_CHANA_POLINVERSED (AQCTL_CAU_FRCHIGH | AQCTL_PRD_FRCLOW | \ 87 AQCTL_ZRO_FRCLOW) 88#define AQCTL_CHANB_POLNORMAL (AQCTL_CBU_FRCLOW | AQCTL_PRD_FRCHIGH | \ 89 AQCTL_ZRO_FRCHIGH) 90#define AQCTL_CHANB_POLINVERSED (AQCTL_CBU_FRCHIGH | AQCTL_PRD_FRCLOW | \ 91 AQCTL_ZRO_FRCLOW) 92 93#define AQSFRC_RLDCSF_MASK (BIT(7) | BIT(6)) 94#define AQSFRC_RLDCSF_ZRO 0 95#define AQSFRC_RLDCSF_PRD BIT(6) 96#define AQSFRC_RLDCSF_ZROPRD BIT(7) 97#define AQSFRC_RLDCSF_IMDT (BIT(7) | BIT(6)) 98 99#define AQCSFRC_CSFB_MASK (BIT(3) | BIT(2)) 100#define AQCSFRC_CSFB_FRCDIS 0 101#define AQCSFRC_CSFB_FRCLOW BIT(2) 102#define AQCSFRC_CSFB_FRCHIGH BIT(3) 103#define AQCSFRC_CSFB_DISSWFRC (BIT(3) | BIT(2)) 104#define AQCSFRC_CSFA_MASK (BIT(1) | BIT(0)) 105#define AQCSFRC_CSFA_FRCDIS 0 106#define AQCSFRC_CSFA_FRCLOW BIT(0) 107#define AQCSFRC_CSFA_FRCHIGH BIT(1) 108#define AQCSFRC_CSFA_DISSWFRC (BIT(1) | BIT(0)) 109 110#define NUM_PWM_CHANNEL 2 /* EHRPWM channels */ 111 112struct ehrpwm_pwm_chip { 113 struct pwm_chip chip; 114 unsigned int clk_rate; 115 void __iomem *mmio_base; 116 unsigned long period_cycles[NUM_PWM_CHANNEL]; 117 enum pwm_polarity polarity[NUM_PWM_CHANNEL]; 118}; 119 120static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip) 121{ 122 return container_of(chip, struct ehrpwm_pwm_chip, chip); 123} 124 125static void ehrpwm_write(void *base, int offset, unsigned int val) 126{ 127 writew(val & 0xFFFF, base + offset); 128} 129 130static void ehrpwm_modify(void *base, int offset, 131 unsigned short mask, unsigned short val) 132{ 133 unsigned short regval; 134 135 regval = readw(base + offset); 136 regval &= ~mask; 137 regval |= val & mask; 138 writew(regval, base + offset); 139} 140 141/** 142 * set_prescale_div - Set up the prescaler divider function 143 * @rqst_prescaler: prescaler value min 144 * @prescale_div: prescaler value set 145 * @tb_clk_div: Time Base Control prescaler bits 146 */ 147static int set_prescale_div(unsigned long rqst_prescaler, 148 unsigned short *prescale_div, unsigned short *tb_clk_div) 149{ 150 unsigned int clkdiv, hspclkdiv; 151 152 for (clkdiv = 0; clkdiv <= CLKDIV_MAX; clkdiv++) { 153 for (hspclkdiv = 0; hspclkdiv <= HSPCLKDIV_MAX; hspclkdiv++) { 154 155 /* 156 * calculations for prescaler value : 157 * prescale_div = HSPCLKDIVIDER * CLKDIVIDER. 158 * HSPCLKDIVIDER = 2 ** hspclkdiv 159 * CLKDIVIDER = (1), if clkdiv == 0 *OR* 160 * (2 * clkdiv), if clkdiv != 0 161 * 162 * Configure prescale_div value such that period 163 * register value is less than 65535. 164 */ 165 166 *prescale_div = (1 << clkdiv) * 167 (hspclkdiv ? (hspclkdiv * 2) : 1); 168 if (*prescale_div > rqst_prescaler) { 169 *tb_clk_div = (clkdiv << TBCTL_CLKDIV_SHIFT) | 170 (hspclkdiv << TBCTL_HSPCLKDIV_SHIFT); 171 return 0; 172 } 173 } 174 } 175 return 1; 176} 177 178static void configure_polarity(struct ehrpwm_pwm_chip *pc, int chan) 179{ 180 int aqctl_reg; 181 unsigned short aqctl_val, aqctl_mask; 182 183 /* 184 * Configure PWM output to HIGH/LOW level on counter 185 * reaches compare register value and LOW/HIGH level 186 * on counter value reaches period register value and 187 * zero value on counter 188 */ 189 if (chan == 1) { 190 aqctl_reg = AQCTLB; 191 aqctl_mask = AQCTL_CBU_MASK; 192 193 if (pc->polarity[chan] == PWM_POLARITY_INVERSED) 194 aqctl_val = AQCTL_CHANB_POLINVERSED; 195 else 196 aqctl_val = AQCTL_CHANB_POLNORMAL; 197 } else { 198 aqctl_reg = AQCTLA; 199 aqctl_mask = AQCTL_CAU_MASK; 200 201 if (pc->polarity[chan] == PWM_POLARITY_INVERSED) 202 aqctl_val = AQCTL_CHANA_POLINVERSED; 203 else 204 aqctl_val = AQCTL_CHANA_POLNORMAL; 205 } 206 207 aqctl_mask |= AQCTL_PRD_MASK | AQCTL_ZRO_MASK; 208 ehrpwm_modify(pc->mmio_base, aqctl_reg, aqctl_mask, aqctl_val); 209} 210 211/* 212 * period_ns = 10^9 * (ps_divval * period_cycles) / PWM_CLK_RATE 213 * duty_ns = 10^9 * (ps_divval * duty_cycles) / PWM_CLK_RATE 214 */ 215static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, 216 int duty_ns, int period_ns) 217{ 218 struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip); 219 unsigned long long c; 220 unsigned long period_cycles, duty_cycles; 221 unsigned short ps_divval, tb_divval; 222 int i, cmp_reg; 223 224 if (period_ns > NSEC_PER_SEC) 225 return -ERANGE; 226 227 c = pc->clk_rate; 228 c = c * period_ns; 229 do_div(c, NSEC_PER_SEC); 230 period_cycles = (unsigned long)c; 231 232 if (period_cycles < 1) { 233 period_cycles = 1; 234 duty_cycles = 1; 235 } else { 236 c = pc->clk_rate; 237 c = c * duty_ns; 238 do_div(c, NSEC_PER_SEC); 239 duty_cycles = (unsigned long)c; 240 } 241 242 /* 243 * Period values should be same for multiple PWM channels as IP uses 244 * same period register for multiple channels. 245 */ 246 for (i = 0; i < NUM_PWM_CHANNEL; i++) { 247 if (pc->period_cycles[i] && 248 (pc->period_cycles[i] != period_cycles)) { 249 /* 250 * Allow channel to reconfigure period if no other 251 * channels being configured. 252 */ 253 if (i == pwm->hwpwm) 254 continue; 255 256 dev_err(chip->dev, "Period value conflicts with channel %d\n", 257 i); 258 return -EINVAL; 259 } 260 } 261 262 pc->period_cycles[pwm->hwpwm] = period_cycles; 263 264 /* Configure clock prescaler to support Low frequency PWM wave */ 265 if (set_prescale_div(period_cycles/PERIOD_MAX, &ps_divval, 266 &tb_divval)) { 267 dev_err(chip->dev, "Unsupported values\n"); 268 return -EINVAL; 269 } 270 271 pm_runtime_get_sync(chip->dev); 272 273 /* Update clock prescaler values */ 274 ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_CLKDIV_MASK, tb_divval); 275 276 /* Update period & duty cycle with presacler division */ 277 period_cycles = period_cycles / ps_divval; 278 duty_cycles = duty_cycles / ps_divval; 279 280 /* Configure shadow loading on Period register */ 281 ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_PRDLD_MASK, TBCTL_PRDLD_SHDW); 282 283 ehrpwm_write(pc->mmio_base, TBPRD, period_cycles); 284 285 /* Configure ehrpwm counter for up-count mode */ 286 ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_CTRMODE_MASK, 287 TBCTL_CTRMODE_UP); 288 289 if (pwm->hwpwm == 1) 290 /* Channel 1 configured with compare B register */ 291 cmp_reg = CMPB; 292 else 293 /* Channel 0 configured with compare A register */ 294 cmp_reg = CMPA; 295 296 ehrpwm_write(pc->mmio_base, cmp_reg, duty_cycles); 297 298 pm_runtime_put_sync(chip->dev); 299 return 0; 300} 301 302static int ehrpwm_pwm_set_polarity(struct pwm_chip *chip, 303 struct pwm_device *pwm, enum pwm_polarity polarity) 304{ 305 struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip); 306 307 /* Configuration of polarity in hardware delayed, do at enable */ 308 pc->polarity[pwm->hwpwm] = polarity; 309 return 0; 310} 311 312static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) 313{ 314 struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip); 315 unsigned short aqcsfrc_val, aqcsfrc_mask; 316 317 /* Leave clock enabled on enabling PWM */ 318 pm_runtime_get_sync(chip->dev); 319 320 /* Disabling Action Qualifier on PWM output */ 321 if (pwm->hwpwm) { 322 aqcsfrc_val = AQCSFRC_CSFB_FRCDIS; 323 aqcsfrc_mask = AQCSFRC_CSFB_MASK; 324 } else { 325 aqcsfrc_val = AQCSFRC_CSFA_FRCDIS; 326 aqcsfrc_mask = AQCSFRC_CSFA_MASK; 327 } 328 329 /* Changes to shadow mode */ 330 ehrpwm_modify(pc->mmio_base, AQSFRC, AQSFRC_RLDCSF_MASK, 331 AQSFRC_RLDCSF_ZRO); 332 333 ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val); 334 335 /* Channels polarity can be configured from action qualifier module */ 336 configure_polarity(pc, pwm->hwpwm); 337 338 /* Enable time counter for free_run */ 339 ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_FREE_RUN); 340 return 0; 341} 342 343static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) 344{ 345 struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip); 346 unsigned short aqcsfrc_val, aqcsfrc_mask; 347 348 /* Action Qualifier puts PWM output low forcefully */ 349 if (pwm->hwpwm) { 350 aqcsfrc_val = AQCSFRC_CSFB_FRCLOW; 351 aqcsfrc_mask = AQCSFRC_CSFB_MASK; 352 } else { 353 aqcsfrc_val = AQCSFRC_CSFA_FRCLOW; 354 aqcsfrc_mask = AQCSFRC_CSFA_MASK; 355 } 356 357 /* 358 * Changes to immediate action on Action Qualifier. This puts 359 * Action Qualifier control on PWM output from next TBCLK 360 */ 361 ehrpwm_modify(pc->mmio_base, AQSFRC, AQSFRC_RLDCSF_MASK, 362 AQSFRC_RLDCSF_IMDT); 363 364 ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val); 365 366 /* Stop Time base counter */ 367 ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_STOP_NEXT); 368 369 /* Disable clock on PWM disable */ 370 pm_runtime_put_sync(chip->dev); 371} 372 373static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) 374{ 375 struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip); 376 377 if (test_bit(PWMF_ENABLED, &pwm->flags)) { 378 dev_warn(chip->dev, "Removing PWM device without disabling\n"); 379 pm_runtime_put_sync(chip->dev); 380 } 381 382 /* set period value to zero on free */ 383 pc->period_cycles[pwm->hwpwm] = 0; 384} 385 386static const struct pwm_ops ehrpwm_pwm_ops = { 387 .free = ehrpwm_pwm_free, 388 .config = ehrpwm_pwm_config, 389 .set_polarity = ehrpwm_pwm_set_polarity, 390 .enable = ehrpwm_pwm_enable, 391 .disable = ehrpwm_pwm_disable, 392 .owner = THIS_MODULE, 393}; 394 395static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev) 396{ 397 int ret; 398 struct resource *r; 399 struct clk *clk; 400 struct ehrpwm_pwm_chip *pc; 401 402 pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); 403 if (!pc) { 404 dev_err(&pdev->dev, "failed to allocate memory\n"); 405 return -ENOMEM; 406 } 407 408 clk = devm_clk_get(&pdev->dev, "fck"); 409 if (IS_ERR(clk)) { 410 dev_err(&pdev->dev, "failed to get clock\n"); 411 return PTR_ERR(clk); 412 } 413 414 pc->clk_rate = clk_get_rate(clk); 415 if (!pc->clk_rate) { 416 dev_err(&pdev->dev, "failed to get clock rate\n"); 417 return -EINVAL; 418 } 419 420 pc->chip.dev = &pdev->dev; 421 pc->chip.ops = &ehrpwm_pwm_ops; 422 pc->chip.base = -1; 423 pc->chip.npwm = NUM_PWM_CHANNEL; 424 425 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 426 if (!r) { 427 dev_err(&pdev->dev, "no memory resource defined\n"); 428 return -ENODEV; 429 } 430 431 pc->mmio_base = devm_request_and_ioremap(&pdev->dev, r); 432 if (!pc->mmio_base) 433 return -EADDRNOTAVAIL; 434 435 ret = pwmchip_add(&pc->chip); 436 if (ret < 0) { 437 dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); 438 return ret; 439 } 440 441 pm_runtime_enable(&pdev->dev); 442 platform_set_drvdata(pdev, pc); 443 return 0; 444} 445 446static int __devexit ehrpwm_pwm_remove(struct platform_device *pdev) 447{ 448 struct ehrpwm_pwm_chip *pc = platform_get_drvdata(pdev); 449 450 pm_runtime_put_sync(&pdev->dev); 451 pm_runtime_disable(&pdev->dev); 452 return pwmchip_remove(&pc->chip); 453} 454 455static struct platform_driver ehrpwm_pwm_driver = { 456 .driver = { 457 .name = "ehrpwm", 458 }, 459 .probe = ehrpwm_pwm_probe, 460 .remove = __devexit_p(ehrpwm_pwm_remove), 461}; 462 463module_platform_driver(ehrpwm_pwm_driver); 464 465MODULE_DESCRIPTION("EHRPWM PWM driver"); 466MODULE_AUTHOR("Texas Instruments"); 467MODULE_LICENSE("GPL");