diff options
| author | Vaibhav Hiremath <hvaibhav@ti.com> | 2012-09-11 19:18:53 -0400 |
|---|---|---|
| committer | Paul Walmsley <paul@pwsan.com> | 2012-09-11 19:18:53 -0400 |
| commit | 1688bf19b8daaa2eb4e861c33a6396ca85b890c3 (patch) | |
| tree | dfb32129f4f4e8f98340145f9e31073362f3a926 | |
| parent | 55d512e245bc7699a8800e23df1a24195dd08217 (diff) | |
ARM: OMAP2+: hwmod: Hook-up am33xx support in omap_hwmod framework
AM33XX PRCM architecture is different that any OMAP family
of devices, so it is required to have separate implementation
to handle AM33XX module enable/disable, reset assert/deassert
functionality.
This patch adds wrapper api's in omap_hwmod framework to
access prm/cm for AM33XX family of devices.
Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>
Cc: Tony Lindgren <tony@atomide.com>
[paul@pwsan.com: fixed checkpatch messages]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
| -rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 6ca8e519968d..948143890539 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
| @@ -149,8 +149,10 @@ | |||
| 149 | 149 | ||
| 150 | #include "cm2xxx_3xxx.h" | 150 | #include "cm2xxx_3xxx.h" |
| 151 | #include "cminst44xx.h" | 151 | #include "cminst44xx.h" |
| 152 | #include "cm33xx.h" | ||
| 152 | #include "prm2xxx_3xxx.h" | 153 | #include "prm2xxx_3xxx.h" |
| 153 | #include "prm44xx.h" | 154 | #include "prm44xx.h" |
| 155 | #include "prm33xx.h" | ||
| 154 | #include "prminst44xx.h" | 156 | #include "prminst44xx.h" |
| 155 | #include "mux.h" | 157 | #include "mux.h" |
| 156 | #include "pm.h" | 158 | #include "pm.h" |
| @@ -868,6 +870,26 @@ static void _omap4_enable_module(struct omap_hwmod *oh) | |||
| 868 | } | 870 | } |
| 869 | 871 | ||
| 870 | /** | 872 | /** |
| 873 | * _am33xx_enable_module - enable CLKCTRL modulemode on AM33XX | ||
| 874 | * @oh: struct omap_hwmod * | ||
| 875 | * | ||
| 876 | * Enables the PRCM module mode related to the hwmod @oh. | ||
| 877 | * No return value. | ||
| 878 | */ | ||
| 879 | static void _am33xx_enable_module(struct omap_hwmod *oh) | ||
| 880 | { | ||
| 881 | if (!oh->clkdm || !oh->prcm.omap4.modulemode) | ||
| 882 | return; | ||
| 883 | |||
| 884 | pr_debug("omap_hwmod: %s: %s: %d\n", | ||
| 885 | oh->name, __func__, oh->prcm.omap4.modulemode); | ||
| 886 | |||
| 887 | am33xx_cm_module_enable(oh->prcm.omap4.modulemode, oh->clkdm->cm_inst, | ||
| 888 | oh->clkdm->clkdm_offs, | ||
| 889 | oh->prcm.omap4.clkctrl_offs); | ||
| 890 | } | ||
| 891 | |||
| 892 | /** | ||
| 871 | * _omap4_wait_target_disable - wait for a module to be disabled on OMAP4 | 893 | * _omap4_wait_target_disable - wait for a module to be disabled on OMAP4 |
| 872 | * @oh: struct omap_hwmod * | 894 | * @oh: struct omap_hwmod * |
| 873 | * | 895 | * |
| @@ -894,6 +916,31 @@ static int _omap4_wait_target_disable(struct omap_hwmod *oh) | |||
| 894 | } | 916 | } |
| 895 | 917 | ||
| 896 | /** | 918 | /** |
| 919 | * _am33xx_wait_target_disable - wait for a module to be disabled on AM33XX | ||
| 920 | * @oh: struct omap_hwmod * | ||
| 921 | * | ||
| 922 | * Wait for a module @oh to enter slave idle. Returns 0 if the module | ||
| 923 | * does not have an IDLEST bit or if the module successfully enters | ||
| 924 | * slave idle; otherwise, pass along the return value of the | ||
| 925 | * appropriate *_cm*_wait_module_idle() function. | ||
| 926 | */ | ||
| 927 | static int _am33xx_wait_target_disable(struct omap_hwmod *oh) | ||
| 928 | { | ||
| 929 | if (!oh) | ||
| 930 | return -EINVAL; | ||
| 931 | |||
| 932 | if (oh->_int_flags & _HWMOD_NO_MPU_PORT) | ||
| 933 | return 0; | ||
| 934 | |||
| 935 | if (oh->flags & HWMOD_NO_IDLEST) | ||
| 936 | return 0; | ||
| 937 | |||
| 938 | return am33xx_cm_wait_module_idle(oh->clkdm->cm_inst, | ||
| 939 | oh->clkdm->clkdm_offs, | ||
| 940 | oh->prcm.omap4.clkctrl_offs); | ||
| 941 | } | ||
| 942 | |||
| 943 | /** | ||
| 897 | * _count_mpu_irqs - count the number of MPU IRQ lines associated with @oh | 944 | * _count_mpu_irqs - count the number of MPU IRQ lines associated with @oh |
| 898 | * @oh: struct omap_hwmod *oh | 945 | * @oh: struct omap_hwmod *oh |
| 899 | * | 946 | * |
| @@ -1614,6 +1661,36 @@ static int _omap4_disable_module(struct omap_hwmod *oh) | |||
| 1614 | } | 1661 | } |
| 1615 | 1662 | ||
| 1616 | /** | 1663 | /** |
| 1664 | * _am33xx_disable_module - enable CLKCTRL modulemode on AM33XX | ||
| 1665 | * @oh: struct omap_hwmod * | ||
| 1666 | * | ||
| 1667 | * Disable the PRCM module mode related to the hwmod @oh. | ||
| 1668 | * Return EINVAL if the modulemode is not supported and 0 in case of success. | ||
| 1669 | */ | ||
| 1670 | static int _am33xx_disable_module(struct omap_hwmod *oh) | ||
| 1671 | { | ||
| 1672 | int v; | ||
| 1673 | |||
| 1674 | if (!oh->clkdm || !oh->prcm.omap4.modulemode) | ||
| 1675 | return -EINVAL; | ||
| 1676 | |||
| 1677 | pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__); | ||
| 1678 | |||
| 1679 | am33xx_cm_module_disable(oh->clkdm->cm_inst, oh->clkdm->clkdm_offs, | ||
| 1680 | oh->prcm.omap4.clkctrl_offs); | ||
| 1681 | |||
| 1682 | if (_are_any_hardreset_lines_asserted(oh)) | ||
| 1683 | return 0; | ||
| 1684 | |||
| 1685 | v = _am33xx_wait_target_disable(oh); | ||
| 1686 | if (v) | ||
| 1687 | pr_warn("omap_hwmod: %s: _wait_target_disable failed\n", | ||
| 1688 | oh->name); | ||
| 1689 | |||
| 1690 | return 0; | ||
| 1691 | } | ||
| 1692 | |||
| 1693 | /** | ||
| 1617 | * _ocp_softreset - reset an omap_hwmod via the OCP_SYSCONFIG bit | 1694 | * _ocp_softreset - reset an omap_hwmod via the OCP_SYSCONFIG bit |
| 1618 | * @oh: struct omap_hwmod * | 1695 | * @oh: struct omap_hwmod * |
| 1619 | * | 1696 | * |
| @@ -2548,6 +2625,33 @@ static int _omap4_wait_target_ready(struct omap_hwmod *oh) | |||
| 2548 | } | 2625 | } |
| 2549 | 2626 | ||
| 2550 | /** | 2627 | /** |
| 2628 | * _am33xx_wait_target_ready - wait for a module to leave slave idle | ||
| 2629 | * @oh: struct omap_hwmod * | ||
| 2630 | * | ||
| 2631 | * Wait for a module @oh to leave slave idle. Returns 0 if the module | ||
| 2632 | * does not have an IDLEST bit or if the module successfully leaves | ||
| 2633 | * slave idle; otherwise, pass along the return value of the | ||
| 2634 | * appropriate *_cm*_wait_module_ready() function. | ||
| 2635 | */ | ||
| 2636 | static int _am33xx_wait_target_ready(struct omap_hwmod *oh) | ||
| 2637 | { | ||
| 2638 | if (!oh || !oh->clkdm) | ||
| 2639 | return -EINVAL; | ||
| 2640 | |||
| 2641 | if (oh->flags & HWMOD_NO_IDLEST) | ||
| 2642 | return 0; | ||
| 2643 | |||
| 2644 | if (!_find_mpu_rt_port(oh)) | ||
| 2645 | return 0; | ||
| 2646 | |||
| 2647 | /* XXX check module SIDLEMODE, hardreset status */ | ||
| 2648 | |||
| 2649 | return am33xx_cm_wait_module_ready(oh->clkdm->cm_inst, | ||
| 2650 | oh->clkdm->clkdm_offs, | ||
| 2651 | oh->prcm.omap4.clkctrl_offs); | ||
| 2652 | } | ||
| 2653 | |||
| 2654 | /** | ||
| 2551 | * _omap2_assert_hardreset - call OMAP2 PRM hardreset fn with hwmod args | 2655 | * _omap2_assert_hardreset - call OMAP2 PRM hardreset fn with hwmod args |
| 2552 | * @oh: struct omap_hwmod * to assert hardreset | 2656 | * @oh: struct omap_hwmod * to assert hardreset |
| 2553 | * @ohri: hardreset line data | 2657 | * @ohri: hardreset line data |
| @@ -2678,6 +2782,72 @@ static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh, | |||
| 2678 | oh->prcm.omap4.rstctrl_offs); | 2782 | oh->prcm.omap4.rstctrl_offs); |
| 2679 | } | 2783 | } |
| 2680 | 2784 | ||
| 2785 | /** | ||
| 2786 | * _am33xx_assert_hardreset - call AM33XX PRM hardreset fn with hwmod args | ||
| 2787 | * @oh: struct omap_hwmod * to assert hardreset | ||
| 2788 | * @ohri: hardreset line data | ||
| 2789 | * | ||
| 2790 | * Call am33xx_prminst_assert_hardreset() with parameters extracted | ||
| 2791 | * from the hwmod @oh and the hardreset line data @ohri. Only | ||
| 2792 | * intended for use as an soc_ops function pointer. Passes along the | ||
| 2793 | * return value from am33xx_prminst_assert_hardreset(). XXX This | ||
| 2794 | * function is scheduled for removal when the PRM code is moved into | ||
| 2795 | * drivers/. | ||
| 2796 | */ | ||
| 2797 | static int _am33xx_assert_hardreset(struct omap_hwmod *oh, | ||
| 2798 | struct omap_hwmod_rst_info *ohri) | ||
| 2799 | |||
| 2800 | { | ||
| 2801 | return am33xx_prm_assert_hardreset(ohri->rst_shift, | ||
| 2802 | oh->clkdm->pwrdm.ptr->prcm_offs, | ||
| 2803 | oh->prcm.omap4.rstctrl_offs); | ||
| 2804 | } | ||
| 2805 | |||
| 2806 | /** | ||
| 2807 | * _am33xx_deassert_hardreset - call AM33XX PRM hardreset fn with hwmod args | ||
| 2808 | * @oh: struct omap_hwmod * to deassert hardreset | ||
| 2809 | * @ohri: hardreset line data | ||
| 2810 | * | ||
| 2811 | * Call am33xx_prminst_deassert_hardreset() with parameters extracted | ||
| 2812 | * from the hwmod @oh and the hardreset line data @ohri. Only | ||
| 2813 | * intended for use as an soc_ops function pointer. Passes along the | ||
| 2814 | * return value from am33xx_prminst_deassert_hardreset(). XXX This | ||
| 2815 | * function is scheduled for removal when the PRM code is moved into | ||
| 2816 | * drivers/. | ||
| 2817 | */ | ||
| 2818 | static int _am33xx_deassert_hardreset(struct omap_hwmod *oh, | ||
| 2819 | struct omap_hwmod_rst_info *ohri) | ||
| 2820 | { | ||
| 2821 | if (ohri->st_shift) | ||
| 2822 | pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n", | ||
| 2823 | oh->name, ohri->name); | ||
| 2824 | |||
| 2825 | return am33xx_prm_deassert_hardreset(ohri->rst_shift, | ||
| 2826 | oh->clkdm->pwrdm.ptr->prcm_offs, | ||
| 2827 | oh->prcm.omap4.rstctrl_offs, | ||
| 2828 | oh->prcm.omap4.rstst_offs); | ||
| 2829 | } | ||
| 2830 | |||
| 2831 | /** | ||
| 2832 | * _am33xx_is_hardreset_asserted - call AM33XX PRM hardreset fn with hwmod args | ||
| 2833 | * @oh: struct omap_hwmod * to test hardreset | ||
| 2834 | * @ohri: hardreset line data | ||
| 2835 | * | ||
| 2836 | * Call am33xx_prminst_is_hardreset_asserted() with parameters | ||
| 2837 | * extracted from the hwmod @oh and the hardreset line data @ohri. | ||
| 2838 | * Only intended for use as an soc_ops function pointer. Passes along | ||
| 2839 | * the return value from am33xx_prminst_is_hardreset_asserted(). XXX | ||
| 2840 | * This function is scheduled for removal when the PRM code is moved | ||
| 2841 | * into drivers/. | ||
| 2842 | */ | ||
| 2843 | static int _am33xx_is_hardreset_asserted(struct omap_hwmod *oh, | ||
| 2844 | struct omap_hwmod_rst_info *ohri) | ||
| 2845 | { | ||
| 2846 | return am33xx_prm_is_hardreset_asserted(ohri->rst_shift, | ||
| 2847 | oh->clkdm->pwrdm.ptr->prcm_offs, | ||
| 2848 | oh->prcm.omap4.rstctrl_offs); | ||
| 2849 | } | ||
| 2850 | |||
| 2681 | /* Public functions */ | 2851 | /* Public functions */ |
| 2682 | 2852 | ||
| 2683 | u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs) | 2853 | u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs) |
| @@ -3677,6 +3847,14 @@ void __init omap_hwmod_init(void) | |||
| 3677 | soc_ops.deassert_hardreset = _omap4_deassert_hardreset; | 3847 | soc_ops.deassert_hardreset = _omap4_deassert_hardreset; |
| 3678 | soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted; | 3848 | soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted; |
| 3679 | soc_ops.init_clkdm = _init_clkdm; | 3849 | soc_ops.init_clkdm = _init_clkdm; |
| 3850 | } else if (soc_is_am33xx()) { | ||
| 3851 | soc_ops.enable_module = _am33xx_enable_module; | ||
| 3852 | soc_ops.disable_module = _am33xx_disable_module; | ||
| 3853 | soc_ops.wait_target_ready = _am33xx_wait_target_ready; | ||
| 3854 | soc_ops.assert_hardreset = _am33xx_assert_hardreset; | ||
| 3855 | soc_ops.deassert_hardreset = _am33xx_deassert_hardreset; | ||
| 3856 | soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted; | ||
| 3857 | soc_ops.init_clkdm = _init_clkdm; | ||
| 3680 | } else { | 3858 | } else { |
| 3681 | WARN(1, "omap_hwmod: unknown SoC type\n"); | 3859 | WARN(1, "omap_hwmod: unknown SoC type\n"); |
| 3682 | } | 3860 | } |
