aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap_hwmod.c
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2012-09-23 19:16:04 -0400
committerPaul Walmsley <paul@pwsan.com>2012-09-23 19:16:04 -0400
commit1e2ee2a60df5c3ab74dd1c9155fb01b5bc6f807d (patch)
tree2adb98096c4a6dec0ceff4e7e04610a079f14026 /arch/arm/mach-omap2/omap_hwmod.c
parent291852e8791a596195edc3ced96481bfd105f35b (diff)
parent11964f53eb4d9ce59a058be9999d9cfcb1ced878 (diff)
Merge tag 'omap-devel-am33xx-for-v3.7' into test_v3.6-rc6_ocb3.7_cff3.7_odaf3.7
From Paul Walmsley <paul@pwsan.com>: AM33xx hwmod data and miscellaneous clock and hwmod fixes. AM33xx should now boot on mainline after this is applied, according to Vaibhav.
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c178
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 3615e0d9ee3c..7d843cd3b33d 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -149,8 +149,10 @@
149#include "powerdomain.h" 149#include "powerdomain.h"
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 */
879static 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 */
927static 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 */
1670static 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 *
@@ -2549,6 +2626,33 @@ static int _omap4_wait_target_ready(struct omap_hwmod *oh)
2549} 2626}
2550 2627
2551/** 2628/**
2629 * _am33xx_wait_target_ready - wait for a module to leave slave idle
2630 * @oh: struct omap_hwmod *
2631 *
2632 * Wait for a module @oh to leave slave idle. Returns 0 if the module
2633 * does not have an IDLEST bit or if the module successfully leaves
2634 * slave idle; otherwise, pass along the return value of the
2635 * appropriate *_cm*_wait_module_ready() function.
2636 */
2637static int _am33xx_wait_target_ready(struct omap_hwmod *oh)
2638{
2639 if (!oh || !oh->clkdm)
2640 return -EINVAL;
2641
2642 if (oh->flags & HWMOD_NO_IDLEST)
2643 return 0;
2644
2645 if (!_find_mpu_rt_port(oh))
2646 return 0;
2647
2648 /* XXX check module SIDLEMODE, hardreset status */
2649
2650 return am33xx_cm_wait_module_ready(oh->clkdm->cm_inst,
2651 oh->clkdm->clkdm_offs,
2652 oh->prcm.omap4.clkctrl_offs);
2653}
2654
2655/**
2552 * _omap2_assert_hardreset - call OMAP2 PRM hardreset fn with hwmod args 2656 * _omap2_assert_hardreset - call OMAP2 PRM hardreset fn with hwmod args
2553 * @oh: struct omap_hwmod * to assert hardreset 2657 * @oh: struct omap_hwmod * to assert hardreset
2554 * @ohri: hardreset line data 2658 * @ohri: hardreset line data
@@ -2679,6 +2783,72 @@ static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh,
2679 oh->prcm.omap4.rstctrl_offs); 2783 oh->prcm.omap4.rstctrl_offs);
2680} 2784}
2681 2785
2786/**
2787 * _am33xx_assert_hardreset - call AM33XX PRM hardreset fn with hwmod args
2788 * @oh: struct omap_hwmod * to assert hardreset
2789 * @ohri: hardreset line data
2790 *
2791 * Call am33xx_prminst_assert_hardreset() with parameters extracted
2792 * from the hwmod @oh and the hardreset line data @ohri. Only
2793 * intended for use as an soc_ops function pointer. Passes along the
2794 * return value from am33xx_prminst_assert_hardreset(). XXX This
2795 * function is scheduled for removal when the PRM code is moved into
2796 * drivers/.
2797 */
2798static int _am33xx_assert_hardreset(struct omap_hwmod *oh,
2799 struct omap_hwmod_rst_info *ohri)
2800
2801{
2802 return am33xx_prm_assert_hardreset(ohri->rst_shift,
2803 oh->clkdm->pwrdm.ptr->prcm_offs,
2804 oh->prcm.omap4.rstctrl_offs);
2805}
2806
2807/**
2808 * _am33xx_deassert_hardreset - call AM33XX PRM hardreset fn with hwmod args
2809 * @oh: struct omap_hwmod * to deassert hardreset
2810 * @ohri: hardreset line data
2811 *
2812 * Call am33xx_prminst_deassert_hardreset() with parameters extracted
2813 * from the hwmod @oh and the hardreset line data @ohri. Only
2814 * intended for use as an soc_ops function pointer. Passes along the
2815 * return value from am33xx_prminst_deassert_hardreset(). XXX This
2816 * function is scheduled for removal when the PRM code is moved into
2817 * drivers/.
2818 */
2819static int _am33xx_deassert_hardreset(struct omap_hwmod *oh,
2820 struct omap_hwmod_rst_info *ohri)
2821{
2822 if (ohri->st_shift)
2823 pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
2824 oh->name, ohri->name);
2825
2826 return am33xx_prm_deassert_hardreset(ohri->rst_shift,
2827 oh->clkdm->pwrdm.ptr->prcm_offs,
2828 oh->prcm.omap4.rstctrl_offs,
2829 oh->prcm.omap4.rstst_offs);
2830}
2831
2832/**
2833 * _am33xx_is_hardreset_asserted - call AM33XX PRM hardreset fn with hwmod args
2834 * @oh: struct omap_hwmod * to test hardreset
2835 * @ohri: hardreset line data
2836 *
2837 * Call am33xx_prminst_is_hardreset_asserted() with parameters
2838 * extracted from the hwmod @oh and the hardreset line data @ohri.
2839 * Only intended for use as an soc_ops function pointer. Passes along
2840 * the return value from am33xx_prminst_is_hardreset_asserted(). XXX
2841 * This function is scheduled for removal when the PRM code is moved
2842 * into drivers/.
2843 */
2844static int _am33xx_is_hardreset_asserted(struct omap_hwmod *oh,
2845 struct omap_hwmod_rst_info *ohri)
2846{
2847 return am33xx_prm_is_hardreset_asserted(ohri->rst_shift,
2848 oh->clkdm->pwrdm.ptr->prcm_offs,
2849 oh->prcm.omap4.rstctrl_offs);
2850}
2851
2682/* Public functions */ 2852/* Public functions */
2683 2853
2684u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs) 2854u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs)
@@ -3678,6 +3848,14 @@ void __init omap_hwmod_init(void)
3678 soc_ops.deassert_hardreset = _omap4_deassert_hardreset; 3848 soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
3679 soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted; 3849 soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
3680 soc_ops.init_clkdm = _init_clkdm; 3850 soc_ops.init_clkdm = _init_clkdm;
3851 } else if (soc_is_am33xx()) {
3852 soc_ops.enable_module = _am33xx_enable_module;
3853 soc_ops.disable_module = _am33xx_disable_module;
3854 soc_ops.wait_target_ready = _am33xx_wait_target_ready;
3855 soc_ops.assert_hardreset = _am33xx_assert_hardreset;
3856 soc_ops.deassert_hardreset = _am33xx_deassert_hardreset;
3857 soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted;
3858 soc_ops.init_clkdm = _init_clkdm;
3681 } else { 3859 } else {
3682 WARN(1, "omap_hwmod: unknown SoC type\n"); 3860 WARN(1, "omap_hwmod: unknown SoC type\n");
3683 } 3861 }