1 /* 2 * linux/arch/arm/plat-omap/dmtimer.c 3 * 4 * OMAP Dual-Mode Timers 5 * 6 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 7 * Tarun Kanti DebBarma <tarun.kanti@ti.com> 8 * Thara Gopinath <thara@ti.com> 9 * 10 * dmtimer adaptation to platform_driver. 11 * 12 * Copyright (C) 2005 Nokia Corporation 13 * OMAP2 support by Juha Yrjola 14 * API improvements and OMAP2 clock framework support by Timo Teras 15 * 16 * Copyright (C) 2009 Texas Instruments 17 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> 18 * 19 * This program is free software; you can redistribute it and/or modify it 20 * under the terms of the GNU General Public License as published by the 21 * Free Software Foundation; either version 2 of the License, or (at your 22 * option) any later version. 23 * 24 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 25 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 27 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * 33 * You should have received a copy of the GNU General Public License along 34 * with this program; if not, write to the Free Software Foundation, Inc., 35 * 675 Mass Ave, Cambridge, MA 02139, USA. 36 */ 37 38 #include <linux/clk.h> 39 #include <linux/clk-provider.h> 40 #include <linux/module.h> 41 #include <linux/io.h> 42 #include <linux/device.h> 43 #include <linux/err.h> 44 #include <linux/pm_runtime.h> 45 #include <linux/of.h> 46 #include <linux/of_device.h> 47 #include <linux/platform_device.h> 48 #include <linux/platform_data/dmtimer-omap.h> 49 50 #include <clocksource/timer-ti-dm.h> 51 52 static u32 omap_reserved_systimers; 53 static LIST_HEAD(omap_timer_list); 54 static DEFINE_SPINLOCK(dm_timer_lock); 55 56 enum { 57 REQUEST_ANY = 0, 58 REQUEST_BY_ID, 59 REQUEST_BY_CAP, 60 REQUEST_BY_NODE, 61 }; 62 63 /** 64 * omap_dm_timer_read_reg - read timer registers in posted and non-posted mode 65 * @timer: timer pointer over which read operation to perform 66 * @reg: lowest byte holds the register offset 67 * 68 * The posted mode bit is encoded in reg. Note that in posted mode write 69 * pending bit must be checked. Otherwise a read of a non completed write 70 * will produce an error. 71 */ 72 static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg) 73 { 74 WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET); 75 return __omap_dm_timer_read(timer, reg, timer->posted); 76 } 77 78 /** 79 * omap_dm_timer_write_reg - write timer registers in posted and non-posted mode 80 * @timer: timer pointer over which write operation is to perform 81 * @reg: lowest byte holds the register offset 82 * @value: data to write into the register 83 * 84 * The posted mode bit is encoded in reg. Note that in posted mode the write 85 * pending bit must be checked. Otherwise a write on a register which has a 86 * pending write will be lost. 87 */ 88 static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg, 89 u32 value) 90 { 91 WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET); 92 __omap_dm_timer_write(timer, reg, value, timer->posted); 93 } 94 95 static void omap_timer_restore_context(struct omap_dm_timer *timer) 96 { 97 omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, 98 timer->context.twer); 99 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, 100 timer->context.tcrr); 101 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, 102 timer->context.tldr); 103 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, 104 timer->context.tmar); 105 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 106 timer->context.tsicr); 107 writel_relaxed(timer->context.tier, timer->irq_ena); 108 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, 109 timer->context.tclr); 110 } 111 112 static int omap_dm_timer_reset(struct omap_dm_timer *timer) 113 { 114 u32 l, timeout = 100000; 115 116 if (timer->revision != 1) 117 return -EINVAL; 118 119 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); 120 121 do { 122 l = __omap_dm_timer_read(timer, 123 OMAP_TIMER_V1_SYS_STAT_OFFSET, 0); 124 } while (!l && timeout--); 125 126 if (!timeout) { 127 dev_err(&timer->pdev->dev, "Timer failed to reset\n"); 128 return -ETIMEDOUT; 129 } 130 131 /* Configure timer for smart-idle mode */ 132 l = __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0); 133 l |= 0x2 << 0x3; 134 __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, l, 0); 135 136 timer->posted = 0; 137 138 return 0; 139 } 140 141 static int omap_dm_timer_of_set_source(struct omap_dm_timer *timer) 142 { 143 int ret; 144 struct clk *parent; 145 146 /* 147 * FIXME: OMAP1 devices do not use the clock framework for dmtimers so 148 * do not call clk_get() for these devices. 149 */ 150 if (!timer->fclk) 151 return -ENODEV; 152 153 parent = clk_get(&timer->pdev->dev, NULL); 154 if (IS_ERR(parent)) 155 return -ENODEV; 156 157 /* Bail out if both clocks point to fck */ 158 if (clk_is_match(parent, timer->fclk)) 159 return 0; 160 161 ret = clk_set_parent(timer->fclk, parent); 162 if (ret < 0) 163 pr_err("%s: failed to set parent\n", __func__); 164 165 clk_put(parent); 166 167 return ret; 168 } 169 170 static int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) 171 { 172 int ret; 173 const char *parent_name; 174 struct clk *parent; 175 struct dmtimer_platform_data *pdata; 176 177 if (unlikely(!timer) || IS_ERR(timer->fclk)) 178 return -EINVAL; 179 180 switch (source) { 181 case OMAP_TIMER_SRC_SYS_CLK: 182 parent_name = "timer_sys_ck"; 183 break; 184 case OMAP_TIMER_SRC_32_KHZ: 185 parent_name = "timer_32k_ck"; 186 break; 187 case OMAP_TIMER_SRC_EXT_CLK: 188 parent_name = "timer_ext_ck"; 189 break; 190 default: 191 return -EINVAL; 192 } 193 194 pdata = timer->pdev->dev.platform_data; 195 196 /* 197 * FIXME: Used for OMAP1 devices only because they do not currently 198 * use the clock framework to set the parent clock. To be removed 199 * once OMAP1 migrated to using clock framework for dmtimers 200 */ 201 if (pdata && pdata->set_timer_src) 202 return pdata->set_timer_src(timer->pdev, source); 203 204 #if defined(CONFIG_COMMON_CLK) 205 /* Check if the clock has configurable parents */ 206 if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2) 207 return 0; 208 #endif 209 210 parent = clk_get(&timer->pdev->dev, parent_name); 211 if (IS_ERR(parent)) { 212 pr_err("%s: %s not found\n", __func__, parent_name); 213 return -EINVAL; 214 } 215 216 ret = clk_set_parent(timer->fclk, parent); 217 if (ret < 0) 218 pr_err("%s: failed to set %s as parent\n", __func__, 219 parent_name); 220 221 clk_put(parent); 222 223 return ret; 224 } 225 226 static void omap_dm_timer_enable(struct omap_dm_timer *timer) 227 { 228 int c; 229 230 pm_runtime_get_sync(&timer->pdev->dev); 231 232 if (!(timer->capability & OMAP_TIMER_ALWON)) { 233 if (timer->get_context_loss_count) { 234 c = timer->get_context_loss_count(&timer->pdev->dev); 235 if (c != timer->ctx_loss_count) { 236 omap_timer_restore_context(timer); 237 timer->ctx_loss_count = c; 238 } 239 } else { 240 omap_timer_restore_context(timer); 241 } 242 } 243 } 244 245 static void omap_dm_timer_disable(struct omap_dm_timer *timer) 246 { 247 pm_runtime_put_sync(&timer->pdev->dev); 248 } 249 250 static int omap_dm_timer_prepare(struct omap_dm_timer *timer) 251 { 252 int rc; 253 254 /* 255 * FIXME: OMAP1 devices do not use the clock framework for dmtimers so 256 * do not call clk_get() for these devices. 257 */ 258 if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) { 259 timer->fclk = clk_get(&timer->pdev->dev, "fck"); 260 if (WARN_ON_ONCE(IS_ERR(timer->fclk))) { 261 dev_err(&timer->pdev->dev, ": No fclk handle.\n"); 262 return -EINVAL; 263 } 264 } 265 266 omap_dm_timer_enable(timer); 267 268 if (timer->capability & OMAP_TIMER_NEEDS_RESET) { 269 rc = omap_dm_timer_reset(timer); 270 if (rc) { 271 omap_dm_timer_disable(timer); 272 return rc; 273 } 274 } 275 276 __omap_dm_timer_enable_posted(timer); 277 omap_dm_timer_disable(timer); 278 279 rc = omap_dm_timer_of_set_source(timer); 280 if (rc == -ENODEV) 281 return omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ); 282 283 return rc; 284 } 285 286 static inline u32 omap_dm_timer_reserved_systimer(int id) 287 { 288 return (omap_reserved_systimers & (1 << (id - 1))) ? 1 : 0; 289 } 290 291 int omap_dm_timer_reserve_systimer(int id) 292 { 293 if (omap_dm_timer_reserved_systimer(id)) 294 return -ENODEV; 295 296 omap_reserved_systimers |= (1 << (id - 1)); 297 298 return 0; 299 } 300 301 static struct omap_dm_timer *_omap_dm_timer_request(int req_type, void *data) 302 { 303 struct omap_dm_timer *timer = NULL, *t; 304 struct device_node *np = NULL; 305 unsigned long flags; 306 u32 cap = 0; 307 int id = 0; 308 309 switch (req_type) { 310 case REQUEST_BY_ID: 311 id = *(int *)data; 312 break; 313 case REQUEST_BY_CAP: 314 cap = *(u32 *)data; 315 break; 316 case REQUEST_BY_NODE: 317 np = (struct device_node *)data; 318 break; 319 default: 320 /* REQUEST_ANY */ 321 break; 322 } 323 324 spin_lock_irqsave(&dm_timer_lock, flags); 325 list_for_each_entry(t, &omap_timer_list, node) { 326 if (t->reserved) 327 continue; 328 329 switch (req_type) { 330 case REQUEST_BY_ID: 331 if (id == t->pdev->id) { 332 timer = t; 333 timer->reserved = 1; 334 goto found; 335 } 336 break; 337 case REQUEST_BY_CAP: 338 if (cap == (t->capability & cap)) { 339 /* 340 * If timer is not NULL, we have already found 341 * one timer. But it was not an exact match 342 * because it had more capabilities than what 343 * was required. Therefore, unreserve the last 344 * timer found and see if this one is a better 345 * match. 346 */ 347 if (timer) 348 timer->reserved = 0; 349 timer = t; 350 timer->reserved = 1; 351 352 /* Exit loop early if we find an exact match */ 353 if (t->capability == cap) 354 goto found; 355 } 356 break; 357 case REQUEST_BY_NODE: 358 if (np == t->pdev->dev.of_node) { 359 timer = t; 360 timer->reserved = 1; 361 goto found; 362 } 363 break; 364 default: 365 /* REQUEST_ANY */ 366 timer = t; 367 timer->reserved = 1; 368 goto found; 369 } 370 } 371 found: 372 spin_unlock_irqrestore(&dm_timer_lock, flags); 373 374 if (timer && omap_dm_timer_prepare(timer)) { 375 timer->reserved = 0; 376 timer = NULL; 377 } 378 379 if (!timer) 380 pr_debug("%s: timer request failed!\n", __func__); 381 382 return timer; 383 } 384 385 static struct omap_dm_timer *omap_dm_timer_request(void) 386 { 387 return _omap_dm_timer_request(REQUEST_ANY, NULL); 388 } 389 390 static struct omap_dm_timer *omap_dm_timer_request_specific(int id) 391 { 392 /* Requesting timer by ID is not supported when device tree is used */ 393 if (of_have_populated_dt()) { 394 pr_warn("%s: Please use omap_dm_timer_request_by_node()\n", 395 __func__); 396 return NULL; 397 } 398 399 return _omap_dm_timer_request(REQUEST_BY_ID, &id); 400 } 401 402 /** 403 * omap_dm_timer_request_by_cap - Request a timer by capability 404 * @cap: Bit mask of capabilities to match 405 * 406 * Find a timer based upon capabilities bit mask. Callers of this function 407 * should use the definitions found in the plat/dmtimer.h file under the 408 * comment "timer capabilities used in hwmod database". Returns pointer to 409 * timer handle on success and a NULL pointer on failure. 410 */ 411 struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap) 412 { 413 return _omap_dm_timer_request(REQUEST_BY_CAP, &cap); 414 } 415 416 /** 417 * omap_dm_timer_request_by_node - Request a timer by device-tree node 418 * @np: Pointer to device-tree timer node 419 * 420 * Request a timer based upon a device node pointer. Returns pointer to 421 * timer handle on success and a NULL pointer on failure. 422 */ 423 static struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np) 424 { 425 if (!np) 426 return NULL; 427 428 return _omap_dm_timer_request(REQUEST_BY_NODE, np); 429 } 430 431 static int omap_dm_timer_free(struct omap_dm_timer *timer) 432 { 433 if (unlikely(!timer)) 434 return -EINVAL; 435 436 clk_put(timer->fclk); 437 438 WARN_ON(!timer->reserved); 439 timer->reserved = 0; 440 return 0; 441 } 442 443 int omap_dm_timer_get_irq(struct omap_dm_timer *timer) 444 { 445 if (timer) 446 return timer->irq; 447 return -EINVAL; 448 } 449 450 #if defined(CONFIG_ARCH_OMAP1) 451 #include <mach/hardware.h> 452 453 static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) 454 { 455 return NULL; 456 } 457 458 /** 459 * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR 460 * @inputmask: current value of idlect mask 461 */ 462 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) 463 { 464 int i = 0; 465 struct omap_dm_timer *timer = NULL; 466 unsigned long flags; 467 468 /* If ARMXOR cannot be idled this function call is unnecessary */ 469 if (!(inputmask & (1 << 1))) 470 return inputmask; 471 472 /* If any active timer is using ARMXOR return modified mask */ 473 spin_lock_irqsave(&dm_timer_lock, flags); 474 list_for_each_entry(timer, &omap_timer_list, node) { 475 u32 l; 476 477 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 478 if (l & OMAP_TIMER_CTRL_ST) { 479 if (((omap_readl(MOD_CONF_CTRL_1) >> (i * 2)) & 0x03) == 0) 480 inputmask &= ~(1 << 1); 481 else 482 inputmask &= ~(1 << 2); 483 } 484 i++; 485 } 486 spin_unlock_irqrestore(&dm_timer_lock, flags); 487 488 return inputmask; 489 } 490 491 #else 492 493 static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) 494 { 495 if (timer && !IS_ERR(timer->fclk)) 496 return timer->fclk; 497 return NULL; 498 } 499 500 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) 501 { 502 BUG(); 503 504 return 0; 505 } 506 507 #endif 508 509 int omap_dm_timer_trigger(struct omap_dm_timer *timer) 510 { 511 if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) { 512 pr_err("%s: timer not available or enabled.\n", __func__); 513 return -EINVAL; 514 } 515 516 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0); 517 return 0; 518 } 519 520 static int omap_dm_timer_start(struct omap_dm_timer *timer) 521 { 522 u32 l; 523 524 if (unlikely(!timer)) 525 return -EINVAL; 526 527 omap_dm_timer_enable(timer); 528 529 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 530 if (!(l & OMAP_TIMER_CTRL_ST)) { 531 l |= OMAP_TIMER_CTRL_ST; 532 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 533 } 534 535 /* Save the context */ 536 timer->context.tclr = l; 537 return 0; 538 } 539 540 static int omap_dm_timer_stop(struct omap_dm_timer *timer) 541 { 542 unsigned long rate = 0; 543 544 if (unlikely(!timer)) 545 return -EINVAL; 546 547 if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) 548 rate = clk_get_rate(timer->fclk); 549 550 __omap_dm_timer_stop(timer, timer->posted, rate); 551 552 /* 553 * Since the register values are computed and written within 554 * __omap_dm_timer_stop, we need to use read to retrieve the 555 * context. 556 */ 557 timer->context.tclr = 558 omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 559 omap_dm_timer_disable(timer); 560 return 0; 561 } 562 563 static int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, 564 unsigned int load) 565 { 566 u32 l; 567 568 if (unlikely(!timer)) 569 return -EINVAL; 570 571 omap_dm_timer_enable(timer); 572 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 573 if (autoreload) 574 l |= OMAP_TIMER_CTRL_AR; 575 else 576 l &= ~OMAP_TIMER_CTRL_AR; 577 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 578 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load); 579 580 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0); 581 /* Save the context */ 582 timer->context.tclr = l; 583 timer->context.tldr = load; 584 omap_dm_timer_disable(timer); 585 return 0; 586 } 587 588 /* Optimized set_load which removes costly spin wait in timer_start */ 589 static int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, 590 int autoreload, unsigned int load) 591 { 592 u32 l; 593 594 if (unlikely(!timer)) 595 return -EINVAL; 596 597 omap_dm_timer_enable(timer); 598 599 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 600 if (autoreload) { 601 l |= OMAP_TIMER_CTRL_AR; 602 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load); 603 } else { 604 l &= ~OMAP_TIMER_CTRL_AR; 605 } 606 l |= OMAP_TIMER_CTRL_ST; 607 608 __omap_dm_timer_load_start(timer, l, load, timer->posted); 609 610 /* Save the context */ 611 timer->context.tclr = l; 612 timer->context.tldr = load; 613 timer->context.tcrr = load; 614 return 0; 615 } 616 static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, 617 unsigned int match) 618 { 619 u32 l; 620 621 if (unlikely(!timer)) 622 return -EINVAL; 623 624 omap_dm_timer_enable(timer); 625 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 626 if (enable) 627 l |= OMAP_TIMER_CTRL_CE; 628 else 629 l &= ~OMAP_TIMER_CTRL_CE; 630 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match); 631 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 632 633 /* Save the context */ 634 timer->context.tclr = l; 635 timer->context.tmar = match; 636 omap_dm_timer_disable(timer); 637 return 0; 638 } 639 640 static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, 641 int toggle, int trigger) 642 { 643 u32 l; 644 645 if (unlikely(!timer)) 646 return -EINVAL; 647 648 omap_dm_timer_enable(timer); 649 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 650 l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM | 651 OMAP_TIMER_CTRL_PT | (0x03 << 10)); 652 if (def_on) 653 l |= OMAP_TIMER_CTRL_SCPWM; 654 if (toggle) 655 l |= OMAP_TIMER_CTRL_PT; 656 l |= trigger << 10; 657 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 658 659 /* Save the context */ 660 timer->context.tclr = l; 661 omap_dm_timer_disable(timer); 662 return 0; 663 } 664 665 static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, 666 int prescaler) 667 { 668 u32 l; 669 670 if (unlikely(!timer) || prescaler < -1 || prescaler > 7) 671 return -EINVAL; 672 673 omap_dm_timer_enable(timer); 674 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 675 l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2)); 676 if (prescaler >= 0) { 677 l |= OMAP_TIMER_CTRL_PRE; 678 l |= prescaler << 2; 679 } 680 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 681 682 /* Save the context */ 683 timer->context.tclr = l; 684 omap_dm_timer_disable(timer); 685 return 0; 686 } 687 688 static int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, 689 unsigned int value) 690 { 691 if (unlikely(!timer)) 692 return -EINVAL; 693 694 omap_dm_timer_enable(timer); 695 __omap_dm_timer_int_enable(timer, value); 696 697 /* Save the context */ 698 timer->context.tier = value; 699 timer->context.twer = value; 700 omap_dm_timer_disable(timer); 701 return 0; 702 } 703 704 /** 705 * omap_dm_timer_set_int_disable - disable timer interrupts 706 * @timer: pointer to timer handle 707 * @mask: bit mask of interrupts to be disabled 708 * 709 * Disables the specified timer interrupts for a timer. 710 */ 711 static int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask) 712 { 713 u32 l = mask; 714 715 if (unlikely(!timer)) 716 return -EINVAL; 717 718 omap_dm_timer_enable(timer); 719 720 if (timer->revision == 1) 721 l = readl_relaxed(timer->irq_ena) & ~mask; 722 723 writel_relaxed(l, timer->irq_dis); 724 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG) & ~mask; 725 omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, l); 726 727 /* Save the context */ 728 timer->context.tier &= ~mask; 729 timer->context.twer &= ~mask; 730 omap_dm_timer_disable(timer); 731 return 0; 732 } 733 734 static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) 735 { 736 unsigned int l; 737 738 if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) { 739 pr_err("%s: timer not available or enabled.\n", __func__); 740 return 0; 741 } 742 743 l = readl_relaxed(timer->irq_stat); 744 745 return l; 746 } 747 748 static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) 749 { 750 if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) 751 return -EINVAL; 752 753 __omap_dm_timer_write_status(timer, value); 754 755 return 0; 756 } 757 758 static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) 759 { 760 if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) { 761 pr_err("%s: timer not iavailable or enabled.\n", __func__); 762 return 0; 763 } 764 765 return __omap_dm_timer_read_counter(timer, timer->posted); 766 } 767 768 static int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) 769 { 770 if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) { 771 pr_err("%s: timer not available or enabled.\n", __func__); 772 return -EINVAL; 773 } 774 775 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value); 776 777 /* Save the context */ 778 timer->context.tcrr = value; 779 return 0; 780 } 781 782 int omap_dm_timers_active(void) 783 { 784 struct omap_dm_timer *timer; 785 786 list_for_each_entry(timer, &omap_timer_list, node) { 787 if (!timer->reserved) 788 continue; 789 790 if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) & 791 OMAP_TIMER_CTRL_ST) { 792 return 1; 793 } 794 } 795 return 0; 796 } 797 798 static const struct of_device_id omap_timer_match[]; 799 800 /** 801 * omap_dm_timer_probe - probe function called for every registered device 802 * @pdev: pointer to current timer platform device 803 * 804 * Called by driver framework at the end of device registration for all 805 * timer devices. 806 */ 807 static int omap_dm_timer_probe(struct platform_device *pdev) 808 { 809 unsigned long flags; 810 struct omap_dm_timer *timer; 811 struct resource *mem, *irq; 812 struct device *dev = &pdev->dev; 813 const struct dmtimer_platform_data *pdata; 814 int ret; 815 816 pdata = of_device_get_match_data(dev); 817 if (!pdata) 818 pdata = dev_get_platdata(dev); 819 else 820 dev->platform_data = (void *)pdata; 821 822 if (!pdata) { 823 dev_err(dev, "%s: no platform data.\n", __func__); 824 return -ENODEV; 825 } 826 827 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 828 if (unlikely(!irq)) { 829 dev_err(dev, "%s: no IRQ resource.\n", __func__); 830 return -ENODEV; 831 } 832 833 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 834 if (unlikely(!mem)) { 835 dev_err(dev, "%s: no memory resource.\n", __func__); 836 return -ENODEV; 837 } 838 839 timer = devm_kzalloc(dev, sizeof(*timer), GFP_KERNEL); 840 if (!timer) 841 return -ENOMEM; 842 843 timer->fclk = ERR_PTR(-ENODEV); 844 timer->io_base = devm_ioremap_resource(dev, mem); 845 if (IS_ERR(timer->io_base)) 846 return PTR_ERR(timer->io_base); 847 848 if (dev->of_node) { 849 if (of_find_property(dev->of_node, "ti,timer-alwon", NULL)) 850 timer->capability |= OMAP_TIMER_ALWON; 851 if (of_find_property(dev->of_node, "ti,timer-dsp", NULL)) 852 timer->capability |= OMAP_TIMER_HAS_DSP_IRQ; 853 if (of_find_property(dev->of_node, "ti,timer-pwm", NULL)) 854 timer->capability |= OMAP_TIMER_HAS_PWM; 855 if (of_find_property(dev->of_node, "ti,timer-secure", NULL)) 856 timer->capability |= OMAP_TIMER_SECURE; 857 } else { 858 timer->id = pdev->id; 859 timer->capability = pdata->timer_capability; 860 timer->reserved = omap_dm_timer_reserved_systimer(timer->id); 861 timer->get_context_loss_count = pdata->get_context_loss_count; 862 } 863 864 if (pdata) 865 timer->errata = pdata->timer_errata; 866 867 timer->irq = irq->start; 868 timer->pdev = pdev; 869 870 pm_runtime_enable(dev); 871 872 if (!timer->reserved) { 873 ret = pm_runtime_get_sync(dev); 874 if (ret < 0) { 875 dev_err(dev, "%s: pm_runtime_get_sync failed!\n", 876 __func__); 877 goto err_get_sync; 878 } 879 __omap_dm_timer_init_regs(timer); 880 pm_runtime_put(dev); 881 } 882 883 /* add the timer element to the list */ 884 spin_lock_irqsave(&dm_timer_lock, flags); 885 list_add_tail(&timer->node, &omap_timer_list); 886 spin_unlock_irqrestore(&dm_timer_lock, flags); 887 888 dev_dbg(dev, "Device Probed.\n"); 889 890 return 0; 891 892 err_get_sync: 893 pm_runtime_put_noidle(dev); 894 pm_runtime_disable(dev); 895 return ret; 896 } 897 898 /** 899 * omap_dm_timer_remove - cleanup a registered timer device 900 * @pdev: pointer to current timer platform device 901 * 902 * Called by driver framework whenever a timer device is unregistered. 903 * In addition to freeing platform resources it also deletes the timer 904 * entry from the local list. 905 */ 906 static int omap_dm_timer_remove(struct platform_device *pdev) 907 { 908 struct omap_dm_timer *timer; 909 unsigned long flags; 910 int ret = -EINVAL; 911 912 spin_lock_irqsave(&dm_timer_lock, flags); 913 list_for_each_entry(timer, &omap_timer_list, node) 914 if (!strcmp(dev_name(&timer->pdev->dev), 915 dev_name(&pdev->dev))) { 916 list_del(&timer->node); 917 ret = 0; 918 break; 919 } 920 spin_unlock_irqrestore(&dm_timer_lock, flags); 921 922 pm_runtime_disable(&pdev->dev); 923 924 return ret; 925 } 926 927 const static struct omap_dm_timer_ops dmtimer_ops = { 928 .request_by_node = omap_dm_timer_request_by_node, 929 .request_specific = omap_dm_timer_request_specific, 930 .request = omap_dm_timer_request, 931 .set_source = omap_dm_timer_set_source, 932 .get_irq = omap_dm_timer_get_irq, 933 .set_int_enable = omap_dm_timer_set_int_enable, 934 .set_int_disable = omap_dm_timer_set_int_disable, 935 .free = omap_dm_timer_free, 936 .enable = omap_dm_timer_enable, 937 .disable = omap_dm_timer_disable, 938 .get_fclk = omap_dm_timer_get_fclk, 939 .start = omap_dm_timer_start, 940 .stop = omap_dm_timer_stop, 941 .set_load = omap_dm_timer_set_load, 942 .set_match = omap_dm_timer_set_match, 943 .set_pwm = omap_dm_timer_set_pwm, 944 .set_prescaler = omap_dm_timer_set_prescaler, 945 .read_counter = omap_dm_timer_read_counter, 946 .write_counter = omap_dm_timer_write_counter, 947 .read_status = omap_dm_timer_read_status, 948 .write_status = omap_dm_timer_write_status, 949 }; 950 951 static const struct dmtimer_platform_data omap3plus_pdata = { 952 .timer_errata = OMAP_TIMER_ERRATA_I103_I767, 953 .timer_ops = &dmtimer_ops, 954 }; 955 956 static const struct of_device_id omap_timer_match[] = { 957 { 958 .compatible = "ti,omap2420-timer", 959 }, 960 { 961 .compatible = "ti,omap3430-timer", 962 .data = &omap3plus_pdata, 963 }, 964 { 965 .compatible = "ti,omap4430-timer", 966 .data = &omap3plus_pdata, 967 }, 968 { 969 .compatible = "ti,omap5430-timer", 970 .data = &omap3plus_pdata, 971 }, 972 { 973 .compatible = "ti,am335x-timer", 974 .data = &omap3plus_pdata, 975 }, 976 { 977 .compatible = "ti,am335x-timer-1ms", 978 .data = &omap3plus_pdata, 979 }, 980 { 981 .compatible = "ti,dm816-timer", 982 .data = &omap3plus_pdata, 983 }, 984 {}, 985 }; 986 MODULE_DEVICE_TABLE(of, omap_timer_match); 987 988 static struct platform_driver omap_dm_timer_driver = { 989 .probe = omap_dm_timer_probe, 990 .remove = omap_dm_timer_remove, 991 .driver = { 992 .name = "omap_timer", 993 .of_match_table = of_match_ptr(omap_timer_match), 994 }, 995 }; 996 997 module_platform_driver(omap_dm_timer_driver); 998 999 MODULE_DESCRIPTION("OMAP Dual-Mode Timer Driver"); 1000 MODULE_LICENSE("GPL"); 1001 MODULE_ALIAS("platform:" DRIVER_NAME); 1002 MODULE_AUTHOR("Texas Instruments Inc"); 1003