clockdomain.c (59fb659b065f52fcc2deed293cfbfc58f890376c) | clockdomain.c (c4d7e58fb52c632d8e33cd23a4917d7a7f8302ac) |
---|---|
1/* 2 * OMAP2/3/4 clockdomain framework functions 3 * 4 * Copyright (C) 2008-2010 Texas Instruments, Inc. 5 * Copyright (C) 2008-2010 Nokia Corporation 6 * 7 * Written by Paul Walmsley and Jouni Högander 8 * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14#undef DEBUG 15 | 1/* 2 * OMAP2/3/4 clockdomain framework functions 3 * 4 * Copyright (C) 2008-2010 Texas Instruments, Inc. 5 * Copyright (C) 2008-2010 Nokia Corporation 6 * 7 * Written by Paul Walmsley and Jouni Högander 8 * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14#undef DEBUG 15 |
16#include <linux/module.h> | |
17#include <linux/kernel.h> 18#include <linux/device.h> 19#include <linux/list.h> 20#include <linux/errno.h> 21#include <linux/delay.h> 22#include <linux/clk.h> 23#include <linux/limits.h> 24#include <linux/err.h> 25 26#include <linux/io.h> 27 28#include <linux/bitops.h> 29 30#include "prm2xxx_3xxx.h" 31#include "prm-regbits-24xx.h" 32#include "cm2xxx_3xxx.h" | 16#include <linux/kernel.h> 17#include <linux/device.h> 18#include <linux/list.h> 19#include <linux/errno.h> 20#include <linux/delay.h> 21#include <linux/clk.h> 22#include <linux/limits.h> 23#include <linux/err.h> 24 25#include <linux/io.h> 26 27#include <linux/bitops.h> 28 29#include "prm2xxx_3xxx.h" 30#include "prm-regbits-24xx.h" 31#include "cm2xxx_3xxx.h" |
33#include "cm2xxx_3xxx.h" | |
34 35#include <plat/clock.h> 36#include <plat/powerdomain.h> 37#include <plat/clockdomain.h> 38#include <plat/prcm.h> 39 40/* clkdm_list contains all registered struct clockdomains */ 41static LIST_HEAD(clkdm_list); --- 363 unchanged lines hidden (view full) --- 405 "%s when %s wakes up\n", clkdm1->name, clkdm2->name); 406 return PTR_ERR(cd); 407 } 408 409 if (atomic_inc_return(&cd->wkdep_usecount) == 1) { 410 pr_debug("clockdomain: hardware will wake up %s when %s wakes " 411 "up\n", clkdm1->name, clkdm2->name); 412 | 32 33#include <plat/clock.h> 34#include <plat/powerdomain.h> 35#include <plat/clockdomain.h> 36#include <plat/prcm.h> 37 38/* clkdm_list contains all registered struct clockdomains */ 39static LIST_HEAD(clkdm_list); --- 363 unchanged lines hidden (view full) --- 403 "%s when %s wakes up\n", clkdm1->name, clkdm2->name); 404 return PTR_ERR(cd); 405 } 406 407 if (atomic_inc_return(&cd->wkdep_usecount) == 1) { 408 pr_debug("clockdomain: hardware will wake up %s when %s wakes " 409 "up\n", clkdm1->name, clkdm2->name); 410 |
413 prm_set_mod_reg_bits((1 << clkdm2->dep_bit), | 411 omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit), |
414 clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP); 415 } 416 417 return 0; 418} 419 420/** 421 * clkdm_del_wkdep - remove a wakeup dependency from clkdm2 to clkdm1 --- 18 unchanged lines hidden (view full) --- 440 "%s when %s wakes up\n", clkdm1->name, clkdm2->name); 441 return PTR_ERR(cd); 442 } 443 444 if (atomic_dec_return(&cd->wkdep_usecount) == 0) { 445 pr_debug("clockdomain: hardware will no longer wake up %s " 446 "after %s wakes up\n", clkdm1->name, clkdm2->name); 447 | 412 clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP); 413 } 414 415 return 0; 416} 417 418/** 419 * clkdm_del_wkdep - remove a wakeup dependency from clkdm2 to clkdm1 --- 18 unchanged lines hidden (view full) --- 438 "%s when %s wakes up\n", clkdm1->name, clkdm2->name); 439 return PTR_ERR(cd); 440 } 441 442 if (atomic_dec_return(&cd->wkdep_usecount) == 0) { 443 pr_debug("clockdomain: hardware will no longer wake up %s " 444 "after %s wakes up\n", clkdm1->name, clkdm2->name); 445 |
448 prm_clear_mod_reg_bits((1 << clkdm2->dep_bit), | 446 omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit), |
449 clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP); 450 } 451 452 return 0; 453} 454 455/** 456 * clkdm_read_wkdep - read wakeup dependency state from clkdm2 to clkdm1 --- 19 unchanged lines hidden (view full) --- 476 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); 477 if (IS_ERR(cd)) { 478 pr_debug("clockdomain: hardware cannot set/clear wake up of " 479 "%s when %s wakes up\n", clkdm1->name, clkdm2->name); 480 return PTR_ERR(cd); 481 } 482 483 /* XXX It's faster to return the atomic wkdep_usecount */ | 447 clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP); 448 } 449 450 return 0; 451} 452 453/** 454 * clkdm_read_wkdep - read wakeup dependency state from clkdm2 to clkdm1 --- 19 unchanged lines hidden (view full) --- 474 cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); 475 if (IS_ERR(cd)) { 476 pr_debug("clockdomain: hardware cannot set/clear wake up of " 477 "%s when %s wakes up\n", clkdm1->name, clkdm2->name); 478 return PTR_ERR(cd); 479 } 480 481 /* XXX It's faster to return the atomic wkdep_usecount */ |
484 return prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP, | 482 return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP, |
485 (1 << clkdm2->dep_bit)); 486} 487 488/** 489 * clkdm_clear_all_wkdeps - remove all wakeup dependencies from target clkdm 490 * @clkdm: struct clockdomain * to remove all wakeup dependencies from 491 * 492 * Remove all inter-clockdomain wakeup dependencies that could cause --- 17 unchanged lines hidden (view full) --- 510 if (!cd->clkdm && cd->clkdm_name) 511 cd->clkdm = _clkdm_lookup(cd->clkdm_name); 512 513 /* PRM accesses are slow, so minimize them */ 514 mask |= 1 << cd->clkdm->dep_bit; 515 atomic_set(&cd->wkdep_usecount, 0); 516 } 517 | 483 (1 << clkdm2->dep_bit)); 484} 485 486/** 487 * clkdm_clear_all_wkdeps - remove all wakeup dependencies from target clkdm 488 * @clkdm: struct clockdomain * to remove all wakeup dependencies from 489 * 490 * Remove all inter-clockdomain wakeup dependencies that could cause --- 17 unchanged lines hidden (view full) --- 508 if (!cd->clkdm && cd->clkdm_name) 509 cd->clkdm = _clkdm_lookup(cd->clkdm_name); 510 511 /* PRM accesses are slow, so minimize them */ 512 mask |= 1 << cd->clkdm->dep_bit; 513 atomic_set(&cd->wkdep_usecount, 0); 514 } 515 |
518 prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, PM_WKDEP); | 516 omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, PM_WKDEP); |
519 520 return 0; 521} 522 523/** 524 * clkdm_add_sleepdep - add a sleep dependency from clkdm2 to clkdm1 525 * @clkdm1: prevent this struct clockdomain * from sleeping (dependent) 526 * @clkdm2: when this struct clockdomain * is active (source) --- 22 unchanged lines hidden (view full) --- 549 clkdm2->name); 550 return PTR_ERR(cd); 551 } 552 553 if (atomic_inc_return(&cd->sleepdep_usecount) == 1) { 554 pr_debug("clockdomain: will prevent %s from sleeping if %s " 555 "is active\n", clkdm1->name, clkdm2->name); 556 | 517 518 return 0; 519} 520 521/** 522 * clkdm_add_sleepdep - add a sleep dependency from clkdm2 to clkdm1 523 * @clkdm1: prevent this struct clockdomain * from sleeping (dependent) 524 * @clkdm2: when this struct clockdomain * is active (source) --- 22 unchanged lines hidden (view full) --- 547 clkdm2->name); 548 return PTR_ERR(cd); 549 } 550 551 if (atomic_inc_return(&cd->sleepdep_usecount) == 1) { 552 pr_debug("clockdomain: will prevent %s from sleeping if %s " 553 "is active\n", clkdm1->name, clkdm2->name); 554 |
557 cm_set_mod_reg_bits((1 << clkdm2->dep_bit), | 555 omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit), |
558 clkdm1->pwrdm.ptr->prcm_offs, 559 OMAP3430_CM_SLEEPDEP); 560 } 561 562 return 0; 563} 564 565/** --- 26 unchanged lines hidden (view full) --- 592 return PTR_ERR(cd); 593 } 594 595 if (atomic_dec_return(&cd->sleepdep_usecount) == 0) { 596 pr_debug("clockdomain: will no longer prevent %s from " 597 "sleeping if %s is active\n", clkdm1->name, 598 clkdm2->name); 599 | 556 clkdm1->pwrdm.ptr->prcm_offs, 557 OMAP3430_CM_SLEEPDEP); 558 } 559 560 return 0; 561} 562 563/** --- 26 unchanged lines hidden (view full) --- 590 return PTR_ERR(cd); 591 } 592 593 if (atomic_dec_return(&cd->sleepdep_usecount) == 0) { 594 pr_debug("clockdomain: will no longer prevent %s from " 595 "sleeping if %s is active\n", clkdm1->name, 596 clkdm2->name); 597 |
600 cm_clear_mod_reg_bits((1 << clkdm2->dep_bit), | 598 omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit), |
601 clkdm1->pwrdm.ptr->prcm_offs, 602 OMAP3430_CM_SLEEPDEP); 603 } 604 605 return 0; 606} 607 608/** --- 26 unchanged lines hidden (view full) --- 635 if (IS_ERR(cd)) { 636 pr_debug("clockdomain: hardware cannot set/clear sleep " 637 "dependency affecting %s from %s\n", clkdm1->name, 638 clkdm2->name); 639 return PTR_ERR(cd); 640 } 641 642 /* XXX It's faster to return the atomic sleepdep_usecount */ | 599 clkdm1->pwrdm.ptr->prcm_offs, 600 OMAP3430_CM_SLEEPDEP); 601 } 602 603 return 0; 604} 605 606/** --- 26 unchanged lines hidden (view full) --- 633 if (IS_ERR(cd)) { 634 pr_debug("clockdomain: hardware cannot set/clear sleep " 635 "dependency affecting %s from %s\n", clkdm1->name, 636 clkdm2->name); 637 return PTR_ERR(cd); 638 } 639 640 /* XXX It's faster to return the atomic sleepdep_usecount */ |
643 return prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, | 641 return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, |
644 OMAP3430_CM_SLEEPDEP, 645 (1 << clkdm2->dep_bit)); 646} 647 648/** 649 * clkdm_clear_all_sleepdeps - remove all sleep dependencies from target clkdm 650 * @clkdm: struct clockdomain * to remove all sleep dependencies from 651 * --- 21 unchanged lines hidden (view full) --- 673 if (!cd->clkdm && cd->clkdm_name) 674 cd->clkdm = _clkdm_lookup(cd->clkdm_name); 675 676 /* PRM accesses are slow, so minimize them */ 677 mask |= 1 << cd->clkdm->dep_bit; 678 atomic_set(&cd->sleepdep_usecount, 0); 679 } 680 | 642 OMAP3430_CM_SLEEPDEP, 643 (1 << clkdm2->dep_bit)); 644} 645 646/** 647 * clkdm_clear_all_sleepdeps - remove all sleep dependencies from target clkdm 648 * @clkdm: struct clockdomain * to remove all sleep dependencies from 649 * --- 21 unchanged lines hidden (view full) --- 671 if (!cd->clkdm && cd->clkdm_name) 672 cd->clkdm = _clkdm_lookup(cd->clkdm_name); 673 674 /* PRM accesses are slow, so minimize them */ 675 mask |= 1 << cd->clkdm->dep_bit; 676 atomic_set(&cd->sleepdep_usecount, 0); 677 } 678 |
681 prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, | 679 omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, |
682 OMAP3430_CM_SLEEPDEP); 683 684 return 0; 685} 686 687/** 688 * omap2_clkdm_clktrctrl_read - read the clkdm's current state transition mode 689 * @clkdm: struct clkdm * of a clockdomain --- 35 unchanged lines hidden (view full) --- 725 "sleep via software\n", clkdm->name); 726 return -EINVAL; 727 } 728 729 pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name); 730 731 if (cpu_is_omap24xx()) { 732 | 680 OMAP3430_CM_SLEEPDEP); 681 682 return 0; 683} 684 685/** 686 * omap2_clkdm_clktrctrl_read - read the clkdm's current state transition mode 687 * @clkdm: struct clkdm * of a clockdomain --- 35 unchanged lines hidden (view full) --- 723 "sleep via software\n", clkdm->name); 724 return -EINVAL; 725 } 726 727 pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name); 728 729 if (cpu_is_omap24xx()) { 730 |
733 cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, | 731 omap2_cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, |
734 clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL); 735 736 } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) { 737 738 u32 bits = (OMAP34XX_CLKSTCTRL_FORCE_SLEEP << 739 __ffs(clkdm->clktrctrl_mask)); 740 741 u32 v = __raw_readl(clkdm->clkstctrl_reg); --- 27 unchanged lines hidden (view full) --- 769 "wakeup via software\n", clkdm->name); 770 return -EINVAL; 771 } 772 773 pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name); 774 775 if (cpu_is_omap24xx()) { 776 | 732 clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL); 733 734 } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) { 735 736 u32 bits = (OMAP34XX_CLKSTCTRL_FORCE_SLEEP << 737 __ffs(clkdm->clktrctrl_mask)); 738 739 u32 v = __raw_readl(clkdm->clkstctrl_reg); --- 27 unchanged lines hidden (view full) --- 767 "wakeup via software\n", clkdm->name); 768 return -EINVAL; 769 } 770 771 pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name); 772 773 if (cpu_is_omap24xx()) { 774 |
777 cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, | 775 omap2_cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, |
778 clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL); 779 780 } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) { 781 782 u32 bits = (OMAP34XX_CLKSTCTRL_FORCE_WAKEUP << 783 __ffs(clkdm->clktrctrl_mask)); 784 785 u32 v = __raw_readl(clkdm->clkstctrl_reg); --- 209 unchanged lines hidden --- | 776 clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL); 777 778 } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) { 779 780 u32 bits = (OMAP34XX_CLKSTCTRL_FORCE_WAKEUP << 781 __ffs(clkdm->clktrctrl_mask)); 782 783 u32 v = __raw_readl(clkdm->clkstctrl_reg); --- 209 unchanged lines hidden --- |