diff options
Diffstat (limited to 'arch/arm/mach-omap2')
322 files changed, 100670 insertions, 16601 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 3754b79092a..1c1ed737f7a 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -1,61 +1,348 @@ -comment "OMAP Core Type" - depends on ARCH_OMAP2 +menu "TI OMAP/AM/DM/DRA Family" + depends on ARCH_MULTI_V6 || ARCH_MULTI_V7 + +config ARCH_OMAP + bool + +config ARCH_OMAP2 + bool "TI OMAP2" + depends on ARCH_MULTI_V6 + select ARCH_OMAP2PLUS + select CPU_V6 + select SOC_HAS_OMAP2_SDRC + +config ARCH_OMAP3 + bool "TI OMAP3" + depends on ARCH_MULTI_V7 + select ARCH_OMAP2PLUS + select ARCH_HAS_OPP + select ARM_CPU_SUSPEND if PM + select OMAP_INTERCONNECT + select PM_OPP if PM + select PM_RUNTIME if CPU_IDLE + select SOC_HAS_OMAP2_SDRC + +config ARCH_OMAP4 + bool "TI OMAP4" + depends on ARCH_MULTI_V7 + select ARCH_OMAP2PLUS + select ARCH_HAS_OPP + select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP + select ARM_CPU_SUSPEND if PM + select ARM_ERRATA_720789 + select ARM_GIC + select HAVE_ARM_SCU if SMP + select HAVE_ARM_TWD if SMP + select OMAP_INTERCONNECT + select PL310_ERRATA_588369 if CACHE_L2X0 + select PL310_ERRATA_727915 if CACHE_L2X0 + select PM_OPP if PM + select PM_RUNTIME if CPU_IDLE + select ARM_ERRATA_754322 + select ARM_ERRATA_775420 + +config SOC_OMAP5 + bool "TI OMAP5" + depends on ARCH_MULTI_V7 + select ARCH_OMAP2PLUS + select ARCH_HAS_OPP + select ARM_CPU_SUSPEND if PM + select ARM_GIC + select HAVE_ARM_SCU if SMP + select HAVE_ARM_TWD if SMP + select HAVE_ARM_ARCH_TIMER + select ARM_ERRATA_798181 if SMP + +config SOC_AM33XX + bool "TI AM33XX" + depends on ARCH_MULTI_V7 + select ARCH_OMAP2PLUS + select ARCH_HAS_OPP + select ARM_CPU_SUSPEND if PM + +config SOC_AM43XX + bool "TI AM43x" + depends on ARCH_MULTI_V7 + select ARCH_OMAP2PLUS + select ARCH_HAS_OPP + select ARM_GIC + select MACH_OMAP_GENERIC + select MIGHT_HAVE_CACHE_L2X0 + +config SOC_DRA7XX + bool "TI DRA7XX" + depends on ARCH_MULTI_V7 + select ARCH_OMAP2PLUS + select ARCH_HAS_OPP + select ARM_CPU_SUSPEND if PM + select ARM_GIC + select HAVE_ARM_ARCH_TIMER + select IRQ_CROSSBAR + +config ARCH_OMAP2PLUS + bool + select ARCH_HAS_BANDGAP + select ARCH_HAS_HOLES_MEMORYMODEL + select ARCH_OMAP + select ARCH_REQUIRE_GPIOLIB + select CLKSRC_MMIO + select GENERIC_IRQ_CHIP + select MACH_OMAP_GENERIC + select OMAP_DM_TIMER + select PINCTRL + select SOC_BUS + select TI_PRIV_EDMA + help + Systems based on OMAP2, OMAP3, OMAP4 or OMAP5 + + +if ARCH_OMAP2PLUS + +menu "TI OMAP2/3/4 Specific Features" + +config ARCH_OMAP2PLUS_TYPICAL + bool "Typical OMAP configuration" + default y + select AEABI + select HIGHMEM + select I2C + select I2C_OMAP + select MENELAUS if ARCH_OMAP2 + select NEON if CPU_V7 + select PM_RUNTIME + select REGULATOR + select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4 + select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4 + select VFP + help + Compile a kernel suitable for booting most boards + +config SOC_HAS_OMAP2_SDRC + bool "OMAP2 SDRAM Controller support" -config ARCH_OMAP24XX - bool "OMAP24xx Based System" +config SOC_HAS_REALTIME_COUNTER + bool "Real time free running counter" + depends on SOC_OMAP5 || SOC_DRA7XX + default y + +comment "OMAP Core Type" depends on ARCH_OMAP2 -config ARCH_OMAP2420 +config SOC_OMAP2420 bool "OMAP2420 support" - depends on ARCH_OMAP24XX + depends on ARCH_OMAP2 + default y select OMAP_DM_TIMER - select ARCH_OMAP_OTG + select SOC_HAS_OMAP2_SDRC -config ARCH_OMAP2430 +config SOC_OMAP2430 bool "OMAP2430 support" - depends on ARCH_OMAP24XX + depends on ARCH_OMAP2 + default y + select SOC_HAS_OMAP2_SDRC -config ARCH_OMAP34XX - bool "OMAP34xx Based System" +config SOC_OMAP3430 + bool "OMAP3430 support" depends on ARCH_OMAP3 + default y + select SOC_HAS_OMAP2_SDRC -config ARCH_OMAP3430 - bool "OMAP3430 support" - depends on ARCH_OMAP3 && ARCH_OMAP34XX - select ARCH_OMAP_OTG +config SOC_TI81XX + bool "TI81XX support" + depends on ARCH_OMAP3 + default y -comment "OMAP Board Type" - depends on ARCH_OMAP2 || ARCH_OMAP3 +config OMAP_PACKAGE_CBC + bool -config MACH_OMAP_GENERIC - bool "Generic OMAP board" - depends on ARCH_OMAP2 && ARCH_OMAP24XX +config OMAP_PACKAGE_CBB + bool -config MACH_OMAP_H4 - bool "OMAP 2420 H4 board" - depends on ARCH_OMAP2 && ARCH_OMAP24XX - select OMAP_DEBUG_DEVICES +config OMAP_PACKAGE_CUS + bool -config MACH_OMAP_APOLLON - bool "OMAP 2420 Apollon board" - depends on ARCH_OMAP2 && ARCH_OMAP24XX +config OMAP_PACKAGE_CBP + bool -config MACH_OMAP_2430SDP - bool "OMAP 2430 SDP board" - depends on ARCH_OMAP2 && ARCH_OMAP24XX +comment "OMAP Legacy Platform Data Board Type" + depends on ARCH_OMAP2PLUS + +config MACH_OMAP_GENERIC + bool + +config MACH_OMAP2_TUSB6010 + bool + depends on ARCH_OMAP2 && SOC_OMAP2420 + default y if MACH_NOKIA_N8X0 config MACH_OMAP3_BEAGLE bool "OMAP3 BEAGLE board" - depends on ARCH_OMAP3 && ARCH_OMAP34XX + depends on ARCH_OMAP3 + default y + select OMAP_PACKAGE_CBB + +config MACH_DEVKIT8000 + bool "DEVKIT8000 board" + depends on ARCH_OMAP3 + default y + select OMAP_PACKAGE_CUS config MACH_OMAP_LDP bool "OMAP3 LDP board" - depends on ARCH_OMAP3 && ARCH_OMAP34XX + depends on ARCH_OMAP3 + default y + select OMAP_PACKAGE_CBB + +config MACH_OMAP3530_LV_SOM + bool "OMAP3 Logic 3530 LV SOM board" + depends on ARCH_OMAP3 + default y + select OMAP_PACKAGE_CBB + help + Support for the LogicPD OMAP3530 SOM Development kit + for full description please see the products webpage at + http://www.logicpd.com/products/development-kits/texas-instruments-zoom%E2%84%A2-omap35x-development-kit + +config MACH_OMAP3_TORPEDO + bool "OMAP3 Logic 35x Torpedo board" + depends on ARCH_OMAP3 + default y + select OMAP_PACKAGE_CBB + help + Support for the LogicPD OMAP35x Torpedo Development kit + for full description please see the products webpage at + http://www.logicpd.com/products/development-kits/zoom-omap35x-torpedo-development-kit config MACH_OVERO bool "Gumstix Overo board" - depends on ARCH_OMAP3 && ARCH_OMAP34XX + depends on ARCH_OMAP3 + default y + select OMAP_PACKAGE_CBB + +config MACH_OMAP3517EVM + bool "OMAP3517/ AM3517 EVM board" + depends on ARCH_OMAP3 + default y + select OMAP_PACKAGE_CBB + +config MACH_CRANEBOARD + bool "AM3517/05 CRANE board" + depends on ARCH_OMAP3 + select OMAP_PACKAGE_CBB config MACH_OMAP3_PANDORA bool "OMAP3 Pandora" - depends on ARCH_OMAP3 && ARCH_OMAP34XX
\ No newline at end of file + depends on ARCH_OMAP3 + default y + select OMAP_PACKAGE_CBB + select REGULATOR_FIXED_VOLTAGE if REGULATOR + +config MACH_TOUCHBOOK + bool "OMAP3 Touch Book" + depends on ARCH_OMAP3 + default y + select OMAP_PACKAGE_CBB + +config MACH_OMAP_3430SDP + bool "OMAP 3430 SDP board" + depends on ARCH_OMAP3 + default y + select OMAP_PACKAGE_CBB + +config MACH_NOKIA_N810 + bool + +config MACH_NOKIA_N810_WIMAX + bool + +config MACH_NOKIA_N8X0 + bool "Nokia N800/N810" + depends on SOC_OMAP2420 + default y + select MACH_NOKIA_N810 + select MACH_NOKIA_N810_WIMAX + +config MACH_NOKIA_RX51 + bool "Nokia N900 (RX-51) phone" + depends on ARCH_OMAP3 + default y + select OMAP_PACKAGE_CBB + +config MACH_CM_T35 + bool "CompuLab CM-T35/CM-T3730 modules" + depends on ARCH_OMAP3 + default y + select MACH_CM_T3730 + select OMAP_PACKAGE_CUS + +config MACH_CM_T3517 + bool "CompuLab CM-T3517 module" + depends on ARCH_OMAP3 + default y + select OMAP_PACKAGE_CBB + +config MACH_CM_T3730 + bool + +config MACH_SBC3530 + bool "OMAP3 SBC STALKER board" + depends on ARCH_OMAP3 + default y + select OMAP_PACKAGE_CUS + +config MACH_TI8168EVM + bool "TI8168 Evaluation Module" + depends on SOC_TI81XX + default y + +config MACH_TI8148EVM + bool "TI8148 Evaluation Module" + depends on SOC_TI81XX + default y + +config OMAP3_EMU + bool "OMAP3 debugging peripherals" + depends on ARCH_OMAP3 + select ARM_AMBA + select OC_ETM + help + Say Y here to enable debugging hardware of omap3 + +config OMAP3_SDRC_AC_TIMING + bool "Enable SDRC AC timing register changes" + depends on ARCH_OMAP3 + default n + help + If you know that none of your system initiators will attempt to + access SDRAM during CORE DVFS, select Y here. This should boost + SDRAM performance at lower CORE OPPs. There are relatively few + users who will wish to say yes at this point - almost everyone will + wish to say no. Selecting yes without understanding what is + going on could result in system crashes; + +config OMAP4_ERRATA_I688 + bool "OMAP4 errata: Async Bridge Corruption" + depends on (ARCH_OMAP4 || SOC_OMAP5) && !ARCH_MULTIPLATFORM + select ARCH_HAS_BARRIERS + help + If a data is stalled inside asynchronous bridge because of back + pressure, it may be accepted multiple times, creating pointer + misalignment that will corrupt next transfers on that data path + until next reset of the system (No recovery procedure once the + issue is hit, the path remains consistently broken). Async bridge + can be found on path between MPU to EMIF and MPU to L3 interconnect. + This situation can happen only when the idle is initiated by a + Master Request Disconnection (which is trigged by software when + executing WFI on CPU). + The work-around for this errata needs all the initiators connected + through async bridge must ensure that data path is properly drained + before issuing WFI. This condition will be met if one Strongly ordered + access is performed to the target right before executing the WFI. + In MPU case, L3 T2ASYNC FIFO and DDR T2ASYNC FIFO needs to be drained. + IO barrier ensure that there is no synchronisation loss on initiators + operating on both interconnect port simultaneously. +endmenu + +endif + +endmenu diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index bbd12bc10fd..8ca99e9321e 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -2,40 +2,300 @@ # Makefile for the linux kernel. # +ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \ + -I$(srctree)/arch/arm/plat-omap/include + # Common support -obj-y := irq.o id.o io.o memory.o control.o prcm.o clock.o mux.o \ - devices.o serial.o gpmc.o timer-gp.o powerdomain.o \ - clockdomain.o +obj-y := id.o io.o control.o mux.o devices.o fb.o serial.o gpmc.o timer.o pm.o \ + common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \ + omap_device.o sram.o drm.o + +omap-2-3-common = irq.o +hwmod-common = omap_hwmod.o omap_hwmod_reset.o \ + omap_hwmod_common_data.o +clock-common = clock.o clock_common_data.o \ + clkt_dpll.o clkt_clksel.o +secure-common = omap-smc.o omap-secure.o + +obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) +obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common) +obj-$(CONFIG_ARCH_OMAP4) += $(hwmod-common) $(secure-common) +obj-$(CONFIG_SOC_AM33XX) += irq.o $(hwmod-common) +obj-$(CONFIG_SOC_OMAP5) += $(hwmod-common) $(secure-common) +obj-$(CONFIG_SOC_AM43XX) += $(hwmod-common) $(secure-common) +obj-$(CONFIG_SOC_DRA7XX) += $(hwmod-common) $(secure-common) + +ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),) +obj-y += mcbsp.o +endif + +obj-$(CONFIG_TWL4030_CORE) += omap_twl.o +obj-$(CONFIG_SOC_HAS_OMAP2_SDRC) += sdrc.o -obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o +# SMP support ONLY available for OMAP4 + +smp-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o +smp-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o +omap-4-5-common = omap4-common.o omap-wakeupgen.o +obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-common) $(smp-y) sleep44xx.o +obj-$(CONFIG_SOC_OMAP5) += $(omap-4-5-common) $(smp-y) sleep44xx.o +obj-$(CONFIG_SOC_AM43XX) += $(omap-4-5-common) +obj-$(CONFIG_SOC_DRA7XX) += $(omap-4-5-common) $(smp-y) sleep44xx.o + +plus_sec := $(call as-instr,.arch_extension sec,+sec) +AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec) +AFLAGS_omap-smc.o :=-Wa,-march=armv7-a$(plus_sec) +AFLAGS_sleep44xx.o :=-Wa,-march=armv7-a$(plus_sec) # Functions loaded to SRAM -obj-$(CONFIG_ARCH_OMAP2420) += sram242x.o -obj-$(CONFIG_ARCH_OMAP2430) += sram243x.o +obj-$(CONFIG_SOC_OMAP2420) += sram242x.o +obj-$(CONFIG_SOC_OMAP2430) += sram243x.o obj-$(CONFIG_ARCH_OMAP3) += sram34xx.o +AFLAGS_sram242x.o :=-Wa,-march=armv6 +AFLAGS_sram243x.o :=-Wa,-march=armv6 +AFLAGS_sram34xx.o :=-Wa,-march=armv7-a + +# Restart code (OMAP4/5 currently in omap4-common.c) +obj-$(CONFIG_SOC_OMAP2420) += omap2-restart.o +obj-$(CONFIG_SOC_OMAP2430) += omap2-restart.o +obj-$(CONFIG_SOC_AM33XX) += am33xx-restart.o +obj-$(CONFIG_SOC_AM43XX) += omap4-restart.o +obj-$(CONFIG_ARCH_OMAP3) += omap3-restart.o +obj-$(CONFIG_ARCH_OMAP4) += omap4-restart.o +obj-$(CONFIG_SOC_OMAP5) += omap4-restart.o +obj-$(CONFIG_SOC_DRA7XX) += omap4-restart.o + +# Pin multiplexing +obj-$(CONFIG_ARCH_OMAP3) += mux34xx.o + +# SMS/SDRC +obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o +# obj-$(CONFIG_ARCH_OMAP3) += sdrc3xxx.o + +# OPP table initialization +ifeq ($(CONFIG_PM_OPP),y) +obj-y += opp.o +obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o +obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o +endif + # Power Management +obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o + ifeq ($(CONFIG_PM),y) -obj-y += pm.o -obj-$(CONFIG_ARCH_OMAP24XX) += sleep24xx.o +obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o +obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o +obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o +obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o +obj-$(CONFIG_SOC_OMAP5) += omap-mpuss-lowpower.o +obj-$(CONFIG_SOC_DRA7XX) += omap-mpuss-lowpower.o +obj-$(CONFIG_PM_DEBUG) += pm-debug.o + +obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o +obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o + +AFLAGS_sleep24xx.o :=-Wa,-march=armv6 +AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec) + endif +ifeq ($(CONFIG_CPU_IDLE),y) +obj-$(CONFIG_ARCH_OMAP3) += cpuidle34xx.o +obj-$(CONFIG_ARCH_OMAP4) += cpuidle44xx.o +endif + +# PRCM +obj-y += prm_common.o cm_common.o +obj-$(CONFIG_ARCH_OMAP2) += prm2xxx_3xxx.o prm2xxx.o cm2xxx.o +obj-$(CONFIG_ARCH_OMAP3) += prm2xxx_3xxx.o prm3xxx.o cm3xxx.o +obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o +omap-prcm-4-5-common = cminst44xx.o cm44xx.o prm44xx.o \ + prcm_mpu44xx.o prminst44xx.o \ + vc44xx_data.o vp44xx_data.o +obj-$(CONFIG_ARCH_OMAP4) += $(omap-prcm-4-5-common) +obj-$(CONFIG_SOC_OMAP5) += $(omap-prcm-4-5-common) +obj-$(CONFIG_SOC_DRA7XX) += $(omap-prcm-4-5-common) +am33xx-43xx-prcm-common += prm33xx.o cm33xx.o +obj-$(CONFIG_SOC_AM33XX) += $(am33xx-43xx-prcm-common) +obj-$(CONFIG_SOC_AM43XX) += $(omap-prcm-4-5-common) \ + $(am33xx-43xx-prcm-common) + +# OMAP voltage domains +voltagedomain-common := voltage.o vc.o vp.o +obj-$(CONFIG_ARCH_OMAP2) += $(voltagedomain-common) +obj-$(CONFIG_ARCH_OMAP2) += voltagedomains2xxx_data.o +obj-$(CONFIG_ARCH_OMAP3) += $(voltagedomain-common) +obj-$(CONFIG_ARCH_OMAP3) += voltagedomains3xxx_data.o +obj-$(CONFIG_ARCH_OMAP4) += $(voltagedomain-common) +obj-$(CONFIG_ARCH_OMAP4) += voltagedomains44xx_data.o +obj-$(CONFIG_SOC_AM33XX) += $(voltagedomain-common) +obj-$(CONFIG_SOC_AM43XX) += $(voltagedomain-common) +obj-$(CONFIG_SOC_OMAP5) += $(voltagedomain-common) +obj-$(CONFIG_SOC_OMAP5) += voltagedomains54xx_data.o +obj-$(CONFIG_SOC_DRA7XX) += $(voltagedomain-common) + +# OMAP powerdomain framework +powerdomain-common += powerdomain.o powerdomain-common.o +obj-$(CONFIG_ARCH_OMAP2) += $(powerdomain-common) +obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_data.o +obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_3xxx_data.o +obj-$(CONFIG_ARCH_OMAP3) += $(powerdomain-common) +obj-$(CONFIG_ARCH_OMAP3) += powerdomains3xxx_data.o +obj-$(CONFIG_ARCH_OMAP3) += powerdomains2xxx_3xxx_data.o +obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common) +obj-$(CONFIG_ARCH_OMAP4) += powerdomains44xx_data.o +obj-$(CONFIG_SOC_AM33XX) += $(powerdomain-common) +obj-$(CONFIG_SOC_AM33XX) += powerdomains33xx_data.o +obj-$(CONFIG_SOC_AM43XX) += $(powerdomain-common) +obj-$(CONFIG_SOC_AM43XX) += powerdomains43xx_data.o +obj-$(CONFIG_SOC_OMAP5) += $(powerdomain-common) +obj-$(CONFIG_SOC_OMAP5) += powerdomains54xx_data.o +obj-$(CONFIG_SOC_DRA7XX) += $(powerdomain-common) +obj-$(CONFIG_SOC_DRA7XX) += powerdomains7xx_data.o + +# PRCM clockdomain control +clockdomain-common += clockdomain.o +obj-$(CONFIG_ARCH_OMAP2) += $(clockdomain-common) +obj-$(CONFIG_ARCH_OMAP2) += clockdomains2xxx_3xxx_data.o +obj-$(CONFIG_SOC_OMAP2420) += clockdomains2420_data.o +obj-$(CONFIG_SOC_OMAP2430) += clockdomains2430_data.o +obj-$(CONFIG_ARCH_OMAP3) += $(clockdomain-common) +obj-$(CONFIG_ARCH_OMAP3) += clockdomains2xxx_3xxx_data.o +obj-$(CONFIG_ARCH_OMAP3) += clockdomains3xxx_data.o +obj-$(CONFIG_ARCH_OMAP4) += $(clockdomain-common) +obj-$(CONFIG_ARCH_OMAP4) += clockdomains44xx_data.o +obj-$(CONFIG_SOC_AM33XX) += $(clockdomain-common) +obj-$(CONFIG_SOC_AM33XX) += clockdomains33xx_data.o +obj-$(CONFIG_SOC_AM43XX) += $(clockdomain-common) +obj-$(CONFIG_SOC_AM43XX) += clockdomains43xx_data.o +obj-$(CONFIG_SOC_OMAP5) += $(clockdomain-common) +obj-$(CONFIG_SOC_OMAP5) += clockdomains54xx_data.o +obj-$(CONFIG_SOC_DRA7XX) += $(clockdomain-common) +obj-$(CONFIG_SOC_DRA7XX) += clockdomains7xx_data.o + # Clock framework -obj-$(CONFIG_ARCH_OMAP2) += clock24xx.o -obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o +obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o +obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_sys.o +obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpllcore.o +obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_virt_prcm_set.o +obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_apll.o clkt2xxx_osc.o +obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpll.o clkt_iclk.o +obj-$(CONFIG_SOC_OMAP2420) += cclock2420_data.o +obj-$(CONFIG_SOC_OMAP2430) += clock2430.o cclock2430_data.o +obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o +obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o clkt34xx_dpll3m2.o +obj-$(CONFIG_ARCH_OMAP3) += clock3517.o clock36xx.o +obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o cclock3xxx_data.o +obj-$(CONFIG_ARCH_OMAP3) += clkt_iclk.o +obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) +obj-$(CONFIG_ARCH_OMAP4) += dpll3xxx.o dpll44xx.o +obj-$(CONFIG_SOC_AM33XX) += $(clock-common) dpll3xxx.o +obj-$(CONFIG_SOC_OMAP5) += $(clock-common) +obj-$(CONFIG_SOC_OMAP5) += dpll3xxx.o dpll44xx.o +obj-$(CONFIG_SOC_DRA7XX) += $(clock-common) +obj-$(CONFIG_SOC_DRA7XX) += dpll3xxx.o dpll44xx.o +obj-$(CONFIG_SOC_AM43XX) += $(clock-common) dpll3xxx.o + +# OMAP2 clock rate set data (old "OPP" data) +obj-$(CONFIG_SOC_OMAP2420) += opp2420_data.o +obj-$(CONFIG_SOC_OMAP2430) += opp2430_data.o + +# hwmod data +obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_ipblock_data.o +obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_3xxx_ipblock_data.o +obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_interconnect_data.o +obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_3xxx_interconnect_data.o +obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2420_data.o +obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_ipblock_data.o +obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_3xxx_ipblock_data.o +obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_interconnect_data.o +obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_3xxx_interconnect_data.o +obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2430_data.o +obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_2xxx_3xxx_ipblock_data.o +obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_2xxx_3xxx_interconnect_data.o +obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_3xxx_data.o +obj-$(CONFIG_SOC_AM33XX) += omap_hwmod_33xx_data.o +obj-$(CONFIG_SOC_AM33XX) += omap_hwmod_33xx_43xx_interconnect_data.o +obj-$(CONFIG_SOC_AM33XX) += omap_hwmod_33xx_43xx_ipblock_data.o +obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_43xx_data.o +obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_33xx_43xx_interconnect_data.o +obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_33xx_43xx_ipblock_data.o +obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o +obj-$(CONFIG_SOC_OMAP5) += omap_hwmod_54xx_data.o +obj-$(CONFIG_SOC_DRA7XX) += omap_hwmod_7xx_data.o + +# EMU peripherals +obj-$(CONFIG_OMAP3_EMU) += emu.o +obj-$(CONFIG_HW_PERF_EVENTS) += pmu.o + +iommu-$(CONFIG_OMAP_IOMMU) := omap-iommu.o +obj-y += $(iommu-m) $(iommu-y) + +ifneq ($(CONFIG_TIDSPBRIDGE),) +obj-y += dsp.o +endif + +# OMAP2420 MSDI controller integration support ("MMC") +obj-$(CONFIG_SOC_OMAP2420) += msdi.o # Specific board support -obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o -obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o -obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o \ - mmc-twl4030.o -obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o -obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o \ - mmc-twl4030.o -obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o \ - mmc-twl4030.o -obj-$(CONFIG_MACH_OVERO) += board-overo.o \ - mmc-twl4030.o -obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o \ - mmc-twl4030.o +obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o pdata-quirks.o +obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o +obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o +obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o +obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o +obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o +obj-$(CONFIG_MACH_OVERO) += board-overo.o +obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o +obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o +obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o +obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o sdram-nokia.o +obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-peripherals.o +obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-video.o +obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o +obj-$(CONFIG_MACH_CM_T3517) += board-cm-t3517.o +obj-$(CONFIG_MACH_TOUCHBOOK) += board-omap3touchbook.o + +obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o + +obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o + +obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o +obj-$(CONFIG_MACH_TI8168EVM) += board-ti8168evm.o +obj-$(CONFIG_MACH_TI8148EVM) += board-ti8168evm.o + +# Platform specific device init code + +omap-flash-$(CONFIG_MTD_NAND_OMAP2) := board-flash.o +omap-flash-$(CONFIG_MTD_ONENAND_OMAP2) := board-flash.o +obj-y += $(omap-flash-y) $(omap-flash-m) + +omap-hsmmc-$(CONFIG_MMC_OMAP_HS) := hsmmc.o +obj-y += $(omap-hsmmc-m) $(omap-hsmmc-y) + +obj-y += usb-musb.o +obj-y += omap_phy_internal.o + +obj-$(CONFIG_MACH_OMAP2_TUSB6010) += usb-tusb6010.o +obj-y += usb-host.o + +onenand-$(CONFIG_MTD_ONENAND_OMAP2) := gpmc-onenand.o +obj-y += $(onenand-m) $(onenand-y) + +nand-$(CONFIG_MTD_NAND_OMAP2) := gpmc-nand.o +obj-y += $(nand-m) $(nand-y) + +smc91x-$(CONFIG_SMC91X) := gpmc-smc91x.o +obj-y += $(smc91x-m) $(smc91x-y) + +smsc911x-$(CONFIG_SMSC911X) := gpmc-smsc911x.o +obj-y += $(smsc911x-m) $(smsc911x-y) +ifneq ($(CONFIG_HWSPINLOCK_OMAP),) +obj-y += hwspinlock.o +endif + +emac-$(CONFIG_TI_DAVINCI_EMAC) := am35xx-emac.o +obj-y += $(emac-m) $(emac-y) +obj-y += common-board-devices.o twl-common.o dss-common.o diff --git a/arch/arm/mach-omap2/Makefile.boot b/arch/arm/mach-omap2/Makefile.boot index 565aff7f37a..b03e562acc6 100644 --- a/arch/arm/mach-omap2/Makefile.boot +++ b/arch/arm/mach-omap2/Makefile.boot @@ -1,3 +1,3 @@ - zreladdr-y := 0x80008000 + zreladdr-y += 0x80008000 params_phys-y := 0x80000100 initrd_phys-y := 0x80800000 diff --git a/arch/arm/mach-omap2/am33xx-restart.c b/arch/arm/mach-omap2/am33xx-restart.c new file mode 100644 index 00000000000..c88d8df753c --- /dev/null +++ b/arch/arm/mach-omap2/am33xx-restart.c @@ -0,0 +1,35 @@ +/* + * am33xx-restart.c - Code common to all AM33xx machines. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/kernel.h> +#include <linux/reboot.h> + +#include "common.h" +#include "prm-regbits-33xx.h" +#include "prm33xx.h" + +/** + * am3xx_restart - trigger a software restart of the SoC + * @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c + * @cmd: passed from the userspace program rebooting the system (if provided) + * + * Resets the SoC. For @cmd, see the 'reboot' syscall in + * kernel/sys.c. No return value. + */ +void am33xx_restart(enum reboot_mode mode, const char *cmd) +{ + /* TODO: Handle mode and cmd if necessary */ + + am33xx_prm_rmw_reg_bits(AM33XX_RST_GLOBAL_WARM_SW_MASK, + AM33XX_RST_GLOBAL_WARM_SW_MASK, + AM33XX_PRM_DEVICE_MOD, + AM33XX_PRM_RSTCTRL_OFFSET); + + /* OCP barrier */ + (void)am33xx_prm_read_reg(AM33XX_PRM_DEVICE_MOD, + AM33XX_PRM_RSTCTRL_OFFSET); +} diff --git a/arch/arm/mach-omap2/am33xx.h b/arch/arm/mach-omap2/am33xx.h new file mode 100644 index 00000000000..5eef093e673 --- /dev/null +++ b/arch/arm/mach-omap2/am33xx.h @@ -0,0 +1,27 @@ +/* + * This file contains the address info for various AM33XX modules. + * + * Copyright (C) 2011 Texas Instruments, Inc. - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARCH_AM33XX_H +#define __ASM_ARCH_AM33XX_H + +#define L4_SLOW_AM33XX_BASE 0x48000000 + +#define AM33XX_SCM_BASE 0x44E10000 +#define AM33XX_CTRL_BASE AM33XX_SCM_BASE +#define AM33XX_PRCM_BASE 0x44E00000 +#define AM43XX_PRCM_BASE 0x44DF0000 +#define AM33XX_TAP_BASE (AM33XX_CTRL_BASE + 0x3FC) + +#endif /* __ASM_ARCH_AM33XX_H */ diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c new file mode 100644 index 00000000000..6a6935caac1 --- /dev/null +++ b/arch/arm/mach-omap2/am35xx-emac.c @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2011 Ilya Yanok, Emcraft Systems + * + * Based on mach-omap2/board-am3517evm.c + * Copyright (C) 2009 Texas Instruments Incorporated + * Author: Ranjith Lohithakshan <ranjithl@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, + * whether express or implied; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include <linux/err.h> +#include <linux/davinci_emac.h> +#include "omap_device.h" +#include "am35xx.h" +#include "control.h" +#include "am35xx-emac.h" + +static void am35xx_enable_emac_int(void) +{ + u32 v; + + v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); + v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR | + AM35XX_CPGMAC_C0_MISC_PULSE_CLR | AM35XX_CPGMAC_C0_RX_THRESH_CLR); + omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR); + omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */ +} + +static void am35xx_disable_emac_int(void) +{ + u32 v; + + v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); + v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR); + omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR); + omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */ +} + +static struct emac_platform_data am35xx_emac_pdata = { + .ctrl_reg_offset = AM35XX_EMAC_CNTRL_OFFSET, + .ctrl_mod_reg_offset = AM35XX_EMAC_CNTRL_MOD_OFFSET, + .ctrl_ram_offset = AM35XX_EMAC_CNTRL_RAM_OFFSET, + .ctrl_ram_size = AM35XX_EMAC_CNTRL_RAM_SIZE, + .hw_ram_addr = AM35XX_EMAC_HW_RAM_ADDR, + .version = EMAC_VERSION_2, + .interrupt_enable = am35xx_enable_emac_int, + .interrupt_disable = am35xx_disable_emac_int, +}; + +static struct mdio_platform_data am35xx_mdio_pdata; + +static int __init omap_davinci_emac_dev_init(struct omap_hwmod *oh, + void *pdata, int pdata_len) +{ + struct platform_device *pdev; + + pdev = omap_device_build(oh->class->name, 0, oh, pdata, pdata_len); + if (IS_ERR(pdev)) { + WARN(1, "Can't build omap_device for %s:%s.\n", + oh->class->name, oh->name); + return PTR_ERR(pdev); + } + + return 0; +} + +void __init am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en) +{ + struct omap_hwmod *oh; + u32 v; + int ret; + + oh = omap_hwmod_lookup("davinci_mdio"); + if (!oh) { + pr_err("Could not find davinci_mdio hwmod\n"); + return; + } + + am35xx_mdio_pdata.bus_freq = mdio_bus_freq; + + ret = omap_davinci_emac_dev_init(oh, &am35xx_mdio_pdata, + sizeof(am35xx_mdio_pdata)); + if (ret) { + pr_err("Could not build davinci_mdio hwmod device\n"); + return; + } + + oh = omap_hwmod_lookup("davinci_emac"); + if (!oh) { + pr_err("Could not find davinci_emac hwmod\n"); + return; + } + + am35xx_emac_pdata.rmii_en = rmii_en; + + ret = omap_davinci_emac_dev_init(oh, &am35xx_emac_pdata, + sizeof(am35xx_emac_pdata)); + if (ret) { + pr_err("Could not build davinci_emac hwmod device\n"); + return; + } + + v = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); + v &= ~AM35XX_CPGMACSS_SW_RST; + omap_ctrl_writel(v, AM35XX_CONTROL_IP_SW_RESET); + omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); /* OCP barrier */ +} diff --git a/arch/arm/mach-omap2/am35xx-emac.h b/arch/arm/mach-omap2/am35xx-emac.h new file mode 100644 index 00000000000..15c6f9ce59a --- /dev/null +++ b/arch/arm/mach-omap2/am35xx-emac.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2011 Ilya Yanok, Emcraft Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#define AM35XX_DEFAULT_MDIO_FREQUENCY 1000000 + +#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE) +void am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en); +#else +static inline void am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en) {} +#endif diff --git a/arch/arm/mach-omap2/am35xx.h b/arch/arm/mach-omap2/am35xx.h new file mode 100644 index 00000000000..95594495fcf --- /dev/null +++ b/arch/arm/mach-omap2/am35xx.h @@ -0,0 +1,46 @@ +/*: + * Address mappings and base address for AM35XX specific interconnects + * and peripherals. + * + * Copyright (C) 2009 Texas Instruments + * + * Author: Sriramakrishnan <srk@ti.com> + * Vaibhav Hiremath <hvaibhav@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_ARCH_AM35XX_H +#define __ASM_ARCH_AM35XX_H + +/* + * Base addresses + * Note: OMAP3430 IVA2 memory space is being used for AM35xx IPSS modules + */ +#define AM35XX_IPSS_EMAC_BASE 0x5C000000 +#define AM35XX_IPSS_USBOTGSS_BASE 0x5C040000 +#define AM35XX_IPSS_HECC_BASE 0x5C050000 +#define AM35XX_IPSS_VPFE_BASE 0x5C060000 + + +/* HECC module specifc offset definitions */ +#define AM35XX_HECC_SCC_HECC_OFFSET (0x0) +#define AM35XX_HECC_SCC_RAM_OFFSET (0x3000) +#define AM35XX_HECC_RAM_OFFSET (0x3000) +#define AM35XX_HECC_MBOX_OFFSET (0x2000) +#define AM35XX_HECC_INT_LINE (0x0) +#define AM35XX_HECC_VERSION (0x1) + +#define AM35XX_EMAC_CNTRL_OFFSET (0x10000) +#define AM35XX_EMAC_CNTRL_MOD_OFFSET (0x0) +#define AM35XX_EMAC_CNTRL_RAM_OFFSET (0x20000) +#define AM35XX_EMAC_MDIO_OFFSET (0x30000) +#define AM35XX_IPSS_MDIO_BASE (AM35XX_IPSS_EMAC_BASE + \ + AM35XX_EMAC_MDIO_OFFSET) +#define AM35XX_EMAC_CNTRL_RAM_SIZE (0x2000) +#define AM35XX_EMAC_RAM_ADDR (AM3517_EMAC_BASE + \ + AM3517_EMAC_CNTRL_RAM_OFFSET) +#define AM35XX_EMAC_HW_RAM_ADDR (0x01E20000) + +#endif /* __ASM_ARCH_AM35XX_H */ diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c deleted file mode 100644 index 83fa37211d7..00000000000 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/board-2430sdp.c - * - * Copyright (C) 2006 Texas Instruments - * - * Modified from mach-omap2/board-generic.c - * - * Initial Code : Based on a patch from Komal Shah and Richard Woodruff - * Updated the Code for 2430 SDP : Syed Mohammed Khasim - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/partitions.h> -#include <linux/delay.h> -#include <linux/i2c/twl4030.h> -#include <linux/err.h> -#include <linux/clk.h> -#include <linux/io.h> - -#include <mach/hardware.h> -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/flash.h> - -#include <mach/gpio.h> -#include <mach/mux.h> -#include <mach/board.h> -#include <mach/common.h> -#include <mach/gpmc.h> - -#include "mmc-twl4030.h" - -#define SDP2430_FLASH_CS 0 -#define SDP2430_SMC91X_CS 5 - -static struct mtd_partition sdp2430_partitions[] = { - /* bootloader (U-Boot, etc) in first sector */ - { - .name = "bootloader", - .offset = 0, - .size = SZ_256K, - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, - /* bootloader params in the next sector */ - { - .name = "params", - .offset = MTDPART_OFS_APPEND, - .size = SZ_128K, - .mask_flags = 0, - }, - /* kernel */ - { - .name = "kernel", - .offset = MTDPART_OFS_APPEND, - .size = SZ_2M, - .mask_flags = 0 - }, - /* file system */ - { - .name = "filesystem", - .offset = MTDPART_OFS_APPEND, - .size = MTDPART_SIZ_FULL, - .mask_flags = 0 - } -}; - -static struct flash_platform_data sdp2430_flash_data = { - .map_name = "cfi_probe", - .width = 2, - .parts = sdp2430_partitions, - .nr_parts = ARRAY_SIZE(sdp2430_partitions), -}; - -static struct resource sdp2430_flash_resource = { - .start = SDP2430_CS0_BASE, - .end = SDP2430_CS0_BASE + SZ_64M - 1, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device sdp2430_flash_device = { - .name = "omapflash", - .id = 0, - .dev = { - .platform_data = &sdp2430_flash_data, - }, - .num_resources = 1, - .resource = &sdp2430_flash_resource, -}; - -static struct resource sdp2430_smc91x_resources[] = { - [0] = { - .start = SDP2430_CS0_BASE, - .end = SDP2430_CS0_BASE + SZ_64M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ), - .end = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ), - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, - }, -}; - -static struct platform_device sdp2430_smc91x_device = { - .name = "smc91x", - .id = -1, - .num_resources = ARRAY_SIZE(sdp2430_smc91x_resources), - .resource = sdp2430_smc91x_resources, -}; - -static struct platform_device *sdp2430_devices[] __initdata = { - &sdp2430_smc91x_device, - &sdp2430_flash_device, -}; - -static inline void __init sdp2430_init_smc91x(void) -{ - int eth_cs; - unsigned long cs_mem_base; - unsigned int rate; - struct clk *gpmc_fck; - - eth_cs = SDP2430_SMC91X_CS; - - gpmc_fck = clk_get(NULL, "gpmc_fck"); /* Always on ENABLE_ON_INIT */ - if (IS_ERR(gpmc_fck)) { - WARN_ON(1); - return; - } - - clk_enable(gpmc_fck); - rate = clk_get_rate(gpmc_fck); - - /* Make sure CS1 timings are correct, for 2430 always muxed */ - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1, 0x00011200); - - if (rate >= 160000000) { - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4); - } else if (rate >= 130000000) { - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4); - } else { /* rate = 100000000 */ - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2); - } - - if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) { - printk(KERN_ERR "Failed to request GPMC mem for smc91x\n"); - goto out; - } - - sdp2430_smc91x_resources[0].start = cs_mem_base + 0x300; - sdp2430_smc91x_resources[0].end = cs_mem_base + 0x30f; - udelay(100); - - if (gpio_request(OMAP24XX_ETHR_GPIO_IRQ, "SMC91x irq") < 0) { - printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n", - OMAP24XX_ETHR_GPIO_IRQ); - gpmc_cs_free(eth_cs); - goto out; - } - gpio_direction_input(OMAP24XX_ETHR_GPIO_IRQ); - -out: - clk_disable(gpmc_fck); - clk_put(gpmc_fck); -} - -static void __init omap_2430sdp_init_irq(void) -{ - omap2_init_common_hw(); - omap_init_irq(); - omap_gpio_init(); - sdp2430_init_smc91x(); -} - -static struct omap_uart_config sdp2430_uart_config __initdata = { - .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), -}; - -static struct omap_board_config_kernel sdp2430_config[] = { - {OMAP_TAG_UART, &sdp2430_uart_config}, -}; - - -static struct twl4030_gpio_platform_data sdp2430_gpio_data = { - .gpio_base = OMAP_MAX_GPIO_LINES, - .irq_base = TWL4030_GPIO_IRQ_BASE, - .irq_end = TWL4030_GPIO_IRQ_END, -}; - -static struct twl4030_platform_data sdp2430_twldata = { - .irq_base = TWL4030_IRQ_BASE, - .irq_end = TWL4030_IRQ_END, - - /* platform_data for children goes here */ - .gpio = &sdp2430_gpio_data, -}; - -static struct i2c_board_info __initdata sdp2430_i2c_boardinfo[] = { - { - I2C_BOARD_INFO("twl4030", 0x48), - .flags = I2C_CLIENT_WAKE, - .irq = INT_24XX_SYS_NIRQ, - .platform_data = &sdp2430_twldata, - }, -}; - -static int __init omap2430_i2c_init(void) -{ - omap_register_i2c_bus(1, 400, NULL, 0); - omap_register_i2c_bus(2, 2600, sdp2430_i2c_boardinfo, - ARRAY_SIZE(sdp2430_i2c_boardinfo)); - return 0; -} - -static struct twl4030_hsmmc_info mmc[] __initdata = { - { - .mmc = 1, - .wires = 4, - .gpio_cd = -EINVAL, - .gpio_wp = -EINVAL, - .ext_clock = 1, - }, - {} /* Terminator */ -}; - -static void __init omap_2430sdp_init(void) -{ - omap2430_i2c_init(); - - platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices)); - omap_board_config = sdp2430_config; - omap_board_config_size = ARRAY_SIZE(sdp2430_config); - omap_serial_init(); - twl4030_mmc_init(mmc); -} - -static void __init omap_2430sdp_map_io(void) -{ - omap2_set_globals_243x(); - omap2_map_common_io(); -} - -MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board") - /* Maintainer: Syed Khasim - Texas Instruments Inc */ - .phys_io = 0x48000000, - .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, - .boot_params = 0x80000100, - .map_io = omap_2430sdp_map_io, - .init_irq = omap_2430sdp_init_irq, - .init_machine = omap_2430sdp_init, - .timer = &omap_timer, -MACHINE_END diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c new file mode 100644 index 00000000000..d95d0ef1354 --- /dev/null +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -0,0 +1,633 @@ +/* + * linux/arch/arm/mach-omap2/board-3430sdp.c + * + * Copyright (C) 2007 Texas Instruments + * + * Modified from mach-omap2/board-generic.c + * + * Initial code: Syed Mohammed Khasim + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/input.h> +#include <linux/input/matrix_keypad.h> +#include <linux/spi/spi.h> +#include <linux/i2c/twl.h> +#include <linux/regulator/machine.h> +#include <linux/io.h> +#include <linux/gpio.h> +#include <linux/mmc/host.h> +#include <linux/platform_data/spi-omap2-mcspi.h> +#include <linux/platform_data/omap-twl4030.h> +#include <linux/usb/phy.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include "common.h" +#include <linux/omap-dma.h> +#include <video/omapdss.h> +#include <video/omap-panel-data.h> + +#include "gpmc.h" +#include "gpmc-smc91x.h" + +#include "soc.h" +#include "board-flash.h" +#include "mux.h" +#include "sdram-qimonda-hyb18m512160af-6.h" +#include "hsmmc.h" +#include "pm.h" +#include "control.h" +#include "common-board-devices.h" + +#define CONFIG_DISABLE_HFCLK 1 + +#define SDP3430_TS_GPIO_IRQ_SDPV1 3 +#define SDP3430_TS_GPIO_IRQ_SDPV2 2 + +#define ENABLE_VAUX3_DEDICATED 0x03 +#define ENABLE_VAUX3_DEV_GRP 0x20 + +#define TWL4030_MSECURE_GPIO 22 + +static uint32_t board_keymap[] = { + KEY(0, 0, KEY_LEFT), + KEY(0, 1, KEY_RIGHT), + KEY(0, 2, KEY_A), + KEY(0, 3, KEY_B), + KEY(0, 4, KEY_C), + KEY(1, 0, KEY_DOWN), + KEY(1, 1, KEY_UP), + KEY(1, 2, KEY_E), + KEY(1, 3, KEY_F), + KEY(1, 4, KEY_G), + KEY(2, 0, KEY_ENTER), + KEY(2, 1, KEY_I), + KEY(2, 2, KEY_J), + KEY(2, 3, KEY_K), + KEY(2, 4, KEY_3), + KEY(3, 0, KEY_M), + KEY(3, 1, KEY_N), + KEY(3, 2, KEY_O), + KEY(3, 3, KEY_P), + KEY(3, 4, KEY_Q), + KEY(4, 0, KEY_R), + KEY(4, 1, KEY_4), + KEY(4, 2, KEY_T), + KEY(4, 3, KEY_U), + KEY(4, 4, KEY_D), + KEY(5, 0, KEY_V), + KEY(5, 1, KEY_W), + KEY(5, 2, KEY_L), + KEY(5, 3, KEY_S), + KEY(5, 4, KEY_H), + 0 +}; + +static struct matrix_keymap_data board_map_data = { + .keymap = board_keymap, + .keymap_size = ARRAY_SIZE(board_keymap), +}; + +static struct twl4030_keypad_data sdp3430_kp_data = { + .keymap_data = &board_map_data, + .rows = 5, + .cols = 6, + .rep = 1, +}; + +#define SDP3430_LCD_PANEL_BACKLIGHT_GPIO 8 +#define SDP3430_LCD_PANEL_ENABLE_GPIO 5 + +static void __init sdp3430_display_init(void) +{ + int r; + + /* + * the backlight GPIO doesn't directly go to the panel, it enables + * an internal circuit on 3430sdp to create the signal V_BKL_28V, + * this is connected to LED+ pin of the sharp panel. This GPIO + * is left enabled in the board file, and not passed to the panel + * as platform_data. + */ + r = gpio_request_one(SDP3430_LCD_PANEL_BACKLIGHT_GPIO, + GPIOF_OUT_INIT_HIGH, "LCD Backlight"); + if (r) + pr_err("failed to get LCD Backlight GPIO\n"); + +} + +static struct panel_sharp_ls037v7dw01_platform_data sdp3430_lcd_pdata = { + .name = "lcd", + .source = "dpi.0", + + .data_lines = 16, + + .resb_gpio = SDP3430_LCD_PANEL_ENABLE_GPIO, + .ini_gpio = -1, + .mo_gpio = -1, + .lr_gpio = -1, + .ud_gpio = -1, +}; + +static struct platform_device sdp3430_lcd_device = { + .name = "panel-sharp-ls037v7dw01", + .id = 0, + .dev.platform_data = &sdp3430_lcd_pdata, +}; + +static struct connector_dvi_platform_data sdp3430_dvi_connector_pdata = { + .name = "dvi", + .source = "tfp410.0", + .i2c_bus_num = -1, +}; + +static struct platform_device sdp3430_dvi_connector_device = { + .name = "connector-dvi", + .id = 0, + .dev.platform_data = &sdp3430_dvi_connector_pdata, +}; + +static struct encoder_tfp410_platform_data sdp3430_tfp410_pdata = { + .name = "tfp410.0", + .source = "dpi.0", + .data_lines = 24, + .power_down_gpio = -1, +}; + +static struct platform_device sdp3430_tfp410_device = { + .name = "tfp410", + .id = 0, + .dev.platform_data = &sdp3430_tfp410_pdata, +}; + +static struct connector_atv_platform_data sdp3430_tv_pdata = { + .name = "tv", + .source = "venc.0", + .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, + .invert_polarity = false, +}; + +static struct platform_device sdp3430_tv_connector_device = { + .name = "connector-analog-tv", + .id = 0, + .dev.platform_data = &sdp3430_tv_pdata, +}; + +static struct omap_dss_board_info sdp3430_dss_data = { + .default_display_name = "lcd", +}; + +static struct omap2_hsmmc_info mmc[] = { + { + .mmc = 1, + /* 8 bits (default) requires S6.3 == ON, + * so the SIM card isn't used; else 4 bits. + */ + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, + .gpio_wp = 4, + .deferred = true, + }, + { + .mmc = 2, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, + .gpio_wp = 7, + .deferred = true, + }, + {} /* Terminator */ +}; + +static struct omap_tw4030_pdata omap_twl4030_audio_data = { + .voice_connected = true, + .custom_routing = true, + + .has_hs = OMAP_TWL4030_LEFT | OMAP_TWL4030_RIGHT, + .has_hf = OMAP_TWL4030_LEFT | OMAP_TWL4030_RIGHT, + + .has_mainmic = true, + .has_submic = true, + .has_hsmic = true, + .has_linein = OMAP_TWL4030_LEFT | OMAP_TWL4030_RIGHT, +}; + +static int sdp3430_twl_gpio_setup(struct device *dev, + unsigned gpio, unsigned ngpio) +{ + /* gpio + 0 is "mmc0_cd" (input/IRQ), + * gpio + 1 is "mmc1_cd" (input/IRQ) + */ + mmc[0].gpio_cd = gpio + 0; + mmc[1].gpio_cd = gpio + 1; + omap_hsmmc_late_init(mmc); + + /* gpio + 7 is "sub_lcd_en_bkl" (output/PWM1) */ + gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "sub_lcd_en_bkl"); + + /* gpio + 15 is "sub_lcd_nRST" (output) */ + gpio_request_one(gpio + 15, GPIOF_OUT_INIT_LOW, "sub_lcd_nRST"); + + omap_twl4030_audio_data.jack_detect = gpio + 2; + omap_twl4030_audio_init("SDP3430", &omap_twl4030_audio_data); + + return 0; +} + +static struct twl4030_gpio_platform_data sdp3430_gpio_data = { + .pulldowns = BIT(2) | BIT(6) | BIT(8) | BIT(13) + | BIT(16) | BIT(17), + .setup = sdp3430_twl_gpio_setup, +}; + +/* regulator consumer mappings */ + +/* ads7846 on SPI */ +static struct regulator_consumer_supply sdp3430_vaux3_supplies[] = { + REGULATOR_SUPPLY("vcc", "spi1.0"), +}; + +static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = { + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), +}; + +static struct regulator_consumer_supply sdp3430_vsim_supplies[] = { + REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"), +}; + +static struct regulator_consumer_supply sdp3430_vmmc2_supplies[] = { + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"), +}; + +/* + * Apply all the fixed voltages since most versions of U-Boot + * don't bother with that initialization. + */ + +/* VAUX1 for mainboard (irda and sub-lcd) */ +static struct regulator_init_data sdp3430_vaux1 = { + .constraints = { + .min_uV = 2800000, + .max_uV = 2800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +/* VAUX2 for camera module */ +static struct regulator_init_data sdp3430_vaux2 = { + .constraints = { + .min_uV = 2800000, + .max_uV = 2800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +/* VAUX3 for LCD board */ +static struct regulator_init_data sdp3430_vaux3 = { + .constraints = { + .min_uV = 2800000, + .max_uV = 2800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(sdp3430_vaux3_supplies), + .consumer_supplies = sdp3430_vaux3_supplies, +}; + +/* VAUX4 for OMAP VDD_CSI2 (camera) */ +static struct regulator_init_data sdp3430_vaux4 = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */ +static struct regulator_init_data sdp3430_vmmc1 = { + .constraints = { + .min_uV = 1850000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(sdp3430_vmmc1_supplies), + .consumer_supplies = sdp3430_vmmc1_supplies, +}; + +/* VMMC2 for MMC2 card */ +static struct regulator_init_data sdp3430_vmmc2 = { + .constraints = { + .min_uV = 1850000, + .max_uV = 1850000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(sdp3430_vmmc2_supplies), + .consumer_supplies = sdp3430_vmmc2_supplies, +}; + +/* VSIM for OMAP VDD_MMC1A (i/o for DAT4..DAT7) */ +static struct regulator_init_data sdp3430_vsim = { + .constraints = { + .min_uV = 1800000, + .max_uV = 3000000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(sdp3430_vsim_supplies), + .consumer_supplies = sdp3430_vsim_supplies, +}; + +static struct twl4030_platform_data sdp3430_twldata = { + /* platform_data for children goes here */ + .gpio = &sdp3430_gpio_data, + .keypad = &sdp3430_kp_data, + + .vaux1 = &sdp3430_vaux1, + .vaux2 = &sdp3430_vaux2, + .vaux3 = &sdp3430_vaux3, + .vaux4 = &sdp3430_vaux4, + .vmmc1 = &sdp3430_vmmc1, + .vmmc2 = &sdp3430_vmmc2, + .vsim = &sdp3430_vsim, +}; + +static int __init omap3430_i2c_init(void) +{ + /* i2c1 for PMIC only */ + omap3_pmic_get_config(&sdp3430_twldata, + TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_BCI | + TWL_COMMON_PDATA_MADC | TWL_COMMON_PDATA_AUDIO, + TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2); + sdp3430_twldata.vdac->constraints.apply_uV = true; + sdp3430_twldata.vpll2->constraints.apply_uV = true; + sdp3430_twldata.vpll2->constraints.name = "VDVI"; + + sdp3430_twldata.audio->codec->hs_extmute = 1; + sdp3430_twldata.audio->codec->hs_extmute_gpio = -EINVAL; + + omap3_pmic_init("twl4030", &sdp3430_twldata); + + /* i2c2 on camera connector (for sensor control) and optional isp1301 */ + omap_register_i2c_bus(2, 400, NULL, 0); + /* i2c3 on display connector (for DVI, tfp410) */ + omap_register_i2c_bus(3, 400, NULL, 0); + return 0; +} + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + +static struct omap_smc91x_platform_data board_smc91x_data = { + .cs = 3, + .flags = GPMC_MUX_ADD_DATA | GPMC_TIMINGS_SMC91C96 | + IORESOURCE_IRQ_LOWLEVEL, +}; + +static void __init board_smc91x_init(void) +{ + if (omap_rev() > OMAP3430_REV_ES1_0) + board_smc91x_data.gpio_irq = 6; + else + board_smc91x_data.gpio_irq = 29; + + gpmc_smc91x_init(&board_smc91x_data); +} + +#else + +static inline void board_smc91x_init(void) +{ +} + +#endif + +static void enable_board_wakeup_source(void) +{ + /* T2 interrupt line (keypad) */ + omap_mux_init_signal("sys_nirq", + OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); +} + +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 1, + .reset_gpio = 57, + .vcc_gpio = -EINVAL, + }, + { + .port = 2, + .reset_gpio = 61, + .vcc_gpio = -EINVAL, + }, +}; + +static struct usbhs_omap_platform_data usbhs_bdata __initdata = { + + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, +}; + +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#else +#define board_mux NULL +#endif + +/* + * SDP3430 V2 Board CS organization + * Different from SDP3430 V1. Now 4 switches used to specify CS + * + * See also the Switch S8 settings in the comments. + */ +static char chip_sel_3430[][GPMC_CS_NUM] = { + {PDC_NOR, PDC_NAND, PDC_ONENAND, DBG_MPDB, 0, 0, 0, 0}, /* S8:1111 */ + {PDC_ONENAND, PDC_NAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1110 */ + {PDC_NAND, PDC_ONENAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1101 */ +}; + +static struct mtd_partition sdp_nor_partitions[] = { + /* bootloader (U-Boot, etc) in first sector */ + { + .name = "Bootloader-NOR", + .offset = 0, + .size = SZ_256K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* bootloader params in the next sector */ + { + .name = "Params-NOR", + .offset = MTDPART_OFS_APPEND, + .size = SZ_256K, + .mask_flags = 0, + }, + /* kernel */ + { + .name = "Kernel-NOR", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M, + .mask_flags = 0 + }, + /* file system */ + { + .name = "Filesystem-NOR", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0 + } +}; + +static struct mtd_partition sdp_onenand_partitions[] = { + { + .name = "X-Loader-OneNAND", + .offset = 0, + .size = 4 * (64 * 2048), + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "U-Boot-OneNAND", + .offset = MTDPART_OFS_APPEND, + .size = 2 * (64 * 2048), + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "U-Boot Environment-OneNAND", + .offset = MTDPART_OFS_APPEND, + .size = 1 * (64 * 2048), + }, + { + .name = "Kernel-OneNAND", + .offset = MTDPART_OFS_APPEND, + .size = 16 * (64 * 2048), + }, + { + .name = "File System-OneNAND", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition sdp_nand_partitions[] = { + /* All the partition sizes are listed in terms of NAND block size */ + { + .name = "X-Loader-NAND", + .offset = 0, + .size = 4 * (64 * 2048), + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "U-Boot-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */ + .size = 10 * (64 * 2048), + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "Boot Env-NAND", + + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c0000 */ + .size = 6 * (64 * 2048), + }, + { + .name = "Kernel-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */ + .size = 40 * (64 * 2048), + }, + { + .name = "File System - NAND", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, /* Offset = 0x780000 */ + }, +}; + +static struct flash_partitions sdp_flash_partitions[] = { + { + .parts = sdp_nor_partitions, + .nr_parts = ARRAY_SIZE(sdp_nor_partitions), + }, + { + .parts = sdp_onenand_partitions, + .nr_parts = ARRAY_SIZE(sdp_onenand_partitions), + }, + { + .parts = sdp_nand_partitions, + .nr_parts = ARRAY_SIZE(sdp_nand_partitions), + }, +}; + +static void __init omap_3430sdp_init(void) +{ + int gpio_pendown; + + omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); + omap_hsmmc_init(mmc); + omap3430_i2c_init(); + omap_display_init(&sdp3430_dss_data); + platform_device_register(&sdp3430_lcd_device); + platform_device_register(&sdp3430_tfp410_device); + platform_device_register(&sdp3430_dvi_connector_device); + platform_device_register(&sdp3430_tv_connector_device); + + if (omap_rev() > OMAP3430_REV_ES1_0) + gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV2; + else + gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV1; + omap_ads7846_init(1, gpio_pendown, 310, NULL); + omap_serial_init(); + omap_sdrc_init(hyb18m512160af6_sdrc_params, NULL); + usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); + usb_musb_init(NULL); + board_smc91x_init(); + board_flash_init(sdp_flash_partitions, chip_sel_3430, 0); + sdp3430_display_init(); + enable_board_wakeup_source(); + + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); + usbhs_init(&usbhs_bdata); +} + +MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board") + /* Maintainer: Syed Khasim - Texas Instruments Inc */ + .atag_offset = 0x100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap3430_init_early, + .init_irq = omap3_init_irq, + .handle_irq = omap3_intc_handle_irq, + .init_machine = omap_3430sdp_init, + .init_late = omap3430_init_late, + .init_time = omap3_sync32k_timer_init, + .restart = omap3xxx_restart, +MACHINE_END diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c new file mode 100644 index 00000000000..0d499a1878f --- /dev/null +++ b/arch/arm/mach-omap2/board-am3517crane.c @@ -0,0 +1,150 @@ +/* + * Support for AM3517/05 Craneboard + * http://www.mistralsolutions.com/products/craneboard.php + * + * Copyright (C) 2010 Mistral Solutions Pvt Ltd. <www.mistralsolutions.com> + * Author: R.Srinath <srinath@mistralsolutions.com> + * + * Based on mach-omap2/board-am3517evm.c + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, + * whether express or implied; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/gpio.h> +#include <linux/mfd/tps65910.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/partitions.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include "common.h" +#include "common-board-devices.h" +#include "board-flash.h" + +#include "am35xx-emac.h" +#include "mux.h" +#include "control.h" + +#define GPIO_USB_POWER 35 +#define GPIO_USB_NRESET 38 + +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#endif + +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 1, + .reset_gpio = GPIO_USB_NRESET, + .vcc_gpio = GPIO_USB_POWER, + .vcc_polarity = 1, + }, +}; + +static struct usbhs_omap_platform_data usbhs_bdata __initdata = { + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, +}; + +static struct mtd_partition crane_nand_partitions[] = { + { + .name = "X-Loader", + .offset = 0, + .size = 4 * NAND_BLOCK_SIZE, + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "U-Boot", + .offset = MTDPART_OFS_APPEND, + .size = 14 * NAND_BLOCK_SIZE, + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "U-Boot Env", + .offset = MTDPART_OFS_APPEND, + .size = 2 * NAND_BLOCK_SIZE, + }, + { + .name = "Kernel", + .offset = MTDPART_OFS_APPEND, + .size = 40 * NAND_BLOCK_SIZE, + }, + { + .name = "File System", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct tps65910_board tps65910_pdata = { + .irq = 7 + OMAP_INTC_START, + .en_ck32k_xtal = true, +}; + +static struct i2c_board_info __initdata tps65910_board_info[] = { + { + I2C_BOARD_INFO("tps65910", 0x2d), + .platform_data = &tps65910_pdata, + }, +}; + +static void __init am3517_crane_i2c_init(void) +{ + omap_register_i2c_bus(1, 2600, tps65910_board_info, + ARRAY_SIZE(tps65910_board_info)); +} + +static void __init am3517_crane_init(void) +{ + omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); + omap_serial_init(); + omap_sdrc_init(NULL, NULL); + board_nand_init(crane_nand_partitions, + ARRAY_SIZE(crane_nand_partitions), 0, + NAND_BUSWIDTH_16, NULL); + am3517_crane_i2c_init(); + + /* Configure GPIO for EHCI port */ + if (omap_mux_init_gpio(GPIO_USB_NRESET, OMAP_PIN_OUTPUT)) { + pr_err("Can not configure mux for GPIO_USB_NRESET %d\n", + GPIO_USB_NRESET); + return; + } + + if (omap_mux_init_gpio(GPIO_USB_POWER, OMAP_PIN_OUTPUT)) { + pr_err("Can not configure mux for GPIO_USB_POWER %d\n", + GPIO_USB_POWER); + return; + } + + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); + usbhs_init(&usbhs_bdata); + am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1); +} + +MACHINE_START(CRANEBOARD, "AM3517/05 CRANEBOARD") + .atag_offset = 0x100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = am35xx_init_early, + .init_irq = omap3_init_irq, + .handle_irq = omap3_intc_handle_irq, + .init_machine = am3517_crane_init, + .init_late = am35xx_init_late, + .init_time = omap3_sync32k_timer_init, + .restart = omap3xxx_restart, +MACHINE_END diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c new file mode 100644 index 00000000000..4f9383cecf7 --- /dev/null +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -0,0 +1,374 @@ +/* + * linux/arch/arm/mach-omap2/board-am3517evm.c + * + * Copyright (C) 2009 Texas Instruments Incorporated + * Author: Ranjith Lohithakshan <ranjithl@ti.com> + * + * Based on mach-omap2/board-omap3evm.c + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, + * whether express or implied; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/clk.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/platform_data/pca953x.h> +#include <linux/can/platform/ti_hecc.h> +#include <linux/davinci_emac.h> +#include <linux/mmc/host.h> +#include <linux/usb/musb.h> +#include <linux/platform_data/gpio-omap.h> + +#include "am35xx.h" +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include "common.h" +#include <video/omapdss.h> +#include <video/omap-panel-data.h> + +#include "am35xx-emac.h" +#include "mux.h" +#include "control.h" +#include "hsmmc.h" + +#define LCD_PANEL_PWR 176 +#define LCD_PANEL_BKLIGHT_PWR 182 +#define LCD_PANEL_PWM 181 + +static struct i2c_board_info __initdata am3517evm_i2c1_boardinfo[] = { + { + I2C_BOARD_INFO("s35390a", 0x30), + }, +}; + +/* + * RTC - S35390A + */ +#define GPIO_RTCS35390A_IRQ 55 + +static void __init am3517_evm_rtc_init(void) +{ + int r; + + omap_mux_init_gpio(GPIO_RTCS35390A_IRQ, OMAP_PIN_INPUT_PULLUP); + + r = gpio_request_one(GPIO_RTCS35390A_IRQ, GPIOF_IN, "rtcs35390a-irq"); + if (r < 0) { + printk(KERN_WARNING "failed to request GPIO#%d\n", + GPIO_RTCS35390A_IRQ); + return; + } + + am3517evm_i2c1_boardinfo[0].irq = gpio_to_irq(GPIO_RTCS35390A_IRQ); +} + +/* + * I2C GPIO Expander - TCA6416 + */ + +/* Mounted on Base-Board */ +static struct pca953x_platform_data am3517evm_gpio_expander_info_0 = { + .gpio_base = OMAP_MAX_GPIO_LINES, +}; +static struct i2c_board_info __initdata am3517evm_i2c2_boardinfo[] = { + { + I2C_BOARD_INFO("tlv320aic23", 0x1A), + }, + { + I2C_BOARD_INFO("tca6416", 0x21), + .platform_data = &am3517evm_gpio_expander_info_0, + }, +}; + +/* Mounted on UI Card */ +static struct pca953x_platform_data am3517evm_ui_gpio_expander_info_1 = { + .gpio_base = OMAP_MAX_GPIO_LINES + 16, +}; +static struct pca953x_platform_data am3517evm_ui_gpio_expander_info_2 = { + .gpio_base = OMAP_MAX_GPIO_LINES + 32, +}; +static struct i2c_board_info __initdata am3517evm_i2c3_boardinfo[] = { + { + I2C_BOARD_INFO("tca6416", 0x20), + .platform_data = &am3517evm_ui_gpio_expander_info_1, + }, + { + I2C_BOARD_INFO("tca6416", 0x21), + .platform_data = &am3517evm_ui_gpio_expander_info_2, + }, +}; + +static int __init am3517_evm_i2c_init(void) +{ + omap_register_i2c_bus(1, 400, NULL, 0); + omap_register_i2c_bus(2, 400, am3517evm_i2c2_boardinfo, + ARRAY_SIZE(am3517evm_i2c2_boardinfo)); + omap_register_i2c_bus(3, 400, am3517evm_i2c3_boardinfo, + ARRAY_SIZE(am3517evm_i2c3_boardinfo)); + + return 0; +} + +static const struct display_timing am3517_evm_lcd_videomode = { + .pixelclock = { 0, 9000000, 0 }, + + .hactive = { 0, 480, 0 }, + .hfront_porch = { 0, 3, 0 }, + .hback_porch = { 0, 2, 0 }, + .hsync_len = { 0, 42, 0 }, + + .vactive = { 0, 272, 0 }, + .vfront_porch = { 0, 3, 0 }, + .vback_porch = { 0, 2, 0 }, + .vsync_len = { 0, 11, 0 }, + + .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | + DISPLAY_FLAGS_DE_LOW | DISPLAY_FLAGS_PIXDATA_POSEDGE, +}; + +static struct panel_dpi_platform_data am3517_evm_lcd_pdata = { + .name = "lcd", + .source = "dpi.0", + + .data_lines = 16, + + .display_timing = &am3517_evm_lcd_videomode, + + .enable_gpio = LCD_PANEL_PWR, + .backlight_gpio = LCD_PANEL_BKLIGHT_PWR, +}; + +static struct platform_device am3517_evm_lcd_device = { + .name = "panel-dpi", + .id = 0, + .dev.platform_data = &am3517_evm_lcd_pdata, +}; + +static struct connector_dvi_platform_data am3517_evm_dvi_connector_pdata = { + .name = "dvi", + .source = "tfp410.0", + .i2c_bus_num = -1, +}; + +static struct platform_device am3517_evm_dvi_connector_device = { + .name = "connector-dvi", + .id = 0, + .dev.platform_data = &am3517_evm_dvi_connector_pdata, +}; + +static struct encoder_tfp410_platform_data am3517_evm_tfp410_pdata = { + .name = "tfp410.0", + .source = "dpi.0", + .data_lines = 24, + .power_down_gpio = -1, +}; + +static struct platform_device am3517_evm_tfp410_device = { + .name = "tfp410", + .id = 0, + .dev.platform_data = &am3517_evm_tfp410_pdata, +}; + +static struct connector_atv_platform_data am3517_evm_tv_pdata = { + .name = "tv", + .source = "venc.0", + .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, + .invert_polarity = false, +}; + +static struct platform_device am3517_evm_tv_connector_device = { + .name = "connector-analog-tv", + .id = 0, + .dev.platform_data = &am3517_evm_tv_pdata, +}; + +static struct omap_dss_board_info am3517_evm_dss_data = { + .default_display_name = "lcd", +}; + +static void __init am3517_evm_display_init(void) +{ + gpio_request_one(LCD_PANEL_PWM, GPIOF_OUT_INIT_HIGH, "lcd panel pwm"); + + omap_display_init(&am3517_evm_dss_data); + + platform_device_register(&am3517_evm_tfp410_device); + platform_device_register(&am3517_evm_dvi_connector_device); + platform_device_register(&am3517_evm_lcd_device); + platform_device_register(&am3517_evm_tv_connector_device); +} + +/* + * Board initialization + */ + +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 500, + .set_phy_power = am35x_musb_phy_power, + .clear_irq = am35x_musb_clear_irq, + .set_mode = am35x_set_mode, + .reset = am35x_musb_reset, +}; + +static __init void am3517_evm_musb_init(void) +{ + u32 devconf2; + + /* + * Set up USB clock/mode in the DEVCONF2 register. + */ + devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); + + /* USB2.0 PHY reference clock is 13 MHz */ + devconf2 &= ~(CONF2_REFFREQ | CONF2_OTGMODE | CONF2_PHY_GPIOMODE); + devconf2 |= CONF2_REFFREQ_13MHZ | CONF2_SESENDEN | CONF2_VBDTCTEN + | CONF2_DATPOL; + + omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); + + usb_musb_init(&musb_board_data); +} + +static __init void am3517_evm_mcbsp1_init(void) +{ + u32 devconf0; + + /* McBSP1 CLKR/FSR signal to be connected to CLKX/FSX pin */ + devconf0 = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); + devconf0 |= OMAP2_MCBSP1_CLKR_MASK | OMAP2_MCBSP1_FSR_MASK; + omap_ctrl_writel(devconf0, OMAP2_CONTROL_DEVCONF0); +} + +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 1, + .reset_gpio = 57, + .vcc_gpio = -EINVAL, + }, +}; + +static struct usbhs_omap_platform_data usbhs_bdata __initdata = { + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, +}; + +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + /* USB OTG DRVVBUS offset = 0x212 */ + OMAP3_MUX(SAD2D_MCAD23, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN), + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#endif + + +static struct resource am3517_hecc_resources[] = { + { + .start = AM35XX_IPSS_HECC_BASE, + .end = AM35XX_IPSS_HECC_BASE + 0x3FFF, + .flags = IORESOURCE_MEM, + }, + { + .start = 24 + OMAP_INTC_START, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device am3517_hecc_device = { + .name = "ti_hecc", + .id = -1, + .num_resources = ARRAY_SIZE(am3517_hecc_resources), + .resource = am3517_hecc_resources, +}; + +static struct ti_hecc_platform_data am3517_evm_hecc_pdata = { + .scc_hecc_offset = AM35XX_HECC_SCC_HECC_OFFSET, + .scc_ram_offset = AM35XX_HECC_SCC_RAM_OFFSET, + .hecc_ram_offset = AM35XX_HECC_RAM_OFFSET, + .mbx_offset = AM35XX_HECC_MBOX_OFFSET, + .int_line = AM35XX_HECC_INT_LINE, + .version = AM35XX_HECC_VERSION, +}; + +static void am3517_evm_hecc_init(struct ti_hecc_platform_data *pdata) +{ + am3517_hecc_device.dev.platform_data = pdata; + platform_device_register(&am3517_hecc_device); +} + +static struct omap2_hsmmc_info mmc[] = { + { + .mmc = 1, + .caps = MMC_CAP_4_BIT_DATA, + .gpio_cd = 127, + .gpio_wp = 126, + }, + { + .mmc = 2, + .caps = MMC_CAP_4_BIT_DATA, + .gpio_cd = 128, + .gpio_wp = 129, + }, + {} /* Terminator */ +}; + +static void __init am3517_evm_init(void) +{ + omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); + + am3517_evm_i2c_init(); + + am3517_evm_display_init(); + + omap_serial_init(); + omap_sdrc_init(NULL, NULL); + + /* Configure GPIO for EHCI port */ + omap_mux_init_gpio(57, OMAP_PIN_OUTPUT); + + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); + usbhs_init(&usbhs_bdata); + am3517_evm_hecc_init(&am3517_evm_hecc_pdata); + + /* RTC - S35390A */ + am3517_evm_rtc_init(); + + i2c_register_board_info(1, am3517evm_i2c1_boardinfo, + ARRAY_SIZE(am3517evm_i2c1_boardinfo)); + /*Ethernet*/ + am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1); + + /* MUSB */ + am3517_evm_musb_init(); + + /* McBSP1 */ + am3517_evm_mcbsp1_init(); + + /* MMC init function */ + omap_hsmmc_init(mmc); +} + +MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM") + .atag_offset = 0x100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = am35xx_init_early, + .init_irq = omap3_init_irq, + .handle_irq = omap3_intc_handle_irq, + .init_machine = am3517_evm_init, + .init_late = am35xx_init_late, + .init_time = omap3_sync32k_timer_init, + .restart = omap3xxx_restart, +MACHINE_END diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c deleted file mode 100644 index 0a7b24ba165..00000000000 --- a/arch/arm/mach-omap2/board-apollon.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/board-apollon.c - * - * Copyright (C) 2005,2006 Samsung Electronics - * Author: Kyungmin Park <kyungmin.park@samsung.com> - * - * Modified from mach-omap/omap2/board-h4.c - * - * Code for apollon OMAP2 board. Should work on many OMAP2 systems where - * the bootloader passes the board-specific data to the kernel. - * Do not put any board specific code to this file; create a new machine - * type if you need custom low-level initializations. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/partitions.h> -#include <linux/mtd/onenand.h> -#include <linux/delay.h> -#include <linux/leds.h> -#include <linux/err.h> -#include <linux/clk.h> - -#include <mach/hardware.h> -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/flash.h> - -#include <mach/gpio.h> -#include <mach/led.h> -#include <mach/mux.h> -#include <mach/usb.h> -#include <mach/board.h> -#include <mach/common.h> -#include <mach/gpmc.h> -#include <mach/control.h> - -/* LED & Switch macros */ -#define LED0_GPIO13 13 -#define LED1_GPIO14 14 -#define LED2_GPIO15 15 -#define SW_ENTER_GPIO16 16 -#define SW_UP_GPIO17 17 -#define SW_DOWN_GPIO58 58 - -#define APOLLON_FLASH_CS 0 -#define APOLLON_ETH_CS 1 - -static struct mtd_partition apollon_partitions[] = { - { - .name = "X-Loader + U-Boot", - .offset = 0, - .size = SZ_128K, - .mask_flags = MTD_WRITEABLE, - }, - { - .name = "params", - .offset = MTDPART_OFS_APPEND, - .size = SZ_128K, - }, - { - .name = "kernel", - .offset = MTDPART_OFS_APPEND, - .size = SZ_2M, - }, - { - .name = "rootfs", - .offset = MTDPART_OFS_APPEND, - .size = SZ_16M, - }, - { - .name = "filesystem00", - .offset = MTDPART_OFS_APPEND, - .size = SZ_32M, - }, - { - .name = "filesystem01", - .offset = MTDPART_OFS_APPEND, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct flash_platform_data apollon_flash_data = { - .parts = apollon_partitions, - .nr_parts = ARRAY_SIZE(apollon_partitions), -}; - -static struct resource apollon_flash_resource[] = { - [0] = { - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device apollon_onenand_device = { - .name = "onenand", - .id = -1, - .dev = { - .platform_data = &apollon_flash_data, - }, - .num_resources = ARRAY_SIZE(apollon_flash_resource), - .resource = apollon_flash_resource, -}; - -static void __init apollon_flash_init(void) -{ - unsigned long base; - - if (gpmc_cs_request(APOLLON_FLASH_CS, SZ_128K, &base) < 0) { - printk(KERN_ERR "Cannot request OneNAND GPMC CS\n"); - return; - } - apollon_flash_resource[0].start = base; - apollon_flash_resource[0].end = base + SZ_128K - 1; -} - -static struct resource apollon_smc91x_resources[] = { - [0] = { - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ), - .end = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ), - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, - }, -}; - -static struct platform_device apollon_smc91x_device = { - .name = "smc91x", - .id = -1, - .num_resources = ARRAY_SIZE(apollon_smc91x_resources), - .resource = apollon_smc91x_resources, -}; - -static struct platform_device apollon_lcd_device = { - .name = "apollon_lcd", - .id = -1, -}; - -static struct omap_led_config apollon_led_config[] = { - { - .cdev = { - .name = "apollon:led0", - }, - .gpio = LED0_GPIO13, - }, - { - .cdev = { - .name = "apollon:led1", - }, - .gpio = LED1_GPIO14, - }, - { - .cdev = { - .name = "apollon:led2", - }, - .gpio = LED2_GPIO15, - }, -}; - -static struct omap_led_platform_data apollon_led_data = { - .nr_leds = ARRAY_SIZE(apollon_led_config), - .leds = apollon_led_config, -}; - -static struct platform_device apollon_led_device = { - .name = "omap-led", - .id = -1, - .dev = { - .platform_data = &apollon_led_data, - }, -}; - -static struct platform_device *apollon_devices[] __initdata = { - &apollon_onenand_device, - &apollon_smc91x_device, - &apollon_lcd_device, - &apollon_led_device, -}; - -static inline void __init apollon_init_smc91x(void) -{ - unsigned long base; - - unsigned int rate; - struct clk *gpmc_fck; - int eth_cs; - - gpmc_fck = clk_get(NULL, "gpmc_fck"); /* Always on ENABLE_ON_INIT */ - if (IS_ERR(gpmc_fck)) { - WARN_ON(1); - return; - } - - clk_enable(gpmc_fck); - rate = clk_get_rate(gpmc_fck); - - eth_cs = APOLLON_ETH_CS; - - /* Make sure CS1 timings are correct */ - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1, 0x00011200); - - if (rate >= 160000000) { - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4); - } else if (rate >= 130000000) { - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4); - } else {/* rate = 100000000 */ - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2); - } - - if (gpmc_cs_request(APOLLON_ETH_CS, SZ_16M, &base) < 0) { - printk(KERN_ERR "Failed to request GPMC CS for smc91x\n"); - goto out; - } - apollon_smc91x_resources[0].start = base + 0x300; - apollon_smc91x_resources[0].end = base + 0x30f; - udelay(100); - - omap_cfg_reg(W4__24XX_GPIO74); - if (gpio_request(APOLLON_ETHR_GPIO_IRQ, "SMC91x irq") < 0) { - printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n", - APOLLON_ETHR_GPIO_IRQ); - gpmc_cs_free(APOLLON_ETH_CS); - goto out; - } - gpio_direction_input(APOLLON_ETHR_GPIO_IRQ); - -out: - clk_disable(gpmc_fck); - clk_put(gpmc_fck); -} - -static void __init omap_apollon_init_irq(void) -{ - omap2_init_common_hw(); - omap_init_irq(); - omap_gpio_init(); - apollon_init_smc91x(); -} - -static struct omap_uart_config apollon_uart_config __initdata = { - .enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2), -}; - -static struct omap_usb_config apollon_usb_config __initdata = { - .register_dev = 1, - .hmc_mode = 0x14, /* 0:dev 1:host1 2:disable */ - - .pins[0] = 6, -}; - -static struct omap_lcd_config apollon_lcd_config __initdata = { - .ctrl_name = "internal", -}; - -static struct omap_board_config_kernel apollon_config[] = { - { OMAP_TAG_UART, &apollon_uart_config }, - { OMAP_TAG_USB, &apollon_usb_config }, - { OMAP_TAG_LCD, &apollon_lcd_config }, -}; - -static void __init apollon_led_init(void) -{ - /* LED0 - AA10 */ - omap_cfg_reg(AA10_242X_GPIO13); - gpio_request(LED0_GPIO13, "LED0"); - gpio_direction_output(LED0_GPIO13, 0); - /* LED1 - AA6 */ - omap_cfg_reg(AA6_242X_GPIO14); - gpio_request(LED1_GPIO14, "LED1"); - gpio_direction_output(LED1_GPIO14, 0); - /* LED2 - AA4 */ - omap_cfg_reg(AA4_242X_GPIO15); - gpio_request(LED2_GPIO15, "LED2"); - gpio_direction_output(LED2_GPIO15, 0); -} - -static void __init apollon_usb_init(void) -{ - /* USB device */ - /* DEVICE_SUSPEND */ - omap_cfg_reg(P21_242X_GPIO12); - gpio_request(12, "USB suspend"); - gpio_direction_output(12, 0); -} - -static void __init omap_apollon_init(void) -{ - u32 v; - - apollon_led_init(); - apollon_flash_init(); - apollon_usb_init(); - - /* REVISIT: where's the correct place */ - omap_cfg_reg(W19_24XX_SYS_NIRQ); - - /* Use Interal loop-back in MMC/SDIO Module Input Clock selection */ - v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); - v |= (1 << 24); - omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); - - /* - * Make sure the serial ports are muxed on at this point. - * You have to mux them off in device drivers later on - * if not needed. - */ - platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices)); - omap_board_config = apollon_config; - omap_board_config_size = ARRAY_SIZE(apollon_config); - omap_serial_init(); -} - -static void __init omap_apollon_map_io(void) -{ - omap2_set_globals_242x(); - omap2_map_common_io(); -} - -MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon") - /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */ - .phys_io = 0x48000000, - .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, - .boot_params = 0x80000100, - .map_io = omap_apollon_map_io, - .init_irq = omap_apollon_init_irq, - .init_machine = omap_apollon_init, - .timer = &omap_timer, -MACHINE_END diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c new file mode 100644 index 00000000000..018353d88b9 --- /dev/null +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -0,0 +1,787 @@ +/* + * CompuLab CM-T35/CM-T3730 modules support + * + * Copyright (C) 2009-2011 CompuLab, Ltd. + * Authors: Mike Rapoport <mike@compulab.co.il> + * Igor Grinberg <grinberg@compulab.co.il> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + */ + +#include <linux/clk-provider.h> +#include <linux/clkdev.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/input.h> +#include <linux/input/matrix_keypad.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/platform_data/gpio-omap.h> + +#include <linux/platform_data/at24.h> +#include <linux/i2c/twl.h> +#include <linux/regulator/fixed.h> +#include <linux/regulator/machine.h> +#include <linux/mmc/host.h> +#include <linux/usb/phy.h> + +#include <linux/spi/spi.h> +#include <linux/spi/tdo24m.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <linux/platform_data/mtd-nand-omap2.h> +#include <video/omapdss.h> +#include <video/omap-panel-data.h> +#include <linux/platform_data/spi-omap2-mcspi.h> + +#include "common.h" +#include "mux.h" +#include "sdram-micron-mt46h32m32lf-6.h" +#include "hsmmc.h" +#include "common-board-devices.h" +#include "gpmc.h" +#include "gpmc-nand.h" + +#define CM_T35_GPIO_PENDOWN 57 +#define SB_T35_USB_HUB_RESET_GPIO 167 + +#define CM_T35_SMSC911X_CS 5 +#define CM_T35_SMSC911X_GPIO 163 +#define SB_T35_SMSC911X_CS 4 +#define SB_T35_SMSC911X_GPIO 65 + +#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) +#include <linux/smsc911x.h> +#include "gpmc-smsc911x.h" + +static struct omap_smsc911x_platform_data cm_t35_smsc911x_cfg = { + .id = 0, + .cs = CM_T35_SMSC911X_CS, + .gpio_irq = CM_T35_SMSC911X_GPIO, + .gpio_reset = -EINVAL, + .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, +}; + +static struct omap_smsc911x_platform_data sb_t35_smsc911x_cfg = { + .id = 1, + .cs = SB_T35_SMSC911X_CS, + .gpio_irq = SB_T35_SMSC911X_GPIO, + .gpio_reset = -EINVAL, + .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, +}; + +static struct regulator_consumer_supply cm_t35_smsc911x_supplies[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x.0"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), +}; + +static struct regulator_consumer_supply sb_t35_smsc911x_supplies[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x.1"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.1"), +}; + +static void __init cm_t35_init_ethernet(void) +{ + regulator_register_fixed(0, cm_t35_smsc911x_supplies, + ARRAY_SIZE(cm_t35_smsc911x_supplies)); + regulator_register_fixed(1, sb_t35_smsc911x_supplies, + ARRAY_SIZE(sb_t35_smsc911x_supplies)); + + gpmc_smsc911x_init(&cm_t35_smsc911x_cfg); + gpmc_smsc911x_init(&sb_t35_smsc911x_cfg); +} +#else +static inline void __init cm_t35_init_ethernet(void) { return; } +#endif + +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +#include <linux/leds.h> + +static struct gpio_led cm_t35_leds[] = { + [0] = { + .gpio = 186, + .name = "cm-t35:green", + .default_trigger = "heartbeat", + .active_low = 0, + }, +}; + +static struct gpio_led_platform_data cm_t35_led_pdata = { + .num_leds = ARRAY_SIZE(cm_t35_leds), + .leds = cm_t35_leds, +}; + +static struct platform_device cm_t35_led_device = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &cm_t35_led_pdata, + }, +}; + +static void __init cm_t35_init_led(void) +{ + platform_device_register(&cm_t35_led_device); +} +#else +static inline void cm_t35_init_led(void) {} +#endif + +#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE) +#include <linux/mtd/mtd.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/partitions.h> + +static struct mtd_partition cm_t35_nand_partitions[] = { + { + .name = "xloader", + .offset = 0, /* Offset = 0x00000 */ + .size = 4 * NAND_BLOCK_SIZE, + .mask_flags = MTD_WRITEABLE + }, + { + .name = "uboot", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */ + .size = 15 * NAND_BLOCK_SIZE, + }, + { + .name = "uboot environment", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */ + .size = 2 * NAND_BLOCK_SIZE, + }, + { + .name = "linux", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x2A0000 */ + .size = 32 * NAND_BLOCK_SIZE, + }, + { + .name = "rootfs", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x6A0000 */ + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct omap_nand_platform_data cm_t35_nand_data = { + .parts = cm_t35_nand_partitions, + .nr_parts = ARRAY_SIZE(cm_t35_nand_partitions), + .cs = 0, +}; + +static void __init cm_t35_init_nand(void) +{ + if (gpmc_nand_init(&cm_t35_nand_data, NULL) < 0) + pr_err("CM-T35: Unable to register NAND device\n"); +} +#else +static inline void cm_t35_init_nand(void) {} +#endif + +#define CM_T35_LCD_EN_GPIO 157 +#define CM_T35_LCD_BL_GPIO 58 +#define CM_T35_DVI_EN_GPIO 54 + +static const struct display_timing cm_t35_lcd_videomode = { + .pixelclock = { 0, 26000000, 0 }, + + .hactive = { 0, 480, 0 }, + .hfront_porch = { 0, 104, 0 }, + .hback_porch = { 0, 8, 0 }, + .hsync_len = { 0, 8, 0 }, + + .vactive = { 0, 640, 0 }, + .vfront_porch = { 0, 4, 0 }, + .vback_porch = { 0, 2, 0 }, + .vsync_len = { 0, 2, 0 }, + + .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | + DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_NEGEDGE, +}; + +static struct panel_dpi_platform_data cm_t35_lcd_pdata = { + .name = "lcd", + .source = "dpi.0", + + .data_lines = 18, + + .display_timing = &cm_t35_lcd_videomode, + + .enable_gpio = -1, + .backlight_gpio = CM_T35_LCD_BL_GPIO, +}; + +static struct platform_device cm_t35_lcd_device = { + .name = "panel-dpi", + .id = 0, + .dev.platform_data = &cm_t35_lcd_pdata, +}; + +static struct connector_dvi_platform_data cm_t35_dvi_connector_pdata = { + .name = "dvi", + .source = "tfp410.0", + .i2c_bus_num = -1, +}; + +static struct platform_device cm_t35_dvi_connector_device = { + .name = "connector-dvi", + .id = 0, + .dev.platform_data = &cm_t35_dvi_connector_pdata, +}; + +static struct encoder_tfp410_platform_data cm_t35_tfp410_pdata = { + .name = "tfp410.0", + .source = "dpi.0", + .data_lines = 24, + .power_down_gpio = CM_T35_DVI_EN_GPIO, +}; + +static struct platform_device cm_t35_tfp410_device = { + .name = "tfp410", + .id = 0, + .dev.platform_data = &cm_t35_tfp410_pdata, +}; + +static struct connector_atv_platform_data cm_t35_tv_pdata = { + .name = "tv", + .source = "venc.0", + .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, + .invert_polarity = false, +}; + +static struct platform_device cm_t35_tv_connector_device = { + .name = "connector-analog-tv", + .id = 0, + .dev.platform_data = &cm_t35_tv_pdata, +}; + +static struct omap_dss_board_info cm_t35_dss_data = { + .default_display_name = "dvi", +}; + +static struct omap2_mcspi_device_config tdo24m_mcspi_config = { + .turbo_mode = 0, +}; + +static struct tdo24m_platform_data tdo24m_config = { + .model = TDO35S, +}; + +static struct spi_board_info cm_t35_lcd_spi_board_info[] __initdata = { + { + .modalias = "tdo24m", + .bus_num = 4, + .chip_select = 0, + .max_speed_hz = 1000000, + .controller_data = &tdo24m_mcspi_config, + .platform_data = &tdo24m_config, + }, +}; + +static void __init cm_t35_init_display(void) +{ + int err; + + spi_register_board_info(cm_t35_lcd_spi_board_info, + ARRAY_SIZE(cm_t35_lcd_spi_board_info)); + + + err = gpio_request_one(CM_T35_LCD_EN_GPIO, GPIOF_OUT_INIT_LOW, + "lcd bl enable"); + if (err) { + pr_err("CM-T35: failed to request LCD EN GPIO\n"); + return; + } + + msleep(50); + gpio_set_value(CM_T35_LCD_EN_GPIO, 1); + + err = omap_display_init(&cm_t35_dss_data); + if (err) { + pr_err("CM-T35: failed to register DSS device\n"); + gpio_free(CM_T35_LCD_EN_GPIO); + } + + platform_device_register(&cm_t35_tfp410_device); + platform_device_register(&cm_t35_dvi_connector_device); + platform_device_register(&cm_t35_lcd_device); + platform_device_register(&cm_t35_tv_connector_device); +} + +static struct regulator_consumer_supply cm_t35_vmmc1_supply[] = { + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), +}; + +static struct regulator_consumer_supply cm_t35_vsim_supply[] = { + REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"), +}; + +static struct regulator_consumer_supply cm_t35_vio_supplies[] = { + REGULATOR_SUPPLY("vcc", "spi1.0"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dpi.0"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"), +}; + +/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ +static struct regulator_init_data cm_t35_vmmc1 = { + .constraints = { + .min_uV = 1850000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(cm_t35_vmmc1_supply), + .consumer_supplies = cm_t35_vmmc1_supply, +}; + +/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */ +static struct regulator_init_data cm_t35_vsim = { + .constraints = { + .min_uV = 1800000, + .max_uV = 3000000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(cm_t35_vsim_supply), + .consumer_supplies = cm_t35_vsim_supply, +}; + +static struct regulator_init_data cm_t35_vio = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE, + }, + .num_consumer_supplies = ARRAY_SIZE(cm_t35_vio_supplies), + .consumer_supplies = cm_t35_vio_supplies, +}; + +static uint32_t cm_t35_keymap[] = { + KEY(0, 0, KEY_A), KEY(0, 1, KEY_B), KEY(0, 2, KEY_LEFT), + KEY(1, 0, KEY_UP), KEY(1, 1, KEY_ENTER), KEY(1, 2, KEY_DOWN), + KEY(2, 0, KEY_RIGHT), KEY(2, 1, KEY_C), KEY(2, 2, KEY_D), +}; + +static struct matrix_keymap_data cm_t35_keymap_data = { + .keymap = cm_t35_keymap, + .keymap_size = ARRAY_SIZE(cm_t35_keymap), +}; + +static struct twl4030_keypad_data cm_t35_kp_data = { + .keymap_data = &cm_t35_keymap_data, + .rows = 3, + .cols = 3, + .rep = 1, +}; + +static struct omap2_hsmmc_info mmc[] = { + { + .mmc = 1, + .caps = MMC_CAP_4_BIT_DATA, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + .deferred = true, + }, + { + .mmc = 2, + .caps = MMC_CAP_4_BIT_DATA, + .transceiver = 1, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + .ocr_mask = 0x00100000, /* 3.3V */ + }, + {} /* Terminator */ +}; + +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 1, + .reset_gpio = OMAP_MAX_GPIO_LINES + 6, + .vcc_gpio = -EINVAL, + }, + { + .port = 2, + .reset_gpio = OMAP_MAX_GPIO_LINES + 7, + .vcc_gpio = -EINVAL, + }, +}; + +static struct usbhs_omap_platform_data usbhs_bdata __initdata = { + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, +}; + +static void __init cm_t35_init_usbh(void) +{ + int err; + + err = gpio_request_one(SB_T35_USB_HUB_RESET_GPIO, + GPIOF_OUT_INIT_LOW, "usb hub rst"); + if (err) { + pr_err("SB-T35: usb hub rst gpio request failed: %d\n", err); + } else { + udelay(10); + gpio_set_value(SB_T35_USB_HUB_RESET_GPIO, 1); + msleep(1); + } + + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); + usbhs_init(&usbhs_bdata); +} + +static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio, + unsigned ngpio) +{ + int wlan_rst = gpio + 2; + + if (gpio_request_one(wlan_rst, GPIOF_OUT_INIT_HIGH, "WLAN RST") == 0) { + gpio_export(wlan_rst, 0); + udelay(10); + gpio_set_value_cansleep(wlan_rst, 0); + udelay(10); + gpio_set_value_cansleep(wlan_rst, 1); + } else { + pr_err("CM-T35: could not obtain gpio for WiFi reset\n"); + } + + /* gpio + 0 is "mmc0_cd" (input/IRQ) */ + mmc[0].gpio_cd = gpio + 0; + omap_hsmmc_late_init(mmc); + + return 0; +} + +static struct twl4030_gpio_platform_data cm_t35_gpio_data = { + .setup = cm_t35_twl_gpio_setup, +}; + +static struct twl4030_power_data cm_t35_power_data = { + .use_poweroff = true, +}; + +static struct twl4030_platform_data cm_t35_twldata = { + /* platform_data for children goes here */ + .keypad = &cm_t35_kp_data, + .gpio = &cm_t35_gpio_data, + .vmmc1 = &cm_t35_vmmc1, + .vsim = &cm_t35_vsim, + .vio = &cm_t35_vio, + .power = &cm_t35_power_data, +}; + +#if defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE) +#include <media/omap3isp.h> +#include "devices.h" + +static struct i2c_board_info cm_t35_isp_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("mt9t001", 0x5d), + }, + { + I2C_BOARD_INFO("tvp5150", 0x5c), + }, +}; + +static struct isp_subdev_i2c_board_info cm_t35_isp_primary_subdevs[] = { + { + .board_info = &cm_t35_isp_i2c_boardinfo[0], + .i2c_adapter_id = 3, + }, + { NULL, 0, }, +}; + +static struct isp_subdev_i2c_board_info cm_t35_isp_secondary_subdevs[] = { + { + .board_info = &cm_t35_isp_i2c_boardinfo[1], + .i2c_adapter_id = 3, + }, + { NULL, 0, }, +}; + +static struct isp_v4l2_subdevs_group cm_t35_isp_subdevs[] = { + { + .subdevs = cm_t35_isp_primary_subdevs, + .interface = ISP_INTERFACE_PARALLEL, + .bus = { + .parallel = { + .clk_pol = 1, + }, + }, + }, + { + .subdevs = cm_t35_isp_secondary_subdevs, + .interface = ISP_INTERFACE_PARALLEL, + .bus = { + .parallel = { + .clk_pol = 0, + }, + }, + }, + { NULL, 0, }, +}; + +static struct isp_platform_data cm_t35_isp_pdata = { + .subdevs = cm_t35_isp_subdevs, +}; + +static struct regulator_consumer_supply cm_t35_camera_supplies[] = { + REGULATOR_SUPPLY("vaa", "3-005d"), + REGULATOR_SUPPLY("vdd", "3-005d"), +}; + +static void __init cm_t35_init_camera(void) +{ + struct clk *clk; + + clk = clk_register_fixed_rate(NULL, "mt9t001-clkin", NULL, CLK_IS_ROOT, + 48000000); + clk_register_clkdev(clk, NULL, "3-005d"); + + regulator_register_fixed(2, cm_t35_camera_supplies, + ARRAY_SIZE(cm_t35_camera_supplies)); + + if (omap3_init_camera(&cm_t35_isp_pdata) < 0) + pr_warn("CM-T3x: Failed registering camera device!\n"); +} + +#else +static inline void cm_t35_init_camera(void) {} +#endif /* CONFIG_VIDEO_OMAP3 */ + +static void __init cm_t35_init_i2c(void) +{ + omap3_pmic_get_config(&cm_t35_twldata, TWL_COMMON_PDATA_USB, + TWL_COMMON_REGULATOR_VDAC | + TWL_COMMON_PDATA_AUDIO); + + omap3_pmic_init("tps65930", &cm_t35_twldata); + + omap_register_i2c_bus(3, 400, NULL, 0); +} + +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + /* nCS and IRQ for CM-T35 ethernet */ + OMAP3_MUX(GPMC_NCS5, OMAP_MUX_MODE0), + OMAP3_MUX(UART3_CTS_RCTX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP), + + /* nCS and IRQ for SB-T35 ethernet */ + OMAP3_MUX(GPMC_NCS4, OMAP_MUX_MODE0), + OMAP3_MUX(GPMC_WAIT3, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP), + + /* PENDOWN GPIO */ + OMAP3_MUX(GPMC_NCS6, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), + + /* mUSB */ + OMAP3_MUX(HSUSB0_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_STP, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(HSUSB0_DIR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_NXT, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + /* MMC 2 */ + OMAP3_MUX(SDMMC2_DAT4, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT), + OMAP3_MUX(SDMMC2_DAT5, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT), + OMAP3_MUX(SDMMC2_DAT6, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT), + OMAP3_MUX(SDMMC2_DAT7, OMAP_MUX_MODE1 | OMAP_PIN_INPUT), + + /* McSPI 1 */ + OMAP3_MUX(MCSPI1_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCSPI1_SIMO, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCSPI1_SOMI, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCSPI1_CS0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN), + + /* McSPI 4 */ + OMAP3_MUX(MCBSP1_CLKR, OMAP_MUX_MODE1 | OMAP_PIN_INPUT), + OMAP3_MUX(MCBSP1_DX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT), + OMAP3_MUX(MCBSP1_DR, OMAP_MUX_MODE1 | OMAP_PIN_INPUT), + OMAP3_MUX(MCBSP1_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT_PULLUP), + + /* McBSP 2 */ + OMAP3_MUX(MCBSP2_FSX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCBSP2_CLKX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCBSP2_DR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCBSP2_DX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + + /* serial ports */ + OMAP3_MUX(MCBSP3_CLKX, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT), + OMAP3_MUX(MCBSP3_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT), + OMAP3_MUX(UART1_TX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(UART1_RX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + /* common DSS */ + OMAP3_MUX(DSS_PCLK, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_HSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_VSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_ACBIAS, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA8, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA9, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA10, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA11, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA12, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA13, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA14, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA15, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA16, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA17, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + + /* Camera */ + OMAP3_MUX(CAM_HS, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(CAM_VS, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(CAM_XCLKA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(CAM_PCLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(CAM_FLD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(CAM_D0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(CAM_D1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(CAM_D2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(CAM_D3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(CAM_D4, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(CAM_D5, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(CAM_D6, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(CAM_D7, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(CAM_D8, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN), + OMAP3_MUX(CAM_D9, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN), + OMAP3_MUX(CAM_STROBE, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + OMAP3_MUX(CAM_D10, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLDOWN), + OMAP3_MUX(CAM_D11, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLDOWN), + + /* display controls */ + OMAP3_MUX(MCBSP1_FSR, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + OMAP3_MUX(GPMC_NCS7, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + OMAP3_MUX(GPMC_NCS3, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + + /* TPS IRQ */ + OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_WAKEUP_EN | \ + OMAP_PIN_INPUT_PULLUP), + + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; + +static void __init cm_t3x_common_dss_mux_init(int mux_mode) +{ + omap_mux_init_signal("dss_data18", mux_mode); + omap_mux_init_signal("dss_data19", mux_mode); + omap_mux_init_signal("dss_data20", mux_mode); + omap_mux_init_signal("dss_data21", mux_mode); + omap_mux_init_signal("dss_data22", mux_mode); + omap_mux_init_signal("dss_data23", mux_mode); +} + +static void __init cm_t35_init_mux(void) +{ + int mux_mode = OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT; + + omap_mux_init_signal("dss_data0.dss_data0", mux_mode); + omap_mux_init_signal("dss_data1.dss_data1", mux_mode); + omap_mux_init_signal("dss_data2.dss_data2", mux_mode); + omap_mux_init_signal("dss_data3.dss_data3", mux_mode); + omap_mux_init_signal("dss_data4.dss_data4", mux_mode); + omap_mux_init_signal("dss_data5.dss_data5", mux_mode); + cm_t3x_common_dss_mux_init(mux_mode); +} + +static void __init cm_t3730_init_mux(void) +{ + int mux_mode = OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT; + + omap_mux_init_signal("sys_boot0", mux_mode); + omap_mux_init_signal("sys_boot1", mux_mode); + omap_mux_init_signal("sys_boot3", mux_mode); + omap_mux_init_signal("sys_boot4", mux_mode); + omap_mux_init_signal("sys_boot5", mux_mode); + omap_mux_init_signal("sys_boot6", mux_mode); + cm_t3x_common_dss_mux_init(mux_mode); +} +#else +static inline void cm_t35_init_mux(void) {} +static inline void cm_t3730_init_mux(void) {} +#endif + +static void __init cm_t3x_common_init(void) +{ + omap3_mux_init(board_mux, OMAP_PACKAGE_CUS); + omap_serial_init(); + omap_sdrc_init(mt46h32m32lf6_sdrc_params, + mt46h32m32lf6_sdrc_params); + omap_hsmmc_init(mmc); + cm_t35_init_i2c(); + omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL); + cm_t35_init_ethernet(); + cm_t35_init_led(); + cm_t35_init_display(); + omap_twl4030_audio_init("cm-t3x", NULL); + + usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); + usb_musb_init(NULL); + cm_t35_init_usbh(); + cm_t35_init_camera(); +} + +static void __init cm_t35_init(void) +{ + cm_t3x_common_init(); + cm_t35_init_mux(); + cm_t35_init_nand(); +} + +static void __init cm_t3730_init(void) +{ + cm_t3x_common_init(); + cm_t3730_init_mux(); +} + +MACHINE_START(CM_T35, "Compulab CM-T35") + .atag_offset = 0x100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap35xx_init_early, + .init_irq = omap3_init_irq, + .handle_irq = omap3_intc_handle_irq, + .init_machine = cm_t35_init, + .init_late = omap35xx_init_late, + .init_time = omap3_sync32k_timer_init, + .restart = omap3xxx_restart, +MACHINE_END + +MACHINE_START(CM_T3730, "Compulab CM-T3730") + .atag_offset = 0x100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap3630_init_early, + .init_irq = omap3_init_irq, + .handle_irq = omap3_intc_handle_irq, + .init_machine = cm_t3730_init, + .init_late = omap3630_init_late, + .init_time = omap3_sync32k_timer_init, + .restart = omap3xxx_restart, +MACHINE_END diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c new file mode 100644 index 00000000000..4eb5e6f2f7f --- /dev/null +++ b/arch/arm/mach-omap2/board-cm-t3517.c @@ -0,0 +1,337 @@ +/* + * linux/arch/arm/mach-omap2/board-cm-t3517.c + * + * Support for the CompuLab CM-T3517 modules + * + * Copyright (C) 2010 CompuLab, Ltd. + * Author: Igor Grinberg <grinberg@compulab.co.il> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/leds.h> +#include <linux/rtc-v3020.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/partitions.h> +#include <linux/mmc/host.h> +#include <linux/can/platform/ti_hecc.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include "common.h" +#include <linux/platform_data/mtd-nand-omap2.h> +#include "gpmc.h" + +#include "am35xx.h" + +#include "mux.h" +#include "control.h" +#include "hsmmc.h" +#include "common-board-devices.h" +#include "am35xx-emac.h" +#include "gpmc-nand.h" + +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +static struct gpio_led cm_t3517_leds[] = { + [0] = { + .gpio = 186, + .name = "cm-t3517:green", + .default_trigger = "heartbeat", + .active_low = 0, + }, +}; + +static struct gpio_led_platform_data cm_t3517_led_pdata = { + .num_leds = ARRAY_SIZE(cm_t3517_leds), + .leds = cm_t3517_leds, +}; + +static struct platform_device cm_t3517_led_device = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &cm_t3517_led_pdata, + }, +}; + +static void __init cm_t3517_init_leds(void) +{ + platform_device_register(&cm_t3517_led_device); +} +#else +static inline void cm_t3517_init_leds(void) {} +#endif + +#if defined(CONFIG_CAN_TI_HECC) || defined(CONFIG_CAN_TI_HECC_MODULE) +static struct resource cm_t3517_hecc_resources[] = { + { + .start = AM35XX_IPSS_HECC_BASE, + .end = AM35XX_IPSS_HECC_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = 24 + OMAP_INTC_START, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct ti_hecc_platform_data cm_t3517_hecc_pdata = { + .scc_hecc_offset = AM35XX_HECC_SCC_HECC_OFFSET, + .scc_ram_offset = AM35XX_HECC_SCC_RAM_OFFSET, + .hecc_ram_offset = AM35XX_HECC_RAM_OFFSET, + .mbx_offset = AM35XX_HECC_MBOX_OFFSET, + .int_line = AM35XX_HECC_INT_LINE, + .version = AM35XX_HECC_VERSION, +}; + +static struct platform_device cm_t3517_hecc_device = { + .name = "ti_hecc", + .id = 1, + .num_resources = ARRAY_SIZE(cm_t3517_hecc_resources), + .resource = cm_t3517_hecc_resources, + .dev = { + .platform_data = &cm_t3517_hecc_pdata, + }, +}; + +static void cm_t3517_init_hecc(void) +{ + platform_device_register(&cm_t3517_hecc_device); +} +#else +static inline void cm_t3517_init_hecc(void) {} +#endif + +#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) +static struct omap2_hsmmc_info cm_t3517_mmc[] = { + { + .mmc = 1, + .caps = MMC_CAP_4_BIT_DATA, + .gpio_cd = 144, + .gpio_wp = 59, + }, + { + .mmc = 2, + .caps = MMC_CAP_4_BIT_DATA, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + }, + {} /* Terminator */ +}; +#else +#define cm_t3517_mmc NULL +#endif + +#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE) +#define RTC_IO_GPIO (153) +#define RTC_WR_GPIO (154) +#define RTC_RD_GPIO (53) +#define RTC_CS_GPIO (163) +#define RTC_CS_EN_GPIO (160) + +struct v3020_platform_data cm_t3517_v3020_pdata = { + .use_gpio = 1, + .gpio_cs = RTC_CS_GPIO, + .gpio_wr = RTC_WR_GPIO, + .gpio_rd = RTC_RD_GPIO, + .gpio_io = RTC_IO_GPIO, +}; + +static struct platform_device cm_t3517_rtc_device = { + .name = "v3020", + .id = -1, + .dev = { + .platform_data = &cm_t3517_v3020_pdata, + } +}; + +static void __init cm_t3517_init_rtc(void) +{ + int err; + + err = gpio_request_one(RTC_CS_EN_GPIO, GPIOF_OUT_INIT_HIGH, + "rtc cs en"); + if (err) { + pr_err("CM-T3517: rtc cs en gpio request failed: %d\n", err); + return; + } + + platform_device_register(&cm_t3517_rtc_device); +} +#else +static inline void cm_t3517_init_rtc(void) {} +#endif + +#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE) +#define HSUSB1_RESET_GPIO (146) +#define HSUSB2_RESET_GPIO (147) +#define USB_HUB_RESET_GPIO (152) + +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 1, + .reset_gpio = HSUSB1_RESET_GPIO, + .vcc_gpio = -EINVAL, + }, + { + .port = 2, + .reset_gpio = HSUSB2_RESET_GPIO, + .vcc_gpio = -EINVAL, + }, +}; + +static struct usbhs_omap_platform_data cm_t3517_ehci_pdata __initdata = { + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, +}; + +static int __init cm_t3517_init_usbh(void) +{ + int err; + + err = gpio_request_one(USB_HUB_RESET_GPIO, GPIOF_OUT_INIT_LOW, + "usb hub rst"); + if (err) { + pr_err("CM-T3517: usb hub rst gpio request failed: %d\n", err); + } else { + udelay(10); + gpio_set_value(USB_HUB_RESET_GPIO, 1); + msleep(1); + } + + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); + usbhs_init(&cm_t3517_ehci_pdata); + + return 0; +} +#else +static inline int cm_t3517_init_usbh(void) +{ + return 0; +} +#endif + +#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE) +static struct mtd_partition cm_t3517_nand_partitions[] = { + { + .name = "xloader", + .offset = 0, /* Offset = 0x00000 */ + .size = 4 * NAND_BLOCK_SIZE, + .mask_flags = MTD_WRITEABLE + }, + { + .name = "uboot", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */ + .size = 15 * NAND_BLOCK_SIZE, + }, + { + .name = "uboot environment", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */ + .size = 2 * NAND_BLOCK_SIZE, + }, + { + .name = "linux", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x2A0000 */ + .size = 32 * NAND_BLOCK_SIZE, + }, + { + .name = "rootfs", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x6A0000 */ + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct omap_nand_platform_data cm_t3517_nand_data = { + .parts = cm_t3517_nand_partitions, + .nr_parts = ARRAY_SIZE(cm_t3517_nand_partitions), + .cs = 0, +}; + +static void __init cm_t3517_init_nand(void) +{ + if (gpmc_nand_init(&cm_t3517_nand_data, NULL) < 0) + pr_err("CM-T3517: NAND initialization failed\n"); +} +#else +static inline void cm_t3517_init_nand(void) {} +#endif + +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + /* GPIO186 - Green LED */ + OMAP3_MUX(SYS_CLKOUT2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + + /* RTC GPIOs: */ + /* IO - GPIO153 */ + OMAP3_MUX(MCBSP4_DR, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), + /* WR# - GPIO154 */ + OMAP3_MUX(MCBSP4_DX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), + /* RD# - GPIO53 */ + OMAP3_MUX(GPMC_NCS2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), + /* CS# - GPIO163 */ + OMAP3_MUX(UART3_CTS_RCTX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), + /* CS EN - GPIO160 */ + OMAP3_MUX(MCBSP_CLKS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), + + /* HSUSB1 RESET */ + OMAP3_MUX(UART2_TX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + /* HSUSB2 RESET */ + OMAP3_MUX(UART2_RX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + /* CM-T3517 USB HUB nRESET */ + OMAP3_MUX(MCBSP4_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + + /* CD - GPIO144 and WP - GPIO59 for MMC1 - SB-T35 */ + OMAP3_MUX(UART2_CTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP), + OMAP3_MUX(GPMC_CLK, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP), + + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#endif + +static void __init cm_t3517_init(void) +{ + omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); + omap_serial_init(); + omap_sdrc_init(NULL, NULL); + cm_t3517_init_leds(); + cm_t3517_init_nand(); + cm_t3517_init_rtc(); + cm_t3517_init_usbh(); + cm_t3517_init_hecc(); + am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1); + omap_hsmmc_init(cm_t3517_mmc); +} + +MACHINE_START(CM_T3517, "Compulab CM-T3517") + .atag_offset = 0x100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = am35xx_init_early, + .init_irq = omap3_init_irq, + .handle_irq = omap3_intc_handle_irq, + .init_machine = cm_t3517_init, + .init_late = am35xx_init_late, + .init_time = omap3_gptimer_timer_init, + .restart = omap3xxx_restart, +MACHINE_END diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c new file mode 100644 index 00000000000..cdc4fb9960a --- /dev/null +++ b/arch/arm/mach-omap2/board-devkit8000.c @@ -0,0 +1,655 @@ +/* + * board-devkit8000.c - TimLL Devkit8000 + * + * Copyright (C) 2009 Kim Botherway + * Copyright (C) 2010 Thomas Weber + * + * Modified from mach-omap2/board-omap3beagle.c + * + * Initial code: Syed Mohammed Khasim + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/leds.h> +#include <linux/gpio.h> +#include <linux/input.h> +#include <linux/gpio_keys.h> + +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/nand.h> +#include <linux/mmc/host.h> +#include <linux/usb/phy.h> + +#include <linux/regulator/machine.h> +#include <linux/i2c/twl.h> +#include "id.h" +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/flash.h> + +#include "common.h" +#include "gpmc.h" +#include <linux/platform_data/mtd-nand-omap2.h> +#include <video/omapdss.h> +#include <video/omap-panel-data.h> + +#include <linux/platform_data/spi-omap2-mcspi.h> +#include <linux/input/matrix_keypad.h> +#include <linux/spi/spi.h> +#include <linux/dm9000.h> +#include <linux/interrupt.h> + +#include "sdram-micron-mt46h32m32lf-6.h" +#include "mux.h" +#include "hsmmc.h" +#include "board-flash.h" +#include "common-board-devices.h" + +#define NAND_CS 0 + +#define OMAP_DM9000_GPIO_IRQ 25 +#define OMAP3_DEVKIT_TS_GPIO 27 + +static struct mtd_partition devkit8000_nand_partitions[] = { + /* All the partition sizes are listed in terms of NAND block size */ + { + .name = "X-Loader", + .offset = 0, + .size = 4 * NAND_BLOCK_SIZE, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "U-Boot", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */ + .size = 15 * NAND_BLOCK_SIZE, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "U-Boot Env", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */ + .size = 1 * NAND_BLOCK_SIZE, + }, + { + .name = "Kernel", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */ + .size = 32 * NAND_BLOCK_SIZE, + }, + { + .name = "File System", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */ + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct omap2_hsmmc_info mmc[] = { + { + .mmc = 1, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, + .gpio_wp = 29, + .deferred = true, + }, + {} /* Terminator */ +}; + +static struct regulator_consumer_supply devkit8000_vmmc1_supply[] = { + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), +}; + +/* ads7846 on SPI */ +static struct regulator_consumer_supply devkit8000_vio_supply[] = { + REGULATOR_SUPPLY("vcc", "spi2.0"), +}; + +static const struct display_timing devkit8000_lcd_videomode = { + .pixelclock = { 0, 40000000, 0 }, + + .hactive = { 0, 800, 0 }, + .hfront_porch = { 0, 1, 0 }, + .hback_porch = { 0, 1, 0 }, + .hsync_len = { 0, 48, 0 }, + + .vactive = { 0, 480, 0 }, + .vfront_porch = { 0, 12, 0 }, + .vback_porch = { 0, 25, 0 }, + .vsync_len = { 0, 3, 0 }, + + .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | + DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE, +}; + +static struct panel_dpi_platform_data devkit8000_lcd_pdata = { + .name = "lcd", + .source = "dpi.0", + + .data_lines = 24, + + .display_timing = &devkit8000_lcd_videomode, + + .enable_gpio = -1, /* filled in code */ + .backlight_gpio = -1, +}; + +static struct platform_device devkit8000_lcd_device = { + .name = "panel-dpi", + .id = 0, + .dev.platform_data = &devkit8000_lcd_pdata, +}; + +static struct connector_dvi_platform_data devkit8000_dvi_connector_pdata = { + .name = "dvi", + .source = "tfp410.0", + .i2c_bus_num = 1, +}; + +static struct platform_device devkit8000_dvi_connector_device = { + .name = "connector-dvi", + .id = 0, + .dev.platform_data = &devkit8000_dvi_connector_pdata, +}; + +static struct encoder_tfp410_platform_data devkit8000_tfp410_pdata = { + .name = "tfp410.0", + .source = "dpi.0", + .data_lines = 24, + .power_down_gpio = -1, /* filled in code */ +}; + +static struct platform_device devkit8000_tfp410_device = { + .name = "tfp410", + .id = 0, + .dev.platform_data = &devkit8000_tfp410_pdata, +}; + +static struct connector_atv_platform_data devkit8000_tv_pdata = { + .name = "tv", + .source = "venc.0", + .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, + .invert_polarity = false, +}; + +static struct platform_device devkit8000_tv_connector_device = { + .name = "connector-analog-tv", + .id = 0, + .dev.platform_data = &devkit8000_tv_pdata, +}; + +static struct omap_dss_board_info devkit8000_dss_data = { + .default_display_name = "lcd", +}; + +static uint32_t board_keymap[] = { + KEY(0, 0, KEY_1), + KEY(1, 0, KEY_2), + KEY(2, 0, KEY_3), + KEY(0, 1, KEY_4), + KEY(1, 1, KEY_5), + KEY(2, 1, KEY_6), + KEY(3, 1, KEY_F5), + KEY(0, 2, KEY_7), + KEY(1, 2, KEY_8), + KEY(2, 2, KEY_9), + KEY(3, 2, KEY_F6), + KEY(0, 3, KEY_F7), + KEY(1, 3, KEY_0), + KEY(2, 3, KEY_F8), + PERSISTENT_KEY(4, 5), + KEY(4, 4, KEY_VOLUMEUP), + KEY(5, 5, KEY_VOLUMEDOWN), + 0 +}; + +static struct matrix_keymap_data board_map_data = { + .keymap = board_keymap, + .keymap_size = ARRAY_SIZE(board_keymap), +}; + +static struct twl4030_keypad_data devkit8000_kp_data = { + .keymap_data = &board_map_data, + .rows = 6, + .cols = 6, + .rep = 1, +}; + +static struct gpio_led gpio_leds[]; + +static int devkit8000_twl_gpio_setup(struct device *dev, + unsigned gpio, unsigned ngpio) +{ + /* gpio + 0 is "mmc0_cd" (input/IRQ) */ + mmc[0].gpio_cd = gpio + 0; + omap_hsmmc_late_init(mmc); + + /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ + gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; + + /* TWL4030_GPIO_MAX + 0 is "LCD_PWREN" (out, active high) */ + devkit8000_lcd_pdata.enable_gpio = gpio + TWL4030_GPIO_MAX + 0; + + /* gpio + 7 is "DVI_PD" (out, active low) */ + devkit8000_tfp410_pdata.power_down_gpio = gpio + 7; + + return 0; +} + +static struct twl4030_gpio_platform_data devkit8000_gpio_data = { + .use_leds = true, + .pulldowns = BIT(1) | BIT(2) | BIT(6) | BIT(8) | BIT(13) + | BIT(15) | BIT(16) | BIT(17), + .setup = devkit8000_twl_gpio_setup, +}; + +static struct regulator_consumer_supply devkit8000_vpll1_supplies[] = { + REGULATOR_SUPPLY("vdds_dsi", "omapdss"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dpi.0"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"), +}; + +/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ +static struct regulator_init_data devkit8000_vmmc1 = { + .constraints = { + .min_uV = 1850000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(devkit8000_vmmc1_supply), + .consumer_supplies = devkit8000_vmmc1_supply, +}; + +/* VPLL1 for digital video outputs */ +static struct regulator_init_data devkit8000_vpll1 = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(devkit8000_vpll1_supplies), + .consumer_supplies = devkit8000_vpll1_supplies, +}; + +/* VAUX4 for ads7846 and nubs */ +static struct regulator_init_data devkit8000_vio = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(devkit8000_vio_supply), + .consumer_supplies = devkit8000_vio_supply, +}; + +static struct twl4030_platform_data devkit8000_twldata = { + /* platform_data for children goes here */ + .gpio = &devkit8000_gpio_data, + .vmmc1 = &devkit8000_vmmc1, + .vpll1 = &devkit8000_vpll1, + .vio = &devkit8000_vio, + .keypad = &devkit8000_kp_data, +}; + +static int __init devkit8000_i2c_init(void) +{ + omap3_pmic_get_config(&devkit8000_twldata, + TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_AUDIO, + TWL_COMMON_REGULATOR_VDAC); + omap3_pmic_init("tps65930", &devkit8000_twldata); + /* Bus 3 is attached to the DVI port where devices like the pico DLP + * projector don't work reliably with 400kHz */ + omap_register_i2c_bus(3, 400, NULL, 0); + return 0; +} + +static struct gpio_led gpio_leds[] = { + { + .name = "led1", + .default_trigger = "heartbeat", + .gpio = 186, + .active_low = true, + }, + { + .name = "led2", + .default_trigger = "mmc0", + .gpio = 163, + .active_low = true, + }, + { + .name = "ledB", + .default_trigger = "none", + .gpio = 153, + .active_low = true, + }, + { + .name = "led3", + .default_trigger = "none", + .gpio = 164, + .active_low = true, + }, +}; + +static struct gpio_led_platform_data gpio_led_info = { + .leds = gpio_leds, + .num_leds = ARRAY_SIZE(gpio_leds), +}; + +static struct platform_device leds_gpio = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &gpio_led_info, + }, +}; + +static struct gpio_keys_button gpio_buttons[] = { + { + .code = BTN_EXTRA, + .gpio = 26, + .desc = "user", + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data gpio_key_info = { + .buttons = gpio_buttons, + .nbuttons = ARRAY_SIZE(gpio_buttons), +}; + +static struct platform_device keys_gpio = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &gpio_key_info, + }, +}; + +#define OMAP_DM9000_BASE 0x2c000000 + +static struct resource omap_dm9000_resources[] = { + [0] = { + .start = OMAP_DM9000_BASE, + .end = (OMAP_DM9000_BASE + 0x4 - 1), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = (OMAP_DM9000_BASE + 0x400), + .end = (OMAP_DM9000_BASE + 0x400 + 0x4 - 1), + .flags = IORESOURCE_MEM, + }, + [2] = { + .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW, + }, +}; + +static struct dm9000_plat_data omap_dm9000_platdata = { + .flags = DM9000_PLATF_16BITONLY, +}; + +static struct platform_device omap_dm9000_dev = { + .name = "dm9000", + .id = -1, + .num_resources = ARRAY_SIZE(omap_dm9000_resources), + .resource = omap_dm9000_resources, + .dev = { + .platform_data = &omap_dm9000_platdata, + }, +}; + +static void __init omap_dm9000_init(void) +{ + unsigned char *eth_addr = omap_dm9000_platdata.dev_addr; + struct omap_die_id odi; + int ret; + + ret = gpio_request_one(OMAP_DM9000_GPIO_IRQ, GPIOF_IN, "dm9000 irq"); + if (ret < 0) { + printk(KERN_ERR "Failed to request GPIO%d for dm9000 IRQ\n", + OMAP_DM9000_GPIO_IRQ); + return; + } + + /* init the mac address using DIE id */ + omap_get_die_id(&odi); + + eth_addr[0] = 0x02; /* locally administered */ + eth_addr[1] = odi.id_1 & 0xff; + eth_addr[2] = (odi.id_0 & 0xff000000) >> 24; + eth_addr[3] = (odi.id_0 & 0x00ff0000) >> 16; + eth_addr[4] = (odi.id_0 & 0x0000ff00) >> 8; + eth_addr[5] = (odi.id_0 & 0x000000ff); +} + +static struct platform_device *devkit8000_devices[] __initdata = { + &leds_gpio, + &keys_gpio, + &omap_dm9000_dev, + &devkit8000_lcd_device, + &devkit8000_tfp410_device, + &devkit8000_dvi_connector_device, + &devkit8000_tv_connector_device, +}; + +static struct usbhs_omap_platform_data usbhs_bdata __initdata = { + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, +}; + +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + /* nCS and IRQ for Devkit8000 ethernet */ + OMAP3_MUX(GPMC_NCS6, OMAP_MUX_MODE0), + OMAP3_MUX(ETK_D11, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP), + + /* McSPI 2*/ + OMAP3_MUX(MCSPI2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCSPI2_SIMO, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(MCSPI2_SOMI, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCSPI2_CS0, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(MCSPI2_CS1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + + /* PENDOWN GPIO */ + OMAP3_MUX(ETK_D13, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), + + /* mUSB */ + OMAP3_MUX(HSUSB0_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_STP, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(HSUSB0_DIR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_NXT, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + /* USB 1 */ + OMAP3_MUX(ETK_CTL, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_CLK, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), + OMAP3_MUX(ETK_D8, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_D9, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_D0, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_D1, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_D2, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_D3, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_D4, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_D5, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_D6, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + OMAP3_MUX(ETK_D7, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + + /* MMC 1 */ + OMAP3_MUX(SDMMC1_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(SDMMC1_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(SDMMC1_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(SDMMC1_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(SDMMC1_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(SDMMC1_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(SDMMC1_DAT4, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(SDMMC1_DAT5, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(SDMMC1_DAT6, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(SDMMC1_DAT7, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + /* McBSP 2 */ + OMAP3_MUX(MCBSP2_FSX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCBSP2_CLKX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCBSP2_DR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCBSP2_DX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + + /* I2C 1 */ + OMAP3_MUX(I2C1_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(I2C1_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + /* I2C 2 */ + OMAP3_MUX(I2C2_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(I2C2_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + /* I2C 3 */ + OMAP3_MUX(I2C3_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(I2C3_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + /* I2C 4 */ + OMAP3_MUX(I2C4_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(I2C4_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + /* serial ports */ + OMAP3_MUX(MCBSP3_CLKX, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT), + OMAP3_MUX(MCBSP3_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT), + OMAP3_MUX(UART1_TX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(UART1_RX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + /* DSS */ + OMAP3_MUX(DSS_PCLK, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_HSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_VSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_ACBIAS, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA8, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA9, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA10, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA11, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA12, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA13, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA14, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA15, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA16, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA17, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA18, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA19, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA20, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA21, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + + /* expansion port */ + /* McSPI 1 */ + OMAP3_MUX(MCSPI1_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCSPI1_SIMO, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCSPI1_SOMI, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(MCSPI1_CS0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN), + OMAP3_MUX(MCSPI1_CS3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN), + + /* HDQ */ + OMAP3_MUX(HDQ_SIO, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + /* McSPI4 */ + OMAP3_MUX(MCBSP1_CLKR, OMAP_MUX_MODE1 | OMAP_PIN_INPUT), + OMAP3_MUX(MCBSP1_DX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT), + OMAP3_MUX(MCBSP1_DR, OMAP_MUX_MODE1 | OMAP_PIN_INPUT), + OMAP3_MUX(MCBSP1_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT_PULLUP), + + /* MMC 2 */ + OMAP3_MUX(SDMMC2_DAT4, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT), + OMAP3_MUX(SDMMC2_DAT5, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT), + OMAP3_MUX(SDMMC2_DAT6, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT), + OMAP3_MUX(SDMMC2_DAT7, OMAP_MUX_MODE1 | OMAP_PIN_INPUT), + + /* I2C3 */ + OMAP3_MUX(I2C3_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(I2C3_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + OMAP3_MUX(MCBSP1_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + OMAP3_MUX(MCBSP_CLKS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + OMAP3_MUX(MCBSP1_FSR, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + + OMAP3_MUX(GPMC_NCS7, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + OMAP3_MUX(GPMC_NCS3, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + + /* TPS IRQ */ + OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_WAKEUP_EN | \ + OMAP_PIN_INPUT_PULLUP), + + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#endif + +static void __init devkit8000_init(void) +{ + omap3_mux_init(board_mux, OMAP_PACKAGE_CUS); + omap_serial_init(); + omap_sdrc_init(mt46h32m32lf6_sdrc_params, + mt46h32m32lf6_sdrc_params); + + omap_dm9000_init(); + + omap_hsmmc_init(mmc); + devkit8000_i2c_init(); + omap_dm9000_resources[2].start = gpio_to_irq(OMAP_DM9000_GPIO_IRQ); + platform_add_devices(devkit8000_devices, + ARRAY_SIZE(devkit8000_devices)); + + omap_display_init(&devkit8000_dss_data); + + omap_ads7846_init(2, OMAP3_DEVKIT_TS_GPIO, 0, NULL); + + usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); + usb_musb_init(NULL); + usbhs_init(&usbhs_bdata); + board_nand_init(devkit8000_nand_partitions, + ARRAY_SIZE(devkit8000_nand_partitions), NAND_CS, + NAND_BUSWIDTH_16, NULL); + omap_twl4030_audio_init("omap3beagle", NULL); + + /* Ensure SDRC pins are mux'd for self-refresh */ + omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); + omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); +} + +MACHINE_START(DEVKIT8000, "OMAP3 Devkit8000") + .atag_offset = 0x100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap35xx_init_early, + .init_irq = omap3_init_irq, + .handle_irq = omap3_intc_handle_irq, + .init_machine = devkit8000_init, + .init_late = omap35xx_init_late, + .init_time = omap3_secure_sync32k_timer_init, + .restart = omap3xxx_restart, +MACHINE_END diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c new file mode 100644 index 00000000000..e87f2a83d6b --- /dev/null +++ b/arch/arm/mach-omap2/board-flash.c @@ -0,0 +1,245 @@ +/* + * board-flash.c + * Modified from mach-omap2/board-3430sdp-flash.c + * + * Copyright (C) 2009 Nokia Corporation + * Copyright (C) 2009 Texas Instruments + * + * Vimal Singh <vimalsingh@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/mtd/physmap.h> +#include <linux/io.h> + +#include <linux/platform_data/mtd-nand-omap2.h> +#include <linux/platform_data/mtd-onenand-omap2.h> + +#include "soc.h" +#include "common.h" +#include "board-flash.h" +#include "gpmc-onenand.h" +#include "gpmc-nand.h" + +#define REG_FPGA_REV 0x10 +#define REG_FPGA_DIP_SWITCH_INPUT2 0x60 +#define MAX_SUPPORTED_GPMC_CONFIG 3 + +#define DEBUG_BASE 0x08000000 /* debug board */ + +/* various memory sizes */ +#define FLASH_SIZE_SDPV1 SZ_64M /* NOR flash (64 Meg aligned) */ +#define FLASH_SIZE_SDPV2 SZ_128M /* NOR flash (256 Meg aligned) */ + +static struct physmap_flash_data board_nor_data = { + .width = 2, +}; + +static struct resource board_nor_resource = { + .flags = IORESOURCE_MEM, +}; + +static struct platform_device board_nor_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &board_nor_data, + }, + .num_resources = 1, + .resource = &board_nor_resource, +}; + +static void +__init board_nor_init(struct mtd_partition *nor_parts, u8 nr_parts, u8 cs) +{ + int err; + + board_nor_data.parts = nor_parts; + board_nor_data.nr_parts = nr_parts; + + /* Configure start address and size of NOR device */ + if (omap_rev() >= OMAP3430_REV_ES1_0) { + err = gpmc_cs_request(cs, FLASH_SIZE_SDPV2 - 1, + (unsigned long *)&board_nor_resource.start); + board_nor_resource.end = board_nor_resource.start + + FLASH_SIZE_SDPV2 - 1; + } else { + err = gpmc_cs_request(cs, FLASH_SIZE_SDPV1 - 1, + (unsigned long *)&board_nor_resource.start); + board_nor_resource.end = board_nor_resource.start + + FLASH_SIZE_SDPV1 - 1; + } + if (err < 0) { + pr_err("NOR: Can't request GPMC CS\n"); + return; + } + if (platform_device_register(&board_nor_device) < 0) + pr_err("Unable to register NOR device\n"); +} + +#if defined(CONFIG_MTD_ONENAND_OMAP2) || \ + defined(CONFIG_MTD_ONENAND_OMAP2_MODULE) +static struct omap_onenand_platform_data board_onenand_data = { + .dma_channel = -1, /* disable DMA in OMAP OneNAND driver */ +}; + +void +__init board_onenand_init(struct mtd_partition *onenand_parts, + u8 nr_parts, u8 cs) +{ + board_onenand_data.cs = cs; + board_onenand_data.parts = onenand_parts; + board_onenand_data.nr_parts = nr_parts; + + gpmc_onenand_init(&board_onenand_data); +} +#endif /* CONFIG_MTD_ONENAND_OMAP2 || CONFIG_MTD_ONENAND_OMAP2_MODULE */ + +#if defined(CONFIG_MTD_NAND_OMAP2) || \ + defined(CONFIG_MTD_NAND_OMAP2_MODULE) + +/* Note that all values in this struct are in nanoseconds */ +struct gpmc_timings nand_default_timings[1] = { + { + .sync_clk = 0, + + .cs_on = 0, + .cs_rd_off = 36, + .cs_wr_off = 36, + + .we_on = 6, + .oe_on = 6, + + .adv_on = 6, + .adv_rd_off = 24, + .adv_wr_off = 36, + + .we_off = 30, + .oe_off = 48, + + .access = 54, + .rd_cycle = 72, + .wr_cycle = 72, + + .wr_access = 30, + .wr_data_mux_bus = 0, + }, +}; + +static struct omap_nand_platform_data board_nand_data; + +void +__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs, + int nand_type, struct gpmc_timings *gpmc_t) +{ + board_nand_data.cs = cs; + board_nand_data.parts = nand_parts; + board_nand_data.nr_parts = nr_parts; + board_nand_data.devsize = nand_type; + + board_nand_data.ecc_opt = OMAP_ECC_HAM1_CODE_HW; + gpmc_nand_init(&board_nand_data, gpmc_t); +} +#endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */ + +/** + * get_gpmc0_type - Reads the FPGA DIP_SWITCH_INPUT_REGISTER2 to get + * the various cs values. + */ +static u8 get_gpmc0_type(void) +{ + u8 cs = 0; + void __iomem *fpga_map_addr; + + fpga_map_addr = ioremap(DEBUG_BASE, 4096); + if (!fpga_map_addr) + return -ENOMEM; + + if (!(readw_relaxed(fpga_map_addr + REG_FPGA_REV))) + /* we dont have an DEBUG FPGA??? */ + /* Depend on #defines!! default to strata boot return param */ + goto unmap; + + /* S8-DIP-OFF = 1, S8-DIP-ON = 0 */ + cs = readw_relaxed(fpga_map_addr + REG_FPGA_DIP_SWITCH_INPUT2) & 0xf; + + /* ES2.0 SDP's onwards 4 dip switches are provided for CS */ + if (omap_rev() >= OMAP3430_REV_ES1_0) + /* change (S8-1:4=DS-2:0) to (S8-4:1=DS-2:0) */ + cs = ((cs & 8) >> 3) | ((cs & 4) >> 1) | + ((cs & 2) << 1) | ((cs & 1) << 3); + else + /* change (S8-1:3=DS-2:0) to (S8-3:1=DS-2:0) */ + cs = ((cs & 4) >> 2) | (cs & 2) | ((cs & 1) << 2); +unmap: + iounmap(fpga_map_addr); + return cs; +} + +/** + * board_flash_init - Identify devices connected to GPMC and register. + * + * @return - void. + */ +void __init board_flash_init(struct flash_partitions partition_info[], + char chip_sel_board[][GPMC_CS_NUM], int nand_type) +{ + u8 cs = 0; + u8 norcs = GPMC_CS_NUM + 1; + u8 nandcs = GPMC_CS_NUM + 1; + u8 onenandcs = GPMC_CS_NUM + 1; + u8 idx; + unsigned char *config_sel = NULL; + + /* REVISIT: Is this return correct idx for 2430 SDP? + * for which cs configuration matches for 2430 SDP? + */ + idx = get_gpmc0_type(); + if (idx >= MAX_SUPPORTED_GPMC_CONFIG) { + pr_err("%s: Invalid chip select: %d\n", __func__, cs); + return; + } + config_sel = (unsigned char *)(chip_sel_board[idx]); + + while (cs < GPMC_CS_NUM) { + switch (config_sel[cs]) { + case PDC_NOR: + if (norcs > GPMC_CS_NUM) + norcs = cs; + break; + case PDC_NAND: + if (nandcs > GPMC_CS_NUM) + nandcs = cs; + break; + case PDC_ONENAND: + if (onenandcs > GPMC_CS_NUM) + onenandcs = cs; + break; + } + cs++; + } + + if (norcs > GPMC_CS_NUM) + pr_err("NOR: Unable to find configuration in GPMC\n"); + else + board_nor_init(partition_info[0].parts, + partition_info[0].nr_parts, norcs); + + if (onenandcs > GPMC_CS_NUM) + pr_err("OneNAND: Unable to find configuration in GPMC\n"); + else + board_onenand_init(partition_info[1].parts, + partition_info[1].nr_parts, onenandcs); + + if (nandcs > GPMC_CS_NUM) + pr_err("NAND: Unable to find configuration in GPMC\n"); + else + board_nand_init(partition_info[2].parts, + partition_info[2].nr_parts, nandcs, + nand_type, nand_default_timings); +} diff --git a/arch/arm/mach-omap2/board-flash.h b/arch/arm/mach-omap2/board-flash.h new file mode 100644 index 00000000000..2fb5d41a9fa --- /dev/null +++ b/arch/arm/mach-omap2/board-flash.h @@ -0,0 +1,62 @@ +/* + * board-sdp.h + * + * Information structures for SDP-specific board config data + * + * Copyright (C) 2009 Nokia Corporation + * Copyright (C) 2009 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include "gpmc.h" + +#define PDC_NOR 1 +#define PDC_NAND 2 +#define PDC_ONENAND 3 +#define DBG_MPDB 4 + +struct flash_partitions { + struct mtd_partition *parts; + int nr_parts; +}; + +#if defined(CONFIG_MTD_NAND_OMAP2) || \ + defined(CONFIG_MTD_NAND_OMAP2_MODULE) || \ + defined(CONFIG_MTD_ONENAND_OMAP2) || \ + defined(CONFIG_MTD_ONENAND_OMAP2_MODULE) +extern void board_flash_init(struct flash_partitions [], + char chip_sel[][GPMC_CS_NUM], int nand_type); +#else +static inline void board_flash_init(struct flash_partitions part[], + char chip_sel[][GPMC_CS_NUM], int nand_type) +{ +} +#endif + +#if defined(CONFIG_MTD_NAND_OMAP2) || \ + defined(CONFIG_MTD_NAND_OMAP2_MODULE) +extern void board_nand_init(struct mtd_partition *nand_parts, + u8 nr_parts, u8 cs, int nand_type, struct gpmc_timings *gpmc_t); +extern struct gpmc_timings nand_default_timings[]; +#else +static inline void board_nand_init(struct mtd_partition *nand_parts, + u8 nr_parts, u8 cs, int nand_type, struct gpmc_timings *gpmc_t) +{ +} +#define nand_default_timings NULL +#endif + +#if defined(CONFIG_MTD_ONENAND_OMAP2) || \ + defined(CONFIG_MTD_ONENAND_OMAP2_MODULE) +extern void board_onenand_init(struct mtd_partition *nand_parts, + u8 nr_parts, u8 cs); +#else +static inline void board_onenand_init(struct mtd_partition *nand_parts, + u8 nr_parts, u8 cs) +{ +} +#endif diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 3b34c20d1df..9480997ba61 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -1,70 +1,278 @@ /* - * linux/arch/arm/mach-omap2/board-generic.c - * * Copyright (C) 2005 Nokia Corporation * Author: Paul Mundt <paul.mundt@nokia.com> * - * Modified from mach-omap/omap1/board-generic.c + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * - * Code for generic OMAP2 board. Should work on many OMAP2 systems where - * the bootloader passes the board-specific data to the kernel. - * Do not put any board specific code to this file; create a new machine - * type if you need custom low-level initializations. + * Modified from the original mach-omap/omap2/board-generic.c did by Paul + * to support the OMAP2+ device tree boards with an unique board file. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include <linux/io.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> +#include <linux/irqdomain.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/device.h> - -#include <mach/hardware.h> -#include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <mach/gpio.h> -#include <mach/mux.h> -#include <mach/usb.h> -#include <mach/board.h> -#include <mach/common.h> +#include "common.h" + +#if !(defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)) +#define intc_of_init NULL +#endif +#ifndef CONFIG_ARCH_OMAP4 +#define gic_of_init NULL +#endif + +static struct of_device_id omap_dt_match_table[] __initdata = { + { .compatible = "simple-bus", }, + { .compatible = "ti,omap-infra", }, + { } +}; -static void __init omap_generic_init_irq(void) +static void __init omap_generic_init(void) { - omap2_init_common_hw(); - omap_init_irq(); + omapdss_early_init_of(); + + pdata_quirks_init(omap_dt_match_table); + + omapdss_init_of(); } -static struct omap_uart_config generic_uart_config __initdata = { - .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), +#ifdef CONFIG_SOC_OMAP2420 +static const char *omap242x_boards_compat[] __initconst = { + "ti,omap2420", + NULL, }; -static struct omap_board_config_kernel generic_config[] = { - { OMAP_TAG_UART, &generic_uart_config }, +DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)") + .reserve = omap_reserve, + .map_io = omap242x_map_io, + .init_early = omap2420_init_early, + .init_irq = omap_intc_of_init, + .handle_irq = omap2_intc_handle_irq, + .init_machine = omap_generic_init, + .init_time = omap2_sync32k_timer_init, + .dt_compat = omap242x_boards_compat, + .restart = omap2xxx_restart, +MACHINE_END +#endif + +#ifdef CONFIG_SOC_OMAP2430 +static const char *omap243x_boards_compat[] __initconst = { + "ti,omap2430", + NULL, }; -static void __init omap_generic_init(void) -{ - omap_board_config = generic_config; - omap_board_config_size = ARRAY_SIZE(generic_config); - omap_serial_init(); -} +DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)") + .reserve = omap_reserve, + .map_io = omap243x_map_io, + .init_early = omap2430_init_early, + .init_irq = omap_intc_of_init, + .handle_irq = omap2_intc_handle_irq, + .init_machine = omap_generic_init, + .init_time = omap2_sync32k_timer_init, + .dt_compat = omap243x_boards_compat, + .restart = omap2xxx_restart, +MACHINE_END +#endif -static void __init omap_generic_map_io(void) -{ - omap2_set_globals_242x(); /* should be 242x, 243x, or 343x */ - omap2_map_common_io(); -} +#ifdef CONFIG_ARCH_OMAP3 +static const char *omap3_boards_compat[] __initconst = { + "ti,omap3430", + "ti,omap3", + NULL, +}; + +DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)") + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap3430_init_early, + .init_irq = omap_intc_of_init, + .handle_irq = omap3_intc_handle_irq, + .init_machine = omap_generic_init, + .init_late = omap3_init_late, + .init_time = omap3_sync32k_timer_init, + .dt_compat = omap3_boards_compat, + .restart = omap3xxx_restart, +MACHINE_END + +static const char *omap36xx_boards_compat[] __initconst = { + "ti,omap36xx", + NULL, +}; + +DT_MACHINE_START(OMAP36XX_DT, "Generic OMAP36xx (Flattened Device Tree)") + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap3630_init_early, + .init_irq = omap_intc_of_init, + .handle_irq = omap3_intc_handle_irq, + .init_machine = omap_generic_init, + .init_late = omap3_init_late, + .init_time = omap3_sync32k_timer_init, + .dt_compat = omap36xx_boards_compat, + .restart = omap3xxx_restart, +MACHINE_END + +static const char *omap3_gp_boards_compat[] __initconst = { + "ti,omap3-beagle", + "timll,omap3-devkit8000", + NULL, +}; + +DT_MACHINE_START(OMAP3_GP_DT, "Generic OMAP3-GP (Flattened Device Tree)") + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap3430_init_early, + .init_irq = omap_intc_of_init, + .handle_irq = omap3_intc_handle_irq, + .init_machine = omap_generic_init, + .init_late = omap3_init_late, + .init_time = omap3_secure_sync32k_timer_init, + .dt_compat = omap3_gp_boards_compat, + .restart = omap3xxx_restart, +MACHINE_END + +static const char *am3517_boards_compat[] __initconst = { + "ti,am3517", + NULL, +}; + +DT_MACHINE_START(AM3517_DT, "Generic AM3517 (Flattened Device Tree)") + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = am35xx_init_early, + .init_irq = omap_intc_of_init, + .handle_irq = omap3_intc_handle_irq, + .init_machine = omap_generic_init, + .init_late = omap3_init_late, + .init_time = omap3_gptimer_timer_init, + .dt_compat = am3517_boards_compat, + .restart = omap3xxx_restart, +MACHINE_END +#endif + +#ifdef CONFIG_SOC_AM33XX +static const char *am33xx_boards_compat[] __initconst = { + "ti,am33xx", + NULL, +}; + +DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)") + .reserve = omap_reserve, + .map_io = am33xx_map_io, + .init_early = am33xx_init_early, + .init_irq = omap_intc_of_init, + .handle_irq = omap3_intc_handle_irq, + .init_machine = omap_generic_init, + .init_late = am33xx_init_late, + .init_time = omap3_gptimer_timer_init, + .dt_compat = am33xx_boards_compat, + .restart = am33xx_restart, +MACHINE_END +#endif + +#ifdef CONFIG_ARCH_OMAP4 +static const char *omap4_boards_compat[] __initconst = { + "ti,omap4460", + "ti,omap4430", + "ti,omap4", + NULL, +}; + +DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)") + .reserve = omap_reserve, + .smp = smp_ops(omap4_smp_ops), + .map_io = omap4_map_io, + .init_early = omap4430_init_early, + .init_irq = omap_gic_of_init, + .init_machine = omap_generic_init, + .init_late = omap4430_init_late, + .init_time = omap4_local_timer_init, + .dt_compat = omap4_boards_compat, + .restart = omap44xx_restart, +MACHINE_END +#endif + +#ifdef CONFIG_SOC_OMAP5 +static const char *omap5_boards_compat[] __initconst = { + "ti,omap5432", + "ti,omap5430", + "ti,omap5", + NULL, +}; + +DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)") + .reserve = omap_reserve, + .smp = smp_ops(omap4_smp_ops), + .map_io = omap5_map_io, + .init_early = omap5_init_early, + .init_irq = omap_gic_of_init, + .init_machine = omap_generic_init, + .init_late = omap5_init_late, + .init_time = omap5_realtime_timer_init, + .dt_compat = omap5_boards_compat, + .restart = omap44xx_restart, +MACHINE_END +#endif + +#ifdef CONFIG_SOC_AM43XX +static const char *am43_boards_compat[] __initconst = { + "ti,am4372", + "ti,am43", + NULL, +}; + +DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)") + .map_io = am33xx_map_io, + .init_early = am43xx_init_early, + .init_late = am43xx_init_late, + .init_irq = omap_gic_of_init, + .init_machine = omap_generic_init, + .init_time = omap3_gptimer_timer_init, + .dt_compat = am43_boards_compat, + .restart = omap44xx_restart, +MACHINE_END +#endif + +#ifdef CONFIG_SOC_DRA7XX +static const char *dra74x_boards_compat[] __initconst = { + "ti,dra742", + "ti,dra7", + NULL, +}; + +DT_MACHINE_START(DRA74X_DT, "Generic DRA74X (Flattened Device Tree)") + .reserve = omap_reserve, + .smp = smp_ops(omap4_smp_ops), + .map_io = omap5_map_io, + .init_early = dra7xx_init_early, + .init_late = dra7xx_init_late, + .init_irq = omap_gic_of_init, + .init_machine = omap_generic_init, + .init_time = omap5_realtime_timer_init, + .dt_compat = dra74x_boards_compat, + .restart = omap44xx_restart, +MACHINE_END + +static const char *dra72x_boards_compat[] __initconst = { + "ti,dra722", + NULL, +}; -MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx") - /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */ - .phys_io = 0x48000000, - .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, - .boot_params = 0x80000100, - .map_io = omap_generic_map_io, - .init_irq = omap_generic_init_irq, +DT_MACHINE_START(DRA72X_DT, "Generic DRA72X (Flattened Device Tree)") + .reserve = omap_reserve, + .map_io = omap5_map_io, + .init_early = dra7xx_init_early, + .init_late = dra7xx_init_late, + .init_irq = omap_gic_of_init, .init_machine = omap_generic_init, - .timer = &omap_timer, + .init_time = omap5_realtime_timer_init, + .dt_compat = dra72x_boards_compat, + .restart = omap44xx_restart, MACHINE_END +#endif diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c deleted file mode 100644 index 5e9b14675b1..00000000000 --- a/arch/arm/mach-omap2/board-h4.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/board-h4.c - * - * Copyright (C) 2005 Nokia Corporation - * Author: Paul Mundt <paul.mundt@nokia.com> - * - * Modified from mach-omap/omap1/board-generic.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/partitions.h> -#include <linux/delay.h> -#include <linux/workqueue.h> -#include <linux/i2c.h> -#include <linux/i2c/at24.h> -#include <linux/input.h> -#include <linux/err.h> -#include <linux/clk.h> -#include <linux/io.h> - -#include <mach/hardware.h> -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/flash.h> - -#include <mach/control.h> -#include <mach/gpio.h> -#include <mach/gpioexpander.h> -#include <mach/mux.h> -#include <mach/usb.h> -#include <mach/irda.h> -#include <mach/board.h> -#include <mach/common.h> -#include <mach/keypad.h> -#include <mach/menelaus.h> -#include <mach/dma.h> -#include <mach/gpmc.h> - -#define H4_FLASH_CS 0 -#define H4_SMC91X_CS 1 - -static unsigned int row_gpios[6] = { 88, 89, 124, 11, 6, 96 }; -static unsigned int col_gpios[7] = { 90, 91, 100, 36, 12, 97, 98 }; - -static int h4_keymap[] = { - KEY(0, 0, KEY_LEFT), - KEY(0, 1, KEY_RIGHT), - KEY(0, 2, KEY_A), - KEY(0, 3, KEY_B), - KEY(0, 4, KEY_C), - KEY(1, 0, KEY_DOWN), - KEY(1, 1, KEY_UP), - KEY(1, 2, KEY_E), - KEY(1, 3, KEY_F), - KEY(1, 4, KEY_G), - KEY(2, 0, KEY_ENTER), - KEY(2, 1, KEY_I), - KEY(2, 2, KEY_J), - KEY(2, 3, KEY_K), - KEY(2, 4, KEY_3), - KEY(3, 0, KEY_M), - KEY(3, 1, KEY_N), - KEY(3, 2, KEY_O), - KEY(3, 3, KEY_P), - KEY(3, 4, KEY_Q), - KEY(4, 0, KEY_R), - KEY(4, 1, KEY_4), - KEY(4, 2, KEY_T), - KEY(4, 3, KEY_U), - KEY(4, 4, KEY_ENTER), - KEY(5, 0, KEY_V), - KEY(5, 1, KEY_W), - KEY(5, 2, KEY_L), - KEY(5, 3, KEY_S), - KEY(5, 4, KEY_ENTER), - 0 -}; - -static struct mtd_partition h4_partitions[] = { - /* bootloader (U-Boot, etc) in first sector */ - { - .name = "bootloader", - .offset = 0, - .size = SZ_128K, - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, - /* bootloader params in the next sector */ - { - .name = "params", - .offset = MTDPART_OFS_APPEND, - .size = SZ_128K, - .mask_flags = 0, - }, - /* kernel */ - { - .name = "kernel", - .offset = MTDPART_OFS_APPEND, - .size = SZ_2M, - .mask_flags = 0 - }, - /* file system */ - { - .name = "filesystem", - .offset = MTDPART_OFS_APPEND, - .size = MTDPART_SIZ_FULL, - .mask_flags = 0 - } -}; - -static struct flash_platform_data h4_flash_data = { - .map_name = "cfi_probe", - .width = 2, - .parts = h4_partitions, - .nr_parts = ARRAY_SIZE(h4_partitions), -}; - -static struct resource h4_flash_resource = { - .flags = IORESOURCE_MEM, -}; - -static struct platform_device h4_flash_device = { - .name = "omapflash", - .id = 0, - .dev = { - .platform_data = &h4_flash_data, - }, - .num_resources = 1, - .resource = &h4_flash_resource, -}; - -/* Select between the IrDA and aGPS module - */ -static int h4_select_irda(struct device *dev, int state) -{ - unsigned char expa; - int err = 0; - - if ((err = read_gpio_expa(&expa, 0x21))) { - printk(KERN_ERR "Error reading from I/O expander\n"); - return err; - } - - /* 'P6' enable/disable IRDA_TX and IRDA_RX */ - if (state & IR_SEL) { /* IrDa */ - if ((err = write_gpio_expa(expa | 0x01, 0x21))) { - printk(KERN_ERR "Error writing to I/O expander\n"); - return err; - } - } else { - if ((err = write_gpio_expa(expa & ~0x01, 0x21))) { - printk(KERN_ERR "Error writing to I/O expander\n"); - return err; - } - } - return err; -} - -static void set_trans_mode(struct work_struct *work) -{ - struct omap_irda_config *irda_config = - container_of(work, struct omap_irda_config, gpio_expa.work); - int mode = irda_config->mode; - unsigned char expa; - int err = 0; - - if ((err = read_gpio_expa(&expa, 0x20)) != 0) { - printk(KERN_ERR "Error reading from I/O expander\n"); - } - - expa &= ~0x01; - - if (!(mode & IR_SIRMODE)) { /* MIR/FIR */ - expa |= 0x01; - } - - if ((err = write_gpio_expa(expa, 0x20)) != 0) { - printk(KERN_ERR "Error writing to I/O expander\n"); - } -} - -static int h4_transceiver_mode(struct device *dev, int mode) -{ - struct omap_irda_config *irda_config = dev->platform_data; - - irda_config->mode = mode; - cancel_delayed_work(&irda_config->gpio_expa); - PREPARE_DELAYED_WORK(&irda_config->gpio_expa, set_trans_mode); - schedule_delayed_work(&irda_config->gpio_expa, 0); - - return 0; -} - -static struct omap_irda_config h4_irda_data = { - .transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE, - .transceiver_mode = h4_transceiver_mode, - .select_irda = h4_select_irda, - .rx_channel = OMAP24XX_DMA_UART3_RX, - .tx_channel = OMAP24XX_DMA_UART3_TX, - .dest_start = OMAP_UART3_BASE, - .src_start = OMAP_UART3_BASE, - .tx_trigger = OMAP24XX_DMA_UART3_TX, - .rx_trigger = OMAP24XX_DMA_UART3_RX, -}; - -static struct resource h4_irda_resources[] = { - [0] = { - .start = INT_24XX_UART3_IRQ, - .end = INT_24XX_UART3_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device h4_irda_device = { - .name = "omapirda", - .id = -1, - .dev = { - .platform_data = &h4_irda_data, - }, - .num_resources = 1, - .resource = h4_irda_resources, -}; - -static struct omap_kp_platform_data h4_kp_data = { - .rows = 6, - .cols = 7, - .keymap = h4_keymap, - .keymapsize = ARRAY_SIZE(h4_keymap), - .rep = 1, - .row_gpios = row_gpios, - .col_gpios = col_gpios, -}; - -static struct platform_device h4_kp_device = { - .name = "omap-keypad", - .id = -1, - .dev = { - .platform_data = &h4_kp_data, - }, -}; - -static struct platform_device h4_lcd_device = { - .name = "lcd_h4", - .id = -1, -}; - -static struct platform_device *h4_devices[] __initdata = { - &h4_flash_device, - &h4_irda_device, - &h4_kp_device, - &h4_lcd_device, -}; - -/* 2420 Sysboot setup (2430 is different) */ -static u32 get_sysboot_value(void) -{ - return (omap_ctrl_readl(OMAP24XX_CONTROL_STATUS) & - (OMAP2_SYSBOOT_5_MASK | OMAP2_SYSBOOT_4_MASK | - OMAP2_SYSBOOT_3_MASK | OMAP2_SYSBOOT_2_MASK | - OMAP2_SYSBOOT_1_MASK | OMAP2_SYSBOOT_0_MASK)); -} - -/* H4-2420's always used muxed mode, H4-2422's always use non-muxed - * - * Note: OMAP-GIT doesn't correctly do is_cpu_omap2422 and is_cpu_omap2423 - * correctly. The macro needs to look at production_id not just hawkeye. - */ -static u32 is_gpmc_muxed(void) -{ - u32 mux; - mux = get_sysboot_value(); - if ((mux & 0xF) == 0xd) - return 1; /* NAND config (could be either) */ - if (mux & 0x2) /* if mux'ed */ - return 1; - else - return 0; -} - -static inline void __init h4_init_debug(void) -{ - int eth_cs; - unsigned long cs_mem_base; - unsigned int muxed, rate; - struct clk *gpmc_fck; - - eth_cs = H4_SMC91X_CS; - - gpmc_fck = clk_get(NULL, "gpmc_fck"); /* Always on ENABLE_ON_INIT */ - if (IS_ERR(gpmc_fck)) { - WARN_ON(1); - return; - } - - clk_enable(gpmc_fck); - rate = clk_get_rate(gpmc_fck); - clk_disable(gpmc_fck); - clk_put(gpmc_fck); - - if (is_gpmc_muxed()) - muxed = 0x200; - else - muxed = 0; - - /* Make sure CS1 timings are correct */ - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1, - 0x00011000 | muxed); - - if (rate >= 160000000) { - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4); - } else if (rate >= 130000000) { - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4); - } else {/* rate = 100000000 */ - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F); - gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2); - } - - if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) { - printk(KERN_ERR "Failed to request GPMC mem for smc91x\n"); - goto out; - } - - udelay(100); - - omap_cfg_reg(M15_24XX_GPIO92); - if (debug_card_init(cs_mem_base, OMAP24XX_ETHR_GPIO_IRQ) < 0) - gpmc_cs_free(eth_cs); - -out: - clk_disable(gpmc_fck); - clk_put(gpmc_fck); -} - -static void __init h4_init_flash(void) -{ - unsigned long base; - - if (gpmc_cs_request(H4_FLASH_CS, SZ_64M, &base) < 0) { - printk("Can't request GPMC CS for flash\n"); - return; - } - h4_flash_resource.start = base; - h4_flash_resource.end = base + SZ_64M - 1; -} - -static void __init omap_h4_init_irq(void) -{ - omap2_init_common_hw(); - omap_init_irq(); - omap_gpio_init(); - h4_init_flash(); -} - -static struct omap_uart_config h4_uart_config __initdata = { - .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), -}; - -static struct omap_lcd_config h4_lcd_config __initdata = { - .ctrl_name = "internal", -}; - -static struct omap_board_config_kernel h4_config[] = { - { OMAP_TAG_UART, &h4_uart_config }, - { OMAP_TAG_LCD, &h4_lcd_config }, -}; - -static struct at24_platform_data m24c01 = { - .byte_len = SZ_1K / 8, - .page_size = 16, -}; - -static struct i2c_board_info __initdata h4_i2c_board_info[] = { - { - I2C_BOARD_INFO("isp1301_omap", 0x2d), - .irq = OMAP_GPIO_IRQ(125), - }, - { /* EEPROM on mainboard */ - I2C_BOARD_INFO("24c01", 0x52), - .platform_data = &m24c01, - }, - { /* EEPROM on cpu card */ - I2C_BOARD_INFO("24c01", 0x57), - .platform_data = &m24c01, - }, -}; - -static void __init omap_h4_init(void) -{ - /* - * Make sure the serial ports are muxed on at this point. - * You have to mux them off in device drivers later on - * if not needed. - */ -#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE) - omap_cfg_reg(K15_24XX_UART3_TX); - omap_cfg_reg(K14_24XX_UART3_RX); -#endif - -#if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE) - if (omap_has_menelaus()) { - row_gpios[5] = 0; - col_gpios[2] = 15; - col_gpios[6] = 18; - } -#endif - - i2c_register_board_info(1, h4_i2c_board_info, - ARRAY_SIZE(h4_i2c_board_info)); - - platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices)); - omap_board_config = h4_config; - omap_board_config_size = ARRAY_SIZE(h4_config); - omap_serial_init(); -} - -static void __init omap_h4_map_io(void) -{ - omap2_set_globals_242x(); - omap2_map_common_io(); -} - -MACHINE_START(OMAP_H4, "OMAP2420 H4 board") - /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */ - .phys_io = 0x48000000, - .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, - .boot_params = 0x80000100, - .map_io = omap_h4_map_io, - .init_irq = omap_h4_init_irq, - .init_machine = omap_h4_init, - .timer = &omap_timer, -MACHINE_END diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index 6031e179926..44a59c3abfb 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c @@ -10,172 +10,421 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ - +#include <linux/gpio.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> #include <linux/delay.h> #include <linux/input.h> +#include <linux/input/matrix_keypad.h> +#include <linux/gpio_keys.h> #include <linux/workqueue.h> #include <linux/err.h> #include <linux/clk.h> #include <linux/spi/spi.h> -#include <linux/spi/ads7846.h> -#include <linux/i2c/twl4030.h> +#include <linux/regulator/fixed.h> +#include <linux/regulator/machine.h> +#include <linux/i2c/twl.h> +#include <linux/io.h> +#include <linux/smsc911x.h> +#include <linux/mmc/host.h> +#include <linux/usb/phy.h> +#include <linux/platform_data/spi-omap2-mcspi.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <mach/board-ldp.h> -#include <mach/mcspi.h> -#include <mach/gpio.h> -#include <mach/board.h> -#include <mach/common.h> -#include <mach/gpmc.h> +#include "common.h" +#include "gpmc.h" +#include "gpmc-smsc911x.h" + +#include <video/omapdss.h> +#include <video/omap-panel-data.h> + +#include "board-flash.h" +#include "mux.h" +#include "hsmmc.h" +#include "control.h" +#include "common-board-devices.h" -#include <asm/io.h> -#include <asm/delay.h> -#include <mach/control.h> +#define LDP_SMSC911X_CS 1 +#define LDP_SMSC911X_GPIO 152 +#define DEBUG_BASE 0x08000000 +#define LDP_ETHR_START DEBUG_BASE + +static uint32_t board_keymap[] = { + KEY(0, 0, KEY_1), + KEY(1, 0, KEY_2), + KEY(2, 0, KEY_3), + KEY(0, 1, KEY_4), + KEY(1, 1, KEY_5), + KEY(2, 1, KEY_6), + KEY(3, 1, KEY_F5), + KEY(0, 2, KEY_7), + KEY(1, 2, KEY_8), + KEY(2, 2, KEY_9), + KEY(3, 2, KEY_F6), + KEY(0, 3, KEY_F7), + KEY(1, 3, KEY_0), + KEY(2, 3, KEY_F8), + PERSISTENT_KEY(4, 5), + KEY(4, 4, KEY_VOLUMEUP), + KEY(5, 5, KEY_VOLUMEDOWN), + 0 +}; -#include "mmc-twl4030.h" +static struct matrix_keymap_data board_map_data = { + .keymap = board_keymap, + .keymap_size = ARRAY_SIZE(board_keymap), +}; -#define SDP3430_SMC91X_CS 3 +static struct twl4030_keypad_data ldp_kp_twl4030_data = { + .keymap_data = &board_map_data, + .rows = 6, + .cols = 6, + .rep = 1, +}; -static struct resource ldp_smc911x_resources[] = { +static struct gpio_keys_button ldp_gpio_keys_buttons[] = { [0] = { - .start = OMAP34XX_ETHR_START, - .end = OMAP34XX_ETHR_START + SZ_4K, - .flags = IORESOURCE_MEM, + .code = KEY_ENTER, + .gpio = 101, + .desc = "enter sw", + .active_low = 1, + .debounce_interval = 30, }, [1] = { - .start = 0, - .end = 0, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + .code = KEY_F1, + .gpio = 102, + .desc = "func 1", + .active_low = 1, + .debounce_interval = 30, + }, + [2] = { + .code = KEY_F2, + .gpio = 103, + .desc = "func 2", + .active_low = 1, + .debounce_interval = 30, + }, + [3] = { + .code = KEY_F3, + .gpio = 104, + .desc = "func 3", + .active_low = 1, + .debounce_interval = 30, + }, + [4] = { + .code = KEY_F4, + .gpio = 105, + .desc = "func 4", + .active_low = 1, + .debounce_interval = 30, }, + [5] = { + .code = KEY_LEFT, + .gpio = 106, + .desc = "left sw", + .active_low = 1, + .debounce_interval = 30, + }, + [6] = { + .code = KEY_RIGHT, + .gpio = 107, + .desc = "right sw", + .active_low = 1, + .debounce_interval = 30, + }, + [7] = { + .code = KEY_UP, + .gpio = 108, + .desc = "up sw", + .active_low = 1, + .debounce_interval = 30, + }, + [8] = { + .code = KEY_DOWN, + .gpio = 109, + .desc = "down sw", + .active_low = 1, + .debounce_interval = 30, + }, +}; + +static struct gpio_keys_platform_data ldp_gpio_keys = { + .buttons = ldp_gpio_keys_buttons, + .nbuttons = ARRAY_SIZE(ldp_gpio_keys_buttons), + .rep = 1, }; -static struct platform_device ldp_smc911x_device = { - .name = "smc911x", +static struct platform_device ldp_gpio_keys_device = { + .name = "gpio-keys", .id = -1, - .num_resources = ARRAY_SIZE(ldp_smc911x_resources), - .resource = ldp_smc911x_resources, + .dev = { + .platform_data = &ldp_gpio_keys, + }, }; -static struct platform_device *ldp_devices[] __initdata = { - &ldp_smc911x_device, +static struct omap_smsc911x_platform_data smsc911x_cfg = { + .cs = LDP_SMSC911X_CS, + .gpio_irq = LDP_SMSC911X_GPIO, + .gpio_reset = -EINVAL, + .flags = SMSC911X_USE_32BIT, }; -static inline void __init ldp_init_smc911x(void) +static inline void __init ldp_init_smsc911x(void) { - int eth_cs; - unsigned long cs_mem_base; - int eth_gpio = 0; + gpmc_smsc911x_init(&smsc911x_cfg); +} - eth_cs = LDP_SMC911X_CS; +/* LCD */ - if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) { - printk(KERN_ERR "Failed to request GPMC mem for smc911x\n"); - return; - } +#define LCD_PANEL_RESET_GPIO 55 +#define LCD_PANEL_QVGA_GPIO 56 + +static const struct display_timing ldp_lcd_videomode = { + .pixelclock = { 0, 5400000, 0 }, + + .hactive = { 0, 240, 0 }, + .hfront_porch = { 0, 3, 0 }, + .hback_porch = { 0, 39, 0 }, + .hsync_len = { 0, 3, 0 }, + + .vactive = { 0, 320, 0 }, + .vfront_porch = { 0, 2, 0 }, + .vback_porch = { 0, 7, 0 }, + .vsync_len = { 0, 1, 0 }, + + .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | + DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE, +}; + +static struct panel_dpi_platform_data ldp_lcd_pdata = { + .name = "lcd", + .source = "dpi.0", + + .data_lines = 18, + + .display_timing = &ldp_lcd_videomode, + + .enable_gpio = -1, /* filled in code */ + .backlight_gpio = -1, /* filled in code */ +}; - ldp_smc911x_resources[0].start = cs_mem_base + 0x0; - ldp_smc911x_resources[0].end = cs_mem_base + 0xff; - udelay(100); +static struct platform_device ldp_lcd_device = { + .name = "panel-dpi", + .id = 0, + .dev.platform_data = &ldp_lcd_pdata, +}; - eth_gpio = LDP_SMC911X_GPIO; +static struct omap_dss_board_info ldp_dss_data = { + .default_display_name = "lcd", +}; + +static void __init ldp_display_init(void) +{ + int r; - ldp_smc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio); + static struct gpio gpios[] __initdata = { + {LCD_PANEL_RESET_GPIO, GPIOF_OUT_INIT_HIGH, "LCD RESET"}, + {LCD_PANEL_QVGA_GPIO, GPIOF_OUT_INIT_HIGH, "LCD QVGA"}, + }; - if (gpio_request(eth_gpio, "smc911x irq") < 0) { - printk(KERN_ERR "Failed to request GPIO%d for smc911x IRQ\n", - eth_gpio); + r = gpio_request_array(gpios, ARRAY_SIZE(gpios)); + if (r) { + pr_err("Cannot request LCD GPIOs, error %d\n", r); return; } - gpio_direction_input(eth_gpio); + + omap_display_init(&ldp_dss_data); } -static void __init omap_ldp_init_irq(void) +static int ldp_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio) { - omap2_init_common_hw(); - omap_init_irq(); - omap_gpio_init(); - ldp_init_smc911x(); + int res; + + /* LCD enable GPIO */ + ldp_lcd_pdata.enable_gpio = gpio + 7; + + /* Backlight enable GPIO */ + ldp_lcd_pdata.backlight_gpio = gpio + 15; + + res = platform_device_register(&ldp_lcd_device); + if (res) + pr_err("Unable to register LCD: %d\n", res); + + return 0; } -static struct omap_uart_config ldp_uart_config __initdata = { - .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), +static struct twl4030_gpio_platform_data ldp_gpio_data = { + .setup = ldp_twl_gpio_setup, }; -static struct omap_board_config_kernel ldp_config[] __initdata = { - { OMAP_TAG_UART, &ldp_uart_config }, +static struct regulator_consumer_supply ldp_vmmc1_supply[] = { + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), }; -static struct twl4030_gpio_platform_data ldp_gpio_data = { - .gpio_base = OMAP_MAX_GPIO_LINES, - .irq_base = TWL4030_GPIO_IRQ_BASE, - .irq_end = TWL4030_GPIO_IRQ_END, +/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ +static struct regulator_init_data ldp_vmmc1 = { + .constraints = { + .min_uV = 1850000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(ldp_vmmc1_supply), + .consumer_supplies = ldp_vmmc1_supply, }; -static struct twl4030_platform_data ldp_twldata = { - .irq_base = TWL4030_IRQ_BASE, - .irq_end = TWL4030_IRQ_END, +/* ads7846 on SPI */ +static struct regulator_consumer_supply ldp_vaux1_supplies[] = { + REGULATOR_SUPPLY("vcc", "spi1.0"), +}; - /* platform_data for children goes here */ - .gpio = &ldp_gpio_data, +/* VAUX1 */ +static struct regulator_init_data ldp_vaux1 = { + .constraints = { + .min_uV = 3000000, + .max_uV = 3000000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(ldp_vaux1_supplies), + .consumer_supplies = ldp_vaux1_supplies, }; -static struct i2c_board_info __initdata ldp_i2c_boardinfo[] = { - { - I2C_BOARD_INFO("twl4030", 0x48), - .flags = I2C_CLIENT_WAKE, - .irq = INT_34XX_SYS_NIRQ, - .platform_data = &ldp_twldata, +static struct regulator_consumer_supply ldp_vpll2_supplies[] = { + REGULATOR_SUPPLY("vdds_dsi", "omapdss"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dpi.0"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"), +}; + +static struct regulator_init_data ldp_vpll2 = { + .constraints = { + .name = "VDVI", + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, }, + .num_consumer_supplies = ARRAY_SIZE(ldp_vpll2_supplies), + .consumer_supplies = ldp_vpll2_supplies, +}; + +static struct twl4030_platform_data ldp_twldata = { + /* platform_data for children goes here */ + .vmmc1 = &ldp_vmmc1, + .vaux1 = &ldp_vaux1, + .vpll2 = &ldp_vpll2, + .gpio = &ldp_gpio_data, + .keypad = &ldp_kp_twl4030_data, }; static int __init omap_i2c_init(void) { - omap_register_i2c_bus(1, 2600, ldp_i2c_boardinfo, - ARRAY_SIZE(ldp_i2c_boardinfo)); + omap3_pmic_get_config(&ldp_twldata, + TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC, 0); + omap3_pmic_init("twl4030", &ldp_twldata); omap_register_i2c_bus(2, 400, NULL, 0); omap_register_i2c_bus(3, 400, NULL, 0); return 0; } -static struct twl4030_hsmmc_info mmc[] __initdata = { +static struct omap2_hsmmc_info mmc[] __initdata = { { .mmc = 1, - .wires = 4, + .caps = MMC_CAP_4_BIT_DATA, .gpio_cd = -EINVAL, .gpio_wp = -EINVAL, }, {} /* Terminator */ }; +static struct platform_device *ldp_devices[] __initdata = { + &ldp_gpio_keys_device, +}; + +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#endif + +static struct mtd_partition ldp_nand_partitions[] = { + /* All the partition sizes are listed in terms of NAND block size */ + { + .name = "X-Loader-NAND", + .offset = 0, + .size = 4 * (64 * 2048), /* 512KB, 0x80000 */ + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "U-Boot-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */ + .size = 10 * (64 * 2048), /* 1.25MB, 0x140000 */ + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "Boot Env-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c0000 */ + .size = 2 * (64 * 2048), /* 256KB, 0x40000 */ + }, + { + .name = "Kernel-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x0200000*/ + .size = 240 * (64 * 2048), /* 30M, 0x1E00000 */ + }, + { + .name = "File System - NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x2000000 */ + .size = MTDPART_SIZ_FULL, /* 96MB, 0x6000000 */ + }, + +}; + +static struct regulator_consumer_supply dummy_supplies[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x.0"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), +}; + static void __init omap_ldp_init(void) { + regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); + omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); + ldp_init_smsc911x(); omap_i2c_init(); platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices)); - omap_board_config = ldp_config; - omap_board_config_size = ARRAY_SIZE(ldp_config); + omap_ads7846_init(1, 54, 310, NULL); omap_serial_init(); - twl4030_mmc_init(mmc); -} + omap_sdrc_init(NULL, NULL); + usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); + usb_musb_init(NULL); + board_nand_init(ldp_nand_partitions, ARRAY_SIZE(ldp_nand_partitions), + 0, 0, nand_default_timings); -static void __init omap_ldp_map_io(void) -{ - omap2_set_globals_343x(); - omap2_map_common_io(); + omap_hsmmc_init(mmc); + ldp_display_init(); } MACHINE_START(OMAP_LDP, "OMAP LDP board") - .phys_io = 0x48000000, - .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, - .boot_params = 0x80000100, - .map_io = omap_ldp_map_io, - .init_irq = omap_ldp_init_irq, + .atag_offset = 0x100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap3430_init_early, + .init_irq = omap3_init_irq, + .handle_irq = omap3_intc_handle_irq, .init_machine = omap_ldp_init, - .timer = &omap_timer, + .init_late = omap3430_init_late, + .init_time = omap3_sync32k_timer_init, + .restart = omap3xxx_restart, MACHINE_END diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c new file mode 100644 index 00000000000..aead77a4bc6 --- /dev/null +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -0,0 +1,622 @@ +/* + * linux/arch/arm/mach-omap2/board-n8x0.c + * + * Copyright (C) 2005-2009 Nokia Corporation + * Author: Juha Yrjola <juha.yrjola@nokia.com> + * + * Modified from mach-omap2/board-generic.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/stddef.h> +#include <linux/i2c.h> +#include <linux/spi/spi.h> +#include <linux/usb/musb.h> +#include <linux/platform_data/spi-omap2-mcspi.h> +#include <linux/platform_data/mtd-onenand-omap2.h> +#include <linux/mfd/menelaus.h> +#include <sound/tlv320aic3x.h> + +#include <asm/mach/arch.h> +#include <asm/mach-types.h> + +#include "common.h" +#include "mmc.h" +#include "soc.h" +#include "gpmc-onenand.h" + +#define TUSB6010_ASYNC_CS 1 +#define TUSB6010_SYNC_CS 4 +#define TUSB6010_GPIO_INT 58 +#define TUSB6010_GPIO_ENABLE 0 +#define TUSB6010_DMACHAN 0x3f + +#define NOKIA_N810_WIMAX (1 << 2) +#define NOKIA_N810 (1 << 1) +#define NOKIA_N800 (1 << 0) + +static u32 board_caps; + +#define board_is_n800() (board_caps & NOKIA_N800) +#define board_is_n810() (board_caps & NOKIA_N810) +#define board_is_n810_wimax() (board_caps & NOKIA_N810_WIMAX) + +static void board_check_revision(void) +{ + if (of_have_populated_dt()) { + if (of_machine_is_compatible("nokia,n800")) + board_caps = NOKIA_N800; + else if (of_machine_is_compatible("nokia,n810")) + board_caps = NOKIA_N810; + else if (of_machine_is_compatible("nokia,n810-wimax")) + board_caps = NOKIA_N810_WIMAX; + } + + if (!board_caps) + pr_err("Unknown board\n"); +} + +#if defined(CONFIG_USB_MUSB_TUSB6010) || defined(CONFIG_USB_MUSB_TUSB6010_MODULE) +/* + * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and + * 1.5 V voltage regulators of PM companion chip. Companion chip will then + * provide then PGOOD signal to TUSB6010 which will release it from reset. + */ +static int tusb_set_power(int state) +{ + int i, retval = 0; + + if (state) { + gpio_set_value(TUSB6010_GPIO_ENABLE, 1); + msleep(1); + + /* Wait until TUSB6010 pulls INT pin down */ + i = 100; + while (i && gpio_get_value(TUSB6010_GPIO_INT)) { + msleep(1); + i--; + } + + if (!i) { + printk(KERN_ERR "tusb: powerup failed\n"); + retval = -ENODEV; + } + } else { + gpio_set_value(TUSB6010_GPIO_ENABLE, 0); + msleep(10); + } + + return retval; +} + +static struct musb_hdrc_config musb_config = { + .multipoint = 1, + .dyn_fifo = 1, + .num_eps = 16, + .ram_bits = 12, +}; + +static struct musb_hdrc_platform_data tusb_data = { + .mode = MUSB_OTG, + .set_power = tusb_set_power, + .min_power = 25, /* x2 = 50 mA drawn from VBUS as peripheral */ + .power = 100, /* Max 100 mA VBUS for host mode */ + .config = &musb_config, +}; + +static void __init n8x0_usb_init(void) +{ + int ret = 0; + static char announce[] __initdata = KERN_INFO "TUSB 6010\n"; + + /* PM companion chip power control pin */ + ret = gpio_request_one(TUSB6010_GPIO_ENABLE, GPIOF_OUT_INIT_LOW, + "TUSB6010 enable"); + if (ret != 0) { + printk(KERN_ERR "Could not get TUSB power GPIO%i\n", + TUSB6010_GPIO_ENABLE); + return; + } + tusb_set_power(0); + + ret = tusb6010_setup_interface(&tusb_data, TUSB6010_REFCLK_19, 2, + TUSB6010_ASYNC_CS, TUSB6010_SYNC_CS, + TUSB6010_GPIO_INT, TUSB6010_DMACHAN); + if (ret != 0) + goto err; + + printk(announce); + + return; + +err: + gpio_free(TUSB6010_GPIO_ENABLE); +} +#else + +static void __init n8x0_usb_init(void) {} + +#endif /*CONFIG_USB_MUSB_TUSB6010 */ + + +static struct omap2_mcspi_device_config p54spi_mcspi_config = { + .turbo_mode = 0, +}; + +static struct spi_board_info n800_spi_board_info[] __initdata = { + { + .modalias = "p54spi", + .bus_num = 2, + .chip_select = 0, + .max_speed_hz = 48000000, + .controller_data = &p54spi_mcspi_config, + }, +}; + +#if defined(CONFIG_MENELAUS) && \ + (defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)) + +/* + * On both N800 and N810, only the first of the two MMC controllers is in use. + * The two MMC slots are multiplexed via Menelaus companion chip over I2C. + * On N800, both slots are powered via Menelaus. On N810, only one of the + * slots is powered via Menelaus. The N810 EMMC is powered via GPIO. + * + * VMMC slot 1 on both N800 and N810 + * VDCDC3_APE and VMCS2_APE slot 2 on N800 + * GPIO23 and GPIO9 slot 2 EMMC on N810 + * + */ +#define N8X0_SLOT_SWITCH_GPIO 96 +#define N810_EMMC_VSD_GPIO 23 +#define N810_EMMC_VIO_GPIO 9 + +static int slot1_cover_open; +static int slot2_cover_open; +static struct device *mmc_device; + +static int n8x0_mmc_switch_slot(struct device *dev, int slot) +{ +#ifdef CONFIG_MMC_DEBUG + dev_dbg(dev, "Choose slot %d\n", slot + 1); +#endif + gpio_set_value(N8X0_SLOT_SWITCH_GPIO, slot); + return 0; +} + +static int n8x0_mmc_set_power_menelaus(struct device *dev, int slot, + int power_on, int vdd) +{ + int mV; + +#ifdef CONFIG_MMC_DEBUG + dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1, + power_on ? "on" : "off", vdd); +#endif + if (slot == 0) { + if (!power_on) + return menelaus_set_vmmc(0); + switch (1 << vdd) { + case MMC_VDD_33_34: + case MMC_VDD_32_33: + case MMC_VDD_31_32: + mV = 3100; + break; + case MMC_VDD_30_31: + mV = 3000; + break; + case MMC_VDD_28_29: + mV = 2800; + break; + case MMC_VDD_165_195: + mV = 1850; + break; + default: + BUG(); + } + return menelaus_set_vmmc(mV); + } else { + if (!power_on) + return menelaus_set_vdcdc(3, 0); + switch (1 << vdd) { + case MMC_VDD_33_34: + case MMC_VDD_32_33: + mV = 3300; + break; + case MMC_VDD_30_31: + case MMC_VDD_29_30: + mV = 3000; + break; + case MMC_VDD_28_29: + case MMC_VDD_27_28: + mV = 2800; + break; + case MMC_VDD_24_25: + case MMC_VDD_23_24: + mV = 2400; + break; + case MMC_VDD_22_23: + case MMC_VDD_21_22: + mV = 2200; + break; + case MMC_VDD_20_21: + mV = 2000; + break; + case MMC_VDD_165_195: + mV = 1800; + break; + default: + BUG(); + } + return menelaus_set_vdcdc(3, mV); + } + return 0; +} + +static void n810_set_power_emmc(struct device *dev, + int power_on) +{ + dev_dbg(dev, "Set EMMC power %s\n", power_on ? "on" : "off"); + + if (power_on) { + gpio_set_value(N810_EMMC_VSD_GPIO, 1); + msleep(1); + gpio_set_value(N810_EMMC_VIO_GPIO, 1); + msleep(1); + } else { + gpio_set_value(N810_EMMC_VIO_GPIO, 0); + msleep(50); + gpio_set_value(N810_EMMC_VSD_GPIO, 0); + msleep(50); + } +} + +static int n8x0_mmc_set_power(struct device *dev, int slot, int power_on, + int vdd) +{ + if (board_is_n800() || slot == 0) + return n8x0_mmc_set_power_menelaus(dev, slot, power_on, vdd); + + n810_set_power_emmc(dev, power_on); + + return 0; +} + +static int n8x0_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode) +{ + int r; + + dev_dbg(dev, "Set slot %d bus mode %s\n", slot + 1, + bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull"); + BUG_ON(slot != 0 && slot != 1); + slot++; + switch (bus_mode) { + case MMC_BUSMODE_OPENDRAIN: + r = menelaus_set_mmc_opendrain(slot, 1); + break; + case MMC_BUSMODE_PUSHPULL: + r = menelaus_set_mmc_opendrain(slot, 0); + break; + default: + BUG(); + } + if (r != 0 && printk_ratelimit()) + dev_err(dev, "MMC: unable to set bus mode for slot %d\n", + slot); + return r; +} + +static int n8x0_mmc_get_cover_state(struct device *dev, int slot) +{ + slot++; + BUG_ON(slot != 1 && slot != 2); + if (slot == 1) + return slot1_cover_open; + else + return slot2_cover_open; +} + +static void n8x0_mmc_callback(void *data, u8 card_mask) +{ + int bit, *openp, index; + + if (board_is_n800()) { + bit = 1 << 1; + openp = &slot2_cover_open; + index = 1; + } else { + bit = 1; + openp = &slot1_cover_open; + index = 0; + } + + if (card_mask & bit) + *openp = 1; + else + *openp = 0; + +#ifdef CONFIG_MMC_OMAP + omap_mmc_notify_cover_event(mmc_device, index, *openp); +#else + pr_warn("MMC: notify cover event not available\n"); +#endif +} + +static int n8x0_mmc_late_init(struct device *dev) +{ + int r, bit, *openp; + int vs2sel; + + mmc_device = dev; + + r = menelaus_set_slot_sel(1); + if (r < 0) + return r; + + if (board_is_n800()) + vs2sel = 0; + else + vs2sel = 2; + + r = menelaus_set_mmc_slot(2, 0, vs2sel, 1); + if (r < 0) + return r; + + n8x0_mmc_set_power(dev, 0, MMC_POWER_ON, 16); /* MMC_VDD_28_29 */ + n8x0_mmc_set_power(dev, 1, MMC_POWER_ON, 16); + + r = menelaus_set_mmc_slot(1, 1, 0, 1); + if (r < 0) + return r; + r = menelaus_set_mmc_slot(2, 1, vs2sel, 1); + if (r < 0) + return r; + + r = menelaus_get_slot_pin_states(); + if (r < 0) + return r; + + if (board_is_n800()) { + bit = 1 << 1; + openp = &slot2_cover_open; + } else { + bit = 1; + openp = &slot1_cover_open; + slot2_cover_open = 0; + } + + /* All slot pin bits seem to be inversed until first switch change */ + if (r == 0xf || r == (0xf & ~bit)) + r = ~r; + + if (r & bit) + *openp = 1; + else + *openp = 0; + + r = menelaus_register_mmc_callback(n8x0_mmc_callback, NULL); + + return r; +} + +static void n8x0_mmc_shutdown(struct device *dev) +{ + int vs2sel; + + if (board_is_n800()) + vs2sel = 0; + else + vs2sel = 2; + + menelaus_set_mmc_slot(1, 0, 0, 0); + menelaus_set_mmc_slot(2, 0, vs2sel, 0); +} + +static void n8x0_mmc_cleanup(struct device *dev) +{ + menelaus_unregister_mmc_callback(); + + gpio_free(N8X0_SLOT_SWITCH_GPIO); + + if (board_is_n810()) { + gpio_free(N810_EMMC_VSD_GPIO); + gpio_free(N810_EMMC_VIO_GPIO); + } +} + +/* + * MMC controller1 has two slots that are multiplexed via I2C. + * MMC controller2 is not in use. + */ +static struct omap_mmc_platform_data mmc1_data = { + .nr_slots = 0, + .switch_slot = n8x0_mmc_switch_slot, + .init = n8x0_mmc_late_init, + .cleanup = n8x0_mmc_cleanup, + .shutdown = n8x0_mmc_shutdown, + .max_freq = 24000000, + .slots[0] = { + .wires = 4, + .set_power = n8x0_mmc_set_power, + .set_bus_mode = n8x0_mmc_set_bus_mode, + .get_cover_state = n8x0_mmc_get_cover_state, + .ocr_mask = MMC_VDD_165_195 | MMC_VDD_30_31 | + MMC_VDD_32_33 | MMC_VDD_33_34, + .name = "internal", + }, + .slots[1] = { + .set_power = n8x0_mmc_set_power, + .set_bus_mode = n8x0_mmc_set_bus_mode, + .get_cover_state = n8x0_mmc_get_cover_state, + .ocr_mask = MMC_VDD_165_195 | MMC_VDD_20_21 | + MMC_VDD_21_22 | MMC_VDD_22_23 | + MMC_VDD_23_24 | MMC_VDD_24_25 | + MMC_VDD_27_28 | MMC_VDD_28_29 | + MMC_VDD_29_30 | MMC_VDD_30_31 | + MMC_VDD_32_33 | MMC_VDD_33_34, + .name = "external", + }, +}; + +static struct omap_mmc_platform_data *mmc_data[OMAP24XX_NR_MMC]; + +static struct gpio n810_emmc_gpios[] __initdata = { + { N810_EMMC_VSD_GPIO, GPIOF_OUT_INIT_LOW, "MMC slot 2 Vddf" }, + { N810_EMMC_VIO_GPIO, GPIOF_OUT_INIT_LOW, "MMC slot 2 Vdd" }, +}; + +static void __init n8x0_mmc_init(void) +{ + int err; + + if (board_is_n810()) { + mmc1_data.slots[0].name = "external"; + + /* + * Some Samsung Movinand chips do not like open-ended + * multi-block reads and fall to braind-dead state + * while doing so. Reducing the number of blocks in + * the transfer or delays in clock disable do not help + */ + mmc1_data.slots[1].name = "internal"; + mmc1_data.slots[1].ban_openended = 1; + } + + err = gpio_request_one(N8X0_SLOT_SWITCH_GPIO, GPIOF_OUT_INIT_LOW, + "MMC slot switch"); + if (err) + return; + + if (board_is_n810()) { + err = gpio_request_array(n810_emmc_gpios, + ARRAY_SIZE(n810_emmc_gpios)); + if (err) { + gpio_free(N8X0_SLOT_SWITCH_GPIO); + return; + } + } + + mmc1_data.nr_slots = 2; + mmc_data[0] = &mmc1_data; +} +#else +static struct omap_mmc_platform_data mmc1_data; +void __init n8x0_mmc_init(void) +{ +} +#endif /* CONFIG_MMC_OMAP */ + +#ifdef CONFIG_MENELAUS + +static int n8x0_auto_sleep_regulators(void) +{ + u32 val; + int ret; + + val = EN_VPLL_SLEEP | EN_VMMC_SLEEP \ + | EN_VAUX_SLEEP | EN_VIO_SLEEP \ + | EN_VMEM_SLEEP | EN_DC3_SLEEP \ + | EN_VC_SLEEP | EN_DC2_SLEEP; + + ret = menelaus_set_regulator_sleep(1, val); + if (ret < 0) { + pr_err("Could not set regulators to sleep on menelaus: %u\n", + ret); + return ret; + } + return 0; +} + +static int n8x0_auto_voltage_scale(void) +{ + int ret; + + ret = menelaus_set_vcore_hw(1400, 1050); + if (ret < 0) { + pr_err("Could not set VCORE voltage on menelaus: %u\n", ret); + return ret; + } + return 0; +} + +static int n8x0_menelaus_late_init(struct device *dev) +{ + int ret; + + ret = n8x0_auto_voltage_scale(); + if (ret < 0) + return ret; + ret = n8x0_auto_sleep_regulators(); + if (ret < 0) + return ret; + return 0; +} + +#else +static int n8x0_menelaus_late_init(struct device *dev) +{ + return 0; +} +#endif + +static struct menelaus_platform_data n8x0_menelaus_platform_data __initdata = { + .late_init = n8x0_menelaus_late_init, +}; + +static struct i2c_board_info __initdata n8x0_i2c_board_info_1[] __initdata = { + { + I2C_BOARD_INFO("menelaus", 0x72), + .irq = 7 + OMAP_INTC_START, + .platform_data = &n8x0_menelaus_platform_data, + }, +}; + +static struct aic3x_pdata n810_aic33_data __initdata = { + .gpio_reset = 118, +}; + +static struct i2c_board_info n810_i2c_board_info_2[] __initdata = { + { + I2C_BOARD_INFO("tlv320aic3x", 0x18), + .platform_data = &n810_aic33_data, + }, +}; + +static int __init n8x0_late_initcall(void) +{ + if (!board_caps) + return -ENODEV; + + n8x0_mmc_init(); + n8x0_usb_init(); + + return 0; +} +omap_late_initcall(n8x0_late_initcall); + +/* + * Legacy init pdata init for n8x0. Note that we want to follow the + * I2C bus numbering starting at 0 for device tree like other omaps. + */ +void * __init n8x0_legacy_init(void) +{ + board_check_revision(); + spi_register_board_info(n800_spi_board_info, + ARRAY_SIZE(n800_spi_board_info)); + i2c_register_board_info(0, n8x0_i2c_board_info_1, + ARRAY_SIZE(n8x0_i2c_board_info_1)); + if (board_is_n810()) + i2c_register_board_info(1, n810_i2c_board_info_2, + ARRAY_SIZE(n810_i2c_board_info_2)); + + return &mmc1_data; +} diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index e39cd2c46cf..e2e52031f05 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -20,34 +20,177 @@ #include <linux/clk.h> #include <linux/io.h> #include <linux/leds.h> +#include <linux/pwm.h> +#include <linux/leds_pwm.h> #include <linux/gpio.h> #include <linux/input.h> #include <linux/gpio_keys.h> +#include <linux/pm_opp.h> +#include <linux/cpu.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/mtd/nand.h> +#include <linux/mmc/host.h> +#include <linux/usb/phy.h> -#include <linux/i2c/twl4030.h> +#include <linux/regulator/machine.h> +#include <linux/i2c/twl.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/flash.h> -#include <mach/board.h> -#include <mach/common.h> -#include <mach/gpmc.h> -#include <mach/nand.h> -#include <mach/mux.h> +#include <video/omapdss.h> +#include <video/omap-panel-data.h> +#include <linux/platform_data/mtd-nand-omap2.h> + +#include "common.h" +#include "omap_device.h" +#include "gpmc.h" +#include "soc.h" +#include "mux.h" +#include "hsmmc.h" +#include "pm.h" +#include "board-flash.h" +#include "common-board-devices.h" + +#define NAND_CS 0 + +static struct pwm_lookup pwm_lookup[] = { + /* LEDB -> PMU_STAT */ + PWM_LOOKUP("twl-pwmled", 1, "leds_pwm", "beagleboard::pmu_stat", + 7812500, PWM_POLARITY_NORMAL), +}; + +static struct led_pwm pwm_leds[] = { + { + .name = "beagleboard::pmu_stat", + .max_brightness = 127, + .pwm_period_ns = 7812500, + }, +}; + +static struct led_pwm_platform_data pwm_data = { + .num_leds = ARRAY_SIZE(pwm_leds), + .leds = pwm_leds, +}; -#include "mmc-twl4030.h" +static struct platform_device leds_pwm = { + .name = "leds_pwm", + .id = -1, + .dev = { + .platform_data = &pwm_data, + }, +}; -#define GPMC_CS0_BASE 0x60 -#define GPMC_CS_SIZE 0x30 +/* + * OMAP3 Beagle revision + * Run time detection of Beagle revision is done by reading GPIO. + * GPIO ID - + * AXBX = GPIO173, GPIO172, GPIO171: 1 1 1 + * C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0 + * C4 = GPIO173, GPIO172, GPIO171: 1 0 1 + * XMA/XMB = GPIO173, GPIO172, GPIO171: 0 0 0 + * XMC = GPIO173, GPIO172, GPIO171: 0 1 0 + */ +enum { + OMAP3BEAGLE_BOARD_UNKN = 0, + OMAP3BEAGLE_BOARD_AXBX, + OMAP3BEAGLE_BOARD_C1_3, + OMAP3BEAGLE_BOARD_C4, + OMAP3BEAGLE_BOARD_XM, + OMAP3BEAGLE_BOARD_XMC, +}; + +static u8 omap3_beagle_version; + +/* + * Board-specific configuration + * Defaults to BeagleBoard-xMC + */ +static struct { + int mmc1_gpio_wp; + bool usb_pwr_level; /* 0 - Active Low, 1 - Active High */ + int dvi_pd_gpio; + int usr_button_gpio; + int mmc_caps; +} beagle_config = { + .mmc1_gpio_wp = -EINVAL, + .usb_pwr_level = 0, + .dvi_pd_gpio = -EINVAL, + .usr_button_gpio = 4, + .mmc_caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, +}; + +static struct gpio omap3_beagle_rev_gpios[] __initdata = { + { 171, GPIOF_IN, "rev_id_0" }, + { 172, GPIOF_IN, "rev_id_1" }, + { 173, GPIOF_IN, "rev_id_2" }, +}; + +static void __init omap3_beagle_init_rev(void) +{ + int ret; + u16 beagle_rev = 0; + + omap_mux_init_gpio(171, OMAP_PIN_INPUT_PULLUP); + omap_mux_init_gpio(172, OMAP_PIN_INPUT_PULLUP); + omap_mux_init_gpio(173, OMAP_PIN_INPUT_PULLUP); + + ret = gpio_request_array(omap3_beagle_rev_gpios, + ARRAY_SIZE(omap3_beagle_rev_gpios)); + if (ret < 0) { + printk(KERN_ERR "Unable to get revision detection GPIO pins\n"); + omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN; + return; + } -#define NAND_BLOCK_SIZE SZ_128K + beagle_rev = gpio_get_value(171) | (gpio_get_value(172) << 1) + | (gpio_get_value(173) << 2); + + gpio_free_array(omap3_beagle_rev_gpios, + ARRAY_SIZE(omap3_beagle_rev_gpios)); + + switch (beagle_rev) { + case 7: + printk(KERN_INFO "OMAP3 Beagle Rev: Ax/Bx\n"); + omap3_beagle_version = OMAP3BEAGLE_BOARD_AXBX; + beagle_config.mmc1_gpio_wp = 29; + beagle_config.dvi_pd_gpio = 170; + beagle_config.usr_button_gpio = 7; + break; + case 6: + printk(KERN_INFO "OMAP3 Beagle Rev: C1/C2/C3\n"); + omap3_beagle_version = OMAP3BEAGLE_BOARD_C1_3; + beagle_config.mmc1_gpio_wp = 23; + beagle_config.dvi_pd_gpio = 170; + beagle_config.usr_button_gpio = 7; + break; + case 5: + printk(KERN_INFO "OMAP3 Beagle Rev: C4\n"); + omap3_beagle_version = OMAP3BEAGLE_BOARD_C4; + beagle_config.mmc1_gpio_wp = 23; + beagle_config.dvi_pd_gpio = 170; + beagle_config.usr_button_gpio = 7; + break; + case 0: + printk(KERN_INFO "OMAP3 Beagle Rev: xM Ax/Bx\n"); + omap3_beagle_version = OMAP3BEAGLE_BOARD_XM; + beagle_config.usb_pwr_level = 1; + beagle_config.mmc_caps &= ~MMC_CAP_8_BIT_DATA; + break; + case 2: + printk(KERN_INFO "OMAP3 Beagle Rev: xM C\n"); + omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC; + beagle_config.mmc_caps &= ~MMC_CAP_8_BIT_DATA; + break; + default: + printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev); + omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN; + } +} static struct mtd_partition omap3beagle_nand_partitions[] = { /* All the partition sizes are listed in terms of NAND block size */ @@ -80,73 +223,135 @@ static struct mtd_partition omap3beagle_nand_partitions[] = { }, }; -static struct omap_nand_platform_data omap3beagle_nand_data = { - .options = NAND_BUSWIDTH_16, - .parts = omap3beagle_nand_partitions, - .nr_parts = ARRAY_SIZE(omap3beagle_nand_partitions), - .dma_channel = -1, /* disable DMA in OMAP NAND driver */ - .nand_setup = NULL, - .dev_ready = NULL, +/* DSS */ + +static struct connector_dvi_platform_data beagle_dvi_connector_pdata = { + .name = "dvi", + .source = "tfp410.0", + .i2c_bus_num = 3, }; -static struct resource omap3beagle_nand_resource = { - .flags = IORESOURCE_MEM, +static struct platform_device beagle_dvi_connector_device = { + .name = "connector-dvi", + .id = 0, + .dev.platform_data = &beagle_dvi_connector_pdata, }; -static struct platform_device omap3beagle_nand_device = { - .name = "omap2-nand", - .id = -1, - .dev = { - .platform_data = &omap3beagle_nand_data, - }, - .num_resources = 1, - .resource = &omap3beagle_nand_resource, +static struct encoder_tfp410_platform_data beagle_tfp410_pdata = { + .name = "tfp410.0", + .source = "dpi.0", + .data_lines = 24, + .power_down_gpio = -1, +}; + +static struct platform_device beagle_tfp410_device = { + .name = "tfp410", + .id = 0, + .dev.platform_data = &beagle_tfp410_pdata, +}; + +static struct connector_atv_platform_data beagle_tv_pdata = { + .name = "tv", + .source = "venc.0", + .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, + .invert_polarity = false, +}; + +static struct platform_device beagle_tv_connector_device = { + .name = "connector-analog-tv", + .id = 0, + .dev.platform_data = &beagle_tv_pdata, }; -static struct omap_uart_config omap3_beagle_uart_config __initdata = { - .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), +static struct omap_dss_board_info beagle_dss_data = { + .default_display_name = "dvi", }; -static struct twl4030_hsmmc_info mmc[] = { +#include "sdram-micron-mt46h32m32lf-6.h" + +static struct omap2_hsmmc_info mmc[] = { { .mmc = 1, - .wires = 8, - .gpio_wp = 29, + .caps = MMC_CAP_4_BIT_DATA, + .gpio_wp = -EINVAL, + .deferred = true, }, {} /* Terminator */ }; +static struct regulator_consumer_supply beagle_vmmc1_supply[] = { + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), +}; + +static struct regulator_consumer_supply beagle_vsim_supply[] = { + REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"), +}; + static struct gpio_led gpio_leds[]; +static struct usbhs_phy_data phy_data[] = { + { + .port = 2, + .reset_gpio = 147, + .vcc_gpio = -1, /* updated in beagle_twl_gpio_setup */ + .vcc_polarity = 1, /* updated in beagle_twl_gpio_setup */ + }, +}; + static int beagle_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio) { + int r; + + mmc[0].gpio_wp = beagle_config.mmc1_gpio_wp; /* gpio + 0 is "mmc0_cd" (input/IRQ) */ - omap_cfg_reg(AH8_34XX_GPIO29); mmc[0].gpio_cd = gpio + 0; - twl4030_mmc_init(mmc); + omap_hsmmc_late_init(mmc); - /* REVISIT: need ehci-omap hooks for external VBUS - * power switch and overcurrent detect + /* + * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active + * high / others active low) + * DVI reset GPIO is different between beagle revisions */ + /* Valid for all -xM revisions */ + if (cpu_is_omap3630()) { + /* + * gpio + 1 on Xm controls the TFP410's enable line (active low) + * gpio + 2 control varies depending on the board rev as below: + * P7/P8 revisions(prototype): Camera EN + * A2+ revisions (production): LDO (DVI, serial, led blocks) + */ + r = gpio_request_one(gpio + 1, GPIOF_OUT_INIT_LOW, + "nDVI_PWR_EN"); + if (r) + pr_err("%s: unable to configure nDVI_PWR_EN\n", + __func__); + + beagle_config.dvi_pd_gpio = gpio + 2; + + } else { + /* + * REVISIT: need ehci-omap hooks for external VBUS + * power switch and overcurrent detect + */ + if (gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC")) + pr_err("%s: unable to configure EHCI_nOC\n", __func__); + } + beagle_tfp410_pdata.power_down_gpio = beagle_config.dvi_pd_gpio; - gpio_request(gpio + 1, "EHCI_nOC"); - gpio_direction_input(gpio + 1); - - /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */ - gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR"); - gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1); + platform_device_register(&beagle_tfp410_device); + platform_device_register(&beagle_dvi_connector_device); + platform_device_register(&beagle_tv_connector_device); - /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ - gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; + /* TWL4030_GPIO_MAX i.e. LED_GPO controls HS USB Port 2 power */ + phy_data[0].vcc_gpio = gpio + TWL4030_GPIO_MAX; + phy_data[0].vcc_polarity = beagle_config.usb_pwr_level; + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); return 0; } static struct twl4030_gpio_platform_data beagle_gpio_data = { - .gpio_base = OMAP_MAX_GPIO_LINES, - .irq_base = TWL4030_GPIO_IRQ_BASE, - .irq_end = TWL4030_GPIO_IRQ_END, .use_leds = true, .pullups = BIT(1), .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13) @@ -154,52 +359,65 @@ static struct twl4030_gpio_platform_data beagle_gpio_data = { .setup = beagle_twl_gpio_setup, }; -static struct twl4030_platform_data beagle_twldata = { - .irq_base = TWL4030_IRQ_BASE, - .irq_end = TWL4030_IRQ_END, +/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ +static struct regulator_init_data beagle_vmmc1 = { + .constraints = { + .min_uV = 1850000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(beagle_vmmc1_supply), + .consumer_supplies = beagle_vmmc1_supply, +}; + +/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */ +static struct regulator_init_data beagle_vsim = { + .constraints = { + .min_uV = 1800000, + .max_uV = 3000000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(beagle_vsim_supply), + .consumer_supplies = beagle_vsim_supply, +}; +static struct twl4030_platform_data beagle_twldata = { /* platform_data for children goes here */ .gpio = &beagle_gpio_data, + .vmmc1 = &beagle_vmmc1, + .vsim = &beagle_vsim, }; -static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = { - { - I2C_BOARD_INFO("twl4030", 0x48), - .flags = I2C_CLIENT_WAKE, - .irq = INT_34XX_SYS_NIRQ, - .platform_data = &beagle_twldata, - }, +static struct i2c_board_info __initdata beagle_i2c_eeprom[] = { + { + I2C_BOARD_INFO("eeprom", 0x50), + }, }; static int __init omap3_beagle_i2c_init(void) { - omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo, - ARRAY_SIZE(beagle_i2c_boardinfo)); -#ifdef CONFIG_I2C2_OMAP_BEAGLE - omap_register_i2c_bus(2, 400, NULL, 0); -#endif + omap3_pmic_get_config(&beagle_twldata, + TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC | + TWL_COMMON_PDATA_AUDIO, + TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2); + + beagle_twldata.vpll2->constraints.name = "VDVI"; + + omap3_pmic_init("twl4030", &beagle_twldata); /* Bus 3 is attached to the DVI port where devices like the pico DLP * projector don't work reliably with 400kHz */ - omap_register_i2c_bus(3, 100, NULL, 0); + omap_register_i2c_bus(3, 100, beagle_i2c_eeprom, ARRAY_SIZE(beagle_i2c_eeprom)); return 0; } -static void __init omap3_beagle_init_irq(void) -{ - omap2_init_common_hw(); - omap_init_irq(); - omap_gpio_init(); -} - -static struct platform_device omap3_beagle_lcd_device = { - .name = "omap3beagle_lcd", - .id = -1, -}; - -static struct omap_lcd_config omap3_beagle_lcd_config __initdata = { - .ctrl_name = "internal", -}; - static struct gpio_led gpio_leds[] = { { .name = "beagleboard::usr0", @@ -211,11 +429,6 @@ static struct gpio_led gpio_leds[] = { .default_trigger = "mmc0", .gpio = 149, }, - { - .name = "beagleboard::pmu_stat", - .gpio = -EINVAL, /* gets replaced */ - .active_low = true, - }, }; static struct gpio_led_platform_data gpio_led_info = { @@ -234,7 +447,8 @@ static struct platform_device leds_gpio = { static struct gpio_keys_button gpio_buttons[] = { { .code = BTN_EXTRA, - .gpio = 7, + /* Dynamically assigned depending on board */ + .gpio = -EINVAL, .desc = "user", .wakeup = 1, }, @@ -253,85 +467,130 @@ static struct platform_device keys_gpio = { }, }; -static struct omap_board_config_kernel omap3_beagle_config[] __initdata = { - { OMAP_TAG_UART, &omap3_beagle_uart_config }, - { OMAP_TAG_LCD, &omap3_beagle_lcd_config }, +static struct platform_device madc_hwmon = { + .name = "twl4030_madc_hwmon", + .id = -1, }; static struct platform_device *omap3_beagle_devices[] __initdata = { - &omap3_beagle_lcd_device, &leds_gpio, &keys_gpio, + &madc_hwmon, + &leds_pwm, }; -static void __init omap3beagle_flash_init(void) -{ - u8 cs = 0; - u8 nandcs = GPMC_CS_NUM + 1; +static struct usbhs_omap_platform_data usbhs_bdata __initdata = { + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, +}; - u32 gpmc_base_add = OMAP34XX_GPMC_VIRT; +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#endif - /* find out the chip-select on which NAND exists */ - while (cs < GPMC_CS_NUM) { - u32 ret = 0; - ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); +static int __init beagle_opp_init(void) +{ + int r = 0; - if ((ret & 0xC00) == 0x800) { - printk(KERN_INFO "Found NAND on CS%d\n", cs); - if (nandcs > GPMC_CS_NUM) - nandcs = cs; - } - cs++; - } + if (!machine_is_omap3_beagle()) + return 0; - if (nandcs > GPMC_CS_NUM) { - printk(KERN_INFO "NAND: Unable to find configuration " - "in GPMC\n "); - return; + /* Initialize the omap3 opp table if not already created. */ + r = omap3_opp_init(); + if (r < 0 && (r != -EEXIST)) { + pr_err("%s: opp default init failed\n", __func__); + return r; } - if (nandcs < GPMC_CS_NUM) { - omap3beagle_nand_data.cs = nandcs; - omap3beagle_nand_data.gpmc_cs_baseaddr = (void *) - (gpmc_base_add + GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE); - omap3beagle_nand_data.gpmc_baseaddr = (void *) (gpmc_base_add); + /* Custom OPP enabled for all xM versions */ + if (cpu_is_omap3630()) { + struct device *mpu_dev, *iva_dev; + + mpu_dev = get_cpu_device(0); + iva_dev = omap_device_get_by_hwmod_name("iva"); - printk(KERN_INFO "Registering NAND on CS%d\n", nandcs); - if (platform_device_register(&omap3beagle_nand_device) < 0) - printk(KERN_ERR "Unable to register NAND device\n"); + if (!mpu_dev || IS_ERR(iva_dev)) { + pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n", + __func__, mpu_dev, iva_dev); + return -ENODEV; + } + /* Enable MPU 1GHz and lower opps */ + r = dev_pm_opp_enable(mpu_dev, 800000000); + /* TODO: MPU 1GHz needs SR and ABB */ + + /* Enable IVA 800MHz and lower opps */ + r |= dev_pm_opp_enable(iva_dev, 660000000); + /* TODO: DSP 800MHz needs SR and ABB */ + if (r) { + pr_err("%s: failed to enable higher opp %d\n", + __func__, r); + /* + * Cleanup - disable the higher freqs - we dont care + * about the results + */ + dev_pm_opp_disable(mpu_dev, 800000000); + dev_pm_opp_disable(iva_dev, 660000000); + } } + return 0; } +omap_device_initcall(beagle_opp_init); static void __init omap3_beagle_init(void) { + omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); + omap3_beagle_init_rev(); + + if (gpio_is_valid(beagle_config.mmc1_gpio_wp)) + omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT); + mmc[0].caps = beagle_config.mmc_caps; + omap_hsmmc_init(mmc); + omap3_beagle_i2c_init(); + + gpio_buttons[0].gpio = beagle_config.usr_button_gpio; + platform_add_devices(omap3_beagle_devices, ARRAY_SIZE(omap3_beagle_devices)); - omap_board_config = omap3_beagle_config; - omap_board_config_size = ARRAY_SIZE(omap3_beagle_config); + if (gpio_is_valid(beagle_config.dvi_pd_gpio)) + omap_mux_init_gpio(beagle_config.dvi_pd_gpio, OMAP_PIN_OUTPUT); + omap_display_init(&beagle_dss_data); + omap_serial_init(); + omap_sdrc_init(mt46h32m32lf6_sdrc_params, + mt46h32m32lf6_sdrc_params); - omap_cfg_reg(J25_34XX_GPIO170); - gpio_request(170, "DVI_nPD"); - /* REVISIT leave DVI powered down until it's needed ... */ - gpio_direction_output(170, true); + usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); + usb_musb_init(NULL); - omap3beagle_flash_init(); -} + usbhs_init(&usbhs_bdata); -static void __init omap3_beagle_map_io(void) -{ - omap2_set_globals_343x(); - omap2_map_common_io(); + board_nand_init(omap3beagle_nand_partitions, + ARRAY_SIZE(omap3beagle_nand_partitions), NAND_CS, + NAND_BUSWIDTH_16, NULL); + omap_twl4030_audio_init("omap3beagle", NULL); + + /* Ensure msecure is mux'd to be able to set the RTC. */ + omap_mux_init_signal("sys_drm_msecure", OMAP_PIN_OFF_OUTPUT_HIGH); + + /* Ensure SDRC pins are mux'd for self-refresh */ + omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); + omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); + + pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup)); } MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board") /* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */ - .phys_io = 0x48000000, - .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, - .boot_params = 0x80000100, - .map_io = omap3_beagle_map_io, - .init_irq = omap3_beagle_init_irq, + .atag_offset = 0x100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap3_init_early, + .init_irq = omap3_init_irq, + .handle_irq = omap3_intc_handle_irq, .init_machine = omap3_beagle_init, - .timer = &omap_timer, + .init_late = omap3_init_late, + .init_time = omap3_secure_sync32k_timer_init, + .restart = omap3xxx_restart, MACHINE_END diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c new file mode 100644 index 00000000000..bab51e64c4b --- /dev/null +++ b/arch/arm/mach-omap2/board-omap3logic.c @@ -0,0 +1,251 @@ +/* + * linux/arch/arm/mach-omap2/board-omap3logic.c + * + * Copyright (C) 2010 Li-Pro.Net + * Stephan Linz <linz@li-pro.net> + * + * Copyright (C) 2010-2012 Logic Product Development, Inc. + * Peter Barada <peter.barada@logicpd.com> + * Ashwin BIhari <ashwin.bihari@logicpd.com> + * + * Modified from Beagle, EVM, and RX51 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/gpio.h> + +#include <linux/regulator/fixed.h> +#include <linux/regulator/machine.h> + +#include <linux/i2c/twl.h> +#include <linux/mmc/host.h> +#include <linux/usb/phy.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include "common.h" +#include "mux.h" +#include "hsmmc.h" +#include "control.h" +#include "common-board-devices.h" +#include "gpmc.h" +#include "gpmc-smsc911x.h" + +#define OMAP3LOGIC_SMSC911X_CS 1 + +#define OMAP3530_LV_SOM_MMC_GPIO_CD 110 +#define OMAP3530_LV_SOM_MMC_GPIO_WP 126 +#define OMAP3530_LV_SOM_SMSC911X_GPIO_IRQ 152 + +#define OMAP3_TORPEDO_MMC_GPIO_CD 127 +#define OMAP3_TORPEDO_SMSC911X_GPIO_IRQ 129 + +static struct regulator_consumer_supply omap3logic_vmmc1_supply[] = { + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), +}; + +/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ +static struct regulator_init_data omap3logic_vmmc1 = { + .constraints = { + .name = "VMMC1", + .min_uV = 1850000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(omap3logic_vmmc1_supply), + .consumer_supplies = omap3logic_vmmc1_supply, +}; + +static struct twl4030_gpio_platform_data omap3logic_gpio_data = { + .use_leds = true, + .pullups = BIT(1), + .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) + | BIT(13) | BIT(15) | BIT(16) | BIT(17), +}; + +static struct twl4030_usb_data omap3logic_usb_data = { + .usb_mode = T2_USB_MODE_ULPI, +}; + + +static struct twl4030_platform_data omap3logic_twldata = { + /* platform_data for children goes here */ + .gpio = &omap3logic_gpio_data, + .vmmc1 = &omap3logic_vmmc1, + .usb = &omap3logic_usb_data, +}; + +static int __init omap3logic_i2c_init(void) +{ + omap3_pmic_init("twl4030", &omap3logic_twldata); + return 0; +} + +static struct omap2_hsmmc_info __initdata board_mmc_info[] = { + { + .name = "external", + .mmc = 1, + .caps = MMC_CAP_4_BIT_DATA, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + }, + {} /* Terminator */ +}; + +static void __init board_mmc_init(void) +{ + if (machine_is_omap3530_lv_som()) { + /* OMAP3530 LV SOM board */ + board_mmc_info[0].gpio_cd = OMAP3530_LV_SOM_MMC_GPIO_CD; + board_mmc_info[0].gpio_wp = OMAP3530_LV_SOM_MMC_GPIO_WP; + omap_mux_init_signal("gpio_110", OMAP_PIN_OUTPUT); + omap_mux_init_signal("gpio_126", OMAP_PIN_OUTPUT); + } else if (machine_is_omap3_torpedo()) { + /* OMAP3 Torpedo board */ + board_mmc_info[0].gpio_cd = OMAP3_TORPEDO_MMC_GPIO_CD; + omap_mux_init_signal("gpio_127", OMAP_PIN_OUTPUT); + } else { + /* unsupported board */ + printk(KERN_ERR "%s(): unknown machine type\n", __func__); + return; + } + + omap_hsmmc_init(board_mmc_info); +} + +static struct omap_smsc911x_platform_data __initdata board_smsc911x_data = { + .cs = OMAP3LOGIC_SMSC911X_CS, + .gpio_irq = -EINVAL, + .gpio_reset = -EINVAL, +}; + +/* TODO/FIXME (comment by Peter Barada, LogicPD): + * Fix the PBIAS voltage for Torpedo MMC1 pins that + * are used for other needs (IRQs, etc). */ +static void omap3torpedo_fix_pbias_voltage(void) +{ + u16 control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE; + u32 reg; + + if (machine_is_omap3_torpedo()) + { + /* Set the bias for the pin */ + reg = omap_ctrl_readl(control_pbias_offset); + + reg &= ~OMAP343X_PBIASLITEPWRDNZ1; + omap_ctrl_writel(reg, control_pbias_offset); + + /* 100ms delay required for PBIAS configuration */ + msleep(100); + + reg |= OMAP343X_PBIASLITEVMODE1; + reg |= OMAP343X_PBIASLITEPWRDNZ1; + omap_ctrl_writel(reg | 0x300, control_pbias_offset); + } +} + +static inline void __init board_smsc911x_init(void) +{ + if (machine_is_omap3530_lv_som()) { + /* OMAP3530 LV SOM board */ + board_smsc911x_data.gpio_irq = + OMAP3530_LV_SOM_SMSC911X_GPIO_IRQ; + omap_mux_init_signal("gpio_152", OMAP_PIN_INPUT); + } else if (machine_is_omap3_torpedo()) { + /* OMAP3 Torpedo board */ + board_smsc911x_data.gpio_irq = OMAP3_TORPEDO_SMSC911X_GPIO_IRQ; + omap_mux_init_signal("gpio_129", OMAP_PIN_INPUT); + } else { + /* unsupported board */ + printk(KERN_ERR "%s(): unknown machine type\n", __func__); + return; + } + + gpmc_smsc911x_init(&board_smsc911x_data); +} + +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + /* mUSB */ + OMAP3_MUX(HSUSB0_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_STP, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), + OMAP3_MUX(HSUSB0_DIR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_NXT, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + OMAP3_MUX(HSUSB0_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), + + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#endif + +static struct regulator_consumer_supply dummy_supplies[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x.0"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), +}; + +static void __init omap3logic_init(void) +{ + regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); + omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); + omap3torpedo_fix_pbias_voltage(); + omap3logic_i2c_init(); + omap_serial_init(); + omap_sdrc_init(NULL, NULL); + board_mmc_init(); + board_smsc911x_init(); + + usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); + usb_musb_init(NULL); + + /* Ensure SDRC pins are mux'd for self-refresh */ + omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); + omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); +} + +MACHINE_START(OMAP3_TORPEDO, "Logic OMAP3 Torpedo board") + .atag_offset = 0x100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap35xx_init_early, + .init_irq = omap3_init_irq, + .handle_irq = omap3_intc_handle_irq, + .init_machine = omap3logic_init, + .init_late = omap35xx_init_late, + .init_time = omap3_sync32k_timer_init, + .restart = omap3xxx_restart, +MACHINE_END + +MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board") + .atag_offset = 0x100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap35xx_init_early, + .init_irq = omap3_init_irq, + .handle_irq = omap3_intc_handle_irq, + .init_machine = omap3logic_init, + .init_late = omap35xx_init_late, + .init_time = omap3_sync32k_timer_init, + .restart = omap3xxx_restart, +MACHINE_END diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index b3196107afd..cf18340eb3b 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -22,191 +22,611 @@ #include <linux/platform_device.h> #include <linux/spi/spi.h> -#include <linux/spi/ads7846.h> -#include <linux/i2c/twl4030.h> +#include <linux/regulator/machine.h> +#include <linux/i2c/twl.h> +#include <linux/wl12xx.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/nand.h> +#include <linux/leds.h> +#include <linux/input.h> +#include <linux/input/matrix_keypad.h> +#include <linux/gpio.h> +#include <linux/gpio_keys.h> +#include <linux/mmc/host.h> +#include <linux/mmc/card.h> +#include <linux/regulator/fixed.h> +#include <linux/usb/phy.h> +#include <linux/platform_data/spi-omap2-mcspi.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <mach/board.h> -#include <mach/common.h> -#include <mach/gpio.h> -#include <mach/hardware.h> -#include <mach/mcspi.h> +#include "common.h" +#include <video/omapdss.h> +#include <video/omap-panel-data.h> +#include <linux/platform_data/mtd-nand-omap2.h> -#include "mmc-twl4030.h" +#include "mux.h" +#include "sdram-micron-mt46h32m32lf-6.h" +#include "hsmmc.h" +#include "common-board-devices.h" +#include "gpmc-nand.h" +#define PANDORA_WIFI_IRQ_GPIO 21 +#define PANDORA_WIFI_NRESET_GPIO 23 #define OMAP3_PANDORA_TS_GPIO 94 -static struct twl4030_hsmmc_info omap3pandora_mmc[] = { +static struct mtd_partition omap3pandora_nand_partitions[] = { + { + .name = "xloader", + .offset = 0, + .size = 4 * NAND_BLOCK_SIZE, + .mask_flags = MTD_WRITEABLE + }, { + .name = "uboot", + .offset = MTDPART_OFS_APPEND, + .size = 15 * NAND_BLOCK_SIZE, + }, { + .name = "uboot-env", + .offset = MTDPART_OFS_APPEND, + .size = 1 * NAND_BLOCK_SIZE, + }, { + .name = "boot", + .offset = MTDPART_OFS_APPEND, + .size = 80 * NAND_BLOCK_SIZE, + }, { + .name = "rootfs", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct omap_nand_platform_data pandora_nand_data = { + .cs = 0, + .devsize = NAND_BUSWIDTH_16, + .xfer_type = NAND_OMAP_PREFETCH_DMA, + .parts = omap3pandora_nand_partitions, + .nr_parts = ARRAY_SIZE(omap3pandora_nand_partitions), +}; + +static struct gpio_led pandora_gpio_leds[] = { + { + .name = "pandora::sd1", + .default_trigger = "mmc0", + .gpio = 128, + }, { + .name = "pandora::sd2", + .default_trigger = "mmc1", + .gpio = 129, + }, { + .name = "pandora::bluetooth", + .gpio = 158, + }, { + .name = "pandora::wifi", + .gpio = 159, + }, +}; + +static struct gpio_led_platform_data pandora_gpio_led_data = { + .leds = pandora_gpio_leds, + .num_leds = ARRAY_SIZE(pandora_gpio_leds), +}; + +static struct platform_device pandora_leds_gpio = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &pandora_gpio_led_data, + }, +}; + +static struct platform_device pandora_backlight = { + .name = "pandora-backlight", + .id = -1, +}; + +#define GPIO_BUTTON(gpio_num, ev_type, ev_code, act_low, descr) \ +{ \ + .gpio = gpio_num, \ + .type = ev_type, \ + .code = ev_code, \ + .active_low = act_low, \ + .debounce_interval = 4, \ + .desc = "btn " descr, \ +} + +#define GPIO_BUTTON_LOW(gpio_num, event_code, description) \ + GPIO_BUTTON(gpio_num, EV_KEY, event_code, 1, description) + +static struct gpio_keys_button pandora_gpio_keys[] = { + GPIO_BUTTON_LOW(110, KEY_UP, "up"), + GPIO_BUTTON_LOW(103, KEY_DOWN, "down"), + GPIO_BUTTON_LOW(96, KEY_LEFT, "left"), + GPIO_BUTTON_LOW(98, KEY_RIGHT, "right"), + GPIO_BUTTON_LOW(109, KEY_PAGEUP, "game 1"), + GPIO_BUTTON_LOW(111, KEY_END, "game 2"), + GPIO_BUTTON_LOW(106, KEY_PAGEDOWN, "game 3"), + GPIO_BUTTON_LOW(101, KEY_HOME, "game 4"), + GPIO_BUTTON_LOW(102, KEY_RIGHTSHIFT, "l"), + GPIO_BUTTON_LOW(97, KEY_KPPLUS, "l2"), + GPIO_BUTTON_LOW(105, KEY_RIGHTCTRL, "r"), + GPIO_BUTTON_LOW(107, KEY_KPMINUS, "r2"), + GPIO_BUTTON_LOW(104, KEY_LEFTCTRL, "ctrl"), + GPIO_BUTTON_LOW(99, KEY_MENU, "menu"), + GPIO_BUTTON_LOW(176, KEY_COFFEE, "hold"), + GPIO_BUTTON(100, EV_KEY, KEY_LEFTALT, 0, "alt"), + GPIO_BUTTON(108, EV_SW, SW_LID, 1, "lid"), +}; + +static struct gpio_keys_platform_data pandora_gpio_key_info = { + .buttons = pandora_gpio_keys, + .nbuttons = ARRAY_SIZE(pandora_gpio_keys), +}; + +static struct platform_device pandora_keys_gpio = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &pandora_gpio_key_info, + }, +}; + +static const uint32_t board_keymap[] = { + /* row, col, code */ + KEY(0, 0, KEY_9), + KEY(0, 1, KEY_8), + KEY(0, 2, KEY_I), + KEY(0, 3, KEY_J), + KEY(0, 4, KEY_N), + KEY(0, 5, KEY_M), + KEY(1, 0, KEY_0), + KEY(1, 1, KEY_7), + KEY(1, 2, KEY_U), + KEY(1, 3, KEY_H), + KEY(1, 4, KEY_B), + KEY(1, 5, KEY_SPACE), + KEY(2, 0, KEY_BACKSPACE), + KEY(2, 1, KEY_6), + KEY(2, 2, KEY_Y), + KEY(2, 3, KEY_G), + KEY(2, 4, KEY_V), + KEY(2, 5, KEY_FN), + KEY(3, 0, KEY_O), + KEY(3, 1, KEY_5), + KEY(3, 2, KEY_T), + KEY(3, 3, KEY_F), + KEY(3, 4, KEY_C), + KEY(4, 0, KEY_P), + KEY(4, 1, KEY_4), + KEY(4, 2, KEY_R), + KEY(4, 3, KEY_D), + KEY(4, 4, KEY_X), + KEY(5, 0, KEY_K), + KEY(5, 1, KEY_3), + KEY(5, 2, KEY_E), + KEY(5, 3, KEY_S), + KEY(5, 4, KEY_Z), + KEY(6, 0, KEY_L), + KEY(6, 1, KEY_2), + KEY(6, 2, KEY_W), + KEY(6, 3, KEY_A), + KEY(6, 4, KEY_DOT), + KEY(7, 0, KEY_ENTER), + KEY(7, 1, KEY_1), + KEY(7, 2, KEY_Q), + KEY(7, 3, KEY_LEFTSHIFT), + KEY(7, 4, KEY_COMMA), +}; + +static struct matrix_keymap_data board_map_data = { + .keymap = board_keymap, + .keymap_size = ARRAY_SIZE(board_keymap), +}; + +static struct twl4030_keypad_data pandora_kp_data = { + .keymap_data = &board_map_data, + .rows = 8, + .cols = 6, + .rep = 1, +}; + +static struct connector_atv_platform_data pandora_tv_pdata = { + .name = "tv", + .source = "venc.0", + .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, + .invert_polarity = false, +}; + +static struct platform_device pandora_tv_connector_device = { + .name = "connector-analog-tv", + .id = 0, + .dev.platform_data = &pandora_tv_pdata, +}; + +static struct omap_dss_board_info pandora_dss_data = { + .default_display_name = "lcd", +}; + +static void pandora_wl1251_init_card(struct mmc_card *card) +{ + /* + * We have TI wl1251 attached to MMC3. Pass this information to + * SDIO core because it can't be probed by normal methods. + */ + card->quirks |= MMC_QUIRK_NONSTD_SDIO; + card->cccr.wide_bus = 1; + card->cis.vendor = 0x104c; + card->cis.device = 0x9066; + card->cis.blksize = 512; + card->cis.max_dtr = 20000000; +} + +static struct omap2_hsmmc_info omap3pandora_mmc[] = { { .mmc = 1, - .wires = 4, + .caps = MMC_CAP_4_BIT_DATA, .gpio_cd = -EINVAL, .gpio_wp = 126, .ext_clock = 0, + .deferred = true, }, { .mmc = 2, - .wires = 4, + .caps = MMC_CAP_4_BIT_DATA, .gpio_cd = -EINVAL, .gpio_wp = 127, .ext_clock = 1, + .transceiver = true, + .deferred = true, + }, + { + .mmc = 3, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + .init_card = pandora_wl1251_init_card, }, {} /* Terminator */ }; -static struct omap_uart_config omap3pandora_uart_config __initdata = { - .enabled_uarts = (1 << 2), /* UART3 */ -}; - static int omap3pandora_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio) { + int ret, gpio_32khz; + /* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */ omap3pandora_mmc[0].gpio_cd = gpio + 0; omap3pandora_mmc[1].gpio_cd = gpio + 1; - twl4030_mmc_init(omap3pandora_mmc); + omap_hsmmc_late_init(omap3pandora_mmc); + + /* gpio + 13 drives 32kHz buffer for wifi module */ + gpio_32khz = gpio + 13; + ret = gpio_request_one(gpio_32khz, GPIOF_OUT_INIT_HIGH, "wifi 32kHz"); + if (ret < 0) { + pr_err("Cannot get GPIO line %d, ret=%d\n", gpio_32khz, ret); + return -ENODEV; + } return 0; } static struct twl4030_gpio_platform_data omap3pandora_gpio_data = { - .gpio_base = OMAP_MAX_GPIO_LINES, - .irq_base = TWL4030_GPIO_IRQ_BASE, - .irq_end = TWL4030_GPIO_IRQ_END, .setup = omap3pandora_twl_gpio_setup, }; -static struct twl4030_usb_data omap3pandora_usb_data = { - .usb_mode = T2_USB_MODE_ULPI, +static struct regulator_consumer_supply pandora_vmmc1_supply[] = { + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), +}; + +static struct regulator_consumer_supply pandora_vmmc2_supply[] = { + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1") +}; + +static struct regulator_consumer_supply pandora_vmmc3_supply[] = { + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.2"), +}; + +static struct regulator_consumer_supply pandora_vdds_supplies[] = { + REGULATOR_SUPPLY("vdds_sdi", "omapdss"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dpi.0"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"), +}; + +static struct regulator_consumer_supply pandora_vcc_lcd_supply[] = { + REGULATOR_SUPPLY("vcc", "spi1.1"), +}; + +static struct regulator_consumer_supply pandora_usb_phy_supply[] = { + REGULATOR_SUPPLY("vcc", "usb_phy_gen_xceiv.2"), /* hsusb port 2 */ +}; + +/* ads7846 on SPI and 2 nub controllers on I2C */ +static struct regulator_consumer_supply pandora_vaux4_supplies[] = { + REGULATOR_SUPPLY("vcc", "spi1.0"), + REGULATOR_SUPPLY("vcc", "3-0066"), + REGULATOR_SUPPLY("vcc", "3-0067"), +}; + +static struct regulator_consumer_supply pandora_adac_supply[] = { + REGULATOR_SUPPLY("vcc", "soc-audio"), +}; + +/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ +static struct regulator_init_data pandora_vmmc1 = { + .constraints = { + .min_uV = 1850000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(pandora_vmmc1_supply), + .consumer_supplies = pandora_vmmc1_supply, +}; + +/* VMMC2 for MMC2 pins CMD, CLK, DAT0..DAT3 (max 100 mA) */ +static struct regulator_init_data pandora_vmmc2 = { + .constraints = { + .min_uV = 1850000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(pandora_vmmc2_supply), + .consumer_supplies = pandora_vmmc2_supply, +}; + +/* VAUX1 for LCD */ +static struct regulator_init_data pandora_vaux1 = { + .constraints = { + .min_uV = 3000000, + .max_uV = 3000000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(pandora_vcc_lcd_supply), + .consumer_supplies = pandora_vcc_lcd_supply, +}; + +/* VAUX2 for USB host PHY */ +static struct regulator_init_data pandora_vaux2 = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(pandora_usb_phy_supply), + .consumer_supplies = pandora_usb_phy_supply, +}; + +/* VAUX4 for ads7846 and nubs */ +static struct regulator_init_data pandora_vaux4 = { + .constraints = { + .min_uV = 2800000, + .max_uV = 2800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(pandora_vaux4_supplies), + .consumer_supplies = pandora_vaux4_supplies, +}; + +/* VSIM for audio DAC */ +static struct regulator_init_data pandora_vsim = { + .constraints = { + .min_uV = 2800000, + .max_uV = 2800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(pandora_adac_supply), + .consumer_supplies = pandora_adac_supply, +}; + +/* Fixed regulator internal to Wifi module */ +static struct regulator_init_data pandora_vmmc3 = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(pandora_vmmc3_supply), + .consumer_supplies = pandora_vmmc3_supply, +}; + +static struct fixed_voltage_config pandora_vwlan = { + .supply_name = "vwlan", + .microvolts = 1800000, /* 1.8V */ + .gpio = PANDORA_WIFI_NRESET_GPIO, + .startup_delay = 50000, /* 50ms */ + .enable_high = 1, + .enabled_at_boot = 0, + .init_data = &pandora_vmmc3, +}; + +static struct platform_device pandora_vwlan_device = { + .name = "reg-fixed-voltage", + .id = 1, + .dev = { + .platform_data = &pandora_vwlan, + }, +}; + +static struct twl4030_bci_platform_data pandora_bci_data; + +static struct twl4030_power_data pandora_power_data = { + .use_poweroff = true, }; static struct twl4030_platform_data omap3pandora_twldata = { - .irq_base = TWL4030_IRQ_BASE, - .irq_end = TWL4030_IRQ_END, .gpio = &omap3pandora_gpio_data, - .usb = &omap3pandora_usb_data, + .vmmc1 = &pandora_vmmc1, + .vmmc2 = &pandora_vmmc2, + .vaux1 = &pandora_vaux1, + .vaux2 = &pandora_vaux2, + .vaux4 = &pandora_vaux4, + .vsim = &pandora_vsim, + .keypad = &pandora_kp_data, + .bci = &pandora_bci_data, + .power = &pandora_power_data, }; -static struct i2c_board_info __initdata omap3pandora_i2c_boardinfo[] = { +static struct i2c_board_info __initdata omap3pandora_i2c3_boardinfo[] = { { - I2C_BOARD_INFO("tps65950", 0x48), + I2C_BOARD_INFO("bq27500", 0x55), .flags = I2C_CLIENT_WAKE, - .irq = INT_34XX_SYS_NIRQ, - .platform_data = &omap3pandora_twldata, }, }; static int __init omap3pandora_i2c_init(void) { - omap_register_i2c_bus(1, 2600, omap3pandora_i2c_boardinfo, - ARRAY_SIZE(omap3pandora_i2c_boardinfo)); - /* i2c2 pins are not connected */ - omap_register_i2c_bus(3, 400, NULL, 0); - return 0; -} - -static void __init omap3pandora_init_irq(void) -{ - omap2_init_common_hw(); - omap_init_irq(); - omap_gpio_init(); -} - -static void __init omap3pandora_ads7846_init(void) -{ - int gpio = OMAP3_PANDORA_TS_GPIO; - int ret; + omap3_pmic_get_config(&omap3pandora_twldata, + TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_AUDIO, + TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2); - ret = gpio_request(gpio, "ads7846_pen_down"); - if (ret < 0) { - printk(KERN_ERR "Failed to request GPIO %d for " - "ads7846 pen down IRQ\n", gpio); - return; - } + omap3pandora_twldata.vdac->constraints.apply_uV = true; - gpio_direction_input(gpio); -} + omap3pandora_twldata.vpll2->constraints.apply_uV = true; + omap3pandora_twldata.vpll2->num_consumer_supplies = + ARRAY_SIZE(pandora_vdds_supplies); + omap3pandora_twldata.vpll2->consumer_supplies = pandora_vdds_supplies; -static int ads7846_get_pendown_state(void) -{ - return !gpio_get_value(OMAP3_PANDORA_TS_GPIO); + omap3_pmic_init("tps65950", &omap3pandora_twldata); + /* i2c2 pins are not connected */ + omap_register_i2c_bus(3, 100, omap3pandora_i2c3_boardinfo, + ARRAY_SIZE(omap3pandora_i2c3_boardinfo)); + return 0; } -static struct ads7846_platform_data ads7846_config = { - .x_max = 0x0fff, - .y_max = 0x0fff, - .x_plate_ohms = 180, - .pressure_max = 255, - .debounce_max = 10, - .debounce_tol = 3, - .debounce_rep = 1, - .get_pendown_state = ads7846_get_pendown_state, - .keep_vref_on = 1, -}; +static struct panel_tpo_td043mtea1_platform_data pandora_lcd_pdata = { + .name = "lcd", + .source = "dpi.0", -static struct omap2_mcspi_device_config ads7846_mcspi_config = { - .turbo_mode = 0, - .single_channel = 1, /* 0: slave, 1: master */ + .data_lines = 24, + .nreset_gpio = 157, }; static struct spi_board_info omap3pandora_spi_board_info[] __initdata = { { - .modalias = "ads7846", + .modalias = "panel-tpo-td043mtea1", .bus_num = 1, - .chip_select = 0, - .max_speed_hz = 1500000, - .controller_data = &ads7846_mcspi_config, - .irq = OMAP_GPIO_IRQ(OMAP3_PANDORA_TS_GPIO), - .platform_data = &ads7846_config, + .chip_select = 1, + .max_speed_hz = 375000, + .platform_data = &pandora_lcd_pdata, } }; -static struct platform_device omap3pandora_lcd_device = { - .name = "pandora_lcd", - .id = -1, +static void __init pandora_wl1251_init(void) +{ + struct wl1251_platform_data pandora_wl1251_pdata; + int ret; + + memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata)); + + pandora_wl1251_pdata.power_gpio = -1; + + ret = gpio_request_one(PANDORA_WIFI_IRQ_GPIO, GPIOF_IN, "wl1251 irq"); + if (ret < 0) + goto fail; + + pandora_wl1251_pdata.irq = gpio_to_irq(PANDORA_WIFI_IRQ_GPIO); + if (pandora_wl1251_pdata.irq < 0) + goto fail_irq; + + pandora_wl1251_pdata.use_eeprom = true; + ret = wl1251_set_platform_data(&pandora_wl1251_pdata); + if (ret < 0) + goto fail_irq; + + return; + +fail_irq: + gpio_free(PANDORA_WIFI_IRQ_GPIO); +fail: + printk(KERN_ERR "wl1251 board initialisation failed\n"); +} + +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 2, + .reset_gpio = 16, + .vcc_gpio = -EINVAL, + }, }; -static struct omap_lcd_config omap3pandora_lcd_config __initdata = { - .ctrl_name = "internal", +static struct platform_device *omap3pandora_devices[] __initdata = { + &pandora_leds_gpio, + &pandora_keys_gpio, + &pandora_vwlan_device, + &pandora_backlight, + &pandora_tv_connector_device, }; -static struct omap_board_config_kernel omap3pandora_config[] __initdata = { - { OMAP_TAG_UART, &omap3pandora_uart_config }, - { OMAP_TAG_LCD, &omap3pandora_lcd_config }, +static struct usbhs_omap_platform_data usbhs_bdata __initdata = { + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, }; -static struct platform_device *omap3pandora_devices[] __initdata = { - &omap3pandora_lcd_device, +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + { .reg_offset = OMAP_MUX_TERMINATOR }, }; +#endif static void __init omap3pandora_init(void) { + omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); + omap_hsmmc_init(omap3pandora_mmc); omap3pandora_i2c_init(); + pandora_wl1251_init(); platform_add_devices(omap3pandora_devices, ARRAY_SIZE(omap3pandora_devices)); - omap_board_config = omap3pandora_config; - omap_board_config_size = ARRAY_SIZE(omap3pandora_config); + omap_display_init(&pandora_dss_data); omap_serial_init(); + omap_sdrc_init(mt46h32m32lf6_sdrc_params, + mt46h32m32lf6_sdrc_params); spi_register_board_info(omap3pandora_spi_board_info, ARRAY_SIZE(omap3pandora_spi_board_info)); - omap3pandora_ads7846_init(); -} + omap_ads7846_init(1, OMAP3_PANDORA_TS_GPIO, 0, NULL); -static void __init omap3pandora_map_io(void) -{ - omap2_set_globals_343x(); - omap2_map_common_io(); + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); + usbhs_init(&usbhs_bdata); + + usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); + usb_musb_init(NULL); + gpmc_nand_init(&pandora_nand_data, NULL); + + /* Ensure SDRC pins are mux'd for self-refresh */ + omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); + omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); } MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console") - .phys_io = 0x48000000, - .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, - .boot_params = 0x80000100, - .map_io = omap3pandora_map_io, - .init_irq = omap3pandora_init_irq, + .atag_offset = 0x100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap35xx_init_early, + .init_irq = omap3_init_irq, + .handle_irq = omap3_intc_handle_irq, .init_machine = omap3pandora_init, - .timer = &omap_timer, + .init_late = omap35xx_init_late, + .init_time = omap3_sync32k_timer_init, + .restart = omap3xxx_restart, MACHINE_END diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c new file mode 100644 index 00000000000..a2e035e0792 --- /dev/null +++ b/arch/arm/mach-omap2/board-omap3stalker.c @@ -0,0 +1,434 @@ +/* + * linux/arch/arm/mach-omap2/board-omap3evm.c + * + * Copyright (C) 2008 Guangzhou EMA-Tech + * + * Modified from mach-omap2/board-omap3evm.c + * + * Initial code: Syed Mohammed Khasim + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/leds.h> +#include <linux/gpio.h> +#include <linux/input.h> +#include <linux/gpio_keys.h> + +#include <linux/regulator/fixed.h> +#include <linux/regulator/machine.h> +#include <linux/i2c/twl.h> +#include <linux/mmc/host.h> +#include <linux/input/matrix_keypad.h> +#include <linux/spi/spi.h> +#include <linux/interrupt.h> +#include <linux/smsc911x.h> +#include <linux/platform_data/at24.h> +#include <linux/usb/phy.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/flash.h> + +#include "common.h" +#include "gpmc.h" +#include <linux/platform_data/mtd-nand-omap2.h> +#include <video/omapdss.h> +#include <video/omap-panel-data.h> + +#include <linux/platform_data/spi-omap2-mcspi.h> + +#include "sdram-micron-mt46h32m32lf-6.h" +#include "mux.h" +#include "hsmmc.h" +#include "common-board-devices.h" + +#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) +#include "gpmc-smsc911x.h" + +#define OMAP3STALKER_ETHR_START 0x2c000000 +#define OMAP3STALKER_ETHR_SIZE 1024 +#define OMAP3STALKER_ETHR_GPIO_IRQ 19 +#define OMAP3STALKER_SMC911X_CS 5 + +static struct omap_smsc911x_platform_data smsc911x_cfg = { + .cs = OMAP3STALKER_SMC911X_CS, + .gpio_irq = OMAP3STALKER_ETHR_GPIO_IRQ, + .gpio_reset = -EINVAL, + .flags = (SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS), +}; + +static inline void __init omap3stalker_init_eth(void) +{ + omap_mux_init_gpio(19, OMAP_PIN_INPUT_PULLUP); + gpmc_smsc911x_init(&smsc911x_cfg); +} + +#else +static inline void __init omap3stalker_init_eth(void) +{ + return; +} +#endif + +/* + * OMAP3 DSS control signals + */ + +#define DSS_ENABLE_GPIO 199 +#define LCD_PANEL_BKLIGHT_GPIO 210 +#define ENABLE_VPLL2_DEV_GRP 0xE0 + +static void __init omap3_stalker_display_init(void) +{ + return; +} +static struct connector_dvi_platform_data omap3stalker_dvi_connector_pdata = { + .name = "dvi", + .source = "tfp410.0", + .i2c_bus_num = -1, +}; + +static struct platform_device omap3stalker_dvi_connector_device = { + .name = "connector-dvi", + .id = 0, + .dev.platform_data = &omap3stalker_dvi_connector_pdata, +}; + +static struct encoder_tfp410_platform_data omap3stalker_tfp410_pdata = { + .name = "tfp410.0", + .source = "dpi.0", + .data_lines = 24, + .power_down_gpio = DSS_ENABLE_GPIO, +}; + +static struct platform_device omap3stalker_tfp410_device = { + .name = "tfp410", + .id = 0, + .dev.platform_data = &omap3stalker_tfp410_pdata, +}; + +static struct connector_atv_platform_data omap3stalker_tv_pdata = { + .name = "tv", + .source = "venc.0", + .connector_type = OMAP_DSS_VENC_TYPE_COMPOSITE, + .invert_polarity = false, +}; + +static struct platform_device omap3stalker_tv_connector_device = { + .name = "connector-analog-tv", + .id = 0, + .dev.platform_data = &omap3stalker_tv_pdata, +}; + +static struct omap_dss_board_info omap3_stalker_dss_data = { + .default_display_name = "dvi", +}; + +static struct regulator_consumer_supply omap3stalker_vmmc1_supply[] = { + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), +}; + +static struct regulator_consumer_supply omap3stalker_vsim_supply[] = { + REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"), +}; + +/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ +static struct regulator_init_data omap3stalker_vmmc1 = { + .constraints = { + .min_uV = 1850000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(omap3stalker_vmmc1_supply), + .consumer_supplies = omap3stalker_vmmc1_supply, +}; + +/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */ +static struct regulator_init_data omap3stalker_vsim = { + .constraints = { + .min_uV = 1800000, + .max_uV = 3000000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(omap3stalker_vsim_supply), + .consumer_supplies = omap3stalker_vsim_supply, +}; + +static struct omap2_hsmmc_info mmc[] = { + { + .mmc = 1, + .caps = MMC_CAP_4_BIT_DATA, + .gpio_cd = -EINVAL, + .gpio_wp = 23, + .deferred = true, + }, + {} /* Terminator */ +}; + +static struct gpio_keys_button gpio_buttons[] = { + { + .code = BTN_EXTRA, + .gpio = 18, + .desc = "user", + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data gpio_key_info = { + .buttons = gpio_buttons, + .nbuttons = ARRAY_SIZE(gpio_buttons), +}; + +static struct platform_device keys_gpio = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &gpio_key_info, + }, +}; + +static struct gpio_led gpio_leds[] = { + { + .name = "stalker:D8:usr0", + .default_trigger = "default-on", + .gpio = 126, + }, + { + .name = "stalker:D9:usr1", + .default_trigger = "default-on", + .gpio = 127, + }, + { + .name = "stalker:D3:mmc0", + .gpio = -EINVAL, /* gets replaced */ + .active_low = true, + .default_trigger = "mmc0", + }, + { + .name = "stalker:D4:heartbeat", + .gpio = -EINVAL, /* gets replaced */ + .active_low = true, + .default_trigger = "heartbeat", + }, +}; + +static struct gpio_led_platform_data gpio_led_info = { + .leds = gpio_leds, + .num_leds = ARRAY_SIZE(gpio_leds), +}; + +static struct platform_device leds_gpio = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &gpio_led_info, + }, +}; + +static int +omap3stalker_twl_gpio_setup(struct device *dev, + unsigned gpio, unsigned ngpio) +{ + /* gpio + 0 is "mmc0_cd" (input/IRQ) */ + mmc[0].gpio_cd = gpio + 0; + omap_hsmmc_late_init(mmc); + + /* + * Most GPIOs are for USB OTG. Some are mostly sent to + * the P2 connector; notably LEDA for the LCD backlight. + */ + + /* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */ + gpio_request_one(gpio + TWL4030_GPIO_MAX, GPIOF_OUT_INIT_LOW, + "EN_LCD_BKL"); + + /* gpio + 7 == DVI Enable */ + gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "EN_DVI"); + + /* TWL4030_GPIO_MAX + 1 == ledB (out, mmc0) */ + gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; + /* GPIO + 13 == ledsync (out, heartbeat) */ + gpio_leds[3].gpio = gpio + 13; + + platform_device_register(&leds_gpio); + return 0; +} + +static struct twl4030_gpio_platform_data omap3stalker_gpio_data = { + .use_leds = true, + .setup = omap3stalker_twl_gpio_setup, +}; + +static uint32_t board_keymap[] = { + KEY(0, 0, KEY_LEFT), + KEY(0, 1, KEY_DOWN), + KEY(0, 2, KEY_ENTER), + KEY(0, 3, KEY_M), + + KEY(1, 0, KEY_RIGHT), + KEY(1, 1, KEY_UP), + KEY(1, 2, KEY_I), + KEY(1, 3, KEY_N), + + KEY(2, 0, KEY_A), + KEY(2, 1, KEY_E), + KEY(2, 2, KEY_J), + KEY(2, 3, KEY_O), + + KEY(3, 0, KEY_B), + KEY(3, 1, KEY_F), + KEY(3, 2, KEY_K), + KEY(3, 3, KEY_P) +}; + +static struct matrix_keymap_data board_map_data = { + .keymap = board_keymap, + .keymap_size = ARRAY_SIZE(board_keymap), +}; + +static struct twl4030_keypad_data omap3stalker_kp_data = { + .keymap_data = &board_map_data, + .rows = 4, + .cols = 4, + .rep = 1, +}; + +static struct twl4030_platform_data omap3stalker_twldata = { + /* platform_data for children goes here */ + .keypad = &omap3stalker_kp_data, + .gpio = &omap3stalker_gpio_data, + .vmmc1 = &omap3stalker_vmmc1, + .vsim = &omap3stalker_vsim, +}; + +static struct at24_platform_data fram_info = { + .byte_len = (64 * 1024) / 8, + .page_size = 8192, + .flags = AT24_FLAG_ADDR16 | AT24_FLAG_IRUGO, +}; + +static struct i2c_board_info __initdata omap3stalker_i2c_boardinfo3[] = { + { + I2C_BOARD_INFO("24c64", 0x50), + .flags = I2C_CLIENT_WAKE, + .platform_data = &fram_info, + }, +}; + +static int __init omap3_stalker_i2c_init(void) +{ + omap3_pmic_get_config(&omap3stalker_twldata, + TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC | + TWL_COMMON_PDATA_AUDIO, + TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2); + + omap3stalker_twldata.vdac->constraints.apply_uV = true; + omap3stalker_twldata.vpll2->constraints.apply_uV = true; + omap3stalker_twldata.vpll2->constraints.name = "VDVI"; + + omap3_pmic_init("twl4030", &omap3stalker_twldata); + omap_register_i2c_bus(2, 400, NULL, 0); + omap_register_i2c_bus(3, 400, omap3stalker_i2c_boardinfo3, + ARRAY_SIZE(omap3stalker_i2c_boardinfo3)); + return 0; +} + +#define OMAP3_STALKER_TS_GPIO 175 + +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 2, + .reset_gpio = 21, + .vcc_gpio = -EINVAL, + }, +}; + +static struct platform_device *omap3_stalker_devices[] __initdata = { + &keys_gpio, + &omap3stalker_tfp410_device, + &omap3stalker_dvi_connector_device, + &omap3stalker_tv_connector_device, +}; + +static struct usbhs_omap_platform_data usbhs_bdata __initdata = { + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, +}; + +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP | + OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE), + OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | + OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE), + {.reg_offset = OMAP_MUX_TERMINATOR}, +}; +#endif + +static struct regulator_consumer_supply dummy_supplies[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x.0"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), +}; + +static void __init omap3_stalker_init(void) +{ + regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); + omap3_mux_init(board_mux, OMAP_PACKAGE_CUS); + + omap_mux_init_gpio(23, OMAP_PIN_INPUT); + omap_hsmmc_init(mmc); + + omap3_stalker_i2c_init(); + + platform_add_devices(omap3_stalker_devices, + ARRAY_SIZE(omap3_stalker_devices)); + + omap_display_init(&omap3_stalker_dss_data); + + omap_serial_init(); + omap_sdrc_init(mt46h32m32lf6_sdrc_params, NULL); + usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); + usb_musb_init(NULL); + + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); + usbhs_init(&usbhs_bdata); + omap_ads7846_init(1, OMAP3_STALKER_TS_GPIO, 310, NULL); + + omap_mux_init_gpio(21, OMAP_PIN_OUTPUT); + omap_mux_init_gpio(18, OMAP_PIN_INPUT_PULLUP); + + omap3stalker_init_eth(); + omap3_stalker_display_init(); +/* Ensure SDRC pins are mux'd for self-refresh */ + omap_mux_init_signal("sdr_cke0", OMAP_PIN_OUTPUT); + omap_mux_init_signal("sdr_cke1", OMAP_PIN_OUTPUT); +} + +MACHINE_START(SBC3530, "OMAP3 STALKER") + /* Maintainer: Jason Lam -lzg@ema-tech.com */ + .atag_offset = 0x100, + .map_io = omap3_map_io, + .init_early = omap35xx_init_early, + .init_irq = omap3_init_irq, + .handle_irq = omap3_intc_handle_irq, + .init_machine = omap3_stalker_init, + .init_late = omap35xx_init_late, + .init_time = omap3_secure_sync32k_timer_init, + .restart = omap3xxx_restart, +MACHINE_END diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c new file mode 100644 index 00000000000..7da48bc42bb --- /dev/null +++ b/arch/arm/mach-omap2/board-omap3touchbook.c @@ -0,0 +1,396 @@ +/* + * linux/arch/arm/mach-omap2/board-omap3touchbook.c + * + * Copyright (C) 2009 Always Innovating + * + * Modified from mach-omap2/board-omap3beagleboard.c + * + * Initial code: Grégoire Gentil, Tim Yamin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/leds.h> +#include <linux/gpio.h> +#include <linux/input.h> +#include <linux/gpio_keys.h> + +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/nand.h> +#include <linux/mmc/host.h> +#include <linux/usb/phy.h> + +#include <linux/platform_data/spi-omap2-mcspi.h> +#include <linux/spi/spi.h> + +#include <linux/spi/ads7846.h> + +#include <linux/regulator/machine.h> +#include <linux/i2c/twl.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/flash.h> +#include <asm/system_info.h> + +#include "common.h" +#include "gpmc.h" +#include <linux/platform_data/mtd-nand-omap2.h> + +#include "mux.h" +#include "hsmmc.h" +#include "board-flash.h" +#include "common-board-devices.h" + +#include <asm/setup.h> + +#define OMAP3_AC_GPIO 136 +#define OMAP3_TS_GPIO 162 +#define TB_BL_PWM_TIMER 9 +#define TB_KILL_POWER_GPIO 168 + +#define NAND_CS 0 + +static unsigned long touchbook_revision; + +static struct mtd_partition omap3touchbook_nand_partitions[] = { + /* All the partition sizes are listed in terms of NAND block size */ + { + .name = "X-Loader", + .offset = 0, + .size = 4 * NAND_BLOCK_SIZE, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "U-Boot", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */ + .size = 15 * NAND_BLOCK_SIZE, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "U-Boot Env", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */ + .size = 1 * NAND_BLOCK_SIZE, + }, + { + .name = "Kernel", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */ + .size = 32 * NAND_BLOCK_SIZE, + }, + { + .name = "File System", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */ + .size = MTDPART_SIZ_FULL, + }, +}; + +#include "sdram-micron-mt46h32m32lf-6.h" + +static struct omap2_hsmmc_info mmc[] = { + { + .mmc = 1, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, + .gpio_wp = 29, + .deferred = true, + }, + {} /* Terminator */ +}; + +static struct regulator_consumer_supply touchbook_vmmc1_supply[] = { + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), +}; + +static struct regulator_consumer_supply touchbook_vsim_supply[] = { + REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"), +}; + +static struct gpio_led gpio_leds[]; + +static int touchbook_twl_gpio_setup(struct device *dev, + unsigned gpio, unsigned ngpio) +{ + /* gpio + 0 is "mmc0_cd" (input/IRQ) */ + mmc[0].gpio_cd = gpio + 0; + omap_hsmmc_late_init(mmc); + + /* REVISIT: need ehci-omap hooks for external VBUS + * power switch and overcurrent detect + */ + gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC"); + + /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */ + gpio_request_one(gpio + TWL4030_GPIO_MAX, GPIOF_OUT_INIT_LOW, + "nEN_USB_PWR"); + + /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ + gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; + + return 0; +} + +static struct twl4030_gpio_platform_data touchbook_gpio_data = { + .use_leds = true, + .pullups = BIT(1), + .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13) + | BIT(15) | BIT(16) | BIT(17), + .setup = touchbook_twl_gpio_setup, +}; + +static struct regulator_consumer_supply touchbook_vdac_supply[] = { +{ + .supply = "vdac", +}, +}; + +static struct regulator_consumer_supply touchbook_vdvi_supply[] = { +{ + .supply = "vdvi", +}, +}; + +/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ +static struct regulator_init_data touchbook_vmmc1 = { + .constraints = { + .min_uV = 1850000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(touchbook_vmmc1_supply), + .consumer_supplies = touchbook_vmmc1_supply, +}; + +/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */ +static struct regulator_init_data touchbook_vsim = { + .constraints = { + .min_uV = 1800000, + .max_uV = 3000000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(touchbook_vsim_supply), + .consumer_supplies = touchbook_vsim_supply, +}; + +static struct twl4030_platform_data touchbook_twldata = { + /* platform_data for children goes here */ + .gpio = &touchbook_gpio_data, + .vmmc1 = &touchbook_vmmc1, + .vsim = &touchbook_vsim, +}; + +static struct i2c_board_info __initdata touchBook_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("bq27200", 0x55), + }, +}; + +static int __init omap3_touchbook_i2c_init(void) +{ + /* Standard TouchBook bus */ + omap3_pmic_get_config(&touchbook_twldata, + TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_AUDIO, + TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2); + + touchbook_twldata.vdac->num_consumer_supplies = + ARRAY_SIZE(touchbook_vdac_supply); + touchbook_twldata.vdac->consumer_supplies = touchbook_vdac_supply; + + touchbook_twldata.vpll2->constraints.name = "VDVI"; + touchbook_twldata.vpll2->num_consumer_supplies = + ARRAY_SIZE(touchbook_vdvi_supply); + touchbook_twldata.vpll2->consumer_supplies = touchbook_vdvi_supply; + + omap3_pmic_init("twl4030", &touchbook_twldata); + /* Additional TouchBook bus */ + omap_register_i2c_bus(3, 100, touchBook_i2c_boardinfo, + ARRAY_SIZE(touchBook_i2c_boardinfo)); + + return 0; +} + +static struct ads7846_platform_data ads7846_pdata = { + .x_min = 100, + .y_min = 265, + .x_max = 3950, + .y_max = 3750, + .x_plate_ohms = 40, + .pressure_max = 255, + .debounce_max = 10, + .debounce_tol = 5, + .debounce_rep = 1, + .gpio_pendown = OMAP3_TS_GPIO, + .keep_vref_on = 1, +}; + +static struct gpio_led gpio_leds[] = { + { + .name = "touchbook::usr0", + .default_trigger = "heartbeat", + .gpio = 150, + }, + { + .name = "touchbook::usr1", + .default_trigger = "mmc0", + .gpio = 149, + }, + { + .name = "touchbook::pmu_stat", + .gpio = -EINVAL, /* gets replaced */ + .active_low = true, + }, +}; + +static struct gpio_led_platform_data gpio_led_info = { + .leds = gpio_leds, + .num_leds = ARRAY_SIZE(gpio_leds), +}; + +static struct platform_device leds_gpio = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &gpio_led_info, + }, +}; + +static struct gpio_keys_button gpio_buttons[] = { + { + .code = BTN_EXTRA, + .gpio = 7, + .desc = "user", + .wakeup = 1, + }, + { + .code = KEY_POWER, + .gpio = 183, + .desc = "power", + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data gpio_key_info = { + .buttons = gpio_buttons, + .nbuttons = ARRAY_SIZE(gpio_buttons), +}; + +static struct platform_device keys_gpio = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &gpio_key_info, + }, +}; + +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#endif + +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 2, + .reset_gpio = 147, + .vcc_gpio = -EINVAL, + }, +}; + +static struct platform_device *omap3_touchbook_devices[] __initdata = { + &leds_gpio, + &keys_gpio, +}; + +static struct usbhs_omap_platform_data usbhs_bdata __initdata = { + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, +}; + +static void omap3_touchbook_poweroff(void) +{ + int pwr_off = TB_KILL_POWER_GPIO; + + if (gpio_request_one(pwr_off, GPIOF_OUT_INIT_LOW, "DVI reset") < 0) + printk(KERN_ERR "Unable to get kill power GPIO\n"); +} + +static int __init early_touchbook_revision(char *p) +{ + if (!p) + return 0; + + return strict_strtoul(p, 10, &touchbook_revision); +} +early_param("tbr", early_touchbook_revision); + +static void __init omap3_touchbook_init(void) +{ + omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); + + pm_power_off = omap3_touchbook_poweroff; + + if (system_rev >= 0x20 && system_rev <= 0x34301000) { + omap_mux_init_gpio(23, OMAP_PIN_INPUT); + mmc[0].gpio_wp = 23; + } else { + omap_mux_init_gpio(29, OMAP_PIN_INPUT); + } + omap_hsmmc_init(mmc); + + omap3_touchbook_i2c_init(); + platform_add_devices(omap3_touchbook_devices, + ARRAY_SIZE(omap3_touchbook_devices)); + omap_serial_init(); + omap_sdrc_init(mt46h32m32lf6_sdrc_params, + mt46h32m32lf6_sdrc_params); + + omap_mux_init_gpio(170, OMAP_PIN_INPUT); + /* REVISIT leave DVI powered down until it's needed ... */ + gpio_request_one(176, GPIOF_OUT_INIT_HIGH, "DVI_nPD"); + + /* Touchscreen and accelerometer */ + omap_ads7846_init(4, OMAP3_TS_GPIO, 310, &ads7846_pdata); + usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); + usb_musb_init(NULL); + + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); + usbhs_init(&usbhs_bdata); + board_nand_init(omap3touchbook_nand_partitions, + ARRAY_SIZE(omap3touchbook_nand_partitions), NAND_CS, + NAND_BUSWIDTH_16, NULL); + + /* Ensure SDRC pins are mux'd for self-refresh */ + omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); + omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); +} + +MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board") + /* Maintainer: Gregoire Gentil - http://www.alwaysinnovating.com */ + .atag_offset = 0x100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap3430_init_early, + .init_irq = omap3_init_irq, + .handle_irq = omap3_intc_handle_irq, + .init_machine = omap3_touchbook_init, + .init_late = omap3430_init_late, + .init_time = omap3_secure_sync32k_timer_init, + .restart = omap3xxx_restart, +MACHINE_END diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index 82b3dc557c9..f6d38411191 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c @@ -24,32 +24,221 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/gpio.h> #include <linux/kernel.h> #include <linux/platform_device.h> -#include <linux/i2c/twl4030.h> +#include <linux/i2c/twl.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/fixed.h> +#include <linux/spi/spi.h> #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> #include <linux/mtd/partitions.h> +#include <linux/mmc/host.h> +#include <linux/usb/phy.h> + +#include <linux/platform_data/mtd-nand-omap2.h> +#include <linux/platform_data/spi-omap2-mcspi.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/flash.h> #include <asm/mach/map.h> -#include <mach/board-overo.h> -#include <mach/board.h> -#include <mach/common.h> -#include <mach/gpio.h> -#include <mach/gpmc.h> -#include <mach/hardware.h> -#include <mach/nand.h> +#include <video/omapdss.h> +#include <video/omap-panel-data.h> + +#include "common.h" +#include "mux.h" +#include "sdram-micron-mt46h32m32lf-6.h" +#include "gpmc.h" +#include "hsmmc.h" +#include "board-flash.h" +#include "common-board-devices.h" + +#define NAND_CS 0 + +#define OVERO_GPIO_BT_XGATE 15 +#define OVERO_GPIO_W2W_NRESET 16 +#define OVERO_GPIO_PENDOWN 114 +#define OVERO_GPIO_BT_NRESET 164 +#define OVERO_GPIO_USBH_CPEN 168 +#define OVERO_GPIO_USBH_NRESET 183 + +#define OVERO_SMSC911X_CS 5 +#define OVERO_SMSC911X_GPIO 176 +#define OVERO_SMSC911X_NRESET 64 +#define OVERO_SMSC911X2_CS 4 +#define OVERO_SMSC911X2_GPIO 65 + +/* whether to register LCD35 instead of LCD43 */ +static bool overo_use_lcd35; + +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ + defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + +/* fixed regulator for ads7846 */ +static struct regulator_consumer_supply ads7846_supply[] = { + REGULATOR_SUPPLY("vcc", "spi1.0"), +}; + +static struct regulator_init_data vads7846_regulator = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(ads7846_supply), + .consumer_supplies = ads7846_supply, +}; + +static struct fixed_voltage_config vads7846 = { + .supply_name = "vads7846", + .microvolts = 3300000, /* 3.3V */ + .gpio = -EINVAL, + .startup_delay = 0, + .init_data = &vads7846_regulator, +}; + +static struct platform_device vads7846_device = { + .name = "reg-fixed-voltage", + .id = 1, + .dev = { + .platform_data = &vads7846, + }, +}; + +static void __init overo_ads7846_init(void) +{ + omap_ads7846_init(1, OVERO_GPIO_PENDOWN, 0, NULL); + platform_device_register(&vads7846_device); +} + +#else +static inline void __init overo_ads7846_init(void) { return; } +#endif + +#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) + +#include <linux/smsc911x.h> +#include "gpmc-smsc911x.h" + +static struct omap_smsc911x_platform_data smsc911x_cfg = { + .id = 0, + .cs = OVERO_SMSC911X_CS, + .gpio_irq = OVERO_SMSC911X_GPIO, + .gpio_reset = OVERO_SMSC911X_NRESET, + .flags = SMSC911X_USE_32BIT, +}; + +static struct omap_smsc911x_platform_data smsc911x2_cfg = { + .id = 1, + .cs = OVERO_SMSC911X2_CS, + .gpio_irq = OVERO_SMSC911X2_GPIO, + .gpio_reset = -EINVAL, + .flags = SMSC911X_USE_32BIT, +}; + +static void __init overo_init_smsc911x(void) +{ + gpmc_smsc911x_init(&smsc911x_cfg); + gpmc_smsc911x_init(&smsc911x2_cfg); +} + +#else +static inline void __init overo_init_smsc911x(void) { return; } +#endif + +/* DSS */ +#define OVERO_GPIO_LCD_EN 144 +#define OVERO_GPIO_LCD_BL 145 + +static struct connector_atv_platform_data overo_tv_pdata = { + .name = "tv", + .source = "venc.0", + .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, + .invert_polarity = false, +}; + +static struct platform_device overo_tv_connector_device = { + .name = "connector-analog-tv", + .id = 0, + .dev.platform_data = &overo_tv_pdata, +}; + +static const struct display_timing overo_lcd43_videomode = { + .pixelclock = { 0, 9200000, 0 }, + + .hactive = { 0, 480, 0 }, + .hfront_porch = { 0, 8, 0 }, + .hback_porch = { 0, 4, 0 }, + .hsync_len = { 0, 41, 0 }, + + .vactive = { 0, 272, 0 }, + .vfront_porch = { 0, 4, 0 }, + .vback_porch = { 0, 2, 0 }, + .vsync_len = { 0, 10, 0 }, + + .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | + DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE, +}; + +static struct panel_dpi_platform_data overo_lcd43_pdata = { + .name = "lcd43", + .source = "dpi.0", + + .data_lines = 24, -#include "mmc-twl4030.h" + .display_timing = &overo_lcd43_videomode, -#define NAND_BLOCK_SIZE SZ_128K -#define GPMC_CS0_BASE 0x60 -#define GPMC_CS_SIZE 0x30 + .enable_gpio = OVERO_GPIO_LCD_EN, + .backlight_gpio = OVERO_GPIO_LCD_BL, +}; + +static struct platform_device overo_lcd43_device = { + .name = "panel-dpi", + .id = 0, + .dev.platform_data = &overo_lcd43_pdata, +}; + +static struct connector_dvi_platform_data overo_dvi_connector_pdata = { + .name = "dvi", + .source = "tfp410.0", + .i2c_bus_num = 3, +}; + +static struct platform_device overo_dvi_connector_device = { + .name = "connector-dvi", + .id = 0, + .dev.platform_data = &overo_dvi_connector_pdata, +}; + +static struct encoder_tfp410_platform_data overo_tfp410_pdata = { + .name = "tfp410.0", + .source = "dpi.0", + .data_lines = 24, + .power_down_gpio = -1, +}; + +static struct platform_device overo_tfp410_device = { + .name = "tfp410", + .id = 0, + .dev.platform_data = &overo_tfp410_pdata, +}; + +static struct omap_dss_board_info overo_dss_data = { + .default_display_name = "lcd43", +}; + +static void __init overo_display_init(void) +{ + omap_display_init(&overo_dss_data); + + if (!overo_use_lcd35) + platform_device_register(&overo_lcd43_device); + platform_device_register(&overo_tfp410_device); + platform_device_register(&overo_dvi_connector_device); + platform_device_register(&overo_tv_connector_device); +} static struct mtd_partition overo_nand_partitions[] = { { @@ -80,206 +269,304 @@ static struct mtd_partition overo_nand_partitions[] = { }, }; -static struct omap_nand_platform_data overo_nand_data = { - .parts = overo_nand_partitions, - .nr_parts = ARRAY_SIZE(overo_nand_partitions), - .dma_channel = -1, /* disable DMA in OMAP NAND driver */ +static struct omap2_hsmmc_info mmc[] = { + { + .mmc = 1, + .caps = MMC_CAP_4_BIT_DATA, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + }, + { + .mmc = 2, + .caps = MMC_CAP_4_BIT_DATA, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + .transceiver = true, + .ocr_mask = 0x00100000, /* 3.3V */ + }, + {} /* Terminator */ +}; + +static struct regulator_consumer_supply overo_vmmc1_supply[] = { + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), +}; + +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +#include <linux/leds.h> + +static struct gpio_led gpio_leds[] = { + { + .name = "overo:red:gpio21", + .default_trigger = "heartbeat", + .gpio = 21, + .active_low = true, + }, + { + .name = "overo:blue:gpio22", + .default_trigger = "none", + .gpio = 22, + .active_low = true, + }, + { + .name = "overo:blue:COM", + .default_trigger = "mmc0", + .gpio = -EINVAL, /* gets replaced */ + .active_low = true, + }, +}; + +static struct gpio_led_platform_data gpio_leds_pdata = { + .leds = gpio_leds, + .num_leds = ARRAY_SIZE(gpio_leds), }; -static struct resource overo_nand_resource = { - .flags = IORESOURCE_MEM, +static struct platform_device gpio_leds_device = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &gpio_leds_pdata, + }, }; -static struct platform_device overo_nand_device = { - .name = "omap2-nand", - .id = -1, - .dev = { - .platform_data = &overo_nand_data, +static void __init overo_init_led(void) +{ + platform_device_register(&gpio_leds_device); +} + +#else +static inline void __init overo_init_led(void) { return; } +#endif + +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +#include <linux/input.h> +#include <linux/gpio_keys.h> + +static struct gpio_keys_button gpio_buttons[] = { + { + .code = BTN_0, + .gpio = 23, + .desc = "button0", + .wakeup = 1, + }, + { + .code = BTN_1, + .gpio = 14, + .desc = "button1", + .wakeup = 1, }, - .num_resources = 1, - .resource = &overo_nand_resource, }; +static struct gpio_keys_platform_data gpio_keys_pdata = { + .buttons = gpio_buttons, + .nbuttons = ARRAY_SIZE(gpio_buttons), +}; + +static struct platform_device gpio_keys_device = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &gpio_keys_pdata, + }, +}; -static void __init overo_flash_init(void) +static void __init overo_init_keys(void) { - u8 cs = 0; - u8 nandcs = GPMC_CS_NUM + 1; - - u32 gpmc_base_add = OMAP34XX_GPMC_VIRT; - - /* find out the chip-select on which NAND exists */ - while (cs < GPMC_CS_NUM) { - u32 ret = 0; - ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); - - if ((ret & 0xC00) == 0x800) { - printk(KERN_INFO "Found NAND on CS%d\n", cs); - if (nandcs > GPMC_CS_NUM) - nandcs = cs; - } - cs++; - } + platform_device_register(&gpio_keys_device); +} - if (nandcs > GPMC_CS_NUM) { - printk(KERN_INFO "NAND: Unable to find configuration " - "in GPMC\n "); - return; - } +#else +static inline void __init overo_init_keys(void) { return; } +#endif - if (nandcs < GPMC_CS_NUM) { - overo_nand_data.cs = nandcs; - overo_nand_data.gpmc_cs_baseaddr = (void *) - (gpmc_base_add + GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE); - overo_nand_data.gpmc_baseaddr = (void *) (gpmc_base_add); +static int overo_twl_gpio_setup(struct device *dev, + unsigned gpio, unsigned ngpio) +{ +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) + /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ + gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; +#endif - printk(KERN_INFO "Registering NAND on CS%d\n", nandcs); - if (platform_device_register(&overo_nand_device) < 0) - printk(KERN_ERR "Unable to register NAND device\n"); - } + return 0; } -static struct omap_uart_config overo_uart_config __initdata = { - .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), -}; static struct twl4030_gpio_platform_data overo_gpio_data = { - .gpio_base = OMAP_MAX_GPIO_LINES, - .irq_base = TWL4030_GPIO_IRQ_BASE, - .irq_end = TWL4030_GPIO_IRQ_END, + .use_leds = true, + .setup = overo_twl_gpio_setup, }; -static struct twl4030_platform_data overo_twldata = { - .irq_base = TWL4030_IRQ_BASE, - .irq_end = TWL4030_IRQ_END, - .gpio = &overo_gpio_data, +static struct regulator_init_data overo_vmmc1 = { + .constraints = { + .min_uV = 1850000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(overo_vmmc1_supply), + .consumer_supplies = overo_vmmc1_supply, }; -static struct i2c_board_info __initdata overo_i2c_boardinfo[] = { - { - I2C_BOARD_INFO("twl4030", 0x48), - .flags = I2C_CLIENT_WAKE, - .irq = INT_34XX_SYS_NIRQ, - .platform_data = &overo_twldata, - }, +static struct twl4030_platform_data overo_twldata = { + .gpio = &overo_gpio_data, + .vmmc1 = &overo_vmmc1, }; static int __init overo_i2c_init(void) { - omap_register_i2c_bus(1, 2600, overo_i2c_boardinfo, - ARRAY_SIZE(overo_i2c_boardinfo)); + omap3_pmic_get_config(&overo_twldata, + TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_AUDIO, + TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2); + + overo_twldata.vpll2->constraints.name = "VDVI"; + + omap3_pmic_init("tps65950", &overo_twldata); /* i2c2 pins are used for gpio */ omap_register_i2c_bus(3, 400, NULL, 0); return 0; } -static void __init overo_init_irq(void) +static struct panel_lb035q02_platform_data overo_lcd35_pdata = { + .name = "lcd35", + .source = "dpi.0", + + .data_lines = 24, + + .enable_gpio = OVERO_GPIO_LCD_EN, + .backlight_gpio = OVERO_GPIO_LCD_BL, +}; + +/* + * NOTE: We need to add either the lgphilips panel, or the lcd43 panel. The + * selection is done based on the overo_use_lcd35 field. If new SPI + * devices are added here, extra work is needed to make only the lgphilips panel + * affected by the overo_use_lcd35 field. + */ +static struct spi_board_info overo_spi_board_info[] __initdata = { + { + .modalias = "panel_lgphilips_lb035q02", + .bus_num = 1, + .chip_select = 1, + .max_speed_hz = 500000, + .mode = SPI_MODE_3, + .platform_data = &overo_lcd35_pdata, + }, +}; + +static int __init overo_spi_init(void) { - omap2_init_common_hw(); - omap_init_irq(); - omap_gpio_init(); + overo_ads7846_init(); + + if (overo_use_lcd35) { + spi_register_board_info(overo_spi_board_info, + ARRAY_SIZE(overo_spi_board_info)); + } + return 0; } -static struct platform_device overo_lcd_device = { - .name = "overo_lcd", - .id = -1, +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 2, + .reset_gpio = OVERO_GPIO_USBH_NRESET, + .vcc_gpio = -EINVAL, + }, }; -static struct omap_lcd_config overo_lcd_config __initdata = { - .ctrl_name = "internal", +static struct usbhs_omap_platform_data usbhs_bdata __initdata = { + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, }; -static struct omap_board_config_kernel overo_config[] __initdata = { - { OMAP_TAG_UART, &overo_uart_config }, - { OMAP_TAG_LCD, &overo_lcd_config }, +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + { .reg_offset = OMAP_MUX_TERMINATOR }, }; +#endif -static struct platform_device *overo_devices[] __initdata = { - &overo_lcd_device, +static struct gpio overo_bt_gpios[] __initdata = { + { OVERO_GPIO_BT_XGATE, GPIOF_OUT_INIT_LOW, "lcd enable" }, + { OVERO_GPIO_BT_NRESET, GPIOF_OUT_INIT_HIGH, "lcd bl enable" }, }; -static struct twl4030_hsmmc_info mmc[] __initdata = { - { - .mmc = 1, - .wires = 4, - .gpio_cd = -EINVAL, - .gpio_wp = -EINVAL, - }, - { - .mmc = 2, - .wires = 4, - .gpio_cd = -EINVAL, - .gpio_wp = -EINVAL, - }, - {} /* Terminator */ +static struct regulator_consumer_supply dummy_supplies[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x.0"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), + REGULATOR_SUPPLY("vddvario", "smsc911x.1"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.1"), }; static void __init overo_init(void) { + int ret; + + if (strstr(boot_command_line, "omapdss.def_disp=lcd35")) + overo_use_lcd35 = true; + + regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); + omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); overo_i2c_init(); - platform_add_devices(overo_devices, ARRAY_SIZE(overo_devices)); - omap_board_config = overo_config; - omap_board_config_size = ARRAY_SIZE(overo_config); + omap_hsmmc_init(mmc); omap_serial_init(); - twl4030_mmc_init(mmc); - overo_flash_init(); - - if ((gpio_request(OVERO_GPIO_W2W_NRESET, - "OVERO_GPIO_W2W_NRESET") == 0) && - (gpio_direction_output(OVERO_GPIO_W2W_NRESET, 1) == 0)) { + omap_sdrc_init(mt46h32m32lf6_sdrc_params, + mt46h32m32lf6_sdrc_params); + board_nand_init(overo_nand_partitions, + ARRAY_SIZE(overo_nand_partitions), NAND_CS, 0, NULL); + usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); + usb_musb_init(NULL); + + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); + usbhs_init(&usbhs_bdata); + overo_spi_init(); + overo_init_smsc911x(); + overo_init_led(); + overo_init_keys(); + omap_twl4030_audio_init("overo", NULL); + + overo_display_init(); + + /* Ensure SDRC pins are mux'd for self-refresh */ + omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); + omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); + + ret = gpio_request_one(OVERO_GPIO_W2W_NRESET, GPIOF_OUT_INIT_HIGH, + "OVERO_GPIO_W2W_NRESET"); + if (ret == 0) { gpio_export(OVERO_GPIO_W2W_NRESET, 0); gpio_set_value(OVERO_GPIO_W2W_NRESET, 0); udelay(10); gpio_set_value(OVERO_GPIO_W2W_NRESET, 1); } else { - printk(KERN_ERR "could not obtain gpio for " - "OVERO_GPIO_W2W_NRESET\n"); + pr_err("could not obtain gpio for OVERO_GPIO_W2W_NRESET\n"); } - if ((gpio_request(OVERO_GPIO_BT_XGATE, "OVERO_GPIO_BT_XGATE") == 0) && - (gpio_direction_output(OVERO_GPIO_BT_XGATE, 0) == 0)) + ret = gpio_request_array(overo_bt_gpios, ARRAY_SIZE(overo_bt_gpios)); + if (ret) { + pr_err("%s: could not obtain BT gpios\n", __func__); + } else { gpio_export(OVERO_GPIO_BT_XGATE, 0); - else - printk(KERN_ERR "could not obtain gpio for OVERO_GPIO_BT_XGATE\n"); - - if ((gpio_request(OVERO_GPIO_BT_NRESET, "OVERO_GPIO_BT_NRESET") == 0) && - (gpio_direction_output(OVERO_GPIO_BT_NRESET, 1) == 0)) { gpio_export(OVERO_GPIO_BT_NRESET, 0); gpio_set_value(OVERO_GPIO_BT_NRESET, 0); mdelay(6); gpio_set_value(OVERO_GPIO_BT_NRESET, 1); - } else { - printk(KERN_ERR "could not obtain gpio for " - "OVERO_GPIO_BT_NRESET\n"); } - if ((gpio_request(OVERO_GPIO_USBH_CPEN, "OVERO_GPIO_USBH_CPEN") == 0) && - (gpio_direction_output(OVERO_GPIO_USBH_CPEN, 1) == 0)) + ret = gpio_request_one(OVERO_GPIO_USBH_CPEN, GPIOF_OUT_INIT_HIGH, + "OVERO_GPIO_USBH_CPEN"); + if (ret == 0) gpio_export(OVERO_GPIO_USBH_CPEN, 0); else - printk(KERN_ERR "could not obtain gpio for " - "OVERO_GPIO_USBH_CPEN\n"); - - if ((gpio_request(OVERO_GPIO_USBH_NRESET, - "OVERO_GPIO_USBH_NRESET") == 0) && - (gpio_direction_output(OVERO_GPIO_USBH_NRESET, 1) == 0)) - gpio_export(OVERO_GPIO_USBH_NRESET, 0); - else - printk(KERN_ERR "could not obtain gpio for " - "OVERO_GPIO_USBH_NRESET\n"); -} - -static void __init overo_map_io(void) -{ - omap2_set_globals_343x(); - omap2_map_common_io(); + pr_err("could not obtain gpio for OVERO_GPIO_USBH_CPEN\n"); } MACHINE_START(OVERO, "Gumstix Overo") - .phys_io = 0x48000000, - .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, - .boot_params = 0x80000100, - .map_io = overo_map_io, - .init_irq = overo_init_irq, + .atag_offset = 0x100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap35xx_init_early, + .init_irq = omap3_init_irq, + .handle_irq = omap3_intc_handle_irq, .init_machine = overo_init, - .timer = &omap_timer, + .init_late = omap35xx_init_late, + .init_time = omap3_sync32k_timer_init, + .restart = omap3xxx_restart, MACHINE_END diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c new file mode 100644 index 00000000000..ddfc8df83c6 --- /dev/null +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -0,0 +1,1323 @@ +/* + * linux/arch/arm/mach-omap2/board-rx51-peripherals.c + * + * Copyright (C) 2008-2009 Nokia + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/input.h> +#include <linux/input/matrix_keypad.h> +#include <linux/spi/spi.h> +#include <linux/wl12xx.h> +#include <linux/spi/tsc2005.h> +#include <linux/i2c.h> +#include <linux/i2c/twl.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/regulator/machine.h> +#include <linux/gpio.h> +#include <linux/gpio_keys.h> +#include <linux/mmc/host.h> +#include <linux/power/isp1704_charger.h> +#include <linux/platform_data/spi-omap2-mcspi.h> +#include <linux/platform_data/mtd-onenand-omap2.h> + +#include <asm/system_info.h> + +#include "common.h" +#include <linux/omap-dma.h> +#include "gpmc-smc91x.h" + +#include "board-rx51.h" + +#include <sound/tlv320aic3x.h> +#include <sound/tpa6130a2-plat.h> +#include <media/radio-si4713.h> +#include <media/si4713.h> +#include <linux/platform_data/leds-lp55xx.h> + +#include <linux/platform_data/tsl2563.h> +#include <linux/lis3lv02d.h> + +#include <video/omap-panel-data.h> + +#if defined(CONFIG_IR_RX51) || defined(CONFIG_IR_RX51_MODULE) +#include <media/ir-rx51.h> +#endif + +#include "mux.h" +#include "omap-pm.h" +#include "hsmmc.h" +#include "common-board-devices.h" +#include "gpmc.h" +#include "gpmc-onenand.h" +#include "soc.h" +#include "omap-secure.h" + +#define SYSTEM_REV_B_USES_VAUX3 0x1699 +#define SYSTEM_REV_S_USES_VAUX3 0x8 + +#define RX51_WL1251_POWER_GPIO 87 +#define RX51_WL1251_IRQ_GPIO 42 +#define RX51_FMTX_RESET_GPIO 163 +#define RX51_FMTX_IRQ 53 +#define RX51_LP5523_CHIP_EN_GPIO 41 + +#define RX51_USB_TRANSCEIVER_RST_GPIO 67 + +#define RX51_TSC2005_RESET_GPIO 104 +#define RX51_TSC2005_IRQ_GPIO 100 + +#define LIS302_IRQ1_GPIO 181 +#define LIS302_IRQ2_GPIO 180 /* Not yet in use */ + +/* List all SPI devices here. Note that the list/probe order seems to matter! */ +enum { + RX51_SPI_WL1251, + RX51_SPI_TSC2005, /* Touch Controller */ + RX51_SPI_MIPID, /* LCD panel */ +}; + +static struct wl1251_platform_data wl1251_pdata; +static struct tsc2005_platform_data tsc2005_pdata; + +#if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE) +static int lis302_setup(void) +{ + int err; + int irq1 = LIS302_IRQ1_GPIO; + int irq2 = LIS302_IRQ2_GPIO; + + /* gpio for interrupt pin 1 */ + err = gpio_request(irq1, "lis3lv02dl_irq1"); + if (err) { + printk(KERN_ERR "lis3lv02dl: gpio request failed\n"); + goto out; + } + + /* gpio for interrupt pin 2 */ + err = gpio_request(irq2, "lis3lv02dl_irq2"); + if (err) { + gpio_free(irq1); + printk(KERN_ERR "lis3lv02dl: gpio request failed\n"); + goto out; + } + + gpio_direction_input(irq1); + gpio_direction_input(irq2); + +out: + return err; +} + +static int lis302_release(void) +{ + gpio_free(LIS302_IRQ1_GPIO); + gpio_free(LIS302_IRQ2_GPIO); + + return 0; +} + +static struct lis3lv02d_platform_data rx51_lis3lv02d_data = { + .click_flags = LIS3_CLICK_SINGLE_X | LIS3_CLICK_SINGLE_Y | + LIS3_CLICK_SINGLE_Z, + /* Limits are 0.5g * value */ + .click_thresh_x = 8, + .click_thresh_y = 8, + .click_thresh_z = 10, + /* Click must be longer than time limit */ + .click_time_limit = 9, + /* Kind of debounce filter */ + .click_latency = 50, + + /* Limits for all axis. millig-value / 18 to get HW values */ + .wakeup_flags = LIS3_WAKEUP_X_HI | LIS3_WAKEUP_Y_HI, + .wakeup_thresh = 800 / 18, + .wakeup_flags2 = LIS3_WAKEUP_Z_HI , + .wakeup_thresh2 = 900 / 18, + + .hipass_ctrl = LIS3_HIPASS1_DISABLE | LIS3_HIPASS2_DISABLE, + + /* Interrupt line 2 for click detection, line 1 for thresholds */ + .irq_cfg = LIS3_IRQ2_CLICK | LIS3_IRQ1_FF_WU_12, + + .axis_x = LIS3_DEV_X, + .axis_y = LIS3_INV_DEV_Y, + .axis_z = LIS3_INV_DEV_Z, + .setup_resources = lis302_setup, + .release_resources = lis302_release, + .st_min_limits = {-32, 3, 3}, + .st_max_limits = {-3, 32, 32}, +}; +#endif + +#if defined(CONFIG_SENSORS_TSL2563) || defined(CONFIG_SENSORS_TSL2563_MODULE) +static struct tsl2563_platform_data rx51_tsl2563_platform_data = { + .cover_comp_gain = 16, +}; +#endif + +#if defined(CONFIG_LEDS_LP5523) || defined(CONFIG_LEDS_LP5523_MODULE) +static struct lp55xx_led_config rx51_lp5523_led_config[] = { + { + .name = "lp5523:kb1", + .chan_nr = 0, + .led_current = 50, + .max_current = 100, + }, { + .name = "lp5523:kb2", + .chan_nr = 1, + .led_current = 50, + .max_current = 100, + }, { + .name = "lp5523:kb3", + .chan_nr = 2, + .led_current = 50, + .max_current = 100, + }, { + .name = "lp5523:kb4", + .chan_nr = 3, + .led_current = 50, + .max_current = 100, + }, { + .name = "lp5523:b", + .chan_nr = 4, + .led_current = 50, + .max_current = 100, + }, { + .name = "lp5523:g", + .chan_nr = 5, + .led_current = 50, + .max_current = 100, + }, { + .name = "lp5523:r", + .chan_nr = 6, + .led_current = 50, + .max_current = 100, + }, { + .name = "lp5523:kb5", + .chan_nr = 7, + .led_current = 50, + .max_current = 100, + }, { + .name = "lp5523:kb6", + .chan_nr = 8, + .led_current = 50, + .max_current = 100, + } +}; + +static struct lp55xx_platform_data rx51_lp5523_platform_data = { + .led_config = rx51_lp5523_led_config, + .num_channels = ARRAY_SIZE(rx51_lp5523_led_config), + .clock_mode = LP55XX_CLOCK_AUTO, + .enable_gpio = RX51_LP5523_CHIP_EN_GPIO, +}; +#endif + +#define RX51_LCD_RESET_GPIO 90 + +static struct panel_acx565akm_platform_data acx_pdata = { + .name = "lcd", + .source = "sdi.0", + .reset_gpio = RX51_LCD_RESET_GPIO, + .datapairs = 2, +}; + +static struct omap2_mcspi_device_config wl1251_mcspi_config = { + .turbo_mode = 0, +}; + +static struct omap2_mcspi_device_config mipid_mcspi_config = { + .turbo_mode = 0, +}; + +static struct omap2_mcspi_device_config tsc2005_mcspi_config = { + .turbo_mode = 0, +}; + +static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = { + [RX51_SPI_WL1251] = { + .modalias = "wl1251", + .bus_num = 4, + .chip_select = 0, + .max_speed_hz = 48000000, + .mode = SPI_MODE_3, + .controller_data = &wl1251_mcspi_config, + .platform_data = &wl1251_pdata, + }, + [RX51_SPI_MIPID] = { + .modalias = "acx565akm", + .bus_num = 1, + .chip_select = 2, + .max_speed_hz = 6000000, + .controller_data = &mipid_mcspi_config, + .platform_data = &acx_pdata, + }, + [RX51_SPI_TSC2005] = { + .modalias = "tsc2005", + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 6000000, + .controller_data = &tsc2005_mcspi_config, + .platform_data = &tsc2005_pdata, + }, +}; + +static struct platform_device rx51_battery_device = { + .name = "rx51-battery", + .id = -1, +}; + +static void rx51_charger_set_power(bool on) +{ + gpio_set_value(RX51_USB_TRANSCEIVER_RST_GPIO, on); +} + +static struct isp1704_charger_data rx51_charger_data = { + .set_power = rx51_charger_set_power, +}; + +static struct platform_device rx51_charger_device = { + .name = "isp1704_charger", + .dev = { + .platform_data = &rx51_charger_data, + }, +}; + +static void __init rx51_charger_init(void) +{ + WARN_ON(gpio_request_one(RX51_USB_TRANSCEIVER_RST_GPIO, + GPIOF_OUT_INIT_HIGH, "isp1704_reset")); + + platform_device_register(&rx51_battery_device); + platform_device_register(&rx51_charger_device); +} + +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) + +#define RX51_GPIO_CAMERA_LENS_COVER 110 +#define RX51_GPIO_CAMERA_FOCUS 68 +#define RX51_GPIO_CAMERA_CAPTURE 69 +#define RX51_GPIO_KEYPAD_SLIDE 71 +#define RX51_GPIO_LOCK_BUTTON 113 +#define RX51_GPIO_PROXIMITY 89 + +#define RX51_GPIO_DEBOUNCE_TIMEOUT 10 + +static struct gpio_keys_button rx51_gpio_keys[] = { + { + .desc = "Camera Lens Cover", + .type = EV_SW, + .code = SW_CAMERA_LENS_COVER, + .gpio = RX51_GPIO_CAMERA_LENS_COVER, + .active_low = 1, + .debounce_interval = RX51_GPIO_DEBOUNCE_TIMEOUT, + }, { + .desc = "Camera Focus", + .type = EV_KEY, + .code = KEY_CAMERA_FOCUS, + .gpio = RX51_GPIO_CAMERA_FOCUS, + .active_low = 1, + .debounce_interval = RX51_GPIO_DEBOUNCE_TIMEOUT, + }, { + .desc = "Camera Capture", + .type = EV_KEY, + .code = KEY_CAMERA, + .gpio = RX51_GPIO_CAMERA_CAPTURE, + .active_low = 1, + .debounce_interval = RX51_GPIO_DEBOUNCE_TIMEOUT, + }, { + .desc = "Lock Button", + .type = EV_KEY, + .code = KEY_SCREENLOCK, + .gpio = RX51_GPIO_LOCK_BUTTON, + .active_low = 1, + .debounce_interval = RX51_GPIO_DEBOUNCE_TIMEOUT, + }, { + .desc = "Keypad Slide", + .type = EV_SW, + .code = SW_KEYPAD_SLIDE, + .gpio = RX51_GPIO_KEYPAD_SLIDE, + .active_low = 1, + .debounce_interval = RX51_GPIO_DEBOUNCE_TIMEOUT, + }, { + .desc = "Proximity Sensor", + .type = EV_SW, + .code = SW_FRONT_PROXIMITY, + .gpio = RX51_GPIO_PROXIMITY, + .active_low = 0, + .debounce_interval = RX51_GPIO_DEBOUNCE_TIMEOUT, + } +}; + +static struct gpio_keys_platform_data rx51_gpio_keys_data = { + .buttons = rx51_gpio_keys, + .nbuttons = ARRAY_SIZE(rx51_gpio_keys), +}; + +static struct platform_device rx51_gpio_keys_device = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &rx51_gpio_keys_data, + }, +}; + +static void __init rx51_add_gpio_keys(void) +{ + platform_device_register(&rx51_gpio_keys_device); +} +#else +static void __init rx51_add_gpio_keys(void) +{ +} +#endif /* CONFIG_KEYBOARD_GPIO || CONFIG_KEYBOARD_GPIO_MODULE */ + +static uint32_t board_keymap[] = { + /* + * Note that KEY(x, 8, KEY_XXX) entries represent "entrire row + * connected to the ground" matrix state. + */ + KEY(0, 0, KEY_Q), + KEY(0, 1, KEY_O), + KEY(0, 2, KEY_P), + KEY(0, 3, KEY_COMMA), + KEY(0, 4, KEY_BACKSPACE), + KEY(0, 6, KEY_A), + KEY(0, 7, KEY_S), + + KEY(1, 0, KEY_W), + KEY(1, 1, KEY_D), + KEY(1, 2, KEY_F), + KEY(1, 3, KEY_G), + KEY(1, 4, KEY_H), + KEY(1, 5, KEY_J), + KEY(1, 6, KEY_K), + KEY(1, 7, KEY_L), + + KEY(2, 0, KEY_E), + KEY(2, 1, KEY_DOT), + KEY(2, 2, KEY_UP), + KEY(2, 3, KEY_ENTER), + KEY(2, 5, KEY_Z), + KEY(2, 6, KEY_X), + KEY(2, 7, KEY_C), + KEY(2, 8, KEY_F9), + + KEY(3, 0, KEY_R), + KEY(3, 1, KEY_V), + KEY(3, 2, KEY_B), + KEY(3, 3, KEY_N), + KEY(3, 4, KEY_M), + KEY(3, 5, KEY_SPACE), + KEY(3, 6, KEY_SPACE), + KEY(3, 7, KEY_LEFT), + + KEY(4, 0, KEY_T), + KEY(4, 1, KEY_DOWN), + KEY(4, 2, KEY_RIGHT), + KEY(4, 4, KEY_LEFTCTRL), + KEY(4, 5, KEY_RIGHTALT), + KEY(4, 6, KEY_LEFTSHIFT), + KEY(4, 8, KEY_F10), + + KEY(5, 0, KEY_Y), + KEY(5, 8, KEY_F11), + + KEY(6, 0, KEY_U), + + KEY(7, 0, KEY_I), + KEY(7, 1, KEY_F7), + KEY(7, 2, KEY_F8), +}; + +static struct matrix_keymap_data board_map_data = { + .keymap = board_keymap, + .keymap_size = ARRAY_SIZE(board_keymap), +}; + +static struct twl4030_keypad_data rx51_kp_data = { + .keymap_data = &board_map_data, + .rows = 8, + .cols = 8, + .rep = 1, +}; + +/* Enable input logic and pull all lines up when eMMC is on. */ +static struct omap_board_mux rx51_mmc2_on_mux[] = { + OMAP3_MUX(SDMMC2_CMD, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), + OMAP3_MUX(SDMMC2_DAT0, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), + OMAP3_MUX(SDMMC2_DAT1, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), + OMAP3_MUX(SDMMC2_DAT2, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), + OMAP3_MUX(SDMMC2_DAT3, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), + OMAP3_MUX(SDMMC2_DAT4, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), + OMAP3_MUX(SDMMC2_DAT5, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), + OMAP3_MUX(SDMMC2_DAT6, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), + OMAP3_MUX(SDMMC2_DAT7, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; + +/* Disable input logic and pull all lines down when eMMC is off. */ +static struct omap_board_mux rx51_mmc2_off_mux[] = { + OMAP3_MUX(SDMMC2_CMD, OMAP_PULL_ENA | OMAP_MUX_MODE0), + OMAP3_MUX(SDMMC2_DAT0, OMAP_PULL_ENA | OMAP_MUX_MODE0), + OMAP3_MUX(SDMMC2_DAT1, OMAP_PULL_ENA | OMAP_MUX_MODE0), + OMAP3_MUX(SDMMC2_DAT2, OMAP_PULL_ENA | OMAP_MUX_MODE0), + OMAP3_MUX(SDMMC2_DAT3, OMAP_PULL_ENA | OMAP_MUX_MODE0), + OMAP3_MUX(SDMMC2_DAT4, OMAP_PULL_ENA | OMAP_MUX_MODE0), + OMAP3_MUX(SDMMC2_DAT5, OMAP_PULL_ENA | OMAP_MUX_MODE0), + OMAP3_MUX(SDMMC2_DAT6, OMAP_PULL_ENA | OMAP_MUX_MODE0), + OMAP3_MUX(SDMMC2_DAT7, OMAP_PULL_ENA | OMAP_MUX_MODE0), + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; + +static struct omap_mux_partition *partition; + +/* + * Current flows to eMMC when eMMC is off and the data lines are pulled up, + * so pull them down. N.B. we pull 8 lines because we are using 8 lines. + */ +static void rx51_mmc2_remux(struct device *dev, int slot, int power_on) +{ + if (power_on) + omap_mux_write_array(partition, rx51_mmc2_on_mux); + else + omap_mux_write_array(partition, rx51_mmc2_off_mux); +} + +static struct omap2_hsmmc_info mmc[] __initdata = { + { + .name = "external", + .mmc = 1, + .caps = MMC_CAP_4_BIT_DATA, + .cover_only = true, + .gpio_cd = 160, + .gpio_wp = -EINVAL, + .power_saving = true, + }, + { + .name = "internal", + .mmc = 2, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, + /* See also rx51_mmc2_remux */ + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + .nonremovable = true, + .power_saving = true, + .remux = rx51_mmc2_remux, + }, + {} /* Terminator */ +}; + +static struct regulator_consumer_supply rx51_vmmc1_supply[] = { + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), +}; + +static struct regulator_consumer_supply rx51_vaux2_supply[] = { + REGULATOR_SUPPLY("vdds_csib", "omap3isp"), +}; + +static struct regulator_consumer_supply rx51_vaux3_supply[] = { + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"), +}; + +static struct regulator_consumer_supply rx51_vsim_supply[] = { + REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.1"), +}; + +static struct regulator_consumer_supply rx51_vmmc2_supplies[] = { + /* tlv320aic3x analog supplies */ + REGULATOR_SUPPLY("AVDD", "2-0018"), + REGULATOR_SUPPLY("DRVDD", "2-0018"), + REGULATOR_SUPPLY("AVDD", "2-0019"), + REGULATOR_SUPPLY("DRVDD", "2-0019"), + /* tpa6130a2 */ + REGULATOR_SUPPLY("Vdd", "2-0060"), + /* Keep vmmc as last item. It is not iterated for newer boards */ + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"), +}; + +static struct regulator_consumer_supply rx51_vio_supplies[] = { + /* tlv320aic3x digital supplies */ + REGULATOR_SUPPLY("IOVDD", "2-0018"), + REGULATOR_SUPPLY("DVDD", "2-0018"), + REGULATOR_SUPPLY("IOVDD", "2-0019"), + REGULATOR_SUPPLY("DVDD", "2-0019"), + /* Si4713 IO supply */ + REGULATOR_SUPPLY("vio", "2-0063"), + /* lis3lv02d */ + REGULATOR_SUPPLY("Vdd_IO", "3-001d"), +}; + +static struct regulator_consumer_supply rx51_vaux1_consumers[] = { + REGULATOR_SUPPLY("vdds_sdi", "omapdss"), + REGULATOR_SUPPLY("vdds_sdi", "omapdss_sdi.0"), + /* Si4713 supply */ + REGULATOR_SUPPLY("vdd", "2-0063"), + /* lis3lv02d */ + REGULATOR_SUPPLY("Vdd", "3-001d"), +}; + +static struct regulator_init_data rx51_vaux1 = { + .constraints = { + .name = "V28", + .min_uV = 2800000, + .max_uV = 2800000, + .always_on = true, /* due battery cover sensor */ + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(rx51_vaux1_consumers), + .consumer_supplies = rx51_vaux1_consumers, +}; + +static struct regulator_init_data rx51_vaux2 = { + .constraints = { + .name = "VCSI", + .min_uV = 1800000, + .max_uV = 1800000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(rx51_vaux2_supply), + .consumer_supplies = rx51_vaux2_supply, +}; + +/* VAUX3 - adds more power to VIO_18 rail */ +static struct regulator_init_data rx51_vaux3_cam = { + .constraints = { + .name = "VCAM_DIG_18", + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data rx51_vaux3_mmc = { + .constraints = { + .name = "VMMC2_30", + .min_uV = 2800000, + .max_uV = 3000000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(rx51_vaux3_supply), + .consumer_supplies = rx51_vaux3_supply, +}; + +static struct regulator_init_data rx51_vaux4 = { + .constraints = { + .name = "VCAM_ANA_28", + .min_uV = 2800000, + .max_uV = 2800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data rx51_vmmc1 = { + .constraints = { + .min_uV = 1850000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(rx51_vmmc1_supply), + .consumer_supplies = rx51_vmmc1_supply, +}; + +static struct regulator_init_data rx51_vmmc2 = { + .constraints = { + .name = "V28_A", + .min_uV = 2800000, + .max_uV = 3000000, + .always_on = true, /* due VIO leak to AIC34 VDDs */ + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(rx51_vmmc2_supplies), + .consumer_supplies = rx51_vmmc2_supplies, +}; + +static struct regulator_init_data rx51_vpll1 = { + .constraints = { + .name = "VPLL", + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .always_on = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE, + }, +}; + +static struct regulator_init_data rx51_vpll2 = { + .constraints = { + .name = "VSDI_CSI", + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .always_on = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE, + }, +}; + +static struct regulator_init_data rx51_vsim = { + .constraints = { + .name = "VMMC2_IO_18", + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(rx51_vsim_supply), + .consumer_supplies = rx51_vsim_supply, +}; + +static struct regulator_init_data rx51_vio = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(rx51_vio_supplies), + .consumer_supplies = rx51_vio_supplies, +}; + +static struct regulator_init_data rx51_vintana1 = { + .constraints = { + .name = "VINTANA1", + .min_uV = 1500000, + .max_uV = 1500000, + .always_on = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE, + }, +}; + +static struct regulator_init_data rx51_vintana2 = { + .constraints = { + .name = "VINTANA2", + .min_uV = 2750000, + .max_uV = 2750000, + .apply_uV = true, + .always_on = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE, + }, +}; + +static struct regulator_init_data rx51_vintdig = { + .constraints = { + .name = "VINTDIG", + .min_uV = 1500000, + .max_uV = 1500000, + .always_on = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE, + }, +}; + +static const char * const si4713_supply_names[] = { + "vio", + "vdd", +}; + +static struct si4713_platform_data rx51_si4713_i2c_data __initdata_or_module = { + .supplies = ARRAY_SIZE(si4713_supply_names), + .supply_names = si4713_supply_names, + .gpio_reset = RX51_FMTX_RESET_GPIO, +}; + +static struct i2c_board_info rx51_si4713_board_info __initdata_or_module = { + I2C_BOARD_INFO("si4713", SI4713_I2C_ADDR_BUSEN_HIGH), + .platform_data = &rx51_si4713_i2c_data, +}; + +static struct radio_si4713_platform_data rx51_si4713_data __initdata_or_module = { + .i2c_bus = 2, + .subdev_board_info = &rx51_si4713_board_info, +}; + +static struct platform_device rx51_si4713_dev __initdata_or_module = { + .name = "radio-si4713", + .id = -1, + .dev = { + .platform_data = &rx51_si4713_data, + }, +}; + +static __init void rx51_init_si4713(void) +{ + int err; + + err = gpio_request_one(RX51_FMTX_IRQ, GPIOF_DIR_IN, "si4713 irq"); + if (err) { + printk(KERN_ERR "Cannot request si4713 irq gpio. %d\n", err); + return; + } + rx51_si4713_board_info.irq = gpio_to_irq(RX51_FMTX_IRQ); + platform_device_register(&rx51_si4713_dev); +} + +static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n) +{ + /* FIXME this gpio setup is just a placeholder for now */ + gpio_request_one(gpio + 6, GPIOF_OUT_INIT_LOW, "backlight_pwm"); + gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "speaker_en"); + + return 0; +} + +static struct twl4030_gpio_platform_data rx51_gpio_data = { + .pulldowns = BIT(0) | BIT(1) | BIT(2) | BIT(3) + | BIT(4) | BIT(5) + | BIT(8) | BIT(9) | BIT(10) | BIT(11) + | BIT(12) | BIT(13) | BIT(14) | BIT(15) + | BIT(16) | BIT(17) , + .setup = rx51_twlgpio_setup, +}; + +static struct twl4030_ins sleep_on_seq[] __initdata = { +/* + * Turn off everything + */ + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, 1, 0, RES_STATE_SLEEP), 2}, +}; + +static struct twl4030_script sleep_on_script __initdata = { + .script = sleep_on_seq, + .size = ARRAY_SIZE(sleep_on_seq), + .flags = TWL4030_SLEEP_SCRIPT, +}; + +static struct twl4030_ins wakeup_seq[] __initdata = { +/* + * Reenable everything + */ + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, 1, 0, RES_STATE_ACTIVE), 2}, +}; + +static struct twl4030_script wakeup_script __initdata = { + .script = wakeup_seq, + .size = ARRAY_SIZE(wakeup_seq), + .flags = TWL4030_WAKEUP12_SCRIPT, +}; + +static struct twl4030_ins wakeup_p3_seq[] __initdata = { +/* + * Reenable everything + */ + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, 1, 0, RES_STATE_ACTIVE), 2}, +}; + +static struct twl4030_script wakeup_p3_script __initdata = { + .script = wakeup_p3_seq, + .size = ARRAY_SIZE(wakeup_p3_seq), + .flags = TWL4030_WAKEUP3_SCRIPT, +}; + +static struct twl4030_ins wrst_seq[] __initdata = { +/* + * Reset twl4030. + * Reset VDD1 regulator. + * Reset VDD2 regulator. + * Reset VPLL1 regulator. + * Enable sysclk output. + * Reenable twl4030. + */ + {MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_OFF), 2}, + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, 0, 1, RES_STATE_ACTIVE), + 0x13}, + {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_PP, 0, 3, RES_STATE_OFF), 0x13}, + {MSG_SINGULAR(DEV_GRP_NULL, RES_VDD1, RES_STATE_WRST), 0x13}, + {MSG_SINGULAR(DEV_GRP_NULL, RES_VDD2, RES_STATE_WRST), 0x13}, + {MSG_SINGULAR(DEV_GRP_NULL, RES_VPLL1, RES_STATE_WRST), 0x35}, + {MSG_SINGULAR(DEV_GRP_P3, RES_HFCLKOUT, RES_STATE_ACTIVE), 2}, + {MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_ACTIVE), 2}, +}; + +static struct twl4030_script wrst_script __initdata = { + .script = wrst_seq, + .size = ARRAY_SIZE(wrst_seq), + .flags = TWL4030_WRST_SCRIPT, +}; + +static struct twl4030_script *twl4030_scripts[] __initdata = { + /* wakeup12 script should be loaded before sleep script, otherwise a + board might hit retention before loading of wakeup script is + completed. This can cause boot failures depending on timing issues. + */ + &wakeup_script, + &sleep_on_script, + &wakeup_p3_script, + &wrst_script, +}; + +static struct twl4030_resconfig twl4030_rconfig[] __initdata = { + { .resource = RES_VDD1, .devgroup = -1, + .type = 1, .type2 = -1, .remap_off = RES_STATE_OFF, + .remap_sleep = RES_STATE_OFF + }, + { .resource = RES_VDD2, .devgroup = -1, + .type = 1, .type2 = -1, .remap_off = RES_STATE_OFF, + .remap_sleep = RES_STATE_OFF + }, + { .resource = RES_VPLL1, .devgroup = -1, + .type = 1, .type2 = -1, .remap_off = RES_STATE_OFF, + .remap_sleep = RES_STATE_OFF + }, + { .resource = RES_VPLL2, .devgroup = -1, + .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_VAUX1, .devgroup = -1, + .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_VAUX2, .devgroup = -1, + .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_VAUX3, .devgroup = -1, + .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_VAUX4, .devgroup = -1, + .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_VMMC1, .devgroup = -1, + .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_VMMC2, .devgroup = -1, + .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_VDAC, .devgroup = -1, + .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_VSIM, .devgroup = -1, + .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_VINTANA1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3, + .type = -1, .type2 = -1, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_VINTANA2, .devgroup = DEV_GRP_P1 | DEV_GRP_P3, + .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_VINTDIG, .devgroup = DEV_GRP_P1 | DEV_GRP_P3, + .type = -1, .type2 = -1, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_VIO, .devgroup = DEV_GRP_P3, + .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_CLKEN, .devgroup = DEV_GRP_P1 | DEV_GRP_P3, + .type = 1, .type2 = -1 , .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_REGEN, .devgroup = DEV_GRP_P1 | DEV_GRP_P3, + .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_NRES_PWRON, .devgroup = DEV_GRP_P1 | DEV_GRP_P3, + .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_SYSEN, .devgroup = DEV_GRP_P1 | DEV_GRP_P3, + .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_HFCLKOUT, .devgroup = DEV_GRP_P3, + .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_32KCLKOUT, .devgroup = -1, + .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_RESET, .devgroup = -1, + .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1 + }, + { .resource = RES_MAIN_REF, .devgroup = -1, + .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1 + }, + { 0, 0}, +}; + +static struct twl4030_power_data rx51_t2scripts_data __initdata = { + .scripts = twl4030_scripts, + .num = ARRAY_SIZE(twl4030_scripts), + .resource_config = twl4030_rconfig, +}; + +static struct twl4030_vibra_data rx51_vibra_data __initdata = { + .coexist = 0, +}; + +static struct twl4030_audio_data rx51_audio_data __initdata = { + .audio_mclk = 26000000, + .vibra = &rx51_vibra_data, +}; + +static struct twl4030_platform_data rx51_twldata __initdata = { + /* platform_data for children goes here */ + .gpio = &rx51_gpio_data, + .keypad = &rx51_kp_data, + .power = &rx51_t2scripts_data, + .audio = &rx51_audio_data, + + .vaux1 = &rx51_vaux1, + .vaux2 = &rx51_vaux2, + .vaux4 = &rx51_vaux4, + .vmmc1 = &rx51_vmmc1, + .vpll1 = &rx51_vpll1, + .vpll2 = &rx51_vpll2, + .vsim = &rx51_vsim, + .vintana1 = &rx51_vintana1, + .vintana2 = &rx51_vintana2, + .vintdig = &rx51_vintdig, + .vio = &rx51_vio, +}; + +static struct tpa6130a2_platform_data rx51_tpa6130a2_data __initdata_or_module = { + .power_gpio = 98, +}; + +/* Audio setup data */ +static struct aic3x_setup_data rx51_aic34_setup = { + .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED, + .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT, +}; + +static struct aic3x_pdata rx51_aic3x_data = { + .setup = &rx51_aic34_setup, + .gpio_reset = 60, +}; + +static struct aic3x_pdata rx51_aic3x_data2 = { + .gpio_reset = 60, +}; + +static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = { + { + I2C_BOARD_INFO("tlv320aic3x", 0x18), + .platform_data = &rx51_aic3x_data, + }, + { + I2C_BOARD_INFO("tlv320aic3x", 0x19), + .platform_data = &rx51_aic3x_data2, + }, +#if defined(CONFIG_SENSORS_TSL2563) || defined(CONFIG_SENSORS_TSL2563_MODULE) + { + I2C_BOARD_INFO("tsl2563", 0x29), + .platform_data = &rx51_tsl2563_platform_data, + }, +#endif +#if defined(CONFIG_LEDS_LP5523) || defined(CONFIG_LEDS_LP5523_MODULE) + { + I2C_BOARD_INFO("lp5523", 0x32), + .platform_data = &rx51_lp5523_platform_data, + }, +#endif + { + I2C_BOARD_INFO("bq27200", 0x55), + }, + { + I2C_BOARD_INFO("tpa6130a2", 0x60), + .platform_data = &rx51_tpa6130a2_data, + } +}; + +static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_3[] = { +#if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE) + { + I2C_BOARD_INFO("lis3lv02d", 0x1d), + .platform_data = &rx51_lis3lv02d_data, + }, +#endif +}; + +static int __init rx51_i2c_init(void) +{ + if ((system_rev >= SYSTEM_REV_S_USES_VAUX3 && system_rev < 0x100) || + system_rev >= SYSTEM_REV_B_USES_VAUX3) { + rx51_twldata.vaux3 = &rx51_vaux3_mmc; + /* Only older boards use VMMC2 for internal MMC */ + rx51_vmmc2.num_consumer_supplies--; + } else { + rx51_twldata.vaux3 = &rx51_vaux3_cam; + } + rx51_twldata.vmmc2 = &rx51_vmmc2; + omap3_pmic_get_config(&rx51_twldata, + TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC, + TWL_COMMON_REGULATOR_VDAC); + + rx51_twldata.vdac->constraints.apply_uV = true; + rx51_twldata.vdac->constraints.name = "VDAC"; + + omap_pmic_init(1, 2200, "twl5030", 7 + OMAP_INTC_START, &rx51_twldata); + omap_register_i2c_bus(2, 100, rx51_peripherals_i2c_board_info_2, + ARRAY_SIZE(rx51_peripherals_i2c_board_info_2)); +#if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE) + rx51_lis3lv02d_data.irq2 = gpio_to_irq(LIS302_IRQ2_GPIO); + rx51_peripherals_i2c_board_info_3[0].irq = gpio_to_irq(LIS302_IRQ1_GPIO); +#endif + omap_register_i2c_bus(3, 400, rx51_peripherals_i2c_board_info_3, + ARRAY_SIZE(rx51_peripherals_i2c_board_info_3)); + return 0; +} + +#if defined(CONFIG_MTD_ONENAND_OMAP2) || \ + defined(CONFIG_MTD_ONENAND_OMAP2_MODULE) + +static struct mtd_partition onenand_partitions[] = { + { + .name = "bootloader", + .offset = 0, + .size = 0x20000, + .mask_flags = MTD_WRITEABLE, /* Force read-only */ + }, + { + .name = "config", + .offset = MTDPART_OFS_APPEND, + .size = 0x60000, + }, + { + .name = "log", + .offset = MTDPART_OFS_APPEND, + .size = 0x40000, + }, + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = 0x200000, + }, + { + .name = "initfs", + .offset = MTDPART_OFS_APPEND, + .size = 0x200000, + }, + { + .name = "rootfs", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct omap_onenand_platform_data board_onenand_data[] = { + { + .cs = 0, + .gpio_irq = 65, + .parts = onenand_partitions, + .nr_parts = ARRAY_SIZE(onenand_partitions), + .flags = ONENAND_SYNC_READWRITE, + } +}; +#endif + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + +static struct omap_smc91x_platform_data board_smc91x_data = { + .cs = 1, + .gpio_irq = 54, + .gpio_pwrdwn = 86, + .gpio_reset = 164, + .flags = GPMC_TIMINGS_SMC91C96 | IORESOURCE_IRQ_HIGHLEVEL, +}; + +static void __init board_smc91x_init(void) +{ + omap_mux_init_gpio(54, OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_gpio(86, OMAP_PIN_OUTPUT); + omap_mux_init_gpio(164, OMAP_PIN_OUTPUT); + + gpmc_smc91x_init(&board_smc91x_data); +} + +#else + +static inline void board_smc91x_init(void) +{ +} + +#endif + +static struct gpio rx51_wl1251_gpios[] __initdata = { + { RX51_WL1251_IRQ_GPIO, GPIOF_IN, "wl1251 irq" }, +}; + +static void __init rx51_init_wl1251(void) +{ + int irq, ret; + + ret = gpio_request_array(rx51_wl1251_gpios, + ARRAY_SIZE(rx51_wl1251_gpios)); + if (ret < 0) + goto error; + + irq = gpio_to_irq(RX51_WL1251_IRQ_GPIO); + if (irq < 0) + goto err_irq; + + wl1251_pdata.power_gpio = RX51_WL1251_POWER_GPIO; + rx51_peripherals_spi_board_info[RX51_SPI_WL1251].irq = irq; + + return; + +err_irq: + gpio_free(RX51_WL1251_IRQ_GPIO); +error: + printk(KERN_ERR "wl1251 board initialisation failed\n"); + wl1251_pdata.power_gpio = -1; + + /* + * Now rx51_peripherals_spi_board_info[1].irq is zero and + * set_power is null, and wl1251_probe() will fail. + */ +} + +static struct tsc2005_platform_data tsc2005_pdata = { + .ts_pressure_max = 2048, + .ts_pressure_fudge = 2, + .ts_x_max = 4096, + .ts_x_fudge = 4, + .ts_y_max = 4096, + .ts_y_fudge = 7, + .ts_x_plate_ohm = 280, + .esd_timeout_ms = 8000, +}; + +static struct gpio rx51_tsc2005_gpios[] __initdata = { + { RX51_TSC2005_IRQ_GPIO, GPIOF_IN, "tsc2005 IRQ" }, + { RX51_TSC2005_RESET_GPIO, GPIOF_OUT_INIT_HIGH, "tsc2005 reset" }, +}; + +static void rx51_tsc2005_set_reset(bool enable) +{ + gpio_set_value(RX51_TSC2005_RESET_GPIO, enable); +} + +static void __init rx51_init_tsc2005(void) +{ + int r; + + omap_mux_init_gpio(RX51_TSC2005_RESET_GPIO, OMAP_PIN_OUTPUT); + omap_mux_init_gpio(RX51_TSC2005_IRQ_GPIO, OMAP_PIN_INPUT_PULLUP); + + r = gpio_request_array(rx51_tsc2005_gpios, + ARRAY_SIZE(rx51_tsc2005_gpios)); + if (r < 0) { + printk(KERN_ERR "tsc2005 board initialization failed\n"); + tsc2005_pdata.esd_timeout_ms = 0; + return; + } + + tsc2005_pdata.set_reset = rx51_tsc2005_set_reset; + rx51_peripherals_spi_board_info[RX51_SPI_TSC2005].irq = + gpio_to_irq(RX51_TSC2005_IRQ_GPIO); +} + +#if defined(CONFIG_IR_RX51) || defined(CONFIG_IR_RX51_MODULE) +static struct lirc_rx51_platform_data rx51_lirc_data = { + .set_max_mpu_wakeup_lat = omap_pm_set_max_mpu_wakeup_lat, + .pwm_timer = 9, /* Use GPT 9 for CIR */ +}; + +static struct platform_device rx51_lirc_device = { + .name = "lirc_rx51", + .id = -1, + .dev = { + .platform_data = &rx51_lirc_data, + }, +}; + +static void __init rx51_init_lirc(void) +{ + platform_device_register(&rx51_lirc_device); +} +#else +static void __init rx51_init_lirc(void) +{ +} +#endif + +static struct platform_device madc_hwmon = { + .name = "twl4030_madc_hwmon", + .id = -1, +}; + +static void __init rx51_init_twl4030_hwmon(void) +{ + platform_device_register(&madc_hwmon); +} + +static struct platform_device omap3_rom_rng_device = { + .name = "omap3-rom-rng", + .id = -1, + .dev = { + .platform_data = rx51_secure_rng_call, + }, +}; + +static void __init rx51_init_omap3_rom_rng(void) +{ + if (omap_type() == OMAP2_DEVICE_TYPE_SEC) { + pr_info("RX-51: Registring OMAP3 HWRNG device\n"); + platform_device_register(&omap3_rom_rng_device); + } +} + +void __init rx51_peripherals_init(void) +{ + rx51_i2c_init(); + regulator_has_full_constraints(); + gpmc_onenand_init(board_onenand_data); + board_smc91x_init(); + rx51_add_gpio_keys(); + rx51_init_wl1251(); + rx51_init_tsc2005(); + rx51_init_si4713(); + rx51_init_lirc(); + spi_register_board_info(rx51_peripherals_spi_board_info, + ARRAY_SIZE(rx51_peripherals_spi_board_info)); + + partition = omap_mux_get("core"); + if (partition) + omap_hsmmc_init(mmc); + + rx51_charger_init(); + rx51_init_twl4030_hwmon(); + rx51_init_omap3_rom_rng(); +} + diff --git a/arch/arm/mach-omap2/board-rx51-video.c b/arch/arm/mach-omap2/board-rx51-video.c new file mode 100644 index 00000000000..9cfebc5c745 --- /dev/null +++ b/arch/arm/mach-omap2/board-rx51-video.c @@ -0,0 +1,67 @@ +/* + * linux/arch/arm/mach-omap2/board-rx51-video.c + * + * Copyright (C) 2010 Nokia + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/spi/spi.h> +#include <linux/mm.h> +#include <asm/mach-types.h> +#include <video/omapdss.h> +#include <video/omap-panel-data.h> + +#include <linux/platform_data/spi-omap2-mcspi.h> + +#include "soc.h" +#include "board-rx51.h" + +#include "mux.h" + +#define RX51_LCD_RESET_GPIO 90 + +#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) + +static struct connector_atv_platform_data rx51_tv_pdata = { + .name = "tv", + .source = "venc.0", + .connector_type = OMAP_DSS_VENC_TYPE_COMPOSITE, + .invert_polarity = false, +}; + +static struct platform_device rx51_tv_connector_device = { + .name = "connector-analog-tv", + .id = 0, + .dev.platform_data = &rx51_tv_pdata, +}; + +static struct omap_dss_board_info rx51_dss_board_info = { + .default_display_name = "lcd", +}; + +static int __init rx51_video_init(void) +{ + if (!machine_is_nokia_rx51()) + return 0; + + if (omap_mux_init_gpio(RX51_LCD_RESET_GPIO, OMAP_PIN_OUTPUT)) { + pr_err("%s cannot configure MUX for LCD RESET\n", __func__); + return 0; + } + + omap_display_init(&rx51_dss_board_info); + + platform_device_register(&rx51_tv_connector_device); + + return 0; +} + +omap_subsys_initcall(rx51_video_init); +#endif /* defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) */ diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c new file mode 100644 index 00000000000..db168c9627a --- /dev/null +++ b/arch/arm/mach-omap2/board-rx51.c @@ -0,0 +1,142 @@ +/* + * Board support file for Nokia N900 (aka RX-51). + * + * Copyright (C) 2007, 2008 Nokia + * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg> + * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/gpio.h> +#include <linux/leds.h> +#include <linux/usb/phy.h> +#include <linux/usb/musb.h> +#include <linux/platform_data/spi-omap2-mcspi.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <linux/omap-dma.h> + +#include "common.h" +#include "mux.h" +#include "gpmc.h" +#include "pm.h" +#include "soc.h" +#include "sdram-nokia.h" +#include "omap-secure.h" + +#define RX51_GPIO_SLEEP_IND 162 + +static struct gpio_led gpio_leds[] = { + { + .name = "sleep_ind", + .gpio = RX51_GPIO_SLEEP_IND, + }, +}; + +static struct gpio_led_platform_data gpio_led_info = { + .leds = gpio_leds, + .num_leds = ARRAY_SIZE(gpio_leds), +}; + +static struct platform_device leds_gpio = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &gpio_led_info, + }, +}; + +/* + * cpuidle C-states definition for rx51. + * + * The 'exit_latency' field is the sum of sleep + * and wake-up latencies. + + --------------------------------------------- + | state | exit_latency | target_residency | + --------------------------------------------- + | C1 | 110 + 162 | 5 | + | C2 | 106 + 180 | 309 | + | C3 | 107 + 410 | 46057 | + | C4 | 121 + 3374 | 46057 | + | C5 | 855 + 1146 | 46057 | + | C6 | 7580 + 4134 | 484329 | + | C7 | 7505 + 15274 | 484329 | + --------------------------------------------- + +*/ + +extern void __init rx51_peripherals_init(void); + +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#endif + +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 0, +}; + +static void __init rx51_init(void) +{ + struct omap_sdrc_params *sdrc_params; + + omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); + omap_serial_init(); + + sdrc_params = nokia_get_sdram_timings(); + omap_sdrc_init(sdrc_params, sdrc_params); + + usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); + usb_musb_init(&musb_board_data); + rx51_peripherals_init(); + + if (omap_type() == OMAP2_DEVICE_TYPE_SEC) { +#ifdef CONFIG_ARM_ERRATA_430973 + pr_info("RX-51: Enabling ARM errata 430973 workaround\n"); + /* set IBE to 1 */ + rx51_secure_update_aux_cr(BIT(6), 0); +#endif + } + + /* Ensure SDRC pins are mux'd for self-refresh */ + omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); + omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); + + platform_device_register(&leds_gpio); +} + +static void __init rx51_reserve(void) +{ + omap_reserve(); +} + +MACHINE_START(NOKIA_RX51, "Nokia RX-51 board") + /* Maintainer: Lauri Leukkunen <lauri.leukkunen@nokia.com> */ + .atag_offset = 0x100, + .reserve = rx51_reserve, + .map_io = omap3_map_io, + .init_early = omap3430_init_early, + .init_irq = omap3_init_irq, + .handle_irq = omap3_intc_handle_irq, + .init_machine = rx51_init, + .init_late = omap3430_init_late, + .init_time = omap3_sync32k_timer_init, + .restart = omap3xxx_restart, +MACHINE_END diff --git a/arch/arm/mach-omap2/board-rx51.h b/arch/arm/mach-omap2/board-rx51.h new file mode 100644 index 00000000000..b76f49e7eed --- /dev/null +++ b/arch/arm/mach-omap2/board-rx51.h @@ -0,0 +1,11 @@ +/* + * Defines for rx51 boards + */ + +#ifndef _OMAP_BOARD_RX51_H +#define _OMAP_BOARD_RX51_H + +extern void __init rx51_peripherals_init(void); +extern void __init rx51_video_mem_init(void); + +#endif diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c new file mode 100644 index 00000000000..6273c286e1d --- /dev/null +++ b/arch/arm/mach-omap2/board-ti8168evm.c @@ -0,0 +1,62 @@ +/* + * Code for TI8168/TI8148 EVM. + * + * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/usb/musb.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include "common.h" + +static struct omap_musb_board_data musb_board_data = { + .set_phy_power = ti81xx_musb_phy_power, + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 500, +}; + +static void __init ti81xx_evm_init(void) +{ + omap_serial_init(); + omap_sdrc_init(NULL, NULL); + usb_musb_init(&musb_board_data); +} + +MACHINE_START(TI8168EVM, "ti8168evm") + /* Maintainer: Texas Instruments */ + .atag_offset = 0x100, + .map_io = ti81xx_map_io, + .init_early = ti81xx_init_early, + .init_irq = ti81xx_init_irq, + .init_time = omap3_sync32k_timer_init, + .init_machine = ti81xx_evm_init, + .init_late = ti81xx_init_late, + .restart = omap44xx_restart, +MACHINE_END + +MACHINE_START(TI8148EVM, "ti8148evm") + /* Maintainer: Texas Instruments */ + .atag_offset = 0x100, + .map_io = ti81xx_map_io, + .init_early = ti81xx_init_early, + .init_irq = ti81xx_init_irq, + .init_time = omap3_sync32k_timer_init, + .init_machine = ti81xx_evm_init, + .init_late = ti81xx_init_late, + .restart = omap44xx_restart, +MACHINE_END diff --git a/arch/arm/mach-omap2/cclock2420_data.c b/arch/arm/mach-omap2/cclock2420_data.c new file mode 100644 index 00000000000..3662f4d4c8e --- /dev/null +++ b/arch/arm/mach-omap2/cclock2420_data.c @@ -0,0 +1,1931 @@ +/* + * OMAP2420 clock data + * + * Copyright (C) 2005-2012 Texas Instruments, Inc. + * Copyright (C) 2004-2011 Nokia Corporation + * + * Contacts: + * Richard Woodruff <r-woodruff2@ti.com> + * Paul Walmsley + * Updated to COMMON clk format by Rajendra Nayak <rnayak@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clk-private.h> +#include <linux/list.h> + +#include "soc.h" +#include "iomap.h" +#include "clock.h" +#include "clock2xxx.h" +#include "opp2xxx.h" +#include "cm2xxx.h" +#include "prm2xxx.h" +#include "prm-regbits-24xx.h" +#include "cm-regbits-24xx.h" +#include "sdrc.h" +#include "control.h" + +#define OMAP_CM_REGADDR OMAP2420_CM_REGADDR + +/* + * 2420 clock tree. + * + * NOTE:In many cases here we are assigning a 'default' parent. In + * many cases the parent is selectable. The set parent calls will + * also switch sources. + * + * Several sources are given initial rates which may be wrong, this will + * be fixed up in the init func. + * + * Things are broadly separated below by clock domains. It is + * noteworthy that most peripherals have dependencies on multiple clock + * domains. Many get their interface clocks from the L4 domain, but get + * functional clocks from fixed sources or other core domain derived + * clocks. + */ + +DEFINE_CLK_FIXED_RATE(alt_ck, CLK_IS_ROOT, 54000000, 0x0); + +DEFINE_CLK_FIXED_RATE(func_32k_ck, CLK_IS_ROOT, 32768, 0x0); + +DEFINE_CLK_FIXED_RATE(mcbsp_clks, CLK_IS_ROOT, 0x0, 0x0); + +static struct clk osc_ck; + +static const struct clk_ops osc_ck_ops = { + .recalc_rate = &omap2_osc_clk_recalc, +}; + +static struct clk_hw_omap osc_ck_hw = { + .hw = { + .clk = &osc_ck, + }, +}; + +static struct clk osc_ck = { + .name = "osc_ck", + .ops = &osc_ck_ops, + .hw = &osc_ck_hw.hw, + .flags = CLK_IS_ROOT, +}; + +DEFINE_CLK_FIXED_RATE(secure_32k_ck, CLK_IS_ROOT, 32768, 0x0); + +static struct clk sys_ck; + +static const char *sys_ck_parent_names[] = { + "osc_ck", +}; + +static const struct clk_ops sys_ck_ops = { + .init = &omap2_init_clk_clkdm, + .recalc_rate = &omap2xxx_sys_clk_recalc, +}; + +DEFINE_STRUCT_CLK_HW_OMAP(sys_ck, "wkup_clkdm"); +DEFINE_STRUCT_CLK(sys_ck, sys_ck_parent_names, sys_ck_ops); + +static struct dpll_data dpll_dd = { + .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), + .mult_mask = OMAP24XX_DPLL_MULT_MASK, + .div1_mask = OMAP24XX_DPLL_DIV_MASK, + .clk_bypass = &sys_ck, + .clk_ref = &sys_ck, + .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), + .enable_mask = OMAP24XX_EN_DPLL_MASK, + .max_multiplier = 1023, + .min_divider = 1, + .max_divider = 16, +}; + +static struct clk dpll_ck; + +static const char *dpll_ck_parent_names[] = { + "sys_ck", +}; + +static const struct clk_ops dpll_ck_ops = { + .init = &omap2_init_clk_clkdm, + .get_parent = &omap2_init_dpll_parent, + .recalc_rate = &omap2_dpllcore_recalc, + .round_rate = &omap2_dpll_round_rate, + .set_rate = &omap2_reprogram_dpllcore, +}; + +static struct clk_hw_omap dpll_ck_hw = { + .hw = { + .clk = &dpll_ck, + }, + .ops = &clkhwops_omap2xxx_dpll, + .dpll_data = &dpll_dd, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(dpll_ck, dpll_ck_parent_names, dpll_ck_ops); + +static struct clk core_ck; + +static const char *core_ck_parent_names[] = { + "dpll_ck", +}; + +static const struct clk_ops core_ck_ops = { + .init = &omap2_init_clk_clkdm, +}; + +DEFINE_STRUCT_CLK_HW_OMAP(core_ck, "wkup_clkdm"); +DEFINE_STRUCT_CLK(core_ck, core_ck_parent_names, core_ck_ops); + +DEFINE_CLK_DIVIDER(core_l3_ck, "core_ck", &core_ck, 0x0, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), + OMAP24XX_CLKSEL_L3_SHIFT, OMAP24XX_CLKSEL_L3_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +DEFINE_CLK_DIVIDER(l4_ck, "core_l3_ck", &core_l3_ck, 0x0, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), + OMAP24XX_CLKSEL_L4_SHIFT, OMAP24XX_CLKSEL_L4_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +static struct clk aes_ick; + +static const char *aes_ick_parent_names[] = { + "l4_ck", +}; + +static const struct clk_ops aes_ick_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, +}; + +static struct clk_hw_omap aes_ick_hw = { + .hw = { + .clk = &aes_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), + .enable_bit = OMAP24XX_EN_AES_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(aes_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk apll54_ck; + +static const struct clk_ops apll54_ck_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap2_clk_apll54_enable, + .disable = &omap2_clk_apll54_disable, + .recalc_rate = &omap2_clk_apll54_recalc, +}; + +static struct clk_hw_omap apll54_ck_hw = { + .hw = { + .clk = &apll54_ck, + }, + .ops = &clkhwops_apll54, + .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), + .enable_bit = OMAP24XX_EN_54M_PLL_SHIFT, + .flags = ENABLE_ON_INIT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(apll54_ck, dpll_ck_parent_names, apll54_ck_ops); + +static struct clk apll96_ck; + +static const struct clk_ops apll96_ck_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap2_clk_apll96_enable, + .disable = &omap2_clk_apll96_disable, + .recalc_rate = &omap2_clk_apll96_recalc, +}; + +static struct clk_hw_omap apll96_ck_hw = { + .hw = { + .clk = &apll96_ck, + }, + .ops = &clkhwops_apll96, + .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), + .enable_bit = OMAP24XX_EN_96M_PLL_SHIFT, + .flags = ENABLE_ON_INIT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(apll96_ck, dpll_ck_parent_names, apll96_ck_ops); + +static struct clk func_96m_ck; + +static const char *func_96m_ck_parent_names[] = { + "apll96_ck", +}; + +DEFINE_STRUCT_CLK_HW_OMAP(func_96m_ck, "wkup_clkdm"); +DEFINE_STRUCT_CLK(func_96m_ck, func_96m_ck_parent_names, core_ck_ops); + +static struct clk cam_fck; + +static const char *cam_fck_parent_names[] = { + "func_96m_ck", +}; + +static struct clk_hw_omap cam_fck_hw = { + .hw = { + .clk = &cam_fck, + }, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_CAM_SHIFT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(cam_fck, cam_fck_parent_names, aes_ick_ops); + +static struct clk cam_ick; + +static struct clk_hw_omap cam_ick_hw = { + .hw = { + .clk = &cam_ick, + }, + .ops = &clkhwops_iclk, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_CAM_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(cam_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk des_ick; + +static struct clk_hw_omap des_ick_hw = { + .hw = { + .clk = &des_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), + .enable_bit = OMAP24XX_EN_DES_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(des_ick, aes_ick_parent_names, aes_ick_ops); + +static const struct clksel_rate dsp_fck_core_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, + { .div = 2, .val = 2, .flags = RATE_IN_24XX }, + { .div = 3, .val = 3, .flags = RATE_IN_24XX }, + { .div = 4, .val = 4, .flags = RATE_IN_24XX }, + { .div = 6, .val = 6, .flags = RATE_IN_242X }, + { .div = 8, .val = 8, .flags = RATE_IN_242X }, + { .div = 12, .val = 12, .flags = RATE_IN_242X }, + { .div = 0 } +}; + +static const struct clksel dsp_fck_clksel[] = { + { .parent = &core_ck, .rates = dsp_fck_core_rates }, + { .parent = NULL }, +}; + +static const char *dsp_fck_parent_names[] = { + "core_ck", +}; + +static const struct clk_ops dsp_fck_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, + .recalc_rate = &omap2_clksel_recalc, + .set_rate = &omap2_clksel_set_rate, + .round_rate = &omap2_clksel_round_rate, +}; + +DEFINE_CLK_OMAP_MUX_GATE(dsp_fck, "dsp_clkdm", dsp_fck_clksel, + OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL), + OMAP24XX_CLKSEL_DSP_MASK, + OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN), + OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT, &clkhwops_wait, + dsp_fck_parent_names, dsp_fck_ops); + +static const struct clksel dsp_ick_clksel[] = { + { .parent = &dsp_fck, .rates = dsp_ick_rates }, + { .parent = NULL }, +}; + +static const char *dsp_ick_parent_names[] = { + "dsp_fck", +}; + +DEFINE_CLK_OMAP_MUX_GATE(dsp_ick, "dsp_clkdm", dsp_ick_clksel, + OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL), + OMAP24XX_CLKSEL_DSP_IF_MASK, + OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_ICLKEN), + OMAP2420_EN_DSP_IPI_SHIFT, &clkhwops_iclk_wait, + dsp_ick_parent_names, dsp_fck_ops); + +static const struct clksel_rate dss1_fck_sys_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel_rate dss1_fck_core_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, + { .div = 2, .val = 2, .flags = RATE_IN_24XX }, + { .div = 3, .val = 3, .flags = RATE_IN_24XX }, + { .div = 4, .val = 4, .flags = RATE_IN_24XX }, + { .div = 5, .val = 5, .flags = RATE_IN_24XX }, + { .div = 6, .val = 6, .flags = RATE_IN_24XX }, + { .div = 8, .val = 8, .flags = RATE_IN_24XX }, + { .div = 9, .val = 9, .flags = RATE_IN_24XX }, + { .div = 12, .val = 12, .flags = RATE_IN_24XX }, + { .div = 16, .val = 16, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel dss1_fck_clksel[] = { + { .parent = &sys_ck, .rates = dss1_fck_sys_rates }, + { .parent = &core_ck, .rates = dss1_fck_core_rates }, + { .parent = NULL }, +}; + +static const char *dss1_fck_parent_names[] = { + "sys_ck", "core_ck", +}; + +static struct clk dss1_fck; + +static const struct clk_ops dss1_fck_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, + .recalc_rate = &omap2_clksel_recalc, + .get_parent = &omap2_clksel_find_parent_index, + .set_parent = &omap2_clksel_set_parent, +}; + +DEFINE_CLK_OMAP_MUX_GATE(dss1_fck, "dss_clkdm", dss1_fck_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), + OMAP24XX_CLKSEL_DSS1_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_DSS1_SHIFT, NULL, + dss1_fck_parent_names, dss1_fck_ops); + +static const struct clksel_rate dss2_fck_sys_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel_rate dss2_fck_48m_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel_rate func_48m_apll96_rates[] = { + { .div = 2, .val = 0, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel_rate func_48m_alt_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel func_48m_clksel[] = { + { .parent = &apll96_ck, .rates = func_48m_apll96_rates }, + { .parent = &alt_ck, .rates = func_48m_alt_rates }, + { .parent = NULL }, +}; + +static const char *func_48m_ck_parent_names[] = { + "apll96_ck", "alt_ck", +}; + +static struct clk func_48m_ck; + +static const struct clk_ops func_48m_ck_ops = { + .init = &omap2_init_clk_clkdm, + .recalc_rate = &omap2_clksel_recalc, + .set_rate = &omap2_clksel_set_rate, + .round_rate = &omap2_clksel_round_rate, + .get_parent = &omap2_clksel_find_parent_index, + .set_parent = &omap2_clksel_set_parent, +}; + +static struct clk_hw_omap func_48m_ck_hw = { + .hw = { + .clk = &func_48m_ck, + }, + .clksel = func_48m_clksel, + .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), + .clksel_mask = OMAP24XX_48M_SOURCE_MASK, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(func_48m_ck, func_48m_ck_parent_names, func_48m_ck_ops); + +static const struct clksel dss2_fck_clksel[] = { + { .parent = &sys_ck, .rates = dss2_fck_sys_rates }, + { .parent = &func_48m_ck, .rates = dss2_fck_48m_rates }, + { .parent = NULL }, +}; + +static const char *dss2_fck_parent_names[] = { + "sys_ck", "func_48m_ck", +}; + +DEFINE_CLK_OMAP_MUX_GATE(dss2_fck, "dss_clkdm", dss2_fck_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), + OMAP24XX_CLKSEL_DSS2_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_DSS2_SHIFT, NULL, + dss2_fck_parent_names, dss1_fck_ops); + +static const char *func_54m_ck_parent_names[] = { + "apll54_ck", "alt_ck", +}; + +DEFINE_CLK_MUX(func_54m_ck, func_54m_ck_parent_names, NULL, 0x0, + OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), + OMAP24XX_54M_SOURCE_SHIFT, OMAP24XX_54M_SOURCE_WIDTH, + 0x0, NULL); + +static struct clk dss_54m_fck; + +static const char *dss_54m_fck_parent_names[] = { + "func_54m_ck", +}; + +static struct clk_hw_omap dss_54m_fck_hw = { + .hw = { + .clk = &dss_54m_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_TV_SHIFT, + .clkdm_name = "dss_clkdm", +}; + +DEFINE_STRUCT_CLK(dss_54m_fck, dss_54m_fck_parent_names, aes_ick_ops); + +static struct clk dss_ick; + +static struct clk_hw_omap dss_ick_hw = { + .hw = { + .clk = &dss_ick, + }, + .ops = &clkhwops_iclk, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_DSS1_SHIFT, + .clkdm_name = "dss_clkdm", +}; + +DEFINE_STRUCT_CLK(dss_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk eac_fck; + +static struct clk_hw_omap eac_fck_hw = { + .hw = { + .clk = &eac_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP2420_EN_EAC_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(eac_fck, cam_fck_parent_names, aes_ick_ops); + +static struct clk eac_ick; + +static struct clk_hw_omap eac_ick_hw = { + .hw = { + .clk = &eac_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP2420_EN_EAC_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(eac_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk emul_ck; + +static struct clk_hw_omap emul_ck_hw = { + .hw = { + .clk = &emul_ck, + }, + .enable_reg = OMAP2420_PRCM_CLKEMUL_CTRL, + .enable_bit = OMAP24XX_EMULATION_EN_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(emul_ck, dss_54m_fck_parent_names, aes_ick_ops); + +DEFINE_CLK_FIXED_FACTOR(func_12m_ck, "func_48m_ck", &func_48m_ck, 0x0, 1, 4); + +static struct clk fac_fck; + +static const char *fac_fck_parent_names[] = { + "func_12m_ck", +}; + +static struct clk_hw_omap fac_fck_hw = { + .hw = { + .clk = &fac_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_FAC_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(fac_fck, fac_fck_parent_names, aes_ick_ops); + +static struct clk fac_ick; + +static struct clk_hw_omap fac_ick_hw = { + .hw = { + .clk = &fac_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_FAC_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(fac_ick, aes_ick_parent_names, aes_ick_ops); + +static const struct clksel gfx_fck_clksel[] = { + { .parent = &core_l3_ck, .rates = gfx_l3_rates }, + { .parent = NULL }, +}; + +static const char *gfx_2d_fck_parent_names[] = { + "core_l3_ck", +}; + +DEFINE_CLK_OMAP_MUX_GATE(gfx_2d_fck, "gfx_clkdm", gfx_fck_clksel, + OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL), + OMAP_CLKSEL_GFX_MASK, + OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), + OMAP24XX_EN_2D_SHIFT, &clkhwops_wait, + gfx_2d_fck_parent_names, dsp_fck_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gfx_3d_fck, "gfx_clkdm", gfx_fck_clksel, + OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL), + OMAP_CLKSEL_GFX_MASK, + OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), + OMAP24XX_EN_3D_SHIFT, &clkhwops_wait, + gfx_2d_fck_parent_names, dsp_fck_ops); + +static struct clk gfx_ick; + +static const char *gfx_ick_parent_names[] = { + "core_l3_ck", +}; + +static struct clk_hw_omap gfx_ick_hw = { + .hw = { + .clk = &gfx_ick, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN), + .enable_bit = OMAP_EN_GFX_SHIFT, + .clkdm_name = "gfx_clkdm", +}; + +DEFINE_STRUCT_CLK(gfx_ick, gfx_ick_parent_names, aes_ick_ops); + +static struct clk gpios_fck; + +static const char *gpios_fck_parent_names[] = { + "func_32k_ck", +}; + +static struct clk_hw_omap gpios_fck_hw = { + .hw = { + .clk = &gpios_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), + .enable_bit = OMAP24XX_EN_GPIOS_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(gpios_fck, gpios_fck_parent_names, aes_ick_ops); + +static struct clk gpios_ick; + +static const char *gpios_ick_parent_names[] = { + "sys_ck", +}; + +static struct clk_hw_omap gpios_ick_hw = { + .hw = { + .clk = &gpios_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP24XX_EN_GPIOS_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(gpios_ick, gpios_ick_parent_names, aes_ick_ops); + +static struct clk gpmc_fck; + +static struct clk_hw_omap gpmc_fck_hw = { + .hw = { + .clk = &gpmc_fck, + }, + .ops = &clkhwops_iclk, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), + .enable_bit = OMAP24XX_AUTO_GPMC_SHIFT, + .flags = ENABLE_ON_INIT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(gpmc_fck, gfx_ick_parent_names, core_ck_ops); + +static const struct clksel_rate gpt_alt_rates[] = { + { .div = 1, .val = 2, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel omap24xx_gpt_clksel[] = { + { .parent = &func_32k_ck, .rates = gpt_32k_rates }, + { .parent = &sys_ck, .rates = gpt_sys_rates }, + { .parent = &alt_ck, .rates = gpt_alt_rates }, + { .parent = NULL }, +}; + +static const char *gpt10_fck_parent_names[] = { + "func_32k_ck", "sys_ck", "alt_ck", +}; + +DEFINE_CLK_OMAP_MUX_GATE(gpt10_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT10_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT10_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt10_ick; + +static struct clk_hw_omap gpt10_ick_hw = { + .hw = { + .clk = &gpt10_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT10_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt10_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt11_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT11_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT11_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt11_ick; + +static struct clk_hw_omap gpt11_ick_hw = { + .hw = { + .clk = &gpt11_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT11_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt11_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt12_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT12_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT12_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt12_ick; + +static struct clk_hw_omap gpt12_ick_hw = { + .hw = { + .clk = &gpt12_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT12_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt12_ick, aes_ick_parent_names, aes_ick_ops); + +static const struct clk_ops gpt1_fck_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, + .recalc_rate = &omap2_clksel_recalc, + .set_rate = &omap2_clksel_set_rate, + .round_rate = &omap2_clksel_round_rate, + .get_parent = &omap2_clksel_find_parent_index, + .set_parent = &omap2_clksel_set_parent, +}; + +DEFINE_CLK_OMAP_MUX_GATE(gpt1_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL1), + OMAP24XX_CLKSEL_GPT1_MASK, + OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), + OMAP24XX_EN_GPT1_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, gpt1_fck_ops); + +static struct clk gpt1_ick; + +static struct clk_hw_omap gpt1_ick_hw = { + .hw = { + .clk = &gpt1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP24XX_EN_GPT1_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt1_ick, gpios_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt2_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT2_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT2_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt2_ick; + +static struct clk_hw_omap gpt2_ick_hw = { + .hw = { + .clk = &gpt2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt2_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt3_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT3_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT3_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt3_ick; + +static struct clk_hw_omap gpt3_ick_hw = { + .hw = { + .clk = &gpt3_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT3_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt3_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt4_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT4_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT4_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt4_ick; + +static struct clk_hw_omap gpt4_ick_hw = { + .hw = { + .clk = &gpt4_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT4_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt4_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt5_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT5_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT5_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt5_ick; + +static struct clk_hw_omap gpt5_ick_hw = { + .hw = { + .clk = &gpt5_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT5_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt5_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt6_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT6_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT6_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt6_ick; + +static struct clk_hw_omap gpt6_ick_hw = { + .hw = { + .clk = &gpt6_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT6_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt6_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt7_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT7_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT7_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt7_ick; + +static struct clk_hw_omap gpt7_ick_hw = { + .hw = { + .clk = &gpt7_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT7_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt7_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt8_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT8_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT8_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt8_ick; + +static struct clk_hw_omap gpt8_ick_hw = { + .hw = { + .clk = &gpt8_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT8_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt8_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt9_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT9_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT9_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt9_ick; + +static struct clk_hw_omap gpt9_ick_hw = { + .hw = { + .clk = &gpt9_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT9_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt9_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk hdq_fck; + +static struct clk_hw_omap hdq_fck_hw = { + .hw = { + .clk = &hdq_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_HDQ_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(hdq_fck, fac_fck_parent_names, aes_ick_ops); + +static struct clk hdq_ick; + +static struct clk_hw_omap hdq_ick_hw = { + .hw = { + .clk = &hdq_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_HDQ_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(hdq_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk i2c1_fck; + +static struct clk_hw_omap i2c1_fck_hw = { + .hw = { + .clk = &i2c1_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP2420_EN_I2C1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(i2c1_fck, fac_fck_parent_names, aes_ick_ops); + +static struct clk i2c1_ick; + +static struct clk_hw_omap i2c1_ick_hw = { + .hw = { + .clk = &i2c1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP2420_EN_I2C1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(i2c1_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk i2c2_fck; + +static struct clk_hw_omap i2c2_fck_hw = { + .hw = { + .clk = &i2c2_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP2420_EN_I2C2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(i2c2_fck, fac_fck_parent_names, aes_ick_ops); + +static struct clk i2c2_ick; + +static struct clk_hw_omap i2c2_ick_hw = { + .hw = { + .clk = &i2c2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP2420_EN_I2C2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(i2c2_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(iva1_ifck, "iva1_clkdm", dsp_fck_clksel, + OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL), + OMAP2420_CLKSEL_IVA_MASK, + OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN), + OMAP2420_EN_IVA_COP_SHIFT, &clkhwops_wait, + dsp_fck_parent_names, dsp_fck_ops); + +static struct clk iva1_mpu_int_ifck; + +static const char *iva1_mpu_int_ifck_parent_names[] = { + "iva1_ifck", +}; + +static const struct clk_ops iva1_mpu_int_ifck_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, + .recalc_rate = &omap_fixed_divisor_recalc, +}; + +static struct clk_hw_omap iva1_mpu_int_ifck_hw = { + .hw = { + .clk = &iva1_mpu_int_ifck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN), + .enable_bit = OMAP2420_EN_IVA_MPU_SHIFT, + .clkdm_name = "iva1_clkdm", + .fixed_div = 2, +}; + +DEFINE_STRUCT_CLK(iva1_mpu_int_ifck, iva1_mpu_int_ifck_parent_names, + iva1_mpu_int_ifck_ops); + +static struct clk mailboxes_ick; + +static struct clk_hw_omap mailboxes_ick_hw = { + .hw = { + .clk = &mailboxes_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_MAILBOXES_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mailboxes_ick, aes_ick_parent_names, aes_ick_ops); + +static const struct clksel_rate common_mcbsp_96m_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel_rate common_mcbsp_mcbsp_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel mcbsp_fck_clksel[] = { + { .parent = &func_96m_ck, .rates = common_mcbsp_96m_rates }, + { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates }, + { .parent = NULL }, +}; + +static const char *mcbsp1_fck_parent_names[] = { + "func_96m_ck", "mcbsp_clks", +}; + +DEFINE_CLK_OMAP_MUX_GATE(mcbsp1_fck, "core_l4_clkdm", mcbsp_fck_clksel, + OMAP242X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0), + OMAP2_MCBSP1_CLKS_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_MCBSP1_SHIFT, &clkhwops_wait, + mcbsp1_fck_parent_names, dss1_fck_ops); + +static struct clk mcbsp1_ick; + +static struct clk_hw_omap mcbsp1_ick_hw = { + .hw = { + .clk = &mcbsp1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_MCBSP1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcbsp1_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(mcbsp2_fck, "core_l4_clkdm", mcbsp_fck_clksel, + OMAP242X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0), + OMAP2_MCBSP2_CLKS_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_MCBSP2_SHIFT, &clkhwops_wait, + mcbsp1_fck_parent_names, dss1_fck_ops); + +static struct clk mcbsp2_ick; + +static struct clk_hw_omap mcbsp2_ick_hw = { + .hw = { + .clk = &mcbsp2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_MCBSP2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcbsp2_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk mcspi1_fck; + +static const char *mcspi1_fck_parent_names[] = { + "func_48m_ck", +}; + +static struct clk_hw_omap mcspi1_fck_hw = { + .hw = { + .clk = &mcspi1_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_MCSPI1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcspi1_fck, mcspi1_fck_parent_names, aes_ick_ops); + +static struct clk mcspi1_ick; + +static struct clk_hw_omap mcspi1_ick_hw = { + .hw = { + .clk = &mcspi1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_MCSPI1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcspi1_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk mcspi2_fck; + +static struct clk_hw_omap mcspi2_fck_hw = { + .hw = { + .clk = &mcspi2_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_MCSPI2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcspi2_fck, mcspi1_fck_parent_names, aes_ick_ops); + +static struct clk mcspi2_ick; + +static struct clk_hw_omap mcspi2_ick_hw = { + .hw = { + .clk = &mcspi2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_MCSPI2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcspi2_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk mmc_fck; + +static struct clk_hw_omap mmc_fck_hw = { + .hw = { + .clk = &mmc_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP2420_EN_MMC_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mmc_fck, cam_fck_parent_names, aes_ick_ops); + +static struct clk mmc_ick; + +static struct clk_hw_omap mmc_ick_hw = { + .hw = { + .clk = &mmc_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP2420_EN_MMC_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mmc_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_DIVIDER(mpu_ck, "core_ck", &core_ck, 0x0, + OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL), + OMAP24XX_CLKSEL_MPU_SHIFT, OMAP24XX_CLKSEL_MPU_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +static struct clk mpu_wdt_fck; + +static struct clk_hw_omap mpu_wdt_fck_hw = { + .hw = { + .clk = &mpu_wdt_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), + .enable_bit = OMAP24XX_EN_MPU_WDT_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(mpu_wdt_fck, gpios_fck_parent_names, aes_ick_ops); + +static struct clk mpu_wdt_ick; + +static struct clk_hw_omap mpu_wdt_ick_hw = { + .hw = { + .clk = &mpu_wdt_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP24XX_EN_MPU_WDT_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(mpu_wdt_ick, gpios_ick_parent_names, aes_ick_ops); + +static struct clk mspro_fck; + +static struct clk_hw_omap mspro_fck_hw = { + .hw = { + .clk = &mspro_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_MSPRO_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mspro_fck, cam_fck_parent_names, aes_ick_ops); + +static struct clk mspro_ick; + +static struct clk_hw_omap mspro_ick_hw = { + .hw = { + .clk = &mspro_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_MSPRO_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mspro_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk omapctrl_ick; + +static struct clk_hw_omap omapctrl_ick_hw = { + .hw = { + .clk = &omapctrl_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP24XX_EN_OMAPCTRL_SHIFT, + .flags = ENABLE_ON_INIT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(omapctrl_ick, gpios_ick_parent_names, aes_ick_ops); + +static struct clk pka_ick; + +static struct clk_hw_omap pka_ick_hw = { + .hw = { + .clk = &pka_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), + .enable_bit = OMAP24XX_EN_PKA_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(pka_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk rng_ick; + +static struct clk_hw_omap rng_ick_hw = { + .hw = { + .clk = &rng_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), + .enable_bit = OMAP24XX_EN_RNG_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(rng_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk sdma_fck; + +DEFINE_STRUCT_CLK_HW_OMAP(sdma_fck, "core_l3_clkdm"); +DEFINE_STRUCT_CLK(sdma_fck, gfx_ick_parent_names, core_ck_ops); + +static struct clk sdma_ick; + +static struct clk_hw_omap sdma_ick_hw = { + .hw = { + .clk = &sdma_ick, + }, + .ops = &clkhwops_iclk, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), + .enable_bit = OMAP24XX_AUTO_SDMA_SHIFT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(sdma_ick, gfx_ick_parent_names, core_ck_ops); + +static struct clk sdrc_ick; + +static struct clk_hw_omap sdrc_ick_hw = { + .hw = { + .clk = &sdrc_ick, + }, + .ops = &clkhwops_iclk, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), + .enable_bit = OMAP24XX_AUTO_SDRC_SHIFT, + .flags = ENABLE_ON_INIT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(sdrc_ick, gfx_ick_parent_names, core_ck_ops); + +static struct clk sha_ick; + +static struct clk_hw_omap sha_ick_hw = { + .hw = { + .clk = &sha_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), + .enable_bit = OMAP24XX_EN_SHA_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(sha_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk ssi_l4_ick; + +static struct clk_hw_omap ssi_l4_ick_hw = { + .hw = { + .clk = &ssi_l4_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP24XX_EN_SSI_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(ssi_l4_ick, aes_ick_parent_names, aes_ick_ops); + +static const struct clksel_rate ssi_ssr_sst_fck_core_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, + { .div = 2, .val = 2, .flags = RATE_IN_24XX }, + { .div = 3, .val = 3, .flags = RATE_IN_24XX }, + { .div = 4, .val = 4, .flags = RATE_IN_24XX }, + { .div = 6, .val = 6, .flags = RATE_IN_242X }, + { .div = 8, .val = 8, .flags = RATE_IN_242X }, + { .div = 0 } +}; + +static const struct clksel ssi_ssr_sst_fck_clksel[] = { + { .parent = &core_ck, .rates = ssi_ssr_sst_fck_core_rates }, + { .parent = NULL }, +}; + +static const char *ssi_ssr_sst_fck_parent_names[] = { + "core_ck", +}; + +DEFINE_CLK_OMAP_MUX_GATE(ssi_ssr_sst_fck, "core_l3_clkdm", + ssi_ssr_sst_fck_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), + OMAP24XX_CLKSEL_SSI_MASK, + OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), + OMAP24XX_EN_SSI_SHIFT, &clkhwops_wait, + ssi_ssr_sst_fck_parent_names, dsp_fck_ops); + +static struct clk sync_32k_ick; + +static struct clk_hw_omap sync_32k_ick_hw = { + .hw = { + .clk = &sync_32k_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP24XX_EN_32KSYNC_SHIFT, + .flags = ENABLE_ON_INIT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(sync_32k_ick, gpios_ick_parent_names, aes_ick_ops); + +static const struct clksel_rate common_clkout_src_core_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel_rate common_clkout_src_sys_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel_rate common_clkout_src_96m_rates[] = { + { .div = 1, .val = 2, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel_rate common_clkout_src_54m_rates[] = { + { .div = 1, .val = 3, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel common_clkout_src_clksel[] = { + { .parent = &core_ck, .rates = common_clkout_src_core_rates }, + { .parent = &sys_ck, .rates = common_clkout_src_sys_rates }, + { .parent = &func_96m_ck, .rates = common_clkout_src_96m_rates }, + { .parent = &func_54m_ck, .rates = common_clkout_src_54m_rates }, + { .parent = NULL }, +}; + +static const char *sys_clkout_src_parent_names[] = { + "core_ck", "sys_ck", "func_96m_ck", "func_54m_ck", +}; + +DEFINE_CLK_OMAP_MUX_GATE(sys_clkout_src, "wkup_clkdm", common_clkout_src_clksel, + OMAP2420_PRCM_CLKOUT_CTRL, OMAP24XX_CLKOUT_SOURCE_MASK, + OMAP2420_PRCM_CLKOUT_CTRL, OMAP24XX_CLKOUT_EN_SHIFT, + NULL, sys_clkout_src_parent_names, gpt1_fck_ops); + +DEFINE_CLK_DIVIDER(sys_clkout, "sys_clkout_src", &sys_clkout_src, 0x0, + OMAP2420_PRCM_CLKOUT_CTRL, OMAP24XX_CLKOUT_DIV_SHIFT, + OMAP24XX_CLKOUT_DIV_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL); + +DEFINE_CLK_OMAP_MUX_GATE(sys_clkout2_src, "wkup_clkdm", + common_clkout_src_clksel, OMAP2420_PRCM_CLKOUT_CTRL, + OMAP2420_CLKOUT2_SOURCE_MASK, + OMAP2420_PRCM_CLKOUT_CTRL, OMAP2420_CLKOUT2_EN_SHIFT, + NULL, sys_clkout_src_parent_names, gpt1_fck_ops); + +DEFINE_CLK_DIVIDER(sys_clkout2, "sys_clkout2_src", &sys_clkout2_src, 0x0, + OMAP2420_PRCM_CLKOUT_CTRL, OMAP2420_CLKOUT2_DIV_SHIFT, + OMAP2420_CLKOUT2_DIV_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL); + +static struct clk uart1_fck; + +static struct clk_hw_omap uart1_fck_hw = { + .hw = { + .clk = &uart1_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_UART1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(uart1_fck, mcspi1_fck_parent_names, aes_ick_ops); + +static struct clk uart1_ick; + +static struct clk_hw_omap uart1_ick_hw = { + .hw = { + .clk = &uart1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_UART1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(uart1_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk uart2_fck; + +static struct clk_hw_omap uart2_fck_hw = { + .hw = { + .clk = &uart2_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_UART2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(uart2_fck, mcspi1_fck_parent_names, aes_ick_ops); + +static struct clk uart2_ick; + +static struct clk_hw_omap uart2_ick_hw = { + .hw = { + .clk = &uart2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_UART2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(uart2_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk uart3_fck; + +static struct clk_hw_omap uart3_fck_hw = { + .hw = { + .clk = &uart3_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), + .enable_bit = OMAP24XX_EN_UART3_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(uart3_fck, mcspi1_fck_parent_names, aes_ick_ops); + +static struct clk uart3_ick; + +static struct clk_hw_omap uart3_ick_hw = { + .hw = { + .clk = &uart3_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP24XX_EN_UART3_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(uart3_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk usb_fck; + +static struct clk_hw_omap usb_fck_hw = { + .hw = { + .clk = &usb_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), + .enable_bit = OMAP24XX_EN_USB_SHIFT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(usb_fck, mcspi1_fck_parent_names, aes_ick_ops); + +static const struct clksel_rate usb_l4_ick_core_l3_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, + { .div = 2, .val = 2, .flags = RATE_IN_24XX }, + { .div = 4, .val = 4, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel usb_l4_ick_clksel[] = { + { .parent = &core_l3_ck, .rates = usb_l4_ick_core_l3_rates }, + { .parent = NULL }, +}; + +static const char *usb_l4_ick_parent_names[] = { + "core_l3_ck", +}; + +DEFINE_CLK_OMAP_MUX_GATE(usb_l4_ick, "core_l4_clkdm", usb_l4_ick_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), + OMAP24XX_CLKSEL_USB_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + OMAP24XX_EN_USB_SHIFT, &clkhwops_iclk_wait, + usb_l4_ick_parent_names, dsp_fck_ops); + +static struct clk virt_prcm_set; + +static const char *virt_prcm_set_parent_names[] = { + "mpu_ck", +}; + +static const struct clk_ops virt_prcm_set_ops = { + .recalc_rate = &omap2_table_mpu_recalc, + .set_rate = &omap2_select_table_rate, + .round_rate = &omap2_round_to_table_rate, +}; + +DEFINE_STRUCT_CLK_HW_OMAP(virt_prcm_set, NULL); +DEFINE_STRUCT_CLK(virt_prcm_set, virt_prcm_set_parent_names, virt_prcm_set_ops); + +static const struct clksel_rate vlynq_fck_96m_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_242X }, + { .div = 0 } +}; + +static const struct clksel_rate vlynq_fck_core_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_242X }, + { .div = 2, .val = 2, .flags = RATE_IN_242X }, + { .div = 3, .val = 3, .flags = RATE_IN_242X }, + { .div = 4, .val = 4, .flags = RATE_IN_242X }, + { .div = 6, .val = 6, .flags = RATE_IN_242X }, + { .div = 8, .val = 8, .flags = RATE_IN_242X }, + { .div = 9, .val = 9, .flags = RATE_IN_242X }, + { .div = 12, .val = 12, .flags = RATE_IN_242X }, + { .div = 16, .val = 16, .flags = RATE_IN_242X }, + { .div = 18, .val = 18, .flags = RATE_IN_242X }, + { .div = 0 } +}; + +static const struct clksel vlynq_fck_clksel[] = { + { .parent = &func_96m_ck, .rates = vlynq_fck_96m_rates }, + { .parent = &core_ck, .rates = vlynq_fck_core_rates }, + { .parent = NULL }, +}; + +static const char *vlynq_fck_parent_names[] = { + "func_96m_ck", "core_ck", +}; + +DEFINE_CLK_OMAP_MUX_GATE(vlynq_fck, "core_l3_clkdm", vlynq_fck_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), + OMAP2420_CLKSEL_VLYNQ_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP2420_EN_VLYNQ_SHIFT, &clkhwops_wait, + vlynq_fck_parent_names, dss1_fck_ops); + +static struct clk vlynq_ick; + +static struct clk_hw_omap vlynq_ick_hw = { + .hw = { + .clk = &vlynq_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP2420_EN_VLYNQ_SHIFT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(vlynq_ick, gfx_ick_parent_names, aes_ick_ops); + +static struct clk wdt1_ick; + +static struct clk_hw_omap wdt1_ick_hw = { + .hw = { + .clk = &wdt1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP24XX_EN_WDT1_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(wdt1_ick, gpios_ick_parent_names, aes_ick_ops); + +static struct clk wdt3_fck; + +static struct clk_hw_omap wdt3_fck_hw = { + .hw = { + .clk = &wdt3_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP2420_EN_WDT3_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(wdt3_fck, gpios_fck_parent_names, aes_ick_ops); + +static struct clk wdt3_ick; + +static struct clk_hw_omap wdt3_ick_hw = { + .hw = { + .clk = &wdt3_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP2420_EN_WDT3_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(wdt3_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk wdt4_fck; + +static struct clk_hw_omap wdt4_fck_hw = { + .hw = { + .clk = &wdt4_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_WDT4_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(wdt4_fck, gpios_fck_parent_names, aes_ick_ops); + +static struct clk wdt4_ick; + +static struct clk_hw_omap wdt4_ick_hw = { + .hw = { + .clk = &wdt4_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_WDT4_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(wdt4_ick, aes_ick_parent_names, aes_ick_ops); + +/* + * clkdev integration + */ + +static struct omap_clk omap2420_clks[] = { + /* external root sources */ + CLK(NULL, "func_32k_ck", &func_32k_ck), + CLK(NULL, "secure_32k_ck", &secure_32k_ck), + CLK(NULL, "osc_ck", &osc_ck), + CLK(NULL, "sys_ck", &sys_ck), + CLK(NULL, "alt_ck", &alt_ck), + CLK(NULL, "mcbsp_clks", &mcbsp_clks), + /* internal analog sources */ + CLK(NULL, "dpll_ck", &dpll_ck), + CLK(NULL, "apll96_ck", &apll96_ck), + CLK(NULL, "apll54_ck", &apll54_ck), + /* internal prcm root sources */ + CLK(NULL, "func_54m_ck", &func_54m_ck), + CLK(NULL, "core_ck", &core_ck), + CLK(NULL, "func_96m_ck", &func_96m_ck), + CLK(NULL, "func_48m_ck", &func_48m_ck), + CLK(NULL, "func_12m_ck", &func_12m_ck), + CLK(NULL, "sys_clkout_src", &sys_clkout_src), + CLK(NULL, "sys_clkout", &sys_clkout), + CLK(NULL, "sys_clkout2_src", &sys_clkout2_src), + CLK(NULL, "sys_clkout2", &sys_clkout2), + CLK(NULL, "emul_ck", &emul_ck), + /* mpu domain clocks */ + CLK(NULL, "mpu_ck", &mpu_ck), + /* dsp domain clocks */ + CLK(NULL, "dsp_fck", &dsp_fck), + CLK(NULL, "dsp_ick", &dsp_ick), + CLK(NULL, "iva1_ifck", &iva1_ifck), + CLK(NULL, "iva1_mpu_int_ifck", &iva1_mpu_int_ifck), + /* GFX domain clocks */ + CLK(NULL, "gfx_3d_fck", &gfx_3d_fck), + CLK(NULL, "gfx_2d_fck", &gfx_2d_fck), + CLK(NULL, "gfx_ick", &gfx_ick), + /* DSS domain clocks */ + CLK("omapdss_dss", "ick", &dss_ick), + CLK(NULL, "dss_ick", &dss_ick), + CLK(NULL, "dss1_fck", &dss1_fck), + CLK(NULL, "dss2_fck", &dss2_fck), + CLK(NULL, "dss_54m_fck", &dss_54m_fck), + /* L3 domain clocks */ + CLK(NULL, "core_l3_ck", &core_l3_ck), + CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck), + CLK(NULL, "usb_l4_ick", &usb_l4_ick), + /* L4 domain clocks */ + CLK(NULL, "l4_ck", &l4_ck), + CLK(NULL, "ssi_l4_ick", &ssi_l4_ick), + /* virtual meta-group clock */ + CLK(NULL, "virt_prcm_set", &virt_prcm_set), + /* general l4 interface ck, multi-parent functional clk */ + CLK(NULL, "gpt1_ick", &gpt1_ick), + CLK(NULL, "gpt1_fck", &gpt1_fck), + CLK(NULL, "gpt2_ick", &gpt2_ick), + CLK(NULL, "gpt2_fck", &gpt2_fck), + CLK(NULL, "gpt3_ick", &gpt3_ick), + CLK(NULL, "gpt3_fck", &gpt3_fck), + CLK(NULL, "gpt4_ick", &gpt4_ick), + CLK(NULL, "gpt4_fck", &gpt4_fck), + CLK(NULL, "gpt5_ick", &gpt5_ick), + CLK(NULL, "gpt5_fck", &gpt5_fck), + CLK(NULL, "gpt6_ick", &gpt6_ick), + CLK(NULL, "gpt6_fck", &gpt6_fck), + CLK(NULL, "gpt7_ick", &gpt7_ick), + CLK(NULL, "gpt7_fck", &gpt7_fck), + CLK(NULL, "gpt8_ick", &gpt8_ick), + CLK(NULL, "gpt8_fck", &gpt8_fck), + CLK(NULL, "gpt9_ick", &gpt9_ick), + CLK(NULL, "gpt9_fck", &gpt9_fck), + CLK(NULL, "gpt10_ick", &gpt10_ick), + CLK(NULL, "gpt10_fck", &gpt10_fck), + CLK(NULL, "gpt11_ick", &gpt11_ick), + CLK(NULL, "gpt11_fck", &gpt11_fck), + CLK(NULL, "gpt12_ick", &gpt12_ick), + CLK(NULL, "gpt12_fck", &gpt12_fck), + CLK("omap-mcbsp.1", "ick", &mcbsp1_ick), + CLK(NULL, "mcbsp1_ick", &mcbsp1_ick), + CLK(NULL, "mcbsp1_fck", &mcbsp1_fck), + CLK("omap-mcbsp.2", "ick", &mcbsp2_ick), + CLK(NULL, "mcbsp2_ick", &mcbsp2_ick), + CLK(NULL, "mcbsp2_fck", &mcbsp2_fck), + CLK("omap2_mcspi.1", "ick", &mcspi1_ick), + CLK(NULL, "mcspi1_ick", &mcspi1_ick), + CLK(NULL, "mcspi1_fck", &mcspi1_fck), + CLK("omap2_mcspi.2", "ick", &mcspi2_ick), + CLK(NULL, "mcspi2_ick", &mcspi2_ick), + CLK(NULL, "mcspi2_fck", &mcspi2_fck), + CLK(NULL, "uart1_ick", &uart1_ick), + CLK(NULL, "uart1_fck", &uart1_fck), + CLK(NULL, "uart2_ick", &uart2_ick), + CLK(NULL, "uart2_fck", &uart2_fck), + CLK(NULL, "uart3_ick", &uart3_ick), + CLK(NULL, "uart3_fck", &uart3_fck), + CLK(NULL, "gpios_ick", &gpios_ick), + CLK(NULL, "gpios_fck", &gpios_fck), + CLK("omap_wdt", "ick", &mpu_wdt_ick), + CLK(NULL, "mpu_wdt_ick", &mpu_wdt_ick), + CLK(NULL, "mpu_wdt_fck", &mpu_wdt_fck), + CLK(NULL, "sync_32k_ick", &sync_32k_ick), + CLK(NULL, "wdt1_ick", &wdt1_ick), + CLK(NULL, "omapctrl_ick", &omapctrl_ick), + CLK("omap24xxcam", "fck", &cam_fck), + CLK(NULL, "cam_fck", &cam_fck), + CLK("omap24xxcam", "ick", &cam_ick), + CLK(NULL, "cam_ick", &cam_ick), + CLK(NULL, "mailboxes_ick", &mailboxes_ick), + CLK(NULL, "wdt4_ick", &wdt4_ick), + CLK(NULL, "wdt4_fck", &wdt4_fck), + CLK(NULL, "wdt3_ick", &wdt3_ick), + CLK(NULL, "wdt3_fck", &wdt3_fck), + CLK(NULL, "mspro_ick", &mspro_ick), + CLK(NULL, "mspro_fck", &mspro_fck), + CLK("mmci-omap.0", "ick", &mmc_ick), + CLK(NULL, "mmc_ick", &mmc_ick), + CLK("mmci-omap.0", "fck", &mmc_fck), + CLK(NULL, "mmc_fck", &mmc_fck), + CLK(NULL, "fac_ick", &fac_ick), + CLK(NULL, "fac_fck", &fac_fck), + CLK(NULL, "eac_ick", &eac_ick), + CLK(NULL, "eac_fck", &eac_fck), + CLK("omap_hdq.0", "ick", &hdq_ick), + CLK(NULL, "hdq_ick", &hdq_ick), + CLK("omap_hdq.0", "fck", &hdq_fck), + CLK(NULL, "hdq_fck", &hdq_fck), + CLK("omap_i2c.1", "ick", &i2c1_ick), + CLK(NULL, "i2c1_ick", &i2c1_ick), + CLK(NULL, "i2c1_fck", &i2c1_fck), + CLK("omap_i2c.2", "ick", &i2c2_ick), + CLK(NULL, "i2c2_ick", &i2c2_ick), + CLK(NULL, "i2c2_fck", &i2c2_fck), + CLK(NULL, "gpmc_fck", &gpmc_fck), + CLK(NULL, "sdma_fck", &sdma_fck), + CLK(NULL, "sdma_ick", &sdma_ick), + CLK(NULL, "sdrc_ick", &sdrc_ick), + CLK(NULL, "vlynq_ick", &vlynq_ick), + CLK(NULL, "vlynq_fck", &vlynq_fck), + CLK(NULL, "des_ick", &des_ick), + CLK("omap-sham", "ick", &sha_ick), + CLK(NULL, "sha_ick", &sha_ick), + CLK("omap_rng", "ick", &rng_ick), + CLK(NULL, "rng_ick", &rng_ick), + CLK("omap-aes", "ick", &aes_ick), + CLK(NULL, "aes_ick", &aes_ick), + CLK(NULL, "pka_ick", &pka_ick), + CLK(NULL, "usb_fck", &usb_fck), + CLK("musb-hdrc", "fck", &osc_ck), + CLK(NULL, "timer_32k_ck", &func_32k_ck), + CLK(NULL, "timer_sys_ck", &sys_ck), + CLK(NULL, "timer_ext_ck", &alt_ck), + CLK(NULL, "cpufreq_ck", &virt_prcm_set), +}; + + +static const char *enable_init_clks[] = { + "apll96_ck", + "apll54_ck", + "sync_32k_ick", + "omapctrl_ick", + "gpmc_fck", + "sdrc_ick", +}; + +/* + * init code + */ + +int __init omap2420_clk_init(void) +{ + prcm_clksrc_ctrl = OMAP2420_PRCM_CLKSRC_CTRL; + cpu_mask = RATE_IN_242X; + rate_table = omap2420_rate_table; + + omap2xxx_clkt_dpllcore_init(&dpll_ck_hw.hw); + + omap2xxx_clkt_vps_check_bootloader_rates(); + + omap_clocks_register(omap2420_clks, ARRAY_SIZE(omap2420_clks)); + + omap2xxx_clkt_vps_late_init(); + + omap2_clk_disable_autoidle_all(); + + omap2_clk_enable_init_clocks(enable_init_clks, + ARRAY_SIZE(enable_init_clks)); + + pr_info("Clocking rate (Crystal/DPLL/MPU): %ld.%01ld/%ld/%ld MHz\n", + (clk_get_rate(&sys_ck) / 1000000), + (clk_get_rate(&sys_ck) / 100000) % 10, + (clk_get_rate(&dpll_ck) / 1000000), + (clk_get_rate(&mpu_ck) / 1000000)); + + return 0; +} diff --git a/arch/arm/mach-omap2/cclock2430_data.c b/arch/arm/mach-omap2/cclock2430_data.c new file mode 100644 index 00000000000..5e4b037bb24 --- /dev/null +++ b/arch/arm/mach-omap2/cclock2430_data.c @@ -0,0 +1,2048 @@ +/* + * OMAP2430 clock data + * + * Copyright (C) 2005-2009, 2012 Texas Instruments, Inc. + * Copyright (C) 2004-2011 Nokia Corporation + * + * Contacts: + * Richard Woodruff <r-woodruff2@ti.com> + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/clk.h> +#include <linux/clk-private.h> +#include <linux/list.h> + +#include "soc.h" +#include "iomap.h" +#include "clock.h" +#include "clock2xxx.h" +#include "opp2xxx.h" +#include "cm2xxx.h" +#include "prm2xxx.h" +#include "prm-regbits-24xx.h" +#include "cm-regbits-24xx.h" +#include "sdrc.h" +#include "control.h" + +#define OMAP_CM_REGADDR OMAP2430_CM_REGADDR + +/* + * 2430 clock tree. + * + * NOTE:In many cases here we are assigning a 'default' parent. In + * many cases the parent is selectable. The set parent calls will + * also switch sources. + * + * Several sources are given initial rates which may be wrong, this will + * be fixed up in the init func. + * + * Things are broadly separated below by clock domains. It is + * noteworthy that most peripherals have dependencies on multiple clock + * domains. Many get their interface clocks from the L4 domain, but get + * functional clocks from fixed sources or other core domain derived + * clocks. + */ + +DEFINE_CLK_FIXED_RATE(alt_ck, CLK_IS_ROOT, 54000000, 0x0); + +DEFINE_CLK_FIXED_RATE(func_32k_ck, CLK_IS_ROOT, 32768, 0x0); + +DEFINE_CLK_FIXED_RATE(mcbsp_clks, CLK_IS_ROOT, 0x0, 0x0); + +static struct clk osc_ck; + +static const struct clk_ops osc_ck_ops = { + .enable = &omap2_enable_osc_ck, + .disable = omap2_disable_osc_ck, + .recalc_rate = &omap2_osc_clk_recalc, +}; + +static struct clk_hw_omap osc_ck_hw = { + .hw = { + .clk = &osc_ck, + }, +}; + +static struct clk osc_ck = { + .name = "osc_ck", + .ops = &osc_ck_ops, + .hw = &osc_ck_hw.hw, + .flags = CLK_IS_ROOT, +}; + +DEFINE_CLK_FIXED_RATE(secure_32k_ck, CLK_IS_ROOT, 32768, 0x0); + +static struct clk sys_ck; + +static const char *sys_ck_parent_names[] = { + "osc_ck", +}; + +static const struct clk_ops sys_ck_ops = { + .init = &omap2_init_clk_clkdm, + .recalc_rate = &omap2xxx_sys_clk_recalc, +}; + +DEFINE_STRUCT_CLK_HW_OMAP(sys_ck, "wkup_clkdm"); +DEFINE_STRUCT_CLK(sys_ck, sys_ck_parent_names, sys_ck_ops); + +static struct dpll_data dpll_dd = { + .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), + .mult_mask = OMAP24XX_DPLL_MULT_MASK, + .div1_mask = OMAP24XX_DPLL_DIV_MASK, + .clk_bypass = &sys_ck, + .clk_ref = &sys_ck, + .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), + .enable_mask = OMAP24XX_EN_DPLL_MASK, + .max_multiplier = 1023, + .min_divider = 1, + .max_divider = 16, +}; + +static struct clk dpll_ck; + +static const char *dpll_ck_parent_names[] = { + "sys_ck", +}; + +static const struct clk_ops dpll_ck_ops = { + .init = &omap2_init_clk_clkdm, + .get_parent = &omap2_init_dpll_parent, + .recalc_rate = &omap2_dpllcore_recalc, + .round_rate = &omap2_dpll_round_rate, + .set_rate = &omap2_reprogram_dpllcore, +}; + +static struct clk_hw_omap dpll_ck_hw = { + .hw = { + .clk = &dpll_ck, + }, + .ops = &clkhwops_omap2xxx_dpll, + .dpll_data = &dpll_dd, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(dpll_ck, dpll_ck_parent_names, dpll_ck_ops); + +static struct clk core_ck; + +static const char *core_ck_parent_names[] = { + "dpll_ck", +}; + +static const struct clk_ops core_ck_ops = { + .init = &omap2_init_clk_clkdm, +}; + +DEFINE_STRUCT_CLK_HW_OMAP(core_ck, "wkup_clkdm"); +DEFINE_STRUCT_CLK(core_ck, core_ck_parent_names, core_ck_ops); + +DEFINE_CLK_DIVIDER(core_l3_ck, "core_ck", &core_ck, 0x0, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), + OMAP24XX_CLKSEL_L3_SHIFT, OMAP24XX_CLKSEL_L3_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +DEFINE_CLK_DIVIDER(l4_ck, "core_l3_ck", &core_l3_ck, 0x0, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), + OMAP24XX_CLKSEL_L4_SHIFT, OMAP24XX_CLKSEL_L4_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +static struct clk aes_ick; + +static const char *aes_ick_parent_names[] = { + "l4_ck", +}; + +static const struct clk_ops aes_ick_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, +}; + +static struct clk_hw_omap aes_ick_hw = { + .hw = { + .clk = &aes_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), + .enable_bit = OMAP24XX_EN_AES_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(aes_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk apll54_ck; + +static const struct clk_ops apll54_ck_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap2_clk_apll54_enable, + .disable = &omap2_clk_apll54_disable, + .recalc_rate = &omap2_clk_apll54_recalc, +}; + +static struct clk_hw_omap apll54_ck_hw = { + .hw = { + .clk = &apll54_ck, + }, + .ops = &clkhwops_apll54, + .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), + .enable_bit = OMAP24XX_EN_54M_PLL_SHIFT, + .flags = ENABLE_ON_INIT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(apll54_ck, dpll_ck_parent_names, apll54_ck_ops); + +static struct clk apll96_ck; + +static const struct clk_ops apll96_ck_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap2_clk_apll96_enable, + .disable = &omap2_clk_apll96_disable, + .recalc_rate = &omap2_clk_apll96_recalc, +}; + +static struct clk_hw_omap apll96_ck_hw = { + .hw = { + .clk = &apll96_ck, + }, + .ops = &clkhwops_apll96, + .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), + .enable_bit = OMAP24XX_EN_96M_PLL_SHIFT, + .flags = ENABLE_ON_INIT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(apll96_ck, dpll_ck_parent_names, apll96_ck_ops); + +static const char *func_96m_ck_parent_names[] = { + "apll96_ck", "alt_ck", +}; + +DEFINE_CLK_MUX(func_96m_ck, func_96m_ck_parent_names, NULL, 0x0, + OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), OMAP2430_96M_SOURCE_SHIFT, + OMAP2430_96M_SOURCE_WIDTH, 0x0, NULL); + +static struct clk cam_fck; + +static const char *cam_fck_parent_names[] = { + "func_96m_ck", +}; + +static struct clk_hw_omap cam_fck_hw = { + .hw = { + .clk = &cam_fck, + }, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_CAM_SHIFT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(cam_fck, cam_fck_parent_names, aes_ick_ops); + +static struct clk cam_ick; + +static struct clk_hw_omap cam_ick_hw = { + .hw = { + .clk = &cam_ick, + }, + .ops = &clkhwops_iclk, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_CAM_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(cam_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk des_ick; + +static struct clk_hw_omap des_ick_hw = { + .hw = { + .clk = &des_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), + .enable_bit = OMAP24XX_EN_DES_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(des_ick, aes_ick_parent_names, aes_ick_ops); + +static const struct clksel_rate dsp_fck_core_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, + { .div = 2, .val = 2, .flags = RATE_IN_24XX }, + { .div = 3, .val = 3, .flags = RATE_IN_24XX }, + { .div = 4, .val = 4, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel dsp_fck_clksel[] = { + { .parent = &core_ck, .rates = dsp_fck_core_rates }, + { .parent = NULL }, +}; + +static const char *dsp_fck_parent_names[] = { + "core_ck", +}; + +static struct clk dsp_fck; + +static const struct clk_ops dsp_fck_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, + .recalc_rate = &omap2_clksel_recalc, + .set_rate = &omap2_clksel_set_rate, + .round_rate = &omap2_clksel_round_rate, +}; + +DEFINE_CLK_OMAP_MUX_GATE(dsp_fck, "dsp_clkdm", dsp_fck_clksel, + OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL), + OMAP24XX_CLKSEL_DSP_MASK, + OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN), + OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT, &clkhwops_wait, + dsp_fck_parent_names, dsp_fck_ops); + +static const struct clksel_rate dss1_fck_sys_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel_rate dss1_fck_core_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, + { .div = 2, .val = 2, .flags = RATE_IN_24XX }, + { .div = 3, .val = 3, .flags = RATE_IN_24XX }, + { .div = 4, .val = 4, .flags = RATE_IN_24XX }, + { .div = 5, .val = 5, .flags = RATE_IN_24XX }, + { .div = 6, .val = 6, .flags = RATE_IN_24XX }, + { .div = 8, .val = 8, .flags = RATE_IN_24XX }, + { .div = 9, .val = 9, .flags = RATE_IN_24XX }, + { .div = 12, .val = 12, .flags = RATE_IN_24XX }, + { .div = 16, .val = 16, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel dss1_fck_clksel[] = { + { .parent = &sys_ck, .rates = dss1_fck_sys_rates }, + { .parent = &core_ck, .rates = dss1_fck_core_rates }, + { .parent = NULL }, +}; + +static const char *dss1_fck_parent_names[] = { + "sys_ck", "core_ck", +}; + +static const struct clk_ops dss1_fck_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, + .recalc_rate = &omap2_clksel_recalc, + .get_parent = &omap2_clksel_find_parent_index, + .set_parent = &omap2_clksel_set_parent, +}; + +DEFINE_CLK_OMAP_MUX_GATE(dss1_fck, "dss_clkdm", dss1_fck_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), + OMAP24XX_CLKSEL_DSS1_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_DSS1_SHIFT, NULL, + dss1_fck_parent_names, dss1_fck_ops); + +static const struct clksel_rate dss2_fck_sys_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel_rate dss2_fck_48m_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel_rate func_48m_apll96_rates[] = { + { .div = 2, .val = 0, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel_rate func_48m_alt_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel func_48m_clksel[] = { + { .parent = &apll96_ck, .rates = func_48m_apll96_rates }, + { .parent = &alt_ck, .rates = func_48m_alt_rates }, + { .parent = NULL }, +}; + +static const char *func_48m_ck_parent_names[] = { + "apll96_ck", "alt_ck", +}; + +static struct clk func_48m_ck; + +static const struct clk_ops func_48m_ck_ops = { + .init = &omap2_init_clk_clkdm, + .recalc_rate = &omap2_clksel_recalc, + .set_rate = &omap2_clksel_set_rate, + .round_rate = &omap2_clksel_round_rate, + .get_parent = &omap2_clksel_find_parent_index, + .set_parent = &omap2_clksel_set_parent, +}; + +static struct clk_hw_omap func_48m_ck_hw = { + .hw = { + .clk = &func_48m_ck, + }, + .clksel = func_48m_clksel, + .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), + .clksel_mask = OMAP24XX_48M_SOURCE_MASK, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(func_48m_ck, func_48m_ck_parent_names, func_48m_ck_ops); + +static const struct clksel dss2_fck_clksel[] = { + { .parent = &sys_ck, .rates = dss2_fck_sys_rates }, + { .parent = &func_48m_ck, .rates = dss2_fck_48m_rates }, + { .parent = NULL }, +}; + +static const char *dss2_fck_parent_names[] = { + "sys_ck", "func_48m_ck", +}; + +DEFINE_CLK_OMAP_MUX_GATE(dss2_fck, "dss_clkdm", dss2_fck_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), + OMAP24XX_CLKSEL_DSS2_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_DSS2_SHIFT, NULL, + dss2_fck_parent_names, dss1_fck_ops); + +static const char *func_54m_ck_parent_names[] = { + "apll54_ck", "alt_ck", +}; + +DEFINE_CLK_MUX(func_54m_ck, func_54m_ck_parent_names, NULL, 0x0, + OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), + OMAP24XX_54M_SOURCE_SHIFT, OMAP24XX_54M_SOURCE_WIDTH, 0x0, NULL); + +static struct clk dss_54m_fck; + +static const char *dss_54m_fck_parent_names[] = { + "func_54m_ck", +}; + +static struct clk_hw_omap dss_54m_fck_hw = { + .hw = { + .clk = &dss_54m_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_TV_SHIFT, + .clkdm_name = "dss_clkdm", +}; + +DEFINE_STRUCT_CLK(dss_54m_fck, dss_54m_fck_parent_names, aes_ick_ops); + +static struct clk dss_ick; + +static struct clk_hw_omap dss_ick_hw = { + .hw = { + .clk = &dss_ick, + }, + .ops = &clkhwops_iclk, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_DSS1_SHIFT, + .clkdm_name = "dss_clkdm", +}; + +DEFINE_STRUCT_CLK(dss_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk emul_ck; + +static struct clk_hw_omap emul_ck_hw = { + .hw = { + .clk = &emul_ck, + }, + .enable_reg = OMAP2430_PRCM_CLKEMUL_CTRL, + .enable_bit = OMAP24XX_EMULATION_EN_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(emul_ck, dss_54m_fck_parent_names, aes_ick_ops); + +DEFINE_CLK_FIXED_FACTOR(func_12m_ck, "func_48m_ck", &func_48m_ck, 0x0, 1, 4); + +static struct clk fac_fck; + +static const char *fac_fck_parent_names[] = { + "func_12m_ck", +}; + +static struct clk_hw_omap fac_fck_hw = { + .hw = { + .clk = &fac_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_FAC_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(fac_fck, fac_fck_parent_names, aes_ick_ops); + +static struct clk fac_ick; + +static struct clk_hw_omap fac_ick_hw = { + .hw = { + .clk = &fac_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_FAC_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(fac_ick, aes_ick_parent_names, aes_ick_ops); + +static const struct clksel gfx_fck_clksel[] = { + { .parent = &core_l3_ck, .rates = gfx_l3_rates }, + { .parent = NULL }, +}; + +static const char *gfx_2d_fck_parent_names[] = { + "core_l3_ck", +}; + +DEFINE_CLK_OMAP_MUX_GATE(gfx_2d_fck, "gfx_clkdm", gfx_fck_clksel, + OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL), + OMAP_CLKSEL_GFX_MASK, + OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), + OMAP24XX_EN_2D_SHIFT, &clkhwops_wait, + gfx_2d_fck_parent_names, dsp_fck_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gfx_3d_fck, "gfx_clkdm", gfx_fck_clksel, + OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL), + OMAP_CLKSEL_GFX_MASK, + OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), + OMAP24XX_EN_3D_SHIFT, &clkhwops_wait, + gfx_2d_fck_parent_names, dsp_fck_ops); + +static struct clk gfx_ick; + +static const char *gfx_ick_parent_names[] = { + "core_l3_ck", +}; + +static struct clk_hw_omap gfx_ick_hw = { + .hw = { + .clk = &gfx_ick, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN), + .enable_bit = OMAP_EN_GFX_SHIFT, + .clkdm_name = "gfx_clkdm", +}; + +DEFINE_STRUCT_CLK(gfx_ick, gfx_ick_parent_names, aes_ick_ops); + +static struct clk gpio5_fck; + +static const char *gpio5_fck_parent_names[] = { + "func_32k_ck", +}; + +static struct clk_hw_omap gpio5_fck_hw = { + .hw = { + .clk = &gpio5_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), + .enable_bit = OMAP2430_EN_GPIO5_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpio5_fck, gpio5_fck_parent_names, aes_ick_ops); + +static struct clk gpio5_ick; + +static struct clk_hw_omap gpio5_ick_hw = { + .hw = { + .clk = &gpio5_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP2430_EN_GPIO5_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpio5_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk gpios_fck; + +static struct clk_hw_omap gpios_fck_hw = { + .hw = { + .clk = &gpios_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), + .enable_bit = OMAP24XX_EN_GPIOS_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(gpios_fck, gpio5_fck_parent_names, aes_ick_ops); + +static struct clk gpios_ick; + +static const char *gpios_ick_parent_names[] = { + "sys_ck", +}; + +static struct clk_hw_omap gpios_ick_hw = { + .hw = { + .clk = &gpios_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP24XX_EN_GPIOS_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(gpios_ick, gpios_ick_parent_names, aes_ick_ops); + +static struct clk gpmc_fck; + +static struct clk_hw_omap gpmc_fck_hw = { + .hw = { + .clk = &gpmc_fck, + }, + .ops = &clkhwops_iclk, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), + .enable_bit = OMAP24XX_AUTO_GPMC_SHIFT, + .flags = ENABLE_ON_INIT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(gpmc_fck, gfx_ick_parent_names, core_ck_ops); + +static const struct clksel_rate gpt_alt_rates[] = { + { .div = 1, .val = 2, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel omap24xx_gpt_clksel[] = { + { .parent = &func_32k_ck, .rates = gpt_32k_rates }, + { .parent = &sys_ck, .rates = gpt_sys_rates }, + { .parent = &alt_ck, .rates = gpt_alt_rates }, + { .parent = NULL }, +}; + +static const char *gpt10_fck_parent_names[] = { + "func_32k_ck", "sys_ck", "alt_ck", +}; + +DEFINE_CLK_OMAP_MUX_GATE(gpt10_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT10_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT10_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt10_ick; + +static struct clk_hw_omap gpt10_ick_hw = { + .hw = { + .clk = &gpt10_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT10_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt10_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt11_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT11_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT11_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt11_ick; + +static struct clk_hw_omap gpt11_ick_hw = { + .hw = { + .clk = &gpt11_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT11_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt11_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt12_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT12_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT12_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt12_ick; + +static struct clk_hw_omap gpt12_ick_hw = { + .hw = { + .clk = &gpt12_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT12_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt12_ick, aes_ick_parent_names, aes_ick_ops); + +static const struct clk_ops gpt1_fck_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, + .recalc_rate = &omap2_clksel_recalc, + .set_rate = &omap2_clksel_set_rate, + .round_rate = &omap2_clksel_round_rate, + .get_parent = &omap2_clksel_find_parent_index, + .set_parent = &omap2_clksel_set_parent, +}; + +DEFINE_CLK_OMAP_MUX_GATE(gpt1_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL1), + OMAP24XX_CLKSEL_GPT1_MASK, + OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), + OMAP24XX_EN_GPT1_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, gpt1_fck_ops); + +static struct clk gpt1_ick; + +static struct clk_hw_omap gpt1_ick_hw = { + .hw = { + .clk = &gpt1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP24XX_EN_GPT1_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt1_ick, gpios_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt2_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT2_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT2_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt2_ick; + +static struct clk_hw_omap gpt2_ick_hw = { + .hw = { + .clk = &gpt2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt2_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt3_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT3_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT3_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt3_ick; + +static struct clk_hw_omap gpt3_ick_hw = { + .hw = { + .clk = &gpt3_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT3_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt3_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt4_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT4_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT4_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt4_ick; + +static struct clk_hw_omap gpt4_ick_hw = { + .hw = { + .clk = &gpt4_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT4_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt4_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt5_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT5_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT5_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt5_ick; + +static struct clk_hw_omap gpt5_ick_hw = { + .hw = { + .clk = &gpt5_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT5_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt5_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt6_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT6_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT6_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt6_ick; + +static struct clk_hw_omap gpt6_ick_hw = { + .hw = { + .clk = &gpt6_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT6_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt6_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt7_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT7_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT7_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt7_ick; + +static struct clk_hw_omap gpt7_ick_hw = { + .hw = { + .clk = &gpt7_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT7_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt7_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk gpt8_fck; + +DEFINE_CLK_OMAP_MUX_GATE(gpt8_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT8_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT8_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt8_ick; + +static struct clk_hw_omap gpt8_ick_hw = { + .hw = { + .clk = &gpt8_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT8_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt8_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt9_fck, "core_l4_clkdm", omap24xx_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), + OMAP24XX_CLKSEL_GPT9_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_GPT9_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, dss1_fck_ops); + +static struct clk gpt9_ick; + +static struct clk_hw_omap gpt9_ick_hw = { + .hw = { + .clk = &gpt9_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_GPT9_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt9_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk hdq_fck; + +static struct clk_hw_omap hdq_fck_hw = { + .hw = { + .clk = &hdq_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_HDQ_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(hdq_fck, fac_fck_parent_names, aes_ick_ops); + +static struct clk hdq_ick; + +static struct clk_hw_omap hdq_ick_hw = { + .hw = { + .clk = &hdq_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_HDQ_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(hdq_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk i2c1_ick; + +static struct clk_hw_omap i2c1_ick_hw = { + .hw = { + .clk = &i2c1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP2420_EN_I2C1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(i2c1_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk i2c2_ick; + +static struct clk_hw_omap i2c2_ick_hw = { + .hw = { + .clk = &i2c2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP2420_EN_I2C2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(i2c2_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk i2chs1_fck; + +static struct clk_hw_omap i2chs1_fck_hw = { + .hw = { + .clk = &i2chs1_fck, + }, + .ops = &clkhwops_omap2430_i2chs_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), + .enable_bit = OMAP2430_EN_I2CHS1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(i2chs1_fck, cam_fck_parent_names, aes_ick_ops); + +static struct clk i2chs2_fck; + +static struct clk_hw_omap i2chs2_fck_hw = { + .hw = { + .clk = &i2chs2_fck, + }, + .ops = &clkhwops_omap2430_i2chs_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), + .enable_bit = OMAP2430_EN_I2CHS2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(i2chs2_fck, cam_fck_parent_names, aes_ick_ops); + +static struct clk icr_ick; + +static struct clk_hw_omap icr_ick_hw = { + .hw = { + .clk = &icr_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP2430_EN_ICR_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(icr_ick, gpios_ick_parent_names, aes_ick_ops); + +static const struct clksel dsp_ick_clksel[] = { + { .parent = &dsp_fck, .rates = dsp_ick_rates }, + { .parent = NULL }, +}; + +static const char *iva2_1_ick_parent_names[] = { + "dsp_fck", +}; + +DEFINE_CLK_OMAP_MUX_GATE(iva2_1_ick, "dsp_clkdm", dsp_ick_clksel, + OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL), + OMAP24XX_CLKSEL_DSP_IF_MASK, + OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN), + OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT, &clkhwops_wait, + iva2_1_ick_parent_names, dsp_fck_ops); + +static struct clk mailboxes_ick; + +static struct clk_hw_omap mailboxes_ick_hw = { + .hw = { + .clk = &mailboxes_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_MAILBOXES_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mailboxes_ick, aes_ick_parent_names, aes_ick_ops); + +static const struct clksel_rate common_mcbsp_96m_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel_rate common_mcbsp_mcbsp_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel mcbsp_fck_clksel[] = { + { .parent = &func_96m_ck, .rates = common_mcbsp_96m_rates }, + { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates }, + { .parent = NULL }, +}; + +static const char *mcbsp1_fck_parent_names[] = { + "func_96m_ck", "mcbsp_clks", +}; + +DEFINE_CLK_OMAP_MUX_GATE(mcbsp1_fck, "core_l4_clkdm", mcbsp_fck_clksel, + OMAP243X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0), + OMAP2_MCBSP1_CLKS_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_MCBSP1_SHIFT, &clkhwops_wait, + mcbsp1_fck_parent_names, dss1_fck_ops); + +static struct clk mcbsp1_ick; + +static struct clk_hw_omap mcbsp1_ick_hw = { + .hw = { + .clk = &mcbsp1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_MCBSP1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcbsp1_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(mcbsp2_fck, "core_l4_clkdm", mcbsp_fck_clksel, + OMAP243X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0), + OMAP2_MCBSP2_CLKS_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP24XX_EN_MCBSP2_SHIFT, &clkhwops_wait, + mcbsp1_fck_parent_names, dss1_fck_ops); + +static struct clk mcbsp2_ick; + +static struct clk_hw_omap mcbsp2_ick_hw = { + .hw = { + .clk = &mcbsp2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_MCBSP2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcbsp2_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(mcbsp3_fck, "core_l4_clkdm", mcbsp_fck_clksel, + OMAP243X_CTRL_REGADDR(OMAP243X_CONTROL_DEVCONF1), + OMAP2_MCBSP3_CLKS_MASK, + OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), + OMAP2430_EN_MCBSP3_SHIFT, &clkhwops_wait, + mcbsp1_fck_parent_names, dss1_fck_ops); + +static struct clk mcbsp3_ick; + +static struct clk_hw_omap mcbsp3_ick_hw = { + .hw = { + .clk = &mcbsp3_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP2430_EN_MCBSP3_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcbsp3_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(mcbsp4_fck, "core_l4_clkdm", mcbsp_fck_clksel, + OMAP243X_CTRL_REGADDR(OMAP243X_CONTROL_DEVCONF1), + OMAP2_MCBSP4_CLKS_MASK, + OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), + OMAP2430_EN_MCBSP4_SHIFT, &clkhwops_wait, + mcbsp1_fck_parent_names, dss1_fck_ops); + +static struct clk mcbsp4_ick; + +static struct clk_hw_omap mcbsp4_ick_hw = { + .hw = { + .clk = &mcbsp4_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP2430_EN_MCBSP4_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcbsp4_ick, aes_ick_parent_names, aes_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(mcbsp5_fck, "core_l4_clkdm", mcbsp_fck_clksel, + OMAP243X_CTRL_REGADDR(OMAP243X_CONTROL_DEVCONF1), + OMAP2_MCBSP5_CLKS_MASK, + OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), + OMAP2430_EN_MCBSP5_SHIFT, &clkhwops_wait, + mcbsp1_fck_parent_names, dss1_fck_ops); + +static struct clk mcbsp5_ick; + +static struct clk_hw_omap mcbsp5_ick_hw = { + .hw = { + .clk = &mcbsp5_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP2430_EN_MCBSP5_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcbsp5_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk mcspi1_fck; + +static const char *mcspi1_fck_parent_names[] = { + "func_48m_ck", +}; + +static struct clk_hw_omap mcspi1_fck_hw = { + .hw = { + .clk = &mcspi1_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_MCSPI1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcspi1_fck, mcspi1_fck_parent_names, aes_ick_ops); + +static struct clk mcspi1_ick; + +static struct clk_hw_omap mcspi1_ick_hw = { + .hw = { + .clk = &mcspi1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_MCSPI1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcspi1_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk mcspi2_fck; + +static struct clk_hw_omap mcspi2_fck_hw = { + .hw = { + .clk = &mcspi2_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_MCSPI2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcspi2_fck, mcspi1_fck_parent_names, aes_ick_ops); + +static struct clk mcspi2_ick; + +static struct clk_hw_omap mcspi2_ick_hw = { + .hw = { + .clk = &mcspi2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_MCSPI2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcspi2_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk mcspi3_fck; + +static struct clk_hw_omap mcspi3_fck_hw = { + .hw = { + .clk = &mcspi3_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), + .enable_bit = OMAP2430_EN_MCSPI3_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcspi3_fck, mcspi1_fck_parent_names, aes_ick_ops); + +static struct clk mcspi3_ick; + +static struct clk_hw_omap mcspi3_ick_hw = { + .hw = { + .clk = &mcspi3_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP2430_EN_MCSPI3_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcspi3_ick, aes_ick_parent_names, aes_ick_ops); + +static const struct clksel_rate mdm_ick_core_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_243X }, + { .div = 4, .val = 4, .flags = RATE_IN_243X }, + { .div = 6, .val = 6, .flags = RATE_IN_243X }, + { .div = 9, .val = 9, .flags = RATE_IN_243X }, + { .div = 0 } +}; + +static const struct clksel mdm_ick_clksel[] = { + { .parent = &core_ck, .rates = mdm_ick_core_rates }, + { .parent = NULL }, +}; + +static const char *mdm_ick_parent_names[] = { + "core_ck", +}; + +DEFINE_CLK_OMAP_MUX_GATE(mdm_ick, "mdm_clkdm", mdm_ick_clksel, + OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_CLKSEL), + OMAP2430_CLKSEL_MDM_MASK, + OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_ICLKEN), + OMAP2430_CM_ICLKEN_MDM_EN_MDM_SHIFT, + &clkhwops_iclk_wait, mdm_ick_parent_names, + dsp_fck_ops); + +static struct clk mdm_intc_ick; + +static struct clk_hw_omap mdm_intc_ick_hw = { + .hw = { + .clk = &mdm_intc_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP2430_EN_MDM_INTC_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mdm_intc_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk mdm_osc_ck; + +static struct clk_hw_omap mdm_osc_ck_hw = { + .hw = { + .clk = &mdm_osc_ck, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_FCLKEN), + .enable_bit = OMAP2430_EN_OSC_SHIFT, + .clkdm_name = "mdm_clkdm", +}; + +DEFINE_STRUCT_CLK(mdm_osc_ck, sys_ck_parent_names, aes_ick_ops); + +static struct clk mmchs1_fck; + +static struct clk_hw_omap mmchs1_fck_hw = { + .hw = { + .clk = &mmchs1_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), + .enable_bit = OMAP2430_EN_MMCHS1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mmchs1_fck, cam_fck_parent_names, aes_ick_ops); + +static struct clk mmchs1_ick; + +static struct clk_hw_omap mmchs1_ick_hw = { + .hw = { + .clk = &mmchs1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP2430_EN_MMCHS1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mmchs1_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk mmchs2_fck; + +static struct clk_hw_omap mmchs2_fck_hw = { + .hw = { + .clk = &mmchs2_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), + .enable_bit = OMAP2430_EN_MMCHS2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mmchs2_fck, cam_fck_parent_names, aes_ick_ops); + +static struct clk mmchs2_ick; + +static struct clk_hw_omap mmchs2_ick_hw = { + .hw = { + .clk = &mmchs2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP2430_EN_MMCHS2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mmchs2_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk mmchsdb1_fck; + +static struct clk_hw_omap mmchsdb1_fck_hw = { + .hw = { + .clk = &mmchsdb1_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), + .enable_bit = OMAP2430_EN_MMCHSDB1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mmchsdb1_fck, gpio5_fck_parent_names, aes_ick_ops); + +static struct clk mmchsdb2_fck; + +static struct clk_hw_omap mmchsdb2_fck_hw = { + .hw = { + .clk = &mmchsdb2_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), + .enable_bit = OMAP2430_EN_MMCHSDB2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mmchsdb2_fck, gpio5_fck_parent_names, aes_ick_ops); + +DEFINE_CLK_DIVIDER(mpu_ck, "core_ck", &core_ck, 0x0, + OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL), + OMAP24XX_CLKSEL_MPU_SHIFT, OMAP24XX_CLKSEL_MPU_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +static struct clk mpu_wdt_fck; + +static struct clk_hw_omap mpu_wdt_fck_hw = { + .hw = { + .clk = &mpu_wdt_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), + .enable_bit = OMAP24XX_EN_MPU_WDT_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(mpu_wdt_fck, gpio5_fck_parent_names, aes_ick_ops); + +static struct clk mpu_wdt_ick; + +static struct clk_hw_omap mpu_wdt_ick_hw = { + .hw = { + .clk = &mpu_wdt_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP24XX_EN_MPU_WDT_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(mpu_wdt_ick, gpios_ick_parent_names, aes_ick_ops); + +static struct clk mspro_fck; + +static struct clk_hw_omap mspro_fck_hw = { + .hw = { + .clk = &mspro_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_MSPRO_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mspro_fck, cam_fck_parent_names, aes_ick_ops); + +static struct clk mspro_ick; + +static struct clk_hw_omap mspro_ick_hw = { + .hw = { + .clk = &mspro_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_MSPRO_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mspro_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk omapctrl_ick; + +static struct clk_hw_omap omapctrl_ick_hw = { + .hw = { + .clk = &omapctrl_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP24XX_EN_OMAPCTRL_SHIFT, + .flags = ENABLE_ON_INIT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(omapctrl_ick, gpios_ick_parent_names, aes_ick_ops); + +static struct clk pka_ick; + +static struct clk_hw_omap pka_ick_hw = { + .hw = { + .clk = &pka_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), + .enable_bit = OMAP24XX_EN_PKA_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(pka_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk rng_ick; + +static struct clk_hw_omap rng_ick_hw = { + .hw = { + .clk = &rng_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), + .enable_bit = OMAP24XX_EN_RNG_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(rng_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk sdma_fck; + +DEFINE_STRUCT_CLK_HW_OMAP(sdma_fck, "core_l3_clkdm"); +DEFINE_STRUCT_CLK(sdma_fck, gfx_ick_parent_names, core_ck_ops); + +static struct clk sdma_ick; + +static struct clk_hw_omap sdma_ick_hw = { + .hw = { + .clk = &sdma_ick, + }, + .ops = &clkhwops_iclk, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), + .enable_bit = OMAP24XX_AUTO_SDMA_SHIFT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(sdma_ick, gfx_ick_parent_names, core_ck_ops); + +static struct clk sdrc_ick; + +static struct clk_hw_omap sdrc_ick_hw = { + .hw = { + .clk = &sdrc_ick, + }, + .ops = &clkhwops_iclk, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), + .enable_bit = OMAP2430_EN_SDRC_SHIFT, + .flags = ENABLE_ON_INIT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(sdrc_ick, gfx_ick_parent_names, core_ck_ops); + +static struct clk sha_ick; + +static struct clk_hw_omap sha_ick_hw = { + .hw = { + .clk = &sha_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), + .enable_bit = OMAP24XX_EN_SHA_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(sha_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk ssi_l4_ick; + +static struct clk_hw_omap ssi_l4_ick_hw = { + .hw = { + .clk = &ssi_l4_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP24XX_EN_SSI_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(ssi_l4_ick, aes_ick_parent_names, aes_ick_ops); + +static const struct clksel_rate ssi_ssr_sst_fck_core_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, + { .div = 2, .val = 2, .flags = RATE_IN_24XX }, + { .div = 3, .val = 3, .flags = RATE_IN_24XX }, + { .div = 4, .val = 4, .flags = RATE_IN_24XX }, + { .div = 5, .val = 5, .flags = RATE_IN_243X }, + { .div = 0 } +}; + +static const struct clksel ssi_ssr_sst_fck_clksel[] = { + { .parent = &core_ck, .rates = ssi_ssr_sst_fck_core_rates }, + { .parent = NULL }, +}; + +static const char *ssi_ssr_sst_fck_parent_names[] = { + "core_ck", +}; + +DEFINE_CLK_OMAP_MUX_GATE(ssi_ssr_sst_fck, "core_l3_clkdm", + ssi_ssr_sst_fck_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), + OMAP24XX_CLKSEL_SSI_MASK, + OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), + OMAP24XX_EN_SSI_SHIFT, &clkhwops_wait, + ssi_ssr_sst_fck_parent_names, dsp_fck_ops); + +static struct clk sync_32k_ick; + +static struct clk_hw_omap sync_32k_ick_hw = { + .hw = { + .clk = &sync_32k_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP24XX_EN_32KSYNC_SHIFT, + .flags = ENABLE_ON_INIT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(sync_32k_ick, gpios_ick_parent_names, aes_ick_ops); + +static const struct clksel_rate common_clkout_src_core_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel_rate common_clkout_src_sys_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel_rate common_clkout_src_96m_rates[] = { + { .div = 1, .val = 2, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel_rate common_clkout_src_54m_rates[] = { + { .div = 1, .val = 3, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel common_clkout_src_clksel[] = { + { .parent = &core_ck, .rates = common_clkout_src_core_rates }, + { .parent = &sys_ck, .rates = common_clkout_src_sys_rates }, + { .parent = &func_96m_ck, .rates = common_clkout_src_96m_rates }, + { .parent = &func_54m_ck, .rates = common_clkout_src_54m_rates }, + { .parent = NULL }, +}; + +static const char *sys_clkout_src_parent_names[] = { + "core_ck", "sys_ck", "func_96m_ck", "func_54m_ck", +}; + +DEFINE_CLK_OMAP_MUX_GATE(sys_clkout_src, "wkup_clkdm", common_clkout_src_clksel, + OMAP2430_PRCM_CLKOUT_CTRL, OMAP24XX_CLKOUT_SOURCE_MASK, + OMAP2430_PRCM_CLKOUT_CTRL, OMAP24XX_CLKOUT_EN_SHIFT, + NULL, sys_clkout_src_parent_names, gpt1_fck_ops); + +DEFINE_CLK_DIVIDER(sys_clkout, "sys_clkout_src", &sys_clkout_src, 0x0, + OMAP2430_PRCM_CLKOUT_CTRL, OMAP24XX_CLKOUT_DIV_SHIFT, + OMAP24XX_CLKOUT_DIV_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL); + +static struct clk uart1_fck; + +static struct clk_hw_omap uart1_fck_hw = { + .hw = { + .clk = &uart1_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_UART1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(uart1_fck, mcspi1_fck_parent_names, aes_ick_ops); + +static struct clk uart1_ick; + +static struct clk_hw_omap uart1_ick_hw = { + .hw = { + .clk = &uart1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_UART1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(uart1_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk uart2_fck; + +static struct clk_hw_omap uart2_fck_hw = { + .hw = { + .clk = &uart2_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_UART2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(uart2_fck, mcspi1_fck_parent_names, aes_ick_ops); + +static struct clk uart2_ick; + +static struct clk_hw_omap uart2_ick_hw = { + .hw = { + .clk = &uart2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_UART2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(uart2_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk uart3_fck; + +static struct clk_hw_omap uart3_fck_hw = { + .hw = { + .clk = &uart3_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), + .enable_bit = OMAP24XX_EN_UART3_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(uart3_fck, mcspi1_fck_parent_names, aes_ick_ops); + +static struct clk uart3_ick; + +static struct clk_hw_omap uart3_ick_hw = { + .hw = { + .clk = &uart3_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP24XX_EN_UART3_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(uart3_ick, aes_ick_parent_names, aes_ick_ops); + +static struct clk usb_fck; + +static struct clk_hw_omap usb_fck_hw = { + .hw = { + .clk = &usb_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), + .enable_bit = OMAP24XX_EN_USB_SHIFT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(usb_fck, mcspi1_fck_parent_names, aes_ick_ops); + +static const struct clksel_rate usb_l4_ick_core_l3_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, + { .div = 2, .val = 2, .flags = RATE_IN_24XX }, + { .div = 4, .val = 4, .flags = RATE_IN_24XX }, + { .div = 0 } +}; + +static const struct clksel usb_l4_ick_clksel[] = { + { .parent = &core_l3_ck, .rates = usb_l4_ick_core_l3_rates }, + { .parent = NULL }, +}; + +static const char *usb_l4_ick_parent_names[] = { + "core_l3_ck", +}; + +DEFINE_CLK_OMAP_MUX_GATE(usb_l4_ick, "core_l4_clkdm", usb_l4_ick_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), + OMAP24XX_CLKSEL_USB_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + OMAP24XX_EN_USB_SHIFT, &clkhwops_iclk_wait, + usb_l4_ick_parent_names, dsp_fck_ops); + +static struct clk usbhs_ick; + +static struct clk_hw_omap usbhs_ick_hw = { + .hw = { + .clk = &usbhs_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP2430_EN_USBHS_SHIFT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(usbhs_ick, gfx_ick_parent_names, aes_ick_ops); + +static struct clk virt_prcm_set; + +static const char *virt_prcm_set_parent_names[] = { + "mpu_ck", +}; + +static const struct clk_ops virt_prcm_set_ops = { + .recalc_rate = &omap2_table_mpu_recalc, + .set_rate = &omap2_select_table_rate, + .round_rate = &omap2_round_to_table_rate, +}; + +DEFINE_STRUCT_CLK_HW_OMAP(virt_prcm_set, NULL); +DEFINE_STRUCT_CLK(virt_prcm_set, virt_prcm_set_parent_names, virt_prcm_set_ops); + +static struct clk wdt1_ick; + +static struct clk_hw_omap wdt1_ick_hw = { + .hw = { + .clk = &wdt1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP24XX_EN_WDT1_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(wdt1_ick, gpios_ick_parent_names, aes_ick_ops); + +static struct clk wdt4_fck; + +static struct clk_hw_omap wdt4_fck_hw = { + .hw = { + .clk = &wdt4_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP24XX_EN_WDT4_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(wdt4_fck, gpio5_fck_parent_names, aes_ick_ops); + +static struct clk wdt4_ick; + +static struct clk_hw_omap wdt4_ick_hw = { + .hw = { + .clk = &wdt4_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP24XX_EN_WDT4_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(wdt4_ick, aes_ick_parent_names, aes_ick_ops); + +/* + * clkdev integration + */ + +static struct omap_clk omap2430_clks[] = { + /* external root sources */ + CLK(NULL, "func_32k_ck", &func_32k_ck), + CLK(NULL, "secure_32k_ck", &secure_32k_ck), + CLK(NULL, "osc_ck", &osc_ck), + CLK("twl", "fck", &osc_ck), + CLK(NULL, "sys_ck", &sys_ck), + CLK(NULL, "alt_ck", &alt_ck), + CLK(NULL, "mcbsp_clks", &mcbsp_clks), + /* internal analog sources */ + CLK(NULL, "dpll_ck", &dpll_ck), + CLK(NULL, "apll96_ck", &apll96_ck), + CLK(NULL, "apll54_ck", &apll54_ck), + /* internal prcm root sources */ + CLK(NULL, "func_54m_ck", &func_54m_ck), + CLK(NULL, "core_ck", &core_ck), + CLK(NULL, "func_96m_ck", &func_96m_ck), + CLK(NULL, "func_48m_ck", &func_48m_ck), + CLK(NULL, "func_12m_ck", &func_12m_ck), + CLK(NULL, "sys_clkout_src", &sys_clkout_src), + CLK(NULL, "sys_clkout", &sys_clkout), + CLK(NULL, "emul_ck", &emul_ck), + /* mpu domain clocks */ + CLK(NULL, "mpu_ck", &mpu_ck), + /* dsp domain clocks */ + CLK(NULL, "dsp_fck", &dsp_fck), + CLK(NULL, "iva2_1_ick", &iva2_1_ick), + /* GFX domain clocks */ + CLK(NULL, "gfx_3d_fck", &gfx_3d_fck), + CLK(NULL, "gfx_2d_fck", &gfx_2d_fck), + CLK(NULL, "gfx_ick", &gfx_ick), + /* Modem domain clocks */ + CLK(NULL, "mdm_ick", &mdm_ick), + CLK(NULL, "mdm_osc_ck", &mdm_osc_ck), + /* DSS domain clocks */ + CLK("omapdss_dss", "ick", &dss_ick), + CLK(NULL, "dss_ick", &dss_ick), + CLK(NULL, "dss1_fck", &dss1_fck), + CLK(NULL, "dss2_fck", &dss2_fck), + CLK(NULL, "dss_54m_fck", &dss_54m_fck), + /* L3 domain clocks */ + CLK(NULL, "core_l3_ck", &core_l3_ck), + CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck), + CLK(NULL, "usb_l4_ick", &usb_l4_ick), + /* L4 domain clocks */ + CLK(NULL, "l4_ck", &l4_ck), + CLK(NULL, "ssi_l4_ick", &ssi_l4_ick), + /* virtual meta-group clock */ + CLK(NULL, "virt_prcm_set", &virt_prcm_set), + /* general l4 interface ck, multi-parent functional clk */ + CLK(NULL, "gpt1_ick", &gpt1_ick), + CLK(NULL, "gpt1_fck", &gpt1_fck), + CLK(NULL, "gpt2_ick", &gpt2_ick), + CLK(NULL, "gpt2_fck", &gpt2_fck), + CLK(NULL, "gpt3_ick", &gpt3_ick), + CLK(NULL, "gpt3_fck", &gpt3_fck), + CLK(NULL, "gpt4_ick", &gpt4_ick), + CLK(NULL, "gpt4_fck", &gpt4_fck), + CLK(NULL, "gpt5_ick", &gpt5_ick), + CLK(NULL, "gpt5_fck", &gpt5_fck), + CLK(NULL, "gpt6_ick", &gpt6_ick), + CLK(NULL, "gpt6_fck", &gpt6_fck), + CLK(NULL, "gpt7_ick", &gpt7_ick), + CLK(NULL, "gpt7_fck", &gpt7_fck), + CLK(NULL, "gpt8_ick", &gpt8_ick), + CLK(NULL, "gpt8_fck", &gpt8_fck), + CLK(NULL, "gpt9_ick", &gpt9_ick), + CLK(NULL, "gpt9_fck", &gpt9_fck), + CLK(NULL, "gpt10_ick", &gpt10_ick), + CLK(NULL, "gpt10_fck", &gpt10_fck), + CLK(NULL, "gpt11_ick", &gpt11_ick), + CLK(NULL, "gpt11_fck", &gpt11_fck), + CLK(NULL, "gpt12_ick", &gpt12_ick), + CLK(NULL, "gpt12_fck", &gpt12_fck), + CLK("omap-mcbsp.1", "ick", &mcbsp1_ick), + CLK(NULL, "mcbsp1_ick", &mcbsp1_ick), + CLK(NULL, "mcbsp1_fck", &mcbsp1_fck), + CLK("omap-mcbsp.2", "ick", &mcbsp2_ick), + CLK(NULL, "mcbsp2_ick", &mcbsp2_ick), + CLK(NULL, "mcbsp2_fck", &mcbsp2_fck), + CLK("omap-mcbsp.3", "ick", &mcbsp3_ick), + CLK(NULL, "mcbsp3_ick", &mcbsp3_ick), + CLK(NULL, "mcbsp3_fck", &mcbsp3_fck), + CLK("omap-mcbsp.4", "ick", &mcbsp4_ick), + CLK(NULL, "mcbsp4_ick", &mcbsp4_ick), + CLK(NULL, "mcbsp4_fck", &mcbsp4_fck), + CLK("omap-mcbsp.5", "ick", &mcbsp5_ick), + CLK(NULL, "mcbsp5_ick", &mcbsp5_ick), + CLK(NULL, "mcbsp5_fck", &mcbsp5_fck), + CLK("omap2_mcspi.1", "ick", &mcspi1_ick), + CLK(NULL, "mcspi1_ick", &mcspi1_ick), + CLK(NULL, "mcspi1_fck", &mcspi1_fck), + CLK("omap2_mcspi.2", "ick", &mcspi2_ick), + CLK(NULL, "mcspi2_ick", &mcspi2_ick), + CLK(NULL, "mcspi2_fck", &mcspi2_fck), + CLK("omap2_mcspi.3", "ick", &mcspi3_ick), + CLK(NULL, "mcspi3_ick", &mcspi3_ick), + CLK(NULL, "mcspi3_fck", &mcspi3_fck), + CLK(NULL, "uart1_ick", &uart1_ick), + CLK(NULL, "uart1_fck", &uart1_fck), + CLK(NULL, "uart2_ick", &uart2_ick), + CLK(NULL, "uart2_fck", &uart2_fck), + CLK(NULL, "uart3_ick", &uart3_ick), + CLK(NULL, "uart3_fck", &uart3_fck), + CLK(NULL, "gpios_ick", &gpios_ick), + CLK(NULL, "gpios_fck", &gpios_fck), + CLK("omap_wdt", "ick", &mpu_wdt_ick), + CLK(NULL, "mpu_wdt_ick", &mpu_wdt_ick), + CLK(NULL, "mpu_wdt_fck", &mpu_wdt_fck), + CLK(NULL, "sync_32k_ick", &sync_32k_ick), + CLK(NULL, "wdt1_ick", &wdt1_ick), + CLK(NULL, "omapctrl_ick", &omapctrl_ick), + CLK(NULL, "icr_ick", &icr_ick), + CLK("omap24xxcam", "fck", &cam_fck), + CLK(NULL, "cam_fck", &cam_fck), + CLK("omap24xxcam", "ick", &cam_ick), + CLK(NULL, "cam_ick", &cam_ick), + CLK(NULL, "mailboxes_ick", &mailboxes_ick), + CLK(NULL, "wdt4_ick", &wdt4_ick), + CLK(NULL, "wdt4_fck", &wdt4_fck), + CLK(NULL, "mspro_ick", &mspro_ick), + CLK(NULL, "mspro_fck", &mspro_fck), + CLK(NULL, "fac_ick", &fac_ick), + CLK(NULL, "fac_fck", &fac_fck), + CLK("omap_hdq.0", "ick", &hdq_ick), + CLK(NULL, "hdq_ick", &hdq_ick), + CLK("omap_hdq.1", "fck", &hdq_fck), + CLK(NULL, "hdq_fck", &hdq_fck), + CLK("omap_i2c.1", "ick", &i2c1_ick), + CLK(NULL, "i2c1_ick", &i2c1_ick), + CLK(NULL, "i2chs1_fck", &i2chs1_fck), + CLK("omap_i2c.2", "ick", &i2c2_ick), + CLK(NULL, "i2c2_ick", &i2c2_ick), + CLK(NULL, "i2chs2_fck", &i2chs2_fck), + CLK(NULL, "gpmc_fck", &gpmc_fck), + CLK(NULL, "sdma_fck", &sdma_fck), + CLK(NULL, "sdma_ick", &sdma_ick), + CLK(NULL, "sdrc_ick", &sdrc_ick), + CLK(NULL, "des_ick", &des_ick), + CLK("omap-sham", "ick", &sha_ick), + CLK(NULL, "sha_ick", &sha_ick), + CLK("omap_rng", "ick", &rng_ick), + CLK(NULL, "rng_ick", &rng_ick), + CLK("omap-aes", "ick", &aes_ick), + CLK(NULL, "aes_ick", &aes_ick), + CLK(NULL, "pka_ick", &pka_ick), + CLK(NULL, "usb_fck", &usb_fck), + CLK("musb-omap2430", "ick", &usbhs_ick), + CLK(NULL, "usbhs_ick", &usbhs_ick), + CLK("omap_hsmmc.0", "ick", &mmchs1_ick), + CLK(NULL, "mmchs1_ick", &mmchs1_ick), + CLK(NULL, "mmchs1_fck", &mmchs1_fck), + CLK("omap_hsmmc.1", "ick", &mmchs2_ick), + CLK(NULL, "mmchs2_ick", &mmchs2_ick), + CLK(NULL, "mmchs2_fck", &mmchs2_fck), + CLK(NULL, "gpio5_ick", &gpio5_ick), + CLK(NULL, "gpio5_fck", &gpio5_fck), + CLK(NULL, "mdm_intc_ick", &mdm_intc_ick), + CLK("omap_hsmmc.0", "mmchsdb_fck", &mmchsdb1_fck), + CLK(NULL, "mmchsdb1_fck", &mmchsdb1_fck), + CLK("omap_hsmmc.1", "mmchsdb_fck", &mmchsdb2_fck), + CLK(NULL, "mmchsdb2_fck", &mmchsdb2_fck), + CLK(NULL, "timer_32k_ck", &func_32k_ck), + CLK(NULL, "timer_sys_ck", &sys_ck), + CLK(NULL, "timer_ext_ck", &alt_ck), + CLK(NULL, "cpufreq_ck", &virt_prcm_set), +}; + +static const char *enable_init_clks[] = { + "apll96_ck", + "apll54_ck", + "sync_32k_ick", + "omapctrl_ick", + "gpmc_fck", + "sdrc_ick", +}; + +/* + * init code + */ + +int __init omap2430_clk_init(void) +{ + prcm_clksrc_ctrl = OMAP2430_PRCM_CLKSRC_CTRL; + cpu_mask = RATE_IN_243X; + rate_table = omap2430_rate_table; + + omap2xxx_clkt_dpllcore_init(&dpll_ck_hw.hw); + + omap2xxx_clkt_vps_check_bootloader_rates(); + + omap_clocks_register(omap2430_clks, ARRAY_SIZE(omap2430_clks)); + + omap2xxx_clkt_vps_late_init(); + + omap2_clk_disable_autoidle_all(); + + omap2_clk_enable_init_clocks(enable_init_clks, + ARRAY_SIZE(enable_init_clks)); + + pr_info("Clocking rate (Crystal/DPLL/MPU): %ld.%01ld/%ld/%ld MHz\n", + (clk_get_rate(&sys_ck) / 1000000), + (clk_get_rate(&sys_ck) / 100000) % 10, + (clk_get_rate(&dpll_ck) / 1000000), + (clk_get_rate(&mpu_ck) / 1000000)); + + return 0; +} diff --git a/arch/arm/mach-omap2/cclock3xxx_data.c b/arch/arm/mach-omap2/cclock3xxx_data.c new file mode 100644 index 00000000000..eb8c75ec3b1 --- /dev/null +++ b/arch/arm/mach-omap2/cclock3xxx_data.c @@ -0,0 +1,3681 @@ +/* + * OMAP3 clock data + * + * Copyright (C) 2007-2012 Texas Instruments, Inc. + * Copyright (C) 2007-2011 Nokia Corporation + * + * Written by Paul Walmsley + * Updated to COMMON clk data format by Rajendra Nayak <rnayak@ti.com> + * With many device clock fixes by Kevin Hilman and Jouni Högander + * DPLL bypass clock support added by Roman Tereshonkov + * + */ + +/* + * Virtual clocks are introduced as convenient tools. + * They are sources for other clocks and not supposed + * to be requested from drivers directly. + */ + +#include <linux/kernel.h> +#include <linux/clk.h> +#include <linux/clk-private.h> +#include <linux/list.h> +#include <linux/io.h> + +#include "soc.h" +#include "iomap.h" +#include "clock.h" +#include "clock3xxx.h" +#include "clock34xx.h" +#include "clock36xx.h" +#include "clock3517.h" +#include "cm3xxx.h" +#include "cm-regbits-34xx.h" +#include "prm3xxx.h" +#include "prm-regbits-34xx.h" +#include "control.h" + +/* + * clocks + */ + +#define OMAP_CM_REGADDR OMAP34XX_CM_REGADDR + +/* Maximum DPLL multiplier, divider values for OMAP3 */ +#define OMAP3_MAX_DPLL_MULT 2047 +#define OMAP3630_MAX_JTYPE_DPLL_MULT 4095 +#define OMAP3_MAX_DPLL_DIV 128 + +DEFINE_CLK_FIXED_RATE(dummy_apb_pclk, CLK_IS_ROOT, 0x0, 0x0); + +DEFINE_CLK_FIXED_RATE(mcbsp_clks, CLK_IS_ROOT, 0x0, 0x0); + +DEFINE_CLK_FIXED_RATE(omap_32k_fck, CLK_IS_ROOT, 32768, 0x0); + +DEFINE_CLK_FIXED_RATE(pclk_ck, CLK_IS_ROOT, 27000000, 0x0); + +DEFINE_CLK_FIXED_RATE(rmii_ck, CLK_IS_ROOT, 50000000, 0x0); + +DEFINE_CLK_FIXED_RATE(secure_32k_fck, CLK_IS_ROOT, 32768, 0x0); + +DEFINE_CLK_FIXED_RATE(sys_altclk, CLK_IS_ROOT, 0x0, 0x0); + +DEFINE_CLK_FIXED_RATE(virt_12m_ck, CLK_IS_ROOT, 12000000, 0x0); + +DEFINE_CLK_FIXED_RATE(virt_13m_ck, CLK_IS_ROOT, 13000000, 0x0); + +DEFINE_CLK_FIXED_RATE(virt_16_8m_ck, CLK_IS_ROOT, 16800000, 0x0); + +DEFINE_CLK_FIXED_RATE(virt_19200000_ck, CLK_IS_ROOT, 19200000, 0x0); + +DEFINE_CLK_FIXED_RATE(virt_26000000_ck, CLK_IS_ROOT, 26000000, 0x0); + +DEFINE_CLK_FIXED_RATE(virt_38_4m_ck, CLK_IS_ROOT, 38400000, 0x0); + +static const char *osc_sys_ck_parent_names[] = { + "virt_12m_ck", "virt_13m_ck", "virt_19200000_ck", "virt_26000000_ck", + "virt_38_4m_ck", "virt_16_8m_ck", +}; + +DEFINE_CLK_MUX(osc_sys_ck, osc_sys_ck_parent_names, NULL, 0x0, + OMAP3430_PRM_CLKSEL, OMAP3430_SYS_CLKIN_SEL_SHIFT, + OMAP3430_SYS_CLKIN_SEL_WIDTH, 0x0, NULL); + +DEFINE_CLK_DIVIDER(sys_ck, "osc_sys_ck", &osc_sys_ck, 0x0, + OMAP3430_PRM_CLKSRC_CTRL, OMAP_SYSCLKDIV_SHIFT, + OMAP_SYSCLKDIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL); + +static struct dpll_data dpll3_dd = { + .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), + .mult_mask = OMAP3430_CORE_DPLL_MULT_MASK, + .div1_mask = OMAP3430_CORE_DPLL_DIV_MASK, + .clk_bypass = &sys_ck, + .clk_ref = &sys_ck, + .freqsel_mask = OMAP3430_CORE_DPLL_FREQSEL_MASK, + .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), + .enable_mask = OMAP3430_EN_CORE_DPLL_MASK, + .auto_recal_bit = OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT, + .recal_en_bit = OMAP3430_CORE_DPLL_RECAL_EN_SHIFT, + .recal_st_bit = OMAP3430_CORE_DPLL_ST_SHIFT, + .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE), + .autoidle_mask = OMAP3430_AUTO_CORE_DPLL_MASK, + .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), + .idlest_mask = OMAP3430_ST_CORE_CLK_MASK, + .max_multiplier = OMAP3_MAX_DPLL_MULT, + .min_divider = 1, + .max_divider = OMAP3_MAX_DPLL_DIV, +}; + +static struct clk dpll3_ck; + +static const char *dpll3_ck_parent_names[] = { + "sys_ck", +}; + +static const struct clk_ops dpll3_ck_ops = { + .init = &omap2_init_clk_clkdm, + .get_parent = &omap2_init_dpll_parent, + .recalc_rate = &omap3_dpll_recalc, + .round_rate = &omap2_dpll_round_rate, +}; + +static struct clk_hw_omap dpll3_ck_hw = { + .hw = { + .clk = &dpll3_ck, + }, + .ops = &clkhwops_omap3_dpll, + .dpll_data = &dpll3_dd, + .clkdm_name = "dpll3_clkdm", +}; + +DEFINE_STRUCT_CLK(dpll3_ck, dpll3_ck_parent_names, dpll3_ck_ops); + +DEFINE_CLK_DIVIDER(dpll3_m2_ck, "dpll3_ck", &dpll3_ck, 0x0, + OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), + OMAP3430_CORE_DPLL_CLKOUT_DIV_SHIFT, + OMAP3430_CORE_DPLL_CLKOUT_DIV_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +static struct clk core_ck; + +static const char *core_ck_parent_names[] = { + "dpll3_m2_ck", +}; + +static const struct clk_ops core_ck_ops = {}; + +DEFINE_STRUCT_CLK_HW_OMAP(core_ck, NULL); +DEFINE_STRUCT_CLK(core_ck, core_ck_parent_names, core_ck_ops); + +DEFINE_CLK_DIVIDER(l3_ick, "core_ck", &core_ck, 0x0, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_L3_SHIFT, OMAP3430_CLKSEL_L3_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +DEFINE_CLK_DIVIDER(l4_ick, "l3_ick", &l3_ick, 0x0, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_L4_SHIFT, OMAP3430_CLKSEL_L4_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +static struct clk security_l4_ick2; + +static const char *security_l4_ick2_parent_names[] = { + "l4_ick", +}; + +DEFINE_STRUCT_CLK_HW_OMAP(security_l4_ick2, NULL); +DEFINE_STRUCT_CLK(security_l4_ick2, security_l4_ick2_parent_names, core_ck_ops); + +static struct clk aes1_ick; + +static const char *aes1_ick_parent_names[] = { + "security_l4_ick2", +}; + +static const struct clk_ops aes1_ick_ops = { + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, +}; + +static struct clk_hw_omap aes1_ick_hw = { + .hw = { + .clk = &aes1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP3430_EN_AES1_SHIFT, +}; + +DEFINE_STRUCT_CLK(aes1_ick, aes1_ick_parent_names, aes1_ick_ops); + +static struct clk core_l4_ick; + +static const struct clk_ops core_l4_ick_ops = { + .init = &omap2_init_clk_clkdm, +}; + +DEFINE_STRUCT_CLK_HW_OMAP(core_l4_ick, "core_l4_clkdm"); +DEFINE_STRUCT_CLK(core_l4_ick, security_l4_ick2_parent_names, core_l4_ick_ops); + +static struct clk aes2_ick; + +static const char *aes2_ick_parent_names[] = { + "core_l4_ick", +}; + +static const struct clk_ops aes2_ick_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, +}; + +static struct clk_hw_omap aes2_ick_hw = { + .hw = { + .clk = &aes2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_AES2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(aes2_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk dpll1_fck; + +static struct dpll_data dpll1_dd = { + .mult_div1_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL), + .mult_mask = OMAP3430_MPU_DPLL_MULT_MASK, + .div1_mask = OMAP3430_MPU_DPLL_DIV_MASK, + .clk_bypass = &dpll1_fck, + .clk_ref = &sys_ck, + .freqsel_mask = OMAP3430_MPU_DPLL_FREQSEL_MASK, + .control_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKEN_PLL), + .enable_mask = OMAP3430_EN_MPU_DPLL_MASK, + .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), + .auto_recal_bit = OMAP3430_EN_MPU_DPLL_DRIFTGUARD_SHIFT, + .recal_en_bit = OMAP3430_MPU_DPLL_RECAL_EN_SHIFT, + .recal_st_bit = OMAP3430_MPU_DPLL_ST_SHIFT, + .autoidle_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL), + .autoidle_mask = OMAP3430_AUTO_MPU_DPLL_MASK, + .idlest_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL), + .idlest_mask = OMAP3430_ST_MPU_CLK_MASK, + .max_multiplier = OMAP3_MAX_DPLL_MULT, + .min_divider = 1, + .max_divider = OMAP3_MAX_DPLL_DIV, +}; + +static struct clk dpll1_ck; + +static const struct clk_ops dpll1_ck_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap3_noncore_dpll_enable, + .disable = &omap3_noncore_dpll_disable, + .get_parent = &omap2_init_dpll_parent, + .recalc_rate = &omap3_dpll_recalc, + .set_rate = &omap3_noncore_dpll_set_rate, + .round_rate = &omap2_dpll_round_rate, +}; + +static struct clk_hw_omap dpll1_ck_hw = { + .hw = { + .clk = &dpll1_ck, + }, + .ops = &clkhwops_omap3_dpll, + .dpll_data = &dpll1_dd, + .clkdm_name = "dpll1_clkdm", +}; + +DEFINE_STRUCT_CLK(dpll1_ck, dpll3_ck_parent_names, dpll1_ck_ops); + +DEFINE_CLK_FIXED_FACTOR(dpll1_x2_ck, "dpll1_ck", &dpll1_ck, 0x0, 2, 1); + +DEFINE_CLK_DIVIDER(dpll1_x2m2_ck, "dpll1_x2_ck", &dpll1_x2_ck, 0x0, + OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL), + OMAP3430_MPU_DPLL_CLKOUT_DIV_SHIFT, + OMAP3430_MPU_DPLL_CLKOUT_DIV_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +static struct clk mpu_ck; + +static const char *mpu_ck_parent_names[] = { + "dpll1_x2m2_ck", +}; + +DEFINE_STRUCT_CLK_HW_OMAP(mpu_ck, "mpu_clkdm"); +DEFINE_STRUCT_CLK(mpu_ck, mpu_ck_parent_names, core_l4_ick_ops); + +DEFINE_CLK_DIVIDER(arm_fck, "mpu_ck", &mpu_ck, 0x0, + OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL), + OMAP3430_ST_MPU_CLK_SHIFT, OMAP3430_ST_MPU_CLK_WIDTH, + 0x0, NULL); + +static struct clk cam_ick; + +static struct clk_hw_omap cam_ick_hw = { + .hw = { + .clk = &cam_ick, + }, + .ops = &clkhwops_iclk, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_CAM_SHIFT, + .clkdm_name = "cam_clkdm", +}; + +DEFINE_STRUCT_CLK(cam_ick, security_l4_ick2_parent_names, aes2_ick_ops); + +/* DPLL4 */ +/* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */ +/* Type: DPLL */ +static struct dpll_data dpll4_dd; + +static struct dpll_data dpll4_dd_34xx __initdata = { + .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2), + .mult_mask = OMAP3430_PERIPH_DPLL_MULT_MASK, + .div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK, + .clk_bypass = &sys_ck, + .clk_ref = &sys_ck, + .freqsel_mask = OMAP3430_PERIPH_DPLL_FREQSEL_MASK, + .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), + .enable_mask = OMAP3430_EN_PERIPH_DPLL_MASK, + .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), + .auto_recal_bit = OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT, + .recal_en_bit = OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT, + .recal_st_bit = OMAP3430_PERIPH_DPLL_ST_SHIFT, + .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE), + .autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK, + .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), + .idlest_mask = OMAP3430_ST_PERIPH_CLK_MASK, + .max_multiplier = OMAP3_MAX_DPLL_MULT, + .min_divider = 1, + .max_divider = OMAP3_MAX_DPLL_DIV, +}; + +static struct dpll_data dpll4_dd_3630 __initdata = { + .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2), + .mult_mask = OMAP3630_PERIPH_DPLL_MULT_MASK, + .div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK, + .clk_bypass = &sys_ck, + .clk_ref = &sys_ck, + .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), + .enable_mask = OMAP3430_EN_PERIPH_DPLL_MASK, + .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), + .auto_recal_bit = OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT, + .recal_en_bit = OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT, + .recal_st_bit = OMAP3430_PERIPH_DPLL_ST_SHIFT, + .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE), + .autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK, + .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), + .idlest_mask = OMAP3430_ST_PERIPH_CLK_MASK, + .dco_mask = OMAP3630_PERIPH_DPLL_DCO_SEL_MASK, + .sddiv_mask = OMAP3630_PERIPH_DPLL_SD_DIV_MASK, + .max_multiplier = OMAP3630_MAX_JTYPE_DPLL_MULT, + .min_divider = 1, + .max_divider = OMAP3_MAX_DPLL_DIV, + .flags = DPLL_J_TYPE +}; + +static struct clk dpll4_ck; + +static const struct clk_ops dpll4_ck_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap3_noncore_dpll_enable, + .disable = &omap3_noncore_dpll_disable, + .get_parent = &omap2_init_dpll_parent, + .recalc_rate = &omap3_dpll_recalc, + .set_rate = &omap3_dpll4_set_rate, + .round_rate = &omap2_dpll_round_rate, +}; + +static struct clk_hw_omap dpll4_ck_hw = { + .hw = { + .clk = &dpll4_ck, + }, + .dpll_data = &dpll4_dd, + .ops = &clkhwops_omap3_dpll, + .clkdm_name = "dpll4_clkdm", +}; + +DEFINE_STRUCT_CLK(dpll4_ck, dpll3_ck_parent_names, dpll4_ck_ops); + +static const struct clk_div_table dpll4_mx_ck_div_table[] = { + { .div = 1, .val = 1 }, + { .div = 2, .val = 2 }, + { .div = 3, .val = 3 }, + { .div = 4, .val = 4 }, + { .div = 5, .val = 5 }, + { .div = 6, .val = 6 }, + { .div = 7, .val = 7 }, + { .div = 8, .val = 8 }, + { .div = 9, .val = 9 }, + { .div = 10, .val = 10 }, + { .div = 11, .val = 11 }, + { .div = 12, .val = 12 }, + { .div = 13, .val = 13 }, + { .div = 14, .val = 14 }, + { .div = 15, .val = 15 }, + { .div = 16, .val = 16 }, + { .div = 17, .val = 17 }, + { .div = 18, .val = 18 }, + { .div = 19, .val = 19 }, + { .div = 20, .val = 20 }, + { .div = 21, .val = 21 }, + { .div = 22, .val = 22 }, + { .div = 23, .val = 23 }, + { .div = 24, .val = 24 }, + { .div = 25, .val = 25 }, + { .div = 26, .val = 26 }, + { .div = 27, .val = 27 }, + { .div = 28, .val = 28 }, + { .div = 29, .val = 29 }, + { .div = 30, .val = 30 }, + { .div = 31, .val = 31 }, + { .div = 32, .val = 32 }, + { .div = 0 }, +}; + +DEFINE_CLK_DIVIDER(dpll4_m5_ck, "dpll4_ck", &dpll4_ck, 0x0, + OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_CAM_SHIFT, OMAP3630_CLKSEL_CAM_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +static struct clk dpll4_m5x2_ck; + +static const char *dpll4_m5x2_ck_parent_names[] = { + "dpll4_m5_ck", +}; + +static const struct clk_ops dpll4_m5x2_ck_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, + .set_rate = &omap3_clkoutx2_set_rate, + .recalc_rate = &omap3_clkoutx2_recalc, + .round_rate = &omap3_clkoutx2_round_rate, +}; + +static const struct clk_ops dpll4_m5x2_ck_3630_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap36xx_pwrdn_clk_enable_with_hsdiv_restore, + .disable = &omap2_dflt_clk_disable, + .recalc_rate = &omap3_clkoutx2_recalc, +}; + +static struct clk_hw_omap dpll4_m5x2_ck_hw = { + .hw = { + .clk = &dpll4_m5x2_ck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), + .enable_bit = OMAP3430_PWRDN_CAM_SHIFT, + .flags = INVERT_ENABLE, + .clkdm_name = "dpll4_clkdm", +}; + +DEFINE_STRUCT_CLK_FLAGS(dpll4_m5x2_ck, dpll4_m5x2_ck_parent_names, + dpll4_m5x2_ck_ops, CLK_SET_RATE_PARENT); + +static struct clk dpll4_m5x2_ck_3630 = { + .name = "dpll4_m5x2_ck", + .hw = &dpll4_m5x2_ck_hw.hw, + .parent_names = dpll4_m5x2_ck_parent_names, + .num_parents = ARRAY_SIZE(dpll4_m5x2_ck_parent_names), + .ops = &dpll4_m5x2_ck_3630_ops, + .flags = CLK_SET_RATE_PARENT, +}; + +static struct clk cam_mclk; + +static const char *cam_mclk_parent_names[] = { + "dpll4_m5x2_ck", +}; + +static struct clk_hw_omap cam_mclk_hw = { + .hw = { + .clk = &cam_mclk, + }, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_EN_CAM_SHIFT, + .clkdm_name = "cam_clkdm", +}; + +static struct clk cam_mclk = { + .name = "cam_mclk", + .hw = &cam_mclk_hw.hw, + .parent_names = cam_mclk_parent_names, + .num_parents = ARRAY_SIZE(cam_mclk_parent_names), + .ops = &aes2_ick_ops, + .flags = CLK_SET_RATE_PARENT, +}; + +static const struct clksel_rate clkout2_src_core_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_3XXX }, + { .div = 0 } +}; + +static const struct clksel_rate clkout2_src_sys_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, + { .div = 0 } +}; + +static const struct clksel_rate clkout2_src_96m_rates[] = { + { .div = 1, .val = 2, .flags = RATE_IN_3XXX }, + { .div = 0 } +}; + +DEFINE_CLK_DIVIDER(dpll4_m2_ck, "dpll4_ck", &dpll4_ck, 0x0, + OMAP_CM_REGADDR(PLL_MOD, OMAP3430_CM_CLKSEL3), + OMAP3430_DIV_96M_SHIFT, OMAP3630_DIV_96M_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +static struct clk dpll4_m2x2_ck; + +static const char *dpll4_m2x2_ck_parent_names[] = { + "dpll4_m2_ck", +}; + +static struct clk_hw_omap dpll4_m2x2_ck_hw = { + .hw = { + .clk = &dpll4_m2x2_ck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), + .enable_bit = OMAP3430_PWRDN_96M_SHIFT, + .flags = INVERT_ENABLE, + .clkdm_name = "dpll4_clkdm", +}; + +DEFINE_STRUCT_CLK(dpll4_m2x2_ck, dpll4_m2x2_ck_parent_names, dpll4_m5x2_ck_ops); + +static struct clk dpll4_m2x2_ck_3630 = { + .name = "dpll4_m2x2_ck", + .hw = &dpll4_m2x2_ck_hw.hw, + .parent_names = dpll4_m2x2_ck_parent_names, + .num_parents = ARRAY_SIZE(dpll4_m2x2_ck_parent_names), + .ops = &dpll4_m5x2_ck_3630_ops, +}; + +static struct clk omap_96m_alwon_fck; + +static const char *omap_96m_alwon_fck_parent_names[] = { + "dpll4_m2x2_ck", +}; + +DEFINE_STRUCT_CLK_HW_OMAP(omap_96m_alwon_fck, NULL); +DEFINE_STRUCT_CLK(omap_96m_alwon_fck, omap_96m_alwon_fck_parent_names, + core_ck_ops); + +static struct clk cm_96m_fck; + +static const char *cm_96m_fck_parent_names[] = { + "omap_96m_alwon_fck", +}; + +DEFINE_STRUCT_CLK_HW_OMAP(cm_96m_fck, NULL); +DEFINE_STRUCT_CLK(cm_96m_fck, cm_96m_fck_parent_names, core_ck_ops); + +static const struct clksel_rate clkout2_src_54m_rates[] = { + { .div = 1, .val = 3, .flags = RATE_IN_3XXX }, + { .div = 0 } +}; + +DEFINE_CLK_DIVIDER_TABLE(dpll4_m3_ck, "dpll4_ck", &dpll4_ck, 0x0, + OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_TV_SHIFT, OMAP3630_CLKSEL_TV_WIDTH, + 0, dpll4_mx_ck_div_table, NULL); + +static struct clk dpll4_m3x2_ck; + +static const char *dpll4_m3x2_ck_parent_names[] = { + "dpll4_m3_ck", +}; + +static struct clk_hw_omap dpll4_m3x2_ck_hw = { + .hw = { + .clk = &dpll4_m3x2_ck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), + .enable_bit = OMAP3430_PWRDN_TV_SHIFT, + .flags = INVERT_ENABLE, + .clkdm_name = "dpll4_clkdm", +}; + +DEFINE_STRUCT_CLK(dpll4_m3x2_ck, dpll4_m3x2_ck_parent_names, dpll4_m5x2_ck_ops); + +static struct clk dpll4_m3x2_ck_3630 = { + .name = "dpll4_m3x2_ck", + .hw = &dpll4_m3x2_ck_hw.hw, + .parent_names = dpll4_m3x2_ck_parent_names, + .num_parents = ARRAY_SIZE(dpll4_m3x2_ck_parent_names), + .ops = &dpll4_m5x2_ck_3630_ops, +}; + +static const char *omap_54m_fck_parent_names[] = { + "dpll4_m3x2_ck", "sys_altclk", +}; + +DEFINE_CLK_MUX(omap_54m_fck, omap_54m_fck_parent_names, NULL, 0x0, + OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), OMAP3430_SOURCE_54M_SHIFT, + OMAP3430_SOURCE_54M_WIDTH, 0x0, NULL); + +static const struct clksel clkout2_src_clksel[] = { + { .parent = &core_ck, .rates = clkout2_src_core_rates }, + { .parent = &sys_ck, .rates = clkout2_src_sys_rates }, + { .parent = &cm_96m_fck, .rates = clkout2_src_96m_rates }, + { .parent = &omap_54m_fck, .rates = clkout2_src_54m_rates }, + { .parent = NULL }, +}; + +static const char *clkout2_src_ck_parent_names[] = { + "core_ck", "sys_ck", "cm_96m_fck", "omap_54m_fck", +}; + +static const struct clk_ops clkout2_src_ck_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, + .recalc_rate = &omap2_clksel_recalc, + .get_parent = &omap2_clksel_find_parent_index, + .set_parent = &omap2_clksel_set_parent, +}; + +DEFINE_CLK_OMAP_MUX_GATE(clkout2_src_ck, "core_clkdm", + clkout2_src_clksel, OMAP3430_CM_CLKOUT_CTRL, + OMAP3430_CLKOUT2SOURCE_MASK, + OMAP3430_CM_CLKOUT_CTRL, OMAP3430_CLKOUT2_EN_SHIFT, + NULL, clkout2_src_ck_parent_names, clkout2_src_ck_ops); + +static const struct clksel_rate omap_48m_cm96m_rates[] = { + { .div = 2, .val = 0, .flags = RATE_IN_3XXX }, + { .div = 0 } +}; + +static const struct clksel_rate omap_48m_alt_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, + { .div = 0 } +}; + +static const struct clksel omap_48m_clksel[] = { + { .parent = &cm_96m_fck, .rates = omap_48m_cm96m_rates }, + { .parent = &sys_altclk, .rates = omap_48m_alt_rates }, + { .parent = NULL }, +}; + +static const char *omap_48m_fck_parent_names[] = { + "cm_96m_fck", "sys_altclk", +}; + +static struct clk omap_48m_fck; + +static const struct clk_ops omap_48m_fck_ops = { + .recalc_rate = &omap2_clksel_recalc, + .get_parent = &omap2_clksel_find_parent_index, + .set_parent = &omap2_clksel_set_parent, +}; + +static struct clk_hw_omap omap_48m_fck_hw = { + .hw = { + .clk = &omap_48m_fck, + }, + .clksel = omap_48m_clksel, + .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), + .clksel_mask = OMAP3430_SOURCE_48M_MASK, +}; + +DEFINE_STRUCT_CLK(omap_48m_fck, omap_48m_fck_parent_names, omap_48m_fck_ops); + +DEFINE_CLK_FIXED_FACTOR(omap_12m_fck, "omap_48m_fck", &omap_48m_fck, 0x0, 1, 4); + +static struct clk core_12m_fck; + +static const char *core_12m_fck_parent_names[] = { + "omap_12m_fck", +}; + +DEFINE_STRUCT_CLK_HW_OMAP(core_12m_fck, "core_l4_clkdm"); +DEFINE_STRUCT_CLK(core_12m_fck, core_12m_fck_parent_names, core_l4_ick_ops); + +static struct clk core_48m_fck; + +static const char *core_48m_fck_parent_names[] = { + "omap_48m_fck", +}; + +DEFINE_STRUCT_CLK_HW_OMAP(core_48m_fck, "core_l4_clkdm"); +DEFINE_STRUCT_CLK(core_48m_fck, core_48m_fck_parent_names, core_l4_ick_ops); + +static const char *omap_96m_fck_parent_names[] = { + "cm_96m_fck", "sys_ck", +}; + +DEFINE_CLK_MUX(omap_96m_fck, omap_96m_fck_parent_names, NULL, 0x0, + OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), + OMAP3430_SOURCE_96M_SHIFT, OMAP3430_SOURCE_96M_WIDTH, 0x0, NULL); + +static struct clk core_96m_fck; + +static const char *core_96m_fck_parent_names[] = { + "omap_96m_fck", +}; + +DEFINE_STRUCT_CLK_HW_OMAP(core_96m_fck, "core_l4_clkdm"); +DEFINE_STRUCT_CLK(core_96m_fck, core_96m_fck_parent_names, core_l4_ick_ops); + +static struct clk core_l3_ick; + +static const char *core_l3_ick_parent_names[] = { + "l3_ick", +}; + +DEFINE_STRUCT_CLK_HW_OMAP(core_l3_ick, "core_l3_clkdm"); +DEFINE_STRUCT_CLK(core_l3_ick, core_l3_ick_parent_names, core_l4_ick_ops); + +DEFINE_CLK_FIXED_FACTOR(dpll3_m2x2_ck, "dpll3_m2_ck", &dpll3_m2_ck, 0x0, 2, 1); + +static struct clk corex2_fck; + +static const char *corex2_fck_parent_names[] = { + "dpll3_m2x2_ck", +}; + +DEFINE_STRUCT_CLK_HW_OMAP(corex2_fck, NULL); +DEFINE_STRUCT_CLK(corex2_fck, corex2_fck_parent_names, core_ck_ops); + +static struct clk cpefuse_fck; + +static struct clk_hw_omap cpefuse_fck_hw = { + .hw = { + .clk = &cpefuse_fck, + }, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3), + .enable_bit = OMAP3430ES2_EN_CPEFUSE_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(cpefuse_fck, dpll3_ck_parent_names, aes2_ick_ops); + +static struct clk csi2_96m_fck; + +static const char *csi2_96m_fck_parent_names[] = { + "core_96m_fck", +}; + +static struct clk_hw_omap csi2_96m_fck_hw = { + .hw = { + .clk = &csi2_96m_fck, + }, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_EN_CSI2_SHIFT, + .clkdm_name = "cam_clkdm", +}; + +DEFINE_STRUCT_CLK(csi2_96m_fck, csi2_96m_fck_parent_names, aes2_ick_ops); + +static struct clk d2d_26m_fck; + +static struct clk_hw_omap d2d_26m_fck_hw = { + .hw = { + .clk = &d2d_26m_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP3430ES1_EN_D2D_SHIFT, + .clkdm_name = "d2d_clkdm", +}; + +DEFINE_STRUCT_CLK(d2d_26m_fck, dpll3_ck_parent_names, aes2_ick_ops); + +static struct clk des1_ick; + +static struct clk_hw_omap des1_ick_hw = { + .hw = { + .clk = &des1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP3430_EN_DES1_SHIFT, +}; + +DEFINE_STRUCT_CLK(des1_ick, aes1_ick_parent_names, aes1_ick_ops); + +static struct clk des2_ick; + +static struct clk_hw_omap des2_ick_hw = { + .hw = { + .clk = &des2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_DES2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(des2_ick, aes2_ick_parent_names, aes2_ick_ops); + +DEFINE_CLK_DIVIDER(dpll1_fck, "core_ck", &core_ck, 0x0, + OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL), + OMAP3430_MPU_CLK_SRC_SHIFT, OMAP3430_MPU_CLK_SRC_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +static struct clk dpll2_fck; + +static struct dpll_data dpll2_dd = { + .mult_div1_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL), + .mult_mask = OMAP3430_IVA2_DPLL_MULT_MASK, + .div1_mask = OMAP3430_IVA2_DPLL_DIV_MASK, + .clk_bypass = &dpll2_fck, + .clk_ref = &sys_ck, + .freqsel_mask = OMAP3430_IVA2_DPLL_FREQSEL_MASK, + .control_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL), + .enable_mask = OMAP3430_EN_IVA2_DPLL_MASK, + .modes = ((1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED) | + (1 << DPLL_LOW_POWER_BYPASS)), + .auto_recal_bit = OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_SHIFT, + .recal_en_bit = OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT, + .recal_st_bit = OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT, + .autoidle_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL), + .autoidle_mask = OMAP3430_AUTO_IVA2_DPLL_MASK, + .idlest_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL), + .idlest_mask = OMAP3430_ST_IVA2_CLK_MASK, + .max_multiplier = OMAP3_MAX_DPLL_MULT, + .min_divider = 1, + .max_divider = OMAP3_MAX_DPLL_DIV, +}; + +static struct clk dpll2_ck; + +static struct clk_hw_omap dpll2_ck_hw = { + .hw = { + .clk = &dpll2_ck, + }, + .ops = &clkhwops_omap3_dpll, + .dpll_data = &dpll2_dd, + .clkdm_name = "dpll2_clkdm", +}; + +DEFINE_STRUCT_CLK(dpll2_ck, dpll3_ck_parent_names, dpll1_ck_ops); + +DEFINE_CLK_DIVIDER(dpll2_fck, "core_ck", &core_ck, 0x0, + OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL), + OMAP3430_IVA2_CLK_SRC_SHIFT, OMAP3430_IVA2_CLK_SRC_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +DEFINE_CLK_DIVIDER(dpll2_m2_ck, "dpll2_ck", &dpll2_ck, 0x0, + OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL2_PLL), + OMAP3430_IVA2_DPLL_CLKOUT_DIV_SHIFT, + OMAP3430_IVA2_DPLL_CLKOUT_DIV_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +DEFINE_CLK_DIVIDER(dpll3_m3_ck, "dpll3_ck", &dpll3_ck, 0x0, + OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), + OMAP3430_DIV_DPLL3_SHIFT, OMAP3430_DIV_DPLL3_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +static struct clk dpll3_m3x2_ck; + +static const char *dpll3_m3x2_ck_parent_names[] = { + "dpll3_m3_ck", +}; + +static struct clk_hw_omap dpll3_m3x2_ck_hw = { + .hw = { + .clk = &dpll3_m3x2_ck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), + .enable_bit = OMAP3430_PWRDN_EMU_CORE_SHIFT, + .flags = INVERT_ENABLE, + .clkdm_name = "dpll3_clkdm", +}; + +DEFINE_STRUCT_CLK(dpll3_m3x2_ck, dpll3_m3x2_ck_parent_names, dpll4_m5x2_ck_ops); + +static struct clk dpll3_m3x2_ck_3630 = { + .name = "dpll3_m3x2_ck", + .hw = &dpll3_m3x2_ck_hw.hw, + .parent_names = dpll3_m3x2_ck_parent_names, + .num_parents = ARRAY_SIZE(dpll3_m3x2_ck_parent_names), + .ops = &dpll4_m5x2_ck_3630_ops, +}; + +DEFINE_CLK_FIXED_FACTOR(dpll3_x2_ck, "dpll3_ck", &dpll3_ck, 0x0, 2, 1); + +DEFINE_CLK_DIVIDER_TABLE(dpll4_m4_ck, "dpll4_ck", &dpll4_ck, 0x0, + OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_DSS1_SHIFT, OMAP3630_CLKSEL_DSS1_WIDTH, + 0, dpll4_mx_ck_div_table, NULL); + +static struct clk dpll4_m4x2_ck; + +static const char *dpll4_m4x2_ck_parent_names[] = { + "dpll4_m4_ck", +}; + +static struct clk_hw_omap dpll4_m4x2_ck_hw = { + .hw = { + .clk = &dpll4_m4x2_ck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), + .enable_bit = OMAP3430_PWRDN_DSS1_SHIFT, + .flags = INVERT_ENABLE, + .clkdm_name = "dpll4_clkdm", +}; + +DEFINE_STRUCT_CLK_FLAGS(dpll4_m4x2_ck, dpll4_m4x2_ck_parent_names, + dpll4_m5x2_ck_ops, CLK_SET_RATE_PARENT); + +static struct clk dpll4_m4x2_ck_3630 = { + .name = "dpll4_m4x2_ck", + .hw = &dpll4_m4x2_ck_hw.hw, + .parent_names = dpll4_m4x2_ck_parent_names, + .num_parents = ARRAY_SIZE(dpll4_m4x2_ck_parent_names), + .ops = &dpll4_m5x2_ck_3630_ops, + .flags = CLK_SET_RATE_PARENT, +}; + +DEFINE_CLK_DIVIDER(dpll4_m6_ck, "dpll4_ck", &dpll4_ck, 0x0, + OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), + OMAP3430_DIV_DPLL4_SHIFT, OMAP3630_DIV_DPLL4_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +static struct clk dpll4_m6x2_ck; + +static const char *dpll4_m6x2_ck_parent_names[] = { + "dpll4_m6_ck", +}; + +static struct clk_hw_omap dpll4_m6x2_ck_hw = { + .hw = { + .clk = &dpll4_m6x2_ck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), + .enable_bit = OMAP3430_PWRDN_EMU_PERIPH_SHIFT, + .flags = INVERT_ENABLE, + .clkdm_name = "dpll4_clkdm", +}; + +DEFINE_STRUCT_CLK(dpll4_m6x2_ck, dpll4_m6x2_ck_parent_names, dpll4_m5x2_ck_ops); + +static struct clk dpll4_m6x2_ck_3630 = { + .name = "dpll4_m6x2_ck", + .hw = &dpll4_m6x2_ck_hw.hw, + .parent_names = dpll4_m6x2_ck_parent_names, + .num_parents = ARRAY_SIZE(dpll4_m6x2_ck_parent_names), + .ops = &dpll4_m5x2_ck_3630_ops, +}; + +DEFINE_CLK_FIXED_FACTOR(dpll4_x2_ck, "dpll4_ck", &dpll4_ck, 0x0, 2, 1); + +static struct dpll_data dpll5_dd = { + .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL4), + .mult_mask = OMAP3430ES2_PERIPH2_DPLL_MULT_MASK, + .div1_mask = OMAP3430ES2_PERIPH2_DPLL_DIV_MASK, + .clk_bypass = &sys_ck, + .clk_ref = &sys_ck, + .freqsel_mask = OMAP3430ES2_PERIPH2_DPLL_FREQSEL_MASK, + .control_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKEN2), + .enable_mask = OMAP3430ES2_EN_PERIPH2_DPLL_MASK, + .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), + .auto_recal_bit = OMAP3430ES2_EN_PERIPH2_DPLL_DRIFTGUARD_SHIFT, + .recal_en_bit = OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT, + .recal_st_bit = OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT, + .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_AUTOIDLE2_PLL), + .autoidle_mask = OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK, + .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2), + .idlest_mask = OMAP3430ES2_ST_PERIPH2_CLK_MASK, + .max_multiplier = OMAP3_MAX_DPLL_MULT, + .min_divider = 1, + .max_divider = OMAP3_MAX_DPLL_DIV, +}; + +static struct clk dpll5_ck; + +static struct clk_hw_omap dpll5_ck_hw = { + .hw = { + .clk = &dpll5_ck, + }, + .ops = &clkhwops_omap3_dpll, + .dpll_data = &dpll5_dd, + .clkdm_name = "dpll5_clkdm", +}; + +DEFINE_STRUCT_CLK(dpll5_ck, dpll3_ck_parent_names, dpll1_ck_ops); + +DEFINE_CLK_DIVIDER(dpll5_m2_ck, "dpll5_ck", &dpll5_ck, 0x0, + OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL5), + OMAP3430ES2_DIV_120M_SHIFT, OMAP3430ES2_DIV_120M_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +static struct clk dss1_alwon_fck_3430es1; + +static const char *dss1_alwon_fck_3430es1_parent_names[] = { + "dpll4_m4x2_ck", +}; + +static struct clk_hw_omap dss1_alwon_fck_3430es1_hw = { + .hw = { + .clk = &dss1_alwon_fck_3430es1, + }, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_EN_DSS1_SHIFT, + .clkdm_name = "dss_clkdm", +}; + +DEFINE_STRUCT_CLK_FLAGS(dss1_alwon_fck_3430es1, + dss1_alwon_fck_3430es1_parent_names, aes2_ick_ops, + CLK_SET_RATE_PARENT); + +static struct clk dss1_alwon_fck_3430es2; + +static struct clk_hw_omap dss1_alwon_fck_3430es2_hw = { + .hw = { + .clk = &dss1_alwon_fck_3430es2, + }, + .ops = &clkhwops_omap3430es2_dss_usbhost_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_EN_DSS1_SHIFT, + .clkdm_name = "dss_clkdm", +}; + +DEFINE_STRUCT_CLK_FLAGS(dss1_alwon_fck_3430es2, + dss1_alwon_fck_3430es1_parent_names, aes2_ick_ops, + CLK_SET_RATE_PARENT); + +static struct clk dss2_alwon_fck; + +static struct clk_hw_omap dss2_alwon_fck_hw = { + .hw = { + .clk = &dss2_alwon_fck, + }, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_EN_DSS2_SHIFT, + .clkdm_name = "dss_clkdm", +}; + +DEFINE_STRUCT_CLK(dss2_alwon_fck, dpll3_ck_parent_names, aes2_ick_ops); + +static struct clk dss_96m_fck; + +static struct clk_hw_omap dss_96m_fck_hw = { + .hw = { + .clk = &dss_96m_fck, + }, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_EN_TV_SHIFT, + .clkdm_name = "dss_clkdm", +}; + +DEFINE_STRUCT_CLK(dss_96m_fck, core_96m_fck_parent_names, aes2_ick_ops); + +static struct clk dss_ick_3430es1; + +static struct clk_hw_omap dss_ick_3430es1_hw = { + .hw = { + .clk = &dss_ick_3430es1, + }, + .ops = &clkhwops_iclk, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT, + .clkdm_name = "dss_clkdm", +}; + +DEFINE_STRUCT_CLK(dss_ick_3430es1, security_l4_ick2_parent_names, aes2_ick_ops); + +static struct clk dss_ick_3430es2; + +static struct clk_hw_omap dss_ick_3430es2_hw = { + .hw = { + .clk = &dss_ick_3430es2, + }, + .ops = &clkhwops_omap3430es2_iclk_dss_usbhost_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT, + .clkdm_name = "dss_clkdm", +}; + +DEFINE_STRUCT_CLK(dss_ick_3430es2, security_l4_ick2_parent_names, aes2_ick_ops); + +static struct clk dss_tv_fck; + +static const char *dss_tv_fck_parent_names[] = { + "omap_54m_fck", +}; + +static struct clk_hw_omap dss_tv_fck_hw = { + .hw = { + .clk = &dss_tv_fck, + }, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_EN_TV_SHIFT, + .clkdm_name = "dss_clkdm", +}; + +DEFINE_STRUCT_CLK(dss_tv_fck, dss_tv_fck_parent_names, aes2_ick_ops); + +static struct clk emac_fck; + +static const char *emac_fck_parent_names[] = { + "rmii_ck", +}; + +static struct clk_hw_omap emac_fck_hw = { + .hw = { + .clk = &emac_fck, + }, + .enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL), + .enable_bit = AM35XX_CPGMAC_FCLK_SHIFT, +}; + +DEFINE_STRUCT_CLK(emac_fck, emac_fck_parent_names, aes1_ick_ops); + +static struct clk ipss_ick; + +static const char *ipss_ick_parent_names[] = { + "core_l3_ick", +}; + +static struct clk_hw_omap ipss_ick_hw = { + .hw = { + .clk = &ipss_ick, + }, + .ops = &clkhwops_am35xx_ipss_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = AM35XX_EN_IPSS_SHIFT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(ipss_ick, ipss_ick_parent_names, aes2_ick_ops); + +static struct clk emac_ick; + +static const char *emac_ick_parent_names[] = { + "ipss_ick", +}; + +static struct clk_hw_omap emac_ick_hw = { + .hw = { + .clk = &emac_ick, + }, + .ops = &clkhwops_am35xx_ipss_module_wait, + .enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL), + .enable_bit = AM35XX_CPGMAC_VBUSP_CLK_SHIFT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(emac_ick, emac_ick_parent_names, aes2_ick_ops); + +static struct clk emu_core_alwon_ck; + +static const char *emu_core_alwon_ck_parent_names[] = { + "dpll3_m3x2_ck", +}; + +DEFINE_STRUCT_CLK_HW_OMAP(emu_core_alwon_ck, "dpll3_clkdm"); +DEFINE_STRUCT_CLK(emu_core_alwon_ck, emu_core_alwon_ck_parent_names, + core_l4_ick_ops); + +static struct clk emu_mpu_alwon_ck; + +static const char *emu_mpu_alwon_ck_parent_names[] = { + "mpu_ck", +}; + +DEFINE_STRUCT_CLK_HW_OMAP(emu_mpu_alwon_ck, NULL); +DEFINE_STRUCT_CLK(emu_mpu_alwon_ck, emu_mpu_alwon_ck_parent_names, core_ck_ops); + +static struct clk emu_per_alwon_ck; + +static const char *emu_per_alwon_ck_parent_names[] = { + "dpll4_m6x2_ck", +}; + +DEFINE_STRUCT_CLK_HW_OMAP(emu_per_alwon_ck, "dpll4_clkdm"); +DEFINE_STRUCT_CLK(emu_per_alwon_ck, emu_per_alwon_ck_parent_names, + core_l4_ick_ops); + +static const char *emu_src_ck_parent_names[] = { + "sys_ck", "emu_core_alwon_ck", "emu_per_alwon_ck", "emu_mpu_alwon_ck", +}; + +static const struct clksel_rate emu_src_sys_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_3XXX }, + { .div = 0 }, +}; + +static const struct clksel_rate emu_src_core_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, + { .div = 0 }, +}; + +static const struct clksel_rate emu_src_per_rates[] = { + { .div = 1, .val = 2, .flags = RATE_IN_3XXX }, + { .div = 0 }, +}; + +static const struct clksel_rate emu_src_mpu_rates[] = { + { .div = 1, .val = 3, .flags = RATE_IN_3XXX }, + { .div = 0 }, +}; + +static const struct clksel emu_src_clksel[] = { + { .parent = &sys_ck, .rates = emu_src_sys_rates }, + { .parent = &emu_core_alwon_ck, .rates = emu_src_core_rates }, + { .parent = &emu_per_alwon_ck, .rates = emu_src_per_rates }, + { .parent = &emu_mpu_alwon_ck, .rates = emu_src_mpu_rates }, + { .parent = NULL }, +}; + +static const struct clk_ops emu_src_ck_ops = { + .init = &omap2_init_clk_clkdm, + .recalc_rate = &omap2_clksel_recalc, + .get_parent = &omap2_clksel_find_parent_index, + .set_parent = &omap2_clksel_set_parent, + .enable = &omap2_clkops_enable_clkdm, + .disable = &omap2_clkops_disable_clkdm, +}; + +static struct clk emu_src_ck; + +static struct clk_hw_omap emu_src_ck_hw = { + .hw = { + .clk = &emu_src_ck, + }, + .clksel = emu_src_clksel, + .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), + .clksel_mask = OMAP3430_MUX_CTRL_MASK, + .clkdm_name = "emu_clkdm", +}; + +DEFINE_STRUCT_CLK(emu_src_ck, emu_src_ck_parent_names, emu_src_ck_ops); + +DEFINE_CLK_DIVIDER(atclk_fck, "emu_src_ck", &emu_src_ck, 0x0, + OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), + OMAP3430_CLKSEL_ATCLK_SHIFT, OMAP3430_CLKSEL_ATCLK_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +static struct clk fac_ick; + +static struct clk_hw_omap fac_ick_hw = { + .hw = { + .clk = &fac_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430ES1_EN_FAC_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(fac_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk fshostusb_fck; + +static const char *fshostusb_fck_parent_names[] = { + "core_48m_fck", +}; + +static struct clk_hw_omap fshostusb_fck_hw = { + .hw = { + .clk = &fshostusb_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP3430ES1_EN_FSHOSTUSB_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(fshostusb_fck, fshostusb_fck_parent_names, aes2_ick_ops); + +static struct clk gfx_l3_ck; + +static struct clk_hw_omap gfx_l3_ck_hw = { + .hw = { + .clk = &gfx_l3_ck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN), + .enable_bit = OMAP_EN_GFX_SHIFT, + .clkdm_name = "gfx_3430es1_clkdm", +}; + +DEFINE_STRUCT_CLK(gfx_l3_ck, core_l3_ick_parent_names, aes1_ick_ops); + +DEFINE_CLK_DIVIDER(gfx_l3_fck, "l3_ick", &l3_ick, 0x0, + OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL), + OMAP_CLKSEL_GFX_SHIFT, OMAP_CLKSEL_GFX_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +static struct clk gfx_cg1_ck; + +static const char *gfx_cg1_ck_parent_names[] = { + "gfx_l3_fck", +}; + +static struct clk_hw_omap gfx_cg1_ck_hw = { + .hw = { + .clk = &gfx_cg1_ck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), + .enable_bit = OMAP3430ES1_EN_2D_SHIFT, + .clkdm_name = "gfx_3430es1_clkdm", +}; + +DEFINE_STRUCT_CLK(gfx_cg1_ck, gfx_cg1_ck_parent_names, aes2_ick_ops); + +static struct clk gfx_cg2_ck; + +static struct clk_hw_omap gfx_cg2_ck_hw = { + .hw = { + .clk = &gfx_cg2_ck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), + .enable_bit = OMAP3430ES1_EN_3D_SHIFT, + .clkdm_name = "gfx_3430es1_clkdm", +}; + +DEFINE_STRUCT_CLK(gfx_cg2_ck, gfx_cg1_ck_parent_names, aes2_ick_ops); + +static struct clk gfx_l3_ick; + +static const char *gfx_l3_ick_parent_names[] = { + "gfx_l3_ck", +}; + +DEFINE_STRUCT_CLK_HW_OMAP(gfx_l3_ick, "gfx_3430es1_clkdm"); +DEFINE_STRUCT_CLK(gfx_l3_ick, gfx_l3_ick_parent_names, core_l4_ick_ops); + +static struct clk wkup_32k_fck; + +static const char *wkup_32k_fck_parent_names[] = { + "omap_32k_fck", +}; + +DEFINE_STRUCT_CLK_HW_OMAP(wkup_32k_fck, "wkup_clkdm"); +DEFINE_STRUCT_CLK(wkup_32k_fck, wkup_32k_fck_parent_names, core_l4_ick_ops); + +static struct clk gpio1_dbck; + +static const char *gpio1_dbck_parent_names[] = { + "wkup_32k_fck", +}; + +static struct clk_hw_omap gpio1_dbck_hw = { + .hw = { + .clk = &gpio1_dbck, + }, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_EN_GPIO1_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(gpio1_dbck, gpio1_dbck_parent_names, aes2_ick_ops); + +static struct clk wkup_l4_ick; + +DEFINE_STRUCT_CLK_HW_OMAP(wkup_l4_ick, "wkup_clkdm"); +DEFINE_STRUCT_CLK(wkup_l4_ick, dpll3_ck_parent_names, core_l4_ick_ops); + +static struct clk gpio1_ick; + +static const char *gpio1_ick_parent_names[] = { + "wkup_l4_ick", +}; + +static struct clk_hw_omap gpio1_ick_hw = { + .hw = { + .clk = &gpio1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_GPIO1_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(gpio1_ick, gpio1_ick_parent_names, aes2_ick_ops); + +static struct clk per_32k_alwon_fck; + +DEFINE_STRUCT_CLK_HW_OMAP(per_32k_alwon_fck, "per_clkdm"); +DEFINE_STRUCT_CLK(per_32k_alwon_fck, wkup_32k_fck_parent_names, + core_l4_ick_ops); + +static struct clk gpio2_dbck; + +static const char *gpio2_dbck_parent_names[] = { + "per_32k_alwon_fck", +}; + +static struct clk_hw_omap gpio2_dbck_hw = { + .hw = { + .clk = &gpio2_dbck, + }, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_EN_GPIO2_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(gpio2_dbck, gpio2_dbck_parent_names, aes2_ick_ops); + +static struct clk per_l4_ick; + +DEFINE_STRUCT_CLK_HW_OMAP(per_l4_ick, "per_clkdm"); +DEFINE_STRUCT_CLK(per_l4_ick, security_l4_ick2_parent_names, core_l4_ick_ops); + +static struct clk gpio2_ick; + +static const char *gpio2_ick_parent_names[] = { + "per_l4_ick", +}; + +static struct clk_hw_omap gpio2_ick_hw = { + .hw = { + .clk = &gpio2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_GPIO2_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(gpio2_ick, gpio2_ick_parent_names, aes2_ick_ops); + +static struct clk gpio3_dbck; + +static struct clk_hw_omap gpio3_dbck_hw = { + .hw = { + .clk = &gpio3_dbck, + }, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_EN_GPIO3_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(gpio3_dbck, gpio2_dbck_parent_names, aes2_ick_ops); + +static struct clk gpio3_ick; + +static struct clk_hw_omap gpio3_ick_hw = { + .hw = { + .clk = &gpio3_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_GPIO3_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(gpio3_ick, gpio2_ick_parent_names, aes2_ick_ops); + +static struct clk gpio4_dbck; + +static struct clk_hw_omap gpio4_dbck_hw = { + .hw = { + .clk = &gpio4_dbck, + }, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_EN_GPIO4_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(gpio4_dbck, gpio2_dbck_parent_names, aes2_ick_ops); + +static struct clk gpio4_ick; + +static struct clk_hw_omap gpio4_ick_hw = { + .hw = { + .clk = &gpio4_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_GPIO4_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(gpio4_ick, gpio2_ick_parent_names, aes2_ick_ops); + +static struct clk gpio5_dbck; + +static struct clk_hw_omap gpio5_dbck_hw = { + .hw = { + .clk = &gpio5_dbck, + }, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_EN_GPIO5_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(gpio5_dbck, gpio2_dbck_parent_names, aes2_ick_ops); + +static struct clk gpio5_ick; + +static struct clk_hw_omap gpio5_ick_hw = { + .hw = { + .clk = &gpio5_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_GPIO5_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(gpio5_ick, gpio2_ick_parent_names, aes2_ick_ops); + +static struct clk gpio6_dbck; + +static struct clk_hw_omap gpio6_dbck_hw = { + .hw = { + .clk = &gpio6_dbck, + }, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_EN_GPIO6_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(gpio6_dbck, gpio2_dbck_parent_names, aes2_ick_ops); + +static struct clk gpio6_ick; + +static struct clk_hw_omap gpio6_ick_hw = { + .hw = { + .clk = &gpio6_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_GPIO6_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(gpio6_ick, gpio2_ick_parent_names, aes2_ick_ops); + +static struct clk gpmc_fck; + +static struct clk_hw_omap gpmc_fck_hw = { + .hw = { + .clk = &gpmc_fck, + }, + .flags = ENABLE_ON_INIT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(gpmc_fck, ipss_ick_parent_names, core_l4_ick_ops); + +static const struct clksel omap343x_gpt_clksel[] = { + { .parent = &omap_32k_fck, .rates = gpt_32k_rates }, + { .parent = &sys_ck, .rates = gpt_sys_rates }, + { .parent = NULL }, +}; + +static const char *gpt10_fck_parent_names[] = { + "omap_32k_fck", "sys_ck", +}; + +DEFINE_CLK_OMAP_MUX_GATE(gpt10_fck, "core_l4_clkdm", omap343x_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_GPT10_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP3430_EN_GPT10_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, clkout2_src_ck_ops); + +static struct clk gpt10_ick; + +static struct clk_hw_omap gpt10_ick_hw = { + .hw = { + .clk = &gpt10_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_GPT10_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt10_ick, aes2_ick_parent_names, aes2_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt11_fck, "core_l4_clkdm", omap343x_gpt_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_GPT11_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP3430_EN_GPT11_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, clkout2_src_ck_ops); + +static struct clk gpt11_ick; + +static struct clk_hw_omap gpt11_ick_hw = { + .hw = { + .clk = &gpt11_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_GPT11_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt11_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk gpt12_fck; + +static const char *gpt12_fck_parent_names[] = { + "secure_32k_fck", +}; + +DEFINE_STRUCT_CLK_HW_OMAP(gpt12_fck, "wkup_clkdm"); +DEFINE_STRUCT_CLK(gpt12_fck, gpt12_fck_parent_names, core_l4_ick_ops); + +static struct clk gpt12_ick; + +static struct clk_hw_omap gpt12_ick_hw = { + .hw = { + .clk = &gpt12_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_GPT12_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt12_ick, gpio1_ick_parent_names, aes2_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt1_fck, "wkup_clkdm", omap343x_gpt_clksel, + OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_GPT1_MASK, + OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), + OMAP3430_EN_GPT1_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, clkout2_src_ck_ops); + +static struct clk gpt1_ick; + +static struct clk_hw_omap gpt1_ick_hw = { + .hw = { + .clk = &gpt1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_GPT1_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt1_ick, gpio1_ick_parent_names, aes2_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt2_fck, "per_clkdm", omap343x_gpt_clksel, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_GPT2_MASK, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + OMAP3430_EN_GPT2_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, clkout2_src_ck_ops); + +static struct clk gpt2_ick; + +static struct clk_hw_omap gpt2_ick_hw = { + .hw = { + .clk = &gpt2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_GPT2_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt2_ick, gpio2_ick_parent_names, aes2_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt3_fck, "per_clkdm", omap343x_gpt_clksel, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_GPT3_MASK, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + OMAP3430_EN_GPT3_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, clkout2_src_ck_ops); + +static struct clk gpt3_ick; + +static struct clk_hw_omap gpt3_ick_hw = { + .hw = { + .clk = &gpt3_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_GPT3_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt3_ick, gpio2_ick_parent_names, aes2_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt4_fck, "per_clkdm", omap343x_gpt_clksel, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_GPT4_MASK, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + OMAP3430_EN_GPT4_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, clkout2_src_ck_ops); + +static struct clk gpt4_ick; + +static struct clk_hw_omap gpt4_ick_hw = { + .hw = { + .clk = &gpt4_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_GPT4_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt4_ick, gpio2_ick_parent_names, aes2_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt5_fck, "per_clkdm", omap343x_gpt_clksel, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_GPT5_MASK, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + OMAP3430_EN_GPT5_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, clkout2_src_ck_ops); + +static struct clk gpt5_ick; + +static struct clk_hw_omap gpt5_ick_hw = { + .hw = { + .clk = &gpt5_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_GPT5_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt5_ick, gpio2_ick_parent_names, aes2_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt6_fck, "per_clkdm", omap343x_gpt_clksel, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_GPT6_MASK, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + OMAP3430_EN_GPT6_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, clkout2_src_ck_ops); + +static struct clk gpt6_ick; + +static struct clk_hw_omap gpt6_ick_hw = { + .hw = { + .clk = &gpt6_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_GPT6_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt6_ick, gpio2_ick_parent_names, aes2_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt7_fck, "per_clkdm", omap343x_gpt_clksel, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_GPT7_MASK, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + OMAP3430_EN_GPT7_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, clkout2_src_ck_ops); + +static struct clk gpt7_ick; + +static struct clk_hw_omap gpt7_ick_hw = { + .hw = { + .clk = &gpt7_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_GPT7_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt7_ick, gpio2_ick_parent_names, aes2_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt8_fck, "per_clkdm", omap343x_gpt_clksel, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_GPT8_MASK, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + OMAP3430_EN_GPT8_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, clkout2_src_ck_ops); + +static struct clk gpt8_ick; + +static struct clk_hw_omap gpt8_ick_hw = { + .hw = { + .clk = &gpt8_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_GPT8_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt8_ick, gpio2_ick_parent_names, aes2_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(gpt9_fck, "per_clkdm", omap343x_gpt_clksel, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_GPT9_MASK, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + OMAP3430_EN_GPT9_SHIFT, &clkhwops_wait, + gpt10_fck_parent_names, clkout2_src_ck_ops); + +static struct clk gpt9_ick; + +static struct clk_hw_omap gpt9_ick_hw = { + .hw = { + .clk = &gpt9_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_GPT9_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(gpt9_ick, gpio2_ick_parent_names, aes2_ick_ops); + +static struct clk hdq_fck; + +static const char *hdq_fck_parent_names[] = { + "core_12m_fck", +}; + +static struct clk_hw_omap hdq_fck_hw = { + .hw = { + .clk = &hdq_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP3430_EN_HDQ_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(hdq_fck, hdq_fck_parent_names, aes2_ick_ops); + +static struct clk hdq_ick; + +static struct clk_hw_omap hdq_ick_hw = { + .hw = { + .clk = &hdq_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_HDQ_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(hdq_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk hecc_ck; + +static struct clk_hw_omap hecc_ck_hw = { + .hw = { + .clk = &hecc_ck, + }, + .ops = &clkhwops_am35xx_ipss_module_wait, + .enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL), + .enable_bit = AM35XX_HECC_VBUSP_CLK_SHIFT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(hecc_ck, dpll3_ck_parent_names, aes2_ick_ops); + +static struct clk hsotgusb_fck_am35xx; + +static struct clk_hw_omap hsotgusb_fck_am35xx_hw = { + .hw = { + .clk = &hsotgusb_fck_am35xx, + }, + .enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL), + .enable_bit = AM35XX_USBOTG_FCLK_SHIFT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(hsotgusb_fck_am35xx, dpll3_ck_parent_names, aes2_ick_ops); + +static struct clk hsotgusb_ick_3430es1; + +static struct clk_hw_omap hsotgusb_ick_3430es1_hw = { + .hw = { + .clk = &hsotgusb_ick_3430es1, + }, + .ops = &clkhwops_iclk, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_HSOTGUSB_SHIFT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(hsotgusb_ick_3430es1, ipss_ick_parent_names, aes2_ick_ops); + +static struct clk hsotgusb_ick_3430es2; + +static struct clk_hw_omap hsotgusb_ick_3430es2_hw = { + .hw = { + .clk = &hsotgusb_ick_3430es2, + }, + .ops = &clkhwops_omap3430es2_iclk_hsotgusb_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_HSOTGUSB_SHIFT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(hsotgusb_ick_3430es2, ipss_ick_parent_names, aes2_ick_ops); + +static struct clk hsotgusb_ick_am35xx; + +static struct clk_hw_omap hsotgusb_ick_am35xx_hw = { + .hw = { + .clk = &hsotgusb_ick_am35xx, + }, + .ops = &clkhwops_am35xx_ipss_module_wait, + .enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL), + .enable_bit = AM35XX_USBOTG_VBUSP_CLK_SHIFT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(hsotgusb_ick_am35xx, emac_ick_parent_names, aes2_ick_ops); + +static struct clk i2c1_fck; + +static struct clk_hw_omap i2c1_fck_hw = { + .hw = { + .clk = &i2c1_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP3430_EN_I2C1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(i2c1_fck, csi2_96m_fck_parent_names, aes2_ick_ops); + +static struct clk i2c1_ick; + +static struct clk_hw_omap i2c1_ick_hw = { + .hw = { + .clk = &i2c1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_I2C1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(i2c1_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk i2c2_fck; + +static struct clk_hw_omap i2c2_fck_hw = { + .hw = { + .clk = &i2c2_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP3430_EN_I2C2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(i2c2_fck, csi2_96m_fck_parent_names, aes2_ick_ops); + +static struct clk i2c2_ick; + +static struct clk_hw_omap i2c2_ick_hw = { + .hw = { + .clk = &i2c2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_I2C2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(i2c2_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk i2c3_fck; + +static struct clk_hw_omap i2c3_fck_hw = { + .hw = { + .clk = &i2c3_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP3430_EN_I2C3_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(i2c3_fck, csi2_96m_fck_parent_names, aes2_ick_ops); + +static struct clk i2c3_ick; + +static struct clk_hw_omap i2c3_ick_hw = { + .hw = { + .clk = &i2c3_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_I2C3_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(i2c3_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk icr_ick; + +static struct clk_hw_omap icr_ick_hw = { + .hw = { + .clk = &icr_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_ICR_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(icr_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk iva2_ck; + +static const char *iva2_ck_parent_names[] = { + "dpll2_m2_ck", +}; + +static struct clk_hw_omap iva2_ck_hw = { + .hw = { + .clk = &iva2_ck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT, + .clkdm_name = "iva2_clkdm", +}; + +DEFINE_STRUCT_CLK(iva2_ck, iva2_ck_parent_names, aes2_ick_ops); + +static struct clk mad2d_ick; + +static struct clk_hw_omap mad2d_ick_hw = { + .hw = { + .clk = &mad2d_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), + .enable_bit = OMAP3430_EN_MAD2D_SHIFT, + .clkdm_name = "d2d_clkdm", +}; + +DEFINE_STRUCT_CLK(mad2d_ick, core_l3_ick_parent_names, aes2_ick_ops); + +static struct clk mailboxes_ick; + +static struct clk_hw_omap mailboxes_ick_hw = { + .hw = { + .clk = &mailboxes_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_MAILBOXES_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mailboxes_ick, aes2_ick_parent_names, aes2_ick_ops); + +static const struct clksel_rate common_mcbsp_96m_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_3XXX }, + { .div = 0 } +}; + +static const struct clksel_rate common_mcbsp_mcbsp_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, + { .div = 0 } +}; + +static const struct clksel mcbsp_15_clksel[] = { + { .parent = &core_96m_fck, .rates = common_mcbsp_96m_rates }, + { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates }, + { .parent = NULL }, +}; + +static const char *mcbsp1_fck_parent_names[] = { + "core_96m_fck", "mcbsp_clks", +}; + +DEFINE_CLK_OMAP_MUX_GATE(mcbsp1_fck, "core_l4_clkdm", mcbsp_15_clksel, + OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0), + OMAP2_MCBSP1_CLKS_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP3430_EN_MCBSP1_SHIFT, &clkhwops_wait, + mcbsp1_fck_parent_names, clkout2_src_ck_ops); + +static struct clk mcbsp1_ick; + +static struct clk_hw_omap mcbsp1_ick_hw = { + .hw = { + .clk = &mcbsp1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_MCBSP1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcbsp1_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk per_96m_fck; + +DEFINE_STRUCT_CLK_HW_OMAP(per_96m_fck, "per_clkdm"); +DEFINE_STRUCT_CLK(per_96m_fck, cm_96m_fck_parent_names, core_l4_ick_ops); + +static const struct clksel mcbsp_234_clksel[] = { + { .parent = &per_96m_fck, .rates = common_mcbsp_96m_rates }, + { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates }, + { .parent = NULL }, +}; + +static const char *mcbsp2_fck_parent_names[] = { + "per_96m_fck", "mcbsp_clks", +}; + +DEFINE_CLK_OMAP_MUX_GATE(mcbsp2_fck, "per_clkdm", mcbsp_234_clksel, + OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0), + OMAP2_MCBSP2_CLKS_MASK, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + OMAP3430_EN_MCBSP2_SHIFT, &clkhwops_wait, + mcbsp2_fck_parent_names, clkout2_src_ck_ops); + +static struct clk mcbsp2_ick; + +static struct clk_hw_omap mcbsp2_ick_hw = { + .hw = { + .clk = &mcbsp2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_MCBSP2_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(mcbsp2_ick, gpio2_ick_parent_names, aes2_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(mcbsp3_fck, "per_clkdm", mcbsp_234_clksel, + OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1), + OMAP2_MCBSP3_CLKS_MASK, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + OMAP3430_EN_MCBSP3_SHIFT, &clkhwops_wait, + mcbsp2_fck_parent_names, clkout2_src_ck_ops); + +static struct clk mcbsp3_ick; + +static struct clk_hw_omap mcbsp3_ick_hw = { + .hw = { + .clk = &mcbsp3_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_MCBSP3_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(mcbsp3_ick, gpio2_ick_parent_names, aes2_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(mcbsp4_fck, "per_clkdm", mcbsp_234_clksel, + OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1), + OMAP2_MCBSP4_CLKS_MASK, + OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + OMAP3430_EN_MCBSP4_SHIFT, &clkhwops_wait, + mcbsp2_fck_parent_names, clkout2_src_ck_ops); + +static struct clk mcbsp4_ick; + +static struct clk_hw_omap mcbsp4_ick_hw = { + .hw = { + .clk = &mcbsp4_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_MCBSP4_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(mcbsp4_ick, gpio2_ick_parent_names, aes2_ick_ops); + +DEFINE_CLK_OMAP_MUX_GATE(mcbsp5_fck, "core_l4_clkdm", mcbsp_15_clksel, + OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1), + OMAP2_MCBSP5_CLKS_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP3430_EN_MCBSP5_SHIFT, &clkhwops_wait, + mcbsp1_fck_parent_names, clkout2_src_ck_ops); + +static struct clk mcbsp5_ick; + +static struct clk_hw_omap mcbsp5_ick_hw = { + .hw = { + .clk = &mcbsp5_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_MCBSP5_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcbsp5_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk mcspi1_fck; + +static struct clk_hw_omap mcspi1_fck_hw = { + .hw = { + .clk = &mcspi1_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP3430_EN_MCSPI1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcspi1_fck, fshostusb_fck_parent_names, aes2_ick_ops); + +static struct clk mcspi1_ick; + +static struct clk_hw_omap mcspi1_ick_hw = { + .hw = { + .clk = &mcspi1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_MCSPI1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcspi1_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk mcspi2_fck; + +static struct clk_hw_omap mcspi2_fck_hw = { + .hw = { + .clk = &mcspi2_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP3430_EN_MCSPI2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcspi2_fck, fshostusb_fck_parent_names, aes2_ick_ops); + +static struct clk mcspi2_ick; + +static struct clk_hw_omap mcspi2_ick_hw = { + .hw = { + .clk = &mcspi2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_MCSPI2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcspi2_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk mcspi3_fck; + +static struct clk_hw_omap mcspi3_fck_hw = { + .hw = { + .clk = &mcspi3_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP3430_EN_MCSPI3_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcspi3_fck, fshostusb_fck_parent_names, aes2_ick_ops); + +static struct clk mcspi3_ick; + +static struct clk_hw_omap mcspi3_ick_hw = { + .hw = { + .clk = &mcspi3_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_MCSPI3_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcspi3_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk mcspi4_fck; + +static struct clk_hw_omap mcspi4_fck_hw = { + .hw = { + .clk = &mcspi4_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP3430_EN_MCSPI4_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcspi4_fck, fshostusb_fck_parent_names, aes2_ick_ops); + +static struct clk mcspi4_ick; + +static struct clk_hw_omap mcspi4_ick_hw = { + .hw = { + .clk = &mcspi4_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_MCSPI4_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mcspi4_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk mmchs1_fck; + +static struct clk_hw_omap mmchs1_fck_hw = { + .hw = { + .clk = &mmchs1_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP3430_EN_MMC1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mmchs1_fck, csi2_96m_fck_parent_names, aes2_ick_ops); + +static struct clk mmchs1_ick; + +static struct clk_hw_omap mmchs1_ick_hw = { + .hw = { + .clk = &mmchs1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_MMC1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mmchs1_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk mmchs2_fck; + +static struct clk_hw_omap mmchs2_fck_hw = { + .hw = { + .clk = &mmchs2_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP3430_EN_MMC2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mmchs2_fck, csi2_96m_fck_parent_names, aes2_ick_ops); + +static struct clk mmchs2_ick; + +static struct clk_hw_omap mmchs2_ick_hw = { + .hw = { + .clk = &mmchs2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_MMC2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mmchs2_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk mmchs3_fck; + +static struct clk_hw_omap mmchs3_fck_hw = { + .hw = { + .clk = &mmchs3_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mmchs3_fck, csi2_96m_fck_parent_names, aes2_ick_ops); + +static struct clk mmchs3_ick; + +static struct clk_hw_omap mmchs3_ick_hw = { + .hw = { + .clk = &mmchs3_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mmchs3_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk modem_fck; + +static struct clk_hw_omap modem_fck_hw = { + .hw = { + .clk = &modem_fck, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP3430_EN_MODEM_SHIFT, + .clkdm_name = "d2d_clkdm", +}; + +DEFINE_STRUCT_CLK(modem_fck, dpll3_ck_parent_names, aes2_ick_ops); + +static struct clk mspro_fck; + +static struct clk_hw_omap mspro_fck_hw = { + .hw = { + .clk = &mspro_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP3430_EN_MSPRO_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mspro_fck, csi2_96m_fck_parent_names, aes2_ick_ops); + +static struct clk mspro_ick; + +static struct clk_hw_omap mspro_ick_hw = { + .hw = { + .clk = &mspro_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_MSPRO_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(mspro_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk omap_192m_alwon_fck; + +DEFINE_STRUCT_CLK_HW_OMAP(omap_192m_alwon_fck, NULL); +DEFINE_STRUCT_CLK(omap_192m_alwon_fck, omap_96m_alwon_fck_parent_names, + core_ck_ops); + +static struct clk omap_32ksync_ick; + +static struct clk_hw_omap omap_32ksync_ick_hw = { + .hw = { + .clk = &omap_32ksync_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_32KSYNC_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(omap_32ksync_ick, gpio1_ick_parent_names, aes2_ick_ops); + +static const struct clksel_rate omap_96m_alwon_fck_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_36XX }, + { .div = 2, .val = 2, .flags = RATE_IN_36XX }, + { .div = 0 } +}; + +static const struct clksel omap_96m_alwon_fck_clksel[] = { + { .parent = &omap_192m_alwon_fck, .rates = omap_96m_alwon_fck_rates }, + { .parent = NULL } +}; + +static struct clk omap_96m_alwon_fck_3630; + +static const char *omap_96m_alwon_fck_3630_parent_names[] = { + "omap_192m_alwon_fck", +}; + +static const struct clk_ops omap_96m_alwon_fck_3630_ops = { + .set_rate = &omap2_clksel_set_rate, + .recalc_rate = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, +}; + +static struct clk_hw_omap omap_96m_alwon_fck_3630_hw = { + .hw = { + .clk = &omap_96m_alwon_fck_3630, + }, + .clksel = omap_96m_alwon_fck_clksel, + .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), + .clksel_mask = OMAP3630_CLKSEL_96M_MASK, +}; + +static struct clk omap_96m_alwon_fck_3630 = { + .name = "omap_96m_alwon_fck", + .hw = &omap_96m_alwon_fck_3630_hw.hw, + .parent_names = omap_96m_alwon_fck_3630_parent_names, + .num_parents = ARRAY_SIZE(omap_96m_alwon_fck_3630_parent_names), + .ops = &omap_96m_alwon_fck_3630_ops, +}; + +static struct clk omapctrl_ick; + +static struct clk_hw_omap omapctrl_ick_hw = { + .hw = { + .clk = &omapctrl_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_OMAPCTRL_SHIFT, + .flags = ENABLE_ON_INIT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(omapctrl_ick, aes2_ick_parent_names, aes2_ick_ops); + +DEFINE_CLK_DIVIDER(pclk_fck, "emu_src_ck", &emu_src_ck, 0x0, + OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), + OMAP3430_CLKSEL_PCLK_SHIFT, OMAP3430_CLKSEL_PCLK_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +DEFINE_CLK_DIVIDER(pclkx2_fck, "emu_src_ck", &emu_src_ck, 0x0, + OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), + OMAP3430_CLKSEL_PCLKX2_SHIFT, OMAP3430_CLKSEL_PCLKX2_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +static struct clk per_48m_fck; + +DEFINE_STRUCT_CLK_HW_OMAP(per_48m_fck, "per_clkdm"); +DEFINE_STRUCT_CLK(per_48m_fck, core_48m_fck_parent_names, core_l4_ick_ops); + +static struct clk security_l3_ick; + +DEFINE_STRUCT_CLK_HW_OMAP(security_l3_ick, NULL); +DEFINE_STRUCT_CLK(security_l3_ick, core_l3_ick_parent_names, core_ck_ops); + +static struct clk pka_ick; + +static const char *pka_ick_parent_names[] = { + "security_l3_ick", +}; + +static struct clk_hw_omap pka_ick_hw = { + .hw = { + .clk = &pka_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP3430_EN_PKA_SHIFT, +}; + +DEFINE_STRUCT_CLK(pka_ick, pka_ick_parent_names, aes1_ick_ops); + +DEFINE_CLK_DIVIDER(rm_ick, "l4_ick", &l4_ick, 0x0, + OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_RM_SHIFT, OMAP3430_CLKSEL_RM_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); + +static struct clk rng_ick; + +static struct clk_hw_omap rng_ick_hw = { + .hw = { + .clk = &rng_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP3430_EN_RNG_SHIFT, +}; + +DEFINE_STRUCT_CLK(rng_ick, aes1_ick_parent_names, aes1_ick_ops); + +static struct clk sad2d_ick; + +static struct clk_hw_omap sad2d_ick_hw = { + .hw = { + .clk = &sad2d_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_SAD2D_SHIFT, + .clkdm_name = "d2d_clkdm", +}; + +DEFINE_STRUCT_CLK(sad2d_ick, core_l3_ick_parent_names, aes2_ick_ops); + +static struct clk sdrc_ick; + +static struct clk_hw_omap sdrc_ick_hw = { + .hw = { + .clk = &sdrc_ick, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_SDRC_SHIFT, + .flags = ENABLE_ON_INIT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(sdrc_ick, ipss_ick_parent_names, aes2_ick_ops); + +static const struct clksel_rate sgx_core_rates[] = { + { .div = 2, .val = 5, .flags = RATE_IN_36XX }, + { .div = 3, .val = 0, .flags = RATE_IN_3XXX }, + { .div = 4, .val = 1, .flags = RATE_IN_3XXX }, + { .div = 6, .val = 2, .flags = RATE_IN_3XXX }, + { .div = 0 } +}; + +static const struct clksel_rate sgx_96m_rates[] = { + { .div = 1, .val = 3, .flags = RATE_IN_3XXX }, + { .div = 0 } +}; + +static const struct clksel_rate sgx_192m_rates[] = { + { .div = 1, .val = 4, .flags = RATE_IN_36XX }, + { .div = 0 } +}; + +static const struct clksel_rate sgx_corex2_rates[] = { + { .div = 3, .val = 6, .flags = RATE_IN_36XX }, + { .div = 5, .val = 7, .flags = RATE_IN_36XX }, + { .div = 0 } +}; + +static const struct clksel sgx_clksel[] = { + { .parent = &core_ck, .rates = sgx_core_rates }, + { .parent = &cm_96m_fck, .rates = sgx_96m_rates }, + { .parent = &omap_192m_alwon_fck, .rates = sgx_192m_rates }, + { .parent = &corex2_fck, .rates = sgx_corex2_rates }, + { .parent = NULL }, +}; + +static const char *sgx_fck_parent_names[] = { + "core_ck", "cm_96m_fck", "omap_192m_alwon_fck", "corex2_fck", +}; + +static struct clk sgx_fck; + +static const struct clk_ops sgx_fck_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, + .recalc_rate = &omap2_clksel_recalc, + .set_rate = &omap2_clksel_set_rate, + .round_rate = &omap2_clksel_round_rate, + .get_parent = &omap2_clksel_find_parent_index, + .set_parent = &omap2_clksel_set_parent, +}; + +DEFINE_CLK_OMAP_MUX_GATE(sgx_fck, "sgx_clkdm", sgx_clksel, + OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_CLKSEL), + OMAP3430ES2_CLKSEL_SGX_MASK, + OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_FCLKEN), + OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT, + &clkhwops_wait, sgx_fck_parent_names, sgx_fck_ops); + +static struct clk sgx_ick; + +static struct clk_hw_omap sgx_ick_hw = { + .hw = { + .clk = &sgx_ick, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN), + .enable_bit = OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT, + .clkdm_name = "sgx_clkdm", +}; + +DEFINE_STRUCT_CLK(sgx_ick, core_l3_ick_parent_names, aes2_ick_ops); + +static struct clk sha11_ick; + +static struct clk_hw_omap sha11_ick_hw = { + .hw = { + .clk = &sha11_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), + .enable_bit = OMAP3430_EN_SHA11_SHIFT, +}; + +DEFINE_STRUCT_CLK(sha11_ick, aes1_ick_parent_names, aes1_ick_ops); + +static struct clk sha12_ick; + +static struct clk_hw_omap sha12_ick_hw = { + .hw = { + .clk = &sha12_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_SHA12_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(sha12_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk sr1_fck; + +static struct clk_hw_omap sr1_fck_hw = { + .hw = { + .clk = &sr1_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_EN_SR1_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(sr1_fck, dpll3_ck_parent_names, aes2_ick_ops); + +static struct clk sr2_fck; + +static struct clk_hw_omap sr2_fck_hw = { + .hw = { + .clk = &sr2_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_EN_SR2_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(sr2_fck, dpll3_ck_parent_names, aes2_ick_ops); + +static struct clk sr_l4_ick; + +DEFINE_STRUCT_CLK_HW_OMAP(sr_l4_ick, "core_l4_clkdm"); +DEFINE_STRUCT_CLK(sr_l4_ick, security_l4_ick2_parent_names, core_l4_ick_ops); + +static struct clk ssi_l4_ick; + +DEFINE_STRUCT_CLK_HW_OMAP(ssi_l4_ick, "core_l4_clkdm"); +DEFINE_STRUCT_CLK(ssi_l4_ick, security_l4_ick2_parent_names, core_l4_ick_ops); + +static struct clk ssi_ick_3430es1; + +static const char *ssi_ick_3430es1_parent_names[] = { + "ssi_l4_ick", +}; + +static struct clk_hw_omap ssi_ick_3430es1_hw = { + .hw = { + .clk = &ssi_ick_3430es1, + }, + .ops = &clkhwops_iclk, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_SSI_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(ssi_ick_3430es1, ssi_ick_3430es1_parent_names, aes2_ick_ops); + +static struct clk ssi_ick_3430es2; + +static struct clk_hw_omap ssi_ick_3430es2_hw = { + .hw = { + .clk = &ssi_ick_3430es2, + }, + .ops = &clkhwops_omap3430es2_iclk_ssi_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_SSI_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(ssi_ick_3430es2, ssi_ick_3430es1_parent_names, aes2_ick_ops); + +static const struct clksel_rate ssi_ssr_corex2_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, + { .div = 2, .val = 2, .flags = RATE_IN_3XXX }, + { .div = 3, .val = 3, .flags = RATE_IN_3XXX }, + { .div = 4, .val = 4, .flags = RATE_IN_3XXX }, + { .div = 6, .val = 6, .flags = RATE_IN_3XXX }, + { .div = 8, .val = 8, .flags = RATE_IN_3XXX }, + { .div = 0 } +}; + +static const struct clksel ssi_ssr_clksel[] = { + { .parent = &corex2_fck, .rates = ssi_ssr_corex2_rates }, + { .parent = NULL }, +}; + +static const char *ssi_ssr_fck_3430es1_parent_names[] = { + "corex2_fck", +}; + +static const struct clk_ops ssi_ssr_fck_3430es1_ops = { + .init = &omap2_init_clk_clkdm, + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, + .recalc_rate = &omap2_clksel_recalc, + .set_rate = &omap2_clksel_set_rate, + .round_rate = &omap2_clksel_round_rate, +}; + +DEFINE_CLK_OMAP_MUX_GATE(ssi_ssr_fck_3430es1, "core_l4_clkdm", + ssi_ssr_clksel, OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_SSI_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP3430_EN_SSI_SHIFT, + NULL, ssi_ssr_fck_3430es1_parent_names, + ssi_ssr_fck_3430es1_ops); + +DEFINE_CLK_OMAP_MUX_GATE(ssi_ssr_fck_3430es2, "core_l4_clkdm", + ssi_ssr_clksel, OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), + OMAP3430_CLKSEL_SSI_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + OMAP3430_EN_SSI_SHIFT, + NULL, ssi_ssr_fck_3430es1_parent_names, + ssi_ssr_fck_3430es1_ops); + +DEFINE_CLK_FIXED_FACTOR(ssi_sst_fck_3430es1, "ssi_ssr_fck_3430es1", + &ssi_ssr_fck_3430es1, 0x0, 1, 2); + +DEFINE_CLK_FIXED_FACTOR(ssi_sst_fck_3430es2, "ssi_ssr_fck_3430es2", + &ssi_ssr_fck_3430es2, 0x0, 1, 2); + +static struct clk sys_clkout1; + +static const char *sys_clkout1_parent_names[] = { + "osc_sys_ck", +}; + +static struct clk_hw_omap sys_clkout1_hw = { + .hw = { + .clk = &sys_clkout1, + }, + .enable_reg = OMAP3430_PRM_CLKOUT_CTRL, + .enable_bit = OMAP3430_CLKOUT_EN_SHIFT, +}; + +DEFINE_STRUCT_CLK(sys_clkout1, sys_clkout1_parent_names, aes1_ick_ops); + +DEFINE_CLK_DIVIDER(sys_clkout2, "clkout2_src_ck", &clkout2_src_ck, 0x0, + OMAP3430_CM_CLKOUT_CTRL, OMAP3430_CLKOUT2_DIV_SHIFT, + OMAP3430_CLKOUT2_DIV_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL); + +DEFINE_CLK_MUX(traceclk_src_fck, emu_src_ck_parent_names, NULL, 0x0, + OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), + OMAP3430_TRACE_MUX_CTRL_SHIFT, OMAP3430_TRACE_MUX_CTRL_WIDTH, + 0x0, NULL); + +DEFINE_CLK_DIVIDER(traceclk_fck, "traceclk_src_fck", &traceclk_src_fck, 0x0, + OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), + OMAP3430_CLKSEL_TRACECLK_SHIFT, + OMAP3430_CLKSEL_TRACECLK_WIDTH, CLK_DIVIDER_ONE_BASED, NULL); + +static struct clk ts_fck; + +static struct clk_hw_omap ts_fck_hw = { + .hw = { + .clk = &ts_fck, + }, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3), + .enable_bit = OMAP3430ES2_EN_TS_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(ts_fck, wkup_32k_fck_parent_names, aes2_ick_ops); + +static struct clk uart1_fck; + +static struct clk_hw_omap uart1_fck_hw = { + .hw = { + .clk = &uart1_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP3430_EN_UART1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(uart1_fck, fshostusb_fck_parent_names, aes2_ick_ops); + +static struct clk uart1_ick; + +static struct clk_hw_omap uart1_ick_hw = { + .hw = { + .clk = &uart1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_UART1_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(uart1_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk uart2_fck; + +static struct clk_hw_omap uart2_fck_hw = { + .hw = { + .clk = &uart2_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = OMAP3430_EN_UART2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(uart2_fck, fshostusb_fck_parent_names, aes2_ick_ops); + +static struct clk uart2_ick; + +static struct clk_hw_omap uart2_ick_hw = { + .hw = { + .clk = &uart2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = OMAP3430_EN_UART2_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(uart2_ick, aes2_ick_parent_names, aes2_ick_ops); + +static struct clk uart3_fck; + +static const char *uart3_fck_parent_names[] = { + "per_48m_fck", +}; + +static struct clk_hw_omap uart3_fck_hw = { + .hw = { + .clk = &uart3_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_EN_UART3_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(uart3_fck, uart3_fck_parent_names, aes2_ick_ops); + +static struct clk uart3_ick; + +static struct clk_hw_omap uart3_ick_hw = { + .hw = { + .clk = &uart3_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_UART3_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(uart3_ick, gpio2_ick_parent_names, aes2_ick_ops); + +static struct clk uart4_fck; + +static struct clk_hw_omap uart4_fck_hw = { + .hw = { + .clk = &uart4_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + .enable_bit = OMAP3630_EN_UART4_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(uart4_fck, uart3_fck_parent_names, aes2_ick_ops); + +static struct clk uart4_fck_am35xx; + +static struct clk_hw_omap uart4_fck_am35xx_hw = { + .hw = { + .clk = &uart4_fck_am35xx, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), + .enable_bit = AM35XX_EN_UART4_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(uart4_fck_am35xx, fshostusb_fck_parent_names, aes2_ick_ops); + +static struct clk uart4_ick; + +static struct clk_hw_omap uart4_ick_hw = { + .hw = { + .clk = &uart4_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3630_EN_UART4_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(uart4_ick, gpio2_ick_parent_names, aes2_ick_ops); + +static struct clk uart4_ick_am35xx; + +static struct clk_hw_omap uart4_ick_am35xx_hw = { + .hw = { + .clk = &uart4_ick_am35xx, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + .enable_bit = AM35XX_EN_UART4_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(uart4_ick_am35xx, aes2_ick_parent_names, aes2_ick_ops); + +static const struct clksel_rate div2_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_3XXX }, + { .div = 2, .val = 2, .flags = RATE_IN_3XXX }, + { .div = 0 } +}; + +static const struct clksel usb_l4_clksel[] = { + { .parent = &l4_ick, .rates = div2_rates }, + { .parent = NULL }, +}; + +static const char *usb_l4_ick_parent_names[] = { + "l4_ick", +}; + +DEFINE_CLK_OMAP_MUX_GATE(usb_l4_ick, "core_l4_clkdm", usb_l4_clksel, + OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), + OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK, + OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), + OMAP3430ES1_EN_FSHOSTUSB_SHIFT, + &clkhwops_iclk_wait, usb_l4_ick_parent_names, + ssi_ssr_fck_3430es1_ops); + +static struct clk usbhost_120m_fck; + +static const char *usbhost_120m_fck_parent_names[] = { + "dpll5_m2_ck", +}; + +static struct clk_hw_omap usbhost_120m_fck_hw = { + .hw = { + .clk = &usbhost_120m_fck, + }, + .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN), + .enable_bit = OMAP3430ES2_EN_USBHOST2_SHIFT, + .clkdm_name = "usbhost_clkdm", +}; + +DEFINE_STRUCT_CLK(usbhost_120m_fck, usbhost_120m_fck_parent_names, + aes2_ick_ops); + +static struct clk usbhost_48m_fck; + +static struct clk_hw_omap usbhost_48m_fck_hw = { + .hw = { + .clk = &usbhost_48m_fck, + }, + .ops = &clkhwops_omap3430es2_dss_usbhost_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN), + .enable_bit = OMAP3430ES2_EN_USBHOST1_SHIFT, + .clkdm_name = "usbhost_clkdm", +}; + +DEFINE_STRUCT_CLK(usbhost_48m_fck, core_48m_fck_parent_names, aes2_ick_ops); + +static struct clk usbhost_ick; + +static struct clk_hw_omap usbhost_ick_hw = { + .hw = { + .clk = &usbhost_ick, + }, + .ops = &clkhwops_omap3430es2_iclk_dss_usbhost_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN), + .enable_bit = OMAP3430ES2_EN_USBHOST_SHIFT, + .clkdm_name = "usbhost_clkdm", +}; + +DEFINE_STRUCT_CLK(usbhost_ick, security_l4_ick2_parent_names, aes2_ick_ops); + +static struct clk usbtll_fck; + +static struct clk_hw_omap usbtll_fck_hw = { + .hw = { + .clk = &usbtll_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3), + .enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(usbtll_fck, usbhost_120m_fck_parent_names, aes2_ick_ops); + +static struct clk usbtll_ick; + +static struct clk_hw_omap usbtll_ick_hw = { + .hw = { + .clk = &usbtll_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), + .enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT, + .clkdm_name = "core_l4_clkdm", +}; + +DEFINE_STRUCT_CLK(usbtll_ick, aes2_ick_parent_names, aes2_ick_ops); + +static const struct clksel_rate usim_96m_rates[] = { + { .div = 2, .val = 3, .flags = RATE_IN_3XXX }, + { .div = 4, .val = 4, .flags = RATE_IN_3XXX }, + { .div = 8, .val = 5, .flags = RATE_IN_3XXX }, + { .div = 10, .val = 6, .flags = RATE_IN_3XXX }, + { .div = 0 } +}; + +static const struct clksel_rate usim_120m_rates[] = { + { .div = 4, .val = 7, .flags = RATE_IN_3XXX }, + { .div = 8, .val = 8, .flags = RATE_IN_3XXX }, + { .div = 16, .val = 9, .flags = RATE_IN_3XXX }, + { .div = 20, .val = 10, .flags = RATE_IN_3XXX }, + { .div = 0 } +}; + +static const struct clksel usim_clksel[] = { + { .parent = &omap_96m_fck, .rates = usim_96m_rates }, + { .parent = &dpll5_m2_ck, .rates = usim_120m_rates }, + { .parent = &sys_ck, .rates = div2_rates }, + { .parent = NULL }, +}; + +static const char *usim_fck_parent_names[] = { + "omap_96m_fck", "dpll5_m2_ck", "sys_ck", +}; + +static struct clk usim_fck; + +static const struct clk_ops usim_fck_ops = { + .enable = &omap2_dflt_clk_enable, + .disable = &omap2_dflt_clk_disable, + .is_enabled = &omap2_dflt_clk_is_enabled, + .recalc_rate = &omap2_clksel_recalc, + .get_parent = &omap2_clksel_find_parent_index, + .set_parent = &omap2_clksel_set_parent, +}; + +DEFINE_CLK_OMAP_MUX_GATE(usim_fck, NULL, usim_clksel, + OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL), + OMAP3430ES2_CLKSEL_USIMOCP_MASK, + OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), + OMAP3430ES2_EN_USIMOCP_SHIFT, &clkhwops_wait, + usim_fck_parent_names, usim_fck_ops); + +static struct clk usim_ick; + +static struct clk_hw_omap usim_ick_hw = { + .hw = { + .clk = &usim_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP3430ES2_EN_USIMOCP_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(usim_ick, gpio1_ick_parent_names, aes2_ick_ops); + +static struct clk vpfe_fck; + +static const char *vpfe_fck_parent_names[] = { + "pclk_ck", +}; + +static struct clk_hw_omap vpfe_fck_hw = { + .hw = { + .clk = &vpfe_fck, + }, + .enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL), + .enable_bit = AM35XX_VPFE_FCLK_SHIFT, +}; + +DEFINE_STRUCT_CLK(vpfe_fck, vpfe_fck_parent_names, aes1_ick_ops); + +static struct clk vpfe_ick; + +static struct clk_hw_omap vpfe_ick_hw = { + .hw = { + .clk = &vpfe_ick, + }, + .ops = &clkhwops_am35xx_ipss_module_wait, + .enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL), + .enable_bit = AM35XX_VPFE_VBUSP_CLK_SHIFT, + .clkdm_name = "core_l3_clkdm", +}; + +DEFINE_STRUCT_CLK(vpfe_ick, emac_ick_parent_names, aes2_ick_ops); + +static struct clk wdt1_fck; + +DEFINE_STRUCT_CLK_HW_OMAP(wdt1_fck, "wkup_clkdm"); +DEFINE_STRUCT_CLK(wdt1_fck, gpt12_fck_parent_names, core_l4_ick_ops); + +static struct clk wdt1_ick; + +static struct clk_hw_omap wdt1_ick_hw = { + .hw = { + .clk = &wdt1_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_WDT1_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(wdt1_ick, gpio1_ick_parent_names, aes2_ick_ops); + +static struct clk wdt2_fck; + +static struct clk_hw_omap wdt2_fck_hw = { + .hw = { + .clk = &wdt2_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_EN_WDT2_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(wdt2_fck, gpio1_dbck_parent_names, aes2_ick_ops); + +static struct clk wdt2_ick; + +static struct clk_hw_omap wdt2_ick_hw = { + .hw = { + .clk = &wdt2_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_WDT2_SHIFT, + .clkdm_name = "wkup_clkdm", +}; + +DEFINE_STRUCT_CLK(wdt2_ick, gpio1_ick_parent_names, aes2_ick_ops); + +static struct clk wdt3_fck; + +static struct clk_hw_omap wdt3_fck_hw = { + .hw = { + .clk = &wdt3_fck, + }, + .ops = &clkhwops_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), + .enable_bit = OMAP3430_EN_WDT3_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(wdt3_fck, gpio2_dbck_parent_names, aes2_ick_ops); + +static struct clk wdt3_ick; + +static struct clk_hw_omap wdt3_ick_hw = { + .hw = { + .clk = &wdt3_ick, + }, + .ops = &clkhwops_iclk_wait, + .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), + .enable_bit = OMAP3430_EN_WDT3_SHIFT, + .clkdm_name = "per_clkdm", +}; + +DEFINE_STRUCT_CLK(wdt3_ick, gpio2_ick_parent_names, aes2_ick_ops); + +/* + * clocks specific to omap3430es1 + */ +static struct omap_clk omap3430es1_clks[] = { + CLK(NULL, "gfx_l3_ck", &gfx_l3_ck), + CLK(NULL, "gfx_l3_fck", &gfx_l3_fck), + CLK(NULL, "gfx_l3_ick", &gfx_l3_ick), + CLK(NULL, "gfx_cg1_ck", &gfx_cg1_ck), + CLK(NULL, "gfx_cg2_ck", &gfx_cg2_ck), + CLK(NULL, "d2d_26m_fck", &d2d_26m_fck), + CLK(NULL, "fshostusb_fck", &fshostusb_fck), + CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es1), + CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es1), + CLK("musb-omap2430", "ick", &hsotgusb_ick_3430es1), + CLK(NULL, "hsotgusb_ick", &hsotgusb_ick_3430es1), + CLK(NULL, "fac_ick", &fac_ick), + CLK(NULL, "ssi_ick", &ssi_ick_3430es1), + CLK(NULL, "usb_l4_ick", &usb_l4_ick), + CLK(NULL, "dss1_alwon_fck", &dss1_alwon_fck_3430es1), + CLK("omapdss_dss", "ick", &dss_ick_3430es1), + CLK(NULL, "dss_ick", &dss_ick_3430es1), +}; + +/* + * clocks specific to am35xx + */ +static struct omap_clk am35xx_clks[] = { + CLK(NULL, "ipss_ick", &ipss_ick), + CLK(NULL, "rmii_ck", &rmii_ck), + CLK(NULL, "pclk_ck", &pclk_ck), + CLK(NULL, "emac_ick", &emac_ick), + CLK(NULL, "emac_fck", &emac_fck), + CLK("davinci_emac.0", NULL, &emac_ick), + CLK("davinci_mdio.0", NULL, &emac_fck), + CLK("vpfe-capture", "master", &vpfe_ick), + CLK("vpfe-capture", "slave", &vpfe_fck), + CLK(NULL, "hsotgusb_ick", &hsotgusb_ick_am35xx), + CLK(NULL, "hsotgusb_fck", &hsotgusb_fck_am35xx), + CLK(NULL, "hecc_ck", &hecc_ck), + CLK(NULL, "uart4_ick", &uart4_ick_am35xx), + CLK(NULL, "uart4_fck", &uart4_fck_am35xx), +}; + +/* + * clocks specific to omap36xx + */ +static struct omap_clk omap36xx_clks[] = { + CLK(NULL, "omap_192m_alwon_fck", &omap_192m_alwon_fck), + CLK(NULL, "uart4_fck", &uart4_fck), +}; + +/* + * clocks common to omap36xx omap34xx + */ +static struct omap_clk omap34xx_omap36xx_clks[] = { + CLK(NULL, "aes1_ick", &aes1_ick), + CLK("omap_rng", "ick", &rng_ick), + CLK("omap3-rom-rng", "ick", &rng_ick), + CLK(NULL, "sha11_ick", &sha11_ick), + CLK(NULL, "des1_ick", &des1_ick), + CLK(NULL, "cam_mclk", &cam_mclk), + CLK(NULL, "cam_ick", &cam_ick), + CLK(NULL, "csi2_96m_fck", &csi2_96m_fck), + CLK(NULL, "security_l3_ick", &security_l3_ick), + CLK(NULL, "pka_ick", &pka_ick), + CLK(NULL, "icr_ick", &icr_ick), + CLK("omap-aes", "ick", &aes2_ick), + CLK("omap-sham", "ick", &sha12_ick), + CLK(NULL, "des2_ick", &des2_ick), + CLK(NULL, "mspro_ick", &mspro_ick), + CLK(NULL, "mailboxes_ick", &mailboxes_ick), + CLK(NULL, "ssi_l4_ick", &ssi_l4_ick), + CLK(NULL, "sr1_fck", &sr1_fck), + CLK(NULL, "sr2_fck", &sr2_fck), + CLK(NULL, "sr_l4_ick", &sr_l4_ick), + CLK(NULL, "security_l4_ick2", &security_l4_ick2), + CLK(NULL, "wkup_l4_ick", &wkup_l4_ick), + CLK(NULL, "dpll2_fck", &dpll2_fck), + CLK(NULL, "iva2_ck", &iva2_ck), + CLK(NULL, "modem_fck", &modem_fck), + CLK(NULL, "sad2d_ick", &sad2d_ick), + CLK(NULL, "mad2d_ick", &mad2d_ick), + CLK(NULL, "mspro_fck", &mspro_fck), + CLK(NULL, "dpll2_ck", &dpll2_ck), + CLK(NULL, "dpll2_m2_ck", &dpll2_m2_ck), +}; + +/* + * clocks common to omap36xx and omap3430es2plus + */ +static struct omap_clk omap36xx_omap3430es2plus_clks[] = { + CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es2), + CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es2), + CLK("musb-omap2430", "ick", &hsotgusb_ick_3430es2), + CLK(NULL, "hsotgusb_ick", &hsotgusb_ick_3430es2), + CLK(NULL, "ssi_ick", &ssi_ick_3430es2), + CLK(NULL, "usim_fck", &usim_fck), + CLK(NULL, "usim_ick", &usim_ick), +}; + +/* + * clocks common to am35xx omap36xx and omap3430es2plus + */ +static struct omap_clk omap36xx_am35xx_omap3430es2plus_clks[] = { + CLK(NULL, "virt_16_8m_ck", &virt_16_8m_ck), + CLK(NULL, "dpll5_ck", &dpll5_ck), + CLK(NULL, "dpll5_m2_ck", &dpll5_m2_ck), + CLK(NULL, "sgx_fck", &sgx_fck), + CLK(NULL, "sgx_ick", &sgx_ick), + CLK(NULL, "cpefuse_fck", &cpefuse_fck), + CLK(NULL, "ts_fck", &ts_fck), + CLK(NULL, "usbtll_fck", &usbtll_fck), + CLK(NULL, "usbtll_ick", &usbtll_ick), + CLK("omap_hsmmc.2", "ick", &mmchs3_ick), + CLK(NULL, "mmchs3_ick", &mmchs3_ick), + CLK(NULL, "mmchs3_fck", &mmchs3_fck), + CLK(NULL, "dss1_alwon_fck", &dss1_alwon_fck_3430es2), + CLK("omapdss_dss", "ick", &dss_ick_3430es2), + CLK(NULL, "dss_ick", &dss_ick_3430es2), + CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck), + CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck), + CLK(NULL, "usbhost_ick", &usbhost_ick), +}; + +/* + * common clocks + */ +static struct omap_clk omap3xxx_clks[] = { + CLK(NULL, "apb_pclk", &dummy_apb_pclk), + CLK(NULL, "omap_32k_fck", &omap_32k_fck), + CLK(NULL, "virt_12m_ck", &virt_12m_ck), + CLK(NULL, "virt_13m_ck", &virt_13m_ck), + CLK(NULL, "virt_19200000_ck", &virt_19200000_ck), + CLK(NULL, "virt_26000000_ck", &virt_26000000_ck), + CLK(NULL, "virt_38_4m_ck", &virt_38_4m_ck), + CLK(NULL, "osc_sys_ck", &osc_sys_ck), + CLK("twl", "fck", &osc_sys_ck), + CLK(NULL, "sys_ck", &sys_ck), + CLK(NULL, "omap_96m_alwon_fck", &omap_96m_alwon_fck), + CLK("etb", "emu_core_alwon_ck", &emu_core_alwon_ck), + CLK(NULL, "sys_altclk", &sys_altclk), + CLK(NULL, "mcbsp_clks", &mcbsp_clks), + CLK(NULL, "sys_clkout1", &sys_clkout1), + CLK(NULL, "dpll1_ck", &dpll1_ck), + CLK(NULL, "dpll1_x2_ck", &dpll1_x2_ck), + CLK(NULL, "dpll1_x2m2_ck", &dpll1_x2m2_ck), + CLK(NULL, "dpll3_ck", &dpll3_ck), + CLK(NULL, "core_ck", &core_ck), + CLK(NULL, "dpll3_x2_ck", &dpll3_x2_ck), + CLK(NULL, "dpll3_m2_ck", &dpll3_m2_ck), + CLK(NULL, "dpll3_m2x2_ck", &dpll3_m2x2_ck), + CLK(NULL, "dpll3_m3_ck", &dpll3_m3_ck), + CLK(NULL, "dpll3_m3x2_ck", &dpll3_m3x2_ck), + CLK(NULL, "dpll4_ck", &dpll4_ck), + CLK(NULL, "dpll4_x2_ck", &dpll4_x2_ck), + CLK(NULL, "omap_96m_fck", &omap_96m_fck), + CLK(NULL, "cm_96m_fck", &cm_96m_fck), + CLK(NULL, "omap_54m_fck", &omap_54m_fck), + CLK(NULL, "omap_48m_fck", &omap_48m_fck), + CLK(NULL, "omap_12m_fck", &omap_12m_fck), + CLK(NULL, "dpll4_m2_ck", &dpll4_m2_ck), + CLK(NULL, "dpll4_m2x2_ck", &dpll4_m2x2_ck), + CLK(NULL, "dpll4_m3_ck", &dpll4_m3_ck), + CLK(NULL, "dpll4_m3x2_ck", &dpll4_m3x2_ck), + CLK(NULL, "dpll4_m4_ck", &dpll4_m4_ck), + CLK(NULL, "dpll4_m4x2_ck", &dpll4_m4x2_ck), + CLK(NULL, "dpll4_m5_ck", &dpll4_m5_ck), + CLK(NULL, "dpll4_m5x2_ck", &dpll4_m5x2_ck), + CLK(NULL, "dpll4_m6_ck", &dpll4_m6_ck), + CLK(NULL, "dpll4_m6x2_ck", &dpll4_m6x2_ck), + CLK("etb", "emu_per_alwon_ck", &emu_per_alwon_ck), + CLK(NULL, "clkout2_src_ck", &clkout2_src_ck), + CLK(NULL, "sys_clkout2", &sys_clkout2), + CLK(NULL, "corex2_fck", &corex2_fck), + CLK(NULL, "dpll1_fck", &dpll1_fck), + CLK(NULL, "mpu_ck", &mpu_ck), + CLK(NULL, "arm_fck", &arm_fck), + CLK("etb", "emu_mpu_alwon_ck", &emu_mpu_alwon_ck), + CLK(NULL, "l3_ick", &l3_ick), + CLK(NULL, "l4_ick", &l4_ick), + CLK(NULL, "rm_ick", &rm_ick), + CLK(NULL, "gpt10_fck", &gpt10_fck), + CLK(NULL, "gpt11_fck", &gpt11_fck), + CLK(NULL, "core_96m_fck", &core_96m_fck), + CLK(NULL, "mmchs2_fck", &mmchs2_fck), + CLK(NULL, "mmchs1_fck", &mmchs1_fck), + CLK(NULL, "i2c3_fck", &i2c3_fck), + CLK(NULL, "i2c2_fck", &i2c2_fck), + CLK(NULL, "i2c1_fck", &i2c1_fck), + CLK(NULL, "mcbsp5_fck", &mcbsp5_fck), + CLK(NULL, "mcbsp1_fck", &mcbsp1_fck), + CLK(NULL, "core_48m_fck", &core_48m_fck), + CLK(NULL, "mcspi4_fck", &mcspi4_fck), + CLK(NULL, "mcspi3_fck", &mcspi3_fck), + CLK(NULL, "mcspi2_fck", &mcspi2_fck), + CLK(NULL, "mcspi1_fck", &mcspi1_fck), + CLK(NULL, "uart2_fck", &uart2_fck), + CLK(NULL, "uart1_fck", &uart1_fck), + CLK(NULL, "core_12m_fck", &core_12m_fck), + CLK("omap_hdq.0", "fck", &hdq_fck), + CLK(NULL, "hdq_fck", &hdq_fck), + CLK(NULL, "core_l3_ick", &core_l3_ick), + CLK(NULL, "sdrc_ick", &sdrc_ick), + CLK(NULL, "gpmc_fck", &gpmc_fck), + CLK(NULL, "core_l4_ick", &core_l4_ick), + CLK("omap_hsmmc.1", "ick", &mmchs2_ick), + CLK("omap_hsmmc.0", "ick", &mmchs1_ick), + CLK(NULL, "mmchs2_ick", &mmchs2_ick), + CLK(NULL, "mmchs1_ick", &mmchs1_ick), + CLK("omap_hdq.0", "ick", &hdq_ick), + CLK(NULL, "hdq_ick", &hdq_ick), + CLK("omap2_mcspi.4", "ick", &mcspi4_ick), + CLK("omap2_mcspi.3", "ick", &mcspi3_ick), + CLK("omap2_mcspi.2", "ick", &mcspi2_ick), + CLK("omap2_mcspi.1", "ick", &mcspi1_ick), + CLK(NULL, "mcspi4_ick", &mcspi4_ick), + CLK(NULL, "mcspi3_ick", &mcspi3_ick), + CLK(NULL, "mcspi2_ick", &mcspi2_ick), + CLK(NULL, "mcspi1_ick", &mcspi1_ick), + CLK("omap_i2c.3", "ick", &i2c3_ick), + CLK("omap_i2c.2", "ick", &i2c2_ick), + CLK("omap_i2c.1", "ick", &i2c1_ick), + CLK(NULL, "i2c3_ick", &i2c3_ick), + CLK(NULL, "i2c2_ick", &i2c2_ick), + CLK(NULL, "i2c1_ick", &i2c1_ick), + CLK(NULL, "uart2_ick", &uart2_ick), + CLK(NULL, "uart1_ick", &uart1_ick), + CLK(NULL, "gpt11_ick", &gpt11_ick), + CLK(NULL, "gpt10_ick", &gpt10_ick), + CLK("omap-mcbsp.5", "ick", &mcbsp5_ick), + CLK("omap-mcbsp.1", "ick", &mcbsp1_ick), + CLK(NULL, "mcbsp5_ick", &mcbsp5_ick), + CLK(NULL, "mcbsp1_ick", &mcbsp1_ick), + CLK(NULL, "omapctrl_ick", &omapctrl_ick), + CLK(NULL, "dss_tv_fck", &dss_tv_fck), + CLK(NULL, "dss_96m_fck", &dss_96m_fck), + CLK(NULL, "dss2_alwon_fck", &dss2_alwon_fck), + CLK(NULL, "init_60m_fclk", &dummy_ck), + CLK(NULL, "gpt1_fck", &gpt1_fck), + CLK(NULL, "aes2_ick", &aes2_ick), + CLK(NULL, "wkup_32k_fck", &wkup_32k_fck), + CLK(NULL, "gpio1_dbck", &gpio1_dbck), + CLK(NULL, "sha12_ick", &sha12_ick), + CLK(NULL, "wdt2_fck", &wdt2_fck), + CLK("omap_wdt", "ick", &wdt2_ick), + CLK(NULL, "wdt2_ick", &wdt2_ick), + CLK(NULL, "wdt1_ick", &wdt1_ick), + CLK(NULL, "gpio1_ick", &gpio1_ick), + CLK(NULL, "omap_32ksync_ick", &omap_32ksync_ick), + CLK(NULL, "gpt12_ick", &gpt12_ick), + CLK(NULL, "gpt1_ick", &gpt1_ick), + CLK(NULL, "per_96m_fck", &per_96m_fck), + CLK(NULL, "per_48m_fck", &per_48m_fck), + CLK(NULL, "uart3_fck", &uart3_fck), + CLK(NULL, "gpt2_fck", &gpt2_fck), + CLK(NULL, "gpt3_fck", &gpt3_fck), + CLK(NULL, "gpt4_fck", &gpt4_fck), + CLK(NULL, "gpt5_fck", &gpt5_fck), + CLK(NULL, "gpt6_fck", &gpt6_fck), + CLK(NULL, "gpt7_fck", &gpt7_fck), + CLK(NULL, "gpt8_fck", &gpt8_fck), + CLK(NULL, "gpt9_fck", &gpt9_fck), + CLK(NULL, "per_32k_alwon_fck", &per_32k_alwon_fck), + CLK(NULL, "gpio6_dbck", &gpio6_dbck), + CLK(NULL, "gpio5_dbck", &gpio5_dbck), + CLK(NULL, "gpio4_dbck", &gpio4_dbck), + CLK(NULL, "gpio3_dbck", &gpio3_dbck), + CLK(NULL, "gpio2_dbck", &gpio2_dbck), + CLK(NULL, "wdt3_fck", &wdt3_fck), + CLK(NULL, "per_l4_ick", &per_l4_ick), + CLK(NULL, "gpio6_ick", &gpio6_ick), + CLK(NULL, "gpio5_ick", &gpio5_ick), + CLK(NULL, "gpio4_ick", &gpio4_ick), + CLK(NULL, "gpio3_ick", &gpio3_ick), + CLK(NULL, "gpio2_ick", &gpio2_ick), + CLK(NULL, "wdt3_ick", &wdt3_ick), + CLK(NULL, "uart3_ick", &uart3_ick), + CLK(NULL, "uart4_ick", &uart4_ick), + CLK(NULL, "gpt9_ick", &gpt9_ick), + CLK(NULL, "gpt8_ick", &gpt8_ick), + CLK(NULL, "gpt7_ick", &gpt7_ick), + CLK(NULL, "gpt6_ick", &gpt6_ick), + CLK(NULL, "gpt5_ick", &gpt5_ick), + CLK(NULL, "gpt4_ick", &gpt4_ick), + CLK(NULL, "gpt3_ick", &gpt3_ick), + CLK(NULL, "gpt2_ick", &gpt2_ick), + CLK("omap-mcbsp.2", "ick", &mcbsp2_ick), + CLK("omap-mcbsp.3", "ick", &mcbsp3_ick), + CLK("omap-mcbsp.4", "ick", &mcbsp4_ick), + CLK(NULL, "mcbsp4_ick", &mcbsp2_ick), + CLK(NULL, "mcbsp3_ick", &mcbsp3_ick), + CLK(NULL, "mcbsp2_ick", &mcbsp4_ick), + CLK(NULL, "mcbsp2_fck", &mcbsp2_fck), + CLK(NULL, "mcbsp3_fck", &mcbsp3_fck), + CLK(NULL, "mcbsp4_fck", &mcbsp4_fck), + CLK("etb", "emu_src_ck", &emu_src_ck), + CLK(NULL, "emu_src_ck", &emu_src_ck), + CLK(NULL, "pclk_fck", &pclk_fck), + CLK(NULL, "pclkx2_fck", &pclkx2_fck), + CLK(NULL, "atclk_fck", &atclk_fck), + CLK(NULL, "traceclk_src_fck", &traceclk_src_fck), + CLK(NULL, "traceclk_fck", &traceclk_fck), + CLK(NULL, "secure_32k_fck", &secure_32k_fck), + CLK(NULL, "gpt12_fck", &gpt12_fck), + CLK(NULL, "wdt1_fck", &wdt1_fck), + CLK(NULL, "timer_32k_ck", &omap_32k_fck), + CLK(NULL, "timer_sys_ck", &sys_ck), + CLK(NULL, "cpufreq_ck", &dpll1_ck), +}; + +static const char *enable_init_clks[] = { + "sdrc_ick", + "gpmc_fck", + "omapctrl_ick", +}; + +int __init omap3xxx_clk_init(void) +{ + if (omap3_has_192mhz_clk()) + omap_96m_alwon_fck = omap_96m_alwon_fck_3630; + + if (cpu_is_omap3630()) { + dpll3_m3x2_ck = dpll3_m3x2_ck_3630; + dpll4_m2x2_ck = dpll4_m2x2_ck_3630; + dpll4_m3x2_ck = dpll4_m3x2_ck_3630; + dpll4_m4x2_ck = dpll4_m4x2_ck_3630; + dpll4_m5x2_ck = dpll4_m5x2_ck_3630; + dpll4_m6x2_ck = dpll4_m6x2_ck_3630; + } + + /* + * XXX This type of dynamic rewriting of the clock tree is + * deprecated and should be revised soon. + */ + if (cpu_is_omap3630()) + dpll4_dd = dpll4_dd_3630; + else + dpll4_dd = dpll4_dd_34xx; + + + /* + * 3505 must be tested before 3517, since 3517 returns true + * for both AM3517 chips and AM3517 family chips, which + * includes 3505. Unfortunately there's no obvious family + * test for 3517/3505 :-( + */ + if (soc_is_am35xx()) { + cpu_mask = RATE_IN_34XX; + omap_clocks_register(am35xx_clks, ARRAY_SIZE(am35xx_clks)); + omap_clocks_register(omap36xx_am35xx_omap3430es2plus_clks, + ARRAY_SIZE(omap36xx_am35xx_omap3430es2plus_clks)); + omap_clocks_register(omap3xxx_clks, ARRAY_SIZE(omap3xxx_clks)); + } else if (cpu_is_omap3630()) { + cpu_mask = (RATE_IN_34XX | RATE_IN_36XX); + omap_clocks_register(omap36xx_clks, ARRAY_SIZE(omap36xx_clks)); + omap_clocks_register(omap36xx_omap3430es2plus_clks, + ARRAY_SIZE(omap36xx_omap3430es2plus_clks)); + omap_clocks_register(omap34xx_omap36xx_clks, + ARRAY_SIZE(omap34xx_omap36xx_clks)); + omap_clocks_register(omap36xx_am35xx_omap3430es2plus_clks, + ARRAY_SIZE(omap36xx_am35xx_omap3430es2plus_clks)); + omap_clocks_register(omap3xxx_clks, ARRAY_SIZE(omap3xxx_clks)); + } else if (soc_is_am33xx()) { + cpu_mask = RATE_IN_AM33XX; + } else if (cpu_is_ti814x()) { + cpu_mask = RATE_IN_TI814X; + } else if (cpu_is_omap34xx()) { + if (omap_rev() == OMAP3430_REV_ES1_0) { + cpu_mask = RATE_IN_3430ES1; + omap_clocks_register(omap3430es1_clks, + ARRAY_SIZE(omap3430es1_clks)); + omap_clocks_register(omap34xx_omap36xx_clks, + ARRAY_SIZE(omap34xx_omap36xx_clks)); + omap_clocks_register(omap3xxx_clks, + ARRAY_SIZE(omap3xxx_clks)); + } else { + /* + * Assume that anything that we haven't matched yet + * has 3430ES2-type clocks. + */ + cpu_mask = RATE_IN_3430ES2PLUS; + omap_clocks_register(omap34xx_omap36xx_clks, + ARRAY_SIZE(omap34xx_omap36xx_clks)); + omap_clocks_register(omap36xx_omap3430es2plus_clks, + ARRAY_SIZE(omap36xx_omap3430es2plus_clks)); + omap_clocks_register(omap36xx_am35xx_omap3430es2plus_clks, + ARRAY_SIZE(omap36xx_am35xx_omap3430es2plus_clks)); + omap_clocks_register(omap3xxx_clks, + ARRAY_SIZE(omap3xxx_clks)); + } + } else { + WARN(1, "clock: could not identify OMAP3 variant\n"); + } + + omap2_clk_disable_autoidle_all(); + + omap2_clk_enable_init_clocks(enable_init_clks, + ARRAY_SIZE(enable_init_clks)); + + pr_info("Clocking rate (Crystal/Core/MPU): %ld.%01ld/%ld/%ld MHz\n", + (clk_get_rate(&osc_sys_ck) / 1000000), + (clk_get_rate(&osc_sys_ck) / 100000) % 10, + (clk_get_rate(&core_ck) / 1000000), + (clk_get_rate(&arm_fck) / 1000000)); + + /* + * Lock DPLL5 -- here only until other device init code can + * handle this + */ + if (!cpu_is_ti81xx() && (omap_rev() >= OMAP3430_REV_ES2_0)) + omap3_clk_lock_dpll5(); + + /* Avoid sleeping during omap3_core_dpll_m2_set_rate() */ + sdrc_ick_p = clk_get(NULL, "sdrc_ick"); + arm_fck_p = clk_get(NULL, "arm_fck"); + + return 0; +} diff --git a/arch/arm/mach-omap2/clkt2xxx_apll.c b/arch/arm/mach-omap2/clkt2xxx_apll.c new file mode 100644 index 00000000000..c78e893eba7 --- /dev/null +++ b/arch/arm/mach-omap2/clkt2xxx_apll.c @@ -0,0 +1,142 @@ +/* + * OMAP2xxx APLL clock control functions + * + * Copyright (C) 2005-2008 Texas Instruments, Inc. + * Copyright (C) 2004-2010 Nokia Corporation + * + * Contacts: + * Richard Woodruff <r-woodruff2@ti.com> + * Paul Walmsley + * + * Based on earlier work by Tuukka Tikkanen, Tony Lindgren, + * Gordon McNutt and RidgeRun, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#undef DEBUG + +#include <linux/kernel.h> +#include <linux/clk.h> +#include <linux/io.h> + + +#include "clock.h" +#include "clock2xxx.h" +#include "cm2xxx.h" +#include "cm-regbits-24xx.h" + +/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */ +#define EN_APLL_STOPPED 0 +#define EN_APLL_LOCKED 3 + +/* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */ +#define APLLS_CLKIN_19_2MHZ 0 +#define APLLS_CLKIN_13MHZ 2 +#define APLLS_CLKIN_12MHZ 3 + +/* Private functions */ + +/** + * omap2xxx_clk_apll_locked - is the APLL locked? + * @hw: struct clk_hw * of the APLL to check + * + * If the APLL IP block referred to by @hw indicates that it's locked, + * return true; otherwise, return false. + */ +static bool omap2xxx_clk_apll_locked(struct clk_hw *hw) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + u32 r, apll_mask; + + apll_mask = EN_APLL_LOCKED << clk->enable_bit; + + r = omap2xxx_cm_get_pll_status(); + + return ((r & apll_mask) == apll_mask) ? true : false; +} + +int omap2_clk_apll96_enable(struct clk_hw *hw) +{ + return omap2xxx_cm_apll96_enable(); +} + +int omap2_clk_apll54_enable(struct clk_hw *hw) +{ + return omap2xxx_cm_apll54_enable(); +} + +static void _apll96_allow_idle(struct clk_hw_omap *clk) +{ + omap2xxx_cm_set_apll96_auto_low_power_stop(); +} + +static void _apll96_deny_idle(struct clk_hw_omap *clk) +{ + omap2xxx_cm_set_apll96_disable_autoidle(); +} + +static void _apll54_allow_idle(struct clk_hw_omap *clk) +{ + omap2xxx_cm_set_apll54_auto_low_power_stop(); +} + +static void _apll54_deny_idle(struct clk_hw_omap *clk) +{ + omap2xxx_cm_set_apll54_disable_autoidle(); +} + +void omap2_clk_apll96_disable(struct clk_hw *hw) +{ + omap2xxx_cm_apll96_disable(); +} + +void omap2_clk_apll54_disable(struct clk_hw *hw) +{ + omap2xxx_cm_apll54_disable(); +} + +unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw, + unsigned long parent_rate) +{ + return (omap2xxx_clk_apll_locked(hw)) ? 54000000 : 0; +} + +unsigned long omap2_clk_apll96_recalc(struct clk_hw *hw, + unsigned long parent_rate) +{ + return (omap2xxx_clk_apll_locked(hw)) ? 96000000 : 0; +} + +/* Public data */ +const struct clk_hw_omap_ops clkhwops_apll54 = { + .allow_idle = _apll54_allow_idle, + .deny_idle = _apll54_deny_idle, +}; + +const struct clk_hw_omap_ops clkhwops_apll96 = { + .allow_idle = _apll96_allow_idle, + .deny_idle = _apll96_deny_idle, +}; + +/* Public functions */ + +u32 omap2xxx_get_apll_clkin(void) +{ + u32 aplls, srate = 0; + + aplls = omap2xxx_cm_get_pll_config(); + aplls &= OMAP24XX_APLLS_CLKIN_MASK; + aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT; + + if (aplls == APLLS_CLKIN_19_2MHZ) + srate = 19200000; + else if (aplls == APLLS_CLKIN_13MHZ) + srate = 13000000; + else if (aplls == APLLS_CLKIN_12MHZ) + srate = 12000000; + + return srate; +} + diff --git a/arch/arm/mach-omap2/clkt2xxx_dpll.c b/arch/arm/mach-omap2/clkt2xxx_dpll.c new file mode 100644 index 00000000000..82572e277b9 --- /dev/null +++ b/arch/arm/mach-omap2/clkt2xxx_dpll.c @@ -0,0 +1,59 @@ +/* + * OMAP2-specific DPLL control functions + * + * Copyright (C) 2011 Nokia Corporation + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/clk.h> +#include <linux/io.h> + +#include "clock.h" +#include "cm2xxx.h" +#include "cm-regbits-24xx.h" + +/* Private functions */ + +/** + * _allow_idle - enable DPLL autoidle bits + * @clk: struct clk * of the DPLL to operate on + * + * Enable DPLL automatic idle control. The DPLL will enter low-power + * stop when its downstream clocks are gated. No return value. + * REVISIT: DPLL can optionally enter low-power bypass by writing 0x1 + * instead. Add some mechanism to optionally enter this mode. + */ +static void _allow_idle(struct clk_hw_omap *clk) +{ + if (!clk || !clk->dpll_data) + return; + + omap2xxx_cm_set_dpll_auto_low_power_stop(); +} + +/** + * _deny_idle - prevent DPLL from automatically idling + * @clk: struct clk * of the DPLL to operate on + * + * Disable DPLL automatic idle control. No return value. + */ +static void _deny_idle(struct clk_hw_omap *clk) +{ + if (!clk || !clk->dpll_data) + return; + + omap2xxx_cm_set_dpll_disable_autoidle(); +} + + +/* Public data */ +const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll = { + .allow_idle = _allow_idle, + .deny_idle = _deny_idle, +}; diff --git a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c new file mode 100644 index 00000000000..59cf310bc1e --- /dev/null +++ b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c @@ -0,0 +1,195 @@ +/* + * DPLL + CORE_CLK composite clock functions + * + * Copyright (C) 2005-2008 Texas Instruments, Inc. + * Copyright (C) 2004-2010 Nokia Corporation + * + * Contacts: + * Richard Woodruff <r-woodruff2@ti.com> + * Paul Walmsley + * + * Based on earlier work by Tuukka Tikkanen, Tony Lindgren, + * Gordon McNutt and RidgeRun, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * XXX The DPLL and CORE clocks should be split into two separate clock + * types. + */ +#undef DEBUG + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/clk.h> +#include <linux/io.h> + +#include "clock.h" +#include "clock2xxx.h" +#include "opp2xxx.h" +#include "cm2xxx.h" +#include "cm-regbits-24xx.h" +#include "sdrc.h" +#include "sram.h" + +/* #define DOWN_VARIABLE_DPLL 1 */ /* Experimental */ + +/* + * dpll_core_ck: pointer to the combined dpll_ck + core_ck on OMAP2xxx + * (currently defined as "dpll_ck" in the OMAP2xxx clock tree). Set + * during dpll_ck init and used later by omap2xxx_clk_get_core_rate(). + */ +static struct clk_hw_omap *dpll_core_ck; + +/** + * omap2xxx_clk_get_core_rate - return the CORE_CLK rate + * + * Returns the CORE_CLK rate. CORE_CLK can have one of three rate + * sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz + * (the latter is unusual). This currently should be called with + * struct clk *dpll_ck, which is a composite clock of dpll_ck and + * core_ck. + */ +unsigned long omap2xxx_clk_get_core_rate(void) +{ + long long core_clk; + u32 v; + + WARN_ON(!dpll_core_ck); + + core_clk = omap2_get_dpll_rate(dpll_core_ck); + + v = omap2xxx_cm_get_core_clk_src(); + + if (v == CORE_CLK_SRC_32K) + core_clk = 32768; + else + core_clk *= v; + + return core_clk; +} + +/* + * Uses the current prcm set to tell if a rate is valid. + * You can go slower, but not faster within a given rate set. + */ +static long omap2_dpllcore_round_rate(unsigned long target_rate) +{ + u32 high, low, core_clk_src; + + core_clk_src = omap2xxx_cm_get_core_clk_src(); + + if (core_clk_src == CORE_CLK_SRC_DPLL) { /* DPLL clockout */ + high = curr_prcm_set->dpll_speed * 2; + low = curr_prcm_set->dpll_speed; + } else { /* DPLL clockout x 2 */ + high = curr_prcm_set->dpll_speed; + low = curr_prcm_set->dpll_speed / 2; + } + +#ifdef DOWN_VARIABLE_DPLL + if (target_rate > high) + return high; + else + return target_rate; +#else + if (target_rate > low) + return high; + else + return low; +#endif + +} + +unsigned long omap2_dpllcore_recalc(struct clk_hw *hw, + unsigned long parent_rate) +{ + return omap2xxx_clk_get_core_rate(); +} + +int omap2_reprogram_dpllcore(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + u32 cur_rate, low, mult, div, valid_rate, done_rate; + u32 bypass = 0; + struct prcm_config tmpset; + const struct dpll_data *dd; + + cur_rate = omap2xxx_clk_get_core_rate(); + mult = omap2xxx_cm_get_core_clk_src(); + + if ((rate == (cur_rate / 2)) && (mult == 2)) { + omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1); + } else if ((rate == (cur_rate * 2)) && (mult == 1)) { + omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1); + } else if (rate != cur_rate) { + valid_rate = omap2_dpllcore_round_rate(rate); + if (valid_rate != rate) + return -EINVAL; + + if (mult == 1) + low = curr_prcm_set->dpll_speed; + else + low = curr_prcm_set->dpll_speed / 2; + + dd = clk->dpll_data; + if (!dd) + return -EINVAL; + + tmpset.cm_clksel1_pll = readl_relaxed(dd->mult_div1_reg); + tmpset.cm_clksel1_pll &= ~(dd->mult_mask | + dd->div1_mask); + div = ((curr_prcm_set->xtal_speed / 1000000) - 1); + tmpset.cm_clksel2_pll = omap2xxx_cm_get_core_pll_config(); + tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK; + if (rate > low) { + tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2; + mult = ((rate / 2) / 1000000); + done_rate = CORE_CLK_SRC_DPLL_X2; + } else { + tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL; + mult = (rate / 1000000); + done_rate = CORE_CLK_SRC_DPLL; + } + tmpset.cm_clksel1_pll |= (div << __ffs(dd->mult_mask)); + tmpset.cm_clksel1_pll |= (mult << __ffs(dd->div1_mask)); + + /* Worst case */ + tmpset.base_sdrc_rfr = SDRC_RFR_CTRL_BYPASS; + + if (rate == curr_prcm_set->xtal_speed) /* If asking for 1-1 */ + bypass = 1; + + /* For omap2xxx_sdrc_init_params() */ + omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1); + + /* Force dll lock mode */ + omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr, + bypass); + + /* Errata: ret dll entry state */ + omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked()); + omap2xxx_sdrc_reprogram(done_rate, 0); + } + + return 0; +} + +/** + * omap2xxx_clkt_dpllcore_init - clk init function for dpll_ck + * @clk: struct clk *dpll_ck + * + * Store a local copy of @clk in dpll_core_ck so other code can query + * the core rate without having to clk_get(), which can sleep. Must + * only be called once. No return value. XXX If the clock + * registration process is ever changed such that dpll_ck is no longer + * statically defined, this code may need to change to increment some + * kind of use count on dpll_ck. + */ +void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw) +{ + WARN(dpll_core_ck, "dpll_core_ck already set - should never happen"); + dpll_core_ck = to_clk_hw_omap(hw); +} diff --git a/arch/arm/mach-omap2/clkt2xxx_osc.c b/arch/arm/mach-omap2/clkt2xxx_osc.c new file mode 100644 index 00000000000..0717dff1bc0 --- /dev/null +++ b/arch/arm/mach-omap2/clkt2xxx_osc.c @@ -0,0 +1,69 @@ +/* + * OMAP2xxx osc_clk-specific clock code + * + * Copyright (C) 2005-2008 Texas Instruments, Inc. + * Copyright (C) 2004-2010 Nokia Corporation + * + * Contacts: + * Richard Woodruff <r-woodruff2@ti.com> + * Paul Walmsley + * + * Based on earlier work by Tuukka Tikkanen, Tony Lindgren, + * Gordon McNutt and RidgeRun, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#undef DEBUG + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/clk.h> +#include <linux/io.h> + +#include "clock.h" +#include "clock2xxx.h" +#include "prm2xxx_3xxx.h" +#include "prm-regbits-24xx.h" + +/* + * XXX This does not actually enable the osc_ck, since the osc_ck must + * be running for this function to be called. Instead, this function + * is used to disable an autoidle mode on the osc_ck. The existing + * clk_enable/clk_disable()-based usecounting for osc_ck should be + * replaced with autoidle-based usecounting. + */ +int omap2_enable_osc_ck(struct clk_hw *clk) +{ + u32 pcc; + + pcc = readl_relaxed(prcm_clksrc_ctrl); + + writel_relaxed(pcc & ~OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl); + + return 0; +} + +/* + * XXX This does not actually disable the osc_ck, since doing so would + * immediately halt the system. Instead, this function is used to + * enable an autoidle mode on the osc_ck. The existing + * clk_enable/clk_disable()-based usecounting for osc_ck should be + * replaced with autoidle-based usecounting. + */ +void omap2_disable_osc_ck(struct clk_hw *clk) +{ + u32 pcc; + + pcc = readl_relaxed(prcm_clksrc_ctrl); + + writel_relaxed(pcc | OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl); +} + +unsigned long omap2_osc_clk_recalc(struct clk_hw *clk, + unsigned long parent_rate) +{ + return omap2xxx_get_apll_clkin() * omap2xxx_get_sysclkdiv(); +} diff --git a/arch/arm/mach-omap2/clkt2xxx_sys.c b/arch/arm/mach-omap2/clkt2xxx_sys.c new file mode 100644 index 00000000000..58dd3a9b726 --- /dev/null +++ b/arch/arm/mach-omap2/clkt2xxx_sys.c @@ -0,0 +1,47 @@ +/* + * OMAP2xxx sys_clk-specific clock code + * + * Copyright (C) 2005-2008 Texas Instruments, Inc. + * Copyright (C) 2004-2010 Nokia Corporation + * + * Contacts: + * Richard Woodruff <r-woodruff2@ti.com> + * Paul Walmsley + * + * Based on earlier work by Tuukka Tikkanen, Tony Lindgren, + * Gordon McNutt and RidgeRun, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#undef DEBUG + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/clk.h> +#include <linux/io.h> + +#include "clock.h" +#include "clock2xxx.h" +#include "prm2xxx_3xxx.h" +#include "prm-regbits-24xx.h" + +void __iomem *prcm_clksrc_ctrl; + +u32 omap2xxx_get_sysclkdiv(void) +{ + u32 div; + + div = readl_relaxed(prcm_clksrc_ctrl); + div &= OMAP_SYSCLKDIV_MASK; + div >>= OMAP_SYSCLKDIV_SHIFT; + + return div; +} + +unsigned long omap2xxx_sys_clk_recalc(struct clk_hw *clk, + unsigned long parent_rate) +{ + return parent_rate / omap2xxx_get_sysclkdiv(); +} diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c new file mode 100644 index 00000000000..85e0b0c0671 --- /dev/null +++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c @@ -0,0 +1,263 @@ +/* + * OMAP2xxx DVFS virtual clock functions + * + * Copyright (C) 2005-2008, 2012 Texas Instruments, Inc. + * Copyright (C) 2004-2010 Nokia Corporation + * + * Contacts: + * Richard Woodruff <r-woodruff2@ti.com> + * Paul Walmsley + * + * Based on earlier work by Tuukka Tikkanen, Tony Lindgren, + * Gordon McNutt and RidgeRun, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * XXX Some of this code should be replaceable by the upcoming OPP layer + * code. However, some notion of "rate set" is probably still necessary + * for OMAP2xxx at least. Rate sets should be generalized so they can be + * used for any OMAP chip, not just OMAP2xxx. In particular, Richard Woodruff + * has in the past expressed a preference to use rate sets for OPP changes, + * rather than dynamically recalculating the clock tree, so if someone wants + * this badly enough to write the code to handle it, we should support it + * as an option. + */ +#undef DEBUG + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/cpufreq.h> +#include <linux/slab.h> + +#include "soc.h" +#include "clock.h" +#include "clock2xxx.h" +#include "opp2xxx.h" +#include "cm2xxx.h" +#include "cm-regbits-24xx.h" +#include "sdrc.h" +#include "sram.h" + +const struct prcm_config *curr_prcm_set; +const struct prcm_config *rate_table; + +/* + * sys_ck_rate: the rate of the external high-frequency clock + * oscillator on the board. Set by the SoC-specific clock init code. + * Once set during a boot, will not change. + */ +static unsigned long sys_ck_rate; + +/** + * omap2_table_mpu_recalc - just return the MPU speed + * @clk: virt_prcm_set struct clk + * + * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set. + */ +unsigned long omap2_table_mpu_recalc(struct clk_hw *clk, + unsigned long parent_rate) +{ + return curr_prcm_set->mpu_speed; +} + +/* + * Look for a rate equal or less than the target rate given a configuration set. + * + * What's not entirely clear is "which" field represents the key field. + * Some might argue L3-DDR, others ARM, others IVA. This code is simple and + * just uses the ARM rates. + */ +long omap2_round_to_table_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + const struct prcm_config *ptr; + long highest_rate; + + highest_rate = -EINVAL; + + for (ptr = rate_table; ptr->mpu_speed; ptr++) { + if (!(ptr->flags & cpu_mask)) + continue; + if (ptr->xtal_speed != sys_ck_rate) + continue; + + highest_rate = ptr->mpu_speed; + + /* Can check only after xtal frequency check */ + if (ptr->mpu_speed <= rate) + break; + } + return highest_rate; +} + +/* Sets basic clocks based on the specified rate */ +int omap2_select_table_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + u32 cur_rate, done_rate, bypass = 0; + const struct prcm_config *prcm; + unsigned long found_speed = 0; + unsigned long flags; + + for (prcm = rate_table; prcm->mpu_speed; prcm++) { + if (!(prcm->flags & cpu_mask)) + continue; + + if (prcm->xtal_speed != sys_ck_rate) + continue; + + if (prcm->mpu_speed <= rate) { + found_speed = prcm->mpu_speed; + break; + } + } + + if (!found_speed) { + printk(KERN_INFO "Could not set MPU rate to %luMHz\n", + rate / 1000000); + return -EINVAL; + } + + curr_prcm_set = prcm; + cur_rate = omap2xxx_clk_get_core_rate(); + + if (prcm->dpll_speed == cur_rate / 2) { + omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1); + } else if (prcm->dpll_speed == cur_rate * 2) { + omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1); + } else if (prcm->dpll_speed != cur_rate) { + local_irq_save(flags); + + if (prcm->dpll_speed == prcm->xtal_speed) + bypass = 1; + + if ((prcm->cm_clksel2_pll & OMAP24XX_CORE_CLK_SRC_MASK) == + CORE_CLK_SRC_DPLL_X2) + done_rate = CORE_CLK_SRC_DPLL_X2; + else + done_rate = CORE_CLK_SRC_DPLL; + + omap2xxx_cm_set_mod_dividers(prcm->cm_clksel_mpu, + prcm->cm_clksel_dsp, + prcm->cm_clksel_gfx, + prcm->cm_clksel1_core, + prcm->cm_clksel_mdm); + + /* x2 to enter omap2xxx_sdrc_init_params() */ + omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1); + + omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr, + bypass); + + omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked()); + omap2xxx_sdrc_reprogram(done_rate, 0); + + local_irq_restore(flags); + } + + return 0; +} + +/** + * omap2xxx_clkt_vps_check_bootloader_rate - determine which of the rate + * table sets matches the current CORE DPLL hardware rate + * + * Check the MPU rate set by bootloader. Sets the 'curr_prcm_set' + * global to point to the active rate set when found; otherwise, sets + * it to NULL. No return value; + */ +void omap2xxx_clkt_vps_check_bootloader_rates(void) +{ + const struct prcm_config *prcm = NULL; + unsigned long rate; + + rate = omap2xxx_clk_get_core_rate(); + for (prcm = rate_table; prcm->mpu_speed; prcm++) { + if (!(prcm->flags & cpu_mask)) + continue; + if (prcm->xtal_speed != sys_ck_rate) + continue; + if (prcm->dpll_speed <= rate) + break; + } + curr_prcm_set = prcm; +} + +/** + * omap2xxx_clkt_vps_late_init - store a copy of the sys_ck rate + * + * Store a copy of the sys_ck rate for later use by the OMAP2xxx DVFS + * code. (The sys_ck rate does not -- or rather, must not -- change + * during kernel runtime.) Must be called after we have a valid + * sys_ck rate, but before the virt_prcm_set clock rate is + * recalculated. No return value. + */ +void omap2xxx_clkt_vps_late_init(void) +{ + struct clk *c; + + c = clk_get(NULL, "sys_ck"); + if (IS_ERR(c)) { + WARN(1, "could not locate sys_ck\n"); + } else { + sys_ck_rate = clk_get_rate(c); + clk_put(c); + } +} + +#ifdef CONFIG_OF +#include <linux/clk-provider.h> +#include <linux/clkdev.h> + +static const struct clk_ops virt_prcm_set_ops = { + .recalc_rate = &omap2_table_mpu_recalc, + .set_rate = &omap2_select_table_rate, + .round_rate = &omap2_round_to_table_rate, +}; + +/** + * omap2xxx_clkt_vps_init - initialize virt_prcm_set clock + * + * Does a manual init for the virtual prcm DVFS clock for OMAP2. This + * function is called only from omap2 DT clock init, as the virtual + * node is not modelled in the DT clock data. + */ +void omap2xxx_clkt_vps_init(void) +{ + struct clk_init_data init = { NULL }; + struct clk_hw_omap *hw = NULL; + struct clk *clk; + const char *parent_name = "mpu_ck"; + struct clk_lookup *lookup = NULL; + + omap2xxx_clkt_vps_late_init(); + omap2xxx_clkt_vps_check_bootloader_rates(); + + hw = kzalloc(sizeof(*hw), GFP_KERNEL); + lookup = kzalloc(sizeof(*lookup), GFP_KERNEL); + if (!hw || !lookup) + goto cleanup; + init.name = "virt_prcm_set"; + init.ops = &virt_prcm_set_ops; + init.parent_names = &parent_name; + init.num_parents = 1; + + hw->hw.init = &init; + + clk = clk_register(NULL, &hw->hw); + + lookup->dev_id = NULL; + lookup->con_id = "cpufreq_ck"; + lookup->clk = clk; + + clkdev_add(lookup); + return; +cleanup: + kfree(hw); + kfree(lookup); +} +#endif diff --git a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c new file mode 100644 index 00000000000..eb69acf2101 --- /dev/null +++ b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c @@ -0,0 +1,119 @@ +/* + * OMAP34xx M2 divider clock code + * + * Copyright (C) 2007-2008 Texas Instruments, Inc. + * Copyright (C) 2007-2010 Nokia Corporation + * + * Paul Walmsley + * Jouni Högander + * + * Parts of this code are based on code written by + * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#undef DEBUG + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/clk.h> +#include <linux/io.h> + +#include "clock.h" +#include "clock3xxx.h" +#include "clock34xx.h" +#include "sdrc.h" +#include "sram.h" + +#define CYCLES_PER_MHZ 1000000 + +/* + * CORE DPLL (DPLL3) M2 divider rate programming functions + * + * These call into SRAM code to do the actual CM writes, since the SDRAM + * is clocked from DPLL3. + */ + +/** + * omap3_core_dpll_m2_set_rate - set CORE DPLL M2 divider + * @clk: struct clk * of DPLL to set + * @rate: rounded target rate + * + * Program the DPLL M2 divider with the rounded target rate. Returns + * -EINVAL upon error, or 0 upon success. + */ +int omap3_core_dpll_m2_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + u32 new_div = 0; + u32 unlock_dll = 0; + u32 c; + unsigned long validrate, sdrcrate, _mpurate; + struct omap_sdrc_params *sdrc_cs0; + struct omap_sdrc_params *sdrc_cs1; + int ret; + unsigned long clkrate; + + if (!clk || !rate) + return -EINVAL; + + validrate = omap2_clksel_round_rate_div(clk, rate, &new_div); + if (validrate != rate) + return -EINVAL; + + sdrcrate = __clk_get_rate(sdrc_ick_p); + clkrate = __clk_get_rate(hw->clk); + if (rate > clkrate) + sdrcrate <<= ((rate / clkrate) >> 1); + else + sdrcrate >>= ((clkrate / rate) >> 1); + + ret = omap2_sdrc_get_params(sdrcrate, &sdrc_cs0, &sdrc_cs1); + if (ret) + return -EINVAL; + + if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) { + pr_debug("clock: will unlock SDRC DLL\n"); + unlock_dll = 1; + } + + /* + * XXX This only needs to be done when the CPU frequency changes + */ + _mpurate = __clk_get_rate(arm_fck_p) / CYCLES_PER_MHZ; + c = (_mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT; + c += 1; /* for safety */ + c *= SDRC_MPURATE_LOOPS; + c >>= SDRC_MPURATE_SCALE; + if (c == 0) + c = 1; + + pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", + clkrate, validrate); + pr_debug("clock: SDRC CS0 timing params used: RFR %08x CTRLA %08x CTRLB %08x MR %08x\n", + sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla, + sdrc_cs0->actim_ctrlb, sdrc_cs0->mr); + if (sdrc_cs1) + pr_debug("clock: SDRC CS1 timing params used: RFR %08x CTRLA %08x CTRLB %08x MR %08x\n", + sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla, + sdrc_cs1->actim_ctrlb, sdrc_cs1->mr); + + if (sdrc_cs1) + omap3_configure_core_dpll( + new_div, unlock_dll, c, rate > clkrate, + sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla, + sdrc_cs0->actim_ctrlb, sdrc_cs0->mr, + sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla, + sdrc_cs1->actim_ctrlb, sdrc_cs1->mr); + else + omap3_configure_core_dpll( + new_div, unlock_dll, c, rate > clkrate, + sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla, + sdrc_cs0->actim_ctrlb, sdrc_cs0->mr, + 0, 0, 0, 0); + return 0; +} + diff --git a/arch/arm/mach-omap2/clkt_clksel.c b/arch/arm/mach-omap2/clkt_clksel.c new file mode 100644 index 00000000000..7ee26108ac0 --- /dev/null +++ b/arch/arm/mach-omap2/clkt_clksel.c @@ -0,0 +1,466 @@ +/* + * clkt_clksel.c - OMAP2/3/4 clksel clock functions + * + * Copyright (C) 2005-2008 Texas Instruments, Inc. + * Copyright (C) 2004-2010 Nokia Corporation + * + * Contacts: + * Richard Woodruff <r-woodruff2@ti.com> + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * + * clksel clocks are clocks that do not have a fixed parent, or that + * can divide their parent's rate, or possibly both at the same time, based + * on the contents of a hardware register bitfield. + * + * All of the various mux and divider settings can be encoded into + * struct clksel* data structures, and then these can be autogenerated + * from some hardware database for each new chip generation. This + * should avoid the need to write, review, and validate a lot of new + * clock code for each new chip, since it can be exported from the SoC + * design flow. This is now done on OMAP4. + * + * The fusion of mux and divider clocks is a software creation. In + * hardware reality, the multiplexer (parent selection) and the + * divider exist separately. XXX At some point these clksel clocks + * should be split into "divider" clocks and "mux" clocks to better + * match the hardware. + * + * (The name "clksel" comes from the name of the corresponding + * register field in the OMAP2/3 family of SoCs.) + * + * XXX Currently these clocks are only used in the OMAP2/3/4 code, but + * many of the OMAP1 clocks should be convertible to use this + * mechanism. + */ +#undef DEBUG + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/clk-provider.h> +#include <linux/io.h> +#include <linux/bug.h> + +#include "clock.h" + +/* Private functions */ + +/** + * _get_clksel_by_parent() - return clksel struct for a given clk & parent + * @clk: OMAP struct clk ptr to inspect + * @src_clk: OMAP struct clk ptr of the parent clk to search for + * + * Scan the struct clksel array associated with the clock to find + * the element associated with the supplied parent clock address. + * Returns a pointer to the struct clksel on success or NULL on error. + */ +static const struct clksel *_get_clksel_by_parent(struct clk_hw_omap *clk, + struct clk *src_clk) +{ + const struct clksel *clks; + + if (!src_clk) + return NULL; + + for (clks = clk->clksel; clks->parent; clks++) + if (clks->parent == src_clk) + break; /* Found the requested parent */ + + if (!clks->parent) { + /* This indicates a data problem */ + WARN(1, "clock: %s: could not find parent clock %s in clksel array\n", + __clk_get_name(clk->hw.clk), __clk_get_name(src_clk)); + return NULL; + } + + return clks; +} + +/** + * _write_clksel_reg() - program a clock's clksel register in hardware + * @clk: struct clk * to program + * @v: clksel bitfield value to program (with LSB at bit 0) + * + * Shift the clksel register bitfield value @v to its appropriate + * location in the clksel register and write it in. This function + * will ensure that the write to the clksel_reg reaches its + * destination before returning -- important since PRM and CM register + * accesses can be quite slow compared to ARM cycles -- but does not + * take into account any time the hardware might take to switch the + * clock source. + */ +static void _write_clksel_reg(struct clk_hw_omap *clk, u32 field_val) +{ + u32 v; + + v = omap2_clk_readl(clk, clk->clksel_reg); + v &= ~clk->clksel_mask; + v |= field_val << __ffs(clk->clksel_mask); + omap2_clk_writel(v, clk, clk->clksel_reg); + + v = omap2_clk_readl(clk, clk->clksel_reg); /* OCP barrier */ +} + +/** + * _clksel_to_divisor() - turn clksel field value into integer divider + * @clk: OMAP struct clk to use + * @field_val: register field value to find + * + * Given a struct clk of a rate-selectable clksel clock, and a register field + * value to search for, find the corresponding clock divisor. The register + * field value should be pre-masked and shifted down so the LSB is at bit 0 + * before calling. Returns 0 on error or returns the actual integer divisor + * upon success. + */ +static u32 _clksel_to_divisor(struct clk_hw_omap *clk, u32 field_val) +{ + const struct clksel *clks; + const struct clksel_rate *clkr; + struct clk *parent; + + parent = __clk_get_parent(clk->hw.clk); + + clks = _get_clksel_by_parent(clk, parent); + if (!clks) + return 0; + + for (clkr = clks->rates; clkr->div; clkr++) { + if (!(clkr->flags & cpu_mask)) + continue; + + if (clkr->val == field_val) + break; + } + + if (!clkr->div) { + /* This indicates a data error */ + WARN(1, "clock: %s: could not find fieldval %d for parent %s\n", + __clk_get_name(clk->hw.clk), field_val, + __clk_get_name(parent)); + return 0; + } + + return clkr->div; +} + +/** + * _divisor_to_clksel() - turn clksel integer divisor into a field value + * @clk: OMAP struct clk to use + * @div: integer divisor to search for + * + * Given a struct clk of a rate-selectable clksel clock, and a clock + * divisor, find the corresponding register field value. Returns the + * register field value _before_ left-shifting (i.e., LSB is at bit + * 0); or returns 0xFFFFFFFF (~0) upon error. + */ +static u32 _divisor_to_clksel(struct clk_hw_omap *clk, u32 div) +{ + const struct clksel *clks; + const struct clksel_rate *clkr; + struct clk *parent; + + /* should never happen */ + WARN_ON(div == 0); + + parent = __clk_get_parent(clk->hw.clk); + clks = _get_clksel_by_parent(clk, parent); + if (!clks) + return ~0; + + for (clkr = clks->rates; clkr->div; clkr++) { + if (!(clkr->flags & cpu_mask)) + continue; + + if (clkr->div == div) + break; + } + + if (!clkr->div) { + pr_err("clock: %s: could not find divisor %d for parent %s\n", + __clk_get_name(clk->hw.clk), div, + __clk_get_name(parent)); + return ~0; + } + + return clkr->val; +} + +/** + * _read_divisor() - get current divisor applied to parent clock (from hdwr) + * @clk: OMAP struct clk to use. + * + * Read the current divisor register value for @clk that is programmed + * into the hardware, convert it into the actual divisor value, and + * return it; or return 0 on error. + */ +static u32 _read_divisor(struct clk_hw_omap *clk) +{ + u32 v; + + if (!clk->clksel || !clk->clksel_mask) + return 0; + + v = omap2_clk_readl(clk, clk->clksel_reg); + v &= clk->clksel_mask; + v >>= __ffs(clk->clksel_mask); + + return _clksel_to_divisor(clk, v); +} + +/* Public functions */ + +/** + * omap2_clksel_round_rate_div() - find divisor for the given clock and rate + * @clk: OMAP struct clk to use + * @target_rate: desired clock rate + * @new_div: ptr to where we should store the divisor + * + * Finds 'best' divider value in an array based on the source and target + * rates. The divider array must be sorted with smallest divider first. + * This function is also used by the DPLL3 M2 divider code. + * + * Returns the rounded clock rate or returns 0xffffffff on error. + */ +u32 omap2_clksel_round_rate_div(struct clk_hw_omap *clk, + unsigned long target_rate, + u32 *new_div) +{ + unsigned long test_rate; + const struct clksel *clks; + const struct clksel_rate *clkr; + u32 last_div = 0; + struct clk *parent; + unsigned long parent_rate; + const char *clk_name; + + parent = __clk_get_parent(clk->hw.clk); + clk_name = __clk_get_name(clk->hw.clk); + parent_rate = __clk_get_rate(parent); + + if (!clk->clksel || !clk->clksel_mask) + return ~0; + + pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n", + clk_name, target_rate); + + *new_div = 1; + + clks = _get_clksel_by_parent(clk, parent); + if (!clks) + return ~0; + + for (clkr = clks->rates; clkr->div; clkr++) { + if (!(clkr->flags & cpu_mask)) + continue; + + /* Sanity check */ + if (clkr->div <= last_div) + pr_err("clock: %s: clksel_rate table not sorted\n", + clk_name); + + last_div = clkr->div; + + test_rate = parent_rate / clkr->div; + + if (test_rate <= target_rate) + break; /* found it */ + } + + if (!clkr->div) { + pr_err("clock: %s: could not find divisor for target rate %ld for parent %s\n", + clk_name, target_rate, __clk_get_name(parent)); + return ~0; + } + + *new_div = clkr->div; + + pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div, + (parent_rate / clkr->div)); + + return parent_rate / clkr->div; +} + +/* + * Clocktype interface functions to the OMAP clock code + * (i.e., those used in struct clk field function pointers, etc.) + */ + +/** + * omap2_clksel_find_parent_index() - return the array index of the current + * hardware parent of @hw + * @hw: struct clk_hw * to find the current hardware parent of + * + * Given a struct clk_hw pointer @hw to the 'hw' member of a struct + * clk_hw_omap record representing a source-selectable hardware clock, + * read the hardware register and determine what its parent is + * currently set to. Intended to be called only by the common clock + * framework struct clk_hw_ops.get_parent function pointer. Return + * the array index of this parent clock upon success -- there is no + * way to return an error, so if we encounter an error, just WARN() + * and pretend that we know that we're doing. + */ +u8 omap2_clksel_find_parent_index(struct clk_hw *hw) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + const struct clksel *clks; + const struct clksel_rate *clkr; + u32 r, found = 0; + struct clk *parent; + const char *clk_name; + int ret = 0, f = 0; + + parent = __clk_get_parent(hw->clk); + clk_name = __clk_get_name(hw->clk); + + /* XXX should be able to return an error */ + WARN((!clk->clksel || !clk->clksel_mask), + "clock: %s: attempt to call on a non-clksel clock", clk_name); + + r = omap2_clk_readl(clk, clk->clksel_reg) & clk->clksel_mask; + r >>= __ffs(clk->clksel_mask); + + for (clks = clk->clksel; clks->parent && !found; clks++) { + for (clkr = clks->rates; clkr->div && !found; clkr++) { + if (!(clkr->flags & cpu_mask)) + continue; + + if (clkr->val == r) { + found = 1; + ret = f; + } + } + f++; + } + + /* This indicates a data error */ + WARN(!found, "clock: %s: init parent: could not find regval %0x\n", + clk_name, r); + + return ret; +} + + +/** + * omap2_clksel_recalc() - function ptr to pass via struct clk .recalc field + * @clk: struct clk * + * + * This function is intended to be called only by the clock framework. + * Each clksel clock should have its struct clk .recalc field set to this + * function. Returns the clock's current rate, based on its parent's rate + * and its current divisor setting in the hardware. + */ +unsigned long omap2_clksel_recalc(struct clk_hw *hw, unsigned long parent_rate) +{ + unsigned long rate; + u32 div = 0; + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + + if (!parent_rate) + return 0; + + div = _read_divisor(clk); + if (!div) + rate = parent_rate; + else + rate = parent_rate / div; + + pr_debug("%s: recalc'd %s's rate to %lu (div %d)\n", __func__, + __clk_get_name(hw->clk), rate, div); + + return rate; +} + +/** + * omap2_clksel_round_rate() - find rounded rate for the given clock and rate + * @clk: OMAP struct clk to use + * @target_rate: desired clock rate + * + * This function is intended to be called only by the clock framework. + * Finds best target rate based on the source clock and possible dividers. + * rates. The divider array must be sorted with smallest divider first. + * + * Returns the rounded clock rate or returns 0xffffffff on error. + */ +long omap2_clksel_round_rate(struct clk_hw *hw, unsigned long target_rate, + unsigned long *parent_rate) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + u32 new_div; + + return omap2_clksel_round_rate_div(clk, target_rate, &new_div); +} + +/** + * omap2_clksel_set_rate() - program clock rate in hardware + * @clk: struct clk * to program rate + * @rate: target rate to program + * + * This function is intended to be called only by the clock framework. + * Program @clk's rate to @rate in the hardware. The clock can be + * either enabled or disabled when this happens, although if the clock + * is enabled, some downstream devices may glitch or behave + * unpredictably when the clock rate is changed - this depends on the + * hardware. This function does not currently check the usecount of + * the clock, so if multiple drivers are using the clock, and the rate + * is changed, they will all be affected without any notification. + * Returns -EINVAL upon error, or 0 upon success. + */ +int omap2_clksel_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + u32 field_val, validrate, new_div = 0; + + if (!clk->clksel || !clk->clksel_mask) + return -EINVAL; + + validrate = omap2_clksel_round_rate_div(clk, rate, &new_div); + if (validrate != rate) + return -EINVAL; + + field_val = _divisor_to_clksel(clk, new_div); + if (field_val == ~0) + return -EINVAL; + + _write_clksel_reg(clk, field_val); + + pr_debug("clock: %s: set rate to %ld\n", __clk_get_name(hw->clk), + __clk_get_rate(hw->clk)); + + return 0; +} + +/* + * Clksel parent setting function - not passed in struct clk function + * pointer - instead, the OMAP clock code currently assumes that any + * parent-setting clock is a clksel clock, and calls + * omap2_clksel_set_parent() by default + */ + +/** + * omap2_clksel_set_parent() - change a clock's parent clock + * @clk: struct clk * of the child clock + * @new_parent: struct clk * of the new parent clock + * + * This function is intended to be called only by the clock framework. + * Change the parent clock of clock @clk to @new_parent. This is + * intended to be used while @clk is disabled. This function does not + * currently check the usecount of the clock, so if multiple drivers + * are using the clock, and the parent is changed, they will all be + * affected without any notification. Returns -EINVAL upon error, or + * 0 upon success. + */ +int omap2_clksel_set_parent(struct clk_hw *hw, u8 field_val) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + + if (!clk->clksel || !clk->clksel_mask) + return -EINVAL; + + _write_clksel_reg(clk, field_val); + return 0; +} diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c new file mode 100644 index 00000000000..67fd26a1844 --- /dev/null +++ b/arch/arm/mach-omap2/clkt_dpll.c @@ -0,0 +1,364 @@ +/* + * OMAP2/3/4 DPLL clock functions + * + * Copyright (C) 2005-2008 Texas Instruments, Inc. + * Copyright (C) 2004-2010 Nokia Corporation + * + * Contacts: + * Richard Woodruff <r-woodruff2@ti.com> + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#undef DEBUG + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/clk-provider.h> +#include <linux/io.h> + +#include <asm/div64.h> + +#include "soc.h" +#include "clock.h" +#include "cm-regbits-24xx.h" +#include "cm-regbits-34xx.h" + +/* DPLL rate rounding: minimum DPLL multiplier, divider values */ +#define DPLL_MIN_MULTIPLIER 2 +#define DPLL_MIN_DIVIDER 1 + +/* Possible error results from _dpll_test_mult */ +#define DPLL_MULT_UNDERFLOW -1 + +/* + * Scale factor to mitigate roundoff errors in DPLL rate rounding. + * The higher the scale factor, the greater the risk of arithmetic overflow, + * but the closer the rounded rate to the target rate. DPLL_SCALE_FACTOR + * must be a power of DPLL_SCALE_BASE. + */ +#define DPLL_SCALE_FACTOR 64 +#define DPLL_SCALE_BASE 2 +#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \ + (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE)) + +/* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */ +#define OMAP3430_DPLL_FINT_BAND1_MIN 750000 +#define OMAP3430_DPLL_FINT_BAND1_MAX 2100000 +#define OMAP3430_DPLL_FINT_BAND2_MIN 7500000 +#define OMAP3430_DPLL_FINT_BAND2_MAX 21000000 + +/* + * DPLL valid Fint frequency range for OMAP36xx and OMAP4xxx. + * From device data manual section 4.3 "DPLL and DLL Specifications". + */ +#define OMAP3PLUS_DPLL_FINT_JTYPE_MIN 500000 +#define OMAP3PLUS_DPLL_FINT_JTYPE_MAX 2500000 +#define OMAP3PLUS_DPLL_FINT_MIN 32000 +#define OMAP3PLUS_DPLL_FINT_MAX 52000000 + +/* _dpll_test_fint() return codes */ +#define DPLL_FINT_UNDERFLOW -1 +#define DPLL_FINT_INVALID -2 + +/* Private functions */ + +/* + * _dpll_test_fint - test whether an Fint value is valid for the DPLL + * @clk: DPLL struct clk to test + * @n: divider value (N) to test + * + * Tests whether a particular divider @n will result in a valid DPLL + * internal clock frequency Fint. See the 34xx TRM 4.7.6.2 "DPLL Jitter + * Correction". Returns 0 if OK, -1 if the enclosing loop can terminate + * (assuming that it is counting N upwards), or -2 if the enclosing loop + * should skip to the next iteration (again assuming N is increasing). + */ +static int _dpll_test_fint(struct clk_hw_omap *clk, unsigned int n) +{ + struct dpll_data *dd; + long fint, fint_min, fint_max; + int ret = 0; + + dd = clk->dpll_data; + + /* DPLL divider must result in a valid jitter correction val */ + fint = __clk_get_rate(__clk_get_parent(clk->hw.clk)) / n; + + if (cpu_is_omap24xx()) { + /* Should not be called for OMAP2, so warn if it is called */ + WARN(1, "No fint limits available for OMAP2!\n"); + return DPLL_FINT_INVALID; + } else if (cpu_is_omap3430()) { + fint_min = OMAP3430_DPLL_FINT_BAND1_MIN; + fint_max = OMAP3430_DPLL_FINT_BAND2_MAX; + } else if (dd->flags & DPLL_J_TYPE) { + fint_min = OMAP3PLUS_DPLL_FINT_JTYPE_MIN; + fint_max = OMAP3PLUS_DPLL_FINT_JTYPE_MAX; + } else { + fint_min = OMAP3PLUS_DPLL_FINT_MIN; + fint_max = OMAP3PLUS_DPLL_FINT_MAX; + } + + if (fint < fint_min) { + pr_debug("rejecting n=%d due to Fint failure, lowering max_divider\n", + n); + dd->max_divider = n; + ret = DPLL_FINT_UNDERFLOW; + } else if (fint > fint_max) { + pr_debug("rejecting n=%d due to Fint failure, boosting min_divider\n", + n); + dd->min_divider = n; + ret = DPLL_FINT_INVALID; + } else if (cpu_is_omap3430() && fint > OMAP3430_DPLL_FINT_BAND1_MAX && + fint < OMAP3430_DPLL_FINT_BAND2_MIN) { + pr_debug("rejecting n=%d due to Fint failure\n", n); + ret = DPLL_FINT_INVALID; + } + + return ret; +} + +static unsigned long _dpll_compute_new_rate(unsigned long parent_rate, + unsigned int m, unsigned int n) +{ + unsigned long long num; + + num = (unsigned long long)parent_rate * m; + do_div(num, n); + return num; +} + +/* + * _dpll_test_mult - test a DPLL multiplier value + * @m: pointer to the DPLL m (multiplier) value under test + * @n: current DPLL n (divider) value under test + * @new_rate: pointer to storage for the resulting rounded rate + * @target_rate: the desired DPLL rate + * @parent_rate: the DPLL's parent clock rate + * + * This code tests a DPLL multiplier value, ensuring that the + * resulting rate will not be higher than the target_rate, and that + * the multiplier value itself is valid for the DPLL. Initially, the + * integer pointed to by the m argument should be prescaled by + * multiplying by DPLL_SCALE_FACTOR. The code will replace this with + * a non-scaled m upon return. This non-scaled m will result in a + * new_rate as close as possible to target_rate (but not greater than + * target_rate) given the current (parent_rate, n, prescaled m) + * triple. Returns DPLL_MULT_UNDERFLOW in the event that the + * non-scaled m attempted to underflow, which can allow the calling + * function to bail out early; or 0 upon success. + */ +static int _dpll_test_mult(int *m, int n, unsigned long *new_rate, + unsigned long target_rate, + unsigned long parent_rate) +{ + int r = 0, carry = 0; + + /* Unscale m and round if necessary */ + if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL) + carry = 1; + *m = (*m / DPLL_SCALE_FACTOR) + carry; + + /* + * The new rate must be <= the target rate to avoid programming + * a rate that is impossible for the hardware to handle + */ + *new_rate = _dpll_compute_new_rate(parent_rate, *m, n); + if (*new_rate > target_rate) { + (*m)--; + *new_rate = 0; + } + + /* Guard against m underflow */ + if (*m < DPLL_MIN_MULTIPLIER) { + *m = DPLL_MIN_MULTIPLIER; + *new_rate = 0; + r = DPLL_MULT_UNDERFLOW; + } + + if (*new_rate == 0) + *new_rate = _dpll_compute_new_rate(parent_rate, *m, n); + + return r; +} + +/* Public functions */ +u8 omap2_init_dpll_parent(struct clk_hw *hw) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + u32 v; + struct dpll_data *dd; + + dd = clk->dpll_data; + if (!dd) + return -EINVAL; + + v = omap2_clk_readl(clk, dd->control_reg); + v &= dd->enable_mask; + v >>= __ffs(dd->enable_mask); + + /* Reparent the struct clk in case the dpll is in bypass */ + if (cpu_is_omap24xx()) { + if (v == OMAP2XXX_EN_DPLL_LPBYPASS || + v == OMAP2XXX_EN_DPLL_FRBYPASS) + return 1; + } else if (cpu_is_omap34xx()) { + if (v == OMAP3XXX_EN_DPLL_LPBYPASS || + v == OMAP3XXX_EN_DPLL_FRBYPASS) + return 1; + } else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx()) { + if (v == OMAP4XXX_EN_DPLL_LPBYPASS || + v == OMAP4XXX_EN_DPLL_FRBYPASS || + v == OMAP4XXX_EN_DPLL_MNBYPASS) + return 1; + } + return 0; +} + +/** + * omap2_get_dpll_rate - returns the current DPLL CLKOUT rate + * @clk: struct clk * of a DPLL + * + * DPLLs can be locked or bypassed - basically, enabled or disabled. + * When locked, the DPLL output depends on the M and N values. When + * bypassed, on OMAP2xxx, the output rate is either the 32KiHz clock + * or sys_clk. Bypass rates on OMAP3 depend on the DPLL: DPLLs 1 and + * 2 are bypassed with dpll1_fclk and dpll2_fclk respectively + * (generated by DPLL3), while DPLL 3, 4, and 5 bypass rates are sys_clk. + * Returns the current DPLL CLKOUT rate (*not* CLKOUTX2) if the DPLL is + * locked, or the appropriate bypass rate if the DPLL is bypassed, or 0 + * if the clock @clk is not a DPLL. + */ +unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk) +{ + long long dpll_clk; + u32 dpll_mult, dpll_div, v; + struct dpll_data *dd; + + dd = clk->dpll_data; + if (!dd) + return 0; + + /* Return bypass rate if DPLL is bypassed */ + v = omap2_clk_readl(clk, dd->control_reg); + v &= dd->enable_mask; + v >>= __ffs(dd->enable_mask); + + if (cpu_is_omap24xx()) { + if (v == OMAP2XXX_EN_DPLL_LPBYPASS || + v == OMAP2XXX_EN_DPLL_FRBYPASS) + return __clk_get_rate(dd->clk_bypass); + } else if (cpu_is_omap34xx()) { + if (v == OMAP3XXX_EN_DPLL_LPBYPASS || + v == OMAP3XXX_EN_DPLL_FRBYPASS) + return __clk_get_rate(dd->clk_bypass); + } else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx()) { + if (v == OMAP4XXX_EN_DPLL_LPBYPASS || + v == OMAP4XXX_EN_DPLL_FRBYPASS || + v == OMAP4XXX_EN_DPLL_MNBYPASS) + return __clk_get_rate(dd->clk_bypass); + } + + v = omap2_clk_readl(clk, dd->mult_div1_reg); + dpll_mult = v & dd->mult_mask; + dpll_mult >>= __ffs(dd->mult_mask); + dpll_div = v & dd->div1_mask; + dpll_div >>= __ffs(dd->div1_mask); + + dpll_clk = (long long) __clk_get_rate(dd->clk_ref) * dpll_mult; + do_div(dpll_clk, dpll_div + 1); + + return dpll_clk; +} + +/* DPLL rate rounding code */ + +/** + * omap2_dpll_round_rate - round a target rate for an OMAP DPLL + * @clk: struct clk * for a DPLL + * @target_rate: desired DPLL clock rate + * + * Given a DPLL and a desired target rate, round the target rate to a + * possible, programmable rate for this DPLL. Attempts to select the + * minimum possible n. Stores the computed (m, n) in the DPLL's + * dpll_data structure so set_rate() will not need to call this + * (expensive) function again. Returns ~0 if the target rate cannot + * be rounded, or the rounded rate upon success. + */ +long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, + unsigned long *parent_rate) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + int m, n, r, scaled_max_m; + unsigned long scaled_rt_rp; + unsigned long new_rate = 0; + struct dpll_data *dd; + unsigned long ref_rate; + const char *clk_name; + + if (!clk || !clk->dpll_data) + return ~0; + + dd = clk->dpll_data; + + ref_rate = __clk_get_rate(dd->clk_ref); + clk_name = __clk_get_name(hw->clk); + pr_debug("clock: %s: starting DPLL round_rate, target rate %lu\n", + clk_name, target_rate); + + scaled_rt_rp = target_rate / (ref_rate / DPLL_SCALE_FACTOR); + scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR; + + dd->last_rounded_rate = 0; + + for (n = dd->min_divider; n <= dd->max_divider; n++) { + + /* Is the (input clk, divider) pair valid for the DPLL? */ + r = _dpll_test_fint(clk, n); + if (r == DPLL_FINT_UNDERFLOW) + break; + else if (r == DPLL_FINT_INVALID) + continue; + + /* Compute the scaled DPLL multiplier, based on the divider */ + m = scaled_rt_rp * n; + + /* + * Since we're counting n up, a m overflow means we + * can bail out completely (since as n increases in + * the next iteration, there's no way that m can + * increase beyond the current m) + */ + if (m > scaled_max_m) + break; + + r = _dpll_test_mult(&m, n, &new_rate, target_rate, + ref_rate); + + /* m can't be set low enough for this n - try with a larger n */ + if (r == DPLL_MULT_UNDERFLOW) + continue; + + pr_debug("clock: %s: m = %d: n = %d: new_rate = %lu\n", + clk_name, m, n, new_rate); + + if (target_rate == new_rate) { + dd->last_rounded_m = m; + dd->last_rounded_n = n; + dd->last_rounded_rate = target_rate; + break; + } + } + + if (target_rate != new_rate) { + pr_debug("clock: %s: cannot round to rate %lu\n", + clk_name, target_rate); + return ~0; + } + + return target_rate; +} + diff --git a/arch/arm/mach-omap2/clkt_iclk.c b/arch/arm/mach-omap2/clkt_iclk.c new file mode 100644 index 00000000000..333f0a66617 --- /dev/null +++ b/arch/arm/mach-omap2/clkt_iclk.c @@ -0,0 +1,68 @@ +/* + * OMAP2/3 interface clock control + * + * Copyright (C) 2011 Nokia Corporation + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#undef DEBUG + +#include <linux/kernel.h> +#include <linux/clk-provider.h> +#include <linux/io.h> + + +#include "clock.h" +#include "clock2xxx.h" +#include "cm2xxx_3xxx.h" +#include "cm-regbits-24xx.h" + +/* Private functions */ + +/* XXX */ +void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk) +{ + u32 v; + void __iomem *r; + + r = (__force void __iomem *) + ((__force u32)clk->enable_reg ^ (CM_AUTOIDLE ^ CM_ICLKEN)); + + v = omap2_clk_readl(clk, r); + v |= (1 << clk->enable_bit); + omap2_clk_writel(v, clk, r); +} + +/* XXX */ +void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk) +{ + u32 v; + void __iomem *r; + + r = (__force void __iomem *) + ((__force u32)clk->enable_reg ^ (CM_AUTOIDLE ^ CM_ICLKEN)); + + v = omap2_clk_readl(clk, r); + v &= ~(1 << clk->enable_bit); + omap2_clk_writel(v, clk, r); +} + +/* Public data */ + +const struct clk_hw_omap_ops clkhwops_iclk = { + .allow_idle = omap2_clkt_iclk_allow_idle, + .deny_idle = omap2_clkt_iclk_deny_idle, +}; + +const struct clk_hw_omap_ops clkhwops_iclk_wait = { + .allow_idle = omap2_clkt_iclk_allow_idle, + .deny_idle = omap2_clkt_iclk_deny_idle, + .find_idlest = omap2_clk_dflt_find_idlest, + .find_companion = omap2_clk_dflt_find_companion, +}; + + + diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index ce4d46a4a83..591581a6653 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -2,7 +2,7 @@ * linux/arch/arm/mach-omap2/clock.c * * Copyright (C) 2005-2008 Texas Instruments, Inc. - * Copyright (C) 2004-2008 Nokia Corporation + * Copyright (C) 2004-2010 Nokia Corporation * * Contacts: * Richard Woodruff <r-woodruff2@ti.com> @@ -14,965 +14,720 @@ */ #undef DEBUG -#include <linux/module.h> #include <linux/kernel.h> -#include <linux/device.h> +#include <linux/export.h> #include <linux/list.h> #include <linux/errno.h> +#include <linux/err.h> #include <linux/delay.h> -#include <linux/clk.h> +#include <linux/clk-provider.h> #include <linux/io.h> #include <linux/bitops.h> +#include <linux/clk-private.h> +#include <asm/cpu.h> -#include <mach/clock.h> -#include <mach/clockdomain.h> -#include <mach/sram.h> -#include <mach/cpu.h> -#include <asm/div64.h> +#include <trace/events/power.h> -#include "memory.h" -#include "sdrc.h" +#include "soc.h" +#include "clockdomain.h" #include "clock.h" -#include "prm.h" -#include "prm-regbits-24xx.h" #include "cm.h" +#include "cm2xxx.h" +#include "cm3xxx.h" #include "cm-regbits-24xx.h" #include "cm-regbits-34xx.h" - -#define MAX_CLOCK_ENABLE_WAIT 100000 - -/* DPLL rate rounding: minimum DPLL multiplier, divider values */ -#define DPLL_MIN_MULTIPLIER 1 -#define DPLL_MIN_DIVIDER 1 - -/* Possible error results from _dpll_test_mult */ -#define DPLL_MULT_UNDERFLOW (1 << 0) +#include "common.h" /* - * Scale factor to mitigate roundoff errors in DPLL rate rounding. - * The higher the scale factor, the greater the risk of arithmetic overflow, - * but the closer the rounded rate to the target rate. DPLL_SCALE_FACTOR - * must be a power of DPLL_SCALE_BASE. + * MAX_MODULE_ENABLE_WAIT: maximum of number of microseconds to wait + * for a module to indicate that it is no longer in idle */ -#define DPLL_SCALE_FACTOR 64 -#define DPLL_SCALE_BASE 2 -#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \ - (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE)) +#define MAX_MODULE_ENABLE_WAIT 100000 -u8 cpu_mask; +u16 cpu_mask; -/*------------------------------------------------------------------------- - * OMAP2/3 specific clock functions - *-------------------------------------------------------------------------*/ - -/** - * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk - * @clk: OMAP clock struct ptr to use - * - * Convert a clockdomain name stored in a struct clk 'clk' into a - * clockdomain pointer, and save it into the struct clk. Intended to be - * called during clk_register(). No return value. +/* + * clkdm_control: if true, then when a clock is enabled in the + * hardware, its clockdomain will first be enabled; and when a clock + * is disabled in the hardware, its clockdomain will be disabled + * afterwards. */ -void omap2_init_clk_clkdm(struct clk *clk) -{ - struct clockdomain *clkdm; +static bool clkdm_control = true; - if (!clk->clkdm_name) - return; +static LIST_HEAD(clk_hw_omap_clocks); +void __iomem *clk_memmaps[CLK_MAX_MEMMAPS]; - clkdm = clkdm_lookup(clk->clkdm_name); - if (clkdm) { - pr_debug("clock: associated clk %s to clkdm %s\n", - clk->name, clk->clkdm_name); - clk->clkdm = clkdm; +void omap2_clk_writel(u32 val, struct clk_hw_omap *clk, void __iomem *reg) +{ + if (clk->flags & MEMMAP_ADDRESSING) { + struct clk_omap_reg *r = (struct clk_omap_reg *)® + writel_relaxed(val, clk_memmaps[r->index] + r->offset); } else { - pr_debug("clock: could not associate clk %s to " - "clkdm %s\n", clk->name, clk->clkdm_name); + writel_relaxed(val, reg); } } -/** - * omap2_init_clksel_parent - set a clksel clk's parent field from the hardware - * @clk: OMAP clock struct ptr to use - * - * Given a pointer to a source-selectable struct clk, read the hardware - * register and determine what its parent is currently set to. Update the - * clk->parent field with the appropriate clk ptr. - */ -void omap2_init_clksel_parent(struct clk *clk) +u32 omap2_clk_readl(struct clk_hw_omap *clk, void __iomem *reg) { - const struct clksel *clks; - const struct clksel_rate *clkr; - u32 r, found = 0; - - if (!clk->clksel) - return; + u32 val; - r = __raw_readl(clk->clksel_reg) & clk->clksel_mask; - r >>= __ffs(clk->clksel_mask); - - for (clks = clk->clksel; clks->parent && !found; clks++) { - for (clkr = clks->rates; clkr->div && !found; clkr++) { - if ((clkr->flags & cpu_mask) && (clkr->val == r)) { - if (clk->parent != clks->parent) { - pr_debug("clock: inited %s parent " - "to %s (was %s)\n", - clk->name, clks->parent->name, - ((clk->parent) ? - clk->parent->name : "NULL")); - clk->parent = clks->parent; - }; - found = 1; - } - } + if (clk->flags & MEMMAP_ADDRESSING) { + struct clk_omap_reg *r = (struct clk_omap_reg *)® + val = readl_relaxed(clk_memmaps[r->index] + r->offset); + } else { + val = readl_relaxed(reg); } - if (!found) - printk(KERN_ERR "clock: init parent: could not find " - "regval %0x for clock %s\n", r, clk->name); - - return; + return val; } -/* Returns the DPLL rate */ -u32 omap2_get_dpll_rate(struct clk *clk) +/* + * Used for clocks that have the same value as the parent clock, + * divided by some factor + */ +unsigned long omap_fixed_divisor_recalc(struct clk_hw *hw, + unsigned long parent_rate) { - long long dpll_clk; - u32 dpll_mult, dpll_div, dpll; - struct dpll_data *dd; + struct clk_hw_omap *oclk; - dd = clk->dpll_data; - /* REVISIT: What do we return on error? */ - if (!dd) - return 0; + if (!hw) { + pr_warn("%s: hw is NULL\n", __func__); + return -EINVAL; + } - dpll = __raw_readl(dd->mult_div1_reg); - dpll_mult = dpll & dd->mult_mask; - dpll_mult >>= __ffs(dd->mult_mask); - dpll_div = dpll & dd->div1_mask; - dpll_div >>= __ffs(dd->div1_mask); + oclk = to_clk_hw_omap(hw); - dpll_clk = (long long)clk->parent->rate * dpll_mult; - do_div(dpll_clk, dpll_div + 1); + WARN_ON(!oclk->fixed_div); - return dpll_clk; + return parent_rate / oclk->fixed_div; } /* - * Used for clocks that have the same value as the parent clock, - * divided by some factor + * OMAP2+ specific clock functions */ -void omap2_fixed_divisor_recalc(struct clk *clk) -{ - WARN_ON(!clk->fixed_div); - clk->rate = clk->parent->rate / clk->fixed_div; +/* Private functions */ - if (clk->flags & RATE_PROPAGATES) - propagate_rate(clk); -} /** - * omap2_wait_clock_ready - wait for clock to enable - * @reg: physical address of clock IDLEST register - * @mask: value to mask against to determine if the clock is active + * _wait_idlest_generic - wait for a module to leave the idle state + * @clk: module clock to wait for (needed for register offsets) + * @reg: virtual address of module IDLEST register + * @mask: value to mask against to determine if the module is active + * @idlest: idle state indicator (0 or 1) for the clock * @name: name of the clock (for printk) * - * Returns 1 if the clock enabled in time, or 0 if it failed to enable - * in roughly MAX_CLOCK_ENABLE_WAIT microseconds. + * Wait for a module to leave idle, where its idle-status register is + * not inside the CM module. Returns 1 if the module left idle + * promptly, or 0 if the module did not leave idle before the timeout + * elapsed. XXX Deprecated - should be moved into drivers for the + * individual IP block that the IDLEST register exists in. */ -int omap2_wait_clock_ready(void __iomem *reg, u32 mask, const char *name) +static int _wait_idlest_generic(struct clk_hw_omap *clk, void __iomem *reg, + u32 mask, u8 idlest, const char *name) { - int i = 0; - int ena = 0; + int i = 0, ena = 0; - /* - * 24xx uses 0 to indicate not ready, and 1 to indicate ready. - * 34xx reverses this, just to keep us on our toes - */ - if (cpu_mask & (RATE_IN_242X | RATE_IN_243X)) { - ena = mask; - } else if (cpu_mask & RATE_IN_343X) { - ena = 0; - } + ena = (idlest) ? 0 : mask; - /* Wait for lock */ - while (((__raw_readl(reg) & mask) != ena) && - (i++ < MAX_CLOCK_ENABLE_WAIT)) { - udelay(1); - } + omap_test_timeout(((omap2_clk_readl(clk, reg) & mask) == ena), + MAX_MODULE_ENABLE_WAIT, i); - if (i < MAX_CLOCK_ENABLE_WAIT) - pr_debug("Clock %s stable after %d loops\n", name, i); + if (i < MAX_MODULE_ENABLE_WAIT) + pr_debug("omap clock: module associated with clock %s ready after %d loops\n", + name, i); else - printk(KERN_ERR "Clock %s didn't enable in %d tries\n", - name, MAX_CLOCK_ENABLE_WAIT); - + pr_err("omap clock: module associated with clock %s didn't enable in %d tries\n", + name, MAX_MODULE_ENABLE_WAIT); - return (i < MAX_CLOCK_ENABLE_WAIT) ? 1 : 0; + return (i < MAX_MODULE_ENABLE_WAIT) ? 1 : 0; }; - -/* - * Note: We don't need special code here for INVERT_ENABLE - * for the time being since INVERT_ENABLE only applies to clocks enabled by - * CM_CLKEN_PLL +/** + * _omap2_module_wait_ready - wait for an OMAP module to leave IDLE + * @clk: struct clk * belonging to the module + * + * If the necessary clocks for the OMAP hardware IP block that + * corresponds to clock @clk are enabled, then wait for the module to + * indicate readiness (i.e., to leave IDLE). This code does not + * belong in the clock code and will be moved in the medium term to + * module-dependent code. No return value. */ -static void omap2_clk_wait_ready(struct clk *clk) +static void _omap2_module_wait_ready(struct clk_hw_omap *clk) { - void __iomem *reg, *other_reg, *st_reg; - u32 bit; - - /* - * REVISIT: This code is pretty ugly. It would be nice to generalize - * it and pull it into struct clk itself somehow. - */ - reg = clk->enable_reg; - if ((((u32)reg & 0xff) >= CM_FCLKEN1) && - (((u32)reg & 0xff) <= OMAP24XX_CM_FCLKEN2)) - other_reg = (void __iomem *)(((u32)reg & ~0xf0) | 0x10); /* CM_ICLKEN* */ - else if ((((u32)reg & 0xff) >= CM_ICLKEN1) && - (((u32)reg & 0xff) <= OMAP24XX_CM_ICLKEN4)) - other_reg = (void __iomem *)(((u32)reg & ~0xf0) | 0x00); /* CM_FCLKEN* */ - else - return; - - /* REVISIT: What are the appropriate exclusions for 34XX? */ - /* No check for DSS or cam clocks */ - if (cpu_is_omap24xx() && ((u32)reg & 0x0f) == 0) { /* CM_{F,I}CLKEN1 */ - if (clk->enable_bit == OMAP24XX_EN_DSS2_SHIFT || - clk->enable_bit == OMAP24XX_EN_DSS1_SHIFT || - clk->enable_bit == OMAP24XX_EN_CAM_SHIFT) + void __iomem *companion_reg, *idlest_reg; + u8 other_bit, idlest_bit, idlest_val, idlest_reg_id; + s16 prcm_mod; + int r; + + /* Not all modules have multiple clocks that their IDLEST depends on */ + if (clk->ops->find_companion) { + clk->ops->find_companion(clk, &companion_reg, &other_bit); + if (!(omap2_clk_readl(clk, companion_reg) & (1 << other_bit))) return; } - /* REVISIT: What are the appropriate exclusions for 34XX? */ - /* OMAP3: ignore DSS-mod clocks */ - if (cpu_is_omap34xx() && - (((u32)reg & ~0xff) == (u32)OMAP_CM_REGADDR(OMAP3430_DSS_MOD, 0) || - ((((u32)reg & ~0xff) == (u32)OMAP_CM_REGADDR(CORE_MOD, 0)) && - clk->enable_bit == OMAP3430_EN_SSI_SHIFT))) - return; - - /* Check if both functional and interface clocks - * are running. */ - bit = 1 << clk->enable_bit; - if (!(__raw_readl(other_reg) & bit)) - return; - st_reg = (void __iomem *)(((u32)other_reg & ~0xf0) | 0x20); /* CM_IDLEST* */ - - omap2_wait_clock_ready(st_reg, bit, clk->name); + clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val); + r = cm_split_idlest_reg(idlest_reg, &prcm_mod, &idlest_reg_id); + if (r) { + /* IDLEST register not in the CM module */ + _wait_idlest_generic(clk, idlest_reg, (1 << idlest_bit), + idlest_val, __clk_get_name(clk->hw.clk)); + } else { + cm_wait_module_ready(prcm_mod, idlest_reg_id, idlest_bit); + }; } -/* Enables clock without considering parent dependencies or use count - * REVISIT: Maybe change this to use clk->enable like on omap1? +/* Public functions */ + +/** + * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk + * @clk: OMAP clock struct ptr to use + * + * Convert a clockdomain name stored in a struct clk 'clk' into a + * clockdomain pointer, and save it into the struct clk. Intended to be + * called during clk_register(). No return value. */ -int _omap2_clk_enable(struct clk *clk) +void omap2_init_clk_clkdm(struct clk_hw *hw) { - u32 regval32; + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + struct clockdomain *clkdm; + const char *clk_name; - if (clk->flags & (ALWAYS_ENABLED | PARENT_CONTROLS_CLOCK)) - return 0; + if (!clk->clkdm_name) + return; - if (clk->enable) - return clk->enable(clk); + clk_name = __clk_get_name(hw->clk); - if (unlikely(clk->enable_reg == NULL)) { - printk(KERN_ERR "clock.c: Enable for %s without enable code\n", - clk->name); - return 0; /* REVISIT: -EINVAL */ + clkdm = clkdm_lookup(clk->clkdm_name); + if (clkdm) { + pr_debug("clock: associated clk %s to clkdm %s\n", + clk_name, clk->clkdm_name); + clk->clkdm = clkdm; + } else { + pr_debug("clock: could not associate clk %s to clkdm %s\n", + clk_name, clk->clkdm_name); } - - regval32 = __raw_readl(clk->enable_reg); - if (clk->flags & INVERT_ENABLE) - regval32 &= ~(1 << clk->enable_bit); - else - regval32 |= (1 << clk->enable_bit); - __raw_writel(regval32, clk->enable_reg); - wmb(); - - omap2_clk_wait_ready(clk); - - return 0; } -/* Disables clock without considering parent dependencies or use count */ -void _omap2_clk_disable(struct clk *clk) +/** + * omap2_clk_disable_clkdm_control - disable clkdm control on clk enable/disable + * + * Prevent the OMAP clock code from calling into the clockdomain code + * when a hardware clock in that clockdomain is enabled or disabled. + * Intended to be called at init time from omap*_clk_init(). No + * return value. + */ +void __init omap2_clk_disable_clkdm_control(void) { - u32 regval32; - - if (clk->flags & (ALWAYS_ENABLED | PARENT_CONTROLS_CLOCK)) - return; + clkdm_control = false; +} - if (clk->disable) { - clk->disable(clk); - return; - } +/** + * omap2_clk_dflt_find_companion - find companion clock to @clk + * @clk: struct clk * to find the companion clock of + * @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in + * @other_bit: u8 ** to return the companion clock bit shift in + * + * Note: We don't need special code here for INVERT_ENABLE for the + * time being since INVERT_ENABLE only applies to clocks enabled by + * CM_CLKEN_PLL + * + * Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes it's + * just a matter of XORing the bits. + * + * Some clocks don't have companion clocks. For example, modules with + * only an interface clock (such as MAILBOXES) don't have a companion + * clock. Right now, this code relies on the hardware exporting a bit + * in the correct companion register that indicates that the + * nonexistent 'companion clock' is active. Future patches will + * associate this type of code with per-module data structures to + * avoid this issue, and remove the casts. No return value. + */ +void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk, + void __iomem **other_reg, u8 *other_bit) +{ + u32 r; - if (clk->enable_reg == NULL) { - /* - * 'Independent' here refers to a clock which is not - * controlled by its parent. - */ - printk(KERN_ERR "clock: clk_disable called on independent " - "clock %s which has no enable_reg\n", clk->name); - return; - } + /* + * Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes + * it's just a matter of XORing the bits. + */ + r = ((__force u32)clk->enable_reg ^ (CM_FCLKEN ^ CM_ICLKEN)); - regval32 = __raw_readl(clk->enable_reg); - if (clk->flags & INVERT_ENABLE) - regval32 |= (1 << clk->enable_bit); - else - regval32 &= ~(1 << clk->enable_bit); - __raw_writel(regval32, clk->enable_reg); - wmb(); + *other_reg = (__force void __iomem *)r; + *other_bit = clk->enable_bit; } -void omap2_clk_disable(struct clk *clk) +/** + * omap2_clk_dflt_find_idlest - find CM_IDLEST reg va, bit shift for @clk + * @clk: struct clk * to find IDLEST info for + * @idlest_reg: void __iomem ** to return the CM_IDLEST va in + * @idlest_bit: u8 * to return the CM_IDLEST bit shift in + * @idlest_val: u8 * to return the idle status indicator + * + * Return the CM_IDLEST register address and bit shift corresponding + * to the module that "owns" this clock. This default code assumes + * that the CM_IDLEST bit shift is the CM_*CLKEN bit shift, and that + * the IDLEST register address ID corresponds to the CM_*CLKEN + * register address ID (e.g., that CM_FCLKEN2 corresponds to + * CM_IDLEST2). This is not true for all modules. No return value. + */ +void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk, + void __iomem **idlest_reg, u8 *idlest_bit, u8 *idlest_val) { - if (clk->usecount > 0 && !(--clk->usecount)) { - _omap2_clk_disable(clk); - if (likely((u32)clk->parent)) - omap2_clk_disable(clk->parent); - if (clk->clkdm) - omap2_clkdm_clk_disable(clk->clkdm, clk); + u32 r; + + r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); + *idlest_reg = (__force void __iomem *)r; + *idlest_bit = clk->enable_bit; + + /* + * 24xx uses 0 to indicate not ready, and 1 to indicate ready. + * 34xx reverses this, just to keep us on our toes + * AM35xx uses both, depending on the module. + */ + if (cpu_is_omap24xx()) + *idlest_val = OMAP24XX_CM_IDLEST_VAL; + else if (cpu_is_omap34xx()) + *idlest_val = OMAP34XX_CM_IDLEST_VAL; + else + BUG(); - } } -int omap2_clk_enable(struct clk *clk) +/** + * omap2_dflt_clk_enable - enable a clock in the hardware + * @hw: struct clk_hw * of the clock to enable + * + * Enable the clock @hw in the hardware. We first call into the OMAP + * clockdomain code to "enable" the corresponding clockdomain if this + * is the first enabled user of the clockdomain. Then program the + * hardware to enable the clock. Then wait for the IP block that uses + * this clock to leave idle (if applicable). Returns the error value + * from clkdm_clk_enable() if it terminated with an error, or -EINVAL + * if @hw has a null clock enable_reg, or zero upon success. + */ +int omap2_dflt_clk_enable(struct clk_hw *hw) { + struct clk_hw_omap *clk; + u32 v; int ret = 0; - if (clk->usecount++ == 0) { - if (likely((u32)clk->parent)) - ret = omap2_clk_enable(clk->parent); + clk = to_clk_hw_omap(hw); - if (unlikely(ret != 0)) { - clk->usecount--; + if (clkdm_control && clk->clkdm) { + ret = clkdm_clk_enable(clk->clkdm, hw->clk); + if (ret) { + WARN(1, "%s: could not enable %s's clockdomain %s: %d\n", + __func__, __clk_get_name(hw->clk), + clk->clkdm->name, ret); return ret; } - - if (clk->clkdm) - omap2_clkdm_clk_enable(clk->clkdm, clk); - - ret = _omap2_clk_enable(clk); - - if (unlikely(ret != 0)) { - if (clk->clkdm) - omap2_clkdm_clk_disable(clk->clkdm, clk); - - if (clk->parent) { - omap2_clk_disable(clk->parent); - clk->usecount--; - } - } } - return ret; -} - -/* - * Used for clocks that are part of CLKSEL_xyz governed clocks. - * REVISIT: Maybe change to use clk->enable() functions like on omap1? - */ -void omap2_clksel_recalc(struct clk *clk) -{ - u32 div = 0; - - pr_debug("clock: recalc'ing clksel clk %s\n", clk->name); + if (unlikely(clk->enable_reg == NULL)) { + pr_err("%s: %s missing enable_reg\n", __func__, + __clk_get_name(hw->clk)); + ret = -EINVAL; + goto err; + } - div = omap2_clksel_get_divisor(clk); - if (div == 0) - return; + /* FIXME should not have INVERT_ENABLE bit here */ + v = omap2_clk_readl(clk, clk->enable_reg); + if (clk->flags & INVERT_ENABLE) + v &= ~(1 << clk->enable_bit); + else + v |= (1 << clk->enable_bit); + omap2_clk_writel(v, clk, clk->enable_reg); + v = omap2_clk_readl(clk, clk->enable_reg); /* OCP barrier */ - if (unlikely(clk->rate == clk->parent->rate / div)) - return; - clk->rate = clk->parent->rate / div; + if (clk->ops && clk->ops->find_idlest) + _omap2_module_wait_ready(clk); - pr_debug("clock: new clock rate is %ld (div %d)\n", clk->rate, div); + return 0; - if (unlikely(clk->flags & RATE_PROPAGATES)) - propagate_rate(clk); +err: + if (clkdm_control && clk->clkdm) + clkdm_clk_disable(clk->clkdm, hw->clk); + return ret; } /** - * omap2_get_clksel_by_parent - return clksel struct for a given clk & parent - * @clk: OMAP struct clk ptr to inspect - * @src_clk: OMAP struct clk ptr of the parent clk to search for + * omap2_dflt_clk_disable - disable a clock in the hardware + * @hw: struct clk_hw * of the clock to disable * - * Scan the struct clksel array associated with the clock to find - * the element associated with the supplied parent clock address. - * Returns a pointer to the struct clksel on success or NULL on error. + * Disable the clock @hw in the hardware, and call into the OMAP + * clockdomain code to "disable" the corresponding clockdomain if all + * clocks/hwmods in that clockdomain are now disabled. No return + * value. */ -const struct clksel *omap2_get_clksel_by_parent(struct clk *clk, - struct clk *src_clk) +void omap2_dflt_clk_disable(struct clk_hw *hw) { - const struct clksel *clks; - - if (!clk->clksel) - return NULL; + struct clk_hw_omap *clk; + u32 v; - for (clks = clk->clksel; clks->parent; clks++) { - if (clks->parent == src_clk) - break; /* Found the requested parent */ + clk = to_clk_hw_omap(hw); + if (!clk->enable_reg) { + /* + * 'independent' here refers to a clock which is not + * controlled by its parent. + */ + pr_err("%s: independent clock %s has no enable_reg\n", + __func__, __clk_get_name(hw->clk)); + return; } - if (!clks->parent) { - printk(KERN_ERR "clock: Could not find parent clock %s in " - "clksel array of clock %s\n", src_clk->name, - clk->name); - return NULL; - } + v = omap2_clk_readl(clk, clk->enable_reg); + if (clk->flags & INVERT_ENABLE) + v |= (1 << clk->enable_bit); + else + v &= ~(1 << clk->enable_bit); + omap2_clk_writel(v, clk, clk->enable_reg); + /* No OCP barrier needed here since it is a disable operation */ - return clks; + if (clkdm_control && clk->clkdm) + clkdm_clk_disable(clk->clkdm, hw->clk); } /** - * omap2_clksel_round_rate_div - find divisor for the given clock and rate - * @clk: OMAP struct clk to use - * @target_rate: desired clock rate - * @new_div: ptr to where we should store the divisor - * - * Finds 'best' divider value in an array based on the source and target - * rates. The divider array must be sorted with smallest divider first. - * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT, - * they are only settable as part of virtual_prcm set. + * omap2_clkops_enable_clkdm - increment usecount on clkdm of @hw + * @hw: struct clk_hw * of the clock being enabled * - * Returns the rounded clock rate or returns 0xffffffff on error. + * Increment the usecount of the clockdomain of the clock pointed to + * by @hw; if the usecount is 1, the clockdomain will be "enabled." + * Only needed for clocks that don't use omap2_dflt_clk_enable() as + * their enable function pointer. Passes along the return value of + * clkdm_clk_enable(), -EINVAL if @hw is not associated with a + * clockdomain, or 0 if clock framework-based clockdomain control is + * not implemented. */ -u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate, - u32 *new_div) +int omap2_clkops_enable_clkdm(struct clk_hw *hw) { - unsigned long test_rate; - const struct clksel *clks; - const struct clksel_rate *clkr; - u32 last_div = 0; - - printk(KERN_INFO "clock: clksel_round_rate_div: %s target_rate %ld\n", - clk->name, target_rate); - - *new_div = 1; - - clks = omap2_get_clksel_by_parent(clk, clk->parent); - if (clks == NULL) - return ~0; - - for (clkr = clks->rates; clkr->div; clkr++) { - if (!(clkr->flags & cpu_mask)) - continue; - - /* Sanity check */ - if (clkr->div <= last_div) - printk(KERN_ERR "clock: clksel_rate table not sorted " - "for clock %s", clk->name); - - last_div = clkr->div; + struct clk_hw_omap *clk; + int ret = 0; - test_rate = clk->parent->rate / clkr->div; + clk = to_clk_hw_omap(hw); - if (test_rate <= target_rate) - break; /* found it */ + if (unlikely(!clk->clkdm)) { + pr_err("%s: %s: no clkdm set ?!\n", __func__, + __clk_get_name(hw->clk)); + return -EINVAL; } - if (!clkr->div) { - printk(KERN_ERR "clock: Could not find divisor for target " - "rate %ld for clock %s parent %s\n", target_rate, - clk->name, clk->parent->name); - return ~0; - } + if (unlikely(clk->enable_reg)) + pr_err("%s: %s: should use dflt_clk_enable ?!\n", __func__, + __clk_get_name(hw->clk)); - *new_div = clkr->div; + if (!clkdm_control) { + pr_err("%s: %s: clkfw-based clockdomain control disabled ?!\n", + __func__, __clk_get_name(hw->clk)); + return 0; + } - printk(KERN_INFO "clock: new_div = %d, new_rate = %ld\n", *new_div, - (clk->parent->rate / clkr->div)); + ret = clkdm_clk_enable(clk->clkdm, hw->clk); + WARN(ret, "%s: could not enable %s's clockdomain %s: %d\n", + __func__, __clk_get_name(hw->clk), clk->clkdm->name, ret); - return (clk->parent->rate / clkr->div); + return ret; } /** - * omap2_clksel_round_rate - find rounded rate for the given clock and rate - * @clk: OMAP struct clk to use - * @target_rate: desired clock rate + * omap2_clkops_disable_clkdm - decrement usecount on clkdm of @hw + * @hw: struct clk_hw * of the clock being disabled * - * Compatibility wrapper for OMAP clock framework - * Finds best target rate based on the source clock and possible dividers. - * rates. The divider array must be sorted with smallest divider first. - * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT, - * they are only settable as part of virtual_prcm set. - * - * Returns the rounded clock rate or returns 0xffffffff on error. + * Decrement the usecount of the clockdomain of the clock pointed to + * by @hw; if the usecount is 0, the clockdomain will be "disabled." + * Only needed for clocks that don't use omap2_dflt_clk_disable() as their + * disable function pointer. No return value. */ -long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate) +void omap2_clkops_disable_clkdm(struct clk_hw *hw) { - u32 new_div; + struct clk_hw_omap *clk; - return omap2_clksel_round_rate_div(clk, target_rate, &new_div); -} + clk = to_clk_hw_omap(hw); + if (unlikely(!clk->clkdm)) { + pr_err("%s: %s: no clkdm set ?!\n", __func__, + __clk_get_name(hw->clk)); + return; + } -/* Given a clock and a rate apply a clock specific rounding function */ -long omap2_clk_round_rate(struct clk *clk, unsigned long rate) -{ - if (clk->round_rate != NULL) - return clk->round_rate(clk, rate); + if (unlikely(clk->enable_reg)) + pr_err("%s: %s: should use dflt_clk_disable ?!\n", __func__, + __clk_get_name(hw->clk)); - if (clk->flags & RATE_FIXED) - printk(KERN_ERR "clock: generic omap2_clk_round_rate called " - "on fixed-rate clock %s\n", clk->name); + if (!clkdm_control) { + pr_err("%s: %s: clkfw-based clockdomain control disabled ?!\n", + __func__, __clk_get_name(hw->clk)); + return; + } - return clk->rate; + clkdm_clk_disable(clk->clkdm, hw->clk); } /** - * omap2_clksel_to_divisor() - turn clksel field value into integer divider - * @clk: OMAP struct clk to use - * @field_val: register field value to find + * omap2_dflt_clk_is_enabled - is clock enabled in the hardware? + * @hw: struct clk_hw * to check * - * Given a struct clk of a rate-selectable clksel clock, and a register field - * value to search for, find the corresponding clock divisor. The register - * field value should be pre-masked and shifted down so the LSB is at bit 0 - * before calling. Returns 0 on error + * Return 1 if the clock represented by @hw is enabled in the + * hardware, or 0 otherwise. Intended for use in the struct + * clk_ops.is_enabled function pointer. */ -u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val) +int omap2_dflt_clk_is_enabled(struct clk_hw *hw) { - const struct clksel *clks; - const struct clksel_rate *clkr; + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + u32 v; - clks = omap2_get_clksel_by_parent(clk, clk->parent); - if (clks == NULL) - return 0; + v = omap2_clk_readl(clk, clk->enable_reg); - for (clkr = clks->rates; clkr->div; clkr++) { - if ((clkr->flags & cpu_mask) && (clkr->val == field_val)) - break; - } + if (clk->flags & INVERT_ENABLE) + v ^= BIT(clk->enable_bit); - if (!clkr->div) { - printk(KERN_ERR "clock: Could not find fieldval %d for " - "clock %s parent %s\n", field_val, clk->name, - clk->parent->name); - return 0; - } + v &= BIT(clk->enable_bit); - return clkr->div; + return v ? 1 : 0; } -/** - * omap2_divisor_to_clksel() - turn clksel integer divisor into a field value - * @clk: OMAP struct clk to use - * @div: integer divisor to search for - * - * Given a struct clk of a rate-selectable clksel clock, and a clock divisor, - * find the corresponding register field value. The return register value is - * the value before left-shifting. Returns ~0 on error +static int __initdata mpurate; + +/* + * By default we use the rate set by the bootloader. + * You can override this with mpurate= cmdline option. */ -u32 omap2_divisor_to_clksel(struct clk *clk, u32 div) +static int __init omap_clk_setup(char *str) { - const struct clksel *clks; - const struct clksel_rate *clkr; + get_option(&str, &mpurate); - /* should never happen */ - WARN_ON(div == 0); + if (!mpurate) + return 1; - clks = omap2_get_clksel_by_parent(clk, clk->parent); - if (clks == NULL) - return ~0; - - for (clkr = clks->rates; clkr->div; clkr++) { - if ((clkr->flags & cpu_mask) && (clkr->div == div)) - break; - } + if (mpurate < 1000) + mpurate *= 1000000; - if (!clkr->div) { - printk(KERN_ERR "clock: Could not find divisor %d for " - "clock %s parent %s\n", div, clk->name, - clk->parent->name); - return ~0; - } - - return clkr->val; + return 1; } +__setup("mpurate=", omap_clk_setup); /** - * omap2_get_clksel - find clksel register addr & field mask for a clk - * @clk: struct clk to use - * @field_mask: ptr to u32 to store the register field mask + * omap2_init_clk_hw_omap_clocks - initialize an OMAP clock + * @clk: struct clk * to initialize * - * Returns the address of the clksel register upon success or NULL on error. + * Add an OMAP clock @clk to the internal list of OMAP clocks. Used + * temporarily for autoidle handling, until this support can be + * integrated into the common clock framework code in some way. No + * return value. */ -void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask) +void omap2_init_clk_hw_omap_clocks(struct clk *clk) { - if (unlikely((clk->clksel_reg == NULL) || (clk->clksel_mask == NULL))) - return NULL; + struct clk_hw_omap *c; - *field_mask = clk->clksel_mask; + if (__clk_get_flags(clk) & CLK_IS_BASIC) + return; - return clk->clksel_reg; + c = to_clk_hw_omap(__clk_get_hw(clk)); + list_add(&c->node, &clk_hw_omap_clocks); } /** - * omap2_clksel_get_divisor - get current divider applied to parent clock. - * @clk: OMAP struct clk to use. + * omap2_clk_enable_autoidle_all - enable autoidle on all OMAP clocks that + * support it * - * Returns the integer divisor upon success or 0 on error. + * Enable clock autoidle on all OMAP clocks that have allow_idle + * function pointers associated with them. This function is intended + * to be temporary until support for this is added to the common clock + * code. Returns 0. */ -u32 omap2_clksel_get_divisor(struct clk *clk) +int omap2_clk_enable_autoidle_all(void) { - u32 field_mask, field_val; - void __iomem *div_addr; + struct clk_hw_omap *c; - div_addr = omap2_get_clksel(clk, &field_mask); - if (div_addr == NULL) - return 0; + list_for_each_entry(c, &clk_hw_omap_clocks, node) + if (c->ops && c->ops->allow_idle) + c->ops->allow_idle(c); - field_val = __raw_readl(div_addr) & field_mask; - field_val >>= __ffs(field_mask); + of_ti_clk_allow_autoidle_all(); - return omap2_clksel_to_divisor(clk, field_val); + return 0; } -int omap2_clksel_set_rate(struct clk *clk, unsigned long rate) +/** + * omap2_clk_disable_autoidle_all - disable autoidle on all OMAP clocks that + * support it + * + * Disable clock autoidle on all OMAP clocks that have allow_idle + * function pointers associated with them. This function is intended + * to be temporary until support for this is added to the common clock + * code. Returns 0. + */ +int omap2_clk_disable_autoidle_all(void) { - u32 field_mask, field_val, reg_val, validrate, new_div = 0; - void __iomem *div_addr; - - validrate = omap2_clksel_round_rate_div(clk, rate, &new_div); - if (validrate != rate) - return -EINVAL; - - div_addr = omap2_get_clksel(clk, &field_mask); - if (div_addr == NULL) - return -EINVAL; - - field_val = omap2_divisor_to_clksel(clk, new_div); - if (field_val == ~0) - return -EINVAL; - - reg_val = __raw_readl(div_addr); - reg_val &= ~field_mask; - reg_val |= (field_val << __ffs(field_mask)); - __raw_writel(reg_val, div_addr); - wmb(); + struct clk_hw_omap *c; - clk->rate = clk->parent->rate / new_div; + list_for_each_entry(c, &clk_hw_omap_clocks, node) + if (c->ops && c->ops->deny_idle) + c->ops->deny_idle(c); - if (clk->flags & DELAYED_APP && cpu_is_omap24xx()) { - prm_write_mod_reg(OMAP24XX_VALID_CONFIG, - OMAP24XX_GR_MOD, OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET); - wmb(); - } + of_ti_clk_deny_autoidle_all(); return 0; } - -/* Set the clock rate for a clock source */ -int omap2_clk_set_rate(struct clk *clk, unsigned long rate) +/** + * omap2_clk_deny_idle - disable autoidle on an OMAP clock + * @clk: struct clk * to disable autoidle for + * + * Disable autoidle on an OMAP clock. + */ +int omap2_clk_deny_idle(struct clk *clk) { - int ret = -EINVAL; + struct clk_hw_omap *c; - pr_debug("clock: set_rate for clock %s to rate %ld\n", clk->name, rate); - - /* CONFIG_PARTICIPANT clocks are changed only in sets via the - rate table mechanism, driven by mpu_speed */ - if (clk->flags & CONFIG_PARTICIPANT) + if (__clk_get_flags(clk) & CLK_IS_BASIC) return -EINVAL; - /* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */ - if (clk->set_rate != NULL) - ret = clk->set_rate(clk, rate); - - if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES))) - propagate_rate(clk); - - return ret; + c = to_clk_hw_omap(__clk_get_hw(clk)); + if (c->ops && c->ops->deny_idle) + c->ops->deny_idle(c); + return 0; } -/* - * Converts encoded control register address into a full address - * On error, *src_addr will be returned as 0. +/** + * omap2_clk_allow_idle - enable autoidle on an OMAP clock + * @clk: struct clk * to enable autoidle for + * + * Enable autoidle on an OMAP clock. */ -static u32 omap2_clksel_get_src_field(void __iomem **src_addr, - struct clk *src_clk, u32 *field_mask, - struct clk *clk, u32 *parent_div) -{ - const struct clksel *clks; - const struct clksel_rate *clkr; - - *parent_div = 0; - *src_addr = NULL; - - clks = omap2_get_clksel_by_parent(clk, src_clk); - if (clks == NULL) - return 0; - - for (clkr = clks->rates; clkr->div; clkr++) { - if (clkr->flags & cpu_mask && clkr->flags & DEFAULT_RATE) - break; /* Found the default rate for this platform */ - } - - if (!clkr->div) { - printk(KERN_ERR "clock: Could not find default rate for " - "clock %s parent %s\n", clk->name, - src_clk->parent->name); - return 0; - } - - /* Should never happen. Add a clksel mask to the struct clk. */ - WARN_ON(clk->clksel_mask == 0); - - *field_mask = clk->clksel_mask; - *src_addr = clk->clksel_reg; - *parent_div = clkr->div; - - return clkr->val; -} - -int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) +int omap2_clk_allow_idle(struct clk *clk) { - void __iomem *src_addr; - u32 field_val, field_mask, reg_val, parent_div; + struct clk_hw_omap *c; - if (unlikely(clk->flags & CONFIG_PARTICIPANT)) + if (__clk_get_flags(clk) & CLK_IS_BASIC) return -EINVAL; - if (!clk->clksel) - return -EINVAL; - - field_val = omap2_clksel_get_src_field(&src_addr, new_parent, - &field_mask, clk, &parent_div); - if (src_addr == NULL) - return -EINVAL; - - if (clk->usecount > 0) - omap2_clk_disable(clk); - - /* Set new source value (previous dividers if any in effect) */ - reg_val = __raw_readl(src_addr) & ~field_mask; - reg_val |= (field_val << __ffs(field_mask)); - __raw_writel(reg_val, src_addr); - wmb(); - - if (clk->flags & DELAYED_APP && cpu_is_omap24xx()) { - __raw_writel(OMAP24XX_VALID_CONFIG, OMAP24XX_PRCM_CLKCFG_CTRL); - wmb(); - } - - clk->parent = new_parent; - - if (clk->usecount > 0) - omap2_clk_enable(clk); - - /* CLKSEL clocks follow their parents' rates, divided by a divisor */ - clk->rate = new_parent->rate; - - if (parent_div > 0) - clk->rate /= parent_div; - - pr_debug("clock: set parent of %s to %s (new rate %ld)\n", - clk->name, clk->parent->name, clk->rate); - - if (unlikely(clk->flags & RATE_PROPAGATES)) - propagate_rate(clk); - + c = to_clk_hw_omap(__clk_get_hw(clk)); + if (c->ops && c->ops->allow_idle) + c->ops->allow_idle(c); return 0; } -/* DPLL rate rounding code */ - /** - * omap2_dpll_set_rate_tolerance: set the error tolerance during rate rounding - * @clk: struct clk * of the DPLL - * @tolerance: maximum rate error tolerance + * omap2_clk_enable_init_clocks - prepare & enable a list of clocks + * @clk_names: ptr to an array of strings of clock names to enable + * @num_clocks: number of clock names in @clk_names * - * Set the maximum DPLL rate error tolerance for the rate rounding - * algorithm. The rate tolerance is an attempt to balance DPLL power - * saving (the least divider value "n") vs. rate fidelity (the least - * difference between the desired DPLL target rate and the rounded - * rate out of the algorithm). So, increasing the tolerance is likely - * to decrease DPLL power consumption and increase DPLL rate error. - * Returns -EINVAL if provided a null clock ptr or a clk that is not a - * DPLL; or 0 upon success. + * Prepare and enable a list of clocks, named by @clk_names. No + * return value. XXX Deprecated; only needed until these clocks are + * properly claimed and enabled by the drivers or core code that uses + * them. XXX What code disables & calls clk_put on these clocks? */ -int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance) +void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks) { - if (!clk || !clk->dpll_data) - return -EINVAL; + struct clk *init_clk; + int i; - clk->dpll_data->rate_tolerance = tolerance; - - return 0; + for (i = 0; i < num_clocks; i++) { + init_clk = clk_get(NULL, clk_names[i]); + clk_prepare_enable(init_clk); + } } -static unsigned long _dpll_compute_new_rate(unsigned long parent_rate, unsigned int m, unsigned int n) -{ - unsigned long long num; - - num = (unsigned long long)parent_rate * m; - do_div(num, n); - return num; -} +const struct clk_hw_omap_ops clkhwops_wait = { + .find_idlest = omap2_clk_dflt_find_idlest, + .find_companion = omap2_clk_dflt_find_companion, +}; -/* - * _dpll_test_mult - test a DPLL multiplier value - * @m: pointer to the DPLL m (multiplier) value under test - * @n: current DPLL n (divider) value under test - * @new_rate: pointer to storage for the resulting rounded rate - * @target_rate: the desired DPLL rate - * @parent_rate: the DPLL's parent clock rate - * - * This code tests a DPLL multiplier value, ensuring that the - * resulting rate will not be higher than the target_rate, and that - * the multiplier value itself is valid for the DPLL. Initially, the - * integer pointed to by the m argument should be prescaled by - * multiplying by DPLL_SCALE_FACTOR. The code will replace this with - * a non-scaled m upon return. This non-scaled m will result in a - * new_rate as close as possible to target_rate (but not greater than - * target_rate) given the current (parent_rate, n, prescaled m) - * triple. Returns DPLL_MULT_UNDERFLOW in the event that the - * non-scaled m attempted to underflow, which can allow the calling - * function to bail out early; or 0 upon success. +/** + * omap_clocks_register - register an array of omap_clk + * @ocs: pointer to an array of omap_clk to register */ -static int _dpll_test_mult(int *m, int n, unsigned long *new_rate, - unsigned long target_rate, - unsigned long parent_rate) +void __init omap_clocks_register(struct omap_clk oclks[], int cnt) { - int flags = 0, carry = 0; - - /* Unscale m and round if necessary */ - if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL) - carry = 1; - *m = (*m / DPLL_SCALE_FACTOR) + carry; + struct omap_clk *c; - /* - * The new rate must be <= the target rate to avoid programming - * a rate that is impossible for the hardware to handle - */ - *new_rate = _dpll_compute_new_rate(parent_rate, *m, n); - if (*new_rate > target_rate) { - (*m)--; - *new_rate = 0; + for (c = oclks; c < oclks + cnt; c++) { + clkdev_add(&c->lk); + if (!__clk_init(NULL, c->lk.clk)) + omap2_init_clk_hw_omap_clocks(c->lk.clk); } - - /* Guard against m underflow */ - if (*m < DPLL_MIN_MULTIPLIER) { - *m = DPLL_MIN_MULTIPLIER; - *new_rate = 0; - flags = DPLL_MULT_UNDERFLOW; - } - - if (*new_rate == 0) - *new_rate = _dpll_compute_new_rate(parent_rate, *m, n); - - return flags; } /** - * omap2_dpll_round_rate - round a target rate for an OMAP DPLL - * @clk: struct clk * for a DPLL - * @target_rate: desired DPLL clock rate + * omap2_clk_switch_mpurate_at_boot - switch ARM MPU rate by boot-time argument + * @mpurate_ck_name: clk name of the clock to change rate * - * Given a DPLL, a desired target rate, and a rate tolerance, round - * the target rate to a possible, programmable rate for this DPLL. - * Rate tolerance is assumed to be set by the caller before this - * function is called. Attempts to select the minimum possible n - * within the tolerance to reduce power consumption. Stores the - * computed (m, n) in the DPLL's dpll_data structure so set_rate() - * will not need to call this (expensive) function again. Returns ~0 - * if the target rate cannot be rounded, either because the rate is - * too low or because the rate tolerance is set too tightly; or the - * rounded rate upon success. + * Change the ARM MPU clock rate to the rate specified on the command + * line, if one was specified. @mpurate_ck_name should be + * "virt_prcm_set" on OMAP2xxx and "dpll1_ck" on OMAP34xx/OMAP36xx. + * XXX Does not handle voltage scaling - on OMAP2xxx this is currently + * handled by the virt_prcm_set clock, but this should be handled by + * the OPP layer. XXX This is intended to be handled by the OPP layer + * code in the near future and should be removed from the clock code. + * Returns -EINVAL if 'mpurate' is zero or if clk_set_rate() rejects + * the rate, -ENOENT if the struct clk referred to by @mpurate_ck_name + * cannot be found, or 0 upon success. */ -long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate) +int __init omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name) { - int m, n, r, e, scaled_max_m; - unsigned long scaled_rt_rp, new_rate; - int min_e = -1, min_e_m = -1, min_e_n = -1; - - if (!clk || !clk->dpll_data) - return ~0; - - pr_debug("clock: starting DPLL round_rate for clock %s, target rate " - "%ld\n", clk->name, target_rate); - - scaled_rt_rp = target_rate / (clk->parent->rate / DPLL_SCALE_FACTOR); - scaled_max_m = clk->dpll_data->max_multiplier * DPLL_SCALE_FACTOR; - - clk->dpll_data->last_rounded_rate = 0; - - for (n = clk->dpll_data->max_divider; n >= DPLL_MIN_DIVIDER; n--) { - - /* Compute the scaled DPLL multiplier, based on the divider */ - m = scaled_rt_rp * n; - - /* - * Since we're counting n down, a m overflow means we can - * can immediately skip to the next n - */ - if (m > scaled_max_m) - continue; - - r = _dpll_test_mult(&m, n, &new_rate, target_rate, - clk->parent->rate); + struct clk *mpurate_ck; + int r; - e = target_rate - new_rate; - pr_debug("clock: n = %d: m = %d: rate error is %d " - "(new_rate = %ld)\n", n, m, e, new_rate); - - if (min_e == -1 || - min_e >= (int)(abs(e) - clk->dpll_data->rate_tolerance)) { - min_e = e; - min_e_m = m; - min_e_n = n; + if (!mpurate) + return -EINVAL; - pr_debug("clock: found new least error %d\n", min_e); - } + mpurate_ck = clk_get(NULL, mpurate_ck_name); + if (WARN(IS_ERR(mpurate_ck), "Failed to get %s.\n", mpurate_ck_name)) + return -ENOENT; - /* - * Since we're counting n down, a m underflow means we - * can bail out completely (since as n decreases in - * the next iteration, there's no way that m can - * increase beyond the current m) - */ - if (r & DPLL_MULT_UNDERFLOW) - break; - } - - if (min_e < 0) { - pr_debug("clock: error: target rate or tolerance too low\n"); - return ~0; + r = clk_set_rate(mpurate_ck, mpurate); + if (r < 0) { + WARN(1, "clock: %s: unable to set MPU rate to %d: %d\n", + mpurate_ck_name, mpurate, r); + clk_put(mpurate_ck); + return -EINVAL; } - clk->dpll_data->last_rounded_m = min_e_m; - clk->dpll_data->last_rounded_n = min_e_n; - clk->dpll_data->last_rounded_rate = - _dpll_compute_new_rate(clk->parent->rate, min_e_m, min_e_n); - - pr_debug("clock: final least error: e = %d, m = %d, n = %d\n", - min_e, min_e_m, min_e_n); - pr_debug("clock: final rate: %ld (target rate: %ld)\n", - clk->dpll_data->last_rounded_rate, target_rate); + calibrate_delay(); + clk_put(mpurate_ck); - return clk->dpll_data->last_rounded_rate; + return 0; } -/*------------------------------------------------------------------------- - * Omap2 clock reset and init functions - *-------------------------------------------------------------------------*/ - -#ifdef CONFIG_OMAP_RESET_CLOCKS -void omap2_clk_disable_unused(struct clk *clk) +/** + * omap2_clk_print_new_rates - print summary of current clock tree rates + * @hfclkin_ck_name: clk name for the off-chip HF oscillator + * @core_ck_name: clk name for the on-chip CORE_CLK + * @mpu_ck_name: clk name for the ARM MPU clock + * + * Prints a short message to the console with the HFCLKIN oscillator + * rate, the rate of the CORE clock, and the rate of the ARM MPU clock. + * Called by the boot-time MPU rate switching code. XXX This is intended + * to be handled by the OPP layer code in the near future and should be + * removed from the clock code. No return value. + */ +void __init omap2_clk_print_new_rates(const char *hfclkin_ck_name, + const char *core_ck_name, + const char *mpu_ck_name) { - u32 regval32, v; + struct clk *hfclkin_ck, *core_ck, *mpu_ck; + unsigned long hfclkin_rate; - v = (clk->flags & INVERT_ENABLE) ? (1 << clk->enable_bit) : 0; + mpu_ck = clk_get(NULL, mpu_ck_name); + if (WARN(IS_ERR(mpu_ck), "clock: failed to get %s.\n", mpu_ck_name)) + return; + + core_ck = clk_get(NULL, core_ck_name); + if (WARN(IS_ERR(core_ck), "clock: failed to get %s.\n", core_ck_name)) + return; - regval32 = __raw_readl(clk->enable_reg); - if ((regval32 & (1 << clk->enable_bit)) == v) + hfclkin_ck = clk_get(NULL, hfclkin_ck_name); + if (WARN(IS_ERR(hfclkin_ck), "Failed to get %s.\n", hfclkin_ck_name)) return; - printk(KERN_INFO "Disabling unused clock \"%s\"\n", clk->name); - _omap2_clk_disable(clk); + hfclkin_rate = clk_get_rate(hfclkin_ck); + + pr_info("Switched to new clocking rate (Crystal/Core/MPU): %ld.%01ld/%ld/%ld MHz\n", + (hfclkin_rate / 1000000), ((hfclkin_rate / 100000) % 10), + (clk_get_rate(core_ck) / 1000000), + (clk_get_rate(mpu_ck) / 1000000)); } -#endif diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 1fb330e0847..12f54d428d7 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -1,8 +1,8 @@ /* * linux/arch/arm/mach-omap2/clock.h * - * Copyright (C) 2005-2008 Texas Instruments, Inc. - * Copyright (C) 2004-2008 Nokia Corporation + * Copyright (C) 2005-2009 Texas Instruments, Inc. + * Copyright (C) 2004-2011 Nokia Corporation * * Contacts: * Richard Woodruff <r-woodruff2@ti.com> @@ -16,61 +16,274 @@ #ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_H #define __ARCH_ARM_MACH_OMAP2_CLOCK_H -#include <mach/clock.h> +#include <linux/kernel.h> +#include <linux/list.h> -/* The maximum error between a target DPLL rate and the rounded rate in Hz */ -#define DEFAULT_DPLL_RATE_TOLERANCE 50000 +#include <linux/clkdev.h> +#include <linux/clk-provider.h> +#include <linux/clk/ti.h> -int omap2_clk_init(void); -int omap2_clk_enable(struct clk *clk); -void omap2_clk_disable(struct clk *clk); -long omap2_clk_round_rate(struct clk *clk, unsigned long rate); -int omap2_clk_set_rate(struct clk *clk, unsigned long rate); -int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent); -int omap2_dpll_rate_tolerance_set(struct clk *clk, unsigned int tolerance); -long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate); +struct omap_clk { + u16 cpu; + struct clk_lookup lk; +}; -#ifdef CONFIG_OMAP_RESET_CLOCKS -void omap2_clk_disable_unused(struct clk *clk); -#else -#define omap2_clk_disable_unused NULL -#endif +#define CLK(dev, con, ck) \ + { \ + .lk = { \ + .dev_id = dev, \ + .con_id = con, \ + .clk = ck, \ + }, \ + } -void omap2_clksel_recalc(struct clk *clk); -void omap2_init_clk_clkdm(struct clk *clk); -void omap2_init_clksel_parent(struct clk *clk); -u32 omap2_clksel_get_divisor(struct clk *clk); -u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate, - u32 *new_div); -u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val); -u32 omap2_divisor_to_clksel(struct clk *clk, u32 div); -void omap2_fixed_divisor_recalc(struct clk *clk); -long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate); -int omap2_clksel_set_rate(struct clk *clk, unsigned long rate); -u32 omap2_get_dpll_rate(struct clk *clk); -int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name); -void omap2_clk_prepare_for_reboot(void); - -extern u8 cpu_mask; - -/* clksel_rate data common to 24xx/343x */ -static const struct clksel_rate gpt_32k_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } -}; +struct clockdomain; + +#define DEFINE_STRUCT_CLK(_name, _parent_array_name, _clkops_name) \ + static struct clk _name = { \ + .name = #_name, \ + .hw = &_name##_hw.hw, \ + .parent_names = _parent_array_name, \ + .num_parents = ARRAY_SIZE(_parent_array_name), \ + .ops = &_clkops_name, \ + }; + +#define DEFINE_STRUCT_CLK_FLAGS(_name, _parent_array_name, \ + _clkops_name, _flags) \ + static struct clk _name = { \ + .name = #_name, \ + .hw = &_name##_hw.hw, \ + .parent_names = _parent_array_name, \ + .num_parents = ARRAY_SIZE(_parent_array_name), \ + .ops = &_clkops_name, \ + .flags = _flags, \ + }; + +#define DEFINE_STRUCT_CLK_HW_OMAP(_name, _clkdm_name) \ + static struct clk_hw_omap _name##_hw = { \ + .hw = { \ + .clk = &_name, \ + }, \ + .clkdm_name = _clkdm_name, \ + }; + +#define DEFINE_CLK_OMAP_MUX(_name, _clkdm_name, _clksel, \ + _clksel_reg, _clksel_mask, \ + _parent_names, _ops) \ + static struct clk _name; \ + static struct clk_hw_omap _name##_hw = { \ + .hw = { \ + .clk = &_name, \ + }, \ + .clksel = _clksel, \ + .clksel_reg = _clksel_reg, \ + .clksel_mask = _clksel_mask, \ + .clkdm_name = _clkdm_name, \ + }; \ + DEFINE_STRUCT_CLK(_name, _parent_names, _ops); + +#define DEFINE_CLK_OMAP_MUX_GATE(_name, _clkdm_name, _clksel, \ + _clksel_reg, _clksel_mask, \ + _enable_reg, _enable_bit, \ + _hwops, _parent_names, _ops) \ + static struct clk _name; \ + static struct clk_hw_omap _name##_hw = { \ + .hw = { \ + .clk = &_name, \ + }, \ + .ops = _hwops, \ + .enable_reg = _enable_reg, \ + .enable_bit = _enable_bit, \ + .clksel = _clksel, \ + .clksel_reg = _clksel_reg, \ + .clksel_mask = _clksel_mask, \ + .clkdm_name = _clkdm_name, \ + }; \ + DEFINE_STRUCT_CLK(_name, _parent_names, _ops); + +#define DEFINE_CLK_OMAP_HSDIVIDER(_name, _parent_name, \ + _parent_ptr, _flags, \ + _clksel_reg, _clksel_mask) \ + static const struct clksel _name##_div[] = { \ + { \ + .parent = _parent_ptr, \ + .rates = div31_1to31_rates \ + }, \ + { .parent = NULL }, \ + }; \ + static struct clk _name; \ + static const char *_name##_parent_names[] = { \ + _parent_name, \ + }; \ + static struct clk_hw_omap _name##_hw = { \ + .hw = { \ + .clk = &_name, \ + }, \ + .clksel = _name##_div, \ + .clksel_reg = _clksel_reg, \ + .clksel_mask = _clksel_mask, \ + .ops = &clkhwops_omap4_dpllmx, \ + }; \ + DEFINE_STRUCT_CLK(_name, _name##_parent_names, omap_hsdivider_ops); -static const struct clksel_rate gpt_sys_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } +/* struct clksel_rate.flags possibilities */ +#define RATE_IN_242X (1 << 0) +#define RATE_IN_243X (1 << 1) +#define RATE_IN_3430ES1 (1 << 2) /* 3430ES1 rates only */ +#define RATE_IN_3430ES2PLUS (1 << 3) /* 3430 ES >= 2 rates only */ +#define RATE_IN_36XX (1 << 4) +#define RATE_IN_4430 (1 << 5) +#define RATE_IN_TI816X (1 << 6) +#define RATE_IN_4460 (1 << 7) +#define RATE_IN_AM33XX (1 << 8) +#define RATE_IN_TI814X (1 << 9) + +#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X) +#define RATE_IN_34XX (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS) +#define RATE_IN_3XXX (RATE_IN_34XX | RATE_IN_36XX) +#define RATE_IN_44XX (RATE_IN_4430 | RATE_IN_4460) + +/* RATE_IN_3430ES2PLUS_36XX includes 34xx/35xx with ES >=2, and all 36xx/37xx */ +#define RATE_IN_3430ES2PLUS_36XX (RATE_IN_3430ES2PLUS | RATE_IN_36XX) + + +/** + * struct clksel_rate - register bitfield values corresponding to clk divisors + * @val: register bitfield value (shifted to bit 0) + * @div: clock divisor corresponding to @val + * @flags: (see "struct clksel_rate.flags possibilities" above) + * + * @val should match the value of a read from struct clk.clksel_reg + * AND'ed with struct clk.clksel_mask, shifted right to bit 0. + * + * @div is the divisor that should be applied to the parent clock's rate + * to produce the current clock's rate. + */ +struct clksel_rate { + u32 val; + u8 div; + u16 flags; }; -static const struct clksel_rate gfx_l3_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | RATE_IN_343X }, - { .div = 2, .val = 2, .flags = RATE_IN_24XX | RATE_IN_343X | DEFAULT_RATE }, - { .div = 3, .val = 3, .flags = RATE_IN_243X | RATE_IN_343X }, - { .div = 4, .val = 4, .flags = RATE_IN_243X | RATE_IN_343X }, - { .div = 0 } +/** + * struct clksel - available parent clocks, and a pointer to their divisors + * @parent: struct clk * to a possible parent clock + * @rates: available divisors for this parent clock + * + * A struct clksel is always associated with one or more struct clks + * and one or more struct clksel_rates. + */ +struct clksel { + struct clk *parent; + const struct clksel_rate *rates; }; +unsigned long omap_fixed_divisor_recalc(struct clk_hw *hw, + unsigned long parent_rate); + +/* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */ +#define CORE_CLK_SRC_32K 0x0 +#define CORE_CLK_SRC_DPLL 0x1 +#define CORE_CLK_SRC_DPLL_X2 0x2 + +/* OMAP2xxx CM_CLKEN_PLL.EN_DPLL bits - for omap2_get_dpll_rate() */ +#define OMAP2XXX_EN_DPLL_LPBYPASS 0x1 +#define OMAP2XXX_EN_DPLL_FRBYPASS 0x2 +#define OMAP2XXX_EN_DPLL_LOCKED 0x3 + +/* OMAP3xxx CM_CLKEN_PLL*.EN_*_DPLL bits - for omap2_get_dpll_rate() */ +#define OMAP3XXX_EN_DPLL_LPBYPASS 0x5 +#define OMAP3XXX_EN_DPLL_FRBYPASS 0x6 +#define OMAP3XXX_EN_DPLL_LOCKED 0x7 + +/* OMAP4xxx CM_CLKMODE_DPLL*.EN_*_DPLL bits - for omap2_get_dpll_rate() */ +#define OMAP4XXX_EN_DPLL_MNBYPASS 0x4 +#define OMAP4XXX_EN_DPLL_LPBYPASS 0x5 +#define OMAP4XXX_EN_DPLL_FRBYPASS 0x6 +#define OMAP4XXX_EN_DPLL_LOCKED 0x7 + +u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk); +void omap3_dpll_allow_idle(struct clk_hw_omap *clk); +void omap3_dpll_deny_idle(struct clk_hw_omap *clk); +int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk); +void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk); +void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk); + +void __init omap2_clk_disable_clkdm_control(void); + +/* clkt_clksel.c public functions */ +u32 omap2_clksel_round_rate_div(struct clk_hw_omap *clk, + unsigned long target_rate, + u32 *new_div); +u8 omap2_clksel_find_parent_index(struct clk_hw *hw); +unsigned long omap2_clksel_recalc(struct clk_hw *hw, unsigned long parent_rate); +long omap2_clksel_round_rate(struct clk_hw *hw, unsigned long target_rate, + unsigned long *parent_rate); +int omap2_clksel_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate); +int omap2_clksel_set_parent(struct clk_hw *hw, u8 field_val); + +/* clkt_iclk.c public functions */ +extern void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk); +extern void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk); + +unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk); + +void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk, + void __iomem **other_reg, + u8 *other_bit); +void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk, + void __iomem **idlest_reg, + u8 *idlest_bit, u8 *idlest_val); +int omap2_clk_enable_autoidle_all(void); +int omap2_clk_allow_idle(struct clk *clk); +int omap2_clk_deny_idle(struct clk *clk); +int omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name); +void omap2_clk_print_new_rates(const char *hfclkin_ck_name, + const char *core_ck_name, + const char *mpu_ck_name); + +u32 omap2_clk_readl(struct clk_hw_omap *clk, void __iomem *reg); +void omap2_clk_writel(u32 val, struct clk_hw_omap *clk, void __iomem *reg); + +extern u16 cpu_mask; + +extern const struct clkops clkops_omap2_dflt_wait; +extern const struct clkops clkops_dummy; +extern const struct clkops clkops_omap2_dflt; + +extern struct clk_functions omap2_clk_functions; + +extern const struct clksel_rate gpt_32k_rates[]; +extern const struct clksel_rate gpt_sys_rates[]; +extern const struct clksel_rate gfx_l3_rates[]; +extern const struct clksel_rate dsp_ick_rates[]; +extern struct clk dummy_ck; + +extern const struct clk_hw_omap_ops clkhwops_iclk_wait; +extern const struct clk_hw_omap_ops clkhwops_wait; +extern const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait; +extern const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait; +extern const struct clk_hw_omap_ops clkhwops_omap3430es2_hsotgusb_wait; +extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait; +extern const struct clk_hw_omap_ops clkhwops_apll54; +extern const struct clk_hw_omap_ops clkhwops_apll96; + +/* clksel_rate blocks shared between OMAP44xx and AM33xx */ +extern const struct clksel_rate div_1_0_rates[]; +extern const struct clksel_rate div3_1to4_rates[]; +extern const struct clksel_rate div_1_1_rates[]; +extern const struct clksel_rate div_1_2_rates[]; +extern const struct clksel_rate div_1_3_rates[]; +extern const struct clksel_rate div_1_4_rates[]; +extern const struct clksel_rate div31_1to31_rates[]; + +extern void __iomem *clk_memmaps[]; + +extern int am33xx_clk_init(void); + +extern int omap2_clkops_enable_clkdm(struct clk_hw *hw); +extern void omap2_clkops_disable_clkdm(struct clk_hw *hw); +extern void omap_clocks_register(struct omap_clk *oclks, int cnt); #endif diff --git a/arch/arm/mach-omap2/clock2430.c b/arch/arm/mach-omap2/clock2430.c new file mode 100644 index 00000000000..cef0c8d1de5 --- /dev/null +++ b/arch/arm/mach-omap2/clock2430.c @@ -0,0 +1,57 @@ +/* + * clock2430.c - OMAP2430-specific clock integration code + * + * Copyright (C) 2005-2008 Texas Instruments, Inc. + * Copyright (C) 2004-2010 Nokia Corporation + * + * Contacts: + * Richard Woodruff <r-woodruff2@ti.com> + * Paul Walmsley + * + * Based on earlier work by Tuukka Tikkanen, Tony Lindgren, + * Gordon McNutt and RidgeRun, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#undef DEBUG + +#include <linux/kernel.h> +#include <linux/clk.h> +#include <linux/io.h> + +#include "soc.h" +#include "iomap.h" +#include "clock.h" +#include "clock2xxx.h" +#include "cm2xxx.h" +#include "cm-regbits-24xx.h" + +/** + * omap2430_clk_i2chs_find_idlest - return CM_IDLEST info for 2430 I2CHS + * @clk: struct clk * being enabled + * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into + * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into + * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator + * + * OMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE, but the + * CM_*CLKEN bits are in CM_{I,F}CLKEN2_CORE. This custom function + * passes back the correct CM_IDLEST register address for I2CHS + * modules. No return value. + */ +static void omap2430_clk_i2chs_find_idlest(struct clk_hw_omap *clk, + void __iomem **idlest_reg, + u8 *idlest_bit, + u8 *idlest_val) +{ + *idlest_reg = OMAP2430_CM_REGADDR(CORE_MOD, CM_IDLEST); + *idlest_bit = clk->enable_bit; + *idlest_val = OMAP24XX_CM_IDLEST_VAL; +} + +/* 2430 I2CHS has non-standard IDLEST register */ +const struct clk_hw_omap_ops clkhwops_omap2430_i2chs_wait = { + .find_idlest = omap2430_clk_i2chs_find_idlest, + .find_companion = omap2_clk_dflt_find_companion, +}; diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c deleted file mode 100644 index d382eb0184a..00000000000 --- a/arch/arm/mach-omap2/clock24xx.c +++ /dev/null @@ -1,538 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/clock.c - * - * Copyright (C) 2005-2008 Texas Instruments, Inc. - * Copyright (C) 2004-2008 Nokia Corporation - * - * Contacts: - * Richard Woodruff <r-woodruff2@ti.com> - * Paul Walmsley - * - * Based on earlier work by Tuukka Tikkanen, Tony Lindgren, - * Gordon McNutt and RidgeRun, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#undef DEBUG - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/device.h> -#include <linux/list.h> -#include <linux/errno.h> -#include <linux/delay.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/cpufreq.h> -#include <linux/bitops.h> - -#include <mach/clock.h> -#include <mach/sram.h> -#include <asm/div64.h> - -#include "memory.h" -#include "clock.h" -#include "clock24xx.h" -#include "prm.h" -#include "prm-regbits-24xx.h" -#include "cm.h" -#include "cm-regbits-24xx.h" - -/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */ -#define EN_APLL_STOPPED 0 -#define EN_APLL_LOCKED 3 - -/* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */ -#define APLLS_CLKIN_19_2MHZ 0 -#define APLLS_CLKIN_13MHZ 2 -#define APLLS_CLKIN_12MHZ 3 - -/* #define DOWN_VARIABLE_DPLL 1 */ /* Experimental */ - -static struct prcm_config *curr_prcm_set; -static struct clk *vclk; -static struct clk *sclk; - -/*------------------------------------------------------------------------- - * Omap24xx specific clock functions - *-------------------------------------------------------------------------*/ - -/* This actually returns the rate of core_ck, not dpll_ck. */ -static u32 omap2_get_dpll_rate_24xx(struct clk *tclk) -{ - long long dpll_clk; - u8 amult; - - dpll_clk = omap2_get_dpll_rate(tclk); - - amult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); - amult &= OMAP24XX_CORE_CLK_SRC_MASK; - dpll_clk *= amult; - - return dpll_clk; -} - -static int omap2_enable_osc_ck(struct clk *clk) -{ - u32 pcc; - - pcc = __raw_readl(OMAP24XX_PRCM_CLKSRC_CTRL); - - __raw_writel(pcc & ~OMAP_AUTOEXTCLKMODE_MASK, - OMAP24XX_PRCM_CLKSRC_CTRL); - - return 0; -} - -static void omap2_disable_osc_ck(struct clk *clk) -{ - u32 pcc; - - pcc = __raw_readl(OMAP24XX_PRCM_CLKSRC_CTRL); - - __raw_writel(pcc | OMAP_AUTOEXTCLKMODE_MASK, - OMAP24XX_PRCM_CLKSRC_CTRL); -} - -#ifdef OLD_CK -/* Recalculate SYST_CLK */ -static void omap2_sys_clk_recalc(struct clk * clk) -{ - u32 div = PRCM_CLKSRC_CTRL; - div &= (1 << 7) | (1 << 6); /* Test if ext clk divided by 1 or 2 */ - div >>= clk->rate_offset; - clk->rate = (clk->parent->rate / div); - propagate_rate(clk); -} -#endif /* OLD_CK */ - -/* Enable an APLL if off */ -static int omap2_clk_fixed_enable(struct clk *clk) -{ - u32 cval, apll_mask; - - apll_mask = EN_APLL_LOCKED << clk->enable_bit; - - cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN); - - if ((cval & apll_mask) == apll_mask) - return 0; /* apll already enabled */ - - cval &= ~apll_mask; - cval |= apll_mask; - cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN); - - if (clk == &apll96_ck) - cval = OMAP24XX_ST_96M_APLL; - else if (clk == &apll54_ck) - cval = OMAP24XX_ST_54M_APLL; - - omap2_wait_clock_ready(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), cval, - clk->name); - - /* - * REVISIT: Should we return an error code if omap2_wait_clock_ready() - * fails? - */ - return 0; -} - -/* Stop APLL */ -static void omap2_clk_fixed_disable(struct clk *clk) -{ - u32 cval; - - cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN); - cval &= ~(EN_APLL_LOCKED << clk->enable_bit); - cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN); -} - -/* - * Uses the current prcm set to tell if a rate is valid. - * You can go slower, but not faster within a given rate set. - */ -long omap2_dpllcore_round_rate(unsigned long target_rate) -{ - u32 high, low, core_clk_src; - - core_clk_src = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); - core_clk_src &= OMAP24XX_CORE_CLK_SRC_MASK; - - if (core_clk_src == CORE_CLK_SRC_DPLL) { /* DPLL clockout */ - high = curr_prcm_set->dpll_speed * 2; - low = curr_prcm_set->dpll_speed; - } else { /* DPLL clockout x 2 */ - high = curr_prcm_set->dpll_speed; - low = curr_prcm_set->dpll_speed / 2; - } - -#ifdef DOWN_VARIABLE_DPLL - if (target_rate > high) - return high; - else - return target_rate; -#else - if (target_rate > low) - return high; - else - return low; -#endif - -} - -static void omap2_dpllcore_recalc(struct clk *clk) -{ - clk->rate = omap2_get_dpll_rate_24xx(clk); - - propagate_rate(clk); -} - -static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate) -{ - u32 cur_rate, low, mult, div, valid_rate, done_rate; - u32 bypass = 0; - struct prcm_config tmpset; - const struct dpll_data *dd; - unsigned long flags; - int ret = -EINVAL; - - local_irq_save(flags); - cur_rate = omap2_get_dpll_rate_24xx(&dpll_ck); - mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); - mult &= OMAP24XX_CORE_CLK_SRC_MASK; - - if ((rate == (cur_rate / 2)) && (mult == 2)) { - omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL, 1); - } else if ((rate == (cur_rate * 2)) && (mult == 1)) { - omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1); - } else if (rate != cur_rate) { - valid_rate = omap2_dpllcore_round_rate(rate); - if (valid_rate != rate) - goto dpll_exit; - - if (mult == 1) - low = curr_prcm_set->dpll_speed; - else - low = curr_prcm_set->dpll_speed / 2; - - dd = clk->dpll_data; - if (!dd) - goto dpll_exit; - - tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg); - tmpset.cm_clksel1_pll &= ~(dd->mult_mask | - dd->div1_mask); - div = ((curr_prcm_set->xtal_speed / 1000000) - 1); - tmpset.cm_clksel2_pll = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); - tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK; - if (rate > low) { - tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2; - mult = ((rate / 2) / 1000000); - done_rate = CORE_CLK_SRC_DPLL_X2; - } else { - tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL; - mult = (rate / 1000000); - done_rate = CORE_CLK_SRC_DPLL; - } - tmpset.cm_clksel1_pll |= (div << __ffs(dd->mult_mask)); - tmpset.cm_clksel1_pll |= (mult << __ffs(dd->div1_mask)); - - /* Worst case */ - tmpset.base_sdrc_rfr = SDRC_RFR_CTRL_BYPASS; - - if (rate == curr_prcm_set->xtal_speed) /* If asking for 1-1 */ - bypass = 1; - - omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1); /* For init_mem */ - - /* Force dll lock mode */ - omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr, - bypass); - - /* Errata: ret dll entry state */ - omap2_init_memory_params(omap2_dll_force_needed()); - omap2_reprogram_sdrc(done_rate, 0); - } - omap2_dpllcore_recalc(&dpll_ck); - ret = 0; - -dpll_exit: - local_irq_restore(flags); - return(ret); -} - -/** - * omap2_table_mpu_recalc - just return the MPU speed - * @clk: virt_prcm_set struct clk - * - * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set. - */ -static void omap2_table_mpu_recalc(struct clk *clk) -{ - clk->rate = curr_prcm_set->mpu_speed; -} - -/* - * Look for a rate equal or less than the target rate given a configuration set. - * - * What's not entirely clear is "which" field represents the key field. - * Some might argue L3-DDR, others ARM, others IVA. This code is simple and - * just uses the ARM rates. - */ -static long omap2_round_to_table_rate(struct clk *clk, unsigned long rate) -{ - struct prcm_config *ptr; - long highest_rate; - - if (clk != &virt_prcm_set) - return -EINVAL; - - highest_rate = -EINVAL; - - for (ptr = rate_table; ptr->mpu_speed; ptr++) { - if (!(ptr->flags & cpu_mask)) - continue; - if (ptr->xtal_speed != sys_ck.rate) - continue; - - highest_rate = ptr->mpu_speed; - - /* Can check only after xtal frequency check */ - if (ptr->mpu_speed <= rate) - break; - } - return highest_rate; -} - -/* Sets basic clocks based on the specified rate */ -static int omap2_select_table_rate(struct clk *clk, unsigned long rate) -{ - u32 cur_rate, done_rate, bypass = 0, tmp; - struct prcm_config *prcm; - unsigned long found_speed = 0; - unsigned long flags; - - if (clk != &virt_prcm_set) - return -EINVAL; - - for (prcm = rate_table; prcm->mpu_speed; prcm++) { - if (!(prcm->flags & cpu_mask)) - continue; - - if (prcm->xtal_speed != sys_ck.rate) - continue; - - if (prcm->mpu_speed <= rate) { - found_speed = prcm->mpu_speed; - break; - } - } - - if (!found_speed) { - printk(KERN_INFO "Could not set MPU rate to %luMHz\n", - rate / 1000000); - return -EINVAL; - } - - curr_prcm_set = prcm; - cur_rate = omap2_get_dpll_rate_24xx(&dpll_ck); - - if (prcm->dpll_speed == cur_rate / 2) { - omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL, 1); - } else if (prcm->dpll_speed == cur_rate * 2) { - omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1); - } else if (prcm->dpll_speed != cur_rate) { - local_irq_save(flags); - - if (prcm->dpll_speed == prcm->xtal_speed) - bypass = 1; - - if ((prcm->cm_clksel2_pll & OMAP24XX_CORE_CLK_SRC_MASK) == - CORE_CLK_SRC_DPLL_X2) - done_rate = CORE_CLK_SRC_DPLL_X2; - else - done_rate = CORE_CLK_SRC_DPLL; - - /* MPU divider */ - cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL); - - /* dsp + iva1 div(2420), iva2.1(2430) */ - cm_write_mod_reg(prcm->cm_clksel_dsp, - OMAP24XX_DSP_MOD, CM_CLKSEL); - - cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL); - - /* Major subsystem dividers */ - tmp = cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK; - cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD, CM_CLKSEL1); - if (cpu_is_omap2430()) - cm_write_mod_reg(prcm->cm_clksel_mdm, - OMAP2430_MDM_MOD, CM_CLKSEL); - - /* x2 to enter init_mem */ - omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1); - - omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr, - bypass); - - omap2_init_memory_params(omap2_dll_force_needed()); - omap2_reprogram_sdrc(done_rate, 0); - - local_irq_restore(flags); - } - omap2_dpllcore_recalc(&dpll_ck); - - return 0; -} - -static struct clk_functions omap2_clk_functions = { - .clk_enable = omap2_clk_enable, - .clk_disable = omap2_clk_disable, - .clk_round_rate = omap2_clk_round_rate, - .clk_set_rate = omap2_clk_set_rate, - .clk_set_parent = omap2_clk_set_parent, - .clk_disable_unused = omap2_clk_disable_unused, -}; - -static u32 omap2_get_apll_clkin(void) -{ - u32 aplls, sclk = 0; - - aplls = cm_read_mod_reg(PLL_MOD, CM_CLKSEL1); - aplls &= OMAP24XX_APLLS_CLKIN_MASK; - aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT; - - if (aplls == APLLS_CLKIN_19_2MHZ) - sclk = 19200000; - else if (aplls == APLLS_CLKIN_13MHZ) - sclk = 13000000; - else if (aplls == APLLS_CLKIN_12MHZ) - sclk = 12000000; - - return sclk; -} - -static u32 omap2_get_sysclkdiv(void) -{ - u32 div; - - div = __raw_readl(OMAP24XX_PRCM_CLKSRC_CTRL); - div &= OMAP_SYSCLKDIV_MASK; - div >>= OMAP_SYSCLKDIV_SHIFT; - - return div; -} - -static void omap2_osc_clk_recalc(struct clk *clk) -{ - clk->rate = omap2_get_apll_clkin() * omap2_get_sysclkdiv(); - propagate_rate(clk); -} - -static void omap2_sys_clk_recalc(struct clk *clk) -{ - clk->rate = clk->parent->rate / omap2_get_sysclkdiv(); - propagate_rate(clk); -} - -/* - * Set clocks for bypass mode for reboot to work. - */ -void omap2_clk_prepare_for_reboot(void) -{ - u32 rate; - - if (vclk == NULL || sclk == NULL) - return; - - rate = clk_get_rate(sclk); - clk_set_rate(vclk, rate); -} - -/* - * Switch the MPU rate if specified on cmdline. - * We cannot do this early until cmdline is parsed. - */ -static int __init omap2_clk_arch_init(void) -{ - if (!mpurate) - return -EINVAL; - - if (omap2_select_table_rate(&virt_prcm_set, mpurate)) - printk(KERN_ERR "Could not find matching MPU rate\n"); - - recalculate_root_clocks(); - - printk(KERN_INFO "Switched to new clocking rate (Crystal/DPLL/MPU): " - "%ld.%01ld/%ld/%ld MHz\n", - (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10, - (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ; - - return 0; -} -arch_initcall(omap2_clk_arch_init); - -int __init omap2_clk_init(void) -{ - struct prcm_config *prcm; - struct clk **clkp; - u32 clkrate; - - if (cpu_is_omap242x()) - cpu_mask = RATE_IN_242X; - else if (cpu_is_omap2430()) - cpu_mask = RATE_IN_243X; - - clk_init(&omap2_clk_functions); - - omap2_osc_clk_recalc(&osc_ck); - omap2_sys_clk_recalc(&sys_ck); - - for (clkp = onchip_24xx_clks; - clkp < onchip_24xx_clks + ARRAY_SIZE(onchip_24xx_clks); - clkp++) { - - if ((*clkp)->flags & CLOCK_IN_OMAP242X && cpu_is_omap2420()) { - clk_register(*clkp); - continue; - } - - if ((*clkp)->flags & CLOCK_IN_OMAP243X && cpu_is_omap2430()) { - clk_register(*clkp); - continue; - } - } - - /* Check the MPU rate set by bootloader */ - clkrate = omap2_get_dpll_rate_24xx(&dpll_ck); - for (prcm = rate_table; prcm->mpu_speed; prcm++) { - if (!(prcm->flags & cpu_mask)) - continue; - if (prcm->xtal_speed != sys_ck.rate) - continue; - if (prcm->dpll_speed <= clkrate) - break; - } - curr_prcm_set = prcm; - - recalculate_root_clocks(); - - printk(KERN_INFO "Clocking rate (Crystal/DPLL/MPU): " - "%ld.%01ld/%ld/%ld MHz\n", - (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10, - (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ; - - /* - * Only enable those clocks we will need, let the drivers - * enable other clocks as necessary - */ - clk_enable_init_clocks(); - - /* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */ - vclk = clk_get(NULL, "virt_prcm_set"); - sclk = clk_get(NULL, "sys_ck"); - - return 0; -} diff --git a/arch/arm/mach-omap2/clock24xx.h b/arch/arm/mach-omap2/clock24xx.h deleted file mode 100644 index ad6d98d177c..00000000000 --- a/arch/arm/mach-omap2/clock24xx.h +++ /dev/null @@ -1,2793 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/clock24xx.h - * - * Copyright (C) 2005-2008 Texas Instruments, Inc. - * Copyright (C) 2004-2008 Nokia Corporation - * - * Contacts: - * Richard Woodruff <r-woodruff2@ti.com> - * Paul Walmsley - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK24XX_H -#define __ARCH_ARM_MACH_OMAP2_CLOCK24XX_H - -#include "clock.h" - -#include "prm.h" -#include "cm.h" -#include "prm-regbits-24xx.h" -#include "cm-regbits-24xx.h" -#include "sdrc.h" - -static void omap2_table_mpu_recalc(struct clk *clk); -static int omap2_select_table_rate(struct clk *clk, unsigned long rate); -static long omap2_round_to_table_rate(struct clk *clk, unsigned long rate); -static void omap2_sys_clk_recalc(struct clk *clk); -static void omap2_osc_clk_recalc(struct clk *clk); -static void omap2_sys_clk_recalc(struct clk *clk); -static void omap2_dpllcore_recalc(struct clk *clk); -static int omap2_clk_fixed_enable(struct clk *clk); -static void omap2_clk_fixed_disable(struct clk *clk); -static int omap2_enable_osc_ck(struct clk *clk); -static void omap2_disable_osc_ck(struct clk *clk); -static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate); - -/* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated. - * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP - * CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL CM_CLKSEL2_PLL, CM_CLKSEL_MDM - */ -struct prcm_config { - unsigned long xtal_speed; /* crystal rate */ - unsigned long dpll_speed; /* dpll: out*xtal*M/(N-1)table_recalc */ - unsigned long mpu_speed; /* speed of MPU */ - unsigned long cm_clksel_mpu; /* mpu divider */ - unsigned long cm_clksel_dsp; /* dsp+iva1 div(2420), iva2.1(2430) */ - unsigned long cm_clksel_gfx; /* gfx dividers */ - unsigned long cm_clksel1_core; /* major subsystem dividers */ - unsigned long cm_clksel1_pll; /* m,n */ - unsigned long cm_clksel2_pll; /* dpllx1 or x2 out */ - unsigned long cm_clksel_mdm; /* modem dividers 2430 only */ - unsigned long base_sdrc_rfr; /* base refresh timing for a set */ - unsigned char flags; -}; - -/* - * The OMAP2 processor can be run at several discrete 'PRCM configurations'. - * These configurations are characterized by voltage and speed for clocks. - * The device is only validated for certain combinations. One way to express - * these combinations is via the 'ratio's' which the clocks operate with - * respect to each other. These ratio sets are for a given voltage/DPLL - * setting. All configurations can be described by a DPLL setting and a ratio - * There are 3 ratio sets for the 2430 and X ratio sets for 2420. - * - * 2430 differs from 2420 in that there are no more phase synchronizers used. - * They both have a slightly different clock domain setup. 2420(iva1,dsp) vs - * 2430 (iva2.1, NOdsp, mdm) - */ - -/* Core fields for cm_clksel, not ratio governed */ -#define RX_CLKSEL_DSS1 (0x10 << 8) -#define RX_CLKSEL_DSS2 (0x0 << 13) -#define RX_CLKSEL_SSI (0x5 << 20) - -/*------------------------------------------------------------------------- - * Voltage/DPLL ratios - *-------------------------------------------------------------------------*/ - -/* 2430 Ratio's, 2430-Ratio Config 1 */ -#define R1_CLKSEL_L3 (4 << 0) -#define R1_CLKSEL_L4 (2 << 5) -#define R1_CLKSEL_USB (4 << 25) -#define R1_CM_CLKSEL1_CORE_VAL R1_CLKSEL_USB | RX_CLKSEL_SSI | \ - RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \ - R1_CLKSEL_L4 | R1_CLKSEL_L3 -#define R1_CLKSEL_MPU (2 << 0) -#define R1_CM_CLKSEL_MPU_VAL R1_CLKSEL_MPU -#define R1_CLKSEL_DSP (2 << 0) -#define R1_CLKSEL_DSP_IF (2 << 5) -#define R1_CM_CLKSEL_DSP_VAL R1_CLKSEL_DSP | R1_CLKSEL_DSP_IF -#define R1_CLKSEL_GFX (2 << 0) -#define R1_CM_CLKSEL_GFX_VAL R1_CLKSEL_GFX -#define R1_CLKSEL_MDM (4 << 0) -#define R1_CM_CLKSEL_MDM_VAL R1_CLKSEL_MDM - -/* 2430-Ratio Config 2 */ -#define R2_CLKSEL_L3 (6 << 0) -#define R2_CLKSEL_L4 (2 << 5) -#define R2_CLKSEL_USB (2 << 25) -#define R2_CM_CLKSEL1_CORE_VAL R2_CLKSEL_USB | RX_CLKSEL_SSI | \ - RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \ - R2_CLKSEL_L4 | R2_CLKSEL_L3 -#define R2_CLKSEL_MPU (2 << 0) -#define R2_CM_CLKSEL_MPU_VAL R2_CLKSEL_MPU -#define R2_CLKSEL_DSP (2 << 0) -#define R2_CLKSEL_DSP_IF (3 << 5) -#define R2_CM_CLKSEL_DSP_VAL R2_CLKSEL_DSP | R2_CLKSEL_DSP_IF -#define R2_CLKSEL_GFX (2 << 0) -#define R2_CM_CLKSEL_GFX_VAL R2_CLKSEL_GFX -#define R2_CLKSEL_MDM (6 << 0) -#define R2_CM_CLKSEL_MDM_VAL R2_CLKSEL_MDM - -/* 2430-Ratio Bootm (BYPASS) */ -#define RB_CLKSEL_L3 (1 << 0) -#define RB_CLKSEL_L4 (1 << 5) -#define RB_CLKSEL_USB (1 << 25) -#define RB_CM_CLKSEL1_CORE_VAL RB_CLKSEL_USB | RX_CLKSEL_SSI | \ - RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \ - RB_CLKSEL_L4 | RB_CLKSEL_L3 -#define RB_CLKSEL_MPU (1 << 0) -#define RB_CM_CLKSEL_MPU_VAL RB_CLKSEL_MPU -#define RB_CLKSEL_DSP (1 << 0) -#define RB_CLKSEL_DSP_IF (1 << 5) -#define RB_CM_CLKSEL_DSP_VAL RB_CLKSEL_DSP | RB_CLKSEL_DSP_IF -#define RB_CLKSEL_GFX (1 << 0) -#define RB_CM_CLKSEL_GFX_VAL RB_CLKSEL_GFX -#define RB_CLKSEL_MDM (1 << 0) -#define RB_CM_CLKSEL_MDM_VAL RB_CLKSEL_MDM - -/* 2420 Ratio Equivalents */ -#define RXX_CLKSEL_VLYNQ (0x12 << 15) -#define RXX_CLKSEL_SSI (0x8 << 20) - -/* 2420-PRCM III 532MHz core */ -#define RIII_CLKSEL_L3 (4 << 0) /* 133MHz */ -#define RIII_CLKSEL_L4 (2 << 5) /* 66.5MHz */ -#define RIII_CLKSEL_USB (4 << 25) /* 33.25MHz */ -#define RIII_CM_CLKSEL1_CORE_VAL RIII_CLKSEL_USB | RXX_CLKSEL_SSI | \ - RXX_CLKSEL_VLYNQ | RX_CLKSEL_DSS2 | \ - RX_CLKSEL_DSS1 | RIII_CLKSEL_L4 | \ - RIII_CLKSEL_L3 -#define RIII_CLKSEL_MPU (2 << 0) /* 266MHz */ -#define RIII_CM_CLKSEL_MPU_VAL RIII_CLKSEL_MPU -#define RIII_CLKSEL_DSP (3 << 0) /* c5x - 177.3MHz */ -#define RIII_CLKSEL_DSP_IF (2 << 5) /* c5x - 88.67MHz */ -#define RIII_SYNC_DSP (1 << 7) /* Enable sync */ -#define RIII_CLKSEL_IVA (6 << 8) /* iva1 - 88.67MHz */ -#define RIII_SYNC_IVA (1 << 13) /* Enable sync */ -#define RIII_CM_CLKSEL_DSP_VAL RIII_SYNC_IVA | RIII_CLKSEL_IVA | \ - RIII_SYNC_DSP | RIII_CLKSEL_DSP_IF | \ - RIII_CLKSEL_DSP -#define RIII_CLKSEL_GFX (2 << 0) /* 66.5MHz */ -#define RIII_CM_CLKSEL_GFX_VAL RIII_CLKSEL_GFX - -/* 2420-PRCM II 600MHz core */ -#define RII_CLKSEL_L3 (6 << 0) /* 100MHz */ -#define RII_CLKSEL_L4 (2 << 5) /* 50MHz */ -#define RII_CLKSEL_USB (2 << 25) /* 50MHz */ -#define RII_CM_CLKSEL1_CORE_VAL RII_CLKSEL_USB | \ - RXX_CLKSEL_SSI | RXX_CLKSEL_VLYNQ | \ - RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \ - RII_CLKSEL_L4 | RII_CLKSEL_L3 -#define RII_CLKSEL_MPU (2 << 0) /* 300MHz */ -#define RII_CM_CLKSEL_MPU_VAL RII_CLKSEL_MPU -#define RII_CLKSEL_DSP (3 << 0) /* c5x - 200MHz */ -#define RII_CLKSEL_DSP_IF (2 << 5) /* c5x - 100MHz */ -#define RII_SYNC_DSP (0 << 7) /* Bypass sync */ -#define RII_CLKSEL_IVA (3 << 8) /* iva1 - 200MHz */ -#define RII_SYNC_IVA (0 << 13) /* Bypass sync */ -#define RII_CM_CLKSEL_DSP_VAL RII_SYNC_IVA | RII_CLKSEL_IVA | \ - RII_SYNC_DSP | RII_CLKSEL_DSP_IF | \ - RII_CLKSEL_DSP -#define RII_CLKSEL_GFX (2 << 0) /* 50MHz */ -#define RII_CM_CLKSEL_GFX_VAL RII_CLKSEL_GFX - -/* 2420-PRCM I 660MHz core */ -#define RI_CLKSEL_L3 (4 << 0) /* 165MHz */ -#define RI_CLKSEL_L4 (2 << 5) /* 82.5MHz */ -#define RI_CLKSEL_USB (4 << 25) /* 41.25MHz */ -#define RI_CM_CLKSEL1_CORE_VAL RI_CLKSEL_USB | \ - RXX_CLKSEL_SSI | RXX_CLKSEL_VLYNQ | \ - RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \ - RI_CLKSEL_L4 | RI_CLKSEL_L3 -#define RI_CLKSEL_MPU (2 << 0) /* 330MHz */ -#define RI_CM_CLKSEL_MPU_VAL RI_CLKSEL_MPU -#define RI_CLKSEL_DSP (3 << 0) /* c5x - 220MHz */ -#define RI_CLKSEL_DSP_IF (2 << 5) /* c5x - 110MHz */ -#define RI_SYNC_DSP (1 << 7) /* Activate sync */ -#define RI_CLKSEL_IVA (4 << 8) /* iva1 - 165MHz */ -#define RI_SYNC_IVA (0 << 13) /* Bypass sync */ -#define RI_CM_CLKSEL_DSP_VAL RI_SYNC_IVA | RI_CLKSEL_IVA | \ - RI_SYNC_DSP | RI_CLKSEL_DSP_IF | \ - RI_CLKSEL_DSP -#define RI_CLKSEL_GFX (1 << 0) /* 165MHz */ -#define RI_CM_CLKSEL_GFX_VAL RI_CLKSEL_GFX - -/* 2420-PRCM VII (boot) */ -#define RVII_CLKSEL_L3 (1 << 0) -#define RVII_CLKSEL_L4 (1 << 5) -#define RVII_CLKSEL_DSS1 (1 << 8) -#define RVII_CLKSEL_DSS2 (0 << 13) -#define RVII_CLKSEL_VLYNQ (1 << 15) -#define RVII_CLKSEL_SSI (1 << 20) -#define RVII_CLKSEL_USB (1 << 25) - -#define RVII_CM_CLKSEL1_CORE_VAL RVII_CLKSEL_USB | RVII_CLKSEL_SSI | \ - RVII_CLKSEL_VLYNQ | RVII_CLKSEL_DSS2 | \ - RVII_CLKSEL_DSS1 | RVII_CLKSEL_L4 | RVII_CLKSEL_L3 - -#define RVII_CLKSEL_MPU (1 << 0) /* all divide by 1 */ -#define RVII_CM_CLKSEL_MPU_VAL RVII_CLKSEL_MPU - -#define RVII_CLKSEL_DSP (1 << 0) -#define RVII_CLKSEL_DSP_IF (1 << 5) -#define RVII_SYNC_DSP (0 << 7) -#define RVII_CLKSEL_IVA (1 << 8) -#define RVII_SYNC_IVA (0 << 13) -#define RVII_CM_CLKSEL_DSP_VAL RVII_SYNC_IVA | RVII_CLKSEL_IVA | RVII_SYNC_DSP | \ - RVII_CLKSEL_DSP_IF | RVII_CLKSEL_DSP - -#define RVII_CLKSEL_GFX (1 << 0) -#define RVII_CM_CLKSEL_GFX_VAL RVII_CLKSEL_GFX - -/*------------------------------------------------------------------------- - * 2430 Target modes: Along with each configuration the CPU has several - * modes which goes along with them. Modes mainly are the addition of - * describe DPLL combinations to go along with a ratio. - *-------------------------------------------------------------------------*/ - -/* Hardware governed */ -#define MX_48M_SRC (0 << 3) -#define MX_54M_SRC (0 << 5) -#define MX_APLLS_CLIKIN_12 (3 << 23) -#define MX_APLLS_CLIKIN_13 (2 << 23) -#define MX_APLLS_CLIKIN_19_2 (0 << 23) - -/* - * 2430 - standalone, 2*ref*M/(n+1), M/N is for exactness not relock speed - * #5a (ratio1) baseport-target, target DPLL = 266*2 = 532MHz - */ -#define M5A_DPLL_MULT_12 (133 << 12) -#define M5A_DPLL_DIV_12 (5 << 8) -#define M5A_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \ - M5A_DPLL_DIV_12 | M5A_DPLL_MULT_12 | \ - MX_APLLS_CLIKIN_12 -#define M5A_DPLL_MULT_13 (61 << 12) -#define M5A_DPLL_DIV_13 (2 << 8) -#define M5A_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \ - M5A_DPLL_DIV_13 | M5A_DPLL_MULT_13 | \ - MX_APLLS_CLIKIN_13 -#define M5A_DPLL_MULT_19 (55 << 12) -#define M5A_DPLL_DIV_19 (3 << 8) -#define M5A_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | \ - M5A_DPLL_DIV_19 | M5A_DPLL_MULT_19 | \ - MX_APLLS_CLIKIN_19_2 -/* #5b (ratio1) target DPLL = 200*2 = 400MHz */ -#define M5B_DPLL_MULT_12 (50 << 12) -#define M5B_DPLL_DIV_12 (2 << 8) -#define M5B_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \ - M5B_DPLL_DIV_12 | M5B_DPLL_MULT_12 | \ - MX_APLLS_CLIKIN_12 -#define M5B_DPLL_MULT_13 (200 << 12) -#define M5B_DPLL_DIV_13 (12 << 8) - -#define M5B_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \ - M5B_DPLL_DIV_13 | M5B_DPLL_MULT_13 | \ - MX_APLLS_CLIKIN_13 -#define M5B_DPLL_MULT_19 (125 << 12) -#define M5B_DPLL_DIV_19 (31 << 8) -#define M5B_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | \ - M5B_DPLL_DIV_19 | M5B_DPLL_MULT_19 | \ - MX_APLLS_CLIKIN_19_2 -/* - * #4 (ratio2), DPLL = 399*2 = 798MHz, L3=133MHz - */ -#define M4_DPLL_MULT_12 (133 << 12) -#define M4_DPLL_DIV_12 (3 << 8) -#define M4_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \ - M4_DPLL_DIV_12 | M4_DPLL_MULT_12 | \ - MX_APLLS_CLIKIN_12 - -#define M4_DPLL_MULT_13 (399 << 12) -#define M4_DPLL_DIV_13 (12 << 8) -#define M4_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \ - M4_DPLL_DIV_13 | M4_DPLL_MULT_13 | \ - MX_APLLS_CLIKIN_13 - -#define M4_DPLL_MULT_19 (145 << 12) -#define M4_DPLL_DIV_19 (6 << 8) -#define M4_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | \ - M4_DPLL_DIV_19 | M4_DPLL_MULT_19 | \ - MX_APLLS_CLIKIN_19_2 - -/* - * #3 (ratio2) baseport-target, target DPLL = 330*2 = 660MHz - */ -#define M3_DPLL_MULT_12 (55 << 12) -#define M3_DPLL_DIV_12 (1 << 8) -#define M3_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \ - M3_DPLL_DIV_12 | M3_DPLL_MULT_12 | \ - MX_APLLS_CLIKIN_12 -#define M3_DPLL_MULT_13 (76 << 12) -#define M3_DPLL_DIV_13 (2 << 8) -#define M3_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \ - M3_DPLL_DIV_13 | M3_DPLL_MULT_13 | \ - MX_APLLS_CLIKIN_13 -#define M3_DPLL_MULT_19 (17 << 12) -#define M3_DPLL_DIV_19 (0 << 8) -#define M3_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | \ - M3_DPLL_DIV_19 | M3_DPLL_MULT_19 | \ - MX_APLLS_CLIKIN_19_2 - -/* - * #2 (ratio1) DPLL = 330*2 = 660MHz, L3=165MHz - */ -#define M2_DPLL_MULT_12 (55 << 12) -#define M2_DPLL_DIV_12 (1 << 8) -#define M2_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \ - M2_DPLL_DIV_12 | M2_DPLL_MULT_12 | \ - MX_APLLS_CLIKIN_12 - -/* Speed changes - Used 658.7MHz instead of 660MHz for LP-Refresh M=76 N=2, - * relock time issue */ -/* Core frequency changed from 330/165 to 329/164 MHz*/ -#define M2_DPLL_MULT_13 (76 << 12) -#define M2_DPLL_DIV_13 (2 << 8) -#define M2_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \ - M2_DPLL_DIV_13 | M2_DPLL_MULT_13 | \ - MX_APLLS_CLIKIN_13 - -#define M2_DPLL_MULT_19 (17 << 12) -#define M2_DPLL_DIV_19 (0 << 8) -#define M2_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | \ - M2_DPLL_DIV_19 | M2_DPLL_MULT_19 | \ - MX_APLLS_CLIKIN_19_2 - -/* boot (boot) */ -#define MB_DPLL_MULT (1 << 12) -#define MB_DPLL_DIV (0 << 8) -#define MB_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV |\ - MB_DPLL_MULT | MX_APLLS_CLIKIN_12 - -#define MB_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV |\ - MB_DPLL_MULT | MX_APLLS_CLIKIN_13 - -#define MB_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV |\ - MB_DPLL_MULT | MX_APLLS_CLIKIN_19 - -/* - * 2430 - chassis (sedna) - * 165 (ratio1) same as above #2 - * 150 (ratio1) - * 133 (ratio2) same as above #4 - * 110 (ratio2) same as above #3 - * 104 (ratio2) - * boot (boot) - */ - -/* PRCM I target DPLL = 2*330MHz = 660MHz */ -#define MI_DPLL_MULT_12 (55 << 12) -#define MI_DPLL_DIV_12 (1 << 8) -#define MI_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \ - MI_DPLL_DIV_12 | MI_DPLL_MULT_12 | \ - MX_APLLS_CLIKIN_12 - -/* - * 2420 Equivalent - mode registers - * PRCM II , target DPLL = 2*300MHz = 600MHz - */ -#define MII_DPLL_MULT_12 (50 << 12) -#define MII_DPLL_DIV_12 (1 << 8) -#define MII_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \ - MII_DPLL_DIV_12 | MII_DPLL_MULT_12 | \ - MX_APLLS_CLIKIN_12 -#define MII_DPLL_MULT_13 (300 << 12) -#define MII_DPLL_DIV_13 (12 << 8) -#define MII_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \ - MII_DPLL_DIV_13 | MII_DPLL_MULT_13 | \ - MX_APLLS_CLIKIN_13 - -/* PRCM III target DPLL = 2*266 = 532MHz*/ -#define MIII_DPLL_MULT_12 (133 << 12) -#define MIII_DPLL_DIV_12 (5 << 8) -#define MIII_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \ - MIII_DPLL_DIV_12 | MIII_DPLL_MULT_12 | \ - MX_APLLS_CLIKIN_12 -#define MIII_DPLL_MULT_13 (266 << 12) -#define MIII_DPLL_DIV_13 (12 << 8) -#define MIII_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \ - MIII_DPLL_DIV_13 | MIII_DPLL_MULT_13 | \ - MX_APLLS_CLIKIN_13 - -/* PRCM VII (boot bypass) */ -#define MVII_CM_CLKSEL1_PLL_12_VAL MB_CM_CLKSEL1_PLL_12_VAL -#define MVII_CM_CLKSEL1_PLL_13_VAL MB_CM_CLKSEL1_PLL_13_VAL - -/* High and low operation value */ -#define MX_CLKSEL2_PLL_2x_VAL (2 << 0) -#define MX_CLKSEL2_PLL_1x_VAL (1 << 0) - -/* MPU speed defines */ -#define S12M 12000000 -#define S13M 13000000 -#define S19M 19200000 -#define S26M 26000000 -#define S100M 100000000 -#define S133M 133000000 -#define S150M 150000000 -#define S164M 164000000 -#define S165M 165000000 -#define S199M 199000000 -#define S200M 200000000 -#define S266M 266000000 -#define S300M 300000000 -#define S329M 329000000 -#define S330M 330000000 -#define S399M 399000000 -#define S400M 400000000 -#define S532M 532000000 -#define S600M 600000000 -#define S658M 658000000 -#define S660M 660000000 -#define S798M 798000000 - -/*------------------------------------------------------------------------- - * Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated. - * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU, - * CM_CLKSEL_DSP, CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL, - * CM_CLKSEL2_PLL, CM_CLKSEL_MDM - * - * Filling in table based on H4 boards and 2430-SDPs variants available. - * There are quite a few more rates combinations which could be defined. - * - * When multiple values are defined the start up will try and choose the - * fastest one. If a 'fast' value is defined, then automatically, the /2 - * one should be included as it can be used. Generally having more that - * one fast set does not make sense, as static timings need to be changed - * to change the set. The exception is the bypass setting which is - * availble for low power bypass. - * - * Note: This table needs to be sorted, fastest to slowest. - *-------------------------------------------------------------------------*/ -static struct prcm_config rate_table[] = { - /* PRCM I - FAST */ - {S12M, S660M, S330M, RI_CM_CLKSEL_MPU_VAL, /* 330MHz ARM */ - RI_CM_CLKSEL_DSP_VAL, RI_CM_CLKSEL_GFX_VAL, - RI_CM_CLKSEL1_CORE_VAL, MI_CM_CLKSEL1_PLL_12_VAL, - MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_165MHz, - RATE_IN_242X}, - - /* PRCM II - FAST */ - {S12M, S600M, S300M, RII_CM_CLKSEL_MPU_VAL, /* 300MHz ARM */ - RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL, - RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_12_VAL, - MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz, - RATE_IN_242X}, - - {S13M, S600M, S300M, RII_CM_CLKSEL_MPU_VAL, /* 300MHz ARM */ - RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL, - RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_13_VAL, - MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz, - RATE_IN_242X}, - - /* PRCM III - FAST */ - {S12M, S532M, S266M, RIII_CM_CLKSEL_MPU_VAL, /* 266MHz ARM */ - RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL, - RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_12_VAL, - MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz, - RATE_IN_242X}, - - {S13M, S532M, S266M, RIII_CM_CLKSEL_MPU_VAL, /* 266MHz ARM */ - RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL, - RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_13_VAL, - MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz, - RATE_IN_242X}, - - /* PRCM II - SLOW */ - {S12M, S300M, S150M, RII_CM_CLKSEL_MPU_VAL, /* 150MHz ARM */ - RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL, - RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_12_VAL, - MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz, - RATE_IN_242X}, - - {S13M, S300M, S150M, RII_CM_CLKSEL_MPU_VAL, /* 150MHz ARM */ - RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL, - RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_13_VAL, - MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz, - RATE_IN_242X}, - - /* PRCM III - SLOW */ - {S12M, S266M, S133M, RIII_CM_CLKSEL_MPU_VAL, /* 133MHz ARM */ - RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL, - RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_12_VAL, - MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz, - RATE_IN_242X}, - - {S13M, S266M, S133M, RIII_CM_CLKSEL_MPU_VAL, /* 133MHz ARM */ - RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL, - RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_13_VAL, - MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz, - RATE_IN_242X}, - - /* PRCM-VII (boot-bypass) */ - {S12M, S12M, S12M, RVII_CM_CLKSEL_MPU_VAL, /* 12MHz ARM*/ - RVII_CM_CLKSEL_DSP_VAL, RVII_CM_CLKSEL_GFX_VAL, - RVII_CM_CLKSEL1_CORE_VAL, MVII_CM_CLKSEL1_PLL_12_VAL, - MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_BYPASS, - RATE_IN_242X}, - - /* PRCM-VII (boot-bypass) */ - {S13M, S13M, S13M, RVII_CM_CLKSEL_MPU_VAL, /* 13MHz ARM */ - RVII_CM_CLKSEL_DSP_VAL, RVII_CM_CLKSEL_GFX_VAL, - RVII_CM_CLKSEL1_CORE_VAL, MVII_CM_CLKSEL1_PLL_13_VAL, - MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_BYPASS, - RATE_IN_242X}, - - /* PRCM #4 - ratio2 (ES2.1) - FAST */ - {S13M, S798M, S399M, R2_CM_CLKSEL_MPU_VAL, /* 399MHz ARM */ - R2_CM_CLKSEL_DSP_VAL, R2_CM_CLKSEL_GFX_VAL, - R2_CM_CLKSEL1_CORE_VAL, M4_CM_CLKSEL1_PLL_13_VAL, - MX_CLKSEL2_PLL_2x_VAL, R2_CM_CLKSEL_MDM_VAL, - SDRC_RFR_CTRL_133MHz, - RATE_IN_243X}, - - /* PRCM #2 - ratio1 (ES2) - FAST */ - {S13M, S658M, S329M, R1_CM_CLKSEL_MPU_VAL, /* 330MHz ARM */ - R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL, - R1_CM_CLKSEL1_CORE_VAL, M2_CM_CLKSEL1_PLL_13_VAL, - MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL, - SDRC_RFR_CTRL_165MHz, - RATE_IN_243X}, - - /* PRCM #5a - ratio1 - FAST */ - {S13M, S532M, S266M, R1_CM_CLKSEL_MPU_VAL, /* 266MHz ARM */ - R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL, - R1_CM_CLKSEL1_CORE_VAL, M5A_CM_CLKSEL1_PLL_13_VAL, - MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL, - SDRC_RFR_CTRL_133MHz, - RATE_IN_243X}, - - /* PRCM #5b - ratio1 - FAST */ - {S13M, S400M, S200M, R1_CM_CLKSEL_MPU_VAL, /* 200MHz ARM */ - R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL, - R1_CM_CLKSEL1_CORE_VAL, M5B_CM_CLKSEL1_PLL_13_VAL, - MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL, - SDRC_RFR_CTRL_100MHz, - RATE_IN_243X}, - - /* PRCM #4 - ratio1 (ES2.1) - SLOW */ - {S13M, S399M, S199M, R2_CM_CLKSEL_MPU_VAL, /* 200MHz ARM */ - R2_CM_CLKSEL_DSP_VAL, R2_CM_CLKSEL_GFX_VAL, - R2_CM_CLKSEL1_CORE_VAL, M4_CM_CLKSEL1_PLL_13_VAL, - MX_CLKSEL2_PLL_1x_VAL, R2_CM_CLKSEL_MDM_VAL, - SDRC_RFR_CTRL_133MHz, - RATE_IN_243X}, - - /* PRCM #2 - ratio1 (ES2) - SLOW */ - {S13M, S329M, S164M, R1_CM_CLKSEL_MPU_VAL, /* 165MHz ARM */ - R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL, - R1_CM_CLKSEL1_CORE_VAL, M2_CM_CLKSEL1_PLL_13_VAL, - MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL, - SDRC_RFR_CTRL_165MHz, - RATE_IN_243X}, - - /* PRCM #5a - ratio1 - SLOW */ - {S13M, S266M, S133M, R1_CM_CLKSEL_MPU_VAL, /* 133MHz ARM */ - R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL, - R1_CM_CLKSEL1_CORE_VAL, M5A_CM_CLKSEL1_PLL_13_VAL, - MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL, - SDRC_RFR_CTRL_133MHz, - RATE_IN_243X}, - - /* PRCM #5b - ratio1 - SLOW*/ - {S13M, S200M, S100M, R1_CM_CLKSEL_MPU_VAL, /* 100MHz ARM */ - R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL, - R1_CM_CLKSEL1_CORE_VAL, M5B_CM_CLKSEL1_PLL_13_VAL, - MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL, - SDRC_RFR_CTRL_100MHz, - RATE_IN_243X}, - - /* PRCM-boot/bypass */ - {S13M, S13M, S13M, RB_CM_CLKSEL_MPU_VAL, /* 13Mhz */ - RB_CM_CLKSEL_DSP_VAL, RB_CM_CLKSEL_GFX_VAL, - RB_CM_CLKSEL1_CORE_VAL, MB_CM_CLKSEL1_PLL_13_VAL, - MX_CLKSEL2_PLL_2x_VAL, RB_CM_CLKSEL_MDM_VAL, - SDRC_RFR_CTRL_BYPASS, - RATE_IN_243X}, - - /* PRCM-boot/bypass */ - {S12M, S12M, S12M, RB_CM_CLKSEL_MPU_VAL, /* 12Mhz */ - RB_CM_CLKSEL_DSP_VAL, RB_CM_CLKSEL_GFX_VAL, - RB_CM_CLKSEL1_CORE_VAL, MB_CM_CLKSEL1_PLL_12_VAL, - MX_CLKSEL2_PLL_2x_VAL, RB_CM_CLKSEL_MDM_VAL, - SDRC_RFR_CTRL_BYPASS, - RATE_IN_243X}, - - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -}; - -/*------------------------------------------------------------------------- - * 24xx clock tree. - * - * NOTE:In many cases here we are assigning a 'default' parent. In many - * cases the parent is selectable. The get/set parent calls will also - * switch sources. - * - * Many some clocks say always_enabled, but they can be auto idled for - * power savings. They will always be available upon clock request. - * - * Several sources are given initial rates which may be wrong, this will - * be fixed up in the init func. - * - * Things are broadly separated below by clock domains. It is - * noteworthy that most periferals have dependencies on multiple clock - * domains. Many get their interface clocks from the L4 domain, but get - * functional clocks from fixed sources or other core domain derived - * clocks. - *-------------------------------------------------------------------------*/ - -/* Base external input clocks */ -static struct clk func_32k_ck = { - .name = "func_32k_ck", - .rate = 32000, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES, - .clkdm_name = "wkup_clkdm", - .recalc = &propagate_rate, -}; - -/* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */ -static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */ - .name = "osc_ck", - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - RATE_PROPAGATES, - .clkdm_name = "wkup_clkdm", - .enable = &omap2_enable_osc_ck, - .disable = &omap2_disable_osc_ck, - .recalc = &omap2_osc_clk_recalc, -}; - -/* Without modem likely 12MHz, with modem likely 13MHz */ -static struct clk sys_ck = { /* (*12, *13, 19.2, 26, 38.4)MHz */ - .name = "sys_ck", /* ~ ref_clk also */ - .parent = &osc_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - ALWAYS_ENABLED | RATE_PROPAGATES, - .clkdm_name = "wkup_clkdm", - .recalc = &omap2_sys_clk_recalc, -}; - -static struct clk alt_ck = { /* Typical 54M or 48M, may not exist */ - .name = "alt_ck", - .rate = 54000000, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES, - .clkdm_name = "wkup_clkdm", - .recalc = &propagate_rate, -}; - -/* - * Analog domain root source clocks - */ - -/* dpll_ck, is broken out in to special cases through clksel */ -/* REVISIT: Rate changes on dpll_ck trigger a full set change. ... - * deal with this - */ - -static struct dpll_data dpll_dd = { - .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), - .mult_mask = OMAP24XX_DPLL_MULT_MASK, - .div1_mask = OMAP24XX_DPLL_DIV_MASK, - .max_multiplier = 1024, - .max_divider = 16, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE -}; - -/* - * XXX Cannot add round_rate here yet, as this is still a composite clock, - * not just a DPLL - */ -static struct clk dpll_ck = { - .name = "dpll_ck", - .parent = &sys_ck, /* Can be func_32k also */ - .dpll_data = &dpll_dd, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - RATE_PROPAGATES | ALWAYS_ENABLED, - .clkdm_name = "wkup_clkdm", - .recalc = &omap2_dpllcore_recalc, - .set_rate = &omap2_reprogram_dpllcore, -}; - -static struct clk apll96_ck = { - .name = "apll96_ck", - .parent = &sys_ck, - .rate = 96000000, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - RATE_FIXED | RATE_PROPAGATES | ENABLE_ON_INIT, - .clkdm_name = "wkup_clkdm", - .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), - .enable_bit = OMAP24XX_EN_96M_PLL_SHIFT, - .enable = &omap2_clk_fixed_enable, - .disable = &omap2_clk_fixed_disable, - .recalc = &propagate_rate, -}; - -static struct clk apll54_ck = { - .name = "apll54_ck", - .parent = &sys_ck, - .rate = 54000000, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - RATE_FIXED | RATE_PROPAGATES | ENABLE_ON_INIT, - .clkdm_name = "wkup_clkdm", - .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), - .enable_bit = OMAP24XX_EN_54M_PLL_SHIFT, - .enable = &omap2_clk_fixed_enable, - .disable = &omap2_clk_fixed_disable, - .recalc = &propagate_rate, -}; - -/* - * PRCM digital base sources - */ - -/* func_54m_ck */ - -static const struct clksel_rate func_54m_apll54_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 0 }, -}; - -static const struct clksel_rate func_54m_alt_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 0 }, -}; - -static const struct clksel func_54m_clksel[] = { - { .parent = &apll54_ck, .rates = func_54m_apll54_rates, }, - { .parent = &alt_ck, .rates = func_54m_alt_rates, }, - { .parent = NULL }, -}; - -static struct clk func_54m_ck = { - .name = "func_54m_ck", - .parent = &apll54_ck, /* can also be alt_clk */ - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "wkup_clkdm", - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), - .clksel_mask = OMAP24XX_54M_SOURCE, - .clksel = func_54m_clksel, - .recalc = &omap2_clksel_recalc, -}; - -static struct clk core_ck = { - .name = "core_ck", - .parent = &dpll_ck, /* can also be 32k */ - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - ALWAYS_ENABLED | RATE_PROPAGATES, - .clkdm_name = "wkup_clkdm", - .recalc = &followparent_recalc, -}; - -/* func_96m_ck */ -static const struct clksel_rate func_96m_apll96_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 0 }, -}; - -static const struct clksel_rate func_96m_alt_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_243X | DEFAULT_RATE }, - { .div = 0 }, -}; - -static const struct clksel func_96m_clksel[] = { - { .parent = &apll96_ck, .rates = func_96m_apll96_rates }, - { .parent = &alt_ck, .rates = func_96m_alt_rates }, - { .parent = NULL } -}; - -/* The parent of this clock is not selectable on 2420. */ -static struct clk func_96m_ck = { - .name = "func_96m_ck", - .parent = &apll96_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "wkup_clkdm", - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), - .clksel_mask = OMAP2430_96M_SOURCE, - .clksel = func_96m_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -/* func_48m_ck */ - -static const struct clksel_rate func_48m_apll96_rates[] = { - { .div = 2, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 0 }, -}; - -static const struct clksel_rate func_48m_alt_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 0 }, -}; - -static const struct clksel func_48m_clksel[] = { - { .parent = &apll96_ck, .rates = func_48m_apll96_rates }, - { .parent = &alt_ck, .rates = func_48m_alt_rates }, - { .parent = NULL } -}; - -static struct clk func_48m_ck = { - .name = "func_48m_ck", - .parent = &apll96_ck, /* 96M or Alt */ - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "wkup_clkdm", - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), - .clksel_mask = OMAP24XX_48M_SOURCE, - .clksel = func_48m_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -static struct clk func_12m_ck = { - .name = "func_12m_ck", - .parent = &func_48m_ck, - .fixed_div = 4, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, - .clkdm_name = "wkup_clkdm", - .recalc = &omap2_fixed_divisor_recalc, -}; - -/* Secure timer, only available in secure mode */ -static struct clk wdt1_osc_ck = { - .name = "ck_wdt1_osc", - .parent = &osc_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .recalc = &followparent_recalc, -}; - -/* - * The common_clkout* clksel_rate structs are common to - * sys_clkout, sys_clkout_src, sys_clkout2, and sys_clkout2_src. - * sys_clkout2_* are 2420-only, so the - * clksel_rate flags fields are inaccurate for those clocks. This is - * harmless since access to those clocks are gated by the struct clk - * flags fields, which mark them as 2420-only. - */ -static const struct clksel_rate common_clkout_src_core_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate common_clkout_src_sys_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate common_clkout_src_96m_rates[] = { - { .div = 1, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate common_clkout_src_54m_rates[] = { - { .div = 1, .val = 3, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel common_clkout_src_clksel[] = { - { .parent = &core_ck, .rates = common_clkout_src_core_rates }, - { .parent = &sys_ck, .rates = common_clkout_src_sys_rates }, - { .parent = &func_96m_ck, .rates = common_clkout_src_96m_rates }, - { .parent = &func_54m_ck, .rates = common_clkout_src_54m_rates }, - { .parent = NULL } -}; - -static struct clk sys_clkout_src = { - .name = "sys_clkout_src", - .parent = &func_54m_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - RATE_PROPAGATES, - .clkdm_name = "wkup_clkdm", - .enable_reg = OMAP24XX_PRCM_CLKOUT_CTRL, - .enable_bit = OMAP24XX_CLKOUT_EN_SHIFT, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP24XX_PRCM_CLKOUT_CTRL, - .clksel_mask = OMAP24XX_CLKOUT_SOURCE_MASK, - .clksel = common_clkout_src_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -static const struct clksel_rate common_clkout_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 2, .val = 1, .flags = RATE_IN_24XX }, - { .div = 4, .val = 2, .flags = RATE_IN_24XX }, - { .div = 8, .val = 3, .flags = RATE_IN_24XX }, - { .div = 16, .val = 4, .flags = RATE_IN_24XX }, - { .div = 0 }, -}; - -static const struct clksel sys_clkout_clksel[] = { - { .parent = &sys_clkout_src, .rates = common_clkout_rates }, - { .parent = NULL } -}; - -static struct clk sys_clkout = { - .name = "sys_clkout", - .parent = &sys_clkout_src, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - PARENT_CONTROLS_CLOCK, - .clkdm_name = "wkup_clkdm", - .clksel_reg = OMAP24XX_PRCM_CLKOUT_CTRL, - .clksel_mask = OMAP24XX_CLKOUT_DIV_MASK, - .clksel = sys_clkout_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -/* In 2430, new in 2420 ES2 */ -static struct clk sys_clkout2_src = { - .name = "sys_clkout2_src", - .parent = &func_54m_ck, - .flags = CLOCK_IN_OMAP242X | RATE_PROPAGATES, - .clkdm_name = "wkup_clkdm", - .enable_reg = OMAP24XX_PRCM_CLKOUT_CTRL, - .enable_bit = OMAP2420_CLKOUT2_EN_SHIFT, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP24XX_PRCM_CLKOUT_CTRL, - .clksel_mask = OMAP2420_CLKOUT2_SOURCE_MASK, - .clksel = common_clkout_src_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -static const struct clksel sys_clkout2_clksel[] = { - { .parent = &sys_clkout2_src, .rates = common_clkout_rates }, - { .parent = NULL } -}; - -/* In 2430, new in 2420 ES2 */ -static struct clk sys_clkout2 = { - .name = "sys_clkout2", - .parent = &sys_clkout2_src, - .flags = CLOCK_IN_OMAP242X | PARENT_CONTROLS_CLOCK, - .clkdm_name = "wkup_clkdm", - .clksel_reg = OMAP24XX_PRCM_CLKOUT_CTRL, - .clksel_mask = OMAP2420_CLKOUT2_DIV_MASK, - .clksel = sys_clkout2_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -static struct clk emul_ck = { - .name = "emul_ck", - .parent = &func_54m_ck, - .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "wkup_clkdm", - .enable_reg = OMAP24XX_PRCM_CLKEMUL_CTRL, - .enable_bit = OMAP24XX_EMULATION_EN_SHIFT, - .recalc = &followparent_recalc, - -}; - -/* - * MPU clock domain - * Clocks: - * MPU_FCLK, MPU_ICLK - * INT_M_FCLK, INT_M_I_CLK - * - * - Individual clocks are hardware managed. - * - Base divider comes from: CM_CLKSEL_MPU - * - */ -static const struct clksel_rate mpu_core_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 2, .val = 2, .flags = RATE_IN_24XX }, - { .div = 4, .val = 4, .flags = RATE_IN_242X }, - { .div = 6, .val = 6, .flags = RATE_IN_242X }, - { .div = 8, .val = 8, .flags = RATE_IN_242X }, - { .div = 0 }, -}; - -static const struct clksel mpu_clksel[] = { - { .parent = &core_ck, .rates = mpu_core_rates }, - { .parent = NULL } -}; - -static struct clk mpu_ck = { /* Control cpu */ - .name = "mpu_ck", - .parent = &core_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - ALWAYS_ENABLED | DELAYED_APP | - CONFIG_PARTICIPANT | RATE_PROPAGATES, - .clkdm_name = "mpu_clkdm", - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL), - .clksel_mask = OMAP24XX_CLKSEL_MPU_MASK, - .clksel = mpu_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -/* - * DSP (2430-IVA2.1) (2420-UMA+IVA1) clock domain - * Clocks: - * 2430: IVA2.1_FCLK (really just DSP_FCLK), IVA2.1_ICLK - * 2420: UMA_FCLK, UMA_ICLK, IVA_MPU, IVA_COP - * - * Won't be too specific here. The core clock comes into this block - * it is divided then tee'ed. One branch goes directly to xyz enable - * controls. The other branch gets further divided by 2 then possibly - * routed into a synchronizer and out of clocks abc. - */ -static const struct clksel_rate dsp_fck_core_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 2, .val = 2, .flags = RATE_IN_24XX }, - { .div = 3, .val = 3, .flags = RATE_IN_24XX }, - { .div = 4, .val = 4, .flags = RATE_IN_24XX }, - { .div = 6, .val = 6, .flags = RATE_IN_242X }, - { .div = 8, .val = 8, .flags = RATE_IN_242X }, - { .div = 12, .val = 12, .flags = RATE_IN_242X }, - { .div = 0 }, -}; - -static const struct clksel dsp_fck_clksel[] = { - { .parent = &core_ck, .rates = dsp_fck_core_rates }, - { .parent = NULL } -}; - -static struct clk dsp_fck = { - .name = "dsp_fck", - .parent = &core_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | DELAYED_APP | - CONFIG_PARTICIPANT | RATE_PROPAGATES, - .clkdm_name = "dsp_clkdm", - .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN), - .enable_bit = OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL), - .clksel_mask = OMAP24XX_CLKSEL_DSP_MASK, - .clksel = dsp_fck_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -/* DSP interface clock */ -static const struct clksel_rate dsp_irate_ick_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 2, .val = 2, .flags = RATE_IN_24XX }, - { .div = 3, .val = 3, .flags = RATE_IN_243X }, - { .div = 0 }, -}; - -static const struct clksel dsp_irate_ick_clksel[] = { - { .parent = &dsp_fck, .rates = dsp_irate_ick_rates }, - { .parent = NULL } -}; - -/* This clock does not exist as such in the TRM. */ -static struct clk dsp_irate_ick = { - .name = "dsp_irate_ick", - .parent = &dsp_fck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | DELAYED_APP | - CONFIG_PARTICIPANT | PARENT_CONTROLS_CLOCK, - .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL), - .clksel_mask = OMAP24XX_CLKSEL_DSP_IF_MASK, - .clksel = dsp_irate_ick_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -/* 2420 only */ -static struct clk dsp_ick = { - .name = "dsp_ick", /* apparently ipi and isp */ - .parent = &dsp_irate_ick, - .flags = CLOCK_IN_OMAP242X | DELAYED_APP | CONFIG_PARTICIPANT, - .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_ICLKEN), - .enable_bit = OMAP2420_EN_DSP_IPI_SHIFT, /* for ipi */ -}; - -/* 2430 only - EN_DSP controls both dsp fclk and iclk on 2430 */ -static struct clk iva2_1_ick = { - .name = "iva2_1_ick", - .parent = &dsp_irate_ick, - .flags = CLOCK_IN_OMAP243X | DELAYED_APP | CONFIG_PARTICIPANT, - .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN), - .enable_bit = OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT, -}; - -/* - * The IVA1 is an ARM7 core on the 2420 that has nothing to do with - * the C54x, but which is contained in the DSP powerdomain. Does not - * exist on later OMAPs. - */ -static struct clk iva1_ifck = { - .name = "iva1_ifck", - .parent = &core_ck, - .flags = CLOCK_IN_OMAP242X | CONFIG_PARTICIPANT | - RATE_PROPAGATES | DELAYED_APP, - .clkdm_name = "iva1_clkdm", - .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN), - .enable_bit = OMAP2420_EN_IVA_COP_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL), - .clksel_mask = OMAP2420_CLKSEL_IVA_MASK, - .clksel = dsp_fck_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -/* IVA1 mpu/int/i/f clocks are /2 of parent */ -static struct clk iva1_mpu_int_ifck = { - .name = "iva1_mpu_int_ifck", - .parent = &iva1_ifck, - .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "iva1_clkdm", - .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN), - .enable_bit = OMAP2420_EN_IVA_MPU_SHIFT, - .fixed_div = 2, - .recalc = &omap2_fixed_divisor_recalc, -}; - -/* - * L3 clock domain - * L3 clocks are used for both interface and functional clocks to - * multiple entities. Some of these clocks are completely managed - * by hardware, and some others allow software control. Hardware - * managed ones general are based on directly CLK_REQ signals and - * various auto idle settings. The functional spec sets many of these - * as 'tie-high' for their enables. - * - * I-CLOCKS: - * L3-Interconnect, SMS, GPMC, SDRC, OCM_RAM, OCM_ROM, SDMA - * CAM, HS-USB. - * F-CLOCK - * SSI. - * - * GPMC memories and SDRC have timing and clock sensitive registers which - * may very well need notification when the clock changes. Currently for low - * operating points, these are taken care of in sleep.S. - */ -static const struct clksel_rate core_l3_core_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX }, - { .div = 2, .val = 2, .flags = RATE_IN_242X }, - { .div = 4, .val = 4, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 6, .val = 6, .flags = RATE_IN_24XX }, - { .div = 8, .val = 8, .flags = RATE_IN_242X }, - { .div = 12, .val = 12, .flags = RATE_IN_242X }, - { .div = 16, .val = 16, .flags = RATE_IN_242X }, - { .div = 0 } -}; - -static const struct clksel core_l3_clksel[] = { - { .parent = &core_ck, .rates = core_l3_core_rates }, - { .parent = NULL } -}; - -static struct clk core_l3_ck = { /* Used for ick and fck, interconnect */ - .name = "core_l3_ck", - .parent = &core_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - ALWAYS_ENABLED | DELAYED_APP | - CONFIG_PARTICIPANT | RATE_PROPAGATES, - .clkdm_name = "core_l3_clkdm", - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), - .clksel_mask = OMAP24XX_CLKSEL_L3_MASK, - .clksel = core_l3_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -/* usb_l4_ick */ -static const struct clksel_rate usb_l4_ick_core_l3_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX }, - { .div = 2, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 4, .val = 4, .flags = RATE_IN_24XX }, - { .div = 0 } -}; - -static const struct clksel usb_l4_ick_clksel[] = { - { .parent = &core_l3_ck, .rates = usb_l4_ick_core_l3_rates }, - { .parent = NULL }, -}; - -/* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */ -static struct clk usb_l4_ick = { /* FS-USB interface clock */ - .name = "usb_l4_ick", - .parent = &core_l3_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - DELAYED_APP | CONFIG_PARTICIPANT, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), - .enable_bit = OMAP24XX_EN_USB_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), - .clksel_mask = OMAP24XX_CLKSEL_USB_MASK, - .clksel = usb_l4_ick_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -/* - * L4 clock management domain - * - * This domain contains lots of interface clocks from the L4 interface, some - * functional clocks. Fixed APLL functional source clocks are managed in - * this domain. - */ -static const struct clksel_rate l4_core_l3_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 2, .val = 2, .flags = RATE_IN_24XX }, - { .div = 0 } -}; - -static const struct clksel l4_clksel[] = { - { .parent = &core_l3_ck, .rates = l4_core_l3_rates }, - { .parent = NULL } -}; - -static struct clk l4_ck = { /* used both as an ick and fck */ - .name = "l4_ck", - .parent = &core_l3_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - ALWAYS_ENABLED | DELAYED_APP | RATE_PROPAGATES, - .clkdm_name = "core_l4_clkdm", - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), - .clksel_mask = OMAP24XX_CLKSEL_L4_MASK, - .clksel = l4_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -/* - * SSI is in L3 management domain, its direct parent is core not l3, - * many core power domain entities are grouped into the L3 clock - * domain. - * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_ICLK - * - * ssr = core/1/2/3/4/5, sst = 1/2 ssr. - */ -static const struct clksel_rate ssi_ssr_sst_fck_core_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX }, - { .div = 2, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 3, .val = 3, .flags = RATE_IN_24XX }, - { .div = 4, .val = 4, .flags = RATE_IN_24XX }, - { .div = 5, .val = 5, .flags = RATE_IN_243X }, - { .div = 6, .val = 6, .flags = RATE_IN_242X }, - { .div = 8, .val = 8, .flags = RATE_IN_242X }, - { .div = 0 } -}; - -static const struct clksel ssi_ssr_sst_fck_clksel[] = { - { .parent = &core_ck, .rates = ssi_ssr_sst_fck_core_rates }, - { .parent = NULL } -}; - -static struct clk ssi_ssr_sst_fck = { - .name = "ssi_fck", - .parent = &core_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - DELAYED_APP, - .clkdm_name = "core_l3_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), - .enable_bit = OMAP24XX_EN_SSI_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), - .clksel_mask = OMAP24XX_CLKSEL_SSI_MASK, - .clksel = ssi_ssr_sst_fck_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - - -/* - * GFX clock domain - * Clocks: - * GFX_FCLK, GFX_ICLK - * GFX_CG1(2d), GFX_CG2(3d) - * - * GFX_FCLK runs from L3, and is divided by (1,2,3,4) - * The 2d and 3d clocks run at a hardware determined - * divided value of fclk. - * - */ -/* XXX REVISIT: GFX clock is part of CONFIG_PARTICIPANT, no? doublecheck. */ - -/* This clksel struct is shared between gfx_3d_fck and gfx_2d_fck */ -static const struct clksel gfx_fck_clksel[] = { - { .parent = &core_l3_ck, .rates = gfx_l3_rates }, - { .parent = NULL }, -}; - -static struct clk gfx_3d_fck = { - .name = "gfx_3d_fck", - .parent = &core_l3_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "gfx_clkdm", - .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), - .enable_bit = OMAP24XX_EN_3D_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL), - .clksel_mask = OMAP_CLKSEL_GFX_MASK, - .clksel = gfx_fck_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -static struct clk gfx_2d_fck = { - .name = "gfx_2d_fck", - .parent = &core_l3_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "gfx_clkdm", - .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), - .enable_bit = OMAP24XX_EN_2D_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL), - .clksel_mask = OMAP_CLKSEL_GFX_MASK, - .clksel = gfx_fck_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -static struct clk gfx_ick = { - .name = "gfx_ick", /* From l3 */ - .parent = &core_l3_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "gfx_clkdm", - .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN), - .enable_bit = OMAP_EN_GFX_SHIFT, - .recalc = &followparent_recalc, -}; - -/* - * Modem clock domain (2430) - * CLOCKS: - * MDM_OSC_CLK - * MDM_ICLK - * These clocks are usable in chassis mode only. - */ -static const struct clksel_rate mdm_ick_core_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_243X }, - { .div = 4, .val = 4, .flags = RATE_IN_243X | DEFAULT_RATE }, - { .div = 6, .val = 6, .flags = RATE_IN_243X }, - { .div = 9, .val = 9, .flags = RATE_IN_243X }, - { .div = 0 } -}; - -static const struct clksel mdm_ick_clksel[] = { - { .parent = &core_ck, .rates = mdm_ick_core_rates }, - { .parent = NULL } -}; - -static struct clk mdm_ick = { /* used both as a ick and fck */ - .name = "mdm_ick", - .parent = &core_ck, - .flags = CLOCK_IN_OMAP243X | DELAYED_APP | CONFIG_PARTICIPANT, - .clkdm_name = "mdm_clkdm", - .enable_reg = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_ICLKEN), - .enable_bit = OMAP2430_CM_ICLKEN_MDM_EN_MDM_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_CLKSEL), - .clksel_mask = OMAP2430_CLKSEL_MDM_MASK, - .clksel = mdm_ick_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -static struct clk mdm_osc_ck = { - .name = "mdm_osc_ck", - .parent = &osc_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "mdm_clkdm", - .enable_reg = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_FCLKEN), - .enable_bit = OMAP2430_EN_OSC_SHIFT, - .recalc = &followparent_recalc, -}; - -/* - * DSS clock domain - * CLOCKs: - * DSS_L4_ICLK, DSS_L3_ICLK, - * DSS_CLK1, DSS_CLK2, DSS_54MHz_CLK - * - * DSS is both initiator and target. - */ -/* XXX Add RATE_NOT_VALIDATED */ - -static const struct clksel_rate dss1_fck_sys_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate dss1_fck_core_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX }, - { .div = 2, .val = 2, .flags = RATE_IN_24XX }, - { .div = 3, .val = 3, .flags = RATE_IN_24XX }, - { .div = 4, .val = 4, .flags = RATE_IN_24XX }, - { .div = 5, .val = 5, .flags = RATE_IN_24XX }, - { .div = 6, .val = 6, .flags = RATE_IN_24XX }, - { .div = 8, .val = 8, .flags = RATE_IN_24XX }, - { .div = 9, .val = 9, .flags = RATE_IN_24XX }, - { .div = 12, .val = 12, .flags = RATE_IN_24XX }, - { .div = 16, .val = 16, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel dss1_fck_clksel[] = { - { .parent = &sys_ck, .rates = dss1_fck_sys_rates }, - { .parent = &core_ck, .rates = dss1_fck_core_rates }, - { .parent = NULL }, -}; - -static struct clk dss_ick = { /* Enables both L3,L4 ICLK's */ - .name = "dss_ick", - .parent = &l4_ck, /* really both l3 and l4 */ - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "dss_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_DSS1_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk dss1_fck = { - .name = "dss1_fck", - .parent = &core_ck, /* Core or sys */ - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - DELAYED_APP, - .clkdm_name = "dss_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_DSS1_SHIFT, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), - .clksel_mask = OMAP24XX_CLKSEL_DSS1_MASK, - .clksel = dss1_fck_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -static const struct clksel_rate dss2_fck_sys_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate dss2_fck_48m_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel dss2_fck_clksel[] = { - { .parent = &sys_ck, .rates = dss2_fck_sys_rates }, - { .parent = &func_48m_ck, .rates = dss2_fck_48m_rates }, - { .parent = NULL } -}; - -static struct clk dss2_fck = { /* Alt clk used in power management */ - .name = "dss2_fck", - .parent = &sys_ck, /* fixed at sys_ck or 48MHz */ - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - DELAYED_APP, - .clkdm_name = "dss_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_DSS2_SHIFT, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), - .clksel_mask = OMAP24XX_CLKSEL_DSS2_MASK, - .clksel = dss2_fck_clksel, - .recalc = &followparent_recalc, -}; - -static struct clk dss_54m_fck = { /* Alt clk used in power management */ - .name = "dss_54m_fck", /* 54m tv clk */ - .parent = &func_54m_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "dss_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_TV_SHIFT, - .recalc = &followparent_recalc, -}; - -/* - * CORE power domain ICLK & FCLK defines. - * Many of the these can have more than one possible parent. Entries - * here will likely have an L4 interface parent, and may have multiple - * functional clock parents. - */ -static const struct clksel_rate gpt_alt_rates[] = { - { .div = 1, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel omap24xx_gpt_clksel[] = { - { .parent = &func_32k_ck, .rates = gpt_32k_rates }, - { .parent = &sys_ck, .rates = gpt_sys_rates }, - { .parent = &alt_ck, .rates = gpt_alt_rates }, - { .parent = NULL }, -}; - -static struct clk gpt1_ick = { - .name = "gpt1_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), - .enable_bit = OMAP24XX_EN_GPT1_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk gpt1_fck = { - .name = "gpt1_fck", - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), - .enable_bit = OMAP24XX_EN_GPT1_SHIFT, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL1), - .clksel_mask = OMAP24XX_CLKSEL_GPT1_MASK, - .clksel = omap24xx_gpt_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -static struct clk gpt2_ick = { - .name = "gpt2_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_GPT2_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk gpt2_fck = { - .name = "gpt2_fck", - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_GPT2_SHIFT, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), - .clksel_mask = OMAP24XX_CLKSEL_GPT2_MASK, - .clksel = omap24xx_gpt_clksel, - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gpt3_ick = { - .name = "gpt3_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_GPT3_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk gpt3_fck = { - .name = "gpt3_fck", - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_GPT3_SHIFT, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), - .clksel_mask = OMAP24XX_CLKSEL_GPT3_MASK, - .clksel = omap24xx_gpt_clksel, - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gpt4_ick = { - .name = "gpt4_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_GPT4_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk gpt4_fck = { - .name = "gpt4_fck", - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_GPT4_SHIFT, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), - .clksel_mask = OMAP24XX_CLKSEL_GPT4_MASK, - .clksel = omap24xx_gpt_clksel, - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gpt5_ick = { - .name = "gpt5_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_GPT5_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk gpt5_fck = { - .name = "gpt5_fck", - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_GPT5_SHIFT, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), - .clksel_mask = OMAP24XX_CLKSEL_GPT5_MASK, - .clksel = omap24xx_gpt_clksel, - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gpt6_ick = { - .name = "gpt6_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_GPT6_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk gpt6_fck = { - .name = "gpt6_fck", - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_GPT6_SHIFT, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), - .clksel_mask = OMAP24XX_CLKSEL_GPT6_MASK, - .clksel = omap24xx_gpt_clksel, - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gpt7_ick = { - .name = "gpt7_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_GPT7_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk gpt7_fck = { - .name = "gpt7_fck", - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_GPT7_SHIFT, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), - .clksel_mask = OMAP24XX_CLKSEL_GPT7_MASK, - .clksel = omap24xx_gpt_clksel, - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gpt8_ick = { - .name = "gpt8_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_GPT8_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk gpt8_fck = { - .name = "gpt8_fck", - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_GPT8_SHIFT, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), - .clksel_mask = OMAP24XX_CLKSEL_GPT8_MASK, - .clksel = omap24xx_gpt_clksel, - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gpt9_ick = { - .name = "gpt9_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_GPT9_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk gpt9_fck = { - .name = "gpt9_fck", - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_GPT9_SHIFT, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), - .clksel_mask = OMAP24XX_CLKSEL_GPT9_MASK, - .clksel = omap24xx_gpt_clksel, - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gpt10_ick = { - .name = "gpt10_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_GPT10_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk gpt10_fck = { - .name = "gpt10_fck", - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_GPT10_SHIFT, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), - .clksel_mask = OMAP24XX_CLKSEL_GPT10_MASK, - .clksel = omap24xx_gpt_clksel, - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gpt11_ick = { - .name = "gpt11_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_GPT11_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk gpt11_fck = { - .name = "gpt11_fck", - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_GPT11_SHIFT, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), - .clksel_mask = OMAP24XX_CLKSEL_GPT11_MASK, - .clksel = omap24xx_gpt_clksel, - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gpt12_ick = { - .name = "gpt12_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_GPT12_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk gpt12_fck = { - .name = "gpt12_fck", - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_GPT12_SHIFT, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2), - .clksel_mask = OMAP24XX_CLKSEL_GPT12_MASK, - .clksel = omap24xx_gpt_clksel, - .recalc = &omap2_clksel_recalc, -}; - -static struct clk mcbsp1_ick = { - .name = "mcbsp_ick", - .id = 1, - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_MCBSP1_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mcbsp1_fck = { - .name = "mcbsp_fck", - .id = 1, - .parent = &func_96m_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_MCBSP1_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mcbsp2_ick = { - .name = "mcbsp_ick", - .id = 2, - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_MCBSP2_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mcbsp2_fck = { - .name = "mcbsp_fck", - .id = 2, - .parent = &func_96m_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_MCBSP2_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mcbsp3_ick = { - .name = "mcbsp_ick", - .id = 3, - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), - .enable_bit = OMAP2430_EN_MCBSP3_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mcbsp3_fck = { - .name = "mcbsp_fck", - .id = 3, - .parent = &func_96m_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), - .enable_bit = OMAP2430_EN_MCBSP3_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mcbsp4_ick = { - .name = "mcbsp_ick", - .id = 4, - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), - .enable_bit = OMAP2430_EN_MCBSP4_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mcbsp4_fck = { - .name = "mcbsp_fck", - .id = 4, - .parent = &func_96m_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), - .enable_bit = OMAP2430_EN_MCBSP4_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mcbsp5_ick = { - .name = "mcbsp_ick", - .id = 5, - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), - .enable_bit = OMAP2430_EN_MCBSP5_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mcbsp5_fck = { - .name = "mcbsp_fck", - .id = 5, - .parent = &func_96m_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), - .enable_bit = OMAP2430_EN_MCBSP5_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mcspi1_ick = { - .name = "mcspi_ick", - .id = 1, - .parent = &l4_ck, - .clkdm_name = "core_l4_clkdm", - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_MCSPI1_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mcspi1_fck = { - .name = "mcspi_fck", - .id = 1, - .parent = &func_48m_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_MCSPI1_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mcspi2_ick = { - .name = "mcspi_ick", - .id = 2, - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_MCSPI2_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mcspi2_fck = { - .name = "mcspi_fck", - .id = 2, - .parent = &func_48m_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_MCSPI2_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mcspi3_ick = { - .name = "mcspi_ick", - .id = 3, - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), - .enable_bit = OMAP2430_EN_MCSPI3_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mcspi3_fck = { - .name = "mcspi_fck", - .id = 3, - .parent = &func_48m_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), - .enable_bit = OMAP2430_EN_MCSPI3_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk uart1_ick = { - .name = "uart1_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_UART1_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk uart1_fck = { - .name = "uart1_fck", - .parent = &func_48m_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_UART1_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk uart2_ick = { - .name = "uart2_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_UART2_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk uart2_fck = { - .name = "uart2_fck", - .parent = &func_48m_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_UART2_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk uart3_ick = { - .name = "uart3_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), - .enable_bit = OMAP24XX_EN_UART3_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk uart3_fck = { - .name = "uart3_fck", - .parent = &func_48m_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), - .enable_bit = OMAP24XX_EN_UART3_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk gpios_ick = { - .name = "gpios_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), - .enable_bit = OMAP24XX_EN_GPIOS_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk gpios_fck = { - .name = "gpios_fck", - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "wkup_clkdm", - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), - .enable_bit = OMAP24XX_EN_GPIOS_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mpu_wdt_ick = { - .name = "mpu_wdt_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), - .enable_bit = OMAP24XX_EN_MPU_WDT_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mpu_wdt_fck = { - .name = "mpu_wdt_fck", - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "wkup_clkdm", - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), - .enable_bit = OMAP24XX_EN_MPU_WDT_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk sync_32k_ick = { - .name = "sync_32k_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - ENABLE_ON_INIT, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), - .enable_bit = OMAP24XX_EN_32KSYNC_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk wdt1_ick = { - .name = "wdt1_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), - .enable_bit = OMAP24XX_EN_WDT1_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk omapctrl_ick = { - .name = "omapctrl_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - ENABLE_ON_INIT, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), - .enable_bit = OMAP24XX_EN_OMAPCTRL_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk icr_ick = { - .name = "icr_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), - .enable_bit = OMAP2430_EN_ICR_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk cam_ick = { - .name = "cam_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_CAM_SHIFT, - .recalc = &followparent_recalc, -}; - -/* - * cam_fck controls both CAM_MCLK and CAM_FCLK. It should probably be - * split into two separate clocks, since the parent clocks are different - * and the clockdomains are also different. - */ -static struct clk cam_fck = { - .name = "cam_fck", - .parent = &func_96m_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l3_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_CAM_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mailboxes_ick = { - .name = "mailboxes_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_MAILBOXES_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk wdt4_ick = { - .name = "wdt4_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_WDT4_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk wdt4_fck = { - .name = "wdt4_fck", - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_WDT4_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk wdt3_ick = { - .name = "wdt3_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP2420_EN_WDT3_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk wdt3_fck = { - .name = "wdt3_fck", - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP2420_EN_WDT3_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mspro_ick = { - .name = "mspro_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_MSPRO_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mspro_fck = { - .name = "mspro_fck", - .parent = &func_96m_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_MSPRO_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mmc_ick = { - .name = "mmc_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP2420_EN_MMC_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mmc_fck = { - .name = "mmc_fck", - .parent = &func_96m_ck, - .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP2420_EN_MMC_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk fac_ick = { - .name = "fac_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_FAC_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk fac_fck = { - .name = "fac_fck", - .parent = &func_12m_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_FAC_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk eac_ick = { - .name = "eac_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP2420_EN_EAC_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk eac_fck = { - .name = "eac_fck", - .parent = &func_96m_ck, - .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP2420_EN_EAC_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk hdq_ick = { - .name = "hdq_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP24XX_EN_HDQ_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk hdq_fck = { - .name = "hdq_fck", - .parent = &func_12m_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP24XX_EN_HDQ_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk i2c2_ick = { - .name = "i2c_ick", - .id = 2, - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP2420_EN_I2C2_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk i2c2_fck = { - .name = "i2c_fck", - .id = 2, - .parent = &func_12m_ck, - .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP2420_EN_I2C2_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk i2chs2_fck = { - .name = "i2c_fck", - .id = 2, - .parent = &func_96m_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), - .enable_bit = OMAP2430_EN_I2CHS2_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk i2c1_ick = { - .name = "i2c_ick", - .id = 1, - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP2420_EN_I2C1_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk i2c1_fck = { - .name = "i2c_fck", - .id = 1, - .parent = &func_12m_ck, - .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP2420_EN_I2C1_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk i2chs1_fck = { - .name = "i2c_fck", - .id = 1, - .parent = &func_96m_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), - .enable_bit = OMAP2430_EN_I2CHS1_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk gpmc_fck = { - .name = "gpmc_fck", - .parent = &core_l3_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - ENABLE_ON_INIT, - .clkdm_name = "core_l3_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk sdma_fck = { - .name = "sdma_fck", - .parent = &core_l3_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l3_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk sdma_ick = { - .name = "sdma_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - .clkdm_name = "core_l3_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk vlynq_ick = { - .name = "vlynq_ick", - .parent = &core_l3_ck, - .flags = CLOCK_IN_OMAP242X, - .clkdm_name = "core_l3_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP2420_EN_VLYNQ_SHIFT, - .recalc = &followparent_recalc, -}; - -static const struct clksel_rate vlynq_fck_96m_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_242X | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate vlynq_fck_core_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_242X }, - { .div = 2, .val = 2, .flags = RATE_IN_242X }, - { .div = 3, .val = 3, .flags = RATE_IN_242X }, - { .div = 4, .val = 4, .flags = RATE_IN_242X }, - { .div = 6, .val = 6, .flags = RATE_IN_242X }, - { .div = 8, .val = 8, .flags = RATE_IN_242X }, - { .div = 9, .val = 9, .flags = RATE_IN_242X }, - { .div = 12, .val = 12, .flags = RATE_IN_242X }, - { .div = 16, .val = 16, .flags = RATE_IN_242X | DEFAULT_RATE }, - { .div = 18, .val = 18, .flags = RATE_IN_242X }, - { .div = 0 } -}; - -static const struct clksel vlynq_fck_clksel[] = { - { .parent = &func_96m_ck, .rates = vlynq_fck_96m_rates }, - { .parent = &core_ck, .rates = vlynq_fck_core_rates }, - { .parent = NULL } -}; - -static struct clk vlynq_fck = { - .name = "vlynq_fck", - .parent = &func_96m_ck, - .flags = CLOCK_IN_OMAP242X | DELAYED_APP, - .clkdm_name = "core_l3_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP2420_EN_VLYNQ_SHIFT, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1), - .clksel_mask = OMAP2420_CLKSEL_VLYNQ_MASK, - .clksel = vlynq_fck_clksel, - .recalc = &omap2_clksel_recalc, - .round_rate = &omap2_clksel_round_rate, - .set_rate = &omap2_clksel_set_rate -}; - -static struct clk sdrc_ick = { - .name = "sdrc_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP243X | ENABLE_ON_INIT, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), - .enable_bit = OMAP2430_EN_SDRC_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk des_ick = { - .name = "des_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), - .enable_bit = OMAP24XX_EN_DES_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk sha_ick = { - .name = "sha_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), - .enable_bit = OMAP24XX_EN_SHA_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk rng_ick = { - .name = "rng_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), - .enable_bit = OMAP24XX_EN_RNG_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk aes_ick = { - .name = "aes_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), - .enable_bit = OMAP24XX_EN_AES_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk pka_ick = { - .name = "pka_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), - .enable_bit = OMAP24XX_EN_PKA_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk usb_fck = { - .name = "usb_fck", - .parent = &func_48m_ck, - .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X, - .clkdm_name = "core_l3_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), - .enable_bit = OMAP24XX_EN_USB_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk usbhs_ick = { - .name = "usbhs_ick", - .parent = &core_l3_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l3_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), - .enable_bit = OMAP2430_EN_USBHS_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mmchs1_ick = { - .name = "mmchs_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), - .enable_bit = OMAP2430_EN_MMCHS1_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mmchs1_fck = { - .name = "mmchs_fck", - .parent = &func_96m_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l3_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), - .enable_bit = OMAP2430_EN_MMCHS1_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mmchs2_ick = { - .name = "mmchs_ick", - .id = 1, - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), - .enable_bit = OMAP2430_EN_MMCHS2_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mmchs2_fck = { - .name = "mmchs_fck", - .id = 1, - .parent = &func_96m_ck, - .flags = CLOCK_IN_OMAP243X, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), - .enable_bit = OMAP2430_EN_MMCHS2_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk gpio5_ick = { - .name = "gpio5_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), - .enable_bit = OMAP2430_EN_GPIO5_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk gpio5_fck = { - .name = "gpio5_fck", - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), - .enable_bit = OMAP2430_EN_GPIO5_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mdm_intc_ick = { - .name = "mdm_intc_ick", - .parent = &l4_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), - .enable_bit = OMAP2430_EN_MDM_INTC_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mmchsdb1_fck = { - .name = "mmchsdb_fck", - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), - .enable_bit = OMAP2430_EN_MMCHSDB1_SHIFT, - .recalc = &followparent_recalc, -}; - -static struct clk mmchsdb2_fck = { - .name = "mmchsdb_fck", - .id = 1, - .parent = &func_32k_ck, - .flags = CLOCK_IN_OMAP243X, - .clkdm_name = "core_l4_clkdm", - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), - .enable_bit = OMAP2430_EN_MMCHSDB2_SHIFT, - .recalc = &followparent_recalc, -}; - -/* - * This clock is a composite clock which does entire set changes then - * forces a rebalance. It keys on the MPU speed, but it really could - * be any key speed part of a set in the rate table. - * - * to really change a set, you need memory table sets which get changed - * in sram, pre-notifiers & post notifiers, changing the top set, without - * having low level display recalc's won't work... this is why dpm notifiers - * work, isr's off, walk a list of clocks already _off_ and not messing with - * the bus. - * - * This clock should have no parent. It embodies the entire upper level - * active set. A parent will mess up some of the init also. - */ -static struct clk virt_prcm_set = { - .name = "virt_prcm_set", - .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - VIRTUAL_CLOCK | ALWAYS_ENABLED | DELAYED_APP, - .parent = &mpu_ck, /* Indexed by mpu speed, no parent */ - .recalc = &omap2_table_mpu_recalc, /* sets are keyed on mpu rate */ - .set_rate = &omap2_select_table_rate, - .round_rate = &omap2_round_to_table_rate, -}; - -static struct clk *onchip_24xx_clks[] __initdata = { - /* external root sources */ - &func_32k_ck, - &osc_ck, - &sys_ck, - &alt_ck, - /* internal analog sources */ - &dpll_ck, - &apll96_ck, - &apll54_ck, - /* internal prcm root sources */ - &func_54m_ck, - &core_ck, - &func_96m_ck, - &func_48m_ck, - &func_12m_ck, - &wdt1_osc_ck, - &sys_clkout_src, - &sys_clkout, - &sys_clkout2_src, - &sys_clkout2, - &emul_ck, - /* mpu domain clocks */ - &mpu_ck, - /* dsp domain clocks */ - &dsp_fck, - &dsp_irate_ick, - &dsp_ick, /* 242x */ - &iva2_1_ick, /* 243x */ - &iva1_ifck, /* 242x */ - &iva1_mpu_int_ifck, /* 242x */ - /* GFX domain clocks */ - &gfx_3d_fck, - &gfx_2d_fck, - &gfx_ick, - /* Modem domain clocks */ - &mdm_ick, - &mdm_osc_ck, - /* DSS domain clocks */ - &dss_ick, - &dss1_fck, - &dss2_fck, - &dss_54m_fck, - /* L3 domain clocks */ - &core_l3_ck, - &ssi_ssr_sst_fck, - &usb_l4_ick, - /* L4 domain clocks */ - &l4_ck, /* used as both core_l4 and wu_l4 */ - /* virtual meta-group clock */ - &virt_prcm_set, - /* general l4 interface ck, multi-parent functional clk */ - &gpt1_ick, - &gpt1_fck, - &gpt2_ick, - &gpt2_fck, - &gpt3_ick, - &gpt3_fck, - &gpt4_ick, - &gpt4_fck, - &gpt5_ick, - &gpt5_fck, - &gpt6_ick, - &gpt6_fck, - &gpt7_ick, - &gpt7_fck, - &gpt8_ick, - &gpt8_fck, - &gpt9_ick, - &gpt9_fck, - &gpt10_ick, - &gpt10_fck, - &gpt11_ick, - &gpt11_fck, - &gpt12_ick, - &gpt12_fck, - &mcbsp1_ick, - &mcbsp1_fck, - &mcbsp2_ick, - &mcbsp2_fck, - &mcbsp3_ick, - &mcbsp3_fck, - &mcbsp4_ick, - &mcbsp4_fck, - &mcbsp5_ick, - &mcbsp5_fck, - &mcspi1_ick, - &mcspi1_fck, - &mcspi2_ick, - &mcspi2_fck, - &mcspi3_ick, - &mcspi3_fck, - &uart1_ick, - &uart1_fck, - &uart2_ick, - &uart2_fck, - &uart3_ick, - &uart3_fck, - &gpios_ick, - &gpios_fck, - &mpu_wdt_ick, - &mpu_wdt_fck, - &sync_32k_ick, - &wdt1_ick, - &omapctrl_ick, - &icr_ick, - &cam_fck, - &cam_ick, - &mailboxes_ick, - &wdt4_ick, - &wdt4_fck, - &wdt3_ick, - &wdt3_fck, - &mspro_ick, - &mspro_fck, - &mmc_ick, - &mmc_fck, - &fac_ick, - &fac_fck, - &eac_ick, - &eac_fck, - &hdq_ick, - &hdq_fck, - &i2c1_ick, - &i2c1_fck, - &i2chs1_fck, - &i2c2_ick, - &i2c2_fck, - &i2chs2_fck, - &gpmc_fck, - &sdma_fck, - &sdma_ick, - &vlynq_ick, - &vlynq_fck, - &sdrc_ick, - &des_ick, - &sha_ick, - &rng_ick, - &aes_ick, - &pka_ick, - &usb_fck, - &usbhs_ick, - &mmchs1_ick, - &mmchs1_fck, - &mmchs2_ick, - &mmchs2_fck, - &gpio5_ick, - &gpio5_fck, - &mdm_intc_ick, - &mmchsdb1_fck, - &mmchsdb2_fck, -}; - -#endif - diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c new file mode 100644 index 00000000000..b870f6a9e28 --- /dev/null +++ b/arch/arm/mach-omap2/clock2xxx.c @@ -0,0 +1,57 @@ +/* + * clock2xxx.c - OMAP2xxx-specific clock integration code + * + * Copyright (C) 2005-2008 Texas Instruments, Inc. + * Copyright (C) 2004-2010 Nokia Corporation + * + * Contacts: + * Richard Woodruff <r-woodruff2@ti.com> + * Paul Walmsley + * + * Based on earlier work by Tuukka Tikkanen, Tony Lindgren, + * Gordon McNutt and RidgeRun, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#undef DEBUG + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/clk.h> +#include <linux/io.h> + +#include "soc.h" +#include "clock.h" +#include "clock2xxx.h" +#include "cm.h" +#include "cm-regbits-24xx.h" + +struct clk_hw *dclk_hw; +/* + * Omap24xx specific clock functions + */ + +/* + * Switch the MPU rate if specified on cmdline. We cannot do this + * early until cmdline is parsed. XXX This should be removed from the + * clock code and handled by the OPP layer code in the near future. + */ +static int __init omap2xxx_clk_arch_init(void) +{ + int ret; + + if (!cpu_is_omap24xx()) + return 0; + + ret = omap2_clk_switch_mpurate_at_boot("virt_prcm_set"); + if (!ret) + omap2_clk_print_new_rates("sys_ck", "dpll_ck", "mpu_ck"); + + return ret; +} + +omap_arch_initcall(omap2xxx_clk_arch_init); + + diff --git a/arch/arm/mach-omap2/clock2xxx.h b/arch/arm/mach-omap2/clock2xxx.h new file mode 100644 index 00000000000..45f41a41160 --- /dev/null +++ b/arch/arm/mach-omap2/clock2xxx.h @@ -0,0 +1,58 @@ +/* + * OMAP2 clock function prototypes and macros + * + * Copyright (C) 2005-2010 Texas Instruments, Inc. + * Copyright (C) 2004-2010 Nokia Corporation + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK2XXX_H +#define __ARCH_ARM_MACH_OMAP2_CLOCK2XXX_H + +#include <linux/clk-provider.h> +#include "clock.h" + +unsigned long omap2_table_mpu_recalc(struct clk_hw *clk, + unsigned long parent_rate); +int omap2_select_table_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate); +long omap2_round_to_table_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate); +unsigned long omap2xxx_sys_clk_recalc(struct clk_hw *clk, + unsigned long parent_rate); +unsigned long omap2_osc_clk_recalc(struct clk_hw *clk, + unsigned long parent_rate); +void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw); +unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw, + unsigned long parent_rate); +unsigned long omap2_clk_apll96_recalc(struct clk_hw *hw, + unsigned long parent_rate); +unsigned long omap2xxx_clk_get_core_rate(void); +u32 omap2xxx_get_apll_clkin(void); +u32 omap2xxx_get_sysclkdiv(void); +void omap2xxx_clk_prepare_for_reboot(void); +void omap2xxx_clkt_vps_check_bootloader_rates(void); +void omap2xxx_clkt_vps_late_init(void); + +#ifdef CONFIG_SOC_OMAP2420 +int omap2420_clk_init(void); +#else +#define omap2420_clk_init() do { } while(0) +#endif + +#ifdef CONFIG_SOC_OMAP2430 +int omap2430_clk_init(void); +#else +#define omap2430_clk_init() do { } while(0) +#endif + +extern void __iomem *prcm_clksrc_ctrl; + +extern struct clk_hw *dclk_hw; +int omap2_enable_osc_ck(struct clk_hw *hw); +void omap2_disable_osc_ck(struct clk_hw *hw); +int omap2_clk_apll96_enable(struct clk_hw *hw); +int omap2_clk_apll54_enable(struct clk_hw *hw); +void omap2_clk_apll96_disable(struct clk_hw *hw); +void omap2_clk_apll54_disable(struct clk_hw *hw); + +#endif diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index 31bb7010bd4..4596468e50a 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c @@ -2,13 +2,14 @@ * OMAP3-specific clock framework functions * * Copyright (C) 2007-2008 Texas Instruments, Inc. - * Copyright (C) 2007-2008 Nokia Corporation + * Copyright (C) 2007-2011 Nokia Corporation * - * Written by Paul Walmsley - * Testing and integration fixes by Jouni Högander + * Paul Walmsley + * Jouni Högander * * Parts of this code are based on code written by - * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu + * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu, + * Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -16,520 +17,122 @@ */ #undef DEBUG -#include <linux/module.h> #include <linux/kernel.h> -#include <linux/device.h> -#include <linux/list.h> -#include <linux/errno.h> -#include <linux/delay.h> #include <linux/clk.h> #include <linux/io.h> -#include <linux/limits.h> -#include <linux/bitops.h> -#include <mach/clock.h> -#include <mach/sram.h> -#include <asm/div64.h> - -#include "memory.h" #include "clock.h" #include "clock34xx.h" -#include "prm.h" -#include "prm-regbits-34xx.h" -#include "cm.h" +#include "cm3xxx.h" #include "cm-regbits-34xx.h" -/* CM_AUTOIDLE_PLL*.AUTO_* bit values */ -#define DPLL_AUTOIDLE_DISABLE 0x0 -#define DPLL_AUTOIDLE_LOW_POWER_STOP 0x1 - -#define MAX_DPLL_WAIT_TRIES 1000000 - -/** - * omap3_dpll_recalc - recalculate DPLL rate - * @clk: DPLL struct clk - * - * Recalculate and propagate the DPLL rate. - */ -static void omap3_dpll_recalc(struct clk *clk) -{ - clk->rate = omap2_get_dpll_rate(clk); - - propagate_rate(clk); -} - -/* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */ -static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits) -{ - const struct dpll_data *dd; - u32 v; - - dd = clk->dpll_data; - - v = __raw_readl(dd->control_reg); - v &= ~dd->enable_mask; - v |= clken_bits << __ffs(dd->enable_mask); - __raw_writel(v, dd->control_reg); -} - -/* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */ -static int _omap3_wait_dpll_status(struct clk *clk, u8 state) -{ - const struct dpll_data *dd; - int i = 0; - int ret = -EINVAL; - u32 idlest_mask; - - dd = clk->dpll_data; - - state <<= dd->idlest_bit; - idlest_mask = 1 << dd->idlest_bit; - - while (((__raw_readl(dd->idlest_reg) & idlest_mask) != state) && - i < MAX_DPLL_WAIT_TRIES) { - i++; - udelay(1); - } - - if (i == MAX_DPLL_WAIT_TRIES) { - printk(KERN_ERR "clock: %s failed transition to '%s'\n", - clk->name, (state) ? "locked" : "bypassed"); - } else { - pr_debug("clock: %s transition to '%s' in %d loops\n", - clk->name, (state) ? "locked" : "bypassed", i); - - ret = 0; - } - - return ret; -} - -/* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */ - -/* - * _omap3_noncore_dpll_lock - instruct a DPLL to lock and wait for readiness - * @clk: pointer to a DPLL struct clk - * - * Instructs a non-CORE DPLL to lock. Waits for the DPLL to report - * readiness before returning. Will save and restore the DPLL's - * autoidle state across the enable, per the CDP code. If the DPLL - * locked successfully, return 0; if the DPLL did not lock in the time - * allotted, or DPLL3 was passed in, return -EINVAL. - */ -static int _omap3_noncore_dpll_lock(struct clk *clk) -{ - u8 ai; - int r; - - if (clk == &dpll3_ck) - return -EINVAL; - - pr_debug("clock: locking DPLL %s\n", clk->name); - - ai = omap3_dpll_autoidle_read(clk); - - _omap3_dpll_write_clken(clk, DPLL_LOCKED); - - if (ai) { - /* - * If no downstream clocks are enabled, CM_IDLEST bit - * may never become active, so don't wait for DPLL to lock. - */ - r = 0; - omap3_dpll_allow_idle(clk); - } else { - r = _omap3_wait_dpll_status(clk, 1); - omap3_dpll_deny_idle(clk); - }; - - return r; -} - -/* - * omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness - * @clk: pointer to a DPLL struct clk - * - * Instructs a non-CORE DPLL to enter low-power bypass mode. In - * bypass mode, the DPLL's rate is set equal to its parent clock's - * rate. Waits for the DPLL to report readiness before returning. - * Will save and restore the DPLL's autoidle state across the enable, - * per the CDP code. If the DPLL entered bypass mode successfully, - * return 0; if the DPLL did not enter bypass in the time allotted, or - * DPLL3 was passed in, or the DPLL does not support low-power bypass, - * return -EINVAL. - */ -static int _omap3_noncore_dpll_bypass(struct clk *clk) -{ - int r; - u8 ai; - - if (clk == &dpll3_ck) - return -EINVAL; - - if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) - return -EINVAL; - - pr_debug("clock: configuring DPLL %s for low-power bypass\n", - clk->name); - - ai = omap3_dpll_autoidle_read(clk); - - _omap3_dpll_write_clken(clk, DPLL_LOW_POWER_BYPASS); - - r = _omap3_wait_dpll_status(clk, 0); - - if (ai) - omap3_dpll_allow_idle(clk); - else - omap3_dpll_deny_idle(clk); - - return r; -} - -/* - * _omap3_noncore_dpll_stop - instruct a DPLL to stop - * @clk: pointer to a DPLL struct clk - * - * Instructs a non-CORE DPLL to enter low-power stop. Will save and - * restore the DPLL's autoidle state across the stop, per the CDP - * code. If DPLL3 was passed in, or the DPLL does not support - * low-power stop, return -EINVAL; otherwise, return 0. - */ -static int _omap3_noncore_dpll_stop(struct clk *clk) -{ - u8 ai; - - if (clk == &dpll3_ck) - return -EINVAL; - - if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP))) - return -EINVAL; - - pr_debug("clock: stopping DPLL %s\n", clk->name); - - ai = omap3_dpll_autoidle_read(clk); - - _omap3_dpll_write_clken(clk, DPLL_LOW_POWER_STOP); - - if (ai) - omap3_dpll_allow_idle(clk); - else - omap3_dpll_deny_idle(clk); - - return 0; -} - /** - * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode - * @clk: pointer to a DPLL struct clk + * omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI + * @clk: struct clk * being enabled + * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into + * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into + * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator * - * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock. - * The choice of modes depends on the DPLL's programmed rate: if it is - * the same as the DPLL's parent clock, it will enter bypass; - * otherwise, it will enter lock. This code will wait for the DPLL to - * indicate readiness before returning, unless the DPLL takes too long - * to enter the target state. Intended to be used as the struct clk's - * enable function. If DPLL3 was passed in, or the DPLL does not - * support low-power stop, or if the DPLL took too long to enter - * bypass or lock, return -EINVAL; otherwise, return 0. + * The OMAP3430ES2 SSI target CM_IDLEST bit is at a different shift + * from the CM_{I,F}CLKEN bit. Pass back the correct info via + * @idlest_reg and @idlest_bit. No return value. */ -static int omap3_noncore_dpll_enable(struct clk *clk) +static void omap3430es2_clk_ssi_find_idlest(struct clk_hw_omap *clk, + void __iomem **idlest_reg, + u8 *idlest_bit, + u8 *idlest_val) { - int r; + u32 r; - if (clk == &dpll3_ck) - return -EINVAL; - - if (clk->parent->rate == clk_get_rate(clk)) - r = _omap3_noncore_dpll_bypass(clk); - else - r = _omap3_noncore_dpll_lock(clk); - - return r; + r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); + *idlest_reg = (__force void __iomem *)r; + *idlest_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT; + *idlest_val = OMAP34XX_CM_IDLEST_VAL; } +const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait = { + .find_idlest = omap3430es2_clk_ssi_find_idlest, + .find_companion = omap2_clk_dflt_find_companion, +}; -/** - * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode - * @clk: pointer to a DPLL struct clk - * - * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock. - * The choice of modes depends on the DPLL's programmed rate: if it is - * the same as the DPLL's parent clock, it will enter bypass; - * otherwise, it will enter lock. This code will wait for the DPLL to - * indicate readiness before returning, unless the DPLL takes too long - * to enter the target state. Intended to be used as the struct clk's - * enable function. If DPLL3 was passed in, or the DPLL does not - * support low-power stop, or if the DPLL took too long to enter - * bypass or lock, return -EINVAL; otherwise, return 0. - */ -static void omap3_noncore_dpll_disable(struct clk *clk) -{ - if (clk == &dpll3_ck) - return; - - _omap3_noncore_dpll_stop(clk); -} - -/** - * omap3_dpll_autoidle_read - read a DPLL's autoidle bits - * @clk: struct clk * of the DPLL to read - * - * Return the DPLL's autoidle bits, shifted down to bit 0. Returns - * -EINVAL if passed a null pointer or if the struct clk does not - * appear to refer to a DPLL. - */ -static u32 omap3_dpll_autoidle_read(struct clk *clk) -{ - const struct dpll_data *dd; - u32 v; - - if (!clk || !clk->dpll_data) - return -EINVAL; - - dd = clk->dpll_data; - - v = __raw_readl(dd->autoidle_reg); - v &= dd->autoidle_mask; - v >>= __ffs(dd->autoidle_mask); - - return v; -} +const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait = { + .allow_idle = omap2_clkt_iclk_allow_idle, + .deny_idle = omap2_clkt_iclk_deny_idle, + .find_idlest = omap3430es2_clk_ssi_find_idlest, + .find_companion = omap2_clk_dflt_find_companion, +}; /** - * omap3_dpll_allow_idle - enable DPLL autoidle bits - * @clk: struct clk * of the DPLL to operate on + * omap3430es2_clk_dss_usbhost_find_idlest - CM_IDLEST info for DSS, USBHOST + * @clk: struct clk * being enabled + * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into + * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into + * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator * - * Enable DPLL automatic idle control. This automatic idle mode - * switching takes effect only when the DPLL is locked, at least on - * OMAP3430. The DPLL will enter low-power stop when its downstream - * clocks are gated. No return value. + * Some OMAP modules on OMAP3 ES2+ chips have both initiator and + * target IDLEST bits. For our purposes, we are concerned with the + * target IDLEST bits, which exist at a different bit position than + * the *CLKEN bit position for these modules (DSS and USBHOST) (The + * default find_idlest code assumes that they are at the same + * position.) No return value. */ -static void omap3_dpll_allow_idle(struct clk *clk) +static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk_hw_omap *clk, + void __iomem **idlest_reg, + u8 *idlest_bit, + u8 *idlest_val) { - const struct dpll_data *dd; - u32 v; - - if (!clk || !clk->dpll_data) - return; + u32 r; - dd = clk->dpll_data; - - /* - * REVISIT: CORE DPLL can optionally enter low-power bypass - * by writing 0x5 instead of 0x1. Add some mechanism to - * optionally enter this mode. - */ - v = __raw_readl(dd->autoidle_reg); - v &= ~dd->autoidle_mask; - v |= DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask); - __raw_writel(v, dd->autoidle_reg); + r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); + *idlest_reg = (__force void __iomem *)r; + /* USBHOST_IDLE has same shift */ + *idlest_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT; + *idlest_val = OMAP34XX_CM_IDLEST_VAL; } -/** - * omap3_dpll_deny_idle - prevent DPLL from automatically idling - * @clk: struct clk * of the DPLL to operate on - * - * Disable DPLL automatic idle control. No return value. - */ -static void omap3_dpll_deny_idle(struct clk *clk) -{ - const struct dpll_data *dd; - u32 v; - - if (!clk || !clk->dpll_data) - return; - - dd = clk->dpll_data; - - v = __raw_readl(dd->autoidle_reg); - v &= ~dd->autoidle_mask; - v |= DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask); - __raw_writel(v, dd->autoidle_reg); -} +const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait = { + .find_idlest = omap3430es2_clk_dss_usbhost_find_idlest, + .find_companion = omap2_clk_dflt_find_companion, +}; -/* Clock control for DPLL outputs */ +const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_dss_usbhost_wait = { + .allow_idle = omap2_clkt_iclk_allow_idle, + .deny_idle = omap2_clkt_iclk_deny_idle, + .find_idlest = omap3430es2_clk_dss_usbhost_find_idlest, + .find_companion = omap2_clk_dflt_find_companion, +}; /** - * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate - * @clk: DPLL output struct clk + * omap3430es2_clk_hsotgusb_find_idlest - return CM_IDLEST info for HSOTGUSB + * @clk: struct clk * being enabled + * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into + * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into + * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator * - * Using parent clock DPLL data, look up DPLL state. If locked, set our - * rate to the dpll_clk * 2; otherwise, just use dpll_clk. + * The OMAP3430ES2 HSOTGUSB target CM_IDLEST bit is at a different + * shift from the CM_{I,F}CLKEN bit. Pass back the correct info via + * @idlest_reg and @idlest_bit. No return value. */ -static void omap3_clkoutx2_recalc(struct clk *clk) +static void omap3430es2_clk_hsotgusb_find_idlest(struct clk_hw_omap *clk, + void __iomem **idlest_reg, + u8 *idlest_bit, + u8 *idlest_val) { - const struct dpll_data *dd; - u32 v; - struct clk *pclk; - - /* Walk up the parents of clk, looking for a DPLL */ - pclk = clk->parent; - while (pclk && !pclk->dpll_data) - pclk = pclk->parent; - - /* clk does not have a DPLL as a parent? */ - WARN_ON(!pclk); + u32 r; - dd = pclk->dpll_data; - - WARN_ON(!dd->control_reg || !dd->enable_mask); - - v = __raw_readl(dd->control_reg) & dd->enable_mask; - v >>= __ffs(dd->enable_mask); - if (v != DPLL_LOCKED) - clk->rate = clk->parent->rate; - else - clk->rate = clk->parent->rate * 2; - - if (clk->flags & RATE_PROPAGATES) - propagate_rate(clk); + r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); + *idlest_reg = (__force void __iomem *)r; + *idlest_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT; + *idlest_val = OMAP34XX_CM_IDLEST_VAL; } -/* Common clock code */ - -/* - * As it is structured now, this will prevent an OMAP2/3 multiboot - * kernel from compiling. This will need further attention. - */ -#if defined(CONFIG_ARCH_OMAP3) - -static struct clk_functions omap2_clk_functions = { - .clk_enable = omap2_clk_enable, - .clk_disable = omap2_clk_disable, - .clk_round_rate = omap2_clk_round_rate, - .clk_set_rate = omap2_clk_set_rate, - .clk_set_parent = omap2_clk_set_parent, - .clk_disable_unused = omap2_clk_disable_unused, +const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_hsotgusb_wait = { + .allow_idle = omap2_clkt_iclk_allow_idle, + .deny_idle = omap2_clkt_iclk_deny_idle, + .find_idlest = omap3430es2_clk_hsotgusb_find_idlest, + .find_companion = omap2_clk_dflt_find_companion, }; -/* - * Set clocks for bypass mode for reboot to work. - */ -void omap2_clk_prepare_for_reboot(void) -{ - /* REVISIT: Not ready for 343x */ -#if 0 - u32 rate; - - if (vclk == NULL || sclk == NULL) - return; - - rate = clk_get_rate(sclk); - clk_set_rate(vclk, rate); -#endif -} - -/* REVISIT: Move this init stuff out into clock.c */ - -/* - * Switch the MPU rate if specified on cmdline. - * We cannot do this early until cmdline is parsed. - */ -static int __init omap2_clk_arch_init(void) -{ - if (!mpurate) - return -EINVAL; - - /* REVISIT: not yet ready for 343x */ -#if 0 - if (omap2_select_table_rate(&virt_prcm_set, mpurate)) - printk(KERN_ERR "Could not find matching MPU rate\n"); -#endif - - recalculate_root_clocks(); - - printk(KERN_INFO "Switched to new clocking rate (Crystal/DPLL3/MPU): " - "%ld.%01ld/%ld/%ld MHz\n", - (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10, - (core_ck.rate / 1000000), (dpll1_fck.rate / 1000000)) ; - - return 0; -} -arch_initcall(omap2_clk_arch_init); - -int __init omap2_clk_init(void) -{ - /* struct prcm_config *prcm; */ - struct clk **clkp; - /* u32 clkrate; */ - u32 cpu_clkflg; - - /* REVISIT: Ultimately this will be used for multiboot */ -#if 0 - if (cpu_is_omap242x()) { - cpu_mask = RATE_IN_242X; - cpu_clkflg = CLOCK_IN_OMAP242X; - clkp = onchip_24xx_clks; - } else if (cpu_is_omap2430()) { - cpu_mask = RATE_IN_243X; - cpu_clkflg = CLOCK_IN_OMAP243X; - clkp = onchip_24xx_clks; - } -#endif - if (cpu_is_omap34xx()) { - cpu_mask = RATE_IN_343X; - cpu_clkflg = CLOCK_IN_OMAP343X; - clkp = onchip_34xx_clks; - - /* - * Update this if there are further clock changes between ES2 - * and production parts - */ - if (omap_rev() == OMAP3430_REV_ES1_0) { - /* No 3430ES1-only rates exist, so no RATE_IN_3430ES1 */ - cpu_clkflg |= CLOCK_IN_OMAP3430ES1; - } else { - cpu_mask |= RATE_IN_3430ES2; - cpu_clkflg |= CLOCK_IN_OMAP3430ES2; - } - } - - clk_init(&omap2_clk_functions); - - for (clkp = onchip_34xx_clks; - clkp < onchip_34xx_clks + ARRAY_SIZE(onchip_34xx_clks); - clkp++) { - if ((*clkp)->flags & cpu_clkflg) { - clk_register(*clkp); - omap2_init_clk_clkdm(*clkp); - } - } - - /* REVISIT: Not yet ready for OMAP3 */ -#if 0 - /* Check the MPU rate set by bootloader */ - clkrate = omap2_get_dpll_rate_24xx(&dpll_ck); - for (prcm = rate_table; prcm->mpu_speed; prcm++) { - if (!(prcm->flags & cpu_mask)) - continue; - if (prcm->xtal_speed != sys_ck.rate) - continue; - if (prcm->dpll_speed <= clkrate) - break; - } - curr_prcm_set = prcm; -#endif - - recalculate_root_clocks(); - - printk(KERN_INFO "Clocking rate (Crystal/DPLL/ARM core): " - "%ld.%01ld/%ld/%ld MHz\n", - (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10, - (core_ck.rate / 1000000), (arm_fck.rate / 1000000)); - - /* - * Only enable those clocks we will need, let the drivers - * enable other clocks as necessary - */ - clk_enable_init_clocks(); - - /* Avoid sleeping during omap2_clk_prepare_for_reboot() */ - /* REVISIT: not yet ready for 343x */ -#if 0 - vclk = clk_get(NULL, "virt_prcm_set"); - sclk = clk_get(NULL, "sys_ck"); -#endif - return 0; -} - -#endif +const struct clk_hw_omap_ops clkhwops_omap3430es2_hsotgusb_wait = { + .find_idlest = omap3430es2_clk_hsotgusb_find_idlest, + .find_companion = omap2_clk_dflt_find_companion, +}; diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h index a826094d89b..084ba71b2b3 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h @@ -1,3235 +1,18 @@ /* - * OMAP3 clock framework + * OMAP34xx clock function prototypes and macros * - * Copyright (C) 2007-2008 Texas Instruments, Inc. - * Copyright (C) 2007-2008 Nokia Corporation - * - * Written by Paul Walmsley - * With many device clock fixes by Kevin Hilman and Jouni Högander - * DPLL bypass clock support added by Roman Tereshonkov - * - */ - -/* - * Virtual clocks are introduced as convenient tools. - * They are sources for other clocks and not supposed - * to be requested from drivers directly. + * Copyright (C) 2007-2010 Texas Instruments, Inc. + * Copyright (C) 2007-2011 Nokia Corporation */ #ifndef __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H #define __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H -#include <mach/control.h> - -#include "clock.h" -#include "cm.h" -#include "cm-regbits-34xx.h" -#include "prm.h" -#include "prm-regbits-34xx.h" - -static void omap3_dpll_recalc(struct clk *clk); -static void omap3_clkoutx2_recalc(struct clk *clk); -static void omap3_dpll_allow_idle(struct clk *clk); -static void omap3_dpll_deny_idle(struct clk *clk); -static u32 omap3_dpll_autoidle_read(struct clk *clk); -static int omap3_noncore_dpll_enable(struct clk *clk); -static void omap3_noncore_dpll_disable(struct clk *clk); - -/* Maximum DPLL multiplier, divider values for OMAP3 */ -#define OMAP3_MAX_DPLL_MULT 2048 -#define OMAP3_MAX_DPLL_DIV 128 - -/* - * DPLL1 supplies clock to the MPU. - * DPLL2 supplies clock to the IVA2. - * DPLL3 supplies CORE domain clocks. - * DPLL4 supplies peripheral clocks. - * DPLL5 supplies other peripheral clocks (USBHOST, USIM). - */ - -/* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */ -#define DPLL_LOW_POWER_STOP 0x1 -#define DPLL_LOW_POWER_BYPASS 0x5 -#define DPLL_LOCKED 0x7 - -/* PRM CLOCKS */ - -/* According to timer32k.c, this is a 32768Hz clock, not a 32000Hz clock. */ -static struct clk omap_32k_fck = { - .name = "omap_32k_fck", - .rate = 32768, - .flags = CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES | - ALWAYS_ENABLED, - .recalc = &propagate_rate, -}; - -static struct clk secure_32k_fck = { - .name = "secure_32k_fck", - .rate = 32768, - .flags = CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES | - ALWAYS_ENABLED, - .recalc = &propagate_rate, -}; - -/* Virtual source clocks for osc_sys_ck */ -static struct clk virt_12m_ck = { - .name = "virt_12m_ck", - .rate = 12000000, - .flags = CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES | - ALWAYS_ENABLED, - .recalc = &propagate_rate, -}; - -static struct clk virt_13m_ck = { - .name = "virt_13m_ck", - .rate = 13000000, - .flags = CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES | - ALWAYS_ENABLED, - .recalc = &propagate_rate, -}; - -static struct clk virt_16_8m_ck = { - .name = "virt_16_8m_ck", - .rate = 16800000, - .flags = CLOCK_IN_OMAP3430ES2 | RATE_FIXED | RATE_PROPAGATES | - ALWAYS_ENABLED, - .recalc = &propagate_rate, -}; - -static struct clk virt_19_2m_ck = { - .name = "virt_19_2m_ck", - .rate = 19200000, - .flags = CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES | - ALWAYS_ENABLED, - .recalc = &propagate_rate, -}; - -static struct clk virt_26m_ck = { - .name = "virt_26m_ck", - .rate = 26000000, - .flags = CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES | - ALWAYS_ENABLED, - .recalc = &propagate_rate, -}; - -static struct clk virt_38_4m_ck = { - .name = "virt_38_4m_ck", - .rate = 38400000, - .flags = CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES | - ALWAYS_ENABLED, - .recalc = &propagate_rate, -}; - -static const struct clksel_rate osc_sys_12m_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate osc_sys_13m_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate osc_sys_16_8m_rates[] = { - { .div = 1, .val = 5, .flags = RATE_IN_3430ES2 | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate osc_sys_19_2m_rates[] = { - { .div = 1, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate osc_sys_26m_rates[] = { - { .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate osc_sys_38_4m_rates[] = { - { .div = 1, .val = 4, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel osc_sys_clksel[] = { - { .parent = &virt_12m_ck, .rates = osc_sys_12m_rates }, - { .parent = &virt_13m_ck, .rates = osc_sys_13m_rates }, - { .parent = &virt_16_8m_ck, .rates = osc_sys_16_8m_rates }, - { .parent = &virt_19_2m_ck, .rates = osc_sys_19_2m_rates }, - { .parent = &virt_26m_ck, .rates = osc_sys_26m_rates }, - { .parent = &virt_38_4m_ck, .rates = osc_sys_38_4m_rates }, - { .parent = NULL }, -}; - -/* Oscillator clock */ -/* 12, 13, 16.8, 19.2, 26, or 38.4 MHz */ -static struct clk osc_sys_ck = { - .name = "osc_sys_ck", - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP3430_PRM_CLKSEL, - .clksel_mask = OMAP3430_SYS_CLKIN_SEL_MASK, - .clksel = osc_sys_clksel, - /* REVISIT: deal with autoextclkmode? */ - .flags = CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES | - ALWAYS_ENABLED, - .recalc = &omap2_clksel_recalc, -}; - -static const struct clksel_rate div2_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 2, .val = 2, .flags = RATE_IN_343X }, - { .div = 0 } -}; - -static const struct clksel sys_clksel[] = { - { .parent = &osc_sys_ck, .rates = div2_rates }, - { .parent = NULL } -}; - -/* Latency: this clock is only enabled after PRM_CLKSETUP.SETUP_TIME */ -/* Feeds DPLLs - divided first by PRM_CLKSRC_CTRL.SYSCLKDIV? */ -static struct clk sys_ck = { - .name = "sys_ck", - .parent = &osc_sys_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP3430_PRM_CLKSRC_CTRL, - .clksel_mask = OMAP_SYSCLKDIV_MASK, - .clksel = sys_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .recalc = &omap2_clksel_recalc, -}; - -static struct clk sys_altclk = { - .name = "sys_altclk", - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .recalc = &propagate_rate, -}; - -/* Optional external clock input for some McBSPs */ -static struct clk mcbsp_clks = { - .name = "mcbsp_clks", - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .recalc = &propagate_rate, -}; - -/* PRM EXTERNAL CLOCK OUTPUT */ - -static struct clk sys_clkout1 = { - .name = "sys_clkout1", - .parent = &osc_sys_ck, - .enable_reg = OMAP3430_PRM_CLKOUT_CTRL, - .enable_bit = OMAP3430_CLKOUT_EN_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .recalc = &followparent_recalc, -}; - -/* DPLLS */ - -/* CM CLOCKS */ - -static const struct clksel_rate dpll_bypass_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate dpll_locked_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate div16_dpll_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 2, .val = 2, .flags = RATE_IN_343X }, - { .div = 3, .val = 3, .flags = RATE_IN_343X }, - { .div = 4, .val = 4, .flags = RATE_IN_343X }, - { .div = 5, .val = 5, .flags = RATE_IN_343X }, - { .div = 6, .val = 6, .flags = RATE_IN_343X }, - { .div = 7, .val = 7, .flags = RATE_IN_343X }, - { .div = 8, .val = 8, .flags = RATE_IN_343X }, - { .div = 9, .val = 9, .flags = RATE_IN_343X }, - { .div = 10, .val = 10, .flags = RATE_IN_343X }, - { .div = 11, .val = 11, .flags = RATE_IN_343X }, - { .div = 12, .val = 12, .flags = RATE_IN_343X }, - { .div = 13, .val = 13, .flags = RATE_IN_343X }, - { .div = 14, .val = 14, .flags = RATE_IN_343X }, - { .div = 15, .val = 15, .flags = RATE_IN_343X }, - { .div = 16, .val = 16, .flags = RATE_IN_343X }, - { .div = 0 } -}; - -/* DPLL1 */ -/* MPU clock source */ -/* Type: DPLL */ -static struct dpll_data dpll1_dd = { - .mult_div1_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL), - .mult_mask = OMAP3430_MPU_DPLL_MULT_MASK, - .div1_mask = OMAP3430_MPU_DPLL_DIV_MASK, - .control_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKEN_PLL), - .enable_mask = OMAP3430_EN_MPU_DPLL_MASK, - .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), - .auto_recal_bit = OMAP3430_EN_MPU_DPLL_DRIFTGUARD_SHIFT, - .recal_en_bit = OMAP3430_MPU_DPLL_RECAL_EN_SHIFT, - .recal_st_bit = OMAP3430_MPU_DPLL_ST_SHIFT, - .autoidle_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL), - .autoidle_mask = OMAP3430_AUTO_MPU_DPLL_MASK, - .idlest_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL), - .idlest_bit = OMAP3430_ST_MPU_CLK_SHIFT, - .max_multiplier = OMAP3_MAX_DPLL_MULT, - .max_divider = OMAP3_MAX_DPLL_DIV, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE -}; - -static struct clk dpll1_ck = { - .name = "dpll1_ck", - .parent = &sys_ck, - .dpll_data = &dpll1_dd, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .round_rate = &omap2_dpll_round_rate, - .recalc = &omap3_dpll_recalc, -}; - -/* - * This virtual clock provides the CLKOUTX2 output from the DPLL if the - * DPLL isn't bypassed. - */ -static struct clk dpll1_x2_ck = { - .name = "dpll1_x2_ck", - .parent = &dpll1_ck, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap3_clkoutx2_recalc, -}; - -/* On DPLL1, unlike other DPLLs, the divider is downstream from CLKOUTX2 */ -static const struct clksel div16_dpll1_x2m2_clksel[] = { - { .parent = &dpll1_x2_ck, .rates = div16_dpll_rates }, - { .parent = NULL } -}; - -/* - * Does not exist in the TRM - needed to separate the M2 divider from - * bypass selection in mpu_ck - */ -static struct clk dpll1_x2m2_ck = { - .name = "dpll1_x2m2_ck", - .parent = &dpll1_x2_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL), - .clksel_mask = OMAP3430_MPU_DPLL_CLKOUT_DIV_MASK, - .clksel = div16_dpll1_x2m2_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -/* DPLL2 */ -/* IVA2 clock source */ -/* Type: DPLL */ - -static struct dpll_data dpll2_dd = { - .mult_div1_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL), - .mult_mask = OMAP3430_IVA2_DPLL_MULT_MASK, - .div1_mask = OMAP3430_IVA2_DPLL_DIV_MASK, - .control_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL), - .enable_mask = OMAP3430_EN_IVA2_DPLL_MASK, - .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED) | - (1 << DPLL_LOW_POWER_BYPASS), - .auto_recal_bit = OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_SHIFT, - .recal_en_bit = OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT, - .recal_st_bit = OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT, - .autoidle_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL), - .autoidle_mask = OMAP3430_AUTO_IVA2_DPLL_MASK, - .idlest_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL), - .idlest_bit = OMAP3430_ST_IVA2_CLK_SHIFT, - .max_multiplier = OMAP3_MAX_DPLL_MULT, - .max_divider = OMAP3_MAX_DPLL_DIV, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE -}; - -static struct clk dpll2_ck = { - .name = "dpll2_ck", - .parent = &sys_ck, - .dpll_data = &dpll2_dd, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, - .enable = &omap3_noncore_dpll_enable, - .disable = &omap3_noncore_dpll_disable, - .round_rate = &omap2_dpll_round_rate, - .recalc = &omap3_dpll_recalc, -}; - -static const struct clksel div16_dpll2_m2x2_clksel[] = { - { .parent = &dpll2_ck, .rates = div16_dpll_rates }, - { .parent = NULL } -}; - -/* - * The TRM is conflicted on whether IVA2 clock comes from DPLL2 CLKOUT - * or CLKOUTX2. CLKOUT seems most plausible. - */ -static struct clk dpll2_m2_ck = { - .name = "dpll2_m2_ck", - .parent = &dpll2_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, - OMAP3430_CM_CLKSEL2_PLL), - .clksel_mask = OMAP3430_IVA2_DPLL_CLKOUT_DIV_MASK, - .clksel = div16_dpll2_m2x2_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -/* - * DPLL3 - * Source clock for all interfaces and for some device fclks - * REVISIT: Also supports fast relock bypass - not included below - */ -static struct dpll_data dpll3_dd = { - .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), - .mult_mask = OMAP3430_CORE_DPLL_MULT_MASK, - .div1_mask = OMAP3430_CORE_DPLL_DIV_MASK, - .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), - .enable_mask = OMAP3430_EN_CORE_DPLL_MASK, - .auto_recal_bit = OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT, - .recal_en_bit = OMAP3430_CORE_DPLL_RECAL_EN_SHIFT, - .recal_st_bit = OMAP3430_CORE_DPLL_ST_SHIFT, - .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE), - .autoidle_mask = OMAP3430_AUTO_CORE_DPLL_MASK, - .max_multiplier = OMAP3_MAX_DPLL_MULT, - .max_divider = OMAP3_MAX_DPLL_DIV, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE -}; - -static struct clk dpll3_ck = { - .name = "dpll3_ck", - .parent = &sys_ck, - .dpll_data = &dpll3_dd, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .round_rate = &omap2_dpll_round_rate, - .recalc = &omap3_dpll_recalc, -}; - -/* - * This virtual clock provides the CLKOUTX2 output from the DPLL if the - * DPLL isn't bypassed - */ -static struct clk dpll3_x2_ck = { - .name = "dpll3_x2_ck", - .parent = &dpll3_ck, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap3_clkoutx2_recalc, -}; - -static const struct clksel_rate div31_dpll3_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 2, .val = 2, .flags = RATE_IN_343X }, - { .div = 3, .val = 3, .flags = RATE_IN_3430ES2 }, - { .div = 4, .val = 4, .flags = RATE_IN_3430ES2 }, - { .div = 5, .val = 5, .flags = RATE_IN_3430ES2 }, - { .div = 6, .val = 6, .flags = RATE_IN_3430ES2 }, - { .div = 7, .val = 7, .flags = RATE_IN_3430ES2 }, - { .div = 8, .val = 8, .flags = RATE_IN_3430ES2 }, - { .div = 9, .val = 9, .flags = RATE_IN_3430ES2 }, - { .div = 10, .val = 10, .flags = RATE_IN_3430ES2 }, - { .div = 11, .val = 11, .flags = RATE_IN_3430ES2 }, - { .div = 12, .val = 12, .flags = RATE_IN_3430ES2 }, - { .div = 13, .val = 13, .flags = RATE_IN_3430ES2 }, - { .div = 14, .val = 14, .flags = RATE_IN_3430ES2 }, - { .div = 15, .val = 15, .flags = RATE_IN_3430ES2 }, - { .div = 16, .val = 16, .flags = RATE_IN_3430ES2 }, - { .div = 17, .val = 17, .flags = RATE_IN_3430ES2 }, - { .div = 18, .val = 18, .flags = RATE_IN_3430ES2 }, - { .div = 19, .val = 19, .flags = RATE_IN_3430ES2 }, - { .div = 20, .val = 20, .flags = RATE_IN_3430ES2 }, - { .div = 21, .val = 21, .flags = RATE_IN_3430ES2 }, - { .div = 22, .val = 22, .flags = RATE_IN_3430ES2 }, - { .div = 23, .val = 23, .flags = RATE_IN_3430ES2 }, - { .div = 24, .val = 24, .flags = RATE_IN_3430ES2 }, - { .div = 25, .val = 25, .flags = RATE_IN_3430ES2 }, - { .div = 26, .val = 26, .flags = RATE_IN_3430ES2 }, - { .div = 27, .val = 27, .flags = RATE_IN_3430ES2 }, - { .div = 28, .val = 28, .flags = RATE_IN_3430ES2 }, - { .div = 29, .val = 29, .flags = RATE_IN_3430ES2 }, - { .div = 30, .val = 30, .flags = RATE_IN_3430ES2 }, - { .div = 31, .val = 31, .flags = RATE_IN_3430ES2 }, - { .div = 0 }, -}; - -static const struct clksel div31_dpll3m2_clksel[] = { - { .parent = &dpll3_ck, .rates = div31_dpll3_rates }, - { .parent = NULL } -}; - -/* - * DPLL3 output M2 - * REVISIT: This DPLL output divider must be changed in SRAM, so until - * that code is ready, this should remain a 'read-only' clksel clock. - */ -static struct clk dpll3_m2_ck = { - .name = "dpll3_m2_ck", - .parent = &dpll3_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), - .clksel_mask = OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK, - .clksel = div31_dpll3m2_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -static const struct clksel core_ck_clksel[] = { - { .parent = &sys_ck, .rates = dpll_bypass_rates }, - { .parent = &dpll3_m2_ck, .rates = dpll_locked_rates }, - { .parent = NULL } -}; - -static struct clk core_ck = { - .name = "core_ck", - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_CORE_CLK_MASK, - .clksel = core_ck_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -static const struct clksel dpll3_m2x2_ck_clksel[] = { - { .parent = &sys_ck, .rates = dpll_bypass_rates }, - { .parent = &dpll3_x2_ck, .rates = dpll_locked_rates }, - { .parent = NULL } -}; - -static struct clk dpll3_m2x2_ck = { - .name = "dpll3_m2x2_ck", - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_CORE_CLK_MASK, - .clksel = dpll3_m2x2_ck_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -/* The PWRDN bit is apparently only available on 3430ES2 and above */ -static const struct clksel div16_dpll3_clksel[] = { - { .parent = &dpll3_ck, .rates = div16_dpll_rates }, - { .parent = NULL } -}; - -/* This virtual clock is the source for dpll3_m3x2_ck */ -static struct clk dpll3_m3_ck = { - .name = "dpll3_m3_ck", - .parent = &dpll3_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), - .clksel_mask = OMAP3430_DIV_DPLL3_MASK, - .clksel = div16_dpll3_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -/* The PWRDN bit is apparently only available on 3430ES2 and above */ -static struct clk dpll3_m3x2_ck = { - .name = "dpll3_m3x2_ck", - .parent = &dpll3_m3_ck, - .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), - .enable_bit = OMAP3430_PWRDN_EMU_CORE_SHIFT, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | INVERT_ENABLE, - .recalc = &omap3_clkoutx2_recalc, -}; - -static const struct clksel emu_core_alwon_ck_clksel[] = { - { .parent = &sys_ck, .rates = dpll_bypass_rates }, - { .parent = &dpll3_m3x2_ck, .rates = dpll_locked_rates }, - { .parent = NULL } -}; - -static struct clk emu_core_alwon_ck = { - .name = "emu_core_alwon_ck", - .parent = &dpll3_m3x2_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_CORE_CLK_MASK, - .clksel = emu_core_alwon_ck_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -/* DPLL4 */ -/* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */ -/* Type: DPLL */ -static struct dpll_data dpll4_dd = { - .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2), - .mult_mask = OMAP3430_PERIPH_DPLL_MULT_MASK, - .div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK, - .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), - .enable_mask = OMAP3430_EN_PERIPH_DPLL_MASK, - .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), - .auto_recal_bit = OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT, - .recal_en_bit = OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT, - .recal_st_bit = OMAP3430_PERIPH_DPLL_ST_SHIFT, - .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE), - .autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK, - .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .idlest_bit = OMAP3430_ST_PERIPH_CLK_SHIFT, - .max_multiplier = OMAP3_MAX_DPLL_MULT, - .max_divider = OMAP3_MAX_DPLL_DIV, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE -}; - -static struct clk dpll4_ck = { - .name = "dpll4_ck", - .parent = &sys_ck, - .dpll_data = &dpll4_dd, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, - .enable = &omap3_noncore_dpll_enable, - .disable = &omap3_noncore_dpll_disable, - .round_rate = &omap2_dpll_round_rate, - .recalc = &omap3_dpll_recalc, -}; - -/* - * This virtual clock provides the CLKOUTX2 output from the DPLL if the - * DPLL isn't bypassed -- - * XXX does this serve any downstream clocks? - */ -static struct clk dpll4_x2_ck = { - .name = "dpll4_x2_ck", - .parent = &dpll4_ck, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap3_clkoutx2_recalc, -}; - -static const struct clksel div16_dpll4_clksel[] = { - { .parent = &dpll4_ck, .rates = div16_dpll_rates }, - { .parent = NULL } -}; - -/* This virtual clock is the source for dpll4_m2x2_ck */ -static struct clk dpll4_m2_ck = { - .name = "dpll4_m2_ck", - .parent = &dpll4_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430_CM_CLKSEL3), - .clksel_mask = OMAP3430_DIV_96M_MASK, - .clksel = div16_dpll4_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -/* The PWRDN bit is apparently only available on 3430ES2 and above */ -static struct clk dpll4_m2x2_ck = { - .name = "dpll4_m2x2_ck", - .parent = &dpll4_m2_ck, - .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), - .enable_bit = OMAP3430_PWRDN_96M_SHIFT, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | INVERT_ENABLE, - .recalc = &omap3_clkoutx2_recalc, -}; - -static const struct clksel omap_96m_alwon_fck_clksel[] = { - { .parent = &sys_ck, .rates = dpll_bypass_rates }, - { .parent = &dpll4_m2x2_ck, .rates = dpll_locked_rates }, - { .parent = NULL } -}; - -static struct clk omap_96m_alwon_fck = { - .name = "omap_96m_alwon_fck", - .parent = &dpll4_m2x2_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, - .clksel = omap_96m_alwon_fck_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -static struct clk omap_96m_fck = { - .name = "omap_96m_fck", - .parent = &omap_96m_alwon_fck, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &followparent_recalc, -}; - -static const struct clksel cm_96m_fck_clksel[] = { - { .parent = &sys_ck, .rates = dpll_bypass_rates }, - { .parent = &dpll4_m2x2_ck, .rates = dpll_locked_rates }, - { .parent = NULL } -}; - -static struct clk cm_96m_fck = { - .name = "cm_96m_fck", - .parent = &dpll4_m2x2_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, - .clksel = cm_96m_fck_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -/* This virtual clock is the source for dpll4_m3x2_ck */ -static struct clk dpll4_m3_ck = { - .name = "dpll4_m3_ck", - .parent = &dpll4_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_TV_MASK, - .clksel = div16_dpll4_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -/* The PWRDN bit is apparently only available on 3430ES2 and above */ -static struct clk dpll4_m3x2_ck = { - .name = "dpll4_m3x2_ck", - .parent = &dpll4_m3_ck, - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), - .enable_bit = OMAP3430_PWRDN_TV_SHIFT, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | INVERT_ENABLE, - .recalc = &omap3_clkoutx2_recalc, -}; - -static const struct clksel virt_omap_54m_fck_clksel[] = { - { .parent = &sys_ck, .rates = dpll_bypass_rates }, - { .parent = &dpll4_m3x2_ck, .rates = dpll_locked_rates }, - { .parent = NULL } -}; - -static struct clk virt_omap_54m_fck = { - .name = "virt_omap_54m_fck", - .parent = &dpll4_m3x2_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, - .clksel = virt_omap_54m_fck_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -static const struct clksel_rate omap_54m_d4m3x2_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate omap_54m_alt_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel omap_54m_clksel[] = { - { .parent = &virt_omap_54m_fck, .rates = omap_54m_d4m3x2_rates }, - { .parent = &sys_altclk, .rates = omap_54m_alt_rates }, - { .parent = NULL } -}; - -static struct clk omap_54m_fck = { - .name = "omap_54m_fck", - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), - .clksel_mask = OMAP3430_SOURCE_54M, - .clksel = omap_54m_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -static const struct clksel_rate omap_48m_96md2_rates[] = { - { .div = 2, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate omap_48m_alt_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel omap_48m_clksel[] = { - { .parent = &cm_96m_fck, .rates = omap_48m_96md2_rates }, - { .parent = &sys_altclk, .rates = omap_48m_alt_rates }, - { .parent = NULL } -}; - -static struct clk omap_48m_fck = { - .name = "omap_48m_fck", - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), - .clksel_mask = OMAP3430_SOURCE_48M, - .clksel = omap_48m_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -static struct clk omap_12m_fck = { - .name = "omap_12m_fck", - .parent = &omap_48m_fck, - .fixed_div = 4, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_fixed_divisor_recalc, -}; - -/* This virstual clock is the source for dpll4_m4x2_ck */ -static struct clk dpll4_m4_ck = { - .name = "dpll4_m4_ck", - .parent = &dpll4_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_DSS1_MASK, - .clksel = div16_dpll4_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -/* The PWRDN bit is apparently only available on 3430ES2 and above */ -static struct clk dpll4_m4x2_ck = { - .name = "dpll4_m4x2_ck", - .parent = &dpll4_m4_ck, - .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), - .enable_bit = OMAP3430_PWRDN_CAM_SHIFT, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | INVERT_ENABLE, - .recalc = &omap3_clkoutx2_recalc, -}; - -/* This virtual clock is the source for dpll4_m5x2_ck */ -static struct clk dpll4_m5_ck = { - .name = "dpll4_m5_ck", - .parent = &dpll4_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_CAM_MASK, - .clksel = div16_dpll4_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -/* The PWRDN bit is apparently only available on 3430ES2 and above */ -static struct clk dpll4_m5x2_ck = { - .name = "dpll4_m5x2_ck", - .parent = &dpll4_m5_ck, - .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), - .enable_bit = OMAP3430_PWRDN_CAM_SHIFT, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | INVERT_ENABLE, - .recalc = &omap3_clkoutx2_recalc, -}; - -/* This virtual clock is the source for dpll4_m6x2_ck */ -static struct clk dpll4_m6_ck = { - .name = "dpll4_m6_ck", - .parent = &dpll4_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), - .clksel_mask = OMAP3430_DIV_DPLL4_MASK, - .clksel = div16_dpll4_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -/* The PWRDN bit is apparently only available on 3430ES2 and above */ -static struct clk dpll4_m6x2_ck = { - .name = "dpll4_m6x2_ck", - .parent = &dpll4_m6_ck, - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), - .enable_bit = OMAP3430_PWRDN_EMU_PERIPH_SHIFT, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | INVERT_ENABLE, - .recalc = &omap3_clkoutx2_recalc, -}; - -static struct clk emu_per_alwon_ck = { - .name = "emu_per_alwon_ck", - .parent = &dpll4_m6x2_ck, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &followparent_recalc, -}; - -/* DPLL5 */ -/* Supplies 120MHz clock, USIM source clock */ -/* Type: DPLL */ -/* 3430ES2 only */ -static struct dpll_data dpll5_dd = { - .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL4), - .mult_mask = OMAP3430ES2_PERIPH2_DPLL_MULT_MASK, - .div1_mask = OMAP3430ES2_PERIPH2_DPLL_DIV_MASK, - .control_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKEN2), - .enable_mask = OMAP3430ES2_EN_PERIPH2_DPLL_MASK, - .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), - .auto_recal_bit = OMAP3430ES2_EN_PERIPH2_DPLL_DRIFTGUARD_SHIFT, - .recal_en_bit = OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT, - .recal_st_bit = OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT, - .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_AUTOIDLE2_PLL), - .autoidle_mask = OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK, - .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2), - .idlest_bit = OMAP3430ES2_ST_PERIPH2_CLK_SHIFT, - .max_multiplier = OMAP3_MAX_DPLL_MULT, - .max_divider = OMAP3_MAX_DPLL_DIV, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE -}; - -static struct clk dpll5_ck = { - .name = "dpll5_ck", - .parent = &sys_ck, - .dpll_data = &dpll5_dd, - .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES, - .enable = &omap3_noncore_dpll_enable, - .disable = &omap3_noncore_dpll_disable, - .round_rate = &omap2_dpll_round_rate, - .recalc = &omap3_dpll_recalc, -}; - -static const struct clksel div16_dpll5_clksel[] = { - { .parent = &dpll5_ck, .rates = div16_dpll_rates }, - { .parent = NULL } -}; - -static struct clk dpll5_m2_ck = { - .name = "dpll5_m2_ck", - .parent = &dpll5_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL5), - .clksel_mask = OMAP3430ES2_DIV_120M_MASK, - .clksel = div16_dpll5_clksel, - .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -static const struct clksel omap_120m_fck_clksel[] = { - { .parent = &sys_ck, .rates = dpll_bypass_rates }, - { .parent = &dpll5_m2_ck, .rates = dpll_locked_rates }, - { .parent = NULL } -}; - -static struct clk omap_120m_fck = { - .name = "omap_120m_fck", - .parent = &dpll5_m2_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2), - .clksel_mask = OMAP3430ES2_ST_PERIPH2_CLK_MASK, - .clksel = omap_120m_fck_clksel, - .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -/* CM EXTERNAL CLOCK OUTPUTS */ - -static const struct clksel_rate clkout2_src_core_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate clkout2_src_sys_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate clkout2_src_96m_rates[] = { - { .div = 1, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate clkout2_src_54m_rates[] = { - { .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel clkout2_src_clksel[] = { - { .parent = &core_ck, .rates = clkout2_src_core_rates }, - { .parent = &sys_ck, .rates = clkout2_src_sys_rates }, - { .parent = &omap_96m_alwon_fck, .rates = clkout2_src_96m_rates }, - { .parent = &omap_54m_fck, .rates = clkout2_src_54m_rates }, - { .parent = NULL } -}; - -static struct clk clkout2_src_ck = { - .name = "clkout2_src_ck", - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP3430_CM_CLKOUT_CTRL, - .enable_bit = OMAP3430_CLKOUT2_EN_SHIFT, - .clksel_reg = OMAP3430_CM_CLKOUT_CTRL, - .clksel_mask = OMAP3430_CLKOUT2SOURCE_MASK, - .clksel = clkout2_src_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, - .recalc = &omap2_clksel_recalc, -}; - -static const struct clksel_rate sys_clkout2_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 2, .val = 1, .flags = RATE_IN_343X }, - { .div = 4, .val = 2, .flags = RATE_IN_343X }, - { .div = 8, .val = 3, .flags = RATE_IN_343X }, - { .div = 16, .val = 4, .flags = RATE_IN_343X }, - { .div = 0 }, -}; - -static const struct clksel sys_clkout2_clksel[] = { - { .parent = &clkout2_src_ck, .rates = sys_clkout2_rates }, - { .parent = NULL }, -}; - -static struct clk sys_clkout2 = { - .name = "sys_clkout2", - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP3430_CM_CLKOUT_CTRL, - .clksel_mask = OMAP3430_CLKOUT2_DIV_MASK, - .clksel = sys_clkout2_clksel, - .flags = CLOCK_IN_OMAP343X | PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -/* CM OUTPUT CLOCKS */ - -static struct clk corex2_fck = { - .name = "corex2_fck", - .parent = &dpll3_m2x2_ck, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &followparent_recalc, -}; - -/* DPLL power domain clock controls */ - -static const struct clksel div2_core_clksel[] = { - { .parent = &core_ck, .rates = div2_rates }, - { .parent = NULL } -}; - -/* - * REVISIT: Are these in DPLL power domain or CM power domain? docs - * may be inconsistent here? - */ -static struct clk dpll1_fck = { - .name = "dpll1_fck", - .parent = &core_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL), - .clksel_mask = OMAP3430_MPU_CLK_SRC_MASK, - .clksel = div2_core_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -/* - * MPU clksel: - * If DPLL1 is locked, mpu_ck derives from DPLL1; otherwise, mpu_ck - * derives from the high-frequency bypass clock originating from DPLL3, - * called 'dpll1_fck' - */ -static const struct clksel mpu_clksel[] = { - { .parent = &dpll1_fck, .rates = dpll_bypass_rates }, - { .parent = &dpll1_x2m2_ck, .rates = dpll_locked_rates }, - { .parent = NULL } -}; - -static struct clk mpu_ck = { - .name = "mpu_ck", - .parent = &dpll1_x2m2_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL), - .clksel_mask = OMAP3430_ST_MPU_CLK_MASK, - .clksel = mpu_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .clkdm_name = "mpu_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -/* arm_fck is divided by two when DPLL1 locked; otherwise, passthrough mpu_ck */ -static const struct clksel_rate arm_fck_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 2, .val = 1, .flags = RATE_IN_343X }, - { .div = 0 }, -}; - -static const struct clksel arm_fck_clksel[] = { - { .parent = &mpu_ck, .rates = arm_fck_rates }, - { .parent = NULL } -}; - -static struct clk arm_fck = { - .name = "arm_fck", - .parent = &mpu_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL), - .clksel_mask = OMAP3430_ST_MPU_CLK_MASK, - .clksel = arm_fck_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -/* XXX What about neon_clkdm ? */ - -/* - * REVISIT: This clock is never specifically defined in the 3430 TRM, - * although it is referenced - so this is a guess - */ -static struct clk emu_mpu_alwon_ck = { - .name = "emu_mpu_alwon_ck", - .parent = &mpu_ck, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &followparent_recalc, -}; - -static struct clk dpll2_fck = { - .name = "dpll2_fck", - .parent = &core_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL), - .clksel_mask = OMAP3430_IVA2_CLK_SRC_MASK, - .clksel = div2_core_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -/* - * IVA2 clksel: - * If DPLL2 is locked, iva2_ck derives from DPLL2; otherwise, iva2_ck - * derives from the high-frequency bypass clock originating from DPLL3, - * called 'dpll2_fck' - */ - -static const struct clksel iva2_clksel[] = { - { .parent = &dpll2_fck, .rates = dpll_bypass_rates }, - { .parent = &dpll2_m2_ck, .rates = dpll_locked_rates }, - { .parent = NULL } -}; - -static struct clk iva2_ck = { - .name = "iva2_ck", - .parent = &dpll2_m2_ck, - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, - OMAP3430_CM_IDLEST_PLL), - .clksel_mask = OMAP3430_ST_IVA2_CLK_MASK, - .clksel = iva2_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, - .clkdm_name = "iva2_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -/* Common interface clocks */ - -static struct clk l3_ick = { - .name = "l3_ick", - .parent = &core_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_L3_MASK, - .clksel = div2_core_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .clkdm_name = "core_l3_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static const struct clksel div2_l3_clksel[] = { - { .parent = &l3_ick, .rates = div2_rates }, - { .parent = NULL } -}; - -static struct clk l4_ick = { - .name = "l4_ick", - .parent = &l3_ick, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_L4_MASK, - .clksel = div2_l3_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .clkdm_name = "core_l4_clkdm", - .recalc = &omap2_clksel_recalc, - -}; - -static const struct clksel div2_l4_clksel[] = { - { .parent = &l4_ick, .rates = div2_rates }, - { .parent = NULL } -}; - -static struct clk rm_ick = { - .name = "rm_ick", - .parent = &l4_ick, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_RM_MASK, - .clksel = div2_l4_clksel, - .flags = CLOCK_IN_OMAP343X | PARENT_CONTROLS_CLOCK, - .recalc = &omap2_clksel_recalc, -}; - -/* GFX power domain */ - -/* GFX clocks are in 3430ES1 only. 3430ES2 and later uses the SGX instead */ - -static const struct clksel gfx_l3_clksel[] = { - { .parent = &l3_ick, .rates = gfx_l3_rates }, - { .parent = NULL } -}; - -/* Virtual parent clock for gfx_l3_ick and gfx_l3_fck */ -static struct clk gfx_l3_ck = { - .name = "gfx_l3_ck", - .parent = &l3_ick, - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN), - .enable_bit = OMAP_EN_GFX_SHIFT, - .flags = CLOCK_IN_OMAP3430ES1, - .recalc = &followparent_recalc, -}; - -static struct clk gfx_l3_fck = { - .name = "gfx_l3_fck", - .parent = &gfx_l3_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL), - .clksel_mask = OMAP_CLKSEL_GFX_MASK, - .clksel = gfx_l3_clksel, - .flags = CLOCK_IN_OMAP3430ES1 | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .clkdm_name = "gfx_3430es1_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gfx_l3_ick = { - .name = "gfx_l3_ick", - .parent = &gfx_l3_ck, - .flags = CLOCK_IN_OMAP3430ES1 | PARENT_CONTROLS_CLOCK, - .clkdm_name = "gfx_3430es1_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gfx_cg1_ck = { - .name = "gfx_cg1_ck", - .parent = &gfx_l3_fck, /* REVISIT: correct? */ - .init = &omap2_init_clk_clkdm, - .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), - .enable_bit = OMAP3430ES1_EN_2D_SHIFT, - .flags = CLOCK_IN_OMAP3430ES1, - .clkdm_name = "gfx_3430es1_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gfx_cg2_ck = { - .name = "gfx_cg2_ck", - .parent = &gfx_l3_fck, /* REVISIT: correct? */ - .init = &omap2_init_clk_clkdm, - .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), - .enable_bit = OMAP3430ES1_EN_3D_SHIFT, - .flags = CLOCK_IN_OMAP3430ES1, - .clkdm_name = "gfx_3430es1_clkdm", - .recalc = &followparent_recalc, -}; - -/* SGX power domain - 3430ES2 only */ - -static const struct clksel_rate sgx_core_rates[] = { - { .div = 3, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 4, .val = 1, .flags = RATE_IN_343X }, - { .div = 6, .val = 2, .flags = RATE_IN_343X }, - { .div = 0 }, -}; - -static const struct clksel_rate sgx_96m_rates[] = { - { .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 }, -}; - -static const struct clksel sgx_clksel[] = { - { .parent = &core_ck, .rates = sgx_core_rates }, - { .parent = &cm_96m_fck, .rates = sgx_96m_rates }, - { .parent = NULL }, -}; - -static struct clk sgx_fck = { - .name = "sgx_fck", - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_FCLKEN), - .enable_bit = OMAP3430ES2_EN_SGX_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430ES2_CLKSEL_SGX_MASK, - .clksel = sgx_clksel, - .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "sgx_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk sgx_ick = { - .name = "sgx_ick", - .parent = &l3_ick, - .init = &omap2_init_clk_clkdm, - .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN), - .enable_bit = OMAP3430ES2_EN_SGX_SHIFT, - .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "sgx_clkdm", - .recalc = &followparent_recalc, -}; - -/* CORE power domain */ - -static struct clk d2d_26m_fck = { - .name = "d2d_26m_fck", - .parent = &sys_ck, - .init = &omap2_init_clk_clkdm, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430ES1_EN_D2D_SHIFT, - .flags = CLOCK_IN_OMAP3430ES1, - .clkdm_name = "d2d_clkdm", - .recalc = &followparent_recalc, -}; - -static const struct clksel omap343x_gpt_clksel[] = { - { .parent = &omap_32k_fck, .rates = gpt_32k_rates }, - { .parent = &sys_ck, .rates = gpt_sys_rates }, - { .parent = NULL} -}; - -static struct clk gpt10_fck = { - .name = "gpt10_fck", - .parent = &sys_ck, - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_GPT10_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_GPT10_MASK, - .clksel = omap343x_gpt_clksel, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gpt11_fck = { - .name = "gpt11_fck", - .parent = &sys_ck, - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_GPT11_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_GPT11_MASK, - .clksel = omap343x_gpt_clksel, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk cpefuse_fck = { - .name = "cpefuse_fck", - .parent = &sys_ck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3), - .enable_bit = OMAP3430ES2_EN_CPEFUSE_SHIFT, - .flags = CLOCK_IN_OMAP3430ES2, - .recalc = &followparent_recalc, -}; - -static struct clk ts_fck = { - .name = "ts_fck", - .parent = &omap_32k_fck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3), - .enable_bit = OMAP3430ES2_EN_TS_SHIFT, - .flags = CLOCK_IN_OMAP3430ES2, - .recalc = &followparent_recalc, -}; - -static struct clk usbtll_fck = { - .name = "usbtll_fck", - .parent = &omap_120m_fck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3), - .enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT, - .flags = CLOCK_IN_OMAP3430ES2, - .recalc = &followparent_recalc, -}; - -/* CORE 96M FCLK-derived clocks */ - -static struct clk core_96m_fck = { - .name = "core_96m_fck", - .parent = &omap_96m_fck, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mmchs3_fck = { - .name = "mmchs_fck", - .id = 2, - .parent = &core_96m_fck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT, - .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mmchs2_fck = { - .name = "mmchs_fck", - .id = 1, - .parent = &core_96m_fck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_MMC2_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mspro_fck = { - .name = "mspro_fck", - .parent = &core_96m_fck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_MSPRO_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mmchs1_fck = { - .name = "mmchs_fck", - .parent = &core_96m_fck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_MMC1_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk i2c3_fck = { - .name = "i2c_fck", - .id = 3, - .parent = &core_96m_fck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_I2C3_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk i2c2_fck = { - .name = "i2c_fck", - .id = 2, - .parent = &core_96m_fck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_I2C2_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk i2c1_fck = { - .name = "i2c_fck", - .id = 1, - .parent = &core_96m_fck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_I2C1_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -/* - * MCBSP 1 & 5 get their 96MHz clock from core_96m_fck; - * MCBSP 2, 3, 4 get their 96MHz clock from per_96m_fck. - */ -static const struct clksel_rate common_mcbsp_96m_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel_rate common_mcbsp_mcbsp_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 } -}; - -static const struct clksel mcbsp_15_clksel[] = { - { .parent = &core_96m_fck, .rates = common_mcbsp_96m_rates }, - { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates }, - { .parent = NULL } -}; - -static struct clk mcbsp5_fck = { - .name = "mcbsp_fck", - .id = 5, - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_MCBSP5_SHIFT, - .clksel_reg = OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1), - .clksel_mask = OMAP2_MCBSP5_CLKS_MASK, - .clksel = mcbsp_15_clksel, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk mcbsp1_fck = { - .name = "mcbsp_fck", - .id = 1, - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_MCBSP1_SHIFT, - .clksel_reg = OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0), - .clksel_mask = OMAP2_MCBSP1_CLKS_MASK, - .clksel = mcbsp_15_clksel, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -/* CORE_48M_FCK-derived clocks */ - -static struct clk core_48m_fck = { - .name = "core_48m_fck", - .parent = &omap_48m_fck, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mcspi4_fck = { - .name = "mcspi_fck", - .id = 4, - .parent = &core_48m_fck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_MCSPI4_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .recalc = &followparent_recalc, -}; - -static struct clk mcspi3_fck = { - .name = "mcspi_fck", - .id = 3, - .parent = &core_48m_fck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_MCSPI3_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .recalc = &followparent_recalc, -}; - -static struct clk mcspi2_fck = { - .name = "mcspi_fck", - .id = 2, - .parent = &core_48m_fck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_MCSPI2_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .recalc = &followparent_recalc, -}; - -static struct clk mcspi1_fck = { - .name = "mcspi_fck", - .id = 1, - .parent = &core_48m_fck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_MCSPI1_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .recalc = &followparent_recalc, -}; - -static struct clk uart2_fck = { - .name = "uart2_fck", - .parent = &core_48m_fck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_UART2_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .recalc = &followparent_recalc, -}; - -static struct clk uart1_fck = { - .name = "uart1_fck", - .parent = &core_48m_fck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_UART1_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .recalc = &followparent_recalc, -}; - -static struct clk fshostusb_fck = { - .name = "fshostusb_fck", - .parent = &core_48m_fck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430ES1_EN_FSHOSTUSB_SHIFT, - .flags = CLOCK_IN_OMAP3430ES1, - .recalc = &followparent_recalc, -}; - -/* CORE_12M_FCK based clocks */ - -static struct clk core_12m_fck = { - .name = "core_12m_fck", - .parent = &omap_12m_fck, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk hdq_fck = { - .name = "hdq_fck", - .parent = &core_12m_fck, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_HDQ_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .recalc = &followparent_recalc, -}; - -/* DPLL3-derived clock */ - -static const struct clksel_rate ssi_ssr_corex2_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 2, .val = 2, .flags = RATE_IN_343X }, - { .div = 3, .val = 3, .flags = RATE_IN_343X }, - { .div = 4, .val = 4, .flags = RATE_IN_343X }, - { .div = 6, .val = 6, .flags = RATE_IN_343X }, - { .div = 8, .val = 8, .flags = RATE_IN_343X }, - { .div = 0 } -}; - -static const struct clksel ssi_ssr_clksel[] = { - { .parent = &corex2_fck, .rates = ssi_ssr_corex2_rates }, - { .parent = NULL } -}; - -static struct clk ssi_ssr_fck = { - .name = "ssi_ssr_fck", - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), - .enable_bit = OMAP3430_EN_SSI_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_SSI_MASK, - .clksel = ssi_ssr_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, - .clkdm_name = "core_l4_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk ssi_sst_fck = { - .name = "ssi_sst_fck", - .parent = &ssi_ssr_fck, - .fixed_div = 2, - .flags = CLOCK_IN_OMAP343X | PARENT_CONTROLS_CLOCK, - .recalc = &omap2_fixed_divisor_recalc, -}; - - - -/* CORE_L3_ICK based clocks */ - -/* - * XXX must add clk_enable/clk_disable for these if standard code won't - * handle it - */ -static struct clk core_l3_ick = { - .name = "core_l3_ick", - .parent = &l3_ick, - .init = &omap2_init_clk_clkdm, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .clkdm_name = "core_l3_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk hsotgusb_ick = { - .name = "hsotgusb_ick", - .parent = &core_l3_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_HSOTGUSB_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l3_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk sdrc_ick = { - .name = "sdrc_ick", - .parent = &core_l3_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_SDRC_SHIFT, - .flags = CLOCK_IN_OMAP343X | ENABLE_ON_INIT, - .clkdm_name = "core_l3_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpmc_fck = { - .name = "gpmc_fck", - .parent = &core_l3_ick, - .flags = CLOCK_IN_OMAP343X | PARENT_CONTROLS_CLOCK | - ENABLE_ON_INIT, - .clkdm_name = "core_l3_clkdm", - .recalc = &followparent_recalc, -}; - -/* SECURITY_L3_ICK based clocks */ - -static struct clk security_l3_ick = { - .name = "security_l3_ick", - .parent = &l3_ick, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &followparent_recalc, -}; - -static struct clk pka_ick = { - .name = "pka_ick", - .parent = &security_l3_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), - .enable_bit = OMAP3430_EN_PKA_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .recalc = &followparent_recalc, -}; - -/* CORE_L4_ICK based clocks */ - -static struct clk core_l4_ick = { - .name = "core_l4_ick", - .parent = &l4_ick, - .init = &omap2_init_clk_clkdm, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk usbtll_ick = { - .name = "usbtll_ick", - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), - .enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT, - .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mmchs3_ick = { - .name = "mmchs_ick", - .id = 2, - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT, - .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -/* Intersystem Communication Registers - chassis mode only */ -static struct clk icr_ick = { - .name = "icr_ick", - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_ICR_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk aes2_ick = { - .name = "aes2_ick", - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_AES2_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk sha12_ick = { - .name = "sha12_ick", - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_SHA12_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk des2_ick = { - .name = "des2_ick", - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_DES2_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mmchs2_ick = { - .name = "mmchs_ick", - .id = 1, - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_MMC2_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mmchs1_ick = { - .name = "mmchs_ick", - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_MMC1_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mspro_ick = { - .name = "mspro_ick", - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_MSPRO_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk hdq_ick = { - .name = "hdq_ick", - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_HDQ_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mcspi4_ick = { - .name = "mcspi_ick", - .id = 4, - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_MCSPI4_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mcspi3_ick = { - .name = "mcspi_ick", - .id = 3, - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_MCSPI3_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mcspi2_ick = { - .name = "mcspi_ick", - .id = 2, - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_MCSPI2_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mcspi1_ick = { - .name = "mcspi_ick", - .id = 1, - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_MCSPI1_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk i2c3_ick = { - .name = "i2c_ick", - .id = 3, - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_I2C3_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk i2c2_ick = { - .name = "i2c_ick", - .id = 2, - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_I2C2_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk i2c1_ick = { - .name = "i2c_ick", - .id = 1, - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_I2C1_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk uart2_ick = { - .name = "uart2_ick", - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_UART2_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk uart1_ick = { - .name = "uart1_ick", - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_UART1_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpt11_ick = { - .name = "gpt11_ick", - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_GPT11_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpt10_ick = { - .name = "gpt10_ick", - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_GPT10_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mcbsp5_ick = { - .name = "mcbsp_ick", - .id = 5, - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_MCBSP5_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mcbsp1_ick = { - .name = "mcbsp_ick", - .id = 1, - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_MCBSP1_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk fac_ick = { - .name = "fac_ick", - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430ES1_EN_FAC_SHIFT, - .flags = CLOCK_IN_OMAP3430ES1, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mailboxes_ick = { - .name = "mailboxes_ick", - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_MAILBOXES_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk omapctrl_ick = { - .name = "omapctrl_ick", - .parent = &core_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_OMAPCTRL_SHIFT, - .flags = CLOCK_IN_OMAP343X | ENABLE_ON_INIT, - .recalc = &followparent_recalc, -}; - -/* SSI_L4_ICK based clocks */ - -static struct clk ssi_l4_ick = { - .name = "ssi_l4_ick", - .parent = &l4_ick, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk ssi_ick = { - .name = "ssi_ick", - .parent = &ssi_l4_ick, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430_EN_SSI_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -/* REVISIT: Technically the TRM claims that this is CORE_CLK based, - * but l4_ick makes more sense to me */ - -static const struct clksel usb_l4_clksel[] = { - { .parent = &l4_ick, .rates = div2_rates }, - { .parent = NULL }, -}; - -static struct clk usb_l4_ick = { - .name = "usb_l4_ick", - .parent = &l4_ick, - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), - .enable_bit = OMAP3430ES1_EN_FSHOSTUSB_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK, - .clksel = usb_l4_clksel, - .flags = CLOCK_IN_OMAP3430ES1, - .recalc = &omap2_clksel_recalc, -}; - -/* XXX MDM_INTC_ICK, SAD2D_ICK ?? */ - -/* SECURITY_L4_ICK2 based clocks */ - -static struct clk security_l4_ick2 = { - .name = "security_l4_ick2", - .parent = &l4_ick, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .recalc = &followparent_recalc, -}; - -static struct clk aes1_ick = { - .name = "aes1_ick", - .parent = &security_l4_ick2, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), - .enable_bit = OMAP3430_EN_AES1_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .recalc = &followparent_recalc, -}; - -static struct clk rng_ick = { - .name = "rng_ick", - .parent = &security_l4_ick2, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), - .enable_bit = OMAP3430_EN_RNG_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .recalc = &followparent_recalc, -}; - -static struct clk sha11_ick = { - .name = "sha11_ick", - .parent = &security_l4_ick2, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), - .enable_bit = OMAP3430_EN_SHA11_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .recalc = &followparent_recalc, -}; - -static struct clk des1_ick = { - .name = "des1_ick", - .parent = &security_l4_ick2, - .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), - .enable_bit = OMAP3430_EN_DES1_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .recalc = &followparent_recalc, -}; - -/* DSS */ -static const struct clksel dss1_alwon_fck_clksel[] = { - { .parent = &sys_ck, .rates = dpll_bypass_rates }, - { .parent = &dpll4_m4x2_ck, .rates = dpll_locked_rates }, - { .parent = NULL } -}; - -static struct clk dss1_alwon_fck = { - .name = "dss1_alwon_fck", - .parent = &dpll4_m4x2_ck, - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_DSS1_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, - .clksel = dss1_alwon_fck_clksel, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "dss_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk dss_tv_fck = { - .name = "dss_tv_fck", - .parent = &omap_54m_fck, - .init = &omap2_init_clk_clkdm, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_TV_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "dss_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk dss_96m_fck = { - .name = "dss_96m_fck", - .parent = &omap_96m_fck, - .init = &omap2_init_clk_clkdm, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_TV_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "dss_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk dss2_alwon_fck = { - .name = "dss2_alwon_fck", - .parent = &sys_ck, - .init = &omap2_init_clk_clkdm, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_DSS2_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "dss_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk dss_ick = { - /* Handles both L3 and L4 clocks */ - .name = "dss_ick", - .parent = &l4_ick, - .init = &omap2_init_clk_clkdm, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "dss_clkdm", - .recalc = &followparent_recalc, -}; - -/* CAM */ - -static const struct clksel cam_mclk_clksel[] = { - { .parent = &sys_ck, .rates = dpll_bypass_rates }, - { .parent = &dpll4_m5x2_ck, .rates = dpll_locked_rates }, - { .parent = NULL } -}; - -static struct clk cam_mclk = { - .name = "cam_mclk", - .parent = &dpll4_m5x2_ck, - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, - .clksel = cam_mclk_clksel, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_CAM_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "cam_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk cam_ick = { - /* Handles both L3 and L4 clocks */ - .name = "cam_ick", - .parent = &l4_ick, - .init = &omap2_init_clk_clkdm, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_CAM_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "cam_clkdm", - .recalc = &followparent_recalc, -}; - -/* USBHOST - 3430ES2 only */ - -static struct clk usbhost_120m_fck = { - .name = "usbhost_120m_fck", - .parent = &omap_120m_fck, - .init = &omap2_init_clk_clkdm, - .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN), - .enable_bit = OMAP3430ES2_EN_USBHOST2_SHIFT, - .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "usbhost_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk usbhost_48m_fck = { - .name = "usbhost_48m_fck", - .parent = &omap_48m_fck, - .init = &omap2_init_clk_clkdm, - .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN), - .enable_bit = OMAP3430ES2_EN_USBHOST1_SHIFT, - .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "usbhost_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk usbhost_ick = { - /* Handles both L3 and L4 clocks */ - .name = "usbhost_ick", - .parent = &l4_ick, - .init = &omap2_init_clk_clkdm, - .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN), - .enable_bit = OMAP3430ES2_EN_USBHOST_SHIFT, - .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "usbhost_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk usbhost_sar_fck = { - .name = "usbhost_sar_fck", - .parent = &osc_sys_ck, - .init = &omap2_init_clk_clkdm, - .enable_reg = OMAP_PRM_REGADDR(OMAP3430ES2_USBHOST_MOD, PM_PWSTCTRL), - .enable_bit = OMAP3430ES2_SAVEANDRESTORE_SHIFT, - .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "usbhost_clkdm", - .recalc = &followparent_recalc, -}; - -/* WKUP */ - -static const struct clksel_rate usim_96m_rates[] = { - { .div = 2, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 4, .val = 4, .flags = RATE_IN_343X }, - { .div = 8, .val = 5, .flags = RATE_IN_343X }, - { .div = 10, .val = 6, .flags = RATE_IN_343X }, - { .div = 0 }, -}; - -static const struct clksel_rate usim_120m_rates[] = { - { .div = 4, .val = 7, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 8, .val = 8, .flags = RATE_IN_343X }, - { .div = 16, .val = 9, .flags = RATE_IN_343X }, - { .div = 20, .val = 10, .flags = RATE_IN_343X }, - { .div = 0 }, -}; - -static const struct clksel usim_clksel[] = { - { .parent = &omap_96m_fck, .rates = usim_96m_rates }, - { .parent = &omap_120m_fck, .rates = usim_120m_rates }, - { .parent = &sys_ck, .rates = div2_rates }, - { .parent = NULL }, -}; - -/* 3430ES2 only */ -static struct clk usim_fck = { - .name = "usim_fck", - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), - .enable_bit = OMAP3430ES2_EN_USIMOCP_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430ES2_CLKSEL_USIMOCP_MASK, - .clksel = usim_clksel, - .flags = CLOCK_IN_OMAP3430ES2, - .recalc = &omap2_clksel_recalc, -}; - -/* XXX should gpt1's clksel have wkup_32k_fck as the 32k opt? */ -static struct clk gpt1_fck = { - .name = "gpt1_fck", - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPT1_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_GPT1_MASK, - .clksel = omap343x_gpt_clksel, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "wkup_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk wkup_32k_fck = { - .name = "wkup_32k_fck", - .init = &omap2_init_clk_clkdm, - .parent = &omap_32k_fck, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .clkdm_name = "wkup_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpio1_dbck = { - .name = "gpio1_dbck", - .parent = &wkup_32k_fck, - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPIO1_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "wkup_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk wdt2_fck = { - .name = "wdt2_fck", - .parent = &wkup_32k_fck, - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_WDT2_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "wkup_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk wkup_l4_ick = { - .name = "wkup_l4_ick", - .parent = &sys_ck, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .clkdm_name = "wkup_clkdm", - .recalc = &followparent_recalc, -}; - -/* 3430ES2 only */ -/* Never specifically named in the TRM, so we have to infer a likely name */ -static struct clk usim_ick = { - .name = "usim_ick", - .parent = &wkup_l4_ick, - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), - .enable_bit = OMAP3430ES2_EN_USIMOCP_SHIFT, - .flags = CLOCK_IN_OMAP3430ES2, - .clkdm_name = "wkup_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk wdt2_ick = { - .name = "wdt2_ick", - .parent = &wkup_l4_ick, - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_WDT2_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "wkup_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk wdt1_ick = { - .name = "wdt1_ick", - .parent = &wkup_l4_ick, - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_WDT1_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "wkup_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpio1_ick = { - .name = "gpio1_ick", - .parent = &wkup_l4_ick, - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_GPIO1_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "wkup_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk omap_32ksync_ick = { - .name = "omap_32ksync_ick", - .parent = &wkup_l4_ick, - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_32KSYNC_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "wkup_clkdm", - .recalc = &followparent_recalc, -}; - -/* XXX This clock no longer exists in 3430 TRM rev F */ -static struct clk gpt12_ick = { - .name = "gpt12_ick", - .parent = &wkup_l4_ick, - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_GPT12_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "wkup_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpt1_ick = { - .name = "gpt1_ick", - .parent = &wkup_l4_ick, - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_GPT1_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "wkup_clkdm", - .recalc = &followparent_recalc, -}; - - - -/* PER clock domain */ - -static struct clk per_96m_fck = { - .name = "per_96m_fck", - .parent = &omap_96m_alwon_fck, - .init = &omap2_init_clk_clkdm, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk per_48m_fck = { - .name = "per_48m_fck", - .parent = &omap_48m_fck, - .init = &omap2_init_clk_clkdm, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk uart3_fck = { - .name = "uart3_fck", - .parent = &per_48m_fck, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_UART3_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpt2_fck = { - .name = "gpt2_fck", - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPT2_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_GPT2_MASK, - .clksel = omap343x_gpt_clksel, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gpt3_fck = { - .name = "gpt3_fck", - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPT3_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_GPT3_MASK, - .clksel = omap343x_gpt_clksel, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gpt4_fck = { - .name = "gpt4_fck", - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPT4_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_GPT4_MASK, - .clksel = omap343x_gpt_clksel, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gpt5_fck = { - .name = "gpt5_fck", - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPT5_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_GPT5_MASK, - .clksel = omap343x_gpt_clksel, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gpt6_fck = { - .name = "gpt6_fck", - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPT6_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_GPT6_MASK, - .clksel = omap343x_gpt_clksel, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gpt7_fck = { - .name = "gpt7_fck", - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPT7_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_GPT7_MASK, - .clksel = omap343x_gpt_clksel, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gpt8_fck = { - .name = "gpt8_fck", - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPT8_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_GPT8_MASK, - .clksel = omap343x_gpt_clksel, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk gpt9_fck = { - .name = "gpt9_fck", - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPT9_SHIFT, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_GPT9_MASK, - .clksel = omap343x_gpt_clksel, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk per_32k_alwon_fck = { - .name = "per_32k_alwon_fck", - .parent = &omap_32k_fck, - .clkdm_name = "per_clkdm", - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .recalc = &followparent_recalc, -}; - -static struct clk gpio6_dbck = { - .name = "gpio6_dbck", - .parent = &per_32k_alwon_fck, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPIO6_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpio5_dbck = { - .name = "gpio5_dbck", - .parent = &per_32k_alwon_fck, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPIO5_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpio4_dbck = { - .name = "gpio4_dbck", - .parent = &per_32k_alwon_fck, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPIO4_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpio3_dbck = { - .name = "gpio3_dbck", - .parent = &per_32k_alwon_fck, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPIO3_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpio2_dbck = { - .name = "gpio2_dbck", - .parent = &per_32k_alwon_fck, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_GPIO2_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk wdt3_fck = { - .name = "wdt3_fck", - .parent = &per_32k_alwon_fck, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_WDT3_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk per_l4_ick = { - .name = "per_l4_ick", - .parent = &l4_ick, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | - PARENT_CONTROLS_CLOCK, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpio6_ick = { - .name = "gpio6_ick", - .parent = &per_l4_ick, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_GPIO6_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpio5_ick = { - .name = "gpio5_ick", - .parent = &per_l4_ick, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_GPIO5_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpio4_ick = { - .name = "gpio4_ick", - .parent = &per_l4_ick, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_GPIO4_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpio3_ick = { - .name = "gpio3_ick", - .parent = &per_l4_ick, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_GPIO3_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpio2_ick = { - .name = "gpio2_ick", - .parent = &per_l4_ick, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_GPIO2_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk wdt3_ick = { - .name = "wdt3_ick", - .parent = &per_l4_ick, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_WDT3_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk uart3_ick = { - .name = "uart3_ick", - .parent = &per_l4_ick, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_UART3_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpt9_ick = { - .name = "gpt9_ick", - .parent = &per_l4_ick, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_GPT9_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpt8_ick = { - .name = "gpt8_ick", - .parent = &per_l4_ick, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_GPT8_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpt7_ick = { - .name = "gpt7_ick", - .parent = &per_l4_ick, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_GPT7_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpt6_ick = { - .name = "gpt6_ick", - .parent = &per_l4_ick, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_GPT6_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpt5_ick = { - .name = "gpt5_ick", - .parent = &per_l4_ick, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_GPT5_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpt4_ick = { - .name = "gpt4_ick", - .parent = &per_l4_ick, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_GPT4_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpt3_ick = { - .name = "gpt3_ick", - .parent = &per_l4_ick, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_GPT3_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk gpt2_ick = { - .name = "gpt2_ick", - .parent = &per_l4_ick, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_GPT2_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mcbsp2_ick = { - .name = "mcbsp_ick", - .id = 2, - .parent = &per_l4_ick, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_MCBSP2_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mcbsp3_ick = { - .name = "mcbsp_ick", - .id = 3, - .parent = &per_l4_ick, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_MCBSP3_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static struct clk mcbsp4_ick = { - .name = "mcbsp_ick", - .id = 4, - .parent = &per_l4_ick, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), - .enable_bit = OMAP3430_EN_MCBSP4_SHIFT, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &followparent_recalc, -}; - -static const struct clksel mcbsp_234_clksel[] = { - { .parent = &per_96m_fck, .rates = common_mcbsp_96m_rates }, - { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates }, - { .parent = NULL } -}; - -static struct clk mcbsp2_fck = { - .name = "mcbsp_fck", - .id = 2, - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_MCBSP2_SHIFT, - .clksel_reg = OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0), - .clksel_mask = OMAP2_MCBSP2_CLKS_MASK, - .clksel = mcbsp_234_clksel, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk mcbsp3_fck = { - .name = "mcbsp_fck", - .id = 3, - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_MCBSP3_SHIFT, - .clksel_reg = OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1), - .clksel_mask = OMAP2_MCBSP3_CLKS_MASK, - .clksel = mcbsp_234_clksel, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk mcbsp4_fck = { - .name = "mcbsp_fck", - .id = 4, - .init = &omap2_init_clksel_parent, - .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_MCBSP4_SHIFT, - .clksel_reg = OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1), - .clksel_mask = OMAP2_MCBSP4_CLKS_MASK, - .clksel = mcbsp_234_clksel, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "per_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -/* EMU clocks */ - -/* More information: ARM Cortex-A8 Technical Reference Manual, sect 10.1 */ - -static const struct clksel_rate emu_src_sys_rates[] = { - { .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 }, -}; - -static const struct clksel_rate emu_src_core_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 }, -}; - -static const struct clksel_rate emu_src_per_rates[] = { - { .div = 1, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 }, -}; - -static const struct clksel_rate emu_src_mpu_rates[] = { - { .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 0 }, -}; - -static const struct clksel emu_src_clksel[] = { - { .parent = &sys_ck, .rates = emu_src_sys_rates }, - { .parent = &emu_core_alwon_ck, .rates = emu_src_core_rates }, - { .parent = &emu_per_alwon_ck, .rates = emu_src_per_rates }, - { .parent = &emu_mpu_alwon_ck, .rates = emu_src_mpu_rates }, - { .parent = NULL }, -}; - -/* - * Like the clkout_src clocks, emu_src_clk is a virtual clock, existing only - * to switch the source of some of the EMU clocks. - * XXX Are there CLKEN bits for these EMU clks? - */ -static struct clk emu_src_ck = { - .name = "emu_src_ck", - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), - .clksel_mask = OMAP3430_MUX_CTRL_MASK, - .clksel = emu_src_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .clkdm_name = "emu_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static const struct clksel_rate pclk_emu_rates[] = { - { .div = 2, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 3, .val = 3, .flags = RATE_IN_343X }, - { .div = 4, .val = 4, .flags = RATE_IN_343X }, - { .div = 6, .val = 6, .flags = RATE_IN_343X }, - { .div = 0 }, -}; - -static const struct clksel pclk_emu_clksel[] = { - { .parent = &emu_src_ck, .rates = pclk_emu_rates }, - { .parent = NULL }, -}; - -static struct clk pclk_fck = { - .name = "pclk_fck", - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), - .clksel_mask = OMAP3430_CLKSEL_PCLK_MASK, - .clksel = pclk_emu_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .clkdm_name = "emu_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static const struct clksel_rate pclkx2_emu_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 2, .val = 2, .flags = RATE_IN_343X }, - { .div = 3, .val = 3, .flags = RATE_IN_343X }, - { .div = 0 }, -}; - -static const struct clksel pclkx2_emu_clksel[] = { - { .parent = &emu_src_ck, .rates = pclkx2_emu_rates }, - { .parent = NULL }, -}; - -static struct clk pclkx2_fck = { - .name = "pclkx2_fck", - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), - .clksel_mask = OMAP3430_CLKSEL_PCLKX2_MASK, - .clksel = pclkx2_emu_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .clkdm_name = "emu_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static const struct clksel atclk_emu_clksel[] = { - { .parent = &emu_src_ck, .rates = div2_rates }, - { .parent = NULL }, -}; - -static struct clk atclk_fck = { - .name = "atclk_fck", - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), - .clksel_mask = OMAP3430_CLKSEL_ATCLK_MASK, - .clksel = atclk_emu_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .clkdm_name = "emu_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static struct clk traceclk_src_fck = { - .name = "traceclk_src_fck", - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), - .clksel_mask = OMAP3430_TRACE_MUX_CTRL_MASK, - .clksel = emu_src_clksel, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .clkdm_name = "emu_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -static const struct clksel_rate traceclk_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE }, - { .div = 2, .val = 2, .flags = RATE_IN_343X }, - { .div = 4, .val = 4, .flags = RATE_IN_343X }, - { .div = 0 }, -}; - -static const struct clksel traceclk_clksel[] = { - { .parent = &traceclk_src_fck, .rates = traceclk_rates }, - { .parent = NULL }, -}; - -static struct clk traceclk_fck = { - .name = "traceclk_fck", - .init = &omap2_init_clksel_parent, - .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), - .clksel_mask = OMAP3430_CLKSEL_TRACECLK_MASK, - .clksel = traceclk_clksel, - .flags = CLOCK_IN_OMAP343X | ALWAYS_ENABLED, - .clkdm_name = "emu_clkdm", - .recalc = &omap2_clksel_recalc, -}; - -/* SR clocks */ - -/* SmartReflex fclk (VDD1) */ -static struct clk sr1_fck = { - .name = "sr1_fck", - .parent = &sys_ck, - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_SR1_SHIFT, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, - .recalc = &followparent_recalc, -}; - -/* SmartReflex fclk (VDD2) */ -static struct clk sr2_fck = { - .name = "sr2_fck", - .parent = &sys_ck, - .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), - .enable_bit = OMAP3430_EN_SR2_SHIFT, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, - .recalc = &followparent_recalc, -}; - -static struct clk sr_l4_ick = { - .name = "sr_l4_ick", - .parent = &l4_ick, - .flags = CLOCK_IN_OMAP343X, - .clkdm_name = "core_l4_clkdm", - .recalc = &followparent_recalc, -}; - -/* SECURE_32K_FCK clocks */ - -/* XXX This clock no longer exists in 3430 TRM rev F */ -static struct clk gpt12_fck = { - .name = "gpt12_fck", - .parent = &secure_32k_fck, - .flags = CLOCK_IN_OMAP343X | ALWAYS_ENABLED, - .recalc = &followparent_recalc, -}; - -static struct clk wdt1_fck = { - .name = "wdt1_fck", - .parent = &secure_32k_fck, - .flags = CLOCK_IN_OMAP343X | ALWAYS_ENABLED, - .recalc = &followparent_recalc, -}; - -static struct clk *onchip_34xx_clks[] __initdata = { - &omap_32k_fck, - &virt_12m_ck, - &virt_13m_ck, - &virt_16_8m_ck, - &virt_19_2m_ck, - &virt_26m_ck, - &virt_38_4m_ck, - &osc_sys_ck, - &sys_ck, - &sys_altclk, - &mcbsp_clks, - &sys_clkout1, - &dpll1_ck, - &dpll1_x2_ck, - &dpll1_x2m2_ck, - &dpll2_ck, - &dpll2_m2_ck, - &dpll3_ck, - &core_ck, - &dpll3_x2_ck, - &dpll3_m2_ck, - &dpll3_m2x2_ck, - &dpll3_m3_ck, - &dpll3_m3x2_ck, - &emu_core_alwon_ck, - &dpll4_ck, - &dpll4_x2_ck, - &omap_96m_alwon_fck, - &omap_96m_fck, - &cm_96m_fck, - &virt_omap_54m_fck, - &omap_54m_fck, - &omap_48m_fck, - &omap_12m_fck, - &dpll4_m2_ck, - &dpll4_m2x2_ck, - &dpll4_m3_ck, - &dpll4_m3x2_ck, - &dpll4_m4_ck, - &dpll4_m4x2_ck, - &dpll4_m5_ck, - &dpll4_m5x2_ck, - &dpll4_m6_ck, - &dpll4_m6x2_ck, - &emu_per_alwon_ck, - &dpll5_ck, - &dpll5_m2_ck, - &omap_120m_fck, - &clkout2_src_ck, - &sys_clkout2, - &corex2_fck, - &dpll1_fck, - &mpu_ck, - &arm_fck, - &emu_mpu_alwon_ck, - &dpll2_fck, - &iva2_ck, - &l3_ick, - &l4_ick, - &rm_ick, - &gfx_l3_ck, - &gfx_l3_fck, - &gfx_l3_ick, - &gfx_cg1_ck, - &gfx_cg2_ck, - &sgx_fck, - &sgx_ick, - &d2d_26m_fck, - &gpt10_fck, - &gpt11_fck, - &cpefuse_fck, - &ts_fck, - &usbtll_fck, - &core_96m_fck, - &mmchs3_fck, - &mmchs2_fck, - &mspro_fck, - &mmchs1_fck, - &i2c3_fck, - &i2c2_fck, - &i2c1_fck, - &mcbsp5_fck, - &mcbsp1_fck, - &core_48m_fck, - &mcspi4_fck, - &mcspi3_fck, - &mcspi2_fck, - &mcspi1_fck, - &uart2_fck, - &uart1_fck, - &fshostusb_fck, - &core_12m_fck, - &hdq_fck, - &ssi_ssr_fck, - &ssi_sst_fck, - &core_l3_ick, - &hsotgusb_ick, - &sdrc_ick, - &gpmc_fck, - &security_l3_ick, - &pka_ick, - &core_l4_ick, - &usbtll_ick, - &mmchs3_ick, - &icr_ick, - &aes2_ick, - &sha12_ick, - &des2_ick, - &mmchs2_ick, - &mmchs1_ick, - &mspro_ick, - &hdq_ick, - &mcspi4_ick, - &mcspi3_ick, - &mcspi2_ick, - &mcspi1_ick, - &i2c3_ick, - &i2c2_ick, - &i2c1_ick, - &uart2_ick, - &uart1_ick, - &gpt11_ick, - &gpt10_ick, - &mcbsp5_ick, - &mcbsp1_ick, - &fac_ick, - &mailboxes_ick, - &omapctrl_ick, - &ssi_l4_ick, - &ssi_ick, - &usb_l4_ick, - &security_l4_ick2, - &aes1_ick, - &rng_ick, - &sha11_ick, - &des1_ick, - &dss1_alwon_fck, - &dss_tv_fck, - &dss_96m_fck, - &dss2_alwon_fck, - &dss_ick, - &cam_mclk, - &cam_ick, - &usbhost_120m_fck, - &usbhost_48m_fck, - &usbhost_ick, - &usbhost_sar_fck, - &usim_fck, - &gpt1_fck, - &wkup_32k_fck, - &gpio1_dbck, - &wdt2_fck, - &wkup_l4_ick, - &usim_ick, - &wdt2_ick, - &wdt1_ick, - &gpio1_ick, - &omap_32ksync_ick, - &gpt12_ick, - &gpt1_ick, - &per_96m_fck, - &per_48m_fck, - &uart3_fck, - &gpt2_fck, - &gpt3_fck, - &gpt4_fck, - &gpt5_fck, - &gpt6_fck, - &gpt7_fck, - &gpt8_fck, - &gpt9_fck, - &per_32k_alwon_fck, - &gpio6_dbck, - &gpio5_dbck, - &gpio4_dbck, - &gpio3_dbck, - &gpio2_dbck, - &wdt3_fck, - &per_l4_ick, - &gpio6_ick, - &gpio5_ick, - &gpio4_ick, - &gpio3_ick, - &gpio2_ick, - &wdt3_ick, - &uart3_ick, - &gpt9_ick, - &gpt8_ick, - &gpt7_ick, - &gpt6_ick, - &gpt5_ick, - &gpt4_ick, - &gpt3_ick, - &gpt2_ick, - &mcbsp2_ick, - &mcbsp3_ick, - &mcbsp4_ick, - &mcbsp2_fck, - &mcbsp3_fck, - &mcbsp4_fck, - &emu_src_ck, - &pclk_fck, - &pclkx2_fck, - &atclk_fck, - &traceclk_src_fck, - &traceclk_fck, - &sr1_fck, - &sr2_fck, - &sr_l4_ick, - &secure_32k_fck, - &gpt12_fck, - &wdt1_fck, -}; +extern const struct clkops clkops_omap3430es2_ssi_wait; +extern const struct clkops clkops_omap3430es2_iclk_ssi_wait; +extern const struct clkops clkops_omap3430es2_hsotgusb_wait; +extern const struct clkops clkops_omap3430es2_iclk_hsotgusb_wait; +extern const struct clkops clkops_omap3430es2_dss_usbhost_wait; +extern const struct clkops clkops_omap3430es2_iclk_dss_usbhost_wait; #endif diff --git a/arch/arm/mach-omap2/clock3517.c b/arch/arm/mach-omap2/clock3517.c new file mode 100644 index 00000000000..4d79ae2c024 --- /dev/null +++ b/arch/arm/mach-omap2/clock3517.c @@ -0,0 +1,118 @@ +/* + * OMAP3517/3505-specific clock framework functions + * + * Copyright (C) 2010 Texas Instruments, Inc. + * Copyright (C) 2011 Nokia Corporation + * + * Ranjith Lohithakshan + * Paul Walmsley + * + * Parts of this code are based on code written by + * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu, + * Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#undef DEBUG + +#include <linux/kernel.h> +#include <linux/clk.h> +#include <linux/io.h> + +#include "clock.h" +#include "clock3517.h" +#include "cm3xxx.h" +#include "cm-regbits-34xx.h" + +/* + * In AM35xx IPSS, the {ICK,FCK} enable bits for modules are exported + * in the same register at a bit offset of 0x8. The EN_ACK for ICK is + * at an offset of 4 from ICK enable bit. + */ +#define AM35XX_IPSS_ICK_MASK 0xF +#define AM35XX_IPSS_ICK_EN_ACK_OFFSET 0x4 +#define AM35XX_IPSS_ICK_FCK_OFFSET 0x8 +#define AM35XX_IPSS_CLK_IDLEST_VAL 0 + +/** + * am35xx_clk_find_idlest - return clock ACK info for AM35XX IPSS + * @clk: struct clk * being enabled + * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into + * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into + * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator + * + * The interface clocks on AM35xx IPSS reflects the clock idle status + * in the enable register itsel at a bit offset of 4 from the enable + * bit. A value of 1 indicates that clock is enabled. + */ +static void am35xx_clk_find_idlest(struct clk_hw_omap *clk, + void __iomem **idlest_reg, + u8 *idlest_bit, + u8 *idlest_val) +{ + *idlest_reg = (__force void __iomem *)(clk->enable_reg); + *idlest_bit = clk->enable_bit + AM35XX_IPSS_ICK_EN_ACK_OFFSET; + *idlest_val = AM35XX_IPSS_CLK_IDLEST_VAL; +} + +/** + * am35xx_clk_find_companion - find companion clock to @clk + * @clk: struct clk * to find the companion clock of + * @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in + * @other_bit: u8 ** to return the companion clock bit shift in + * + * Some clocks don't have companion clocks. For example, modules with + * only an interface clock (such as HECC) don't have a companion + * clock. Right now, this code relies on the hardware exporting a bit + * in the correct companion register that indicates that the + * nonexistent 'companion clock' is active. Future patches will + * associate this type of code with per-module data structures to + * avoid this issue, and remove the casts. No return value. + */ +static void am35xx_clk_find_companion(struct clk_hw_omap *clk, + void __iomem **other_reg, + u8 *other_bit) +{ + *other_reg = (__force void __iomem *)(clk->enable_reg); + if (clk->enable_bit & AM35XX_IPSS_ICK_MASK) + *other_bit = clk->enable_bit + AM35XX_IPSS_ICK_FCK_OFFSET; + else + *other_bit = clk->enable_bit - AM35XX_IPSS_ICK_FCK_OFFSET; +} +const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait = { + .find_idlest = am35xx_clk_find_idlest, + .find_companion = am35xx_clk_find_companion, +}; + +/** + * am35xx_clk_ipss_find_idlest - return CM_IDLEST info for IPSS + * @clk: struct clk * being enabled + * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into + * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into + * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator + * + * The IPSS target CM_IDLEST bit is at a different shift from the + * CM_{I,F}CLKEN bit. Pass back the correct info via @idlest_reg + * and @idlest_bit. No return value. + */ +static void am35xx_clk_ipss_find_idlest(struct clk_hw_omap *clk, + void __iomem **idlest_reg, + u8 *idlest_bit, + u8 *idlest_val) +{ + u32 r; + + r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); + *idlest_reg = (__force void __iomem *)r; + *idlest_bit = AM35XX_ST_IPSS_SHIFT; + *idlest_val = OMAP34XX_CM_IDLEST_VAL; +} + +const struct clk_hw_omap_ops clkhwops_am35xx_ipss_wait = { + .allow_idle = omap2_clkt_iclk_allow_idle, + .deny_idle = omap2_clkt_iclk_deny_idle, + .find_idlest = am35xx_clk_ipss_find_idlest, + .find_companion = omap2_clk_dflt_find_companion, +}; diff --git a/arch/arm/mach-omap2/clock3517.h b/arch/arm/mach-omap2/clock3517.h new file mode 100644 index 00000000000..ca5e5a64c2e --- /dev/null +++ b/arch/arm/mach-omap2/clock3517.h @@ -0,0 +1,14 @@ +/* + * OMAP3517/3505 clock function prototypes and macros + * + * Copyright (C) 2010 Texas Instruments, Inc. + * Copyright (C) 2010 Nokia Corporation + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK3517_H +#define __ARCH_ARM_MACH_OMAP2_CLOCK3517_H + +extern const struct clkops clkops_am35xx_ipss_module_wait; +extern const struct clkops clkops_am35xx_ipss_wait; + +#endif diff --git a/arch/arm/mach-omap2/clock36xx.c b/arch/arm/mach-omap2/clock36xx.c new file mode 100644 index 00000000000..91ccb962e09 --- /dev/null +++ b/arch/arm/mach-omap2/clock36xx.c @@ -0,0 +1,69 @@ +/* + * OMAP36xx-specific clkops + * + * Copyright (C) 2010 Texas Instruments, Inc. + * Copyright (C) 2010 Nokia Corporation + * + * Mike Turquette + * Vijaykumar GN + * Paul Walmsley + * + * Parts of this code are based on code written by + * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu, + * Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#undef DEBUG + +#include <linux/kernel.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/io.h> + +#include "clock.h" +#include "clock36xx.h" +#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) + +/** + * omap36xx_pwrdn_clk_enable_with_hsdiv_restore - enable clocks suffering + * from HSDivider PWRDN problem Implements Errata ID: i556. + * @clk: DPLL output struct clk + * + * 3630 only: dpll3_m3_ck, dpll4_m2_ck, dpll4_m3_ck, dpll4_m4_ck, + * dpll4_m5_ck & dpll4_m6_ck dividers gets loaded with reset + * valueafter their respective PWRDN bits are set. Any dummy write + * (Any other value different from the Read value) to the + * corresponding CM_CLKSEL register will refresh the dividers. + */ +int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk_hw *clk) +{ + struct clk_divider *parent; + struct clk_hw *parent_hw; + u32 dummy_v, orig_v; + struct clk_hw_omap *omap_clk = to_clk_hw_omap(clk); + int ret; + + /* Clear PWRDN bit of HSDIVIDER */ + ret = omap2_dflt_clk_enable(clk); + + parent_hw = __clk_get_hw(__clk_get_parent(clk->clk)); + parent = to_clk_divider(parent_hw); + + /* Restore the dividers */ + if (!ret) { + orig_v = omap2_clk_readl(omap_clk, parent->reg); + dummy_v = orig_v; + + /* Write any other value different from the Read value */ + dummy_v ^= (1 << parent->shift); + omap2_clk_writel(dummy_v, omap_clk, parent->reg); + + /* Write the original divider */ + omap2_clk_writel(orig_v, omap_clk, parent->reg); + } + + return ret; +} diff --git a/arch/arm/mach-omap2/clock36xx.h b/arch/arm/mach-omap2/clock36xx.h new file mode 100644 index 00000000000..945bb7f083e --- /dev/null +++ b/arch/arm/mach-omap2/clock36xx.h @@ -0,0 +1,13 @@ +/* + * OMAP36xx clock function prototypes and macros + * + * Copyright (C) 2010 Texas Instruments, Inc. + * Copyright (C) 2010 Nokia Corporation + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK36XX_H +#define __ARCH_ARM_MACH_OMAP2_CLOCK36XX_H + +extern int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk_hw *hw); + +#endif diff --git a/arch/arm/mach-omap2/clock3xxx.c b/arch/arm/mach-omap2/clock3xxx.c new file mode 100644 index 00000000000..0b02b4161d7 --- /dev/null +++ b/arch/arm/mach-omap2/clock3xxx.c @@ -0,0 +1,99 @@ +/* + * OMAP3-specific clock framework functions + * + * Copyright (C) 2007-2008 Texas Instruments, Inc. + * Copyright (C) 2007-2010 Nokia Corporation + * + * Paul Walmsley + * Jouni Högander + * + * Parts of this code are based on code written by + * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#undef DEBUG + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/clk.h> +#include <linux/io.h> + +#include "soc.h" +#include "clock.h" +#include "clock3xxx.h" +#include "prm2xxx_3xxx.h" +#include "prm-regbits-34xx.h" +#include "cm2xxx_3xxx.h" +#include "cm-regbits-34xx.h" + +/* + * DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks + * that are sourced by DPLL5, and both of these require this clock + * to be at 120 MHz for proper operation. + */ +#define DPLL5_FREQ_FOR_USBHOST 120000000 + +/* needed by omap3_core_dpll_m2_set_rate() */ +struct clk *sdrc_ick_p, *arm_fck_p; +int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + /* + * According to the 12-5 CDP code from TI, "Limitation 2.5" + * on 3430ES1 prevents us from changing DPLL multipliers or dividers + * on DPLL4. + */ + if (omap_rev() == OMAP3430_REV_ES1_0) { + pr_err("clock: DPLL4 cannot change rate due to silicon 'Limitation 2.5' on 3430ES1.\n"); + return -EINVAL; + } + + return omap3_noncore_dpll_set_rate(hw, rate, parent_rate); +} + +void __init omap3_clk_lock_dpll5(void) +{ + struct clk *dpll5_clk; + struct clk *dpll5_m2_clk; + + dpll5_clk = clk_get(NULL, "dpll5_ck"); + clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST); + clk_prepare_enable(dpll5_clk); + + /* Program dpll5_m2_clk divider for no division */ + dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck"); + clk_prepare_enable(dpll5_m2_clk); + clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST); + + clk_disable_unprepare(dpll5_m2_clk); + clk_disable_unprepare(dpll5_clk); + return; +} + +/* Common clock code */ + +/* + * Switch the MPU rate if specified on cmdline. We cannot do this + * early until cmdline is parsed. XXX This should be removed from the + * clock code and handled by the OPP layer code in the near future. + */ +static int __init omap3xxx_clk_arch_init(void) +{ + int ret; + + if (!cpu_is_omap34xx()) + return 0; + + ret = omap2_clk_switch_mpurate_at_boot("dpll1_ck"); + if (!ret) + omap2_clk_print_new_rates("osc_sys_ck", "core_ck", "arm_fck"); + + return ret; +} + +omap_arch_initcall(omap3xxx_clk_arch_init); + + diff --git a/arch/arm/mach-omap2/clock3xxx.h b/arch/arm/mach-omap2/clock3xxx.h new file mode 100644 index 00000000000..78d9f562e3c --- /dev/null +++ b/arch/arm/mach-omap2/clock3xxx.h @@ -0,0 +1,20 @@ +/* + * OMAP3-common clock function prototypes and macros + * + * Copyright (C) 2007-2010 Texas Instruments, Inc. + * Copyright (C) 2007-2010 Nokia Corporation + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_H +#define __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_H + +int omap3xxx_clk_init(void); +int omap3_core_dpll_m2_set_rate(struct clk_hw *clk, unsigned long rate, + unsigned long parent_rate); + +extern struct clk *sdrc_ick_p; +extern struct clk *arm_fck_p; + +extern const struct clkops clkops_noncore_dpll_ops; + +#endif diff --git a/arch/arm/mach-omap2/clock44xx.h b/arch/arm/mach-omap2/clock44xx.h new file mode 100644 index 00000000000..287a46f78d9 --- /dev/null +++ b/arch/arm/mach-omap2/clock44xx.h @@ -0,0 +1,20 @@ +/* + * OMAP4 clock function prototypes and macros + * + * Copyright (C) 2009 Texas Instruments, Inc. + * Copyright (C) 2010 Nokia Corporation + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK44XX_H +#define __ARCH_ARM_MACH_OMAP2_CLOCK44XX_H + +/* + * OMAP4430_REGM4XEN_MULT: If the CM_CLKMODE_DPLL_ABE.DPLL_REGM4XEN bit is + * set, then the DPLL's lock frequency is multiplied by 4 (OMAP4430 TRM + * vV Section 3.6.3.3.1 "DPLLs Output Clocks Parameters") + */ +#define OMAP4430_REGM4XEN_MULT 4 + +int omap4xxx_clk_init(void); + +#endif diff --git a/arch/arm/mach-omap2/clock_common_data.c b/arch/arm/mach-omap2/clock_common_data.c new file mode 100644 index 00000000000..ef4d21bfb96 --- /dev/null +++ b/arch/arm/mach-omap2/clock_common_data.c @@ -0,0 +1,126 @@ +/* + * linux/arch/arm/mach-omap2/clock_common_data.c + * + * Copyright (C) 2005-2009 Texas Instruments, Inc. + * Copyright (C) 2004-2009 Nokia Corporation + * + * Contacts: + * Richard Woodruff <r-woodruff2@ti.com> + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This file contains clock data that is common to both the OMAP2xxx and + * OMAP3xxx clock definition files. + */ + +#include <linux/clk-private.h> +#include "clock.h" + +/* clksel_rate data common to 24xx/343x */ +const struct clksel_rate gpt_32k_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_24XX | RATE_IN_3XXX }, + { .div = 0 } +}; + +const struct clksel_rate gpt_sys_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX | RATE_IN_3XXX }, + { .div = 0 } +}; + +const struct clksel_rate gfx_l3_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX | RATE_IN_3XXX }, + { .div = 2, .val = 2, .flags = RATE_IN_24XX | RATE_IN_3XXX }, + { .div = 3, .val = 3, .flags = RATE_IN_243X | RATE_IN_3XXX }, + { .div = 4, .val = 4, .flags = RATE_IN_243X | RATE_IN_3XXX }, + { .div = 0 } +}; + +const struct clksel_rate dsp_ick_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, + { .div = 2, .val = 2, .flags = RATE_IN_24XX }, + { .div = 3, .val = 3, .flags = RATE_IN_243X }, + { .div = 0 }, +}; + + +/* clksel_rate blocks shared between OMAP44xx and AM33xx */ + +const struct clksel_rate div_1_0_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 0 }, +}; + +const struct clksel_rate div3_1to4_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_4430 }, + { .div = 2, .val = 1, .flags = RATE_IN_4430 }, + { .div = 4, .val = 2, .flags = RATE_IN_4430 }, + { .div = 0 }, +}; + +const struct clksel_rate div_1_1_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 0 }, +}; + +const struct clksel_rate div_1_2_rates[] = { + { .div = 1, .val = 2, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 0 }, +}; + +const struct clksel_rate div_1_3_rates[] = { + { .div = 1, .val = 3, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 0 }, +}; + +const struct clksel_rate div_1_4_rates[] = { + { .div = 1, .val = 4, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 0 }, +}; + +const struct clksel_rate div31_1to31_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 2, .val = 2, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 3, .val = 3, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 4, .val = 4, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 5, .val = 5, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 6, .val = 6, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 7, .val = 7, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 8, .val = 8, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 9, .val = 9, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 10, .val = 10, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 11, .val = 11, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 12, .val = 12, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 13, .val = 13, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 14, .val = 14, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 15, .val = 15, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 16, .val = 16, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 17, .val = 17, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 18, .val = 18, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 19, .val = 19, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 20, .val = 20, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 21, .val = 21, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 22, .val = 22, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 23, .val = 23, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 24, .val = 24, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 25, .val = 25, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 26, .val = 26, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 27, .val = 27, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 28, .val = 28, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 29, .val = 29, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 30, .val = 30, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 31, .val = 31, .flags = RATE_IN_4430 | RATE_IN_AM33XX }, + { .div = 0 }, +}; + +/* Clocks shared between various OMAP SoCs */ + +static struct clk_ops dummy_ck_ops = {}; + +struct clk dummy_ck = { + .name = "dummy_clk", + .ops = &dummy_ck_ops, + .flags = CLK_IS_BASIC, +}; diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 4c3ce9cfd94..2da3b5ec010 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -1,254 +1,481 @@ /* - * OMAP2/3 clockdomain framework functions + * OMAP2/3/4 clockdomain framework functions * - * Copyright (C) 2008 Texas Instruments, Inc. - * Copyright (C) 2008 Nokia Corporation + * Copyright (C) 2008-2011 Texas Instruments, Inc. + * Copyright (C) 2008-2011 Nokia Corporation * * Written by Paul Walmsley and Jouni Högander + * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#ifdef CONFIG_OMAP_DEBUG_CLOCKDOMAIN -# define DEBUG -#endif +#undef DEBUG -#include <linux/module.h> #include <linux/kernel.h> #include <linux/device.h> #include <linux/list.h> #include <linux/errno.h> +#include <linux/string.h> #include <linux/delay.h> #include <linux/clk.h> #include <linux/limits.h> +#include <linux/err.h> +#include <linux/clk-provider.h> #include <linux/io.h> #include <linux/bitops.h> -#include <mach/clock.h> - -#include "prm.h" -#include "prm-regbits-24xx.h" -#include "cm.h" - -#include <mach/powerdomain.h> -#include <mach/clockdomain.h> +#include "soc.h" +#include "clock.h" +#include "clockdomain.h" /* clkdm_list contains all registered struct clockdomains */ static LIST_HEAD(clkdm_list); -/* clkdm_mutex protects clkdm_list add and del ops */ -static DEFINE_MUTEX(clkdm_mutex); - -/* array of powerdomain deps to be added/removed when clkdm in hwsup mode */ -static struct clkdm_pwrdm_autodep *autodeps; +/* array of clockdomain deps to be added/removed when clkdm in hwsup mode */ +static struct clkdm_autodep *autodeps; +static struct clkdm_ops *arch_clkdm; /* Private functions */ -/* - * _autodep_lookup - resolve autodep pwrdm names to pwrdm pointers; store - * @autodep: struct clkdm_pwrdm_autodep * to resolve +static struct clockdomain *_clkdm_lookup(const char *name) +{ + struct clockdomain *clkdm, *temp_clkdm; + + if (!name) + return NULL; + + clkdm = NULL; + + list_for_each_entry(temp_clkdm, &clkdm_list, node) { + if (!strcmp(name, temp_clkdm->name)) { + clkdm = temp_clkdm; + break; + } + } + + return clkdm; +} + +/** + * _clkdm_register - register a clockdomain + * @clkdm: struct clockdomain * to register * - * Resolve autodep powerdomain names to powerdomain pointers via - * pwrdm_lookup() and store the pointers in the autodep structure. An - * "autodep" is a powerdomain sleep/wakeup dependency that is + * Adds a clockdomain to the internal clockdomain list. + * Returns -EINVAL if given a null pointer, -EEXIST if a clockdomain is + * already registered by the provided name, or 0 upon success. + */ +static int _clkdm_register(struct clockdomain *clkdm) +{ + struct powerdomain *pwrdm; + + if (!clkdm || !clkdm->name) + return -EINVAL; + + pwrdm = pwrdm_lookup(clkdm->pwrdm.name); + if (!pwrdm) { + pr_err("clockdomain: %s: powerdomain %s does not exist\n", + clkdm->name, clkdm->pwrdm.name); + return -EINVAL; + } + clkdm->pwrdm.ptr = pwrdm; + + /* Verify that the clockdomain is not already registered */ + if (_clkdm_lookup(clkdm->name)) + return -EEXIST; + + list_add(&clkdm->node, &clkdm_list); + + pwrdm_add_clkdm(pwrdm, clkdm); + + pr_debug("clockdomain: registered %s\n", clkdm->name); + + return 0; +} + +/* _clkdm_deps_lookup - look up the specified clockdomain in a clkdm list */ +static struct clkdm_dep *_clkdm_deps_lookup(struct clockdomain *clkdm, + struct clkdm_dep *deps) +{ + struct clkdm_dep *cd; + + if (!clkdm || !deps) + return ERR_PTR(-EINVAL); + + for (cd = deps; cd->clkdm_name; cd++) { + if (!cd->clkdm && cd->clkdm_name) + cd->clkdm = _clkdm_lookup(cd->clkdm_name); + + if (cd->clkdm == clkdm) + break; + } + + if (!cd->clkdm_name) + return ERR_PTR(-ENOENT); + + return cd; +} + +/** + * _autodep_lookup - resolve autodep clkdm names to clkdm pointers; store + * @autodep: struct clkdm_autodep * to resolve + * + * Resolve autodep clockdomain names to clockdomain pointers via + * clkdm_lookup() and store the pointers in the autodep structure. An + * "autodep" is a clockdomain sleep/wakeup dependency that is * automatically added and removed whenever clocks in the associated * clockdomain are enabled or disabled (respectively) when the * clockdomain is in hardware-supervised mode. Meant to be called * once at clockdomain layer initialization, since these should remain * fixed for a particular architecture. No return value. + * + * XXX autodeps are deprecated and should be removed at the earliest + * opportunity */ -static void _autodep_lookup(struct clkdm_pwrdm_autodep *autodep) +static void _autodep_lookup(struct clkdm_autodep *autodep) { - struct powerdomain *pwrdm; + struct clockdomain *clkdm; if (!autodep) return; - if (!omap_chip_is(autodep->omap_chip)) - return; - - pwrdm = pwrdm_lookup(autodep->pwrdm_name); - if (!pwrdm) { - pr_debug("clockdomain: _autodep_lookup: powerdomain %s " - "does not exist\n", autodep->pwrdm_name); - WARN_ON(1); - return; + clkdm = clkdm_lookup(autodep->clkdm.name); + if (!clkdm) { + pr_err("clockdomain: autodeps: clockdomain %s does not exist\n", + autodep->clkdm.name); + clkdm = ERR_PTR(-ENOENT); } - autodep->pwrdm = pwrdm; - - return; + autodep->clkdm.ptr = clkdm; } -/* - * _clkdm_add_autodeps - add auto sleepdeps/wkdeps to clkdm upon clock enable - * @clkdm: struct clockdomain * +/** + * _resolve_clkdm_deps() - resolve clkdm_names in @clkdm_deps to clkdms + * @clkdm: clockdomain that we are resolving dependencies for + * @clkdm_deps: ptr to array of struct clkdm_deps to resolve * - * Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm' - * in hardware-supervised mode. Meant to be called from clock framework - * when a clock inside clockdomain 'clkdm' is enabled. No return value. + * Iterates through @clkdm_deps, looking up the struct clockdomain named by + * clkdm_name and storing the clockdomain pointer in the struct clkdm_dep. + * No return value. */ -static void _clkdm_add_autodeps(struct clockdomain *clkdm) +static void _resolve_clkdm_deps(struct clockdomain *clkdm, + struct clkdm_dep *clkdm_deps) { - struct clkdm_pwrdm_autodep *autodep; + struct clkdm_dep *cd; - for (autodep = autodeps; autodep->pwrdm_name; autodep++) { - if (!autodep->pwrdm) + for (cd = clkdm_deps; cd && cd->clkdm_name; cd++) { + if (cd->clkdm) continue; + cd->clkdm = _clkdm_lookup(cd->clkdm_name); - pr_debug("clockdomain: adding %s sleepdep/wkdep for " - "pwrdm %s\n", autodep->pwrdm_name, - clkdm->pwrdm->name); - - pwrdm_add_sleepdep(clkdm->pwrdm, autodep->pwrdm); - pwrdm_add_wkdep(clkdm->pwrdm, autodep->pwrdm); + WARN(!cd->clkdm, "clockdomain: %s: could not find clkdm %s while resolving dependencies - should never happen", + clkdm->name, cd->clkdm_name); } } -/* - * _clkdm_add_autodeps - remove auto sleepdeps/wkdeps from clkdm - * @clkdm: struct clockdomain * +/** + * _clkdm_add_wkdep - add a wakeup dependency from clkdm2 to clkdm1 (lockless) + * @clkdm1: wake this struct clockdomain * up (dependent) + * @clkdm2: when this struct clockdomain * wakes up (source) * - * Remove the "autodep" sleep & wakeup dependencies from clockdomain 'clkdm' - * in hardware-supervised mode. Meant to be called from clock framework - * when a clock inside clockdomain 'clkdm' is disabled. No return value. + * When the clockdomain represented by @clkdm2 wakes up, wake up + * @clkdm1. Implemented in hardware on the OMAP, this feature is + * designed to reduce wakeup latency of the dependent clockdomain @clkdm1. + * Returns -EINVAL if presented with invalid clockdomain pointers, + * -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or 0 upon + * success. */ -static void _clkdm_del_autodeps(struct clockdomain *clkdm) +static int _clkdm_add_wkdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) { - struct clkdm_pwrdm_autodep *autodep; + struct clkdm_dep *cd; + int ret = 0; - for (autodep = autodeps; autodep->pwrdm_name; autodep++) { - if (!autodep->pwrdm) - continue; + if (!clkdm1 || !clkdm2) + return -EINVAL; - pr_debug("clockdomain: removing %s sleepdep/wkdep for " - "pwrdm %s\n", autodep->pwrdm_name, - clkdm->pwrdm->name); + cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); + if (IS_ERR(cd)) + ret = PTR_ERR(cd); - pwrdm_del_sleepdep(clkdm->pwrdm, autodep->pwrdm); - pwrdm_del_wkdep(clkdm->pwrdm, autodep->pwrdm); + if (!arch_clkdm || !arch_clkdm->clkdm_add_wkdep) + ret = -EINVAL; + + if (ret) { + pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", + clkdm1->name, clkdm2->name); + return ret; } -} + cd->wkdep_usecount++; + if (cd->wkdep_usecount == 1) { + pr_debug("clockdomain: hardware will wake up %s when %s wakes up\n", + clkdm1->name, clkdm2->name); -static struct clockdomain *_clkdm_lookup(const char *name) + ret = arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2); + } + + return ret; +} + +/** + * _clkdm_del_wkdep - remove a wakeup dep from clkdm2 to clkdm1 (lockless) + * @clkdm1: wake this struct clockdomain * up (dependent) + * @clkdm2: when this struct clockdomain * wakes up (source) + * + * Remove a wakeup dependency causing @clkdm1 to wake up when @clkdm2 + * wakes up. Returns -EINVAL if presented with invalid clockdomain + * pointers, -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or + * 0 upon success. + */ +static int _clkdm_del_wkdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) { - struct clockdomain *clkdm, *temp_clkdm; + struct clkdm_dep *cd; + int ret = 0; - if (!name) - return NULL; + if (!clkdm1 || !clkdm2) + return -EINVAL; - clkdm = NULL; + cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); + if (IS_ERR(cd)) + ret = PTR_ERR(cd); - list_for_each_entry(temp_clkdm, &clkdm_list, node) { - if (!strcmp(name, temp_clkdm->name)) { - clkdm = temp_clkdm; - break; - } + if (!arch_clkdm || !arch_clkdm->clkdm_del_wkdep) + ret = -EINVAL; + + if (ret) { + pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", + clkdm1->name, clkdm2->name); + return ret; } - return clkdm; -} + cd->wkdep_usecount--; + if (cd->wkdep_usecount == 0) { + pr_debug("clockdomain: hardware will no longer wake up %s after %s wakes up\n", + clkdm1->name, clkdm2->name); + ret = arch_clkdm->clkdm_del_wkdep(clkdm1, clkdm2); + } -/* Public functions */ + return ret; +} /** - * clkdm_init - set up the clockdomain layer - * @clkdms: optional pointer to an array of clockdomains to register - * @init_autodeps: optional pointer to an array of autodeps to register + * _clkdm_add_sleepdep - add a sleep dependency from clkdm2 to clkdm1 (lockless) + * @clkdm1: prevent this struct clockdomain * from sleeping (dependent) + * @clkdm2: when this struct clockdomain * is active (source) * - * Set up internal state. If a pointer to an array of clockdomains - * was supplied, loop through the list of clockdomains, register all - * that are available on the current platform. Similarly, if a - * pointer to an array of clockdomain-powerdomain autodependencies was - * provided, register those. No return value. + * Prevent @clkdm1 from automatically going inactive (and then to + * retention or off) if @clkdm2 is active. Returns -EINVAL if + * presented with invalid clockdomain pointers or called on a machine + * that does not support software-configurable hardware sleep + * dependencies, -ENOENT if the specified dependency cannot be set in + * hardware, or 0 upon success. */ -void clkdm_init(struct clockdomain **clkdms, - struct clkdm_pwrdm_autodep *init_autodeps) +static int _clkdm_add_sleepdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) { - struct clockdomain **c = NULL; - struct clkdm_pwrdm_autodep *autodep = NULL; + struct clkdm_dep *cd; + int ret = 0; + + if (!clkdm1 || !clkdm2) + return -EINVAL; - if (clkdms) - for (c = clkdms; *c; c++) - clkdm_register(*c); + cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); + if (IS_ERR(cd)) + ret = PTR_ERR(cd); - autodeps = init_autodeps; - if (autodeps) - for (autodep = autodeps; autodep->pwrdm_name; autodep++) - _autodep_lookup(autodep); + if (!arch_clkdm || !arch_clkdm->clkdm_add_sleepdep) + ret = -EINVAL; + + if (ret) { + pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", + clkdm1->name, clkdm2->name); + return ret; + } + + cd->sleepdep_usecount++; + if (cd->sleepdep_usecount == 1) { + pr_debug("clockdomain: will prevent %s from sleeping if %s is active\n", + clkdm1->name, clkdm2->name); + + ret = arch_clkdm->clkdm_add_sleepdep(clkdm1, clkdm2); + } + + return ret; } /** - * clkdm_register - register a clockdomain - * @clkdm: struct clockdomain * to register + * _clkdm_del_sleepdep - remove a sleep dep from clkdm2 to clkdm1 (lockless) + * @clkdm1: prevent this struct clockdomain * from sleeping (dependent) + * @clkdm2: when this struct clockdomain * is active (source) * - * Adds a clockdomain to the internal clockdomain list. - * Returns -EINVAL if given a null pointer, -EEXIST if a clockdomain is - * already registered by the provided name, or 0 upon success. + * Allow @clkdm1 to automatically go inactive (and then to retention or + * off), independent of the activity state of @clkdm2. Returns -EINVAL + * if presented with invalid clockdomain pointers or called on a machine + * that does not support software-configurable hardware sleep dependencies, + * -ENOENT if the specified dependency cannot be cleared in hardware, or + * 0 upon success. */ -int clkdm_register(struct clockdomain *clkdm) +static int _clkdm_del_sleepdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) { - int ret = -EINVAL; - struct powerdomain *pwrdm; + struct clkdm_dep *cd; + int ret = 0; - if (!clkdm || !clkdm->name) + if (!clkdm1 || !clkdm2) return -EINVAL; - if (!omap_chip_is(clkdm->omap_chip)) - return -EINVAL; + cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); + if (IS_ERR(cd)) + ret = PTR_ERR(cd); - pwrdm = pwrdm_lookup(clkdm->pwrdm_name); - if (!pwrdm) { - pr_debug("clockdomain: clkdm_register %s: powerdomain %s " - "does not exist\n", clkdm->name, clkdm->pwrdm_name); - return -EINVAL; + if (!arch_clkdm || !arch_clkdm->clkdm_del_sleepdep) + ret = -EINVAL; + + if (ret) { + pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", + clkdm1->name, clkdm2->name); + return ret; } - clkdm->pwrdm = pwrdm; - mutex_lock(&clkdm_mutex); - /* Verify that the clockdomain is not already registered */ - if (_clkdm_lookup(clkdm->name)) { - ret = -EEXIST; - goto cr_unlock; - }; + cd->sleepdep_usecount--; + if (cd->sleepdep_usecount == 0) { + pr_debug("clockdomain: will no longer prevent %s from sleeping if %s is active\n", + clkdm1->name, clkdm2->name); - list_add(&clkdm->node, &clkdm_list); + ret = arch_clkdm->clkdm_del_sleepdep(clkdm1, clkdm2); + } - pwrdm_add_clkdm(pwrdm, clkdm); + return ret; +} - pr_debug("clockdomain: registered %s\n", clkdm->name); - ret = 0; +/* Public functions */ + +/** + * clkdm_register_platform_funcs - register clockdomain implementation fns + * @co: func pointers for arch specific implementations + * + * Register the list of function pointers used to implement the + * clockdomain functions on different OMAP SoCs. Should be called + * before any other clkdm_register*() function. Returns -EINVAL if + * @co is null, -EEXIST if platform functions have already been + * registered, or 0 upon success. + */ +int clkdm_register_platform_funcs(struct clkdm_ops *co) +{ + if (!co) + return -EINVAL; -cr_unlock: - mutex_unlock(&clkdm_mutex); + if (arch_clkdm) + return -EEXIST; - return ret; + arch_clkdm = co; + + return 0; +}; + +/** + * clkdm_register_clkdms - register SoC clockdomains + * @cs: pointer to an array of struct clockdomain to register + * + * Register the clockdomains available on a particular OMAP SoC. Must + * be called after clkdm_register_platform_funcs(). May be called + * multiple times. Returns -EACCES if called before + * clkdm_register_platform_funcs(); -EINVAL if the argument @cs is + * null; or 0 upon success. + */ +int clkdm_register_clkdms(struct clockdomain **cs) +{ + struct clockdomain **c = NULL; + + if (!arch_clkdm) + return -EACCES; + + if (!cs) + return -EINVAL; + + for (c = cs; *c; c++) + _clkdm_register(*c); + + return 0; } /** - * clkdm_unregister - unregister a clockdomain - * @clkdm: struct clockdomain * to unregister + * clkdm_register_autodeps - register autodeps (if required) + * @ia: pointer to a static array of struct clkdm_autodep to register + * + * Register clockdomain "automatic dependencies." These are + * clockdomain wakeup and sleep dependencies that are automatically + * added whenever the first clock inside a clockdomain is enabled, and + * removed whenever the last clock inside a clockdomain is disabled. + * These are currently only used on OMAP3 devices, and are deprecated, + * since they waste energy. However, until the OMAP2/3 IP block + * enable/disable sequence can be converted to match the OMAP4 + * sequence, they are needed. * - * Removes a clockdomain from the internal clockdomain list. Returns - * -EINVAL if clkdm argument is NULL. + * Must be called only after all of the SoC clockdomains are + * registered, since the function will resolve autodep clockdomain + * names into clockdomain pointers. + * + * The struct clkdm_autodep @ia array must be static, as this function + * does not copy the array elements. + * + * Returns -EACCES if called before any clockdomains have been + * registered, -EINVAL if called with a null @ia argument, -EEXIST if + * autodeps have already been registered, or 0 upon success. */ -int clkdm_unregister(struct clockdomain *clkdm) +int clkdm_register_autodeps(struct clkdm_autodep *ia) { - if (!clkdm) + struct clkdm_autodep *a = NULL; + + if (list_empty(&clkdm_list)) + return -EACCES; + + if (!ia) return -EINVAL; - pwrdm_del_clkdm(clkdm->pwrdm, clkdm); + if (autodeps) + return -EEXIST; + + autodeps = ia; + for (a = autodeps; a->clkdm.ptr; a++) + _autodep_lookup(a); - mutex_lock(&clkdm_mutex); - list_del(&clkdm->node); - mutex_unlock(&clkdm_mutex); + return 0; +} + +/** + * clkdm_complete_init - set up the clockdomain layer + * + * Put all clockdomains into software-supervised mode; PM code should + * later enable hardware-supervised mode as appropriate. Must be + * called after clkdm_register_clkdms(). Returns -EACCES if called + * before clkdm_register_clkdms(), or 0 upon success. + */ +int clkdm_complete_init(void) +{ + struct clockdomain *clkdm; + + if (list_empty(&clkdm_list)) + return -EACCES; + + list_for_each_entry(clkdm, &clkdm_list, node) { + if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) + clkdm_wakeup(clkdm); + else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO) + clkdm_deny_idle(clkdm); - pr_debug("clockdomain: unregistered %s\n", clkdm->name); + _resolve_clkdm_deps(clkdm, clkdm->wkdep_srcs); + clkdm_clear_all_wkdeps(clkdm); + + _resolve_clkdm_deps(clkdm, clkdm->sleepdep_srcs); + clkdm_clear_all_sleepdeps(clkdm); + } return 0; } @@ -257,8 +484,8 @@ int clkdm_unregister(struct clockdomain *clkdm) * clkdm_lookup - look up a clockdomain by name, return a pointer * @name: name of clockdomain * - * Find a registered clockdomain by its name. Returns a pointer to the - * struct clockdomain if found, or NULL otherwise. + * Find a registered clockdomain by its name @name. Returns a pointer + * to the struct clockdomain if found, or NULL otherwise. */ struct clockdomain *clkdm_lookup(const char *name) { @@ -269,14 +496,12 @@ struct clockdomain *clkdm_lookup(const char *name) clkdm = NULL; - mutex_lock(&clkdm_mutex); list_for_each_entry(temp_clkdm, &clkdm_list, node) { if (!strcmp(name, temp_clkdm->name)) { clkdm = temp_clkdm; break; } } - mutex_unlock(&clkdm_mutex); return clkdm; } @@ -285,8 +510,8 @@ struct clockdomain *clkdm_lookup(const char *name) * clkdm_for_each - call function on each registered clockdomain * @fn: callback function * * - * Call the supplied function for each registered clockdomain. - * The callback function can return anything but 0 to bail + * Call the supplied function @fn for each registered clockdomain. + * The callback function @fn can return anything but 0 to bail * out early from the iterator. The callback function is called with * the clkdm_mutex held, so no clockdomain structure manipulation * functions should be called from the callback, although hardware @@ -295,7 +520,8 @@ struct clockdomain *clkdm_lookup(const char *name) * anything else to indicate failure; or -EINVAL if the function pointer * is null. */ -int clkdm_for_each(int (*fn)(struct clockdomain *clkdm)) +int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user), + void *user) { struct clockdomain *clkdm; int ret = 0; @@ -303,13 +529,11 @@ int clkdm_for_each(int (*fn)(struct clockdomain *clkdm)) if (!fn) return -EINVAL; - mutex_lock(&clkdm_mutex); list_for_each_entry(clkdm, &clkdm_list, node) { - ret = (*fn)(clkdm); + ret = (*fn)(clkdm, user); if (ret) break; } - mutex_unlock(&clkdm_mutex); return ret; } @@ -320,303 +544,753 @@ int clkdm_for_each(int (*fn)(struct clockdomain *clkdm)) * @clkdm: struct clockdomain * * * Return a pointer to the struct powerdomain that the specified clockdomain - * 'clkdm' exists in, or returns NULL if clkdm argument is NULL. + * @clkdm exists in, or returns NULL if @clkdm is NULL. */ struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm) { if (!clkdm) return NULL; - return clkdm->pwrdm; + return clkdm->pwrdm.ptr; } /* Hardware clockdomain control */ /** - * omap2_clkdm_clktrctrl_read - read the clkdm's current state transition mode - * @clk: struct clk * of a clockdomain + * clkdm_add_wkdep - add a wakeup dependency from clkdm2 to clkdm1 + * @clkdm1: wake this struct clockdomain * up (dependent) + * @clkdm2: when this struct clockdomain * wakes up (source) * - * Return the clockdomain's current state transition mode from the - * corresponding domain CM_CLKSTCTRL register. Returns -EINVAL if clk - * is NULL or the current mode upon success. + * When the clockdomain represented by @clkdm2 wakes up, wake up + * @clkdm1. Implemented in hardware on the OMAP, this feature is + * designed to reduce wakeup latency of the dependent clockdomain @clkdm1. + * Returns -EINVAL if presented with invalid clockdomain pointers, + * -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or 0 upon + * success. */ -static int omap2_clkdm_clktrctrl_read(struct clockdomain *clkdm) +int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) { - u32 v; + struct clkdm_dep *cd; + int ret; + + if (!clkdm1 || !clkdm2) + return -EINVAL; + + cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); + if (IS_ERR(cd)) + return PTR_ERR(cd); + + pwrdm_lock(cd->clkdm->pwrdm.ptr); + ret = _clkdm_add_wkdep(clkdm1, clkdm2); + pwrdm_unlock(cd->clkdm->pwrdm.ptr); + return ret; +} + +/** + * clkdm_del_wkdep - remove a wakeup dependency from clkdm2 to clkdm1 + * @clkdm1: wake this struct clockdomain * up (dependent) + * @clkdm2: when this struct clockdomain * wakes up (source) + * + * Remove a wakeup dependency causing @clkdm1 to wake up when @clkdm2 + * wakes up. Returns -EINVAL if presented with invalid clockdomain + * pointers, -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or + * 0 upon success. + */ +int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) +{ + struct clkdm_dep *cd; + int ret; + + if (!clkdm1 || !clkdm2) + return -EINVAL; + + cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); + if (IS_ERR(cd)) + return PTR_ERR(cd); + + pwrdm_lock(cd->clkdm->pwrdm.ptr); + ret = _clkdm_del_wkdep(clkdm1, clkdm2); + pwrdm_unlock(cd->clkdm->pwrdm.ptr); + + return ret; +} + +/** + * clkdm_read_wkdep - read wakeup dependency state from clkdm2 to clkdm1 + * @clkdm1: wake this struct clockdomain * up (dependent) + * @clkdm2: when this struct clockdomain * wakes up (source) + * + * Return 1 if a hardware wakeup dependency exists wherein @clkdm1 will be + * awoken when @clkdm2 wakes up; 0 if dependency is not set; -EINVAL + * if either clockdomain pointer is invalid; or -ENOENT if the hardware + * is incapable. + * + * REVISIT: Currently this function only represents software-controllable + * wakeup dependencies. Wakeup dependencies fixed in hardware are not + * yet handled here. + */ +int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) +{ + struct clkdm_dep *cd; + int ret = 0; + + if (!clkdm1 || !clkdm2) + return -EINVAL; + + cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); + if (IS_ERR(cd)) + ret = PTR_ERR(cd); + + if (!arch_clkdm || !arch_clkdm->clkdm_read_wkdep) + ret = -EINVAL; + + if (ret) { + pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", + clkdm1->name, clkdm2->name); + return ret; + } + + /* XXX It's faster to return the wkdep_usecount */ + return arch_clkdm->clkdm_read_wkdep(clkdm1, clkdm2); +} + +/** + * clkdm_clear_all_wkdeps - remove all wakeup dependencies from target clkdm + * @clkdm: struct clockdomain * to remove all wakeup dependencies from + * + * Remove all inter-clockdomain wakeup dependencies that could cause + * @clkdm to wake. Intended to be used during boot to initialize the + * PRCM to a known state, after all clockdomains are put into swsup idle + * and woken up. Returns -EINVAL if @clkdm pointer is invalid, or + * 0 upon success. + */ +int clkdm_clear_all_wkdeps(struct clockdomain *clkdm) +{ if (!clkdm) return -EINVAL; - v = cm_read_mod_reg(clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL); - v &= clkdm->clktrctrl_mask; - v >>= __ffs(clkdm->clktrctrl_mask); + if (!arch_clkdm || !arch_clkdm->clkdm_clear_all_wkdeps) + return -EINVAL; - return v; + return arch_clkdm->clkdm_clear_all_wkdeps(clkdm); } /** - * omap2_clkdm_sleep - force clockdomain sleep transition + * clkdm_add_sleepdep - add a sleep dependency from clkdm2 to clkdm1 + * @clkdm1: prevent this struct clockdomain * from sleeping (dependent) + * @clkdm2: when this struct clockdomain * is active (source) + * + * Prevent @clkdm1 from automatically going inactive (and then to + * retention or off) if @clkdm2 is active. Returns -EINVAL if + * presented with invalid clockdomain pointers or called on a machine + * that does not support software-configurable hardware sleep + * dependencies, -ENOENT if the specified dependency cannot be set in + * hardware, or 0 upon success. + */ +int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) +{ + struct clkdm_dep *cd; + int ret; + + if (!clkdm1 || !clkdm2) + return -EINVAL; + + cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); + if (IS_ERR(cd)) + return PTR_ERR(cd); + + pwrdm_lock(cd->clkdm->pwrdm.ptr); + ret = _clkdm_add_sleepdep(clkdm1, clkdm2); + pwrdm_unlock(cd->clkdm->pwrdm.ptr); + + return ret; +} + +/** + * clkdm_del_sleepdep - remove a sleep dependency from clkdm2 to clkdm1 + * @clkdm1: prevent this struct clockdomain * from sleeping (dependent) + * @clkdm2: when this struct clockdomain * is active (source) + * + * Allow @clkdm1 to automatically go inactive (and then to retention or + * off), independent of the activity state of @clkdm2. Returns -EINVAL + * if presented with invalid clockdomain pointers or called on a machine + * that does not support software-configurable hardware sleep dependencies, + * -ENOENT if the specified dependency cannot be cleared in hardware, or + * 0 upon success. + */ +int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) +{ + struct clkdm_dep *cd; + int ret; + + if (!clkdm1 || !clkdm2) + return -EINVAL; + + cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); + if (IS_ERR(cd)) + return PTR_ERR(cd); + + pwrdm_lock(cd->clkdm->pwrdm.ptr); + ret = _clkdm_del_sleepdep(clkdm1, clkdm2); + pwrdm_unlock(cd->clkdm->pwrdm.ptr); + + return ret; +} + +/** + * clkdm_read_sleepdep - read sleep dependency state from clkdm2 to clkdm1 + * @clkdm1: prevent this struct clockdomain * from sleeping (dependent) + * @clkdm2: when this struct clockdomain * is active (source) + * + * Return 1 if a hardware sleep dependency exists wherein @clkdm1 will + * not be allowed to automatically go inactive if @clkdm2 is active; + * 0 if @clkdm1's automatic power state inactivity transition is independent + * of @clkdm2's; -EINVAL if either clockdomain pointer is invalid or called + * on a machine that does not support software-configurable hardware sleep + * dependencies; or -ENOENT if the hardware is incapable. + * + * REVISIT: Currently this function only represents software-controllable + * sleep dependencies. Sleep dependencies fixed in hardware are not + * yet handled here. + */ +int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) +{ + struct clkdm_dep *cd; + int ret = 0; + + if (!clkdm1 || !clkdm2) + return -EINVAL; + + cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); + if (IS_ERR(cd)) + ret = PTR_ERR(cd); + + if (!arch_clkdm || !arch_clkdm->clkdm_read_sleepdep) + ret = -EINVAL; + + if (ret) { + pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", + clkdm1->name, clkdm2->name); + return ret; + } + + /* XXX It's faster to return the sleepdep_usecount */ + return arch_clkdm->clkdm_read_sleepdep(clkdm1, clkdm2); +} + +/** + * clkdm_clear_all_sleepdeps - remove all sleep dependencies from target clkdm + * @clkdm: struct clockdomain * to remove all sleep dependencies from + * + * Remove all inter-clockdomain sleep dependencies that could prevent + * @clkdm from idling. Intended to be used during boot to initialize the + * PRCM to a known state, after all clockdomains are put into swsup idle + * and woken up. Returns -EINVAL if @clkdm pointer is invalid, or + * 0 upon success. + */ +int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm) +{ + if (!clkdm) + return -EINVAL; + + if (!arch_clkdm || !arch_clkdm->clkdm_clear_all_sleepdeps) + return -EINVAL; + + return arch_clkdm->clkdm_clear_all_sleepdeps(clkdm); +} + +/** + * clkdm_sleep_nolock - force clockdomain sleep transition (lockless) * @clkdm: struct clockdomain * * * Instruct the CM to force a sleep transition on the specified - * clockdomain 'clkdm'. Returns -EINVAL if clk is NULL or if - * clockdomain does not support software-initiated sleep; 0 upon - * success. + * clockdomain @clkdm. Only for use by the powerdomain code. Returns + * -EINVAL if @clkdm is NULL or if clockdomain does not support + * software-initiated sleep; 0 upon success. */ -int omap2_clkdm_sleep(struct clockdomain *clkdm) +int clkdm_sleep_nolock(struct clockdomain *clkdm) { + int ret; + if (!clkdm) return -EINVAL; if (!(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) { - pr_debug("clockdomain: %s does not support forcing " - "sleep via software\n", clkdm->name); + pr_debug("clockdomain: %s does not support forcing sleep via software\n", + clkdm->name); return -EINVAL; } - pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name); - - if (cpu_is_omap24xx()) { + if (!arch_clkdm || !arch_clkdm->clkdm_sleep) + return -EINVAL; - cm_set_mod_reg_bits(OMAP24XX_FORCESTATE, - clkdm->pwrdm->prcm_offs, PM_PWSTCTRL); + pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name); - } else if (cpu_is_omap34xx()) { + clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; + ret = arch_clkdm->clkdm_sleep(clkdm); + ret |= pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); - u32 v = (OMAP34XX_CLKSTCTRL_FORCE_SLEEP << - __ffs(clkdm->clktrctrl_mask)); + return ret; +} - cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, v, - clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL); +/** + * clkdm_sleep - force clockdomain sleep transition + * @clkdm: struct clockdomain * + * + * Instruct the CM to force a sleep transition on the specified + * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if + * clockdomain does not support software-initiated sleep; 0 upon + * success. + */ +int clkdm_sleep(struct clockdomain *clkdm) +{ + int ret; - } else { - BUG(); - }; + pwrdm_lock(clkdm->pwrdm.ptr); + ret = clkdm_sleep_nolock(clkdm); + pwrdm_unlock(clkdm->pwrdm.ptr); - return 0; + return ret; } /** - * omap2_clkdm_wakeup - force clockdomain wakeup transition + * clkdm_wakeup_nolock - force clockdomain wakeup transition (lockless) * @clkdm: struct clockdomain * * * Instruct the CM to force a wakeup transition on the specified - * clockdomain 'clkdm'. Returns -EINVAL if clkdm is NULL or if the - * clockdomain does not support software-controlled wakeup; 0 upon - * success. + * clockdomain @clkdm. Only for use by the powerdomain code. Returns + * -EINVAL if @clkdm is NULL or if the clockdomain does not support + * software-controlled wakeup; 0 upon success. */ -int omap2_clkdm_wakeup(struct clockdomain *clkdm) +int clkdm_wakeup_nolock(struct clockdomain *clkdm) { + int ret; + if (!clkdm) return -EINVAL; if (!(clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) { - pr_debug("clockdomain: %s does not support forcing " - "wakeup via software\n", clkdm->name); + pr_debug("clockdomain: %s does not support forcing wakeup via software\n", + clkdm->name); return -EINVAL; } - pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name); - - if (cpu_is_omap24xx()) { + if (!arch_clkdm || !arch_clkdm->clkdm_wakeup) + return -EINVAL; - cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE, - clkdm->pwrdm->prcm_offs, PM_PWSTCTRL); + pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name); - } else if (cpu_is_omap34xx()) { + clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; + ret = arch_clkdm->clkdm_wakeup(clkdm); + ret |= pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); - u32 v = (OMAP34XX_CLKSTCTRL_FORCE_WAKEUP << - __ffs(clkdm->clktrctrl_mask)); + return ret; +} - cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, v, - clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL); +/** + * clkdm_wakeup - force clockdomain wakeup transition + * @clkdm: struct clockdomain * + * + * Instruct the CM to force a wakeup transition on the specified + * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if the + * clockdomain does not support software-controlled wakeup; 0 upon + * success. + */ +int clkdm_wakeup(struct clockdomain *clkdm) +{ + int ret; - } else { - BUG(); - }; + pwrdm_lock(clkdm->pwrdm.ptr); + ret = clkdm_wakeup_nolock(clkdm); + pwrdm_unlock(clkdm->pwrdm.ptr); - return 0; + return ret; } /** - * omap2_clkdm_allow_idle - enable hwsup idle transitions for clkdm + * clkdm_allow_idle_nolock - enable hwsup idle transitions for clkdm * @clkdm: struct clockdomain * * - * Allow the hardware to automatically switch the clockdomain into - * active or idle states, as needed by downstream clocks. If the + * Allow the hardware to automatically switch the clockdomain @clkdm + * into active or idle states, as needed by downstream clocks. If the * clockdomain has any downstream clocks enabled in the clock * framework, wkdep/sleepdep autodependencies are added; this is so - * device drivers can read and write to the device. No return value. + * device drivers can read and write to the device. Only for use by + * the powerdomain code. No return value. */ -void omap2_clkdm_allow_idle(struct clockdomain *clkdm) +void clkdm_allow_idle_nolock(struct clockdomain *clkdm) { - u32 v; - if (!clkdm) return; if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO)) { - pr_debug("clock: automatic idle transitions cannot be enabled " - "on clockdomain %s\n", clkdm->name); + pr_debug("clock: %s: automatic idle transitions cannot be enabled\n", + clkdm->name); return; } + if (!arch_clkdm || !arch_clkdm->clkdm_allow_idle) + return; + pr_debug("clockdomain: enabling automatic idle transitions for %s\n", clkdm->name); - if (atomic_read(&clkdm->usecount) > 0) - _clkdm_add_autodeps(clkdm); - - if (cpu_is_omap24xx()) - v = OMAP24XX_CLKSTCTRL_ENABLE_AUTO; - else if (cpu_is_omap34xx()) - v = OMAP34XX_CLKSTCTRL_ENABLE_AUTO; - else - BUG(); - + clkdm->_flags |= _CLKDM_FLAG_HWSUP_ENABLED; + arch_clkdm->clkdm_allow_idle(clkdm); + pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); +} - cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, - v << __ffs(clkdm->clktrctrl_mask), - clkdm->pwrdm->prcm_offs, - CM_CLKSTCTRL); +/** + * clkdm_allow_idle - enable hwsup idle transitions for clkdm + * @clkdm: struct clockdomain * + * + * Allow the hardware to automatically switch the clockdomain @clkdm into + * active or idle states, as needed by downstream clocks. If the + * clockdomain has any downstream clocks enabled in the clock + * framework, wkdep/sleepdep autodependencies are added; this is so + * device drivers can read and write to the device. No return value. + */ +void clkdm_allow_idle(struct clockdomain *clkdm) +{ + pwrdm_lock(clkdm->pwrdm.ptr); + clkdm_allow_idle_nolock(clkdm); + pwrdm_unlock(clkdm->pwrdm.ptr); } /** - * omap2_clkdm_deny_idle - disable hwsup idle transitions for clkdm + * clkdm_deny_idle - disable hwsup idle transitions for clkdm * @clkdm: struct clockdomain * * * Prevent the hardware from automatically switching the clockdomain - * into inactive or idle states. If the clockdomain has downstream - * clocks enabled in the clock framework, wkdep/sleepdep - * autodependencies are removed. No return value. + * @clkdm into inactive or idle states. If the clockdomain has + * downstream clocks enabled in the clock framework, wkdep/sleepdep + * autodependencies are removed. Only for use by the powerdomain + * code. No return value. */ -void omap2_clkdm_deny_idle(struct clockdomain *clkdm) +void clkdm_deny_idle_nolock(struct clockdomain *clkdm) { - u32 v; - if (!clkdm) return; if (!(clkdm->flags & CLKDM_CAN_DISABLE_AUTO)) { - pr_debug("clockdomain: automatic idle transitions cannot be " - "disabled on %s\n", clkdm->name); + pr_debug("clockdomain: %s: automatic idle transitions cannot be disabled\n", + clkdm->name); return; } + if (!arch_clkdm || !arch_clkdm->clkdm_deny_idle) + return; + pr_debug("clockdomain: disabling automatic idle transitions for %s\n", clkdm->name); - if (cpu_is_omap24xx()) - v = OMAP24XX_CLKSTCTRL_DISABLE_AUTO; - else if (cpu_is_omap34xx()) - v = OMAP34XX_CLKSTCTRL_DISABLE_AUTO; - else - BUG(); + clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; + arch_clkdm->clkdm_deny_idle(clkdm); + pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); +} + +/** + * clkdm_deny_idle - disable hwsup idle transitions for clkdm + * @clkdm: struct clockdomain * + * + * Prevent the hardware from automatically switching the clockdomain + * @clkdm into inactive or idle states. If the clockdomain has + * downstream clocks enabled in the clock framework, wkdep/sleepdep + * autodependencies are removed. No return value. + */ +void clkdm_deny_idle(struct clockdomain *clkdm) +{ + pwrdm_lock(clkdm->pwrdm.ptr); + clkdm_deny_idle_nolock(clkdm); + pwrdm_unlock(clkdm->pwrdm.ptr); +} + +/** + * clkdm_in_hwsup - is clockdomain @clkdm have hardware-supervised idle enabled? + * @clkdm: struct clockdomain * + * + * Returns true if clockdomain @clkdm currently has + * hardware-supervised idle enabled, or false if it does not or if + * @clkdm is NULL. It is only valid to call this function after + * clkdm_init() has been called. This function does not actually read + * bits from the hardware; it instead tests an in-memory flag that is + * changed whenever the clockdomain code changes the auto-idle mode. + */ +bool clkdm_in_hwsup(struct clockdomain *clkdm) +{ + bool ret; - cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, - v << __ffs(clkdm->clktrctrl_mask), - clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL); + if (!clkdm) + return false; - if (atomic_read(&clkdm->usecount) > 0) - _clkdm_del_autodeps(clkdm); + ret = (clkdm->_flags & _CLKDM_FLAG_HWSUP_ENABLED) ? true : false; + + return ret; } +/** + * clkdm_missing_idle_reporting - can @clkdm enter autoidle even if in use? + * @clkdm: struct clockdomain * + * + * Returns true if clockdomain @clkdm has the + * CLKDM_MISSING_IDLE_REPORTING flag set, or false if not or @clkdm is + * null. More information is available in the documentation for the + * CLKDM_MISSING_IDLE_REPORTING macro. + */ +bool clkdm_missing_idle_reporting(struct clockdomain *clkdm) +{ + if (!clkdm) + return false; + + return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false; +} -/* Clockdomain-to-clock framework interface code */ +/* Public autodep handling functions (deprecated) */ /** - * omap2_clkdm_clk_enable - add an enabled downstream clock to this clkdm + * clkdm_add_autodeps - add auto sleepdeps/wkdeps to clkdm upon clock enable * @clkdm: struct clockdomain * - * @clk: struct clk * of the enabled downstream clock * - * Increment the usecount of this clockdomain 'clkdm' and ensure that - * it is awake. Intended to be called by clk_enable() code. If the - * clockdomain is in software-supervised idle mode, force the - * clockdomain to wake. If the clockdomain is in hardware-supervised - * idle mode, add clkdm-pwrdm autodependencies, to ensure that devices - * in the clockdomain can be read from/written to by on-chip processors. - * Returns -EINVAL if passed null pointers; returns 0 upon success or - * if the clockdomain is in hwsup idle mode. + * Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm' + * in hardware-supervised mode. Meant to be called from clock framework + * when a clock inside clockdomain 'clkdm' is enabled. No return value. + * + * XXX autodeps are deprecated and should be removed at the earliest + * opportunity */ -int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) +void clkdm_add_autodeps(struct clockdomain *clkdm) { - int v; + struct clkdm_autodep *autodep; + + if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS) + return; + + for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { + if (IS_ERR(autodep->clkdm.ptr)) + continue; + + pr_debug("clockdomain: %s: adding %s sleepdep/wkdep\n", + clkdm->name, autodep->clkdm.ptr->name); + + _clkdm_add_sleepdep(clkdm, autodep->clkdm.ptr); + _clkdm_add_wkdep(clkdm, autodep->clkdm.ptr); + } +} + +/** + * clkdm_del_autodeps - remove auto sleepdeps/wkdeps from clkdm + * @clkdm: struct clockdomain * + * + * Remove the "autodep" sleep & wakeup dependencies from clockdomain 'clkdm' + * in hardware-supervised mode. Meant to be called from clock framework + * when a clock inside clockdomain 'clkdm' is disabled. No return value. + * + * XXX autodeps are deprecated and should be removed at the earliest + * opportunity + */ +void clkdm_del_autodeps(struct clockdomain *clkdm) +{ + struct clkdm_autodep *autodep; + + if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS) + return; + + for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { + if (IS_ERR(autodep->clkdm.ptr)) + continue; + + pr_debug("clockdomain: %s: removing %s sleepdep/wkdep\n", + clkdm->name, autodep->clkdm.ptr->name); + + _clkdm_del_sleepdep(clkdm, autodep->clkdm.ptr); + _clkdm_del_wkdep(clkdm, autodep->clkdm.ptr); + } +} + +/* Clockdomain-to-clock/hwmod framework interface code */ + +static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm) +{ + if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable) + return -EINVAL; + + pwrdm_lock(clkdm->pwrdm.ptr); /* + * For arch's with no autodeps, clkcm_clk_enable + * should be called for every clock instance or hwmod that is + * enabled, so the clkdm can be force woken up. + */ + clkdm->usecount++; + if (clkdm->usecount > 1 && autodeps) { + pwrdm_unlock(clkdm->pwrdm.ptr); + return 0; + } + + arch_clkdm->clkdm_clk_enable(clkdm); + pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); + pwrdm_unlock(clkdm->pwrdm.ptr); + + pr_debug("clockdomain: %s: enabled\n", clkdm->name); + + return 0; +} + +/** + * clkdm_clk_enable - add an enabled downstream clock to this clkdm + * @clkdm: struct clockdomain * + * @clk: struct clk * of the enabled downstream clock + * + * Increment the usecount of the clockdomain @clkdm and ensure that it + * is awake before @clk is enabled. Intended to be called by + * clk_enable() code. If the clockdomain is in software-supervised + * idle mode, force the clockdomain to wake. If the clockdomain is in + * hardware-supervised idle mode, add clkdm-pwrdm autodependencies, to + * ensure that devices in the clockdomain can be read from/written to + * by on-chip processors. Returns -EINVAL if passed null pointers; + * returns 0 upon success or if the clockdomain is in hwsup idle mode. + */ +int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) +{ + /* * XXX Rewrite this code to maintain a list of enabled * downstream clocks for debugging purposes? */ - if (!clkdm || !clk) + if (!clk) return -EINVAL; - if (atomic_inc_return(&clkdm->usecount) > 1) - return 0; + return _clkdm_clk_hwmod_enable(clkdm); +} - /* Clockdomain now has one enabled downstream clock */ +/** + * clkdm_clk_disable - remove an enabled downstream clock from this clkdm + * @clkdm: struct clockdomain * + * @clk: struct clk * of the disabled downstream clock + * + * Decrement the usecount of this clockdomain @clkdm when @clk is + * disabled. Intended to be called by clk_disable() code. If the + * clockdomain usecount goes to 0, put the clockdomain to sleep + * (software-supervised mode) or remove the clkdm autodependencies + * (hardware-supervised mode). Returns -EINVAL if passed null + * pointers; -ERANGE if the @clkdm usecount underflows; or returns 0 + * upon success or if the clockdomain is in hwsup idle mode. + */ +int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) +{ + if (!clkdm || !clk || !arch_clkdm || !arch_clkdm->clkdm_clk_disable) + return -EINVAL; - pr_debug("clockdomain: clkdm %s: clk %s now enabled\n", clkdm->name, - clk->name); + pwrdm_lock(clkdm->pwrdm.ptr); - v = omap2_clkdm_clktrctrl_read(clkdm); + /* corner case: disabling unused clocks */ + if ((__clk_get_enable_count(clk) == 0) && clkdm->usecount == 0) + goto ccd_exit; - if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) || - (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO)) - _clkdm_add_autodeps(clkdm); - else - omap2_clkdm_wakeup(clkdm); + if (clkdm->usecount == 0) { + pwrdm_unlock(clkdm->pwrdm.ptr); + WARN_ON(1); /* underflow */ + return -ERANGE; + } + + clkdm->usecount--; + if (clkdm->usecount > 0) { + pwrdm_unlock(clkdm->pwrdm.ptr); + return 0; + } + + arch_clkdm->clkdm_clk_disable(clkdm); + pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); + + pr_debug("clockdomain: %s: disabled\n", clkdm->name); + +ccd_exit: + pwrdm_unlock(clkdm->pwrdm.ptr); return 0; } /** - * omap2_clkdm_clk_disable - remove an enabled downstream clock from this clkdm + * clkdm_hwmod_enable - add an enabled downstream hwmod to this clkdm * @clkdm: struct clockdomain * - * @clk: struct clk * of the disabled downstream clock + * @oh: struct omap_hwmod * of the enabled downstream hwmod * - * Decrement the usecount of this clockdomain 'clkdm'. Intended to be - * called by clk_disable() code. If the usecount goes to 0, put the - * clockdomain to sleep (software-supervised mode) or remove the - * clkdm-pwrdm autodependencies (hardware-supervised mode). Returns - * -EINVAL if passed null pointers; -ERANGE if the clkdm usecount - * underflows and debugging is enabled; or returns 0 upon success or - * if the clockdomain is in hwsup idle mode. + * Increment the usecount of the clockdomain @clkdm and ensure that it + * is awake before @oh is enabled. Intended to be called by + * module_enable() code. + * If the clockdomain is in software-supervised idle mode, force the + * clockdomain to wake. If the clockdomain is in hardware-supervised idle + * mode, add clkdm-pwrdm autodependencies, to ensure that devices in the + * clockdomain can be read from/written to by on-chip processors. + * Returns -EINVAL if passed null pointers; + * returns 0 upon success or if the clockdomain is in hwsup idle mode. */ -int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) +int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh) { - int v; + /* The clkdm attribute does not exist yet prior OMAP4 */ + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + return 0; /* * XXX Rewrite this code to maintain a list of enabled - * downstream clocks for debugging purposes? + * downstream hwmods for debugging purposes? + */ + + if (!oh) + return -EINVAL; + + return _clkdm_clk_hwmod_enable(clkdm); +} + +/** + * clkdm_hwmod_disable - remove an enabled downstream hwmod from this clkdm + * @clkdm: struct clockdomain * + * @oh: struct omap_hwmod * of the disabled downstream hwmod + * + * Decrement the usecount of this clockdomain @clkdm when @oh is + * disabled. Intended to be called by module_disable() code. + * If the clockdomain usecount goes to 0, put the clockdomain to sleep + * (software-supervised mode) or remove the clkdm autodependencies + * (hardware-supervised mode). + * Returns -EINVAL if passed null pointers; -ERANGE if the @clkdm usecount + * underflows; or returns 0 upon success or if the clockdomain is in hwsup + * idle mode. + */ +int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh) +{ + /* The clkdm attribute does not exist yet prior OMAP4 */ + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + return 0; + + /* + * XXX Rewrite this code to maintain a list of enabled + * downstream hwmods for debugging purposes? */ - if (!clkdm || !clk) + if (!clkdm || !oh || !arch_clkdm || !arch_clkdm->clkdm_clk_disable) return -EINVAL; -#ifdef DEBUG - if (atomic_read(&clkdm->usecount) == 0) { + pwrdm_lock(clkdm->pwrdm.ptr); + + if (clkdm->usecount == 0) { + pwrdm_unlock(clkdm->pwrdm.ptr); WARN_ON(1); /* underflow */ return -ERANGE; } -#endif - if (atomic_dec_return(&clkdm->usecount) > 0) + clkdm->usecount--; + if (clkdm->usecount > 0) { + pwrdm_unlock(clkdm->pwrdm.ptr); return 0; + } - /* All downstream clocks of this clockdomain are now disabled */ - - pr_debug("clockdomain: clkdm %s: clk %s now disabled\n", clkdm->name, - clk->name); - - v = omap2_clkdm_clktrctrl_read(clkdm); + arch_clkdm->clkdm_clk_disable(clkdm); + pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); + pwrdm_unlock(clkdm->pwrdm.ptr); - if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) || - (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO)) - _clkdm_del_autodeps(clkdm); - else - omap2_clkdm_sleep(clkdm); + pr_debug("clockdomain: %s: disabled\n", clkdm->name); return 0; } diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h new file mode 100644 index 00000000000..82c37b1becc --- /dev/null +++ b/arch/arm/mach-omap2/clockdomain.h @@ -0,0 +1,237 @@ +/* + * OMAP2/3 clockdomain framework functions + * + * Copyright (C) 2008, 2012 Texas Instruments, Inc. + * Copyright (C) 2008-2011 Nokia Corporation + * + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_H +#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_H + +#include <linux/init.h> + +#include "powerdomain.h" +#include "clock.h" + +/* + * Clockdomain flags + * + * XXX Document CLKDM_CAN_* flags + * + * CLKDM_NO_AUTODEPS: Prevent "autodeps" from being added/removed from this + * clockdomain. (Currently, this applies to OMAP3 clockdomains only.) + * CLKDM_ACTIVE_WITH_MPU: The PRCM guarantees that this clockdomain is + * active whenever the MPU is active. True for interconnects and + * the WKUP clockdomains. + * CLKDM_MISSING_IDLE_REPORTING: The idle status of the IP blocks and + * clocks inside this clockdomain are not taken into account by + * the PRCM when determining whether the clockdomain is idle. + * Without this flag, if the clockdomain is set to + * hardware-supervised idle mode, the PRCM may transition the + * enclosing powerdomain to a low power state, even when devices + * inside the clockdomain and powerdomain are in use. (An example + * of such a clockdomain is the EMU clockdomain on OMAP3/4.) If + * this flag is set, and the clockdomain does not support the + * force-sleep mode, then the HW_AUTO mode will be used to put the + * clockdomain to sleep. Similarly, if the clockdomain supports + * the force-wakeup mode, then it will be used whenever a clock or + * IP block inside the clockdomain is active, rather than the + * HW_AUTO mode. + */ +#define CLKDM_CAN_FORCE_SLEEP (1 << 0) +#define CLKDM_CAN_FORCE_WAKEUP (1 << 1) +#define CLKDM_CAN_ENABLE_AUTO (1 << 2) +#define CLKDM_CAN_DISABLE_AUTO (1 << 3) +#define CLKDM_NO_AUTODEPS (1 << 4) +#define CLKDM_ACTIVE_WITH_MPU (1 << 5) +#define CLKDM_MISSING_IDLE_REPORTING (1 << 6) + +#define CLKDM_CAN_HWSUP (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO) +#define CLKDM_CAN_SWSUP (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP) +#define CLKDM_CAN_HWSUP_SWSUP (CLKDM_CAN_SWSUP | CLKDM_CAN_HWSUP) + +/** + * struct clkdm_autodep - clkdm deps to add when entering/exiting hwsup mode + * @clkdm: clockdomain to add wkdep+sleepdep on - set name member only + * + * A clockdomain that should have wkdeps and sleepdeps added when a + * clockdomain should stay active in hwsup mode; and conversely, + * removed when the clockdomain should be allowed to go inactive in + * hwsup mode. + * + * Autodeps are deprecated and should be removed after + * omap_hwmod-based fine-grained module idle control is added. + */ +struct clkdm_autodep { + union { + const char *name; + struct clockdomain *ptr; + } clkdm; +}; + +/** + * struct clkdm_dep - encode dependencies between clockdomains + * @clkdm_name: clockdomain name + * @clkdm: pointer to the struct clockdomain of @clkdm_name + * @wkdep_usecount: Number of wakeup dependencies causing this clkdm to wake + * @sleepdep_usecount: Number of sleep deps that could prevent clkdm from idle + * + * Statically defined. @clkdm is resolved from @clkdm_name at runtime and + * should not be pre-initialized. + * + * XXX Should also include hardware (fixed) dependencies. + */ +struct clkdm_dep { + const char *clkdm_name; + struct clockdomain *clkdm; + s16 wkdep_usecount; + s16 sleepdep_usecount; +}; + +/* Possible flags for struct clockdomain._flags */ +#define _CLKDM_FLAG_HWSUP_ENABLED BIT(0) + +struct omap_hwmod; + +/** + * struct clockdomain - OMAP clockdomain + * @name: clockdomain name + * @pwrdm: powerdomain containing this clockdomain + * @clktrctrl_reg: CLKSTCTRL reg for the given clock domain + * @clktrctrl_mask: CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg + * @flags: Clockdomain capability flags + * @_flags: Flags for use only by internal clockdomain code + * @dep_bit: Bit shift of this clockdomain's PM_WKDEP/CM_SLEEPDEP bit + * @prcm_partition: (OMAP4 only) PRCM partition ID for this clkdm's registers + * @cm_inst: (OMAP4 only) CM instance register offset + * @clkdm_offs: (OMAP4 only) CM clockdomain register offset + * @wkdep_srcs: Clockdomains that can be told to wake this powerdomain up + * @sleepdep_srcs: Clockdomains that can be told to keep this clkdm from inact + * @usecount: Usecount tracking + * @node: list_head to link all clockdomains together + * + * @prcm_partition should be a macro from mach-omap2/prcm44xx.h (OMAP4 only) + * @cm_inst should be a macro ending in _INST from the OMAP4 CM instance + * definitions (OMAP4 only) + * @clkdm_offs should be a macro ending in _CDOFFS from the OMAP4 CM instance + * definitions (OMAP4 only) + */ +struct clockdomain { + const char *name; + union { + const char *name; + struct powerdomain *ptr; + } pwrdm; + const u16 clktrctrl_mask; + const u8 flags; + u8 _flags; + const u8 dep_bit; + const u8 prcm_partition; + const u16 cm_inst; + const u16 clkdm_offs; + struct clkdm_dep *wkdep_srcs; + struct clkdm_dep *sleepdep_srcs; + int usecount; + struct list_head node; +}; + +/** + * struct clkdm_ops - Arch specific function implementations + * @clkdm_add_wkdep: Add a wakeup dependency between clk domains + * @clkdm_del_wkdep: Delete a wakeup dependency between clk domains + * @clkdm_read_wkdep: Read wakeup dependency state between clk domains + * @clkdm_clear_all_wkdeps: Remove all wakeup dependencies from the clk domain + * @clkdm_add_sleepdep: Add a sleep dependency between clk domains + * @clkdm_del_sleepdep: Delete a sleep dependency between clk domains + * @clkdm_read_sleepdep: Read sleep dependency state between clk domains + * @clkdm_clear_all_sleepdeps: Remove all sleep dependencies from the clk domain + * @clkdm_sleep: Force a clockdomain to sleep + * @clkdm_wakeup: Force a clockdomain to wakeup + * @clkdm_allow_idle: Enable hw supervised idle transitions for clock domain + * @clkdm_deny_idle: Disable hw supervised idle transitions for clock domain + * @clkdm_clk_enable: Put the clkdm in right state for a clock enable + * @clkdm_clk_disable: Put the clkdm in right state for a clock disable + */ +struct clkdm_ops { + int (*clkdm_add_wkdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2); + int (*clkdm_del_wkdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2); + int (*clkdm_read_wkdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2); + int (*clkdm_clear_all_wkdeps)(struct clockdomain *clkdm); + int (*clkdm_add_sleepdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2); + int (*clkdm_del_sleepdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2); + int (*clkdm_read_sleepdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2); + int (*clkdm_clear_all_sleepdeps)(struct clockdomain *clkdm); + int (*clkdm_sleep)(struct clockdomain *clkdm); + int (*clkdm_wakeup)(struct clockdomain *clkdm); + void (*clkdm_allow_idle)(struct clockdomain *clkdm); + void (*clkdm_deny_idle)(struct clockdomain *clkdm); + int (*clkdm_clk_enable)(struct clockdomain *clkdm); + int (*clkdm_clk_disable)(struct clockdomain *clkdm); +}; + +int clkdm_register_platform_funcs(struct clkdm_ops *co); +int clkdm_register_autodeps(struct clkdm_autodep *ia); +int clkdm_register_clkdms(struct clockdomain **c); +int clkdm_complete_init(void); + +struct clockdomain *clkdm_lookup(const char *name); + +int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user), + void *user); +struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm); + +int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); +int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); +int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); +int clkdm_clear_all_wkdeps(struct clockdomain *clkdm); +int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); +int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); +int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); +int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm); + +void clkdm_allow_idle_nolock(struct clockdomain *clkdm); +void clkdm_allow_idle(struct clockdomain *clkdm); +void clkdm_deny_idle_nolock(struct clockdomain *clkdm); +void clkdm_deny_idle(struct clockdomain *clkdm); +bool clkdm_in_hwsup(struct clockdomain *clkdm); +bool clkdm_missing_idle_reporting(struct clockdomain *clkdm); + +int clkdm_wakeup_nolock(struct clockdomain *clkdm); +int clkdm_wakeup(struct clockdomain *clkdm); +int clkdm_sleep_nolock(struct clockdomain *clkdm); +int clkdm_sleep(struct clockdomain *clkdm); + +int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); +int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk); +int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh); +int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh); + +extern void __init omap242x_clockdomains_init(void); +extern void __init omap243x_clockdomains_init(void); +extern void __init omap3xxx_clockdomains_init(void); +extern void __init am33xx_clockdomains_init(void); +extern void __init omap44xx_clockdomains_init(void); +extern void __init omap54xx_clockdomains_init(void); +extern void __init dra7xx_clockdomains_init(void); +void am43xx_clockdomains_init(void); + +extern void clkdm_add_autodeps(struct clockdomain *clkdm); +extern void clkdm_del_autodeps(struct clockdomain *clkdm); + +extern struct clkdm_ops omap2_clkdm_operations; +extern struct clkdm_ops omap3_clkdm_operations; +extern struct clkdm_ops omap4_clkdm_operations; +extern struct clkdm_ops am33xx_clkdm_operations; +extern struct clkdm_ops am43xx_clkdm_operations; + +extern struct clkdm_dep gfx_24xx_wkdeps[]; +extern struct clkdm_dep dsp_24xx_wkdeps[]; +extern struct clockdomain wkup_common_clkdm; + +#endif diff --git a/arch/arm/mach-omap2/clockdomains.h b/arch/arm/mach-omap2/clockdomains.h deleted file mode 100644 index cd86dcc7b42..00000000000 --- a/arch/arm/mach-omap2/clockdomains.h +++ /dev/null @@ -1,305 +0,0 @@ -/* - * OMAP2/3 clockdomains - * - * Copyright (C) 2008 Texas Instruments, Inc. - * Copyright (C) 2008 Nokia Corporation - * - * Written by Paul Walmsley - */ - -#ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_H -#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_H - -#include <mach/clockdomain.h> - -/* - * OMAP2/3-common clockdomains - */ - -/* This is an implicit clockdomain - it is never defined as such in TRM */ -static struct clockdomain wkup_clkdm = { - .name = "wkup_clkdm", - .pwrdm_name = "wkup_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430), -}; - -/* - * 2420-only clockdomains - */ - -#if defined(CONFIG_ARCH_OMAP2420) - -static struct clockdomain mpu_2420_clkdm = { - .name = "mpu_clkdm", - .pwrdm_name = "mpu_pwrdm", - .flags = CLKDM_CAN_HWSUP, - .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), -}; - -static struct clockdomain iva1_2420_clkdm = { - .name = "iva1_clkdm", - .pwrdm_name = "dsp_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP2420_AUTOSTATE_IVA_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), -}; - -#endif /* CONFIG_ARCH_OMAP2420 */ - - -/* - * 2430-only clockdomains - */ - -#if defined(CONFIG_ARCH_OMAP2430) - -static struct clockdomain mpu_2430_clkdm = { - .name = "mpu_clkdm", - .pwrdm_name = "mpu_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -}; - -static struct clockdomain mdm_clkdm = { - .name = "mdm_clkdm", - .pwrdm_name = "mdm_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP2430_AUTOSTATE_MDM_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -}; - -#endif /* CONFIG_ARCH_OMAP2430 */ - - -/* - * 24XX-only clockdomains - */ - -#if defined(CONFIG_ARCH_OMAP24XX) - -static struct clockdomain dsp_clkdm = { - .name = "dsp_clkdm", - .pwrdm_name = "dsp_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), -}; - -static struct clockdomain gfx_24xx_clkdm = { - .name = "gfx_clkdm", - .pwrdm_name = "gfx_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), -}; - -static struct clockdomain core_l3_24xx_clkdm = { - .name = "core_l3_clkdm", - .pwrdm_name = "core_pwrdm", - .flags = CLKDM_CAN_HWSUP, - .clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), -}; - -static struct clockdomain core_l4_24xx_clkdm = { - .name = "core_l4_clkdm", - .pwrdm_name = "core_pwrdm", - .flags = CLKDM_CAN_HWSUP, - .clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), -}; - -static struct clockdomain dss_24xx_clkdm = { - .name = "dss_clkdm", - .pwrdm_name = "core_pwrdm", - .flags = CLKDM_CAN_HWSUP, - .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), -}; - -#endif /* CONFIG_ARCH_OMAP24XX */ - - -/* - * 34xx clockdomains - */ - -#if defined(CONFIG_ARCH_OMAP34XX) - -static struct clockdomain mpu_34xx_clkdm = { - .name = "mpu_clkdm", - .pwrdm_name = "mpu_pwrdm", - .flags = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP, - .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct clockdomain neon_clkdm = { - .name = "neon_clkdm", - .pwrdm_name = "neon_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP3430_CLKTRCTRL_NEON_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct clockdomain iva2_clkdm = { - .name = "iva2_clkdm", - .pwrdm_name = "iva2_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct clockdomain gfx_3430es1_clkdm = { - .name = "gfx_clkdm", - .pwrdm_name = "gfx_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1), -}; - -static struct clockdomain sgx_clkdm = { - .name = "sgx_clkdm", - .pwrdm_name = "sgx_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2), -}; - -/* - * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but - * then that information was removed from the 34xx ES2+ TRM. It is - * unclear whether the core is still there, but the clockdomain logic - * is there, and must be programmed to an appropriate state if the - * CORE clockdomain is to become inactive. - */ -static struct clockdomain d2d_clkdm = { - .name = "d2d_clkdm", - .pwrdm_name = "core_pwrdm", - .flags = CLKDM_CAN_HWSUP, - .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct clockdomain core_l3_34xx_clkdm = { - .name = "core_l3_clkdm", - .pwrdm_name = "core_pwrdm", - .flags = CLKDM_CAN_HWSUP, - .clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct clockdomain core_l4_34xx_clkdm = { - .name = "core_l4_clkdm", - .pwrdm_name = "core_pwrdm", - .flags = CLKDM_CAN_HWSUP, - .clktrctrl_mask = OMAP3430_CLKTRCTRL_L4_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct clockdomain dss_34xx_clkdm = { - .name = "dss_clkdm", - .pwrdm_name = "dss_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct clockdomain cam_clkdm = { - .name = "cam_clkdm", - .pwrdm_name = "cam_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct clockdomain usbhost_clkdm = { - .name = "usbhost_clkdm", - .pwrdm_name = "usbhost_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2), -}; - -static struct clockdomain per_clkdm = { - .name = "per_clkdm", - .pwrdm_name = "per_pwrdm", - .flags = CLKDM_CAN_HWSUP_SWSUP, - .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct clockdomain emu_clkdm = { - .name = "emu_clkdm", - .pwrdm_name = "emu_pwrdm", - .flags = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP, - .clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -#endif /* CONFIG_ARCH_OMAP34XX */ - -/* - * Clockdomain-powerdomain hwsup dependencies (34XX only) - */ - -static struct clkdm_pwrdm_autodep clkdm_pwrdm_autodeps[] = { - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "iva2_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { NULL } -}; - -/* - * - */ - -static struct clockdomain *clockdomains_omap[] = { - - &wkup_clkdm, - -#ifdef CONFIG_ARCH_OMAP2420 - &mpu_2420_clkdm, - &iva1_2420_clkdm, -#endif - -#ifdef CONFIG_ARCH_OMAP2430 - &mpu_2430_clkdm, - &mdm_clkdm, -#endif - -#ifdef CONFIG_ARCH_OMAP24XX - &dsp_clkdm, - &gfx_24xx_clkdm, - &core_l3_24xx_clkdm, - &core_l4_24xx_clkdm, - &dss_24xx_clkdm, -#endif - -#ifdef CONFIG_ARCH_OMAP34XX - &mpu_34xx_clkdm, - &neon_clkdm, - &iva2_clkdm, - &gfx_3430es1_clkdm, - &sgx_clkdm, - &d2d_clkdm, - &core_l3_34xx_clkdm, - &core_l4_34xx_clkdm, - &dss_34xx_clkdm, - &cam_clkdm, - &usbhost_clkdm, - &per_clkdm, - &emu_clkdm, -#endif - - NULL, -}; - -#endif diff --git a/arch/arm/mach-omap2/clockdomains2420_data.c b/arch/arm/mach-omap2/clockdomains2420_data.c new file mode 100644 index 00000000000..7e76becf3a4 --- /dev/null +++ b/arch/arm/mach-omap2/clockdomains2420_data.c @@ -0,0 +1,153 @@ +/* + * OMAP2420 clockdomains + * + * Copyright (C) 2008-2011 Texas Instruments, Inc. + * Copyright (C) 2008-2010 Nokia Corporation + * + * Paul Walmsley, Jouni Högander + * + * This file contains clockdomains and clockdomain wakeup dependencies + * for OMAP2420 chips. Some notes: + * + * A useful validation rule for struct clockdomain: Any clockdomain + * referenced by a wkdep_srcs must have a dep_bit assigned. So + * wkdep_srcs are really just software-controllable dependencies. + * Non-software-controllable dependencies do exist, but they are not + * encoded below (yet). + * + * 24xx does not support programmable sleep dependencies (SLEEPDEP) + * + * The overly-specific dep_bit names are due to a bit name collision + * with CM_FCLKEN_{DSP,IVA2}. The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift + * value are the same for all powerdomains: 2 + * + * XXX should dep_bit be a mask, so we can test to see if it is 0 as a + * sanity check? + * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE + */ + +/* + * To-Do List + * -> Port the Sleep/Wakeup dependencies for the domains + * from the Power domain framework + */ + +#include <linux/kernel.h> +#include <linux/io.h> + +#include "soc.h" +#include "clockdomain.h" +#include "prm2xxx_3xxx.h" +#include "cm2xxx_3xxx.h" +#include "cm-regbits-24xx.h" +#include "prm-regbits-24xx.h" + +/* + * Clockdomain dependencies for wkdeps + * + * XXX Hardware dependencies (e.g., dependencies that cannot be + * changed in software) are not included here yet, but should be. + */ + +/* Wakeup dependency source arrays */ + +/* 2420-specific possible wakeup dependencies */ + +/* 2420 PM_WKDEP_MPU: CORE, DSP, WKUP */ +static struct clkdm_dep mpu_2420_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "dsp_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + +/* 2420 PM_WKDEP_CORE: DSP, GFX, MPU, WKUP */ +static struct clkdm_dep core_2420_wkdeps[] = { + { .clkdm_name = "dsp_clkdm" }, + { .clkdm_name = "gfx_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + +/* + * 2420-only clockdomains + */ + +static struct clockdomain mpu_2420_clkdm = { + .name = "mpu_clkdm", + .pwrdm = { .name = "mpu_pwrdm" }, + .flags = CLKDM_CAN_HWSUP, + .wkdep_srcs = mpu_2420_wkdeps, + .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK, +}; + +static struct clockdomain iva1_2420_clkdm = { + .name = "iva1_clkdm", + .pwrdm = { .name = "dsp_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT, + .wkdep_srcs = dsp_24xx_wkdeps, + .clktrctrl_mask = OMAP2420_AUTOSTATE_IVA_MASK, +}; + +static struct clockdomain dsp_2420_clkdm = { + .name = "dsp_clkdm", + .pwrdm = { .name = "dsp_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK, +}; + +static struct clockdomain gfx_2420_clkdm = { + .name = "gfx_clkdm", + .pwrdm = { .name = "gfx_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .wkdep_srcs = gfx_24xx_wkdeps, + .clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK, +}; + +static struct clockdomain core_l3_2420_clkdm = { + .name = "core_l3_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .flags = CLKDM_CAN_HWSUP, + .wkdep_srcs = core_2420_wkdeps, + .clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK, +}; + +static struct clockdomain core_l4_2420_clkdm = { + .name = "core_l4_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .flags = CLKDM_CAN_HWSUP, + .wkdep_srcs = core_2420_wkdeps, + .clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK, +}; + +static struct clockdomain dss_2420_clkdm = { + .name = "dss_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .flags = CLKDM_CAN_HWSUP, + .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK, +}; + +static struct clockdomain *clockdomains_omap242x[] __initdata = { + &wkup_common_clkdm, + &mpu_2420_clkdm, + &iva1_2420_clkdm, + &dsp_2420_clkdm, + &gfx_2420_clkdm, + &core_l3_2420_clkdm, + &core_l4_2420_clkdm, + &dss_2420_clkdm, + NULL, +}; + +void __init omap242x_clockdomains_init(void) +{ + if (!cpu_is_omap242x()) + return; + + clkdm_register_platform_funcs(&omap2_clkdm_operations); + clkdm_register_clkdms(clockdomains_omap242x); + clkdm_complete_init(); +} diff --git a/arch/arm/mach-omap2/clockdomains2430_data.c b/arch/arm/mach-omap2/clockdomains2430_data.c new file mode 100644 index 00000000000..b923007e45d --- /dev/null +++ b/arch/arm/mach-omap2/clockdomains2430_data.c @@ -0,0 +1,180 @@ +/* + * OMAP2xxx clockdomains + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * Copyright (C) 2008-2010 Nokia Corporation + * + * Paul Walmsley, Jouni Högander + * + * This file contains clockdomains and clockdomain wakeup dependencies + * for OMAP2xxx chips. Some notes: + * + * A useful validation rule for struct clockdomain: Any clockdomain + * referenced by a wkdep_srcs must have a dep_bit assigned. So + * wkdep_srcs are really just software-controllable dependencies. + * Non-software-controllable dependencies do exist, but they are not + * encoded below (yet). + * + * 24xx does not support programmable sleep dependencies (SLEEPDEP) + * + * The overly-specific dep_bit names are due to a bit name collision + * with CM_FCLKEN_{DSP,IVA2}. The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift + * value are the same for all powerdomains: 2 + * + * XXX should dep_bit be a mask, so we can test to see if it is 0 as a + * sanity check? + * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE + */ + +/* + * To-Do List + * -> Port the Sleep/Wakeup dependencies for the domains + * from the Power domain framework + */ + +#include <linux/kernel.h> +#include <linux/io.h> + +#include "soc.h" +#include "clockdomain.h" +#include "prm2xxx_3xxx.h" +#include "cm2xxx_3xxx.h" +#include "cm-regbits-24xx.h" +#include "prm-regbits-24xx.h" + +/* + * Clockdomain dependencies for wkdeps + * + * XXX Hardware dependencies (e.g., dependencies that cannot be + * changed in software) are not included here yet, but should be. + */ + +/* Wakeup dependency source arrays */ + +/* 2430-specific possible wakeup dependencies */ + +/* 2430 PM_WKDEP_CORE: DSP, GFX, MPU, WKUP, MDM */ +static struct clkdm_dep core_2430_wkdeps[] = { + { .clkdm_name = "dsp_clkdm" }, + { .clkdm_name = "gfx_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { .clkdm_name = "mdm_clkdm" }, + { NULL }, +}; + +/* 2430 PM_WKDEP_MPU: CORE, DSP, WKUP, MDM */ +static struct clkdm_dep mpu_2430_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "dsp_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { .clkdm_name = "mdm_clkdm" }, + { NULL }, +}; + +/* 2430 PM_WKDEP_MDM: CORE, MPU, WKUP */ +static struct clkdm_dep mdm_2430_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + +/* + * 2430-only clockdomains + */ + +static struct clockdomain mpu_2430_clkdm = { + .name = "mpu_clkdm", + .pwrdm = { .name = "mpu_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .wkdep_srcs = mpu_2430_wkdeps, + .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK, +}; + +/* Another case of bit name collisions between several registers: EN_MDM */ +static struct clockdomain mdm_clkdm = { + .name = "mdm_clkdm", + .pwrdm = { .name = "mdm_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .dep_bit = OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT, + .wkdep_srcs = mdm_2430_wkdeps, + .clktrctrl_mask = OMAP2430_AUTOSTATE_MDM_MASK, +}; + +static struct clockdomain dsp_2430_clkdm = { + .name = "dsp_clkdm", + .pwrdm = { .name = "dsp_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT, + .wkdep_srcs = dsp_24xx_wkdeps, + .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK, +}; + +static struct clockdomain gfx_2430_clkdm = { + .name = "gfx_clkdm", + .pwrdm = { .name = "gfx_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .wkdep_srcs = gfx_24xx_wkdeps, + .clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK, +}; + +/* + * XXX add usecounting for clkdm dependencies, otherwise the presence + * of a single dep bit for core_l3_24xx_clkdm and core_l4_24xx_clkdm + * could cause trouble + */ +static struct clockdomain core_l3_2430_clkdm = { + .name = "core_l3_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .flags = CLKDM_CAN_HWSUP, + .dep_bit = OMAP24XX_EN_CORE_SHIFT, + .wkdep_srcs = core_2430_wkdeps, + .clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK, +}; + +/* + * XXX add usecounting for clkdm dependencies, otherwise the presence + * of a single dep bit for core_l3_24xx_clkdm and core_l4_24xx_clkdm + * could cause trouble + */ +static struct clockdomain core_l4_2430_clkdm = { + .name = "core_l4_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .flags = CLKDM_CAN_HWSUP, + .dep_bit = OMAP24XX_EN_CORE_SHIFT, + .wkdep_srcs = core_2430_wkdeps, + .clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK, +}; + +static struct clockdomain dss_2430_clkdm = { + .name = "dss_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .flags = CLKDM_CAN_HWSUP, + .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK, +}; + +static struct clockdomain *clockdomains_omap243x[] __initdata = { + &wkup_common_clkdm, + &mpu_2430_clkdm, + &mdm_clkdm, + &dsp_2430_clkdm, + &gfx_2430_clkdm, + &core_l3_2430_clkdm, + &core_l4_2430_clkdm, + &dss_2430_clkdm, + NULL, +}; + +void __init omap243x_clockdomains_init(void) +{ + if (!cpu_is_omap243x()) + return; + + clkdm_register_platform_funcs(&omap2_clkdm_operations); + clkdm_register_clkdms(clockdomains_omap243x); + clkdm_complete_init(); +} + diff --git a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c new file mode 100644 index 00000000000..4972219653c --- /dev/null +++ b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c @@ -0,0 +1,92 @@ +/* + * OMAP2/3 clockdomain common data + * + * Copyright (C) 2008-2011 Texas Instruments, Inc. + * Copyright (C) 2008-2010 Nokia Corporation + * + * Paul Walmsley, Jouni Högander + * + * This file contains clockdomains and clockdomain wakeup/sleep + * dependencies for the OMAP2/3 chips. Some notes: + * + * A useful validation rule for struct clockdomain: Any clockdomain + * referenced by a wkdep_srcs or sleepdep_srcs array must have a + * dep_bit assigned. So wkdep_srcs/sleepdep_srcs are really just + * software-controllable dependencies. Non-software-controllable + * dependencies do exist, but they are not encoded below (yet). + * + * 24xx does not support programmable sleep dependencies (SLEEPDEP) + * + * The overly-specific dep_bit names are due to a bit name collision + * with CM_FCLKEN_{DSP,IVA2}. The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift + * value are the same for all powerdomains: 2 + * + * XXX should dep_bit be a mask, so we can test to see if it is 0 as a + * sanity check? + * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE + */ + +/* + * To-Do List + * -> Port the Sleep/Wakeup dependencies for the domains + * from the Power domain framework + */ + +#include <linux/kernel.h> +#include <linux/io.h> + +#include "clockdomain.h" +#include "prm2xxx_3xxx.h" +#include "cm2xxx_3xxx.h" +#include "cm-regbits-24xx.h" +#include "cm-regbits-34xx.h" +#include "cm-regbits-44xx.h" +#include "prm-regbits-24xx.h" +#include "prm-regbits-34xx.h" + +/* + * Clockdomain dependencies for wkdeps/sleepdeps + * + * XXX Hardware dependencies (e.g., dependencies that cannot be + * changed in software) are not included here yet, but should be. + */ + +/* Wakeup dependency source arrays */ + +/* 2xxx-specific possible dependencies */ + +/* 2xxx PM_WKDEP_GFX: CORE, MPU, WKUP */ +struct clkdm_dep gfx_24xx_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + +/* 2xxx PM_WKDEP_DSP: CORE, MPU, WKUP */ +struct clkdm_dep dsp_24xx_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + + +/* + * OMAP2/3-common clockdomains + * + * Even though the 2420 has a single PRCM module from the + * interconnect's perspective, internally it does appear to have + * separate PRM and CM clockdomains. The usual test case is + * sys_clkout/sys_clkout2. + */ + +/* This is an implicit clockdomain - it is never defined as such in TRM */ +struct clockdomain wkup_common_clkdm = { + .name = "wkup_clkdm", + .pwrdm = { .name = "wkup_pwrdm" }, + .dep_bit = OMAP_EN_WKUP_SHIFT, + .flags = CLKDM_ACTIVE_WITH_MPU, +}; diff --git a/arch/arm/mach-omap2/clockdomains33xx_data.c b/arch/arm/mach-omap2/clockdomains33xx_data.c new file mode 100644 index 00000000000..32c90fd9eba --- /dev/null +++ b/arch/arm/mach-omap2/clockdomains33xx_data.c @@ -0,0 +1,196 @@ +/* + * AM33XX Clock Domain data. + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * Vaibhav Hiremath <hvaibhav@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/io.h> + +#include "clockdomain.h" +#include "cm.h" +#include "cm33xx.h" +#include "cm-regbits-33xx.h" + +static struct clockdomain l4ls_am33xx_clkdm = { + .name = "l4ls_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_L4LS_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l3s_am33xx_clkdm = { + .name = "l3s_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_L3S_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l4fw_am33xx_clkdm = { + .name = "l4fw_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_L4FW_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l3_am33xx_clkdm = { + .name = "l3_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_L3_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l4hs_am33xx_clkdm = { + .name = "l4hs_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_L4HS_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain ocpwp_l3_am33xx_clkdm = { + .name = "ocpwp_l3_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_OCPWP_L3_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain pruss_ocp_am33xx_clkdm = { + .name = "pruss_ocp_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_PRUSS_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain cpsw_125mhz_am33xx_clkdm = { + .name = "cpsw_125mhz_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_CPSW_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain lcdc_am33xx_clkdm = { + .name = "lcdc_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_LCDC_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain clk_24mhz_am33xx_clkdm = { + .name = "clk_24mhz_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .cm_inst = AM33XX_CM_PER_MOD, + .clkdm_offs = AM33XX_CM_PER_CLK_24MHZ_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l4_wkup_am33xx_clkdm = { + .name = "l4_wkup_clkdm", + .pwrdm = { .name = "wkup_pwrdm" }, + .cm_inst = AM33XX_CM_WKUP_MOD, + .clkdm_offs = AM33XX_CM_WKUP_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l3_aon_am33xx_clkdm = { + .name = "l3_aon_clkdm", + .pwrdm = { .name = "wkup_pwrdm" }, + .cm_inst = AM33XX_CM_WKUP_MOD, + .clkdm_offs = AM33XX_CM_L3_AON_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l4_wkup_aon_am33xx_clkdm = { + .name = "l4_wkup_aon_clkdm", + .pwrdm = { .name = "wkup_pwrdm" }, + .cm_inst = AM33XX_CM_WKUP_MOD, + .clkdm_offs = AM33XX_CM_L4_WKUP_AON_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain mpu_am33xx_clkdm = { + .name = "mpu_clkdm", + .pwrdm = { .name = "mpu_pwrdm" }, + .cm_inst = AM33XX_CM_MPU_MOD, + .clkdm_offs = AM33XX_CM_MPU_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l4_rtc_am33xx_clkdm = { + .name = "l4_rtc_clkdm", + .pwrdm = { .name = "rtc_pwrdm" }, + .cm_inst = AM33XX_CM_RTC_MOD, + .clkdm_offs = AM33XX_CM_RTC_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain gfx_l3_am33xx_clkdm = { + .name = "gfx_l3_clkdm", + .pwrdm = { .name = "gfx_pwrdm" }, + .cm_inst = AM33XX_CM_GFX_MOD, + .clkdm_offs = AM33XX_CM_GFX_L3_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain gfx_l4ls_gfx_am33xx_clkdm = { + .name = "gfx_l4ls_gfx_clkdm", + .pwrdm = { .name = "gfx_pwrdm" }, + .cm_inst = AM33XX_CM_GFX_MOD, + .clkdm_offs = AM33XX_CM_GFX_L4LS_GFX_CLKSTCTRL__1_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l4_cefuse_am33xx_clkdm = { + .name = "l4_cefuse_clkdm", + .pwrdm = { .name = "cefuse_pwrdm" }, + .cm_inst = AM33XX_CM_CEFUSE_MOD, + .clkdm_offs = AM33XX_CM_CEFUSE_CLKSTCTRL_OFFSET, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain *clockdomains_am33xx[] __initdata = { + &l4ls_am33xx_clkdm, + &l3s_am33xx_clkdm, + &l4fw_am33xx_clkdm, + &l3_am33xx_clkdm, + &l4hs_am33xx_clkdm, + &ocpwp_l3_am33xx_clkdm, + &pruss_ocp_am33xx_clkdm, + &cpsw_125mhz_am33xx_clkdm, + &lcdc_am33xx_clkdm, + &clk_24mhz_am33xx_clkdm, + &l4_wkup_am33xx_clkdm, + &l3_aon_am33xx_clkdm, + &l4_wkup_aon_am33xx_clkdm, + &mpu_am33xx_clkdm, + &l4_rtc_am33xx_clkdm, + &gfx_l3_am33xx_clkdm, + &gfx_l4ls_gfx_am33xx_clkdm, + &l4_cefuse_am33xx_clkdm, + NULL, +}; + +void __init am33xx_clockdomains_init(void) +{ + clkdm_register_platform_funcs(&am33xx_clkdm_operations); + clkdm_register_clkdms(clockdomains_am33xx); + clkdm_complete_init(); +} diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c new file mode 100644 index 00000000000..f03dc97921a --- /dev/null +++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c @@ -0,0 +1,525 @@ +/* + * OMAP3xxx clockdomains + * + * Copyright (C) 2008-2011 Texas Instruments, Inc. + * Copyright (C) 2008-2010 Nokia Corporation + * + * Paul Walmsley, Jouni Högander + * + * This file contains clockdomains and clockdomain wakeup/sleep + * dependencies for the OMAP3xxx chips. Some notes: + * + * A useful validation rule for struct clockdomain: Any clockdomain + * referenced by a wkdep_srcs or sleepdep_srcs array must have a + * dep_bit assigned. So wkdep_srcs/sleepdep_srcs are really just + * software-controllable dependencies. Non-software-controllable + * dependencies do exist, but they are not encoded below (yet). + * + * The overly-specific dep_bit names are due to a bit name collision + * with CM_FCLKEN_{DSP,IVA2}. The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift + * value are the same for all powerdomains: 2 + * + * XXX should dep_bit be a mask, so we can test to see if it is 0 as a + * sanity check? + * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE + */ + +/* + * To-Do List + * -> Port the Sleep/Wakeup dependencies for the domains + * from the Power domain framework + */ + +#include <linux/kernel.h> +#include <linux/io.h> + +#include "soc.h" +#include "clockdomain.h" +#include "prm2xxx_3xxx.h" +#include "cm2xxx_3xxx.h" +#include "cm-regbits-34xx.h" +#include "prm-regbits-34xx.h" + +/* + * Clockdomain dependencies for wkdeps/sleepdeps + * + * XXX Hardware dependencies (e.g., dependencies that cannot be + * changed in software) are not included here yet, but should be. + */ + +/* OMAP3-specific possible dependencies */ + +/* + * 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE + * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE + */ +static struct clkdm_dep gfx_sgx_3xxx_wkdeps[] = { + { .clkdm_name = "iva2_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + +/* 3430: PM_WKDEP_PER: CORE, IVA2, MPU, WKUP */ +static struct clkdm_dep per_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "iva2_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep per_am35x_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + +/* 3430ES2: PM_WKDEP_USBHOST: CORE, IVA2, MPU, WKUP */ +static struct clkdm_dep usbhost_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "iva2_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep usbhost_am35x_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + +/* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER */ +static struct clkdm_dep mpu_3xxx_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "iva2_clkdm" }, + { .clkdm_name = "dss_clkdm" }, + { .clkdm_name = "per_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep mpu_am35x_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "dss_clkdm" }, + { .clkdm_name = "per_clkdm" }, + { NULL }, +}; + +/* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER */ +static struct clkdm_dep iva2_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { .clkdm_name = "dss_clkdm" }, + { .clkdm_name = "per_clkdm" }, + { NULL }, +}; + +/* 3430 PM_WKDEP_CAM: IVA2, MPU, WKUP */ +static struct clkdm_dep cam_wkdeps[] = { + { .clkdm_name = "iva2_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + +/* 3430 PM_WKDEP_DSS: IVA2, MPU, WKUP */ +static struct clkdm_dep dss_wkdeps[] = { + { .clkdm_name = "iva2_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep dss_am35x_wkdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + +/* 3430: PM_WKDEP_NEON: MPU */ +static struct clkdm_dep neon_wkdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { NULL }, +}; + +/* Sleep dependency source arrays for OMAP3-specific clkdms */ + +/* 3430: CM_SLEEPDEP_DSS: MPU, IVA */ +static struct clkdm_dep dss_sleepdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "iva2_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep dss_am35x_sleepdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { NULL }, +}; + +/* 3430: CM_SLEEPDEP_PER: MPU, IVA */ +static struct clkdm_dep per_sleepdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "iva2_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep per_am35x_sleepdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { NULL }, +}; + +/* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */ +static struct clkdm_dep usbhost_sleepdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "iva2_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep usbhost_am35x_sleepdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { NULL }, +}; + +/* 3430: CM_SLEEPDEP_CAM: MPU */ +static struct clkdm_dep cam_sleepdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { NULL }, +}; + +/* + * 3430ES1: CM_SLEEPDEP_GFX: MPU + * 3430ES2: CM_SLEEPDEP_SGX: MPU + * These can share data since they will never be present simultaneously + * on the same device. + */ +static struct clkdm_dep gfx_sgx_sleepdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { NULL }, +}; + +/* + * OMAP3 clockdomains + */ + +static struct clockdomain mpu_3xxx_clkdm = { + .name = "mpu_clkdm", + .pwrdm = { .name = "mpu_pwrdm" }, + .flags = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP, + .dep_bit = OMAP3430_EN_MPU_SHIFT, + .wkdep_srcs = mpu_3xxx_wkdeps, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK, +}; + +static struct clockdomain mpu_am35x_clkdm = { + .name = "mpu_clkdm", + .pwrdm = { .name = "mpu_pwrdm" }, + .flags = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP, + .dep_bit = OMAP3430_EN_MPU_SHIFT, + .wkdep_srcs = mpu_am35x_wkdeps, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK, +}; + +static struct clockdomain neon_clkdm = { + .name = "neon_clkdm", + .pwrdm = { .name = "neon_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .wkdep_srcs = neon_wkdeps, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_NEON_MASK, +}; + +static struct clockdomain iva2_clkdm = { + .name = "iva2_clkdm", + .pwrdm = { .name = "iva2_pwrdm" }, + .flags = CLKDM_CAN_SWSUP, + .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT, + .wkdep_srcs = iva2_wkdeps, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK, +}; + +static struct clockdomain gfx_3430es1_clkdm = { + .name = "gfx_clkdm", + .pwrdm = { .name = "gfx_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .wkdep_srcs = gfx_sgx_3xxx_wkdeps, + .sleepdep_srcs = gfx_sgx_sleepdeps, + .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK, +}; + +static struct clockdomain sgx_clkdm = { + .name = "sgx_clkdm", + .pwrdm = { .name = "sgx_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .wkdep_srcs = gfx_sgx_3xxx_wkdeps, + .sleepdep_srcs = gfx_sgx_sleepdeps, + .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK, +}; + +static struct clockdomain sgx_am35x_clkdm = { + .name = "sgx_clkdm", + .pwrdm = { .name = "sgx_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .wkdep_srcs = gfx_sgx_am35x_wkdeps, + .sleepdep_srcs = gfx_sgx_sleepdeps, + .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK, +}; + +/* + * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but + * then that information was removed from the 34xx ES2+ TRM. It is + * unclear whether the core is still there, but the clockdomain logic + * is there, and must be programmed to an appropriate state if the + * CORE clockdomain is to become inactive. + */ +static struct clockdomain d2d_clkdm = { + .name = "d2d_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK, +}; + +/* + * XXX add usecounting for clkdm dependencies, otherwise the presence + * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm + * could cause trouble + */ +static struct clockdomain core_l3_3xxx_clkdm = { + .name = "core_l3_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .flags = CLKDM_CAN_HWSUP, + .dep_bit = OMAP3430_EN_CORE_SHIFT, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK, +}; + +/* + * XXX add usecounting for clkdm dependencies, otherwise the presence + * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm + * could cause trouble + */ +static struct clockdomain core_l4_3xxx_clkdm = { + .name = "core_l4_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .flags = CLKDM_CAN_HWSUP, + .dep_bit = OMAP3430_EN_CORE_SHIFT, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_L4_MASK, +}; + +/* Another case of bit name collisions between several registers: EN_DSS */ +static struct clockdomain dss_3xxx_clkdm = { + .name = "dss_clkdm", + .pwrdm = { .name = "dss_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT, + .wkdep_srcs = dss_wkdeps, + .sleepdep_srcs = dss_sleepdeps, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK, +}; + +static struct clockdomain dss_am35x_clkdm = { + .name = "dss_clkdm", + .pwrdm = { .name = "dss_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT, + .wkdep_srcs = dss_am35x_wkdeps, + .sleepdep_srcs = dss_am35x_sleepdeps, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK, +}; + +static struct clockdomain cam_clkdm = { + .name = "cam_clkdm", + .pwrdm = { .name = "cam_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .wkdep_srcs = cam_wkdeps, + .sleepdep_srcs = cam_sleepdeps, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK, +}; + +static struct clockdomain usbhost_clkdm = { + .name = "usbhost_clkdm", + .pwrdm = { .name = "usbhost_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .wkdep_srcs = usbhost_wkdeps, + .sleepdep_srcs = usbhost_sleepdeps, + .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK, +}; + +static struct clockdomain usbhost_am35x_clkdm = { + .name = "usbhost_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .wkdep_srcs = usbhost_am35x_wkdeps, + .sleepdep_srcs = usbhost_am35x_sleepdeps, + .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK, +}; + +static struct clockdomain per_clkdm = { + .name = "per_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .dep_bit = OMAP3430_EN_PER_SHIFT, + .wkdep_srcs = per_wkdeps, + .sleepdep_srcs = per_sleepdeps, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK, +}; + +static struct clockdomain per_am35x_clkdm = { + .name = "per_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .dep_bit = OMAP3430_EN_PER_SHIFT, + .wkdep_srcs = per_am35x_wkdeps, + .sleepdep_srcs = per_am35x_sleepdeps, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK, +}; + +static struct clockdomain emu_clkdm = { + .name = "emu_clkdm", + .pwrdm = { .name = "emu_pwrdm" }, + .flags = (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP | + CLKDM_MISSING_IDLE_REPORTING), + .clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK, +}; + +static struct clockdomain dpll1_clkdm = { + .name = "dpll1_clkdm", + .pwrdm = { .name = "dpll1_pwrdm" }, +}; + +static struct clockdomain dpll2_clkdm = { + .name = "dpll2_clkdm", + .pwrdm = { .name = "dpll2_pwrdm" }, +}; + +static struct clockdomain dpll3_clkdm = { + .name = "dpll3_clkdm", + .pwrdm = { .name = "dpll3_pwrdm" }, +}; + +static struct clockdomain dpll4_clkdm = { + .name = "dpll4_clkdm", + .pwrdm = { .name = "dpll4_pwrdm" }, +}; + +static struct clockdomain dpll5_clkdm = { + .name = "dpll5_clkdm", + .pwrdm = { .name = "dpll5_pwrdm" }, +}; + +/* + * Clockdomain hwsup dependencies + */ + +static struct clkdm_autodep clkdm_autodeps[] = { + { + .clkdm = { .name = "mpu_clkdm" }, + }, + { + .clkdm = { .name = "iva2_clkdm" }, + }, + { + .clkdm = { .name = NULL }, + } +}; + +static struct clkdm_autodep clkdm_am35x_autodeps[] = { + { + .clkdm = { .name = "mpu_clkdm" }, + }, + { + .clkdm = { .name = NULL }, + } +}; + +/* + * + */ + +static struct clockdomain *clockdomains_common[] __initdata = { + &wkup_common_clkdm, + &neon_clkdm, + &core_l3_3xxx_clkdm, + &core_l4_3xxx_clkdm, + &emu_clkdm, + &dpll1_clkdm, + &dpll3_clkdm, + &dpll4_clkdm, + NULL +}; + +static struct clockdomain *clockdomains_omap3430[] __initdata = { + &mpu_3xxx_clkdm, + &iva2_clkdm, + &d2d_clkdm, + &dss_3xxx_clkdm, + &cam_clkdm, + &per_clkdm, + &dpll2_clkdm, + NULL +}; + +static struct clockdomain *clockdomains_omap3430es1[] __initdata = { + &gfx_3430es1_clkdm, + NULL, +}; + +static struct clockdomain *clockdomains_omap3430es2plus[] __initdata = { + &sgx_clkdm, + &dpll5_clkdm, + &usbhost_clkdm, + NULL, +}; + +static struct clockdomain *clockdomains_am35x[] __initdata = { + &mpu_am35x_clkdm, + &sgx_am35x_clkdm, + &dss_am35x_clkdm, + &per_am35x_clkdm, + &usbhost_am35x_clkdm, + &dpll5_clkdm, + NULL +}; + +void __init omap3xxx_clockdomains_init(void) +{ + struct clockdomain **sc; + unsigned int rev; + + if (!cpu_is_omap34xx()) + return; + + clkdm_register_platform_funcs(&omap3_clkdm_operations); + clkdm_register_clkdms(clockdomains_common); + + rev = omap_rev(); + + if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) { + clkdm_register_clkdms(clockdomains_am35x); + clkdm_register_autodeps(clkdm_am35x_autodeps); + } else { + clkdm_register_clkdms(clockdomains_omap3430); + + sc = (rev == OMAP3430_REV_ES1_0) ? + clockdomains_omap3430es1 : clockdomains_omap3430es2plus; + + clkdm_register_clkdms(sc); + clkdm_register_autodeps(clkdm_autodeps); + } + + clkdm_complete_init(); +} diff --git a/arch/arm/mach-omap2/clockdomains43xx_data.c b/arch/arm/mach-omap2/clockdomains43xx_data.c new file mode 100644 index 00000000000..6d71c6082a2 --- /dev/null +++ b/arch/arm/mach-omap2/clockdomains43xx_data.c @@ -0,0 +1,196 @@ +/* + * AM43xx Clock domains framework + * + * Copyright (C) 2013 Texas Instruments, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/io.h> + +#include "clockdomain.h" +#include "prcm44xx.h" +#include "prcm43xx.h" + +static struct clockdomain l4_cefuse_43xx_clkdm = { + .name = "l4_cefuse_clkdm", + .pwrdm = { .name = "cefuse_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_CEFUSE_INST, + .clkdm_offs = AM43XX_CM_CEFUSE_CEFUSE_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain mpu_43xx_clkdm = { + .name = "mpu_clkdm", + .pwrdm = { .name = "mpu_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_MPU_INST, + .clkdm_offs = AM43XX_CM_MPU_MPU_CDOFFS, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain l4ls_43xx_clkdm = { + .name = "l4ls_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_PER_INST, + .clkdm_offs = AM43XX_CM_PER_L4LS_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain tamper_43xx_clkdm = { + .name = "tamper_clkdm", + .pwrdm = { .name = "tamper_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_TAMPER_INST, + .clkdm_offs = AM43XX_CM_TAMPER_TAMPER_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l4_rtc_43xx_clkdm = { + .name = "l4_rtc_clkdm", + .pwrdm = { .name = "rtc_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_RTC_INST, + .clkdm_offs = AM43XX_CM_RTC_RTC_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain pruss_ocp_43xx_clkdm = { + .name = "pruss_ocp_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_PER_INST, + .clkdm_offs = AM43XX_CM_PER_ICSS_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain ocpwp_l3_43xx_clkdm = { + .name = "ocpwp_l3_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_PER_INST, + .clkdm_offs = AM43XX_CM_PER_OCPWP_L3_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l3s_tsc_43xx_clkdm = { + .name = "l3s_tsc_clkdm", + .pwrdm = { .name = "wkup_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_WKUP_INST, + .clkdm_offs = AM43XX_CM_WKUP_L3S_TSC_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain dss_43xx_clkdm = { + .name = "dss_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_PER_INST, + .clkdm_offs = AM43XX_CM_PER_DSS_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l3_aon_43xx_clkdm = { + .name = "l3_aon_clkdm", + .pwrdm = { .name = "wkup_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_WKUP_INST, + .clkdm_offs = AM43XX_CM_WKUP_L3_AON_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain emif_43xx_clkdm = { + .name = "emif_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_PER_INST, + .clkdm_offs = AM43XX_CM_PER_EMIF_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l4_wkup_aon_43xx_clkdm = { + .name = "l4_wkup_aon_clkdm", + .pwrdm = { .name = "wkup_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_WKUP_INST, + .clkdm_offs = AM43XX_CM_WKUP_L4_WKUP_AON_CDOFFS, +}; + +static struct clockdomain l3_43xx_clkdm = { + .name = "l3_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_PER_INST, + .clkdm_offs = AM43XX_CM_PER_L3_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l4_wkup_43xx_clkdm = { + .name = "l4_wkup_clkdm", + .pwrdm = { .name = "wkup_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_WKUP_INST, + .clkdm_offs = AM43XX_CM_WKUP_WKUP_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain cpsw_125mhz_43xx_clkdm = { + .name = "cpsw_125mhz_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_PER_INST, + .clkdm_offs = AM43XX_CM_PER_CPSW_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain gfx_l3_43xx_clkdm = { + .name = "gfx_l3_clkdm", + .pwrdm = { .name = "gfx_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_GFX_INST, + .clkdm_offs = AM43XX_CM_GFX_GFX_L3_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l3s_43xx_clkdm = { + .name = "l3s_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .prcm_partition = AM43XX_CM_PARTITION, + .cm_inst = AM43XX_CM_PER_INST, + .clkdm_offs = AM43XX_CM_PER_L3S_CDOFFS, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain *clockdomains_am43xx[] __initdata = { + &l4_cefuse_43xx_clkdm, + &mpu_43xx_clkdm, + &l4ls_43xx_clkdm, + &tamper_43xx_clkdm, + &l4_rtc_43xx_clkdm, + &pruss_ocp_43xx_clkdm, + &ocpwp_l3_43xx_clkdm, + &l3s_tsc_43xx_clkdm, + &dss_43xx_clkdm, + &l3_aon_43xx_clkdm, + &emif_43xx_clkdm, + &l4_wkup_aon_43xx_clkdm, + &l3_43xx_clkdm, + &l4_wkup_43xx_clkdm, + &cpsw_125mhz_43xx_clkdm, + &gfx_l3_43xx_clkdm, + &l3s_43xx_clkdm, + NULL +}; + +void __init am43xx_clockdomains_init(void) +{ + clkdm_register_platform_funcs(&am43xx_clkdm_operations); + clkdm_register_clkdms(clockdomains_am43xx); + clkdm_complete_init(); +} diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c new file mode 100644 index 00000000000..95192a062d5 --- /dev/null +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -0,0 +1,443 @@ +/* + * OMAP4 Clock domains framework + * + * Copyright (C) 2009-2011 Texas Instruments, Inc. + * Copyright (C) 2009-2011 Nokia Corporation + * + * Abhijit Pagare (abhijitpagare@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * Paul Walmsley (paul@pwsan.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/io.h> + +#include "clockdomain.h" +#include "cm1_44xx.h" +#include "cm2_44xx.h" + +#include "cm-regbits-44xx.h" +#include "prm44xx.h" +#include "prcm44xx.h" +#include "prcm_mpu44xx.h" + +/* Static Dependencies for OMAP4 Clock Domains */ + +static struct clkdm_dep d2d_wkup_sleep_deps[] = { + { .clkdm_name = "abe_clkdm" }, + { .clkdm_name = "ivahd_clkdm" }, + { .clkdm_name = "l3_1_clkdm" }, + { .clkdm_name = "l3_2_clkdm" }, + { .clkdm_name = "l3_emif_clkdm" }, + { .clkdm_name = "l3_init_clkdm" }, + { .clkdm_name = "l4_cfg_clkdm" }, + { .clkdm_name = "l4_per_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep ducati_wkup_sleep_deps[] = { + { .clkdm_name = "abe_clkdm" }, + { .clkdm_name = "ivahd_clkdm" }, + { .clkdm_name = "l3_1_clkdm" }, + { .clkdm_name = "l3_2_clkdm" }, + { .clkdm_name = "l3_dss_clkdm" }, + { .clkdm_name = "l3_emif_clkdm" }, + { .clkdm_name = "l3_gfx_clkdm" }, + { .clkdm_name = "l3_init_clkdm" }, + { .clkdm_name = "l4_cfg_clkdm" }, + { .clkdm_name = "l4_per_clkdm" }, + { .clkdm_name = "l4_secure_clkdm" }, + { .clkdm_name = "l4_wkup_clkdm" }, + { .clkdm_name = "tesla_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep iss_wkup_sleep_deps[] = { + { .clkdm_name = "ivahd_clkdm" }, + { .clkdm_name = "l3_1_clkdm" }, + { .clkdm_name = "l3_emif_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep ivahd_wkup_sleep_deps[] = { + { .clkdm_name = "l3_1_clkdm" }, + { .clkdm_name = "l3_emif_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep l3_dma_wkup_sleep_deps[] = { + { .clkdm_name = "abe_clkdm" }, + { .clkdm_name = "ducati_clkdm" }, + { .clkdm_name = "ivahd_clkdm" }, + { .clkdm_name = "l3_1_clkdm" }, + { .clkdm_name = "l3_dss_clkdm" }, + { .clkdm_name = "l3_emif_clkdm" }, + { .clkdm_name = "l3_init_clkdm" }, + { .clkdm_name = "l4_cfg_clkdm" }, + { .clkdm_name = "l4_per_clkdm" }, + { .clkdm_name = "l4_secure_clkdm" }, + { .clkdm_name = "l4_wkup_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep l3_dss_wkup_sleep_deps[] = { + { .clkdm_name = "ivahd_clkdm" }, + { .clkdm_name = "l3_2_clkdm" }, + { .clkdm_name = "l3_emif_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep l3_gfx_wkup_sleep_deps[] = { + { .clkdm_name = "ivahd_clkdm" }, + { .clkdm_name = "l3_1_clkdm" }, + { .clkdm_name = "l3_emif_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep l3_init_wkup_sleep_deps[] = { + { .clkdm_name = "abe_clkdm" }, + { .clkdm_name = "ivahd_clkdm" }, + { .clkdm_name = "l3_emif_clkdm" }, + { .clkdm_name = "l4_cfg_clkdm" }, + { .clkdm_name = "l4_per_clkdm" }, + { .clkdm_name = "l4_secure_clkdm" }, + { .clkdm_name = "l4_wkup_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep l4_secure_wkup_sleep_deps[] = { + { .clkdm_name = "l3_1_clkdm" }, + { .clkdm_name = "l3_emif_clkdm" }, + { .clkdm_name = "l4_per_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep mpu_wkup_sleep_deps[] = { + { .clkdm_name = "abe_clkdm" }, + { .clkdm_name = "ducati_clkdm" }, + { .clkdm_name = "ivahd_clkdm" }, + { .clkdm_name = "l3_1_clkdm" }, + { .clkdm_name = "l3_2_clkdm" }, + { .clkdm_name = "l3_dss_clkdm" }, + { .clkdm_name = "l3_emif_clkdm" }, + { .clkdm_name = "l3_gfx_clkdm" }, + { .clkdm_name = "l3_init_clkdm" }, + { .clkdm_name = "l4_cfg_clkdm" }, + { .clkdm_name = "l4_per_clkdm" }, + { .clkdm_name = "l4_secure_clkdm" }, + { .clkdm_name = "l4_wkup_clkdm" }, + { .clkdm_name = "tesla_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep tesla_wkup_sleep_deps[] = { + { .clkdm_name = "abe_clkdm" }, + { .clkdm_name = "ivahd_clkdm" }, + { .clkdm_name = "l3_1_clkdm" }, + { .clkdm_name = "l3_2_clkdm" }, + { .clkdm_name = "l3_emif_clkdm" }, + { .clkdm_name = "l3_init_clkdm" }, + { .clkdm_name = "l4_cfg_clkdm" }, + { .clkdm_name = "l4_per_clkdm" }, + { .clkdm_name = "l4_wkup_clkdm" }, + { NULL }, +}; + +static struct clockdomain l4_cefuse_44xx_clkdm = { + .name = "l4_cefuse_clkdm", + .pwrdm = { .name = "cefuse_pwrdm" }, + .prcm_partition = OMAP4430_CM2_PARTITION, + .cm_inst = OMAP4430_CM2_CEFUSE_INST, + .clkdm_offs = OMAP4430_CM2_CEFUSE_CEFUSE_CDOFFS, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain l4_cfg_44xx_clkdm = { + .name = "l4_cfg_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP4430_CM2_PARTITION, + .cm_inst = OMAP4430_CM2_CORE_INST, + .clkdm_offs = OMAP4430_CM2_CORE_L4CFG_CDOFFS, + .dep_bit = OMAP4430_L4CFG_STATDEP_SHIFT, + .flags = CLKDM_CAN_HWSUP, +}; + +static struct clockdomain tesla_44xx_clkdm = { + .name = "tesla_clkdm", + .pwrdm = { .name = "tesla_pwrdm" }, + .prcm_partition = OMAP4430_CM1_PARTITION, + .cm_inst = OMAP4430_CM1_TESLA_INST, + .clkdm_offs = OMAP4430_CM1_TESLA_TESLA_CDOFFS, + .dep_bit = OMAP4430_TESLA_STATDEP_SHIFT, + .wkdep_srcs = tesla_wkup_sleep_deps, + .sleepdep_srcs = tesla_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain l3_gfx_44xx_clkdm = { + .name = "l3_gfx_clkdm", + .pwrdm = { .name = "gfx_pwrdm" }, + .prcm_partition = OMAP4430_CM2_PARTITION, + .cm_inst = OMAP4430_CM2_GFX_INST, + .clkdm_offs = OMAP4430_CM2_GFX_GFX_CDOFFS, + .dep_bit = OMAP4430_GFX_STATDEP_SHIFT, + .wkdep_srcs = l3_gfx_wkup_sleep_deps, + .sleepdep_srcs = l3_gfx_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain ivahd_44xx_clkdm = { + .name = "ivahd_clkdm", + .pwrdm = { .name = "ivahd_pwrdm" }, + .prcm_partition = OMAP4430_CM2_PARTITION, + .cm_inst = OMAP4430_CM2_IVAHD_INST, + .clkdm_offs = OMAP4430_CM2_IVAHD_IVAHD_CDOFFS, + .dep_bit = OMAP4430_IVAHD_STATDEP_SHIFT, + .wkdep_srcs = ivahd_wkup_sleep_deps, + .sleepdep_srcs = ivahd_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain l4_secure_44xx_clkdm = { + .name = "l4_secure_clkdm", + .pwrdm = { .name = "l4per_pwrdm" }, + .prcm_partition = OMAP4430_CM2_PARTITION, + .cm_inst = OMAP4430_CM2_L4PER_INST, + .clkdm_offs = OMAP4430_CM2_L4PER_L4SEC_CDOFFS, + .dep_bit = OMAP4430_L4SEC_STATDEP_SHIFT, + .wkdep_srcs = l4_secure_wkup_sleep_deps, + .sleepdep_srcs = l4_secure_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain l4_per_44xx_clkdm = { + .name = "l4_per_clkdm", + .pwrdm = { .name = "l4per_pwrdm" }, + .prcm_partition = OMAP4430_CM2_PARTITION, + .cm_inst = OMAP4430_CM2_L4PER_INST, + .clkdm_offs = OMAP4430_CM2_L4PER_L4PER_CDOFFS, + .dep_bit = OMAP4430_L4PER_STATDEP_SHIFT, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain abe_44xx_clkdm = { + .name = "abe_clkdm", + .pwrdm = { .name = "abe_pwrdm" }, + .prcm_partition = OMAP4430_CM1_PARTITION, + .cm_inst = OMAP4430_CM1_ABE_INST, + .clkdm_offs = OMAP4430_CM1_ABE_ABE_CDOFFS, + .dep_bit = OMAP4430_ABE_STATDEP_SHIFT, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain l3_instr_44xx_clkdm = { + .name = "l3_instr_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP4430_CM2_PARTITION, + .cm_inst = OMAP4430_CM2_CORE_INST, + .clkdm_offs = OMAP4430_CM2_CORE_L3INSTR_CDOFFS, +}; + +static struct clockdomain l3_init_44xx_clkdm = { + .name = "l3_init_clkdm", + .pwrdm = { .name = "l3init_pwrdm" }, + .prcm_partition = OMAP4430_CM2_PARTITION, + .cm_inst = OMAP4430_CM2_L3INIT_INST, + .clkdm_offs = OMAP4430_CM2_L3INIT_L3INIT_CDOFFS, + .dep_bit = OMAP4430_L3INIT_STATDEP_SHIFT, + .wkdep_srcs = l3_init_wkup_sleep_deps, + .sleepdep_srcs = l3_init_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain d2d_44xx_clkdm = { + .name = "d2d_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP4430_CM2_PARTITION, + .cm_inst = OMAP4430_CM2_CORE_INST, + .clkdm_offs = OMAP4430_CM2_CORE_D2D_CDOFFS, + .wkdep_srcs = d2d_wkup_sleep_deps, + .sleepdep_srcs = d2d_wkup_sleep_deps, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain mpu0_44xx_clkdm = { + .name = "mpu0_clkdm", + .pwrdm = { .name = "cpu0_pwrdm" }, + .prcm_partition = OMAP4430_PRCM_MPU_PARTITION, + .cm_inst = OMAP4430_PRCM_MPU_CPU0_INST, + .clkdm_offs = OMAP4430_PRCM_MPU_CPU0_CPU0_CDOFFS, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain mpu1_44xx_clkdm = { + .name = "mpu1_clkdm", + .pwrdm = { .name = "cpu1_pwrdm" }, + .prcm_partition = OMAP4430_PRCM_MPU_PARTITION, + .cm_inst = OMAP4430_PRCM_MPU_CPU1_INST, + .clkdm_offs = OMAP4430_PRCM_MPU_CPU1_CPU1_CDOFFS, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain l3_emif_44xx_clkdm = { + .name = "l3_emif_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP4430_CM2_PARTITION, + .cm_inst = OMAP4430_CM2_CORE_INST, + .clkdm_offs = OMAP4430_CM2_CORE_MEMIF_CDOFFS, + .dep_bit = OMAP4430_MEMIF_STATDEP_SHIFT, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain l4_ao_44xx_clkdm = { + .name = "l4_ao_clkdm", + .pwrdm = { .name = "always_on_core_pwrdm" }, + .prcm_partition = OMAP4430_CM2_PARTITION, + .cm_inst = OMAP4430_CM2_ALWAYS_ON_INST, + .clkdm_offs = OMAP4430_CM2_ALWAYS_ON_ALWON_CDOFFS, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain ducati_44xx_clkdm = { + .name = "ducati_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP4430_CM2_PARTITION, + .cm_inst = OMAP4430_CM2_CORE_INST, + .clkdm_offs = OMAP4430_CM2_CORE_DUCATI_CDOFFS, + .dep_bit = OMAP4430_DUCATI_STATDEP_SHIFT, + .wkdep_srcs = ducati_wkup_sleep_deps, + .sleepdep_srcs = ducati_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain mpu_44xx_clkdm = { + .name = "mpuss_clkdm", + .pwrdm = { .name = "mpu_pwrdm" }, + .prcm_partition = OMAP4430_CM1_PARTITION, + .cm_inst = OMAP4430_CM1_MPU_INST, + .clkdm_offs = OMAP4430_CM1_MPU_MPU_CDOFFS, + .wkdep_srcs = mpu_wkup_sleep_deps, + .sleepdep_srcs = mpu_wkup_sleep_deps, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain l3_2_44xx_clkdm = { + .name = "l3_2_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP4430_CM2_PARTITION, + .cm_inst = OMAP4430_CM2_CORE_INST, + .clkdm_offs = OMAP4430_CM2_CORE_L3_2_CDOFFS, + .dep_bit = OMAP4430_L3_2_STATDEP_SHIFT, + .flags = CLKDM_CAN_HWSUP, +}; + +static struct clockdomain l3_1_44xx_clkdm = { + .name = "l3_1_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP4430_CM2_PARTITION, + .cm_inst = OMAP4430_CM2_CORE_INST, + .clkdm_offs = OMAP4430_CM2_CORE_L3_1_CDOFFS, + .dep_bit = OMAP4430_L3_1_STATDEP_SHIFT, + .flags = CLKDM_CAN_HWSUP, +}; + +static struct clockdomain iss_44xx_clkdm = { + .name = "iss_clkdm", + .pwrdm = { .name = "cam_pwrdm" }, + .prcm_partition = OMAP4430_CM2_PARTITION, + .cm_inst = OMAP4430_CM2_CAM_INST, + .clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS, + .wkdep_srcs = iss_wkup_sleep_deps, + .sleepdep_srcs = iss_wkup_sleep_deps, + .flags = CLKDM_CAN_SWSUP, +}; + +static struct clockdomain l3_dss_44xx_clkdm = { + .name = "l3_dss_clkdm", + .pwrdm = { .name = "dss_pwrdm" }, + .prcm_partition = OMAP4430_CM2_PARTITION, + .cm_inst = OMAP4430_CM2_DSS_INST, + .clkdm_offs = OMAP4430_CM2_DSS_DSS_CDOFFS, + .dep_bit = OMAP4430_DSS_STATDEP_SHIFT, + .wkdep_srcs = l3_dss_wkup_sleep_deps, + .sleepdep_srcs = l3_dss_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain l4_wkup_44xx_clkdm = { + .name = "l4_wkup_clkdm", + .pwrdm = { .name = "wkup_pwrdm" }, + .prcm_partition = OMAP4430_PRM_PARTITION, + .cm_inst = OMAP4430_PRM_WKUP_CM_INST, + .clkdm_offs = OMAP4430_PRM_WKUP_CM_WKUP_CDOFFS, + .dep_bit = OMAP4430_L4WKUP_STATDEP_SHIFT, + .flags = CLKDM_CAN_HWSUP | CLKDM_ACTIVE_WITH_MPU, +}; + +static struct clockdomain emu_sys_44xx_clkdm = { + .name = "emu_sys_clkdm", + .pwrdm = { .name = "emu_pwrdm" }, + .prcm_partition = OMAP4430_PRM_PARTITION, + .cm_inst = OMAP4430_PRM_EMU_CM_INST, + .clkdm_offs = OMAP4430_PRM_EMU_CM_EMU_CDOFFS, + .flags = (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP | + CLKDM_MISSING_IDLE_REPORTING), +}; + +static struct clockdomain l3_dma_44xx_clkdm = { + .name = "l3_dma_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP4430_CM2_PARTITION, + .cm_inst = OMAP4430_CM2_CORE_INST, + .clkdm_offs = OMAP4430_CM2_CORE_SDMA_CDOFFS, + .wkdep_srcs = l3_dma_wkup_sleep_deps, + .sleepdep_srcs = l3_dma_wkup_sleep_deps, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +/* As clockdomains are added or removed above, this list must also be changed */ +static struct clockdomain *clockdomains_omap44xx[] __initdata = { + &l4_cefuse_44xx_clkdm, + &l4_cfg_44xx_clkdm, + &tesla_44xx_clkdm, + &l3_gfx_44xx_clkdm, + &ivahd_44xx_clkdm, + &l4_secure_44xx_clkdm, + &l4_per_44xx_clkdm, + &abe_44xx_clkdm, + &l3_instr_44xx_clkdm, + &l3_init_44xx_clkdm, + &d2d_44xx_clkdm, + &mpu0_44xx_clkdm, + &mpu1_44xx_clkdm, + &l3_emif_44xx_clkdm, + &l4_ao_44xx_clkdm, + &ducati_44xx_clkdm, + &mpu_44xx_clkdm, + &l3_2_44xx_clkdm, + &l3_1_44xx_clkdm, + &iss_44xx_clkdm, + &l3_dss_44xx_clkdm, + &l4_wkup_44xx_clkdm, + &emu_sys_44xx_clkdm, + &l3_dma_44xx_clkdm, + NULL +}; + + +void __init omap44xx_clockdomains_init(void) +{ + clkdm_register_platform_funcs(&omap4_clkdm_operations); + clkdm_register_clkdms(clockdomains_omap44xx); + clkdm_complete_init(); +} diff --git a/arch/arm/mach-omap2/clockdomains54xx_data.c b/arch/arm/mach-omap2/clockdomains54xx_data.c new file mode 100644 index 00000000000..1a3c69d2e14 --- /dev/null +++ b/arch/arm/mach-omap2/clockdomains54xx_data.c @@ -0,0 +1,464 @@ +/* + * OMAP54XX Clock domains framework + * + * Copyright (C) 2013 Texas Instruments, Inc. + * + * Abhijit Pagare (abhijitpagare@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * Paul Walmsley (paul@pwsan.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/io.h> + +#include "clockdomain.h" +#include "cm1_54xx.h" +#include "cm2_54xx.h" + +#include "cm-regbits-54xx.h" +#include "prm54xx.h" +#include "prcm44xx.h" +#include "prcm_mpu54xx.h" + +/* Static Dependencies for OMAP4 Clock Domains */ + +static struct clkdm_dep c2c_wkup_sleep_deps[] = { + { .clkdm_name = "abe_clkdm" }, + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { .clkdm_name = "l3init_clkdm" }, + { .clkdm_name = "l3main1_clkdm" }, + { .clkdm_name = "l3main2_clkdm" }, + { .clkdm_name = "l4cfg_clkdm" }, + { .clkdm_name = "l4per_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep cam_wkup_sleep_deps[] = { + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { .clkdm_name = "l3main1_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep dma_wkup_sleep_deps[] = { + { .clkdm_name = "abe_clkdm" }, + { .clkdm_name = "dss_clkdm" }, + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "ipu_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { .clkdm_name = "l3init_clkdm" }, + { .clkdm_name = "l3main1_clkdm" }, + { .clkdm_name = "l4cfg_clkdm" }, + { .clkdm_name = "l4per_clkdm" }, + { .clkdm_name = "l4sec_clkdm" }, + { .clkdm_name = "wkupaon_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep dsp_wkup_sleep_deps[] = { + { .clkdm_name = "abe_clkdm" }, + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { .clkdm_name = "l3init_clkdm" }, + { .clkdm_name = "l3main1_clkdm" }, + { .clkdm_name = "l3main2_clkdm" }, + { .clkdm_name = "l4cfg_clkdm" }, + { .clkdm_name = "l4per_clkdm" }, + { .clkdm_name = "wkupaon_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep dss_wkup_sleep_deps[] = { + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { .clkdm_name = "l3main2_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep gpu_wkup_sleep_deps[] = { + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { .clkdm_name = "l3main1_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep ipu_wkup_sleep_deps[] = { + { .clkdm_name = "abe_clkdm" }, + { .clkdm_name = "dsp_clkdm" }, + { .clkdm_name = "dss_clkdm" }, + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "gpu_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { .clkdm_name = "l3init_clkdm" }, + { .clkdm_name = "l3main1_clkdm" }, + { .clkdm_name = "l3main2_clkdm" }, + { .clkdm_name = "l4cfg_clkdm" }, + { .clkdm_name = "l4per_clkdm" }, + { .clkdm_name = "l4sec_clkdm" }, + { .clkdm_name = "wkupaon_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep iva_wkup_sleep_deps[] = { + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "l3main1_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep l3init_wkup_sleep_deps[] = { + { .clkdm_name = "abe_clkdm" }, + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { .clkdm_name = "l4cfg_clkdm" }, + { .clkdm_name = "l4per_clkdm" }, + { .clkdm_name = "l4sec_clkdm" }, + { .clkdm_name = "wkupaon_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep l4sec_wkup_sleep_deps[] = { + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "l3main1_clkdm" }, + { .clkdm_name = "l4per_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep mipiext_wkup_sleep_deps[] = { + { .clkdm_name = "abe_clkdm" }, + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { .clkdm_name = "l3init_clkdm" }, + { .clkdm_name = "l3main1_clkdm" }, + { .clkdm_name = "l3main2_clkdm" }, + { .clkdm_name = "l4cfg_clkdm" }, + { .clkdm_name = "l4per_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep mpu_wkup_sleep_deps[] = { + { .clkdm_name = "abe_clkdm" }, + { .clkdm_name = "dsp_clkdm" }, + { .clkdm_name = "dss_clkdm" }, + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "gpu_clkdm" }, + { .clkdm_name = "ipu_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { .clkdm_name = "l3init_clkdm" }, + { .clkdm_name = "l3main1_clkdm" }, + { .clkdm_name = "l3main2_clkdm" }, + { .clkdm_name = "l4cfg_clkdm" }, + { .clkdm_name = "l4per_clkdm" }, + { .clkdm_name = "l4sec_clkdm" }, + { .clkdm_name = "wkupaon_clkdm" }, + { NULL }, +}; + +static struct clockdomain l4sec_54xx_clkdm = { + .name = "l4sec_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_CORE_INST, + .clkdm_offs = OMAP54XX_CM_CORE_CORE_L4SEC_CDOFFS, + .dep_bit = OMAP54XX_L4SEC_STATDEP_SHIFT, + .wkdep_srcs = l4sec_wkup_sleep_deps, + .sleepdep_srcs = l4sec_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain iva_54xx_clkdm = { + .name = "iva_clkdm", + .pwrdm = { .name = "iva_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_IVA_INST, + .clkdm_offs = OMAP54XX_CM_CORE_IVA_IVA_CDOFFS, + .dep_bit = OMAP54XX_IVA_STATDEP_SHIFT, + .wkdep_srcs = iva_wkup_sleep_deps, + .sleepdep_srcs = iva_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain mipiext_54xx_clkdm = { + .name = "mipiext_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_CORE_INST, + .clkdm_offs = OMAP54XX_CM_CORE_CORE_MIPIEXT_CDOFFS, + .wkdep_srcs = mipiext_wkup_sleep_deps, + .sleepdep_srcs = mipiext_wkup_sleep_deps, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain l3main2_54xx_clkdm = { + .name = "l3main2_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_CORE_INST, + .clkdm_offs = OMAP54XX_CM_CORE_CORE_L3MAIN2_CDOFFS, + .dep_bit = OMAP54XX_L3MAIN2_STATDEP_SHIFT, + .flags = CLKDM_CAN_HWSUP, +}; + +static struct clockdomain l3main1_54xx_clkdm = { + .name = "l3main1_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_CORE_INST, + .clkdm_offs = OMAP54XX_CM_CORE_CORE_L3MAIN1_CDOFFS, + .dep_bit = OMAP54XX_L3MAIN1_STATDEP_SHIFT, + .flags = CLKDM_CAN_HWSUP, +}; + +static struct clockdomain custefuse_54xx_clkdm = { + .name = "custefuse_clkdm", + .pwrdm = { .name = "custefuse_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_CUSTEFUSE_INST, + .clkdm_offs = OMAP54XX_CM_CORE_CUSTEFUSE_CUSTEFUSE_CDOFFS, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain ipu_54xx_clkdm = { + .name = "ipu_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_CORE_INST, + .clkdm_offs = OMAP54XX_CM_CORE_CORE_IPU_CDOFFS, + .dep_bit = OMAP54XX_IPU_STATDEP_SHIFT, + .wkdep_srcs = ipu_wkup_sleep_deps, + .sleepdep_srcs = ipu_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain l4cfg_54xx_clkdm = { + .name = "l4cfg_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_CORE_INST, + .clkdm_offs = OMAP54XX_CM_CORE_CORE_L4CFG_CDOFFS, + .dep_bit = OMAP54XX_L4CFG_STATDEP_SHIFT, + .flags = CLKDM_CAN_HWSUP, +}; + +static struct clockdomain abe_54xx_clkdm = { + .name = "abe_clkdm", + .pwrdm = { .name = "abe_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_AON_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_AON_ABE_INST, + .clkdm_offs = OMAP54XX_CM_CORE_AON_ABE_ABE_CDOFFS, + .dep_bit = OMAP54XX_ABE_STATDEP_SHIFT, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain dss_54xx_clkdm = { + .name = "dss_clkdm", + .pwrdm = { .name = "dss_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_DSS_INST, + .clkdm_offs = OMAP54XX_CM_CORE_DSS_DSS_CDOFFS, + .dep_bit = OMAP54XX_DSS_STATDEP_SHIFT, + .wkdep_srcs = dss_wkup_sleep_deps, + .sleepdep_srcs = dss_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain dsp_54xx_clkdm = { + .name = "dsp_clkdm", + .pwrdm = { .name = "dsp_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_AON_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_AON_DSP_INST, + .clkdm_offs = OMAP54XX_CM_CORE_AON_DSP_DSP_CDOFFS, + .dep_bit = OMAP54XX_DSP_STATDEP_SHIFT, + .wkdep_srcs = dsp_wkup_sleep_deps, + .sleepdep_srcs = dsp_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain c2c_54xx_clkdm = { + .name = "c2c_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_CORE_INST, + .clkdm_offs = OMAP54XX_CM_CORE_CORE_C2C_CDOFFS, + .wkdep_srcs = c2c_wkup_sleep_deps, + .sleepdep_srcs = c2c_wkup_sleep_deps, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain l4per_54xx_clkdm = { + .name = "l4per_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_CORE_INST, + .clkdm_offs = OMAP54XX_CM_CORE_CORE_L4PER_CDOFFS, + .dep_bit = OMAP54XX_L4PER_STATDEP_SHIFT, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain gpu_54xx_clkdm = { + .name = "gpu_clkdm", + .pwrdm = { .name = "gpu_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_GPU_INST, + .clkdm_offs = OMAP54XX_CM_CORE_GPU_GPU_CDOFFS, + .dep_bit = OMAP54XX_GPU_STATDEP_SHIFT, + .wkdep_srcs = gpu_wkup_sleep_deps, + .sleepdep_srcs = gpu_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain wkupaon_54xx_clkdm = { + .name = "wkupaon_clkdm", + .pwrdm = { .name = "wkupaon_pwrdm" }, + .prcm_partition = OMAP54XX_PRM_PARTITION, + .cm_inst = OMAP54XX_PRM_WKUPAON_CM_INST, + .clkdm_offs = OMAP54XX_PRM_WKUPAON_CM_WKUPAON_CDOFFS, + .dep_bit = OMAP54XX_WKUPAON_STATDEP_SHIFT, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain mpu0_54xx_clkdm = { + .name = "mpu0_clkdm", + .pwrdm = { .name = "cpu0_pwrdm" }, + .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION, + .cm_inst = OMAP54XX_PRCM_MPU_CM_C0_INST, + .clkdm_offs = OMAP54XX_PRCM_MPU_CM_C0_CPU0_CDOFFS, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain mpu1_54xx_clkdm = { + .name = "mpu1_clkdm", + .pwrdm = { .name = "cpu1_pwrdm" }, + .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION, + .cm_inst = OMAP54XX_PRCM_MPU_CM_C1_INST, + .clkdm_offs = OMAP54XX_PRCM_MPU_CM_C1_CPU1_CDOFFS, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain coreaon_54xx_clkdm = { + .name = "coreaon_clkdm", + .pwrdm = { .name = "coreaon_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_COREAON_INST, + .clkdm_offs = OMAP54XX_CM_CORE_COREAON_COREAON_CDOFFS, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain mpu_54xx_clkdm = { + .name = "mpu_clkdm", + .pwrdm = { .name = "mpu_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_AON_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_AON_MPU_INST, + .clkdm_offs = OMAP54XX_CM_CORE_AON_MPU_MPU_CDOFFS, + .wkdep_srcs = mpu_wkup_sleep_deps, + .sleepdep_srcs = mpu_wkup_sleep_deps, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain l3init_54xx_clkdm = { + .name = "l3init_clkdm", + .pwrdm = { .name = "l3init_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_L3INIT_INST, + .clkdm_offs = OMAP54XX_CM_CORE_L3INIT_L3INIT_CDOFFS, + .dep_bit = OMAP54XX_L3INIT_STATDEP_SHIFT, + .wkdep_srcs = l3init_wkup_sleep_deps, + .sleepdep_srcs = l3init_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain dma_54xx_clkdm = { + .name = "dma_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_CORE_INST, + .clkdm_offs = OMAP54XX_CM_CORE_CORE_DMA_CDOFFS, + .wkdep_srcs = dma_wkup_sleep_deps, + .sleepdep_srcs = dma_wkup_sleep_deps, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain l3instr_54xx_clkdm = { + .name = "l3instr_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_CORE_INST, + .clkdm_offs = OMAP54XX_CM_CORE_CORE_L3INSTR_CDOFFS, +}; + +static struct clockdomain emif_54xx_clkdm = { + .name = "emif_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_CORE_INST, + .clkdm_offs = OMAP54XX_CM_CORE_CORE_EMIF_CDOFFS, + .dep_bit = OMAP54XX_EMIF_STATDEP_SHIFT, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain emu_54xx_clkdm = { + .name = "emu_clkdm", + .pwrdm = { .name = "emu_pwrdm" }, + .prcm_partition = OMAP54XX_PRM_PARTITION, + .cm_inst = OMAP54XX_PRM_EMU_CM_INST, + .clkdm_offs = OMAP54XX_PRM_EMU_CM_EMU_CDOFFS, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain cam_54xx_clkdm = { + .name = "cam_clkdm", + .pwrdm = { .name = "cam_pwrdm" }, + .prcm_partition = OMAP54XX_CM_CORE_PARTITION, + .cm_inst = OMAP54XX_CM_CORE_CAM_INST, + .clkdm_offs = OMAP54XX_CM_CORE_CAM_CAM_CDOFFS, + .wkdep_srcs = cam_wkup_sleep_deps, + .sleepdep_srcs = cam_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +/* As clockdomains are added or removed above, this list must also be changed */ +static struct clockdomain *clockdomains_omap54xx[] __initdata = { + &l4sec_54xx_clkdm, + &iva_54xx_clkdm, + &mipiext_54xx_clkdm, + &l3main2_54xx_clkdm, + &l3main1_54xx_clkdm, + &custefuse_54xx_clkdm, + &ipu_54xx_clkdm, + &l4cfg_54xx_clkdm, + &abe_54xx_clkdm, + &dss_54xx_clkdm, + &dsp_54xx_clkdm, + &c2c_54xx_clkdm, + &l4per_54xx_clkdm, + &gpu_54xx_clkdm, + &wkupaon_54xx_clkdm, + &mpu0_54xx_clkdm, + &mpu1_54xx_clkdm, + &coreaon_54xx_clkdm, + &mpu_54xx_clkdm, + &l3init_54xx_clkdm, + &dma_54xx_clkdm, + &l3instr_54xx_clkdm, + &emif_54xx_clkdm, + &emu_54xx_clkdm, + &cam_54xx_clkdm, + NULL +}; + +void __init omap54xx_clockdomains_init(void) +{ + clkdm_register_platform_funcs(&omap4_clkdm_operations); + clkdm_register_clkdms(clockdomains_omap54xx); + clkdm_complete_init(); +} diff --git a/arch/arm/mach-omap2/clockdomains7xx_data.c b/arch/arm/mach-omap2/clockdomains7xx_data.c new file mode 100644 index 00000000000..57d5df0c1fb --- /dev/null +++ b/arch/arm/mach-omap2/clockdomains7xx_data.c @@ -0,0 +1,740 @@ +/* + * DRA7xx Clock domains framework + * + * Copyright (C) 2009-2013 Texas Instruments, Inc. + * Copyright (C) 2009-2011 Nokia Corporation + * + * Generated by code originally written by: + * Abhijit Pagare (abhijitpagare@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * Paul Walmsley (paul@pwsan.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/io.h> + +#include "clockdomain.h" +#include "cm1_7xx.h" +#include "cm2_7xx.h" + +#include "cm-regbits-7xx.h" +#include "prm7xx.h" +#include "prcm44xx.h" +#include "prcm_mpu7xx.h" + +/* Static Dependencies for DRA7xx Clock Domains */ + +static struct clkdm_dep cam_wkup_sleep_deps[] = { + { .clkdm_name = "emif_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep dma_wkup_sleep_deps[] = { + { .clkdm_name = "dss_clkdm" }, + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "ipu_clkdm" }, + { .clkdm_name = "ipu1_clkdm" }, + { .clkdm_name = "ipu2_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { .clkdm_name = "l3init_clkdm" }, + { .clkdm_name = "l4cfg_clkdm" }, + { .clkdm_name = "l4per_clkdm" }, + { .clkdm_name = "l4per2_clkdm" }, + { .clkdm_name = "l4per3_clkdm" }, + { .clkdm_name = "l4sec_clkdm" }, + { .clkdm_name = "pcie_clkdm" }, + { .clkdm_name = "wkupaon_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep dsp1_wkup_sleep_deps[] = { + { .clkdm_name = "atl_clkdm" }, + { .clkdm_name = "cam_clkdm" }, + { .clkdm_name = "dsp2_clkdm" }, + { .clkdm_name = "dss_clkdm" }, + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "eve1_clkdm" }, + { .clkdm_name = "eve2_clkdm" }, + { .clkdm_name = "eve3_clkdm" }, + { .clkdm_name = "eve4_clkdm" }, + { .clkdm_name = "gmac_clkdm" }, + { .clkdm_name = "gpu_clkdm" }, + { .clkdm_name = "ipu_clkdm" }, + { .clkdm_name = "ipu1_clkdm" }, + { .clkdm_name = "ipu2_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { .clkdm_name = "l3init_clkdm" }, + { .clkdm_name = "l4per_clkdm" }, + { .clkdm_name = "l4per2_clkdm" }, + { .clkdm_name = "l4per3_clkdm" }, + { .clkdm_name = "l4sec_clkdm" }, + { .clkdm_name = "pcie_clkdm" }, + { .clkdm_name = "vpe_clkdm" }, + { .clkdm_name = "wkupaon_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep dsp2_wkup_sleep_deps[] = { + { .clkdm_name = "atl_clkdm" }, + { .clkdm_name = "cam_clkdm" }, + { .clkdm_name = "dsp1_clkdm" }, + { .clkdm_name = "dss_clkdm" }, + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "eve1_clkdm" }, + { .clkdm_name = "eve2_clkdm" }, + { .clkdm_name = "eve3_clkdm" }, + { .clkdm_name = "eve4_clkdm" }, + { .clkdm_name = "gmac_clkdm" }, + { .clkdm_name = "gpu_clkdm" }, + { .clkdm_name = "ipu_clkdm" }, + { .clkdm_name = "ipu1_clkdm" }, + { .clkdm_name = "ipu2_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { .clkdm_name = "l3init_clkdm" }, + { .clkdm_name = "l4per_clkdm" }, + { .clkdm_name = "l4per2_clkdm" }, + { .clkdm_name = "l4per3_clkdm" }, + { .clkdm_name = "l4sec_clkdm" }, + { .clkdm_name = "pcie_clkdm" }, + { .clkdm_name = "vpe_clkdm" }, + { .clkdm_name = "wkupaon_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep dss_wkup_sleep_deps[] = { + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep eve1_wkup_sleep_deps[] = { + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "eve2_clkdm" }, + { .clkdm_name = "eve3_clkdm" }, + { .clkdm_name = "eve4_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep eve2_wkup_sleep_deps[] = { + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "eve1_clkdm" }, + { .clkdm_name = "eve3_clkdm" }, + { .clkdm_name = "eve4_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep eve3_wkup_sleep_deps[] = { + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "eve1_clkdm" }, + { .clkdm_name = "eve2_clkdm" }, + { .clkdm_name = "eve4_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep eve4_wkup_sleep_deps[] = { + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "eve1_clkdm" }, + { .clkdm_name = "eve2_clkdm" }, + { .clkdm_name = "eve3_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep gmac_wkup_sleep_deps[] = { + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "l4per2_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep gpu_wkup_sleep_deps[] = { + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep ipu1_wkup_sleep_deps[] = { + { .clkdm_name = "atl_clkdm" }, + { .clkdm_name = "dsp1_clkdm" }, + { .clkdm_name = "dsp2_clkdm" }, + { .clkdm_name = "dss_clkdm" }, + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "eve1_clkdm" }, + { .clkdm_name = "eve2_clkdm" }, + { .clkdm_name = "eve3_clkdm" }, + { .clkdm_name = "eve4_clkdm" }, + { .clkdm_name = "gmac_clkdm" }, + { .clkdm_name = "gpu_clkdm" }, + { .clkdm_name = "ipu_clkdm" }, + { .clkdm_name = "ipu2_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { .clkdm_name = "l3init_clkdm" }, + { .clkdm_name = "l3main1_clkdm" }, + { .clkdm_name = "l4cfg_clkdm" }, + { .clkdm_name = "l4per_clkdm" }, + { .clkdm_name = "l4per2_clkdm" }, + { .clkdm_name = "l4per3_clkdm" }, + { .clkdm_name = "l4sec_clkdm" }, + { .clkdm_name = "pcie_clkdm" }, + { .clkdm_name = "vpe_clkdm" }, + { .clkdm_name = "wkupaon_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep ipu2_wkup_sleep_deps[] = { + { .clkdm_name = "atl_clkdm" }, + { .clkdm_name = "dsp1_clkdm" }, + { .clkdm_name = "dsp2_clkdm" }, + { .clkdm_name = "dss_clkdm" }, + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "eve1_clkdm" }, + { .clkdm_name = "eve2_clkdm" }, + { .clkdm_name = "eve3_clkdm" }, + { .clkdm_name = "eve4_clkdm" }, + { .clkdm_name = "gmac_clkdm" }, + { .clkdm_name = "gpu_clkdm" }, + { .clkdm_name = "ipu_clkdm" }, + { .clkdm_name = "ipu1_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { .clkdm_name = "l3init_clkdm" }, + { .clkdm_name = "l3main1_clkdm" }, + { .clkdm_name = "l4cfg_clkdm" }, + { .clkdm_name = "l4per_clkdm" }, + { .clkdm_name = "l4per2_clkdm" }, + { .clkdm_name = "l4per3_clkdm" }, + { .clkdm_name = "l4sec_clkdm" }, + { .clkdm_name = "pcie_clkdm" }, + { .clkdm_name = "vpe_clkdm" }, + { .clkdm_name = "wkupaon_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep iva_wkup_sleep_deps[] = { + { .clkdm_name = "emif_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep l3init_wkup_sleep_deps[] = { + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { .clkdm_name = "l4cfg_clkdm" }, + { .clkdm_name = "l4per_clkdm" }, + { .clkdm_name = "l4per3_clkdm" }, + { .clkdm_name = "l4sec_clkdm" }, + { .clkdm_name = "wkupaon_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep l4per2_wkup_sleep_deps[] = { + { .clkdm_name = "dsp1_clkdm" }, + { .clkdm_name = "dsp2_clkdm" }, + { .clkdm_name = "ipu1_clkdm" }, + { .clkdm_name = "ipu2_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep l4sec_wkup_sleep_deps[] = { + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "l4per_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep mpu_wkup_sleep_deps[] = { + { .clkdm_name = "cam_clkdm" }, + { .clkdm_name = "dsp1_clkdm" }, + { .clkdm_name = "dsp2_clkdm" }, + { .clkdm_name = "dss_clkdm" }, + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "eve1_clkdm" }, + { .clkdm_name = "eve2_clkdm" }, + { .clkdm_name = "eve3_clkdm" }, + { .clkdm_name = "eve4_clkdm" }, + { .clkdm_name = "gmac_clkdm" }, + { .clkdm_name = "gpu_clkdm" }, + { .clkdm_name = "ipu_clkdm" }, + { .clkdm_name = "ipu1_clkdm" }, + { .clkdm_name = "ipu2_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { .clkdm_name = "l3init_clkdm" }, + { .clkdm_name = "l3main1_clkdm" }, + { .clkdm_name = "l4cfg_clkdm" }, + { .clkdm_name = "l4per_clkdm" }, + { .clkdm_name = "l4per2_clkdm" }, + { .clkdm_name = "l4per3_clkdm" }, + { .clkdm_name = "l4sec_clkdm" }, + { .clkdm_name = "pcie_clkdm" }, + { .clkdm_name = "vpe_clkdm" }, + { .clkdm_name = "wkupaon_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep pcie_wkup_sleep_deps[] = { + { .clkdm_name = "atl_clkdm" }, + { .clkdm_name = "cam_clkdm" }, + { .clkdm_name = "dsp1_clkdm" }, + { .clkdm_name = "dsp2_clkdm" }, + { .clkdm_name = "dss_clkdm" }, + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "eve1_clkdm" }, + { .clkdm_name = "eve2_clkdm" }, + { .clkdm_name = "eve3_clkdm" }, + { .clkdm_name = "eve4_clkdm" }, + { .clkdm_name = "gmac_clkdm" }, + { .clkdm_name = "gpu_clkdm" }, + { .clkdm_name = "ipu_clkdm" }, + { .clkdm_name = "ipu1_clkdm" }, + { .clkdm_name = "iva_clkdm" }, + { .clkdm_name = "l3init_clkdm" }, + { .clkdm_name = "l4cfg_clkdm" }, + { .clkdm_name = "l4per_clkdm" }, + { .clkdm_name = "l4per2_clkdm" }, + { .clkdm_name = "l4per3_clkdm" }, + { .clkdm_name = "l4sec_clkdm" }, + { .clkdm_name = "vpe_clkdm" }, + { NULL }, +}; + +static struct clkdm_dep vpe_wkup_sleep_deps[] = { + { .clkdm_name = "emif_clkdm" }, + { .clkdm_name = "l4per3_clkdm" }, + { NULL }, +}; + +static struct clockdomain l4per3_7xx_clkdm = { + .name = "l4per3_clkdm", + .pwrdm = { .name = "l4per_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_L4PER_INST, + .clkdm_offs = DRA7XX_CM_CORE_L4PER_L4PER3_CDOFFS, + .dep_bit = DRA7XX_L4PER3_STATDEP_SHIFT, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain l4per2_7xx_clkdm = { + .name = "l4per2_clkdm", + .pwrdm = { .name = "l4per_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_L4PER_INST, + .clkdm_offs = DRA7XX_CM_CORE_L4PER_L4PER2_CDOFFS, + .dep_bit = DRA7XX_L4PER2_STATDEP_SHIFT, + .wkdep_srcs = l4per2_wkup_sleep_deps, + .sleepdep_srcs = l4per2_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain mpu0_7xx_clkdm = { + .name = "mpu0_clkdm", + .pwrdm = { .name = "cpu0_pwrdm" }, + .prcm_partition = DRA7XX_MPU_PRCM_PARTITION, + .cm_inst = DRA7XX_MPU_PRCM_CM_C0_INST, + .clkdm_offs = DRA7XX_MPU_PRCM_CM_C0_CPU0_CDOFFS, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain iva_7xx_clkdm = { + .name = "iva_clkdm", + .pwrdm = { .name = "iva_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_IVA_INST, + .clkdm_offs = DRA7XX_CM_CORE_IVA_IVA_CDOFFS, + .dep_bit = DRA7XX_IVA_STATDEP_SHIFT, + .wkdep_srcs = iva_wkup_sleep_deps, + .sleepdep_srcs = iva_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain coreaon_7xx_clkdm = { + .name = "coreaon_clkdm", + .pwrdm = { .name = "coreaon_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_COREAON_INST, + .clkdm_offs = DRA7XX_CM_CORE_COREAON_COREAON_CDOFFS, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain ipu1_7xx_clkdm = { + .name = "ipu1_clkdm", + .pwrdm = { .name = "ipu_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION, + .cm_inst = DRA7XX_CM_CORE_AON_IPU_INST, + .clkdm_offs = DRA7XX_CM_CORE_AON_IPU_IPU1_CDOFFS, + .dep_bit = DRA7XX_IPU1_STATDEP_SHIFT, + .wkdep_srcs = ipu1_wkup_sleep_deps, + .sleepdep_srcs = ipu1_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain ipu2_7xx_clkdm = { + .name = "ipu2_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_CORE_INST, + .clkdm_offs = DRA7XX_CM_CORE_CORE_IPU2_CDOFFS, + .dep_bit = DRA7XX_IPU2_STATDEP_SHIFT, + .wkdep_srcs = ipu2_wkup_sleep_deps, + .sleepdep_srcs = ipu2_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain l3init_7xx_clkdm = { + .name = "l3init_clkdm", + .pwrdm = { .name = "l3init_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_L3INIT_INST, + .clkdm_offs = DRA7XX_CM_CORE_L3INIT_L3INIT_CDOFFS, + .dep_bit = DRA7XX_L3INIT_STATDEP_SHIFT, + .wkdep_srcs = l3init_wkup_sleep_deps, + .sleepdep_srcs = l3init_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain l4sec_7xx_clkdm = { + .name = "l4sec_clkdm", + .pwrdm = { .name = "l4per_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_L4PER_INST, + .clkdm_offs = DRA7XX_CM_CORE_L4PER_L4SEC_CDOFFS, + .dep_bit = DRA7XX_L4SEC_STATDEP_SHIFT, + .wkdep_srcs = l4sec_wkup_sleep_deps, + .sleepdep_srcs = l4sec_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain l3main1_7xx_clkdm = { + .name = "l3main1_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_CORE_INST, + .clkdm_offs = DRA7XX_CM_CORE_CORE_L3MAIN1_CDOFFS, + .dep_bit = DRA7XX_L3MAIN1_STATDEP_SHIFT, + .flags = CLKDM_CAN_HWSUP, +}; + +static struct clockdomain vpe_7xx_clkdm = { + .name = "vpe_clkdm", + .pwrdm = { .name = "vpe_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION, + .cm_inst = DRA7XX_CM_CORE_AON_VPE_INST, + .clkdm_offs = DRA7XX_CM_CORE_AON_VPE_VPE_CDOFFS, + .dep_bit = DRA7XX_VPE_STATDEP_SHIFT, + .wkdep_srcs = vpe_wkup_sleep_deps, + .sleepdep_srcs = vpe_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain mpu_7xx_clkdm = { + .name = "mpu_clkdm", + .pwrdm = { .name = "mpu_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION, + .cm_inst = DRA7XX_CM_CORE_AON_MPU_INST, + .clkdm_offs = DRA7XX_CM_CORE_AON_MPU_MPU_CDOFFS, + .wkdep_srcs = mpu_wkup_sleep_deps, + .sleepdep_srcs = mpu_wkup_sleep_deps, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain custefuse_7xx_clkdm = { + .name = "custefuse_clkdm", + .pwrdm = { .name = "custefuse_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_CUSTEFUSE_INST, + .clkdm_offs = DRA7XX_CM_CORE_CUSTEFUSE_CUSTEFUSE_CDOFFS, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain ipu_7xx_clkdm = { + .name = "ipu_clkdm", + .pwrdm = { .name = "ipu_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION, + .cm_inst = DRA7XX_CM_CORE_AON_IPU_INST, + .clkdm_offs = DRA7XX_CM_CORE_AON_IPU_IPU_CDOFFS, + .dep_bit = DRA7XX_IPU_STATDEP_SHIFT, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain mpu1_7xx_clkdm = { + .name = "mpu1_clkdm", + .pwrdm = { .name = "cpu1_pwrdm" }, + .prcm_partition = DRA7XX_MPU_PRCM_PARTITION, + .cm_inst = DRA7XX_MPU_PRCM_CM_C1_INST, + .clkdm_offs = DRA7XX_MPU_PRCM_CM_C1_CPU1_CDOFFS, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain gmac_7xx_clkdm = { + .name = "gmac_clkdm", + .pwrdm = { .name = "l3init_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_L3INIT_INST, + .clkdm_offs = DRA7XX_CM_CORE_L3INIT_GMAC_CDOFFS, + .dep_bit = DRA7XX_GMAC_STATDEP_SHIFT, + .wkdep_srcs = gmac_wkup_sleep_deps, + .sleepdep_srcs = gmac_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain l4cfg_7xx_clkdm = { + .name = "l4cfg_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_CORE_INST, + .clkdm_offs = DRA7XX_CM_CORE_CORE_L4CFG_CDOFFS, + .dep_bit = DRA7XX_L4CFG_STATDEP_SHIFT, + .flags = CLKDM_CAN_HWSUP, +}; + +static struct clockdomain dma_7xx_clkdm = { + .name = "dma_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_CORE_INST, + .clkdm_offs = DRA7XX_CM_CORE_CORE_DMA_CDOFFS, + .wkdep_srcs = dma_wkup_sleep_deps, + .sleepdep_srcs = dma_wkup_sleep_deps, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain rtc_7xx_clkdm = { + .name = "rtc_clkdm", + .pwrdm = { .name = "rtc_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION, + .cm_inst = DRA7XX_CM_CORE_AON_RTC_INST, + .clkdm_offs = DRA7XX_CM_CORE_AON_RTC_RTC_CDOFFS, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain pcie_7xx_clkdm = { + .name = "pcie_clkdm", + .pwrdm = { .name = "l3init_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_L3INIT_INST, + .clkdm_offs = DRA7XX_CM_CORE_L3INIT_PCIE_CDOFFS, + .dep_bit = DRA7XX_PCIE_STATDEP_SHIFT, + .wkdep_srcs = pcie_wkup_sleep_deps, + .sleepdep_srcs = pcie_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain atl_7xx_clkdm = { + .name = "atl_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_CORE_INST, + .clkdm_offs = DRA7XX_CM_CORE_CORE_ATL_CDOFFS, + .dep_bit = DRA7XX_ATL_STATDEP_SHIFT, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain l3instr_7xx_clkdm = { + .name = "l3instr_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_CORE_INST, + .clkdm_offs = DRA7XX_CM_CORE_CORE_L3INSTR_CDOFFS, +}; + +static struct clockdomain dss_7xx_clkdm = { + .name = "dss_clkdm", + .pwrdm = { .name = "dss_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_DSS_INST, + .clkdm_offs = DRA7XX_CM_CORE_DSS_DSS_CDOFFS, + .dep_bit = DRA7XX_DSS_STATDEP_SHIFT, + .wkdep_srcs = dss_wkup_sleep_deps, + .sleepdep_srcs = dss_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain emif_7xx_clkdm = { + .name = "emif_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_CORE_INST, + .clkdm_offs = DRA7XX_CM_CORE_CORE_EMIF_CDOFFS, + .dep_bit = DRA7XX_EMIF_STATDEP_SHIFT, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain emu_7xx_clkdm = { + .name = "emu_clkdm", + .pwrdm = { .name = "emu_pwrdm" }, + .prcm_partition = DRA7XX_PRM_PARTITION, + .cm_inst = DRA7XX_PRM_EMU_CM_INST, + .clkdm_offs = DRA7XX_PRM_EMU_CM_EMU_CDOFFS, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain dsp2_7xx_clkdm = { + .name = "dsp2_clkdm", + .pwrdm = { .name = "dsp2_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION, + .cm_inst = DRA7XX_CM_CORE_AON_DSP2_INST, + .clkdm_offs = DRA7XX_CM_CORE_AON_DSP2_DSP2_CDOFFS, + .dep_bit = DRA7XX_DSP2_STATDEP_SHIFT, + .wkdep_srcs = dsp2_wkup_sleep_deps, + .sleepdep_srcs = dsp2_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain dsp1_7xx_clkdm = { + .name = "dsp1_clkdm", + .pwrdm = { .name = "dsp1_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION, + .cm_inst = DRA7XX_CM_CORE_AON_DSP1_INST, + .clkdm_offs = DRA7XX_CM_CORE_AON_DSP1_DSP1_CDOFFS, + .dep_bit = DRA7XX_DSP1_STATDEP_SHIFT, + .wkdep_srcs = dsp1_wkup_sleep_deps, + .sleepdep_srcs = dsp1_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain cam_7xx_clkdm = { + .name = "cam_clkdm", + .pwrdm = { .name = "cam_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_CAM_INST, + .clkdm_offs = DRA7XX_CM_CORE_CAM_CAM_CDOFFS, + .dep_bit = DRA7XX_CAM_STATDEP_SHIFT, + .wkdep_srcs = cam_wkup_sleep_deps, + .sleepdep_srcs = cam_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain l4per_7xx_clkdm = { + .name = "l4per_clkdm", + .pwrdm = { .name = "l4per_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_L4PER_INST, + .clkdm_offs = DRA7XX_CM_CORE_L4PER_L4PER_CDOFFS, + .dep_bit = DRA7XX_L4PER_STATDEP_SHIFT, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain gpu_7xx_clkdm = { + .name = "gpu_clkdm", + .pwrdm = { .name = "gpu_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_PARTITION, + .cm_inst = DRA7XX_CM_CORE_GPU_INST, + .clkdm_offs = DRA7XX_CM_CORE_GPU_GPU_CDOFFS, + .dep_bit = DRA7XX_GPU_STATDEP_SHIFT, + .wkdep_srcs = gpu_wkup_sleep_deps, + .sleepdep_srcs = gpu_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain eve4_7xx_clkdm = { + .name = "eve4_clkdm", + .pwrdm = { .name = "eve4_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION, + .cm_inst = DRA7XX_CM_CORE_AON_EVE4_INST, + .clkdm_offs = DRA7XX_CM_CORE_AON_EVE4_EVE4_CDOFFS, + .dep_bit = DRA7XX_EVE4_STATDEP_SHIFT, + .wkdep_srcs = eve4_wkup_sleep_deps, + .sleepdep_srcs = eve4_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain eve2_7xx_clkdm = { + .name = "eve2_clkdm", + .pwrdm = { .name = "eve2_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION, + .cm_inst = DRA7XX_CM_CORE_AON_EVE2_INST, + .clkdm_offs = DRA7XX_CM_CORE_AON_EVE2_EVE2_CDOFFS, + .dep_bit = DRA7XX_EVE2_STATDEP_SHIFT, + .wkdep_srcs = eve2_wkup_sleep_deps, + .sleepdep_srcs = eve2_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain eve3_7xx_clkdm = { + .name = "eve3_clkdm", + .pwrdm = { .name = "eve3_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION, + .cm_inst = DRA7XX_CM_CORE_AON_EVE3_INST, + .clkdm_offs = DRA7XX_CM_CORE_AON_EVE3_EVE3_CDOFFS, + .dep_bit = DRA7XX_EVE3_STATDEP_SHIFT, + .wkdep_srcs = eve3_wkup_sleep_deps, + .sleepdep_srcs = eve3_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +static struct clockdomain wkupaon_7xx_clkdm = { + .name = "wkupaon_clkdm", + .pwrdm = { .name = "wkupaon_pwrdm" }, + .prcm_partition = DRA7XX_PRM_PARTITION, + .cm_inst = DRA7XX_PRM_WKUPAON_CM_INST, + .clkdm_offs = DRA7XX_PRM_WKUPAON_CM_WKUPAON_CDOFFS, + .dep_bit = DRA7XX_WKUPAON_STATDEP_SHIFT, + .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, +}; + +static struct clockdomain eve1_7xx_clkdm = { + .name = "eve1_clkdm", + .pwrdm = { .name = "eve1_pwrdm" }, + .prcm_partition = DRA7XX_CM_CORE_AON_PARTITION, + .cm_inst = DRA7XX_CM_CORE_AON_EVE1_INST, + .clkdm_offs = DRA7XX_CM_CORE_AON_EVE1_EVE1_CDOFFS, + .dep_bit = DRA7XX_EVE1_STATDEP_SHIFT, + .wkdep_srcs = eve1_wkup_sleep_deps, + .sleepdep_srcs = eve1_wkup_sleep_deps, + .flags = CLKDM_CAN_HWSUP_SWSUP, +}; + +/* As clockdomains are added or removed above, this list must also be changed */ +static struct clockdomain *clockdomains_dra7xx[] __initdata = { + &l4per3_7xx_clkdm, + &l4per2_7xx_clkdm, + &mpu0_7xx_clkdm, + &iva_7xx_clkdm, + &coreaon_7xx_clkdm, + &ipu1_7xx_clkdm, + &ipu2_7xx_clkdm, + &l3init_7xx_clkdm, + &l4sec_7xx_clkdm, + &l3main1_7xx_clkdm, + &vpe_7xx_clkdm, + &mpu_7xx_clkdm, + &custefuse_7xx_clkdm, + &ipu_7xx_clkdm, + &mpu1_7xx_clkdm, + &gmac_7xx_clkdm, + &l4cfg_7xx_clkdm, + &dma_7xx_clkdm, + &rtc_7xx_clkdm, + &pcie_7xx_clkdm, + &atl_7xx_clkdm, + &l3instr_7xx_clkdm, + &dss_7xx_clkdm, + &emif_7xx_clkdm, + &emu_7xx_clkdm, + &dsp2_7xx_clkdm, + &dsp1_7xx_clkdm, + &cam_7xx_clkdm, + &l4per_7xx_clkdm, + &gpu_7xx_clkdm, + &eve4_7xx_clkdm, + &eve2_7xx_clkdm, + &eve3_7xx_clkdm, + &wkupaon_7xx_clkdm, + &eve1_7xx_clkdm, + NULL +}; + +void __init dra7xx_clockdomains_init(void) +{ + clkdm_register_platform_funcs(&omap4_clkdm_operations); + clkdm_register_clkdms(clockdomains_dra7xx); + clkdm_complete_init(); +} diff --git a/arch/arm/mach-omap2/cm-regbits-24xx.h b/arch/arm/mach-omap2/cm-regbits-24xx.h index 1098ecfab86..8538669cc2a 100644 --- a/arch/arm/mach-omap2/cm-regbits-24xx.h +++ b/arch/arm/mach-omap2/cm-regbits-24xx.h @@ -14,396 +14,121 @@ * published by the Free Software Foundation. */ -#include "cm.h" - -/* Bits shared between registers */ - -/* CM_FCLKEN1_CORE and CM_ICLKEN1_CORE shared bits */ #define OMAP24XX_EN_CAM_SHIFT 31 -#define OMAP24XX_EN_CAM (1 << 31) #define OMAP24XX_EN_WDT4_SHIFT 29 -#define OMAP24XX_EN_WDT4 (1 << 29) #define OMAP2420_EN_WDT3_SHIFT 28 -#define OMAP2420_EN_WDT3 (1 << 28) #define OMAP24XX_EN_MSPRO_SHIFT 27 -#define OMAP24XX_EN_MSPRO (1 << 27) #define OMAP24XX_EN_FAC_SHIFT 25 -#define OMAP24XX_EN_FAC (1 << 25) #define OMAP2420_EN_EAC_SHIFT 24 -#define OMAP2420_EN_EAC (1 << 24) #define OMAP24XX_EN_HDQ_SHIFT 23 -#define OMAP24XX_EN_HDQ (1 << 23) #define OMAP2420_EN_I2C2_SHIFT 20 -#define OMAP2420_EN_I2C2 (1 << 20) #define OMAP2420_EN_I2C1_SHIFT 19 -#define OMAP2420_EN_I2C1 (1 << 19) - -/* CM_FCLKEN2_CORE and CM_ICLKEN2_CORE shared bits */ #define OMAP2430_EN_MCBSP5_SHIFT 5 -#define OMAP2430_EN_MCBSP5 (1 << 5) #define OMAP2430_EN_MCBSP4_SHIFT 4 -#define OMAP2430_EN_MCBSP4 (1 << 4) #define OMAP2430_EN_MCBSP3_SHIFT 3 -#define OMAP2430_EN_MCBSP3 (1 << 3) #define OMAP24XX_EN_SSI_SHIFT 1 -#define OMAP24XX_EN_SSI (1 << 1) - -/* CM_FCLKEN_WKUP and CM_ICLKEN_WKUP shared bits */ #define OMAP24XX_EN_MPU_WDT_SHIFT 3 -#define OMAP24XX_EN_MPU_WDT (1 << 3) - -/* Bits specific to each register */ - -/* CM_IDLEST_MPU */ -/* 2430 only */ -#define OMAP2430_ST_MPU (1 << 0) - -/* CM_CLKSEL_MPU */ #define OMAP24XX_CLKSEL_MPU_SHIFT 0 -#define OMAP24XX_CLKSEL_MPU_MASK (0x1f << 0) - -/* CM_CLKSTCTRL_MPU */ -#define OMAP24XX_AUTOSTATE_MPU_SHIFT 0 +#define OMAP24XX_CLKSEL_MPU_WIDTH 5 #define OMAP24XX_AUTOSTATE_MPU_MASK (1 << 0) - -/* CM_FCLKEN1_CORE specific bits*/ #define OMAP24XX_EN_TV_SHIFT 2 -#define OMAP24XX_EN_TV (1 << 2) #define OMAP24XX_EN_DSS2_SHIFT 1 -#define OMAP24XX_EN_DSS2 (1 << 1) #define OMAP24XX_EN_DSS1_SHIFT 0 -#define OMAP24XX_EN_DSS1 (1 << 0) - -/* CM_FCLKEN2_CORE specific bits */ +#define OMAP24XX_EN_DSS1_MASK (1 << 0) #define OMAP2430_EN_I2CHS2_SHIFT 20 -#define OMAP2430_EN_I2CHS2 (1 << 20) #define OMAP2430_EN_I2CHS1_SHIFT 19 -#define OMAP2430_EN_I2CHS1 (1 << 19) #define OMAP2430_EN_MMCHSDB2_SHIFT 17 -#define OMAP2430_EN_MMCHSDB2 (1 << 17) #define OMAP2430_EN_MMCHSDB1_SHIFT 16 -#define OMAP2430_EN_MMCHSDB1 (1 << 16) - -/* CM_ICLKEN1_CORE specific bits */ #define OMAP24XX_EN_MAILBOXES_SHIFT 30 -#define OMAP24XX_EN_MAILBOXES (1 << 30) -#define OMAP24XX_EN_DSS_SHIFT 0 -#define OMAP24XX_EN_DSS (1 << 0) - -/* CM_ICLKEN2_CORE specific bits */ - -/* CM_ICLKEN3_CORE */ -/* 2430 only */ #define OMAP2430_EN_SDRC_SHIFT 2 -#define OMAP2430_EN_SDRC (1 << 2) - -/* CM_ICLKEN4_CORE */ #define OMAP24XX_EN_PKA_SHIFT 4 -#define OMAP24XX_EN_PKA (1 << 4) #define OMAP24XX_EN_AES_SHIFT 3 -#define OMAP24XX_EN_AES (1 << 3) #define OMAP24XX_EN_RNG_SHIFT 2 -#define OMAP24XX_EN_RNG (1 << 2) #define OMAP24XX_EN_SHA_SHIFT 1 -#define OMAP24XX_EN_SHA (1 << 1) #define OMAP24XX_EN_DES_SHIFT 0 -#define OMAP24XX_EN_DES (1 << 0) - -/* CM_IDLEST1_CORE specific bits */ -#define OMAP24XX_ST_MAILBOXES (1 << 30) -#define OMAP24XX_ST_WDT4 (1 << 29) -#define OMAP2420_ST_WDT3 (1 << 28) -#define OMAP24XX_ST_MSPRO (1 << 27) -#define OMAP24XX_ST_FAC (1 << 25) -#define OMAP2420_ST_EAC (1 << 24) -#define OMAP24XX_ST_HDQ (1 << 23) -#define OMAP24XX_ST_I2C2 (1 << 20) -#define OMAP24XX_ST_I2C1 (1 << 19) -#define OMAP24XX_ST_MCBSP2 (1 << 16) -#define OMAP24XX_ST_MCBSP1 (1 << 15) -#define OMAP24XX_ST_DSS (1 << 0) - -/* CM_IDLEST2_CORE */ -#define OMAP2430_ST_MCBSP5 (1 << 5) -#define OMAP2430_ST_MCBSP4 (1 << 4) -#define OMAP2430_ST_MCBSP3 (1 << 3) -#define OMAP24XX_ST_SSI (1 << 1) - -/* CM_IDLEST3_CORE */ -/* 2430 only */ -#define OMAP2430_ST_SDRC (1 << 2) - -/* CM_IDLEST4_CORE */ -#define OMAP24XX_ST_PKA (1 << 4) -#define OMAP24XX_ST_AES (1 << 3) -#define OMAP24XX_ST_RNG (1 << 2) -#define OMAP24XX_ST_SHA (1 << 1) -#define OMAP24XX_ST_DES (1 << 0) - -/* CM_AUTOIDLE1_CORE */ -#define OMAP24XX_AUTO_CAM (1 << 31) -#define OMAP24XX_AUTO_MAILBOXES (1 << 30) -#define OMAP24XX_AUTO_WDT4 (1 << 29) -#define OMAP2420_AUTO_WDT3 (1 << 28) -#define OMAP24XX_AUTO_MSPRO (1 << 27) -#define OMAP2420_AUTO_MMC (1 << 26) -#define OMAP24XX_AUTO_FAC (1 << 25) -#define OMAP2420_AUTO_EAC (1 << 24) -#define OMAP24XX_AUTO_HDQ (1 << 23) -#define OMAP24XX_AUTO_UART2 (1 << 22) -#define OMAP24XX_AUTO_UART1 (1 << 21) -#define OMAP24XX_AUTO_I2C2 (1 << 20) -#define OMAP24XX_AUTO_I2C1 (1 << 19) -#define OMAP24XX_AUTO_MCSPI2 (1 << 18) -#define OMAP24XX_AUTO_MCSPI1 (1 << 17) -#define OMAP24XX_AUTO_MCBSP2 (1 << 16) -#define OMAP24XX_AUTO_MCBSP1 (1 << 15) -#define OMAP24XX_AUTO_GPT12 (1 << 14) -#define OMAP24XX_AUTO_GPT11 (1 << 13) -#define OMAP24XX_AUTO_GPT10 (1 << 12) -#define OMAP24XX_AUTO_GPT9 (1 << 11) -#define OMAP24XX_AUTO_GPT8 (1 << 10) -#define OMAP24XX_AUTO_GPT7 (1 << 9) -#define OMAP24XX_AUTO_GPT6 (1 << 8) -#define OMAP24XX_AUTO_GPT5 (1 << 7) -#define OMAP24XX_AUTO_GPT4 (1 << 6) -#define OMAP24XX_AUTO_GPT3 (1 << 5) -#define OMAP24XX_AUTO_GPT2 (1 << 4) -#define OMAP2420_AUTO_VLYNQ (1 << 3) -#define OMAP24XX_AUTO_DSS (1 << 0) - -/* CM_AUTOIDLE2_CORE */ -#define OMAP2430_AUTO_MDM_INTC (1 << 11) -#define OMAP2430_AUTO_GPIO5 (1 << 10) -#define OMAP2430_AUTO_MCSPI3 (1 << 9) -#define OMAP2430_AUTO_MMCHS2 (1 << 8) -#define OMAP2430_AUTO_MMCHS1 (1 << 7) -#define OMAP2430_AUTO_USBHS (1 << 6) -#define OMAP2430_AUTO_MCBSP5 (1 << 5) -#define OMAP2430_AUTO_MCBSP4 (1 << 4) -#define OMAP2430_AUTO_MCBSP3 (1 << 3) -#define OMAP24XX_AUTO_UART3 (1 << 2) -#define OMAP24XX_AUTO_SSI (1 << 1) -#define OMAP24XX_AUTO_USB (1 << 0) - -/* CM_AUTOIDLE3_CORE */ -#define OMAP24XX_AUTO_SDRC (1 << 2) -#define OMAP24XX_AUTO_GPMC (1 << 1) -#define OMAP24XX_AUTO_SDMA (1 << 0) - -/* CM_AUTOIDLE4_CORE */ -#define OMAP24XX_AUTO_PKA (1 << 4) -#define OMAP24XX_AUTO_AES (1 << 3) -#define OMAP24XX_AUTO_RNG (1 << 2) -#define OMAP24XX_AUTO_SHA (1 << 1) -#define OMAP24XX_AUTO_DES (1 << 0) - -/* CM_CLKSEL1_CORE */ -#define OMAP24XX_CLKSEL_USB_SHIFT 25 +#define OMAP24XX_ST_MAILBOXES_SHIFT 30 +#define OMAP24XX_ST_HDQ_SHIFT 23 +#define OMAP2420_ST_I2C2_SHIFT 20 +#define OMAP2430_ST_I2CHS1_SHIFT 19 +#define OMAP2420_ST_I2C1_SHIFT 19 +#define OMAP2430_ST_I2CHS2_SHIFT 20 +#define OMAP24XX_ST_MCBSP2_SHIFT 16 +#define OMAP24XX_ST_MCBSP1_SHIFT 15 +#define OMAP24XX_ST_DSS_SHIFT 0 +#define OMAP2430_ST_MCBSP5_SHIFT 5 +#define OMAP2430_ST_MCBSP4_SHIFT 4 +#define OMAP2430_ST_MCBSP3_SHIFT 3 +#define OMAP24XX_ST_AES_SHIFT 3 +#define OMAP24XX_ST_RNG_SHIFT 2 +#define OMAP24XX_ST_SHA_SHIFT 1 +#define OMAP24XX_AUTO_SDRC_SHIFT 2 +#define OMAP24XX_AUTO_GPMC_SHIFT 1 +#define OMAP24XX_AUTO_SDMA_SHIFT 0 #define OMAP24XX_CLKSEL_USB_MASK (0x7 << 25) -#define OMAP24XX_CLKSEL_SSI_SHIFT 20 #define OMAP24XX_CLKSEL_SSI_MASK (0x1f << 20) -#define OMAP2420_CLKSEL_VLYNQ_SHIFT 15 #define OMAP2420_CLKSEL_VLYNQ_MASK (0x1f << 15) -#define OMAP24XX_CLKSEL_DSS2_SHIFT 13 #define OMAP24XX_CLKSEL_DSS2_MASK (0x1 << 13) -#define OMAP24XX_CLKSEL_DSS1_SHIFT 8 #define OMAP24XX_CLKSEL_DSS1_MASK (0x1f << 8) #define OMAP24XX_CLKSEL_L4_SHIFT 5 -#define OMAP24XX_CLKSEL_L4_MASK (0x3 << 5) +#define OMAP24XX_CLKSEL_L4_WIDTH 2 #define OMAP24XX_CLKSEL_L3_SHIFT 0 -#define OMAP24XX_CLKSEL_L3_MASK (0x1f << 0) - -/* CM_CLKSEL2_CORE */ -#define OMAP24XX_CLKSEL_GPT12_SHIFT 22 +#define OMAP24XX_CLKSEL_L3_WIDTH 5 #define OMAP24XX_CLKSEL_GPT12_MASK (0x3 << 22) -#define OMAP24XX_CLKSEL_GPT11_SHIFT 20 #define OMAP24XX_CLKSEL_GPT11_MASK (0x3 << 20) -#define OMAP24XX_CLKSEL_GPT10_SHIFT 18 #define OMAP24XX_CLKSEL_GPT10_MASK (0x3 << 18) -#define OMAP24XX_CLKSEL_GPT9_SHIFT 16 #define OMAP24XX_CLKSEL_GPT9_MASK (0x3 << 16) -#define OMAP24XX_CLKSEL_GPT8_SHIFT 14 #define OMAP24XX_CLKSEL_GPT8_MASK (0x3 << 14) -#define OMAP24XX_CLKSEL_GPT7_SHIFT 12 #define OMAP24XX_CLKSEL_GPT7_MASK (0x3 << 12) -#define OMAP24XX_CLKSEL_GPT6_SHIFT 10 #define OMAP24XX_CLKSEL_GPT6_MASK (0x3 << 10) -#define OMAP24XX_CLKSEL_GPT5_SHIFT 8 #define OMAP24XX_CLKSEL_GPT5_MASK (0x3 << 8) -#define OMAP24XX_CLKSEL_GPT4_SHIFT 6 #define OMAP24XX_CLKSEL_GPT4_MASK (0x3 << 6) -#define OMAP24XX_CLKSEL_GPT3_SHIFT 4 #define OMAP24XX_CLKSEL_GPT3_MASK (0x3 << 4) -#define OMAP24XX_CLKSEL_GPT2_SHIFT 2 #define OMAP24XX_CLKSEL_GPT2_MASK (0x3 << 2) - -/* CM_CLKSTCTRL_CORE */ -#define OMAP24XX_AUTOSTATE_DSS_SHIFT 2 #define OMAP24XX_AUTOSTATE_DSS_MASK (1 << 2) -#define OMAP24XX_AUTOSTATE_L4_SHIFT 1 #define OMAP24XX_AUTOSTATE_L4_MASK (1 << 1) -#define OMAP24XX_AUTOSTATE_L3_SHIFT 0 #define OMAP24XX_AUTOSTATE_L3_MASK (1 << 0) - -/* CM_FCLKEN_GFX */ #define OMAP24XX_EN_3D_SHIFT 2 -#define OMAP24XX_EN_3D (1 << 2) #define OMAP24XX_EN_2D_SHIFT 1 -#define OMAP24XX_EN_2D (1 << 1) - -/* CM_ICLKEN_GFX specific bits */ - -/* CM_IDLEST_GFX specific bits */ - -/* CM_CLKSEL_GFX specific bits */ - -/* CM_CLKSTCTRL_GFX */ -#define OMAP24XX_AUTOSTATE_GFX_SHIFT 0 #define OMAP24XX_AUTOSTATE_GFX_MASK (1 << 0) - -/* CM_FCLKEN_WKUP specific bits */ - -/* CM_ICLKEN_WKUP specific bits */ #define OMAP2430_EN_ICR_SHIFT 6 -#define OMAP2430_EN_ICR (1 << 6) #define OMAP24XX_EN_OMAPCTRL_SHIFT 5 -#define OMAP24XX_EN_OMAPCTRL (1 << 5) #define OMAP24XX_EN_WDT1_SHIFT 4 -#define OMAP24XX_EN_WDT1 (1 << 4) #define OMAP24XX_EN_32KSYNC_SHIFT 1 -#define OMAP24XX_EN_32KSYNC (1 << 1) - -/* CM_IDLEST_WKUP specific bits */ -#define OMAP2430_ST_ICR (1 << 6) -#define OMAP24XX_ST_OMAPCTRL (1 << 5) -#define OMAP24XX_ST_WDT1 (1 << 4) -#define OMAP24XX_ST_MPU_WDT (1 << 3) -#define OMAP24XX_ST_32KSYNC (1 << 1) - -/* CM_AUTOIDLE_WKUP */ -#define OMAP24XX_AUTO_OMAPCTRL (1 << 5) -#define OMAP24XX_AUTO_WDT1 (1 << 4) -#define OMAP24XX_AUTO_MPU_WDT (1 << 3) -#define OMAP24XX_AUTO_GPIOS (1 << 2) -#define OMAP24XX_AUTO_32KSYNC (1 << 1) -#define OMAP24XX_AUTO_GPT1 (1 << 0) - -/* CM_CLKSEL_WKUP */ -#define OMAP24XX_CLKSEL_GPT1_SHIFT 0 +#define OMAP24XX_ST_MPU_WDT_SHIFT 3 +#define OMAP24XX_ST_32KSYNC_SHIFT 1 #define OMAP24XX_CLKSEL_GPT1_MASK (0x3 << 0) - -/* CM_CLKEN_PLL */ #define OMAP24XX_EN_54M_PLL_SHIFT 6 -#define OMAP24XX_EN_54M_PLL_MASK (0x3 << 6) #define OMAP24XX_EN_96M_PLL_SHIFT 2 -#define OMAP24XX_EN_96M_PLL_MASK (0x3 << 2) -#define OMAP24XX_EN_DPLL_SHIFT 0 #define OMAP24XX_EN_DPLL_MASK (0x3 << 0) - -/* CM_IDLEST_CKGEN */ -#define OMAP24XX_ST_54M_APLL (1 << 9) -#define OMAP24XX_ST_96M_APLL (1 << 8) -#define OMAP24XX_ST_54M_CLK (1 << 6) -#define OMAP24XX_ST_12M_CLK (1 << 5) -#define OMAP24XX_ST_48M_CLK (1 << 4) -#define OMAP24XX_ST_96M_CLK (1 << 2) -#define OMAP24XX_ST_CORE_CLK_SHIFT 0 -#define OMAP24XX_ST_CORE_CLK_MASK (0x3 << 0) - -/* CM_AUTOIDLE_PLL */ -#define OMAP24XX_AUTO_54M_SHIFT 6 +#define OMAP24XX_ST_54M_APLL_SHIFT 9 +#define OMAP24XX_ST_96M_APLL_SHIFT 8 #define OMAP24XX_AUTO_54M_MASK (0x3 << 6) -#define OMAP24XX_AUTO_96M_SHIFT 2 #define OMAP24XX_AUTO_96M_MASK (0x3 << 2) #define OMAP24XX_AUTO_DPLL_SHIFT 0 #define OMAP24XX_AUTO_DPLL_MASK (0x3 << 0) - -/* CM_CLKSEL1_PLL */ -#define OMAP2430_MAXDPLLFASTLOCK_SHIFT 28 -#define OMAP2430_MAXDPLLFASTLOCK_MASK (0x7 << 28) #define OMAP24XX_APLLS_CLKIN_SHIFT 23 #define OMAP24XX_APLLS_CLKIN_MASK (0x7 << 23) -#define OMAP24XX_DPLL_MULT_SHIFT 12 #define OMAP24XX_DPLL_MULT_MASK (0x3ff << 12) -#define OMAP24XX_DPLL_DIV_SHIFT 8 #define OMAP24XX_DPLL_DIV_MASK (0xf << 8) #define OMAP24XX_54M_SOURCE_SHIFT 5 -#define OMAP24XX_54M_SOURCE (1 << 5) +#define OMAP24XX_54M_SOURCE_WIDTH 1 #define OMAP2430_96M_SOURCE_SHIFT 4 -#define OMAP2430_96M_SOURCE (1 << 4) -#define OMAP24XX_48M_SOURCE_SHIFT 3 -#define OMAP24XX_48M_SOURCE (1 << 3) -#define OMAP2430_ALTCLK_SOURCE_SHIFT 0 -#define OMAP2430_ALTCLK_SOURCE_MASK (0x7 << 0) - -/* CM_CLKSEL2_PLL */ -#define OMAP24XX_CORE_CLK_SRC_SHIFT 0 +#define OMAP2430_96M_SOURCE_WIDTH 1 +#define OMAP24XX_48M_SOURCE_MASK (1 << 3) #define OMAP24XX_CORE_CLK_SRC_MASK (0x3 << 0) - -/* CM_FCLKEN_DSP */ #define OMAP2420_EN_IVA_COP_SHIFT 10 -#define OMAP2420_EN_IVA_COP (1 << 10) #define OMAP2420_EN_IVA_MPU_SHIFT 8 -#define OMAP2420_EN_IVA_MPU (1 << 8) #define OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT 0 -#define OMAP24XX_CM_FCLKEN_DSP_EN_DSP (1 << 0) - -/* CM_ICLKEN_DSP */ #define OMAP2420_EN_DSP_IPI_SHIFT 1 -#define OMAP2420_EN_DSP_IPI (1 << 1) - -/* CM_IDLEST_DSP */ -#define OMAP2420_ST_IVA (1 << 8) -#define OMAP2420_ST_IPI (1 << 1) -#define OMAP24XX_ST_DSP (1 << 0) - -/* CM_AUTOIDLE_DSP */ -#define OMAP2420_AUTO_DSP_IPI (1 << 1) - -/* CM_CLKSEL_DSP */ -#define OMAP2420_SYNC_IVA (1 << 13) -#define OMAP2420_CLKSEL_IVA_SHIFT 8 #define OMAP2420_CLKSEL_IVA_MASK (0x1f << 8) -#define OMAP24XX_SYNC_DSP (1 << 7) -#define OMAP24XX_CLKSEL_DSP_IF_SHIFT 5 #define OMAP24XX_CLKSEL_DSP_IF_MASK (0x3 << 5) -#define OMAP24XX_CLKSEL_DSP_SHIFT 0 #define OMAP24XX_CLKSEL_DSP_MASK (0x1f << 0) - -/* CM_CLKSTCTRL_DSP */ -#define OMAP2420_AUTOSTATE_IVA_SHIFT 8 #define OMAP2420_AUTOSTATE_IVA_MASK (1 << 8) -#define OMAP24XX_AUTOSTATE_DSP_SHIFT 0 #define OMAP24XX_AUTOSTATE_DSP_MASK (1 << 0) - -/* CM_FCLKEN_MDM */ -/* 2430 only */ #define OMAP2430_EN_OSC_SHIFT 1 -#define OMAP2430_EN_OSC (1 << 1) - -/* CM_ICLKEN_MDM */ -/* 2430 only */ #define OMAP2430_CM_ICLKEN_MDM_EN_MDM_SHIFT 0 -#define OMAP2430_CM_ICLKEN_MDM_EN_MDM (1 << 0) - -/* CM_IDLEST_MDM specific bits */ -/* 2430 only */ - -/* CM_AUTOIDLE_MDM */ -/* 2430 only */ -#define OMAP2430_AUTO_OSC (1 << 1) -#define OMAP2430_AUTO_MDM (1 << 0) - -/* CM_CLKSEL_MDM */ -/* 2430 only */ -#define OMAP2430_SYNC_MDM (1 << 4) -#define OMAP2430_CLKSEL_MDM_SHIFT 0 #define OMAP2430_CLKSEL_MDM_MASK (0xf << 0) - -/* CM_CLKSTCTRL_MDM */ -/* 2430 only */ -#define OMAP2430_AUTOSTATE_MDM_SHIFT 0 #define OMAP2430_AUTOSTATE_MDM_MASK (1 << 0) - +#define OMAP24XX_CLKSTCTRL_DISABLE_AUTO 0x0 +#define OMAP24XX_CLKSTCTRL_ENABLE_AUTO 0x1 #endif diff --git a/arch/arm/mach-omap2/cm-regbits-33xx.h b/arch/arm/mach-omap2/cm-regbits-33xx.h new file mode 100644 index 00000000000..c0823fd6d5e --- /dev/null +++ b/arch/arm/mach-omap2/cm-regbits-33xx.h @@ -0,0 +1,68 @@ +/* + * AM33XX Power Management register bits + * + * This file is automatically generated from the AM33XX hardware databases. + * Vaibhav Hiremath <hvaibhav@ti.com> + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#ifndef __ARCH_ARM_MACH_OMAP2_CM_REGBITS_33XX_H +#define __ARCH_ARM_MACH_OMAP2_CM_REGBITS_33XX_H + +#define AM33XX_CLKOUT2DIV_SHIFT 3 +#define AM33XX_CLKOUT2DIV_WIDTH 3 +#define AM33XX_CLKOUT2EN_SHIFT 7 +#define AM33XX_CLKOUT2SOURCE_MASK (0x7 << 0) +#define AM33XX_CLKSEL_0_0_SHIFT 0 +#define AM33XX_CLKSEL_0_0_WIDTH 1 +#define AM33XX_CLKSEL_0_0_MASK (1 << 0) +#define AM33XX_CLKSEL_0_1_MASK (3 << 0) +#define AM33XX_CLKSEL_0_2_MASK (7 << 0) +#define AM33XX_CLKSEL_GFX_FCLK_MASK (1 << 1) +#define AM33XX_CLKTRCTRL_SHIFT 0 +#define AM33XX_CLKTRCTRL_MASK (0x3 << 0) +#define AM33XX_DPLL_CLKOUT_DIV_SHIFT 0 +#define AM33XX_DPLL_CLKOUT_DIV_WIDTH 5 +#define AM33XX_DPLL_DIV_MASK (0x7f << 0) +#define AM33XX_DPLL_PER_DIV_MASK (0xff << 0) +#define AM33XX_DPLL_EN_MASK (0x7 << 0) +#define AM33XX_DPLL_MULT_MASK (0x7ff << 8) +#define AM33XX_DPLL_MULT_PERIPH_MASK (0xfff << 8) +#define AM33XX_HSDIVIDER_CLKOUT1_DIV_SHIFT 0 +#define AM33XX_HSDIVIDER_CLKOUT1_DIV_WIDTH 5 +#define AM33XX_HSDIVIDER_CLKOUT2_DIV_SHIFT 0 +#define AM33XX_HSDIVIDER_CLKOUT2_DIV_WIDTH 5 +#define AM33XX_HSDIVIDER_CLKOUT3_DIV_SHIFT 0 +#define AM33XX_HSDIVIDER_CLKOUT3_DIV_WIDTH 5 +#define AM33XX_IDLEST_SHIFT 16 +#define AM33XX_IDLEST_MASK (0x3 << 16) +#define AM33XX_MODULEMODE_SHIFT 0 +#define AM33XX_MODULEMODE_MASK (0x3 << 0) +#define AM33XX_OPTCLK_DEBUG_CLKA_SHIFT 30 +#define AM33XX_OPTFCLKEN_DBGSYSCLK_SHIFT 19 +#define AM33XX_OPTFCLKEN_GPIO0_GDBCLK_SHIFT 18 +#define AM33XX_OPTFCLKEN_GPIO_1_GDBCLK_SHIFT 18 +#define AM33XX_OPTFCLKEN_GPIO_2_GDBCLK_SHIFT 18 +#define AM33XX_OPTFCLKEN_GPIO_3_GDBCLK_SHIFT 18 +#define AM33XX_STM_PMD_CLKDIVSEL_SHIFT 27 +#define AM33XX_STM_PMD_CLKDIVSEL_WIDTH 3 +#define AM33XX_STM_PMD_CLKSEL_SHIFT 22 +#define AM33XX_STM_PMD_CLKSEL_WIDTH 2 +#define AM33XX_ST_DPLL_CLK_MASK (1 << 0) +#define AM33XX_ST_DPLL_CLKDCOLDO_SHIFT 8 +#define AM33XX_TRC_PMD_CLKDIVSEL_SHIFT 24 +#define AM33XX_TRC_PMD_CLKDIVSEL_WIDTH 3 +#define AM33XX_TRC_PMD_CLKSEL_SHIFT 20 +#define AM33XX_TRC_PMD_CLKSEL_WIDTH 2 +#endif diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h index 219f5c8d965..ee6c784cd6b 100644 --- a/arch/arm/mach-omap2/cm-regbits-34xx.h +++ b/arch/arm/mach-omap2/cm-regbits-34xx.h @@ -14,685 +14,204 @@ * published by the Free Software Foundation. */ -#include "cm.h" - -/* Bits shared between registers */ - -/* CM_FCLKEN1_CORE and CM_ICLKEN1_CORE shared bits */ -#define OMAP3430ES2_EN_MMC3_MASK (1 << 30) #define OMAP3430ES2_EN_MMC3_SHIFT 30 -#define OMAP3430_EN_MSPRO (1 << 23) #define OMAP3430_EN_MSPRO_SHIFT 23 -#define OMAP3430_EN_HDQ (1 << 22) #define OMAP3430_EN_HDQ_SHIFT 22 -#define OMAP3430ES1_EN_FSHOSTUSB (1 << 5) #define OMAP3430ES1_EN_FSHOSTUSB_SHIFT 5 -#define OMAP3430ES1_EN_D2D (1 << 3) #define OMAP3430ES1_EN_D2D_SHIFT 3 -#define OMAP3430_EN_SSI (1 << 0) #define OMAP3430_EN_SSI_SHIFT 0 - -/* CM_FCLKEN3_CORE and CM_ICLKEN3_CORE shared bits */ #define OMAP3430ES2_EN_USBTLL_SHIFT 2 -#define OMAP3430ES2_EN_USBTLL_MASK (1 << 2) - -/* CM_FCLKEN_WKUP and CM_ICLKEN_WKUP shared bits */ -#define OMAP3430_EN_WDT2 (1 << 5) #define OMAP3430_EN_WDT2_SHIFT 5 - -/* CM_ICLKEN_CAM, CM_FCLKEN_CAM shared bits */ -#define OMAP3430_EN_CAM (1 << 0) #define OMAP3430_EN_CAM_SHIFT 0 - -/* CM_FCLKEN_PER, CM_ICLKEN_PER shared bits */ -#define OMAP3430_EN_WDT3 (1 << 12) #define OMAP3430_EN_WDT3_SHIFT 12 - -/* CM_CLKSEL2_EMU, CM_CLKSEL3_EMU shared bits */ -#define OMAP3430_OVERRIDE_ENABLE (1 << 19) - - -/* Bits specific to each register */ - -/* CM_FCLKEN_IVA2 */ -#define OMAP3430_CM_FCLKEN_IVA2_EN_IVA2 (1 << 0) +#define OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_MASK (1 << 0) #define OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT 0 - -/* CM_CLKEN_PLL_IVA2 */ -#define OMAP3430_IVA2_DPLL_RAMPTIME_SHIFT 8 -#define OMAP3430_IVA2_DPLL_RAMPTIME_MASK (0x3 << 8) #define OMAP3430_IVA2_DPLL_FREQSEL_SHIFT 4 #define OMAP3430_IVA2_DPLL_FREQSEL_MASK (0xf << 4) #define OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_SHIFT 3 -#define OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_MASK (1 << 3) #define OMAP3430_EN_IVA2_DPLL_SHIFT 0 #define OMAP3430_EN_IVA2_DPLL_MASK (0x7 << 0) - -/* CM_IDLEST_IVA2 */ -#define OMAP3430_ST_IVA2 (1 << 0) - -/* CM_IDLEST_PLL_IVA2 */ -#define OMAP3430_ST_IVA2_CLK_SHIFT 0 +#define OMAP3430_ST_IVA2_SHIFT 0 #define OMAP3430_ST_IVA2_CLK_MASK (1 << 0) - -/* CM_AUTOIDLE_PLL_IVA2 */ #define OMAP3430_AUTO_IVA2_DPLL_SHIFT 0 #define OMAP3430_AUTO_IVA2_DPLL_MASK (0x7 << 0) - -/* CM_CLKSEL1_PLL_IVA2 */ #define OMAP3430_IVA2_CLK_SRC_SHIFT 19 -#define OMAP3430_IVA2_CLK_SRC_MASK (0x3 << 19) -#define OMAP3430_IVA2_DPLL_MULT_SHIFT 8 +#define OMAP3430_IVA2_CLK_SRC_WIDTH 3 #define OMAP3430_IVA2_DPLL_MULT_MASK (0x7ff << 8) -#define OMAP3430_IVA2_DPLL_DIV_SHIFT 0 #define OMAP3430_IVA2_DPLL_DIV_MASK (0x7f << 0) - -/* CM_CLKSEL2_PLL_IVA2 */ #define OMAP3430_IVA2_DPLL_CLKOUT_DIV_SHIFT 0 -#define OMAP3430_IVA2_DPLL_CLKOUT_DIV_MASK (0x1f << 0) - -/* CM_CLKSTCTRL_IVA2 */ -#define OMAP3430_CLKTRCTRL_IVA2_SHIFT 0 +#define OMAP3430_IVA2_DPLL_CLKOUT_DIV_WIDTH 5 #define OMAP3430_CLKTRCTRL_IVA2_MASK (0x3 << 0) - -/* CM_CLKSTST_IVA2 */ -#define OMAP3430_CLKACTIVITY_IVA2_SHIFT 0 #define OMAP3430_CLKACTIVITY_IVA2_MASK (1 << 0) - -/* CM_REVISION specific bits */ - -/* CM_SYSCONFIG specific bits */ - -/* CM_CLKEN_PLL_MPU */ -#define OMAP3430_MPU_DPLL_RAMPTIME_SHIFT 8 -#define OMAP3430_MPU_DPLL_RAMPTIME_MASK (0x3 << 8) -#define OMAP3430_MPU_DPLL_FREQSEL_SHIFT 4 #define OMAP3430_MPU_DPLL_FREQSEL_MASK (0xf << 4) #define OMAP3430_EN_MPU_DPLL_DRIFTGUARD_SHIFT 3 -#define OMAP3430_EN_MPU_DPLL_DRIFTGUARD_MASK (1 << 3) -#define OMAP3430_EN_MPU_DPLL_SHIFT 0 #define OMAP3430_EN_MPU_DPLL_MASK (0x7 << 0) - -/* CM_IDLEST_MPU */ -#define OMAP3430_ST_MPU (1 << 0) - -/* CM_IDLEST_PLL_MPU */ #define OMAP3430_ST_MPU_CLK_SHIFT 0 #define OMAP3430_ST_MPU_CLK_MASK (1 << 0) - -/* CM_AUTOIDLE_PLL_MPU */ -#define OMAP3430_AUTO_MPU_DPLL_SHIFT 0 +#define OMAP3430_ST_MPU_CLK_WIDTH 1 #define OMAP3430_AUTO_MPU_DPLL_MASK (0x7 << 0) - -/* CM_CLKSEL1_PLL_MPU */ #define OMAP3430_MPU_CLK_SRC_SHIFT 19 -#define OMAP3430_MPU_CLK_SRC_MASK (0x3 << 19) -#define OMAP3430_MPU_DPLL_MULT_SHIFT 8 +#define OMAP3430_MPU_CLK_SRC_WIDTH 3 #define OMAP3430_MPU_DPLL_MULT_MASK (0x7ff << 8) -#define OMAP3430_MPU_DPLL_DIV_SHIFT 0 #define OMAP3430_MPU_DPLL_DIV_MASK (0x7f << 0) - -/* CM_CLKSEL2_PLL_MPU */ #define OMAP3430_MPU_DPLL_CLKOUT_DIV_SHIFT 0 -#define OMAP3430_MPU_DPLL_CLKOUT_DIV_MASK (0x1f << 0) - -/* CM_CLKSTCTRL_MPU */ -#define OMAP3430_CLKTRCTRL_MPU_SHIFT 0 +#define OMAP3430_MPU_DPLL_CLKOUT_DIV_WIDTH 5 #define OMAP3430_CLKTRCTRL_MPU_MASK (0x3 << 0) - -/* CM_CLKSTST_MPU */ -#define OMAP3430_CLKACTIVITY_MPU_SHIFT 0 -#define OMAP3430_CLKACTIVITY_MPU_MASK (1 << 0) - -/* CM_FCLKEN1_CORE specific bits */ - -/* CM_ICLKEN1_CORE specific bits */ -#define OMAP3430_EN_ICR (1 << 29) +#define OMAP3430_EN_MODEM_SHIFT 31 #define OMAP3430_EN_ICR_SHIFT 29 -#define OMAP3430_EN_AES2 (1 << 28) #define OMAP3430_EN_AES2_SHIFT 28 -#define OMAP3430_EN_SHA12 (1 << 27) #define OMAP3430_EN_SHA12_SHIFT 27 -#define OMAP3430_EN_DES2 (1 << 26) #define OMAP3430_EN_DES2_SHIFT 26 -#define OMAP3430ES1_EN_FAC (1 << 8) #define OMAP3430ES1_EN_FAC_SHIFT 8 -#define OMAP3430_EN_MAILBOXES (1 << 7) #define OMAP3430_EN_MAILBOXES_SHIFT 7 -#define OMAP3430_EN_OMAPCTRL (1 << 6) #define OMAP3430_EN_OMAPCTRL_SHIFT 6 -#define OMAP3430_EN_SDRC (1 << 1) +#define OMAP3430_EN_SAD2D_SHIFT 3 #define OMAP3430_EN_SDRC_SHIFT 1 - -/* CM_ICLKEN2_CORE */ -#define OMAP3430_EN_PKA (1 << 4) +#define AM35XX_EN_IPSS_SHIFT 4 #define OMAP3430_EN_PKA_SHIFT 4 -#define OMAP3430_EN_AES1 (1 << 3) #define OMAP3430_EN_AES1_SHIFT 3 -#define OMAP3430_EN_RNG (1 << 2) #define OMAP3430_EN_RNG_SHIFT 2 -#define OMAP3430_EN_SHA11 (1 << 1) #define OMAP3430_EN_SHA11_SHIFT 1 -#define OMAP3430_EN_DES1 (1 << 0) #define OMAP3430_EN_DES1_SHIFT 0 - -/* CM_FCLKEN3_CORE specific bits */ +#define OMAP3430_EN_MAD2D_SHIFT 3 #define OMAP3430ES2_EN_TS_SHIFT 1 -#define OMAP3430ES2_EN_TS_MASK (1 << 1) #define OMAP3430ES2_EN_CPEFUSE_SHIFT 0 -#define OMAP3430ES2_EN_CPEFUSE_MASK (1 << 0) - -/* CM_IDLEST1_CORE specific bits */ -#define OMAP3430_ST_ICR (1 << 29) -#define OMAP3430_ST_AES2 (1 << 28) -#define OMAP3430_ST_SHA12 (1 << 27) -#define OMAP3430_ST_DES2 (1 << 26) -#define OMAP3430_ST_MSPRO (1 << 23) -#define OMAP3430_ST_HDQ (1 << 22) -#define OMAP3430ES1_ST_FAC (1 << 8) -#define OMAP3430ES1_ST_MAILBOXES (1 << 7) -#define OMAP3430_ST_OMAPCTRL (1 << 6) -#define OMAP3430_ST_SDMA (1 << 2) -#define OMAP3430_ST_SDRC (1 << 1) -#define OMAP3430_ST_SSI (1 << 0) - -/* CM_IDLEST2_CORE */ -#define OMAP3430_ST_PKA (1 << 4) -#define OMAP3430_ST_AES1 (1 << 3) -#define OMAP3430_ST_RNG (1 << 2) -#define OMAP3430_ST_SHA11 (1 << 1) -#define OMAP3430_ST_DES1 (1 << 0) - -/* CM_IDLEST3_CORE */ +#define OMAP3430_ST_AES2_SHIFT 28 +#define OMAP3430_ST_SHA12_SHIFT 27 +#define AM35XX_ST_UART4_SHIFT 23 +#define OMAP3430_ST_HDQ_SHIFT 22 +#define OMAP3430ES2_ST_SSI_IDLE_SHIFT 8 +#define OMAP3430_ST_MAILBOXES_SHIFT 7 +#define OMAP3430_ST_SAD2D_SHIFT 3 +#define OMAP3430_ST_SDMA_SHIFT 2 +#define AM35XX_ST_IPSS_SHIFT 5 #define OMAP3430ES2_ST_USBTLL_SHIFT 2 -#define OMAP3430ES2_ST_USBTLL_MASK (1 << 2) - -/* CM_AUTOIDLE1_CORE */ -#define OMAP3430_AUTO_AES2 (1 << 28) -#define OMAP3430_AUTO_AES2_SHIFT 28 -#define OMAP3430_AUTO_SHA12 (1 << 27) -#define OMAP3430_AUTO_SHA12_SHIFT 27 -#define OMAP3430_AUTO_DES2 (1 << 26) -#define OMAP3430_AUTO_DES2_SHIFT 26 -#define OMAP3430_AUTO_MMC2 (1 << 25) -#define OMAP3430_AUTO_MMC2_SHIFT 25 -#define OMAP3430_AUTO_MMC1 (1 << 24) -#define OMAP3430_AUTO_MMC1_SHIFT 24 -#define OMAP3430_AUTO_MSPRO (1 << 23) -#define OMAP3430_AUTO_MSPRO_SHIFT 23 -#define OMAP3430_AUTO_HDQ (1 << 22) -#define OMAP3430_AUTO_HDQ_SHIFT 22 -#define OMAP3430_AUTO_MCSPI4 (1 << 21) -#define OMAP3430_AUTO_MCSPI4_SHIFT 21 -#define OMAP3430_AUTO_MCSPI3 (1 << 20) -#define OMAP3430_AUTO_MCSPI3_SHIFT 20 -#define OMAP3430_AUTO_MCSPI2 (1 << 19) -#define OMAP3430_AUTO_MCSPI2_SHIFT 19 -#define OMAP3430_AUTO_MCSPI1 (1 << 18) -#define OMAP3430_AUTO_MCSPI1_SHIFT 18 -#define OMAP3430_AUTO_I2C3 (1 << 17) -#define OMAP3430_AUTO_I2C3_SHIFT 17 -#define OMAP3430_AUTO_I2C2 (1 << 16) -#define OMAP3430_AUTO_I2C2_SHIFT 16 -#define OMAP3430_AUTO_I2C1 (1 << 15) -#define OMAP3430_AUTO_I2C1_SHIFT 15 -#define OMAP3430_AUTO_UART2 (1 << 14) -#define OMAP3430_AUTO_UART2_SHIFT 14 -#define OMAP3430_AUTO_UART1 (1 << 13) -#define OMAP3430_AUTO_UART1_SHIFT 13 -#define OMAP3430_AUTO_GPT11 (1 << 12) -#define OMAP3430_AUTO_GPT11_SHIFT 12 -#define OMAP3430_AUTO_GPT10 (1 << 11) -#define OMAP3430_AUTO_GPT10_SHIFT 11 -#define OMAP3430_AUTO_MCBSP5 (1 << 10) -#define OMAP3430_AUTO_MCBSP5_SHIFT 10 -#define OMAP3430_AUTO_MCBSP1 (1 << 9) -#define OMAP3430_AUTO_MCBSP1_SHIFT 9 -#define OMAP3430ES1_AUTO_FAC (1 << 8) -#define OMAP3430ES1_AUTO_FAC_SHIFT 8 -#define OMAP3430_AUTO_MAILBOXES (1 << 7) -#define OMAP3430_AUTO_MAILBOXES_SHIFT 7 -#define OMAP3430_AUTO_OMAPCTRL (1 << 6) -#define OMAP3430_AUTO_OMAPCTRL_SHIFT 6 -#define OMAP3430ES1_AUTO_FSHOSTUSB (1 << 5) -#define OMAP3430ES1_AUTO_FSHOSTUSB_SHIFT 5 -#define OMAP3430_AUTO_HSOTGUSB (1 << 4) -#define OMAP3430_AUTO_HSOTGUSB_SHIFT 4 -#define OMAP3430ES1_AUTO_D2D (1 << 3) -#define OMAP3430ES1_AUTO_D2D_SHIFT 3 -#define OMAP3430_AUTO_SSI (1 << 0) -#define OMAP3430_AUTO_SSI_SHIFT 0 - -/* CM_AUTOIDLE2_CORE */ -#define OMAP3430_AUTO_PKA (1 << 4) -#define OMAP3430_AUTO_PKA_SHIFT 4 -#define OMAP3430_AUTO_AES1 (1 << 3) -#define OMAP3430_AUTO_AES1_SHIFT 3 -#define OMAP3430_AUTO_RNG (1 << 2) -#define OMAP3430_AUTO_RNG_SHIFT 2 -#define OMAP3430_AUTO_SHA11 (1 << 1) -#define OMAP3430_AUTO_SHA11_SHIFT 1 -#define OMAP3430_AUTO_DES1 (1 << 0) -#define OMAP3430_AUTO_DES1_SHIFT 0 - -/* CM_AUTOIDLE3_CORE */ -#define OMAP3430ES2_AUTO_USBTLL_SHIFT 2 -#define OMAP3430ES2_AUTO_USBTLL_MASK (1 << 2) - -/* CM_CLKSEL_CORE */ -#define OMAP3430_CLKSEL_SSI_SHIFT 8 #define OMAP3430_CLKSEL_SSI_MASK (0xf << 8) #define OMAP3430_CLKSEL_GPT11_MASK (1 << 7) -#define OMAP3430_CLKSEL_GPT11_SHIFT 7 #define OMAP3430_CLKSEL_GPT10_MASK (1 << 6) -#define OMAP3430_CLKSEL_GPT10_SHIFT 6 -#define OMAP3430ES1_CLKSEL_FSHOSTUSB_SHIFT 4 #define OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK (0x3 << 4) #define OMAP3430_CLKSEL_L4_SHIFT 2 -#define OMAP3430_CLKSEL_L4_MASK (0x3 << 2) +#define OMAP3430_CLKSEL_L4_WIDTH 2 #define OMAP3430_CLKSEL_L3_SHIFT 0 -#define OMAP3430_CLKSEL_L3_MASK (0x3 << 0) - -/* CM_CLKSTCTRL_CORE */ -#define OMAP3430ES1_CLKTRCTRL_D2D_SHIFT 4 +#define OMAP3430_CLKSEL_L3_WIDTH 2 +#define OMAP3630_CLKSEL_96M_MASK (0x3 << 12) #define OMAP3430ES1_CLKTRCTRL_D2D_MASK (0x3 << 4) -#define OMAP3430_CLKTRCTRL_L4_SHIFT 2 #define OMAP3430_CLKTRCTRL_L4_MASK (0x3 << 2) -#define OMAP3430_CLKTRCTRL_L3_SHIFT 0 #define OMAP3430_CLKTRCTRL_L3_MASK (0x3 << 0) - -/* CM_CLKSTST_CORE */ -#define OMAP3430ES1_CLKACTIVITY_D2D_SHIFT 2 -#define OMAP3430ES1_CLKACTIVITY_D2D_MASK (1 << 2) -#define OMAP3430_CLKACTIVITY_L4_SHIFT 1 -#define OMAP3430_CLKACTIVITY_L4_MASK (1 << 1) -#define OMAP3430_CLKACTIVITY_L3_SHIFT 0 -#define OMAP3430_CLKACTIVITY_L3_MASK (1 << 0) - -/* CM_FCLKEN_GFX */ -#define OMAP3430ES1_EN_3D (1 << 2) #define OMAP3430ES1_EN_3D_SHIFT 2 -#define OMAP3430ES1_EN_2D (1 << 1) #define OMAP3430ES1_EN_2D_SHIFT 1 - -/* CM_ICLKEN_GFX specific bits */ - -/* CM_IDLEST_GFX specific bits */ - -/* CM_CLKSEL_GFX specific bits */ - -/* CM_SLEEPDEP_GFX specific bits */ - -/* CM_CLKSTCTRL_GFX */ -#define OMAP3430ES1_CLKTRCTRL_GFX_SHIFT 0 #define OMAP3430ES1_CLKTRCTRL_GFX_MASK (0x3 << 0) - -/* CM_CLKSTST_GFX */ -#define OMAP3430ES1_CLKACTIVITY_GFX_SHIFT 0 -#define OMAP3430ES1_CLKACTIVITY_GFX_MASK (1 << 0) - -/* CM_FCLKEN_SGX */ -#define OMAP3430ES2_EN_SGX_SHIFT 1 -#define OMAP3430ES2_EN_SGX_MASK (1 << 1) - -/* CM_CLKSEL_SGX */ -#define OMAP3430ES2_CLKSEL_SGX_SHIFT 0 +#define OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT 1 +#define OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT 0 #define OMAP3430ES2_CLKSEL_SGX_MASK (0x7 << 0) - -/* CM_CLKSTCTRL_SGX */ -#define OMAP3430ES2_CLKTRCTRL_SGX_SHIFT 0 #define OMAP3430ES2_CLKTRCTRL_SGX_MASK (0x3 << 0) - -/* CM_CLKSTST_SGX */ -#define OMAP3430ES2_CLKACTIVITY_SGX_SHIFT 0 -#define OMAP3430ES2_CLKACTIVITY_SGX_MASK (1 << 0) - -/* CM_FCLKEN_WKUP specific bits */ #define OMAP3430ES2_EN_USIMOCP_SHIFT 9 - -/* CM_ICLKEN_WKUP specific bits */ -#define OMAP3430_EN_WDT1 (1 << 4) #define OMAP3430_EN_WDT1_SHIFT 4 -#define OMAP3430_EN_32KSYNC (1 << 2) #define OMAP3430_EN_32KSYNC_SHIFT 2 - -/* CM_IDLEST_WKUP specific bits */ -#define OMAP3430_ST_WDT2 (1 << 5) -#define OMAP3430_ST_WDT1 (1 << 4) -#define OMAP3430_ST_32KSYNC (1 << 2) - -/* CM_AUTOIDLE_WKUP */ -#define OMAP3430_AUTO_WDT2 (1 << 5) -#define OMAP3430_AUTO_WDT2_SHIFT 5 -#define OMAP3430_AUTO_WDT1 (1 << 4) -#define OMAP3430_AUTO_WDT1_SHIFT 4 -#define OMAP3430_AUTO_GPIO1 (1 << 3) -#define OMAP3430_AUTO_GPIO1_SHIFT 3 -#define OMAP3430_AUTO_32KSYNC (1 << 2) -#define OMAP3430_AUTO_32KSYNC_SHIFT 2 -#define OMAP3430_AUTO_GPT12 (1 << 1) -#define OMAP3430_AUTO_GPT12_SHIFT 1 -#define OMAP3430_AUTO_GPT1 (1 << 0) -#define OMAP3430_AUTO_GPT1_SHIFT 0 - -/* CM_CLKSEL_WKUP */ +#define OMAP3430_ST_WDT2_SHIFT 5 +#define OMAP3430_ST_32KSYNC_SHIFT 2 #define OMAP3430ES2_CLKSEL_USIMOCP_MASK (0xf << 3) #define OMAP3430_CLKSEL_RM_SHIFT 1 -#define OMAP3430_CLKSEL_RM_MASK (0x3 << 1) -#define OMAP3430_CLKSEL_GPT1_SHIFT 0 +#define OMAP3430_CLKSEL_RM_WIDTH 2 #define OMAP3430_CLKSEL_GPT1_MASK (1 << 0) - -/* CM_CLKEN_PLL */ #define OMAP3430_PWRDN_EMU_PERIPH_SHIFT 31 #define OMAP3430_PWRDN_CAM_SHIFT 30 #define OMAP3430_PWRDN_DSS1_SHIFT 29 #define OMAP3430_PWRDN_TV_SHIFT 28 #define OMAP3430_PWRDN_96M_SHIFT 27 -#define OMAP3430_PERIPH_DPLL_RAMPTIME_SHIFT 24 -#define OMAP3430_PERIPH_DPLL_RAMPTIME_MASK (0x3 << 24) -#define OMAP3430_PERIPH_DPLL_FREQSEL_SHIFT 20 #define OMAP3430_PERIPH_DPLL_FREQSEL_MASK (0xf << 20) #define OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT 19 -#define OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_MASK (1 << 19) -#define OMAP3430_EN_PERIPH_DPLL_SHIFT 16 #define OMAP3430_EN_PERIPH_DPLL_MASK (0x7 << 16) #define OMAP3430_PWRDN_EMU_CORE_SHIFT 12 -#define OMAP3430_CORE_DPLL_RAMPTIME_SHIFT 8 -#define OMAP3430_CORE_DPLL_RAMPTIME_MASK (0x3 << 8) -#define OMAP3430_CORE_DPLL_FREQSEL_SHIFT 4 #define OMAP3430_CORE_DPLL_FREQSEL_MASK (0xf << 4) #define OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT 3 -#define OMAP3430_EN_CORE_DPLL_DRIFTGUARD_MASK (1 << 3) -#define OMAP3430_EN_CORE_DPLL_SHIFT 0 #define OMAP3430_EN_CORE_DPLL_MASK (0x7 << 0) - -/* CM_CLKEN2_PLL */ -#define OMAP3430ES2_EN_PERIPH2_DPLL_LPMODE_SHIFT 10 -#define OMAP3430ES2_PERIPH2_DPLL_RAMPTIME_MASK (0x3 << 8) -#define OMAP3430ES2_PERIPH2_DPLL_FREQSEL_SHIFT 4 #define OMAP3430ES2_PERIPH2_DPLL_FREQSEL_MASK (0xf << 4) #define OMAP3430ES2_EN_PERIPH2_DPLL_DRIFTGUARD_SHIFT 3 -#define OMAP3430ES2_EN_PERIPH2_DPLL_SHIFT 0 #define OMAP3430ES2_EN_PERIPH2_DPLL_MASK (0x7 << 0) - -/* CM_IDLEST_CKGEN */ -#define OMAP3430_ST_54M_CLK (1 << 5) -#define OMAP3430_ST_12M_CLK (1 << 4) -#define OMAP3430_ST_48M_CLK (1 << 3) -#define OMAP3430_ST_96M_CLK (1 << 2) -#define OMAP3430_ST_PERIPH_CLK_SHIFT 1 #define OMAP3430_ST_PERIPH_CLK_MASK (1 << 1) -#define OMAP3430_ST_CORE_CLK_SHIFT 0 #define OMAP3430_ST_CORE_CLK_MASK (1 << 0) - -/* CM_IDLEST2_CKGEN */ -#define OMAP3430ES2_ST_120M_CLK_SHIFT 1 -#define OMAP3430ES2_ST_120M_CLK_MASK (1 << 1) -#define OMAP3430ES2_ST_PERIPH2_CLK_SHIFT 0 #define OMAP3430ES2_ST_PERIPH2_CLK_MASK (1 << 0) - -/* CM_AUTOIDLE_PLL */ -#define OMAP3430_AUTO_PERIPH_DPLL_SHIFT 3 #define OMAP3430_AUTO_PERIPH_DPLL_MASK (0x7 << 3) -#define OMAP3430_AUTO_CORE_DPLL_SHIFT 0 #define OMAP3430_AUTO_CORE_DPLL_MASK (0x7 << 0) - -/* CM_AUTOIDLE2_PLL */ -#define OMAP3430ES2_AUTO_PERIPH2_DPLL_SHIFT 0 #define OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK (0x7 << 0) - -/* CM_CLKSEL1_PLL */ -/* Note that OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK was (0x3 << 27) on 3430ES1 */ #define OMAP3430_CORE_DPLL_CLKOUT_DIV_SHIFT 27 -#define OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK (0x1f << 27) -#define OMAP3430_CORE_DPLL_MULT_SHIFT 16 +#define OMAP3430_CORE_DPLL_CLKOUT_DIV_WIDTH 5 #define OMAP3430_CORE_DPLL_MULT_MASK (0x7ff << 16) -#define OMAP3430_CORE_DPLL_DIV_SHIFT 8 #define OMAP3430_CORE_DPLL_DIV_MASK (0x7f << 8) -#define OMAP3430_SOURCE_54M (1 << 5) -#define OMAP3430_SOURCE_48M (1 << 3) - -/* CM_CLKSEL2_PLL */ -#define OMAP3430_PERIPH_DPLL_MULT_SHIFT 8 +#define OMAP3430_SOURCE_96M_SHIFT 6 +#define OMAP3430_SOURCE_96M_WIDTH 1 +#define OMAP3430_SOURCE_54M_SHIFT 5 +#define OMAP3430_SOURCE_54M_WIDTH 1 +#define OMAP3430_SOURCE_48M_MASK (1 << 3) #define OMAP3430_PERIPH_DPLL_MULT_MASK (0x7ff << 8) -#define OMAP3430_PERIPH_DPLL_DIV_SHIFT 0 +#define OMAP3630_PERIPH_DPLL_MULT_MASK (0xfff << 8) #define OMAP3430_PERIPH_DPLL_DIV_MASK (0x7f << 0) - -/* CM_CLKSEL3_PLL */ +#define OMAP3630_PERIPH_DPLL_DCO_SEL_MASK (0x7 << 21) +#define OMAP3630_PERIPH_DPLL_SD_DIV_MASK (0xff << 24) #define OMAP3430_DIV_96M_SHIFT 0 -#define OMAP3430_DIV_96M_MASK (0x1f << 0) - -/* CM_CLKSEL4_PLL */ -#define OMAP3430ES2_PERIPH2_DPLL_MULT_SHIFT 8 +#define OMAP3630_DIV_96M_WIDTH 6 #define OMAP3430ES2_PERIPH2_DPLL_MULT_MASK (0x7ff << 8) -#define OMAP3430ES2_PERIPH2_DPLL_DIV_SHIFT 0 #define OMAP3430ES2_PERIPH2_DPLL_DIV_MASK (0x7f << 0) - -/* CM_CLKSEL5_PLL */ #define OMAP3430ES2_DIV_120M_SHIFT 0 -#define OMAP3430ES2_DIV_120M_MASK (0x1f << 0) - -/* CM_CLKOUT_CTRL */ +#define OMAP3430ES2_DIV_120M_WIDTH 5 #define OMAP3430_CLKOUT2_EN_SHIFT 7 -#define OMAP3430_CLKOUT2_EN (1 << 7) #define OMAP3430_CLKOUT2_DIV_SHIFT 3 -#define OMAP3430_CLKOUT2_DIV_MASK (0x7 << 3) -#define OMAP3430_CLKOUT2SOURCE_SHIFT 0 +#define OMAP3430_CLKOUT2_DIV_WIDTH 3 #define OMAP3430_CLKOUT2SOURCE_MASK (0x3 << 0) - -/* CM_FCLKEN_DSS */ -#define OMAP3430_EN_TV (1 << 2) #define OMAP3430_EN_TV_SHIFT 2 -#define OMAP3430_EN_DSS2 (1 << 1) #define OMAP3430_EN_DSS2_SHIFT 1 -#define OMAP3430_EN_DSS1 (1 << 0) #define OMAP3430_EN_DSS1_SHIFT 0 - -/* CM_ICLKEN_DSS */ -#define OMAP3430_CM_ICLKEN_DSS_EN_DSS (1 << 0) #define OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT 0 - -/* CM_IDLEST_DSS */ -#define OMAP3430_ST_DSS (1 << 0) - -/* CM_AUTOIDLE_DSS */ -#define OMAP3430_AUTO_DSS (1 << 0) -#define OMAP3430_AUTO_DSS_SHIFT 0 - -/* CM_CLKSEL_DSS */ +#define OMAP3430ES2_ST_DSS_IDLE_SHIFT 1 +#define OMAP3430ES2_ST_DSS_STDBY_SHIFT 0 +#define OMAP3430ES1_ST_DSS_SHIFT 0 #define OMAP3430_CLKSEL_TV_SHIFT 8 -#define OMAP3430_CLKSEL_TV_MASK (0x1f << 8) +#define OMAP3630_CLKSEL_TV_WIDTH 6 #define OMAP3430_CLKSEL_DSS1_SHIFT 0 -#define OMAP3430_CLKSEL_DSS1_MASK (0x1f << 0) - -/* CM_SLEEPDEP_DSS specific bits */ - -/* CM_CLKSTCTRL_DSS */ -#define OMAP3430_CLKTRCTRL_DSS_SHIFT 0 +#define OMAP3630_CLKSEL_DSS1_WIDTH 6 #define OMAP3430_CLKTRCTRL_DSS_MASK (0x3 << 0) - -/* CM_CLKSTST_DSS */ -#define OMAP3430_CLKACTIVITY_DSS_SHIFT 0 -#define OMAP3430_CLKACTIVITY_DSS_MASK (1 << 0) - -/* CM_FCLKEN_CAM specific bits */ - -/* CM_ICLKEN_CAM specific bits */ - -/* CM_IDLEST_CAM */ -#define OMAP3430_ST_CAM (1 << 0) - -/* CM_AUTOIDLE_CAM */ -#define OMAP3430_AUTO_CAM (1 << 0) -#define OMAP3430_AUTO_CAM_SHIFT 0 - -/* CM_CLKSEL_CAM */ +#define OMAP3430_EN_CSI2_SHIFT 1 #define OMAP3430_CLKSEL_CAM_SHIFT 0 -#define OMAP3430_CLKSEL_CAM_MASK (0x1f << 0) - -/* CM_SLEEPDEP_CAM specific bits */ - -/* CM_CLKSTCTRL_CAM */ -#define OMAP3430_CLKTRCTRL_CAM_SHIFT 0 +#define OMAP3630_CLKSEL_CAM_WIDTH 6 #define OMAP3430_CLKTRCTRL_CAM_MASK (0x3 << 0) - -/* CM_CLKSTST_CAM */ -#define OMAP3430_CLKACTIVITY_CAM_SHIFT 0 -#define OMAP3430_CLKACTIVITY_CAM_MASK (1 << 0) - -/* CM_FCLKEN_PER specific bits */ - -/* CM_ICLKEN_PER specific bits */ - -/* CM_IDLEST_PER */ -#define OMAP3430_ST_WDT3 (1 << 12) -#define OMAP3430_ST_MCBSP4 (1 << 2) -#define OMAP3430_ST_MCBSP3 (1 << 1) -#define OMAP3430_ST_MCBSP2 (1 << 0) - -/* CM_AUTOIDLE_PER */ -#define OMAP3430_AUTO_GPIO6 (1 << 17) -#define OMAP3430_AUTO_GPIO6_SHIFT 17 -#define OMAP3430_AUTO_GPIO5 (1 << 16) -#define OMAP3430_AUTO_GPIO5_SHIFT 16 -#define OMAP3430_AUTO_GPIO4 (1 << 15) -#define OMAP3430_AUTO_GPIO4_SHIFT 15 -#define OMAP3430_AUTO_GPIO3 (1 << 14) -#define OMAP3430_AUTO_GPIO3_SHIFT 14 -#define OMAP3430_AUTO_GPIO2 (1 << 13) -#define OMAP3430_AUTO_GPIO2_SHIFT 13 -#define OMAP3430_AUTO_WDT3 (1 << 12) -#define OMAP3430_AUTO_WDT3_SHIFT 12 -#define OMAP3430_AUTO_UART3 (1 << 11) -#define OMAP3430_AUTO_UART3_SHIFT 11 -#define OMAP3430_AUTO_GPT9 (1 << 10) -#define OMAP3430_AUTO_GPT9_SHIFT 10 -#define OMAP3430_AUTO_GPT8 (1 << 9) -#define OMAP3430_AUTO_GPT8_SHIFT 9 -#define OMAP3430_AUTO_GPT7 (1 << 8) -#define OMAP3430_AUTO_GPT7_SHIFT 8 -#define OMAP3430_AUTO_GPT6 (1 << 7) -#define OMAP3430_AUTO_GPT6_SHIFT 7 -#define OMAP3430_AUTO_GPT5 (1 << 6) -#define OMAP3430_AUTO_GPT5_SHIFT 6 -#define OMAP3430_AUTO_GPT4 (1 << 5) -#define OMAP3430_AUTO_GPT4_SHIFT 5 -#define OMAP3430_AUTO_GPT3 (1 << 4) -#define OMAP3430_AUTO_GPT3_SHIFT 4 -#define OMAP3430_AUTO_GPT2 (1 << 3) -#define OMAP3430_AUTO_GPT2_SHIFT 3 -#define OMAP3430_AUTO_MCBSP4 (1 << 2) -#define OMAP3430_AUTO_MCBSP4_SHIFT 2 -#define OMAP3430_AUTO_MCBSP3 (1 << 1) -#define OMAP3430_AUTO_MCBSP3_SHIFT 1 -#define OMAP3430_AUTO_MCBSP2 (1 << 0) -#define OMAP3430_AUTO_MCBSP2_SHIFT 0 - -/* CM_CLKSEL_PER */ +#define OMAP3430_ST_MCBSP4_SHIFT 2 +#define OMAP3430_ST_MCBSP3_SHIFT 1 +#define OMAP3430_ST_MCBSP2_SHIFT 0 #define OMAP3430_CLKSEL_GPT9_MASK (1 << 7) -#define OMAP3430_CLKSEL_GPT9_SHIFT 7 #define OMAP3430_CLKSEL_GPT8_MASK (1 << 6) -#define OMAP3430_CLKSEL_GPT8_SHIFT 6 #define OMAP3430_CLKSEL_GPT7_MASK (1 << 5) -#define OMAP3430_CLKSEL_GPT7_SHIFT 5 #define OMAP3430_CLKSEL_GPT6_MASK (1 << 4) -#define OMAP3430_CLKSEL_GPT6_SHIFT 4 #define OMAP3430_CLKSEL_GPT5_MASK (1 << 3) -#define OMAP3430_CLKSEL_GPT5_SHIFT 3 #define OMAP3430_CLKSEL_GPT4_MASK (1 << 2) -#define OMAP3430_CLKSEL_GPT4_SHIFT 2 #define OMAP3430_CLKSEL_GPT3_MASK (1 << 1) -#define OMAP3430_CLKSEL_GPT3_SHIFT 1 #define OMAP3430_CLKSEL_GPT2_MASK (1 << 0) -#define OMAP3430_CLKSEL_GPT2_SHIFT 0 - -/* CM_SLEEPDEP_PER specific bits */ -#define OMAP3430_CM_SLEEPDEP_PER_EN_IVA2 (1 << 2) - -/* CM_CLKSTCTRL_PER */ -#define OMAP3430_CLKTRCTRL_PER_SHIFT 0 #define OMAP3430_CLKTRCTRL_PER_MASK (0x3 << 0) - -/* CM_CLKSTST_PER */ -#define OMAP3430_CLKACTIVITY_PER_SHIFT 0 -#define OMAP3430_CLKACTIVITY_PER_MASK (1 << 0) - -/* CM_CLKSEL1_EMU */ #define OMAP3430_DIV_DPLL4_SHIFT 24 -#define OMAP3430_DIV_DPLL4_MASK (0x1f << 24) +#define OMAP3630_DIV_DPLL4_WIDTH 6 #define OMAP3430_DIV_DPLL3_SHIFT 16 -#define OMAP3430_DIV_DPLL3_MASK (0x1f << 16) +#define OMAP3430_DIV_DPLL3_WIDTH 5 #define OMAP3430_CLKSEL_TRACECLK_SHIFT 11 -#define OMAP3430_CLKSEL_TRACECLK_MASK (0x7 << 11) +#define OMAP3430_CLKSEL_TRACECLK_WIDTH 3 #define OMAP3430_CLKSEL_PCLK_SHIFT 8 -#define OMAP3430_CLKSEL_PCLK_MASK (0x7 << 8) +#define OMAP3430_CLKSEL_PCLK_WIDTH 3 #define OMAP3430_CLKSEL_PCLKX2_SHIFT 6 -#define OMAP3430_CLKSEL_PCLKX2_MASK (0x3 << 6) +#define OMAP3430_CLKSEL_PCLKX2_WIDTH 2 #define OMAP3430_CLKSEL_ATCLK_SHIFT 4 -#define OMAP3430_CLKSEL_ATCLK_MASK (0x3 << 4) +#define OMAP3430_CLKSEL_ATCLK_WIDTH 2 #define OMAP3430_TRACE_MUX_CTRL_SHIFT 2 -#define OMAP3430_TRACE_MUX_CTRL_MASK (0x3 << 2) -#define OMAP3430_MUX_CTRL_SHIFT 0 +#define OMAP3430_TRACE_MUX_CTRL_WIDTH 2 #define OMAP3430_MUX_CTRL_MASK (0x3 << 0) - -/* CM_CLKSTCTRL_EMU */ -#define OMAP3430_CLKTRCTRL_EMU_SHIFT 0 #define OMAP3430_CLKTRCTRL_EMU_MASK (0x3 << 0) - -/* CM_CLKSTST_EMU */ -#define OMAP3430_CLKACTIVITY_EMU_SHIFT 0 -#define OMAP3430_CLKACTIVITY_EMU_MASK (1 << 0) - -/* CM_CLKSEL2_EMU specific bits */ -#define OMAP3430_CORE_DPLL_EMU_MULT_SHIFT 8 -#define OMAP3430_CORE_DPLL_EMU_MULT_MASK (0x7ff << 8) -#define OMAP3430_CORE_DPLL_EMU_DIV_SHIFT 0 -#define OMAP3430_CORE_DPLL_EMU_DIV_MASK (0x7f << 0) - -/* CM_CLKSEL3_EMU specific bits */ -#define OMAP3430_PERIPH_DPLL_EMU_MULT_SHIFT 8 -#define OMAP3430_PERIPH_DPLL_EMU_MULT_MASK (0x7ff << 8) -#define OMAP3430_PERIPH_DPLL_EMU_DIV_SHIFT 0 -#define OMAP3430_PERIPH_DPLL_EMU_DIV_MASK (0x7f << 0) - -/* CM_POLCTRL */ -#define OMAP3430_CLKOUT2_POL (1 << 0) - -/* CM_IDLEST_NEON */ -#define OMAP3430_ST_NEON (1 << 0) - -/* CM_CLKSTCTRL_NEON */ -#define OMAP3430_CLKTRCTRL_NEON_SHIFT 0 #define OMAP3430_CLKTRCTRL_NEON_MASK (0x3 << 0) - -/* CM_FCLKEN_USBHOST */ #define OMAP3430ES2_EN_USBHOST2_SHIFT 1 -#define OMAP3430ES2_EN_USBHOST2_MASK (1 << 1) #define OMAP3430ES2_EN_USBHOST1_SHIFT 0 -#define OMAP3430ES2_EN_USBHOST1_MASK (1 << 0) - -/* CM_ICLKEN_USBHOST */ #define OMAP3430ES2_EN_USBHOST_SHIFT 0 -#define OMAP3430ES2_EN_USBHOST_MASK (1 << 0) - -/* CM_IDLEST_USBHOST */ - -/* CM_AUTOIDLE_USBHOST */ -#define OMAP3430ES2_AUTO_USBHOST_SHIFT 0 -#define OMAP3430ES2_AUTO_USBHOST_MASK (1 << 0) - -/* CM_SLEEPDEP_USBHOST */ -#define OMAP3430ES2_EN_MPU_SHIFT 1 -#define OMAP3430ES2_EN_MPU_MASK (1 << 1) -#define OMAP3430ES2_EN_IVA2_SHIFT 2 -#define OMAP3430ES2_EN_IVA2_MASK (1 << 2) - -/* CM_CLKSTCTRL_USBHOST */ -#define OMAP3430ES2_CLKTRCTRL_USBHOST_SHIFT 0 +#define OMAP3430ES2_ST_USBHOST_IDLE_SHIFT 1 +#define OMAP3430ES2_ST_USBHOST_STDBY_SHIFT 0 #define OMAP3430ES2_CLKTRCTRL_USBHOST_MASK (3 << 0) - -/* CM_CLKSTST_USBHOST */ -#define OMAP3430ES2_CLKACTIVITY_USBHOST_SHIFT 0 -#define OMAP3430ES2_CLKACTIVITY_USBHOST_MASK (1 << 0) - +#define OMAP34XX_CLKSTCTRL_DISABLE_AUTO 0x0 +#define OMAP34XX_CLKSTCTRL_FORCE_SLEEP 0x1 +#define OMAP34XX_CLKSTCTRL_FORCE_WAKEUP 0x2 +#define OMAP34XX_CLKSTCTRL_ENABLE_AUTO 0x3 #endif diff --git a/arch/arm/mach-omap2/cm-regbits-44xx.h b/arch/arm/mach-omap2/cm-regbits-44xx.h new file mode 100644 index 00000000000..4dbbd99b6e1 --- /dev/null +++ b/arch/arm/mach-omap2/cm-regbits-44xx.h @@ -0,0 +1,146 @@ +/* + * OMAP44xx Clock Management register bits + * + * Copyright (C) 2009-2012 Texas Instruments, Inc. + * Copyright (C) 2009-2010 Nokia Corporation + * + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CM_REGBITS_44XX_H +#define __ARCH_ARM_MACH_OMAP2_CM_REGBITS_44XX_H + +#define OMAP4430_ABE_STATDEP_SHIFT 3 +#define OMAP4430_AUTO_DPLL_MODE_MASK (0x7 << 0) +#define OMAP4430_CLKSEL_SHIFT 24 +#define OMAP4430_CLKSEL_WIDTH 0x1 +#define OMAP4430_CLKSEL_MASK (1 << 24) +#define OMAP4430_CLKSEL_0_0_SHIFT 0 +#define OMAP4430_CLKSEL_0_0_WIDTH 0x1 +#define OMAP4430_CLKSEL_0_1_SHIFT 0 +#define OMAP4430_CLKSEL_0_1_WIDTH 0x2 +#define OMAP4430_CLKSEL_24_25_SHIFT 24 +#define OMAP4430_CLKSEL_24_25_WIDTH 0x2 +#define OMAP4430_CLKSEL_60M_SHIFT 24 +#define OMAP4430_CLKSEL_60M_WIDTH 0x1 +#define OMAP4430_CLKSEL_AESS_FCLK_SHIFT 24 +#define OMAP4430_CLKSEL_AESS_FCLK_WIDTH 0x1 +#define OMAP4430_CLKSEL_CORE_SHIFT 0 +#define OMAP4430_CLKSEL_CORE_WIDTH 0x1 +#define OMAP4430_CLKSEL_DIV_SHIFT 24 +#define OMAP4430_CLKSEL_DIV_WIDTH 0x1 +#define OMAP4430_CLKSEL_FCLK_SHIFT 24 +#define OMAP4430_CLKSEL_FCLK_WIDTH 0x2 +#define OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT 25 +#define OMAP4430_CLKSEL_INTERNAL_SOURCE_WIDTH 0x1 +#define OMAP4430_CLKSEL_L3_SHIFT 4 +#define OMAP4430_CLKSEL_L3_WIDTH 0x1 +#define OMAP4430_CLKSEL_L4_SHIFT 8 +#define OMAP4430_CLKSEL_L4_WIDTH 0x1 +#define OMAP4430_CLKSEL_OPP_SHIFT 0 +#define OMAP4430_CLKSEL_OPP_WIDTH 0x2 +#define OMAP4430_CLKSEL_PMD_STM_CLK_SHIFT 27 +#define OMAP4430_CLKSEL_PMD_STM_CLK_WIDTH 0x3 +#define OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK (0x7 << 24) +#define OMAP4430_CLKSEL_SGX_FCLK_MASK (1 << 24) +#define OMAP4430_CLKSEL_SOURCE_MASK (0x3 << 24) +#define OMAP4430_CLKSEL_SOURCE_24_24_MASK (1 << 24) +#define OMAP4430_CLKSEL_UTMI_P1_SHIFT 24 +#define OMAP4430_CLKSEL_UTMI_P1_WIDTH 0x1 +#define OMAP4430_CLKSEL_UTMI_P2_SHIFT 25 +#define OMAP4430_CLKSEL_UTMI_P2_WIDTH 0x1 +#define OMAP4430_CLKTRCTRL_SHIFT 0 +#define OMAP4430_CLKTRCTRL_MASK (0x3 << 0) +#define OMAP4430_DPLL_BYP_CLKSEL_SHIFT 23 +#define OMAP4430_DPLL_BYP_CLKSEL_WIDTH 0x1 +#define OMAP4430_DPLL_CLKOUTHIF_DIV_MASK (0x1f << 0) +#define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT 8 +#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK (1 << 10) +#define OMAP4430_DPLL_CLKOUT_DIV_SHIFT 0 +#define OMAP4430_DPLL_CLKOUT_DIV_WIDTH 0x5 +#define OMAP4430_DPLL_CLKOUT_DIV_MASK (0x1f << 0) +#define OMAP4430_DPLL_CLKOUT_DIV_0_6_MASK (0x7f << 0) +#define OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK (1 << 8) +#define OMAP4430_DPLL_DIV_MASK (0x7f << 0) +#define OMAP4430_DPLL_DIV_0_7_MASK (0xff << 0) +#define OMAP4430_DPLL_EN_MASK (0x7 << 0) +#define OMAP4430_DPLL_LPMODE_EN_MASK (1 << 10) +#define OMAP4430_DPLL_MULT_MASK (0x7ff << 8) +#define OMAP4430_DPLL_MULT_USB_MASK (0xfff << 8) +#define OMAP4430_DPLL_REGM4XEN_MASK (1 << 11) +#define OMAP4430_DPLL_SD_DIV_MASK (0xff << 24) +#define OMAP4430_DSS_STATDEP_SHIFT 8 +#define OMAP4430_DUCATI_STATDEP_SHIFT 0 +#define OMAP4430_GFX_STATDEP_SHIFT 10 +#define OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK (0x1f << 0) +#define OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK (0x1f << 0) +#define OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK (0x1f << 0) +#define OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK (0x1f << 0) +#define OMAP4430_IDLEST_SHIFT 16 +#define OMAP4430_IDLEST_MASK (0x3 << 16) +#define OMAP4430_IVAHD_STATDEP_SHIFT 2 +#define OMAP4430_L3INIT_STATDEP_SHIFT 7 +#define OMAP4430_L3_1_STATDEP_SHIFT 5 +#define OMAP4430_L3_2_STATDEP_SHIFT 6 +#define OMAP4430_L4CFG_STATDEP_SHIFT 12 +#define OMAP4430_L4PER_STATDEP_SHIFT 13 +#define OMAP4430_L4SEC_STATDEP_SHIFT 14 +#define OMAP4430_L4WKUP_STATDEP_SHIFT 15 +#define OMAP4430_MEMIF_STATDEP_SHIFT 4 +#define OMAP4430_MODULEMODE_SHIFT 0 +#define OMAP4430_MODULEMODE_MASK (0x3 << 0) +#define OMAP4430_OPTFCLKEN_48MHZ_CLK_SHIFT 9 +#define OMAP4430_OPTFCLKEN_BGAP_32K_SHIFT 8 +#define OMAP4430_OPTFCLKEN_CLK32K_SHIFT 8 +#define OMAP4430_OPTFCLKEN_CTRLCLK_SHIFT 8 +#define OMAP4430_OPTFCLKEN_DBCLK_SHIFT 8 +#define OMAP4430_OPTFCLKEN_DSSCLK_SHIFT 8 +#define OMAP4430_OPTFCLKEN_FCLK_SHIFT 8 +#define OMAP4430_OPTFCLKEN_FCLK0_SHIFT 8 +#define OMAP4430_OPTFCLKEN_FCLK1_SHIFT 9 +#define OMAP4430_OPTFCLKEN_FCLK2_SHIFT 10 +#define OMAP4430_OPTFCLKEN_FUNC48MCLK_SHIFT 15 +#define OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_SHIFT 13 +#define OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_SHIFT 14 +#define OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT 11 +#define OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT 12 +#define OMAP4430_OPTFCLKEN_PER24MC_GFCLK_SHIFT 8 +#define OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_SHIFT 9 +#define OMAP4430_OPTFCLKEN_PHY_48M_SHIFT 8 +#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_SHIFT 10 +#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_SHIFT 11 +#define OMAP4430_OPTFCLKEN_SYS_CLK_SHIFT 10 +#define OMAP4460_OPTFCLKEN_TS_FCLK_SHIFT 8 +#define OMAP4430_OPTFCLKEN_TV_CLK_SHIFT 11 +#define OMAP4430_OPTFCLKEN_USB_CH0_CLK_SHIFT 8 +#define OMAP4430_OPTFCLKEN_USB_CH1_CLK_SHIFT 9 +#define OMAP4430_OPTFCLKEN_USB_CH2_CLK_SHIFT 10 +#define OMAP4430_OPTFCLKEN_UTMI_P1_CLK_SHIFT 8 +#define OMAP4430_OPTFCLKEN_UTMI_P2_CLK_SHIFT 9 +#define OMAP4430_OPTFCLKEN_UTMI_P3_CLK_SHIFT 10 +#define OMAP4430_OPTFCLKEN_XCLK_SHIFT 8 +#define OMAP4430_PAD_CLKS_GATE_SHIFT 8 +#define OMAP4430_PMD_STM_MUX_CTRL_SHIFT 20 +#define OMAP4430_PMD_STM_MUX_CTRL_WIDTH 0x2 +#define OMAP4430_PMD_TRACE_MUX_CTRL_SHIFT 22 +#define OMAP4430_PMD_TRACE_MUX_CTRL_WIDTH 0x2 +#define OMAP4430_SCALE_FCLK_SHIFT 0 +#define OMAP4430_SCALE_FCLK_WIDTH 0x1 +#define OMAP4430_SLIMBUS_CLK_GATE_SHIFT 10 +#define OMAP4430_ST_DPLL_CLK_MASK (1 << 0) +#define OMAP4430_SYS_CLKSEL_SHIFT 0 +#define OMAP4430_SYS_CLKSEL_WIDTH 0x3 +#define OMAP4430_TESLA_STATDEP_SHIFT 1 +#endif diff --git a/arch/arm/mach-omap2/cm-regbits-54xx.h b/arch/arm/mach-omap2/cm-regbits-54xx.h new file mode 100644 index 00000000000..896ae9fc4cf --- /dev/null +++ b/arch/arm/mach-omap2/cm-regbits-54xx.h @@ -0,0 +1,104 @@ +/* + * OMAP54xx Clock Management register bits + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CM_REGBITS_54XX_H +#define __ARCH_ARM_MACH_OMAP2_CM_REGBITS_54XX_H + +#define OMAP54XX_ABE_STATDEP_SHIFT 3 +#define OMAP54XX_AUTO_DPLL_MODE_MASK (0x7 << 0) +#define OMAP54XX_CLKSEL_SHIFT 24 +#define OMAP54XX_CLKSEL_WIDTH 0x1 +#define OMAP54XX_CLKSEL_0_0_SHIFT 0 +#define OMAP54XX_CLKSEL_0_0_WIDTH 0x1 +#define OMAP54XX_CLKSEL_AESS_FCLK_SHIFT 24 +#define OMAP54XX_CLKSEL_AESS_FCLK_WIDTH 0x1 +#define OMAP54XX_CLKSEL_DIV_SHIFT 25 +#define OMAP54XX_CLKSEL_DIV_WIDTH 0x1 +#define OMAP54XX_CLKSEL_FCLK_SHIFT 24 +#define OMAP54XX_CLKSEL_FCLK_WIDTH 0x1 +#define OMAP54XX_CLKSEL_GPU_CORE_GCLK_SHIFT 24 +#define OMAP54XX_CLKSEL_GPU_CORE_GCLK_WIDTH 0x1 +#define OMAP54XX_CLKSEL_GPU_HYD_GCLK_SHIFT 25 +#define OMAP54XX_CLKSEL_GPU_HYD_GCLK_WIDTH 0x1 +#define OMAP54XX_CLKSEL_INTERNAL_SOURCE_SHIFT 26 +#define OMAP54XX_CLKSEL_INTERNAL_SOURCE_WIDTH 0x2 +#define OMAP54XX_CLKSEL_OPP_SHIFT 0 +#define OMAP54XX_CLKSEL_OPP_WIDTH 0x2 +#define OMAP54XX_CLKSEL_SOURCE_SHIFT 24 +#define OMAP54XX_CLKSEL_SOURCE_WIDTH 0x2 +#define OMAP54XX_CLKSEL_SOURCE_L3INIT_MMC1_SHIFT 24 +#define OMAP54XX_CLKSEL_SOURCE_L3INIT_MMC1_WIDTH 0x1 +#define OMAP54XX_CLKSEL_UTMI_P1_SHIFT 24 +#define OMAP54XX_CLKSEL_UTMI_P1_WIDTH 0x1 +#define OMAP54XX_CLKSEL_UTMI_P2_SHIFT 25 +#define OMAP54XX_CLKSEL_UTMI_P2_WIDTH 0x1 +#define OMAP54XX_DIVHS_MASK (0x3f << 0) +#define OMAP54XX_DIVHS_0_4_MASK (0x1f << 0) +#define OMAP54XX_DIVHS_0_6_MASK (0x7f << 0) +#define OMAP54XX_DPLL_DIV_MASK (0x7f << 0) +#define OMAP54XX_DPLL_EN_MASK (0x7 << 0) +#define OMAP54XX_DPLL_LPMODE_EN_MASK (1 << 10) +#define OMAP54XX_DPLL_MULT_MASK (0x7ff << 8) +#define OMAP54XX_DPLL_REGM4XEN_MASK (1 << 11) +#define OMAP54XX_DPLL_SD_DIV_MASK (0xff << 24) +#define OMAP54XX_DSP_STATDEP_SHIFT 1 +#define OMAP54XX_DSS_STATDEP_SHIFT 8 +#define OMAP54XX_EMIF_STATDEP_SHIFT 4 +#define OMAP54XX_GPU_STATDEP_SHIFT 10 +#define OMAP54XX_IPU_STATDEP_SHIFT 0 +#define OMAP54XX_IVA_STATDEP_SHIFT 2 +#define OMAP54XX_L3INIT_STATDEP_SHIFT 7 +#define OMAP54XX_L3MAIN1_STATDEP_SHIFT 5 +#define OMAP54XX_L3MAIN2_STATDEP_SHIFT 6 +#define OMAP54XX_L4CFG_STATDEP_SHIFT 12 +#define OMAP54XX_L4PER_STATDEP_SHIFT 13 +#define OMAP54XX_L4SEC_STATDEP_SHIFT 14 +#define OMAP54XX_OPTFCLKEN_32KHZ_CLK_SHIFT 11 +#define OMAP54XX_OPTFCLKEN_32KHZ_CLK_8_8_SHIFT 8 +#define OMAP54XX_OPTFCLKEN_48MHZ_CLK_SHIFT 9 +#define OMAP54XX_OPTFCLKEN_CLK32K_SHIFT 8 +#define OMAP54XX_OPTFCLKEN_CTRLCLK_SHIFT 8 +#define OMAP54XX_OPTFCLKEN_DBCLK_SHIFT 8 +#define OMAP54XX_OPTFCLKEN_DSSCLK_SHIFT 8 +#define OMAP54XX_OPTFCLKEN_HSIC480M_P1_CLK_SHIFT 13 +#define OMAP54XX_OPTFCLKEN_HSIC480M_P2_CLK_SHIFT 14 +#define OMAP54XX_OPTFCLKEN_HSIC480M_P3_CLK_SHIFT 7 +#define OMAP54XX_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT 11 +#define OMAP54XX_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT 12 +#define OMAP54XX_OPTFCLKEN_HSIC60M_P3_CLK_SHIFT 6 +#define OMAP54XX_OPTFCLKEN_REFCLK960M_SHIFT 8 +#define OMAP54XX_OPTFCLKEN_REF_CLK_SHIFT 8 +#define OMAP54XX_OPTFCLKEN_SLIMBUS_CLK_SHIFT 11 +#define OMAP54XX_OPTFCLKEN_SYS_CLK_SHIFT 10 +#define OMAP54XX_OPTFCLKEN_TXPHY_CLK_SHIFT 8 +#define OMAP54XX_OPTFCLKEN_TXPHY_LS_CLK_SHIFT 9 +#define OMAP54XX_OPTFCLKEN_USB_CH0_CLK_SHIFT 8 +#define OMAP54XX_OPTFCLKEN_USB_CH1_CLK_SHIFT 9 +#define OMAP54XX_OPTFCLKEN_USB_CH2_CLK_SHIFT 10 +#define OMAP54XX_OPTFCLKEN_UTMI_P1_CLK_SHIFT 8 +#define OMAP54XX_OPTFCLKEN_UTMI_P2_CLK_SHIFT 9 +#define OMAP54XX_OPTFCLKEN_UTMI_P3_CLK_SHIFT 10 +#define OMAP54XX_PAD_CLKS_GATE_SHIFT 8 +#define OMAP54XX_SLIMBUS1_CLK_GATE_SHIFT 10 +#define OMAP54XX_ST_DPLL_CLK_MASK (1 << 0) +#define OMAP54XX_SYS_CLKSEL_SHIFT 0 +#define OMAP54XX_SYS_CLKSEL_WIDTH 0x3 +#define OMAP54XX_WKUPAON_STATDEP_SHIFT 15 +#endif diff --git a/arch/arm/mach-omap2/cm-regbits-7xx.h b/arch/arm/mach-omap2/cm-regbits-7xx.h new file mode 100644 index 00000000000..ad8f81ce9b1 --- /dev/null +++ b/arch/arm/mach-omap2/cm-regbits-7xx.h @@ -0,0 +1,51 @@ +/* + * DRA7xx Clock Management register bits + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * + * Generated by code originally written by: + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CM_REGBITS_7XX_H +#define __ARCH_ARM_MACH_OMAP2_CM_REGBITS_7XX_H + +#define DRA7XX_ATL_STATDEP_SHIFT 30 +#define DRA7XX_CAM_STATDEP_SHIFT 9 +#define DRA7XX_DSP1_STATDEP_SHIFT 1 +#define DRA7XX_DSP2_STATDEP_SHIFT 18 +#define DRA7XX_DSS_STATDEP_SHIFT 8 +#define DRA7XX_EMIF_STATDEP_SHIFT 4 +#define DRA7XX_EVE1_STATDEP_SHIFT 19 +#define DRA7XX_EVE2_STATDEP_SHIFT 20 +#define DRA7XX_EVE3_STATDEP_SHIFT 21 +#define DRA7XX_EVE4_STATDEP_SHIFT 22 +#define DRA7XX_GMAC_STATDEP_SHIFT 25 +#define DRA7XX_GPU_STATDEP_SHIFT 10 +#define DRA7XX_IPU1_STATDEP_SHIFT 23 +#define DRA7XX_IPU2_STATDEP_SHIFT 0 +#define DRA7XX_IPU_STATDEP_SHIFT 24 +#define DRA7XX_IVA_STATDEP_SHIFT 2 +#define DRA7XX_L3INIT_STATDEP_SHIFT 7 +#define DRA7XX_L3MAIN1_STATDEP_SHIFT 5 +#define DRA7XX_L4CFG_STATDEP_SHIFT 12 +#define DRA7XX_L4PER2_STATDEP_SHIFT 26 +#define DRA7XX_L4PER3_STATDEP_SHIFT 27 +#define DRA7XX_L4PER_STATDEP_SHIFT 13 +#define DRA7XX_L4SEC_STATDEP_SHIFT 14 +#define DRA7XX_PCIE_STATDEP_SHIFT 29 +#define DRA7XX_VPE_STATDEP_SHIFT 28 +#define DRA7XX_WKUPAON_STATDEP_SHIFT 15 +#endif diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index 65fdf78c91e..93473f9a551 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h @@ -1,11 +1,8 @@ -#ifndef __ARCH_ASM_MACH_OMAP2_CM_H -#define __ARCH_ASM_MACH_OMAP2_CM_H - /* - * OMAP2/3 Clock Management (CM) register definitions + * OMAP2+ Clock Management prototypes * - * Copyright (C) 2007-2008 Texas Instruments, Inc. - * Copyright (C) 2007-2008 Nokia Corporation + * Copyright (C) 2007-2009, 2012 Texas Instruments, Inc. + * Copyright (C) 2007-2009 Nokia Corporation * * Written by Paul Walmsley * @@ -13,119 +10,55 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ - -#include "prcm-common.h" - -#ifndef __ASSEMBLER__ -#define OMAP_CM_REGADDR(module, reg) \ - IO_ADDRESS(OMAP2_CM_BASE + (module) + (reg)) -#else -#define OMAP2420_CM_REGADDR(module, reg) \ - IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg)) -#define OMAP2430_CM_REGADDR(module, reg) \ - IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg)) -#define OMAP34XX_CM_REGADDR(module, reg) \ - IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg)) -#endif +#ifndef __ARCH_ASM_MACH_OMAP2_CM_H +#define __ARCH_ASM_MACH_OMAP2_CM_H /* - * Architecture-specific global CM registers - * Use cm_{read,write}_reg() with these registers. - * These registers appear once per CM module. + * MAX_MODULE_READY_TIME: max duration in microseconds to wait for the + * PRCM to request that a module exit the inactive state in the case of + * OMAP2 & 3. + * In the case of OMAP4 this is the max duration in microseconds for the + * module to reach the functionnal state from an inactive state. */ +#define MAX_MODULE_READY_TIME 2000 -#define OMAP3430_CM_REVISION OMAP_CM_REGADDR(OCP_MOD, 0x0000) -#define OMAP3430_CM_SYSCONFIG OMAP_CM_REGADDR(OCP_MOD, 0x0010) -#define OMAP3430_CM_POLCTRL OMAP_CM_REGADDR(OCP_MOD, 0x009c) - -#define OMAP3430_CM_CLKOUT_CTRL OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070) +# ifndef __ASSEMBLER__ +extern void __iomem *cm_base; +extern void __iomem *cm2_base; +extern void omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2); +# endif /* - * Module specific CM registers from CM_BASE + domain offset - * Use cm_{read,write}_mod_reg() with these registers. - * These register offsets generally appear in more than one PRCM submodule. + * MAX_MODULE_DISABLE_TIME: max duration in microseconds to wait for + * the PRCM to request that a module enter the inactive state in the + * case of OMAP2 & 3. In the case of OMAP4 this is the max duration + * in microseconds for the module to reach the inactive state from + * a functional state. + * XXX FSUSB on OMAP4430 takes ~4ms to idle after reset during + * kernel init. */ +#define MAX_MODULE_DISABLE_TIME 5000 -/* Common between 24xx and 34xx */ - -#define CM_FCLKEN 0x0000 -#define CM_FCLKEN1 CM_FCLKEN -#define CM_CLKEN CM_FCLKEN -#define CM_ICLKEN 0x0010 -#define CM_ICLKEN1 CM_ICLKEN -#define CM_ICLKEN2 0x0014 -#define CM_ICLKEN3 0x0018 -#define CM_IDLEST 0x0020 -#define CM_IDLEST1 CM_IDLEST -#define CM_IDLEST2 0x0024 -#define CM_AUTOIDLE 0x0030 -#define CM_AUTOIDLE1 CM_AUTOIDLE -#define CM_AUTOIDLE2 0x0034 -#define CM_AUTOIDLE3 0x0038 -#define CM_CLKSEL 0x0040 -#define CM_CLKSEL1 CM_CLKSEL -#define CM_CLKSEL2 0x0044 -#define CM_CLKSTCTRL 0x0048 - - -/* Architecture-specific registers */ - -#define OMAP24XX_CM_FCLKEN2 0x0004 -#define OMAP24XX_CM_ICLKEN4 0x001c -#define OMAP24XX_CM_AUTOIDLE4 0x003c +# ifndef __ASSEMBLER__ -#define OMAP2430_CM_IDLEST3 0x0028 - -#define OMAP3430_CM_CLKEN_PLL 0x0004 -#define OMAP3430ES2_CM_CLKEN2 0x0004 -#define OMAP3430ES2_CM_FCLKEN3 0x0008 -#define OMAP3430_CM_IDLEST_PLL CM_IDLEST2 -#define OMAP3430_CM_AUTOIDLE_PLL CM_AUTOIDLE2 -#define OMAP3430ES2_CM_AUTOIDLE2_PLL CM_AUTOIDLE2 -#define OMAP3430_CM_CLKSEL1 CM_CLKSEL -#define OMAP3430_CM_CLKSEL1_PLL CM_CLKSEL -#define OMAP3430_CM_CLKSEL2_PLL CM_CLKSEL2 -#define OMAP3430_CM_SLEEPDEP CM_CLKSEL2 -#define OMAP3430_CM_CLKSEL3 CM_CLKSTCTRL -#define OMAP3430_CM_CLKSTST 0x004c -#define OMAP3430ES2_CM_CLKSEL4 0x004c -#define OMAP3430ES2_CM_CLKSEL5 0x0050 -#define OMAP3430_CM_CLKSEL2_EMU 0x0050 -#define OMAP3430_CM_CLKSEL3_EMU 0x0054 - - -/* Clock management domain register get/set */ - -#ifndef __ASSEMBLER__ - -extern u32 cm_read_mod_reg(s16 module, u16 idx); -extern void cm_write_mod_reg(u32 val, s16 module, u16 idx); -extern u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); - -static inline u32 cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) -{ - return cm_rmw_mod_reg_bits(bits, bits, module, idx); -} - -static inline u32 cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) -{ - return cm_rmw_mod_reg_bits(bits, 0x0, module, idx); -} - -#endif - -/* CM register bits shared between 24XX and 3430 */ - -/* CM_CLKSEL_GFX */ -#define OMAP_CLKSEL_GFX_SHIFT 0 -#define OMAP_CLKSEL_GFX_MASK (0x7 << 0) +/** + * struct cm_ll_data - fn ptrs to per-SoC CM function implementations + * @split_idlest_reg: ptr to the SoC CM-specific split_idlest_reg impl + * @wait_module_ready: ptr to the SoC CM-specific wait_module_ready impl + */ +struct cm_ll_data { + int (*split_idlest_reg)(void __iomem *idlest_reg, s16 *prcm_inst, + u8 *idlest_reg_id); + int (*wait_module_ready)(s16 prcm_mod, u8 idlest_id, u8 idlest_shift); +}; -/* CM_ICLKEN_GFX */ -#define OMAP_EN_GFX_SHIFT 0 -#define OMAP_EN_GFX (1 << 0) +extern int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, + u8 *idlest_reg_id); +extern int cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift); -/* CM_IDLEST_GFX */ -#define OMAP_ST_GFX (1 << 0) +extern int cm_register(struct cm_ll_data *cld); +extern int cm_unregister(struct cm_ll_data *cld); +# endif #endif diff --git a/arch/arm/mach-omap2/cm1_44xx.h b/arch/arm/mach-omap2/cm1_44xx.h new file mode 100644 index 00000000000..5ae8fe39d6e --- /dev/null +++ b/arch/arm/mach-omap2/cm1_44xx.h @@ -0,0 +1,222 @@ +/* + * OMAP44xx CM1 instance offset macros + * + * Copyright (C) 2009-2011 Texas Instruments, Inc. + * Copyright (C) 2009-2010 Nokia Corporation + * + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * XXX This file needs to be updated to align on one of "OMAP4", "OMAP44XX", + * or "OMAP4430". + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CM1_44XX_H +#define __ARCH_ARM_MACH_OMAP2_CM1_44XX_H + +#include "cm_44xx_54xx.h" + +/* CM1 base address */ +#define OMAP4430_CM1_BASE 0x4a004000 + +#define OMAP44XX_CM1_REGADDR(inst, reg) \ + OMAP2_L4_IO_ADDRESS(OMAP4430_CM1_BASE + (inst) + (reg)) + +/* CM1 instances */ +#define OMAP4430_CM1_OCP_SOCKET_INST 0x0000 +#define OMAP4430_CM1_CKGEN_INST 0x0100 +#define OMAP4430_CM1_MPU_INST 0x0300 +#define OMAP4430_CM1_TESLA_INST 0x0400 +#define OMAP4430_CM1_ABE_INST 0x0500 +#define OMAP4430_CM1_RESTORE_INST 0x0e00 +#define OMAP4430_CM1_INSTR_INST 0x0f00 + +/* CM1 clockdomain register offsets (from instance start) */ +#define OMAP4430_CM1_MPU_MPU_CDOFFS 0x0000 +#define OMAP4430_CM1_TESLA_TESLA_CDOFFS 0x0000 +#define OMAP4430_CM1_ABE_ABE_CDOFFS 0x0000 + +/* CM1 */ + +/* CM1.OCP_SOCKET_CM1 register offsets */ +#define OMAP4_REVISION_CM1_OFFSET 0x0000 +#define OMAP4430_REVISION_CM1 OMAP44XX_CM1_REGADDR(OMAP4430_CM1_OCP_SOCKET_INST, 0x0000) +#define OMAP4_CM_CM1_PROFILING_CLKCTRL_OFFSET 0x0040 +#define OMAP4430_CM_CM1_PROFILING_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_OCP_SOCKET_INST, 0x0040) + +/* CM1.CKGEN_CM1 register offsets */ +#define OMAP4_CM_CLKSEL_CORE_OFFSET 0x0000 +#define OMAP4430_CM_CLKSEL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0000) +#define OMAP4_CM_CLKSEL_ABE_OFFSET 0x0008 +#define OMAP4430_CM_CLKSEL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0008) +#define OMAP4_CM_DLL_CTRL_OFFSET 0x0010 +#define OMAP4430_CM_DLL_CTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0010) +#define OMAP4_CM_CLKMODE_DPLL_CORE_OFFSET 0x0020 +#define OMAP4430_CM_CLKMODE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0020) +#define OMAP4_CM_IDLEST_DPLL_CORE_OFFSET 0x0024 +#define OMAP4430_CM_IDLEST_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0024) +#define OMAP4_CM_AUTOIDLE_DPLL_CORE_OFFSET 0x0028 +#define OMAP4430_CM_AUTOIDLE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0028) +#define OMAP4_CM_CLKSEL_DPLL_CORE_OFFSET 0x002c +#define OMAP4430_CM_CLKSEL_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x002c) +#define OMAP4_CM_DIV_M2_DPLL_CORE_OFFSET 0x0030 +#define OMAP4430_CM_DIV_M2_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0030) +#define OMAP4_CM_DIV_M3_DPLL_CORE_OFFSET 0x0034 +#define OMAP4430_CM_DIV_M3_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0034) +#define OMAP4_CM_DIV_M4_DPLL_CORE_OFFSET 0x0038 +#define OMAP4430_CM_DIV_M4_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0038) +#define OMAP4_CM_DIV_M5_DPLL_CORE_OFFSET 0x003c +#define OMAP4430_CM_DIV_M5_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x003c) +#define OMAP4_CM_DIV_M6_DPLL_CORE_OFFSET 0x0040 +#define OMAP4430_CM_DIV_M6_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0040) +#define OMAP4_CM_DIV_M7_DPLL_CORE_OFFSET 0x0044 +#define OMAP4430_CM_DIV_M7_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0044) +#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_CORE_OFFSET 0x0048 +#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0048) +#define OMAP4_CM_SSC_MODFREQDIV_DPLL_CORE_OFFSET 0x004c +#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x004c) +#define OMAP4_CM_EMU_OVERRIDE_DPLL_CORE_OFFSET 0x0050 +#define OMAP4430_CM_EMU_OVERRIDE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0050) +#define OMAP4_CM_CLKMODE_DPLL_MPU_OFFSET 0x0060 +#define OMAP4430_CM_CLKMODE_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0060) +#define OMAP4_CM_IDLEST_DPLL_MPU_OFFSET 0x0064 +#define OMAP4430_CM_IDLEST_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0064) +#define OMAP4_CM_AUTOIDLE_DPLL_MPU_OFFSET 0x0068 +#define OMAP4430_CM_AUTOIDLE_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0068) +#define OMAP4_CM_CLKSEL_DPLL_MPU_OFFSET 0x006c +#define OMAP4430_CM_CLKSEL_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x006c) +#define OMAP4_CM_DIV_M2_DPLL_MPU_OFFSET 0x0070 +#define OMAP4430_CM_DIV_M2_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0070) +#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_MPU_OFFSET 0x0088 +#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0088) +#define OMAP4_CM_SSC_MODFREQDIV_DPLL_MPU_OFFSET 0x008c +#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x008c) +#define OMAP4_CM_BYPCLK_DPLL_MPU_OFFSET 0x009c +#define OMAP4430_CM_BYPCLK_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x009c) +#define OMAP4_CM_CLKMODE_DPLL_IVA_OFFSET 0x00a0 +#define OMAP4430_CM_CLKMODE_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00a0) +#define OMAP4_CM_IDLEST_DPLL_IVA_OFFSET 0x00a4 +#define OMAP4430_CM_IDLEST_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00a4) +#define OMAP4_CM_AUTOIDLE_DPLL_IVA_OFFSET 0x00a8 +#define OMAP4430_CM_AUTOIDLE_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00a8) +#define OMAP4_CM_CLKSEL_DPLL_IVA_OFFSET 0x00ac +#define OMAP4430_CM_CLKSEL_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00ac) +#define OMAP4_CM_DIV_M4_DPLL_IVA_OFFSET 0x00b8 +#define OMAP4430_CM_DIV_M4_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00b8) +#define OMAP4_CM_DIV_M5_DPLL_IVA_OFFSET 0x00bc +#define OMAP4430_CM_DIV_M5_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00bc) +#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_IVA_OFFSET 0x00c8 +#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00c8) +#define OMAP4_CM_SSC_MODFREQDIV_DPLL_IVA_OFFSET 0x00cc +#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00cc) +#define OMAP4_CM_BYPCLK_DPLL_IVA_OFFSET 0x00dc +#define OMAP4430_CM_BYPCLK_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00dc) +#define OMAP4_CM_CLKMODE_DPLL_ABE_OFFSET 0x00e0 +#define OMAP4430_CM_CLKMODE_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00e0) +#define OMAP4_CM_IDLEST_DPLL_ABE_OFFSET 0x00e4 +#define OMAP4430_CM_IDLEST_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00e4) +#define OMAP4_CM_AUTOIDLE_DPLL_ABE_OFFSET 0x00e8 +#define OMAP4430_CM_AUTOIDLE_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00e8) +#define OMAP4_CM_CLKSEL_DPLL_ABE_OFFSET 0x00ec +#define OMAP4430_CM_CLKSEL_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00ec) +#define OMAP4_CM_DIV_M2_DPLL_ABE_OFFSET 0x00f0 +#define OMAP4430_CM_DIV_M2_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00f0) +#define OMAP4_CM_DIV_M3_DPLL_ABE_OFFSET 0x00f4 +#define OMAP4430_CM_DIV_M3_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00f4) +#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_ABE_OFFSET 0x0108 +#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0108) +#define OMAP4_CM_SSC_MODFREQDIV_DPLL_ABE_OFFSET 0x010c +#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x010c) +#define OMAP4_CM_CLKMODE_DPLL_DDRPHY_OFFSET 0x0120 +#define OMAP4430_CM_CLKMODE_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0120) +#define OMAP4_CM_IDLEST_DPLL_DDRPHY_OFFSET 0x0124 +#define OMAP4430_CM_IDLEST_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0124) +#define OMAP4_CM_AUTOIDLE_DPLL_DDRPHY_OFFSET 0x0128 +#define OMAP4430_CM_AUTOIDLE_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0128) +#define OMAP4_CM_CLKSEL_DPLL_DDRPHY_OFFSET 0x012c +#define OMAP4430_CM_CLKSEL_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x012c) +#define OMAP4_CM_DIV_M2_DPLL_DDRPHY_OFFSET 0x0130 +#define OMAP4430_CM_DIV_M2_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0130) +#define OMAP4_CM_DIV_M4_DPLL_DDRPHY_OFFSET 0x0138 +#define OMAP4430_CM_DIV_M4_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0138) +#define OMAP4_CM_DIV_M5_DPLL_DDRPHY_OFFSET 0x013c +#define OMAP4430_CM_DIV_M5_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x013c) +#define OMAP4_CM_DIV_M6_DPLL_DDRPHY_OFFSET 0x0140 +#define OMAP4430_CM_DIV_M6_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0140) +#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_DDRPHY_OFFSET 0x0148 +#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0148) +#define OMAP4_CM_SSC_MODFREQDIV_DPLL_DDRPHY_OFFSET 0x014c +#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x014c) +#define OMAP4_CM_SHADOW_FREQ_CONFIG1_OFFSET 0x0160 +#define OMAP4430_CM_SHADOW_FREQ_CONFIG1 OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0160) +#define OMAP4_CM_SHADOW_FREQ_CONFIG2_OFFSET 0x0164 +#define OMAP4430_CM_SHADOW_FREQ_CONFIG2 OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0164) +#define OMAP4_CM_DYN_DEP_PRESCAL_OFFSET 0x0170 +#define OMAP4430_CM_DYN_DEP_PRESCAL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0170) +#define OMAP4_CM_RESTORE_ST_OFFSET 0x0180 +#define OMAP4430_CM_RESTORE_ST OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0180) + +/* CM1.MPU_CM1 register offsets */ +#define OMAP4_CM_MPU_CLKSTCTRL_OFFSET 0x0000 +#define OMAP4430_CM_MPU_CLKSTCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_INST, 0x0000) +#define OMAP4_CM_MPU_STATICDEP_OFFSET 0x0004 +#define OMAP4430_CM_MPU_STATICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_INST, 0x0004) +#define OMAP4_CM_MPU_DYNAMICDEP_OFFSET 0x0008 +#define OMAP4430_CM_MPU_DYNAMICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_INST, 0x0008) +#define OMAP4_CM_MPU_MPU_CLKCTRL_OFFSET 0x0020 +#define OMAP4430_CM_MPU_MPU_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_INST, 0x0020) + +/* CM1.TESLA_CM1 register offsets */ +#define OMAP4_CM_TESLA_CLKSTCTRL_OFFSET 0x0000 +#define OMAP4430_CM_TESLA_CLKSTCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_INST, 0x0000) +#define OMAP4_CM_TESLA_STATICDEP_OFFSET 0x0004 +#define OMAP4430_CM_TESLA_STATICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_INST, 0x0004) +#define OMAP4_CM_TESLA_DYNAMICDEP_OFFSET 0x0008 +#define OMAP4430_CM_TESLA_DYNAMICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_INST, 0x0008) +#define OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET 0x0020 +#define OMAP4430_CM_TESLA_TESLA_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_INST, 0x0020) + +/* CM1.ABE_CM1 register offsets */ +#define OMAP4_CM1_ABE_CLKSTCTRL_OFFSET 0x0000 +#define OMAP4430_CM1_ABE_CLKSTCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0000) +#define OMAP4_CM1_ABE_L4ABE_CLKCTRL_OFFSET 0x0020 +#define OMAP4430_CM1_ABE_L4ABE_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0020) +#define OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET 0x0028 +#define OMAP4430_CM1_ABE_AESS_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0028) +#define OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET 0x0030 +#define OMAP4430_CM1_ABE_PDM_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0030) +#define OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET 0x0038 +#define OMAP4430_CM1_ABE_DMIC_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0038) +#define OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET 0x0040 +#define OMAP4430_CM1_ABE_MCASP_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0040) +#define OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET 0x0048 +#define OMAP4430_CM1_ABE_MCBSP1_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0048) +#define OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET 0x0050 +#define OMAP4430_CM1_ABE_MCBSP2_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0050) +#define OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET 0x0058 +#define OMAP4430_CM1_ABE_MCBSP3_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0058) +#define OMAP4_CM1_ABE_SLIMBUS_CLKCTRL_OFFSET 0x0060 +#define OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0060) +#define OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET 0x0068 +#define OMAP4430_CM1_ABE_TIMER5_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0068) +#define OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET 0x0070 +#define OMAP4430_CM1_ABE_TIMER6_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0070) +#define OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET 0x0078 +#define OMAP4430_CM1_ABE_TIMER7_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0078) +#define OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET 0x0080 +#define OMAP4430_CM1_ABE_TIMER8_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0080) +#define OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET 0x0088 +#define OMAP4430_CM1_ABE_WDT3_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0088) + +#endif diff --git a/arch/arm/mach-omap2/cm1_54xx.h b/arch/arm/mach-omap2/cm1_54xx.h new file mode 100644 index 00000000000..90b3348e667 --- /dev/null +++ b/arch/arm/mach-omap2/cm1_54xx.h @@ -0,0 +1,213 @@ +/* + * OMAP54xx CM1 instance offset macros + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CM1_54XX_H +#define __ARCH_ARM_MACH_OMAP2_CM1_54XX_H + +#include "cm_44xx_54xx.h" + +/* CM1 base address */ +#define OMAP54XX_CM_CORE_AON_BASE 0x4a004000 + +#define OMAP54XX_CM_CORE_AON_REGADDR(inst, reg) \ + OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_AON_BASE + (inst) + (reg)) + +/* CM_CORE_AON instances */ +#define OMAP54XX_CM_CORE_AON_OCP_SOCKET_INST 0x0000 +#define OMAP54XX_CM_CORE_AON_CKGEN_INST 0x0100 +#define OMAP54XX_CM_CORE_AON_MPU_INST 0x0300 +#define OMAP54XX_CM_CORE_AON_DSP_INST 0x0400 +#define OMAP54XX_CM_CORE_AON_ABE_INST 0x0500 +#define OMAP54XX_CM_CORE_AON_RESTORE_INST 0x0e00 +#define OMAP54XX_CM_CORE_AON_INSTR_INST 0x0f00 + +/* CM_CORE_AON clockdomain register offsets (from instance start) */ +#define OMAP54XX_CM_CORE_AON_MPU_MPU_CDOFFS 0x0000 +#define OMAP54XX_CM_CORE_AON_DSP_DSP_CDOFFS 0x0000 +#define OMAP54XX_CM_CORE_AON_ABE_ABE_CDOFFS 0x0000 + +/* CM_CORE_AON */ + +/* CM_CORE_AON.OCP_SOCKET_CM_CORE_AON register offsets */ +#define OMAP54XX_REVISION_CM_CORE_AON_OFFSET 0x0000 +#define OMAP54XX_CM_CM_CORE_AON_PROFILING_CLKCTRL_OFFSET 0x0040 +#define OMAP54XX_CM_CM_CORE_AON_PROFILING_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_OCP_SOCKET_INST, 0x0040) +#define OMAP54XX_CM_CORE_AON_DEBUG_CFG_OFFSET 0x0080 +#define OMAP54XX_CM_CORE_AON_DEBUG_OUT_OFFSET 0x0084 +#define OMAP54XX_CM_CORE_AON_DEBUG_MPU_FD_TRANS_OFFSET 0x0090 +#define OMAP54XX_CM_CORE_AON_DEBUG_DSP_FD_TRANS_OFFSET 0x0094 +#define OMAP54XX_CM_CORE_AON_DEBUG_ABE_FD_TRANS_OFFSET 0x0098 +#define OMAP54XX_CM_CORE_AON_DEBUG_ABE_FD_TRANS2_OFFSET 0x009c +#define OMAP54XX_CM_CORE_AON_DEBUG_CM_CORE_AON_FD_TRANS_OFFSET 0x00a0 +#define OMAP54XX_CM_CORE_AON_DEBUG_C2C_FD_TRANS_OFFSET 0x00a4 +#define OMAP54XX_CM_CORE_AON_DEBUG_CAM_FD_TRANS_OFFSET 0x00a8 +#define OMAP54XX_CM_CORE_AON_DEBUG_COREAON_FD_TRANS_OFFSET 0x00ac +#define OMAP54XX_CM_CORE_AON_DEBUG_CUSTEFUSE_FD_TRANS_OFFSET 0x00b0 +#define OMAP54XX_CM_CORE_AON_DEBUG_DMA_FD_TRANS_OFFSET 0x00b4 +#define OMAP54XX_CM_CORE_AON_DEBUG_DSS_FD_TRANS_OFFSET 0x00b8 +#define OMAP54XX_CM_CORE_AON_DEBUG_EMIF_FD_TRANS_OFFSET 0x00bc +#define OMAP54XX_CM_CORE_AON_DEBUG_GPU_FD_TRANS_OFFSET 0x00c0 +#define OMAP54XX_CM_CORE_AON_DEBUG_IPU_FD_TRANS_OFFSET 0x00c4 +#define OMAP54XX_CM_CORE_AON_DEBUG_IVA_FD_TRANS_OFFSET 0x00c8 +#define OMAP54XX_CM_CORE_AON_DEBUG_L3INIT_FD_TRANS_OFFSET 0x00cc +#define OMAP54XX_CM_CORE_AON_DEBUG_L3INIT_FD_TRANS2_OFFSET 0x00d0 +#define OMAP54XX_CM_CORE_AON_DEBUG_L3INSTR_FD_TRANS_OFFSET 0x00d4 +#define OMAP54XX_CM_CORE_AON_DEBUG_L3MAIN1_FD_TRANS_OFFSET 0x00d8 +#define OMAP54XX_CM_CORE_AON_DEBUG_L3MAIN2_FD_TRANS_OFFSET 0x00dc +#define OMAP54XX_CM_CORE_AON_DEBUG_L4CFG_FD_TRANS_OFFSET 0x00e0 +#define OMAP54XX_CM_CORE_AON_DEBUG_L4PER_FD_TRANS_OFFSET 0x00e4 +#define OMAP54XX_CM_CORE_AON_DEBUG_L4PER_FD_TRANS2_OFFSET 0x00e8 +#define OMAP54XX_CM_CORE_AON_DEBUG_L4SEC_FD_TRANS_OFFSET 0x00ec +#define OMAP54XX_CM_CORE_AON_DEBUG_MIPIEXT_FD_TRANS_OFFSET 0x00f0 + +/* CM_CORE_AON.CKGEN_CM_CORE_AON register offsets */ +#define OMAP54XX_CM_CLKSEL_CORE_OFFSET 0x0000 +#define OMAP54XX_CM_CLKSEL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0000) +#define OMAP54XX_CM_CLKSEL_ABE_OFFSET 0x0008 +#define OMAP54XX_CM_CLKSEL_ABE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0008) +#define OMAP54XX_CM_DLL_CTRL_OFFSET 0x0010 +#define OMAP54XX_CM_CLKMODE_DPLL_CORE_OFFSET 0x0020 +#define OMAP54XX_CM_CLKMODE_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0020) +#define OMAP54XX_CM_IDLEST_DPLL_CORE_OFFSET 0x0024 +#define OMAP54XX_CM_IDLEST_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0024) +#define OMAP54XX_CM_AUTOIDLE_DPLL_CORE_OFFSET 0x0028 +#define OMAP54XX_CM_AUTOIDLE_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0028) +#define OMAP54XX_CM_CLKSEL_DPLL_CORE_OFFSET 0x002c +#define OMAP54XX_CM_CLKSEL_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x002c) +#define OMAP54XX_CM_DIV_M2_DPLL_CORE_OFFSET 0x0030 +#define OMAP54XX_CM_DIV_M2_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0030) +#define OMAP54XX_CM_DIV_M3_DPLL_CORE_OFFSET 0x0034 +#define OMAP54XX_CM_DIV_M3_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0034) +#define OMAP54XX_CM_DIV_H11_DPLL_CORE_OFFSET 0x0038 +#define OMAP54XX_CM_DIV_H11_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0038) +#define OMAP54XX_CM_DIV_H12_DPLL_CORE_OFFSET 0x003c +#define OMAP54XX_CM_DIV_H12_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x003c) +#define OMAP54XX_CM_DIV_H13_DPLL_CORE_OFFSET 0x0040 +#define OMAP54XX_CM_DIV_H13_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0040) +#define OMAP54XX_CM_DIV_H14_DPLL_CORE_OFFSET 0x0044 +#define OMAP54XX_CM_DIV_H14_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0044) +#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_CORE_OFFSET 0x0048 +#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_CORE_OFFSET 0x004c +#define OMAP54XX_CM_DIV_H21_DPLL_CORE_OFFSET 0x0050 +#define OMAP54XX_CM_DIV_H21_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0050) +#define OMAP54XX_CM_DIV_H22_DPLL_CORE_OFFSET 0x0054 +#define OMAP54XX_CM_DIV_H22_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0054) +#define OMAP54XX_CM_DIV_H23_DPLL_CORE_OFFSET 0x0058 +#define OMAP54XX_CM_DIV_H23_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0058) +#define OMAP54XX_CM_DIV_H24_DPLL_CORE_OFFSET 0x005c +#define OMAP54XX_CM_DIV_H24_DPLL_CORE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x005c) +#define OMAP54XX_CM_CLKMODE_DPLL_MPU_OFFSET 0x0060 +#define OMAP54XX_CM_CLKMODE_DPLL_MPU OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0060) +#define OMAP54XX_CM_IDLEST_DPLL_MPU_OFFSET 0x0064 +#define OMAP54XX_CM_IDLEST_DPLL_MPU OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0064) +#define OMAP54XX_CM_AUTOIDLE_DPLL_MPU_OFFSET 0x0068 +#define OMAP54XX_CM_AUTOIDLE_DPLL_MPU OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0068) +#define OMAP54XX_CM_CLKSEL_DPLL_MPU_OFFSET 0x006c +#define OMAP54XX_CM_CLKSEL_DPLL_MPU OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x006c) +#define OMAP54XX_CM_DIV_M2_DPLL_MPU_OFFSET 0x0070 +#define OMAP54XX_CM_DIV_M2_DPLL_MPU OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0070) +#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_MPU_OFFSET 0x0088 +#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_MPU_OFFSET 0x008c +#define OMAP54XX_CM_BYPCLK_DPLL_MPU_OFFSET 0x009c +#define OMAP54XX_CM_BYPCLK_DPLL_MPU OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x009c) +#define OMAP54XX_CM_CLKMODE_DPLL_IVA_OFFSET 0x00a0 +#define OMAP54XX_CM_CLKMODE_DPLL_IVA OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00a0) +#define OMAP54XX_CM_IDLEST_DPLL_IVA_OFFSET 0x00a4 +#define OMAP54XX_CM_IDLEST_DPLL_IVA OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00a4) +#define OMAP54XX_CM_AUTOIDLE_DPLL_IVA_OFFSET 0x00a8 +#define OMAP54XX_CM_AUTOIDLE_DPLL_IVA OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00a8) +#define OMAP54XX_CM_CLKSEL_DPLL_IVA_OFFSET 0x00ac +#define OMAP54XX_CM_CLKSEL_DPLL_IVA OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00ac) +#define OMAP54XX_CM_DIV_H11_DPLL_IVA_OFFSET 0x00b8 +#define OMAP54XX_CM_DIV_H11_DPLL_IVA OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00b8) +#define OMAP54XX_CM_DIV_H12_DPLL_IVA_OFFSET 0x00bc +#define OMAP54XX_CM_DIV_H12_DPLL_IVA OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00bc) +#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_IVA_OFFSET 0x00c8 +#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_IVA_OFFSET 0x00cc +#define OMAP54XX_CM_BYPCLK_DPLL_IVA_OFFSET 0x00dc +#define OMAP54XX_CM_BYPCLK_DPLL_IVA OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00dc) +#define OMAP54XX_CM_CLKMODE_DPLL_ABE_OFFSET 0x00e0 +#define OMAP54XX_CM_CLKMODE_DPLL_ABE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00e0) +#define OMAP54XX_CM_IDLEST_DPLL_ABE_OFFSET 0x00e4 +#define OMAP54XX_CM_IDLEST_DPLL_ABE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00e4) +#define OMAP54XX_CM_AUTOIDLE_DPLL_ABE_OFFSET 0x00e8 +#define OMAP54XX_CM_AUTOIDLE_DPLL_ABE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00e8) +#define OMAP54XX_CM_CLKSEL_DPLL_ABE_OFFSET 0x00ec +#define OMAP54XX_CM_CLKSEL_DPLL_ABE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00ec) +#define OMAP54XX_CM_DIV_M2_DPLL_ABE_OFFSET 0x00f0 +#define OMAP54XX_CM_DIV_M2_DPLL_ABE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00f0) +#define OMAP54XX_CM_DIV_M3_DPLL_ABE_OFFSET 0x00f4 +#define OMAP54XX_CM_DIV_M3_DPLL_ABE OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00f4) +#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_ABE_OFFSET 0x0108 +#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_ABE_OFFSET 0x010c +#define OMAP54XX_CM_SHADOW_FREQ_CONFIG1_OFFSET 0x0160 +#define OMAP54XX_CM_SHADOW_FREQ_CONFIG2_OFFSET 0x0164 +#define OMAP54XX_CM_DYN_DEP_PRESCAL_OFFSET 0x0170 +#define OMAP54XX_CM_RESTORE_ST_OFFSET 0x0180 + +/* CM_CORE_AON.MPU_CM_CORE_AON register offsets */ +#define OMAP54XX_CM_MPU_CLKSTCTRL_OFFSET 0x0000 +#define OMAP54XX_CM_MPU_STATICDEP_OFFSET 0x0004 +#define OMAP54XX_CM_MPU_DYNAMICDEP_OFFSET 0x0008 +#define OMAP54XX_CM_MPU_MPU_CLKCTRL_OFFSET 0x0020 +#define OMAP54XX_CM_MPU_MPU_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_MPU_INST, 0x0020) +#define OMAP54XX_CM_MPU_MPU_MPU_DBG_CLKCTRL_OFFSET 0x0028 +#define OMAP54XX_CM_MPU_MPU_MPU_DBG_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_MPU_INST, 0x0028) + +/* CM_CORE_AON.DSP_CM_CORE_AON register offsets */ +#define OMAP54XX_CM_DSP_CLKSTCTRL_OFFSET 0x0000 +#define OMAP54XX_CM_DSP_STATICDEP_OFFSET 0x0004 +#define OMAP54XX_CM_DSP_DYNAMICDEP_OFFSET 0x0008 +#define OMAP54XX_CM_DSP_DSP_CLKCTRL_OFFSET 0x0020 +#define OMAP54XX_CM_DSP_DSP_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_DSP_INST, 0x0020) + +/* CM_CORE_AON.ABE_CM_CORE_AON register offsets */ +#define OMAP54XX_CM_ABE_CLKSTCTRL_OFFSET 0x0000 +#define OMAP54XX_CM_ABE_L4_ABE_CLKCTRL_OFFSET 0x0020 +#define OMAP54XX_CM_ABE_L4_ABE_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0020) +#define OMAP54XX_CM_ABE_AESS_CLKCTRL_OFFSET 0x0028 +#define OMAP54XX_CM_ABE_AESS_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0028) +#define OMAP54XX_CM_ABE_MCPDM_CLKCTRL_OFFSET 0x0030 +#define OMAP54XX_CM_ABE_MCPDM_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0030) +#define OMAP54XX_CM_ABE_DMIC_CLKCTRL_OFFSET 0x0038 +#define OMAP54XX_CM_ABE_DMIC_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0038) +#define OMAP54XX_CM_ABE_MCASP_CLKCTRL_OFFSET 0x0040 +#define OMAP54XX_CM_ABE_MCASP_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0040) +#define OMAP54XX_CM_ABE_MCBSP1_CLKCTRL_OFFSET 0x0048 +#define OMAP54XX_CM_ABE_MCBSP1_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0048) +#define OMAP54XX_CM_ABE_MCBSP2_CLKCTRL_OFFSET 0x0050 +#define OMAP54XX_CM_ABE_MCBSP2_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0050) +#define OMAP54XX_CM_ABE_MCBSP3_CLKCTRL_OFFSET 0x0058 +#define OMAP54XX_CM_ABE_MCBSP3_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0058) +#define OMAP54XX_CM_ABE_SLIMBUS1_CLKCTRL_OFFSET 0x0060 +#define OMAP54XX_CM_ABE_SLIMBUS1_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0060) +#define OMAP54XX_CM_ABE_TIMER5_CLKCTRL_OFFSET 0x0068 +#define OMAP54XX_CM_ABE_TIMER5_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0068) +#define OMAP54XX_CM_ABE_TIMER6_CLKCTRL_OFFSET 0x0070 +#define OMAP54XX_CM_ABE_TIMER6_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0070) +#define OMAP54XX_CM_ABE_TIMER7_CLKCTRL_OFFSET 0x0078 +#define OMAP54XX_CM_ABE_TIMER7_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0078) +#define OMAP54XX_CM_ABE_TIMER8_CLKCTRL_OFFSET 0x0080 +#define OMAP54XX_CM_ABE_TIMER8_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0080) +#define OMAP54XX_CM_ABE_WD_TIMER3_CLKCTRL_OFFSET 0x0088 +#define OMAP54XX_CM_ABE_WD_TIMER3_CLKCTRL OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0088) + +#endif diff --git a/arch/arm/mach-omap2/cm1_7xx.h b/arch/arm/mach-omap2/cm1_7xx.h new file mode 100644 index 00000000000..ca6fa1febaa --- /dev/null +++ b/arch/arm/mach-omap2/cm1_7xx.h @@ -0,0 +1,324 @@ +/* + * DRA7xx CM1 instance offset macros + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * + * Generated by code originally written by: + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CM1_7XX_H +#define __ARCH_ARM_MACH_OMAP2_CM1_7XX_H + +#include "cm_44xx_54xx.h" + +/* CM1 base address */ +#define DRA7XX_CM_CORE_AON_BASE 0x4a005000 + +#define DRA7XX_CM_CORE_AON_REGADDR(inst, reg) \ + OMAP2_L4_IO_ADDRESS(DRA7XX_CM_CORE_AON_BASE + (inst) + (reg)) + +/* CM_CORE_AON instances */ +#define DRA7XX_CM_CORE_AON_OCP_SOCKET_INST 0x0000 +#define DRA7XX_CM_CORE_AON_CKGEN_INST 0x0100 +#define DRA7XX_CM_CORE_AON_MPU_INST 0x0300 +#define DRA7XX_CM_CORE_AON_DSP1_INST 0x0400 +#define DRA7XX_CM_CORE_AON_IPU_INST 0x0500 +#define DRA7XX_CM_CORE_AON_DSP2_INST 0x0600 +#define DRA7XX_CM_CORE_AON_EVE1_INST 0x0640 +#define DRA7XX_CM_CORE_AON_EVE2_INST 0x0680 +#define DRA7XX_CM_CORE_AON_EVE3_INST 0x06c0 +#define DRA7XX_CM_CORE_AON_EVE4_INST 0x0700 +#define DRA7XX_CM_CORE_AON_RTC_INST 0x0740 +#define DRA7XX_CM_CORE_AON_VPE_INST 0x0760 +#define DRA7XX_CM_CORE_AON_RESTORE_INST 0x0e00 +#define DRA7XX_CM_CORE_AON_INSTR_INST 0x0f00 + +/* CM_CORE_AON clockdomain register offsets (from instance start) */ +#define DRA7XX_CM_CORE_AON_MPU_MPU_CDOFFS 0x0000 +#define DRA7XX_CM_CORE_AON_DSP1_DSP1_CDOFFS 0x0000 +#define DRA7XX_CM_CORE_AON_IPU_IPU1_CDOFFS 0x0000 +#define DRA7XX_CM_CORE_AON_IPU_IPU_CDOFFS 0x0040 +#define DRA7XX_CM_CORE_AON_DSP2_DSP2_CDOFFS 0x0000 +#define DRA7XX_CM_CORE_AON_EVE1_EVE1_CDOFFS 0x0000 +#define DRA7XX_CM_CORE_AON_EVE2_EVE2_CDOFFS 0x0000 +#define DRA7XX_CM_CORE_AON_EVE3_EVE3_CDOFFS 0x0000 +#define DRA7XX_CM_CORE_AON_EVE4_EVE4_CDOFFS 0x0000 +#define DRA7XX_CM_CORE_AON_RTC_RTC_CDOFFS 0x0000 +#define DRA7XX_CM_CORE_AON_VPE_VPE_CDOFFS 0x0000 + +/* CM_CORE_AON */ + +/* CM_CORE_AON.OCP_SOCKET_CM_CORE_AON register offsets */ +#define DRA7XX_REVISION_CM_CORE_AON_OFFSET 0x0000 +#define DRA7XX_CM_CM_CORE_AON_PROFILING_CLKCTRL_OFFSET 0x0040 +#define DRA7XX_CM_CM_CORE_AON_PROFILING_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_OCP_SOCKET_INST, 0x0040) +#define DRA7XX_CM_CORE_AON_DEBUG_OUT_OFFSET 0x00ec +#define DRA7XX_CM_CORE_AON_DEBUG_CFG0_OFFSET 0x00f0 +#define DRA7XX_CM_CORE_AON_DEBUG_CFG1_OFFSET 0x00f4 +#define DRA7XX_CM_CORE_AON_DEBUG_CFG2_OFFSET 0x00f8 +#define DRA7XX_CM_CORE_AON_DEBUG_CFG3_OFFSET 0x00fc + +/* CM_CORE_AON.CKGEN_CM_CORE_AON register offsets */ +#define DRA7XX_CM_CLKSEL_CORE_OFFSET 0x0000 +#define DRA7XX_CM_CLKSEL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0000) +#define DRA7XX_CM_CLKSEL_ABE_OFFSET 0x0008 +#define DRA7XX_CM_CLKSEL_ABE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0008) +#define DRA7XX_CM_DLL_CTRL_OFFSET 0x0010 +#define DRA7XX_CM_CLKMODE_DPLL_CORE_OFFSET 0x0020 +#define DRA7XX_CM_CLKMODE_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0020) +#define DRA7XX_CM_IDLEST_DPLL_CORE_OFFSET 0x0024 +#define DRA7XX_CM_IDLEST_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0024) +#define DRA7XX_CM_AUTOIDLE_DPLL_CORE_OFFSET 0x0028 +#define DRA7XX_CM_AUTOIDLE_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0028) +#define DRA7XX_CM_CLKSEL_DPLL_CORE_OFFSET 0x002c +#define DRA7XX_CM_CLKSEL_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x002c) +#define DRA7XX_CM_DIV_M2_DPLL_CORE_OFFSET 0x0030 +#define DRA7XX_CM_DIV_M2_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0030) +#define DRA7XX_CM_DIV_M3_DPLL_CORE_OFFSET 0x0034 +#define DRA7XX_CM_DIV_M3_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0034) +#define DRA7XX_CM_DIV_H11_DPLL_CORE_OFFSET 0x0038 +#define DRA7XX_CM_DIV_H11_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0038) +#define DRA7XX_CM_DIV_H12_DPLL_CORE_OFFSET 0x003c +#define DRA7XX_CM_DIV_H12_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x003c) +#define DRA7XX_CM_DIV_H13_DPLL_CORE_OFFSET 0x0040 +#define DRA7XX_CM_DIV_H13_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0040) +#define DRA7XX_CM_DIV_H14_DPLL_CORE_OFFSET 0x0044 +#define DRA7XX_CM_DIV_H14_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0044) +#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_CORE_OFFSET 0x0048 +#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_CORE_OFFSET 0x004c +#define DRA7XX_CM_DIV_H21_DPLL_CORE_OFFSET 0x0050 +#define DRA7XX_CM_DIV_H21_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0050) +#define DRA7XX_CM_DIV_H22_DPLL_CORE_OFFSET 0x0054 +#define DRA7XX_CM_DIV_H22_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0054) +#define DRA7XX_CM_DIV_H23_DPLL_CORE_OFFSET 0x0058 +#define DRA7XX_CM_DIV_H23_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0058) +#define DRA7XX_CM_DIV_H24_DPLL_CORE_OFFSET 0x005c +#define DRA7XX_CM_DIV_H24_DPLL_CORE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x005c) +#define DRA7XX_CM_CLKMODE_DPLL_MPU_OFFSET 0x0060 +#define DRA7XX_CM_CLKMODE_DPLL_MPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0060) +#define DRA7XX_CM_IDLEST_DPLL_MPU_OFFSET 0x0064 +#define DRA7XX_CM_IDLEST_DPLL_MPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0064) +#define DRA7XX_CM_AUTOIDLE_DPLL_MPU_OFFSET 0x0068 +#define DRA7XX_CM_AUTOIDLE_DPLL_MPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0068) +#define DRA7XX_CM_CLKSEL_DPLL_MPU_OFFSET 0x006c +#define DRA7XX_CM_CLKSEL_DPLL_MPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x006c) +#define DRA7XX_CM_DIV_M2_DPLL_MPU_OFFSET 0x0070 +#define DRA7XX_CM_DIV_M2_DPLL_MPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0070) +#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_MPU_OFFSET 0x0088 +#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_MPU_OFFSET 0x008c +#define DRA7XX_CM_BYPCLK_DPLL_MPU_OFFSET 0x009c +#define DRA7XX_CM_BYPCLK_DPLL_MPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x009c) +#define DRA7XX_CM_CLKMODE_DPLL_IVA_OFFSET 0x00a0 +#define DRA7XX_CM_CLKMODE_DPLL_IVA DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00a0) +#define DRA7XX_CM_IDLEST_DPLL_IVA_OFFSET 0x00a4 +#define DRA7XX_CM_IDLEST_DPLL_IVA DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00a4) +#define DRA7XX_CM_AUTOIDLE_DPLL_IVA_OFFSET 0x00a8 +#define DRA7XX_CM_AUTOIDLE_DPLL_IVA DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00a8) +#define DRA7XX_CM_CLKSEL_DPLL_IVA_OFFSET 0x00ac +#define DRA7XX_CM_CLKSEL_DPLL_IVA DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00ac) +#define DRA7XX_CM_DIV_M2_DPLL_IVA_OFFSET 0x00b0 +#define DRA7XX_CM_DIV_M2_DPLL_IVA DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00b0) +#define DRA7XX_CM_DIV_M3_DPLL_IVA_OFFSET 0x00b4 +#define DRA7XX_CM_DIV_M3_DPLL_IVA DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00b4) +#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_IVA_OFFSET 0x00c8 +#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_IVA_OFFSET 0x00cc +#define DRA7XX_CM_BYPCLK_DPLL_IVA_OFFSET 0x00dc +#define DRA7XX_CM_BYPCLK_DPLL_IVA DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00dc) +#define DRA7XX_CM_CLKMODE_DPLL_ABE_OFFSET 0x00e0 +#define DRA7XX_CM_CLKMODE_DPLL_ABE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00e0) +#define DRA7XX_CM_IDLEST_DPLL_ABE_OFFSET 0x00e4 +#define DRA7XX_CM_IDLEST_DPLL_ABE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00e4) +#define DRA7XX_CM_AUTOIDLE_DPLL_ABE_OFFSET 0x00e8 +#define DRA7XX_CM_AUTOIDLE_DPLL_ABE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00e8) +#define DRA7XX_CM_CLKSEL_DPLL_ABE_OFFSET 0x00ec +#define DRA7XX_CM_CLKSEL_DPLL_ABE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00ec) +#define DRA7XX_CM_DIV_M2_DPLL_ABE_OFFSET 0x00f0 +#define DRA7XX_CM_DIV_M2_DPLL_ABE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00f0) +#define DRA7XX_CM_DIV_M3_DPLL_ABE_OFFSET 0x00f4 +#define DRA7XX_CM_DIV_M3_DPLL_ABE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x00f4) +#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_ABE_OFFSET 0x0108 +#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_ABE_OFFSET 0x010c +#define DRA7XX_CM_CLKMODE_DPLL_DDR_OFFSET 0x0110 +#define DRA7XX_CM_CLKMODE_DPLL_DDR DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0110) +#define DRA7XX_CM_IDLEST_DPLL_DDR_OFFSET 0x0114 +#define DRA7XX_CM_IDLEST_DPLL_DDR DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0114) +#define DRA7XX_CM_AUTOIDLE_DPLL_DDR_OFFSET 0x0118 +#define DRA7XX_CM_AUTOIDLE_DPLL_DDR DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0118) +#define DRA7XX_CM_CLKSEL_DPLL_DDR_OFFSET 0x011c +#define DRA7XX_CM_CLKSEL_DPLL_DDR DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x011c) +#define DRA7XX_CM_DIV_M2_DPLL_DDR_OFFSET 0x0120 +#define DRA7XX_CM_DIV_M2_DPLL_DDR DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0120) +#define DRA7XX_CM_DIV_M3_DPLL_DDR_OFFSET 0x0124 +#define DRA7XX_CM_DIV_M3_DPLL_DDR DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0124) +#define DRA7XX_CM_DIV_H11_DPLL_DDR_OFFSET 0x0128 +#define DRA7XX_CM_DIV_H11_DPLL_DDR DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0128) +#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_DDR_OFFSET 0x012c +#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_DDR_OFFSET 0x0130 +#define DRA7XX_CM_CLKMODE_DPLL_DSP_OFFSET 0x0134 +#define DRA7XX_CM_CLKMODE_DPLL_DSP DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0134) +#define DRA7XX_CM_IDLEST_DPLL_DSP_OFFSET 0x0138 +#define DRA7XX_CM_IDLEST_DPLL_DSP DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0138) +#define DRA7XX_CM_AUTOIDLE_DPLL_DSP_OFFSET 0x013c +#define DRA7XX_CM_AUTOIDLE_DPLL_DSP DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x013c) +#define DRA7XX_CM_CLKSEL_DPLL_DSP_OFFSET 0x0140 +#define DRA7XX_CM_CLKSEL_DPLL_DSP DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0140) +#define DRA7XX_CM_DIV_M2_DPLL_DSP_OFFSET 0x0144 +#define DRA7XX_CM_DIV_M2_DPLL_DSP DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0144) +#define DRA7XX_CM_DIV_M3_DPLL_DSP_OFFSET 0x0148 +#define DRA7XX_CM_DIV_M3_DPLL_DSP DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0148) +#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_DSP_OFFSET 0x014c +#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_DSP_OFFSET 0x0150 +#define DRA7XX_CM_BYPCLK_DPLL_DSP_OFFSET 0x0154 +#define DRA7XX_CM_BYPCLK_DPLL_DSP DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0154) +#define DRA7XX_CM_SHADOW_FREQ_CONFIG1_OFFSET 0x0160 +#define DRA7XX_CM_SHADOW_FREQ_CONFIG2_OFFSET 0x0164 +#define DRA7XX_CM_DYN_DEP_PRESCAL_OFFSET 0x0170 +#define DRA7XX_CM_RESTORE_ST_OFFSET 0x0180 +#define DRA7XX_CM_CLKMODE_DPLL_EVE_OFFSET 0x0184 +#define DRA7XX_CM_CLKMODE_DPLL_EVE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0184) +#define DRA7XX_CM_IDLEST_DPLL_EVE_OFFSET 0x0188 +#define DRA7XX_CM_IDLEST_DPLL_EVE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0188) +#define DRA7XX_CM_AUTOIDLE_DPLL_EVE_OFFSET 0x018c +#define DRA7XX_CM_AUTOIDLE_DPLL_EVE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x018c) +#define DRA7XX_CM_CLKSEL_DPLL_EVE_OFFSET 0x0190 +#define DRA7XX_CM_CLKSEL_DPLL_EVE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0190) +#define DRA7XX_CM_DIV_M2_DPLL_EVE_OFFSET 0x0194 +#define DRA7XX_CM_DIV_M2_DPLL_EVE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0194) +#define DRA7XX_CM_DIV_M3_DPLL_EVE_OFFSET 0x0198 +#define DRA7XX_CM_DIV_M3_DPLL_EVE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x0198) +#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_EVE_OFFSET 0x019c +#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_EVE_OFFSET 0x01a0 +#define DRA7XX_CM_BYPCLK_DPLL_EVE_OFFSET 0x01a4 +#define DRA7XX_CM_BYPCLK_DPLL_EVE DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01a4) +#define DRA7XX_CM_CLKMODE_DPLL_GMAC_OFFSET 0x01a8 +#define DRA7XX_CM_CLKMODE_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01a8) +#define DRA7XX_CM_IDLEST_DPLL_GMAC_OFFSET 0x01ac +#define DRA7XX_CM_IDLEST_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01ac) +#define DRA7XX_CM_AUTOIDLE_DPLL_GMAC_OFFSET 0x01b0 +#define DRA7XX_CM_AUTOIDLE_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01b0) +#define DRA7XX_CM_CLKSEL_DPLL_GMAC_OFFSET 0x01b4 +#define DRA7XX_CM_CLKSEL_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01b4) +#define DRA7XX_CM_DIV_M2_DPLL_GMAC_OFFSET 0x01b8 +#define DRA7XX_CM_DIV_M2_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01b8) +#define DRA7XX_CM_DIV_M3_DPLL_GMAC_OFFSET 0x01bc +#define DRA7XX_CM_DIV_M3_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01bc) +#define DRA7XX_CM_DIV_H11_DPLL_GMAC_OFFSET 0x01c0 +#define DRA7XX_CM_DIV_H11_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01c0) +#define DRA7XX_CM_DIV_H12_DPLL_GMAC_OFFSET 0x01c4 +#define DRA7XX_CM_DIV_H12_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01c4) +#define DRA7XX_CM_DIV_H13_DPLL_GMAC_OFFSET 0x01c8 +#define DRA7XX_CM_DIV_H13_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01c8) +#define DRA7XX_CM_DIV_H14_DPLL_GMAC_OFFSET 0x01cc +#define DRA7XX_CM_DIV_H14_DPLL_GMAC DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01cc) +#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_GMAC_OFFSET 0x01d0 +#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_GMAC_OFFSET 0x01d4 +#define DRA7XX_CM_CLKMODE_DPLL_GPU_OFFSET 0x01d8 +#define DRA7XX_CM_CLKMODE_DPLL_GPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01d8) +#define DRA7XX_CM_IDLEST_DPLL_GPU_OFFSET 0x01dc +#define DRA7XX_CM_IDLEST_DPLL_GPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01dc) +#define DRA7XX_CM_AUTOIDLE_DPLL_GPU_OFFSET 0x01e0 +#define DRA7XX_CM_AUTOIDLE_DPLL_GPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01e0) +#define DRA7XX_CM_CLKSEL_DPLL_GPU_OFFSET 0x01e4 +#define DRA7XX_CM_CLKSEL_DPLL_GPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01e4) +#define DRA7XX_CM_DIV_M2_DPLL_GPU_OFFSET 0x01e8 +#define DRA7XX_CM_DIV_M2_DPLL_GPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01e8) +#define DRA7XX_CM_DIV_M3_DPLL_GPU_OFFSET 0x01ec +#define DRA7XX_CM_DIV_M3_DPLL_GPU DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_CKGEN_INST, 0x01ec) +#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_GPU_OFFSET 0x01f0 +#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_GPU_OFFSET 0x01f4 + +/* CM_CORE_AON.MPU_CM_CORE_AON register offsets */ +#define DRA7XX_CM_MPU_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_MPU_STATICDEP_OFFSET 0x0004 +#define DRA7XX_CM_MPU_DYNAMICDEP_OFFSET 0x0008 +#define DRA7XX_CM_MPU_MPU_CLKCTRL_OFFSET 0x0020 +#define DRA7XX_CM_MPU_MPU_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_MPU_INST, 0x0020) +#define DRA7XX_CM_MPU_MPU_MPU_DBG_CLKCTRL_OFFSET 0x0028 +#define DRA7XX_CM_MPU_MPU_MPU_DBG_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_MPU_INST, 0x0028) + +/* CM_CORE_AON.DSP1_CM_CORE_AON register offsets */ +#define DRA7XX_CM_DSP1_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_DSP1_STATICDEP_OFFSET 0x0004 +#define DRA7XX_CM_DSP1_DYNAMICDEP_OFFSET 0x0008 +#define DRA7XX_CM_DSP1_DSP1_CLKCTRL_OFFSET 0x0020 +#define DRA7XX_CM_DSP1_DSP1_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_DSP1_INST, 0x0020) + +/* CM_CORE_AON.IPU_CM_CORE_AON register offsets */ +#define DRA7XX_CM_IPU1_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_IPU1_STATICDEP_OFFSET 0x0004 +#define DRA7XX_CM_IPU1_DYNAMICDEP_OFFSET 0x0008 +#define DRA7XX_CM_IPU1_IPU1_CLKCTRL_OFFSET 0x0020 +#define DRA7XX_CM_IPU1_IPU1_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_IPU_INST, 0x0020) +#define DRA7XX_CM_IPU_CLKSTCTRL_OFFSET 0x0040 +#define DRA7XX_CM_IPU_MCASP1_CLKCTRL_OFFSET 0x0050 +#define DRA7XX_CM_IPU_MCASP1_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_IPU_INST, 0x0050) +#define DRA7XX_CM_IPU_TIMER5_CLKCTRL_OFFSET 0x0058 +#define DRA7XX_CM_IPU_TIMER5_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_IPU_INST, 0x0058) +#define DRA7XX_CM_IPU_TIMER6_CLKCTRL_OFFSET 0x0060 +#define DRA7XX_CM_IPU_TIMER6_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_IPU_INST, 0x0060) +#define DRA7XX_CM_IPU_TIMER7_CLKCTRL_OFFSET 0x0068 +#define DRA7XX_CM_IPU_TIMER7_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_IPU_INST, 0x0068) +#define DRA7XX_CM_IPU_TIMER8_CLKCTRL_OFFSET 0x0070 +#define DRA7XX_CM_IPU_TIMER8_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_IPU_INST, 0x0070) +#define DRA7XX_CM_IPU_I2C5_CLKCTRL_OFFSET 0x0078 +#define DRA7XX_CM_IPU_I2C5_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_IPU_INST, 0x0078) +#define DRA7XX_CM_IPU_UART6_CLKCTRL_OFFSET 0x0080 +#define DRA7XX_CM_IPU_UART6_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_IPU_INST, 0x0080) + +/* CM_CORE_AON.DSP2_CM_CORE_AON register offsets */ +#define DRA7XX_CM_DSP2_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_DSP2_STATICDEP_OFFSET 0x0004 +#define DRA7XX_CM_DSP2_DYNAMICDEP_OFFSET 0x0008 +#define DRA7XX_CM_DSP2_DSP2_CLKCTRL_OFFSET 0x0020 +#define DRA7XX_CM_DSP2_DSP2_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_DSP2_INST, 0x0020) + +/* CM_CORE_AON.EVE1_CM_CORE_AON register offsets */ +#define DRA7XX_CM_EVE1_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_EVE1_STATICDEP_OFFSET 0x0004 +#define DRA7XX_CM_EVE1_EVE1_CLKCTRL_OFFSET 0x0020 +#define DRA7XX_CM_EVE1_EVE1_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_EVE1_INST, 0x0020) + +/* CM_CORE_AON.EVE2_CM_CORE_AON register offsets */ +#define DRA7XX_CM_EVE2_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_EVE2_STATICDEP_OFFSET 0x0004 +#define DRA7XX_CM_EVE2_EVE2_CLKCTRL_OFFSET 0x0020 +#define DRA7XX_CM_EVE2_EVE2_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_EVE2_INST, 0x0020) + +/* CM_CORE_AON.EVE3_CM_CORE_AON register offsets */ +#define DRA7XX_CM_EVE3_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_EVE3_STATICDEP_OFFSET 0x0004 +#define DRA7XX_CM_EVE3_EVE3_CLKCTRL_OFFSET 0x0020 +#define DRA7XX_CM_EVE3_EVE3_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_EVE3_INST, 0x0020) + +/* CM_CORE_AON.EVE4_CM_CORE_AON register offsets */ +#define DRA7XX_CM_EVE4_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_EVE4_STATICDEP_OFFSET 0x0004 +#define DRA7XX_CM_EVE4_EVE4_CLKCTRL_OFFSET 0x0020 +#define DRA7XX_CM_EVE4_EVE4_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_EVE4_INST, 0x0020) + +/* CM_CORE_AON.RTC_CM_CORE_AON register offsets */ +#define DRA7XX_CM_RTC_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_RTC_RTCSS_CLKCTRL_OFFSET 0x0004 +#define DRA7XX_CM_RTC_RTCSS_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_RTC_INST, 0x0004) + +/* CM_CORE_AON.VPE_CM_CORE_AON register offsets */ +#define DRA7XX_CM_VPE_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_VPE_VPE_CLKCTRL_OFFSET 0x0004 +#define DRA7XX_CM_VPE_VPE_CLKCTRL DRA7XX_CM_CORE_AON_REGADDR(DRA7XX_CM_CORE_AON_VPE_INST, 0x0004) +#define DRA7XX_CM_VPE_STATICDEP_OFFSET 0x0008 + +#endif diff --git a/arch/arm/mach-omap2/cm2_44xx.h b/arch/arm/mach-omap2/cm2_44xx.h new file mode 100644 index 00000000000..ee5136d7cdd --- /dev/null +++ b/arch/arm/mach-omap2/cm2_44xx.h @@ -0,0 +1,454 @@ +/* + * OMAP44xx CM2 instance offset macros + * + * Copyright (C) 2009-2011 Texas Instruments, Inc. + * Copyright (C) 2009-2010 Nokia Corporation + * + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * XXX This file needs to be updated to align on one of "OMAP4", "OMAP44XX", + * or "OMAP4430". + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CM2_44XX_H +#define __ARCH_ARM_MACH_OMAP2_CM2_44XX_H + +#include "cm_44xx_54xx.h" + +/* CM2 base address */ +#define OMAP4430_CM2_BASE 0x4a008000 + +#define OMAP44XX_CM2_REGADDR(inst, reg) \ + OMAP2_L4_IO_ADDRESS(OMAP4430_CM2_BASE + (inst) + (reg)) + +/* CM2 instances */ +#define OMAP4430_CM2_OCP_SOCKET_INST 0x0000 +#define OMAP4430_CM2_CKGEN_INST 0x0100 +#define OMAP4430_CM2_ALWAYS_ON_INST 0x0600 +#define OMAP4430_CM2_CORE_INST 0x0700 +#define OMAP4430_CM2_IVAHD_INST 0x0f00 +#define OMAP4430_CM2_CAM_INST 0x1000 +#define OMAP4430_CM2_DSS_INST 0x1100 +#define OMAP4430_CM2_GFX_INST 0x1200 +#define OMAP4430_CM2_L3INIT_INST 0x1300 +#define OMAP4430_CM2_L4PER_INST 0x1400 +#define OMAP4430_CM2_CEFUSE_INST 0x1600 +#define OMAP4430_CM2_RESTORE_INST 0x1e00 +#define OMAP4430_CM2_INSTR_INST 0x1f00 + +/* CM2 clockdomain register offsets (from instance start) */ +#define OMAP4430_CM2_ALWAYS_ON_ALWON_CDOFFS 0x0000 +#define OMAP4430_CM2_CORE_L3_1_CDOFFS 0x0000 +#define OMAP4430_CM2_CORE_L3_2_CDOFFS 0x0100 +#define OMAP4430_CM2_CORE_DUCATI_CDOFFS 0x0200 +#define OMAP4430_CM2_CORE_SDMA_CDOFFS 0x0300 +#define OMAP4430_CM2_CORE_MEMIF_CDOFFS 0x0400 +#define OMAP4430_CM2_CORE_D2D_CDOFFS 0x0500 +#define OMAP4430_CM2_CORE_L4CFG_CDOFFS 0x0600 +#define OMAP4430_CM2_CORE_L3INSTR_CDOFFS 0x0700 +#define OMAP4430_CM2_IVAHD_IVAHD_CDOFFS 0x0000 +#define OMAP4430_CM2_CAM_CAM_CDOFFS 0x0000 +#define OMAP4430_CM2_DSS_DSS_CDOFFS 0x0000 +#define OMAP4430_CM2_GFX_GFX_CDOFFS 0x0000 +#define OMAP4430_CM2_L3INIT_L3INIT_CDOFFS 0x0000 +#define OMAP4430_CM2_L4PER_L4PER_CDOFFS 0x0000 +#define OMAP4430_CM2_L4PER_L4SEC_CDOFFS 0x0180 +#define OMAP4430_CM2_CEFUSE_CEFUSE_CDOFFS 0x0000 + +/* CM2 */ + +/* CM2.OCP_SOCKET_CM2 register offsets */ +#define OMAP4_REVISION_CM2_OFFSET 0x0000 +#define OMAP4430_REVISION_CM2 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_OCP_SOCKET_INST, 0x0000) +#define OMAP4_CM_CM2_PROFILING_CLKCTRL_OFFSET 0x0040 +#define OMAP4430_CM_CM2_PROFILING_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_OCP_SOCKET_INST, 0x0040) + +/* CM2.CKGEN_CM2 register offsets */ +#define OMAP4_CM_CLKSEL_DUCATI_ISS_ROOT_OFFSET 0x0000 +#define OMAP4430_CM_CLKSEL_DUCATI_ISS_ROOT OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0000) +#define OMAP4_CM_CLKSEL_USB_60MHZ_OFFSET 0x0004 +#define OMAP4430_CM_CLKSEL_USB_60MHZ OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0004) +#define OMAP4_CM_SCALE_FCLK_OFFSET 0x0008 +#define OMAP4430_CM_SCALE_FCLK OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0008) +#define OMAP4_CM_CORE_DVFS_PERF1_OFFSET 0x0010 +#define OMAP4430_CM_CORE_DVFS_PERF1 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0010) +#define OMAP4_CM_CORE_DVFS_PERF2_OFFSET 0x0014 +#define OMAP4430_CM_CORE_DVFS_PERF2 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0014) +#define OMAP4_CM_CORE_DVFS_PERF3_OFFSET 0x0018 +#define OMAP4430_CM_CORE_DVFS_PERF3 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0018) +#define OMAP4_CM_CORE_DVFS_PERF4_OFFSET 0x001c +#define OMAP4430_CM_CORE_DVFS_PERF4 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x001c) +#define OMAP4_CM_CORE_DVFS_CURRENT_OFFSET 0x0024 +#define OMAP4430_CM_CORE_DVFS_CURRENT OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0024) +#define OMAP4_CM_IVA_DVFS_PERF_TESLA_OFFSET 0x0028 +#define OMAP4430_CM_IVA_DVFS_PERF_TESLA OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0028) +#define OMAP4_CM_IVA_DVFS_PERF_IVAHD_OFFSET 0x002c +#define OMAP4430_CM_IVA_DVFS_PERF_IVAHD OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x002c) +#define OMAP4_CM_IVA_DVFS_PERF_ABE_OFFSET 0x0030 +#define OMAP4430_CM_IVA_DVFS_PERF_ABE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0030) +#define OMAP4_CM_IVA_DVFS_CURRENT_OFFSET 0x0038 +#define OMAP4430_CM_IVA_DVFS_CURRENT OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0038) +#define OMAP4_CM_CLKMODE_DPLL_PER_OFFSET 0x0040 +#define OMAP4430_CM_CLKMODE_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0040) +#define OMAP4_CM_IDLEST_DPLL_PER_OFFSET 0x0044 +#define OMAP4430_CM_IDLEST_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0044) +#define OMAP4_CM_AUTOIDLE_DPLL_PER_OFFSET 0x0048 +#define OMAP4430_CM_AUTOIDLE_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0048) +#define OMAP4_CM_CLKSEL_DPLL_PER_OFFSET 0x004c +#define OMAP4430_CM_CLKSEL_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x004c) +#define OMAP4_CM_DIV_M2_DPLL_PER_OFFSET 0x0050 +#define OMAP4430_CM_DIV_M2_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0050) +#define OMAP4_CM_DIV_M3_DPLL_PER_OFFSET 0x0054 +#define OMAP4430_CM_DIV_M3_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0054) +#define OMAP4_CM_DIV_M4_DPLL_PER_OFFSET 0x0058 +#define OMAP4430_CM_DIV_M4_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0058) +#define OMAP4_CM_DIV_M5_DPLL_PER_OFFSET 0x005c +#define OMAP4430_CM_DIV_M5_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x005c) +#define OMAP4_CM_DIV_M6_DPLL_PER_OFFSET 0x0060 +#define OMAP4430_CM_DIV_M6_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0060) +#define OMAP4_CM_DIV_M7_DPLL_PER_OFFSET 0x0064 +#define OMAP4430_CM_DIV_M7_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0064) +#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_PER_OFFSET 0x0068 +#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0068) +#define OMAP4_CM_SSC_MODFREQDIV_DPLL_PER_OFFSET 0x006c +#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x006c) +#define OMAP4_CM_CLKMODE_DPLL_USB_OFFSET 0x0080 +#define OMAP4430_CM_CLKMODE_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0080) +#define OMAP4_CM_IDLEST_DPLL_USB_OFFSET 0x0084 +#define OMAP4430_CM_IDLEST_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0084) +#define OMAP4_CM_AUTOIDLE_DPLL_USB_OFFSET 0x0088 +#define OMAP4430_CM_AUTOIDLE_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0088) +#define OMAP4_CM_CLKSEL_DPLL_USB_OFFSET 0x008c +#define OMAP4430_CM_CLKSEL_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x008c) +#define OMAP4_CM_DIV_M2_DPLL_USB_OFFSET 0x0090 +#define OMAP4430_CM_DIV_M2_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0090) +#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_USB_OFFSET 0x00a8 +#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00a8) +#define OMAP4_CM_SSC_MODFREQDIV_DPLL_USB_OFFSET 0x00ac +#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00ac) +#define OMAP4_CM_CLKDCOLDO_DPLL_USB_OFFSET 0x00b4 +#define OMAP4430_CM_CLKDCOLDO_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00b4) +#define OMAP4_CM_CLKMODE_DPLL_UNIPRO_OFFSET 0x00c0 +#define OMAP4430_CM_CLKMODE_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00c0) +#define OMAP4_CM_IDLEST_DPLL_UNIPRO_OFFSET 0x00c4 +#define OMAP4430_CM_IDLEST_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00c4) +#define OMAP4_CM_AUTOIDLE_DPLL_UNIPRO_OFFSET 0x00c8 +#define OMAP4430_CM_AUTOIDLE_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00c8) +#define OMAP4_CM_CLKSEL_DPLL_UNIPRO_OFFSET 0x00cc +#define OMAP4430_CM_CLKSEL_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00cc) +#define OMAP4_CM_DIV_M2_DPLL_UNIPRO_OFFSET 0x00d0 +#define OMAP4430_CM_DIV_M2_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00d0) +#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_UNIPRO_OFFSET 0x00e8 +#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00e8) +#define OMAP4_CM_SSC_MODFREQDIV_DPLL_UNIPRO_OFFSET 0x00ec +#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00ec) + +/* CM2.ALWAYS_ON_CM2 register offsets */ +#define OMAP4_CM_ALWON_CLKSTCTRL_OFFSET 0x0000 +#define OMAP4430_CM_ALWON_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_INST, 0x0000) +#define OMAP4_CM_ALWON_MDMINTC_CLKCTRL_OFFSET 0x0020 +#define OMAP4430_CM_ALWON_MDMINTC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_INST, 0x0020) +#define OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET 0x0028 +#define OMAP4430_CM_ALWON_SR_MPU_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_INST, 0x0028) +#define OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET 0x0030 +#define OMAP4430_CM_ALWON_SR_IVA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_INST, 0x0030) +#define OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET 0x0038 +#define OMAP4430_CM_ALWON_SR_CORE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_INST, 0x0038) +#define OMAP4_CM_ALWON_USBPHY_CLKCTRL_OFFSET 0x0040 +#define OMAP4430_CM_ALWON_USBPHY_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_INST, 0x0040) + +/* CM2.CORE_CM2 register offsets */ +#define OMAP4_CM_L3_1_CLKSTCTRL_OFFSET 0x0000 +#define OMAP4430_CM_L3_1_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0000) +#define OMAP4_CM_L3_1_DYNAMICDEP_OFFSET 0x0008 +#define OMAP4430_CM_L3_1_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0008) +#define OMAP4_CM_L3_1_L3_1_CLKCTRL_OFFSET 0x0020 +#define OMAP4430_CM_L3_1_L3_1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0020) +#define OMAP4_CM_L3_2_CLKSTCTRL_OFFSET 0x0100 +#define OMAP4430_CM_L3_2_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0100) +#define OMAP4_CM_L3_2_DYNAMICDEP_OFFSET 0x0108 +#define OMAP4430_CM_L3_2_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0108) +#define OMAP4_CM_L3_2_L3_2_CLKCTRL_OFFSET 0x0120 +#define OMAP4430_CM_L3_2_L3_2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0120) +#define OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET 0x0128 +#define OMAP4430_CM_L3_2_GPMC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0128) +#define OMAP4_CM_L3_2_OCMC_RAM_CLKCTRL_OFFSET 0x0130 +#define OMAP4430_CM_L3_2_OCMC_RAM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0130) +#define OMAP4_CM_DUCATI_CLKSTCTRL_OFFSET 0x0200 +#define OMAP4430_CM_DUCATI_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0200) +#define OMAP4_CM_DUCATI_STATICDEP_OFFSET 0x0204 +#define OMAP4430_CM_DUCATI_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0204) +#define OMAP4_CM_DUCATI_DYNAMICDEP_OFFSET 0x0208 +#define OMAP4430_CM_DUCATI_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0208) +#define OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET 0x0220 +#define OMAP4430_CM_DUCATI_DUCATI_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0220) +#define OMAP4_CM_SDMA_CLKSTCTRL_OFFSET 0x0300 +#define OMAP4430_CM_SDMA_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0300) +#define OMAP4_CM_SDMA_STATICDEP_OFFSET 0x0304 +#define OMAP4430_CM_SDMA_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0304) +#define OMAP4_CM_SDMA_DYNAMICDEP_OFFSET 0x0308 +#define OMAP4430_CM_SDMA_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0308) +#define OMAP4_CM_SDMA_SDMA_CLKCTRL_OFFSET 0x0320 +#define OMAP4430_CM_SDMA_SDMA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0320) +#define OMAP4_CM_MEMIF_CLKSTCTRL_OFFSET 0x0400 +#define OMAP4430_CM_MEMIF_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0400) +#define OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET 0x0420 +#define OMAP4430_CM_MEMIF_DMM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0420) +#define OMAP4_CM_MEMIF_EMIF_FW_CLKCTRL_OFFSET 0x0428 +#define OMAP4430_CM_MEMIF_EMIF_FW_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0428) +#define OMAP4_CM_MEMIF_EMIF_1_CLKCTRL_OFFSET 0x0430 +#define OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0430) +#define OMAP4_CM_MEMIF_EMIF_2_CLKCTRL_OFFSET 0x0438 +#define OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0438) +#define OMAP4_CM_MEMIF_DLL_CLKCTRL_OFFSET 0x0440 +#define OMAP4430_CM_MEMIF_DLL_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0440) +#define OMAP4_CM_MEMIF_EMIF_H1_CLKCTRL_OFFSET 0x0450 +#define OMAP4430_CM_MEMIF_EMIF_H1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0450) +#define OMAP4_CM_MEMIF_EMIF_H2_CLKCTRL_OFFSET 0x0458 +#define OMAP4430_CM_MEMIF_EMIF_H2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0458) +#define OMAP4_CM_MEMIF_DLL_H_CLKCTRL_OFFSET 0x0460 +#define OMAP4430_CM_MEMIF_DLL_H_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0460) +#define OMAP4_CM_D2D_CLKSTCTRL_OFFSET 0x0500 +#define OMAP4430_CM_D2D_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0500) +#define OMAP4_CM_D2D_STATICDEP_OFFSET 0x0504 +#define OMAP4430_CM_D2D_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0504) +#define OMAP4_CM_D2D_DYNAMICDEP_OFFSET 0x0508 +#define OMAP4430_CM_D2D_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0508) +#define OMAP4_CM_D2D_SAD2D_CLKCTRL_OFFSET 0x0520 +#define OMAP4430_CM_D2D_SAD2D_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0520) +#define OMAP4_CM_D2D_MODEM_ICR_CLKCTRL_OFFSET 0x0528 +#define OMAP4430_CM_D2D_MODEM_ICR_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0528) +#define OMAP4_CM_D2D_SAD2D_FW_CLKCTRL_OFFSET 0x0530 +#define OMAP4430_CM_D2D_SAD2D_FW_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0530) +#define OMAP4_CM_L4CFG_CLKSTCTRL_OFFSET 0x0600 +#define OMAP4430_CM_L4CFG_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0600) +#define OMAP4_CM_L4CFG_DYNAMICDEP_OFFSET 0x0608 +#define OMAP4430_CM_L4CFG_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0608) +#define OMAP4_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET 0x0620 +#define OMAP4430_CM_L4CFG_L4_CFG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0620) +#define OMAP4_CM_L4CFG_HW_SEM_CLKCTRL_OFFSET 0x0628 +#define OMAP4430_CM_L4CFG_HW_SEM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0628) +#define OMAP4_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET 0x0630 +#define OMAP4430_CM_L4CFG_MAILBOX_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0630) +#define OMAP4_CM_L4CFG_SAR_ROM_CLKCTRL_OFFSET 0x0638 +#define OMAP4430_CM_L4CFG_SAR_ROM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0638) +#define OMAP4_CM_L3INSTR_CLKSTCTRL_OFFSET 0x0700 +#define OMAP4430_CM_L3INSTR_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0700) +#define OMAP4_CM_L3INSTR_L3_3_CLKCTRL_OFFSET 0x0720 +#define OMAP4430_CM_L3INSTR_L3_3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0720) +#define OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET 0x0728 +#define OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0728) +#define OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_OFFSET 0x0740 +#define OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0740) + +/* CM2.IVAHD_CM2 register offsets */ +#define OMAP4_CM_IVAHD_CLKSTCTRL_OFFSET 0x0000 +#define OMAP4430_CM_IVAHD_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_INST, 0x0000) +#define OMAP4_CM_IVAHD_STATICDEP_OFFSET 0x0004 +#define OMAP4430_CM_IVAHD_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_INST, 0x0004) +#define OMAP4_CM_IVAHD_DYNAMICDEP_OFFSET 0x0008 +#define OMAP4430_CM_IVAHD_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_INST, 0x0008) +#define OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET 0x0020 +#define OMAP4430_CM_IVAHD_IVAHD_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_INST, 0x0020) +#define OMAP4_CM_IVAHD_SL2_CLKCTRL_OFFSET 0x0028 +#define OMAP4430_CM_IVAHD_SL2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_INST, 0x0028) + +/* CM2.CAM_CM2 register offsets */ +#define OMAP4_CM_CAM_CLKSTCTRL_OFFSET 0x0000 +#define OMAP4430_CM_CAM_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_INST, 0x0000) +#define OMAP4_CM_CAM_STATICDEP_OFFSET 0x0004 +#define OMAP4430_CM_CAM_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_INST, 0x0004) +#define OMAP4_CM_CAM_DYNAMICDEP_OFFSET 0x0008 +#define OMAP4430_CM_CAM_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_INST, 0x0008) +#define OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET 0x0020 +#define OMAP4430_CM_CAM_ISS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_INST, 0x0020) +#define OMAP4_CM_CAM_FDIF_CLKCTRL_OFFSET 0x0028 +#define OMAP4430_CM_CAM_FDIF_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_INST, 0x0028) + +/* CM2.DSS_CM2 register offsets */ +#define OMAP4_CM_DSS_CLKSTCTRL_OFFSET 0x0000 +#define OMAP4430_CM_DSS_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_INST, 0x0000) +#define OMAP4_CM_DSS_STATICDEP_OFFSET 0x0004 +#define OMAP4430_CM_DSS_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_INST, 0x0004) +#define OMAP4_CM_DSS_DYNAMICDEP_OFFSET 0x0008 +#define OMAP4430_CM_DSS_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_INST, 0x0008) +#define OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET 0x0020 +#define OMAP4430_CM_DSS_DSS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_INST, 0x0020) +#define OMAP4_CM_DSS_DEISS_CLKCTRL_OFFSET 0x0028 +#define OMAP4430_CM_DSS_DEISS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_INST, 0x0028) + +/* CM2.GFX_CM2 register offsets */ +#define OMAP4_CM_GFX_CLKSTCTRL_OFFSET 0x0000 +#define OMAP4430_CM_GFX_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_INST, 0x0000) +#define OMAP4_CM_GFX_STATICDEP_OFFSET 0x0004 +#define OMAP4430_CM_GFX_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_INST, 0x0004) +#define OMAP4_CM_GFX_DYNAMICDEP_OFFSET 0x0008 +#define OMAP4430_CM_GFX_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_INST, 0x0008) +#define OMAP4_CM_GFX_GFX_CLKCTRL_OFFSET 0x0020 +#define OMAP4430_CM_GFX_GFX_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_INST, 0x0020) + +/* CM2.L3INIT_CM2 register offsets */ +#define OMAP4_CM_L3INIT_CLKSTCTRL_OFFSET 0x0000 +#define OMAP4430_CM_L3INIT_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0000) +#define OMAP4_CM_L3INIT_STATICDEP_OFFSET 0x0004 +#define OMAP4430_CM_L3INIT_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0004) +#define OMAP4_CM_L3INIT_DYNAMICDEP_OFFSET 0x0008 +#define OMAP4430_CM_L3INIT_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0008) +#define OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET 0x0028 +#define OMAP4430_CM_L3INIT_MMC1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0028) +#define OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET 0x0030 +#define OMAP4430_CM_L3INIT_MMC2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0030) +#define OMAP4_CM_L3INIT_HSI_CLKCTRL_OFFSET 0x0038 +#define OMAP4430_CM_L3INIT_HSI_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0038) +#define OMAP4_CM_L3INIT_UNIPRO1_CLKCTRL_OFFSET 0x0040 +#define OMAP4430_CM_L3INIT_UNIPRO1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0040) +#define OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET 0x0058 +#define OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0058) +#define OMAP4_CM_L3INIT_USB_OTG_CLKCTRL_OFFSET 0x0060 +#define OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0060) +#define OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET 0x0068 +#define OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0068) +#define OMAP4_CM_L3INIT_P1500_CLKCTRL_OFFSET 0x0078 +#define OMAP4430_CM_L3INIT_P1500_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0078) +#define OMAP4_CM_L3INIT_EMAC_CLKCTRL_OFFSET 0x0080 +#define OMAP4430_CM_L3INIT_EMAC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0080) +#define OMAP4_CM_L3INIT_SATA_CLKCTRL_OFFSET 0x0088 +#define OMAP4430_CM_L3INIT_SATA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0088) +#define OMAP4_CM_L3INIT_TPPSS_CLKCTRL_OFFSET 0x0090 +#define OMAP4430_CM_L3INIT_TPPSS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0090) +#define OMAP4_CM_L3INIT_PCIESS_CLKCTRL_OFFSET 0x0098 +#define OMAP4430_CM_L3INIT_PCIESS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0098) +#define OMAP4_CM_L3INIT_CCPTX_CLKCTRL_OFFSET 0x00a8 +#define OMAP4430_CM_L3INIT_CCPTX_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x00a8) +#define OMAP4_CM_L3INIT_XHPI_CLKCTRL_OFFSET 0x00c0 +#define OMAP4430_CM_L3INIT_XHPI_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x00c0) +#define OMAP4_CM_L3INIT_MMC6_CLKCTRL_OFFSET 0x00c8 +#define OMAP4430_CM_L3INIT_MMC6_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x00c8) +#define OMAP4_CM_L3INIT_USB_HOST_FS_CLKCTRL_OFFSET 0x00d0 +#define OMAP4430_CM_L3INIT_USB_HOST_FS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x00d0) +#define OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET 0x00e0 +#define OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x00e0) + +/* CM2.L4PER_CM2 register offsets */ +#define OMAP4_CM_L4PER_CLKSTCTRL_OFFSET 0x0000 +#define OMAP4430_CM_L4PER_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0000) +#define OMAP4_CM_L4PER_DYNAMICDEP_OFFSET 0x0008 +#define OMAP4430_CM_L4PER_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0008) +#define OMAP4_CM_L4PER_ADC_CLKCTRL_OFFSET 0x0020 +#define OMAP4430_CM_L4PER_ADC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0020) +#define OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET 0x0028 +#define OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0028) +#define OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET 0x0030 +#define OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0030) +#define OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET 0x0038 +#define OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0038) +#define OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET 0x0040 +#define OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0040) +#define OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET 0x0048 +#define OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0048) +#define OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET 0x0050 +#define OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0050) +#define OMAP4_CM_L4PER_ELM_CLKCTRL_OFFSET 0x0058 +#define OMAP4430_CM_L4PER_ELM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0058) +#define OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET 0x0060 +#define OMAP4430_CM_L4PER_GPIO2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0060) +#define OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET 0x0068 +#define OMAP4430_CM_L4PER_GPIO3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0068) +#define OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET 0x0070 +#define OMAP4430_CM_L4PER_GPIO4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0070) +#define OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET 0x0078 +#define OMAP4430_CM_L4PER_GPIO5_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0078) +#define OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET 0x0080 +#define OMAP4430_CM_L4PER_GPIO6_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0080) +#define OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET 0x0088 +#define OMAP4430_CM_L4PER_HDQ1W_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0088) +#define OMAP4_CM_L4PER_HECC1_CLKCTRL_OFFSET 0x0090 +#define OMAP4430_CM_L4PER_HECC1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0090) +#define OMAP4_CM_L4PER_HECC2_CLKCTRL_OFFSET 0x0098 +#define OMAP4430_CM_L4PER_HECC2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0098) +#define OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET 0x00a0 +#define OMAP4430_CM_L4PER_I2C1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00a0) +#define OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET 0x00a8 +#define OMAP4430_CM_L4PER_I2C2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00a8) +#define OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET 0x00b0 +#define OMAP4430_CM_L4PER_I2C3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00b0) +#define OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET 0x00b8 +#define OMAP4430_CM_L4PER_I2C4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00b8) +#define OMAP4_CM_L4PER_L4PER_CLKCTRL_OFFSET 0x00c0 +#define OMAP4430_CM_L4PER_L4PER_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00c0) +#define OMAP4_CM_L4PER_MCASP2_CLKCTRL_OFFSET 0x00d0 +#define OMAP4430_CM_L4PER_MCASP2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00d0) +#define OMAP4_CM_L4PER_MCASP3_CLKCTRL_OFFSET 0x00d8 +#define OMAP4430_CM_L4PER_MCASP3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00d8) +#define OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET 0x00e0 +#define OMAP4430_CM_L4PER_MCBSP4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00e0) +#define OMAP4_CM_L4PER_MGATE_CLKCTRL_OFFSET 0x00e8 +#define OMAP4430_CM_L4PER_MGATE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00e8) +#define OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET 0x00f0 +#define OMAP4430_CM_L4PER_MCSPI1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00f0) +#define OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET 0x00f8 +#define OMAP4430_CM_L4PER_MCSPI2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00f8) +#define OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET 0x0100 +#define OMAP4430_CM_L4PER_MCSPI3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0100) +#define OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET 0x0108 +#define OMAP4430_CM_L4PER_MCSPI4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0108) +#define OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET 0x0120 +#define OMAP4430_CM_L4PER_MMCSD3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0120) +#define OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET 0x0128 +#define OMAP4430_CM_L4PER_MMCSD4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0128) +#define OMAP4_CM_L4PER_MSPROHG_CLKCTRL_OFFSET 0x0130 +#define OMAP4430_CM_L4PER_MSPROHG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0130) +#define OMAP4_CM_L4PER_SLIMBUS2_CLKCTRL_OFFSET 0x0138 +#define OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0138) +#define OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET 0x0140 +#define OMAP4430_CM_L4PER_UART1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0140) +#define OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET 0x0148 +#define OMAP4430_CM_L4PER_UART2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0148) +#define OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET 0x0150 +#define OMAP4430_CM_L4PER_UART3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0150) +#define OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET 0x0158 +#define OMAP4430_CM_L4PER_UART4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0158) +#define OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET 0x0160 +#define OMAP4430_CM_L4PER_MMCSD5_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0160) +#define OMAP4_CM_L4PER_I2C5_CLKCTRL_OFFSET 0x0168 +#define OMAP4430_CM_L4PER_I2C5_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0168) +#define OMAP4_CM_L4SEC_CLKSTCTRL_OFFSET 0x0180 +#define OMAP4430_CM_L4SEC_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0180) +#define OMAP4_CM_L4SEC_STATICDEP_OFFSET 0x0184 +#define OMAP4430_CM_L4SEC_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0184) +#define OMAP4_CM_L4SEC_DYNAMICDEP_OFFSET 0x0188 +#define OMAP4430_CM_L4SEC_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0188) +#define OMAP4_CM_L4SEC_AES1_CLKCTRL_OFFSET 0x01a0 +#define OMAP4430_CM_L4SEC_AES1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01a0) +#define OMAP4_CM_L4SEC_AES2_CLKCTRL_OFFSET 0x01a8 +#define OMAP4430_CM_L4SEC_AES2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01a8) +#define OMAP4_CM_L4SEC_DES3DES_CLKCTRL_OFFSET 0x01b0 +#define OMAP4430_CM_L4SEC_DES3DES_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01b0) +#define OMAP4_CM_L4SEC_PKAEIP29_CLKCTRL_OFFSET 0x01b8 +#define OMAP4430_CM_L4SEC_PKAEIP29_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01b8) +#define OMAP4_CM_L4SEC_RNG_CLKCTRL_OFFSET 0x01c0 +#define OMAP4430_CM_L4SEC_RNG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01c0) +#define OMAP4_CM_L4SEC_SHA2MD51_CLKCTRL_OFFSET 0x01c8 +#define OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01c8) +#define OMAP4_CM_L4SEC_CRYPTODMA_CLKCTRL_OFFSET 0x01d8 +#define OMAP4430_CM_L4SEC_CRYPTODMA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01d8) + +/* CM2.CEFUSE_CM2 register offsets */ +#define OMAP4_CM_CEFUSE_CLKSTCTRL_OFFSET 0x0000 +#define OMAP4430_CM_CEFUSE_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_INST, 0x0000) +#define OMAP4_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET 0x0020 +#define OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_INST, 0x0020) + +#endif diff --git a/arch/arm/mach-omap2/cm2_54xx.h b/arch/arm/mach-omap2/cm2_54xx.h new file mode 100644 index 00000000000..2683231b299 --- /dev/null +++ b/arch/arm/mach-omap2/cm2_54xx.h @@ -0,0 +1,389 @@ +/* + * OMAP54xx CM2 instance offset macros + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CM2_54XX_H +#define __ARCH_ARM_MACH_OMAP2_CM2_54XX_H + +#include "cm_44xx_54xx.h" + +/* CM2 base address */ +#define OMAP54XX_CM_CORE_BASE 0x4a008000 + +#define OMAP54XX_CM_CORE_REGADDR(inst, reg) \ + OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_BASE + (inst) + (reg)) + +/* CM_CORE instances */ +#define OMAP54XX_CM_CORE_OCP_SOCKET_INST 0x0000 +#define OMAP54XX_CM_CORE_CKGEN_INST 0x0100 +#define OMAP54XX_CM_CORE_COREAON_INST 0x0600 +#define OMAP54XX_CM_CORE_CORE_INST 0x0700 +#define OMAP54XX_CM_CORE_IVA_INST 0x1200 +#define OMAP54XX_CM_CORE_CAM_INST 0x1300 +#define OMAP54XX_CM_CORE_DSS_INST 0x1400 +#define OMAP54XX_CM_CORE_GPU_INST 0x1500 +#define OMAP54XX_CM_CORE_L3INIT_INST 0x1600 +#define OMAP54XX_CM_CORE_CUSTEFUSE_INST 0x1700 +#define OMAP54XX_CM_CORE_RESTORE_INST 0x1e00 +#define OMAP54XX_CM_CORE_INSTR_INST 0x1f00 + +/* CM_CORE clockdomain register offsets (from instance start) */ +#define OMAP54XX_CM_CORE_COREAON_COREAON_CDOFFS 0x0000 +#define OMAP54XX_CM_CORE_CORE_L3MAIN1_CDOFFS 0x0000 +#define OMAP54XX_CM_CORE_CORE_L3MAIN2_CDOFFS 0x0100 +#define OMAP54XX_CM_CORE_CORE_IPU_CDOFFS 0x0200 +#define OMAP54XX_CM_CORE_CORE_DMA_CDOFFS 0x0300 +#define OMAP54XX_CM_CORE_CORE_EMIF_CDOFFS 0x0400 +#define OMAP54XX_CM_CORE_CORE_C2C_CDOFFS 0x0500 +#define OMAP54XX_CM_CORE_CORE_L4CFG_CDOFFS 0x0600 +#define OMAP54XX_CM_CORE_CORE_L3INSTR_CDOFFS 0x0700 +#define OMAP54XX_CM_CORE_CORE_MIPIEXT_CDOFFS 0x0800 +#define OMAP54XX_CM_CORE_CORE_L4PER_CDOFFS 0x0900 +#define OMAP54XX_CM_CORE_CORE_L4SEC_CDOFFS 0x0a80 +#define OMAP54XX_CM_CORE_IVA_IVA_CDOFFS 0x0000 +#define OMAP54XX_CM_CORE_CAM_CAM_CDOFFS 0x0000 +#define OMAP54XX_CM_CORE_DSS_DSS_CDOFFS 0x0000 +#define OMAP54XX_CM_CORE_GPU_GPU_CDOFFS 0x0000 +#define OMAP54XX_CM_CORE_L3INIT_L3INIT_CDOFFS 0x0000 +#define OMAP54XX_CM_CORE_CUSTEFUSE_CUSTEFUSE_CDOFFS 0x0000 + +/* CM_CORE */ + +/* CM_CORE.OCP_SOCKET_CM_CORE register offsets */ +#define OMAP54XX_REVISION_CM_CORE_OFFSET 0x0000 +#define OMAP54XX_CM_CM_CORE_PROFILING_CLKCTRL_OFFSET 0x0040 +#define OMAP54XX_CM_CM_CORE_PROFILING_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_OCP_SOCKET_INST, 0x0040) +#define OMAP54XX_CM_CORE_DEBUG_CFG_OFFSET 0x0080 +#define OMAP54XX_CM_CORE_DEBUG_OUT_OFFSET 0x0084 + +/* CM_CORE.CKGEN_CM_CORE register offsets */ +#define OMAP54XX_CM_CLKSEL_USB_60MHZ_OFFSET 0x0004 +#define OMAP54XX_CM_CLKSEL_USB_60MHZ OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0004) +#define OMAP54XX_CM_CLKMODE_DPLL_PER_OFFSET 0x0040 +#define OMAP54XX_CM_CLKMODE_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0040) +#define OMAP54XX_CM_IDLEST_DPLL_PER_OFFSET 0x0044 +#define OMAP54XX_CM_IDLEST_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0044) +#define OMAP54XX_CM_AUTOIDLE_DPLL_PER_OFFSET 0x0048 +#define OMAP54XX_CM_AUTOIDLE_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0048) +#define OMAP54XX_CM_CLKSEL_DPLL_PER_OFFSET 0x004c +#define OMAP54XX_CM_CLKSEL_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x004c) +#define OMAP54XX_CM_DIV_M2_DPLL_PER_OFFSET 0x0050 +#define OMAP54XX_CM_DIV_M2_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0050) +#define OMAP54XX_CM_DIV_M3_DPLL_PER_OFFSET 0x0054 +#define OMAP54XX_CM_DIV_M3_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0054) +#define OMAP54XX_CM_DIV_H11_DPLL_PER_OFFSET 0x0058 +#define OMAP54XX_CM_DIV_H11_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0058) +#define OMAP54XX_CM_DIV_H12_DPLL_PER_OFFSET 0x005c +#define OMAP54XX_CM_DIV_H12_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x005c) +#define OMAP54XX_CM_DIV_H13_DPLL_PER_OFFSET 0x0060 +#define OMAP54XX_CM_DIV_H13_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0060) +#define OMAP54XX_CM_DIV_H14_DPLL_PER_OFFSET 0x0064 +#define OMAP54XX_CM_DIV_H14_DPLL_PER OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0064) +#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_PER_OFFSET 0x0068 +#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_PER_OFFSET 0x006c +#define OMAP54XX_CM_CLKMODE_DPLL_USB_OFFSET 0x0080 +#define OMAP54XX_CM_CLKMODE_DPLL_USB OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0080) +#define OMAP54XX_CM_IDLEST_DPLL_USB_OFFSET 0x0084 +#define OMAP54XX_CM_IDLEST_DPLL_USB OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0084) +#define OMAP54XX_CM_AUTOIDLE_DPLL_USB_OFFSET 0x0088 +#define OMAP54XX_CM_AUTOIDLE_DPLL_USB OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0088) +#define OMAP54XX_CM_CLKSEL_DPLL_USB_OFFSET 0x008c +#define OMAP54XX_CM_CLKSEL_DPLL_USB OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x008c) +#define OMAP54XX_CM_DIV_M2_DPLL_USB_OFFSET 0x0090 +#define OMAP54XX_CM_DIV_M2_DPLL_USB OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0090) +#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_USB_OFFSET 0x00a8 +#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_USB_OFFSET 0x00ac +#define OMAP54XX_CM_CLKDCOLDO_DPLL_USB_OFFSET 0x00b4 +#define OMAP54XX_CM_CLKDCOLDO_DPLL_USB OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00b4) +#define OMAP54XX_CM_CLKMODE_DPLL_UNIPRO2_OFFSET 0x00c0 +#define OMAP54XX_CM_CLKMODE_DPLL_UNIPRO2 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00c0) +#define OMAP54XX_CM_IDLEST_DPLL_UNIPRO2_OFFSET 0x00c4 +#define OMAP54XX_CM_IDLEST_DPLL_UNIPRO2 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00c4) +#define OMAP54XX_CM_AUTOIDLE_DPLL_UNIPRO2_OFFSET 0x00c8 +#define OMAP54XX_CM_AUTOIDLE_DPLL_UNIPRO2 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00c8) +#define OMAP54XX_CM_CLKSEL_DPLL_UNIPRO2_OFFSET 0x00cc +#define OMAP54XX_CM_CLKSEL_DPLL_UNIPRO2 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00cc) +#define OMAP54XX_CM_DIV_M2_DPLL_UNIPRO2_OFFSET 0x00d0 +#define OMAP54XX_CM_DIV_M2_DPLL_UNIPRO2 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00d0) +#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_UNIPRO2_OFFSET 0x00e8 +#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_UNIPRO2_OFFSET 0x00ec +#define OMAP54XX_CM_CLKDCOLDO_DPLL_UNIPRO2_OFFSET 0x00f4 +#define OMAP54XX_CM_CLKDCOLDO_DPLL_UNIPRO2 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00f4) +#define OMAP54XX_CM_CLKMODE_DPLL_UNIPRO1_OFFSET 0x0100 +#define OMAP54XX_CM_CLKMODE_DPLL_UNIPRO1 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0100) +#define OMAP54XX_CM_IDLEST_DPLL_UNIPRO1_OFFSET 0x0104 +#define OMAP54XX_CM_IDLEST_DPLL_UNIPRO1 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0104) +#define OMAP54XX_CM_AUTOIDLE_DPLL_UNIPRO1_OFFSET 0x0108 +#define OMAP54XX_CM_AUTOIDLE_DPLL_UNIPRO1 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0108) +#define OMAP54XX_CM_CLKSEL_DPLL_UNIPRO1_OFFSET 0x010c +#define OMAP54XX_CM_CLKSEL_DPLL_UNIPRO1 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x010c) +#define OMAP54XX_CM_DIV_M2_DPLL_UNIPRO1_OFFSET 0x0110 +#define OMAP54XX_CM_DIV_M2_DPLL_UNIPRO1 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0110) +#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_UNIPRO1_OFFSET 0x0128 +#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_UNIPRO1_OFFSET 0x012c +#define OMAP54XX_CM_CLKDCOLDO_DPLL_UNIPRO1_OFFSET 0x0134 +#define OMAP54XX_CM_CLKDCOLDO_DPLL_UNIPRO1 OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0134) + +/* CM_CORE.COREAON_CM_CORE register offsets */ +#define OMAP54XX_CM_COREAON_CLKSTCTRL_OFFSET 0x0000 +#define OMAP54XX_CM_COREAON_SMARTREFLEX_MPU_CLKCTRL_OFFSET 0x0028 +#define OMAP54XX_CM_COREAON_SMARTREFLEX_MPU_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_COREAON_INST, 0x0028) +#define OMAP54XX_CM_COREAON_SMARTREFLEX_MM_CLKCTRL_OFFSET 0x0030 +#define OMAP54XX_CM_COREAON_SMARTREFLEX_MM_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_COREAON_INST, 0x0030) +#define OMAP54XX_CM_COREAON_SMARTREFLEX_CORE_CLKCTRL_OFFSET 0x0038 +#define OMAP54XX_CM_COREAON_SMARTREFLEX_CORE_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_COREAON_INST, 0x0038) +#define OMAP54XX_CM_COREAON_USB_PHY_CORE_CLKCTRL_OFFSET 0x0040 +#define OMAP54XX_CM_COREAON_USB_PHY_CORE_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_COREAON_INST, 0x0040) +#define OMAP54XX_CM_COREAON_IO_SRCOMP_CLKCTRL_OFFSET 0x0050 +#define OMAP54XX_CM_COREAON_IO_SRCOMP_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_COREAON_INST, 0x0050) + +/* CM_CORE.CORE_CM_CORE register offsets */ +#define OMAP54XX_CM_L3MAIN1_CLKSTCTRL_OFFSET 0x0000 +#define OMAP54XX_CM_L3MAIN1_DYNAMICDEP_OFFSET 0x0008 +#define OMAP54XX_CM_L3MAIN1_L3_MAIN_1_CLKCTRL_OFFSET 0x0020 +#define OMAP54XX_CM_L3MAIN1_L3_MAIN_1_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0020) +#define OMAP54XX_CM_L3MAIN2_CLKSTCTRL_OFFSET 0x0100 +#define OMAP54XX_CM_L3MAIN2_DYNAMICDEP_OFFSET 0x0108 +#define OMAP54XX_CM_L3MAIN2_L3_MAIN_2_CLKCTRL_OFFSET 0x0120 +#define OMAP54XX_CM_L3MAIN2_L3_MAIN_2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0120) +#define OMAP54XX_CM_L3MAIN2_GPMC_CLKCTRL_OFFSET 0x0128 +#define OMAP54XX_CM_L3MAIN2_GPMC_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0128) +#define OMAP54XX_CM_L3MAIN2_OCMC_RAM_CLKCTRL_OFFSET 0x0130 +#define OMAP54XX_CM_L3MAIN2_OCMC_RAM_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0130) +#define OMAP54XX_CM_IPU_CLKSTCTRL_OFFSET 0x0200 +#define OMAP54XX_CM_IPU_STATICDEP_OFFSET 0x0204 +#define OMAP54XX_CM_IPU_DYNAMICDEP_OFFSET 0x0208 +#define OMAP54XX_CM_IPU_IPU_CLKCTRL_OFFSET 0x0220 +#define OMAP54XX_CM_IPU_IPU_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0220) +#define OMAP54XX_CM_DMA_CLKSTCTRL_OFFSET 0x0300 +#define OMAP54XX_CM_DMA_STATICDEP_OFFSET 0x0304 +#define OMAP54XX_CM_DMA_DYNAMICDEP_OFFSET 0x0308 +#define OMAP54XX_CM_DMA_DMA_SYSTEM_CLKCTRL_OFFSET 0x0320 +#define OMAP54XX_CM_DMA_DMA_SYSTEM_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0320) +#define OMAP54XX_CM_EMIF_CLKSTCTRL_OFFSET 0x0400 +#define OMAP54XX_CM_EMIF_DMM_CLKCTRL_OFFSET 0x0420 +#define OMAP54XX_CM_EMIF_DMM_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0420) +#define OMAP54XX_CM_EMIF_EMIF_OCP_FW_CLKCTRL_OFFSET 0x0428 +#define OMAP54XX_CM_EMIF_EMIF_OCP_FW_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0428) +#define OMAP54XX_CM_EMIF_EMIF1_CLKCTRL_OFFSET 0x0430 +#define OMAP54XX_CM_EMIF_EMIF1_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0430) +#define OMAP54XX_CM_EMIF_EMIF2_CLKCTRL_OFFSET 0x0438 +#define OMAP54XX_CM_EMIF_EMIF2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0438) +#define OMAP54XX_CM_EMIF_EMIF_DLL_CLKCTRL_OFFSET 0x0440 +#define OMAP54XX_CM_EMIF_EMIF_DLL_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0440) +#define OMAP54XX_CM_C2C_CLKSTCTRL_OFFSET 0x0500 +#define OMAP54XX_CM_C2C_STATICDEP_OFFSET 0x0504 +#define OMAP54XX_CM_C2C_DYNAMICDEP_OFFSET 0x0508 +#define OMAP54XX_CM_C2C_C2C_CLKCTRL_OFFSET 0x0520 +#define OMAP54XX_CM_C2C_C2C_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0520) +#define OMAP54XX_CM_C2C_MODEM_ICR_CLKCTRL_OFFSET 0x0528 +#define OMAP54XX_CM_C2C_MODEM_ICR_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0528) +#define OMAP54XX_CM_C2C_C2C_OCP_FW_CLKCTRL_OFFSET 0x0530 +#define OMAP54XX_CM_C2C_C2C_OCP_FW_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0530) +#define OMAP54XX_CM_L4CFG_CLKSTCTRL_OFFSET 0x0600 +#define OMAP54XX_CM_L4CFG_DYNAMICDEP_OFFSET 0x0608 +#define OMAP54XX_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET 0x0620 +#define OMAP54XX_CM_L4CFG_L4_CFG_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0620) +#define OMAP54XX_CM_L4CFG_SPINLOCK_CLKCTRL_OFFSET 0x0628 +#define OMAP54XX_CM_L4CFG_SPINLOCK_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0628) +#define OMAP54XX_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET 0x0630 +#define OMAP54XX_CM_L4CFG_MAILBOX_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0630) +#define OMAP54XX_CM_L4CFG_SAR_ROM_CLKCTRL_OFFSET 0x0638 +#define OMAP54XX_CM_L4CFG_SAR_ROM_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0638) +#define OMAP54XX_CM_L4CFG_OCP2SCP2_CLKCTRL_OFFSET 0x0640 +#define OMAP54XX_CM_L4CFG_OCP2SCP2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0640) +#define OMAP54XX_CM_L3INSTR_CLKSTCTRL_OFFSET 0x0700 +#define OMAP54XX_CM_L3INSTR_L3_MAIN_3_CLKCTRL_OFFSET 0x0720 +#define OMAP54XX_CM_L3INSTR_L3_MAIN_3_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0720) +#define OMAP54XX_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET 0x0728 +#define OMAP54XX_CM_L3INSTR_L3_INSTR_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0728) +#define OMAP54XX_CM_L3INSTR_OCP_WP_NOC_CLKCTRL_OFFSET 0x0740 +#define OMAP54XX_CM_L3INSTR_OCP_WP_NOC_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0740) +#define OMAP54XX_CM_L3INSTR_DLL_AGING_CLKCTRL_OFFSET 0x0748 +#define OMAP54XX_CM_L3INSTR_DLL_AGING_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0748) +#define OMAP54XX_CM_L3INSTR_CTRL_MODULE_BANDGAP_CLKCTRL_OFFSET 0x0750 +#define OMAP54XX_CM_L3INSTR_CTRL_MODULE_BANDGAP_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0750) +#define OMAP54XX_CM_MIPIEXT_CLKSTCTRL_OFFSET 0x0800 +#define OMAP54XX_CM_MIPIEXT_STATICDEP_OFFSET 0x0804 +#define OMAP54XX_CM_MIPIEXT_DYNAMICDEP_OFFSET 0x0808 +#define OMAP54XX_CM_MIPIEXT_LLI_CLKCTRL_OFFSET 0x0820 +#define OMAP54XX_CM_MIPIEXT_LLI_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0820) +#define OMAP54XX_CM_MIPIEXT_LLI_OCP_FW_CLKCTRL_OFFSET 0x0828 +#define OMAP54XX_CM_MIPIEXT_LLI_OCP_FW_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0828) +#define OMAP54XX_CM_MIPIEXT_MPHY_CLKCTRL_OFFSET 0x0830 +#define OMAP54XX_CM_MIPIEXT_MPHY_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0830) +#define OMAP54XX_CM_L4PER_CLKSTCTRL_OFFSET 0x0900 +#define OMAP54XX_CM_L4PER_DYNAMICDEP_OFFSET 0x0908 +#define OMAP54XX_CM_L4PER_TIMER10_CLKCTRL_OFFSET 0x0928 +#define OMAP54XX_CM_L4PER_TIMER10_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0928) +#define OMAP54XX_CM_L4PER_TIMER11_CLKCTRL_OFFSET 0x0930 +#define OMAP54XX_CM_L4PER_TIMER11_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0930) +#define OMAP54XX_CM_L4PER_TIMER2_CLKCTRL_OFFSET 0x0938 +#define OMAP54XX_CM_L4PER_TIMER2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0938) +#define OMAP54XX_CM_L4PER_TIMER3_CLKCTRL_OFFSET 0x0940 +#define OMAP54XX_CM_L4PER_TIMER3_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0940) +#define OMAP54XX_CM_L4PER_TIMER4_CLKCTRL_OFFSET 0x0948 +#define OMAP54XX_CM_L4PER_TIMER4_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0948) +#define OMAP54XX_CM_L4PER_TIMER9_CLKCTRL_OFFSET 0x0950 +#define OMAP54XX_CM_L4PER_TIMER9_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0950) +#define OMAP54XX_CM_L4PER_ELM_CLKCTRL_OFFSET 0x0958 +#define OMAP54XX_CM_L4PER_ELM_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0958) +#define OMAP54XX_CM_L4PER_GPIO2_CLKCTRL_OFFSET 0x0960 +#define OMAP54XX_CM_L4PER_GPIO2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0960) +#define OMAP54XX_CM_L4PER_GPIO3_CLKCTRL_OFFSET 0x0968 +#define OMAP54XX_CM_L4PER_GPIO3_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0968) +#define OMAP54XX_CM_L4PER_GPIO4_CLKCTRL_OFFSET 0x0970 +#define OMAP54XX_CM_L4PER_GPIO4_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0970) +#define OMAP54XX_CM_L4PER_GPIO5_CLKCTRL_OFFSET 0x0978 +#define OMAP54XX_CM_L4PER_GPIO5_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0978) +#define OMAP54XX_CM_L4PER_GPIO6_CLKCTRL_OFFSET 0x0980 +#define OMAP54XX_CM_L4PER_GPIO6_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0980) +#define OMAP54XX_CM_L4PER_HDQ1W_CLKCTRL_OFFSET 0x0988 +#define OMAP54XX_CM_L4PER_HDQ1W_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0988) +#define OMAP54XX_CM_L4PER_I2C1_CLKCTRL_OFFSET 0x09a0 +#define OMAP54XX_CM_L4PER_I2C1_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09a0) +#define OMAP54XX_CM_L4PER_I2C2_CLKCTRL_OFFSET 0x09a8 +#define OMAP54XX_CM_L4PER_I2C2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09a8) +#define OMAP54XX_CM_L4PER_I2C3_CLKCTRL_OFFSET 0x09b0 +#define OMAP54XX_CM_L4PER_I2C3_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09b0) +#define OMAP54XX_CM_L4PER_I2C4_CLKCTRL_OFFSET 0x09b8 +#define OMAP54XX_CM_L4PER_I2C4_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09b8) +#define OMAP54XX_CM_L4PER_L4_PER_CLKCTRL_OFFSET 0x09c0 +#define OMAP54XX_CM_L4PER_L4_PER_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09c0) +#define OMAP54XX_CM_L4PER_MCSPI1_CLKCTRL_OFFSET 0x09f0 +#define OMAP54XX_CM_L4PER_MCSPI1_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09f0) +#define OMAP54XX_CM_L4PER_MCSPI2_CLKCTRL_OFFSET 0x09f8 +#define OMAP54XX_CM_L4PER_MCSPI2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09f8) +#define OMAP54XX_CM_L4PER_MCSPI3_CLKCTRL_OFFSET 0x0a00 +#define OMAP54XX_CM_L4PER_MCSPI3_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a00) +#define OMAP54XX_CM_L4PER_MCSPI4_CLKCTRL_OFFSET 0x0a08 +#define OMAP54XX_CM_L4PER_MCSPI4_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a08) +#define OMAP54XX_CM_L4PER_GPIO7_CLKCTRL_OFFSET 0x0a10 +#define OMAP54XX_CM_L4PER_GPIO7_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a10) +#define OMAP54XX_CM_L4PER_GPIO8_CLKCTRL_OFFSET 0x0a18 +#define OMAP54XX_CM_L4PER_GPIO8_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a18) +#define OMAP54XX_CM_L4PER_MMC3_CLKCTRL_OFFSET 0x0a20 +#define OMAP54XX_CM_L4PER_MMC3_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a20) +#define OMAP54XX_CM_L4PER_MMC4_CLKCTRL_OFFSET 0x0a28 +#define OMAP54XX_CM_L4PER_MMC4_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a28) +#define OMAP54XX_CM_L4PER_UART1_CLKCTRL_OFFSET 0x0a40 +#define OMAP54XX_CM_L4PER_UART1_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a40) +#define OMAP54XX_CM_L4PER_UART2_CLKCTRL_OFFSET 0x0a48 +#define OMAP54XX_CM_L4PER_UART2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a48) +#define OMAP54XX_CM_L4PER_UART3_CLKCTRL_OFFSET 0x0a50 +#define OMAP54XX_CM_L4PER_UART3_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a50) +#define OMAP54XX_CM_L4PER_UART4_CLKCTRL_OFFSET 0x0a58 +#define OMAP54XX_CM_L4PER_UART4_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a58) +#define OMAP54XX_CM_L4PER_MMC5_CLKCTRL_OFFSET 0x0a60 +#define OMAP54XX_CM_L4PER_MMC5_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a60) +#define OMAP54XX_CM_L4PER_I2C5_CLKCTRL_OFFSET 0x0a68 +#define OMAP54XX_CM_L4PER_I2C5_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a68) +#define OMAP54XX_CM_L4PER_UART5_CLKCTRL_OFFSET 0x0a70 +#define OMAP54XX_CM_L4PER_UART5_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a70) +#define OMAP54XX_CM_L4PER_UART6_CLKCTRL_OFFSET 0x0a78 +#define OMAP54XX_CM_L4PER_UART6_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a78) +#define OMAP54XX_CM_L4SEC_CLKSTCTRL_OFFSET 0x0a80 +#define OMAP54XX_CM_L4SEC_STATICDEP_OFFSET 0x0a84 +#define OMAP54XX_CM_L4SEC_DYNAMICDEP_OFFSET 0x0a88 +#define OMAP54XX_CM_L4SEC_AES1_CLKCTRL_OFFSET 0x0aa0 +#define OMAP54XX_CM_L4SEC_AES1_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0aa0) +#define OMAP54XX_CM_L4SEC_AES2_CLKCTRL_OFFSET 0x0aa8 +#define OMAP54XX_CM_L4SEC_AES2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0aa8) +#define OMAP54XX_CM_L4SEC_DES3DES_CLKCTRL_OFFSET 0x0ab0 +#define OMAP54XX_CM_L4SEC_DES3DES_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0ab0) +#define OMAP54XX_CM_L4SEC_FPKA_CLKCTRL_OFFSET 0x0ab8 +#define OMAP54XX_CM_L4SEC_FPKA_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0ab8) +#define OMAP54XX_CM_L4SEC_RNG_CLKCTRL_OFFSET 0x0ac0 +#define OMAP54XX_CM_L4SEC_RNG_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0ac0) +#define OMAP54XX_CM_L4SEC_SHA2MD5_CLKCTRL_OFFSET 0x0ac8 +#define OMAP54XX_CM_L4SEC_SHA2MD5_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0ac8) +#define OMAP54XX_CM_L4SEC_DMA_CRYPTO_CLKCTRL_OFFSET 0x0ad8 +#define OMAP54XX_CM_L4SEC_DMA_CRYPTO_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0ad8) + +/* CM_CORE.IVA_CM_CORE register offsets */ +#define OMAP54XX_CM_IVA_CLKSTCTRL_OFFSET 0x0000 +#define OMAP54XX_CM_IVA_STATICDEP_OFFSET 0x0004 +#define OMAP54XX_CM_IVA_DYNAMICDEP_OFFSET 0x0008 +#define OMAP54XX_CM_IVA_IVA_CLKCTRL_OFFSET 0x0020 +#define OMAP54XX_CM_IVA_IVA_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_IVA_INST, 0x0020) +#define OMAP54XX_CM_IVA_SL2_CLKCTRL_OFFSET 0x0028 +#define OMAP54XX_CM_IVA_SL2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_IVA_INST, 0x0028) + +/* CM_CORE.CAM_CM_CORE register offsets */ +#define OMAP54XX_CM_CAM_CLKSTCTRL_OFFSET 0x0000 +#define OMAP54XX_CM_CAM_STATICDEP_OFFSET 0x0004 +#define OMAP54XX_CM_CAM_DYNAMICDEP_OFFSET 0x0008 +#define OMAP54XX_CM_CAM_ISS_CLKCTRL_OFFSET 0x0020 +#define OMAP54XX_CM_CAM_ISS_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CAM_INST, 0x0020) +#define OMAP54XX_CM_CAM_FDIF_CLKCTRL_OFFSET 0x0028 +#define OMAP54XX_CM_CAM_FDIF_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CAM_INST, 0x0028) +#define OMAP54XX_CM_CAM_CAL_CLKCTRL_OFFSET 0x0030 +#define OMAP54XX_CM_CAM_CAL_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CAM_INST, 0x0030) + +/* CM_CORE.DSS_CM_CORE register offsets */ +#define OMAP54XX_CM_DSS_CLKSTCTRL_OFFSET 0x0000 +#define OMAP54XX_CM_DSS_STATICDEP_OFFSET 0x0004 +#define OMAP54XX_CM_DSS_DYNAMICDEP_OFFSET 0x0008 +#define OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET 0x0020 +#define OMAP54XX_CM_DSS_DSS_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_DSS_INST, 0x0020) +#define OMAP54XX_CM_DSS_BB2D_CLKCTRL_OFFSET 0x0030 +#define OMAP54XX_CM_DSS_BB2D_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_DSS_INST, 0x0030) + +/* CM_CORE.GPU_CM_CORE register offsets */ +#define OMAP54XX_CM_GPU_CLKSTCTRL_OFFSET 0x0000 +#define OMAP54XX_CM_GPU_STATICDEP_OFFSET 0x0004 +#define OMAP54XX_CM_GPU_DYNAMICDEP_OFFSET 0x0008 +#define OMAP54XX_CM_GPU_GPU_CLKCTRL_OFFSET 0x0020 +#define OMAP54XX_CM_GPU_GPU_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_GPU_INST, 0x0020) + +/* CM_CORE.L3INIT_CM_CORE register offsets */ +#define OMAP54XX_CM_L3INIT_CLKSTCTRL_OFFSET 0x0000 +#define OMAP54XX_CM_L3INIT_STATICDEP_OFFSET 0x0004 +#define OMAP54XX_CM_L3INIT_DYNAMICDEP_OFFSET 0x0008 +#define OMAP54XX_CM_L3INIT_MMC1_CLKCTRL_OFFSET 0x0028 +#define OMAP54XX_CM_L3INIT_MMC1_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0028) +#define OMAP54XX_CM_L3INIT_MMC2_CLKCTRL_OFFSET 0x0030 +#define OMAP54XX_CM_L3INIT_MMC2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0030) +#define OMAP54XX_CM_L3INIT_HSI_CLKCTRL_OFFSET 0x0038 +#define OMAP54XX_CM_L3INIT_HSI_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0038) +#define OMAP54XX_CM_L3INIT_UNIPRO2_CLKCTRL_OFFSET 0x0040 +#define OMAP54XX_CM_L3INIT_UNIPRO2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0040) +#define OMAP54XX_CM_L3INIT_MPHY_UNIPRO2_CLKCTRL_OFFSET 0x0048 +#define OMAP54XX_CM_L3INIT_MPHY_UNIPRO2_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0048) +#define OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL_OFFSET 0x0058 +#define OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0058) +#define OMAP54XX_CM_L3INIT_USB_TLL_HS_CLKCTRL_OFFSET 0x0068 +#define OMAP54XX_CM_L3INIT_USB_TLL_HS_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0068) +#define OMAP54XX_CM_L3INIT_IEEE1500_2_OCP_CLKCTRL_OFFSET 0x0078 +#define OMAP54XX_CM_L3INIT_IEEE1500_2_OCP_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0078) +#define OMAP54XX_CM_L3INIT_SATA_CLKCTRL_OFFSET 0x0088 +#define OMAP54XX_CM_L3INIT_SATA_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0088) +#define OMAP54XX_CM_L3INIT_OCP2SCP1_CLKCTRL_OFFSET 0x00e0 +#define OMAP54XX_CM_L3INIT_OCP2SCP1_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x00e0) +#define OMAP54XX_CM_L3INIT_OCP2SCP3_CLKCTRL_OFFSET 0x00e8 +#define OMAP54XX_CM_L3INIT_OCP2SCP3_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x00e8) +#define OMAP54XX_CM_L3INIT_USB_OTG_SS_CLKCTRL_OFFSET 0x00f0 +#define OMAP54XX_CM_L3INIT_USB_OTG_SS_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x00f0) + +/* CM_CORE.CUSTEFUSE_CM_CORE register offsets */ +#define OMAP54XX_CM_CUSTEFUSE_CLKSTCTRL_OFFSET 0x0000 +#define OMAP54XX_CM_CUSTEFUSE_EFUSE_CTRL_CUST_CLKCTRL_OFFSET 0x0020 +#define OMAP54XX_CM_CUSTEFUSE_EFUSE_CTRL_CUST_CLKCTRL OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CUSTEFUSE_INST, 0x0020) + +#endif diff --git a/arch/arm/mach-omap2/cm2_7xx.h b/arch/arm/mach-omap2/cm2_7xx.h new file mode 100644 index 00000000000..9ad7594e762 --- /dev/null +++ b/arch/arm/mach-omap2/cm2_7xx.h @@ -0,0 +1,513 @@ +/* + * DRA7xx CM2 instance offset macros + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * + * Generated by code originally written by: + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CM2_7XX_H +#define __ARCH_ARM_MACH_OMAP2_CM2_7XX_H + +#include "cm_44xx_54xx.h" + +/* CM2 base address */ +#define DRA7XX_CM_CORE_BASE 0x4a008000 + +#define DRA7XX_CM_CORE_REGADDR(inst, reg) \ + OMAP2_L4_IO_ADDRESS(DRA7XX_CM_CORE_BASE + (inst) + (reg)) + +/* CM_CORE instances */ +#define DRA7XX_CM_CORE_OCP_SOCKET_INST 0x0000 +#define DRA7XX_CM_CORE_CKGEN_INST 0x0104 +#define DRA7XX_CM_CORE_COREAON_INST 0x0600 +#define DRA7XX_CM_CORE_CORE_INST 0x0700 +#define DRA7XX_CM_CORE_IVA_INST 0x0f00 +#define DRA7XX_CM_CORE_CAM_INST 0x1000 +#define DRA7XX_CM_CORE_DSS_INST 0x1100 +#define DRA7XX_CM_CORE_GPU_INST 0x1200 +#define DRA7XX_CM_CORE_L3INIT_INST 0x1300 +#define DRA7XX_CM_CORE_CUSTEFUSE_INST 0x1600 +#define DRA7XX_CM_CORE_L4PER_INST 0x1700 +#define DRA7XX_CM_CORE_RESTORE_INST 0x1e18 + +/* CM_CORE clockdomain register offsets (from instance start) */ +#define DRA7XX_CM_CORE_COREAON_COREAON_CDOFFS 0x0000 +#define DRA7XX_CM_CORE_CORE_L3MAIN1_CDOFFS 0x0000 +#define DRA7XX_CM_CORE_CORE_IPU2_CDOFFS 0x0200 +#define DRA7XX_CM_CORE_CORE_DMA_CDOFFS 0x0300 +#define DRA7XX_CM_CORE_CORE_EMIF_CDOFFS 0x0400 +#define DRA7XX_CM_CORE_CORE_ATL_CDOFFS 0x0520 +#define DRA7XX_CM_CORE_CORE_L4CFG_CDOFFS 0x0600 +#define DRA7XX_CM_CORE_CORE_L3INSTR_CDOFFS 0x0700 +#define DRA7XX_CM_CORE_IVA_IVA_CDOFFS 0x0000 +#define DRA7XX_CM_CORE_CAM_CAM_CDOFFS 0x0000 +#define DRA7XX_CM_CORE_DSS_DSS_CDOFFS 0x0000 +#define DRA7XX_CM_CORE_GPU_GPU_CDOFFS 0x0000 +#define DRA7XX_CM_CORE_L3INIT_L3INIT_CDOFFS 0x0000 +#define DRA7XX_CM_CORE_L3INIT_PCIE_CDOFFS 0x00a0 +#define DRA7XX_CM_CORE_L3INIT_GMAC_CDOFFS 0x00c0 +#define DRA7XX_CM_CORE_CUSTEFUSE_CUSTEFUSE_CDOFFS 0x0000 +#define DRA7XX_CM_CORE_L4PER_L4PER_CDOFFS 0x0000 +#define DRA7XX_CM_CORE_L4PER_L4SEC_CDOFFS 0x0180 +#define DRA7XX_CM_CORE_L4PER_L4PER2_CDOFFS 0x01fc +#define DRA7XX_CM_CORE_L4PER_L4PER3_CDOFFS 0x0210 + +/* CM_CORE */ + +/* CM_CORE.OCP_SOCKET_CM_CORE register offsets */ +#define DRA7XX_REVISION_CM_CORE_OFFSET 0x0000 +#define DRA7XX_CM_CM_CORE_PROFILING_CLKCTRL_OFFSET 0x0040 +#define DRA7XX_CM_CM_CORE_PROFILING_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_OCP_SOCKET_INST, 0x0040) +#define DRA7XX_CM_CORE_DEBUG_CFG_OFFSET 0x00f0 + +/* CM_CORE.CKGEN_CM_CORE register offsets */ +#define DRA7XX_CM_CLKSEL_USB_60MHZ_OFFSET 0x0000 +#define DRA7XX_CM_CLKSEL_USB_60MHZ DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0000) +#define DRA7XX_CM_CLKMODE_DPLL_PER_OFFSET 0x003c +#define DRA7XX_CM_CLKMODE_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x003c) +#define DRA7XX_CM_IDLEST_DPLL_PER_OFFSET 0x0040 +#define DRA7XX_CM_IDLEST_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0040) +#define DRA7XX_CM_AUTOIDLE_DPLL_PER_OFFSET 0x0044 +#define DRA7XX_CM_AUTOIDLE_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0044) +#define DRA7XX_CM_CLKSEL_DPLL_PER_OFFSET 0x0048 +#define DRA7XX_CM_CLKSEL_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0048) +#define DRA7XX_CM_DIV_M2_DPLL_PER_OFFSET 0x004c +#define DRA7XX_CM_DIV_M2_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x004c) +#define DRA7XX_CM_DIV_M3_DPLL_PER_OFFSET 0x0050 +#define DRA7XX_CM_DIV_M3_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0050) +#define DRA7XX_CM_DIV_H11_DPLL_PER_OFFSET 0x0054 +#define DRA7XX_CM_DIV_H11_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0054) +#define DRA7XX_CM_DIV_H12_DPLL_PER_OFFSET 0x0058 +#define DRA7XX_CM_DIV_H12_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0058) +#define DRA7XX_CM_DIV_H13_DPLL_PER_OFFSET 0x005c +#define DRA7XX_CM_DIV_H13_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x005c) +#define DRA7XX_CM_DIV_H14_DPLL_PER_OFFSET 0x0060 +#define DRA7XX_CM_DIV_H14_DPLL_PER DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0060) +#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_PER_OFFSET 0x0064 +#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_PER_OFFSET 0x0068 +#define DRA7XX_CM_CLKMODE_DPLL_USB_OFFSET 0x007c +#define DRA7XX_CM_CLKMODE_DPLL_USB DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x007c) +#define DRA7XX_CM_IDLEST_DPLL_USB_OFFSET 0x0080 +#define DRA7XX_CM_IDLEST_DPLL_USB DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0080) +#define DRA7XX_CM_AUTOIDLE_DPLL_USB_OFFSET 0x0084 +#define DRA7XX_CM_AUTOIDLE_DPLL_USB DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0084) +#define DRA7XX_CM_CLKSEL_DPLL_USB_OFFSET 0x0088 +#define DRA7XX_CM_CLKSEL_DPLL_USB DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0088) +#define DRA7XX_CM_DIV_M2_DPLL_USB_OFFSET 0x008c +#define DRA7XX_CM_DIV_M2_DPLL_USB DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x008c) +#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_USB_OFFSET 0x00a4 +#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_USB_OFFSET 0x00a8 +#define DRA7XX_CM_CLKDCOLDO_DPLL_USB_OFFSET 0x00b0 +#define DRA7XX_CM_CLKDCOLDO_DPLL_USB DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x00b0) +#define DRA7XX_CM_CLKMODE_DPLL_PCIE_REF_OFFSET 0x00fc +#define DRA7XX_CM_CLKMODE_DPLL_PCIE_REF DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x00fc) +#define DRA7XX_CM_IDLEST_DPLL_PCIE_REF_OFFSET 0x0100 +#define DRA7XX_CM_IDLEST_DPLL_PCIE_REF DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0100) +#define DRA7XX_CM_AUTOIDLE_DPLL_PCIE_REF_OFFSET 0x0104 +#define DRA7XX_CM_AUTOIDLE_DPLL_PCIE_REF DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0104) +#define DRA7XX_CM_CLKSEL_DPLL_PCIE_REF_OFFSET 0x0108 +#define DRA7XX_CM_CLKSEL_DPLL_PCIE_REF DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0108) +#define DRA7XX_CM_DIV_M2_DPLL_PCIE_REF_OFFSET 0x010c +#define DRA7XX_CM_DIV_M2_DPLL_PCIE_REF DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x010c) +#define DRA7XX_CM_SSC_DELTAMSTEP_DPLL_PCIE_REF_OFFSET 0x0110 +#define DRA7XX_CM_SSC_MODFREQDIV_DPLL_PCIE_REF_OFFSET 0x0114 +#define DRA7XX_CM_CLKMODE_APLL_PCIE_OFFSET 0x0118 +#define DRA7XX_CM_CLKMODE_APLL_PCIE DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0118) +#define DRA7XX_CM_IDLEST_APLL_PCIE_OFFSET 0x011c +#define DRA7XX_CM_IDLEST_APLL_PCIE DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x011c) +#define DRA7XX_CM_DIV_M2_APLL_PCIE_OFFSET 0x0120 +#define DRA7XX_CM_DIV_M2_APLL_PCIE DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0120) +#define DRA7XX_CM_CLKVCOLDO_APLL_PCIE_OFFSET 0x0124 +#define DRA7XX_CM_CLKVCOLDO_APLL_PCIE DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CKGEN_INST, 0x0124) + +/* CM_CORE.COREAON_CM_CORE register offsets */ +#define DRA7XX_CM_COREAON_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_COREAON_SMARTREFLEX_MPU_CLKCTRL_OFFSET 0x0028 +#define DRA7XX_CM_COREAON_SMARTREFLEX_MPU_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x0028) +#define DRA7XX_CM_COREAON_SMARTREFLEX_CORE_CLKCTRL_OFFSET 0x0038 +#define DRA7XX_CM_COREAON_SMARTREFLEX_CORE_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x0038) +#define DRA7XX_CM_COREAON_USB_PHY1_CORE_CLKCTRL_OFFSET 0x0040 +#define DRA7XX_CM_COREAON_USB_PHY1_CORE_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x0040) +#define DRA7XX_CM_COREAON_IO_SRCOMP_CLKCTRL_OFFSET 0x0050 +#define DRA7XX_CM_COREAON_IO_SRCOMP_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x0050) +#define DRA7XX_CM_COREAON_SMARTREFLEX_GPU_CLKCTRL_OFFSET 0x0058 +#define DRA7XX_CM_COREAON_SMARTREFLEX_GPU_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x0058) +#define DRA7XX_CM_COREAON_SMARTREFLEX_DSPEVE_CLKCTRL_OFFSET 0x0068 +#define DRA7XX_CM_COREAON_SMARTREFLEX_DSPEVE_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x0068) +#define DRA7XX_CM_COREAON_SMARTREFLEX_IVAHD_CLKCTRL_OFFSET 0x0078 +#define DRA7XX_CM_COREAON_SMARTREFLEX_IVAHD_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x0078) +#define DRA7XX_CM_COREAON_USB_PHY2_CORE_CLKCTRL_OFFSET 0x0088 +#define DRA7XX_CM_COREAON_USB_PHY2_CORE_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x0088) +#define DRA7XX_CM_COREAON_USB_PHY3_CORE_CLKCTRL_OFFSET 0x0098 +#define DRA7XX_CM_COREAON_USB_PHY3_CORE_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x0098) +#define DRA7XX_CM_COREAON_DUMMY_MODULE1_CLKCTRL_OFFSET 0x00a0 +#define DRA7XX_CM_COREAON_DUMMY_MODULE1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x00a0) +#define DRA7XX_CM_COREAON_DUMMY_MODULE2_CLKCTRL_OFFSET 0x00b0 +#define DRA7XX_CM_COREAON_DUMMY_MODULE2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x00b0) +#define DRA7XX_CM_COREAON_DUMMY_MODULE3_CLKCTRL_OFFSET 0x00c0 +#define DRA7XX_CM_COREAON_DUMMY_MODULE3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x00c0) +#define DRA7XX_CM_COREAON_DUMMY_MODULE4_CLKCTRL_OFFSET 0x00d0 +#define DRA7XX_CM_COREAON_DUMMY_MODULE4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_COREAON_INST, 0x00d0) + +/* CM_CORE.CORE_CM_CORE register offsets */ +#define DRA7XX_CM_L3MAIN1_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_L3MAIN1_DYNAMICDEP_OFFSET 0x0008 +#define DRA7XX_CM_L3MAIN1_L3_MAIN_1_CLKCTRL_OFFSET 0x0020 +#define DRA7XX_CM_L3MAIN1_L3_MAIN_1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0020) +#define DRA7XX_CM_L3MAIN1_GPMC_CLKCTRL_OFFSET 0x0028 +#define DRA7XX_CM_L3MAIN1_GPMC_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0028) +#define DRA7XX_CM_L3MAIN1_MMU_EDMA_CLKCTRL_OFFSET 0x0030 +#define DRA7XX_CM_L3MAIN1_MMU_EDMA_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0030) +#define DRA7XX_CM_L3MAIN1_OCMC_RAM1_CLKCTRL_OFFSET 0x0050 +#define DRA7XX_CM_L3MAIN1_OCMC_RAM1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0050) +#define DRA7XX_CM_L3MAIN1_OCMC_RAM2_CLKCTRL_OFFSET 0x0058 +#define DRA7XX_CM_L3MAIN1_OCMC_RAM2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0058) +#define DRA7XX_CM_L3MAIN1_OCMC_RAM3_CLKCTRL_OFFSET 0x0060 +#define DRA7XX_CM_L3MAIN1_OCMC_RAM3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0060) +#define DRA7XX_CM_L3MAIN1_OCMC_ROM_CLKCTRL_OFFSET 0x0068 +#define DRA7XX_CM_L3MAIN1_OCMC_ROM_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0068) +#define DRA7XX_CM_L3MAIN1_TPCC_CLKCTRL_OFFSET 0x0070 +#define DRA7XX_CM_L3MAIN1_TPCC_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0070) +#define DRA7XX_CM_L3MAIN1_TPTC1_CLKCTRL_OFFSET 0x0078 +#define DRA7XX_CM_L3MAIN1_TPTC1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0078) +#define DRA7XX_CM_L3MAIN1_TPTC2_CLKCTRL_OFFSET 0x0080 +#define DRA7XX_CM_L3MAIN1_TPTC2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0080) +#define DRA7XX_CM_L3MAIN1_VCP1_CLKCTRL_OFFSET 0x0088 +#define DRA7XX_CM_L3MAIN1_VCP1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0088) +#define DRA7XX_CM_L3MAIN1_VCP2_CLKCTRL_OFFSET 0x0090 +#define DRA7XX_CM_L3MAIN1_VCP2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0090) +#define DRA7XX_CM_L3MAIN1_SPARE_CME_CLKCTRL_OFFSET 0x0098 +#define DRA7XX_CM_L3MAIN1_SPARE_CME_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0098) +#define DRA7XX_CM_L3MAIN1_SPARE_HDMI_CLKCTRL_OFFSET 0x00a0 +#define DRA7XX_CM_L3MAIN1_SPARE_HDMI_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00a0) +#define DRA7XX_CM_L3MAIN1_SPARE_ICM_CLKCTRL_OFFSET 0x00a8 +#define DRA7XX_CM_L3MAIN1_SPARE_ICM_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00a8) +#define DRA7XX_CM_L3MAIN1_SPARE_IVA2_CLKCTRL_OFFSET 0x00b0 +#define DRA7XX_CM_L3MAIN1_SPARE_IVA2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00b0) +#define DRA7XX_CM_L3MAIN1_SPARE_SATA2_CLKCTRL_OFFSET 0x00b8 +#define DRA7XX_CM_L3MAIN1_SPARE_SATA2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00b8) +#define DRA7XX_CM_L3MAIN1_SPARE_UNKNOWN4_CLKCTRL_OFFSET 0x00c0 +#define DRA7XX_CM_L3MAIN1_SPARE_UNKNOWN4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00c0) +#define DRA7XX_CM_L3MAIN1_SPARE_UNKNOWN5_CLKCTRL_OFFSET 0x00c8 +#define DRA7XX_CM_L3MAIN1_SPARE_UNKNOWN5_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00c8) +#define DRA7XX_CM_L3MAIN1_SPARE_UNKNOWN6_CLKCTRL_OFFSET 0x00d0 +#define DRA7XX_CM_L3MAIN1_SPARE_UNKNOWN6_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00d0) +#define DRA7XX_CM_L3MAIN1_SPARE_VIDEOPLL1_CLKCTRL_OFFSET 0x00d8 +#define DRA7XX_CM_L3MAIN1_SPARE_VIDEOPLL1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00d8) +#define DRA7XX_CM_L3MAIN1_SPARE_VIDEOPLL2_CLKCTRL_OFFSET 0x00f0 +#define DRA7XX_CM_L3MAIN1_SPARE_VIDEOPLL2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00f0) +#define DRA7XX_CM_L3MAIN1_SPARE_VIDEOPLL3_CLKCTRL_OFFSET 0x00f8 +#define DRA7XX_CM_L3MAIN1_SPARE_VIDEOPLL3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x00f8) +#define DRA7XX_CM_IPU2_CLKSTCTRL_OFFSET 0x0200 +#define DRA7XX_CM_IPU2_STATICDEP_OFFSET 0x0204 +#define DRA7XX_CM_IPU2_DYNAMICDEP_OFFSET 0x0208 +#define DRA7XX_CM_IPU2_IPU2_CLKCTRL_OFFSET 0x0220 +#define DRA7XX_CM_IPU2_IPU2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0220) +#define DRA7XX_CM_DMA_CLKSTCTRL_OFFSET 0x0300 +#define DRA7XX_CM_DMA_STATICDEP_OFFSET 0x0304 +#define DRA7XX_CM_DMA_DYNAMICDEP_OFFSET 0x0308 +#define DRA7XX_CM_DMA_DMA_SYSTEM_CLKCTRL_OFFSET 0x0320 +#define DRA7XX_CM_DMA_DMA_SYSTEM_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0320) +#define DRA7XX_CM_EMIF_CLKSTCTRL_OFFSET 0x0400 +#define DRA7XX_CM_EMIF_DMM_CLKCTRL_OFFSET 0x0420 +#define DRA7XX_CM_EMIF_DMM_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0420) +#define DRA7XX_CM_EMIF_EMIF_OCP_FW_CLKCTRL_OFFSET 0x0428 +#define DRA7XX_CM_EMIF_EMIF_OCP_FW_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0428) +#define DRA7XX_CM_EMIF_EMIF1_CLKCTRL_OFFSET 0x0430 +#define DRA7XX_CM_EMIF_EMIF1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0430) +#define DRA7XX_CM_EMIF_EMIF2_CLKCTRL_OFFSET 0x0438 +#define DRA7XX_CM_EMIF_EMIF2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0438) +#define DRA7XX_CM_EMIF_EMIF_DLL_CLKCTRL_OFFSET 0x0440 +#define DRA7XX_CM_EMIF_EMIF_DLL_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0440) +#define DRA7XX_CM_ATL_ATL_CLKCTRL_OFFSET 0x0500 +#define DRA7XX_CM_ATL_ATL_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0500) +#define DRA7XX_CM_ATL_CLKSTCTRL_OFFSET 0x0520 +#define DRA7XX_CM_L4CFG_CLKSTCTRL_OFFSET 0x0600 +#define DRA7XX_CM_L4CFG_DYNAMICDEP_OFFSET 0x0608 +#define DRA7XX_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET 0x0620 +#define DRA7XX_CM_L4CFG_L4_CFG_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0620) +#define DRA7XX_CM_L4CFG_SPINLOCK_CLKCTRL_OFFSET 0x0628 +#define DRA7XX_CM_L4CFG_SPINLOCK_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0628) +#define DRA7XX_CM_L4CFG_MAILBOX1_CLKCTRL_OFFSET 0x0630 +#define DRA7XX_CM_L4CFG_MAILBOX1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0630) +#define DRA7XX_CM_L4CFG_SAR_ROM_CLKCTRL_OFFSET 0x0638 +#define DRA7XX_CM_L4CFG_SAR_ROM_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0638) +#define DRA7XX_CM_L4CFG_OCP2SCP2_CLKCTRL_OFFSET 0x0640 +#define DRA7XX_CM_L4CFG_OCP2SCP2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0640) +#define DRA7XX_CM_L4CFG_MAILBOX2_CLKCTRL_OFFSET 0x0648 +#define DRA7XX_CM_L4CFG_MAILBOX2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0648) +#define DRA7XX_CM_L4CFG_MAILBOX3_CLKCTRL_OFFSET 0x0650 +#define DRA7XX_CM_L4CFG_MAILBOX3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0650) +#define DRA7XX_CM_L4CFG_MAILBOX4_CLKCTRL_OFFSET 0x0658 +#define DRA7XX_CM_L4CFG_MAILBOX4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0658) +#define DRA7XX_CM_L4CFG_MAILBOX5_CLKCTRL_OFFSET 0x0660 +#define DRA7XX_CM_L4CFG_MAILBOX5_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0660) +#define DRA7XX_CM_L4CFG_MAILBOX6_CLKCTRL_OFFSET 0x0668 +#define DRA7XX_CM_L4CFG_MAILBOX6_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0668) +#define DRA7XX_CM_L4CFG_MAILBOX7_CLKCTRL_OFFSET 0x0670 +#define DRA7XX_CM_L4CFG_MAILBOX7_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0670) +#define DRA7XX_CM_L4CFG_MAILBOX8_CLKCTRL_OFFSET 0x0678 +#define DRA7XX_CM_L4CFG_MAILBOX8_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0678) +#define DRA7XX_CM_L4CFG_MAILBOX9_CLKCTRL_OFFSET 0x0680 +#define DRA7XX_CM_L4CFG_MAILBOX9_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0680) +#define DRA7XX_CM_L4CFG_MAILBOX10_CLKCTRL_OFFSET 0x0688 +#define DRA7XX_CM_L4CFG_MAILBOX10_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0688) +#define DRA7XX_CM_L4CFG_MAILBOX11_CLKCTRL_OFFSET 0x0690 +#define DRA7XX_CM_L4CFG_MAILBOX11_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0690) +#define DRA7XX_CM_L4CFG_MAILBOX12_CLKCTRL_OFFSET 0x0698 +#define DRA7XX_CM_L4CFG_MAILBOX12_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0698) +#define DRA7XX_CM_L4CFG_MAILBOX13_CLKCTRL_OFFSET 0x06a0 +#define DRA7XX_CM_L4CFG_MAILBOX13_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x06a0) +#define DRA7XX_CM_L4CFG_SPARE_SMARTREFLEX_RTC_CLKCTRL_OFFSET 0x06a8 +#define DRA7XX_CM_L4CFG_SPARE_SMARTREFLEX_RTC_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x06a8) +#define DRA7XX_CM_L4CFG_SPARE_SMARTREFLEX_SDRAM_CLKCTRL_OFFSET 0x06b0 +#define DRA7XX_CM_L4CFG_SPARE_SMARTREFLEX_SDRAM_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x06b0) +#define DRA7XX_CM_L4CFG_SPARE_SMARTREFLEX_WKUP_CLKCTRL_OFFSET 0x06b8 +#define DRA7XX_CM_L4CFG_SPARE_SMARTREFLEX_WKUP_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x06b8) +#define DRA7XX_CM_L4CFG_IO_DELAY_BLOCK_CLKCTRL_OFFSET 0x06c0 +#define DRA7XX_CM_L4CFG_IO_DELAY_BLOCK_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x06c0) +#define DRA7XX_CM_L3INSTR_CLKSTCTRL_OFFSET 0x0700 +#define DRA7XX_CM_L3INSTR_L3_MAIN_2_CLKCTRL_OFFSET 0x0720 +#define DRA7XX_CM_L3INSTR_L3_MAIN_2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0720) +#define DRA7XX_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET 0x0728 +#define DRA7XX_CM_L3INSTR_L3_INSTR_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0728) +#define DRA7XX_CM_L3INSTR_OCP_WP_NOC_CLKCTRL_OFFSET 0x0740 +#define DRA7XX_CM_L3INSTR_OCP_WP_NOC_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0740) +#define DRA7XX_CM_L3INSTR_DLL_AGING_CLKCTRL_OFFSET 0x0748 +#define DRA7XX_CM_L3INSTR_DLL_AGING_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0748) +#define DRA7XX_CM_L3INSTR_CTRL_MODULE_BANDGAP_CLKCTRL_OFFSET 0x0750 +#define DRA7XX_CM_L3INSTR_CTRL_MODULE_BANDGAP_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CORE_INST, 0x0750) + +/* CM_CORE.IVA_CM_CORE register offsets */ +#define DRA7XX_CM_IVA_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_IVA_STATICDEP_OFFSET 0x0004 +#define DRA7XX_CM_IVA_DYNAMICDEP_OFFSET 0x0008 +#define DRA7XX_CM_IVA_IVA_CLKCTRL_OFFSET 0x0020 +#define DRA7XX_CM_IVA_IVA_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_IVA_INST, 0x0020) +#define DRA7XX_CM_IVA_SL2_CLKCTRL_OFFSET 0x0028 +#define DRA7XX_CM_IVA_SL2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_IVA_INST, 0x0028) + +/* CM_CORE.CAM_CM_CORE register offsets */ +#define DRA7XX_CM_CAM_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_CAM_STATICDEP_OFFSET 0x0004 +#define DRA7XX_CM_CAM_VIP1_CLKCTRL_OFFSET 0x0020 +#define DRA7XX_CM_CAM_VIP1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CAM_INST, 0x0020) +#define DRA7XX_CM_CAM_VIP2_CLKCTRL_OFFSET 0x0028 +#define DRA7XX_CM_CAM_VIP2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CAM_INST, 0x0028) +#define DRA7XX_CM_CAM_VIP3_CLKCTRL_OFFSET 0x0030 +#define DRA7XX_CM_CAM_VIP3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CAM_INST, 0x0030) +#define DRA7XX_CM_CAM_LVDSRX_CLKCTRL_OFFSET 0x0038 +#define DRA7XX_CM_CAM_LVDSRX_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CAM_INST, 0x0038) +#define DRA7XX_CM_CAM_CSI1_CLKCTRL_OFFSET 0x0040 +#define DRA7XX_CM_CAM_CSI1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CAM_INST, 0x0040) +#define DRA7XX_CM_CAM_CSI2_CLKCTRL_OFFSET 0x0048 +#define DRA7XX_CM_CAM_CSI2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CAM_INST, 0x0048) + +/* CM_CORE.DSS_CM_CORE register offsets */ +#define DRA7XX_CM_DSS_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_DSS_STATICDEP_OFFSET 0x0004 +#define DRA7XX_CM_DSS_DYNAMICDEP_OFFSET 0x0008 +#define DRA7XX_CM_DSS_DSS_CLKCTRL_OFFSET 0x0020 +#define DRA7XX_CM_DSS_DSS_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_DSS_INST, 0x0020) +#define DRA7XX_CM_DSS_BB2D_CLKCTRL_OFFSET 0x0030 +#define DRA7XX_CM_DSS_BB2D_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_DSS_INST, 0x0030) +#define DRA7XX_CM_DSS_SDVENC_CLKCTRL_OFFSET 0x003c +#define DRA7XX_CM_DSS_SDVENC_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_DSS_INST, 0x003c) + +/* CM_CORE.GPU_CM_CORE register offsets */ +#define DRA7XX_CM_GPU_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_GPU_STATICDEP_OFFSET 0x0004 +#define DRA7XX_CM_GPU_DYNAMICDEP_OFFSET 0x0008 +#define DRA7XX_CM_GPU_GPU_CLKCTRL_OFFSET 0x0020 +#define DRA7XX_CM_GPU_GPU_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_GPU_INST, 0x0020) + +/* CM_CORE.L3INIT_CM_CORE register offsets */ +#define DRA7XX_CM_L3INIT_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_L3INIT_STATICDEP_OFFSET 0x0004 +#define DRA7XX_CM_L3INIT_DYNAMICDEP_OFFSET 0x0008 +#define DRA7XX_CM_L3INIT_MMC1_CLKCTRL_OFFSET 0x0028 +#define DRA7XX_CM_L3INIT_MMC1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x0028) +#define DRA7XX_CM_L3INIT_MMC2_CLKCTRL_OFFSET 0x0030 +#define DRA7XX_CM_L3INIT_MMC2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x0030) +#define DRA7XX_CM_L3INIT_USB_OTG_SS2_CLKCTRL_OFFSET 0x0040 +#define DRA7XX_CM_L3INIT_USB_OTG_SS2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x0040) +#define DRA7XX_CM_L3INIT_USB_OTG_SS3_CLKCTRL_OFFSET 0x0048 +#define DRA7XX_CM_L3INIT_USB_OTG_SS3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x0048) +#define DRA7XX_CM_L3INIT_USB_OTG_SS4_CLKCTRL_OFFSET 0x0050 +#define DRA7XX_CM_L3INIT_USB_OTG_SS4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x0050) +#define DRA7XX_CM_L3INIT_MLB_SS_CLKCTRL_OFFSET 0x0058 +#define DRA7XX_CM_L3INIT_MLB_SS_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x0058) +#define DRA7XX_CM_L3INIT_IEEE1500_2_OCP_CLKCTRL_OFFSET 0x0078 +#define DRA7XX_CM_L3INIT_IEEE1500_2_OCP_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x0078) +#define DRA7XX_CM_L3INIT_SATA_CLKCTRL_OFFSET 0x0088 +#define DRA7XX_CM_L3INIT_SATA_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x0088) +#define DRA7XX_CM_PCIE_CLKSTCTRL_OFFSET 0x00a0 +#define DRA7XX_CM_PCIE_STATICDEP_OFFSET 0x00a4 +#define DRA7XX_CM_GMAC_CLKSTCTRL_OFFSET 0x00c0 +#define DRA7XX_CM_GMAC_STATICDEP_OFFSET 0x00c4 +#define DRA7XX_CM_GMAC_DYNAMICDEP_OFFSET 0x00c8 +#define DRA7XX_CM_GMAC_GMAC_CLKCTRL_OFFSET 0x00d0 +#define DRA7XX_CM_GMAC_GMAC_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x00d0) +#define DRA7XX_CM_L3INIT_OCP2SCP1_CLKCTRL_OFFSET 0x00e0 +#define DRA7XX_CM_L3INIT_OCP2SCP1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x00e0) +#define DRA7XX_CM_L3INIT_OCP2SCP3_CLKCTRL_OFFSET 0x00e8 +#define DRA7XX_CM_L3INIT_OCP2SCP3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x00e8) +#define DRA7XX_CM_L3INIT_USB_OTG_SS1_CLKCTRL_OFFSET 0x00f0 +#define DRA7XX_CM_L3INIT_USB_OTG_SS1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L3INIT_INST, 0x00f0) + +/* CM_CORE.CUSTEFUSE_CM_CORE register offsets */ +#define DRA7XX_CM_CUSTEFUSE_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_CUSTEFUSE_EFUSE_CTRL_CUST_CLKCTRL_OFFSET 0x0020 +#define DRA7XX_CM_CUSTEFUSE_EFUSE_CTRL_CUST_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_CUSTEFUSE_INST, 0x0020) + +/* CM_CORE.L4PER_CM_CORE register offsets */ +#define DRA7XX_CM_L4PER_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_L4PER_DYNAMICDEP_OFFSET 0x0008 +#define DRA7XX_CM_L4PER2_L4_PER2_CLKCTRL_OFFSET 0x000c +#define DRA7XX_CM_L4PER2_L4_PER2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x000c) +#define DRA7XX_CM_L4PER3_L4_PER3_CLKCTRL_OFFSET 0x0014 +#define DRA7XX_CM_L4PER3_L4_PER3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0014) +#define DRA7XX_CM_L4PER2_PRUSS1_CLKCTRL_OFFSET 0x0018 +#define DRA7XX_CM_L4PER2_PRUSS1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0018) +#define DRA7XX_CM_L4PER2_PRUSS2_CLKCTRL_OFFSET 0x0020 +#define DRA7XX_CM_L4PER2_PRUSS2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0020) +#define DRA7XX_CM_L4PER_TIMER10_CLKCTRL_OFFSET 0x0028 +#define DRA7XX_CM_L4PER_TIMER10_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0028) +#define DRA7XX_CM_L4PER_TIMER11_CLKCTRL_OFFSET 0x0030 +#define DRA7XX_CM_L4PER_TIMER11_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0030) +#define DRA7XX_CM_L4PER_TIMER2_CLKCTRL_OFFSET 0x0038 +#define DRA7XX_CM_L4PER_TIMER2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0038) +#define DRA7XX_CM_L4PER_TIMER3_CLKCTRL_OFFSET 0x0040 +#define DRA7XX_CM_L4PER_TIMER3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0040) +#define DRA7XX_CM_L4PER_TIMER4_CLKCTRL_OFFSET 0x0048 +#define DRA7XX_CM_L4PER_TIMER4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0048) +#define DRA7XX_CM_L4PER_TIMER9_CLKCTRL_OFFSET 0x0050 +#define DRA7XX_CM_L4PER_TIMER9_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0050) +#define DRA7XX_CM_L4PER_ELM_CLKCTRL_OFFSET 0x0058 +#define DRA7XX_CM_L4PER_ELM_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0058) +#define DRA7XX_CM_L4PER_GPIO2_CLKCTRL_OFFSET 0x0060 +#define DRA7XX_CM_L4PER_GPIO2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0060) +#define DRA7XX_CM_L4PER_GPIO3_CLKCTRL_OFFSET 0x0068 +#define DRA7XX_CM_L4PER_GPIO3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0068) +#define DRA7XX_CM_L4PER_GPIO4_CLKCTRL_OFFSET 0x0070 +#define DRA7XX_CM_L4PER_GPIO4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0070) +#define DRA7XX_CM_L4PER_GPIO5_CLKCTRL_OFFSET 0x0078 +#define DRA7XX_CM_L4PER_GPIO5_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0078) +#define DRA7XX_CM_L4PER_GPIO6_CLKCTRL_OFFSET 0x0080 +#define DRA7XX_CM_L4PER_GPIO6_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0080) +#define DRA7XX_CM_L4PER_HDQ1W_CLKCTRL_OFFSET 0x0088 +#define DRA7XX_CM_L4PER_HDQ1W_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0088) +#define DRA7XX_CM_L4PER2_PWMSS2_CLKCTRL_OFFSET 0x0090 +#define DRA7XX_CM_L4PER2_PWMSS2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0090) +#define DRA7XX_CM_L4PER2_PWMSS3_CLKCTRL_OFFSET 0x0098 +#define DRA7XX_CM_L4PER2_PWMSS3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0098) +#define DRA7XX_CM_L4PER_I2C1_CLKCTRL_OFFSET 0x00a0 +#define DRA7XX_CM_L4PER_I2C1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00a0) +#define DRA7XX_CM_L4PER_I2C2_CLKCTRL_OFFSET 0x00a8 +#define DRA7XX_CM_L4PER_I2C2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00a8) +#define DRA7XX_CM_L4PER_I2C3_CLKCTRL_OFFSET 0x00b0 +#define DRA7XX_CM_L4PER_I2C3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00b0) +#define DRA7XX_CM_L4PER_I2C4_CLKCTRL_OFFSET 0x00b8 +#define DRA7XX_CM_L4PER_I2C4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00b8) +#define DRA7XX_CM_L4PER_L4_PER1_CLKCTRL_OFFSET 0x00c0 +#define DRA7XX_CM_L4PER_L4_PER1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00c0) +#define DRA7XX_CM_L4PER2_PWMSS1_CLKCTRL_OFFSET 0x00c4 +#define DRA7XX_CM_L4PER2_PWMSS1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00c4) +#define DRA7XX_CM_L4PER3_TIMER13_CLKCTRL_OFFSET 0x00c8 +#define DRA7XX_CM_L4PER3_TIMER13_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00c8) +#define DRA7XX_CM_L4PER3_TIMER14_CLKCTRL_OFFSET 0x00d0 +#define DRA7XX_CM_L4PER3_TIMER14_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00d0) +#define DRA7XX_CM_L4PER3_TIMER15_CLKCTRL_OFFSET 0x00d8 +#define DRA7XX_CM_L4PER3_TIMER15_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00d8) +#define DRA7XX_CM_L4PER_MCSPI1_CLKCTRL_OFFSET 0x00f0 +#define DRA7XX_CM_L4PER_MCSPI1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00f0) +#define DRA7XX_CM_L4PER_MCSPI2_CLKCTRL_OFFSET 0x00f8 +#define DRA7XX_CM_L4PER_MCSPI2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x00f8) +#define DRA7XX_CM_L4PER_MCSPI3_CLKCTRL_OFFSET 0x0100 +#define DRA7XX_CM_L4PER_MCSPI3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0100) +#define DRA7XX_CM_L4PER_MCSPI4_CLKCTRL_OFFSET 0x0108 +#define DRA7XX_CM_L4PER_MCSPI4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0108) +#define DRA7XX_CM_L4PER_GPIO7_CLKCTRL_OFFSET 0x0110 +#define DRA7XX_CM_L4PER_GPIO7_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0110) +#define DRA7XX_CM_L4PER_GPIO8_CLKCTRL_OFFSET 0x0118 +#define DRA7XX_CM_L4PER_GPIO8_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0118) +#define DRA7XX_CM_L4PER_MMC3_CLKCTRL_OFFSET 0x0120 +#define DRA7XX_CM_L4PER_MMC3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0120) +#define DRA7XX_CM_L4PER_MMC4_CLKCTRL_OFFSET 0x0128 +#define DRA7XX_CM_L4PER_MMC4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0128) +#define DRA7XX_CM_L4PER3_TIMER16_CLKCTRL_OFFSET 0x0130 +#define DRA7XX_CM_L4PER3_TIMER16_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0130) +#define DRA7XX_CM_L4PER2_QSPI_CLKCTRL_OFFSET 0x0138 +#define DRA7XX_CM_L4PER2_QSPI_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0138) +#define DRA7XX_CM_L4PER_UART1_CLKCTRL_OFFSET 0x0140 +#define DRA7XX_CM_L4PER_UART1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0140) +#define DRA7XX_CM_L4PER_UART2_CLKCTRL_OFFSET 0x0148 +#define DRA7XX_CM_L4PER_UART2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0148) +#define DRA7XX_CM_L4PER_UART3_CLKCTRL_OFFSET 0x0150 +#define DRA7XX_CM_L4PER_UART3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0150) +#define DRA7XX_CM_L4PER_UART4_CLKCTRL_OFFSET 0x0158 +#define DRA7XX_CM_L4PER_UART4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0158) +#define DRA7XX_CM_L4PER2_MCASP2_CLKCTRL_OFFSET 0x0160 +#define DRA7XX_CM_L4PER2_MCASP2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0160) +#define DRA7XX_CM_L4PER2_MCASP3_CLKCTRL_OFFSET 0x0168 +#define DRA7XX_CM_L4PER2_MCASP3_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0168) +#define DRA7XX_CM_L4PER_UART5_CLKCTRL_OFFSET 0x0170 +#define DRA7XX_CM_L4PER_UART5_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0170) +#define DRA7XX_CM_L4PER2_MCASP5_CLKCTRL_OFFSET 0x0178 +#define DRA7XX_CM_L4PER2_MCASP5_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0178) +#define DRA7XX_CM_L4SEC_CLKSTCTRL_OFFSET 0x0180 +#define DRA7XX_CM_L4SEC_STATICDEP_OFFSET 0x0184 +#define DRA7XX_CM_L4SEC_DYNAMICDEP_OFFSET 0x0188 +#define DRA7XX_CM_L4PER2_MCASP8_CLKCTRL_OFFSET 0x0190 +#define DRA7XX_CM_L4PER2_MCASP8_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0190) +#define DRA7XX_CM_L4PER2_MCASP4_CLKCTRL_OFFSET 0x0198 +#define DRA7XX_CM_L4PER2_MCASP4_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0198) +#define DRA7XX_CM_L4SEC_AES1_CLKCTRL_OFFSET 0x01a0 +#define DRA7XX_CM_L4SEC_AES1_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01a0) +#define DRA7XX_CM_L4SEC_AES2_CLKCTRL_OFFSET 0x01a8 +#define DRA7XX_CM_L4SEC_AES2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01a8) +#define DRA7XX_CM_L4SEC_DES3DES_CLKCTRL_OFFSET 0x01b0 +#define DRA7XX_CM_L4SEC_DES3DES_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01b0) +#define DRA7XX_CM_L4SEC_FPKA_CLKCTRL_OFFSET 0x01b8 +#define DRA7XX_CM_L4SEC_FPKA_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01b8) +#define DRA7XX_CM_L4SEC_RNG_CLKCTRL_OFFSET 0x01c0 +#define DRA7XX_CM_L4SEC_RNG_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01c0) +#define DRA7XX_CM_L4SEC_SHA2MD51_CLKCTRL_OFFSET 0x01c8 +#define DRA7XX_CM_L4SEC_SHA2MD51_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01c8) +#define DRA7XX_CM_L4PER2_UART7_CLKCTRL_OFFSET 0x01d0 +#define DRA7XX_CM_L4PER2_UART7_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01d0) +#define DRA7XX_CM_L4SEC_DMA_CRYPTO_CLKCTRL_OFFSET 0x01d8 +#define DRA7XX_CM_L4SEC_DMA_CRYPTO_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01d8) +#define DRA7XX_CM_L4PER2_UART8_CLKCTRL_OFFSET 0x01e0 +#define DRA7XX_CM_L4PER2_UART8_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01e0) +#define DRA7XX_CM_L4PER2_UART9_CLKCTRL_OFFSET 0x01e8 +#define DRA7XX_CM_L4PER2_UART9_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01e8) +#define DRA7XX_CM_L4PER2_DCAN2_CLKCTRL_OFFSET 0x01f0 +#define DRA7XX_CM_L4PER2_DCAN2_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01f0) +#define DRA7XX_CM_L4SEC_SHA2MD52_CLKCTRL_OFFSET 0x01f8 +#define DRA7XX_CM_L4SEC_SHA2MD52_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x01f8) +#define DRA7XX_CM_L4PER2_CLKSTCTRL_OFFSET 0x01fc +#define DRA7XX_CM_L4PER2_DYNAMICDEP_OFFSET 0x0200 +#define DRA7XX_CM_L4PER2_MCASP6_CLKCTRL_OFFSET 0x0204 +#define DRA7XX_CM_L4PER2_MCASP6_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0204) +#define DRA7XX_CM_L4PER2_MCASP7_CLKCTRL_OFFSET 0x0208 +#define DRA7XX_CM_L4PER2_MCASP7_CLKCTRL DRA7XX_CM_CORE_REGADDR(DRA7XX_CM_CORE_L4PER_INST, 0x0208) +#define DRA7XX_CM_L4PER2_STATICDEP_OFFSET 0x020c +#define DRA7XX_CM_L4PER3_CLKSTCTRL_OFFSET 0x0210 +#define DRA7XX_CM_L4PER3_DYNAMICDEP_OFFSET 0x0214 + +#endif diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c new file mode 100644 index 00000000000..8be6ea50c09 --- /dev/null +++ b/arch/arm/mach-omap2/cm2xxx.c @@ -0,0 +1,412 @@ +/* + * OMAP2xxx CM module functions + * + * Copyright (C) 2009 Nokia Corporation + * Copyright (C) 2008-2010, 2012 Texas Instruments, Inc. + * Paul Walmsley + * Rajendra Nayak <rnayak@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/io.h> + +#include "prm2xxx.h" +#include "cm.h" +#include "cm2xxx.h" +#include "cm-regbits-24xx.h" +#include "clockdomain.h" + +/* CM_AUTOIDLE_PLL.AUTO_* bit values for DPLLs */ +#define DPLL_AUTOIDLE_DISABLE 0x0 +#define OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP 0x3 + +/* CM_AUTOIDLE_PLL.AUTO_* bit values for APLLs (OMAP2xxx only) */ +#define OMAP2XXX_APLL_AUTOIDLE_DISABLE 0x0 +#define OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP 0x3 + +/* CM_IDLEST_PLL bit value offset for APLLs (OMAP2xxx only) */ +#define EN_APLL_LOCKED 3 + +static const u8 omap2xxx_cm_idlest_offs[] = { + CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3, OMAP24XX_CM_IDLEST4 +}; + +/* + * + */ + +static void _write_clktrctrl(u8 c, s16 module, u32 mask) +{ + u32 v; + + v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL); + v &= ~mask; + v |= c << __ffs(mask); + omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL); +} + +bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask) +{ + u32 v; + + v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL); + v &= mask; + v >>= __ffs(mask); + + return (v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0; +} + +void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask) +{ + _write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask); +} + +void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask) +{ + _write_clktrctrl(OMAP24XX_CLKSTCTRL_DISABLE_AUTO, module, mask); +} + +/* + * DPLL autoidle control + */ + +static void _omap2xxx_set_dpll_autoidle(u8 m) +{ + u32 v; + + v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE); + v &= ~OMAP24XX_AUTO_DPLL_MASK; + v |= m << OMAP24XX_AUTO_DPLL_SHIFT; + omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE); +} + +void omap2xxx_cm_set_dpll_disable_autoidle(void) +{ + _omap2xxx_set_dpll_autoidle(OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP); +} + +void omap2xxx_cm_set_dpll_auto_low_power_stop(void) +{ + _omap2xxx_set_dpll_autoidle(DPLL_AUTOIDLE_DISABLE); +} + +/* + * APLL control + */ + +static void _omap2xxx_set_apll_autoidle(u8 m, u32 mask) +{ + u32 v; + + v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE); + v &= ~mask; + v |= m << __ffs(mask); + omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE); +} + +void omap2xxx_cm_set_apll54_disable_autoidle(void) +{ + _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP, + OMAP24XX_AUTO_54M_MASK); +} + +void omap2xxx_cm_set_apll54_auto_low_power_stop(void) +{ + _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE, + OMAP24XX_AUTO_54M_MASK); +} + +void omap2xxx_cm_set_apll96_disable_autoidle(void) +{ + _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP, + OMAP24XX_AUTO_96M_MASK); +} + +void omap2xxx_cm_set_apll96_auto_low_power_stop(void) +{ + _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE, + OMAP24XX_AUTO_96M_MASK); +} + +/* Enable an APLL if off */ +static int _omap2xxx_apll_enable(u8 enable_bit, u8 status_bit) +{ + u32 v, m; + + m = EN_APLL_LOCKED << enable_bit; + + v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN); + if (v & m) + return 0; /* apll already enabled */ + + v |= m; + omap2_cm_write_mod_reg(v, PLL_MOD, CM_CLKEN); + + omap2xxx_cm_wait_module_ready(PLL_MOD, 1, status_bit); + + /* + * REVISIT: Should we return an error code if + * omap2xxx_cm_wait_module_ready() fails? + */ + return 0; +} + +/* Stop APLL */ +static void _omap2xxx_apll_disable(u8 enable_bit) +{ + u32 v; + + v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN); + v &= ~(EN_APLL_LOCKED << enable_bit); + omap2_cm_write_mod_reg(v, PLL_MOD, CM_CLKEN); +} + +/* Enable an APLL if off */ +int omap2xxx_cm_apll54_enable(void) +{ + return _omap2xxx_apll_enable(OMAP24XX_EN_54M_PLL_SHIFT, + OMAP24XX_ST_54M_APLL_SHIFT); +} + +/* Enable an APLL if off */ +int omap2xxx_cm_apll96_enable(void) +{ + return _omap2xxx_apll_enable(OMAP24XX_EN_96M_PLL_SHIFT, + OMAP24XX_ST_96M_APLL_SHIFT); +} + +/* Stop APLL */ +void omap2xxx_cm_apll54_disable(void) +{ + _omap2xxx_apll_disable(OMAP24XX_EN_54M_PLL_SHIFT); +} + +/* Stop APLL */ +void omap2xxx_cm_apll96_disable(void) +{ + _omap2xxx_apll_disable(OMAP24XX_EN_96M_PLL_SHIFT); +} + +/** + * omap2xxx_cm_split_idlest_reg - split CM_IDLEST reg addr into its components + * @idlest_reg: CM_IDLEST* virtual address + * @prcm_inst: pointer to an s16 to return the PRCM instance offset + * @idlest_reg_id: pointer to a u8 to return the CM_IDLESTx register ID + * + * XXX This function is only needed until absolute register addresses are + * removed from the OMAP struct clk records. + */ +int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, + u8 *idlest_reg_id) +{ + unsigned long offs; + u8 idlest_offs; + int i; + + if (idlest_reg < cm_base || idlest_reg > (cm_base + 0x0fff)) + return -EINVAL; + + idlest_offs = (unsigned long)idlest_reg & 0xff; + for (i = 0; i < ARRAY_SIZE(omap2xxx_cm_idlest_offs); i++) { + if (idlest_offs == omap2xxx_cm_idlest_offs[i]) { + *idlest_reg_id = i + 1; + break; + } + } + + if (i == ARRAY_SIZE(omap2xxx_cm_idlest_offs)) + return -EINVAL; + + offs = idlest_reg - cm_base; + offs &= 0xff00; + *prcm_inst = offs; + + return 0; +} + +/* + * + */ + +/** + * omap2xxx_cm_wait_module_ready - wait for a module to leave idle or standby + * @prcm_mod: PRCM module offset + * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3) + * @idlest_shift: shift of the bit in the CM_IDLEST* register to check + * + * Wait for the PRCM to indicate that the module identified by + * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon + * success or -EBUSY if the module doesn't enable in time. + */ +int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) +{ + int ena = 0, i = 0; + u8 cm_idlest_reg; + u32 mask; + + if (!idlest_id || (idlest_id > ARRAY_SIZE(omap2xxx_cm_idlest_offs))) + return -EINVAL; + + cm_idlest_reg = omap2xxx_cm_idlest_offs[idlest_id - 1]; + + mask = 1 << idlest_shift; + ena = mask; + + omap_test_timeout(((omap2_cm_read_mod_reg(prcm_mod, cm_idlest_reg) & + mask) == ena), MAX_MODULE_READY_TIME, i); + + return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; +} + +/* Clockdomain low-level functions */ + +static void omap2xxx_clkdm_allow_idle(struct clockdomain *clkdm) +{ + omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); +} + +static void omap2xxx_clkdm_deny_idle(struct clockdomain *clkdm) +{ + omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); +} + +static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm) +{ + bool hwsup = false; + + if (!clkdm->clktrctrl_mask) + return 0; + + hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + if (!hwsup && clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) + omap2xxx_clkdm_wakeup(clkdm); + + return 0; +} + +static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm) +{ + bool hwsup = false; + + if (!clkdm->clktrctrl_mask) + return 0; + + hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + + if (!hwsup && clkdm->flags & CLKDM_CAN_FORCE_SLEEP) + omap2xxx_clkdm_sleep(clkdm); + + return 0; +} + +struct clkdm_ops omap2_clkdm_operations = { + .clkdm_add_wkdep = omap2_clkdm_add_wkdep, + .clkdm_del_wkdep = omap2_clkdm_del_wkdep, + .clkdm_read_wkdep = omap2_clkdm_read_wkdep, + .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps, + .clkdm_sleep = omap2xxx_clkdm_sleep, + .clkdm_wakeup = omap2xxx_clkdm_wakeup, + .clkdm_allow_idle = omap2xxx_clkdm_allow_idle, + .clkdm_deny_idle = omap2xxx_clkdm_deny_idle, + .clkdm_clk_enable = omap2xxx_clkdm_clk_enable, + .clkdm_clk_disable = omap2xxx_clkdm_clk_disable, +}; + +int omap2xxx_cm_fclks_active(void) +{ + u32 f1, f2; + + f1 = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1); + f2 = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2); + + return (f1 | f2) ? 1 : 0; +} + +int omap2xxx_cm_mpu_retention_allowed(void) +{ + u32 l; + + /* Check for MMC, UART2, UART1, McSPI2, McSPI1 and DSS1. */ + l = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1); + if (l & (OMAP2420_EN_MMC_MASK | OMAP24XX_EN_UART2_MASK | + OMAP24XX_EN_UART1_MASK | OMAP24XX_EN_MCSPI2_MASK | + OMAP24XX_EN_MCSPI1_MASK | OMAP24XX_EN_DSS1_MASK)) + return 0; + /* Check for UART3. */ + l = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2); + if (l & OMAP24XX_EN_UART3_MASK) + return 0; + + return 1; +} + +u32 omap2xxx_cm_get_core_clk_src(void) +{ + u32 v; + + v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); + v &= OMAP24XX_CORE_CLK_SRC_MASK; + + return v; +} + +u32 omap2xxx_cm_get_core_pll_config(void) +{ + return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); +} + +u32 omap2xxx_cm_get_pll_config(void) +{ + return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL1); +} + +u32 omap2xxx_cm_get_pll_status(void) +{ + return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN); +} + +void omap2xxx_cm_set_mod_dividers(u32 mpu, u32 dsp, u32 gfx, u32 core, u32 mdm) +{ + u32 tmp; + + omap2_cm_write_mod_reg(mpu, MPU_MOD, CM_CLKSEL); + omap2_cm_write_mod_reg(dsp, OMAP24XX_DSP_MOD, CM_CLKSEL); + omap2_cm_write_mod_reg(gfx, GFX_MOD, CM_CLKSEL); + tmp = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & + OMAP24XX_CLKSEL_DSS2_MASK; + omap2_cm_write_mod_reg(core | tmp, CORE_MOD, CM_CLKSEL1); + if (mdm) + omap2_cm_write_mod_reg(mdm, OMAP2430_MDM_MOD, CM_CLKSEL); +} + +/* + * + */ + +static struct cm_ll_data omap2xxx_cm_ll_data = { + .split_idlest_reg = &omap2xxx_cm_split_idlest_reg, + .wait_module_ready = &omap2xxx_cm_wait_module_ready, +}; + +int __init omap2xxx_cm_init(void) +{ + return cm_register(&omap2xxx_cm_ll_data); +} + +static void __exit omap2xxx_cm_exit(void) +{ + cm_unregister(&omap2xxx_cm_ll_data); +} +__exitcall(omap2xxx_cm_exit); diff --git a/arch/arm/mach-omap2/cm2xxx.h b/arch/arm/mach-omap2/cm2xxx.h new file mode 100644 index 00000000000..891d81c3c8f --- /dev/null +++ b/arch/arm/mach-omap2/cm2xxx.h @@ -0,0 +1,78 @@ +/* + * OMAP2xxx Clock Management (CM) register definitions + * + * Copyright (C) 2007-2009, 2012 Texas Instruments, Inc. + * Copyright (C) 2007-2010 Nokia Corporation + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * The CM hardware modules on the OMAP2/3 are quite similar to each + * other. The CM modules/instances on OMAP4 are quite different, so + * they are handled in a separate file. + */ +#ifndef __ARCH_ASM_MACH_OMAP2_CM2XXX_H +#define __ARCH_ASM_MACH_OMAP2_CM2XXX_H + +#include "prcm-common.h" +#include "cm2xxx_3xxx.h" + +#define OMAP2420_CM_REGADDR(module, reg) \ + OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg)) +#define OMAP2430_CM_REGADDR(module, reg) \ + OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg)) + +/* + * Module specific CM register offsets from CM_BASE + domain offset + * Use cm_{read,write}_mod_reg() with these registers. + * These register offsets generally appear in more than one PRCM submodule. + */ + +/* OMAP2-specific register offsets */ + +#define OMAP24XX_CM_FCLKEN2 0x0004 +#define OMAP24XX_CM_ICLKEN4 0x001c +#define OMAP24XX_CM_AUTOIDLE4 0x003c +#define OMAP24XX_CM_IDLEST4 0x002c + +/* CM_IDLEST bit field values to indicate deasserted IdleReq */ + +#define OMAP24XX_CM_IDLEST_VAL 0 + + +/* Clock management domain register get/set */ + +#ifndef __ASSEMBLER__ + +extern void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask); +extern void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask); + +extern void omap2xxx_cm_set_dpll_disable_autoidle(void); +extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void); + +extern void omap2xxx_cm_set_apll54_disable_autoidle(void); +extern void omap2xxx_cm_set_apll54_auto_low_power_stop(void); +extern void omap2xxx_cm_set_apll96_disable_autoidle(void); +extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void); + +extern bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask); +extern int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, + u8 idlest_shift); +extern int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, + s16 *prcm_inst, u8 *idlest_reg_id); +extern int omap2xxx_cm_fclks_active(void); +extern int omap2xxx_cm_mpu_retention_allowed(void); +extern u32 omap2xxx_cm_get_core_clk_src(void); +extern u32 omap2xxx_cm_get_core_pll_config(void); +extern u32 omap2xxx_cm_get_pll_config(void); +extern u32 omap2xxx_cm_get_pll_status(void); +extern void omap2xxx_cm_set_mod_dividers(u32 mpu, u32 dsp, u32 gfx, u32 core, + u32 mdm); + +extern int __init omap2xxx_cm_init(void); + +#endif + +#endif diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h new file mode 100644 index 00000000000..72928a3ce2a --- /dev/null +++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h @@ -0,0 +1,120 @@ +/* + * OMAP2/3 Clock Management (CM) register definitions + * + * Copyright (C) 2007-2009 Texas Instruments, Inc. + * Copyright (C) 2007-2010 Nokia Corporation + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * The CM hardware modules on the OMAP2/3 are quite similar to each + * other. The CM modules/instances on OMAP4 are quite different, so + * they are handled in a separate file. + */ +#ifndef __ARCH_ASM_MACH_OMAP2_CM2XXX_3XXX_H +#define __ARCH_ASM_MACH_OMAP2_CM2XXX_3XXX_H + +#include "cm.h" + +/* + * Module specific CM register offsets from CM_BASE + domain offset + * Use cm_{read,write}_mod_reg() with these registers. + * These register offsets generally appear in more than one PRCM submodule. + */ + +/* Common between OMAP2 and OMAP3 */ + +#define CM_FCLKEN 0x0000 +#define CM_FCLKEN1 CM_FCLKEN +#define CM_CLKEN CM_FCLKEN +#define CM_ICLKEN 0x0010 +#define CM_ICLKEN1 CM_ICLKEN +#define CM_ICLKEN2 0x0014 +#define CM_ICLKEN3 0x0018 +#define CM_IDLEST 0x0020 +#define CM_IDLEST1 CM_IDLEST +#define CM_IDLEST2 0x0024 +#define OMAP2430_CM_IDLEST3 0x0028 +#define CM_AUTOIDLE 0x0030 +#define CM_AUTOIDLE1 CM_AUTOIDLE +#define CM_AUTOIDLE2 0x0034 +#define CM_AUTOIDLE3 0x0038 +#define CM_CLKSEL 0x0040 +#define CM_CLKSEL1 CM_CLKSEL +#define CM_CLKSEL2 0x0044 +#define OMAP2_CM_CLKSTCTRL 0x0048 + +#ifndef __ASSEMBLER__ + +#include <linux/io.h> + +static inline u32 omap2_cm_read_mod_reg(s16 module, u16 idx) +{ + return readl_relaxed(cm_base + module + idx); +} + +static inline void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx) +{ + writel_relaxed(val, cm_base + module + idx); +} + +/* Read-modify-write a register in a CM module. Caller must lock */ +static inline u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, + s16 idx) +{ + u32 v; + + v = omap2_cm_read_mod_reg(module, idx); + v &= ~mask; + v |= bits; + omap2_cm_write_mod_reg(v, module, idx); + + return v; +} + +/* Read a CM register, AND it, and shift the result down to bit 0 */ +static inline u32 omap2_cm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask) +{ + u32 v; + + v = omap2_cm_read_mod_reg(domain, idx); + v &= mask; + v >>= __ffs(mask); + + return v; +} + +static inline u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) +{ + return omap2_cm_rmw_mod_reg_bits(bits, bits, module, idx); +} + +static inline u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) +{ + return omap2_cm_rmw_mod_reg_bits(bits, 0x0, module, idx); +} + +extern int omap2xxx_cm_apll54_enable(void); +extern void omap2xxx_cm_apll54_disable(void); +extern int omap2xxx_cm_apll96_enable(void); +extern void omap2xxx_cm_apll96_disable(void); + +#endif + +/* CM register bits shared between 24XX and 3430 */ + +/* CM_CLKSEL_GFX */ +#define OMAP_CLKSEL_GFX_SHIFT 0 +#define OMAP_CLKSEL_GFX_MASK (0x7 << 0) +#define OMAP_CLKSEL_GFX_WIDTH 3 + +/* CM_ICLKEN_GFX */ +#define OMAP_EN_GFX_SHIFT 0 +#define OMAP_EN_GFX_MASK (1 << 0) + +/* CM_IDLEST_GFX */ +#define OMAP_ST_GFX_MASK (1 << 0) + +#endif diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c new file mode 100644 index 00000000000..b3f99e93def --- /dev/null +++ b/arch/arm/mach-omap2/cm33xx.c @@ -0,0 +1,364 @@ +/* + * AM33XX CM functions + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * Vaibhav Hiremath <hvaibhav@ti.com> + * + * Reference taken from from OMAP4 cminst44xx.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/io.h> + +#include "clockdomain.h" +#include "cm.h" +#include "cm33xx.h" +#include "cm-regbits-34xx.h" +#include "cm-regbits-33xx.h" +#include "prm33xx.h" + +/* + * CLKCTRL_IDLEST_*: possible values for the CM_*_CLKCTRL.IDLEST bitfield: + * + * 0x0 func: Module is fully functional, including OCP + * 0x1 trans: Module is performing transition: wakeup, or sleep, or sleep + * abortion + * 0x2 idle: Module is in Idle mode (only OCP part). It is functional if + * using separate functional clock + * 0x3 disabled: Module is disabled and cannot be accessed + * + */ +#define CLKCTRL_IDLEST_FUNCTIONAL 0x0 +#define CLKCTRL_IDLEST_INTRANSITION 0x1 +#define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2 +#define CLKCTRL_IDLEST_DISABLED 0x3 + +/* Private functions */ + +/* Read a register in a CM instance */ +static inline u32 am33xx_cm_read_reg(u16 inst, u16 idx) +{ + return readl_relaxed(cm_base + inst + idx); +} + +/* Write into a register in a CM */ +static inline void am33xx_cm_write_reg(u32 val, u16 inst, u16 idx) +{ + writel_relaxed(val, cm_base + inst + idx); +} + +/* Read-modify-write a register in CM */ +static inline u32 am33xx_cm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx) +{ + u32 v; + + v = am33xx_cm_read_reg(inst, idx); + v &= ~mask; + v |= bits; + am33xx_cm_write_reg(v, inst, idx); + + return v; +} + +static inline u32 am33xx_cm_set_reg_bits(u32 bits, s16 inst, s16 idx) +{ + return am33xx_cm_rmw_reg_bits(bits, bits, inst, idx); +} + +static inline u32 am33xx_cm_clear_reg_bits(u32 bits, s16 inst, s16 idx) +{ + return am33xx_cm_rmw_reg_bits(bits, 0x0, inst, idx); +} + +static inline u32 am33xx_cm_read_reg_bits(u16 inst, s16 idx, u32 mask) +{ + u32 v; + + v = am33xx_cm_read_reg(inst, idx); + v &= mask; + v >>= __ffs(mask); + + return v; +} + +/** + * _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to + * bit 0. + */ +static u32 _clkctrl_idlest(u16 inst, s16 cdoffs, u16 clkctrl_offs) +{ + u32 v = am33xx_cm_read_reg(inst, clkctrl_offs); + v &= AM33XX_IDLEST_MASK; + v >>= AM33XX_IDLEST_SHIFT; + return v; +} + +/** + * _is_module_ready - can module registers be accessed without causing an abort? + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either + * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise. + */ +static bool _is_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs) +{ + u32 v; + + v = _clkctrl_idlest(inst, cdoffs, clkctrl_offs); + + return (v == CLKCTRL_IDLEST_FUNCTIONAL || + v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false; +} + +/** + * _clktrctrl_write - write @c to a CM_CLKSTCTRL.CLKTRCTRL register bitfield + * @c: CLKTRCTRL register bitfield (LSB = bit 0, i.e., unshifted) + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * + * @c must be the unshifted value for CLKTRCTRL - i.e., this function + * will handle the shift itself. + */ +static void _clktrctrl_write(u8 c, u16 inst, u16 cdoffs) +{ + u32 v; + + v = am33xx_cm_read_reg(inst, cdoffs); + v &= ~AM33XX_CLKTRCTRL_MASK; + v |= c << AM33XX_CLKTRCTRL_SHIFT; + am33xx_cm_write_reg(v, inst, cdoffs); +} + +/* Public functions */ + +/** + * am33xx_cm_is_clkdm_in_hwsup - is a clockdomain in hwsup idle mode? + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * + * Returns true if the clockdomain referred to by (@inst, @cdoffs) + * is in hardware-supervised idle mode, or 0 otherwise. + */ +bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs) +{ + u32 v; + + v = am33xx_cm_read_reg(inst, cdoffs); + v &= AM33XX_CLKTRCTRL_MASK; + v >>= AM33XX_CLKTRCTRL_SHIFT; + + return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? true : false; +} + +/** + * am33xx_cm_clkdm_enable_hwsup - put a clockdomain in hwsup-idle mode + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * + * Put a clockdomain referred to by (@inst, @cdoffs) into + * hardware-supervised idle mode. No return value. + */ +void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs) +{ + _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, inst, cdoffs); +} + +/** + * am33xx_cm_clkdm_disable_hwsup - put a clockdomain in swsup-idle mode + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * + * Put a clockdomain referred to by (@inst, @cdoffs) into + * software-supervised idle mode, i.e., controlled manually by the + * Linux OMAP clockdomain code. No return value. + */ +void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs) +{ + _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, inst, cdoffs); +} + +/** + * am33xx_cm_clkdm_force_sleep - try to put a clockdomain into idle + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * + * Put a clockdomain referred to by (@inst, @cdoffs) into idle + * No return value. + */ +void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs) +{ + _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, inst, cdoffs); +} + +/** + * am33xx_cm_clkdm_force_wakeup - try to take a clockdomain out of idle + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * + * Take a clockdomain referred to by (@inst, @cdoffs) out of idle, + * waking it up. No return value. + */ +void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs) +{ + _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, inst, cdoffs); +} + +/* + * + */ + +/** + * am33xx_cm_wait_module_ready - wait for a module to be in 'func' state + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * Wait for the module IDLEST to be functional. If the idle state is in any + * the non functional state (trans, idle or disabled), module and thus the + * sysconfig cannot be accessed and will probably lead to an "imprecise + * external abort" + */ +int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs) +{ + int i = 0; + + omap_test_timeout(_is_module_ready(inst, cdoffs, clkctrl_offs), + MAX_MODULE_READY_TIME, i); + + return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; +} + +/** + * am33xx_cm_wait_module_idle - wait for a module to be in 'disabled' + * state + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * Wait for the module IDLEST to be disabled. Some PRCM transition, + * like reset assertion or parent clock de-activation must wait the + * module to be fully disabled. + */ +int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, u16 clkctrl_offs) +{ + int i = 0; + + if (!clkctrl_offs) + return 0; + + omap_test_timeout((_clkctrl_idlest(inst, cdoffs, clkctrl_offs) == + CLKCTRL_IDLEST_DISABLED), + MAX_MODULE_READY_TIME, i); + + return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; +} + +/** + * am33xx_cm_module_enable - Enable the modulemode inside CLKCTRL + * @mode: Module mode (SW or HW) + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * No return value. + */ +void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, u16 clkctrl_offs) +{ + u32 v; + + v = am33xx_cm_read_reg(inst, clkctrl_offs); + v &= ~AM33XX_MODULEMODE_MASK; + v |= mode << AM33XX_MODULEMODE_SHIFT; + am33xx_cm_write_reg(v, inst, clkctrl_offs); +} + +/** + * am33xx_cm_module_disable - Disable the module inside CLKCTRL + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * No return value. + */ +void am33xx_cm_module_disable(u16 inst, s16 cdoffs, u16 clkctrl_offs) +{ + u32 v; + + v = am33xx_cm_read_reg(inst, clkctrl_offs); + v &= ~AM33XX_MODULEMODE_MASK; + am33xx_cm_write_reg(v, inst, clkctrl_offs); +} + +/* + * Clockdomain low-level functions + */ + +static int am33xx_clkdm_sleep(struct clockdomain *clkdm) +{ + am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs); + return 0; +} + +static int am33xx_clkdm_wakeup(struct clockdomain *clkdm) +{ + am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs); + return 0; +} + +static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm) +{ + am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); +} + +static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm) +{ + am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); +} + +static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm) +{ + if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) + return am33xx_clkdm_wakeup(clkdm); + + return 0; +} + +static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm) +{ + bool hwsup = false; + + hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); + + if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) + am33xx_clkdm_sleep(clkdm); + + return 0; +} + +struct clkdm_ops am33xx_clkdm_operations = { + .clkdm_sleep = am33xx_clkdm_sleep, + .clkdm_wakeup = am33xx_clkdm_wakeup, + .clkdm_allow_idle = am33xx_clkdm_allow_idle, + .clkdm_deny_idle = am33xx_clkdm_deny_idle, + .clkdm_clk_enable = am33xx_clkdm_clk_enable, + .clkdm_clk_disable = am33xx_clkdm_clk_disable, +}; diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h new file mode 100644 index 00000000000..bd244179077 --- /dev/null +++ b/arch/arm/mach-omap2/cm33xx.h @@ -0,0 +1,414 @@ +/* + * AM33XX CM offset macros + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * Vaibhav Hiremath <hvaibhav@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CM_33XX_H +#define __ARCH_ARM_MACH_OMAP2_CM_33XX_H + +#include "cm.h" +#include "cm-regbits-33xx.h" + +/* CM base address */ +#define AM33XX_CM_BASE 0x44e00000 + +#define AM33XX_CM_REGADDR(inst, reg) \ + AM33XX_L4_WK_IO_ADDRESS(AM33XX_CM_BASE + (inst) + (reg)) + +/* CM instances */ +#define AM33XX_CM_PER_MOD 0x0000 +#define AM33XX_CM_WKUP_MOD 0x0400 +#define AM33XX_CM_DPLL_MOD 0x0500 +#define AM33XX_CM_MPU_MOD 0x0600 +#define AM33XX_CM_DEVICE_MOD 0x0700 +#define AM33XX_CM_RTC_MOD 0x0800 +#define AM33XX_CM_GFX_MOD 0x0900 +#define AM33XX_CM_CEFUSE_MOD 0x0A00 + +/* CM */ + +/* CM.PER_CM register offsets */ +#define AM33XX_CM_PER_L4LS_CLKSTCTRL_OFFSET 0x0000 +#define AM33XX_CM_PER_L4LS_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0000) +#define AM33XX_CM_PER_L3S_CLKSTCTRL_OFFSET 0x0004 +#define AM33XX_CM_PER_L3S_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0004) +#define AM33XX_CM_PER_L4FW_CLKSTCTRL_OFFSET 0x0008 +#define AM33XX_CM_PER_L4FW_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0008) +#define AM33XX_CM_PER_L3_CLKSTCTRL_OFFSET 0x000c +#define AM33XX_CM_PER_L3_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x000c) +#define AM33XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET 0x0014 +#define AM33XX_CM_PER_CPGMAC0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0014) +#define AM33XX_CM_PER_LCDC_CLKCTRL_OFFSET 0x0018 +#define AM33XX_CM_PER_LCDC_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0018) +#define AM33XX_CM_PER_USB0_CLKCTRL_OFFSET 0x001c +#define AM33XX_CM_PER_USB0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x001c) +#define AM33XX_CM_PER_MLB_CLKCTRL_OFFSET 0x0020 +#define AM33XX_CM_PER_MLB_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0020) +#define AM33XX_CM_PER_TPTC0_CLKCTRL_OFFSET 0x0024 +#define AM33XX_CM_PER_TPTC0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0024) +#define AM33XX_CM_PER_EMIF_CLKCTRL_OFFSET 0x0028 +#define AM33XX_CM_PER_EMIF_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0028) +#define AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET 0x002c +#define AM33XX_CM_PER_OCMCRAM_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x002c) +#define AM33XX_CM_PER_GPMC_CLKCTRL_OFFSET 0x0030 +#define AM33XX_CM_PER_GPMC_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0030) +#define AM33XX_CM_PER_MCASP0_CLKCTRL_OFFSET 0x0034 +#define AM33XX_CM_PER_MCASP0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0034) +#define AM33XX_CM_PER_UART5_CLKCTRL_OFFSET 0x0038 +#define AM33XX_CM_PER_UART5_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0038) +#define AM33XX_CM_PER_MMC0_CLKCTRL_OFFSET 0x003c +#define AM33XX_CM_PER_MMC0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x003c) +#define AM33XX_CM_PER_ELM_CLKCTRL_OFFSET 0x0040 +#define AM33XX_CM_PER_ELM_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0040) +#define AM33XX_CM_PER_I2C2_CLKCTRL_OFFSET 0x0044 +#define AM33XX_CM_PER_I2C2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0044) +#define AM33XX_CM_PER_I2C1_CLKCTRL_OFFSET 0x0048 +#define AM33XX_CM_PER_I2C1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0048) +#define AM33XX_CM_PER_SPI0_CLKCTRL_OFFSET 0x004c +#define AM33XX_CM_PER_SPI0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x004c) +#define AM33XX_CM_PER_SPI1_CLKCTRL_OFFSET 0x0050 +#define AM33XX_CM_PER_SPI1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0050) +#define AM33XX_CM_PER_SPI2_CLKCTRL_OFFSET 0x0054 +#define AM33XX_CM_PER_SPI2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0054) +#define AM33XX_CM_PER_SPI3_CLKCTRL_OFFSET 0x0058 +#define AM33XX_CM_PER_SPI3_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0058) +#define AM33XX_CM_PER_L4LS_CLKCTRL_OFFSET 0x0060 +#define AM33XX_CM_PER_L4LS_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0060) +#define AM33XX_CM_PER_L4FW_CLKCTRL_OFFSET 0x0064 +#define AM33XX_CM_PER_L4FW_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0064) +#define AM33XX_CM_PER_MCASP1_CLKCTRL_OFFSET 0x0068 +#define AM33XX_CM_PER_MCASP1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0068) +#define AM33XX_CM_PER_UART1_CLKCTRL_OFFSET 0x006c +#define AM33XX_CM_PER_UART1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x006c) +#define AM33XX_CM_PER_UART2_CLKCTRL_OFFSET 0x0070 +#define AM33XX_CM_PER_UART2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0070) +#define AM33XX_CM_PER_UART3_CLKCTRL_OFFSET 0x0074 +#define AM33XX_CM_PER_UART3_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0074) +#define AM33XX_CM_PER_UART4_CLKCTRL_OFFSET 0x0078 +#define AM33XX_CM_PER_UART4_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0078) +#define AM33XX_CM_PER_TIMER7_CLKCTRL_OFFSET 0x007c +#define AM33XX_CM_PER_TIMER7_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x007c) +#define AM33XX_CM_PER_TIMER2_CLKCTRL_OFFSET 0x0080 +#define AM33XX_CM_PER_TIMER2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0080) +#define AM33XX_CM_PER_TIMER3_CLKCTRL_OFFSET 0x0084 +#define AM33XX_CM_PER_TIMER3_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0084) +#define AM33XX_CM_PER_TIMER4_CLKCTRL_OFFSET 0x0088 +#define AM33XX_CM_PER_TIMER4_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0088) +#define AM33XX_CM_PER_MCASP2_CLKCTRL_OFFSET 0x008c +#define AM33XX_CM_PER_MCASP2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x008c) +#define AM33XX_CM_PER_RNG_CLKCTRL_OFFSET 0x0090 +#define AM33XX_CM_PER_RNG_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0090) +#define AM33XX_CM_PER_AES0_CLKCTRL_OFFSET 0x0094 +#define AM33XX_CM_PER_AES0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0094) +#define AM33XX_CM_PER_AES1_CLKCTRL_OFFSET 0x0098 +#define AM33XX_CM_PER_AES1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0098) +#define AM33XX_CM_PER_DES_CLKCTRL_OFFSET 0x009c +#define AM33XX_CM_PER_DES_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x009c) +#define AM33XX_CM_PER_SHA0_CLKCTRL_OFFSET 0x00a0 +#define AM33XX_CM_PER_SHA0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00a0) +#define AM33XX_CM_PER_PKA_CLKCTRL_OFFSET 0x00a4 +#define AM33XX_CM_PER_PKA_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00a4) +#define AM33XX_CM_PER_GPIO6_CLKCTRL_OFFSET 0x00a8 +#define AM33XX_CM_PER_GPIO6_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00a8) +#define AM33XX_CM_PER_GPIO1_CLKCTRL_OFFSET 0x00ac +#define AM33XX_CM_PER_GPIO1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00ac) +#define AM33XX_CM_PER_GPIO2_CLKCTRL_OFFSET 0x00b0 +#define AM33XX_CM_PER_GPIO2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00b0) +#define AM33XX_CM_PER_GPIO3_CLKCTRL_OFFSET 0x00b4 +#define AM33XX_CM_PER_GPIO3_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00b4) +#define AM33XX_CM_PER_GPIO4_CLKCTRL_OFFSET 0x00b8 +#define AM33XX_CM_PER_GPIO4_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00b8) +#define AM33XX_CM_PER_TPCC_CLKCTRL_OFFSET 0x00bc +#define AM33XX_CM_PER_TPCC_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00bc) +#define AM33XX_CM_PER_DCAN0_CLKCTRL_OFFSET 0x00c0 +#define AM33XX_CM_PER_DCAN0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00c0) +#define AM33XX_CM_PER_DCAN1_CLKCTRL_OFFSET 0x00c4 +#define AM33XX_CM_PER_DCAN1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00c4) +#define AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET 0x00cc +#define AM33XX_CM_PER_EPWMSS1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00cc) +#define AM33XX_CM_PER_EMIF_FW_CLKCTRL_OFFSET 0x00d0 +#define AM33XX_CM_PER_EMIF_FW_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00d0) +#define AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET 0x00d4 +#define AM33XX_CM_PER_EPWMSS0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00d4) +#define AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET 0x00d8 +#define AM33XX_CM_PER_EPWMSS2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00d8) +#define AM33XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET 0x00dc +#define AM33XX_CM_PER_L3_INSTR_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00dc) +#define AM33XX_CM_PER_L3_CLKCTRL_OFFSET 0x00e0 +#define AM33XX_CM_PER_L3_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00e0) +#define AM33XX_CM_PER_IEEE5000_CLKCTRL_OFFSET 0x00e4 +#define AM33XX_CM_PER_IEEE5000_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00e4) +#define AM33XX_CM_PER_PRUSS_CLKCTRL_OFFSET 0x00e8 +#define AM33XX_CM_PER_PRUSS_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00e8) +#define AM33XX_CM_PER_TIMER5_CLKCTRL_OFFSET 0x00ec +#define AM33XX_CM_PER_TIMER5_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00ec) +#define AM33XX_CM_PER_TIMER6_CLKCTRL_OFFSET 0x00f0 +#define AM33XX_CM_PER_TIMER6_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00f0) +#define AM33XX_CM_PER_MMC1_CLKCTRL_OFFSET 0x00f4 +#define AM33XX_CM_PER_MMC1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00f4) +#define AM33XX_CM_PER_MMC2_CLKCTRL_OFFSET 0x00f8 +#define AM33XX_CM_PER_MMC2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00f8) +#define AM33XX_CM_PER_TPTC1_CLKCTRL_OFFSET 0x00fc +#define AM33XX_CM_PER_TPTC1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x00fc) +#define AM33XX_CM_PER_TPTC2_CLKCTRL_OFFSET 0x0100 +#define AM33XX_CM_PER_TPTC2_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0100) +#define AM33XX_CM_PER_GPIO5_CLKCTRL_OFFSET 0x0104 +#define AM33XX_CM_PER_GPIO5_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0104) +#define AM33XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET 0x010c +#define AM33XX_CM_PER_SPINLOCK_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x010c) +#define AM33XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET 0x0110 +#define AM33XX_CM_PER_MAILBOX0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0110) +#define AM33XX_CM_PER_L4HS_CLKSTCTRL_OFFSET 0x011c +#define AM33XX_CM_PER_L4HS_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x011c) +#define AM33XX_CM_PER_L4HS_CLKCTRL_OFFSET 0x0120 +#define AM33XX_CM_PER_L4HS_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0120) +#define AM33XX_CM_PER_MSTR_EXPS_CLKCTRL_OFFSET 0x0124 +#define AM33XX_CM_PER_MSTR_EXPS_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0124) +#define AM33XX_CM_PER_SLV_EXPS_CLKCTRL_OFFSET 0x0128 +#define AM33XX_CM_PER_SLV_EXPS_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0128) +#define AM33XX_CM_PER_OCPWP_L3_CLKSTCTRL_OFFSET 0x012c +#define AM33XX_CM_PER_OCPWP_L3_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x012c) +#define AM33XX_CM_PER_OCPWP_CLKCTRL_OFFSET 0x0130 +#define AM33XX_CM_PER_OCPWP_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0130) +#define AM33XX_CM_PER_MAILBOX1_CLKCTRL_OFFSET 0x0134 +#define AM33XX_CM_PER_MAILBOX1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0134) +#define AM33XX_CM_PER_PRUSS_CLKSTCTRL_OFFSET 0x0140 +#define AM33XX_CM_PER_PRUSS_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0140) +#define AM33XX_CM_PER_CPSW_CLKSTCTRL_OFFSET 0x0144 +#define AM33XX_CM_PER_CPSW_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0144) +#define AM33XX_CM_PER_LCDC_CLKSTCTRL_OFFSET 0x0148 +#define AM33XX_CM_PER_LCDC_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0148) +#define AM33XX_CM_PER_CLKDIV32K_CLKCTRL_OFFSET 0x014c +#define AM33XX_CM_PER_CLKDIV32K_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x014c) +#define AM33XX_CM_PER_CLK_24MHZ_CLKSTCTRL_OFFSET 0x0150 +#define AM33XX_CM_PER_CLK_24MHZ_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_PER_MOD, 0x0150) + +/* CM.WKUP_CM register offsets */ +#define AM33XX_CM_WKUP_CLKSTCTRL_OFFSET 0x0000 +#define AM33XX_CM_WKUP_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0000) +#define AM33XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET 0x0004 +#define AM33XX_CM_WKUP_CONTROL_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0004) +#define AM33XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET 0x0008 +#define AM33XX_CM_WKUP_GPIO0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0008) +#define AM33XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET 0x000c +#define AM33XX_CM_WKUP_L4WKUP_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x000c) +#define AM33XX_CM_WKUP_TIMER0_CLKCTRL_OFFSET 0x0010 +#define AM33XX_CM_WKUP_TIMER0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0010) +#define AM33XX_CM_WKUP_DEBUGSS_CLKCTRL_OFFSET 0x0014 +#define AM33XX_CM_WKUP_DEBUGSS_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0014) +#define AM33XX_CM_L3_AON_CLKSTCTRL_OFFSET 0x0018 +#define AM33XX_CM_L3_AON_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0018) +#define AM33XX_CM_AUTOIDLE_DPLL_MPU_OFFSET 0x001c +#define AM33XX_CM_AUTOIDLE_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x001c) +#define AM33XX_CM_IDLEST_DPLL_MPU_OFFSET 0x0020 +#define AM33XX_CM_IDLEST_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0020) +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_MPU_OFFSET 0x0024 +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0024) +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_MPU_OFFSET 0x0028 +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0028) +#define AM33XX_CM_CLKSEL_DPLL_MPU_OFFSET 0x002c +#define AM33XX_CM_CLKSEL_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x002c) +#define AM33XX_CM_AUTOIDLE_DPLL_DDR_OFFSET 0x0030 +#define AM33XX_CM_AUTOIDLE_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0030) +#define AM33XX_CM_IDLEST_DPLL_DDR_OFFSET 0x0034 +#define AM33XX_CM_IDLEST_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0034) +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_DDR_OFFSET 0x0038 +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0038) +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_DDR_OFFSET 0x003c +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x003c) +#define AM33XX_CM_CLKSEL_DPLL_DDR_OFFSET 0x0040 +#define AM33XX_CM_CLKSEL_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0040) +#define AM33XX_CM_AUTOIDLE_DPLL_DISP_OFFSET 0x0044 +#define AM33XX_CM_AUTOIDLE_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0044) +#define AM33XX_CM_IDLEST_DPLL_DISP_OFFSET 0x0048 +#define AM33XX_CM_IDLEST_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0048) +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_DISP_OFFSET 0x004c +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x004c) +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_DISP_OFFSET 0x0050 +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0050) +#define AM33XX_CM_CLKSEL_DPLL_DISP_OFFSET 0x0054 +#define AM33XX_CM_CLKSEL_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0054) +#define AM33XX_CM_AUTOIDLE_DPLL_CORE_OFFSET 0x0058 +#define AM33XX_CM_AUTOIDLE_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0058) +#define AM33XX_CM_IDLEST_DPLL_CORE_OFFSET 0x005c +#define AM33XX_CM_IDLEST_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x005c) +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_CORE_OFFSET 0x0060 +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0060) +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_CORE_OFFSET 0x0064 +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0064) +#define AM33XX_CM_CLKSEL_DPLL_CORE_OFFSET 0x0068 +#define AM33XX_CM_CLKSEL_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0068) +#define AM33XX_CM_AUTOIDLE_DPLL_PER_OFFSET 0x006c +#define AM33XX_CM_AUTOIDLE_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x006c) +#define AM33XX_CM_IDLEST_DPLL_PER_OFFSET 0x0070 +#define AM33XX_CM_IDLEST_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0070) +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_PER_OFFSET 0x0074 +#define AM33XX_CM_SSC_DELTAMSTEP_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0074) +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_PER_OFFSET 0x0078 +#define AM33XX_CM_SSC_MODFREQDIV_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0078) +#define AM33XX_CM_CLKDCOLDO_DPLL_PER_OFFSET 0x007c +#define AM33XX_CM_CLKDCOLDO_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x007c) +#define AM33XX_CM_DIV_M4_DPLL_CORE_OFFSET 0x0080 +#define AM33XX_CM_DIV_M4_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0080) +#define AM33XX_CM_DIV_M5_DPLL_CORE_OFFSET 0x0084 +#define AM33XX_CM_DIV_M5_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0084) +#define AM33XX_CM_CLKMODE_DPLL_MPU_OFFSET 0x0088 +#define AM33XX_CM_CLKMODE_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0088) +#define AM33XX_CM_CLKMODE_DPLL_PER_OFFSET 0x008c +#define AM33XX_CM_CLKMODE_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x008c) +#define AM33XX_CM_CLKMODE_DPLL_CORE_OFFSET 0x0090 +#define AM33XX_CM_CLKMODE_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0090) +#define AM33XX_CM_CLKMODE_DPLL_DDR_OFFSET 0x0094 +#define AM33XX_CM_CLKMODE_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0094) +#define AM33XX_CM_CLKMODE_DPLL_DISP_OFFSET 0x0098 +#define AM33XX_CM_CLKMODE_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x0098) +#define AM33XX_CM_CLKSEL_DPLL_PERIPH_OFFSET 0x009c +#define AM33XX_CM_CLKSEL_DPLL_PERIPH AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x009c) +#define AM33XX_CM_DIV_M2_DPLL_DDR_OFFSET 0x00a0 +#define AM33XX_CM_DIV_M2_DPLL_DDR AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00a0) +#define AM33XX_CM_DIV_M2_DPLL_DISP_OFFSET 0x00a4 +#define AM33XX_CM_DIV_M2_DPLL_DISP AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00a4) +#define AM33XX_CM_DIV_M2_DPLL_MPU_OFFSET 0x00a8 +#define AM33XX_CM_DIV_M2_DPLL_MPU AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00a8) +#define AM33XX_CM_DIV_M2_DPLL_PER_OFFSET 0x00ac +#define AM33XX_CM_DIV_M2_DPLL_PER AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00ac) +#define AM33XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET 0x00b0 +#define AM33XX_CM_WKUP_WKUP_M3_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00b0) +#define AM33XX_CM_WKUP_UART0_CLKCTRL_OFFSET 0x00b4 +#define AM33XX_CM_WKUP_UART0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00b4) +#define AM33XX_CM_WKUP_I2C0_CLKCTRL_OFFSET 0x00b8 +#define AM33XX_CM_WKUP_I2C0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00b8) +#define AM33XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET 0x00bc +#define AM33XX_CM_WKUP_ADC_TSC_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00bc) +#define AM33XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET 0x00c0 +#define AM33XX_CM_WKUP_SMARTREFLEX0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00c0) +#define AM33XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET 0x00c4 +#define AM33XX_CM_WKUP_TIMER1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00c4) +#define AM33XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET 0x00c8 +#define AM33XX_CM_WKUP_SMARTREFLEX1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00c8) +#define AM33XX_CM_L4_WKUP_AON_CLKSTCTRL_OFFSET 0x00cc +#define AM33XX_CM_L4_WKUP_AON_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00cc) +#define AM33XX_CM_WKUP_WDT0_CLKCTRL_OFFSET 0x00d0 +#define AM33XX_CM_WKUP_WDT0_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00d0) +#define AM33XX_CM_WKUP_WDT1_CLKCTRL_OFFSET 0x00d4 +#define AM33XX_CM_WKUP_WDT1_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00d4) +#define AM33XX_CM_DIV_M6_DPLL_CORE_OFFSET 0x00d8 +#define AM33XX_CM_DIV_M6_DPLL_CORE AM33XX_CM_REGADDR(AM33XX_CM_WKUP_MOD, 0x00d8) + +/* CM.DPLL_CM register offsets */ +#define AM33XX_CLKSEL_TIMER7_CLK_OFFSET 0x0004 +#define AM33XX_CLKSEL_TIMER7_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0004) +#define AM33XX_CLKSEL_TIMER2_CLK_OFFSET 0x0008 +#define AM33XX_CLKSEL_TIMER2_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0008) +#define AM33XX_CLKSEL_TIMER3_CLK_OFFSET 0x000c +#define AM33XX_CLKSEL_TIMER3_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x000c) +#define AM33XX_CLKSEL_TIMER4_CLK_OFFSET 0x0010 +#define AM33XX_CLKSEL_TIMER4_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0010) +#define AM33XX_CM_MAC_CLKSEL_OFFSET 0x0014 +#define AM33XX_CM_MAC_CLKSEL AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0014) +#define AM33XX_CLKSEL_TIMER5_CLK_OFFSET 0x0018 +#define AM33XX_CLKSEL_TIMER5_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0018) +#define AM33XX_CLKSEL_TIMER6_CLK_OFFSET 0x001c +#define AM33XX_CLKSEL_TIMER6_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x001c) +#define AM33XX_CM_CPTS_RFT_CLKSEL_OFFSET 0x0020 +#define AM33XX_CM_CPTS_RFT_CLKSEL AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0020) +#define AM33XX_CLKSEL_TIMER1MS_CLK_OFFSET 0x0028 +#define AM33XX_CLKSEL_TIMER1MS_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0028) +#define AM33XX_CLKSEL_GFX_FCLK_OFFSET 0x002c +#define AM33XX_CLKSEL_GFX_FCLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x002c) +#define AM33XX_CLKSEL_PRUSS_OCP_CLK_OFFSET 0x0030 +#define AM33XX_CLKSEL_PRUSS_OCP_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0030) +#define AM33XX_CLKSEL_LCDC_PIXEL_CLK_OFFSET 0x0034 +#define AM33XX_CLKSEL_LCDC_PIXEL_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0034) +#define AM33XX_CLKSEL_WDT1_CLK_OFFSET 0x0038 +#define AM33XX_CLKSEL_WDT1_CLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x0038) +#define AM33XX_CLKSEL_GPIO0_DBCLK_OFFSET 0x003c +#define AM33XX_CLKSEL_GPIO0_DBCLK AM33XX_CM_REGADDR(AM33XX_CM_DPLL_MOD, 0x003c) + +/* CM.MPU_CM register offsets */ +#define AM33XX_CM_MPU_CLKSTCTRL_OFFSET 0x0000 +#define AM33XX_CM_MPU_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_MPU_MOD, 0x0000) +#define AM33XX_CM_MPU_MPU_CLKCTRL_OFFSET 0x0004 +#define AM33XX_CM_MPU_MPU_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_MPU_MOD, 0x0004) + +/* CM.DEVICE_CM register offsets */ +#define AM33XX_CM_CLKOUT_CTRL_OFFSET 0x0000 +#define AM33XX_CM_CLKOUT_CTRL AM33XX_CM_REGADDR(AM33XX_CM_DEVICE_MOD, 0x0000) + +/* CM.RTC_CM register offsets */ +#define AM33XX_CM_RTC_RTC_CLKCTRL_OFFSET 0x0000 +#define AM33XX_CM_RTC_RTC_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_RTC_MOD, 0x0000) +#define AM33XX_CM_RTC_CLKSTCTRL_OFFSET 0x0004 +#define AM33XX_CM_RTC_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_RTC_MOD, 0x0004) + +/* CM.GFX_CM register offsets */ +#define AM33XX_CM_GFX_L3_CLKSTCTRL_OFFSET 0x0000 +#define AM33XX_CM_GFX_L3_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_GFX_MOD, 0x0000) +#define AM33XX_CM_GFX_GFX_CLKCTRL_OFFSET 0x0004 +#define AM33XX_CM_GFX_GFX_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_GFX_MOD, 0x0004) +#define AM33XX_CM_GFX_BITBLT_CLKCTRL_OFFSET 0x0008 +#define AM33XX_CM_GFX_BITBLT_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_GFX_MOD, 0x0008) +#define AM33XX_CM_GFX_L4LS_GFX_CLKSTCTRL__1_OFFSET 0x000c +#define AM33XX_CM_GFX_L4LS_GFX_CLKSTCTRL__1 AM33XX_CM_REGADDR(AM33XX_CM_GFX_MOD, 0x000c) +#define AM33XX_CM_GFX_MMUCFG_CLKCTRL_OFFSET 0x0010 +#define AM33XX_CM_GFX_MMUCFG_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_GFX_MOD, 0x0010) +#define AM33XX_CM_GFX_MMUDATA_CLKCTRL_OFFSET 0x0014 +#define AM33XX_CM_GFX_MMUDATA_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_GFX_MOD, 0x0014) + +/* CM.CEFUSE_CM register offsets */ +#define AM33XX_CM_CEFUSE_CLKSTCTRL_OFFSET 0x0000 +#define AM33XX_CM_CEFUSE_CLKSTCTRL AM33XX_CM_REGADDR(AM33XX_CM_CEFUSE_MOD, 0x0000) +#define AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET 0x0020 +#define AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_CEFUSE_MOD, 0x0020) + + +#ifndef __ASSEMBLER__ +bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs); +void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs); +void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs); +void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs); +void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs); + +#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX) +extern int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, + u16 clkctrl_offs); +extern void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, + u16 clkctrl_offs); +extern void am33xx_cm_module_disable(u16 inst, s16 cdoffs, + u16 clkctrl_offs); +extern int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, + u16 clkctrl_offs); +#else +static inline int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, + u16 clkctrl_offs) +{ + return 0; +} +static inline void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, + u16 clkctrl_offs) +{ +} +static inline void am33xx_cm_module_disable(u16 inst, s16 cdoffs, + u16 clkctrl_offs) +{ +} +static inline int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, + u16 clkctrl_offs) +{ + return 0; +} +#endif + +#endif /* ASSEMBLER */ +#endif diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c new file mode 100644 index 00000000000..129a4e7f6ef --- /dev/null +++ b/arch/arm/mach-omap2/cm3xxx.c @@ -0,0 +1,680 @@ +/* + * OMAP3xxx CM module functions + * + * Copyright (C) 2009 Nokia Corporation + * Copyright (C) 2008-2010, 2012 Texas Instruments, Inc. + * Paul Walmsley + * Rajendra Nayak <rnayak@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/io.h> + +#include "prm2xxx_3xxx.h" +#include "cm.h" +#include "cm3xxx.h" +#include "cm-regbits-34xx.h" +#include "clockdomain.h" + +static const u8 omap3xxx_cm_idlest_offs[] = { + CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3 +}; + +/* + * + */ + +static void _write_clktrctrl(u8 c, s16 module, u32 mask) +{ + u32 v; + + v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL); + v &= ~mask; + v |= c << __ffs(mask); + omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL); +} + +bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask) +{ + u32 v; + + v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL); + v &= mask; + v >>= __ffs(mask); + + return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0; +} + +void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask) +{ + _write_clktrctrl(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, module, mask); +} + +void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask) +{ + _write_clktrctrl(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, module, mask); +} + +void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask) +{ + _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, module, mask); +} + +void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask) +{ + _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask); +} + +/* + * + */ + +/** + * omap3xxx_cm_wait_module_ready - wait for a module to leave idle or standby + * @prcm_mod: PRCM module offset + * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3) + * @idlest_shift: shift of the bit in the CM_IDLEST* register to check + * + * Wait for the PRCM to indicate that the module identified by + * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon + * success or -EBUSY if the module doesn't enable in time. + */ +int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) +{ + int ena = 0, i = 0; + u8 cm_idlest_reg; + u32 mask; + + if (!idlest_id || (idlest_id > ARRAY_SIZE(omap3xxx_cm_idlest_offs))) + return -EINVAL; + + cm_idlest_reg = omap3xxx_cm_idlest_offs[idlest_id - 1]; + + mask = 1 << idlest_shift; + ena = 0; + + omap_test_timeout(((omap2_cm_read_mod_reg(prcm_mod, cm_idlest_reg) & + mask) == ena), MAX_MODULE_READY_TIME, i); + + return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; +} + +/** + * omap3xxx_cm_split_idlest_reg - split CM_IDLEST reg addr into its components + * @idlest_reg: CM_IDLEST* virtual address + * @prcm_inst: pointer to an s16 to return the PRCM instance offset + * @idlest_reg_id: pointer to a u8 to return the CM_IDLESTx register ID + * + * XXX This function is only needed until absolute register addresses are + * removed from the OMAP struct clk records. + */ +int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, + u8 *idlest_reg_id) +{ + unsigned long offs; + u8 idlest_offs; + int i; + + if (idlest_reg < (cm_base + OMAP3430_IVA2_MOD) || + idlest_reg > (cm_base + 0x1ffff)) + return -EINVAL; + + idlest_offs = (unsigned long)idlest_reg & 0xff; + for (i = 0; i < ARRAY_SIZE(omap3xxx_cm_idlest_offs); i++) { + if (idlest_offs == omap3xxx_cm_idlest_offs[i]) { + *idlest_reg_id = i + 1; + break; + } + } + + if (i == ARRAY_SIZE(omap3xxx_cm_idlest_offs)) + return -EINVAL; + + offs = idlest_reg - cm_base; + offs &= 0xff00; + *prcm_inst = offs; + + return 0; +} + +/* Clockdomain low-level operations */ + +static int omap3xxx_clkdm_add_sleepdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) +{ + omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit), + clkdm1->pwrdm.ptr->prcm_offs, + OMAP3430_CM_SLEEPDEP); + return 0; +} + +static int omap3xxx_clkdm_del_sleepdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) +{ + omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit), + clkdm1->pwrdm.ptr->prcm_offs, + OMAP3430_CM_SLEEPDEP); + return 0; +} + +static int omap3xxx_clkdm_read_sleepdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) +{ + return omap2_cm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, + OMAP3430_CM_SLEEPDEP, + (1 << clkdm2->dep_bit)); +} + +static int omap3xxx_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm) +{ + struct clkdm_dep *cd; + u32 mask = 0; + + for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) { + if (!cd->clkdm) + continue; /* only happens if data is erroneous */ + + mask |= 1 << cd->clkdm->dep_bit; + cd->sleepdep_usecount = 0; + } + omap2_cm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, + OMAP3430_CM_SLEEPDEP); + return 0; +} + +static int omap3xxx_clkdm_sleep(struct clockdomain *clkdm) +{ + omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + return 0; +} + +static int omap3xxx_clkdm_wakeup(struct clockdomain *clkdm) +{ + omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + return 0; +} + +static void omap3xxx_clkdm_allow_idle(struct clockdomain *clkdm) +{ + if (clkdm->usecount > 0) + clkdm_add_autodeps(clkdm); + + omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); +} + +static void omap3xxx_clkdm_deny_idle(struct clockdomain *clkdm) +{ + omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + + if (clkdm->usecount > 0) + clkdm_del_autodeps(clkdm); +} + +static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm) +{ + bool hwsup = false; + + if (!clkdm->clktrctrl_mask) + return 0; + + /* + * The CLKDM_MISSING_IDLE_REPORTING flag documentation has + * more details on the unpleasant problem this is working + * around + */ + if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) && + (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) { + omap3xxx_clkdm_wakeup(clkdm); + return 0; + } + + hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + + if (hwsup) { + /* Disable HW transitions when we are changing deps */ + omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + clkdm_add_autodeps(clkdm); + omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + } else { + if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) + omap3xxx_clkdm_wakeup(clkdm); + } + + return 0; +} + +static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm) +{ + bool hwsup = false; + + if (!clkdm->clktrctrl_mask) + return 0; + + /* + * The CLKDM_MISSING_IDLE_REPORTING flag documentation has + * more details on the unpleasant problem this is working + * around + */ + if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING && + !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) { + omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + return 0; + } + + hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + + if (hwsup) { + /* Disable HW transitions when we are changing deps */ + omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + clkdm_del_autodeps(clkdm); + omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + } else { + if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP) + omap3xxx_clkdm_sleep(clkdm); + } + + return 0; +} + +struct clkdm_ops omap3_clkdm_operations = { + .clkdm_add_wkdep = omap2_clkdm_add_wkdep, + .clkdm_del_wkdep = omap2_clkdm_del_wkdep, + .clkdm_read_wkdep = omap2_clkdm_read_wkdep, + .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps, + .clkdm_add_sleepdep = omap3xxx_clkdm_add_sleepdep, + .clkdm_del_sleepdep = omap3xxx_clkdm_del_sleepdep, + .clkdm_read_sleepdep = omap3xxx_clkdm_read_sleepdep, + .clkdm_clear_all_sleepdeps = omap3xxx_clkdm_clear_all_sleepdeps, + .clkdm_sleep = omap3xxx_clkdm_sleep, + .clkdm_wakeup = omap3xxx_clkdm_wakeup, + .clkdm_allow_idle = omap3xxx_clkdm_allow_idle, + .clkdm_deny_idle = omap3xxx_clkdm_deny_idle, + .clkdm_clk_enable = omap3xxx_clkdm_clk_enable, + .clkdm_clk_disable = omap3xxx_clkdm_clk_disable, +}; + +/* + * Context save/restore code - OMAP3 only + */ +struct omap3_cm_regs { + u32 iva2_cm_clksel1; + u32 iva2_cm_clksel2; + u32 cm_sysconfig; + u32 sgx_cm_clksel; + u32 dss_cm_clksel; + u32 cam_cm_clksel; + u32 per_cm_clksel; + u32 emu_cm_clksel; + u32 emu_cm_clkstctrl; + u32 pll_cm_autoidle; + u32 pll_cm_autoidle2; + u32 pll_cm_clksel4; + u32 pll_cm_clksel5; + u32 pll_cm_clken2; + u32 cm_polctrl; + u32 iva2_cm_fclken; + u32 iva2_cm_clken_pll; + u32 core_cm_fclken1; + u32 core_cm_fclken3; + u32 sgx_cm_fclken; + u32 wkup_cm_fclken; + u32 dss_cm_fclken; + u32 cam_cm_fclken; + u32 per_cm_fclken; + u32 usbhost_cm_fclken; + u32 core_cm_iclken1; + u32 core_cm_iclken2; + u32 core_cm_iclken3; + u32 sgx_cm_iclken; + u32 wkup_cm_iclken; + u32 dss_cm_iclken; + u32 cam_cm_iclken; + u32 per_cm_iclken; + u32 usbhost_cm_iclken; + u32 iva2_cm_autoidle2; + u32 mpu_cm_autoidle2; + u32 iva2_cm_clkstctrl; + u32 mpu_cm_clkstctrl; + u32 core_cm_clkstctrl; + u32 sgx_cm_clkstctrl; + u32 dss_cm_clkstctrl; + u32 cam_cm_clkstctrl; + u32 per_cm_clkstctrl; + u32 neon_cm_clkstctrl; + u32 usbhost_cm_clkstctrl; + u32 core_cm_autoidle1; + u32 core_cm_autoidle2; + u32 core_cm_autoidle3; + u32 wkup_cm_autoidle; + u32 dss_cm_autoidle; + u32 cam_cm_autoidle; + u32 per_cm_autoidle; + u32 usbhost_cm_autoidle; + u32 sgx_cm_sleepdep; + u32 dss_cm_sleepdep; + u32 cam_cm_sleepdep; + u32 per_cm_sleepdep; + u32 usbhost_cm_sleepdep; + u32 cm_clkout_ctrl; +}; + +static struct omap3_cm_regs cm_context; + +void omap3_cm_save_context(void) +{ + cm_context.iva2_cm_clksel1 = + omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL1); + cm_context.iva2_cm_clksel2 = + omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL2); + cm_context.cm_sysconfig = + omap2_cm_read_mod_reg(OCP_MOD, OMAP3430_CM_SYSCONFIG); + cm_context.sgx_cm_clksel = + omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSEL); + cm_context.dss_cm_clksel = + omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSEL); + cm_context.cam_cm_clksel = + omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSEL); + cm_context.per_cm_clksel = + omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSEL); + cm_context.emu_cm_clksel = + omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1); + cm_context.emu_cm_clkstctrl = + omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL); + /* + * As per erratum i671, ROM code does not respect the PER DPLL + * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1. + * In this case, even though this register has been saved in + * scratchpad contents, we need to restore AUTO_PERIPH_DPLL + * by ourselves. So, we need to save it anyway. + */ + cm_context.pll_cm_autoidle = + omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE); + cm_context.pll_cm_autoidle2 = + omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2); + cm_context.pll_cm_clksel4 = + omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL4); + cm_context.pll_cm_clksel5 = + omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL5); + cm_context.pll_cm_clken2 = + omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKEN2); + cm_context.cm_polctrl = + omap2_cm_read_mod_reg(OCP_MOD, OMAP3430_CM_POLCTRL); + cm_context.iva2_cm_fclken = + omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_FCLKEN); + cm_context.iva2_cm_clken_pll = + omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL); + cm_context.core_cm_fclken1 = + omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1); + cm_context.core_cm_fclken3 = + omap2_cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3); + cm_context.sgx_cm_fclken = + omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_FCLKEN); + cm_context.wkup_cm_fclken = + omap2_cm_read_mod_reg(WKUP_MOD, CM_FCLKEN); + cm_context.dss_cm_fclken = + omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_FCLKEN); + cm_context.cam_cm_fclken = + omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_FCLKEN); + cm_context.per_cm_fclken = + omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN); + cm_context.usbhost_cm_fclken = + omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN); + cm_context.core_cm_iclken1 = + omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN1); + cm_context.core_cm_iclken2 = + omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN2); + cm_context.core_cm_iclken3 = + omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN3); + cm_context.sgx_cm_iclken = + omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_ICLKEN); + cm_context.wkup_cm_iclken = + omap2_cm_read_mod_reg(WKUP_MOD, CM_ICLKEN); + cm_context.dss_cm_iclken = + omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_ICLKEN); + cm_context.cam_cm_iclken = + omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_ICLKEN); + cm_context.per_cm_iclken = + omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN); + cm_context.usbhost_cm_iclken = + omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN); + cm_context.iva2_cm_autoidle2 = + omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_AUTOIDLE2); + cm_context.mpu_cm_autoidle2 = + omap2_cm_read_mod_reg(MPU_MOD, CM_AUTOIDLE2); + cm_context.iva2_cm_clkstctrl = + omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL); + cm_context.mpu_cm_clkstctrl = + omap2_cm_read_mod_reg(MPU_MOD, OMAP2_CM_CLKSTCTRL); + cm_context.core_cm_clkstctrl = + omap2_cm_read_mod_reg(CORE_MOD, OMAP2_CM_CLKSTCTRL); + cm_context.sgx_cm_clkstctrl = + omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, OMAP2_CM_CLKSTCTRL); + cm_context.dss_cm_clkstctrl = + omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP2_CM_CLKSTCTRL); + cm_context.cam_cm_clkstctrl = + omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP2_CM_CLKSTCTRL); + cm_context.per_cm_clkstctrl = + omap2_cm_read_mod_reg(OMAP3430_PER_MOD, OMAP2_CM_CLKSTCTRL); + cm_context.neon_cm_clkstctrl = + omap2_cm_read_mod_reg(OMAP3430_NEON_MOD, OMAP2_CM_CLKSTCTRL); + cm_context.usbhost_cm_clkstctrl = + omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, + OMAP2_CM_CLKSTCTRL); + cm_context.core_cm_autoidle1 = + omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE1); + cm_context.core_cm_autoidle2 = + omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE2); + cm_context.core_cm_autoidle3 = + omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE3); + cm_context.wkup_cm_autoidle = + omap2_cm_read_mod_reg(WKUP_MOD, CM_AUTOIDLE); + cm_context.dss_cm_autoidle = + omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_AUTOIDLE); + cm_context.cam_cm_autoidle = + omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_AUTOIDLE); + cm_context.per_cm_autoidle = + omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE); + cm_context.usbhost_cm_autoidle = + omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE); + cm_context.sgx_cm_sleepdep = + omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, + OMAP3430_CM_SLEEPDEP); + cm_context.dss_cm_sleepdep = + omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP3430_CM_SLEEPDEP); + cm_context.cam_cm_sleepdep = + omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP3430_CM_SLEEPDEP); + cm_context.per_cm_sleepdep = + omap2_cm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_CM_SLEEPDEP); + cm_context.usbhost_cm_sleepdep = + omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, + OMAP3430_CM_SLEEPDEP); + cm_context.cm_clkout_ctrl = + omap2_cm_read_mod_reg(OMAP3430_CCR_MOD, + OMAP3_CM_CLKOUT_CTRL_OFFSET); +} + +void omap3_cm_restore_context(void) +{ + omap2_cm_write_mod_reg(cm_context.iva2_cm_clksel1, OMAP3430_IVA2_MOD, + CM_CLKSEL1); + omap2_cm_write_mod_reg(cm_context.iva2_cm_clksel2, OMAP3430_IVA2_MOD, + CM_CLKSEL2); + omap2_cm_write_mod_reg(cm_context.cm_sysconfig, OCP_MOD, + OMAP3430_CM_SYSCONFIG); + omap2_cm_write_mod_reg(cm_context.sgx_cm_clksel, OMAP3430ES2_SGX_MOD, + CM_CLKSEL); + omap2_cm_write_mod_reg(cm_context.dss_cm_clksel, OMAP3430_DSS_MOD, + CM_CLKSEL); + omap2_cm_write_mod_reg(cm_context.cam_cm_clksel, OMAP3430_CAM_MOD, + CM_CLKSEL); + omap2_cm_write_mod_reg(cm_context.per_cm_clksel, OMAP3430_PER_MOD, + CM_CLKSEL); + omap2_cm_write_mod_reg(cm_context.emu_cm_clksel, OMAP3430_EMU_MOD, + CM_CLKSEL1); + omap2_cm_write_mod_reg(cm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD, + OMAP2_CM_CLKSTCTRL); + /* + * As per erratum i671, ROM code does not respect the PER DPLL + * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1. + * In this case, we need to restore AUTO_PERIPH_DPLL by ourselves. + */ + omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle, PLL_MOD, + CM_AUTOIDLE); + omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle2, PLL_MOD, + CM_AUTOIDLE2); + omap2_cm_write_mod_reg(cm_context.pll_cm_clksel4, PLL_MOD, + OMAP3430ES2_CM_CLKSEL4); + omap2_cm_write_mod_reg(cm_context.pll_cm_clksel5, PLL_MOD, + OMAP3430ES2_CM_CLKSEL5); + omap2_cm_write_mod_reg(cm_context.pll_cm_clken2, PLL_MOD, + OMAP3430ES2_CM_CLKEN2); + omap2_cm_write_mod_reg(cm_context.cm_polctrl, OCP_MOD, + OMAP3430_CM_POLCTRL); + omap2_cm_write_mod_reg(cm_context.iva2_cm_fclken, OMAP3430_IVA2_MOD, + CM_FCLKEN); + omap2_cm_write_mod_reg(cm_context.iva2_cm_clken_pll, OMAP3430_IVA2_MOD, + OMAP3430_CM_CLKEN_PLL); + omap2_cm_write_mod_reg(cm_context.core_cm_fclken1, CORE_MOD, + CM_FCLKEN1); + omap2_cm_write_mod_reg(cm_context.core_cm_fclken3, CORE_MOD, + OMAP3430ES2_CM_FCLKEN3); + omap2_cm_write_mod_reg(cm_context.sgx_cm_fclken, OMAP3430ES2_SGX_MOD, + CM_FCLKEN); + omap2_cm_write_mod_reg(cm_context.wkup_cm_fclken, WKUP_MOD, CM_FCLKEN); + omap2_cm_write_mod_reg(cm_context.dss_cm_fclken, OMAP3430_DSS_MOD, + CM_FCLKEN); + omap2_cm_write_mod_reg(cm_context.cam_cm_fclken, OMAP3430_CAM_MOD, + CM_FCLKEN); + omap2_cm_write_mod_reg(cm_context.per_cm_fclken, OMAP3430_PER_MOD, + CM_FCLKEN); + omap2_cm_write_mod_reg(cm_context.usbhost_cm_fclken, + OMAP3430ES2_USBHOST_MOD, CM_FCLKEN); + omap2_cm_write_mod_reg(cm_context.core_cm_iclken1, CORE_MOD, + CM_ICLKEN1); + omap2_cm_write_mod_reg(cm_context.core_cm_iclken2, CORE_MOD, + CM_ICLKEN2); + omap2_cm_write_mod_reg(cm_context.core_cm_iclken3, CORE_MOD, + CM_ICLKEN3); + omap2_cm_write_mod_reg(cm_context.sgx_cm_iclken, OMAP3430ES2_SGX_MOD, + CM_ICLKEN); + omap2_cm_write_mod_reg(cm_context.wkup_cm_iclken, WKUP_MOD, CM_ICLKEN); + omap2_cm_write_mod_reg(cm_context.dss_cm_iclken, OMAP3430_DSS_MOD, + CM_ICLKEN); + omap2_cm_write_mod_reg(cm_context.cam_cm_iclken, OMAP3430_CAM_MOD, + CM_ICLKEN); + omap2_cm_write_mod_reg(cm_context.per_cm_iclken, OMAP3430_PER_MOD, + CM_ICLKEN); + omap2_cm_write_mod_reg(cm_context.usbhost_cm_iclken, + OMAP3430ES2_USBHOST_MOD, CM_ICLKEN); + omap2_cm_write_mod_reg(cm_context.iva2_cm_autoidle2, OMAP3430_IVA2_MOD, + CM_AUTOIDLE2); + omap2_cm_write_mod_reg(cm_context.mpu_cm_autoidle2, MPU_MOD, + CM_AUTOIDLE2); + omap2_cm_write_mod_reg(cm_context.iva2_cm_clkstctrl, OMAP3430_IVA2_MOD, + OMAP2_CM_CLKSTCTRL); + omap2_cm_write_mod_reg(cm_context.mpu_cm_clkstctrl, MPU_MOD, + OMAP2_CM_CLKSTCTRL); + omap2_cm_write_mod_reg(cm_context.core_cm_clkstctrl, CORE_MOD, + OMAP2_CM_CLKSTCTRL); + omap2_cm_write_mod_reg(cm_context.sgx_cm_clkstctrl, OMAP3430ES2_SGX_MOD, + OMAP2_CM_CLKSTCTRL); + omap2_cm_write_mod_reg(cm_context.dss_cm_clkstctrl, OMAP3430_DSS_MOD, + OMAP2_CM_CLKSTCTRL); + omap2_cm_write_mod_reg(cm_context.cam_cm_clkstctrl, OMAP3430_CAM_MOD, + OMAP2_CM_CLKSTCTRL); + omap2_cm_write_mod_reg(cm_context.per_cm_clkstctrl, OMAP3430_PER_MOD, + OMAP2_CM_CLKSTCTRL); + omap2_cm_write_mod_reg(cm_context.neon_cm_clkstctrl, OMAP3430_NEON_MOD, + OMAP2_CM_CLKSTCTRL); + omap2_cm_write_mod_reg(cm_context.usbhost_cm_clkstctrl, + OMAP3430ES2_USBHOST_MOD, OMAP2_CM_CLKSTCTRL); + omap2_cm_write_mod_reg(cm_context.core_cm_autoidle1, CORE_MOD, + CM_AUTOIDLE1); + omap2_cm_write_mod_reg(cm_context.core_cm_autoidle2, CORE_MOD, + CM_AUTOIDLE2); + omap2_cm_write_mod_reg(cm_context.core_cm_autoidle3, CORE_MOD, + CM_AUTOIDLE3); + omap2_cm_write_mod_reg(cm_context.wkup_cm_autoidle, WKUP_MOD, + CM_AUTOIDLE); + omap2_cm_write_mod_reg(cm_context.dss_cm_autoidle, OMAP3430_DSS_MOD, + CM_AUTOIDLE); + omap2_cm_write_mod_reg(cm_context.cam_cm_autoidle, OMAP3430_CAM_MOD, + CM_AUTOIDLE); + omap2_cm_write_mod_reg(cm_context.per_cm_autoidle, OMAP3430_PER_MOD, + CM_AUTOIDLE); + omap2_cm_write_mod_reg(cm_context.usbhost_cm_autoidle, + OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE); + omap2_cm_write_mod_reg(cm_context.sgx_cm_sleepdep, OMAP3430ES2_SGX_MOD, + OMAP3430_CM_SLEEPDEP); + omap2_cm_write_mod_reg(cm_context.dss_cm_sleepdep, OMAP3430_DSS_MOD, + OMAP3430_CM_SLEEPDEP); + omap2_cm_write_mod_reg(cm_context.cam_cm_sleepdep, OMAP3430_CAM_MOD, + OMAP3430_CM_SLEEPDEP); + omap2_cm_write_mod_reg(cm_context.per_cm_sleepdep, OMAP3430_PER_MOD, + OMAP3430_CM_SLEEPDEP); + omap2_cm_write_mod_reg(cm_context.usbhost_cm_sleepdep, + OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP); + omap2_cm_write_mod_reg(cm_context.cm_clkout_ctrl, OMAP3430_CCR_MOD, + OMAP3_CM_CLKOUT_CTRL_OFFSET); +} + +void omap3_cm_save_scratchpad_contents(u32 *ptr) +{ + *ptr++ = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL); + *ptr++ = omap2_cm_read_mod_reg(WKUP_MOD, CM_CLKSEL); + *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN); + + /* + * As per erratum i671, ROM code does not respect the PER DPLL + * programming scheme if CM_AUTOIDLE_PLL..AUTO_PERIPH_DPLL == 1. + * Then, in anycase, clear these bits to avoid extra latencies. + */ + *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE) & + ~OMAP3430_AUTO_PERIPH_DPLL_MASK; + *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL); + *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL2_PLL); + *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL3); + *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKEN_PLL); + *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL); + *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL); + *ptr++ = omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL); +} + +/* + * + */ + +static struct cm_ll_data omap3xxx_cm_ll_data = { + .split_idlest_reg = &omap3xxx_cm_split_idlest_reg, + .wait_module_ready = &omap3xxx_cm_wait_module_ready, +}; + +int __init omap3xxx_cm_init(void) +{ + return cm_register(&omap3xxx_cm_ll_data); +} + +static void __exit omap3xxx_cm_exit(void) +{ + cm_unregister(&omap3xxx_cm_ll_data); +} +__exitcall(omap3xxx_cm_exit); diff --git a/arch/arm/mach-omap2/cm3xxx.h b/arch/arm/mach-omap2/cm3xxx.h new file mode 100644 index 00000000000..7a16b559812 --- /dev/null +++ b/arch/arm/mach-omap2/cm3xxx.h @@ -0,0 +1,91 @@ +/* + * OMAP2/3 Clock Management (CM) register definitions + * + * Copyright (C) 2007-2009 Texas Instruments, Inc. + * Copyright (C) 2007-2010 Nokia Corporation + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * The CM hardware modules on the OMAP2/3 are quite similar to each + * other. The CM modules/instances on OMAP4 are quite different, so + * they are handled in a separate file. + */ +#ifndef __ARCH_ASM_MACH_OMAP2_CM3XXX_H +#define __ARCH_ASM_MACH_OMAP2_CM3XXX_H + +#include "prcm-common.h" +#include "cm2xxx_3xxx.h" + +#define OMAP34XX_CM_REGADDR(module, reg) \ + OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg)) + + +/* + * OMAP3-specific global CM registers + * Use cm_{read,write}_reg() with these registers. + * These registers appear once per CM module. + */ + +#define OMAP3430_CM_SYSCONFIG 0x0010 +#define OMAP3430_CM_POLCTRL 0x009c + +#define OMAP3_CM_CLKOUT_CTRL_OFFSET 0x0070 +#define OMAP3430_CM_CLKOUT_CTRL OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070) + +/* + * Module specific CM register offsets from CM_BASE + domain offset + * Use cm_{read,write}_mod_reg() with these registers. + * These register offsets generally appear in more than one PRCM submodule. + */ + +/* OMAP3-specific register offsets */ + +#define OMAP3430_CM_CLKEN_PLL 0x0004 +#define OMAP3430ES2_CM_CLKEN2 0x0004 +#define OMAP3430ES2_CM_FCLKEN3 0x0008 +#define OMAP3430_CM_IDLEST_PLL CM_IDLEST2 +#define OMAP3430_CM_AUTOIDLE_PLL CM_AUTOIDLE2 +#define OMAP3430ES2_CM_AUTOIDLE2_PLL CM_AUTOIDLE2 +#define OMAP3430_CM_CLKSEL1 CM_CLKSEL +#define OMAP3430_CM_CLKSEL1_PLL CM_CLKSEL +#define OMAP3430_CM_CLKSEL2_PLL CM_CLKSEL2 +#define OMAP3430_CM_SLEEPDEP CM_CLKSEL2 +#define OMAP3430_CM_CLKSEL3 OMAP2_CM_CLKSTCTRL +#define OMAP3430_CM_CLKSTST 0x004c +#define OMAP3430ES2_CM_CLKSEL4 0x004c +#define OMAP3430ES2_CM_CLKSEL5 0x0050 +#define OMAP3430_CM_CLKSEL2_EMU 0x0050 +#define OMAP3430_CM_CLKSEL3_EMU 0x0054 + + +/* CM_IDLEST bit field values to indicate deasserted IdleReq */ + +#define OMAP34XX_CM_IDLEST_VAL 1 + + +#ifndef __ASSEMBLER__ + +extern void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask); +extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask); +extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask); +extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask); + +extern bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask); +extern int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, + u8 idlest_shift); + +extern int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg, + s16 *prcm_inst, u8 *idlest_reg_id); + +extern void omap3_cm_save_context(void); +extern void omap3_cm_restore_context(void); +extern void omap3_cm_save_scratchpad_contents(u32 *ptr); + +extern int __init omap3xxx_cm_init(void); + +#endif + +#endif diff --git a/arch/arm/mach-omap2/cm44xx.c b/arch/arm/mach-omap2/cm44xx.c new file mode 100644 index 00000000000..fe5cc7bae48 --- /dev/null +++ b/arch/arm/mach-omap2/cm44xx.c @@ -0,0 +1,49 @@ +/* + * OMAP4 CM1, CM2 module low-level functions + * + * Copyright (C) 2010 Nokia Corporation + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * These functions are intended to be used only by the cminst44xx.c file. + * XXX Perhaps we should just move them there and make them static. + */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/io.h> + +#include "cm.h" +#include "cm1_44xx.h" +#include "cm2_44xx.h" + +/* CM1 hardware module low-level functions */ + +/* Read a register in CM1 */ +u32 omap4_cm1_read_inst_reg(s16 inst, u16 reg) +{ + return readl_relaxed(cm_base + inst + reg); +} + +/* Write into a register in CM1 */ +void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 reg) +{ + writel_relaxed(val, cm_base + inst + reg); +} + +/* Read a register in CM2 */ +u32 omap4_cm2_read_inst_reg(s16 inst, u16 reg) +{ + return readl_relaxed(cm2_base + inst + reg); +} + +/* Write into a register in CM2 */ +void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg) +{ + writel_relaxed(val, cm2_base + inst + reg); +} diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h new file mode 100644 index 00000000000..3380beeace6 --- /dev/null +++ b/arch/arm/mach-omap2/cm44xx.h @@ -0,0 +1,26 @@ +/* + * OMAP4 Clock Management (CM) definitions + * + * Copyright (C) 2007-2011 Texas Instruments, Inc. + * Copyright (C) 2007-2009 Nokia Corporation + * + * Written by Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * OMAP4 has two separate CM blocks, CM1 and CM2. This file contains + * macros and function prototypes that are applicable to both. + */ +#ifndef __ARCH_ASM_MACH_OMAP2_CM44XX_H +#define __ARCH_ASM_MACH_OMAP2_CM44XX_H + + +#include "prcm-common.h" +#include "cm.h" + +#define OMAP4_CM_CLKSTCTRL 0x0000 +#define OMAP4_CM_STATICDEP 0x0004 + +#endif diff --git a/arch/arm/mach-omap2/cm_44xx_54xx.h b/arch/arm/mach-omap2/cm_44xx_54xx.h new file mode 100644 index 00000000000..cbb21169032 --- /dev/null +++ b/arch/arm/mach-omap2/cm_44xx_54xx.h @@ -0,0 +1,36 @@ +/* + * OMAP44xx and OMAP54xx CM1/CM2 function prototypes + * + * Copyright (C) 2009-2013 Texas Instruments, Inc. + * Copyright (C) 2009-2010 Nokia Corporation + * + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CM_44XX_54XX_H +#define __ARCH_ARM_MACH_OMAP2_CM_44XX_55XX_H + +/* CM1 Function prototypes */ +extern u32 omap4_cm1_read_inst_reg(s16 inst, u16 idx); +extern void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 idx); +extern u32 omap4_cm1_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx); + +/* CM2 Function prototypes */ +extern u32 omap4_cm2_read_inst_reg(s16 inst, u16 idx); +extern void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 idx); +extern u32 omap4_cm2_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx); + +#endif diff --git a/arch/arm/mach-omap2/cm_common.c b/arch/arm/mach-omap2/cm_common.c new file mode 100644 index 00000000000..8f6c4710877 --- /dev/null +++ b/arch/arm/mach-omap2/cm_common.c @@ -0,0 +1,140 @@ +/* + * OMAP2+ common Clock Management (CM) IP block functions + * + * Copyright (C) 2012 Texas Instruments, Inc. + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * XXX This code should eventually be moved to a CM driver. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/bug.h> + +#include "cm2xxx.h" +#include "cm3xxx.h" +#include "cm44xx.h" + +/* + * cm_ll_data: function pointers to SoC-specific implementations of + * common CM functions + */ +static struct cm_ll_data null_cm_ll_data; +static struct cm_ll_data *cm_ll_data = &null_cm_ll_data; + +/* cm_base: base virtual address of the CM IP block */ +void __iomem *cm_base; + +/* cm2_base: base virtual address of the CM2 IP block (OMAP44xx only) */ +void __iomem *cm2_base; + +/** + * omap2_set_globals_cm - set the CM/CM2 base addresses (for early use) + * @cm: CM base virtual address + * @cm2: CM2 base virtual address (if present on the booted SoC) + * + * XXX Will be replaced when the PRM/CM drivers are completed. + */ +void __init omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2) +{ + cm_base = cm; + cm2_base = cm2; +} + +/** + * cm_split_idlest_reg - split CM_IDLEST reg addr into its components + * @idlest_reg: CM_IDLEST* virtual address + * @prcm_inst: pointer to an s16 to return the PRCM instance offset + * @idlest_reg_id: pointer to a u8 to return the CM_IDLESTx register ID + * + * Given an absolute CM_IDLEST register address @idlest_reg, passes + * the PRCM instance offset and IDLEST register ID back to the caller + * via the @prcm_inst and @idlest_reg_id. Returns -EINVAL upon error, + * or 0 upon success. XXX This function is only needed until absolute + * register addresses are removed from the OMAP struct clk records. + */ +int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, + u8 *idlest_reg_id) +{ + if (!cm_ll_data->split_idlest_reg) { + WARN_ONCE(1, "cm: %s: no low-level function defined\n", + __func__); + return -EINVAL; + } + + return cm_ll_data->split_idlest_reg(idlest_reg, prcm_inst, + idlest_reg_id); +} + +/** + * cm_wait_module_ready - wait for a module to leave idle or standby + * @prcm_mod: PRCM module offset + * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3) + * @idlest_shift: shift of the bit in the CM_IDLEST* register to check + * + * Wait for the PRCM to indicate that the module identified by + * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon + * success, -EBUSY if the module doesn't enable in time, or -EINVAL if + * no per-SoC wait_module_ready() function pointer has been registered + * or if the idlest register is unknown on the SoC. + */ +int cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) +{ + if (!cm_ll_data->wait_module_ready) { + WARN_ONCE(1, "cm: %s: no low-level function defined\n", + __func__); + return -EINVAL; + } + + return cm_ll_data->wait_module_ready(prcm_mod, idlest_id, idlest_shift); +} + +/** + * cm_register - register per-SoC low-level data with the CM + * @cld: low-level per-SoC OMAP CM data & function pointers to register + * + * Register per-SoC low-level OMAP CM data and function pointers with + * the OMAP CM common interface. The caller must keep the data + * pointed to by @cld valid until it calls cm_unregister() and + * it returns successfully. Returns 0 upon success, -EINVAL if @cld + * is NULL, or -EEXIST if cm_register() has already been called + * without an intervening cm_unregister(). + */ +int cm_register(struct cm_ll_data *cld) +{ + if (!cld) + return -EINVAL; + + if (cm_ll_data != &null_cm_ll_data) + return -EEXIST; + + cm_ll_data = cld; + + return 0; +} + +/** + * cm_unregister - unregister per-SoC low-level data & function pointers + * @cld: low-level per-SoC OMAP CM data & function pointers to unregister + * + * Unregister per-SoC low-level OMAP CM data and function pointers + * that were previously registered with cm_register(). The + * caller may not destroy any of the data pointed to by @cld until + * this function returns successfully. Returns 0 upon success, or + * -EINVAL if @cld is NULL or if @cld does not match the struct + * cm_ll_data * previously registered by cm_register(). + */ +int cm_unregister(struct cm_ll_data *cld) +{ + if (!cld || cm_ll_data != cld) + return -EINVAL; + + cm_ll_data = &null_cm_ll_data; + + return 0; +} diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c new file mode 100644 index 00000000000..12aca56942c --- /dev/null +++ b/arch/arm/mach-omap2/cminst44xx.c @@ -0,0 +1,512 @@ +/* + * OMAP4 CM instance functions + * + * Copyright (C) 2009 Nokia Corporation + * Copyright (C) 2008-2011 Texas Instruments, Inc. + * Paul Walmsley + * Rajendra Nayak <rnayak@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This is needed since CM instances can be in the PRM, PRCM_MPU, CM1, + * or CM2 hardware modules. For example, the EMU_CM CM instance is in + * the PRM hardware module. What a mess... + */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/io.h> + +#include "clockdomain.h" +#include "cm.h" +#include "cm1_44xx.h" +#include "cm2_44xx.h" +#include "cm44xx.h" +#include "cminst44xx.h" +#include "cm-regbits-34xx.h" +#include "prcm44xx.h" +#include "prm44xx.h" +#include "prcm_mpu44xx.h" +#include "prcm-common.h" + +#define OMAP4430_IDLEST_SHIFT 16 +#define OMAP4430_IDLEST_MASK (0x3 << 16) +#define OMAP4430_CLKTRCTRL_SHIFT 0 +#define OMAP4430_CLKTRCTRL_MASK (0x3 << 0) +#define OMAP4430_MODULEMODE_SHIFT 0 +#define OMAP4430_MODULEMODE_MASK (0x3 << 0) + +/* + * CLKCTRL_IDLEST_*: possible values for the CM_*_CLKCTRL.IDLEST bitfield: + * + * 0x0 func: Module is fully functional, including OCP + * 0x1 trans: Module is performing transition: wakeup, or sleep, or sleep + * abortion + * 0x2 idle: Module is in Idle mode (only OCP part). It is functional if + * using separate functional clock + * 0x3 disabled: Module is disabled and cannot be accessed + * + */ +#define CLKCTRL_IDLEST_FUNCTIONAL 0x0 +#define CLKCTRL_IDLEST_INTRANSITION 0x1 +#define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2 +#define CLKCTRL_IDLEST_DISABLED 0x3 + +static void __iomem *_cm_bases[OMAP4_MAX_PRCM_PARTITIONS]; + +/** + * omap_cm_base_init - Populates the cm partitions + * + * Populates the base addresses of the _cm_bases + * array used for read/write of cm module registers. + */ +void omap_cm_base_init(void) +{ + _cm_bases[OMAP4430_PRM_PARTITION] = prm_base; + _cm_bases[OMAP4430_CM1_PARTITION] = cm_base; + _cm_bases[OMAP4430_CM2_PARTITION] = cm2_base; + _cm_bases[OMAP4430_PRCM_MPU_PARTITION] = prcm_mpu_base; +} + +/* Private functions */ + +/** + * _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield + * @part: PRCM partition ID that the CM_CLKCTRL register exists in + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to + * bit 0. + */ +static u32 _clkctrl_idlest(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) +{ + u32 v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs); + v &= OMAP4430_IDLEST_MASK; + v >>= OMAP4430_IDLEST_SHIFT; + return v; +} + +/** + * _is_module_ready - can module registers be accessed without causing an abort? + * @part: PRCM partition ID that the CM_CLKCTRL register exists in + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either + * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise. + */ +static bool _is_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) +{ + u32 v; + + v = _clkctrl_idlest(part, inst, cdoffs, clkctrl_offs); + + return (v == CLKCTRL_IDLEST_FUNCTIONAL || + v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false; +} + +/* Public functions */ + +/* Read a register in a CM instance */ +u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx) +{ + BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || + part == OMAP4430_INVALID_PRCM_PARTITION || + !_cm_bases[part]); + return readl_relaxed(_cm_bases[part] + inst + idx); +} + +/* Write into a register in a CM instance */ +void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx) +{ + BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || + part == OMAP4430_INVALID_PRCM_PARTITION || + !_cm_bases[part]); + writel_relaxed(val, _cm_bases[part] + inst + idx); +} + +/* Read-modify-write a register in CM1. Caller must lock */ +u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, u16 inst, + s16 idx) +{ + u32 v; + + v = omap4_cminst_read_inst_reg(part, inst, idx); + v &= ~mask; + v |= bits; + omap4_cminst_write_inst_reg(v, part, inst, idx); + + return v; +} + +u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, u16 inst, s16 idx) +{ + return omap4_cminst_rmw_inst_reg_bits(bits, bits, part, inst, idx); +} + +u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, u16 inst, s16 idx) +{ + return omap4_cminst_rmw_inst_reg_bits(bits, 0x0, part, inst, idx); +} + +u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, u32 mask) +{ + u32 v; + + v = omap4_cminst_read_inst_reg(part, inst, idx); + v &= mask; + v >>= __ffs(mask); + + return v; +} + +/* + * + */ + +/** + * _clktrctrl_write - write @c to a CM_CLKSTCTRL.CLKTRCTRL register bitfield + * @c: CLKTRCTRL register bitfield (LSB = bit 0, i.e., unshifted) + * @part: PRCM partition ID that the CM_CLKSTCTRL register exists in + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * + * @c must be the unshifted value for CLKTRCTRL - i.e., this function + * will handle the shift itself. + */ +static void _clktrctrl_write(u8 c, u8 part, u16 inst, u16 cdoffs) +{ + u32 v; + + v = omap4_cminst_read_inst_reg(part, inst, cdoffs + OMAP4_CM_CLKSTCTRL); + v &= ~OMAP4430_CLKTRCTRL_MASK; + v |= c << OMAP4430_CLKTRCTRL_SHIFT; + omap4_cminst_write_inst_reg(v, part, inst, cdoffs + OMAP4_CM_CLKSTCTRL); +} + +/** + * omap4_cminst_is_clkdm_in_hwsup - is a clockdomain in hwsup idle mode? + * @part: PRCM partition ID that the CM_CLKSTCTRL register exists in + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * + * Returns true if the clockdomain referred to by (@part, @inst, @cdoffs) + * is in hardware-supervised idle mode, or 0 otherwise. + */ +bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs) +{ + u32 v; + + v = omap4_cminst_read_inst_reg(part, inst, cdoffs + OMAP4_CM_CLKSTCTRL); + v &= OMAP4430_CLKTRCTRL_MASK; + v >>= OMAP4430_CLKTRCTRL_SHIFT; + + return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? true : false; +} + +/** + * omap4_cminst_clkdm_enable_hwsup - put a clockdomain in hwsup-idle mode + * @part: PRCM partition ID that the clockdomain registers exist in + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * + * Put a clockdomain referred to by (@part, @inst, @cdoffs) into + * hardware-supervised idle mode. No return value. + */ +void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs) +{ + _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, part, inst, cdoffs); +} + +/** + * omap4_cminst_clkdm_disable_hwsup - put a clockdomain in swsup-idle mode + * @part: PRCM partition ID that the clockdomain registers exist in + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * + * Put a clockdomain referred to by (@part, @inst, @cdoffs) into + * software-supervised idle mode, i.e., controlled manually by the + * Linux OMAP clockdomain code. No return value. + */ +void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs) +{ + _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, part, inst, cdoffs); +} + +/** + * omap4_cminst_clkdm_force_sleep - try to take a clockdomain out of idle + * @part: PRCM partition ID that the clockdomain registers exist in + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * + * Take a clockdomain referred to by (@part, @inst, @cdoffs) out of idle, + * waking it up. No return value. + */ +void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs) +{ + _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, part, inst, cdoffs); +} + +/* + * + */ + +void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs) +{ + _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, part, inst, cdoffs); +} + +/** + * omap4_cminst_wait_module_ready - wait for a module to be in 'func' state + * @part: PRCM partition ID that the CM_CLKCTRL register exists in + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * Wait for the module IDLEST to be functional. If the idle state is in any + * the non functional state (trans, idle or disabled), module and thus the + * sysconfig cannot be accessed and will probably lead to an "imprecise + * external abort" + */ +int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, + u16 clkctrl_offs) +{ + int i = 0; + + if (!clkctrl_offs) + return 0; + + omap_test_timeout(_is_module_ready(part, inst, cdoffs, clkctrl_offs), + MAX_MODULE_READY_TIME, i); + + return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; +} + +/** + * omap4_cminst_wait_module_idle - wait for a module to be in 'disabled' + * state + * @part: PRCM partition ID that the CM_CLKCTRL register exists in + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * Wait for the module IDLEST to be disabled. Some PRCM transition, + * like reset assertion or parent clock de-activation must wait the + * module to be fully disabled. + */ +int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) +{ + int i = 0; + + if (!clkctrl_offs) + return 0; + + omap_test_timeout((_clkctrl_idlest(part, inst, cdoffs, clkctrl_offs) == + CLKCTRL_IDLEST_DISABLED), + MAX_MODULE_DISABLE_TIME, i); + + return (i < MAX_MODULE_DISABLE_TIME) ? 0 : -EBUSY; +} + +/** + * omap4_cminst_module_enable - Enable the modulemode inside CLKCTRL + * @mode: Module mode (SW or HW) + * @part: PRCM partition ID that the CM_CLKCTRL register exists in + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * No return value. + */ +void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs, + u16 clkctrl_offs) +{ + u32 v; + + v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs); + v &= ~OMAP4430_MODULEMODE_MASK; + v |= mode << OMAP4430_MODULEMODE_SHIFT; + omap4_cminst_write_inst_reg(v, part, inst, clkctrl_offs); +} + +/** + * omap4_cminst_module_disable - Disable the module inside CLKCTRL + * @part: PRCM partition ID that the CM_CLKCTRL register exists in + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * No return value. + */ +void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, + u16 clkctrl_offs) +{ + u32 v; + + v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs); + v &= ~OMAP4430_MODULEMODE_MASK; + omap4_cminst_write_inst_reg(v, part, inst, clkctrl_offs); +} + +/* + * Clockdomain low-level functions + */ + +static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) +{ + omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit), + clkdm1->prcm_partition, + clkdm1->cm_inst, clkdm1->clkdm_offs + + OMAP4_CM_STATICDEP); + return 0; +} + +static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) +{ + omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit), + clkdm1->prcm_partition, + clkdm1->cm_inst, clkdm1->clkdm_offs + + OMAP4_CM_STATICDEP); + return 0; +} + +static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) +{ + return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition, + clkdm1->cm_inst, + clkdm1->clkdm_offs + + OMAP4_CM_STATICDEP, + (1 << clkdm2->dep_bit)); +} + +static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm) +{ + struct clkdm_dep *cd; + u32 mask = 0; + + if (!clkdm->prcm_partition) + return 0; + + for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) { + if (!cd->clkdm) + continue; /* only happens if data is erroneous */ + + mask |= 1 << cd->clkdm->dep_bit; + cd->wkdep_usecount = 0; + } + + omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition, + clkdm->cm_inst, clkdm->clkdm_offs + + OMAP4_CM_STATICDEP); + return 0; +} + +static int omap4_clkdm_sleep(struct clockdomain *clkdm) +{ + if (clkdm->flags & CLKDM_CAN_HWSUP) + omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition, + clkdm->cm_inst, + clkdm->clkdm_offs); + else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP) + omap4_cminst_clkdm_force_sleep(clkdm->prcm_partition, + clkdm->cm_inst, + clkdm->clkdm_offs); + else + return -EINVAL; + + return 0; +} + +static int omap4_clkdm_wakeup(struct clockdomain *clkdm) +{ + omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition, + clkdm->cm_inst, clkdm->clkdm_offs); + return 0; +} + +static void omap4_clkdm_allow_idle(struct clockdomain *clkdm) +{ + omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition, + clkdm->cm_inst, clkdm->clkdm_offs); +} + +static void omap4_clkdm_deny_idle(struct clockdomain *clkdm) +{ + if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) + omap4_clkdm_wakeup(clkdm); + else + omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition, + clkdm->cm_inst, + clkdm->clkdm_offs); +} + +static int omap4_clkdm_clk_enable(struct clockdomain *clkdm) +{ + if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) + return omap4_clkdm_wakeup(clkdm); + + return 0; +} + +static int omap4_clkdm_clk_disable(struct clockdomain *clkdm) +{ + bool hwsup = false; + + if (!clkdm->prcm_partition) + return 0; + + /* + * The CLKDM_MISSING_IDLE_REPORTING flag documentation has + * more details on the unpleasant problem this is working + * around + */ + if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING && + !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) { + omap4_clkdm_allow_idle(clkdm); + return 0; + } + + hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition, + clkdm->cm_inst, clkdm->clkdm_offs); + + if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) + omap4_clkdm_sleep(clkdm); + + return 0; +} + +struct clkdm_ops omap4_clkdm_operations = { + .clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep, + .clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep, + .clkdm_read_wkdep = omap4_clkdm_read_wkup_sleep_dep, + .clkdm_clear_all_wkdeps = omap4_clkdm_clear_all_wkup_sleep_deps, + .clkdm_add_sleepdep = omap4_clkdm_add_wkup_sleep_dep, + .clkdm_del_sleepdep = omap4_clkdm_del_wkup_sleep_dep, + .clkdm_read_sleepdep = omap4_clkdm_read_wkup_sleep_dep, + .clkdm_clear_all_sleepdeps = omap4_clkdm_clear_all_wkup_sleep_deps, + .clkdm_sleep = omap4_clkdm_sleep, + .clkdm_wakeup = omap4_clkdm_wakeup, + .clkdm_allow_idle = omap4_clkdm_allow_idle, + .clkdm_deny_idle = omap4_clkdm_deny_idle, + .clkdm_clk_enable = omap4_clkdm_clk_enable, + .clkdm_clk_disable = omap4_clkdm_clk_disable, +}; + +struct clkdm_ops am43xx_clkdm_operations = { + .clkdm_sleep = omap4_clkdm_sleep, + .clkdm_wakeup = omap4_clkdm_wakeup, + .clkdm_allow_idle = omap4_clkdm_allow_idle, + .clkdm_deny_idle = omap4_clkdm_deny_idle, + .clkdm_clk_enable = omap4_clkdm_clk_enable, + .clkdm_clk_disable = omap4_clkdm_clk_disable, +}; diff --git a/arch/arm/mach-omap2/cminst44xx.h b/arch/arm/mach-omap2/cminst44xx.h new file mode 100644 index 00000000000..7f56ea444bc --- /dev/null +++ b/arch/arm/mach-omap2/cminst44xx.h @@ -0,0 +1,43 @@ +/* + * OMAP4 Clock Management (CM) function prototypes + * + * Copyright (C) 2010 Nokia Corporation + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ARCH_ASM_MACH_OMAP2_CMINST44XX_H +#define __ARCH_ASM_MACH_OMAP2_CMINST44XX_H + +bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs); +void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs); +void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs); +void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs); +void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs); +extern int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs); +extern int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, + u16 clkctrl_offs); +extern void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs, + u16 clkctrl_offs); +extern void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, + u16 clkctrl_offs); +/* + * In an ideal world, we would not export these low-level functions, + * but this will probably take some time to fix properly + */ +u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx); +void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx); +u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, + u16 inst, s16 idx); +u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, u16 inst, + s16 idx); +u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, u16 inst, + s16 idx); +extern u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, + u32 mask); + +extern void omap_cm_base_init(void); + +#endif diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c new file mode 100644 index 00000000000..d246efd9f73 --- /dev/null +++ b/arch/arm/mach-omap2/common-board-devices.c @@ -0,0 +1,103 @@ +/* + * common-board-devices.c + * + * Copyright (C) 2011 CompuLab, Ltd. + * Author: Mike Rapoport <mike@compulab.co.il> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include <linux/gpio.h> +#include <linux/spi/spi.h> +#include <linux/spi/ads7846.h> + +#include <linux/platform_data/spi-omap2-mcspi.h> + +#include "common.h" +#include "common-board-devices.h" + +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ + defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) +static struct omap2_mcspi_device_config ads7846_mcspi_config = { + .turbo_mode = 0, +}; + +static struct ads7846_platform_data ads7846_config = { + .x_max = 0x0fff, + .y_max = 0x0fff, + .x_plate_ohms = 180, + .pressure_max = 255, + .debounce_max = 10, + .debounce_tol = 3, + .debounce_rep = 1, + .gpio_pendown = -EINVAL, + .keep_vref_on = 1, +}; + +static struct spi_board_info ads7846_spi_board_info __initdata = { + .modalias = "ads7846", + .bus_num = -EINVAL, + .chip_select = 0, + .max_speed_hz = 1500000, + .controller_data = &ads7846_mcspi_config, + .irq = -EINVAL, + .platform_data = &ads7846_config, +}; + +void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce, + struct ads7846_platform_data *board_pdata) +{ + struct spi_board_info *spi_bi = &ads7846_spi_board_info; + int err; + + /* + * If a board defines get_pendown_state() function, request the pendown + * GPIO and set the GPIO debounce time. + * If a board does not define the get_pendown_state() function, then + * the ads7846 driver will setup the pendown GPIO itself. + */ + if (board_pdata && board_pdata->get_pendown_state) { + err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown"); + if (err) { + pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err); + return; + } + + if (gpio_debounce) + gpio_set_debounce(gpio_pendown, gpio_debounce); + + gpio_export(gpio_pendown, 0); + } + + spi_bi->bus_num = bus_num; + spi_bi->irq = gpio_to_irq(gpio_pendown); + + ads7846_config.gpio_pendown = gpio_pendown; + + if (board_pdata) { + board_pdata->gpio_pendown = gpio_pendown; + board_pdata->gpio_pendown_debounce = gpio_debounce; + spi_bi->platform_data = board_pdata; + } + + spi_register_board_info(&ads7846_spi_board_info, 1); +} +#else +void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce, + struct ads7846_platform_data *board_pdata) +{ +} +#endif diff --git a/arch/arm/mach-omap2/common-board-devices.h b/arch/arm/mach-omap2/common-board-devices.h new file mode 100644 index 00000000000..f338177e690 --- /dev/null +++ b/arch/arm/mach-omap2/common-board-devices.h @@ -0,0 +1,15 @@ +#ifndef __OMAP_COMMON_BOARD_DEVICES__ +#define __OMAP_COMMON_BOARD_DEVICES__ + +#include "twl-common.h" + +#define NAND_BLOCK_SIZE SZ_128K + +struct mtd_partition; +struct ads7846_platform_data; + +void omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce, + struct ads7846_platform_data *board_pdata); +void *n8x0_legacy_init(void); + +#endif /* __OMAP_COMMON_BOARD_DEVICES__ */ diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c new file mode 100644 index 00000000000..2dabb9ecb98 --- /dev/null +++ b/arch/arm/mach-omap2/common.c @@ -0,0 +1,36 @@ +/* + * linux/arch/arm/mach-omap2/common.c + * + * Code common to all OMAP2+ machines. + * + * Copyright (C) 2009 Texas Instruments + * Copyright (C) 2010 Nokia Corporation + * Tony Lindgren <tony@atomide.com> + * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_data/dsp-omap.h> + +#include "common.h" +#include "omap-secure.h" + +/* + * Stub function for OMAP2 so that common files + * continue to build when custom builds are used + */ +int __weak omap_secure_ram_reserve_memblock(void) +{ + return 0; +} + +void __init omap_reserve(void) +{ + omap_dsp_reserve_sdram_memblock(); + omap_secure_ram_reserve_memblock(); + omap_barrier_reserve_memblock(); +} diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h new file mode 100644 index 00000000000..dc571f1d3b8 --- /dev/null +++ b/arch/arm/mach-omap2/common.h @@ -0,0 +1,330 @@ +/* + * Header for code common to all OMAP2+ machines. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H +#define __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H +#ifndef __ASSEMBLER__ + +#include <linux/irq.h> +#include <linux/delay.h> +#include <linux/i2c.h> +#include <linux/i2c/twl.h> +#include <linux/i2c-omap.h> +#include <linux/reboot.h> + +#include <asm/proc-fns.h> + +#include "i2c.h" +#include "serial.h" + +#include "usb.h" + +#define OMAP_INTC_START NR_IRQS + +#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP2) +int omap2_pm_init(void); +#else +static inline int omap2_pm_init(void) +{ + return 0; +} +#endif + +#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) +int omap3_pm_init(void); +#else +static inline int omap3_pm_init(void) +{ + return 0; +} +#endif + +#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4) +int omap4_pm_init(void); +int omap4_pm_init_early(void); +#else +static inline int omap4_pm_init(void) +{ + return 0; +} + +static inline int omap4_pm_init_early(void) +{ + return 0; +} +#endif + +#ifdef CONFIG_OMAP_MUX +int omap_mux_late_init(void); +#else +static inline int omap_mux_late_init(void) +{ + return 0; +} +#endif + +extern void omap2_init_common_infrastructure(void); + +extern void omap2_sync32k_timer_init(void); +extern void omap3_sync32k_timer_init(void); +extern void omap3_secure_sync32k_timer_init(void); +extern void omap3_gptimer_timer_init(void); +extern void omap4_local_timer_init(void); +#ifdef CONFIG_CACHE_L2X0 +int omap_l2_cache_init(void); +#else +static inline int omap_l2_cache_init(void) +{ + return 0; +} +#endif +extern void omap5_realtime_timer_init(void); + +void omap2420_init_early(void); +void omap2430_init_early(void); +void omap3430_init_early(void); +void omap35xx_init_early(void); +void omap3630_init_early(void); +void omap3_init_early(void); /* Do not use this one */ +void am33xx_init_early(void); +void am35xx_init_early(void); +void ti81xx_init_early(void); +void am33xx_init_early(void); +void am43xx_init_early(void); +void am43xx_init_late(void); +void omap4430_init_early(void); +void omap5_init_early(void); +void omap3_init_late(void); /* Do not use this one */ +void omap4430_init_late(void); +void omap2420_init_late(void); +void omap2430_init_late(void); +void omap3430_init_late(void); +void omap35xx_init_late(void); +void omap3630_init_late(void); +void am35xx_init_late(void); +void ti81xx_init_late(void); +void am33xx_init_late(void); +void omap5_init_late(void); +int omap2_common_pm_late_init(void); +void dra7xx_init_early(void); +void dra7xx_init_late(void); + +#ifdef CONFIG_SOC_BUS +void omap_soc_device_init(void); +#else +static inline void omap_soc_device_init(void) +{ +} +#endif + +#if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430) +void omap2xxx_restart(enum reboot_mode mode, const char *cmd); +#else +static inline void omap2xxx_restart(enum reboot_mode mode, const char *cmd) +{ +} +#endif + +#ifdef CONFIG_SOC_AM33XX +void am33xx_restart(enum reboot_mode mode, const char *cmd); +#else +static inline void am33xx_restart(enum reboot_mode mode, const char *cmd) +{ +} +#endif + +#ifdef CONFIG_ARCH_OMAP3 +void omap3xxx_restart(enum reboot_mode mode, const char *cmd); +#else +static inline void omap3xxx_restart(enum reboot_mode mode, const char *cmd) +{ +} +#endif + +#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ + defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM43XX) +void omap44xx_restart(enum reboot_mode mode, const char *cmd); +#else +static inline void omap44xx_restart(enum reboot_mode mode, const char *cmd) +{ +} +#endif + +/* This gets called from mach-omap2/io.c, do not call this */ +void __init omap2_set_globals_tap(u32 class, void __iomem *tap); + +void __init omap242x_map_io(void); +void __init omap243x_map_io(void); +void __init omap3_map_io(void); +void __init am33xx_map_io(void); +void __init omap4_map_io(void); +void __init omap5_map_io(void); +void __init ti81xx_map_io(void); + +/* omap_barriers_init() is OMAP4 only */ +void omap_barriers_init(void); + +/** + * omap_test_timeout - busy-loop, testing a condition + * @cond: condition to test until it evaluates to true + * @timeout: maximum number of microseconds in the timeout + * @index: loop index (integer) + * + * Loop waiting for @cond to become true or until at least @timeout + * microseconds have passed. To use, define some integer @index in the + * calling code. After running, if @index == @timeout, then the loop has + * timed out. + */ +#define omap_test_timeout(cond, timeout, index) \ +({ \ + for (index = 0; index < timeout; index++) { \ + if (cond) \ + break; \ + udelay(1); \ + } \ +}) + +extern struct device *omap2_get_mpuss_device(void); +extern struct device *omap2_get_iva_device(void); +extern struct device *omap2_get_l3_device(void); +extern struct device *omap4_get_dsp_device(void); + +void omap2_init_irq(void); +void omap3_init_irq(void); +void ti81xx_init_irq(void); +extern int omap_irq_pending(void); +void omap_intc_save_context(void); +void omap_intc_restore_context(void); +void omap3_intc_suspend(void); +void omap3_intc_prepare_idle(void); +void omap3_intc_resume_idle(void); +void omap2_intc_handle_irq(struct pt_regs *regs); +void omap3_intc_handle_irq(struct pt_regs *regs); +void omap_intc_of_init(void); +void omap_gic_of_init(void); + +#ifdef CONFIG_CACHE_L2X0 +extern void __iomem *omap4_get_l2cache_base(void); +#endif + +struct device_node; +#ifdef CONFIG_OF +int __init intc_of_init(struct device_node *node, + struct device_node *parent); +#else +int __init intc_of_init(struct device_node *node, + struct device_node *parent) +{ + return 0; +} +#endif + +#ifdef CONFIG_SMP +extern void __iomem *omap4_get_scu_base(void); +#else +static inline void __iomem *omap4_get_scu_base(void) +{ + return NULL; +} +#endif + +extern void gic_dist_disable(void); +extern void gic_dist_enable(void); +extern bool gic_dist_disabled(void); +extern void gic_timer_retrigger(void); +extern void omap_smc1(u32 fn, u32 arg); +extern void __iomem *omap4_get_sar_ram_base(void); +extern void omap_do_wfi(void); + +#ifdef CONFIG_SMP +/* Needed for secondary core boot */ +extern void omap4_secondary_startup(void); +extern void omap4460_secondary_startup(void); +extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); +extern void omap_auxcoreboot_addr(u32 cpu_addr); +extern u32 omap_read_auxcoreboot0(void); + +extern void omap4_cpu_die(unsigned int cpu); + +extern struct smp_operations omap4_smp_ops; + +extern void omap5_secondary_startup(void); +#endif + +#if defined(CONFIG_SMP) && defined(CONFIG_PM) +extern int omap4_mpuss_init(void); +extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state); +extern int omap4_finish_suspend(unsigned long cpu_state); +extern void omap4_cpu_resume(void); +extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state); +#else +static inline int omap4_enter_lowpower(unsigned int cpu, + unsigned int power_state) +{ + cpu_do_idle(); + return 0; +} + +static inline int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) +{ + cpu_do_idle(); + return 0; +} + +static inline int omap4_mpuss_init(void) +{ + return 0; +} + +static inline int omap4_finish_suspend(unsigned long cpu_state) +{ + return 0; +} + +static inline void omap4_cpu_resume(void) +{} + +#endif + +void pdata_quirks_init(struct of_device_id *); +void omap_auxdata_legacy_init(struct device *dev); +void omap_pcs_legacy_init(int irq, void (*rearm)(void)); + +struct omap_sdrc_params; +extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0, + struct omap_sdrc_params *sdrc_cs1); +struct omap2_hsmmc_info; +extern void omap_reserve(void); + +struct omap_hwmod; +extern int omap_dss_reset(struct omap_hwmod *); + +/* SoC specific clock initializer */ +int omap_clk_init(void); + +int __init omapdss_init_of(void); +void __init omapdss_early_init_of(void); + +#endif /* __ASSEMBLER__ */ +#endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index 5f3aad97784..751f3549bf6 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c @@ -1,7 +1,7 @@ /* * OMAP2/3 System Control Module register access * - * Copyright (C) 2007 Texas Instruments, Inc. + * Copyright (C) 2007, 2012 Texas Instruments, Inc. * Copyright (C) 2007 Nokia Corporation * * Written by Paul Walmsley @@ -15,16 +15,133 @@ #include <linux/kernel.h> #include <linux/io.h> -#include <mach/common.h> -#include <mach/control.h> +#include "soc.h" +#include "iomap.h" +#include "common.h" +#include "cm-regbits-34xx.h" +#include "prm-regbits-34xx.h" +#include "prm3xxx.h" +#include "cm3xxx.h" +#include "sdrc.h" +#include "pm.h" +#include "control.h" + +/* Used by omap3_ctrl_save_padconf() */ +#define START_PADCONF_SAVE 0x2 +#define PADCONF_SAVE_DONE 0x1 static void __iomem *omap2_ctrl_base; +static void __iomem *omap4_ctrl_pad_base; + +#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) +struct omap3_scratchpad { + u32 boot_config_ptr; + u32 public_restore_ptr; + u32 secure_ram_restore_ptr; + u32 sdrc_module_semaphore; + u32 prcm_block_offset; + u32 sdrc_block_offset; +}; + +struct omap3_scratchpad_prcm_block { + u32 prm_clksrc_ctrl; + u32 prm_clksel; + u32 cm_contents[11]; + u32 prcm_block_size; +}; + +struct omap3_scratchpad_sdrc_block { + u16 sysconfig; + u16 cs_cfg; + u16 sharing; + u16 err_type; + u32 dll_a_ctrl; + u32 dll_b_ctrl; + u32 power; + u32 cs_0; + u32 mcfg_0; + u16 mr_0; + u16 emr_1_0; + u16 emr_2_0; + u16 emr_3_0; + u32 actim_ctrla_0; + u32 actim_ctrlb_0; + u32 rfr_ctrl_0; + u32 cs_1; + u32 mcfg_1; + u16 mr_1; + u16 emr_1_1; + u16 emr_2_1; + u16 emr_3_1; + u32 actim_ctrla_1; + u32 actim_ctrlb_1; + u32 rfr_ctrl_1; + u16 dcdl_1_ctrl; + u16 dcdl_2_ctrl; + u32 flags; + u32 block_size; +}; + +void *omap3_secure_ram_storage; + +/* + * This is used to store ARM registers in SDRAM before attempting + * an MPU OFF. The save and restore happens from the SRAM sleep code. + * The address is stored in scratchpad, so that it can be used + * during the restore path. + */ +u32 omap3_arm_context[128]; + +struct omap3_control_regs { + u32 sysconfig; + u32 devconf0; + u32 mem_dftrw0; + u32 mem_dftrw1; + u32 msuspendmux_0; + u32 msuspendmux_1; + u32 msuspendmux_2; + u32 msuspendmux_3; + u32 msuspendmux_4; + u32 msuspendmux_5; + u32 sec_ctrl; + u32 devconf1; + u32 csirxfe; + u32 iva2_bootaddr; + u32 iva2_bootmod; + u32 debobs_0; + u32 debobs_1; + u32 debobs_2; + u32 debobs_3; + u32 debobs_4; + u32 debobs_5; + u32 debobs_6; + u32 debobs_7; + u32 debobs_8; + u32 prog_io0; + u32 prog_io1; + u32 dss_dpll_spreading; + u32 core_dpll_spreading; + u32 per_dpll_spreading; + u32 usbhost_dpll_spreading; + u32 pbias_lite; + u32 temp_sensor; + u32 sramldo4; + u32 sramldo5; + u32 csi; + u32 padconf_sys_nirq; +}; + +static struct omap3_control_regs control_context; +#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */ #define OMAP_CTRL_REGADDR(reg) (omap2_ctrl_base + (reg)) +#define OMAP4_CTRL_PAD_REGADDR(reg) (omap4_ctrl_pad_base + (reg)) -void __init omap2_set_globals_control(struct omap_globals *omap2_globals) +void __init omap2_set_globals_control(void __iomem *ctrl, + void __iomem *ctrl_pad) { - omap2_ctrl_base = omap2_globals->ctrl; + omap2_ctrl_base = ctrl; + omap4_ctrl_pad_base = ctrl_pad; } void __iomem *omap_ctrl_base_get(void) @@ -34,31 +151,433 @@ void __iomem *omap_ctrl_base_get(void) u8 omap_ctrl_readb(u16 offset) { - return __raw_readb(OMAP_CTRL_REGADDR(offset)); + return readb_relaxed(OMAP_CTRL_REGADDR(offset)); } u16 omap_ctrl_readw(u16 offset) { - return __raw_readw(OMAP_CTRL_REGADDR(offset)); + return readw_relaxed(OMAP_CTRL_REGADDR(offset)); } u32 omap_ctrl_readl(u16 offset) { - return __raw_readl(OMAP_CTRL_REGADDR(offset)); + return readl_relaxed(OMAP_CTRL_REGADDR(offset)); } void omap_ctrl_writeb(u8 val, u16 offset) { - __raw_writeb(val, OMAP_CTRL_REGADDR(offset)); + writeb_relaxed(val, OMAP_CTRL_REGADDR(offset)); } void omap_ctrl_writew(u16 val, u16 offset) { - __raw_writew(val, OMAP_CTRL_REGADDR(offset)); + writew_relaxed(val, OMAP_CTRL_REGADDR(offset)); } void omap_ctrl_writel(u32 val, u16 offset) { - __raw_writel(val, OMAP_CTRL_REGADDR(offset)); + writel_relaxed(val, OMAP_CTRL_REGADDR(offset)); } +/* + * On OMAP4 control pad are not addressable from control + * core base. So the common omap_ctrl_read/write APIs breaks + * Hence export separate APIs to manage the omap4 pad control + * registers. This APIs will work only for OMAP4 + */ + +u32 omap4_ctrl_pad_readl(u16 offset) +{ + return readl_relaxed(OMAP4_CTRL_PAD_REGADDR(offset)); +} + +void omap4_ctrl_pad_writel(u32 val, u16 offset) +{ + writel_relaxed(val, OMAP4_CTRL_PAD_REGADDR(offset)); +} + +#ifdef CONFIG_ARCH_OMAP3 + +/** + * omap3_ctrl_write_boot_mode - set scratchpad boot mode for the next boot + * @bootmode: 8-bit value to pass to some boot code + * + * Set the bootmode in the scratchpad RAM. This is used after the + * system restarts. Not sure what actually uses this - it may be the + * bootloader, rather than the boot ROM - contrary to the preserved + * comment below. No return value. + */ +void omap3_ctrl_write_boot_mode(u8 bootmode) +{ + u32 l; + + l = ('B' << 24) | ('M' << 16) | bootmode; + + /* + * Reserve the first word in scratchpad for communicating + * with the boot ROM. A pointer to a data structure + * describing the boot process can be stored there, + * cf. OMAP34xx TRM, Initialization / Software Booting + * Configuration. + * + * XXX This should use some omap_ctrl_writel()-type function + */ + writel_relaxed(l, OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD + 4)); +} + +#endif + +/** + * omap_ctrl_write_dsp_boot_addr - set boot address for a remote processor + * @bootaddr: physical address of the boot loader + * + * Set boot address for the boot loader of a supported processor + * when a power ON sequence occurs. + */ +void omap_ctrl_write_dsp_boot_addr(u32 bootaddr) +{ + u32 offset = cpu_is_omap243x() ? OMAP243X_CONTROL_IVA2_BOOTADDR : + cpu_is_omap34xx() ? OMAP343X_CONTROL_IVA2_BOOTADDR : + cpu_is_omap44xx() ? OMAP4_CTRL_MODULE_CORE_DSP_BOOTADDR : + soc_is_omap54xx() ? OMAP4_CTRL_MODULE_CORE_DSP_BOOTADDR : + 0; + + if (!offset) { + pr_err("%s: unsupported omap type\n", __func__); + return; + } + + omap_ctrl_writel(bootaddr, offset); +} + +/** + * omap_ctrl_write_dsp_boot_mode - set boot mode for a remote processor + * @bootmode: 8-bit value to pass to some boot code + * + * Sets boot mode for the boot loader of a supported processor + * when a power ON sequence occurs. + */ +void omap_ctrl_write_dsp_boot_mode(u8 bootmode) +{ + u32 offset = cpu_is_omap243x() ? OMAP243X_CONTROL_IVA2_BOOTMOD : + cpu_is_omap34xx() ? OMAP343X_CONTROL_IVA2_BOOTMOD : + 0; + + if (!offset) { + pr_err("%s: unsupported omap type\n", __func__); + return; + } + + omap_ctrl_writel(bootmode, offset); +} + +#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) +/* + * Clears the scratchpad contents in case of cold boot- + * called during bootup + */ +void omap3_clear_scratchpad_contents(void) +{ + u32 max_offset = OMAP343X_SCRATCHPAD_ROM_OFFSET; + void __iomem *v_addr; + u32 offset = 0; + v_addr = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD_ROM); + if (omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) & + OMAP3430_GLOBAL_COLD_RST_MASK) { + for ( ; offset <= max_offset; offset += 0x4) + writel_relaxed(0x0, (v_addr + offset)); + omap2_prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST_MASK, + OMAP3430_GR_MOD, + OMAP3_PRM_RSTST_OFFSET); + } +} + +/* Populate the scratchpad structure with restore structure */ +void omap3_save_scratchpad_contents(void) +{ + void __iomem *scratchpad_address; + u32 arm_context_addr; + struct omap3_scratchpad scratchpad_contents; + struct omap3_scratchpad_prcm_block prcm_block_contents; + struct omap3_scratchpad_sdrc_block sdrc_block_contents; + + /* + * Populate the Scratchpad contents + * + * The "get_*restore_pointer" functions are used to provide a + * physical restore address where the ROM code jumps while waking + * up from MPU OFF/OSWR state. + * The restore pointer is stored into the scratchpad. + */ + scratchpad_contents.boot_config_ptr = 0x0; + if (cpu_is_omap3630()) + scratchpad_contents.public_restore_ptr = + virt_to_phys(omap3_restore_3630); + else if (omap_rev() != OMAP3430_REV_ES3_0 && + omap_rev() != OMAP3430_REV_ES3_1) + scratchpad_contents.public_restore_ptr = + virt_to_phys(omap3_restore); + else + scratchpad_contents.public_restore_ptr = + virt_to_phys(omap3_restore_es3); + + if (omap_type() == OMAP2_DEVICE_TYPE_GP) + scratchpad_contents.secure_ram_restore_ptr = 0x0; + else + scratchpad_contents.secure_ram_restore_ptr = + (u32) __pa(omap3_secure_ram_storage); + scratchpad_contents.sdrc_module_semaphore = 0x0; + scratchpad_contents.prcm_block_offset = 0x2C; + scratchpad_contents.sdrc_block_offset = 0x64; + + /* Populate the PRCM block contents */ + prcm_block_contents.prm_clksrc_ctrl = + omap2_prm_read_mod_reg(OMAP3430_GR_MOD, + OMAP3_PRM_CLKSRC_CTRL_OFFSET); + prcm_block_contents.prm_clksel = + omap2_prm_read_mod_reg(OMAP3430_CCR_MOD, + OMAP3_PRM_CLKSEL_OFFSET); + + omap3_cm_save_scratchpad_contents(prcm_block_contents.cm_contents); + + prcm_block_contents.prcm_block_size = 0x0; + + /* Populate the SDRC block contents */ + sdrc_block_contents.sysconfig = + (sdrc_read_reg(SDRC_SYSCONFIG) & 0xFFFF); + sdrc_block_contents.cs_cfg = + (sdrc_read_reg(SDRC_CS_CFG) & 0xFFFF); + sdrc_block_contents.sharing = + (sdrc_read_reg(SDRC_SHARING) & 0xFFFF); + sdrc_block_contents.err_type = + (sdrc_read_reg(SDRC_ERR_TYPE) & 0xFFFF); + sdrc_block_contents.dll_a_ctrl = sdrc_read_reg(SDRC_DLLA_CTRL); + sdrc_block_contents.dll_b_ctrl = 0x0; + /* + * Due to a OMAP3 errata (1.142), on EMU/HS devices SRDC should + * be programed to issue automatic self refresh on timeout + * of AUTO_CNT = 1 prior to any transition to OFF mode. + */ + if ((omap_type() != OMAP2_DEVICE_TYPE_GP) + && (omap_rev() >= OMAP3430_REV_ES3_0)) + sdrc_block_contents.power = (sdrc_read_reg(SDRC_POWER) & + ~(SDRC_POWER_AUTOCOUNT_MASK| + SDRC_POWER_CLKCTRL_MASK)) | + (1 << SDRC_POWER_AUTOCOUNT_SHIFT) | + SDRC_SELF_REFRESH_ON_AUTOCOUNT; + else + sdrc_block_contents.power = sdrc_read_reg(SDRC_POWER); + + sdrc_block_contents.cs_0 = 0x0; + sdrc_block_contents.mcfg_0 = sdrc_read_reg(SDRC_MCFG_0); + sdrc_block_contents.mr_0 = (sdrc_read_reg(SDRC_MR_0) & 0xFFFF); + sdrc_block_contents.emr_1_0 = 0x0; + sdrc_block_contents.emr_2_0 = 0x0; + sdrc_block_contents.emr_3_0 = 0x0; + sdrc_block_contents.actim_ctrla_0 = + sdrc_read_reg(SDRC_ACTIM_CTRL_A_0); + sdrc_block_contents.actim_ctrlb_0 = + sdrc_read_reg(SDRC_ACTIM_CTRL_B_0); + sdrc_block_contents.rfr_ctrl_0 = + sdrc_read_reg(SDRC_RFR_CTRL_0); + sdrc_block_contents.cs_1 = 0x0; + sdrc_block_contents.mcfg_1 = sdrc_read_reg(SDRC_MCFG_1); + sdrc_block_contents.mr_1 = sdrc_read_reg(SDRC_MR_1) & 0xFFFF; + sdrc_block_contents.emr_1_1 = 0x0; + sdrc_block_contents.emr_2_1 = 0x0; + sdrc_block_contents.emr_3_1 = 0x0; + sdrc_block_contents.actim_ctrla_1 = + sdrc_read_reg(SDRC_ACTIM_CTRL_A_1); + sdrc_block_contents.actim_ctrlb_1 = + sdrc_read_reg(SDRC_ACTIM_CTRL_B_1); + sdrc_block_contents.rfr_ctrl_1 = + sdrc_read_reg(SDRC_RFR_CTRL_1); + sdrc_block_contents.dcdl_1_ctrl = 0x0; + sdrc_block_contents.dcdl_2_ctrl = 0x0; + sdrc_block_contents.flags = 0x0; + sdrc_block_contents.block_size = 0x0; + + arm_context_addr = virt_to_phys(omap3_arm_context); + + /* Copy all the contents to the scratchpad location */ + scratchpad_address = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD); + memcpy_toio(scratchpad_address, &scratchpad_contents, + sizeof(scratchpad_contents)); + /* Scratchpad contents being 32 bits, a divide by 4 done here */ + memcpy_toio(scratchpad_address + + scratchpad_contents.prcm_block_offset, + &prcm_block_contents, sizeof(prcm_block_contents)); + memcpy_toio(scratchpad_address + + scratchpad_contents.sdrc_block_offset, + &sdrc_block_contents, sizeof(sdrc_block_contents)); + /* + * Copies the address of the location in SDRAM where ARM + * registers get saved during a MPU OFF transition. + */ + memcpy_toio(scratchpad_address + + scratchpad_contents.sdrc_block_offset + + sizeof(sdrc_block_contents), &arm_context_addr, 4); +} + +void omap3_control_save_context(void) +{ + control_context.sysconfig = omap_ctrl_readl(OMAP2_CONTROL_SYSCONFIG); + control_context.devconf0 = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); + control_context.mem_dftrw0 = + omap_ctrl_readl(OMAP343X_CONTROL_MEM_DFTRW0); + control_context.mem_dftrw1 = + omap_ctrl_readl(OMAP343X_CONTROL_MEM_DFTRW1); + control_context.msuspendmux_0 = + omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_0); + control_context.msuspendmux_1 = + omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_1); + control_context.msuspendmux_2 = + omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_2); + control_context.msuspendmux_3 = + omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_3); + control_context.msuspendmux_4 = + omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_4); + control_context.msuspendmux_5 = + omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_5); + control_context.sec_ctrl = omap_ctrl_readl(OMAP2_CONTROL_SEC_CTRL); + control_context.devconf1 = omap_ctrl_readl(OMAP343X_CONTROL_DEVCONF1); + control_context.csirxfe = omap_ctrl_readl(OMAP343X_CONTROL_CSIRXFE); + control_context.iva2_bootaddr = + omap_ctrl_readl(OMAP343X_CONTROL_IVA2_BOOTADDR); + control_context.iva2_bootmod = + omap_ctrl_readl(OMAP343X_CONTROL_IVA2_BOOTMOD); + control_context.debobs_0 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(0)); + control_context.debobs_1 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(1)); + control_context.debobs_2 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(2)); + control_context.debobs_3 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(3)); + control_context.debobs_4 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(4)); + control_context.debobs_5 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(5)); + control_context.debobs_6 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(6)); + control_context.debobs_7 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(7)); + control_context.debobs_8 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(8)); + control_context.prog_io0 = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO0); + control_context.prog_io1 = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO1); + control_context.dss_dpll_spreading = + omap_ctrl_readl(OMAP343X_CONTROL_DSS_DPLL_SPREADING); + control_context.core_dpll_spreading = + omap_ctrl_readl(OMAP343X_CONTROL_CORE_DPLL_SPREADING); + control_context.per_dpll_spreading = + omap_ctrl_readl(OMAP343X_CONTROL_PER_DPLL_SPREADING); + control_context.usbhost_dpll_spreading = + omap_ctrl_readl(OMAP343X_CONTROL_USBHOST_DPLL_SPREADING); + control_context.pbias_lite = + omap_ctrl_readl(OMAP343X_CONTROL_PBIAS_LITE); + control_context.temp_sensor = + omap_ctrl_readl(OMAP343X_CONTROL_TEMP_SENSOR); + control_context.sramldo4 = omap_ctrl_readl(OMAP343X_CONTROL_SRAMLDO4); + control_context.sramldo5 = omap_ctrl_readl(OMAP343X_CONTROL_SRAMLDO5); + control_context.csi = omap_ctrl_readl(OMAP343X_CONTROL_CSI); + control_context.padconf_sys_nirq = + omap_ctrl_readl(OMAP343X_CONTROL_PADCONF_SYSNIRQ); + return; +} + +void omap3_control_restore_context(void) +{ + omap_ctrl_writel(control_context.sysconfig, OMAP2_CONTROL_SYSCONFIG); + omap_ctrl_writel(control_context.devconf0, OMAP2_CONTROL_DEVCONF0); + omap_ctrl_writel(control_context.mem_dftrw0, + OMAP343X_CONTROL_MEM_DFTRW0); + omap_ctrl_writel(control_context.mem_dftrw1, + OMAP343X_CONTROL_MEM_DFTRW1); + omap_ctrl_writel(control_context.msuspendmux_0, + OMAP2_CONTROL_MSUSPENDMUX_0); + omap_ctrl_writel(control_context.msuspendmux_1, + OMAP2_CONTROL_MSUSPENDMUX_1); + omap_ctrl_writel(control_context.msuspendmux_2, + OMAP2_CONTROL_MSUSPENDMUX_2); + omap_ctrl_writel(control_context.msuspendmux_3, + OMAP2_CONTROL_MSUSPENDMUX_3); + omap_ctrl_writel(control_context.msuspendmux_4, + OMAP2_CONTROL_MSUSPENDMUX_4); + omap_ctrl_writel(control_context.msuspendmux_5, + OMAP2_CONTROL_MSUSPENDMUX_5); + omap_ctrl_writel(control_context.sec_ctrl, OMAP2_CONTROL_SEC_CTRL); + omap_ctrl_writel(control_context.devconf1, OMAP343X_CONTROL_DEVCONF1); + omap_ctrl_writel(control_context.csirxfe, OMAP343X_CONTROL_CSIRXFE); + omap_ctrl_writel(control_context.iva2_bootaddr, + OMAP343X_CONTROL_IVA2_BOOTADDR); + omap_ctrl_writel(control_context.iva2_bootmod, + OMAP343X_CONTROL_IVA2_BOOTMOD); + omap_ctrl_writel(control_context.debobs_0, OMAP343X_CONTROL_DEBOBS(0)); + omap_ctrl_writel(control_context.debobs_1, OMAP343X_CONTROL_DEBOBS(1)); + omap_ctrl_writel(control_context.debobs_2, OMAP343X_CONTROL_DEBOBS(2)); + omap_ctrl_writel(control_context.debobs_3, OMAP343X_CONTROL_DEBOBS(3)); + omap_ctrl_writel(control_context.debobs_4, OMAP343X_CONTROL_DEBOBS(4)); + omap_ctrl_writel(control_context.debobs_5, OMAP343X_CONTROL_DEBOBS(5)); + omap_ctrl_writel(control_context.debobs_6, OMAP343X_CONTROL_DEBOBS(6)); + omap_ctrl_writel(control_context.debobs_7, OMAP343X_CONTROL_DEBOBS(7)); + omap_ctrl_writel(control_context.debobs_8, OMAP343X_CONTROL_DEBOBS(8)); + omap_ctrl_writel(control_context.prog_io0, OMAP343X_CONTROL_PROG_IO0); + omap_ctrl_writel(control_context.prog_io1, OMAP343X_CONTROL_PROG_IO1); + omap_ctrl_writel(control_context.dss_dpll_spreading, + OMAP343X_CONTROL_DSS_DPLL_SPREADING); + omap_ctrl_writel(control_context.core_dpll_spreading, + OMAP343X_CONTROL_CORE_DPLL_SPREADING); + omap_ctrl_writel(control_context.per_dpll_spreading, + OMAP343X_CONTROL_PER_DPLL_SPREADING); + omap_ctrl_writel(control_context.usbhost_dpll_spreading, + OMAP343X_CONTROL_USBHOST_DPLL_SPREADING); + omap_ctrl_writel(control_context.pbias_lite, + OMAP343X_CONTROL_PBIAS_LITE); + omap_ctrl_writel(control_context.temp_sensor, + OMAP343X_CONTROL_TEMP_SENSOR); + omap_ctrl_writel(control_context.sramldo4, OMAP343X_CONTROL_SRAMLDO4); + omap_ctrl_writel(control_context.sramldo5, OMAP343X_CONTROL_SRAMLDO5); + omap_ctrl_writel(control_context.csi, OMAP343X_CONTROL_CSI); + omap_ctrl_writel(control_context.padconf_sys_nirq, + OMAP343X_CONTROL_PADCONF_SYSNIRQ); + return; +} + +void omap3630_ctrl_disable_rta(void) +{ + if (!cpu_is_omap3630()) + return; + omap_ctrl_writel(OMAP36XX_RTA_DISABLE, OMAP36XX_CONTROL_MEM_RTA_CTRL); +} + +/** + * omap3_ctrl_save_padconf - save padconf registers to scratchpad RAM + * + * Tell the SCM to start saving the padconf registers, then wait for + * the process to complete. Returns 0 unconditionally, although it + * should also eventually be able to return -ETIMEDOUT, if the save + * does not complete. + * + * XXX This function is missing a timeout. What should it be? + */ +int omap3_ctrl_save_padconf(void) +{ + u32 cpo; + + /* Save the padconf registers */ + cpo = omap_ctrl_readl(OMAP343X_CONTROL_PADCONF_OFF); + cpo |= START_PADCONF_SAVE; + omap_ctrl_writel(cpo, OMAP343X_CONTROL_PADCONF_OFF); + + /* wait for the save to complete */ + while (!(omap_ctrl_readl(OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS) + & PADCONF_SAVE_DONE)) + udelay(1); + + return 0; +} + +/** + * omap3_ctrl_set_iva_bootmode_idle - sets the IVA2 bootmode to idle + * + * Sets the bootmode for IVA2 to idle. This is needed by the PM code to + * force disable IVA2 so that it does not prevent any low-power states. + */ +void omap3_ctrl_set_iva_bootmode_idle(void) +{ + omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE, + OMAP343X_CONTROL_IVA2_BOOTMOD); +} +#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */ diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h new file mode 100644 index 00000000000..da054801b11 --- /dev/null +++ b/arch/arm/mach-omap2/control.h @@ -0,0 +1,447 @@ +/* + * arch/arm/mach-omap2/control.h + * + * OMAP2/3/4 System Control Module definitions + * + * Copyright (C) 2007-2010 Texas Instruments, Inc. + * Copyright (C) 2007-2008, 2010 Nokia Corporation + * + * Written by Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CONTROL_H +#define __ARCH_ARM_MACH_OMAP2_CONTROL_H + +#include "ctrl_module_core_44xx.h" +#include "ctrl_module_wkup_44xx.h" +#include "ctrl_module_pad_core_44xx.h" +#include "ctrl_module_pad_wkup_44xx.h" + +#include "am33xx.h" + +#ifndef __ASSEMBLY__ +#define OMAP242X_CTRL_REGADDR(reg) \ + OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE + (reg)) +#define OMAP243X_CTRL_REGADDR(reg) \ + OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE + (reg)) +#define OMAP343X_CTRL_REGADDR(reg) \ + OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg)) +#define AM33XX_CTRL_REGADDR(reg) \ + AM33XX_L4_WK_IO_ADDRESS(AM33XX_SCM_BASE + (reg)) +#else +#define OMAP242X_CTRL_REGADDR(reg) \ + OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE + (reg)) +#define OMAP243X_CTRL_REGADDR(reg) \ + OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE + (reg)) +#define OMAP343X_CTRL_REGADDR(reg) \ + OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg)) +#define AM33XX_CTRL_REGADDR(reg) \ + AM33XX_L4_WK_IO_ADDRESS(AM33XX_SCM_BASE + (reg)) +#endif /* __ASSEMBLY__ */ + +/* + * As elsewhere, the "OMAP2_" prefix indicates that the macro is valid for + * OMAP24XX and OMAP34XX. + */ + +/* Control submodule offsets */ + +#define OMAP2_CONTROL_INTERFACE 0x000 +#define OMAP2_CONTROL_PADCONFS 0x030 +#define OMAP2_CONTROL_GENERAL 0x270 +#define OMAP343X_CONTROL_MEM_WKUP 0x600 +#define OMAP343X_CONTROL_PADCONFS_WKUP 0xa00 +#define OMAP343X_CONTROL_GENERAL_WKUP 0xa60 + +/* TI81XX spefic control submodules */ +#define TI81XX_CONTROL_DEVCONF 0x600 + +/* Control register offsets - read/write with omap_ctrl_{read,write}{bwl}() */ + +#define OMAP2_CONTROL_SYSCONFIG (OMAP2_CONTROL_INTERFACE + 0x10) + +/* CONTROL_GENERAL register offsets common to OMAP2 & 3 */ +#define OMAP2_CONTROL_DEVCONF0 (OMAP2_CONTROL_GENERAL + 0x0004) +#define OMAP2_CONTROL_MSUSPENDMUX_0 (OMAP2_CONTROL_GENERAL + 0x0020) +#define OMAP2_CONTROL_MSUSPENDMUX_1 (OMAP2_CONTROL_GENERAL + 0x0024) +#define OMAP2_CONTROL_MSUSPENDMUX_2 (OMAP2_CONTROL_GENERAL + 0x0028) +#define OMAP2_CONTROL_MSUSPENDMUX_3 (OMAP2_CONTROL_GENERAL + 0x002c) +#define OMAP2_CONTROL_MSUSPENDMUX_4 (OMAP2_CONTROL_GENERAL + 0x0030) +#define OMAP2_CONTROL_MSUSPENDMUX_5 (OMAP2_CONTROL_GENERAL + 0x0034) +#define OMAP2_CONTROL_SEC_CTRL (OMAP2_CONTROL_GENERAL + 0x0040) +#define OMAP2_CONTROL_RPUB_KEY_H_0 (OMAP2_CONTROL_GENERAL + 0x0090) +#define OMAP2_CONTROL_RPUB_KEY_H_1 (OMAP2_CONTROL_GENERAL + 0x0094) +#define OMAP2_CONTROL_RPUB_KEY_H_2 (OMAP2_CONTROL_GENERAL + 0x0098) +#define OMAP2_CONTROL_RPUB_KEY_H_3 (OMAP2_CONTROL_GENERAL + 0x009c) + +/* 242x-only CONTROL_GENERAL register offsets */ +#define OMAP242X_CONTROL_DEVCONF OMAP2_CONTROL_DEVCONF0 /* match TRM */ +#define OMAP242X_CONTROL_OCM_RAM_PERM (OMAP2_CONTROL_GENERAL + 0x0068) + +/* 243x-only CONTROL_GENERAL register offsets */ +/* CONTROL_IVA2_BOOT{ADDR,MOD} are at the same place on 343x - noted below */ +#define OMAP243X_CONTROL_DEVCONF1 (OMAP2_CONTROL_GENERAL + 0x0078) +#define OMAP243X_CONTROL_CSIRXFE (OMAP2_CONTROL_GENERAL + 0x007c) +#define OMAP243X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) +#define OMAP243X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) +#define OMAP243X_CONTROL_IVA2_GEMCFG (OMAP2_CONTROL_GENERAL + 0x0198) +#define OMAP243X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x0230) + +/* 24xx-only CONTROL_GENERAL register offsets */ +#define OMAP24XX_CONTROL_DEBOBS (OMAP2_CONTROL_GENERAL + 0x0000) +#define OMAP24XX_CONTROL_EMU_SUPPORT (OMAP2_CONTROL_GENERAL + 0x0008) +#define OMAP24XX_CONTROL_SEC_TEST (OMAP2_CONTROL_GENERAL + 0x0044) +#define OMAP24XX_CONTROL_PSA_CTRL (OMAP2_CONTROL_GENERAL + 0x0048) +#define OMAP24XX_CONTROL_PSA_CMD (OMAP2_CONTROL_GENERAL + 0x004c) +#define OMAP24XX_CONTROL_PSA_VALUE (OMAP2_CONTROL_GENERAL + 0x0050) +#define OMAP24XX_CONTROL_SEC_EMU (OMAP2_CONTROL_GENERAL + 0x0060) +#define OMAP24XX_CONTROL_SEC_TAP (OMAP2_CONTROL_GENERAL + 0x0064) +#define OMAP24XX_CONTROL_OCM_PUB_RAM_ADD (OMAP2_CONTROL_GENERAL + 0x006c) +#define OMAP24XX_CONTROL_EXT_SEC_RAM_START_ADD (OMAP2_CONTROL_GENERAL + 0x0070) +#define OMAP24XX_CONTROL_EXT_SEC_RAM_STOP_ADD (OMAP2_CONTROL_GENERAL + 0x0074) +#define OMAP24XX_CONTROL_SEC_STATUS (OMAP2_CONTROL_GENERAL + 0x0080) +#define OMAP24XX_CONTROL_SEC_ERR_STATUS (OMAP2_CONTROL_GENERAL + 0x0084) +#define OMAP24XX_CONTROL_STATUS (OMAP2_CONTROL_GENERAL + 0x0088) +#define OMAP24XX_CONTROL_GENERAL_PURPOSE_STATUS (OMAP2_CONTROL_GENERAL + 0x008c) +#define OMAP24XX_CONTROL_RAND_KEY_0 (OMAP2_CONTROL_GENERAL + 0x00a0) +#define OMAP24XX_CONTROL_RAND_KEY_1 (OMAP2_CONTROL_GENERAL + 0x00a4) +#define OMAP24XX_CONTROL_RAND_KEY_2 (OMAP2_CONTROL_GENERAL + 0x00a8) +#define OMAP24XX_CONTROL_RAND_KEY_3 (OMAP2_CONTROL_GENERAL + 0x00ac) +#define OMAP24XX_CONTROL_CUST_KEY_0 (OMAP2_CONTROL_GENERAL + 0x00b0) +#define OMAP24XX_CONTROL_CUST_KEY_1 (OMAP2_CONTROL_GENERAL + 0x00b4) +#define OMAP24XX_CONTROL_TEST_KEY_0 (OMAP2_CONTROL_GENERAL + 0x00c0) +#define OMAP24XX_CONTROL_TEST_KEY_1 (OMAP2_CONTROL_GENERAL + 0x00c4) +#define OMAP24XX_CONTROL_TEST_KEY_2 (OMAP2_CONTROL_GENERAL + 0x00c8) +#define OMAP24XX_CONTROL_TEST_KEY_3 (OMAP2_CONTROL_GENERAL + 0x00cc) +#define OMAP24XX_CONTROL_TEST_KEY_4 (OMAP2_CONTROL_GENERAL + 0x00d0) +#define OMAP24XX_CONTROL_TEST_KEY_5 (OMAP2_CONTROL_GENERAL + 0x00d4) +#define OMAP24XX_CONTROL_TEST_KEY_6 (OMAP2_CONTROL_GENERAL + 0x00d8) +#define OMAP24XX_CONTROL_TEST_KEY_7 (OMAP2_CONTROL_GENERAL + 0x00dc) +#define OMAP24XX_CONTROL_TEST_KEY_8 (OMAP2_CONTROL_GENERAL + 0x00e0) +#define OMAP24XX_CONTROL_TEST_KEY_9 (OMAP2_CONTROL_GENERAL + 0x00e4) + +#define OMAP343X_CONTROL_PADCONF_SYSNIRQ (OMAP2_CONTROL_INTERFACE + 0x01b0) + +/* 34xx-only CONTROL_GENERAL register offsets */ +#define OMAP343X_CONTROL_PADCONF_OFF (OMAP2_CONTROL_GENERAL + 0x0000) +#define OMAP343X_CONTROL_MEM_DFTRW0 (OMAP2_CONTROL_GENERAL + 0x0008) +#define OMAP343X_CONTROL_MEM_DFTRW1 (OMAP2_CONTROL_GENERAL + 0x000c) +#define OMAP343X_CONTROL_DEVCONF1 (OMAP2_CONTROL_GENERAL + 0x0068) +#define OMAP343X_CONTROL_CSIRXFE (OMAP2_CONTROL_GENERAL + 0x006c) +#define OMAP343X_CONTROL_SEC_STATUS (OMAP2_CONTROL_GENERAL + 0x0070) +#define OMAP343X_CONTROL_SEC_ERR_STATUS (OMAP2_CONTROL_GENERAL + 0x0074) +#define OMAP343X_CONTROL_SEC_ERR_STATUS_DEBUG (OMAP2_CONTROL_GENERAL + 0x0078) +#define OMAP343X_CONTROL_STATUS (OMAP2_CONTROL_GENERAL + 0x0080) +#define OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS (OMAP2_CONTROL_GENERAL + 0x0084) +#define OMAP343X_CONTROL_RPUB_KEY_H_4 (OMAP2_CONTROL_GENERAL + 0x00a0) +#define OMAP343X_CONTROL_RAND_KEY_0 (OMAP2_CONTROL_GENERAL + 0x00a8) +#define OMAP343X_CONTROL_RAND_KEY_1 (OMAP2_CONTROL_GENERAL + 0x00ac) +#define OMAP343X_CONTROL_RAND_KEY_2 (OMAP2_CONTROL_GENERAL + 0x00b0) +#define OMAP343X_CONTROL_RAND_KEY_3 (OMAP2_CONTROL_GENERAL + 0x00b4) +#define OMAP343X_CONTROL_TEST_KEY_0 (OMAP2_CONTROL_GENERAL + 0x00c8) +#define OMAP343X_CONTROL_TEST_KEY_1 (OMAP2_CONTROL_GENERAL + 0x00cc) +#define OMAP343X_CONTROL_TEST_KEY_2 (OMAP2_CONTROL_GENERAL + 0x00d0) +#define OMAP343X_CONTROL_TEST_KEY_3 (OMAP2_CONTROL_GENERAL + 0x00d4) +#define OMAP343X_CONTROL_TEST_KEY_4 (OMAP2_CONTROL_GENERAL + 0x00d8) +#define OMAP343X_CONTROL_TEST_KEY_5 (OMAP2_CONTROL_GENERAL + 0x00dc) +#define OMAP343X_CONTROL_TEST_KEY_6 (OMAP2_CONTROL_GENERAL + 0x00e0) +#define OMAP343X_CONTROL_TEST_KEY_7 (OMAP2_CONTROL_GENERAL + 0x00e4) +#define OMAP343X_CONTROL_TEST_KEY_8 (OMAP2_CONTROL_GENERAL + 0x00e8) +#define OMAP343X_CONTROL_TEST_KEY_9 (OMAP2_CONTROL_GENERAL + 0x00ec) +#define OMAP343X_CONTROL_TEST_KEY_10 (OMAP2_CONTROL_GENERAL + 0x00f0) +#define OMAP343X_CONTROL_TEST_KEY_11 (OMAP2_CONTROL_GENERAL + 0x00f4) +#define OMAP343X_CONTROL_TEST_KEY_12 (OMAP2_CONTROL_GENERAL + 0x00f8) +#define OMAP343X_CONTROL_TEST_KEY_13 (OMAP2_CONTROL_GENERAL + 0x00fc) +#define OMAP343X_CONTROL_FUSE_OPP1_VDD1 (OMAP2_CONTROL_GENERAL + 0x0110) +#define OMAP343X_CONTROL_FUSE_OPP2_VDD1 (OMAP2_CONTROL_GENERAL + 0x0114) +#define OMAP343X_CONTROL_FUSE_OPP3_VDD1 (OMAP2_CONTROL_GENERAL + 0x0118) +#define OMAP343X_CONTROL_FUSE_OPP4_VDD1 (OMAP2_CONTROL_GENERAL + 0x011c) +#define OMAP343X_CONTROL_FUSE_OPP5_VDD1 (OMAP2_CONTROL_GENERAL + 0x0120) +#define OMAP343X_CONTROL_FUSE_OPP1_VDD2 (OMAP2_CONTROL_GENERAL + 0x0124) +#define OMAP343X_CONTROL_FUSE_OPP2_VDD2 (OMAP2_CONTROL_GENERAL + 0x0128) +#define OMAP343X_CONTROL_FUSE_OPP3_VDD2 (OMAP2_CONTROL_GENERAL + 0x012c) +#define OMAP343X_CONTROL_FUSE_SR (OMAP2_CONTROL_GENERAL + 0x0130) +#define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) +#define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) +#define OMAP343X_CONTROL_DEBOBS(i) (OMAP2_CONTROL_GENERAL + 0x01B0 \ + + ((i) >> 1) * 4 + (!((i) & 1)) * 2) +#define OMAP343X_CONTROL_PROG_IO0 (OMAP2_CONTROL_GENERAL + 0x01D4) +#define OMAP343X_CONTROL_PROG_IO1 (OMAP2_CONTROL_GENERAL + 0x01D8) +#define OMAP343X_CONTROL_DSS_DPLL_SPREADING (OMAP2_CONTROL_GENERAL + 0x01E0) +#define OMAP343X_CONTROL_CORE_DPLL_SPREADING (OMAP2_CONTROL_GENERAL + 0x01E4) +#define OMAP343X_CONTROL_PER_DPLL_SPREADING (OMAP2_CONTROL_GENERAL + 0x01E8) +#define OMAP343X_CONTROL_USBHOST_DPLL_SPREADING (OMAP2_CONTROL_GENERAL + 0x01EC) +#define OMAP343X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x02B0) +#define OMAP343X_CONTROL_TEMP_SENSOR (OMAP2_CONTROL_GENERAL + 0x02B4) +#define OMAP343X_CONTROL_SRAMLDO4 (OMAP2_CONTROL_GENERAL + 0x02B8) +#define OMAP343X_CONTROL_SRAMLDO5 (OMAP2_CONTROL_GENERAL + 0x02C0) +#define OMAP343X_CONTROL_CSI (OMAP2_CONTROL_GENERAL + 0x02C4) + +/* OMAP3630 only CONTROL_GENERAL register offsets */ +#define OMAP3630_CONTROL_FUSE_OPP1G_VDD1 (OMAP2_CONTROL_GENERAL + 0x0110) +#define OMAP3630_CONTROL_FUSE_OPP50_VDD1 (OMAP2_CONTROL_GENERAL + 0x0114) +#define OMAP3630_CONTROL_FUSE_OPP100_VDD1 (OMAP2_CONTROL_GENERAL + 0x0118) +#define OMAP3630_CONTROL_FUSE_OPP120_VDD1 (OMAP2_CONTROL_GENERAL + 0x0120) +#define OMAP3630_CONTROL_FUSE_OPP50_VDD2 (OMAP2_CONTROL_GENERAL + 0x0128) +#define OMAP3630_CONTROL_FUSE_OPP100_VDD2 (OMAP2_CONTROL_GENERAL + 0x012C) +#define OMAP3630_CONTROL_CAMERA_PHY_CTRL (OMAP2_CONTROL_GENERAL + 0x02f0) + +/* OMAP44xx control efuse offsets */ +#define OMAP44XX_CONTROL_FUSE_IVA_OPP50 0x22C +#define OMAP44XX_CONTROL_FUSE_IVA_OPP100 0x22F +#define OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO 0x232 +#define OMAP44XX_CONTROL_FUSE_IVA_OPPNITRO 0x235 +#define OMAP44XX_CONTROL_FUSE_MPU_OPP50 0x240 +#define OMAP44XX_CONTROL_FUSE_MPU_OPP100 0x243 +#define OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO 0x246 +#define OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO 0x249 +#define OMAP44XX_CONTROL_FUSE_CORE_OPP50 0x254 +#define OMAP44XX_CONTROL_FUSE_CORE_OPP100 0x257 +#define OMAP44XX_CONTROL_FUSE_CORE_OPP100OV 0x25A + +/* AM35XX only CONTROL_GENERAL register offsets */ +#define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038) +#define AM35XX_CONTROL_DEVCONF2 (OMAP2_CONTROL_GENERAL + 0x0310) +#define AM35XX_CONTROL_DEVCONF3 (OMAP2_CONTROL_GENERAL + 0x0314) +#define AM35XX_CONTROL_CBA_PRIORITY (OMAP2_CONTROL_GENERAL + 0x0320) +#define AM35XX_CONTROL_LVL_INTR_CLEAR (OMAP2_CONTROL_GENERAL + 0x0324) +#define AM35XX_CONTROL_IP_SW_RESET (OMAP2_CONTROL_GENERAL + 0x0328) +#define AM35XX_CONTROL_IPSS_CLK_CTRL (OMAP2_CONTROL_GENERAL + 0x032C) + +/* 34xx PADCONF register offsets */ +#define OMAP343X_PADCONF_ETK(i) (OMAP2_CONTROL_PADCONFS + 0x5a8 + \ + (i)*2) +#define OMAP343X_PADCONF_ETK_CLK OMAP343X_PADCONF_ETK(0) +#define OMAP343X_PADCONF_ETK_CTL OMAP343X_PADCONF_ETK(1) +#define OMAP343X_PADCONF_ETK_D0 OMAP343X_PADCONF_ETK(2) +#define OMAP343X_PADCONF_ETK_D1 OMAP343X_PADCONF_ETK(3) +#define OMAP343X_PADCONF_ETK_D2 OMAP343X_PADCONF_ETK(4) +#define OMAP343X_PADCONF_ETK_D3 OMAP343X_PADCONF_ETK(5) +#define OMAP343X_PADCONF_ETK_D4 OMAP343X_PADCONF_ETK(6) +#define OMAP343X_PADCONF_ETK_D5 OMAP343X_PADCONF_ETK(7) +#define OMAP343X_PADCONF_ETK_D6 OMAP343X_PADCONF_ETK(8) +#define OMAP343X_PADCONF_ETK_D7 OMAP343X_PADCONF_ETK(9) +#define OMAP343X_PADCONF_ETK_D8 OMAP343X_PADCONF_ETK(10) +#define OMAP343X_PADCONF_ETK_D9 OMAP343X_PADCONF_ETK(11) +#define OMAP343X_PADCONF_ETK_D10 OMAP343X_PADCONF_ETK(12) +#define OMAP343X_PADCONF_ETK_D11 OMAP343X_PADCONF_ETK(13) +#define OMAP343X_PADCONF_ETK_D12 OMAP343X_PADCONF_ETK(14) +#define OMAP343X_PADCONF_ETK_D13 OMAP343X_PADCONF_ETK(15) +#define OMAP343X_PADCONF_ETK_D14 OMAP343X_PADCONF_ETK(16) +#define OMAP343X_PADCONF_ETK_D15 OMAP343X_PADCONF_ETK(17) + +/* 34xx GENERAL_WKUP register offsets */ +#define OMAP343X_CONTROL_WKUP_DEBOBSMUX(i) (OMAP343X_CONTROL_GENERAL_WKUP + \ + 0x008 + (i)) +#define OMAP343X_CONTROL_WKUP_DEBOBS0 (OMAP343X_CONTROL_GENERAL_WKUP + 0x008) +#define OMAP343X_CONTROL_WKUP_DEBOBS1 (OMAP343X_CONTROL_GENERAL_WKUP + 0x00C) +#define OMAP343X_CONTROL_WKUP_DEBOBS2 (OMAP343X_CONTROL_GENERAL_WKUP + 0x010) +#define OMAP343X_CONTROL_WKUP_DEBOBS3 (OMAP343X_CONTROL_GENERAL_WKUP + 0x014) +#define OMAP343X_CONTROL_WKUP_DEBOBS4 (OMAP343X_CONTROL_GENERAL_WKUP + 0x018) + +/* 36xx-only RTA - Retention till Access control registers and bits */ +#define OMAP36XX_CONTROL_MEM_RTA_CTRL 0x40C +#define OMAP36XX_RTA_DISABLE 0x0 + +/* 34xx D2D idle-related pins, handled by PM core */ +#define OMAP3_PADCONF_SAD2D_MSTANDBY 0x250 +#define OMAP3_PADCONF_SAD2D_IDLEACK 0x254 + +/* TI81XX CONTROL_DEVCONF register offsets */ +#define TI81XX_CONTROL_DEVICE_ID (TI81XX_CONTROL_DEVCONF + 0x000) + +/* OMAP54XX CONTROL STATUS register */ +#define OMAP5XXX_CONTROL_STATUS 0x134 +#define OMAP5_DEVICETYPE_MASK (0x7 << 6) + +/* + * REVISIT: This list of registers is not comprehensive - there are more + * that should be added. + */ + +/* + * Control module register bit defines - these should eventually go into + * their own regbits file. Some of these will be complicated, depending + * on the device type (general-purpose, emulator, test, secure, bad, other) + * and the security mode (secure, non-secure, don't care) + */ +/* CONTROL_DEVCONF0 bits */ +#define OMAP2_MMCSDIO1ADPCLKISEL (1 << 24) /* MMC1 loop back clock */ +#define OMAP24XX_USBSTANDBYCTRL (1 << 15) +#define OMAP2_MCBSP2_CLKS_MASK (1 << 6) +#define OMAP2_MCBSP1_FSR_MASK (1 << 4) +#define OMAP2_MCBSP1_CLKR_MASK (1 << 3) +#define OMAP2_MCBSP1_CLKS_MASK (1 << 2) + +/* CONTROL_DEVCONF1 bits */ +#define OMAP243X_MMC1_ACTIVE_OVERWRITE (1 << 31) +#define OMAP2_MMCSDIO2ADPCLKISEL (1 << 6) /* MMC2 loop back clock */ +#define OMAP2_MCBSP5_CLKS_MASK (1 << 4) /* > 242x */ +#define OMAP2_MCBSP4_CLKS_MASK (1 << 2) /* > 242x */ +#define OMAP2_MCBSP3_CLKS_MASK (1 << 0) /* > 242x */ + +/* CONTROL_STATUS bits */ +#define OMAP2_DEVICETYPE_MASK (0x7 << 8) +#define OMAP2_SYSBOOT_5_MASK (1 << 5) +#define OMAP2_SYSBOOT_4_MASK (1 << 4) +#define OMAP2_SYSBOOT_3_MASK (1 << 3) +#define OMAP2_SYSBOOT_2_MASK (1 << 2) +#define OMAP2_SYSBOOT_1_MASK (1 << 1) +#define OMAP2_SYSBOOT_0_MASK (1 << 0) + +/* CONTROL_PBIAS_LITE bits */ +#define OMAP343X_PBIASLITESUPPLY_HIGH1 (1 << 15) +#define OMAP343X_PBIASLITEVMODEERROR1 (1 << 11) +#define OMAP343X_PBIASSPEEDCTRL1 (1 << 10) +#define OMAP343X_PBIASLITEPWRDNZ1 (1 << 9) +#define OMAP343X_PBIASLITEVMODE1 (1 << 8) +#define OMAP343X_PBIASLITESUPPLY_HIGH0 (1 << 7) +#define OMAP343X_PBIASLITEVMODEERROR0 (1 << 3) +#define OMAP2_PBIASSPEEDCTRL0 (1 << 2) +#define OMAP2_PBIASLITEPWRDNZ0 (1 << 1) +#define OMAP2_PBIASLITEVMODE0 (1 << 0) + +/* CONTROL_PROG_IO1 bits */ +#define OMAP3630_PRG_SDMMC1_SPEEDCTRL (1 << 20) + +/* CONTROL_IVA2_BOOTMOD bits */ +#define OMAP3_IVA2_BOOTMOD_SHIFT 0 +#define OMAP3_IVA2_BOOTMOD_MASK (0xf << 0) +#define OMAP3_IVA2_BOOTMOD_IDLE (0x1 << 0) + +/* CONTROL_PADCONF_X bits */ +#define OMAP3_PADCONF_WAKEUPEVENT0 (1 << 15) +#define OMAP3_PADCONF_WAKEUPENABLE0 (1 << 14) + +#define OMAP343X_SCRATCHPAD_ROM (OMAP343X_CTRL_BASE + 0x860) +#define OMAP343X_SCRATCHPAD (OMAP343X_CTRL_BASE + 0x910) +#define OMAP343X_SCRATCHPAD_ROM_OFFSET 0x19C +#define OMAP343X_SCRATCHPAD_REGADDR(reg) OMAP2_L4_IO_ADDRESS(\ + OMAP343X_SCRATCHPAD + reg) + +/* AM35XX_CONTROL_IPSS_CLK_CTRL bits */ +#define AM35XX_USBOTG_VBUSP_CLK_SHIFT 0 +#define AM35XX_CPGMAC_VBUSP_CLK_SHIFT 1 +#define AM35XX_VPFE_VBUSP_CLK_SHIFT 2 +#define AM35XX_HECC_VBUSP_CLK_SHIFT 3 +#define AM35XX_USBOTG_FCLK_SHIFT 8 +#define AM35XX_CPGMAC_FCLK_SHIFT 9 +#define AM35XX_VPFE_FCLK_SHIFT 10 + +/* AM35XX CONTROL_LVL_INTR_CLEAR bits */ +#define AM35XX_CPGMAC_C0_MISC_PULSE_CLR BIT(0) +#define AM35XX_CPGMAC_C0_RX_PULSE_CLR BIT(1) +#define AM35XX_CPGMAC_C0_RX_THRESH_CLR BIT(2) +#define AM35XX_CPGMAC_C0_TX_PULSE_CLR BIT(3) +#define AM35XX_USBOTGSS_INT_CLR BIT(4) +#define AM35XX_VPFE_CCDC_VD0_INT_CLR BIT(5) +#define AM35XX_VPFE_CCDC_VD1_INT_CLR BIT(6) +#define AM35XX_VPFE_CCDC_VD2_INT_CLR BIT(7) + +/* AM35XX CONTROL_IP_SW_RESET bits */ +#define AM35XX_USBOTGSS_SW_RST BIT(0) +#define AM35XX_CPGMACSS_SW_RST BIT(1) +#define AM35XX_VPFE_VBUSP_SW_RST BIT(2) +#define AM35XX_HECC_SW_RST BIT(3) +#define AM35XX_VPFE_PCLK_SW_RST BIT(4) + +/* AM33XX CONTROL_STATUS register */ +#define AM33XX_CONTROL_STATUS 0x040 +#define AM33XX_CONTROL_SEC_CLK_CTRL 0x1bc + +/* AM33XX CONTROL_STATUS bitfields (partial) */ +#define AM33XX_CONTROL_STATUS_SYSBOOT1_SHIFT 22 +#define AM33XX_CONTROL_STATUS_SYSBOOT1_WIDTH 0x2 +#define AM33XX_CONTROL_STATUS_SYSBOOT1_MASK (0x3 << 22) + +/* AM33XX PWMSS Control register */ +#define AM33XX_PWMSS_TBCLK_CLKCTRL 0x664 + +/* AM33XX PWMSS Control bitfields */ +#define AM33XX_PWMSS0_TBCLKEN_SHIFT 0 +#define AM33XX_PWMSS1_TBCLKEN_SHIFT 1 +#define AM33XX_PWMSS2_TBCLKEN_SHIFT 2 + +/* DEV Feature register to identify AM33XX features */ +#define AM33XX_DEV_FEATURE 0x604 +#define AM33XX_SGX_MASK BIT(29) + +/* CONTROL OMAP STATUS register to identify OMAP3 features */ +#define OMAP3_CONTROL_OMAP_STATUS 0x044c + +#define OMAP3_SGX_SHIFT 13 +#define OMAP3_SGX_MASK (3 << OMAP3_SGX_SHIFT) +#define FEAT_SGX_FULL 0 +#define FEAT_SGX_HALF 1 +#define FEAT_SGX_NONE 2 + +#define OMAP3_IVA_SHIFT 12 +#define OMAP3_IVA_MASK (1 << OMAP3_IVA_SHIFT) +#define FEAT_IVA 0 +#define FEAT_IVA_NONE 1 + +#define OMAP3_L2CACHE_SHIFT 10 +#define OMAP3_L2CACHE_MASK (3 << OMAP3_L2CACHE_SHIFT) +#define FEAT_L2CACHE_NONE 0 +#define FEAT_L2CACHE_64KB 1 +#define FEAT_L2CACHE_128KB 2 +#define FEAT_L2CACHE_256KB 3 + +#define OMAP3_ISP_SHIFT 5 +#define OMAP3_ISP_MASK (1 << OMAP3_ISP_SHIFT) +#define FEAT_ISP 0 +#define FEAT_ISP_NONE 1 + +#define OMAP3_NEON_SHIFT 4 +#define OMAP3_NEON_MASK (1 << OMAP3_NEON_SHIFT) +#define FEAT_NEON 0 +#define FEAT_NEON_NONE 1 + + +#ifndef __ASSEMBLY__ +#ifdef CONFIG_ARCH_OMAP2PLUS +extern void __iomem *omap_ctrl_base_get(void); +extern u8 omap_ctrl_readb(u16 offset); +extern u16 omap_ctrl_readw(u16 offset); +extern u32 omap_ctrl_readl(u16 offset); +extern u32 omap4_ctrl_pad_readl(u16 offset); +extern void omap_ctrl_writeb(u8 val, u16 offset); +extern void omap_ctrl_writew(u16 val, u16 offset); +extern void omap_ctrl_writel(u32 val, u16 offset); +extern void omap4_ctrl_pad_writel(u32 val, u16 offset); + +extern void omap3_save_scratchpad_contents(void); +extern void omap3_clear_scratchpad_contents(void); +extern void omap3_restore(void); +extern void omap3_restore_es3(void); +extern void omap3_restore_3630(void); +extern u32 omap3_arm_context[128]; +extern void omap3_control_save_context(void); +extern void omap3_control_restore_context(void); +extern void omap3_ctrl_write_boot_mode(u8 bootmode); +extern void omap_ctrl_write_dsp_boot_addr(u32 bootaddr); +extern void omap_ctrl_write_dsp_boot_mode(u8 bootmode); +extern void omap3630_ctrl_disable_rta(void); +extern int omap3_ctrl_save_padconf(void); +extern void omap3_ctrl_set_iva_bootmode_idle(void); +extern void omap2_set_globals_control(void __iomem *ctrl, + void __iomem *ctrl_pad); +#else +#define omap_ctrl_base_get() 0 +#define omap_ctrl_readb(x) 0 +#define omap_ctrl_readw(x) 0 +#define omap_ctrl_readl(x) 0 +#define omap4_ctrl_pad_readl(x) 0 +#define omap_ctrl_writeb(x, y) WARN_ON(1) +#define omap_ctrl_writew(x, y) WARN_ON(1) +#define omap_ctrl_writel(x, y) WARN_ON(1) +#define omap4_ctrl_pad_writel(x, y) WARN_ON(1) +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_MACH_OMAP2_CONTROL_H */ + diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c new file mode 100644 index 00000000000..e18709d3b95 --- /dev/null +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -0,0 +1,344 @@ +/* + * linux/arch/arm/mach-omap2/cpuidle34xx.c + * + * OMAP3 CPU IDLE Routines + * + * Copyright (C) 2008 Texas Instruments, Inc. + * Rajendra Nayak <rnayak@ti.com> + * + * Copyright (C) 2007 Texas Instruments, Inc. + * Karthik Dasu <karthik-dp@ti.com> + * + * Copyright (C) 2006 Nokia Corporation + * Tony Lindgren <tony@atomide.com> + * + * Copyright (C) 2005 Texas Instruments, Inc. + * Richard Woodruff <r-woodruff2@ti.com> + * + * Based on pm.c for omap2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/sched.h> +#include <linux/cpuidle.h> +#include <linux/export.h> +#include <linux/cpu_pm.h> +#include <asm/cpuidle.h> + +#include "powerdomain.h" +#include "clockdomain.h" + +#include "pm.h" +#include "control.h" +#include "common.h" + +/* Mach specific information to be recorded in the C-state driver_data */ +struct omap3_idle_statedata { + u8 mpu_state; + u8 core_state; + u8 per_min_state; + u8 flags; +}; + +static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd; + +/* + * Possible flag bits for struct omap3_idle_statedata.flags: + * + * OMAP_CPUIDLE_CX_NO_CLKDM_IDLE: don't allow the MPU clockdomain to go + * inactive. This in turn prevents the MPU DPLL from entering autoidle + * mode, so wakeup latency is greatly reduced, at the cost of additional + * energy consumption. This also prevents the CORE clockdomain from + * entering idle. + */ +#define OMAP_CPUIDLE_CX_NO_CLKDM_IDLE BIT(0) + +/* + * Prevent PER OFF if CORE is not in RETention or OFF as this would + * disable PER wakeups completely. + */ +static struct omap3_idle_statedata omap3_idle_data[] = { + { + .mpu_state = PWRDM_POWER_ON, + .core_state = PWRDM_POWER_ON, + /* In C1 do not allow PER state lower than CORE state */ + .per_min_state = PWRDM_POWER_ON, + .flags = OMAP_CPUIDLE_CX_NO_CLKDM_IDLE, + }, + { + .mpu_state = PWRDM_POWER_ON, + .core_state = PWRDM_POWER_ON, + .per_min_state = PWRDM_POWER_RET, + }, + { + .mpu_state = PWRDM_POWER_RET, + .core_state = PWRDM_POWER_ON, + .per_min_state = PWRDM_POWER_RET, + }, + { + .mpu_state = PWRDM_POWER_OFF, + .core_state = PWRDM_POWER_ON, + .per_min_state = PWRDM_POWER_RET, + }, + { + .mpu_state = PWRDM_POWER_RET, + .core_state = PWRDM_POWER_RET, + .per_min_state = PWRDM_POWER_OFF, + }, + { + .mpu_state = PWRDM_POWER_OFF, + .core_state = PWRDM_POWER_RET, + .per_min_state = PWRDM_POWER_OFF, + }, + { + .mpu_state = PWRDM_POWER_OFF, + .core_state = PWRDM_POWER_OFF, + .per_min_state = PWRDM_POWER_OFF, + }, +}; + +/** + * omap3_enter_idle - Programs OMAP3 to enter the specified state + * @dev: cpuidle device + * @drv: cpuidle driver + * @index: the index of state to be entered + */ +static int omap3_enter_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + struct omap3_idle_statedata *cx = &omap3_idle_data[index]; + + if (omap_irq_pending() || need_resched()) + goto return_sleep_time; + + /* Deny idle for C1 */ + if (cx->flags & OMAP_CPUIDLE_CX_NO_CLKDM_IDLE) { + clkdm_deny_idle(mpu_pd->pwrdm_clkdms[0]); + } else { + pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state); + pwrdm_set_next_pwrst(core_pd, cx->core_state); + } + + /* + * Call idle CPU PM enter notifier chain so that + * VFP context is saved. + */ + if (cx->mpu_state == PWRDM_POWER_OFF) + cpu_pm_enter(); + + /* Execute ARM wfi */ + omap_sram_idle(); + + /* + * Call idle CPU PM enter notifier chain to restore + * VFP context. + */ + if (cx->mpu_state == PWRDM_POWER_OFF && + pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF) + cpu_pm_exit(); + + /* Re-allow idle for C1 */ + if (cx->flags & OMAP_CPUIDLE_CX_NO_CLKDM_IDLE) + clkdm_allow_idle(mpu_pd->pwrdm_clkdms[0]); + +return_sleep_time: + + return index; +} + +/** + * next_valid_state - Find next valid C-state + * @dev: cpuidle device + * @drv: cpuidle driver + * @index: Index of currently selected c-state + * + * If the state corresponding to index is valid, index is returned back + * to the caller. Else, this function searches for a lower c-state which is + * still valid (as defined in omap3_power_states[]) and returns its index. + * + * A state is valid if the 'valid' field is enabled and + * if it satisfies the enable_off_mode condition. + */ +static int next_valid_state(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + struct omap3_idle_statedata *cx = &omap3_idle_data[index]; + u32 mpu_deepest_state = PWRDM_POWER_RET; + u32 core_deepest_state = PWRDM_POWER_RET; + int idx; + int next_index = 0; /* C1 is the default value */ + + if (enable_off_mode) { + mpu_deepest_state = PWRDM_POWER_OFF; + /* + * Erratum i583: valable for ES rev < Es1.2 on 3630. + * CORE OFF mode is not supported in a stable form, restrict + * instead the CORE state to RET. + */ + if (!IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583)) + core_deepest_state = PWRDM_POWER_OFF; + } + + /* Check if current state is valid */ + if ((cx->mpu_state >= mpu_deepest_state) && + (cx->core_state >= core_deepest_state)) + return index; + + /* + * Drop to next valid state. + * Start search from the next (lower) state. + */ + for (idx = index - 1; idx >= 0; idx--) { + cx = &omap3_idle_data[idx]; + if ((cx->mpu_state >= mpu_deepest_state) && + (cx->core_state >= core_deepest_state)) { + next_index = idx; + break; + } + } + + return next_index; +} + +/** + * omap3_enter_idle_bm - Checks for any bus activity + * @dev: cpuidle device + * @drv: cpuidle driver + * @index: array index of target state to be programmed + * + * This function checks for any pending activity and then programs + * the device to the specified or a safer state. + */ +static int omap3_enter_idle_bm(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + int new_state_idx, ret; + u8 per_next_state, per_saved_state; + struct omap3_idle_statedata *cx; + + /* + * Use only C1 if CAM is active. + * CAM does not have wakeup capability in OMAP3. + */ + if (pwrdm_read_pwrst(cam_pd) == PWRDM_POWER_ON) + new_state_idx = drv->safe_state_index; + else + new_state_idx = next_valid_state(dev, drv, index); + + /* + * FIXME: we currently manage device-specific idle states + * for PER and CORE in combination with CPU-specific + * idle states. This is wrong, and device-specific + * idle management needs to be separated out into + * its own code. + */ + + /* Program PER state */ + cx = &omap3_idle_data[new_state_idx]; + + per_next_state = pwrdm_read_next_pwrst(per_pd); + per_saved_state = per_next_state; + if (per_next_state < cx->per_min_state) { + per_next_state = cx->per_min_state; + pwrdm_set_next_pwrst(per_pd, per_next_state); + } + + ret = omap3_enter_idle(dev, drv, new_state_idx); + + /* Restore original PER state if it was modified */ + if (per_next_state != per_saved_state) + pwrdm_set_next_pwrst(per_pd, per_saved_state); + + return ret; +} + +static struct cpuidle_driver omap3_idle_driver = { + .name = "omap3_idle", + .owner = THIS_MODULE, + .states = { + { + .enter = omap3_enter_idle_bm, + .exit_latency = 2 + 2, + .target_residency = 5, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "C1", + .desc = "MPU ON + CORE ON", + }, + { + .enter = omap3_enter_idle_bm, + .exit_latency = 10 + 10, + .target_residency = 30, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "C2", + .desc = "MPU ON + CORE ON", + }, + { + .enter = omap3_enter_idle_bm, + .exit_latency = 50 + 50, + .target_residency = 300, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "C3", + .desc = "MPU RET + CORE ON", + }, + { + .enter = omap3_enter_idle_bm, + .exit_latency = 1500 + 1800, + .target_residency = 4000, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "C4", + .desc = "MPU OFF + CORE ON", + }, + { + .enter = omap3_enter_idle_bm, + .exit_latency = 2500 + 7500, + .target_residency = 12000, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "C5", + .desc = "MPU RET + CORE RET", + }, + { + .enter = omap3_enter_idle_bm, + .exit_latency = 3000 + 8500, + .target_residency = 15000, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "C6", + .desc = "MPU OFF + CORE RET", + }, + { + .enter = omap3_enter_idle_bm, + .exit_latency = 10000 + 30000, + .target_residency = 30000, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "C7", + .desc = "MPU OFF + CORE OFF", + }, + }, + .state_count = ARRAY_SIZE(omap3_idle_data), + .safe_state_index = 0, +}; + +/* Public functions */ + +/** + * omap3_idle_init - Init routine for OMAP3 idle + * + * Registers the OMAP3 specific cpuidle driver to the cpuidle + * framework with the valid set of states. + */ +int __init omap3_idle_init(void) +{ + mpu_pd = pwrdm_lookup("mpu_pwrdm"); + core_pd = pwrdm_lookup("core_pwrdm"); + per_pd = pwrdm_lookup("per_pwrdm"); + cam_pd = pwrdm_lookup("cam_pwrdm"); + + if (!mpu_pd || !core_pd || !per_pd || !cam_pd) + return -ENODEV; + + return cpuidle_register(&omap3_idle_driver, NULL); +} diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c new file mode 100644 index 00000000000..2498ab025fa --- /dev/null +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -0,0 +1,252 @@ +/* + * OMAP4+ CPU idle Routines + * + * Copyright (C) 2011-2013 Texas Instruments, Inc. + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * Rajendra Nayak <rnayak@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/sched.h> +#include <linux/cpuidle.h> +#include <linux/cpu_pm.h> +#include <linux/export.h> +#include <linux/clockchips.h> + +#include <asm/cpuidle.h> +#include <asm/proc-fns.h> + +#include "common.h" +#include "pm.h" +#include "prm.h" +#include "clockdomain.h" + +#define MAX_CPUS 2 + +/* Machine specific information */ +struct idle_statedata { + u32 cpu_state; + u32 mpu_logic_state; + u32 mpu_state; +}; + +static struct idle_statedata omap4_idle_data[] = { + { + .cpu_state = PWRDM_POWER_ON, + .mpu_state = PWRDM_POWER_ON, + .mpu_logic_state = PWRDM_POWER_RET, + }, + { + .cpu_state = PWRDM_POWER_OFF, + .mpu_state = PWRDM_POWER_RET, + .mpu_logic_state = PWRDM_POWER_RET, + }, + { + .cpu_state = PWRDM_POWER_OFF, + .mpu_state = PWRDM_POWER_RET, + .mpu_logic_state = PWRDM_POWER_OFF, + }, +}; + +static struct powerdomain *mpu_pd, *cpu_pd[MAX_CPUS]; +static struct clockdomain *cpu_clkdm[MAX_CPUS]; + +static atomic_t abort_barrier; +static bool cpu_done[MAX_CPUS]; +static struct idle_statedata *state_ptr = &omap4_idle_data[0]; + +/* Private functions */ + +/** + * omap_enter_idle_[simple/coupled] - OMAP4PLUS cpuidle entry functions + * @dev: cpuidle device + * @drv: cpuidle driver + * @index: the index of state to be entered + * + * Called from the CPUidle framework to program the device to the + * specified low power state selected by the governor. + * Returns the amount of time spent in the low power state. + */ +static int omap_enter_idle_simple(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + omap_do_wfi(); + return index; +} + +static int omap_enter_idle_coupled(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + struct idle_statedata *cx = state_ptr + index; + u32 mpuss_can_lose_context = 0; + int cpu_id = smp_processor_id(); + + /* + * CPU0 has to wait and stay ON until CPU1 is OFF state. + * This is necessary to honour hardware recommondation + * of triggeing all the possible low power modes once CPU1 is + * out of coherency and in OFF mode. + */ + if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) { + while (pwrdm_read_pwrst(cpu_pd[1]) != PWRDM_POWER_OFF) { + cpu_relax(); + + /* + * CPU1 could have already entered & exited idle + * without hitting off because of a wakeup + * or a failed attempt to hit off mode. Check for + * that here, otherwise we could spin forever + * waiting for CPU1 off. + */ + if (cpu_done[1]) + goto fail; + + } + } + + mpuss_can_lose_context = (cx->mpu_state == PWRDM_POWER_RET) && + (cx->mpu_logic_state == PWRDM_POWER_OFF); + + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id); + + /* + * Call idle CPU PM enter notifier chain so that + * VFP and per CPU interrupt context is saved. + */ + cpu_pm_enter(); + + if (dev->cpu == 0) { + pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state); + omap_set_pwrdm_state(mpu_pd, cx->mpu_state); + + /* + * Call idle CPU cluster PM enter notifier chain + * to save GIC and wakeupgen context. + */ + if (mpuss_can_lose_context) + cpu_cluster_pm_enter(); + } + + omap4_enter_lowpower(dev->cpu, cx->cpu_state); + cpu_done[dev->cpu] = true; + + /* Wakeup CPU1 only if it is not offlined */ + if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) { + + if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD) && + mpuss_can_lose_context) + gic_dist_disable(); + + clkdm_wakeup(cpu_clkdm[1]); + omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON); + clkdm_allow_idle(cpu_clkdm[1]); + + if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD) && + mpuss_can_lose_context) { + while (gic_dist_disabled()) { + udelay(1); + cpu_relax(); + } + gic_timer_retrigger(); + } + } + + /* + * Call idle CPU PM exit notifier chain to restore + * VFP and per CPU IRQ context. + */ + cpu_pm_exit(); + + /* + * Call idle CPU cluster PM exit notifier chain + * to restore GIC and wakeupgen context. + */ + if (dev->cpu == 0 && mpuss_can_lose_context) + cpu_cluster_pm_exit(); + + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id); + +fail: + cpuidle_coupled_parallel_barrier(dev, &abort_barrier); + cpu_done[dev->cpu] = false; + + return index; +} + +/* + * For each cpu, setup the broadcast timer because local timers + * stops for the states above C1. + */ +static void omap_setup_broadcast_timer(void *arg) +{ + int cpu = smp_processor_id(); + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu); +} + +static struct cpuidle_driver omap4_idle_driver = { + .name = "omap4_idle", + .owner = THIS_MODULE, + .states = { + { + /* C1 - CPU0 ON + CPU1 ON + MPU ON */ + .exit_latency = 2 + 2, + .target_residency = 5, + .flags = CPUIDLE_FLAG_TIME_VALID, + .enter = omap_enter_idle_simple, + .name = "C1", + .desc = "CPUx ON, MPUSS ON" + }, + { + /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ + .exit_latency = 328 + 440, + .target_residency = 960, + .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED, + .enter = omap_enter_idle_coupled, + .name = "C2", + .desc = "CPUx OFF, MPUSS CSWR", + }, + { + /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ + .exit_latency = 460 + 518, + .target_residency = 1100, + .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED, + .enter = omap_enter_idle_coupled, + .name = "C3", + .desc = "CPUx OFF, MPUSS OSWR", + }, + }, + .state_count = ARRAY_SIZE(omap4_idle_data), + .safe_state_index = 0, +}; + +/* Public functions */ + +/** + * omap4_idle_init - Init routine for OMAP4+ idle + * + * Registers the OMAP4+ specific cpuidle driver to the cpuidle + * framework with the valid set of states. + */ +int __init omap4_idle_init(void) +{ + mpu_pd = pwrdm_lookup("mpu_pwrdm"); + cpu_pd[0] = pwrdm_lookup("cpu0_pwrdm"); + cpu_pd[1] = pwrdm_lookup("cpu1_pwrdm"); + if ((!mpu_pd) || (!cpu_pd[0]) || (!cpu_pd[1])) + return -ENODEV; + + cpu_clkdm[0] = clkdm_lookup("mpu0_clkdm"); + cpu_clkdm[1] = clkdm_lookup("mpu1_clkdm"); + if (!cpu_clkdm[0] || !cpu_clkdm[1]) + return -ENODEV; + + /* Configure the broadcast timer on each cpu */ + on_each_cpu(omap_setup_broadcast_timer, NULL, 1); + + return cpuidle_register(&omap4_idle_driver, cpu_online_mask); +} diff --git a/arch/arm/mach-omap2/ctrl_module_core_44xx.h b/arch/arm/mach-omap2/ctrl_module_core_44xx.h new file mode 100644 index 00000000000..01970824e0e --- /dev/null +++ b/arch/arm/mach-omap2/ctrl_module_core_44xx.h @@ -0,0 +1,392 @@ +/* + * OMAP44xx CTRL_MODULE_CORE registers and bitfields + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * + * Benoit Cousson (b-cousson@ti.com) + * Santosh Shilimkar (santosh.shilimkar@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_CORE_44XX_H +#define __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_CORE_44XX_H + + +/* Base address */ +#define OMAP4_CTRL_MODULE_CORE 0x4a002000 + +/* Registers offset */ +#define OMAP4_CTRL_MODULE_CORE_IP_REVISION 0x0000 +#define OMAP4_CTRL_MODULE_CORE_IP_HWINFO 0x0004 +#define OMAP4_CTRL_MODULE_CORE_IP_SYSCONFIG 0x0010 +#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_DIE_ID_0 0x0200 +#define OMAP4_CTRL_MODULE_CORE_ID_CODE 0x0204 +#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_DIE_ID_1 0x0208 +#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_DIE_ID_2 0x020c +#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_DIE_ID_3 0x0210 +#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_0 0x0214 +#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1 0x0218 +#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_USB_CONF 0x021c +#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_VDD_WKUP 0x0228 +#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_BGAP 0x0260 +#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_DPLL_0 0x0264 +#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_DPLL_1 0x0268 +#define OMAP4_CTRL_MODULE_CORE_STATUS 0x02c4 +#define OMAP4_CTRL_MODULE_CORE_DEV_CONF 0x0300 +#define OMAP4_CTRL_MODULE_CORE_DSP_BOOTADDR 0x0304 +#define OMAP4_CTRL_MODULE_CORE_LDOVBB_IVA_VOLTAGE_CTRL 0x0314 +#define OMAP4_CTRL_MODULE_CORE_LDOVBB_MPU_VOLTAGE_CTRL 0x0318 +#define OMAP4_CTRL_MODULE_CORE_LDOSRAM_IVA_VOLTAGE_CTRL 0x0320 +#define OMAP4_CTRL_MODULE_CORE_LDOSRAM_MPU_VOLTAGE_CTRL 0x0324 +#define OMAP4_CTRL_MODULE_CORE_LDOSRAM_CORE_VOLTAGE_CTRL 0x0328 +#define OMAP4_CTRL_MODULE_CORE_TEMP_SENSOR 0x032c +#define OMAP4_CTRL_MODULE_CORE_DPLL_NWELL_TRIM_0 0x0330 +#define OMAP4_CTRL_MODULE_CORE_DPLL_NWELL_TRIM_1 0x0334 +#define OMAP4_CTRL_MODULE_CORE_USBOTGHS_CONTROL 0x033c +#define OMAP4_CTRL_MODULE_CORE_DSS_CONTROL 0x0340 +#define OMAP4_CTRL_MODULE_CORE_HWOBS_CONTROL 0x0350 +#define OMAP4_CTRL_MODULE_CORE_DEBOBS_FINAL_MUX_SEL 0x0400 +#define OMAP4_CTRL_MODULE_CORE_DEBOBS_MMR_MPU 0x0408 +#define OMAP4_CTRL_MODULE_CORE_CONF_SDMA_REQ_SEL0 0x042c +#define OMAP4_CTRL_MODULE_CORE_CONF_SDMA_REQ_SEL1 0x0430 +#define OMAP4_CTRL_MODULE_CORE_CONF_SDMA_REQ_SEL2 0x0434 +#define OMAP4_CTRL_MODULE_CORE_CONF_SDMA_REQ_SEL3 0x0438 +#define OMAP4_CTRL_MODULE_CORE_CONF_CLK_SEL0 0x0440 +#define OMAP4_CTRL_MODULE_CORE_CONF_CLK_SEL1 0x0444 +#define OMAP4_CTRL_MODULE_CORE_CONF_CLK_SEL2 0x0448 +#define OMAP4_CTRL_MODULE_CORE_CONF_DPLL_FREQLOCK_SEL 0x044c +#define OMAP4_CTRL_MODULE_CORE_CONF_DPLL_TINITZ_SEL 0x0450 +#define OMAP4_CTRL_MODULE_CORE_CONF_DPLL_PHASELOCK_SEL 0x0454 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_0 0x0480 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_1 0x0484 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_2 0x0488 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_3 0x048c +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_4 0x0490 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_5 0x0494 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_6 0x0498 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_7 0x049c +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_8 0x04a0 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_9 0x04a4 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_10 0x04a8 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_11 0x04ac +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_12 0x04b0 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_13 0x04b4 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_14 0x04b8 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_15 0x04bc +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_16 0x04c0 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_17 0x04c4 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_18 0x04c8 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_19 0x04cc +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_20 0x04d0 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_21 0x04d4 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_22 0x04d8 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_23 0x04dc +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_24 0x04e0 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_25 0x04e4 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_26 0x04e8 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_27 0x04ec +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_28 0x04f0 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_29 0x04f4 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_30 0x04f8 +#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_31 0x04fc + +/* Registers shifts and masks */ + +/* IP_REVISION */ +#define OMAP4_IP_REV_SCHEME_SHIFT 30 +#define OMAP4_IP_REV_SCHEME_MASK (0x3 << 30) +#define OMAP4_IP_REV_FUNC_SHIFT 16 +#define OMAP4_IP_REV_FUNC_MASK (0xfff << 16) +#define OMAP4_IP_REV_RTL_SHIFT 11 +#define OMAP4_IP_REV_RTL_MASK (0x1f << 11) +#define OMAP4_IP_REV_MAJOR_SHIFT 8 +#define OMAP4_IP_REV_MAJOR_MASK (0x7 << 8) +#define OMAP4_IP_REV_CUSTOM_SHIFT 6 +#define OMAP4_IP_REV_CUSTOM_MASK (0x3 << 6) +#define OMAP4_IP_REV_MINOR_SHIFT 0 +#define OMAP4_IP_REV_MINOR_MASK (0x3f << 0) + +/* IP_HWINFO */ +#define OMAP4_IP_HWINFO_SHIFT 0 +#define OMAP4_IP_HWINFO_MASK (0xffffffff << 0) + +/* IP_SYSCONFIG */ +#define OMAP4_IP_SYSCONFIG_IDLEMODE_SHIFT 2 +#define OMAP4_IP_SYSCONFIG_IDLEMODE_MASK (0x3 << 2) + +/* STD_FUSE_DIE_ID_0 */ +#define OMAP4_STD_FUSE_DIE_ID_0_SHIFT 0 +#define OMAP4_STD_FUSE_DIE_ID_0_MASK (0xffffffff << 0) + +/* ID_CODE */ +#define OMAP4_STD_FUSE_IDCODE_SHIFT 0 +#define OMAP4_STD_FUSE_IDCODE_MASK (0xffffffff << 0) + +/* STD_FUSE_DIE_ID_1 */ +#define OMAP4_STD_FUSE_DIE_ID_1_SHIFT 0 +#define OMAP4_STD_FUSE_DIE_ID_1_MASK (0xffffffff << 0) + +/* STD_FUSE_DIE_ID_2 */ +#define OMAP4_STD_FUSE_DIE_ID_2_SHIFT 0 +#define OMAP4_STD_FUSE_DIE_ID_2_MASK (0xffffffff << 0) + +/* STD_FUSE_DIE_ID_3 */ +#define OMAP4_STD_FUSE_DIE_ID_3_SHIFT 0 +#define OMAP4_STD_FUSE_DIE_ID_3_MASK (0xffffffff << 0) + +/* STD_FUSE_PROD_ID_0 */ +#define OMAP4_STD_FUSE_PROD_ID_0_SHIFT 0 +#define OMAP4_STD_FUSE_PROD_ID_0_MASK (0xffffffff << 0) + +/* STD_FUSE_PROD_ID_1 */ +#define OMAP4_STD_FUSE_PROD_ID_1_SHIFT 0 +#define OMAP4_STD_FUSE_PROD_ID_1_MASK (0xffffffff << 0) + +/* STD_FUSE_USB_CONF */ +#define OMAP4_USB_PROD_ID_SHIFT 16 +#define OMAP4_USB_PROD_ID_MASK (0xffff << 16) +#define OMAP4_USB_VENDOR_ID_SHIFT 0 +#define OMAP4_USB_VENDOR_ID_MASK (0xffff << 0) + +/* STD_FUSE_OPP_VDD_WKUP */ +#define OMAP4_STD_FUSE_OPP_VDD_WKUP_SHIFT 0 +#define OMAP4_STD_FUSE_OPP_VDD_WKUP_MASK (0xffffffff << 0) + +/* STD_FUSE_OPP_BGAP */ +#define OMAP4_STD_FUSE_OPP_BGAP_SHIFT 0 +#define OMAP4_STD_FUSE_OPP_BGAP_MASK (0xffffffff << 0) + +/* STD_FUSE_OPP_DPLL_0 */ +#define OMAP4_STD_FUSE_OPP_DPLL_0_SHIFT 0 +#define OMAP4_STD_FUSE_OPP_DPLL_0_MASK (0xffffffff << 0) + +/* STD_FUSE_OPP_DPLL_1 */ +#define OMAP4_STD_FUSE_OPP_DPLL_1_SHIFT 0 +#define OMAP4_STD_FUSE_OPP_DPLL_1_MASK (0xffffffff << 0) + +/* STATUS */ +#define OMAP4_ATTILA_CONF_SHIFT 11 +#define OMAP4_ATTILA_CONF_MASK (0x3 << 11) +#define OMAP4_DEVICE_TYPE_SHIFT 8 +#define OMAP4_DEVICE_TYPE_MASK (0x7 << 8) +#define OMAP4_SYS_BOOT_SHIFT 0 +#define OMAP4_SYS_BOOT_MASK (0xff << 0) + +/* DEV_CONF */ +#define OMAP4_DEV_CONF_SHIFT 1 +#define OMAP4_DEV_CONF_MASK (0x7fffffff << 1) +#define OMAP4_USBPHY_PD_SHIFT 0 +#define OMAP4_USBPHY_PD_MASK (1 << 0) + +/* LDOVBB_IVA_VOLTAGE_CTRL */ +#define OMAP4_LDOVBBIVA_RBB_MUX_CTRL_SHIFT 26 +#define OMAP4_LDOVBBIVA_RBB_MUX_CTRL_MASK (1 << 26) +#define OMAP4_LDOVBBIVA_RBB_VSET_IN_SHIFT 21 +#define OMAP4_LDOVBBIVA_RBB_VSET_IN_MASK (0x1f << 21) +#define OMAP4_LDOVBBIVA_RBB_VSET_OUT_SHIFT 16 +#define OMAP4_LDOVBBIVA_RBB_VSET_OUT_MASK (0x1f << 16) +#define OMAP4_LDOVBBIVA_FBB_MUX_CTRL_SHIFT 10 +#define OMAP4_LDOVBBIVA_FBB_MUX_CTRL_MASK (1 << 10) +#define OMAP4_LDOVBBIVA_FBB_VSET_IN_SHIFT 5 +#define OMAP4_LDOVBBIVA_FBB_VSET_IN_MASK (0x1f << 5) +#define OMAP4_LDOVBBIVA_FBB_VSET_OUT_SHIFT 0 +#define OMAP4_LDOVBBIVA_FBB_VSET_OUT_MASK (0x1f << 0) + +/* LDOVBB_MPU_VOLTAGE_CTRL */ +#define OMAP4_LDOVBBMPU_RBB_MUX_CTRL_SHIFT 26 +#define OMAP4_LDOVBBMPU_RBB_MUX_CTRL_MASK (1 << 26) +#define OMAP4_LDOVBBMPU_RBB_VSET_IN_SHIFT 21 +#define OMAP4_LDOVBBMPU_RBB_VSET_IN_MASK (0x1f << 21) +#define OMAP4_LDOVBBMPU_RBB_VSET_OUT_SHIFT 16 +#define OMAP4_LDOVBBMPU_RBB_VSET_OUT_MASK (0x1f << 16) +#define OMAP4_LDOVBBMPU_FBB_MUX_CTRL_SHIFT 10 +#define OMAP4_LDOVBBMPU_FBB_MUX_CTRL_MASK (1 << 10) +#define OMAP4_LDOVBBMPU_FBB_VSET_IN_SHIFT 5 +#define OMAP4_LDOVBBMPU_FBB_VSET_IN_MASK (0x1f << 5) +#define OMAP4_LDOVBBMPU_FBB_VSET_OUT_SHIFT 0 +#define OMAP4_LDOVBBMPU_FBB_VSET_OUT_MASK (0x1f << 0) + +/* LDOSRAM_IVA_VOLTAGE_CTRL */ +#define OMAP4_LDOSRAMIVA_RETMODE_MUX_CTRL_SHIFT 26 +#define OMAP4_LDOSRAMIVA_RETMODE_MUX_CTRL_MASK (1 << 26) +#define OMAP4_LDOSRAMIVA_RETMODE_VSET_IN_SHIFT 21 +#define OMAP4_LDOSRAMIVA_RETMODE_VSET_IN_MASK (0x1f << 21) +#define OMAP4_LDOSRAMIVA_RETMODE_VSET_OUT_SHIFT 16 +#define OMAP4_LDOSRAMIVA_RETMODE_VSET_OUT_MASK (0x1f << 16) +#define OMAP4_LDOSRAMIVA_ACTMODE_MUX_CTRL_SHIFT 10 +#define OMAP4_LDOSRAMIVA_ACTMODE_MUX_CTRL_MASK (1 << 10) +#define OMAP4_LDOSRAMIVA_ACTMODE_VSET_IN_SHIFT 5 +#define OMAP4_LDOSRAMIVA_ACTMODE_VSET_IN_MASK (0x1f << 5) +#define OMAP4_LDOSRAMIVA_ACTMODE_VSET_OUT_SHIFT 0 +#define OMAP4_LDOSRAMIVA_ACTMODE_VSET_OUT_MASK (0x1f << 0) + +/* LDOSRAM_MPU_VOLTAGE_CTRL */ +#define OMAP4_LDOSRAMMPU_RETMODE_MUX_CTRL_SHIFT 26 +#define OMAP4_LDOSRAMMPU_RETMODE_MUX_CTRL_MASK (1 << 26) +#define OMAP4_LDOSRAMMPU_RETMODE_VSET_IN_SHIFT 21 +#define OMAP4_LDOSRAMMPU_RETMODE_VSET_IN_MASK (0x1f << 21) +#define OMAP4_LDOSRAMMPU_RETMODE_VSET_OUT_SHIFT 16 +#define OMAP4_LDOSRAMMPU_RETMODE_VSET_OUT_MASK (0x1f << 16) +#define OMAP4_LDOSRAMMPU_ACTMODE_MUX_CTRL_SHIFT 10 +#define OMAP4_LDOSRAMMPU_ACTMODE_MUX_CTRL_MASK (1 << 10) +#define OMAP4_LDOSRAMMPU_ACTMODE_VSET_IN_SHIFT 5 +#define OMAP4_LDOSRAMMPU_ACTMODE_VSET_IN_MASK (0x1f << 5) +#define OMAP4_LDOSRAMMPU_ACTMODE_VSET_OUT_SHIFT 0 +#define OMAP4_LDOSRAMMPU_ACTMODE_VSET_OUT_MASK (0x1f << 0) + +/* LDOSRAM_CORE_VOLTAGE_CTRL */ +#define OMAP4_LDOSRAMCORE_RETMODE_MUX_CTRL_SHIFT 26 +#define OMAP4_LDOSRAMCORE_RETMODE_MUX_CTRL_MASK (1 << 26) +#define OMAP4_LDOSRAMCORE_RETMODE_VSET_IN_SHIFT 21 +#define OMAP4_LDOSRAMCORE_RETMODE_VSET_IN_MASK (0x1f << 21) +#define OMAP4_LDOSRAMCORE_RETMODE_VSET_OUT_SHIFT 16 +#define OMAP4_LDOSRAMCORE_RETMODE_VSET_OUT_MASK (0x1f << 16) +#define OMAP4_LDOSRAMCORE_ACTMODE_MUX_CTRL_SHIFT 10 +#define OMAP4_LDOSRAMCORE_ACTMODE_MUX_CTRL_MASK (1 << 10) +#define OMAP4_LDOSRAMCORE_ACTMODE_VSET_IN_SHIFT 5 +#define OMAP4_LDOSRAMCORE_ACTMODE_VSET_IN_MASK (0x1f << 5) +#define OMAP4_LDOSRAMCORE_ACTMODE_VSET_OUT_SHIFT 0 +#define OMAP4_LDOSRAMCORE_ACTMODE_VSET_OUT_MASK (0x1f << 0) + +/* TEMP_SENSOR */ +#define OMAP4_BGAP_TEMPSOFF_SHIFT 12 +#define OMAP4_BGAP_TEMPSOFF_MASK (1 << 12) +#define OMAP4_BGAP_TSHUT_SHIFT 11 +#define OMAP4_BGAP_TSHUT_MASK (1 << 11) +#define OMAP4_BGAP_TEMP_SENSOR_CONTCONV_SHIFT 10 +#define OMAP4_BGAP_TEMP_SENSOR_CONTCONV_MASK (1 << 10) +#define OMAP4_BGAP_TEMP_SENSOR_SOC_SHIFT 9 +#define OMAP4_BGAP_TEMP_SENSOR_SOC_MASK (1 << 9) +#define OMAP4_BGAP_TEMP_SENSOR_EOCZ_SHIFT 8 +#define OMAP4_BGAP_TEMP_SENSOR_EOCZ_MASK (1 << 8) +#define OMAP4_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0 +#define OMAP4_BGAP_TEMP_SENSOR_DTEMP_MASK (0xff << 0) + +/* DPLL_NWELL_TRIM_0 */ +#define OMAP4_DPLL_ABE_NWELL_TRIM_MUX_CTRL_SHIFT 29 +#define OMAP4_DPLL_ABE_NWELL_TRIM_MUX_CTRL_MASK (1 << 29) +#define OMAP4_DPLL_ABE_NWELL_TRIM_SHIFT 24 +#define OMAP4_DPLL_ABE_NWELL_TRIM_MASK (0x1f << 24) +#define OMAP4_DPLL_PER_NWELL_TRIM_MUX_CTRL_SHIFT 23 +#define OMAP4_DPLL_PER_NWELL_TRIM_MUX_CTRL_MASK (1 << 23) +#define OMAP4_DPLL_PER_NWELL_TRIM_SHIFT 18 +#define OMAP4_DPLL_PER_NWELL_TRIM_MASK (0x1f << 18) +#define OMAP4_DPLL_CORE_NWELL_TRIM_MUX_CTRL_SHIFT 17 +#define OMAP4_DPLL_CORE_NWELL_TRIM_MUX_CTRL_MASK (1 << 17) +#define OMAP4_DPLL_CORE_NWELL_TRIM_SHIFT 12 +#define OMAP4_DPLL_CORE_NWELL_TRIM_MASK (0x1f << 12) +#define OMAP4_DPLL_IVA_NWELL_TRIM_MUX_CTRL_SHIFT 11 +#define OMAP4_DPLL_IVA_NWELL_TRIM_MUX_CTRL_MASK (1 << 11) +#define OMAP4_DPLL_IVA_NWELL_TRIM_SHIFT 6 +#define OMAP4_DPLL_IVA_NWELL_TRIM_MASK (0x1f << 6) +#define OMAP4_DPLL_MPU_NWELL_TRIM_MUX_CTRL_SHIFT 5 +#define OMAP4_DPLL_MPU_NWELL_TRIM_MUX_CTRL_MASK (1 << 5) +#define OMAP4_DPLL_MPU_NWELL_TRIM_SHIFT 0 +#define OMAP4_DPLL_MPU_NWELL_TRIM_MASK (0x1f << 0) + +/* DPLL_NWELL_TRIM_1 */ +#define OMAP4_DPLL_UNIPRO_NWELL_TRIM_MUX_CTRL_SHIFT 29 +#define OMAP4_DPLL_UNIPRO_NWELL_TRIM_MUX_CTRL_MASK (1 << 29) +#define OMAP4_DPLL_UNIPRO_NWELL_TRIM_SHIFT 24 +#define OMAP4_DPLL_UNIPRO_NWELL_TRIM_MASK (0x1f << 24) +#define OMAP4_DPLL_USB_NWELL_TRIM_MUX_CTRL_SHIFT 23 +#define OMAP4_DPLL_USB_NWELL_TRIM_MUX_CTRL_MASK (1 << 23) +#define OMAP4_DPLL_USB_NWELL_TRIM_SHIFT 18 +#define OMAP4_DPLL_USB_NWELL_TRIM_MASK (0x1f << 18) +#define OMAP4_DPLL_HDMI_NWELL_TRIM_MUX_CTRL_SHIFT 17 +#define OMAP4_DPLL_HDMI_NWELL_TRIM_MUX_CTRL_MASK (1 << 17) +#define OMAP4_DPLL_HDMI_NWELL_TRIM_SHIFT 12 +#define OMAP4_DPLL_HDMI_NWELL_TRIM_MASK (0x1f << 12) +#define OMAP4_DPLL_DSI2_NWELL_TRIM_MUX_CTRL_SHIFT 11 +#define OMAP4_DPLL_DSI2_NWELL_TRIM_MUX_CTRL_MASK (1 << 11) +#define OMAP4_DPLL_DSI2_NWELL_TRIM_SHIFT 6 +#define OMAP4_DPLL_DSI2_NWELL_TRIM_MASK (0x1f << 6) +#define OMAP4_DPLL_DSI1_NWELL_TRIM_MUX_CTRL_SHIFT 5 +#define OMAP4_DPLL_DSI1_NWELL_TRIM_MUX_CTRL_MASK (1 << 5) +#define OMAP4_DPLL_DSI1_NWELL_TRIM_SHIFT 0 +#define OMAP4_DPLL_DSI1_NWELL_TRIM_MASK (0x1f << 0) + +/* USBOTGHS_CONTROL */ +#define OMAP4_DISCHRGVBUS_SHIFT 8 +#define OMAP4_DISCHRGVBUS_MASK (1 << 8) +#define OMAP4_CHRGVBUS_SHIFT 7 +#define OMAP4_CHRGVBUS_MASK (1 << 7) +#define OMAP4_DRVVBUS_SHIFT 6 +#define OMAP4_DRVVBUS_MASK (1 << 6) +#define OMAP4_IDPULLUP_SHIFT 5 +#define OMAP4_IDPULLUP_MASK (1 << 5) +#define OMAP4_IDDIG_SHIFT 4 +#define OMAP4_IDDIG_MASK (1 << 4) +#define OMAP4_SESSEND_SHIFT 3 +#define OMAP4_SESSEND_MASK (1 << 3) +#define OMAP4_VBUSVALID_SHIFT 2 +#define OMAP4_VBUSVALID_MASK (1 << 2) +#define OMAP4_BVALID_SHIFT 1 +#define OMAP4_BVALID_MASK (1 << 1) +#define OMAP4_AVALID_SHIFT 0 +#define OMAP4_AVALID_MASK (1 << 0) + +/* DSS_CONTROL */ +#define OMAP4_DSS_MUX6_SELECT_SHIFT 0 +#define OMAP4_DSS_MUX6_SELECT_MASK (1 << 0) + +/* HWOBS_CONTROL */ +#define OMAP4_HWOBS_CLKDIV_SEL_SHIFT 3 +#define OMAP4_HWOBS_CLKDIV_SEL_MASK (0x1f << 3) +#define OMAP4_HWOBS_ALL_ZERO_MODE_SHIFT 2 +#define OMAP4_HWOBS_ALL_ZERO_MODE_MASK (1 << 2) +#define OMAP4_HWOBS_ALL_ONE_MODE_SHIFT 1 +#define OMAP4_HWOBS_ALL_ONE_MODE_MASK (1 << 1) +#define OMAP4_HWOBS_MACRO_ENABLE_SHIFT 0 +#define OMAP4_HWOBS_MACRO_ENABLE_MASK (1 << 0) + +/* DEBOBS_FINAL_MUX_SEL */ +#define OMAP4_SELECT_SHIFT 0 +#define OMAP4_SELECT_MASK (0xffffffff << 0) + +/* DEBOBS_MMR_MPU */ +#define OMAP4_SELECT_DEBOBS_MMR_MPU_SHIFT 0 +#define OMAP4_SELECT_DEBOBS_MMR_MPU_MASK (0xf << 0) + +/* CONF_SDMA_REQ_SEL0 */ +#define OMAP4_MULT_SHIFT 0 +#define OMAP4_MULT_MASK (0x7f << 0) + +/* CONF_CLK_SEL0 */ +#define OMAP4_MULT_CONF_CLK_SEL0_SHIFT 0 +#define OMAP4_MULT_CONF_CLK_SEL0_MASK (0x7 << 0) + +/* CONF_CLK_SEL1 */ +#define OMAP4_MULT_CONF_CLK_SEL1_SHIFT 0 +#define OMAP4_MULT_CONF_CLK_SEL1_MASK (0x7 << 0) + +/* CONF_CLK_SEL2 */ +#define OMAP4_MULT_CONF_CLK_SEL2_SHIFT 0 +#define OMAP4_MULT_CONF_CLK_SEL2_MASK (0x7 << 0) + +/* CONF_DPLL_FREQLOCK_SEL */ +#define OMAP4_MULT_CONF_DPLL_FREQLOCK_SEL_SHIFT 0 +#define OMAP4_MULT_CONF_DPLL_FREQLOCK_SEL_MASK (0x7 << 0) + +/* CONF_DPLL_TINITZ_SEL */ +#define OMAP4_MULT_CONF_DPLL_TINITZ_SEL_SHIFT 0 +#define OMAP4_MULT_CONF_DPLL_TINITZ_SEL_MASK (0x7 << 0) + +/* CONF_DPLL_PHASELOCK_SEL */ +#define OMAP4_MULT_CONF_DPLL_PHASELOCK_SEL_SHIFT 0 +#define OMAP4_MULT_CONF_DPLL_PHASELOCK_SEL_MASK (0x7 << 0) + +/* CONF_DEBUG_SEL_TST_0 */ +#define OMAP4_MODE_SHIFT 0 +#define OMAP4_MODE_MASK (0xf << 0) + +#endif diff --git a/arch/arm/mach-omap2/ctrl_module_pad_core_44xx.h b/arch/arm/mach-omap2/ctrl_module_pad_core_44xx.h new file mode 100644 index 00000000000..c88420de115 --- /dev/null +++ b/arch/arm/mach-omap2/ctrl_module_pad_core_44xx.h @@ -0,0 +1,1409 @@ +/* + * OMAP44xx CTRL_MODULE_PAD_CORE registers and bitfields + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * + * Benoit Cousson (b-cousson@ti.com) + * Santosh Shilimkar (santosh.shilimkar@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_PAD_CORE_44XX_H +#define __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_PAD_CORE_44XX_H + + +/* Base address */ +#define OMAP4_CTRL_MODULE_PAD_CORE 0x4a100000 + +/* Registers offset */ +#define OMAP4_CTRL_MODULE_PAD_CORE_IP_REVISION 0x0000 +#define OMAP4_CTRL_MODULE_PAD_CORE_IP_HWINFO 0x0004 +#define OMAP4_CTRL_MODULE_PAD_CORE_IP_SYSCONFIG 0x0010 +#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_0 0x01d8 +#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_1 0x01dc +#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_2 0x01e0 +#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_3 0x01e4 +#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_4 0x01e8 +#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_5 0x01ec +#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_6 0x01f0 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PADCONF_GLOBAL 0x05a0 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PADCONF_MODE 0x05a4 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART1IO_PADCONF_0 0x05a8 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART1IO_PADCONF_1 0x05ac +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART2IO_PADCONF_0 0x05b0 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART2IO_PADCONF_1 0x05b4 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART3IO_PADCONF_0 0x05b8 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART3IO_PADCONF_1 0x05bc +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART3IO_PADCONF_2 0x05c0 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_USBB_HSIC 0x05c4 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SLIMBUS 0x05c8 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PBIASLITE 0x0600 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_0 0x0604 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_CAMERA_RX 0x0608 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_AVDAC 0x060c +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_HDMI_TX_PHY 0x0610 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MMC2 0x0614 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY 0x0618 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MCBSPLP 0x061c +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_USB2PHYCORE 0x0620 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_1 0x0624 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MMC1 0x0628 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_HSI 0x062c +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_USB 0x0630 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_HDQ 0x0634 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO1_0 0x0638 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO1_1 0x063c +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO1_2 0x0640 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO1_3 0x0644 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO2_0 0x0648 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO2_1 0x064c +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO2_2 0x0650 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO2_3 0x0654 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_BUS_HOLD 0x0658 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_C2C 0x065c +#define OMAP4_CTRL_MODULE_PAD_CORE_CORE_CONTROL_SPARE_RW 0x0660 +#define OMAP4_CTRL_MODULE_PAD_CORE_CORE_CONTROL_SPARE_R 0x0664 +#define OMAP4_CTRL_MODULE_PAD_CORE_CORE_CONTROL_SPARE_R_C0 0x0668 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_1 0x0700 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_2 0x0704 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_3 0x0708 +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_4 0x070c + +/* Registers shifts and masks */ + +/* IP_REVISION */ +#define OMAP4_IP_REV_SCHEME_SHIFT 30 +#define OMAP4_IP_REV_SCHEME_MASK (0x3 << 30) +#define OMAP4_IP_REV_FUNC_SHIFT 16 +#define OMAP4_IP_REV_FUNC_MASK (0xfff << 16) +#define OMAP4_IP_REV_RTL_SHIFT 11 +#define OMAP4_IP_REV_RTL_MASK (0x1f << 11) +#define OMAP4_IP_REV_MAJOR_SHIFT 8 +#define OMAP4_IP_REV_MAJOR_MASK (0x7 << 8) +#define OMAP4_IP_REV_CUSTOM_SHIFT 6 +#define OMAP4_IP_REV_CUSTOM_MASK (0x3 << 6) +#define OMAP4_IP_REV_MINOR_SHIFT 0 +#define OMAP4_IP_REV_MINOR_MASK (0x3f << 0) + +/* IP_HWINFO */ +#define OMAP4_IP_HWINFO_SHIFT 0 +#define OMAP4_IP_HWINFO_MASK (0xffffffff << 0) + +/* IP_SYSCONFIG */ +#define OMAP4_IP_SYSCONFIG_IDLEMODE_SHIFT 2 +#define OMAP4_IP_SYSCONFIG_IDLEMODE_MASK (0x3 << 2) + +/* PADCONF_WAKEUPEVENT_0 */ +#define OMAP4_GPMC_CLK_DUPLICATEWAKEUPEVENT_SHIFT 31 +#define OMAP4_GPMC_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 31) +#define OMAP4_GPMC_NWP_DUPLICATEWAKEUPEVENT_SHIFT 30 +#define OMAP4_GPMC_NWP_DUPLICATEWAKEUPEVENT_MASK (1 << 30) +#define OMAP4_GPMC_NCS3_DUPLICATEWAKEUPEVENT_SHIFT 29 +#define OMAP4_GPMC_NCS3_DUPLICATEWAKEUPEVENT_MASK (1 << 29) +#define OMAP4_GPMC_NCS2_DUPLICATEWAKEUPEVENT_SHIFT 28 +#define OMAP4_GPMC_NCS2_DUPLICATEWAKEUPEVENT_MASK (1 << 28) +#define OMAP4_GPMC_NCS1_DUPLICATEWAKEUPEVENT_SHIFT 27 +#define OMAP4_GPMC_NCS1_DUPLICATEWAKEUPEVENT_MASK (1 << 27) +#define OMAP4_GPMC_NCS0_DUPLICATEWAKEUPEVENT_SHIFT 26 +#define OMAP4_GPMC_NCS0_DUPLICATEWAKEUPEVENT_MASK (1 << 26) +#define OMAP4_GPMC_A25_DUPLICATEWAKEUPEVENT_SHIFT 25 +#define OMAP4_GPMC_A25_DUPLICATEWAKEUPEVENT_MASK (1 << 25) +#define OMAP4_GPMC_A24_DUPLICATEWAKEUPEVENT_SHIFT 24 +#define OMAP4_GPMC_A24_DUPLICATEWAKEUPEVENT_MASK (1 << 24) +#define OMAP4_GPMC_A23_DUPLICATEWAKEUPEVENT_SHIFT 23 +#define OMAP4_GPMC_A23_DUPLICATEWAKEUPEVENT_MASK (1 << 23) +#define OMAP4_GPMC_A22_DUPLICATEWAKEUPEVENT_SHIFT 22 +#define OMAP4_GPMC_A22_DUPLICATEWAKEUPEVENT_MASK (1 << 22) +#define OMAP4_GPMC_A21_DUPLICATEWAKEUPEVENT_SHIFT 21 +#define OMAP4_GPMC_A21_DUPLICATEWAKEUPEVENT_MASK (1 << 21) +#define OMAP4_GPMC_A20_DUPLICATEWAKEUPEVENT_SHIFT 20 +#define OMAP4_GPMC_A20_DUPLICATEWAKEUPEVENT_MASK (1 << 20) +#define OMAP4_GPMC_A19_DUPLICATEWAKEUPEVENT_SHIFT 19 +#define OMAP4_GPMC_A19_DUPLICATEWAKEUPEVENT_MASK (1 << 19) +#define OMAP4_GPMC_A18_DUPLICATEWAKEUPEVENT_SHIFT 18 +#define OMAP4_GPMC_A18_DUPLICATEWAKEUPEVENT_MASK (1 << 18) +#define OMAP4_GPMC_A17_DUPLICATEWAKEUPEVENT_SHIFT 17 +#define OMAP4_GPMC_A17_DUPLICATEWAKEUPEVENT_MASK (1 << 17) +#define OMAP4_GPMC_A16_DUPLICATEWAKEUPEVENT_SHIFT 16 +#define OMAP4_GPMC_A16_DUPLICATEWAKEUPEVENT_MASK (1 << 16) +#define OMAP4_GPMC_AD15_DUPLICATEWAKEUPEVENT_SHIFT 15 +#define OMAP4_GPMC_AD15_DUPLICATEWAKEUPEVENT_MASK (1 << 15) +#define OMAP4_GPMC_AD14_DUPLICATEWAKEUPEVENT_SHIFT 14 +#define OMAP4_GPMC_AD14_DUPLICATEWAKEUPEVENT_MASK (1 << 14) +#define OMAP4_GPMC_AD13_DUPLICATEWAKEUPEVENT_SHIFT 13 +#define OMAP4_GPMC_AD13_DUPLICATEWAKEUPEVENT_MASK (1 << 13) +#define OMAP4_GPMC_AD12_DUPLICATEWAKEUPEVENT_SHIFT 12 +#define OMAP4_GPMC_AD12_DUPLICATEWAKEUPEVENT_MASK (1 << 12) +#define OMAP4_GPMC_AD11_DUPLICATEWAKEUPEVENT_SHIFT 11 +#define OMAP4_GPMC_AD11_DUPLICATEWAKEUPEVENT_MASK (1 << 11) +#define OMAP4_GPMC_AD10_DUPLICATEWAKEUPEVENT_SHIFT 10 +#define OMAP4_GPMC_AD10_DUPLICATEWAKEUPEVENT_MASK (1 << 10) +#define OMAP4_GPMC_AD9_DUPLICATEWAKEUPEVENT_SHIFT 9 +#define OMAP4_GPMC_AD9_DUPLICATEWAKEUPEVENT_MASK (1 << 9) +#define OMAP4_GPMC_AD8_DUPLICATEWAKEUPEVENT_SHIFT 8 +#define OMAP4_GPMC_AD8_DUPLICATEWAKEUPEVENT_MASK (1 << 8) +#define OMAP4_GPMC_AD7_DUPLICATEWAKEUPEVENT_SHIFT 7 +#define OMAP4_GPMC_AD7_DUPLICATEWAKEUPEVENT_MASK (1 << 7) +#define OMAP4_GPMC_AD6_DUPLICATEWAKEUPEVENT_SHIFT 6 +#define OMAP4_GPMC_AD6_DUPLICATEWAKEUPEVENT_MASK (1 << 6) +#define OMAP4_GPMC_AD5_DUPLICATEWAKEUPEVENT_SHIFT 5 +#define OMAP4_GPMC_AD5_DUPLICATEWAKEUPEVENT_MASK (1 << 5) +#define OMAP4_GPMC_AD4_DUPLICATEWAKEUPEVENT_SHIFT 4 +#define OMAP4_GPMC_AD4_DUPLICATEWAKEUPEVENT_MASK (1 << 4) +#define OMAP4_GPMC_AD3_DUPLICATEWAKEUPEVENT_SHIFT 3 +#define OMAP4_GPMC_AD3_DUPLICATEWAKEUPEVENT_MASK (1 << 3) +#define OMAP4_GPMC_AD2_DUPLICATEWAKEUPEVENT_SHIFT 2 +#define OMAP4_GPMC_AD2_DUPLICATEWAKEUPEVENT_MASK (1 << 2) +#define OMAP4_GPMC_AD1_DUPLICATEWAKEUPEVENT_SHIFT 1 +#define OMAP4_GPMC_AD1_DUPLICATEWAKEUPEVENT_MASK (1 << 1) +#define OMAP4_GPMC_AD0_DUPLICATEWAKEUPEVENT_SHIFT 0 +#define OMAP4_GPMC_AD0_DUPLICATEWAKEUPEVENT_MASK (1 << 0) + +/* PADCONF_WAKEUPEVENT_1 */ +#define OMAP4_CAM_STROBE_DUPLICATEWAKEUPEVENT_SHIFT 31 +#define OMAP4_CAM_STROBE_DUPLICATEWAKEUPEVENT_MASK (1 << 31) +#define OMAP4_CAM_SHUTTER_DUPLICATEWAKEUPEVENT_SHIFT 30 +#define OMAP4_CAM_SHUTTER_DUPLICATEWAKEUPEVENT_MASK (1 << 30) +#define OMAP4_CSI22_DY1_DUPLICATEWAKEUPEVENT_SHIFT 29 +#define OMAP4_CSI22_DY1_DUPLICATEWAKEUPEVENT_MASK (1 << 29) +#define OMAP4_CSI22_DX1_DUPLICATEWAKEUPEVENT_SHIFT 28 +#define OMAP4_CSI22_DX1_DUPLICATEWAKEUPEVENT_MASK (1 << 28) +#define OMAP4_CSI22_DY0_DUPLICATEWAKEUPEVENT_SHIFT 27 +#define OMAP4_CSI22_DY0_DUPLICATEWAKEUPEVENT_MASK (1 << 27) +#define OMAP4_CSI22_DX0_DUPLICATEWAKEUPEVENT_SHIFT 26 +#define OMAP4_CSI22_DX0_DUPLICATEWAKEUPEVENT_MASK (1 << 26) +#define OMAP4_CSI21_DY4_DUPLICATEWAKEUPEVENT_SHIFT 25 +#define OMAP4_CSI21_DY4_DUPLICATEWAKEUPEVENT_MASK (1 << 25) +#define OMAP4_CSI21_DX4_DUPLICATEWAKEUPEVENT_SHIFT 24 +#define OMAP4_CSI21_DX4_DUPLICATEWAKEUPEVENT_MASK (1 << 24) +#define OMAP4_CSI21_DY3_DUPLICATEWAKEUPEVENT_SHIFT 23 +#define OMAP4_CSI21_DY3_DUPLICATEWAKEUPEVENT_MASK (1 << 23) +#define OMAP4_CSI21_DX3_DUPLICATEWAKEUPEVENT_SHIFT 22 +#define OMAP4_CSI21_DX3_DUPLICATEWAKEUPEVENT_MASK (1 << 22) +#define OMAP4_CSI21_DY2_DUPLICATEWAKEUPEVENT_SHIFT 21 +#define OMAP4_CSI21_DY2_DUPLICATEWAKEUPEVENT_MASK (1 << 21) +#define OMAP4_CSI21_DX2_DUPLICATEWAKEUPEVENT_SHIFT 20 +#define OMAP4_CSI21_DX2_DUPLICATEWAKEUPEVENT_MASK (1 << 20) +#define OMAP4_CSI21_DY1_DUPLICATEWAKEUPEVENT_SHIFT 19 +#define OMAP4_CSI21_DY1_DUPLICATEWAKEUPEVENT_MASK (1 << 19) +#define OMAP4_CSI21_DX1_DUPLICATEWAKEUPEVENT_SHIFT 18 +#define OMAP4_CSI21_DX1_DUPLICATEWAKEUPEVENT_MASK (1 << 18) +#define OMAP4_CSI21_DY0_DUPLICATEWAKEUPEVENT_SHIFT 17 +#define OMAP4_CSI21_DY0_DUPLICATEWAKEUPEVENT_MASK (1 << 17) +#define OMAP4_CSI21_DX0_DUPLICATEWAKEUPEVENT_SHIFT 16 +#define OMAP4_CSI21_DX0_DUPLICATEWAKEUPEVENT_MASK (1 << 16) +#define OMAP4_HDMI_DDC_SDA_DUPLICATEWAKEUPEVENT_SHIFT 15 +#define OMAP4_HDMI_DDC_SDA_DUPLICATEWAKEUPEVENT_MASK (1 << 15) +#define OMAP4_HDMI_DDC_SCL_DUPLICATEWAKEUPEVENT_SHIFT 14 +#define OMAP4_HDMI_DDC_SCL_DUPLICATEWAKEUPEVENT_MASK (1 << 14) +#define OMAP4_HDMI_CEC_DUPLICATEWAKEUPEVENT_SHIFT 13 +#define OMAP4_HDMI_CEC_DUPLICATEWAKEUPEVENT_MASK (1 << 13) +#define OMAP4_HDMI_HPD_DUPLICATEWAKEUPEVENT_SHIFT 12 +#define OMAP4_HDMI_HPD_DUPLICATEWAKEUPEVENT_MASK (1 << 12) +#define OMAP4_C2C_DATA15_DUPLICATEWAKEUPEVENT_SHIFT 11 +#define OMAP4_C2C_DATA15_DUPLICATEWAKEUPEVENT_MASK (1 << 11) +#define OMAP4_C2C_DATA14_DUPLICATEWAKEUPEVENT_SHIFT 10 +#define OMAP4_C2C_DATA14_DUPLICATEWAKEUPEVENT_MASK (1 << 10) +#define OMAP4_C2C_DATA13_DUPLICATEWAKEUPEVENT_SHIFT 9 +#define OMAP4_C2C_DATA13_DUPLICATEWAKEUPEVENT_MASK (1 << 9) +#define OMAP4_C2C_DATA12_DUPLICATEWAKEUPEVENT_SHIFT 8 +#define OMAP4_C2C_DATA12_DUPLICATEWAKEUPEVENT_MASK (1 << 8) +#define OMAP4_C2C_DATA11_DUPLICATEWAKEUPEVENT_SHIFT 7 +#define OMAP4_C2C_DATA11_DUPLICATEWAKEUPEVENT_MASK (1 << 7) +#define OMAP4_GPMC_WAIT1_DUPLICATEWAKEUPEVENT_SHIFT 6 +#define OMAP4_GPMC_WAIT1_DUPLICATEWAKEUPEVENT_MASK (1 << 6) +#define OMAP4_GPMC_WAIT0_DUPLICATEWAKEUPEVENT_SHIFT 5 +#define OMAP4_GPMC_WAIT0_DUPLICATEWAKEUPEVENT_MASK (1 << 5) +#define OMAP4_GPMC_NBE1_DUPLICATEWAKEUPEVENT_SHIFT 4 +#define OMAP4_GPMC_NBE1_DUPLICATEWAKEUPEVENT_MASK (1 << 4) +#define OMAP4_GPMC_NBE0_CLE_DUPLICATEWAKEUPEVENT_SHIFT 3 +#define OMAP4_GPMC_NBE0_CLE_DUPLICATEWAKEUPEVENT_MASK (1 << 3) +#define OMAP4_GPMC_NWE_DUPLICATEWAKEUPEVENT_SHIFT 2 +#define OMAP4_GPMC_NWE_DUPLICATEWAKEUPEVENT_MASK (1 << 2) +#define OMAP4_GPMC_NOE_DUPLICATEWAKEUPEVENT_SHIFT 1 +#define OMAP4_GPMC_NOE_DUPLICATEWAKEUPEVENT_MASK (1 << 1) +#define OMAP4_GPMC_NADV_ALE_DUPLICATEWAKEUPEVENT_SHIFT 0 +#define OMAP4_GPMC_NADV_ALE_DUPLICATEWAKEUPEVENT_MASK (1 << 0) + +/* PADCONF_WAKEUPEVENT_2 */ +#define OMAP4_ABE_MCBSP1_CLKX_DUPLICATEWAKEUPEVENT_SHIFT 31 +#define OMAP4_ABE_MCBSP1_CLKX_DUPLICATEWAKEUPEVENT_MASK (1 << 31) +#define OMAP4_ABE_MCBSP2_FSX_DUPLICATEWAKEUPEVENT_SHIFT 30 +#define OMAP4_ABE_MCBSP2_FSX_DUPLICATEWAKEUPEVENT_MASK (1 << 30) +#define OMAP4_ABE_MCBSP2_DX_DUPLICATEWAKEUPEVENT_SHIFT 29 +#define OMAP4_ABE_MCBSP2_DX_DUPLICATEWAKEUPEVENT_MASK (1 << 29) +#define OMAP4_ABE_MCBSP2_DR_DUPLICATEWAKEUPEVENT_SHIFT 28 +#define OMAP4_ABE_MCBSP2_DR_DUPLICATEWAKEUPEVENT_MASK (1 << 28) +#define OMAP4_ABE_MCBSP2_CLKX_DUPLICATEWAKEUPEVENT_SHIFT 27 +#define OMAP4_ABE_MCBSP2_CLKX_DUPLICATEWAKEUPEVENT_MASK (1 << 27) +#define OMAP4_SDMMC1_DAT7_DUPLICATEWAKEUPEVENT_SHIFT 26 +#define OMAP4_SDMMC1_DAT7_DUPLICATEWAKEUPEVENT_MASK (1 << 26) +#define OMAP4_SDMMC1_DAT6_DUPLICATEWAKEUPEVENT_SHIFT 25 +#define OMAP4_SDMMC1_DAT6_DUPLICATEWAKEUPEVENT_MASK (1 << 25) +#define OMAP4_SDMMC1_DAT5_DUPLICATEWAKEUPEVENT_SHIFT 24 +#define OMAP4_SDMMC1_DAT5_DUPLICATEWAKEUPEVENT_MASK (1 << 24) +#define OMAP4_SDMMC1_DAT4_DUPLICATEWAKEUPEVENT_SHIFT 23 +#define OMAP4_SDMMC1_DAT4_DUPLICATEWAKEUPEVENT_MASK (1 << 23) +#define OMAP4_SDMMC1_DAT3_DUPLICATEWAKEUPEVENT_SHIFT 22 +#define OMAP4_SDMMC1_DAT3_DUPLICATEWAKEUPEVENT_MASK (1 << 22) +#define OMAP4_SDMMC1_DAT2_DUPLICATEWAKEUPEVENT_SHIFT 21 +#define OMAP4_SDMMC1_DAT2_DUPLICATEWAKEUPEVENT_MASK (1 << 21) +#define OMAP4_SDMMC1_DAT1_DUPLICATEWAKEUPEVENT_SHIFT 20 +#define OMAP4_SDMMC1_DAT1_DUPLICATEWAKEUPEVENT_MASK (1 << 20) +#define OMAP4_SDMMC1_DAT0_DUPLICATEWAKEUPEVENT_SHIFT 19 +#define OMAP4_SDMMC1_DAT0_DUPLICATEWAKEUPEVENT_MASK (1 << 19) +#define OMAP4_SDMMC1_CMD_DUPLICATEWAKEUPEVENT_SHIFT 18 +#define OMAP4_SDMMC1_CMD_DUPLICATEWAKEUPEVENT_MASK (1 << 18) +#define OMAP4_SDMMC1_CLK_DUPLICATEWAKEUPEVENT_SHIFT 17 +#define OMAP4_SDMMC1_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 17) +#define OMAP4_USBC1_ICUSB_DM_DUPLICATEWAKEUPEVENT_SHIFT 16 +#define OMAP4_USBC1_ICUSB_DM_DUPLICATEWAKEUPEVENT_MASK (1 << 16) +#define OMAP4_USBC1_ICUSB_DP_DUPLICATEWAKEUPEVENT_SHIFT 15 +#define OMAP4_USBC1_ICUSB_DP_DUPLICATEWAKEUPEVENT_MASK (1 << 15) +#define OMAP4_USBB1_HSIC_STROBE_DUPLICATEWAKEUPEVENT_SHIFT 14 +#define OMAP4_USBB1_HSIC_STROBE_DUPLICATEWAKEUPEVENT_MASK (1 << 14) +#define OMAP4_USBB1_HSIC_DATA_DUPLICATEWAKEUPEVENT_SHIFT 13 +#define OMAP4_USBB1_HSIC_DATA_DUPLICATEWAKEUPEVENT_MASK (1 << 13) +#define OMAP4_USBB1_ULPITLL_DAT7_DUPLICATEWAKEUPEVENT_SHIFT 12 +#define OMAP4_USBB1_ULPITLL_DAT7_DUPLICATEWAKEUPEVENT_MASK (1 << 12) +#define OMAP4_USBB1_ULPITLL_DAT6_DUPLICATEWAKEUPEVENT_SHIFT 11 +#define OMAP4_USBB1_ULPITLL_DAT6_DUPLICATEWAKEUPEVENT_MASK (1 << 11) +#define OMAP4_USBB1_ULPITLL_DAT5_DUPLICATEWAKEUPEVENT_SHIFT 10 +#define OMAP4_USBB1_ULPITLL_DAT5_DUPLICATEWAKEUPEVENT_MASK (1 << 10) +#define OMAP4_USBB1_ULPITLL_DAT4_DUPLICATEWAKEUPEVENT_SHIFT 9 +#define OMAP4_USBB1_ULPITLL_DAT4_DUPLICATEWAKEUPEVENT_MASK (1 << 9) +#define OMAP4_USBB1_ULPITLL_DAT3_DUPLICATEWAKEUPEVENT_SHIFT 8 +#define OMAP4_USBB1_ULPITLL_DAT3_DUPLICATEWAKEUPEVENT_MASK (1 << 8) +#define OMAP4_USBB1_ULPITLL_DAT2_DUPLICATEWAKEUPEVENT_SHIFT 7 +#define OMAP4_USBB1_ULPITLL_DAT2_DUPLICATEWAKEUPEVENT_MASK (1 << 7) +#define OMAP4_USBB1_ULPITLL_DAT1_DUPLICATEWAKEUPEVENT_SHIFT 6 +#define OMAP4_USBB1_ULPITLL_DAT1_DUPLICATEWAKEUPEVENT_MASK (1 << 6) +#define OMAP4_USBB1_ULPITLL_DAT0_DUPLICATEWAKEUPEVENT_SHIFT 5 +#define OMAP4_USBB1_ULPITLL_DAT0_DUPLICATEWAKEUPEVENT_MASK (1 << 5) +#define OMAP4_USBB1_ULPITLL_NXT_DUPLICATEWAKEUPEVENT_SHIFT 4 +#define OMAP4_USBB1_ULPITLL_NXT_DUPLICATEWAKEUPEVENT_MASK (1 << 4) +#define OMAP4_USBB1_ULPITLL_DIR_DUPLICATEWAKEUPEVENT_SHIFT 3 +#define OMAP4_USBB1_ULPITLL_DIR_DUPLICATEWAKEUPEVENT_MASK (1 << 3) +#define OMAP4_USBB1_ULPITLL_STP_DUPLICATEWAKEUPEVENT_SHIFT 2 +#define OMAP4_USBB1_ULPITLL_STP_DUPLICATEWAKEUPEVENT_MASK (1 << 2) +#define OMAP4_USBB1_ULPITLL_CLK_DUPLICATEWAKEUPEVENT_SHIFT 1 +#define OMAP4_USBB1_ULPITLL_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 1) +#define OMAP4_CAM_GLOBALRESET_DUPLICATEWAKEUPEVENT_SHIFT 0 +#define OMAP4_CAM_GLOBALRESET_DUPLICATEWAKEUPEVENT_MASK (1 << 0) + +/* PADCONF_WAKEUPEVENT_3 */ +#define OMAP4_MCSPI1_CS3_DUPLICATEWAKEUPEVENT_SHIFT 31 +#define OMAP4_MCSPI1_CS3_DUPLICATEWAKEUPEVENT_MASK (1 << 31) +#define OMAP4_MCSPI1_CS2_DUPLICATEWAKEUPEVENT_SHIFT 30 +#define OMAP4_MCSPI1_CS2_DUPLICATEWAKEUPEVENT_MASK (1 << 30) +#define OMAP4_MCSPI1_CS1_DUPLICATEWAKEUPEVENT_SHIFT 29 +#define OMAP4_MCSPI1_CS1_DUPLICATEWAKEUPEVENT_MASK (1 << 29) +#define OMAP4_MCSPI1_CS0_DUPLICATEWAKEUPEVENT_SHIFT 28 +#define OMAP4_MCSPI1_CS0_DUPLICATEWAKEUPEVENT_MASK (1 << 28) +#define OMAP4_MCSPI1_SIMO_DUPLICATEWAKEUPEVENT_SHIFT 27 +#define OMAP4_MCSPI1_SIMO_DUPLICATEWAKEUPEVENT_MASK (1 << 27) +#define OMAP4_MCSPI1_SOMI_DUPLICATEWAKEUPEVENT_SHIFT 26 +#define OMAP4_MCSPI1_SOMI_DUPLICATEWAKEUPEVENT_MASK (1 << 26) +#define OMAP4_MCSPI1_CLK_DUPLICATEWAKEUPEVENT_SHIFT 25 +#define OMAP4_MCSPI1_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 25) +#define OMAP4_I2C4_SDA_DUPLICATEWAKEUPEVENT_SHIFT 24 +#define OMAP4_I2C4_SDA_DUPLICATEWAKEUPEVENT_MASK (1 << 24) +#define OMAP4_I2C4_SCL_DUPLICATEWAKEUPEVENT_SHIFT 23 +#define OMAP4_I2C4_SCL_DUPLICATEWAKEUPEVENT_MASK (1 << 23) +#define OMAP4_I2C3_SDA_DUPLICATEWAKEUPEVENT_SHIFT 22 +#define OMAP4_I2C3_SDA_DUPLICATEWAKEUPEVENT_MASK (1 << 22) +#define OMAP4_I2C3_SCL_DUPLICATEWAKEUPEVENT_SHIFT 21 +#define OMAP4_I2C3_SCL_DUPLICATEWAKEUPEVENT_MASK (1 << 21) +#define OMAP4_I2C2_SDA_DUPLICATEWAKEUPEVENT_SHIFT 20 +#define OMAP4_I2C2_SDA_DUPLICATEWAKEUPEVENT_MASK (1 << 20) +#define OMAP4_I2C2_SCL_DUPLICATEWAKEUPEVENT_SHIFT 19 +#define OMAP4_I2C2_SCL_DUPLICATEWAKEUPEVENT_MASK (1 << 19) +#define OMAP4_I2C1_SDA_DUPLICATEWAKEUPEVENT_SHIFT 18 +#define OMAP4_I2C1_SDA_DUPLICATEWAKEUPEVENT_MASK (1 << 18) +#define OMAP4_I2C1_SCL_DUPLICATEWAKEUPEVENT_SHIFT 17 +#define OMAP4_I2C1_SCL_DUPLICATEWAKEUPEVENT_MASK (1 << 17) +#define OMAP4_HDQ_SIO_DUPLICATEWAKEUPEVENT_SHIFT 16 +#define OMAP4_HDQ_SIO_DUPLICATEWAKEUPEVENT_MASK (1 << 16) +#define OMAP4_UART2_TX_DUPLICATEWAKEUPEVENT_SHIFT 15 +#define OMAP4_UART2_TX_DUPLICATEWAKEUPEVENT_MASK (1 << 15) +#define OMAP4_UART2_RX_DUPLICATEWAKEUPEVENT_SHIFT 14 +#define OMAP4_UART2_RX_DUPLICATEWAKEUPEVENT_MASK (1 << 14) +#define OMAP4_UART2_RTS_DUPLICATEWAKEUPEVENT_SHIFT 13 +#define OMAP4_UART2_RTS_DUPLICATEWAKEUPEVENT_MASK (1 << 13) +#define OMAP4_UART2_CTS_DUPLICATEWAKEUPEVENT_SHIFT 12 +#define OMAP4_UART2_CTS_DUPLICATEWAKEUPEVENT_MASK (1 << 12) +#define OMAP4_ABE_DMIC_DIN3_DUPLICATEWAKEUPEVENT_SHIFT 11 +#define OMAP4_ABE_DMIC_DIN3_DUPLICATEWAKEUPEVENT_MASK (1 << 11) +#define OMAP4_ABE_DMIC_DIN2_DUPLICATEWAKEUPEVENT_SHIFT 10 +#define OMAP4_ABE_DMIC_DIN2_DUPLICATEWAKEUPEVENT_MASK (1 << 10) +#define OMAP4_ABE_DMIC_DIN1_DUPLICATEWAKEUPEVENT_SHIFT 9 +#define OMAP4_ABE_DMIC_DIN1_DUPLICATEWAKEUPEVENT_MASK (1 << 9) +#define OMAP4_ABE_DMIC_CLK1_DUPLICATEWAKEUPEVENT_SHIFT 8 +#define OMAP4_ABE_DMIC_CLK1_DUPLICATEWAKEUPEVENT_MASK (1 << 8) +#define OMAP4_ABE_CLKS_DUPLICATEWAKEUPEVENT_SHIFT 7 +#define OMAP4_ABE_CLKS_DUPLICATEWAKEUPEVENT_MASK (1 << 7) +#define OMAP4_ABE_PDM_LB_CLK_DUPLICATEWAKEUPEVENT_SHIFT 6 +#define OMAP4_ABE_PDM_LB_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 6) +#define OMAP4_ABE_PDM_FRAME_DUPLICATEWAKEUPEVENT_SHIFT 5 +#define OMAP4_ABE_PDM_FRAME_DUPLICATEWAKEUPEVENT_MASK (1 << 5) +#define OMAP4_ABE_PDM_DL_DATA_DUPLICATEWAKEUPEVENT_SHIFT 4 +#define OMAP4_ABE_PDM_DL_DATA_DUPLICATEWAKEUPEVENT_MASK (1 << 4) +#define OMAP4_ABE_PDM_UL_DATA_DUPLICATEWAKEUPEVENT_SHIFT 3 +#define OMAP4_ABE_PDM_UL_DATA_DUPLICATEWAKEUPEVENT_MASK (1 << 3) +#define OMAP4_ABE_MCBSP1_FSX_DUPLICATEWAKEUPEVENT_SHIFT 2 +#define OMAP4_ABE_MCBSP1_FSX_DUPLICATEWAKEUPEVENT_MASK (1 << 2) +#define OMAP4_ABE_MCBSP1_DX_DUPLICATEWAKEUPEVENT_SHIFT 1 +#define OMAP4_ABE_MCBSP1_DX_DUPLICATEWAKEUPEVENT_MASK (1 << 1) +#define OMAP4_ABE_MCBSP1_DR_DUPLICATEWAKEUPEVENT_SHIFT 0 +#define OMAP4_ABE_MCBSP1_DR_DUPLICATEWAKEUPEVENT_MASK (1 << 0) + +/* PADCONF_WAKEUPEVENT_4 */ +#define OMAP4_UNIPRO_TY0_DUPLICATEWAKEUPEVENT_SHIFT 31 +#define OMAP4_UNIPRO_TY0_DUPLICATEWAKEUPEVENT_MASK (1 << 31) +#define OMAP4_UNIPRO_TX0_DUPLICATEWAKEUPEVENT_SHIFT 30 +#define OMAP4_UNIPRO_TX0_DUPLICATEWAKEUPEVENT_MASK (1 << 30) +#define OMAP4_USBB2_HSIC_STROBE_DUPLICATEWAKEUPEVENT_SHIFT 29 +#define OMAP4_USBB2_HSIC_STROBE_DUPLICATEWAKEUPEVENT_MASK (1 << 29) +#define OMAP4_USBB2_HSIC_DATA_DUPLICATEWAKEUPEVENT_SHIFT 28 +#define OMAP4_USBB2_HSIC_DATA_DUPLICATEWAKEUPEVENT_MASK (1 << 28) +#define OMAP4_USBB2_ULPITLL_DAT7_DUPLICATEWAKEUPEVENT_SHIFT 27 +#define OMAP4_USBB2_ULPITLL_DAT7_DUPLICATEWAKEUPEVENT_MASK (1 << 27) +#define OMAP4_USBB2_ULPITLL_DAT6_DUPLICATEWAKEUPEVENT_SHIFT 26 +#define OMAP4_USBB2_ULPITLL_DAT6_DUPLICATEWAKEUPEVENT_MASK (1 << 26) +#define OMAP4_USBB2_ULPITLL_DAT5_DUPLICATEWAKEUPEVENT_SHIFT 25 +#define OMAP4_USBB2_ULPITLL_DAT5_DUPLICATEWAKEUPEVENT_MASK (1 << 25) +#define OMAP4_USBB2_ULPITLL_DAT4_DUPLICATEWAKEUPEVENT_SHIFT 24 +#define OMAP4_USBB2_ULPITLL_DAT4_DUPLICATEWAKEUPEVENT_MASK (1 << 24) +#define OMAP4_USBB2_ULPITLL_DAT3_DUPLICATEWAKEUPEVENT_SHIFT 23 +#define OMAP4_USBB2_ULPITLL_DAT3_DUPLICATEWAKEUPEVENT_MASK (1 << 23) +#define OMAP4_USBB2_ULPITLL_DAT2_DUPLICATEWAKEUPEVENT_SHIFT 22 +#define OMAP4_USBB2_ULPITLL_DAT2_DUPLICATEWAKEUPEVENT_MASK (1 << 22) +#define OMAP4_USBB2_ULPITLL_DAT1_DUPLICATEWAKEUPEVENT_SHIFT 21 +#define OMAP4_USBB2_ULPITLL_DAT1_DUPLICATEWAKEUPEVENT_MASK (1 << 21) +#define OMAP4_USBB2_ULPITLL_DAT0_DUPLICATEWAKEUPEVENT_SHIFT 20 +#define OMAP4_USBB2_ULPITLL_DAT0_DUPLICATEWAKEUPEVENT_MASK (1 << 20) +#define OMAP4_USBB2_ULPITLL_NXT_DUPLICATEWAKEUPEVENT_SHIFT 19 +#define OMAP4_USBB2_ULPITLL_NXT_DUPLICATEWAKEUPEVENT_MASK (1 << 19) +#define OMAP4_USBB2_ULPITLL_DIR_DUPLICATEWAKEUPEVENT_SHIFT 18 +#define OMAP4_USBB2_ULPITLL_DIR_DUPLICATEWAKEUPEVENT_MASK (1 << 18) +#define OMAP4_USBB2_ULPITLL_STP_DUPLICATEWAKEUPEVENT_SHIFT 17 +#define OMAP4_USBB2_ULPITLL_STP_DUPLICATEWAKEUPEVENT_MASK (1 << 17) +#define OMAP4_USBB2_ULPITLL_CLK_DUPLICATEWAKEUPEVENT_SHIFT 16 +#define OMAP4_USBB2_ULPITLL_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 16) +#define OMAP4_UART4_TX_DUPLICATEWAKEUPEVENT_SHIFT 15 +#define OMAP4_UART4_TX_DUPLICATEWAKEUPEVENT_MASK (1 << 15) +#define OMAP4_UART4_RX_DUPLICATEWAKEUPEVENT_SHIFT 14 +#define OMAP4_UART4_RX_DUPLICATEWAKEUPEVENT_MASK (1 << 14) +#define OMAP4_MCSPI4_CS0_DUPLICATEWAKEUPEVENT_SHIFT 13 +#define OMAP4_MCSPI4_CS0_DUPLICATEWAKEUPEVENT_MASK (1 << 13) +#define OMAP4_MCSPI4_SOMI_DUPLICATEWAKEUPEVENT_SHIFT 12 +#define OMAP4_MCSPI4_SOMI_DUPLICATEWAKEUPEVENT_MASK (1 << 12) +#define OMAP4_MCSPI4_SIMO_DUPLICATEWAKEUPEVENT_SHIFT 11 +#define OMAP4_MCSPI4_SIMO_DUPLICATEWAKEUPEVENT_MASK (1 << 11) +#define OMAP4_MCSPI4_CLK_DUPLICATEWAKEUPEVENT_SHIFT 10 +#define OMAP4_MCSPI4_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 10) +#define OMAP4_SDMMC5_DAT3_DUPLICATEWAKEUPEVENT_SHIFT 9 +#define OMAP4_SDMMC5_DAT3_DUPLICATEWAKEUPEVENT_MASK (1 << 9) +#define OMAP4_SDMMC5_DAT2_DUPLICATEWAKEUPEVENT_SHIFT 8 +#define OMAP4_SDMMC5_DAT2_DUPLICATEWAKEUPEVENT_MASK (1 << 8) +#define OMAP4_SDMMC5_DAT1_DUPLICATEWAKEUPEVENT_SHIFT 7 +#define OMAP4_SDMMC5_DAT1_DUPLICATEWAKEUPEVENT_MASK (1 << 7) +#define OMAP4_SDMMC5_DAT0_DUPLICATEWAKEUPEVENT_SHIFT 6 +#define OMAP4_SDMMC5_DAT0_DUPLICATEWAKEUPEVENT_MASK (1 << 6) +#define OMAP4_SDMMC5_CMD_DUPLICATEWAKEUPEVENT_SHIFT 5 +#define OMAP4_SDMMC5_CMD_DUPLICATEWAKEUPEVENT_MASK (1 << 5) +#define OMAP4_SDMMC5_CLK_DUPLICATEWAKEUPEVENT_SHIFT 4 +#define OMAP4_SDMMC5_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 4) +#define OMAP4_UART3_TX_IRTX_DUPLICATEWAKEUPEVENT_SHIFT 3 +#define OMAP4_UART3_TX_IRTX_DUPLICATEWAKEUPEVENT_MASK (1 << 3) +#define OMAP4_UART3_RX_IRRX_DUPLICATEWAKEUPEVENT_SHIFT 2 +#define OMAP4_UART3_RX_IRRX_DUPLICATEWAKEUPEVENT_MASK (1 << 2) +#define OMAP4_UART3_RTS_SD_DUPLICATEWAKEUPEVENT_SHIFT 1 +#define OMAP4_UART3_RTS_SD_DUPLICATEWAKEUPEVENT_MASK (1 << 1) +#define OMAP4_UART3_CTS_RCTX_DUPLICATEWAKEUPEVENT_SHIFT 0 +#define OMAP4_UART3_CTS_RCTX_DUPLICATEWAKEUPEVENT_MASK (1 << 0) + +/* PADCONF_WAKEUPEVENT_5 */ +#define OMAP4_DPM_EMU11_DUPLICATEWAKEUPEVENT_SHIFT 31 +#define OMAP4_DPM_EMU11_DUPLICATEWAKEUPEVENT_MASK (1 << 31) +#define OMAP4_DPM_EMU10_DUPLICATEWAKEUPEVENT_SHIFT 30 +#define OMAP4_DPM_EMU10_DUPLICATEWAKEUPEVENT_MASK (1 << 30) +#define OMAP4_DPM_EMU9_DUPLICATEWAKEUPEVENT_SHIFT 29 +#define OMAP4_DPM_EMU9_DUPLICATEWAKEUPEVENT_MASK (1 << 29) +#define OMAP4_DPM_EMU8_DUPLICATEWAKEUPEVENT_SHIFT 28 +#define OMAP4_DPM_EMU8_DUPLICATEWAKEUPEVENT_MASK (1 << 28) +#define OMAP4_DPM_EMU7_DUPLICATEWAKEUPEVENT_SHIFT 27 +#define OMAP4_DPM_EMU7_DUPLICATEWAKEUPEVENT_MASK (1 << 27) +#define OMAP4_DPM_EMU6_DUPLICATEWAKEUPEVENT_SHIFT 26 +#define OMAP4_DPM_EMU6_DUPLICATEWAKEUPEVENT_MASK (1 << 26) +#define OMAP4_DPM_EMU5_DUPLICATEWAKEUPEVENT_SHIFT 25 +#define OMAP4_DPM_EMU5_DUPLICATEWAKEUPEVENT_MASK (1 << 25) +#define OMAP4_DPM_EMU4_DUPLICATEWAKEUPEVENT_SHIFT 24 +#define OMAP4_DPM_EMU4_DUPLICATEWAKEUPEVENT_MASK (1 << 24) +#define OMAP4_DPM_EMU3_DUPLICATEWAKEUPEVENT_SHIFT 23 +#define OMAP4_DPM_EMU3_DUPLICATEWAKEUPEVENT_MASK (1 << 23) +#define OMAP4_DPM_EMU2_DUPLICATEWAKEUPEVENT_SHIFT 22 +#define OMAP4_DPM_EMU2_DUPLICATEWAKEUPEVENT_MASK (1 << 22) +#define OMAP4_DPM_EMU1_DUPLICATEWAKEUPEVENT_SHIFT 21 +#define OMAP4_DPM_EMU1_DUPLICATEWAKEUPEVENT_MASK (1 << 21) +#define OMAP4_DPM_EMU0_DUPLICATEWAKEUPEVENT_SHIFT 20 +#define OMAP4_DPM_EMU0_DUPLICATEWAKEUPEVENT_MASK (1 << 20) +#define OMAP4_SYS_BOOT5_DUPLICATEWAKEUPEVENT_SHIFT 19 +#define OMAP4_SYS_BOOT5_DUPLICATEWAKEUPEVENT_MASK (1 << 19) +#define OMAP4_SYS_BOOT4_DUPLICATEWAKEUPEVENT_SHIFT 18 +#define OMAP4_SYS_BOOT4_DUPLICATEWAKEUPEVENT_MASK (1 << 18) +#define OMAP4_SYS_BOOT3_DUPLICATEWAKEUPEVENT_SHIFT 17 +#define OMAP4_SYS_BOOT3_DUPLICATEWAKEUPEVENT_MASK (1 << 17) +#define OMAP4_SYS_BOOT2_DUPLICATEWAKEUPEVENT_SHIFT 16 +#define OMAP4_SYS_BOOT2_DUPLICATEWAKEUPEVENT_MASK (1 << 16) +#define OMAP4_SYS_BOOT1_DUPLICATEWAKEUPEVENT_SHIFT 15 +#define OMAP4_SYS_BOOT1_DUPLICATEWAKEUPEVENT_MASK (1 << 15) +#define OMAP4_SYS_BOOT0_DUPLICATEWAKEUPEVENT_SHIFT 14 +#define OMAP4_SYS_BOOT0_DUPLICATEWAKEUPEVENT_MASK (1 << 14) +#define OMAP4_SYS_NIRQ2_DUPLICATEWAKEUPEVENT_SHIFT 13 +#define OMAP4_SYS_NIRQ2_DUPLICATEWAKEUPEVENT_MASK (1 << 13) +#define OMAP4_SYS_NIRQ1_DUPLICATEWAKEUPEVENT_SHIFT 12 +#define OMAP4_SYS_NIRQ1_DUPLICATEWAKEUPEVENT_MASK (1 << 12) +#define OMAP4_FREF_CLK2_OUT_DUPLICATEWAKEUPEVENT_SHIFT 11 +#define OMAP4_FREF_CLK2_OUT_DUPLICATEWAKEUPEVENT_MASK (1 << 11) +#define OMAP4_FREF_CLK1_OUT_DUPLICATEWAKEUPEVENT_SHIFT 10 +#define OMAP4_FREF_CLK1_OUT_DUPLICATEWAKEUPEVENT_MASK (1 << 10) +#define OMAP4_UNIPRO_RY2_DUPLICATEWAKEUPEVENT_SHIFT 9 +#define OMAP4_UNIPRO_RY2_DUPLICATEWAKEUPEVENT_MASK (1 << 9) +#define OMAP4_UNIPRO_RX2_DUPLICATEWAKEUPEVENT_SHIFT 8 +#define OMAP4_UNIPRO_RX2_DUPLICATEWAKEUPEVENT_MASK (1 << 8) +#define OMAP4_UNIPRO_RY1_DUPLICATEWAKEUPEVENT_SHIFT 7 +#define OMAP4_UNIPRO_RY1_DUPLICATEWAKEUPEVENT_MASK (1 << 7) +#define OMAP4_UNIPRO_RX1_DUPLICATEWAKEUPEVENT_SHIFT 6 +#define OMAP4_UNIPRO_RX1_DUPLICATEWAKEUPEVENT_MASK (1 << 6) +#define OMAP4_UNIPRO_RY0_DUPLICATEWAKEUPEVENT_SHIFT 5 +#define OMAP4_UNIPRO_RY0_DUPLICATEWAKEUPEVENT_MASK (1 << 5) +#define OMAP4_UNIPRO_RX0_DUPLICATEWAKEUPEVENT_SHIFT 4 +#define OMAP4_UNIPRO_RX0_DUPLICATEWAKEUPEVENT_MASK (1 << 4) +#define OMAP4_UNIPRO_TY2_DUPLICATEWAKEUPEVENT_SHIFT 3 +#define OMAP4_UNIPRO_TY2_DUPLICATEWAKEUPEVENT_MASK (1 << 3) +#define OMAP4_UNIPRO_TX2_DUPLICATEWAKEUPEVENT_SHIFT 2 +#define OMAP4_UNIPRO_TX2_DUPLICATEWAKEUPEVENT_MASK (1 << 2) +#define OMAP4_UNIPRO_TY1_DUPLICATEWAKEUPEVENT_SHIFT 1 +#define OMAP4_UNIPRO_TY1_DUPLICATEWAKEUPEVENT_MASK (1 << 1) +#define OMAP4_UNIPRO_TX1_DUPLICATEWAKEUPEVENT_SHIFT 0 +#define OMAP4_UNIPRO_TX1_DUPLICATEWAKEUPEVENT_MASK (1 << 0) + +/* PADCONF_WAKEUPEVENT_6 */ +#define OMAP4_DPM_EMU19_DUPLICATEWAKEUPEVENT_SHIFT 7 +#define OMAP4_DPM_EMU19_DUPLICATEWAKEUPEVENT_MASK (1 << 7) +#define OMAP4_DPM_EMU18_DUPLICATEWAKEUPEVENT_SHIFT 6 +#define OMAP4_DPM_EMU18_DUPLICATEWAKEUPEVENT_MASK (1 << 6) +#define OMAP4_DPM_EMU17_DUPLICATEWAKEUPEVENT_SHIFT 5 +#define OMAP4_DPM_EMU17_DUPLICATEWAKEUPEVENT_MASK (1 << 5) +#define OMAP4_DPM_EMU16_DUPLICATEWAKEUPEVENT_SHIFT 4 +#define OMAP4_DPM_EMU16_DUPLICATEWAKEUPEVENT_MASK (1 << 4) +#define OMAP4_DPM_EMU15_DUPLICATEWAKEUPEVENT_SHIFT 3 +#define OMAP4_DPM_EMU15_DUPLICATEWAKEUPEVENT_MASK (1 << 3) +#define OMAP4_DPM_EMU14_DUPLICATEWAKEUPEVENT_SHIFT 2 +#define OMAP4_DPM_EMU14_DUPLICATEWAKEUPEVENT_MASK (1 << 2) +#define OMAP4_DPM_EMU13_DUPLICATEWAKEUPEVENT_SHIFT 1 +#define OMAP4_DPM_EMU13_DUPLICATEWAKEUPEVENT_MASK (1 << 1) +#define OMAP4_DPM_EMU12_DUPLICATEWAKEUPEVENT_SHIFT 0 +#define OMAP4_DPM_EMU12_DUPLICATEWAKEUPEVENT_MASK (1 << 0) + +/* CONTROL_PADCONF_GLOBAL */ +#define OMAP4_FORCE_OFFMODE_EN_SHIFT 31 +#define OMAP4_FORCE_OFFMODE_EN_MASK (1 << 31) + +/* CONTROL_PADCONF_MODE */ +#define OMAP4_VDDS_DV_BANK0_SHIFT 31 +#define OMAP4_VDDS_DV_BANK0_MASK (1 << 31) +#define OMAP4_VDDS_DV_BANK1_SHIFT 30 +#define OMAP4_VDDS_DV_BANK1_MASK (1 << 30) +#define OMAP4_VDDS_DV_BANK3_SHIFT 29 +#define OMAP4_VDDS_DV_BANK3_MASK (1 << 29) +#define OMAP4_VDDS_DV_BANK4_SHIFT 28 +#define OMAP4_VDDS_DV_BANK4_MASK (1 << 28) +#define OMAP4_VDDS_DV_BANK5_SHIFT 27 +#define OMAP4_VDDS_DV_BANK5_MASK (1 << 27) +#define OMAP4_VDDS_DV_BANK6_SHIFT 26 +#define OMAP4_VDDS_DV_BANK6_MASK (1 << 26) +#define OMAP4_VDDS_DV_C2C_SHIFT 25 +#define OMAP4_VDDS_DV_C2C_MASK (1 << 25) +#define OMAP4_VDDS_DV_CAM_SHIFT 24 +#define OMAP4_VDDS_DV_CAM_MASK (1 << 24) +#define OMAP4_VDDS_DV_GPMC_SHIFT 23 +#define OMAP4_VDDS_DV_GPMC_MASK (1 << 23) +#define OMAP4_VDDS_DV_SDMMC2_SHIFT 22 +#define OMAP4_VDDS_DV_SDMMC2_MASK (1 << 22) + +/* CONTROL_SMART1IO_PADCONF_0 */ +#define OMAP4_ABE_DR0_SC_SHIFT 30 +#define OMAP4_ABE_DR0_SC_MASK (0x3 << 30) +#define OMAP4_CAM_DR0_SC_SHIFT 28 +#define OMAP4_CAM_DR0_SC_MASK (0x3 << 28) +#define OMAP4_FREF_DR2_SC_SHIFT 26 +#define OMAP4_FREF_DR2_SC_MASK (0x3 << 26) +#define OMAP4_FREF_DR3_SC_SHIFT 24 +#define OMAP4_FREF_DR3_SC_MASK (0x3 << 24) +#define OMAP4_GPIO_DR8_SC_SHIFT 22 +#define OMAP4_GPIO_DR8_SC_MASK (0x3 << 22) +#define OMAP4_GPIO_DR9_SC_SHIFT 20 +#define OMAP4_GPIO_DR9_SC_MASK (0x3 << 20) +#define OMAP4_GPMC_DR2_SC_SHIFT 18 +#define OMAP4_GPMC_DR2_SC_MASK (0x3 << 18) +#define OMAP4_GPMC_DR3_SC_SHIFT 16 +#define OMAP4_GPMC_DR3_SC_MASK (0x3 << 16) +#define OMAP4_GPMC_DR6_SC_SHIFT 14 +#define OMAP4_GPMC_DR6_SC_MASK (0x3 << 14) +#define OMAP4_HDMI_DR0_SC_SHIFT 12 +#define OMAP4_HDMI_DR0_SC_MASK (0x3 << 12) +#define OMAP4_MCSPI1_DR0_SC_SHIFT 10 +#define OMAP4_MCSPI1_DR0_SC_MASK (0x3 << 10) +#define OMAP4_UART1_DR0_SC_SHIFT 8 +#define OMAP4_UART1_DR0_SC_MASK (0x3 << 8) +#define OMAP4_UART3_DR0_SC_SHIFT 6 +#define OMAP4_UART3_DR0_SC_MASK (0x3 << 6) +#define OMAP4_UART3_DR1_SC_SHIFT 4 +#define OMAP4_UART3_DR1_SC_MASK (0x3 << 4) +#define OMAP4_UNIPRO_DR0_SC_SHIFT 2 +#define OMAP4_UNIPRO_DR0_SC_MASK (0x3 << 2) +#define OMAP4_UNIPRO_DR1_SC_SHIFT 0 +#define OMAP4_UNIPRO_DR1_SC_MASK (0x3 << 0) + +/* CONTROL_SMART1IO_PADCONF_1 */ +#define OMAP4_ABE_DR0_LB_SHIFT 30 +#define OMAP4_ABE_DR0_LB_MASK (0x3 << 30) +#define OMAP4_CAM_DR0_LB_SHIFT 28 +#define OMAP4_CAM_DR0_LB_MASK (0x3 << 28) +#define OMAP4_FREF_DR2_LB_SHIFT 26 +#define OMAP4_FREF_DR2_LB_MASK (0x3 << 26) +#define OMAP4_FREF_DR3_LB_SHIFT 24 +#define OMAP4_FREF_DR3_LB_MASK (0x3 << 24) +#define OMAP4_GPIO_DR8_LB_SHIFT 22 +#define OMAP4_GPIO_DR8_LB_MASK (0x3 << 22) +#define OMAP4_GPIO_DR9_LB_SHIFT 20 +#define OMAP4_GPIO_DR9_LB_MASK (0x3 << 20) +#define OMAP4_GPMC_DR2_LB_SHIFT 18 +#define OMAP4_GPMC_DR2_LB_MASK (0x3 << 18) +#define OMAP4_GPMC_DR3_LB_SHIFT 16 +#define OMAP4_GPMC_DR3_LB_MASK (0x3 << 16) +#define OMAP4_GPMC_DR6_LB_SHIFT 14 +#define OMAP4_GPMC_DR6_LB_MASK (0x3 << 14) +#define OMAP4_HDMI_DR0_LB_SHIFT 12 +#define OMAP4_HDMI_DR0_LB_MASK (0x3 << 12) +#define OMAP4_MCSPI1_DR0_LB_SHIFT 10 +#define OMAP4_MCSPI1_DR0_LB_MASK (0x3 << 10) +#define OMAP4_UART1_DR0_LB_SHIFT 8 +#define OMAP4_UART1_DR0_LB_MASK (0x3 << 8) +#define OMAP4_UART3_DR0_LB_SHIFT 6 +#define OMAP4_UART3_DR0_LB_MASK (0x3 << 6) +#define OMAP4_UART3_DR1_LB_SHIFT 4 +#define OMAP4_UART3_DR1_LB_MASK (0x3 << 4) +#define OMAP4_UNIPRO_DR0_LB_SHIFT 2 +#define OMAP4_UNIPRO_DR0_LB_MASK (0x3 << 2) +#define OMAP4_UNIPRO_DR1_LB_SHIFT 0 +#define OMAP4_UNIPRO_DR1_LB_MASK (0x3 << 0) + +/* CONTROL_SMART2IO_PADCONF_0 */ +#define OMAP4_C2C_DR0_LB_SHIFT 31 +#define OMAP4_C2C_DR0_LB_MASK (1 << 31) +#define OMAP4_DPM_DR1_LB_SHIFT 30 +#define OMAP4_DPM_DR1_LB_MASK (1 << 30) +#define OMAP4_DPM_DR2_LB_SHIFT 29 +#define OMAP4_DPM_DR2_LB_MASK (1 << 29) +#define OMAP4_DPM_DR3_LB_SHIFT 28 +#define OMAP4_DPM_DR3_LB_MASK (1 << 28) +#define OMAP4_GPIO_DR0_LB_SHIFT 27 +#define OMAP4_GPIO_DR0_LB_MASK (1 << 27) +#define OMAP4_GPIO_DR1_LB_SHIFT 26 +#define OMAP4_GPIO_DR1_LB_MASK (1 << 26) +#define OMAP4_GPIO_DR10_LB_SHIFT 25 +#define OMAP4_GPIO_DR10_LB_MASK (1 << 25) +#define OMAP4_GPIO_DR2_LB_SHIFT 24 +#define OMAP4_GPIO_DR2_LB_MASK (1 << 24) +#define OMAP4_GPMC_DR0_LB_SHIFT 23 +#define OMAP4_GPMC_DR0_LB_MASK (1 << 23) +#define OMAP4_GPMC_DR1_LB_SHIFT 22 +#define OMAP4_GPMC_DR1_LB_MASK (1 << 22) +#define OMAP4_GPMC_DR4_LB_SHIFT 21 +#define OMAP4_GPMC_DR4_LB_MASK (1 << 21) +#define OMAP4_GPMC_DR5_LB_SHIFT 20 +#define OMAP4_GPMC_DR5_LB_MASK (1 << 20) +#define OMAP4_GPMC_DR7_LB_SHIFT 19 +#define OMAP4_GPMC_DR7_LB_MASK (1 << 19) +#define OMAP4_HSI2_DR0_LB_SHIFT 18 +#define OMAP4_HSI2_DR0_LB_MASK (1 << 18) +#define OMAP4_HSI2_DR1_LB_SHIFT 17 +#define OMAP4_HSI2_DR1_LB_MASK (1 << 17) +#define OMAP4_HSI2_DR2_LB_SHIFT 16 +#define OMAP4_HSI2_DR2_LB_MASK (1 << 16) +#define OMAP4_KPD_DR0_LB_SHIFT 15 +#define OMAP4_KPD_DR0_LB_MASK (1 << 15) +#define OMAP4_KPD_DR1_LB_SHIFT 14 +#define OMAP4_KPD_DR1_LB_MASK (1 << 14) +#define OMAP4_PDM_DR0_LB_SHIFT 13 +#define OMAP4_PDM_DR0_LB_MASK (1 << 13) +#define OMAP4_SDMMC2_DR0_LB_SHIFT 12 +#define OMAP4_SDMMC2_DR0_LB_MASK (1 << 12) +#define OMAP4_SDMMC3_DR0_LB_SHIFT 11 +#define OMAP4_SDMMC3_DR0_LB_MASK (1 << 11) +#define OMAP4_SDMMC4_DR0_LB_SHIFT 10 +#define OMAP4_SDMMC4_DR0_LB_MASK (1 << 10) +#define OMAP4_SDMMC4_DR1_LB_SHIFT 9 +#define OMAP4_SDMMC4_DR1_LB_MASK (1 << 9) +#define OMAP4_SPI3_DR0_LB_SHIFT 8 +#define OMAP4_SPI3_DR0_LB_MASK (1 << 8) +#define OMAP4_SPI3_DR1_LB_SHIFT 7 +#define OMAP4_SPI3_DR1_LB_MASK (1 << 7) +#define OMAP4_UART3_DR2_LB_SHIFT 6 +#define OMAP4_UART3_DR2_LB_MASK (1 << 6) +#define OMAP4_UART3_DR3_LB_SHIFT 5 +#define OMAP4_UART3_DR3_LB_MASK (1 << 5) +#define OMAP4_UART3_DR4_LB_SHIFT 4 +#define OMAP4_UART3_DR4_LB_MASK (1 << 4) +#define OMAP4_UART3_DR5_LB_SHIFT 3 +#define OMAP4_UART3_DR5_LB_MASK (1 << 3) +#define OMAP4_USBA0_DR1_LB_SHIFT 2 +#define OMAP4_USBA0_DR1_LB_MASK (1 << 2) +#define OMAP4_USBA_DR2_LB_SHIFT 1 +#define OMAP4_USBA_DR2_LB_MASK (1 << 1) + +/* CONTROL_SMART2IO_PADCONF_1 */ +#define OMAP4_USBB1_DR0_LB_SHIFT 31 +#define OMAP4_USBB1_DR0_LB_MASK (1 << 31) +#define OMAP4_USBB2_DR0_LB_SHIFT 30 +#define OMAP4_USBB2_DR0_LB_MASK (1 << 30) +#define OMAP4_USBA0_DR0_LB_SHIFT 29 +#define OMAP4_USBA0_DR0_LB_MASK (1 << 29) + +/* CONTROL_SMART3IO_PADCONF_0 */ +#define OMAP4_DMIC_DR0_MB_SHIFT 30 +#define OMAP4_DMIC_DR0_MB_MASK (0x3 << 30) +#define OMAP4_GPIO_DR3_MB_SHIFT 28 +#define OMAP4_GPIO_DR3_MB_MASK (0x3 << 28) +#define OMAP4_GPIO_DR4_MB_SHIFT 26 +#define OMAP4_GPIO_DR4_MB_MASK (0x3 << 26) +#define OMAP4_GPIO_DR5_MB_SHIFT 24 +#define OMAP4_GPIO_DR5_MB_MASK (0x3 << 24) +#define OMAP4_GPIO_DR6_MB_SHIFT 22 +#define OMAP4_GPIO_DR6_MB_MASK (0x3 << 22) +#define OMAP4_HSI_DR1_MB_SHIFT 20 +#define OMAP4_HSI_DR1_MB_MASK (0x3 << 20) +#define OMAP4_HSI_DR2_MB_SHIFT 18 +#define OMAP4_HSI_DR2_MB_MASK (0x3 << 18) +#define OMAP4_HSI_DR3_MB_SHIFT 16 +#define OMAP4_HSI_DR3_MB_MASK (0x3 << 16) +#define OMAP4_MCBSP2_DR0_MB_SHIFT 14 +#define OMAP4_MCBSP2_DR0_MB_MASK (0x3 << 14) +#define OMAP4_MCSPI4_DR0_MB_SHIFT 12 +#define OMAP4_MCSPI4_DR0_MB_MASK (0x3 << 12) +#define OMAP4_MCSPI4_DR1_MB_SHIFT 10 +#define OMAP4_MCSPI4_DR1_MB_MASK (0x3 << 10) +#define OMAP4_SDMMC3_DR0_MB_SHIFT 8 +#define OMAP4_SDMMC3_DR0_MB_MASK (0x3 << 8) +#define OMAP4_SPI2_DR0_MB_SHIFT 0 +#define OMAP4_SPI2_DR0_MB_MASK (0x3 << 0) + +/* CONTROL_SMART3IO_PADCONF_1 */ +#define OMAP4_SPI2_DR1_MB_SHIFT 30 +#define OMAP4_SPI2_DR1_MB_MASK (0x3 << 30) +#define OMAP4_SPI2_DR2_MB_SHIFT 28 +#define OMAP4_SPI2_DR2_MB_MASK (0x3 << 28) +#define OMAP4_UART2_DR0_MB_SHIFT 26 +#define OMAP4_UART2_DR0_MB_MASK (0x3 << 26) +#define OMAP4_UART2_DR1_MB_SHIFT 24 +#define OMAP4_UART2_DR1_MB_MASK (0x3 << 24) +#define OMAP4_UART4_DR0_MB_SHIFT 22 +#define OMAP4_UART4_DR0_MB_MASK (0x3 << 22) +#define OMAP4_HSI_DR0_MB_SHIFT 20 +#define OMAP4_HSI_DR0_MB_MASK (0x3 << 20) + +/* CONTROL_SMART3IO_PADCONF_2 */ +#define OMAP4_DMIC_DR0_LB_SHIFT 31 +#define OMAP4_DMIC_DR0_LB_MASK (1 << 31) +#define OMAP4_GPIO_DR3_LB_SHIFT 30 +#define OMAP4_GPIO_DR3_LB_MASK (1 << 30) +#define OMAP4_GPIO_DR4_LB_SHIFT 29 +#define OMAP4_GPIO_DR4_LB_MASK (1 << 29) +#define OMAP4_GPIO_DR5_LB_SHIFT 28 +#define OMAP4_GPIO_DR5_LB_MASK (1 << 28) +#define OMAP4_GPIO_DR6_LB_SHIFT 27 +#define OMAP4_GPIO_DR6_LB_MASK (1 << 27) +#define OMAP4_HSI_DR1_LB_SHIFT 26 +#define OMAP4_HSI_DR1_LB_MASK (1 << 26) +#define OMAP4_HSI_DR2_LB_SHIFT 25 +#define OMAP4_HSI_DR2_LB_MASK (1 << 25) +#define OMAP4_HSI_DR3_LB_SHIFT 24 +#define OMAP4_HSI_DR3_LB_MASK (1 << 24) +#define OMAP4_MCBSP2_DR0_LB_SHIFT 23 +#define OMAP4_MCBSP2_DR0_LB_MASK (1 << 23) +#define OMAP4_MCSPI4_DR0_LB_SHIFT 22 +#define OMAP4_MCSPI4_DR0_LB_MASK (1 << 22) +#define OMAP4_MCSPI4_DR1_LB_SHIFT 21 +#define OMAP4_MCSPI4_DR1_LB_MASK (1 << 21) +#define OMAP4_SLIMBUS2_DR0_LB_SHIFT 18 +#define OMAP4_SLIMBUS2_DR0_LB_MASK (1 << 18) +#define OMAP4_SPI2_DR0_LB_SHIFT 16 +#define OMAP4_SPI2_DR0_LB_MASK (1 << 16) +#define OMAP4_SPI2_DR1_LB_SHIFT 15 +#define OMAP4_SPI2_DR1_LB_MASK (1 << 15) +#define OMAP4_SPI2_DR2_LB_SHIFT 14 +#define OMAP4_SPI2_DR2_LB_MASK (1 << 14) +#define OMAP4_UART2_DR0_LB_SHIFT 13 +#define OMAP4_UART2_DR0_LB_MASK (1 << 13) +#define OMAP4_UART2_DR1_LB_SHIFT 12 +#define OMAP4_UART2_DR1_LB_MASK (1 << 12) +#define OMAP4_UART4_DR0_LB_SHIFT 11 +#define OMAP4_UART4_DR0_LB_MASK (1 << 11) +#define OMAP4_HSI_DR0_LB_SHIFT 10 +#define OMAP4_HSI_DR0_LB_MASK (1 << 10) + +/* CONTROL_USBB_HSIC */ +#define OMAP4_USBB2_DR1_SR_SHIFT 30 +#define OMAP4_USBB2_DR1_SR_MASK (0x3 << 30) +#define OMAP4_USBB2_DR1_I_SHIFT 27 +#define OMAP4_USBB2_DR1_I_MASK (0x7 << 27) +#define OMAP4_USBB1_DR1_SR_SHIFT 25 +#define OMAP4_USBB1_DR1_SR_MASK (0x3 << 25) +#define OMAP4_USBB1_DR1_I_SHIFT 22 +#define OMAP4_USBB1_DR1_I_MASK (0x7 << 22) +#define OMAP4_USBB1_HSIC_DATA_WD_SHIFT 20 +#define OMAP4_USBB1_HSIC_DATA_WD_MASK (0x3 << 20) +#define OMAP4_USBB1_HSIC_STROBE_WD_SHIFT 18 +#define OMAP4_USBB1_HSIC_STROBE_WD_MASK (0x3 << 18) +#define OMAP4_USBB2_HSIC_DATA_WD_SHIFT 16 +#define OMAP4_USBB2_HSIC_DATA_WD_MASK (0x3 << 16) +#define OMAP4_USBB2_HSIC_STROBE_WD_SHIFT 14 +#define OMAP4_USBB2_HSIC_STROBE_WD_MASK (0x3 << 14) +#define OMAP4_USBB1_HSIC_DATA_OFFMODE_WD_ENABLE_SHIFT 13 +#define OMAP4_USBB1_HSIC_DATA_OFFMODE_WD_ENABLE_MASK (1 << 13) +#define OMAP4_USBB1_HSIC_DATA_OFFMODE_WD_SHIFT 11 +#define OMAP4_USBB1_HSIC_DATA_OFFMODE_WD_MASK (0x3 << 11) +#define OMAP4_USBB1_HSIC_STROBE_OFFMODE_WD_ENABLE_SHIFT 10 +#define OMAP4_USBB1_HSIC_STROBE_OFFMODE_WD_ENABLE_MASK (1 << 10) +#define OMAP4_USBB1_HSIC_STROBE_OFFMODE_WD_SHIFT 8 +#define OMAP4_USBB1_HSIC_STROBE_OFFMODE_WD_MASK (0x3 << 8) +#define OMAP4_USBB2_HSIC_DATA_OFFMODE_WD_ENABLE_SHIFT 7 +#define OMAP4_USBB2_HSIC_DATA_OFFMODE_WD_ENABLE_MASK (1 << 7) +#define OMAP4_USBB2_HSIC_DATA_OFFMODE_WD_SHIFT 5 +#define OMAP4_USBB2_HSIC_DATA_OFFMODE_WD_MASK (0x3 << 5) +#define OMAP4_USBB2_HSIC_STROBE_OFFMODE_WD_ENABLE_SHIFT 4 +#define OMAP4_USBB2_HSIC_STROBE_OFFMODE_WD_ENABLE_MASK (1 << 4) +#define OMAP4_USBB2_HSIC_STROBE_OFFMODE_WD_SHIFT 2 +#define OMAP4_USBB2_HSIC_STROBE_OFFMODE_WD_MASK (0x3 << 2) + +/* CONTROL_SLIMBUS */ +#define OMAP4_SLIMBUS1_DR0_MB_SHIFT 30 +#define OMAP4_SLIMBUS1_DR0_MB_MASK (0x3 << 30) +#define OMAP4_SLIMBUS1_DR1_MB_SHIFT 28 +#define OMAP4_SLIMBUS1_DR1_MB_MASK (0x3 << 28) +#define OMAP4_SLIMBUS2_DR0_MB_SHIFT 26 +#define OMAP4_SLIMBUS2_DR0_MB_MASK (0x3 << 26) +#define OMAP4_SLIMBUS2_DR1_MB_SHIFT 24 +#define OMAP4_SLIMBUS2_DR1_MB_MASK (0x3 << 24) +#define OMAP4_SLIMBUS2_DR2_MB_SHIFT 22 +#define OMAP4_SLIMBUS2_DR2_MB_MASK (0x3 << 22) +#define OMAP4_SLIMBUS2_DR3_MB_SHIFT 20 +#define OMAP4_SLIMBUS2_DR3_MB_MASK (0x3 << 20) +#define OMAP4_SLIMBUS1_DR0_LB_SHIFT 19 +#define OMAP4_SLIMBUS1_DR0_LB_MASK (1 << 19) +#define OMAP4_SLIMBUS2_DR1_LB_SHIFT 18 +#define OMAP4_SLIMBUS2_DR1_LB_MASK (1 << 18) + +/* CONTROL_PBIASLITE */ +#define OMAP4_USIM_PBIASLITE_HIZ_MODE_SHIFT 31 +#define OMAP4_USIM_PBIASLITE_HIZ_MODE_MASK (1 << 31) +#define OMAP4_USIM_PBIASLITE_SUPPLY_HI_OUT_SHIFT 30 +#define OMAP4_USIM_PBIASLITE_SUPPLY_HI_OUT_MASK (1 << 30) +#define OMAP4_USIM_PBIASLITE_VMODE_ERROR_SHIFT 29 +#define OMAP4_USIM_PBIASLITE_VMODE_ERROR_MASK (1 << 29) +#define OMAP4_USIM_PBIASLITE_PWRDNZ_SHIFT 28 +#define OMAP4_USIM_PBIASLITE_PWRDNZ_MASK (1 << 28) +#define OMAP4_USIM_PBIASLITE_VMODE_SHIFT 27 +#define OMAP4_USIM_PBIASLITE_VMODE_MASK (1 << 27) +#define OMAP4_MMC1_PWRDNZ_SHIFT 26 +#define OMAP4_MMC1_PWRDNZ_MASK (1 << 26) +#define OMAP4_MMC1_PBIASLITE_HIZ_MODE_SHIFT 25 +#define OMAP4_MMC1_PBIASLITE_HIZ_MODE_MASK (1 << 25) +#define OMAP4_MMC1_PBIASLITE_SUPPLY_HI_OUT_SHIFT 24 +#define OMAP4_MMC1_PBIASLITE_SUPPLY_HI_OUT_MASK (1 << 24) +#define OMAP4_MMC1_PBIASLITE_VMODE_ERROR_SHIFT 23 +#define OMAP4_MMC1_PBIASLITE_VMODE_ERROR_MASK (1 << 23) +#define OMAP4_MMC1_PBIASLITE_PWRDNZ_SHIFT 22 +#define OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK (1 << 22) +#define OMAP4_MMC1_PBIASLITE_VMODE_SHIFT 21 +#define OMAP4_MMC1_PBIASLITE_VMODE_MASK (1 << 21) +#define OMAP4_USBC1_ICUSB_PWRDNZ_SHIFT 20 +#define OMAP4_USBC1_ICUSB_PWRDNZ_MASK (1 << 20) + +/* CONTROL_I2C_0 */ +#define OMAP4_I2C4_SDA_GLFENB_SHIFT 31 +#define OMAP4_I2C4_SDA_GLFENB_MASK (1 << 31) +#define OMAP4_I2C4_SDA_LOAD_BITS_SHIFT 29 +#define OMAP4_I2C4_SDA_LOAD_BITS_MASK (0x3 << 29) +#define OMAP4_I2C4_SDA_PULLUPRESX_SHIFT 28 +#define OMAP4_I2C4_SDA_PULLUPRESX_MASK (1 << 28) +#define OMAP4_I2C3_SDA_GLFENB_SHIFT 27 +#define OMAP4_I2C3_SDA_GLFENB_MASK (1 << 27) +#define OMAP4_I2C3_SDA_LOAD_BITS_SHIFT 25 +#define OMAP4_I2C3_SDA_LOAD_BITS_MASK (0x3 << 25) +#define OMAP4_I2C3_SDA_PULLUPRESX_SHIFT 24 +#define OMAP4_I2C3_SDA_PULLUPRESX_MASK (1 << 24) +#define OMAP4_I2C2_SDA_GLFENB_SHIFT 23 +#define OMAP4_I2C2_SDA_GLFENB_MASK (1 << 23) +#define OMAP4_I2C2_SDA_LOAD_BITS_SHIFT 21 +#define OMAP4_I2C2_SDA_LOAD_BITS_MASK (0x3 << 21) +#define OMAP4_I2C2_SDA_PULLUPRESX_SHIFT 20 +#define OMAP4_I2C2_SDA_PULLUPRESX_MASK (1 << 20) +#define OMAP4_I2C1_SDA_GLFENB_SHIFT 19 +#define OMAP4_I2C1_SDA_GLFENB_MASK (1 << 19) +#define OMAP4_I2C1_SDA_LOAD_BITS_SHIFT 17 +#define OMAP4_I2C1_SDA_LOAD_BITS_MASK (0x3 << 17) +#define OMAP4_I2C1_SDA_PULLUPRESX_SHIFT 16 +#define OMAP4_I2C1_SDA_PULLUPRESX_MASK (1 << 16) +#define OMAP4_I2C4_SCL_GLFENB_SHIFT 15 +#define OMAP4_I2C4_SCL_GLFENB_MASK (1 << 15) +#define OMAP4_I2C4_SCL_LOAD_BITS_SHIFT 13 +#define OMAP4_I2C4_SCL_LOAD_BITS_MASK (0x3 << 13) +#define OMAP4_I2C4_SCL_PULLUPRESX_SHIFT 12 +#define OMAP4_I2C4_SCL_PULLUPRESX_MASK (1 << 12) +#define OMAP4_I2C3_SCL_GLFENB_SHIFT 11 +#define OMAP4_I2C3_SCL_GLFENB_MASK (1 << 11) +#define OMAP4_I2C3_SCL_LOAD_BITS_SHIFT 9 +#define OMAP4_I2C3_SCL_LOAD_BITS_MASK (0x3 << 9) +#define OMAP4_I2C3_SCL_PULLUPRESX_SHIFT 8 +#define OMAP4_I2C3_SCL_PULLUPRESX_MASK (1 << 8) +#define OMAP4_I2C2_SCL_GLFENB_SHIFT 7 +#define OMAP4_I2C2_SCL_GLFENB_MASK (1 << 7) +#define OMAP4_I2C2_SCL_LOAD_BITS_SHIFT 5 +#define OMAP4_I2C2_SCL_LOAD_BITS_MASK (0x3 << 5) +#define OMAP4_I2C2_SCL_PULLUPRESX_SHIFT 4 +#define OMAP4_I2C2_SCL_PULLUPRESX_MASK (1 << 4) +#define OMAP4_I2C1_SCL_GLFENB_SHIFT 3 +#define OMAP4_I2C1_SCL_GLFENB_MASK (1 << 3) +#define OMAP4_I2C1_SCL_LOAD_BITS_SHIFT 1 +#define OMAP4_I2C1_SCL_LOAD_BITS_MASK (0x3 << 1) +#define OMAP4_I2C1_SCL_PULLUPRESX_SHIFT 0 +#define OMAP4_I2C1_SCL_PULLUPRESX_MASK (1 << 0) + +/* CONTROL_CAMERA_RX */ +#define OMAP4_CAMERARX_UNIPRO_CTRLCLKEN_SHIFT 31 +#define OMAP4_CAMERARX_UNIPRO_CTRLCLKEN_MASK (1 << 31) +#define OMAP4_CAMERARX_CSI22_LANEENABLE_SHIFT 29 +#define OMAP4_CAMERARX_CSI22_LANEENABLE_MASK (0x3 << 29) +#define OMAP4_CAMERARX_CSI21_LANEENABLE_SHIFT 24 +#define OMAP4_CAMERARX_CSI21_LANEENABLE_MASK (0x1f << 24) +#define OMAP4_CAMERARX_UNIPRO_CAMMODE_SHIFT 22 +#define OMAP4_CAMERARX_UNIPRO_CAMMODE_MASK (0x3 << 22) +#define OMAP4_CAMERARX_CSI22_CTRLCLKEN_SHIFT 21 +#define OMAP4_CAMERARX_CSI22_CTRLCLKEN_MASK (1 << 21) +#define OMAP4_CAMERARX_CSI22_CAMMODE_SHIFT 19 +#define OMAP4_CAMERARX_CSI22_CAMMODE_MASK (0x3 << 19) +#define OMAP4_CAMERARX_CSI21_CTRLCLKEN_SHIFT 18 +#define OMAP4_CAMERARX_CSI21_CTRLCLKEN_MASK (1 << 18) +#define OMAP4_CAMERARX_CSI21_CAMMODE_SHIFT 16 +#define OMAP4_CAMERARX_CSI21_CAMMODE_MASK (0x3 << 16) + +/* CONTROL_AVDAC */ +#define OMAP4_AVDAC_ACEN_SHIFT 31 +#define OMAP4_AVDAC_ACEN_MASK (1 << 31) +#define OMAP4_AVDAC_TVOUTBYPASS_SHIFT 30 +#define OMAP4_AVDAC_TVOUTBYPASS_MASK (1 << 30) +#define OMAP4_AVDAC_INPUTINV_SHIFT 29 +#define OMAP4_AVDAC_INPUTINV_MASK (1 << 29) +#define OMAP4_AVDAC_CTL_SHIFT 13 +#define OMAP4_AVDAC_CTL_MASK (0xffff << 13) +#define OMAP4_AVDAC_CTL_WR_ACK_SHIFT 12 +#define OMAP4_AVDAC_CTL_WR_ACK_MASK (1 << 12) + +/* CONTROL_HDMI_TX_PHY */ +#define OMAP4_HDMITXPHY_PADORDER_SHIFT 31 +#define OMAP4_HDMITXPHY_PADORDER_MASK (1 << 31) +#define OMAP4_HDMITXPHY_TXVALID_SHIFT 30 +#define OMAP4_HDMITXPHY_TXVALID_MASK (1 << 30) +#define OMAP4_HDMITXPHY_ENBYPASSCLK_SHIFT 29 +#define OMAP4_HDMITXPHY_ENBYPASSCLK_MASK (1 << 29) +#define OMAP4_HDMITXPHY_PD_PULLUPDET_SHIFT 28 +#define OMAP4_HDMITXPHY_PD_PULLUPDET_MASK (1 << 28) + +/* CONTROL_MMC2 */ +#define OMAP4_MMC2_FEEDBACK_CLK_SEL_SHIFT 31 +#define OMAP4_MMC2_FEEDBACK_CLK_SEL_MASK (1 << 31) + +/* CONTROL_DSIPHY */ +#define OMAP4_DSI2_LANEENABLE_SHIFT 29 +#define OMAP4_DSI2_LANEENABLE_MASK (0x7 << 29) +#define OMAP4_DSI1_LANEENABLE_SHIFT 24 +#define OMAP4_DSI1_LANEENABLE_MASK (0x1f << 24) +#define OMAP4_DSI1_PIPD_SHIFT 19 +#define OMAP4_DSI1_PIPD_MASK (0x1f << 19) +#define OMAP4_DSI2_PIPD_SHIFT 14 +#define OMAP4_DSI2_PIPD_MASK (0x1f << 14) + +/* CONTROL_MCBSPLP */ +#define OMAP4_ALBCTRLRX_FSX_SHIFT 31 +#define OMAP4_ALBCTRLRX_FSX_MASK (1 << 31) +#define OMAP4_ALBCTRLRX_CLKX_SHIFT 30 +#define OMAP4_ALBCTRLRX_CLKX_MASK (1 << 30) +#define OMAP4_ABE_MCBSP1_DR_EN_SHIFT 29 +#define OMAP4_ABE_MCBSP1_DR_EN_MASK (1 << 29) + +/* CONTROL_USB2PHYCORE */ +#define OMAP4_USB2PHY_AUTORESUME_EN_SHIFT 31 +#define OMAP4_USB2PHY_AUTORESUME_EN_MASK (1 << 31) +#define OMAP4_USB2PHY_DISCHGDET_SHIFT 30 +#define OMAP4_USB2PHY_DISCHGDET_MASK (1 << 30) +#define OMAP4_USB2PHY_GPIOMODE_SHIFT 29 +#define OMAP4_USB2PHY_GPIOMODE_MASK (1 << 29) +#define OMAP4_USB2PHY_CHG_DET_EXT_CTL_SHIFT 28 +#define OMAP4_USB2PHY_CHG_DET_EXT_CTL_MASK (1 << 28) +#define OMAP4_USB2PHY_RDM_PD_CHGDET_EN_SHIFT 27 +#define OMAP4_USB2PHY_RDM_PD_CHGDET_EN_MASK (1 << 27) +#define OMAP4_USB2PHY_RDP_PU_CHGDET_EN_SHIFT 26 +#define OMAP4_USB2PHY_RDP_PU_CHGDET_EN_MASK (1 << 26) +#define OMAP4_USB2PHY_CHG_VSRC_EN_SHIFT 25 +#define OMAP4_USB2PHY_CHG_VSRC_EN_MASK (1 << 25) +#define OMAP4_USB2PHY_CHG_ISINK_EN_SHIFT 24 +#define OMAP4_USB2PHY_CHG_ISINK_EN_MASK (1 << 24) +#define OMAP4_USB2PHY_CHG_DET_STATUS_SHIFT 21 +#define OMAP4_USB2PHY_CHG_DET_STATUS_MASK (0x7 << 21) +#define OMAP4_USB2PHY_CHG_DET_DM_COMP_SHIFT 20 +#define OMAP4_USB2PHY_CHG_DET_DM_COMP_MASK (1 << 20) +#define OMAP4_USB2PHY_CHG_DET_DP_COMP_SHIFT 19 +#define OMAP4_USB2PHY_CHG_DET_DP_COMP_MASK (1 << 19) +#define OMAP4_USB2PHY_DATADET_SHIFT 18 +#define OMAP4_USB2PHY_DATADET_MASK (1 << 18) +#define OMAP4_USB2PHY_SINKONDP_SHIFT 17 +#define OMAP4_USB2PHY_SINKONDP_MASK (1 << 17) +#define OMAP4_USB2PHY_SRCONDM_SHIFT 16 +#define OMAP4_USB2PHY_SRCONDM_MASK (1 << 16) +#define OMAP4_USB2PHY_RESTARTCHGDET_SHIFT 15 +#define OMAP4_USB2PHY_RESTARTCHGDET_MASK (1 << 15) +#define OMAP4_USB2PHY_CHGDETDONE_SHIFT 14 +#define OMAP4_USB2PHY_CHGDETDONE_MASK (1 << 14) +#define OMAP4_USB2PHY_CHGDETECTED_SHIFT 13 +#define OMAP4_USB2PHY_CHGDETECTED_MASK (1 << 13) +#define OMAP4_USB2PHY_MCPCPUEN_SHIFT 12 +#define OMAP4_USB2PHY_MCPCPUEN_MASK (1 << 12) +#define OMAP4_USB2PHY_MCPCMODEEN_SHIFT 11 +#define OMAP4_USB2PHY_MCPCMODEEN_MASK (1 << 11) +#define OMAP4_USB2PHY_RESETDONEMCLK_SHIFT 10 +#define OMAP4_USB2PHY_RESETDONEMCLK_MASK (1 << 10) +#define OMAP4_USB2PHY_UTMIRESETDONE_SHIFT 9 +#define OMAP4_USB2PHY_UTMIRESETDONE_MASK (1 << 9) +#define OMAP4_USB2PHY_TXBITSTUFFENABLE_SHIFT 8 +#define OMAP4_USB2PHY_TXBITSTUFFENABLE_MASK (1 << 8) +#define OMAP4_USB2PHY_DATAPOLARITYN_SHIFT 7 +#define OMAP4_USB2PHY_DATAPOLARITYN_MASK (1 << 7) +#define OMAP4_USBDPLL_FREQLOCK_SHIFT 6 +#define OMAP4_USBDPLL_FREQLOCK_MASK (1 << 6) +#define OMAP4_USB2PHY_RESETDONETCLK_SHIFT 5 +#define OMAP4_USB2PHY_RESETDONETCLK_MASK (1 << 5) + +/* CONTROL_I2C_1 */ +#define OMAP4_HDMI_DDC_SDA_GLFENB_SHIFT 31 +#define OMAP4_HDMI_DDC_SDA_GLFENB_MASK (1 << 31) +#define OMAP4_HDMI_DDC_SDA_LOAD_BITS_SHIFT 29 +#define OMAP4_HDMI_DDC_SDA_LOAD_BITS_MASK (0x3 << 29) +#define OMAP4_HDMI_DDC_SDA_PULLUPRESX_SHIFT 28 +#define OMAP4_HDMI_DDC_SDA_PULLUPRESX_MASK (1 << 28) +#define OMAP4_HDMI_DDC_SCL_GLFENB_SHIFT 27 +#define OMAP4_HDMI_DDC_SCL_GLFENB_MASK (1 << 27) +#define OMAP4_HDMI_DDC_SCL_LOAD_BITS_SHIFT 25 +#define OMAP4_HDMI_DDC_SCL_LOAD_BITS_MASK (0x3 << 25) +#define OMAP4_HDMI_DDC_SCL_PULLUPRESX_SHIFT 24 +#define OMAP4_HDMI_DDC_SCL_PULLUPRESX_MASK (1 << 24) +#define OMAP4_HDMI_DDC_SDA_HSMODE_SHIFT 23 +#define OMAP4_HDMI_DDC_SDA_HSMODE_MASK (1 << 23) +#define OMAP4_HDMI_DDC_SDA_NMODE_SHIFT 22 +#define OMAP4_HDMI_DDC_SDA_NMODE_MASK (1 << 22) +#define OMAP4_HDMI_DDC_SCL_HSMODE_SHIFT 21 +#define OMAP4_HDMI_DDC_SCL_HSMODE_MASK (1 << 21) +#define OMAP4_HDMI_DDC_SCL_NMODE_SHIFT 20 +#define OMAP4_HDMI_DDC_SCL_NMODE_MASK (1 << 20) + +/* CONTROL_MMC1 */ +#define OMAP4_SDMMC1_PUSTRENGTH_GRP0_SHIFT 31 +#define OMAP4_SDMMC1_PUSTRENGTH_GRP0_MASK (1 << 31) +#define OMAP4_SDMMC1_PUSTRENGTH_GRP1_SHIFT 30 +#define OMAP4_SDMMC1_PUSTRENGTH_GRP1_MASK (1 << 30) +#define OMAP4_SDMMC1_PUSTRENGTH_GRP2_SHIFT 29 +#define OMAP4_SDMMC1_PUSTRENGTH_GRP2_MASK (1 << 29) +#define OMAP4_SDMMC1_PUSTRENGTH_GRP3_SHIFT 28 +#define OMAP4_SDMMC1_PUSTRENGTH_GRP3_MASK (1 << 28) +#define OMAP4_SDMMC1_DR0_SPEEDCTRL_SHIFT 27 +#define OMAP4_SDMMC1_DR0_SPEEDCTRL_MASK (1 << 27) +#define OMAP4_SDMMC1_DR1_SPEEDCTRL_SHIFT 26 +#define OMAP4_SDMMC1_DR1_SPEEDCTRL_MASK (1 << 26) +#define OMAP4_SDMMC1_DR2_SPEEDCTRL_SHIFT 25 +#define OMAP4_SDMMC1_DR2_SPEEDCTRL_MASK (1 << 25) +#define OMAP4_USBC1_DR0_SPEEDCTRL_SHIFT 24 +#define OMAP4_USBC1_DR0_SPEEDCTRL_MASK (1 << 24) +#define OMAP4_USB_FD_CDEN_SHIFT 23 +#define OMAP4_USB_FD_CDEN_MASK (1 << 23) +#define OMAP4_USBC1_ICUSB_DP_PDDIS_SHIFT 22 +#define OMAP4_USBC1_ICUSB_DP_PDDIS_MASK (1 << 22) +#define OMAP4_USBC1_ICUSB_DM_PDDIS_SHIFT 21 +#define OMAP4_USBC1_ICUSB_DM_PDDIS_MASK (1 << 21) + +/* CONTROL_HSI */ +#define OMAP4_HSI1_CALLOOP_SEL_SHIFT 31 +#define OMAP4_HSI1_CALLOOP_SEL_MASK (1 << 31) +#define OMAP4_HSI1_CALMUX_SEL_SHIFT 30 +#define OMAP4_HSI1_CALMUX_SEL_MASK (1 << 30) +#define OMAP4_HSI2_CALLOOP_SEL_SHIFT 29 +#define OMAP4_HSI2_CALLOOP_SEL_MASK (1 << 29) +#define OMAP4_HSI2_CALMUX_SEL_SHIFT 28 +#define OMAP4_HSI2_CALMUX_SEL_MASK (1 << 28) + +/* CONTROL_USB */ +#define OMAP4_CARKIT_USBA0_ULPIPHY_DAT0_AUTO_EN_SHIFT 31 +#define OMAP4_CARKIT_USBA0_ULPIPHY_DAT0_AUTO_EN_MASK (1 << 31) +#define OMAP4_CARKIT_USBA0_ULPIPHY_DAT1_AUTO_EN_SHIFT 30 +#define OMAP4_CARKIT_USBA0_ULPIPHY_DAT1_AUTO_EN_MASK (1 << 30) + +/* CONTROL_HDQ */ +#define OMAP4_HDQ_SIO_PWRDNZ_SHIFT 31 +#define OMAP4_HDQ_SIO_PWRDNZ_MASK (1 << 31) + +/* CONTROL_LPDDR2IO1_0 */ +#define OMAP4_LPDDR2IO1_GR4_SR_SHIFT 30 +#define OMAP4_LPDDR2IO1_GR4_SR_MASK (0x3 << 30) +#define OMAP4_LPDDR2IO1_GR4_I_SHIFT 27 +#define OMAP4_LPDDR2IO1_GR4_I_MASK (0x7 << 27) +#define OMAP4_LPDDR2IO1_GR4_WD_SHIFT 25 +#define OMAP4_LPDDR2IO1_GR4_WD_MASK (0x3 << 25) +#define OMAP4_LPDDR2IO1_GR3_SR_SHIFT 22 +#define OMAP4_LPDDR2IO1_GR3_SR_MASK (0x3 << 22) +#define OMAP4_LPDDR2IO1_GR3_I_SHIFT 19 +#define OMAP4_LPDDR2IO1_GR3_I_MASK (0x7 << 19) +#define OMAP4_LPDDR2IO1_GR3_WD_SHIFT 17 +#define OMAP4_LPDDR2IO1_GR3_WD_MASK (0x3 << 17) +#define OMAP4_LPDDR2IO1_GR2_SR_SHIFT 14 +#define OMAP4_LPDDR2IO1_GR2_SR_MASK (0x3 << 14) +#define OMAP4_LPDDR2IO1_GR2_I_SHIFT 11 +#define OMAP4_LPDDR2IO1_GR2_I_MASK (0x7 << 11) +#define OMAP4_LPDDR2IO1_GR2_WD_SHIFT 9 +#define OMAP4_LPDDR2IO1_GR2_WD_MASK (0x3 << 9) +#define OMAP4_LPDDR2IO1_GR1_SR_SHIFT 6 +#define OMAP4_LPDDR2IO1_GR1_SR_MASK (0x3 << 6) +#define OMAP4_LPDDR2IO1_GR1_I_SHIFT 3 +#define OMAP4_LPDDR2IO1_GR1_I_MASK (0x7 << 3) +#define OMAP4_LPDDR2IO1_GR1_WD_SHIFT 1 +#define OMAP4_LPDDR2IO1_GR1_WD_MASK (0x3 << 1) + +/* CONTROL_LPDDR2IO1_1 */ +#define OMAP4_LPDDR2IO1_GR8_SR_SHIFT 30 +#define OMAP4_LPDDR2IO1_GR8_SR_MASK (0x3 << 30) +#define OMAP4_LPDDR2IO1_GR8_I_SHIFT 27 +#define OMAP4_LPDDR2IO1_GR8_I_MASK (0x7 << 27) +#define OMAP4_LPDDR2IO1_GR8_WD_SHIFT 25 +#define OMAP4_LPDDR2IO1_GR8_WD_MASK (0x3 << 25) +#define OMAP4_LPDDR2IO1_GR7_SR_SHIFT 22 +#define OMAP4_LPDDR2IO1_GR7_SR_MASK (0x3 << 22) +#define OMAP4_LPDDR2IO1_GR7_I_SHIFT 19 +#define OMAP4_LPDDR2IO1_GR7_I_MASK (0x7 << 19) +#define OMAP4_LPDDR2IO1_GR7_WD_SHIFT 17 +#define OMAP4_LPDDR2IO1_GR7_WD_MASK (0x3 << 17) +#define OMAP4_LPDDR2IO1_GR6_SR_SHIFT 14 +#define OMAP4_LPDDR2IO1_GR6_SR_MASK (0x3 << 14) +#define OMAP4_LPDDR2IO1_GR6_I_SHIFT 11 +#define OMAP4_LPDDR2IO1_GR6_I_MASK (0x7 << 11) +#define OMAP4_LPDDR2IO1_GR6_WD_SHIFT 9 +#define OMAP4_LPDDR2IO1_GR6_WD_MASK (0x3 << 9) +#define OMAP4_LPDDR2IO1_GR5_SR_SHIFT 6 +#define OMAP4_LPDDR2IO1_GR5_SR_MASK (0x3 << 6) +#define OMAP4_LPDDR2IO1_GR5_I_SHIFT 3 +#define OMAP4_LPDDR2IO1_GR5_I_MASK (0x7 << 3) +#define OMAP4_LPDDR2IO1_GR5_WD_SHIFT 1 +#define OMAP4_LPDDR2IO1_GR5_WD_MASK (0x3 << 1) + +/* CONTROL_LPDDR2IO1_2 */ +#define OMAP4_LPDDR2IO1_GR11_SR_SHIFT 30 +#define OMAP4_LPDDR2IO1_GR11_SR_MASK (0x3 << 30) +#define OMAP4_LPDDR2IO1_GR11_I_SHIFT 27 +#define OMAP4_LPDDR2IO1_GR11_I_MASK (0x7 << 27) +#define OMAP4_LPDDR2IO1_GR11_WD_SHIFT 25 +#define OMAP4_LPDDR2IO1_GR11_WD_MASK (0x3 << 25) +#define OMAP4_LPDDR2IO1_GR10_SR_SHIFT 22 +#define OMAP4_LPDDR2IO1_GR10_SR_MASK (0x3 << 22) +#define OMAP4_LPDDR2IO1_GR10_I_SHIFT 19 +#define OMAP4_LPDDR2IO1_GR10_I_MASK (0x7 << 19) +#define OMAP4_LPDDR2IO1_GR10_WD_SHIFT 17 +#define OMAP4_LPDDR2IO1_GR10_WD_MASK (0x3 << 17) +#define OMAP4_LPDDR2IO1_GR9_SR_SHIFT 14 +#define OMAP4_LPDDR2IO1_GR9_SR_MASK (0x3 << 14) +#define OMAP4_LPDDR2IO1_GR9_I_SHIFT 11 +#define OMAP4_LPDDR2IO1_GR9_I_MASK (0x7 << 11) +#define OMAP4_LPDDR2IO1_GR9_WD_SHIFT 9 +#define OMAP4_LPDDR2IO1_GR9_WD_MASK (0x3 << 9) + +/* CONTROL_LPDDR2IO1_3 */ +#define OMAP4_LPDDR21_VREF_CA_CCAP0_SHIFT 31 +#define OMAP4_LPDDR21_VREF_CA_CCAP0_MASK (1 << 31) +#define OMAP4_LPDDR21_VREF_CA_CCAP1_SHIFT 30 +#define OMAP4_LPDDR21_VREF_CA_CCAP1_MASK (1 << 30) +#define OMAP4_LPDDR21_VREF_CA_INT_CCAP0_SHIFT 29 +#define OMAP4_LPDDR21_VREF_CA_INT_CCAP0_MASK (1 << 29) +#define OMAP4_LPDDR21_VREF_CA_INT_CCAP1_SHIFT 28 +#define OMAP4_LPDDR21_VREF_CA_INT_CCAP1_MASK (1 << 28) +#define OMAP4_LPDDR21_VREF_CA_INT_TAP0_SHIFT 27 +#define OMAP4_LPDDR21_VREF_CA_INT_TAP0_MASK (1 << 27) +#define OMAP4_LPDDR21_VREF_CA_INT_TAP1_SHIFT 26 +#define OMAP4_LPDDR21_VREF_CA_INT_TAP1_MASK (1 << 26) +#define OMAP4_LPDDR21_VREF_CA_TAP0_SHIFT 25 +#define OMAP4_LPDDR21_VREF_CA_TAP0_MASK (1 << 25) +#define OMAP4_LPDDR21_VREF_CA_TAP1_SHIFT 24 +#define OMAP4_LPDDR21_VREF_CA_TAP1_MASK (1 << 24) +#define OMAP4_LPDDR21_VREF_DQ0_INT_CCAP0_SHIFT 23 +#define OMAP4_LPDDR21_VREF_DQ0_INT_CCAP0_MASK (1 << 23) +#define OMAP4_LPDDR21_VREF_DQ0_INT_CCAP1_SHIFT 22 +#define OMAP4_LPDDR21_VREF_DQ0_INT_CCAP1_MASK (1 << 22) +#define OMAP4_LPDDR21_VREF_DQ0_INT_TAP0_SHIFT 21 +#define OMAP4_LPDDR21_VREF_DQ0_INT_TAP0_MASK (1 << 21) +#define OMAP4_LPDDR21_VREF_DQ0_INT_TAP1_SHIFT 20 +#define OMAP4_LPDDR21_VREF_DQ0_INT_TAP1_MASK (1 << 20) +#define OMAP4_LPDDR21_VREF_DQ1_INT_CCAP0_SHIFT 19 +#define OMAP4_LPDDR21_VREF_DQ1_INT_CCAP0_MASK (1 << 19) +#define OMAP4_LPDDR21_VREF_DQ1_INT_CCAP1_SHIFT 18 +#define OMAP4_LPDDR21_VREF_DQ1_INT_CCAP1_MASK (1 << 18) +#define OMAP4_LPDDR21_VREF_DQ1_INT_TAP0_SHIFT 17 +#define OMAP4_LPDDR21_VREF_DQ1_INT_TAP0_MASK (1 << 17) +#define OMAP4_LPDDR21_VREF_DQ1_INT_TAP1_SHIFT 16 +#define OMAP4_LPDDR21_VREF_DQ1_INT_TAP1_MASK (1 << 16) +#define OMAP4_LPDDR21_VREF_DQ_CCAP0_SHIFT 15 +#define OMAP4_LPDDR21_VREF_DQ_CCAP0_MASK (1 << 15) +#define OMAP4_LPDDR21_VREF_DQ_CCAP1_SHIFT 14 +#define OMAP4_LPDDR21_VREF_DQ_CCAP1_MASK (1 << 14) +#define OMAP4_LPDDR21_VREF_DQ_TAP0_SHIFT 13 +#define OMAP4_LPDDR21_VREF_DQ_TAP0_MASK (1 << 13) +#define OMAP4_LPDDR21_VREF_DQ_TAP1_SHIFT 12 +#define OMAP4_LPDDR21_VREF_DQ_TAP1_MASK (1 << 12) + +/* CONTROL_LPDDR2IO2_0 */ +#define OMAP4_LPDDR2IO2_GR4_SR_SHIFT 30 +#define OMAP4_LPDDR2IO2_GR4_SR_MASK (0x3 << 30) +#define OMAP4_LPDDR2IO2_GR4_I_SHIFT 27 +#define OMAP4_LPDDR2IO2_GR4_I_MASK (0x7 << 27) +#define OMAP4_LPDDR2IO2_GR4_WD_SHIFT 25 +#define OMAP4_LPDDR2IO2_GR4_WD_MASK (0x3 << 25) +#define OMAP4_LPDDR2IO2_GR3_SR_SHIFT 22 +#define OMAP4_LPDDR2IO2_GR3_SR_MASK (0x3 << 22) +#define OMAP4_LPDDR2IO2_GR3_I_SHIFT 19 +#define OMAP4_LPDDR2IO2_GR3_I_MASK (0x7 << 19) +#define OMAP4_LPDDR2IO2_GR3_WD_SHIFT 17 +#define OMAP4_LPDDR2IO2_GR3_WD_MASK (0x3 << 17) +#define OMAP4_LPDDR2IO2_GR2_SR_SHIFT 14 +#define OMAP4_LPDDR2IO2_GR2_SR_MASK (0x3 << 14) +#define OMAP4_LPDDR2IO2_GR2_I_SHIFT 11 +#define OMAP4_LPDDR2IO2_GR2_I_MASK (0x7 << 11) +#define OMAP4_LPDDR2IO2_GR2_WD_SHIFT 9 +#define OMAP4_LPDDR2IO2_GR2_WD_MASK (0x3 << 9) +#define OMAP4_LPDDR2IO2_GR1_SR_SHIFT 6 +#define OMAP4_LPDDR2IO2_GR1_SR_MASK (0x3 << 6) +#define OMAP4_LPDDR2IO2_GR1_I_SHIFT 3 +#define OMAP4_LPDDR2IO2_GR1_I_MASK (0x7 << 3) +#define OMAP4_LPDDR2IO2_GR1_WD_SHIFT 1 +#define OMAP4_LPDDR2IO2_GR1_WD_MASK (0x3 << 1) + +/* CONTROL_LPDDR2IO2_1 */ +#define OMAP4_LPDDR2IO2_GR8_SR_SHIFT 30 +#define OMAP4_LPDDR2IO2_GR8_SR_MASK (0x3 << 30) +#define OMAP4_LPDDR2IO2_GR8_I_SHIFT 27 +#define OMAP4_LPDDR2IO2_GR8_I_MASK (0x7 << 27) +#define OMAP4_LPDDR2IO2_GR8_WD_SHIFT 25 +#define OMAP4_LPDDR2IO2_GR8_WD_MASK (0x3 << 25) +#define OMAP4_LPDDR2IO2_GR7_SR_SHIFT 22 +#define OMAP4_LPDDR2IO2_GR7_SR_MASK (0x3 << 22) +#define OMAP4_LPDDR2IO2_GR7_I_SHIFT 19 +#define OMAP4_LPDDR2IO2_GR7_I_MASK (0x7 << 19) +#define OMAP4_LPDDR2IO2_GR7_WD_SHIFT 17 +#define OMAP4_LPDDR2IO2_GR7_WD_MASK (0x3 << 17) +#define OMAP4_LPDDR2IO2_GR6_SR_SHIFT 14 +#define OMAP4_LPDDR2IO2_GR6_SR_MASK (0x3 << 14) +#define OMAP4_LPDDR2IO2_GR6_I_SHIFT 11 +#define OMAP4_LPDDR2IO2_GR6_I_MASK (0x7 << 11) +#define OMAP4_LPDDR2IO2_GR6_WD_SHIFT 9 +#define OMAP4_LPDDR2IO2_GR6_WD_MASK (0x3 << 9) +#define OMAP4_LPDDR2IO2_GR5_SR_SHIFT 6 +#define OMAP4_LPDDR2IO2_GR5_SR_MASK (0x3 << 6) +#define OMAP4_LPDDR2IO2_GR5_I_SHIFT 3 +#define OMAP4_LPDDR2IO2_GR5_I_MASK (0x7 << 3) +#define OMAP4_LPDDR2IO2_GR5_WD_SHIFT 1 +#define OMAP4_LPDDR2IO2_GR5_WD_MASK (0x3 << 1) + +/* CONTROL_LPDDR2IO2_2 */ +#define OMAP4_LPDDR2IO2_GR11_SR_SHIFT 30 +#define OMAP4_LPDDR2IO2_GR11_SR_MASK (0x3 << 30) +#define OMAP4_LPDDR2IO2_GR11_I_SHIFT 27 +#define OMAP4_LPDDR2IO2_GR11_I_MASK (0x7 << 27) +#define OMAP4_LPDDR2IO2_GR11_WD_SHIFT 25 +#define OMAP4_LPDDR2IO2_GR11_WD_MASK (0x3 << 25) +#define OMAP4_LPDDR2IO2_GR10_SR_SHIFT 22 +#define OMAP4_LPDDR2IO2_GR10_SR_MASK (0x3 << 22) +#define OMAP4_LPDDR2IO2_GR10_I_SHIFT 19 +#define OMAP4_LPDDR2IO2_GR10_I_MASK (0x7 << 19) +#define OMAP4_LPDDR2IO2_GR10_WD_SHIFT 17 +#define OMAP4_LPDDR2IO2_GR10_WD_MASK (0x3 << 17) +#define OMAP4_LPDDR2IO2_GR9_SR_SHIFT 14 +#define OMAP4_LPDDR2IO2_GR9_SR_MASK (0x3 << 14) +#define OMAP4_LPDDR2IO2_GR9_I_SHIFT 11 +#define OMAP4_LPDDR2IO2_GR9_I_MASK (0x7 << 11) +#define OMAP4_LPDDR2IO2_GR9_WD_SHIFT 9 +#define OMAP4_LPDDR2IO2_GR9_WD_MASK (0x3 << 9) + +/* CONTROL_LPDDR2IO2_3 */ +#define OMAP4_LPDDR22_VREF_CA_CCAP0_SHIFT 31 +#define OMAP4_LPDDR22_VREF_CA_CCAP0_MASK (1 << 31) +#define OMAP4_LPDDR22_VREF_CA_CCAP1_SHIFT 30 +#define OMAP4_LPDDR22_VREF_CA_CCAP1_MASK (1 << 30) +#define OMAP4_LPDDR22_VREF_CA_INT_CCAP0_SHIFT 29 +#define OMAP4_LPDDR22_VREF_CA_INT_CCAP0_MASK (1 << 29) +#define OMAP4_LPDDR22_VREF_CA_INT_CCAP1_SHIFT 28 +#define OMAP4_LPDDR22_VREF_CA_INT_CCAP1_MASK (1 << 28) +#define OMAP4_LPDDR22_VREF_CA_INT_TAP0_SHIFT 27 +#define OMAP4_LPDDR22_VREF_CA_INT_TAP0_MASK (1 << 27) +#define OMAP4_LPDDR22_VREF_CA_INT_TAP1_SHIFT 26 +#define OMAP4_LPDDR22_VREF_CA_INT_TAP1_MASK (1 << 26) +#define OMAP4_LPDDR22_VREF_CA_TAP0_SHIFT 25 +#define OMAP4_LPDDR22_VREF_CA_TAP0_MASK (1 << 25) +#define OMAP4_LPDDR22_VREF_CA_TAP1_SHIFT 24 +#define OMAP4_LPDDR22_VREF_CA_TAP1_MASK (1 << 24) +#define OMAP4_LPDDR22_VREF_DQ0_INT_CCAP0_SHIFT 23 +#define OMAP4_LPDDR22_VREF_DQ0_INT_CCAP0_MASK (1 << 23) +#define OMAP4_LPDDR22_VREF_DQ0_INT_CCAP1_SHIFT 22 +#define OMAP4_LPDDR22_VREF_DQ0_INT_CCAP1_MASK (1 << 22) +#define OMAP4_LPDDR22_VREF_DQ0_INT_TAP0_SHIFT 21 +#define OMAP4_LPDDR22_VREF_DQ0_INT_TAP0_MASK (1 << 21) +#define OMAP4_LPDDR22_VREF_DQ0_INT_TAP1_SHIFT 20 +#define OMAP4_LPDDR22_VREF_DQ0_INT_TAP1_MASK (1 << 20) +#define OMAP4_LPDDR22_VREF_DQ1_INT_CCAP0_SHIFT 19 +#define OMAP4_LPDDR22_VREF_DQ1_INT_CCAP0_MASK (1 << 19) +#define OMAP4_LPDDR22_VREF_DQ1_INT_CCAP1_SHIFT 18 +#define OMAP4_LPDDR22_VREF_DQ1_INT_CCAP1_MASK (1 << 18) +#define OMAP4_LPDDR22_VREF_DQ1_INT_TAP0_SHIFT 17 +#define OMAP4_LPDDR22_VREF_DQ1_INT_TAP0_MASK (1 << 17) +#define OMAP4_LPDDR22_VREF_DQ1_INT_TAP1_SHIFT 16 +#define OMAP4_LPDDR22_VREF_DQ1_INT_TAP1_MASK (1 << 16) +#define OMAP4_LPDDR22_VREF_DQ_CCAP0_SHIFT 15 +#define OMAP4_LPDDR22_VREF_DQ_CCAP0_MASK (1 << 15) +#define OMAP4_LPDDR22_VREF_DQ_CCAP1_SHIFT 14 +#define OMAP4_LPDDR22_VREF_DQ_CCAP1_MASK (1 << 14) +#define OMAP4_LPDDR22_VREF_DQ_TAP0_SHIFT 13 +#define OMAP4_LPDDR22_VREF_DQ_TAP0_MASK (1 << 13) +#define OMAP4_LPDDR22_VREF_DQ_TAP1_SHIFT 12 +#define OMAP4_LPDDR22_VREF_DQ_TAP1_MASK (1 << 12) + +/* CONTROL_BUS_HOLD */ +#define OMAP4_ABE_DMIC_DIN3_EN_SHIFT 31 +#define OMAP4_ABE_DMIC_DIN3_EN_MASK (1 << 31) +#define OMAP4_MCSPI1_CS3_EN_SHIFT 30 +#define OMAP4_MCSPI1_CS3_EN_MASK (1 << 30) + +/* CONTROL_C2C */ +#define OMAP4_MIRROR_MODE_EN_SHIFT 31 +#define OMAP4_MIRROR_MODE_EN_MASK (1 << 31) +#define OMAP4_C2C_SPARE_SHIFT 24 +#define OMAP4_C2C_SPARE_MASK (0x7f << 24) + +/* CORE_CONTROL_SPARE_RW */ +#define OMAP4_CORE_CONTROL_SPARE_RW_SHIFT 0 +#define OMAP4_CORE_CONTROL_SPARE_RW_MASK (0xffffffff << 0) + +/* CORE_CONTROL_SPARE_R */ +#define OMAP4_CORE_CONTROL_SPARE_R_SHIFT 0 +#define OMAP4_CORE_CONTROL_SPARE_R_MASK (0xffffffff << 0) + +/* CORE_CONTROL_SPARE_R_C0 */ +#define OMAP4_CORE_CONTROL_SPARE_R_C0_SHIFT 31 +#define OMAP4_CORE_CONTROL_SPARE_R_C0_MASK (1 << 31) +#define OMAP4_CORE_CONTROL_SPARE_R_C1_SHIFT 30 +#define OMAP4_CORE_CONTROL_SPARE_R_C1_MASK (1 << 30) +#define OMAP4_CORE_CONTROL_SPARE_R_C2_SHIFT 29 +#define OMAP4_CORE_CONTROL_SPARE_R_C2_MASK (1 << 29) +#define OMAP4_CORE_CONTROL_SPARE_R_C3_SHIFT 28 +#define OMAP4_CORE_CONTROL_SPARE_R_C3_MASK (1 << 28) +#define OMAP4_CORE_CONTROL_SPARE_R_C4_SHIFT 27 +#define OMAP4_CORE_CONTROL_SPARE_R_C4_MASK (1 << 27) +#define OMAP4_CORE_CONTROL_SPARE_R_C5_SHIFT 26 +#define OMAP4_CORE_CONTROL_SPARE_R_C5_MASK (1 << 26) +#define OMAP4_CORE_CONTROL_SPARE_R_C6_SHIFT 25 +#define OMAP4_CORE_CONTROL_SPARE_R_C6_MASK (1 << 25) +#define OMAP4_CORE_CONTROL_SPARE_R_C7_SHIFT 24 +#define OMAP4_CORE_CONTROL_SPARE_R_C7_MASK (1 << 24) + +/* CONTROL_EFUSE_1 */ +#define OMAP4_AVDAC_TRIM_BYTE3_SHIFT 24 +#define OMAP4_AVDAC_TRIM_BYTE3_MASK (0x7f << 24) +#define OMAP4_AVDAC_TRIM_BYTE2_SHIFT 16 +#define OMAP4_AVDAC_TRIM_BYTE2_MASK (0xff << 16) +#define OMAP4_AVDAC_TRIM_BYTE1_SHIFT 8 +#define OMAP4_AVDAC_TRIM_BYTE1_MASK (0xff << 8) +#define OMAP4_AVDAC_TRIM_BYTE0_SHIFT 0 +#define OMAP4_AVDAC_TRIM_BYTE0_MASK (0xff << 0) + +/* CONTROL_EFUSE_2 */ +#define OMAP4_EFUSE_SMART2TEST_P0_SHIFT 31 +#define OMAP4_EFUSE_SMART2TEST_P0_MASK (1 << 31) +#define OMAP4_EFUSE_SMART2TEST_P1_SHIFT 30 +#define OMAP4_EFUSE_SMART2TEST_P1_MASK (1 << 30) +#define OMAP4_EFUSE_SMART2TEST_P2_SHIFT 29 +#define OMAP4_EFUSE_SMART2TEST_P2_MASK (1 << 29) +#define OMAP4_EFUSE_SMART2TEST_P3_SHIFT 28 +#define OMAP4_EFUSE_SMART2TEST_P3_MASK (1 << 28) +#define OMAP4_EFUSE_SMART2TEST_N0_SHIFT 27 +#define OMAP4_EFUSE_SMART2TEST_N0_MASK (1 << 27) +#define OMAP4_EFUSE_SMART2TEST_N1_SHIFT 26 +#define OMAP4_EFUSE_SMART2TEST_N1_MASK (1 << 26) +#define OMAP4_EFUSE_SMART2TEST_N2_SHIFT 25 +#define OMAP4_EFUSE_SMART2TEST_N2_MASK (1 << 25) +#define OMAP4_EFUSE_SMART2TEST_N3_SHIFT 24 +#define OMAP4_EFUSE_SMART2TEST_N3_MASK (1 << 24) +#define OMAP4_LPDDR2_PTV_N1_SHIFT 23 +#define OMAP4_LPDDR2_PTV_N1_MASK (1 << 23) +#define OMAP4_LPDDR2_PTV_N2_SHIFT 22 +#define OMAP4_LPDDR2_PTV_N2_MASK (1 << 22) +#define OMAP4_LPDDR2_PTV_N3_SHIFT 21 +#define OMAP4_LPDDR2_PTV_N3_MASK (1 << 21) +#define OMAP4_LPDDR2_PTV_N4_SHIFT 20 +#define OMAP4_LPDDR2_PTV_N4_MASK (1 << 20) +#define OMAP4_LPDDR2_PTV_N5_SHIFT 19 +#define OMAP4_LPDDR2_PTV_N5_MASK (1 << 19) +#define OMAP4_LPDDR2_PTV_P1_SHIFT 18 +#define OMAP4_LPDDR2_PTV_P1_MASK (1 << 18) +#define OMAP4_LPDDR2_PTV_P2_SHIFT 17 +#define OMAP4_LPDDR2_PTV_P2_MASK (1 << 17) +#define OMAP4_LPDDR2_PTV_P3_SHIFT 16 +#define OMAP4_LPDDR2_PTV_P3_MASK (1 << 16) +#define OMAP4_LPDDR2_PTV_P4_SHIFT 15 +#define OMAP4_LPDDR2_PTV_P4_MASK (1 << 15) +#define OMAP4_LPDDR2_PTV_P5_SHIFT 14 +#define OMAP4_LPDDR2_PTV_P5_MASK (1 << 14) + +/* CONTROL_EFUSE_3 */ +#define OMAP4_STD_FUSE_SPARE_1_SHIFT 24 +#define OMAP4_STD_FUSE_SPARE_1_MASK (0xff << 24) +#define OMAP4_STD_FUSE_SPARE_2_SHIFT 16 +#define OMAP4_STD_FUSE_SPARE_2_MASK (0xff << 16) +#define OMAP4_STD_FUSE_SPARE_3_SHIFT 8 +#define OMAP4_STD_FUSE_SPARE_3_MASK (0xff << 8) +#define OMAP4_STD_FUSE_SPARE_4_SHIFT 0 +#define OMAP4_STD_FUSE_SPARE_4_MASK (0xff << 0) + +/* CONTROL_EFUSE_4 */ +#define OMAP4_STD_FUSE_SPARE_5_SHIFT 24 +#define OMAP4_STD_FUSE_SPARE_5_MASK (0xff << 24) +#define OMAP4_STD_FUSE_SPARE_6_SHIFT 16 +#define OMAP4_STD_FUSE_SPARE_6_MASK (0xff << 16) +#define OMAP4_STD_FUSE_SPARE_7_SHIFT 8 +#define OMAP4_STD_FUSE_SPARE_7_MASK (0xff << 8) +#define OMAP4_STD_FUSE_SPARE_8_SHIFT 0 +#define OMAP4_STD_FUSE_SPARE_8_MASK (0xff << 0) + +#endif diff --git a/arch/arm/mach-omap2/ctrl_module_pad_wkup_44xx.h b/arch/arm/mach-omap2/ctrl_module_pad_wkup_44xx.h new file mode 100644 index 00000000000..17c9b37042c --- /dev/null +++ b/arch/arm/mach-omap2/ctrl_module_pad_wkup_44xx.h @@ -0,0 +1,236 @@ +/* + * OMAP44xx CTRL_MODULE_PAD_WKUP registers and bitfields + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * + * Benoit Cousson (b-cousson@ti.com) + * Santosh Shilimkar (santosh.shilimkar@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_PAD_WKUP_44XX_H +#define __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_PAD_WKUP_44XX_H + + +/* Base address */ +#define OMAP4_CTRL_MODULE_PAD_WKUP 0x4a31e000 + +/* Registers offset */ +#define OMAP4_CTRL_MODULE_PAD_WKUP_IP_REVISION 0x0000 +#define OMAP4_CTRL_MODULE_PAD_WKUP_IP_HWINFO 0x0004 +#define OMAP4_CTRL_MODULE_PAD_WKUP_IP_SYSCONFIG 0x0010 +#define OMAP4_CTRL_MODULE_PAD_WKUP_PADCONF_WAKEUPEVENT_0 0x007c +#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_SMART1NOPMIO_PADCONF_0 0x05a0 +#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_SMART1NOPMIO_PADCONF_1 0x05a4 +#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_PADCONF_MODE 0x05a8 +#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_XTAL_OSCILLATOR 0x05ac +#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_USIMIO 0x0600 +#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_I2C_2 0x0604 +#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_JTAG 0x0608 +#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_SYS 0x060c +#define OMAP4_CTRL_MODULE_PAD_WKUP_WKUP_CONTROL_SPARE_RW 0x0614 +#define OMAP4_CTRL_MODULE_PAD_WKUP_WKUP_CONTROL_SPARE_R 0x0618 +#define OMAP4_CTRL_MODULE_PAD_WKUP_WKUP_CONTROL_SPARE_R_C0 0x061c + +/* Registers shifts and masks */ + +/* IP_REVISION */ +#define OMAP4_IP_REV_SCHEME_SHIFT 30 +#define OMAP4_IP_REV_SCHEME_MASK (0x3 << 30) +#define OMAP4_IP_REV_FUNC_SHIFT 16 +#define OMAP4_IP_REV_FUNC_MASK (0xfff << 16) +#define OMAP4_IP_REV_RTL_SHIFT 11 +#define OMAP4_IP_REV_RTL_MASK (0x1f << 11) +#define OMAP4_IP_REV_MAJOR_SHIFT 8 +#define OMAP4_IP_REV_MAJOR_MASK (0x7 << 8) +#define OMAP4_IP_REV_CUSTOM_SHIFT 6 +#define OMAP4_IP_REV_CUSTOM_MASK (0x3 << 6) +#define OMAP4_IP_REV_MINOR_SHIFT 0 +#define OMAP4_IP_REV_MINOR_MASK (0x3f << 0) + +/* IP_HWINFO */ +#define OMAP4_IP_HWINFO_SHIFT 0 +#define OMAP4_IP_HWINFO_MASK (0xffffffff << 0) + +/* IP_SYSCONFIG */ +#define OMAP4_IP_SYSCONFIG_IDLEMODE_SHIFT 2 +#define OMAP4_IP_SYSCONFIG_IDLEMODE_MASK (0x3 << 2) + +/* PADCONF_WAKEUPEVENT_0 */ +#define OMAP4_JTAG_TDO_DUPLICATEWAKEUPEVENT_SHIFT 24 +#define OMAP4_JTAG_TDO_DUPLICATEWAKEUPEVENT_MASK (1 << 24) +#define OMAP4_JTAG_TDI_DUPLICATEWAKEUPEVENT_SHIFT 23 +#define OMAP4_JTAG_TDI_DUPLICATEWAKEUPEVENT_MASK (1 << 23) +#define OMAP4_JTAG_TMS_TMSC_DUPLICATEWAKEUPEVENT_SHIFT 22 +#define OMAP4_JTAG_TMS_TMSC_DUPLICATEWAKEUPEVENT_MASK (1 << 22) +#define OMAP4_JTAG_RTCK_DUPLICATEWAKEUPEVENT_SHIFT 21 +#define OMAP4_JTAG_RTCK_DUPLICATEWAKEUPEVENT_MASK (1 << 21) +#define OMAP4_JTAG_TCK_DUPLICATEWAKEUPEVENT_SHIFT 20 +#define OMAP4_JTAG_TCK_DUPLICATEWAKEUPEVENT_MASK (1 << 20) +#define OMAP4_JTAG_NTRST_DUPLICATEWAKEUPEVENT_SHIFT 19 +#define OMAP4_JTAG_NTRST_DUPLICATEWAKEUPEVENT_MASK (1 << 19) +#define OMAP4_SYS_BOOT7_DUPLICATEWAKEUPEVENT_SHIFT 18 +#define OMAP4_SYS_BOOT7_DUPLICATEWAKEUPEVENT_MASK (1 << 18) +#define OMAP4_SYS_BOOT6_DUPLICATEWAKEUPEVENT_SHIFT 17 +#define OMAP4_SYS_BOOT6_DUPLICATEWAKEUPEVENT_MASK (1 << 17) +#define OMAP4_SYS_PWRON_RESET_OUT_DUPLICATEWAKEUPEVENT_SHIFT 16 +#define OMAP4_SYS_PWRON_RESET_OUT_DUPLICATEWAKEUPEVENT_MASK (1 << 16) +#define OMAP4_SYS_PWR_REQ_DUPLICATEWAKEUPEVENT_SHIFT 15 +#define OMAP4_SYS_PWR_REQ_DUPLICATEWAKEUPEVENT_MASK (1 << 15) +#define OMAP4_SYS_NRESWARM_DUPLICATEWAKEUPEVENT_SHIFT 14 +#define OMAP4_SYS_NRESWARM_DUPLICATEWAKEUPEVENT_MASK (1 << 14) +#define OMAP4_SYS_32K_DUPLICATEWAKEUPEVENT_SHIFT 13 +#define OMAP4_SYS_32K_DUPLICATEWAKEUPEVENT_MASK (1 << 13) +#define OMAP4_FREF_CLK4_OUT_DUPLICATEWAKEUPEVENT_SHIFT 12 +#define OMAP4_FREF_CLK4_OUT_DUPLICATEWAKEUPEVENT_MASK (1 << 12) +#define OMAP4_FREF_CLK4_REQ_DUPLICATEWAKEUPEVENT_SHIFT 11 +#define OMAP4_FREF_CLK4_REQ_DUPLICATEWAKEUPEVENT_MASK (1 << 11) +#define OMAP4_FREF_CLK3_OUT_DUPLICATEWAKEUPEVENT_SHIFT 10 +#define OMAP4_FREF_CLK3_OUT_DUPLICATEWAKEUPEVENT_MASK (1 << 10) +#define OMAP4_FREF_CLK3_REQ_DUPLICATEWAKEUPEVENT_SHIFT 9 +#define OMAP4_FREF_CLK3_REQ_DUPLICATEWAKEUPEVENT_MASK (1 << 9) +#define OMAP4_FREF_CLK0_OUT_DUPLICATEWAKEUPEVENT_SHIFT 8 +#define OMAP4_FREF_CLK0_OUT_DUPLICATEWAKEUPEVENT_MASK (1 << 8) +#define OMAP4_FREF_CLK_IOREQ_DUPLICATEWAKEUPEVENT_SHIFT 7 +#define OMAP4_FREF_CLK_IOREQ_DUPLICATEWAKEUPEVENT_MASK (1 << 7) +#define OMAP4_SR_SDA_DUPLICATEWAKEUPEVENT_SHIFT 6 +#define OMAP4_SR_SDA_DUPLICATEWAKEUPEVENT_MASK (1 << 6) +#define OMAP4_SR_SCL_DUPLICATEWAKEUPEVENT_SHIFT 5 +#define OMAP4_SR_SCL_DUPLICATEWAKEUPEVENT_MASK (1 << 5) +#define OMAP4_SIM_PWRCTRL_DUPLICATEWAKEUPEVENT_SHIFT 4 +#define OMAP4_SIM_PWRCTRL_DUPLICATEWAKEUPEVENT_MASK (1 << 4) +#define OMAP4_SIM_CD_DUPLICATEWAKEUPEVENT_SHIFT 3 +#define OMAP4_SIM_CD_DUPLICATEWAKEUPEVENT_MASK (1 << 3) +#define OMAP4_SIM_RESET_DUPLICATEWAKEUPEVENT_SHIFT 2 +#define OMAP4_SIM_RESET_DUPLICATEWAKEUPEVENT_MASK (1 << 2) +#define OMAP4_SIM_CLK_DUPLICATEWAKEUPEVENT_SHIFT 1 +#define OMAP4_SIM_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 1) +#define OMAP4_SIM_IO_DUPLICATEWAKEUPEVENT_SHIFT 0 +#define OMAP4_SIM_IO_DUPLICATEWAKEUPEVENT_MASK (1 << 0) + +/* CONTROL_SMART1NOPMIO_PADCONF_0 */ +#define OMAP4_FREF_DR0_SC_SHIFT 30 +#define OMAP4_FREF_DR0_SC_MASK (0x3 << 30) +#define OMAP4_FREF_DR1_SC_SHIFT 28 +#define OMAP4_FREF_DR1_SC_MASK (0x3 << 28) +#define OMAP4_FREF_DR4_SC_SHIFT 26 +#define OMAP4_FREF_DR4_SC_MASK (0x3 << 26) +#define OMAP4_FREF_DR5_SC_SHIFT 24 +#define OMAP4_FREF_DR5_SC_MASK (0x3 << 24) +#define OMAP4_FREF_DR6_SC_SHIFT 22 +#define OMAP4_FREF_DR6_SC_MASK (0x3 << 22) +#define OMAP4_FREF_DR7_SC_SHIFT 20 +#define OMAP4_FREF_DR7_SC_MASK (0x3 << 20) +#define OMAP4_GPIO_DR7_SC_SHIFT 18 +#define OMAP4_GPIO_DR7_SC_MASK (0x3 << 18) +#define OMAP4_DPM_DR0_SC_SHIFT 14 +#define OMAP4_DPM_DR0_SC_MASK (0x3 << 14) +#define OMAP4_SIM_DR0_SC_SHIFT 12 +#define OMAP4_SIM_DR0_SC_MASK (0x3 << 12) + +/* CONTROL_SMART1NOPMIO_PADCONF_1 */ +#define OMAP4_FREF_DR0_LB_SHIFT 30 +#define OMAP4_FREF_DR0_LB_MASK (0x3 << 30) +#define OMAP4_FREF_DR1_LB_SHIFT 28 +#define OMAP4_FREF_DR1_LB_MASK (0x3 << 28) +#define OMAP4_FREF_DR4_LB_SHIFT 26 +#define OMAP4_FREF_DR4_LB_MASK (0x3 << 26) +#define OMAP4_FREF_DR5_LB_SHIFT 24 +#define OMAP4_FREF_DR5_LB_MASK (0x3 << 24) +#define OMAP4_FREF_DR6_LB_SHIFT 22 +#define OMAP4_FREF_DR6_LB_MASK (0x3 << 22) +#define OMAP4_FREF_DR7_LB_SHIFT 20 +#define OMAP4_FREF_DR7_LB_MASK (0x3 << 20) +#define OMAP4_GPIO_DR7_LB_SHIFT 18 +#define OMAP4_GPIO_DR7_LB_MASK (0x3 << 18) +#define OMAP4_DPM_DR0_LB_SHIFT 14 +#define OMAP4_DPM_DR0_LB_MASK (0x3 << 14) +#define OMAP4_SIM_DR0_LB_SHIFT 12 +#define OMAP4_SIM_DR0_LB_MASK (0x3 << 12) + +/* CONTROL_PADCONF_MODE */ +#define OMAP4_VDDS_DV_FREF_SHIFT 31 +#define OMAP4_VDDS_DV_FREF_MASK (1 << 31) +#define OMAP4_VDDS_DV_BANK2_SHIFT 30 +#define OMAP4_VDDS_DV_BANK2_MASK (1 << 30) + +/* CONTROL_XTAL_OSCILLATOR */ +#define OMAP4_OSCILLATOR_BOOST_SHIFT 31 +#define OMAP4_OSCILLATOR_BOOST_MASK (1 << 31) +#define OMAP4_OSCILLATOR_OS_OUT_SHIFT 30 +#define OMAP4_OSCILLATOR_OS_OUT_MASK (1 << 30) + +/* CONTROL_USIMIO */ +#define OMAP4_PAD_USIM_CLK_LOW_SHIFT 31 +#define OMAP4_PAD_USIM_CLK_LOW_MASK (1 << 31) +#define OMAP4_PAD_USIM_RST_LOW_SHIFT 29 +#define OMAP4_PAD_USIM_RST_LOW_MASK (1 << 29) +#define OMAP4_USIM_PWRDNZ_SHIFT 28 +#define OMAP4_USIM_PWRDNZ_MASK (1 << 28) + +/* CONTROL_I2C_2 */ +#define OMAP4_SR_SDA_GLFENB_SHIFT 31 +#define OMAP4_SR_SDA_GLFENB_MASK (1 << 31) +#define OMAP4_SR_SDA_LOAD_BITS_SHIFT 29 +#define OMAP4_SR_SDA_LOAD_BITS_MASK (0x3 << 29) +#define OMAP4_SR_SDA_PULLUPRESX_SHIFT 28 +#define OMAP4_SR_SDA_PULLUPRESX_MASK (1 << 28) +#define OMAP4_SR_SCL_GLFENB_SHIFT 27 +#define OMAP4_SR_SCL_GLFENB_MASK (1 << 27) +#define OMAP4_SR_SCL_LOAD_BITS_SHIFT 25 +#define OMAP4_SR_SCL_LOAD_BITS_MASK (0x3 << 25) +#define OMAP4_SR_SCL_PULLUPRESX_SHIFT 24 +#define OMAP4_SR_SCL_PULLUPRESX_MASK (1 << 24) + +/* CONTROL_JTAG */ +#define OMAP4_JTAG_NTRST_EN_SHIFT 31 +#define OMAP4_JTAG_NTRST_EN_MASK (1 << 31) +#define OMAP4_JTAG_TCK_EN_SHIFT 30 +#define OMAP4_JTAG_TCK_EN_MASK (1 << 30) +#define OMAP4_JTAG_RTCK_EN_SHIFT 29 +#define OMAP4_JTAG_RTCK_EN_MASK (1 << 29) +#define OMAP4_JTAG_TDI_EN_SHIFT 28 +#define OMAP4_JTAG_TDI_EN_MASK (1 << 28) +#define OMAP4_JTAG_TDO_EN_SHIFT 27 +#define OMAP4_JTAG_TDO_EN_MASK (1 << 27) + +/* CONTROL_SYS */ +#define OMAP4_SYS_NRESWARM_PIPU_SHIFT 31 +#define OMAP4_SYS_NRESWARM_PIPU_MASK (1 << 31) + +/* WKUP_CONTROL_SPARE_RW */ +#define OMAP4_WKUP_CONTROL_SPARE_RW_SHIFT 0 +#define OMAP4_WKUP_CONTROL_SPARE_RW_MASK (0xffffffff << 0) + +/* WKUP_CONTROL_SPARE_R */ +#define OMAP4_WKUP_CONTROL_SPARE_R_SHIFT 0 +#define OMAP4_WKUP_CONTROL_SPARE_R_MASK (0xffffffff << 0) + +/* WKUP_CONTROL_SPARE_R_C0 */ +#define OMAP4_WKUP_CONTROL_SPARE_R_C0_SHIFT 31 +#define OMAP4_WKUP_CONTROL_SPARE_R_C0_MASK (1 << 31) +#define OMAP4_WKUP_CONTROL_SPARE_R_C1_SHIFT 30 +#define OMAP4_WKUP_CONTROL_SPARE_R_C1_MASK (1 << 30) +#define OMAP4_WKUP_CONTROL_SPARE_R_C2_SHIFT 29 +#define OMAP4_WKUP_CONTROL_SPARE_R_C2_MASK (1 << 29) +#define OMAP4_WKUP_CONTROL_SPARE_R_C3_SHIFT 28 +#define OMAP4_WKUP_CONTROL_SPARE_R_C3_MASK (1 << 28) +#define OMAP4_WKUP_CONTROL_SPARE_R_C4_SHIFT 27 +#define OMAP4_WKUP_CONTROL_SPARE_R_C4_MASK (1 << 27) +#define OMAP4_WKUP_CONTROL_SPARE_R_C5_SHIFT 26 +#define OMAP4_WKUP_CONTROL_SPARE_R_C5_MASK (1 << 26) +#define OMAP4_WKUP_CONTROL_SPARE_R_C6_SHIFT 25 +#define OMAP4_WKUP_CONTROL_SPARE_R_C6_MASK (1 << 25) +#define OMAP4_WKUP_CONTROL_SPARE_R_C7_SHIFT 24 +#define OMAP4_WKUP_CONTROL_SPARE_R_C7_MASK (1 << 24) + +#endif diff --git a/arch/arm/mach-omap2/ctrl_module_wkup_44xx.h b/arch/arm/mach-omap2/ctrl_module_wkup_44xx.h new file mode 100644 index 00000000000..a0af9baec3f --- /dev/null +++ b/arch/arm/mach-omap2/ctrl_module_wkup_44xx.h @@ -0,0 +1,92 @@ +/* + * OMAP44xx CTRL_MODULE_WKUP registers and bitfields + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * + * Benoit Cousson (b-cousson@ti.com) + * Santosh Shilimkar (santosh.shilimkar@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_WKUP_44XX_H +#define __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_WKUP_44XX_H + + +/* Base address */ +#define OMAP4_CTRL_MODULE_WKUP 0x4a30c000 + +/* Registers offset */ +#define OMAP4_CTRL_MODULE_WKUP_IP_REVISION 0x0000 +#define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO 0x0004 +#define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG 0x0010 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0 0x0460 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1 0x0464 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2 0x0468 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_3 0x046c +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_4 0x0470 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_5 0x0474 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_6 0x0478 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_7 0x047c +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_8 0x0480 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_9 0x0484 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_10 0x0488 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_11 0x048c +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_12 0x0490 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_13 0x0494 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_14 0x0498 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_15 0x049c +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_16 0x04a0 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_17 0x04a4 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_18 0x04a8 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_19 0x04ac +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_20 0x04b0 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_21 0x04b4 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_22 0x04b8 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_23 0x04bc +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_24 0x04c0 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_25 0x04c4 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_26 0x04c8 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_27 0x04cc +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_28 0x04d0 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_29 0x04d4 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_30 0x04d8 +#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_31 0x04dc + +/* Registers shifts and masks */ + +/* IP_REVISION */ +#define OMAP4_IP_REV_SCHEME_SHIFT 30 +#define OMAP4_IP_REV_SCHEME_MASK (0x3 << 30) +#define OMAP4_IP_REV_FUNC_SHIFT 16 +#define OMAP4_IP_REV_FUNC_MASK (0xfff << 16) +#define OMAP4_IP_REV_RTL_SHIFT 11 +#define OMAP4_IP_REV_RTL_MASK (0x1f << 11) +#define OMAP4_IP_REV_MAJOR_SHIFT 8 +#define OMAP4_IP_REV_MAJOR_MASK (0x7 << 8) +#define OMAP4_IP_REV_CUSTOM_SHIFT 6 +#define OMAP4_IP_REV_CUSTOM_MASK (0x3 << 6) +#define OMAP4_IP_REV_MINOR_SHIFT 0 +#define OMAP4_IP_REV_MINOR_MASK (0x3f << 0) + +/* IP_HWINFO */ +#define OMAP4_IP_HWINFO_SHIFT 0 +#define OMAP4_IP_HWINFO_MASK (0xffffffff << 0) + +/* IP_SYSCONFIG */ +#define OMAP4_IP_SYSCONFIG_IDLEMODE_SHIFT 2 +#define OMAP4_IP_SYSCONFIG_IDLEMODE_MASK (0x3 << 2) + +/* CONF_DEBUG_SEL_TST_0 */ +#define OMAP4_WKUP_MODE_SHIFT 0 +#define OMAP4_WKUP_MODE_MASK (1 << 0) + +#endif diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index ce03fa75077..b6f8f348296 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -8,510 +8,440 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ - -#include <linux/module.h> +#include <linux/gpio.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> #include <linux/io.h> #include <linux/clk.h> +#include <linux/err.h> +#include <linux/slab.h> +#include <linux/of.h> +#include <linux/pinctrl/machine.h> +#include <linux/platform_data/mailbox-omap.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/mach/map.h> -#include <mach/control.h> -#include <mach/tc.h> -#include <mach/board.h> -#include <mach/mux.h> -#include <mach/gpio.h> -#include <mach/eac.h> -#include <mach/mmc.h> +#include <linux/omap-dma.h> + +#include "iomap.h" +#include "omap_hwmod.h" +#include "omap_device.h" + +#include "soc.h" +#include "common.h" +#include "mux.h" +#include "control.h" +#include "devices.h" +#include "display.h" + +#define L3_MODULES_MAX_LEN 12 +#define L3_MODULES 3 + +static int __init omap3_l3_init(void) +{ + struct omap_hwmod *oh; + struct platform_device *pdev; + char oh_name[L3_MODULES_MAX_LEN]; + + /* + * To avoid code running on other OMAPs in + * multi-omap builds + */ + if (!(cpu_is_omap34xx())) + return -ENODEV; + + snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main"); + + oh = omap_hwmod_lookup(oh_name); + + if (!oh) + pr_err("could not look up %s\n", oh_name); + + pdev = omap_device_build("omap_l3_smx", 0, oh, NULL, 0); + + WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); -#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE) -#define OMAP2_MBOX_BASE IO_ADDRESS(OMAP24XX_MAILBOX_BASE) + return PTR_RET(pdev); +} +omap_postcore_initcall(omap3_l3_init); + +static int __init omap4_l3_init(void) +{ + int i; + struct omap_hwmod *oh[3]; + struct platform_device *pdev; + char oh_name[L3_MODULES_MAX_LEN]; + + /* If dtb is there, the devices will be created dynamically */ + if (of_have_populated_dt()) + return -ENODEV; + + /* + * To avoid code running on other OMAPs in + * multi-omap builds + */ + if (!cpu_is_omap44xx() && !soc_is_omap54xx()) + return -ENODEV; -static struct resource mbox_resources[] = { + for (i = 0; i < L3_MODULES; i++) { + snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main_%d", i+1); + + oh[i] = omap_hwmod_lookup(oh_name); + if (!(oh[i])) + pr_err("could not look up %s\n", oh_name); + } + + pdev = omap_device_build_ss("omap_l3_noc", 0, oh, 3, NULL, 0); + + WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); + + return PTR_RET(pdev); +} +omap_postcore_initcall(omap4_l3_init); + +#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE) + +static struct resource omap2cam_resources[] = { { - .start = OMAP2_MBOX_BASE, - .end = OMAP2_MBOX_BASE + 0x11f, + .start = OMAP24XX_CAMERA_BASE, + .end = OMAP24XX_CAMERA_BASE + 0xfff, .flags = IORESOURCE_MEM, }, { - .start = INT_24XX_MAIL_U0_MPU, + .start = 24 + OMAP_INTC_START, .flags = IORESOURCE_IRQ, - }, - { - .start = INT_24XX_MAIL_U3_MPU, - .flags = IORESOURCE_IRQ, - }, + } }; -static struct platform_device mbox_device = { - .name = "mailbox", +static struct platform_device omap2cam_device = { + .name = "omap24xxcam", .id = -1, - .num_resources = ARRAY_SIZE(mbox_resources), - .resource = mbox_resources, + .num_resources = ARRAY_SIZE(omap2cam_resources), + .resource = omap2cam_resources, }; - -static inline void omap_init_mbox(void) -{ - platform_device_register(&mbox_device); -} -#else -static inline void omap_init_mbox(void) { } #endif -#if defined(CONFIG_OMAP_STI) - -#if defined(CONFIG_ARCH_OMAP2) +#if defined(CONFIG_IOMMU_API) -#define OMAP2_STI_BASE 0x48068000 -#define OMAP2_STI_CHANNEL_BASE 0x54000000 -#define OMAP2_STI_IRQ 4 +#include <linux/platform_data/iommu-omap.h> -static struct resource sti_resources[] = { +static struct resource omap3isp_resources[] = { { - .start = OMAP2_STI_BASE, - .end = OMAP2_STI_BASE + 0x7ff, + .start = OMAP3430_ISP_BASE, + .end = OMAP3430_ISP_END, .flags = IORESOURCE_MEM, }, { - .start = OMAP2_STI_CHANNEL_BASE, - .end = OMAP2_STI_CHANNEL_BASE + SZ_64K - 1, + .start = OMAP3430_ISP_CCP2_BASE, + .end = OMAP3430_ISP_CCP2_END, .flags = IORESOURCE_MEM, }, { - .start = OMAP2_STI_IRQ, - .flags = IORESOURCE_IRQ, - } -}; -#elif defined(CONFIG_ARCH_OMAP3) - -#define OMAP3_SDTI_BASE 0x54500000 -#define OMAP3_SDTI_CHANNEL_BASE 0x54600000 - -static struct resource sti_resources[] = { + .start = OMAP3430_ISP_CCDC_BASE, + .end = OMAP3430_ISP_CCDC_END, + .flags = IORESOURCE_MEM, + }, { - .start = OMAP3_SDTI_BASE, - .end = OMAP3_SDTI_BASE + 0xFFF, + .start = OMAP3430_ISP_HIST_BASE, + .end = OMAP3430_ISP_HIST_END, .flags = IORESOURCE_MEM, }, { - .start = OMAP3_SDTI_CHANNEL_BASE, - .end = OMAP3_SDTI_CHANNEL_BASE + SZ_1M - 1, + .start = OMAP3430_ISP_H3A_BASE, + .end = OMAP3430_ISP_H3A_END, .flags = IORESOURCE_MEM, - } -}; - -#endif - -static struct platform_device sti_device = { - .name = "sti", - .id = -1, - .num_resources = ARRAY_SIZE(sti_resources), - .resource = sti_resources, -}; - -static inline void omap_init_sti(void) -{ - platform_device_register(&sti_device); -} -#else -static inline void omap_init_sti(void) {} -#endif - -#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) - -#include <mach/mcspi.h> - -#define OMAP2_MCSPI1_BASE 0x48098000 -#define OMAP2_MCSPI2_BASE 0x4809a000 -#define OMAP2_MCSPI3_BASE 0x480b8000 -#define OMAP2_MCSPI4_BASE 0x480ba000 - -static struct omap2_mcspi_platform_config omap2_mcspi1_config = { - .num_cs = 4, -}; - -static struct resource omap2_mcspi1_resources[] = { + }, { - .start = OMAP2_MCSPI1_BASE, - .end = OMAP2_MCSPI1_BASE + 0xff, + .start = OMAP3430_ISP_PREV_BASE, + .end = OMAP3430_ISP_PREV_END, .flags = IORESOURCE_MEM, }, -}; - -static struct platform_device omap2_mcspi1 = { - .name = "omap2_mcspi", - .id = 1, - .num_resources = ARRAY_SIZE(omap2_mcspi1_resources), - .resource = omap2_mcspi1_resources, - .dev = { - .platform_data = &omap2_mcspi1_config, + { + .start = OMAP3430_ISP_RESZ_BASE, + .end = OMAP3430_ISP_RESZ_END, + .flags = IORESOURCE_MEM, }, -}; - -static struct omap2_mcspi_platform_config omap2_mcspi2_config = { - .num_cs = 2, -}; - -static struct resource omap2_mcspi2_resources[] = { { - .start = OMAP2_MCSPI2_BASE, - .end = OMAP2_MCSPI2_BASE + 0xff, + .start = OMAP3430_ISP_SBL_BASE, + .end = OMAP3430_ISP_SBL_END, .flags = IORESOURCE_MEM, }, -}; - -static struct platform_device omap2_mcspi2 = { - .name = "omap2_mcspi", - .id = 2, - .num_resources = ARRAY_SIZE(omap2_mcspi2_resources), - .resource = omap2_mcspi2_resources, - .dev = { - .platform_data = &omap2_mcspi2_config, + { + .start = OMAP3430_ISP_CSI2A_REGS1_BASE, + .end = OMAP3430_ISP_CSI2A_REGS1_END, + .flags = IORESOURCE_MEM, }, -}; - -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) -static struct omap2_mcspi_platform_config omap2_mcspi3_config = { - .num_cs = 2, -}; - -static struct resource omap2_mcspi3_resources[] = { { - .start = OMAP2_MCSPI3_BASE, - .end = OMAP2_MCSPI3_BASE + 0xff, - .flags = IORESOURCE_MEM, + .start = OMAP3430_ISP_CSIPHY2_BASE, + .end = OMAP3430_ISP_CSIPHY2_END, + .flags = IORESOURCE_MEM, }, -}; - -static struct platform_device omap2_mcspi3 = { - .name = "omap2_mcspi", - .id = 3, - .num_resources = ARRAY_SIZE(omap2_mcspi3_resources), - .resource = omap2_mcspi3_resources, - .dev = { - .platform_data = &omap2_mcspi3_config, + { + .start = OMAP3630_ISP_CSI2A_REGS2_BASE, + .end = OMAP3630_ISP_CSI2A_REGS2_END, + .flags = IORESOURCE_MEM, + }, + { + .start = OMAP3630_ISP_CSI2C_REGS1_BASE, + .end = OMAP3630_ISP_CSI2C_REGS1_END, + .flags = IORESOURCE_MEM, + }, + { + .start = OMAP3630_ISP_CSIPHY1_BASE, + .end = OMAP3630_ISP_CSIPHY1_END, + .flags = IORESOURCE_MEM, + }, + { + .start = OMAP3630_ISP_CSI2C_REGS2_BASE, + .end = OMAP3630_ISP_CSI2C_REGS2_END, + .flags = IORESOURCE_MEM, }, -}; -#endif - -#ifdef CONFIG_ARCH_OMAP3 -static struct omap2_mcspi_platform_config omap2_mcspi4_config = { - .num_cs = 1, -}; - -static struct resource omap2_mcspi4_resources[] = { { - .start = OMAP2_MCSPI4_BASE, - .end = OMAP2_MCSPI4_BASE + 0xff, + .start = OMAP343X_CTRL_BASE + OMAP343X_CONTROL_CSIRXFE, + .end = OMAP343X_CTRL_BASE + OMAP343X_CONTROL_CSIRXFE + 3, .flags = IORESOURCE_MEM, }, + { + .start = OMAP343X_CTRL_BASE + OMAP3630_CONTROL_CAMERA_PHY_CTRL, + .end = OMAP343X_CTRL_BASE + OMAP3630_CONTROL_CAMERA_PHY_CTRL + 3, + .flags = IORESOURCE_MEM, + }, + { + .start = 24 + OMAP_INTC_START, + .flags = IORESOURCE_IRQ, + } }; -static struct platform_device omap2_mcspi4 = { - .name = "omap2_mcspi", - .id = 4, - .num_resources = ARRAY_SIZE(omap2_mcspi4_resources), - .resource = omap2_mcspi4_resources, - .dev = { - .platform_data = &omap2_mcspi4_config, - }, +static struct platform_device omap3isp_device = { + .name = "omap3isp", + .id = -1, + .num_resources = ARRAY_SIZE(omap3isp_resources), + .resource = omap3isp_resources, }; -#endif -static void omap_init_mcspi(void) +static struct omap_iommu_arch_data omap3_isp_iommu = { + .name = "mmu_isp", +}; + +int omap3_init_camera(struct isp_platform_data *pdata) { - platform_device_register(&omap2_mcspi1); - platform_device_register(&omap2_mcspi2); -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) - platform_device_register(&omap2_mcspi3); -#endif -#ifdef CONFIG_ARCH_OMAP3 - platform_device_register(&omap2_mcspi4); -#endif -} + if (of_have_populated_dt()) + omap3_isp_iommu.name = "480bd400.mmu"; -#else -static inline void omap_init_mcspi(void) {} -#endif + omap3isp_device.dev.platform_data = pdata; + omap3isp_device.dev.archdata.iommu = &omap3_isp_iommu; -#ifdef CONFIG_SND_OMAP24XX_EAC + return platform_device_register(&omap3isp_device); +} -#define OMAP2_EAC_BASE 0x48090000 +#else /* !CONFIG_IOMMU_API */ -static struct resource omap2_eac_resources[] = { - { - .start = OMAP2_EAC_BASE, - .end = OMAP2_EAC_BASE + 0x109, - .flags = IORESOURCE_MEM, - }, -}; +int omap3_init_camera(struct isp_platform_data *pdata) +{ + return 0; +} -static struct platform_device omap2_eac_device = { - .name = "omap24xx-eac", - .id = -1, - .num_resources = ARRAY_SIZE(omap2_eac_resources), - .resource = omap2_eac_resources, - .dev = { - .platform_data = NULL, - }, -}; +#endif -void omap_init_eac(struct eac_platform_data *pdata) +static inline void omap_init_camera(void) { - omap2_eac_device.dev.platform_data = pdata; - platform_device_register(&omap2_eac_device); +#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE) + if (cpu_is_omap24xx()) + platform_device_register(&omap2cam_device); +#endif } +#if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE) +static inline void __init omap_init_mbox(void) +{ + struct omap_hwmod *oh; + struct platform_device *pdev; + struct omap_mbox_pdata *pdata; + + oh = omap_hwmod_lookup("mailbox"); + if (!oh) { + pr_err("%s: unable to find hwmod\n", __func__); + return; + } + if (!oh->dev_attr) { + pr_err("%s: hwmod doesn't have valid attrs\n", __func__); + return; + } + + pdata = (struct omap_mbox_pdata *)oh->dev_attr; + pdev = omap_device_build("omap-mailbox", -1, oh, pdata, sizeof(*pdata)); + WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n", + __func__, PTR_ERR(pdev)); +} #else -void omap_init_eac(struct eac_platform_data *pdata) {} -#endif +static inline void omap_init_mbox(void) { } +#endif /* CONFIG_OMAP2PLUS_MBOX */ -#ifdef CONFIG_OMAP_SHA1_MD5 -static struct resource sha1_md5_resources[] = { - { - .start = OMAP24XX_SEC_SHA1MD5_BASE, - .end = OMAP24XX_SEC_SHA1MD5_BASE + 0x64, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_24XX_SHA1MD5, - .flags = IORESOURCE_IRQ, - } -}; +static inline void omap_init_sti(void) {} -static struct platform_device sha1_md5_device = { - .name = "OMAP SHA1/MD5", - .id = -1, - .num_resources = ARRAY_SIZE(sha1_md5_resources), - .resource = sha1_md5_resources, +#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE) + +static struct platform_device omap_pcm = { + .name = "omap-pcm-audio", + .id = -1, }; -static void omap_init_sha1_md5(void) +static void omap_init_audio(void) { - platform_device_register(&sha1_md5_device); + platform_device_register(&omap_pcm); } + #else -static inline void omap_init_sha1_md5(void) { } +static inline void omap_init_audio(void) {} #endif -/*-------------------------------------------------------------------------*/ - -#ifdef CONFIG_ARCH_OMAP3 +#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) -#define MMCHS_SYSCONFIG 0x0010 -#define MMCHS_SYSCONFIG_SWRESET (1 << 1) -#define MMCHS_SYSSTATUS 0x0014 -#define MMCHS_SYSSTATUS_RESETDONE (1 << 0) +#include <linux/platform_data/spi-omap2-mcspi.h> -static struct platform_device dummy_pdev = { - .dev = { - .bus = &platform_bus_type, - }, -}; - -/** - * omap_hsmmc_reset() - Full reset of each HS-MMC controller - * - * Ensure that each MMC controller is fully reset. Controllers - * left in an unknown state (by bootloader) may prevent retention - * or OFF-mode. This is especially important in cases where the - * MMC driver is not enabled, _or_ built as a module. - * - * In order for reset to work, interface, functional and debounce - * clocks must be enabled. The debounce clock comes from func_32k_clk - * and is not under SW control, so we only enable i- and f-clocks. - **/ -static void __init omap_hsmmc_reset(void) +static int __init omap_mcspi_init(struct omap_hwmod *oh, void *unused) { - u32 i, nr_controllers = cpu_is_omap34xx() ? OMAP34XX_NR_MMC : - OMAP24XX_NR_MMC; - - for (i = 0; i < nr_controllers; i++) { - u32 v, base = 0; - struct clk *iclk, *fclk; - struct device *dev = &dummy_pdev.dev; + struct platform_device *pdev; + char *name = "omap2_mcspi"; + struct omap2_mcspi_platform_config *pdata; + static int spi_num; + struct omap2_mcspi_dev_attr *mcspi_attrib = oh->dev_attr; + + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + pr_err("Memory allocation for McSPI device failed\n"); + return -ENOMEM; + } - switch (i) { - case 0: - base = OMAP2_MMC1_BASE; + pdata->num_cs = mcspi_attrib->num_chipselect; + switch (oh->class->rev) { + case OMAP2_MCSPI_REV: + case OMAP3_MCSPI_REV: + pdata->regs_offset = 0; break; - case 1: - base = OMAP2_MMC2_BASE; + case OMAP4_MCSPI_REV: + pdata->regs_offset = OMAP4_MCSPI_REG_OFFSET; break; - case 2: - base = OMAP3_MMC3_BASE; - break; - } - - dummy_pdev.id = i; - iclk = clk_get(dev, "mmchs_ick"); - if (iclk && clk_enable(iclk)) - iclk = NULL; + default: + pr_err("Invalid McSPI Revision value\n"); + kfree(pdata); + return -EINVAL; + } - fclk = clk_get(dev, "mmchs_fck"); - if (fclk && clk_enable(fclk)) - fclk = NULL; + spi_num++; + pdev = omap_device_build(name, spi_num, oh, pdata, sizeof(*pdata)); + WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n", + name, oh->name); + kfree(pdata); + return 0; +} - if (!iclk || !fclk) { - printk(KERN_WARNING - "%s: Unable to enable clocks for MMC%d, " - "cannot reset.\n", __func__, i); - break; - } - - omap_writel(MMCHS_SYSCONFIG_SWRESET, base + MMCHS_SYSCONFIG); - v = omap_readl(base + MMCHS_SYSSTATUS); - while (!(omap_readl(base + MMCHS_SYSSTATUS) & - MMCHS_SYSSTATUS_RESETDONE)) - cpu_relax(); - - if (fclk) { - clk_disable(fclk); - clk_put(fclk); - } - if (iclk) { - clk_disable(iclk); - clk_put(iclk); - } - } +static void omap_init_mcspi(void) +{ + omap_hwmod_for_each_by_class("mcspi", omap_mcspi_init, NULL); } + #else -static inline void omap_hsmmc_reset(void) {} +static inline void omap_init_mcspi(void) {} #endif -#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ - defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) - -static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, - int controller_nr) +/** + * omap_init_rng - bind the RNG hwmod to the RNG omap_device + * + * Bind the RNG hwmod to the RNG omap_device. No return value. + */ +static void omap_init_rng(void) { - if (cpu_is_omap2420() && controller_nr == 0) { - omap_cfg_reg(H18_24XX_MMC_CMD); - omap_cfg_reg(H15_24XX_MMC_CLKI); - omap_cfg_reg(G19_24XX_MMC_CLKO); - omap_cfg_reg(F20_24XX_MMC_DAT0); - omap_cfg_reg(F19_24XX_MMC_DAT_DIR0); - omap_cfg_reg(G18_24XX_MMC_CMD_DIR); - if (mmc_controller->slots[0].wires == 4) { - omap_cfg_reg(H14_24XX_MMC_DAT1); - omap_cfg_reg(E19_24XX_MMC_DAT2); - omap_cfg_reg(D19_24XX_MMC_DAT3); - omap_cfg_reg(E20_24XX_MMC_DAT_DIR1); - omap_cfg_reg(F18_24XX_MMC_DAT_DIR2); - omap_cfg_reg(E18_24XX_MMC_DAT_DIR3); - } - - /* - * Use internal loop-back in MMC/SDIO Module Input Clock - * selection - */ - if (mmc_controller->slots[0].internal_clock) { - u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); - v |= (1 << 24); - omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); - } - } + struct omap_hwmod *oh; + struct platform_device *pdev; + + oh = omap_hwmod_lookup("rng"); + if (!oh) + return; + + pdev = omap_device_build("omap_rng", -1, oh, NULL, 0); + WARN(IS_ERR(pdev), "Can't build omap_device for omap_rng\n"); } -void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, - int nr_controllers) +static void __init omap_init_sham(void) { - int i; - char *name; + struct omap_hwmod *oh; + struct platform_device *pdev; - for (i = 0; i < nr_controllers; i++) { - unsigned long base, size; - unsigned int irq = 0; + oh = omap_hwmod_lookup("sham"); + if (!oh) + return; - if (!mmc_data[i]) - continue; + pdev = omap_device_build("omap-sham", -1, oh, NULL, 0); + WARN(IS_ERR(pdev), "Can't build omap_device for omap-sham\n"); +} - omap2_mmc_mux(mmc_data[i], i); +static void __init omap_init_aes(void) +{ + struct omap_hwmod *oh; + struct platform_device *pdev; - switch (i) { - case 0: - base = OMAP2_MMC1_BASE; - irq = INT_24XX_MMC_IRQ; - break; - case 1: - base = OMAP2_MMC2_BASE; - irq = INT_24XX_MMC2_IRQ; - break; - case 2: - if (!cpu_is_omap34xx()) - return; - base = OMAP3_MMC3_BASE; - irq = INT_34XX_MMC3_IRQ; - break; - default: - continue; - } - - if (cpu_is_omap2420()) { - size = OMAP2420_MMC_SIZE; - name = "mmci-omap"; - } else { - size = HSMMC_SIZE; - name = "mmci-omap-hs"; - } - omap_mmc_add(name, i, base, size, irq, mmc_data[i]); - }; -} + oh = omap_hwmod_lookup("aes"); + if (!oh) + return; -#endif + pdev = omap_device_build("omap-aes", -1, oh, NULL, 0); + WARN(IS_ERR(pdev), "Can't build omap_device for omap-aes\n"); +} /*-------------------------------------------------------------------------*/ -#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE) -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) -#define OMAP_HDQ_BASE 0x480B2000 -#endif -static struct resource omap_hdq_resources[] = { - { - .start = OMAP_HDQ_BASE, - .end = OMAP_HDQ_BASE + 0x1C, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_24XX_HDQ_IRQ, - .flags = IORESOURCE_IRQ, - }, +#if defined(CONFIG_VIDEO_OMAP2_VOUT) || \ + defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE) +#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) +static struct resource omap_vout_resource[3 - CONFIG_FB_OMAP2_NUM_FBS] = { }; -static struct platform_device omap_hdq_dev = { - .name = "omap_hdq", - .id = 0, - .dev = { - .platform_data = NULL, - }, - .num_resources = ARRAY_SIZE(omap_hdq_resources), - .resource = omap_hdq_resources, +#else +static struct resource omap_vout_resource[2] = { +}; +#endif + +static struct platform_device omap_vout_device = { + .name = "omap_vout", + .num_resources = ARRAY_SIZE(omap_vout_resource), + .resource = &omap_vout_resource[0], + .id = -1, }; -static inline void omap_hdq_init(void) + +int __init omap_init_vout(void) { - (void) platform_device_register(&omap_hdq_dev); + return platform_device_register(&omap_vout_device); } #else -static inline void omap_hdq_init(void) {} +int __init omap_init_vout(void) { return 0; } #endif /*-------------------------------------------------------------------------*/ static int __init omap2_init_devices(void) { - /* please keep these calls, and their implementations above, + /* Enable dummy states for those platforms without pinctrl support */ + if (!of_have_populated_dt()) + pinctrl_provide_dummies(); + + /* + * please keep these calls, and their implementations above, * in alphabetical order so they're easier to sort through. */ - omap_hsmmc_reset(); + omap_init_audio(); + omap_init_camera(); omap_init_mbox(); - omap_init_mcspi(); - omap_hdq_init(); + /* If dtb is there, the devices will be created dynamically */ + if (!of_have_populated_dt()) { + omap_init_mcspi(); + omap_init_sham(); + omap_init_aes(); + omap_init_rng(); + } omap_init_sti(); - omap_init_sha1_md5(); return 0; } -arch_initcall(omap2_init_devices); +omap_arch_initcall(omap2_init_devices); diff --git a/arch/arm/mach-omap2/devices.h b/arch/arm/mach-omap2/devices.h new file mode 100644 index 00000000000..f61eb6e5d13 --- /dev/null +++ b/arch/arm/mach-omap2/devices.h @@ -0,0 +1,19 @@ +/* + * arch/arm/mach-omap2/devices.h + * + * OMAP2 platform device setup/initialization + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __ARCH_ARM_MACH_OMAP_DEVICES_H +#define __ARCH_ARM_MACH_OMAP_DEVICES_H + +struct isp_platform_data; + +int omap3_init_camera(struct isp_platform_data *pdata); + +#endif diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c new file mode 100644 index 00000000000..bf852d7ae95 --- /dev/null +++ b/arch/arm/mach-omap2/display.c @@ -0,0 +1,669 @@ +/* + * OMAP2plus display device setup / initialization. + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * Senthilvadivu Guruswamy + * Sumit Semwal + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/string.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/delay.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/slab.h> + +#include <video/omapdss.h> +#include "omap_hwmod.h" +#include "omap_device.h" +#include "omap-pm.h" +#include "common.h" + +#include "soc.h" +#include "iomap.h" +#include "control.h" +#include "display.h" +#include "prm.h" + +#define DISPC_CONTROL 0x0040 +#define DISPC_CONTROL2 0x0238 +#define DISPC_CONTROL3 0x0848 +#define DISPC_IRQSTATUS 0x0018 + +#define DSS_SYSCONFIG 0x10 +#define DSS_SYSSTATUS 0x14 +#define DSS_CONTROL 0x40 +#define DSS_SDI_CONTROL 0x44 +#define DSS_PLL_CONTROL 0x48 + +#define LCD_EN_MASK (0x1 << 0) +#define DIGIT_EN_MASK (0x1 << 1) + +#define FRAMEDONE_IRQ_SHIFT 0 +#define EVSYNC_EVEN_IRQ_SHIFT 2 +#define EVSYNC_ODD_IRQ_SHIFT 3 +#define FRAMEDONE2_IRQ_SHIFT 22 +#define FRAMEDONE3_IRQ_SHIFT 30 +#define FRAMEDONETV_IRQ_SHIFT 24 + +/* + * FRAMEDONE_IRQ_TIMEOUT: how long (in milliseconds) to wait during DISPC + * reset before deciding that something has gone wrong + */ +#define FRAMEDONE_IRQ_TIMEOUT 100 + +static struct platform_device omap_display_device = { + .name = "omapdss", + .id = -1, + .dev = { + .platform_data = NULL, + }, +}; + +struct omap_dss_hwmod_data { + const char *oh_name; + const char *dev_name; + const int id; +}; + +static const struct omap_dss_hwmod_data omap2_dss_hwmod_data[] __initconst = { + { "dss_core", "omapdss_dss", -1 }, + { "dss_dispc", "omapdss_dispc", -1 }, + { "dss_rfbi", "omapdss_rfbi", -1 }, + { "dss_venc", "omapdss_venc", -1 }, +}; + +static const struct omap_dss_hwmod_data omap3_dss_hwmod_data[] __initconst = { + { "dss_core", "omapdss_dss", -1 }, + { "dss_dispc", "omapdss_dispc", -1 }, + { "dss_rfbi", "omapdss_rfbi", -1 }, + { "dss_venc", "omapdss_venc", -1 }, + { "dss_dsi1", "omapdss_dsi", 0 }, +}; + +static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initconst = { + { "dss_core", "omapdss_dss", -1 }, + { "dss_dispc", "omapdss_dispc", -1 }, + { "dss_rfbi", "omapdss_rfbi", -1 }, + { "dss_dsi1", "omapdss_dsi", 0 }, + { "dss_dsi2", "omapdss_dsi", 1 }, + { "dss_hdmi", "omapdss_hdmi", -1 }, +}; + +static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes) +{ + u32 enable_mask, enable_shift; + u32 pipd_mask, pipd_shift; + u32 reg; + + if (dsi_id == 0) { + enable_mask = OMAP4_DSI1_LANEENABLE_MASK; + enable_shift = OMAP4_DSI1_LANEENABLE_SHIFT; + pipd_mask = OMAP4_DSI1_PIPD_MASK; + pipd_shift = OMAP4_DSI1_PIPD_SHIFT; + } else if (dsi_id == 1) { + enable_mask = OMAP4_DSI2_LANEENABLE_MASK; + enable_shift = OMAP4_DSI2_LANEENABLE_SHIFT; + pipd_mask = OMAP4_DSI2_PIPD_MASK; + pipd_shift = OMAP4_DSI2_PIPD_SHIFT; + } else { + return -ENODEV; + } + + reg = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY); + + reg &= ~enable_mask; + reg &= ~pipd_mask; + + reg |= (lanes << enable_shift) & enable_mask; + reg |= (lanes << pipd_shift) & pipd_mask; + + omap4_ctrl_pad_writel(reg, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY); + + return 0; +} + +static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask) +{ + if (cpu_is_omap44xx()) + return omap4_dsi_mux_pads(dsi_id, lane_mask); + + return 0; +} + +static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask) +{ + if (cpu_is_omap44xx()) + omap4_dsi_mux_pads(dsi_id, 0); +} + +static int omap_dss_set_min_bus_tput(struct device *dev, unsigned long tput) +{ + return omap_pm_set_min_bus_tput(dev, OCP_INITIATOR_AGENT, tput); +} + +static struct platform_device *create_dss_pdev(const char *pdev_name, + int pdev_id, const char *oh_name, void *pdata, int pdata_len, + struct platform_device *parent) +{ + struct platform_device *pdev; + struct omap_device *od; + struct omap_hwmod *ohs[1]; + struct omap_hwmod *oh; + int r; + + oh = omap_hwmod_lookup(oh_name); + if (!oh) { + pr_err("Could not look up %s\n", oh_name); + r = -ENODEV; + goto err; + } + + pdev = platform_device_alloc(pdev_name, pdev_id); + if (!pdev) { + pr_err("Could not create pdev for %s\n", pdev_name); + r = -ENOMEM; + goto err; + } + + if (parent != NULL) + pdev->dev.parent = &parent->dev; + + if (pdev->id != -1) + dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); + else + dev_set_name(&pdev->dev, "%s", pdev->name); + + ohs[0] = oh; + od = omap_device_alloc(pdev, ohs, 1); + if (IS_ERR(od)) { + pr_err("Could not alloc omap_device for %s\n", pdev_name); + r = -ENOMEM; + goto err; + } + + r = platform_device_add_data(pdev, pdata, pdata_len); + if (r) { + pr_err("Could not set pdata for %s\n", pdev_name); + goto err; + } + + r = omap_device_register(pdev); + if (r) { + pr_err("Could not register omap_device for %s\n", pdev_name); + goto err; + } + + return pdev; + +err: + return ERR_PTR(r); +} + +static struct platform_device *create_simple_dss_pdev(const char *pdev_name, + int pdev_id, void *pdata, int pdata_len, + struct platform_device *parent) +{ + struct platform_device *pdev; + int r; + + pdev = platform_device_alloc(pdev_name, pdev_id); + if (!pdev) { + pr_err("Could not create pdev for %s\n", pdev_name); + r = -ENOMEM; + goto err; + } + + if (parent != NULL) + pdev->dev.parent = &parent->dev; + + if (pdev->id != -1) + dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); + else + dev_set_name(&pdev->dev, "%s", pdev->name); + + r = platform_device_add_data(pdev, pdata, pdata_len); + if (r) { + pr_err("Could not set pdata for %s\n", pdev_name); + goto err; + } + + r = platform_device_add(pdev); + if (r) { + pr_err("Could not register platform_device for %s\n", pdev_name); + goto err; + } + + return pdev; + +err: + return ERR_PTR(r); +} + +static enum omapdss_version __init omap_display_get_version(void) +{ + if (cpu_is_omap24xx()) + return OMAPDSS_VER_OMAP24xx; + else if (cpu_is_omap3630()) + return OMAPDSS_VER_OMAP3630; + else if (cpu_is_omap34xx()) { + if (soc_is_am35xx()) { + return OMAPDSS_VER_AM35xx; + } else { + if (omap_rev() < OMAP3430_REV_ES3_0) + return OMAPDSS_VER_OMAP34xx_ES1; + else + return OMAPDSS_VER_OMAP34xx_ES3; + } + } else if (omap_rev() == OMAP4430_REV_ES1_0) + return OMAPDSS_VER_OMAP4430_ES1; + else if (omap_rev() == OMAP4430_REV_ES2_0 || + omap_rev() == OMAP4430_REV_ES2_1 || + omap_rev() == OMAP4430_REV_ES2_2) + return OMAPDSS_VER_OMAP4430_ES2; + else if (cpu_is_omap44xx()) + return OMAPDSS_VER_OMAP4; + else if (soc_is_omap54xx()) + return OMAPDSS_VER_OMAP5; + else if (soc_is_am43xx()) + return OMAPDSS_VER_AM43xx; + else + return OMAPDSS_VER_UNKNOWN; +} + +int __init omap_display_init(struct omap_dss_board_info *board_data) +{ + int r = 0; + struct platform_device *pdev; + int i, oh_count; + const struct omap_dss_hwmod_data *curr_dss_hwmod; + struct platform_device *dss_pdev; + enum omapdss_version ver; + + /* create omapdss device */ + + ver = omap_display_get_version(); + + if (ver == OMAPDSS_VER_UNKNOWN) { + pr_err("DSS not supported on this SoC\n"); + return -ENODEV; + } + + board_data->version = ver; + board_data->dsi_enable_pads = omap_dsi_enable_pads; + board_data->dsi_disable_pads = omap_dsi_disable_pads; + board_data->set_min_bus_tput = omap_dss_set_min_bus_tput; + + omap_display_device.dev.platform_data = board_data; + + r = platform_device_register(&omap_display_device); + if (r < 0) { + pr_err("Unable to register omapdss device\n"); + return r; + } + + /* create devices for dss hwmods */ + + if (cpu_is_omap24xx()) { + curr_dss_hwmod = omap2_dss_hwmod_data; + oh_count = ARRAY_SIZE(omap2_dss_hwmod_data); + } else if (cpu_is_omap34xx()) { + curr_dss_hwmod = omap3_dss_hwmod_data; + oh_count = ARRAY_SIZE(omap3_dss_hwmod_data); + } else { + curr_dss_hwmod = omap4_dss_hwmod_data; + oh_count = ARRAY_SIZE(omap4_dss_hwmod_data); + } + + /* + * First create the pdev for dss_core, which is used as a parent device + * by the other dss pdevs. Note: dss_core has to be the first item in + * the hwmod list. + */ + dss_pdev = create_dss_pdev(curr_dss_hwmod[0].dev_name, + curr_dss_hwmod[0].id, + curr_dss_hwmod[0].oh_name, + board_data, sizeof(*board_data), + NULL); + + if (IS_ERR(dss_pdev)) { + pr_err("Could not build omap_device for %s\n", + curr_dss_hwmod[0].oh_name); + + return PTR_ERR(dss_pdev); + } + + for (i = 1; i < oh_count; i++) { + pdev = create_dss_pdev(curr_dss_hwmod[i].dev_name, + curr_dss_hwmod[i].id, + curr_dss_hwmod[i].oh_name, + board_data, sizeof(*board_data), + dss_pdev); + + if (IS_ERR(pdev)) { + pr_err("Could not build omap_device for %s\n", + curr_dss_hwmod[i].oh_name); + + return PTR_ERR(pdev); + } + } + + /* Create devices for DPI and SDI */ + + pdev = create_simple_dss_pdev("omapdss_dpi", 0, + board_data, sizeof(*board_data), dss_pdev); + if (IS_ERR(pdev)) { + pr_err("Could not build platform_device for omapdss_dpi\n"); + return PTR_ERR(pdev); + } + + if (cpu_is_omap34xx()) { + pdev = create_simple_dss_pdev("omapdss_sdi", 0, + board_data, sizeof(*board_data), dss_pdev); + if (IS_ERR(pdev)) { + pr_err("Could not build platform_device for omapdss_sdi\n"); + return PTR_ERR(pdev); + } + } + + /* create DRM device */ + r = omap_init_drm(); + if (r < 0) { + pr_err("Unable to register omapdrm device\n"); + return r; + } + + /* create vrfb device */ + r = omap_init_vrfb(); + if (r < 0) { + pr_err("Unable to register omapvrfb device\n"); + return r; + } + + /* create FB device */ + r = omap_init_fb(); + if (r < 0) { + pr_err("Unable to register omapfb device\n"); + return r; + } + + /* create V4L2 display device */ + r = omap_init_vout(); + if (r < 0) { + pr_err("Unable to register omap_vout device\n"); + return r; + } + + return 0; +} + +static void dispc_disable_outputs(void) +{ + u32 v, irq_mask = 0; + bool lcd_en, digit_en, lcd2_en = false, lcd3_en = false; + int i; + struct omap_dss_dispc_dev_attr *da; + struct omap_hwmod *oh; + + oh = omap_hwmod_lookup("dss_dispc"); + if (!oh) { + WARN(1, "display: could not disable outputs during reset - could not find dss_dispc hwmod\n"); + return; + } + + if (!oh->dev_attr) { + pr_err("display: could not disable outputs during reset due to missing dev_attr\n"); + return; + } + + da = (struct omap_dss_dispc_dev_attr *)oh->dev_attr; + + /* store value of LCDENABLE and DIGITENABLE bits */ + v = omap_hwmod_read(oh, DISPC_CONTROL); + lcd_en = v & LCD_EN_MASK; + digit_en = v & DIGIT_EN_MASK; + + /* store value of LCDENABLE for LCD2 */ + if (da->manager_count > 2) { + v = omap_hwmod_read(oh, DISPC_CONTROL2); + lcd2_en = v & LCD_EN_MASK; + } + + /* store value of LCDENABLE for LCD3 */ + if (da->manager_count > 3) { + v = omap_hwmod_read(oh, DISPC_CONTROL3); + lcd3_en = v & LCD_EN_MASK; + } + + if (!(lcd_en | digit_en | lcd2_en | lcd3_en)) + return; /* no managers currently enabled */ + + /* + * If any manager was enabled, we need to disable it before + * DSS clocks are disabled or DISPC module is reset + */ + if (lcd_en) + irq_mask |= 1 << FRAMEDONE_IRQ_SHIFT; + + if (digit_en) { + if (da->has_framedonetv_irq) { + irq_mask |= 1 << FRAMEDONETV_IRQ_SHIFT; + } else { + irq_mask |= 1 << EVSYNC_EVEN_IRQ_SHIFT | + 1 << EVSYNC_ODD_IRQ_SHIFT; + } + } + + if (lcd2_en) + irq_mask |= 1 << FRAMEDONE2_IRQ_SHIFT; + if (lcd3_en) + irq_mask |= 1 << FRAMEDONE3_IRQ_SHIFT; + + /* + * clear any previous FRAMEDONE, FRAMEDONETV, + * EVSYNC_EVEN/ODD, FRAMEDONE2 or FRAMEDONE3 interrupts + */ + omap_hwmod_write(irq_mask, oh, DISPC_IRQSTATUS); + + /* disable LCD and TV managers */ + v = omap_hwmod_read(oh, DISPC_CONTROL); + v &= ~(LCD_EN_MASK | DIGIT_EN_MASK); + omap_hwmod_write(v, oh, DISPC_CONTROL); + + /* disable LCD2 manager */ + if (da->manager_count > 2) { + v = omap_hwmod_read(oh, DISPC_CONTROL2); + v &= ~LCD_EN_MASK; + omap_hwmod_write(v, oh, DISPC_CONTROL2); + } + + /* disable LCD3 manager */ + if (da->manager_count > 3) { + v = omap_hwmod_read(oh, DISPC_CONTROL3); + v &= ~LCD_EN_MASK; + omap_hwmod_write(v, oh, DISPC_CONTROL3); + } + + i = 0; + while ((omap_hwmod_read(oh, DISPC_IRQSTATUS) & irq_mask) != + irq_mask) { + i++; + if (i > FRAMEDONE_IRQ_TIMEOUT) { + pr_err("didn't get FRAMEDONE1/2/3 or TV interrupt\n"); + break; + } + mdelay(1); + } +} + +int omap_dss_reset(struct omap_hwmod *oh) +{ + struct omap_hwmod_opt_clk *oc; + int c = 0; + int i, r; + + if (!(oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)) { + pr_err("dss_core: hwmod data doesn't contain reset data\n"); + return -EINVAL; + } + + for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) + if (oc->_clk) + clk_prepare_enable(oc->_clk); + + dispc_disable_outputs(); + + /* clear SDI registers */ + if (cpu_is_omap3430()) { + omap_hwmod_write(0x0, oh, DSS_SDI_CONTROL); + omap_hwmod_write(0x0, oh, DSS_PLL_CONTROL); + } + + /* + * clear DSS_CONTROL register to switch DSS clock sources to + * PRCM clock, if any + */ + omap_hwmod_write(0x0, oh, DSS_CONTROL); + + omap_test_timeout((omap_hwmod_read(oh, oh->class->sysc->syss_offs) + & SYSS_RESETDONE_MASK), + MAX_MODULE_SOFTRESET_WAIT, c); + + if (c == MAX_MODULE_SOFTRESET_WAIT) + pr_warning("dss_core: waiting for reset to finish failed\n"); + else + pr_debug("dss_core: softreset done\n"); + + for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) + if (oc->_clk) + clk_disable_unprepare(oc->_clk); + + r = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0; + + return r; +} + +void __init omapdss_early_init_of(void) +{ + +} + +struct device_node * __init omapdss_find_dss_of_node(void) +{ + struct device_node *node; + + node = of_find_compatible_node(NULL, NULL, "ti,omap2-dss"); + if (node) + return node; + + node = of_find_compatible_node(NULL, NULL, "ti,omap3-dss"); + if (node) + return node; + + node = of_find_compatible_node(NULL, NULL, "ti,omap4-dss"); + if (node) + return node; + + node = of_find_compatible_node(NULL, NULL, "ti,omap5-dss"); + if (node) + return node; + + return NULL; +} + +int __init omapdss_init_of(void) +{ + int r; + enum omapdss_version ver; + struct device_node *node; + struct platform_device *pdev; + + static struct omap_dss_board_info board_data = { + .dsi_enable_pads = omap_dsi_enable_pads, + .dsi_disable_pads = omap_dsi_disable_pads, + .set_min_bus_tput = omap_dss_set_min_bus_tput, + }; + + /* only create dss helper devices if dss is enabled in the .dts */ + + node = omapdss_find_dss_of_node(); + if (!node) + return 0; + + if (!of_device_is_available(node)) + return 0; + + ver = omap_display_get_version(); + + if (ver == OMAPDSS_VER_UNKNOWN) { + pr_err("DSS not supported on this SoC\n"); + return -ENODEV; + } + + pdev = of_find_device_by_node(node); + + if (!pdev) { + pr_err("Unable to find DSS platform device\n"); + return -ENODEV; + } + + r = of_platform_populate(node, NULL, NULL, &pdev->dev); + if (r) { + pr_err("Unable to populate DSS submodule devices\n"); + return r; + } + + board_data.version = ver; + + omap_display_device.dev.platform_data = &board_data; + + r = platform_device_register(&omap_display_device); + if (r < 0) { + pr_err("Unable to register omapdss device\n"); + return r; + } + + /* create DRM device */ + r = omap_init_drm(); + if (r < 0) { + pr_err("Unable to register omapdrm device\n"); + return r; + } + + /* create vrfb device */ + r = omap_init_vrfb(); + if (r < 0) { + pr_err("Unable to register omapvrfb device\n"); + return r; + } + + /* create FB device */ + r = omap_init_fb(); + if (r < 0) { + pr_err("Unable to register omapfb device\n"); + return r; + } + + /* create V4L2 display device */ + r = omap_init_vout(); + if (r < 0) { + pr_err("Unable to register omap_vout device\n"); + return r; + } + + return 0; +} diff --git a/arch/arm/mach-omap2/display.h b/arch/arm/mach-omap2/display.h new file mode 100644 index 00000000000..7375854b16c --- /dev/null +++ b/arch/arm/mach-omap2/display.h @@ -0,0 +1,36 @@ +/* + * display.h - OMAP2+ integration-specific DSS header + * + * Copyright (C) 2011 Texas Instruments, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_DISPLAY_H +#define __ARCH_ARM_MACH_OMAP2_DISPLAY_H + +#include <linux/kernel.h> + +struct omap_dss_dispc_dev_attr { + u8 manager_count; + bool has_framedonetv_irq; +}; + +int omap_init_drm(void); +int omap_init_vrfb(void); +int omap_init_fb(void); +int omap_init_vout(void); + +struct device_node * __init omapdss_find_dss_of_node(void); + +#endif diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c new file mode 100644 index 00000000000..a6d2cf1f8d0 --- /dev/null +++ b/arch/arm/mach-omap2/dma.c @@ -0,0 +1,290 @@ +/* + * OMAP2+ DMA driver + * + * Copyright (C) 2003 - 2008 Nokia Corporation + * Author: Juha Yrjölä <juha.yrjola@nokia.com> + * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com> + * Graphics DMA and LCD DMA graphics tranformations + * by Imre Deak <imre.deak@nokia.com> + * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc. + * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc. + * + * Copyright (C) 2009 Texas Instruments + * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * Converted DMA library into platform driver + * - G, Manjunath Kondaiah <manjugk@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/err.h> +#include <linux/io.h> +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/dma-mapping.h> +#include <linux/of.h> +#include <linux/omap-dma.h> + +#include "soc.h" +#include "omap_hwmod.h" +#include "omap_device.h" + +static enum omap_reg_offsets dma_common_ch_end; + +static const struct omap_dma_reg reg_map[] = { + [REVISION] = { 0x0000, 0x00, OMAP_DMA_REG_32BIT }, + [GCR] = { 0x0078, 0x00, OMAP_DMA_REG_32BIT }, + [IRQSTATUS_L0] = { 0x0008, 0x00, OMAP_DMA_REG_32BIT }, + [IRQSTATUS_L1] = { 0x000c, 0x00, OMAP_DMA_REG_32BIT }, + [IRQSTATUS_L2] = { 0x0010, 0x00, OMAP_DMA_REG_32BIT }, + [IRQSTATUS_L3] = { 0x0014, 0x00, OMAP_DMA_REG_32BIT }, + [IRQENABLE_L0] = { 0x0018, 0x00, OMAP_DMA_REG_32BIT }, + [IRQENABLE_L1] = { 0x001c, 0x00, OMAP_DMA_REG_32BIT }, + [IRQENABLE_L2] = { 0x0020, 0x00, OMAP_DMA_REG_32BIT }, + [IRQENABLE_L3] = { 0x0024, 0x00, OMAP_DMA_REG_32BIT }, + [SYSSTATUS] = { 0x0028, 0x00, OMAP_DMA_REG_32BIT }, + [OCP_SYSCONFIG] = { 0x002c, 0x00, OMAP_DMA_REG_32BIT }, + [CAPS_0] = { 0x0064, 0x00, OMAP_DMA_REG_32BIT }, + [CAPS_2] = { 0x006c, 0x00, OMAP_DMA_REG_32BIT }, + [CAPS_3] = { 0x0070, 0x00, OMAP_DMA_REG_32BIT }, + [CAPS_4] = { 0x0074, 0x00, OMAP_DMA_REG_32BIT }, + + /* Common register offsets */ + [CCR] = { 0x0080, 0x60, OMAP_DMA_REG_32BIT }, + [CLNK_CTRL] = { 0x0084, 0x60, OMAP_DMA_REG_32BIT }, + [CICR] = { 0x0088, 0x60, OMAP_DMA_REG_32BIT }, + [CSR] = { 0x008c, 0x60, OMAP_DMA_REG_32BIT }, + [CSDP] = { 0x0090, 0x60, OMAP_DMA_REG_32BIT }, + [CEN] = { 0x0094, 0x60, OMAP_DMA_REG_32BIT }, + [CFN] = { 0x0098, 0x60, OMAP_DMA_REG_32BIT }, + [CSEI] = { 0x00a4, 0x60, OMAP_DMA_REG_32BIT }, + [CSFI] = { 0x00a8, 0x60, OMAP_DMA_REG_32BIT }, + [CDEI] = { 0x00ac, 0x60, OMAP_DMA_REG_32BIT }, + [CDFI] = { 0x00b0, 0x60, OMAP_DMA_REG_32BIT }, + [CSAC] = { 0x00b4, 0x60, OMAP_DMA_REG_32BIT }, + [CDAC] = { 0x00b8, 0x60, OMAP_DMA_REG_32BIT }, + + /* Channel specific register offsets */ + [CSSA] = { 0x009c, 0x60, OMAP_DMA_REG_32BIT }, + [CDSA] = { 0x00a0, 0x60, OMAP_DMA_REG_32BIT }, + [CCEN] = { 0x00bc, 0x60, OMAP_DMA_REG_32BIT }, + [CCFN] = { 0x00c0, 0x60, OMAP_DMA_REG_32BIT }, + [COLOR] = { 0x00c4, 0x60, OMAP_DMA_REG_32BIT }, + + /* OMAP4 specific registers */ + [CDP] = { 0x00d0, 0x60, OMAP_DMA_REG_32BIT }, + [CNDP] = { 0x00d4, 0x60, OMAP_DMA_REG_32BIT }, + [CCDN] = { 0x00d8, 0x60, OMAP_DMA_REG_32BIT }, +}; + +static void __iomem *dma_base; +static inline void dma_write(u32 val, int reg, int lch) +{ + void __iomem *addr = dma_base; + + addr += reg_map[reg].offset; + addr += reg_map[reg].stride * lch; + + writel_relaxed(val, addr); +} + +static inline u32 dma_read(int reg, int lch) +{ + void __iomem *addr = dma_base; + + addr += reg_map[reg].offset; + addr += reg_map[reg].stride * lch; + + return readl_relaxed(addr); +} + +static void omap2_clear_dma(int lch) +{ + int i; + + for (i = CSDP; i <= dma_common_ch_end; i += 1) + dma_write(0, i, lch); +} + +static void omap2_show_dma_caps(void) +{ + u8 revision = dma_read(REVISION, 0) & 0xff; + printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n", + revision >> 4, revision & 0xf); + return; +} + +static unsigned configure_dma_errata(void) +{ + unsigned errata = 0; + + /* + * Errata applicable for OMAP2430ES1.0 and all omap2420 + * + * I. + * Erratum ID: Not Available + * Inter Frame DMA buffering issue DMA will wrongly + * buffer elements if packing and bursting is enabled. This might + * result in data gets stalled in FIFO at the end of the block. + * Workaround: DMA channels must have BUFFERING_DISABLED bit set to + * guarantee no data will stay in the DMA FIFO in case inter frame + * buffering occurs + * + * II. + * Erratum ID: Not Available + * DMA may hang when several channels are used in parallel + * In the following configuration, DMA channel hanging can occur: + * a. Channel i, hardware synchronized, is enabled + * b. Another channel (Channel x), software synchronized, is enabled. + * c. Channel i is disabled before end of transfer + * d. Channel i is reenabled. + * e. Steps 1 to 4 are repeated a certain number of times. + * f. A third channel (Channel y), software synchronized, is enabled. + * Channel x and Channel y may hang immediately after step 'f'. + * Workaround: + * For any channel used - make sure NextLCH_ID is set to the value j. + */ + if (cpu_is_omap2420() || (cpu_is_omap2430() && + (omap_type() == OMAP2430_REV_ES1_0))) { + + SET_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING); + SET_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS); + } + + /* + * Erratum ID: i378: OMAP2+: sDMA Channel is not disabled + * after a transaction error. + * Workaround: SW should explicitely disable the channel. + */ + if (cpu_class_is_omap2()) + SET_DMA_ERRATA(DMA_ERRATA_i378); + + /* + * Erratum ID: i541: sDMA FIFO draining does not finish + * If sDMA channel is disabled on the fly, sDMA enters standby even + * through FIFO Drain is still in progress + * Workaround: Put sDMA in NoStandby more before a logical channel is + * disabled, then put it back to SmartStandby right after the channel + * finishes FIFO draining. + */ + if (cpu_is_omap34xx()) + SET_DMA_ERRATA(DMA_ERRATA_i541); + + /* + * Erratum ID: i88 : Special programming model needed to disable DMA + * before end of block. + * Workaround: software must ensure that the DMA is configured in No + * Standby mode(DMAx_OCP_SYSCONFIG.MIDLEMODE = "01") + */ + if (omap_type() == OMAP3430_REV_ES1_0) + SET_DMA_ERRATA(DMA_ERRATA_i88); + + /* + * Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is + * read before the DMA controller finished disabling the channel. + */ + SET_DMA_ERRATA(DMA_ERRATA_3_3); + + /* + * Erratum ID: Not Available + * A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared + * after secure sram context save and restore. + * Work around: Hence we need to manually clear those IRQs to avoid + * spurious interrupts. This affects only secure devices. + */ + if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) + SET_DMA_ERRATA(DMA_ROMCODE_BUG); + + return errata; +} + +static struct omap_system_dma_plat_info dma_plat_info __initdata = { + .reg_map = reg_map, + .channel_stride = 0x60, + .show_dma_caps = omap2_show_dma_caps, + .clear_dma = omap2_clear_dma, + .dma_write = dma_write, + .dma_read = dma_read, +}; + +static struct platform_device_info omap_dma_dev_info = { + .name = "omap-dma-engine", + .id = -1, + .dma_mask = DMA_BIT_MASK(32), +}; + +/* One time initializations */ +static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) +{ + struct platform_device *pdev; + struct omap_system_dma_plat_info p; + struct omap_dma_dev_attr *d; + struct resource *mem; + char *name = "omap_dma_system"; + + p = dma_plat_info; + p.dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr; + p.errata = configure_dma_errata(); + + pdev = omap_device_build(name, 0, oh, &p, sizeof(p)); + if (IS_ERR(pdev)) { + pr_err("%s: Can't build omap_device for %s:%s.\n", + __func__, name, oh->name); + return PTR_ERR(pdev); + } + + omap_dma_dev_info.res = pdev->resource; + omap_dma_dev_info.num_res = pdev->num_resources; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { + dev_err(&pdev->dev, "%s: no mem resource\n", __func__); + return -EINVAL; + } + + dma_base = ioremap(mem->start, resource_size(mem)); + if (!dma_base) { + dev_err(&pdev->dev, "%s: ioremap fail\n", __func__); + return -ENOMEM; + } + + d = oh->dev_attr; + + if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) + d->dev_caps |= HS_CHANNELS_RESERVED; + + /* Check the capabilities register for descriptor loading feature */ + if (dma_read(CAPS_0, 0) & DMA_HAS_DESCRIPTOR_CAPS) + dma_common_ch_end = CCDN; + else + dma_common_ch_end = CCFN; + + return 0; +} + +static int __init omap2_system_dma_init(void) +{ + struct platform_device *pdev; + int res; + + res = omap_hwmod_for_each_by_class("dma", + omap2_system_dma_init_dev, NULL); + if (res) + return res; + + if (of_have_populated_dt()) + return res; + + pdev = platform_device_register_full(&omap_dma_dev_info); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + return res; +} +omap_arch_initcall(omap2_system_dma_init); diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c new file mode 100644 index 00000000000..6d7ba37e225 --- /dev/null +++ b/arch/arm/mach-omap2/dpll3xxx.c @@ -0,0 +1,750 @@ +/* + * OMAP3/4 - specific DPLL control functions + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * Copyright (C) 2009-2010 Nokia Corporation + * + * Written by Paul Walmsley + * Testing and integration fixes by Jouni Högander + * + * 36xx support added by Vishwanath BS, Richard Woodruff, and Nishanth + * Menon + * + * Parts of this code are based on code written by + * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/device.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/delay.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/bitops.h> +#include <linux/clkdev.h> + +#include "soc.h" +#include "clockdomain.h" +#include "clock.h" +#include "cm2xxx_3xxx.h" +#include "cm-regbits-34xx.h" + +/* CM_AUTOIDLE_PLL*.AUTO_* bit values */ +#define DPLL_AUTOIDLE_DISABLE 0x0 +#define DPLL_AUTOIDLE_LOW_POWER_STOP 0x1 + +#define MAX_DPLL_WAIT_TRIES 1000000 + +/* Private functions */ + +/* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */ +static void _omap3_dpll_write_clken(struct clk_hw_omap *clk, u8 clken_bits) +{ + const struct dpll_data *dd; + u32 v; + + dd = clk->dpll_data; + + v = omap2_clk_readl(clk, dd->control_reg); + v &= ~dd->enable_mask; + v |= clken_bits << __ffs(dd->enable_mask); + omap2_clk_writel(v, clk, dd->control_reg); +} + +/* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */ +static int _omap3_wait_dpll_status(struct clk_hw_omap *clk, u8 state) +{ + const struct dpll_data *dd; + int i = 0; + int ret = -EINVAL; + const char *clk_name; + + dd = clk->dpll_data; + clk_name = __clk_get_name(clk->hw.clk); + + state <<= __ffs(dd->idlest_mask); + + while (((omap2_clk_readl(clk, dd->idlest_reg) & dd->idlest_mask) + != state) && i < MAX_DPLL_WAIT_TRIES) { + i++; + udelay(1); + } + + if (i == MAX_DPLL_WAIT_TRIES) { + printk(KERN_ERR "clock: %s failed transition to '%s'\n", + clk_name, (state) ? "locked" : "bypassed"); + } else { + pr_debug("clock: %s transition to '%s' in %d loops\n", + clk_name, (state) ? "locked" : "bypassed", i); + + ret = 0; + } + + return ret; +} + +/* From 3430 TRM ES2 4.7.6.2 */ +static u16 _omap3_dpll_compute_freqsel(struct clk_hw_omap *clk, u8 n) +{ + unsigned long fint; + u16 f = 0; + + fint = __clk_get_rate(clk->dpll_data->clk_ref) / n; + + pr_debug("clock: fint is %lu\n", fint); + + if (fint >= 750000 && fint <= 1000000) + f = 0x3; + else if (fint > 1000000 && fint <= 1250000) + f = 0x4; + else if (fint > 1250000 && fint <= 1500000) + f = 0x5; + else if (fint > 1500000 && fint <= 1750000) + f = 0x6; + else if (fint > 1750000 && fint <= 2100000) + f = 0x7; + else if (fint > 7500000 && fint <= 10000000) + f = 0xB; + else if (fint > 10000000 && fint <= 12500000) + f = 0xC; + else if (fint > 12500000 && fint <= 15000000) + f = 0xD; + else if (fint > 15000000 && fint <= 17500000) + f = 0xE; + else if (fint > 17500000 && fint <= 21000000) + f = 0xF; + else + pr_debug("clock: unknown freqsel setting for %d\n", n); + + return f; +} + +/* + * _omap3_noncore_dpll_lock - instruct a DPLL to lock and wait for readiness + * @clk: pointer to a DPLL struct clk + * + * Instructs a non-CORE DPLL to lock. Waits for the DPLL to report + * readiness before returning. Will save and restore the DPLL's + * autoidle state across the enable, per the CDP code. If the DPLL + * locked successfully, return 0; if the DPLL did not lock in the time + * allotted, or DPLL3 was passed in, return -EINVAL. + */ +static int _omap3_noncore_dpll_lock(struct clk_hw_omap *clk) +{ + const struct dpll_data *dd; + u8 ai; + u8 state = 1; + int r = 0; + + pr_debug("clock: locking DPLL %s\n", __clk_get_name(clk->hw.clk)); + + dd = clk->dpll_data; + state <<= __ffs(dd->idlest_mask); + + /* Check if already locked */ + if ((omap2_clk_readl(clk, dd->idlest_reg) & dd->idlest_mask) == state) + goto done; + + ai = omap3_dpll_autoidle_read(clk); + + if (ai) + omap3_dpll_deny_idle(clk); + + _omap3_dpll_write_clken(clk, DPLL_LOCKED); + + r = _omap3_wait_dpll_status(clk, 1); + + if (ai) + omap3_dpll_allow_idle(clk); + +done: + return r; +} + +/* + * _omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness + * @clk: pointer to a DPLL struct clk + * + * Instructs a non-CORE DPLL to enter low-power bypass mode. In + * bypass mode, the DPLL's rate is set equal to its parent clock's + * rate. Waits for the DPLL to report readiness before returning. + * Will save and restore the DPLL's autoidle state across the enable, + * per the CDP code. If the DPLL entered bypass mode successfully, + * return 0; if the DPLL did not enter bypass in the time allotted, or + * DPLL3 was passed in, or the DPLL does not support low-power bypass, + * return -EINVAL. + */ +static int _omap3_noncore_dpll_bypass(struct clk_hw_omap *clk) +{ + int r; + u8 ai; + + if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) + return -EINVAL; + + pr_debug("clock: configuring DPLL %s for low-power bypass\n", + __clk_get_name(clk->hw.clk)); + + ai = omap3_dpll_autoidle_read(clk); + + _omap3_dpll_write_clken(clk, DPLL_LOW_POWER_BYPASS); + + r = _omap3_wait_dpll_status(clk, 0); + + if (ai) + omap3_dpll_allow_idle(clk); + + return r; +} + +/* + * _omap3_noncore_dpll_stop - instruct a DPLL to stop + * @clk: pointer to a DPLL struct clk + * + * Instructs a non-CORE DPLL to enter low-power stop. Will save and + * restore the DPLL's autoidle state across the stop, per the CDP + * code. If DPLL3 was passed in, or the DPLL does not support + * low-power stop, return -EINVAL; otherwise, return 0. + */ +static int _omap3_noncore_dpll_stop(struct clk_hw_omap *clk) +{ + u8 ai; + + if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP))) + return -EINVAL; + + pr_debug("clock: stopping DPLL %s\n", __clk_get_name(clk->hw.clk)); + + ai = omap3_dpll_autoidle_read(clk); + + _omap3_dpll_write_clken(clk, DPLL_LOW_POWER_STOP); + + if (ai) + omap3_dpll_allow_idle(clk); + + return 0; +} + +/** + * _lookup_dco - Lookup DCO used by j-type DPLL + * @clk: pointer to a DPLL struct clk + * @dco: digital control oscillator selector + * @m: DPLL multiplier to set + * @n: DPLL divider to set + * + * See 36xx TRM section 3.5.3.3.3.2 "Type B DPLL (Low-Jitter)" + * + * XXX This code is not needed for 3430/AM35xx; can it be optimized + * out in non-multi-OMAP builds for those chips? + */ +static void _lookup_dco(struct clk_hw_omap *clk, u8 *dco, u16 m, u8 n) +{ + unsigned long fint, clkinp; /* watch out for overflow */ + + clkinp = __clk_get_rate(__clk_get_parent(clk->hw.clk)); + fint = (clkinp / n) * m; + + if (fint < 1000000000) + *dco = 2; + else + *dco = 4; +} + +/** + * _lookup_sddiv - Calculate sigma delta divider for j-type DPLL + * @clk: pointer to a DPLL struct clk + * @sd_div: target sigma-delta divider + * @m: DPLL multiplier to set + * @n: DPLL divider to set + * + * See 36xx TRM section 3.5.3.3.3.2 "Type B DPLL (Low-Jitter)" + * + * XXX This code is not needed for 3430/AM35xx; can it be optimized + * out in non-multi-OMAP builds for those chips? + */ +static void _lookup_sddiv(struct clk_hw_omap *clk, u8 *sd_div, u16 m, u8 n) +{ + unsigned long clkinp, sd; /* watch out for overflow */ + int mod1, mod2; + + clkinp = __clk_get_rate(__clk_get_parent(clk->hw.clk)); + + /* + * target sigma-delta to near 250MHz + * sd = ceil[(m/(n+1)) * (clkinp_MHz / 250)] + */ + clkinp /= 100000; /* shift from MHz to 10*Hz for 38.4 and 19.2 */ + mod1 = (clkinp * m) % (250 * n); + sd = (clkinp * m) / (250 * n); + mod2 = sd % 10; + sd /= 10; + + if (mod1 || mod2) + sd++; + *sd_div = sd; +} + +/* + * _omap3_noncore_dpll_program - set non-core DPLL M,N values directly + * @clk: struct clk * of DPLL to set + * @freqsel: FREQSEL value to set + * + * Program the DPLL with the last M, N values calculated, and wait for + * the DPLL to lock. Returns -EINVAL upon error, or 0 upon success. + */ +static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 freqsel) +{ + struct dpll_data *dd = clk->dpll_data; + u8 dco, sd_div; + u32 v; + + /* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */ + _omap3_noncore_dpll_bypass(clk); + + /* + * Set jitter correction. Jitter correction applicable for OMAP343X + * only since freqsel field is no longer present on other devices. + */ + if (cpu_is_omap343x()) { + v = omap2_clk_readl(clk, dd->control_reg); + v &= ~dd->freqsel_mask; + v |= freqsel << __ffs(dd->freqsel_mask); + omap2_clk_writel(v, clk, dd->control_reg); + } + + /* Set DPLL multiplier, divider */ + v = omap2_clk_readl(clk, dd->mult_div1_reg); + + /* Handle Duty Cycle Correction */ + if (dd->dcc_mask) { + if (dd->last_rounded_rate >= dd->dcc_rate) + v |= dd->dcc_mask; /* Enable DCC */ + else + v &= ~dd->dcc_mask; /* Disable DCC */ + } + + v &= ~(dd->mult_mask | dd->div1_mask); + v |= dd->last_rounded_m << __ffs(dd->mult_mask); + v |= (dd->last_rounded_n - 1) << __ffs(dd->div1_mask); + + /* Configure dco and sd_div for dplls that have these fields */ + if (dd->dco_mask) { + _lookup_dco(clk, &dco, dd->last_rounded_m, dd->last_rounded_n); + v &= ~(dd->dco_mask); + v |= dco << __ffs(dd->dco_mask); + } + if (dd->sddiv_mask) { + _lookup_sddiv(clk, &sd_div, dd->last_rounded_m, + dd->last_rounded_n); + v &= ~(dd->sddiv_mask); + v |= sd_div << __ffs(dd->sddiv_mask); + } + + omap2_clk_writel(v, clk, dd->mult_div1_reg); + + /* Set 4X multiplier and low-power mode */ + if (dd->m4xen_mask || dd->lpmode_mask) { + v = omap2_clk_readl(clk, dd->control_reg); + + if (dd->m4xen_mask) { + if (dd->last_rounded_m4xen) + v |= dd->m4xen_mask; + else + v &= ~dd->m4xen_mask; + } + + if (dd->lpmode_mask) { + if (dd->last_rounded_lpmode) + v |= dd->lpmode_mask; + else + v &= ~dd->lpmode_mask; + } + + omap2_clk_writel(v, clk, dd->control_reg); + } + + /* We let the clock framework set the other output dividers later */ + + /* REVISIT: Set ramp-up delay? */ + + _omap3_noncore_dpll_lock(clk); + + return 0; +} + +/* Public functions */ + +/** + * omap3_dpll_recalc - recalculate DPLL rate + * @clk: DPLL struct clk + * + * Recalculate and propagate the DPLL rate. + */ +unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + + return omap2_get_dpll_rate(clk); +} + +/* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */ + +/** + * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode + * @clk: pointer to a DPLL struct clk + * + * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock. + * The choice of modes depends on the DPLL's programmed rate: if it is + * the same as the DPLL's parent clock, it will enter bypass; + * otherwise, it will enter lock. This code will wait for the DPLL to + * indicate readiness before returning, unless the DPLL takes too long + * to enter the target state. Intended to be used as the struct clk's + * enable function. If DPLL3 was passed in, or the DPLL does not + * support low-power stop, or if the DPLL took too long to enter + * bypass or lock, return -EINVAL; otherwise, return 0. + */ +int omap3_noncore_dpll_enable(struct clk_hw *hw) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + int r; + struct dpll_data *dd; + struct clk *parent; + + dd = clk->dpll_data; + if (!dd) + return -EINVAL; + + if (clk->clkdm) { + r = clkdm_clk_enable(clk->clkdm, hw->clk); + if (r) { + WARN(1, + "%s: could not enable %s's clockdomain %s: %d\n", + __func__, __clk_get_name(hw->clk), + clk->clkdm->name, r); + return r; + } + } + + parent = __clk_get_parent(hw->clk); + + if (__clk_get_rate(hw->clk) == __clk_get_rate(dd->clk_bypass)) { + WARN_ON(parent != dd->clk_bypass); + r = _omap3_noncore_dpll_bypass(clk); + } else { + WARN_ON(parent != dd->clk_ref); + r = _omap3_noncore_dpll_lock(clk); + } + + return r; +} + +/** + * omap3_noncore_dpll_disable - instruct a DPLL to enter low-power stop + * @clk: pointer to a DPLL struct clk + * + * Instructs a non-CORE DPLL to enter low-power stop. This function is + * intended for use in struct clkops. No return value. + */ +void omap3_noncore_dpll_disable(struct clk_hw *hw) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + + _omap3_noncore_dpll_stop(clk); + if (clk->clkdm) + clkdm_clk_disable(clk->clkdm, hw->clk); +} + + +/* Non-CORE DPLL rate set code */ + +/** + * omap3_noncore_dpll_set_rate - set non-core DPLL rate + * @clk: struct clk * of DPLL to set + * @rate: rounded target rate + * + * Set the DPLL CLKOUT to the target rate. If the DPLL can enter + * low-power bypass, and the target rate is the bypass source clock + * rate, then configure the DPLL for bypass. Otherwise, round the + * target rate if it hasn't been done already, then program and lock + * the DPLL. Returns -EINVAL upon error, or 0 upon success. + */ +int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + struct clk *new_parent = NULL; + u16 freqsel = 0; + struct dpll_data *dd; + int ret; + + if (!hw || !rate) + return -EINVAL; + + dd = clk->dpll_data; + if (!dd) + return -EINVAL; + + if (__clk_get_rate(dd->clk_bypass) == rate && + (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { + pr_debug("%s: %s: set rate: entering bypass.\n", + __func__, __clk_get_name(hw->clk)); + + __clk_prepare(dd->clk_bypass); + clk_enable(dd->clk_bypass); + ret = _omap3_noncore_dpll_bypass(clk); + if (!ret) + new_parent = dd->clk_bypass; + clk_disable(dd->clk_bypass); + __clk_unprepare(dd->clk_bypass); + } else { + __clk_prepare(dd->clk_ref); + clk_enable(dd->clk_ref); + + if (dd->last_rounded_rate != rate) + rate = __clk_round_rate(hw->clk, rate); + + if (dd->last_rounded_rate == 0) + return -EINVAL; + + /* Freqsel is available only on OMAP343X devices */ + if (cpu_is_omap343x()) { + freqsel = _omap3_dpll_compute_freqsel(clk, + dd->last_rounded_n); + WARN_ON(!freqsel); + } + + pr_debug("%s: %s: set rate: locking rate to %lu.\n", + __func__, __clk_get_name(hw->clk), rate); + + ret = omap3_noncore_dpll_program(clk, freqsel); + if (!ret) + new_parent = dd->clk_ref; + clk_disable(dd->clk_ref); + __clk_unprepare(dd->clk_ref); + } + /* + * FIXME - this is all wrong. common code handles reparenting and + * migrating prepare/enable counts. dplls should be a multiplexer + * clock and this should be a set_parent operation so that all of that + * stuff is inherited for free + */ + + if (!ret && clk_get_parent(hw->clk) != new_parent) + __clk_reparent(hw->clk, new_parent); + + return 0; +} + +/* DPLL autoidle read/set code */ + +/** + * omap3_dpll_autoidle_read - read a DPLL's autoidle bits + * @clk: struct clk * of the DPLL to read + * + * Return the DPLL's autoidle bits, shifted down to bit 0. Returns + * -EINVAL if passed a null pointer or if the struct clk does not + * appear to refer to a DPLL. + */ +u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk) +{ + const struct dpll_data *dd; + u32 v; + + if (!clk || !clk->dpll_data) + return -EINVAL; + + dd = clk->dpll_data; + + if (!dd->autoidle_reg) + return -EINVAL; + + v = omap2_clk_readl(clk, dd->autoidle_reg); + v &= dd->autoidle_mask; + v >>= __ffs(dd->autoidle_mask); + + return v; +} + +/** + * omap3_dpll_allow_idle - enable DPLL autoidle bits + * @clk: struct clk * of the DPLL to operate on + * + * Enable DPLL automatic idle control. This automatic idle mode + * switching takes effect only when the DPLL is locked, at least on + * OMAP3430. The DPLL will enter low-power stop when its downstream + * clocks are gated. No return value. + */ +void omap3_dpll_allow_idle(struct clk_hw_omap *clk) +{ + const struct dpll_data *dd; + u32 v; + + if (!clk || !clk->dpll_data) + return; + + dd = clk->dpll_data; + + if (!dd->autoidle_reg) + return; + + /* + * REVISIT: CORE DPLL can optionally enter low-power bypass + * by writing 0x5 instead of 0x1. Add some mechanism to + * optionally enter this mode. + */ + v = omap2_clk_readl(clk, dd->autoidle_reg); + v &= ~dd->autoidle_mask; + v |= DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask); + omap2_clk_writel(v, clk, dd->autoidle_reg); + +} + +/** + * omap3_dpll_deny_idle - prevent DPLL from automatically idling + * @clk: struct clk * of the DPLL to operate on + * + * Disable DPLL automatic idle control. No return value. + */ +void omap3_dpll_deny_idle(struct clk_hw_omap *clk) +{ + const struct dpll_data *dd; + u32 v; + + if (!clk || !clk->dpll_data) + return; + + dd = clk->dpll_data; + + if (!dd->autoidle_reg) + return; + + v = omap2_clk_readl(clk, dd->autoidle_reg); + v &= ~dd->autoidle_mask; + v |= DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask); + omap2_clk_writel(v, clk, dd->autoidle_reg); + +} + +/* Clock control for DPLL outputs */ + +/* Find the parent DPLL for the given clkoutx2 clock */ +static struct clk_hw_omap *omap3_find_clkoutx2_dpll(struct clk_hw *hw) +{ + struct clk_hw_omap *pclk = NULL; + struct clk *parent; + + /* Walk up the parents of clk, looking for a DPLL */ + do { + do { + parent = __clk_get_parent(hw->clk); + hw = __clk_get_hw(parent); + } while (hw && (__clk_get_flags(hw->clk) & CLK_IS_BASIC)); + if (!hw) + break; + pclk = to_clk_hw_omap(hw); + } while (pclk && !pclk->dpll_data); + + /* clk does not have a DPLL as a parent? error in the clock data */ + if (!pclk) { + WARN_ON(1); + return NULL; + } + + return pclk; +} + +/** + * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate + * @clk: DPLL output struct clk + * + * Using parent clock DPLL data, look up DPLL state. If locked, set our + * rate to the dpll_clk * 2; otherwise, just use dpll_clk. + */ +unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw, + unsigned long parent_rate) +{ + const struct dpll_data *dd; + unsigned long rate; + u32 v; + struct clk_hw_omap *pclk = NULL; + + if (!parent_rate) + return 0; + + pclk = omap3_find_clkoutx2_dpll(hw); + + if (!pclk) + return 0; + + dd = pclk->dpll_data; + + WARN_ON(!dd->enable_mask); + + v = omap2_clk_readl(pclk, dd->control_reg) & dd->enable_mask; + v >>= __ffs(dd->enable_mask); + if ((v != OMAP3XXX_EN_DPLL_LOCKED) || (dd->flags & DPLL_J_TYPE)) + rate = parent_rate; + else + rate = parent_rate * 2; + return rate; +} + +int omap3_clkoutx2_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + return 0; +} + +long omap3_clkoutx2_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + const struct dpll_data *dd; + u32 v; + struct clk_hw_omap *pclk = NULL; + + if (!*prate) + return 0; + + pclk = omap3_find_clkoutx2_dpll(hw); + + if (!pclk) + return 0; + + dd = pclk->dpll_data; + + /* TYPE J does not have a clkoutx2 */ + if (dd->flags & DPLL_J_TYPE) { + *prate = __clk_round_rate(__clk_get_parent(pclk->hw.clk), rate); + return *prate; + } + + WARN_ON(!dd->enable_mask); + + v = omap2_clk_readl(pclk, dd->control_reg) & dd->enable_mask; + v >>= __ffs(dd->enable_mask); + + /* If in bypass, the rate is fixed to the bypass rate*/ + if (v != OMAP3XXX_EN_DPLL_LOCKED) + return *prate; + + if (__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT) { + unsigned long best_parent; + + best_parent = (rate / 2); + *prate = __clk_round_rate(__clk_get_parent(hw->clk), + best_parent); + } + + return *prate * 2; +} + +/* OMAP3/4 non-CORE DPLL clkops */ +const struct clk_hw_omap_ops clkhwops_omap3_dpll = { + .allow_idle = omap3_dpll_allow_idle, + .deny_idle = omap3_dpll_deny_idle, +}; diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c new file mode 100644 index 00000000000..52f9438b92f --- /dev/null +++ b/arch/arm/mach-omap2/dpll44xx.c @@ -0,0 +1,202 @@ +/* + * OMAP4-specific DPLL control functions + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Rajendra Nayak + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/bitops.h> + +#include "soc.h" +#include "clock.h" +#include "clock44xx.h" +#include "cm-regbits-44xx.h" + +/* + * Maximum DPLL input frequency (FINT) and output frequency (FOUT) that + * can supported when using the DPLL low-power mode. Frequencies are + * defined in OMAP4430/60 Public TRM section 3.6.3.3.2 "Enable Control, + * Status, and Low-Power Operation Mode". + */ +#define OMAP4_DPLL_LP_FINT_MAX 1000000 +#define OMAP4_DPLL_LP_FOUT_MAX 100000000 + +/* Supported only on OMAP4 */ +int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk) +{ + u32 v; + u32 mask; + + if (!clk || !clk->clksel_reg || !cpu_is_omap44xx()) + return -EINVAL; + + mask = clk->flags & CLOCK_CLKOUTX2 ? + OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK : + OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK; + + v = omap2_clk_readl(clk, clk->clksel_reg); + v &= mask; + v >>= __ffs(mask); + + return v; +} + +void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk) +{ + u32 v; + u32 mask; + + if (!clk || !clk->clksel_reg || !cpu_is_omap44xx()) + return; + + mask = clk->flags & CLOCK_CLKOUTX2 ? + OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK : + OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK; + + v = omap2_clk_readl(clk, clk->clksel_reg); + /* Clear the bit to allow gatectrl */ + v &= ~mask; + omap2_clk_writel(v, clk, clk->clksel_reg); +} + +void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk) +{ + u32 v; + u32 mask; + + if (!clk || !clk->clksel_reg || !cpu_is_omap44xx()) + return; + + mask = clk->flags & CLOCK_CLKOUTX2 ? + OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK : + OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK; + + v = omap2_clk_readl(clk, clk->clksel_reg); + /* Set the bit to deny gatectrl */ + v |= mask; + omap2_clk_writel(v, clk, clk->clksel_reg); +} + +const struct clk_hw_omap_ops clkhwops_omap4_dpllmx = { + .allow_idle = omap4_dpllmx_allow_gatectrl, + .deny_idle = omap4_dpllmx_deny_gatectrl, +}; + +/** + * omap4_dpll_lpmode_recalc - compute DPLL low-power setting + * @dd: pointer to the dpll data structure + * + * Calculates if low-power mode can be enabled based upon the last + * multiplier and divider values calculated. If low-power mode can be + * enabled, then the bit to enable low-power mode is stored in the + * last_rounded_lpmode variable. This implementation is based upon the + * criteria for enabling low-power mode as described in the OMAP4430/60 + * Public TRM section 3.6.3.3.2 "Enable Control, Status, and Low-Power + * Operation Mode". + */ +static void omap4_dpll_lpmode_recalc(struct dpll_data *dd) +{ + long fint, fout; + + fint = __clk_get_rate(dd->clk_ref) / (dd->last_rounded_n + 1); + fout = fint * dd->last_rounded_m; + + if ((fint < OMAP4_DPLL_LP_FINT_MAX) && (fout < OMAP4_DPLL_LP_FOUT_MAX)) + dd->last_rounded_lpmode = 1; + else + dd->last_rounded_lpmode = 0; +} + +/** + * omap4_dpll_regm4xen_recalc - compute DPLL rate, considering REGM4XEN bit + * @clk: struct clk * of the DPLL to compute the rate for + * + * Compute the output rate for the OMAP4 DPLL represented by @clk. + * Takes the REGM4XEN bit into consideration, which is needed for the + * OMAP4 ABE DPLL. Returns the DPLL's output rate (before M-dividers) + * upon success, or 0 upon error. + */ +unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + u32 v; + unsigned long rate; + struct dpll_data *dd; + + if (!clk || !clk->dpll_data) + return 0; + + dd = clk->dpll_data; + + rate = omap2_get_dpll_rate(clk); + + /* regm4xen adds a multiplier of 4 to DPLL calculations */ + v = omap2_clk_readl(clk, dd->control_reg); + if (v & OMAP4430_DPLL_REGM4XEN_MASK) + rate *= OMAP4430_REGM4XEN_MULT; + + return rate; +} + +/** + * omap4_dpll_regm4xen_round_rate - round DPLL rate, considering REGM4XEN bit + * @clk: struct clk * of the DPLL to round a rate for + * @target_rate: the desired rate of the DPLL + * + * Compute the rate that would be programmed into the DPLL hardware + * for @clk if set_rate() were to be provided with the rate + * @target_rate. Takes the REGM4XEN bit into consideration, which is + * needed for the OMAP4 ABE DPLL. Returns the rounded rate (before + * M-dividers) upon success, -EINVAL if @clk is null or not a DPLL, or + * ~0 if an error occurred in omap2_dpll_round_rate(). + */ +long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw, + unsigned long target_rate, + unsigned long *parent_rate) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + struct dpll_data *dd; + long r; + + if (!clk || !clk->dpll_data) + return -EINVAL; + + dd = clk->dpll_data; + + dd->last_rounded_m4xen = 0; + + /* + * First try to compute the DPLL configuration for + * target rate without using the 4X multiplier. + */ + r = omap2_dpll_round_rate(hw, target_rate, NULL); + if (r != ~0) + goto out; + + /* + * If we did not find a valid DPLL configuration, try again, but + * this time see if using the 4X multiplier can help. Enabling the + * 4X multiplier is equivalent to dividing the target rate by 4. + */ + r = omap2_dpll_round_rate(hw, target_rate / OMAP4430_REGM4XEN_MULT, + NULL); + if (r == ~0) + return r; + + dd->last_rounded_rate *= OMAP4430_REGM4XEN_MULT; + dd->last_rounded_m4xen = 1; + +out: + omap4_dpll_lpmode_recalc(dd); + + return dd->last_rounded_rate; +} diff --git a/arch/arm/mach-omap2/drm.c b/arch/arm/mach-omap2/drm.c new file mode 100644 index 00000000000..facd7406a03 --- /dev/null +++ b/arch/arm/mach-omap2/drm.c @@ -0,0 +1,53 @@ +/* + * DRM/KMS device registration for TI OMAP platforms + * + * Copyright (C) 2012 Texas Instruments + * Author: Rob Clark <rob.clark@linaro.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/platform_data/omap_drm.h> + +#include "soc.h" +#include "display.h" + +#if defined(CONFIG_DRM_OMAP) || defined(CONFIG_DRM_OMAP_MODULE) + +static struct omap_drm_platform_data platform_data; + +static struct platform_device omap_drm_device = { + .dev = { + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &platform_data, + }, + .name = "omapdrm", + .id = 0, +}; + +int __init omap_init_drm(void) +{ + platform_data.omaprev = GET_OMAP_TYPE; + + return platform_device_register(&omap_drm_device); + +} +#else +int __init omap_init_drm(void) { return 0; } +#endif diff --git a/arch/arm/mach-omap2/dsp.c b/arch/arm/mach-omap2/dsp.c new file mode 100644 index 00000000000..f7492df1cbb --- /dev/null +++ b/arch/arm/mach-omap2/dsp.c @@ -0,0 +1,134 @@ +/* + * TI's OMAP DSP platform device registration + * + * Copyright (C) 2005-2006 Texas Instruments, Inc. + * Copyright (C) 2009 Nokia Corporation + * + * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * XXX The function pointers to the PRM/CM functions are incorrect and + * should be removed. No device driver should be changing PRM/CM bits + * directly; that's a layering violation -- those bits are the responsibility + * of the OMAP PM core code. + */ + +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <asm/memblock.h> + +#include "control.h" +#include "cm2xxx_3xxx.h" +#include "prm2xxx_3xxx.h" +#ifdef CONFIG_TIDSPBRIDGE_DVFS +#include "omap-pm.h" +#endif +#include "soc.h" + +#include <linux/platform_data/dsp-omap.h> + +static struct platform_device *omap_dsp_pdev; + +static struct omap_dsp_platform_data omap_dsp_pdata __initdata = { +#ifdef CONFIG_TIDSPBRIDGE_DVFS + .dsp_set_min_opp = omap_pm_dsp_set_min_opp, + .dsp_get_opp = omap_pm_dsp_get_opp, + .cpu_set_freq = omap_pm_cpu_set_freq, + .cpu_get_freq = omap_pm_cpu_get_freq, +#endif + .dsp_prm_read = omap2_prm_read_mod_reg, + .dsp_prm_write = omap2_prm_write_mod_reg, + .dsp_prm_rmw_bits = omap2_prm_rmw_mod_reg_bits, + .dsp_cm_read = omap2_cm_read_mod_reg, + .dsp_cm_write = omap2_cm_write_mod_reg, + .dsp_cm_rmw_bits = omap2_cm_rmw_mod_reg_bits, + + .set_bootaddr = omap_ctrl_write_dsp_boot_addr, + .set_bootmode = omap_ctrl_write_dsp_boot_mode, +}; + +static phys_addr_t omap_dsp_phys_mempool_base; + +void __init omap_dsp_reserve_sdram_memblock(void) +{ + phys_addr_t size = CONFIG_TIDSPBRIDGE_MEMPOOL_SIZE; + phys_addr_t paddr; + + if (!cpu_is_omap34xx()) + return; + + if (!size) + return; + + paddr = arm_memblock_steal(size, SZ_1M); + if (!paddr) { + pr_err("%s: failed to reserve %llx bytes\n", + __func__, (unsigned long long)size); + return; + } + + omap_dsp_phys_mempool_base = paddr; +} + +static phys_addr_t omap_dsp_get_mempool_base(void) +{ + return omap_dsp_phys_mempool_base; +} + +static int __init omap_dsp_init(void) +{ + struct platform_device *pdev; + int err = -ENOMEM; + struct omap_dsp_platform_data *pdata = &omap_dsp_pdata; + + if (!cpu_is_omap34xx()) + return 0; + + pdata->phys_mempool_base = omap_dsp_get_mempool_base(); + + if (pdata->phys_mempool_base) { + pdata->phys_mempool_size = CONFIG_TIDSPBRIDGE_MEMPOOL_SIZE; + pr_info("%s: %llx bytes @ %llx\n", __func__, + (unsigned long long)pdata->phys_mempool_size, + (unsigned long long)pdata->phys_mempool_base); + } + + pdev = platform_device_alloc("omap-dsp", -1); + if (!pdev) + goto err_out; + + err = platform_device_add_data(pdev, pdata, sizeof(*pdata)); + if (err) + goto err_out; + + err = platform_device_add(pdev); + if (err) + goto err_out; + + omap_dsp_pdev = pdev; + return 0; + +err_out: + platform_device_put(pdev); + return err; +} +module_init(omap_dsp_init); + +static void __exit omap_dsp_exit(void) +{ + if (!cpu_is_omap34xx()) + return; + + platform_device_unregister(omap_dsp_pdev); +} +module_exit(omap_dsp_exit); + +MODULE_AUTHOR("Hiroshi DOYU"); +MODULE_DESCRIPTION("TI's OMAP DSP platform device registration"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-omap2/dss-common.c b/arch/arm/mach-omap2/dss-common.c new file mode 100644 index 00000000000..ea2be0f5953 --- /dev/null +++ b/arch/arm/mach-omap2/dss-common.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2012 Texas Instruments, Inc.. + * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +/* + * NOTE: this is a transitional file to help with DT adaptation. + * This file will be removed when DSS supports DT. + */ + +#include <linux/kernel.h> +#include <linux/gpio.h> +#include <linux/platform_device.h> + +#include <video/omapdss.h> +#include <video/omap-panel-data.h> + +#include "soc.h" +#include "dss-common.h" +#include "mux.h" +#include "display.h" + diff --git a/arch/arm/mach-omap2/dss-common.h b/arch/arm/mach-omap2/dss-common.h new file mode 100644 index 00000000000..a9becf0d5be --- /dev/null +++ b/arch/arm/mach-omap2/dss-common.h @@ -0,0 +1,13 @@ +#ifndef __OMAP_DSS_COMMON__ +#define __OMAP_DSS_COMMON__ + +/* + * NOTE: this is a transitional file to help with DT adaptation. + * This file will be removed when DSS supports DT. + */ + +void __init omap4_panda_display_init_of(void); +void __init omap_4430sdp_display_init_of(void); +void __init omap3_igep2_display_init_of(void); + +#endif diff --git a/arch/arm/mach-omap2/emu.c b/arch/arm/mach-omap2/emu.c new file mode 100644 index 00000000000..cbeaca2d769 --- /dev/null +++ b/arch/arm/mach-omap2/emu.c @@ -0,0 +1,50 @@ +/* + * emu.c + * + * ETM and ETB CoreSight components' resources as found in OMAP3xxx. + * + * Copyright (C) 2009 Nokia Corporation. + * Alexander Shishkin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/types.h> +#include <linux/module.h> +#include <linux/device.h> +#include <linux/amba/bus.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/err.h> + +#include "soc.h" +#include "iomap.h" + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Alexander Shishkin"); + +/* Cortex CoreSight components within omap3xxx EMU */ +#define ETM_BASE (L4_EMU_34XX_PHYS + 0x10000) +#define DBG_BASE (L4_EMU_34XX_PHYS + 0x11000) +#define ETB_BASE (L4_EMU_34XX_PHYS + 0x1b000) +#define DAPCTL (L4_EMU_34XX_PHYS + 0x1d000) + +static AMBA_APB_DEVICE(omap3_etb, "etb", 0x000bb907, ETB_BASE, { }, NULL); +static AMBA_APB_DEVICE(omap3_etm, "etm", 0x102bb921, ETM_BASE, { }, NULL); + +static int __init emu_init(void) +{ + if (!cpu_is_omap34xx()) + return -ENODEV; + + amba_device_register(&omap3_etb_device, &iomem_resource); + amba_device_register(&omap3_etm_device, &iomem_resource); + + return 0; +} + +omap_subsys_initcall(emu_init); diff --git a/arch/arm/mach-omap2/fb.c b/arch/arm/mach-omap2/fb.c new file mode 100644 index 00000000000..26e28e94f62 --- /dev/null +++ b/arch/arm/mach-omap2/fb.c @@ -0,0 +1,115 @@ +/* + * Framebuffer device registration for TI OMAP platforms + * + * Copyright (C) 2006 Nokia Corporation + * Author: Imre Deak <imre.deak@nokia.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/memblock.h> +#include <linux/io.h> +#include <linux/omapfb.h> +#include <linux/dma-mapping.h> + +#include <asm/mach/map.h> + +#include "soc.h" +#include "display.h" + +#ifdef CONFIG_OMAP2_VRFB + +/* + * The first memory resource is the register region for VRFB, + * the rest are VRFB virtual memory areas for each VRFB context. + */ + +static const struct resource omap2_vrfb_resources[] = { + DEFINE_RES_MEM_NAMED(0x68008000u, 0x40, "vrfb-regs"), + DEFINE_RES_MEM_NAMED(0x70000000u, 0x4000000, "vrfb-area-0"), + DEFINE_RES_MEM_NAMED(0x74000000u, 0x4000000, "vrfb-area-1"), + DEFINE_RES_MEM_NAMED(0x78000000u, 0x4000000, "vrfb-area-2"), + DEFINE_RES_MEM_NAMED(0x7c000000u, 0x4000000, "vrfb-area-3"), +}; + +static const struct resource omap3_vrfb_resources[] = { + DEFINE_RES_MEM_NAMED(0x6C000180u, 0xc0, "vrfb-regs"), + DEFINE_RES_MEM_NAMED(0x70000000u, 0x4000000, "vrfb-area-0"), + DEFINE_RES_MEM_NAMED(0x74000000u, 0x4000000, "vrfb-area-1"), + DEFINE_RES_MEM_NAMED(0x78000000u, 0x4000000, "vrfb-area-2"), + DEFINE_RES_MEM_NAMED(0x7c000000u, 0x4000000, "vrfb-area-3"), + DEFINE_RES_MEM_NAMED(0xe0000000u, 0x4000000, "vrfb-area-4"), + DEFINE_RES_MEM_NAMED(0xe4000000u, 0x4000000, "vrfb-area-5"), + DEFINE_RES_MEM_NAMED(0xe8000000u, 0x4000000, "vrfb-area-6"), + DEFINE_RES_MEM_NAMED(0xec000000u, 0x4000000, "vrfb-area-7"), + DEFINE_RES_MEM_NAMED(0xf0000000u, 0x4000000, "vrfb-area-8"), + DEFINE_RES_MEM_NAMED(0xf4000000u, 0x4000000, "vrfb-area-9"), + DEFINE_RES_MEM_NAMED(0xf8000000u, 0x4000000, "vrfb-area-10"), + DEFINE_RES_MEM_NAMED(0xfc000000u, 0x4000000, "vrfb-area-11"), +}; + +int __init omap_init_vrfb(void) +{ + struct platform_device *pdev; + const struct resource *res; + unsigned int num_res; + + if (cpu_is_omap24xx()) { + res = omap2_vrfb_resources; + num_res = ARRAY_SIZE(omap2_vrfb_resources); + } else if (cpu_is_omap34xx()) { + res = omap3_vrfb_resources; + num_res = ARRAY_SIZE(omap3_vrfb_resources); + } else { + return 0; + } + + pdev = platform_device_register_resndata(NULL, "omapvrfb", -1, + res, num_res, NULL, 0); + + return PTR_RET(pdev); +} +#else +int __init omap_init_vrfb(void) { return 0; } +#endif + +#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) + +static u64 omap_fb_dma_mask = ~(u32)0; +static struct omapfb_platform_data omapfb_config; + +static struct platform_device omap_fb_device = { + .name = "omapfb", + .id = -1, + .dev = { + .dma_mask = &omap_fb_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &omapfb_config, + }, + .num_resources = 0, +}; + +int __init omap_init_fb(void) +{ + return platform_device_register(&omap_fb_device); +} +#else +int __init omap_init_fb(void) { return 0; } +#endif diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c new file mode 100644 index 00000000000..7a577145b68 --- /dev/null +++ b/arch/arm/mach-omap2/gpio.c @@ -0,0 +1,160 @@ +/* + * OMAP2+ specific gpio initialization + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * Author: + * Charulatha V <charu@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/gpio.h> +#include <linux/err.h> +#include <linux/slab.h> +#include <linux/interrupt.h> +#include <linux/of.h> +#include <linux/platform_data/gpio-omap.h> + +#include "soc.h" +#include "omap_hwmod.h" +#include "omap_device.h" +#include "omap-pm.h" + +#include "powerdomain.h" + +static int __init omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) +{ + struct platform_device *pdev; + struct omap_gpio_platform_data *pdata; + struct omap_gpio_dev_attr *dev_attr; + char *name = "omap_gpio"; + int id; + struct powerdomain *pwrdm; + + /* + * extract the device id from name field available in the + * hwmod database and use the same for constructing ids for + * gpio devices. + * CAUTION: Make sure the name in the hwmod database does + * not change. If changed, make corresponding change here + * or make use of static variable mechanism to handle this. + */ + sscanf(oh->name, "gpio%d", &id); + + pdata = kzalloc(sizeof(struct omap_gpio_platform_data), GFP_KERNEL); + if (!pdata) { + pr_err("gpio%d: Memory allocation failed\n", id); + return -ENOMEM; + } + + dev_attr = (struct omap_gpio_dev_attr *)oh->dev_attr; + pdata->bank_width = dev_attr->bank_width; + pdata->dbck_flag = dev_attr->dbck_flag; + pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count; + pdata->regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL); + if (!pdata->regs) { + pr_err("gpio%d: Memory allocation failed\n", id); + kfree(pdata); + return -ENOMEM; + } + + switch (oh->class->rev) { + case 0: + if (id == 1) + /* non-wakeup GPIO pins for OMAP2 Bank1 */ + pdata->non_wakeup_gpios = 0xe203ffc0; + else if (id == 2) + /* non-wakeup GPIO pins for OMAP2 Bank2 */ + pdata->non_wakeup_gpios = 0x08700040; + /* fall through */ + + case 1: + pdata->regs->revision = OMAP24XX_GPIO_REVISION; + pdata->regs->direction = OMAP24XX_GPIO_OE; + pdata->regs->datain = OMAP24XX_GPIO_DATAIN; + pdata->regs->dataout = OMAP24XX_GPIO_DATAOUT; + pdata->regs->set_dataout = OMAP24XX_GPIO_SETDATAOUT; + pdata->regs->clr_dataout = OMAP24XX_GPIO_CLEARDATAOUT; + pdata->regs->irqstatus = OMAP24XX_GPIO_IRQSTATUS1; + pdata->regs->irqstatus2 = OMAP24XX_GPIO_IRQSTATUS2; + pdata->regs->irqenable = OMAP24XX_GPIO_IRQENABLE1; + pdata->regs->irqenable2 = OMAP24XX_GPIO_IRQENABLE2; + pdata->regs->set_irqenable = OMAP24XX_GPIO_SETIRQENABLE1; + pdata->regs->clr_irqenable = OMAP24XX_GPIO_CLEARIRQENABLE1; + pdata->regs->debounce = OMAP24XX_GPIO_DEBOUNCE_VAL; + pdata->regs->debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN; + pdata->regs->ctrl = OMAP24XX_GPIO_CTRL; + pdata->regs->wkup_en = OMAP24XX_GPIO_WAKE_EN; + pdata->regs->leveldetect0 = OMAP24XX_GPIO_LEVELDETECT0; + pdata->regs->leveldetect1 = OMAP24XX_GPIO_LEVELDETECT1; + pdata->regs->risingdetect = OMAP24XX_GPIO_RISINGDETECT; + pdata->regs->fallingdetect = OMAP24XX_GPIO_FALLINGDETECT; + break; + case 2: + pdata->regs->revision = OMAP4_GPIO_REVISION; + pdata->regs->direction = OMAP4_GPIO_OE; + pdata->regs->datain = OMAP4_GPIO_DATAIN; + pdata->regs->dataout = OMAP4_GPIO_DATAOUT; + pdata->regs->set_dataout = OMAP4_GPIO_SETDATAOUT; + pdata->regs->clr_dataout = OMAP4_GPIO_CLEARDATAOUT; + pdata->regs->irqstatus_raw0 = OMAP4_GPIO_IRQSTATUSRAW0; + pdata->regs->irqstatus_raw1 = OMAP4_GPIO_IRQSTATUSRAW1; + pdata->regs->irqstatus = OMAP4_GPIO_IRQSTATUS0; + pdata->regs->irqstatus2 = OMAP4_GPIO_IRQSTATUS1; + pdata->regs->irqenable = OMAP4_GPIO_IRQSTATUSSET0; + pdata->regs->irqenable2 = OMAP4_GPIO_IRQSTATUSSET1; + pdata->regs->set_irqenable = OMAP4_GPIO_IRQSTATUSSET0; + pdata->regs->clr_irqenable = OMAP4_GPIO_IRQSTATUSCLR0; + pdata->regs->debounce = OMAP4_GPIO_DEBOUNCINGTIME; + pdata->regs->debounce_en = OMAP4_GPIO_DEBOUNCENABLE; + pdata->regs->ctrl = OMAP4_GPIO_CTRL; + pdata->regs->wkup_en = OMAP4_GPIO_IRQWAKEN0; + pdata->regs->leveldetect0 = OMAP4_GPIO_LEVELDETECT0; + pdata->regs->leveldetect1 = OMAP4_GPIO_LEVELDETECT1; + pdata->regs->risingdetect = OMAP4_GPIO_RISINGDETECT; + pdata->regs->fallingdetect = OMAP4_GPIO_FALLINGDETECT; + break; + default: + WARN(1, "Invalid gpio bank_type\n"); + kfree(pdata->regs); + kfree(pdata); + return -EINVAL; + } + + pwrdm = omap_hwmod_get_pwrdm(oh); + pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm); + + pdev = omap_device_build(name, id - 1, oh, pdata, sizeof(*pdata)); + kfree(pdata); + + if (IS_ERR(pdev)) { + WARN(1, "Can't build omap_device for %s:%s.\n", + name, oh->name); + return PTR_ERR(pdev); + } + + return 0; +} + +/* + * gpio_init needs to be done before + * machine_init functions access gpio APIs. + * Hence gpio_init is a omap_postcore_initcall. + */ +static int __init omap2_gpio_init(void) +{ + /* If dtb is there, the devices will be created dynamically */ + if (of_have_populated_dt()) + return -ENODEV; + + return omap_hwmod_for_each_by_class("gpio", omap2_gpio_dev_init, NULL); +} +omap_postcore_initcall(omap2_gpio_init); diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c new file mode 100644 index 00000000000..93914d22006 --- /dev/null +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -0,0 +1,162 @@ +/* + * gpmc-nand.c + * + * Copyright (C) 2009 Texas Instruments + * Vimal Singh <vimalsingh@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/mtd/nand.h> +#include <linux/platform_data/mtd-nand-omap2.h> + +#include <asm/mach/flash.h> + +#include "gpmc.h" +#include "soc.h" +#include "gpmc-nand.h" + +/* minimum size for IO mapping */ +#define NAND_IO_SIZE 4 + +static struct resource gpmc_nand_resource[] = { + { + .flags = IORESOURCE_MEM, + }, + { + .flags = IORESOURCE_IRQ, + }, + { + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device gpmc_nand_device = { + .name = "omap2-nand", + .id = 0, + .num_resources = ARRAY_SIZE(gpmc_nand_resource), + .resource = gpmc_nand_resource, +}; + +static bool gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt) +{ + /* platforms which support all ECC schemes */ + if (soc_is_am33xx() || soc_is_am43xx() || cpu_is_omap44xx() || + soc_is_omap54xx() || soc_is_dra7xx()) + return 1; + + if (ecc_opt == OMAP_ECC_BCH4_CODE_HW_DETECTION_SW || + ecc_opt == OMAP_ECC_BCH8_CODE_HW_DETECTION_SW) { + if (cpu_is_omap24xx()) + return 0; + else if (cpu_is_omap3630() && (GET_OMAP_REVISION() == 0)) + return 0; + else + return 1; + } + + /* OMAP3xxx do not have ELM engine, so cannot support ECC schemes + * which require H/W based ECC error detection */ + if ((cpu_is_omap34xx() || cpu_is_omap3630()) && + ((ecc_opt == OMAP_ECC_BCH4_CODE_HW) || + (ecc_opt == OMAP_ECC_BCH8_CODE_HW))) + return 0; + + /* legacy platforms support only HAM1 (1-bit Hamming) ECC scheme */ + if (ecc_opt == OMAP_ECC_HAM1_CODE_HW) + return 1; + else + return 0; +} + +/* This function will go away once the device-tree convertion is complete */ +static void gpmc_set_legacy(struct omap_nand_platform_data *gpmc_nand_data, + struct gpmc_settings *s) +{ + /* Enable RD PIN Monitoring Reg */ + if (gpmc_nand_data->dev_ready) { + s->wait_on_read = true; + s->wait_on_write = true; + } + + if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16) + s->device_width = GPMC_DEVWIDTH_16BIT; + else + s->device_width = GPMC_DEVWIDTH_8BIT; +} + +int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, + struct gpmc_timings *gpmc_t) +{ + int err = 0; + struct gpmc_settings s; + struct device *dev = &gpmc_nand_device.dev; + + memset(&s, 0, sizeof(struct gpmc_settings)); + + gpmc_nand_device.dev.platform_data = gpmc_nand_data; + + err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE, + (unsigned long *)&gpmc_nand_resource[0].start); + if (err < 0) { + dev_err(dev, "Cannot request GPMC CS %d, error %d\n", + gpmc_nand_data->cs, err); + return err; + } + + gpmc_nand_resource[0].end = gpmc_nand_resource[0].start + + NAND_IO_SIZE - 1; + + gpmc_nand_resource[1].start = + gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE); + gpmc_nand_resource[2].start = + gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT); + + if (gpmc_t) { + err = gpmc_cs_set_timings(gpmc_nand_data->cs, gpmc_t); + if (err < 0) { + dev_err(dev, "Unable to set gpmc timings: %d\n", err); + return err; + } + } + + if (gpmc_nand_data->of_node) + gpmc_read_settings_dt(gpmc_nand_data->of_node, &s); + else + gpmc_set_legacy(gpmc_nand_data, &s); + + s.device_nand = true; + + err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s); + if (err < 0) + goto out_free_cs; + + err = gpmc_configure(GPMC_CONFIG_WP, 0); + if (err < 0) + goto out_free_cs; + + gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs); + + if (!gpmc_hwecc_bch_capable(gpmc_nand_data->ecc_opt)) { + dev_err(dev, "Unsupported NAND ECC scheme selected\n"); + return -EINVAL; + } + + err = platform_device_register(&gpmc_nand_device); + if (err < 0) { + dev_err(dev, "Unable to register NAND device\n"); + goto out_free_cs; + } + + return 0; + +out_free_cs: + gpmc_cs_free(gpmc_nand_data->cs); + + return err; +} diff --git a/arch/arm/mach-omap2/gpmc-nand.h b/arch/arm/mach-omap2/gpmc-nand.h new file mode 100644 index 00000000000..d59e1281e85 --- /dev/null +++ b/arch/arm/mach-omap2/gpmc-nand.h @@ -0,0 +1,27 @@ +/* + * arch/arm/mach-omap2/gpmc-nand.h + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __OMAP2_GPMC_NAND_H +#define __OMAP2_GPMC_NAND_H + +#include "gpmc.h" +#include <linux/platform_data/mtd-nand-omap2.h> + +#if IS_ENABLED(CONFIG_MTD_NAND_OMAP2) +extern int gpmc_nand_init(struct omap_nand_platform_data *d, + struct gpmc_timings *gpmc_t); +#else +static inline int gpmc_nand_init(struct omap_nand_platform_data *d, + struct gpmc_timings *gpmc_t) +{ + return 0; +} +#endif + +#endif diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c new file mode 100644 index 00000000000..8b6876c98ce --- /dev/null +++ b/arch/arm/mach-omap2/gpmc-onenand.c @@ -0,0 +1,404 @@ +/* + * linux/arch/arm/mach-omap2/gpmc-onenand.c + * + * Copyright (C) 2006 - 2009 Nokia Corporation + * Contacts: Juha Yrjola + * Tony Lindgren + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/string.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/mtd/onenand_regs.h> +#include <linux/io.h> +#include <linux/platform_data/mtd-onenand-omap2.h> +#include <linux/err.h> + +#include <asm/mach/flash.h> + +#include "gpmc.h" +#include "soc.h" +#include "gpmc-onenand.h" + +#define ONENAND_IO_SIZE SZ_128K + +#define ONENAND_FLAG_SYNCREAD (1 << 0) +#define ONENAND_FLAG_SYNCWRITE (1 << 1) +#define ONENAND_FLAG_HF (1 << 2) +#define ONENAND_FLAG_VHF (1 << 3) + +static unsigned onenand_flags; +static unsigned latency; + +static struct omap_onenand_platform_data *gpmc_onenand_data; + +static struct resource gpmc_onenand_resource = { + .flags = IORESOURCE_MEM, +}; + +static struct platform_device gpmc_onenand_device = { + .name = "omap2-onenand", + .id = -1, + .num_resources = 1, + .resource = &gpmc_onenand_resource, +}; + +static struct gpmc_settings onenand_async = { + .device_width = GPMC_DEVWIDTH_16BIT, + .mux_add_data = GPMC_MUX_AD, +}; + +static struct gpmc_settings onenand_sync = { + .burst_read = true, + .burst_wrap = true, + .burst_len = GPMC_BURST_16, + .device_width = GPMC_DEVWIDTH_16BIT, + .mux_add_data = GPMC_MUX_AD, + .wait_pin = 0, +}; + +static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) +{ + struct gpmc_device_timings dev_t; + const int t_cer = 15; + const int t_avdp = 12; + const int t_aavdh = 7; + const int t_ce = 76; + const int t_aa = 76; + const int t_oe = 20; + const int t_cez = 20; /* max of t_cez, t_oez */ + const int t_wpl = 40; + const int t_wph = 30; + + memset(&dev_t, 0, sizeof(dev_t)); + + dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000; + dev_t.t_avdp_w = dev_t.t_avdp_r; + dev_t.t_aavdh = t_aavdh * 1000; + dev_t.t_aa = t_aa * 1000; + dev_t.t_ce = t_ce * 1000; + dev_t.t_oe = t_oe * 1000; + dev_t.t_cez_r = t_cez * 1000; + dev_t.t_cez_w = dev_t.t_cez_r; + dev_t.t_wpl = t_wpl * 1000; + dev_t.t_wph = t_wph * 1000; + + gpmc_calc_timings(t, &onenand_async, &dev_t); +} + +static void omap2_onenand_set_async_mode(void __iomem *onenand_base) +{ + u32 reg; + + /* Ensure sync read and sync write are disabled */ + reg = readw(onenand_base + ONENAND_REG_SYS_CFG1); + reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE; + writew(reg, onenand_base + ONENAND_REG_SYS_CFG1); +} + +static void set_onenand_cfg(void __iomem *onenand_base) +{ + u32 reg; + + reg = readw(onenand_base + ONENAND_REG_SYS_CFG1); + reg &= ~((0x7 << ONENAND_SYS_CFG1_BRL_SHIFT) | (0x7 << 9)); + reg |= (latency << ONENAND_SYS_CFG1_BRL_SHIFT) | + ONENAND_SYS_CFG1_BL_16; + if (onenand_flags & ONENAND_FLAG_SYNCREAD) + reg |= ONENAND_SYS_CFG1_SYNC_READ; + else + reg &= ~ONENAND_SYS_CFG1_SYNC_READ; + if (onenand_flags & ONENAND_FLAG_SYNCWRITE) + reg |= ONENAND_SYS_CFG1_SYNC_WRITE; + else + reg &= ~ONENAND_SYS_CFG1_SYNC_WRITE; + if (onenand_flags & ONENAND_FLAG_HF) + reg |= ONENAND_SYS_CFG1_HF; + else + reg &= ~ONENAND_SYS_CFG1_HF; + if (onenand_flags & ONENAND_FLAG_VHF) + reg |= ONENAND_SYS_CFG1_VHF; + else + reg &= ~ONENAND_SYS_CFG1_VHF; + writew(reg, onenand_base + ONENAND_REG_SYS_CFG1); +} + +static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg, + void __iomem *onenand_base) +{ + u16 ver = readw(onenand_base + ONENAND_REG_VERSION_ID); + int freq; + + switch ((ver >> 4) & 0xf) { + case 0: + freq = 40; + break; + case 1: + freq = 54; + break; + case 2: + freq = 66; + break; + case 3: + freq = 83; + break; + case 4: + freq = 104; + break; + default: + freq = 54; + break; + } + + return freq; +} + +static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t, + unsigned int flags, + int freq) +{ + struct gpmc_device_timings dev_t; + const int t_cer = 15; + const int t_avdp = 12; + const int t_cez = 20; /* max of t_cez, t_oez */ + const int t_wpl = 40; + const int t_wph = 30; + int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo; + int div, gpmc_clk_ns; + + if (flags & ONENAND_SYNC_READ) + onenand_flags = ONENAND_FLAG_SYNCREAD; + else if (flags & ONENAND_SYNC_READWRITE) + onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE; + + switch (freq) { + case 104: + min_gpmc_clk_period = 9600; /* 104 MHz */ + t_ces = 3; + t_avds = 4; + t_avdh = 2; + t_ach = 3; + t_aavdh = 6; + t_rdyo = 6; + break; + case 83: + min_gpmc_clk_period = 12000; /* 83 MHz */ + t_ces = 5; + t_avds = 4; + t_avdh = 2; + t_ach = 6; + t_aavdh = 6; + t_rdyo = 9; + break; + case 66: + min_gpmc_clk_period = 15000; /* 66 MHz */ + t_ces = 6; + t_avds = 5; + t_avdh = 2; + t_ach = 6; + t_aavdh = 6; + t_rdyo = 11; + break; + default: + min_gpmc_clk_period = 18500; /* 54 MHz */ + t_ces = 7; + t_avds = 7; + t_avdh = 7; + t_ach = 9; + t_aavdh = 7; + t_rdyo = 15; + onenand_flags &= ~ONENAND_FLAG_SYNCWRITE; + break; + } + + div = gpmc_calc_divider(min_gpmc_clk_period); + gpmc_clk_ns = gpmc_ticks_to_ns(div); + if (gpmc_clk_ns < 15) /* >66Mhz */ + onenand_flags |= ONENAND_FLAG_HF; + else + onenand_flags &= ~ONENAND_FLAG_HF; + if (gpmc_clk_ns < 12) /* >83Mhz */ + onenand_flags |= ONENAND_FLAG_VHF; + else + onenand_flags &= ~ONENAND_FLAG_VHF; + if (onenand_flags & ONENAND_FLAG_VHF) + latency = 8; + else if (onenand_flags & ONENAND_FLAG_HF) + latency = 6; + else if (gpmc_clk_ns >= 25) /* 40 MHz*/ + latency = 3; + else + latency = 4; + + /* Set synchronous read timings */ + memset(&dev_t, 0, sizeof(dev_t)); + + if (onenand_flags & ONENAND_FLAG_SYNCREAD) + onenand_sync.sync_read = true; + if (onenand_flags & ONENAND_FLAG_SYNCWRITE) { + onenand_sync.sync_write = true; + onenand_sync.burst_write = true; + } else { + dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000; + dev_t.t_wpl = t_wpl * 1000; + dev_t.t_wph = t_wph * 1000; + dev_t.t_aavdh = t_aavdh * 1000; + } + dev_t.ce_xdelay = true; + dev_t.avd_xdelay = true; + dev_t.oe_xdelay = true; + dev_t.we_xdelay = true; + dev_t.clk = min_gpmc_clk_period; + dev_t.t_bacc = dev_t.clk; + dev_t.t_ces = t_ces * 1000; + dev_t.t_avds = t_avds * 1000; + dev_t.t_avdh = t_avdh * 1000; + dev_t.t_ach = t_ach * 1000; + dev_t.cyc_iaa = (latency + 1); + dev_t.t_cez_r = t_cez * 1000; + dev_t.t_cez_w = dev_t.t_cez_r; + dev_t.cyc_aavdh_oe = 1; + dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period; + + gpmc_calc_timings(t, &onenand_sync, &dev_t); +} + +static int omap2_onenand_setup_async(void __iomem *onenand_base) +{ + struct gpmc_timings t; + int ret; + + if (gpmc_onenand_data->of_node) { + gpmc_read_settings_dt(gpmc_onenand_data->of_node, + &onenand_async); + if (onenand_async.sync_read || onenand_async.sync_write) { + if (onenand_async.sync_write) + gpmc_onenand_data->flags |= + ONENAND_SYNC_READWRITE; + else + gpmc_onenand_data->flags |= ONENAND_SYNC_READ; + onenand_async.sync_read = false; + onenand_async.sync_write = false; + } + } + + omap2_onenand_set_async_mode(onenand_base); + + omap2_onenand_calc_async_timings(&t); + + ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_async); + if (ret < 0) + return ret; + + ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t); + if (ret < 0) + return ret; + + omap2_onenand_set_async_mode(onenand_base); + + return 0; +} + +static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr) +{ + int ret, freq = *freq_ptr; + struct gpmc_timings t; + + if (!freq) { + /* Very first call freq is not known */ + freq = omap2_onenand_get_freq(gpmc_onenand_data, onenand_base); + set_onenand_cfg(onenand_base); + } + + if (gpmc_onenand_data->of_node) { + gpmc_read_settings_dt(gpmc_onenand_data->of_node, + &onenand_sync); + } else { + /* + * FIXME: Appears to be legacy code from initial ONENAND commit. + * Unclear what boards this is for and if this can be removed. + */ + if (!cpu_is_omap34xx()) + onenand_sync.wait_on_read = true; + } + + omap2_onenand_calc_sync_timings(&t, gpmc_onenand_data->flags, freq); + + ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_sync); + if (ret < 0) + return ret; + + ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t); + if (ret < 0) + return ret; + + set_onenand_cfg(onenand_base); + + *freq_ptr = freq; + + return 0; +} + +static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr) +{ + struct device *dev = &gpmc_onenand_device.dev; + unsigned l = ONENAND_SYNC_READ | ONENAND_SYNC_READWRITE; + int ret; + + ret = omap2_onenand_setup_async(onenand_base); + if (ret) { + dev_err(dev, "unable to set to async mode\n"); + return ret; + } + + if (!(gpmc_onenand_data->flags & l)) + return 0; + + ret = omap2_onenand_setup_sync(onenand_base, freq_ptr); + if (ret) + dev_err(dev, "unable to set to sync mode\n"); + return ret; +} + +void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data) +{ + int err; + struct device *dev = &gpmc_onenand_device.dev; + + gpmc_onenand_data = _onenand_data; + gpmc_onenand_data->onenand_setup = gpmc_onenand_setup; + gpmc_onenand_device.dev.platform_data = gpmc_onenand_data; + + if (cpu_is_omap24xx() && + (gpmc_onenand_data->flags & ONENAND_SYNC_READWRITE)) { + dev_warn(dev, "OneNAND using only SYNC_READ on 24xx\n"); + gpmc_onenand_data->flags &= ~ONENAND_SYNC_READWRITE; + gpmc_onenand_data->flags |= ONENAND_SYNC_READ; + } + + if (cpu_is_omap34xx()) + gpmc_onenand_data->flags |= ONENAND_IN_OMAP34XX; + else + gpmc_onenand_data->flags &= ~ONENAND_IN_OMAP34XX; + + err = gpmc_cs_request(gpmc_onenand_data->cs, ONENAND_IO_SIZE, + (unsigned long *)&gpmc_onenand_resource.start); + if (err < 0) { + dev_err(dev, "Cannot request GPMC CS %d, error %d\n", + gpmc_onenand_data->cs, err); + return; + } + + gpmc_onenand_resource.end = gpmc_onenand_resource.start + + ONENAND_IO_SIZE - 1; + + if (platform_device_register(&gpmc_onenand_device) < 0) { + dev_err(dev, "Unable to register OneNAND device\n"); + gpmc_cs_free(gpmc_onenand_data->cs); + return; + } +} diff --git a/arch/arm/mach-omap2/gpmc-onenand.h b/arch/arm/mach-omap2/gpmc-onenand.h new file mode 100644 index 00000000000..216f23a8b45 --- /dev/null +++ b/arch/arm/mach-omap2/gpmc-onenand.h @@ -0,0 +1,24 @@ +/* + * arch/arm/mach-omap2/gpmc-onenand.h + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __OMAP2_GPMC_ONENAND_H +#define __OMAP2_GPMC_ONENAND_H + +#include <linux/platform_data/mtd-onenand-omap2.h> + +#if IS_ENABLED(CONFIG_MTD_ONENAND_OMAP2) +extern void gpmc_onenand_init(struct omap_onenand_platform_data *d); +#else +#define board_onenand_data NULL +static inline void gpmc_onenand_init(struct omap_onenand_platform_data *d) +{ +} +#endif + +#endif diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c new file mode 100644 index 00000000000..61a063595e6 --- /dev/null +++ b/arch/arm/mach-omap2/gpmc-smc91x.c @@ -0,0 +1,186 @@ +/* + * linux/arch/arm/mach-omap2/gpmc-smc91x.c + * + * Copyright (C) 2009 Nokia Corporation + * Contact: Tony Lindgren + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/smc91x.h> + +#include "gpmc.h" +#include "gpmc-smc91x.h" + +#include "soc.h" + +static struct omap_smc91x_platform_data *gpmc_cfg; + +static struct resource gpmc_smc91x_resources[] = { + [0] = { + .flags = IORESOURCE_MEM, + }, + [1] = { + .flags = IORESOURCE_IRQ, + }, +}; + +static struct smc91x_platdata gpmc_smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_IO_SHIFT_0, + .leda = RPC_LED_100_10, + .ledb = RPC_LED_TX_RX, +}; + +static struct platform_device gpmc_smc91x_device = { + .name = "smc91x", + .id = -1, + .dev = { + .platform_data = &gpmc_smc91x_info, + }, + .num_resources = ARRAY_SIZE(gpmc_smc91x_resources), + .resource = gpmc_smc91x_resources, +}; + +static struct gpmc_settings smc91x_settings = { + .device_width = GPMC_DEVWIDTH_16BIT, +}; + +/* + * Set the gpmc timings for smc91c96. The timings are taken + * from the data sheet available at: + * http://www.smsc.com/main/catalog/lan91c96.html + * REVISIT: Level shifters can add at least to the access latency. + */ +static int smc91c96_gpmc_retime(void) +{ + struct gpmc_timings t; + struct gpmc_device_timings dev_t; + const int t3 = 10; /* Figure 12.2 read and 12.4 write */ + const int t4_r = 20; /* Figure 12.2 read */ + const int t4_w = 5; /* Figure 12.4 write */ + const int t5 = 25; /* Figure 12.2 read */ + const int t6 = 15; /* Figure 12.2 read */ + const int t7 = 5; /* Figure 12.4 write */ + const int t8 = 5; /* Figure 12.4 write */ + const int t20 = 185; /* Figure 12.2 read and 12.4 write */ + + /* + * FIXME: Calculate the address and data bus muxed timings. + * Note that at least adv_rd_off needs to be changed according + * to omap3430 TRM Figure 11-11. Are the sdp boards using the + * FPGA in between smc91x and omap as the timings are different + * from above? + */ + if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA) + return 0; + + memset(&dev_t, 0, sizeof(dev_t)); + + dev_t.t_oeasu = t3 * 1000; + dev_t.t_oe = t5 * 1000; + dev_t.t_cez_r = t4_r * 1000; + dev_t.t_oez = t6 * 1000; + dev_t.t_rd_cycle = (t20 - t3) * 1000; + + dev_t.t_weasu = t3 * 1000; + dev_t.t_wpl = t7 * 1000; + dev_t.t_wph = t8 * 1000; + dev_t.t_cez_w = t4_w * 1000; + dev_t.t_wr_cycle = (t20 - t3) * 1000; + + gpmc_calc_timings(&t, &smc91x_settings, &dev_t); + + return gpmc_cs_set_timings(gpmc_cfg->cs, &t); +} + +/* + * Initialize smc91x device connected to the GPMC. Note that we + * assume that pin multiplexing is done in the board-*.c file, + * or in the bootloader. + */ +void __init gpmc_smc91x_init(struct omap_smc91x_platform_data *board_data) +{ + unsigned long cs_mem_base; + int ret; + + gpmc_cfg = board_data; + + if (gpmc_cfg->flags & GPMC_TIMINGS_SMC91C96) + gpmc_cfg->retime = smc91c96_gpmc_retime; + + if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) { + printk(KERN_ERR "Failed to request GPMC mem for smc91x\n"); + return; + } + + gpmc_smc91x_resources[0].start = cs_mem_base + 0x300; + gpmc_smc91x_resources[0].end = cs_mem_base + 0x30f; + gpmc_smc91x_resources[1].flags |= (gpmc_cfg->flags & IRQF_TRIGGER_MASK); + + if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA) + smc91x_settings.mux_add_data = GPMC_MUX_AD; + if (gpmc_cfg->flags & GPMC_READ_MON) + smc91x_settings.wait_on_read = true; + if (gpmc_cfg->flags & GPMC_WRITE_MON) + smc91x_settings.wait_on_write = true; + if (gpmc_cfg->wait_pin) + smc91x_settings.wait_pin = gpmc_cfg->wait_pin; + ret = gpmc_cs_program_settings(gpmc_cfg->cs, &smc91x_settings); + if (ret < 0) + goto free1; + + if (gpmc_cfg->retime) { + ret = gpmc_cfg->retime(); + if (ret != 0) + goto free1; + } + + if (gpio_request_one(gpmc_cfg->gpio_irq, GPIOF_IN, "SMC91X irq") < 0) + goto free1; + + gpmc_smc91x_resources[1].start = gpio_to_irq(gpmc_cfg->gpio_irq); + + if (gpmc_cfg->gpio_pwrdwn) { + ret = gpio_request_one(gpmc_cfg->gpio_pwrdwn, + GPIOF_OUT_INIT_LOW, "SMC91X powerdown"); + if (ret) + goto free2; + } + + if (gpmc_cfg->gpio_reset) { + ret = gpio_request_one(gpmc_cfg->gpio_reset, + GPIOF_OUT_INIT_LOW, "SMC91X reset"); + if (ret) + goto free3; + + gpio_set_value(gpmc_cfg->gpio_reset, 1); + msleep(100); + gpio_set_value(gpmc_cfg->gpio_reset, 0); + } + + if (platform_device_register(&gpmc_smc91x_device) < 0) { + printk(KERN_ERR "Unable to register smc91x device\n"); + gpio_free(gpmc_cfg->gpio_reset); + goto free3; + } + + return; + +free3: + if (gpmc_cfg->gpio_pwrdwn) + gpio_free(gpmc_cfg->gpio_pwrdwn); +free2: + gpio_free(gpmc_cfg->gpio_irq); +free1: + gpmc_cs_free(gpmc_cfg->cs); + + printk(KERN_ERR "Could not initialize smc91x\n"); +} diff --git a/arch/arm/mach-omap2/gpmc-smc91x.h b/arch/arm/mach-omap2/gpmc-smc91x.h new file mode 100644 index 00000000000..b64fbee4d56 --- /dev/null +++ b/arch/arm/mach-omap2/gpmc-smc91x.h @@ -0,0 +1,42 @@ +/* + * arch/arm/plat-omap/include/mach/gpmc-smc91x.h + * + * Copyright (C) 2009 Nokia Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_ARCH_OMAP_GPMC_SMC91X_H__ + +#define GPMC_TIMINGS_SMC91C96 (1 << 4) +#define GPMC_MUX_ADD_DATA (1 << 5) /* GPMC_CONFIG1_MUXADDDATA */ +#define GPMC_READ_MON (1 << 6) /* GPMC_CONFIG1_WAIT_READ_MON */ +#define GPMC_WRITE_MON (1 << 7) /* GPMC_CONFIG1_WAIT_WRITE_MON */ + +struct omap_smc91x_platform_data { + int cs; + int gpio_irq; + int gpio_pwrdwn; + int gpio_reset; + int wait_pin; /* Optional GPMC_CONFIG1_WAITPINSELECT */ + u32 flags; + int (*retime)(void); +}; + +#if defined(CONFIG_SMC91X) || \ + defined(CONFIG_SMC91X_MODULE) + +extern void gpmc_smc91x_init(struct omap_smc91x_platform_data *d); + +#else + +#define board_smc91x_data NULL + +static inline void gpmc_smc91x_init(struct omap_smc91x_platform_data *d) +{ +} + +#endif +#endif diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.c b/arch/arm/mach-omap2/gpmc-smsc911x.c new file mode 100644 index 00000000000..2757504a13c --- /dev/null +++ b/arch/arm/mach-omap2/gpmc-smsc911x.c @@ -0,0 +1,100 @@ +/* + * linux/arch/arm/mach-omap2/gpmc-smsc911x.c + * + * Copyright (C) 2009 Li-Pro.Net + * Stephan Linz <linz@li-pro.net> + * + * Modified from linux/arch/arm/mach-omap2/gpmc-smc91x.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#define pr_fmt(fmt) "%s: " fmt, __func__ + +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/smsc911x.h> + +#include "gpmc.h" +#include "gpmc-smsc911x.h" + +static struct resource gpmc_smsc911x_resources[] = { + [0] = { + .flags = IORESOURCE_MEM, + }, + [1] = { + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + }, +}; + +static struct smsc911x_platform_config gpmc_smsc911x_config = { + .phy_interface = PHY_INTERFACE_MODE_MII, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, +}; + +/* + * Initialize smsc911x device connected to the GPMC. Note that we + * assume that pin multiplexing is done in the board-*.c file, + * or in the bootloader. + */ +void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *gpmc_cfg) +{ + struct platform_device *pdev; + unsigned long cs_mem_base; + int ret; + + if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) { + pr_err("Failed to request GPMC mem region\n"); + return; + } + + gpmc_smsc911x_resources[0].start = cs_mem_base + 0x0; + gpmc_smsc911x_resources[0].end = cs_mem_base + 0xff; + + if (gpio_request_one(gpmc_cfg->gpio_irq, GPIOF_IN, "smsc911x irq")) { + pr_err("Failed to request IRQ GPIO%d\n", gpmc_cfg->gpio_irq); + goto free1; + } + + gpmc_smsc911x_resources[1].start = gpio_to_irq(gpmc_cfg->gpio_irq); + + if (gpio_is_valid(gpmc_cfg->gpio_reset)) { + ret = gpio_request_one(gpmc_cfg->gpio_reset, + GPIOF_OUT_INIT_HIGH, "smsc911x reset"); + if (ret) { + pr_err("Failed to request reset GPIO%d\n", + gpmc_cfg->gpio_reset); + goto free2; + } + + gpio_set_value(gpmc_cfg->gpio_reset, 0); + msleep(100); + gpio_set_value(gpmc_cfg->gpio_reset, 1); + } + + gpmc_smsc911x_config.flags = gpmc_cfg->flags ? : SMSC911X_USE_16BIT; + + pdev = platform_device_register_resndata(NULL, "smsc911x", gpmc_cfg->id, + gpmc_smsc911x_resources, ARRAY_SIZE(gpmc_smsc911x_resources), + &gpmc_smsc911x_config, sizeof(gpmc_smsc911x_config)); + if (IS_ERR(pdev)) { + pr_err("Unable to register platform device\n"); + gpio_free(gpmc_cfg->gpio_reset); + goto free2; + } + + return; + +free2: + gpio_free(gpmc_cfg->gpio_irq); +free1: + gpmc_cs_free(gpmc_cfg->cs); + + pr_err("Could not initialize smsc911x device\n"); +} diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.h b/arch/arm/mach-omap2/gpmc-smsc911x.h new file mode 100644 index 00000000000..ea6c9c88c72 --- /dev/null +++ b/arch/arm/mach-omap2/gpmc-smsc911x.h @@ -0,0 +1,35 @@ +/* + * arch/arm/plat-omap/include/plat/gpmc-smsc911x.h + * + * Copyright (C) 2009 Li-Pro.Net + * Stephan Linz <linz@li-pro.net> + * + * Modified from arch/arm/plat-omap/include/plat/gpmc-smc91x.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_ARCH_OMAP_GPMC_SMSC911X_H__ + +struct omap_smsc911x_platform_data { + int id; + int cs; + int gpio_irq; + int gpio_reset; + u32 flags; +}; + +#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) + +extern void gpmc_smsc911x_init(struct omap_smsc911x_platform_data *d); + +#else + +static inline void gpmc_smsc911x_init(struct omap_smsc911x_platform_data *d) +{ +} + +#endif +#endif diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 2249049c1d5..8bc13380f0a 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -5,12 +5,16 @@ * * Author: Juha Yrjola * + * Copyright (C) 2009 Texas Instruments + * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #undef DEBUG +#include <linux/irq.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/err.h> @@ -19,11 +23,27 @@ #include <linux/spinlock.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_mtd.h> +#include <linux/of_device.h> +#include <linux/mtd/nand.h> +#include <linux/pm_runtime.h> + +#include <linux/platform_data/mtd-nand-omap2.h> #include <asm/mach-types.h> -#include <mach/gpmc.h> -#include <mach/sdrc.h> +#include "soc.h" +#include "common.h" +#include "omap_device.h" +#include "gpmc.h" +#include "gpmc-nand.h" +#include "gpmc-onenand.h" + +#define DEVICE_NAME "omap-gpmc" /* GPMC register offsets */ #define GPMC_REVISION 0x00 @@ -43,54 +63,142 @@ #define GPMC_ECC_CONFIG 0x1f4 #define GPMC_ECC_CONTROL 0x1f8 #define GPMC_ECC_SIZE_CONFIG 0x1fc - -#define GPMC_CS0 0x60 +#define GPMC_ECC1_RESULT 0x200 +#define GPMC_ECC_BCH_RESULT_0 0x240 /* not available on OMAP2 */ +#define GPMC_ECC_BCH_RESULT_1 0x244 /* not available on OMAP2 */ +#define GPMC_ECC_BCH_RESULT_2 0x248 /* not available on OMAP2 */ +#define GPMC_ECC_BCH_RESULT_3 0x24c /* not available on OMAP2 */ +#define GPMC_ECC_BCH_RESULT_4 0x300 /* not available on OMAP2 */ +#define GPMC_ECC_BCH_RESULT_5 0x304 /* not available on OMAP2 */ +#define GPMC_ECC_BCH_RESULT_6 0x308 /* not available on OMAP2 */ + +/* GPMC ECC control settings */ +#define GPMC_ECC_CTRL_ECCCLEAR 0x100 +#define GPMC_ECC_CTRL_ECCDISABLE 0x000 +#define GPMC_ECC_CTRL_ECCREG1 0x001 +#define GPMC_ECC_CTRL_ECCREG2 0x002 +#define GPMC_ECC_CTRL_ECCREG3 0x003 +#define GPMC_ECC_CTRL_ECCREG4 0x004 +#define GPMC_ECC_CTRL_ECCREG5 0x005 +#define GPMC_ECC_CTRL_ECCREG6 0x006 +#define GPMC_ECC_CTRL_ECCREG7 0x007 +#define GPMC_ECC_CTRL_ECCREG8 0x008 +#define GPMC_ECC_CTRL_ECCREG9 0x009 + +#define GPMC_CONFIG2_CSEXTRADELAY BIT(7) +#define GPMC_CONFIG3_ADVEXTRADELAY BIT(7) +#define GPMC_CONFIG4_OEEXTRADELAY BIT(7) +#define GPMC_CONFIG4_WEEXTRADELAY BIT(23) +#define GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN BIT(6) +#define GPMC_CONFIG6_CYCLE2CYCLESAMECSEN BIT(7) + +#define GPMC_CS0_OFFSET 0x60 #define GPMC_CS_SIZE 0x30 +#define GPMC_BCH_SIZE 0x10 -#define GPMC_MEM_START 0x00000000 #define GPMC_MEM_END 0x3FFFFFFF -#define BOOT_ROM_SPACE 0x100000 /* 1MB */ #define GPMC_CHUNK_SHIFT 24 /* 16 MB */ #define GPMC_SECTION_SHIFT 28 /* 128 MB */ +#define CS_NUM_SHIFT 24 +#define ENABLE_PREFETCH (0x1 << 7) +#define DMA_MPU_MODE 2 + +#define GPMC_REVISION_MAJOR(l) ((l >> 4) & 0xf) +#define GPMC_REVISION_MINOR(l) (l & 0xf) + +#define GPMC_HAS_WR_ACCESS 0x1 +#define GPMC_HAS_WR_DATA_MUX_BUS 0x2 +#define GPMC_HAS_MUX_AAD 0x4 + +#define GPMC_NR_WAITPINS 4 + +/* XXX: Only NAND irq has been considered,currently these are the only ones used + */ +#define GPMC_NR_IRQ 2 + +struct gpmc_client_irq { + unsigned irq; + u32 bitmask; +}; + +/* Structure to save gpmc cs context */ +struct gpmc_cs_config { + u32 config1; + u32 config2; + u32 config3; + u32 config4; + u32 config5; + u32 config6; + u32 config7; + int is_valid; +}; + +/* + * Structure to save/restore gpmc context + * to support core off on OMAP3 + */ +struct omap3_gpmc_regs { + u32 sysconfig; + u32 irqenable; + u32 timeout_ctrl; + u32 config; + u32 prefetch_config1; + u32 prefetch_config2; + u32 prefetch_control; + struct gpmc_cs_config cs_context[GPMC_CS_NUM]; +}; + +static struct gpmc_client_irq gpmc_client_irq[GPMC_NR_IRQ]; +static struct irq_chip gpmc_irq_chip; +static int gpmc_irq_start; + static struct resource gpmc_mem_root; static struct resource gpmc_cs_mem[GPMC_CS_NUM]; static DEFINE_SPINLOCK(gpmc_mem_lock); -static unsigned gpmc_cs_map; - +/* Define chip-selects as reserved by default until probe completes */ +static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1); +static unsigned int gpmc_cs_num = GPMC_CS_NUM; +static unsigned int gpmc_nr_waitpins; +static struct device *gpmc_dev; +static int gpmc_irq; +static resource_size_t phys_base, mem_size; +static unsigned gpmc_capability; static void __iomem *gpmc_base; static struct clk *gpmc_l3_clk; +static irqreturn_t gpmc_handle_irq(int irq, void *dev); + static void gpmc_write_reg(int idx, u32 val) { - __raw_writel(val, gpmc_base + idx); + writel_relaxed(val, gpmc_base + idx); } static u32 gpmc_read_reg(int idx) { - return __raw_readl(gpmc_base + idx); + return readl_relaxed(gpmc_base + idx); } void gpmc_cs_write_reg(int cs, int idx, u32 val) { void __iomem *reg_addr; - reg_addr = gpmc_base + GPMC_CS0 + (cs * GPMC_CS_SIZE) + idx; - __raw_writel(val, reg_addr); + reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; + writel_relaxed(val, reg_addr); } -u32 gpmc_cs_read_reg(int cs, int idx) +static u32 gpmc_cs_read_reg(int cs, int idx) { void __iomem *reg_addr; - reg_addr = gpmc_base + GPMC_CS0 + (cs * GPMC_CS_SIZE) + idx; - return __raw_readl(reg_addr); + reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; + return readl_relaxed(reg_addr); } /* TODO: Add support for gpmc_fck to clock framework and use it */ -unsigned long gpmc_get_fclk_period(void) +static unsigned long gpmc_get_fclk_period(void) { unsigned long rate = clk_get_rate(gpmc_l3_clk); @@ -105,7 +213,7 @@ unsigned long gpmc_get_fclk_period(void) return rate; } -unsigned int gpmc_ns_to_ticks(unsigned int time_ns) +static unsigned int gpmc_ns_to_ticks(unsigned int time_ns) { unsigned long tick_ps; @@ -115,16 +223,64 @@ unsigned int gpmc_ns_to_ticks(unsigned int time_ns) return (time_ns * 1000 + tick_ps - 1) / tick_ps; } +static unsigned int gpmc_ps_to_ticks(unsigned int time_ps) +{ + unsigned long tick_ps; + + /* Calculate in picosecs to yield more exact results */ + tick_ps = gpmc_get_fclk_period(); + + return (time_ps + tick_ps - 1) / tick_ps; +} + unsigned int gpmc_ticks_to_ns(unsigned int ticks) { return ticks * gpmc_get_fclk_period() / 1000; } -unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns) +static unsigned int gpmc_ticks_to_ps(unsigned int ticks) +{ + return ticks * gpmc_get_fclk_period(); +} + +static unsigned int gpmc_round_ps_to_ticks(unsigned int time_ps) { - unsigned long ticks = gpmc_ns_to_ticks(time_ns); + unsigned long ticks = gpmc_ps_to_ticks(time_ps); - return ticks * gpmc_get_fclk_period() / 1000; + return ticks * gpmc_get_fclk_period(); +} + +static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value) +{ + u32 l; + + l = gpmc_cs_read_reg(cs, reg); + if (value) + l |= mask; + else + l &= ~mask; + gpmc_cs_write_reg(cs, reg, l); +} + +static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p) +{ + gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG1, + GPMC_CONFIG1_TIME_PARA_GRAN, + p->time_para_granularity); + gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG2, + GPMC_CONFIG2_CSEXTRADELAY, p->cs_extra_delay); + gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG3, + GPMC_CONFIG3_ADVEXTRADELAY, p->adv_extra_delay); + gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4, + GPMC_CONFIG4_OEEXTRADELAY, p->oe_extra_delay); + gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4, + GPMC_CONFIG4_OEEXTRADELAY, p->we_extra_delay); + gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6, + GPMC_CONFIG6_CYCLE2CYCLESAMECSEN, + p->cycle2cyclesamecsen); + gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6, + GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN, + p->cycle2cyclediffcsen); } #ifdef DEBUG @@ -177,12 +333,12 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, return -1 #endif -int gpmc_cs_calc_divider(int cs, unsigned int sync_clk) +int gpmc_calc_divider(unsigned int sync_clk) { int div; u32 l; - l = sync_clk * 1000 + (gpmc_get_fclk_period() - 1); + l = sync_clk + (gpmc_get_fclk_period() - 1); div = l / gpmc_get_fclk_period(); if (div > 4) return -1; @@ -197,9 +353,9 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) int div; u32 l; - div = gpmc_cs_calc_divider(cs, t->sync_clk); + div = gpmc_calc_divider(t->sync_clk); if (div < 0) - return -1; + return div; GPMC_SET_ONE(GPMC_CS_CONFIG2, 0, 3, cs_on); GPMC_SET_ONE(GPMC_CS_CONFIG2, 8, 12, cs_rd_off); @@ -220,10 +376,16 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access); - if (cpu_is_omap34xx()) { + GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround); + GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay); + + GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring); + GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation); + + if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS) GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus); + if (gpmc_capability & GPMC_HAS_WR_ACCESS) GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access); - } /* caller is expected to have initialized CONFIG1 to cover * at least sync vs async @@ -239,22 +401,33 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l); } + gpmc_cs_bool_timings(cs, &t->bool_timings); + return 0; } -static void gpmc_cs_enable_mem(int cs, u32 base, u32 size) +static int gpmc_cs_enable_mem(int cs, u32 base, u32 size) { u32 l; u32 mask; + /* + * Ensure that base address is aligned on a + * boundary equal to or greater than size. + */ + if (base & (size - 1)) + return -EINVAL; + mask = (1 << GPMC_SECTION_SHIFT) - size; l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); l &= ~0x3f; l = (base >> GPMC_CHUNK_SHIFT) & 0x3f; l &= ~(0x0f << 8); l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8; - l |= 1 << 6; /* CSVALID */ + l |= GPMC_CONFIG7_CSVALID; gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); + + return 0; } static void gpmc_cs_disable_mem(int cs) @@ -262,7 +435,7 @@ static void gpmc_cs_disable_mem(int cs) u32 l; l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); - l &= ~(1 << 6); /* CSVALID */ + l &= ~GPMC_CONFIG7_CSVALID; gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); } @@ -282,25 +455,17 @@ static int gpmc_cs_mem_enabled(int cs) u32 l; l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); - return l & (1 << 6); + return l & GPMC_CONFIG7_CSVALID; } -int gpmc_cs_set_reserved(int cs, int reserved) +static void gpmc_cs_set_reserved(int cs, int reserved) { - if (cs > GPMC_CS_NUM) - return -ENODEV; - gpmc_cs_map &= ~(1 << cs); gpmc_cs_map |= (reserved ? 1 : 0) << cs; - - return 0; } -int gpmc_cs_reserved(int cs) +static bool gpmc_cs_reserved(int cs) { - if (cs > GPMC_CS_NUM) - return -ENODEV; - return gpmc_cs_map & (1 << cs); } @@ -333,14 +498,72 @@ static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size) return r; } +static int gpmc_cs_delete_mem(int cs) +{ + struct resource *res = &gpmc_cs_mem[cs]; + int r; + + spin_lock(&gpmc_mem_lock); + r = release_resource(res); + res->start = 0; + res->end = 0; + spin_unlock(&gpmc_mem_lock); + + return r; +} + +/** + * gpmc_cs_remap - remaps a chip-select physical base address + * @cs: chip-select to remap + * @base: physical base address to re-map chip-select to + * + * Re-maps a chip-select to a new physical base address specified by + * "base". Returns 0 on success and appropriate negative error code + * on failure. + */ +static int gpmc_cs_remap(int cs, u32 base) +{ + int ret; + u32 old_base, size; + + if (cs > gpmc_cs_num) { + pr_err("%s: requested chip-select is disabled\n", __func__); + return -ENODEV; + } + + /* + * Make sure we ignore any device offsets from the GPMC partition + * allocated for the chip select and that the new base confirms + * to the GPMC 16MB minimum granularity. + */ + base &= ~(SZ_16M - 1); + + gpmc_cs_get_memconf(cs, &old_base, &size); + if (base == old_base) + return 0; + gpmc_cs_disable_mem(cs); + ret = gpmc_cs_delete_mem(cs); + if (ret < 0) + return ret; + ret = gpmc_cs_insert_mem(cs, base, size); + if (ret < 0) + return ret; + ret = gpmc_cs_enable_mem(cs, base, size); + if (ret < 0) + return ret; + + return 0; +} + int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) { struct resource *res = &gpmc_cs_mem[cs]; int r = -1; - if (cs > GPMC_CS_NUM) + if (cs > gpmc_cs_num) { + pr_err("%s: requested chip-select is disabled\n", __func__); return -ENODEV; - + } size = gpmc_mem_align(size); if (size > (1 << GPMC_SECTION_SHIFT)) return -ENOMEM; @@ -358,7 +581,12 @@ int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) if (r < 0) goto out; - gpmc_cs_enable_mem(cs, res->start, res->end - res->start + 1); + r = gpmc_cs_enable_mem(cs, res->start, resource_size(res)); + if (r < 0) { + release_resource(res); + goto out; + } + *base = res->start; gpmc_cs_set_reserved(cs, 1); out: @@ -369,83 +597,1291 @@ EXPORT_SYMBOL(gpmc_cs_request); void gpmc_cs_free(int cs) { + struct resource *res = &gpmc_cs_mem[cs]; + spin_lock(&gpmc_mem_lock); - if (cs >= GPMC_CS_NUM || !gpmc_cs_reserved(cs)) { + if (cs >= gpmc_cs_num || cs < 0 || !gpmc_cs_reserved(cs)) { printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs); BUG(); spin_unlock(&gpmc_mem_lock); return; } gpmc_cs_disable_mem(cs); - release_resource(&gpmc_cs_mem[cs]); + if (res->flags) + release_resource(res); gpmc_cs_set_reserved(cs, 0); spin_unlock(&gpmc_mem_lock); } EXPORT_SYMBOL(gpmc_cs_free); -static void __init gpmc_mem_init(void) +/** + * gpmc_configure - write request to configure gpmc + * @cmd: command type + * @wval: value to write + * @return status of the operation + */ +int gpmc_configure(int cmd, int wval) +{ + u32 regval; + + switch (cmd) { + case GPMC_ENABLE_IRQ: + gpmc_write_reg(GPMC_IRQENABLE, wval); + break; + + case GPMC_SET_IRQ_STATUS: + gpmc_write_reg(GPMC_IRQSTATUS, wval); + break; + + case GPMC_CONFIG_WP: + regval = gpmc_read_reg(GPMC_CONFIG); + if (wval) + regval &= ~GPMC_CONFIG_WRITEPROTECT; /* WP is ON */ + else + regval |= GPMC_CONFIG_WRITEPROTECT; /* WP is OFF */ + gpmc_write_reg(GPMC_CONFIG, regval); + break; + + default: + pr_err("%s: command not supported\n", __func__); + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL(gpmc_configure); + +void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs) +{ + int i; + + reg->gpmc_status = gpmc_base + GPMC_STATUS; + reg->gpmc_nand_command = gpmc_base + GPMC_CS0_OFFSET + + GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs; + reg->gpmc_nand_address = gpmc_base + GPMC_CS0_OFFSET + + GPMC_CS_NAND_ADDRESS + GPMC_CS_SIZE * cs; + reg->gpmc_nand_data = gpmc_base + GPMC_CS0_OFFSET + + GPMC_CS_NAND_DATA + GPMC_CS_SIZE * cs; + reg->gpmc_prefetch_config1 = gpmc_base + GPMC_PREFETCH_CONFIG1; + reg->gpmc_prefetch_config2 = gpmc_base + GPMC_PREFETCH_CONFIG2; + reg->gpmc_prefetch_control = gpmc_base + GPMC_PREFETCH_CONTROL; + reg->gpmc_prefetch_status = gpmc_base + GPMC_PREFETCH_STATUS; + reg->gpmc_ecc_config = gpmc_base + GPMC_ECC_CONFIG; + reg->gpmc_ecc_control = gpmc_base + GPMC_ECC_CONTROL; + reg->gpmc_ecc_size_config = gpmc_base + GPMC_ECC_SIZE_CONFIG; + reg->gpmc_ecc1_result = gpmc_base + GPMC_ECC1_RESULT; + + for (i = 0; i < GPMC_BCH_NUM_REMAINDER; i++) { + reg->gpmc_bch_result0[i] = gpmc_base + GPMC_ECC_BCH_RESULT_0 + + GPMC_BCH_SIZE * i; + reg->gpmc_bch_result1[i] = gpmc_base + GPMC_ECC_BCH_RESULT_1 + + GPMC_BCH_SIZE * i; + reg->gpmc_bch_result2[i] = gpmc_base + GPMC_ECC_BCH_RESULT_2 + + GPMC_BCH_SIZE * i; + reg->gpmc_bch_result3[i] = gpmc_base + GPMC_ECC_BCH_RESULT_3 + + GPMC_BCH_SIZE * i; + reg->gpmc_bch_result4[i] = gpmc_base + GPMC_ECC_BCH_RESULT_4 + + i * GPMC_BCH_SIZE; + reg->gpmc_bch_result5[i] = gpmc_base + GPMC_ECC_BCH_RESULT_5 + + i * GPMC_BCH_SIZE; + reg->gpmc_bch_result6[i] = gpmc_base + GPMC_ECC_BCH_RESULT_6 + + i * GPMC_BCH_SIZE; + } +} + +int gpmc_get_client_irq(unsigned irq_config) +{ + int i; + + if (hweight32(irq_config) > 1) + return 0; + + for (i = 0; i < GPMC_NR_IRQ; i++) + if (gpmc_client_irq[i].bitmask & irq_config) + return gpmc_client_irq[i].irq; + + return 0; +} + +static int gpmc_irq_endis(unsigned irq, bool endis) +{ + int i; + u32 regval; + + for (i = 0; i < GPMC_NR_IRQ; i++) + if (irq == gpmc_client_irq[i].irq) { + regval = gpmc_read_reg(GPMC_IRQENABLE); + if (endis) + regval |= gpmc_client_irq[i].bitmask; + else + regval &= ~gpmc_client_irq[i].bitmask; + gpmc_write_reg(GPMC_IRQENABLE, regval); + break; + } + + return 0; +} + +static void gpmc_irq_disable(struct irq_data *p) +{ + gpmc_irq_endis(p->irq, false); +} + +static void gpmc_irq_enable(struct irq_data *p) +{ + gpmc_irq_endis(p->irq, true); +} + +static void gpmc_irq_noop(struct irq_data *data) { } + +static unsigned int gpmc_irq_noop_ret(struct irq_data *data) { return 0; } + +static int gpmc_setup_irq(void) +{ + int i; + u32 regval; + + if (!gpmc_irq) + return -EINVAL; + + gpmc_irq_start = irq_alloc_descs(-1, 0, GPMC_NR_IRQ, 0); + if (gpmc_irq_start < 0) { + pr_err("irq_alloc_descs failed\n"); + return gpmc_irq_start; + } + + gpmc_irq_chip.name = "gpmc"; + gpmc_irq_chip.irq_startup = gpmc_irq_noop_ret; + gpmc_irq_chip.irq_enable = gpmc_irq_enable; + gpmc_irq_chip.irq_disable = gpmc_irq_disable; + gpmc_irq_chip.irq_shutdown = gpmc_irq_noop; + gpmc_irq_chip.irq_ack = gpmc_irq_noop; + gpmc_irq_chip.irq_mask = gpmc_irq_noop; + gpmc_irq_chip.irq_unmask = gpmc_irq_noop; + + gpmc_client_irq[0].bitmask = GPMC_IRQ_FIFOEVENTENABLE; + gpmc_client_irq[1].bitmask = GPMC_IRQ_COUNT_EVENT; + + for (i = 0; i < GPMC_NR_IRQ; i++) { + gpmc_client_irq[i].irq = gpmc_irq_start + i; + irq_set_chip_and_handler(gpmc_client_irq[i].irq, + &gpmc_irq_chip, handle_simple_irq); + set_irq_flags(gpmc_client_irq[i].irq, + IRQF_VALID | IRQF_NOAUTOEN); + } + + /* Disable interrupts */ + gpmc_write_reg(GPMC_IRQENABLE, 0); + + /* clear interrupts */ + regval = gpmc_read_reg(GPMC_IRQSTATUS); + gpmc_write_reg(GPMC_IRQSTATUS, regval); + + return request_irq(gpmc_irq, gpmc_handle_irq, 0, "gpmc", NULL); +} + +static int gpmc_free_irq(void) +{ + int i; + + if (gpmc_irq) + free_irq(gpmc_irq, NULL); + + for (i = 0; i < GPMC_NR_IRQ; i++) { + irq_set_handler(gpmc_client_irq[i].irq, NULL); + irq_set_chip(gpmc_client_irq[i].irq, &no_irq_chip); + irq_modify_status(gpmc_client_irq[i].irq, 0, 0); + } + + irq_free_descs(gpmc_irq_start, GPMC_NR_IRQ); + + return 0; +} + +static void gpmc_mem_exit(void) +{ + int cs; + + for (cs = 0; cs < gpmc_cs_num; cs++) { + if (!gpmc_cs_mem_enabled(cs)) + continue; + gpmc_cs_delete_mem(cs); + } + +} + +static void gpmc_mem_init(void) { int cs; - unsigned long boot_rom_space = 0; - /* never allocate the first page, to facilitate bug detection; - * even if we didn't boot from ROM. + /* + * The first 1MB of GPMC address space is typically mapped to + * the internal ROM. Never allocate the first page, to + * facilitate bug detection; even if we didn't boot from ROM. */ - boot_rom_space = BOOT_ROM_SPACE; - /* In apollon the CS0 is mapped as 0x0000 0000 */ - if (machine_is_omap_apollon()) - boot_rom_space = 0; - gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space; + gpmc_mem_root.start = SZ_1M; gpmc_mem_root.end = GPMC_MEM_END; /* Reserve all regions that has been set up by bootloader */ - for (cs = 0; cs < GPMC_CS_NUM; cs++) { + for (cs = 0; cs < gpmc_cs_num; cs++) { u32 base, size; if (!gpmc_cs_mem_enabled(cs)) continue; gpmc_cs_get_memconf(cs, &base, &size); - if (gpmc_cs_insert_mem(cs, base, size) < 0) - BUG(); + if (gpmc_cs_insert_mem(cs, base, size)) { + pr_warn("%s: disabling cs %d mapped at 0x%x-0x%x\n", + __func__, cs, base, base + size); + gpmc_cs_disable_mem(cs); + } } } -void __init gpmc_init(void) +static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk) { - u32 l; - char *ck; + u32 temp; + int div; + + div = gpmc_calc_divider(sync_clk); + temp = gpmc_ps_to_ticks(time_ps); + temp = (temp + div - 1) / div; + return gpmc_ticks_to_ps(temp * div); +} + +/* XXX: can the cycles be avoided ? */ +static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t, + struct gpmc_device_timings *dev_t, + bool mux) +{ + u32 temp; + + /* adv_rd_off */ + temp = dev_t->t_avdp_r; + /* XXX: mux check required ? */ + if (mux) { + /* XXX: t_avdp not to be required for sync, only added for tusb + * this indirectly necessitates requirement of t_avdp_r and + * t_avdp_w instead of having a single t_avdp + */ + temp = max_t(u32, temp, gpmc_t->clk_activation + dev_t->t_avdh); + temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp); + } + gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp); + + /* oe_on */ + temp = dev_t->t_oeasu; /* XXX: remove this ? */ + if (mux) { + temp = max_t(u32, temp, gpmc_t->clk_activation + dev_t->t_ach); + temp = max_t(u32, temp, gpmc_t->adv_rd_off + + gpmc_ticks_to_ps(dev_t->cyc_aavdh_oe)); + } + gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp); + + /* access */ + /* XXX: any scope for improvement ?, by combining oe_on + * and clk_activation, need to check whether + * access = clk_activation + round to sync clk ? + */ + temp = max_t(u32, dev_t->t_iaa, dev_t->cyc_iaa * gpmc_t->sync_clk); + temp += gpmc_t->clk_activation; + if (dev_t->cyc_oe) + temp = max_t(u32, temp, gpmc_t->oe_on + + gpmc_ticks_to_ps(dev_t->cyc_oe)); + gpmc_t->access = gpmc_round_ps_to_ticks(temp); + + gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1); + gpmc_t->cs_rd_off = gpmc_t->oe_off; + + /* rd_cycle */ + temp = max_t(u32, dev_t->t_cez_r, dev_t->t_oez); + temp = gpmc_round_ps_to_sync_clk(temp, gpmc_t->sync_clk) + + gpmc_t->access; + /* XXX: barter t_ce_rdyz with t_cez_r ? */ + if (dev_t->t_ce_rdyz) + temp = max_t(u32, temp, gpmc_t->cs_rd_off + dev_t->t_ce_rdyz); + gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp); + + return 0; +} + +static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t, + struct gpmc_device_timings *dev_t, + bool mux) +{ + u32 temp; + + /* adv_wr_off */ + temp = dev_t->t_avdp_w; + if (mux) { + temp = max_t(u32, temp, + gpmc_t->clk_activation + dev_t->t_avdh); + temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp); + } + gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp); + + /* wr_data_mux_bus */ + temp = max_t(u32, dev_t->t_weasu, + gpmc_t->clk_activation + dev_t->t_rdyo); + /* XXX: shouldn't mux be kept as a whole for wr_data_mux_bus ?, + * and in that case remember to handle we_on properly + */ + if (mux) { + temp = max_t(u32, temp, + gpmc_t->adv_wr_off + dev_t->t_aavdh); + temp = max_t(u32, temp, gpmc_t->adv_wr_off + + gpmc_ticks_to_ps(dev_t->cyc_aavdh_we)); + } + gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp); + + /* we_on */ + if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS) + gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu); + else + gpmc_t->we_on = gpmc_t->wr_data_mux_bus; + + /* wr_access */ + /* XXX: gpmc_capability check reqd ? , even if not, will not harm */ + gpmc_t->wr_access = gpmc_t->access; + + /* we_off */ + temp = gpmc_t->we_on + dev_t->t_wpl; + temp = max_t(u32, temp, + gpmc_t->wr_access + gpmc_ticks_to_ps(1)); + temp = max_t(u32, temp, + gpmc_t->we_on + gpmc_ticks_to_ps(dev_t->cyc_wpl)); + gpmc_t->we_off = gpmc_round_ps_to_ticks(temp); + + gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off + + dev_t->t_wph); + + /* wr_cycle */ + temp = gpmc_round_ps_to_sync_clk(dev_t->t_cez_w, gpmc_t->sync_clk); + temp += gpmc_t->wr_access; + /* XXX: barter t_ce_rdyz with t_cez_w ? */ + if (dev_t->t_ce_rdyz) + temp = max_t(u32, temp, + gpmc_t->cs_wr_off + dev_t->t_ce_rdyz); + gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp); + + return 0; +} + +static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t, + struct gpmc_device_timings *dev_t, + bool mux) +{ + u32 temp; + + /* adv_rd_off */ + temp = dev_t->t_avdp_r; + if (mux) + temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp); + gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp); + + /* oe_on */ + temp = dev_t->t_oeasu; + if (mux) + temp = max_t(u32, temp, + gpmc_t->adv_rd_off + dev_t->t_aavdh); + gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp); + + /* access */ + temp = max_t(u32, dev_t->t_iaa, /* XXX: remove t_iaa in async ? */ + gpmc_t->oe_on + dev_t->t_oe); + temp = max_t(u32, temp, + gpmc_t->cs_on + dev_t->t_ce); + temp = max_t(u32, temp, + gpmc_t->adv_on + dev_t->t_aa); + gpmc_t->access = gpmc_round_ps_to_ticks(temp); + + gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1); + gpmc_t->cs_rd_off = gpmc_t->oe_off; + + /* rd_cycle */ + temp = max_t(u32, dev_t->t_rd_cycle, + gpmc_t->cs_rd_off + dev_t->t_cez_r); + temp = max_t(u32, temp, gpmc_t->oe_off + dev_t->t_oez); + gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp); + + return 0; +} + +static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t, + struct gpmc_device_timings *dev_t, + bool mux) +{ + u32 temp; + + /* adv_wr_off */ + temp = dev_t->t_avdp_w; + if (mux) + temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp); + gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp); + + /* wr_data_mux_bus */ + temp = dev_t->t_weasu; + if (mux) { + temp = max_t(u32, temp, gpmc_t->adv_wr_off + dev_t->t_aavdh); + temp = max_t(u32, temp, gpmc_t->adv_wr_off + + gpmc_ticks_to_ps(dev_t->cyc_aavdh_we)); + } + gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp); + + /* we_on */ + if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS) + gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu); + else + gpmc_t->we_on = gpmc_t->wr_data_mux_bus; + + /* we_off */ + temp = gpmc_t->we_on + dev_t->t_wpl; + gpmc_t->we_off = gpmc_round_ps_to_ticks(temp); + + gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off + + dev_t->t_wph); + + /* wr_cycle */ + temp = max_t(u32, dev_t->t_wr_cycle, + gpmc_t->cs_wr_off + dev_t->t_cez_w); + gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp); + + return 0; +} + +static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t, + struct gpmc_device_timings *dev_t) +{ + u32 temp; + + gpmc_t->sync_clk = gpmc_calc_divider(dev_t->clk) * + gpmc_get_fclk_period(); + + gpmc_t->page_burst_access = gpmc_round_ps_to_sync_clk( + dev_t->t_bacc, + gpmc_t->sync_clk); + + temp = max_t(u32, dev_t->t_ces, dev_t->t_avds); + gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp); + + if (gpmc_calc_divider(gpmc_t->sync_clk) != 1) + return 0; + + if (dev_t->ce_xdelay) + gpmc_t->bool_timings.cs_extra_delay = true; + if (dev_t->avd_xdelay) + gpmc_t->bool_timings.adv_extra_delay = true; + if (dev_t->oe_xdelay) + gpmc_t->bool_timings.oe_extra_delay = true; + if (dev_t->we_xdelay) + gpmc_t->bool_timings.we_extra_delay = true; + + return 0; +} + +static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t, + struct gpmc_device_timings *dev_t, + bool sync) +{ + u32 temp; + + /* cs_on */ + gpmc_t->cs_on = gpmc_round_ps_to_ticks(dev_t->t_ceasu); + + /* adv_on */ + temp = dev_t->t_avdasu; + if (dev_t->t_ce_avd) + temp = max_t(u32, temp, + gpmc_t->cs_on + dev_t->t_ce_avd); + gpmc_t->adv_on = gpmc_round_ps_to_ticks(temp); + + if (sync) + gpmc_calc_sync_common_timings(gpmc_t, dev_t); + + return 0; +} + +/* TODO: remove this function once all peripherals are confirmed to + * work with generic timing. Simultaneously gpmc_cs_set_timings() + * has to be modified to handle timings in ps instead of ns +*/ +static void gpmc_convert_ps_to_ns(struct gpmc_timings *t) +{ + t->cs_on /= 1000; + t->cs_rd_off /= 1000; + t->cs_wr_off /= 1000; + t->adv_on /= 1000; + t->adv_rd_off /= 1000; + t->adv_wr_off /= 1000; + t->we_on /= 1000; + t->we_off /= 1000; + t->oe_on /= 1000; + t->oe_off /= 1000; + t->page_burst_access /= 1000; + t->access /= 1000; + t->rd_cycle /= 1000; + t->wr_cycle /= 1000; + t->bus_turnaround /= 1000; + t->cycle2cycle_delay /= 1000; + t->wait_monitoring /= 1000; + t->clk_activation /= 1000; + t->wr_access /= 1000; + t->wr_data_mux_bus /= 1000; +} + +int gpmc_calc_timings(struct gpmc_timings *gpmc_t, + struct gpmc_settings *gpmc_s, + struct gpmc_device_timings *dev_t) +{ + bool mux = false, sync = false; + + if (gpmc_s) { + mux = gpmc_s->mux_add_data ? true : false; + sync = (gpmc_s->sync_read || gpmc_s->sync_write); + } + + memset(gpmc_t, 0, sizeof(*gpmc_t)); + + gpmc_calc_common_timings(gpmc_t, dev_t, sync); + + if (gpmc_s && gpmc_s->sync_read) + gpmc_calc_sync_read_timings(gpmc_t, dev_t, mux); + else + gpmc_calc_async_read_timings(gpmc_t, dev_t, mux); + + if (gpmc_s && gpmc_s->sync_write) + gpmc_calc_sync_write_timings(gpmc_t, dev_t, mux); + else + gpmc_calc_async_write_timings(gpmc_t, dev_t, mux); + + /* TODO: remove, see function definition */ + gpmc_convert_ps_to_ns(gpmc_t); + + return 0; +} + +/** + * gpmc_cs_program_settings - programs non-timing related settings + * @cs: GPMC chip-select to program + * @p: pointer to GPMC settings structure + * + * Programs non-timing related settings for a GPMC chip-select, such as + * bus-width, burst configuration, etc. Function should be called once + * for each chip-select that is being used and must be called before + * calling gpmc_cs_set_timings() as timing parameters in the CONFIG1 + * register will be initialised to zero by this function. Returns 0 on + * success and appropriate negative error code on failure. + */ +int gpmc_cs_program_settings(int cs, struct gpmc_settings *p) +{ + u32 config1; + + if ((!p->device_width) || (p->device_width > GPMC_DEVWIDTH_16BIT)) { + pr_err("%s: invalid width %d!", __func__, p->device_width); + return -EINVAL; + } + + /* Address-data multiplexing not supported for NAND devices */ + if (p->device_nand && p->mux_add_data) { + pr_err("%s: invalid configuration!\n", __func__); + return -EINVAL; + } + + if ((p->mux_add_data > GPMC_MUX_AD) || + ((p->mux_add_data == GPMC_MUX_AAD) && + !(gpmc_capability & GPMC_HAS_MUX_AAD))) { + pr_err("%s: invalid multiplex configuration!\n", __func__); + return -EINVAL; + } + + /* Page/burst mode supports lengths of 4, 8 and 16 bytes */ + if (p->burst_read || p->burst_write) { + switch (p->burst_len) { + case GPMC_BURST_4: + case GPMC_BURST_8: + case GPMC_BURST_16: + break; + default: + pr_err("%s: invalid page/burst-length (%d)\n", + __func__, p->burst_len); + return -EINVAL; + } + } + + if ((p->wait_on_read || p->wait_on_write) && + (p->wait_pin > gpmc_nr_waitpins)) { + pr_err("%s: invalid wait-pin (%d)\n", __func__, p->wait_pin); + return -EINVAL; + } - if (cpu_is_omap24xx()) { - ck = "core_l3_ck"; - if (cpu_is_omap2420()) - l = OMAP2420_GPMC_BASE; + config1 = GPMC_CONFIG1_DEVICESIZE((p->device_width - 1)); + + if (p->sync_read) + config1 |= GPMC_CONFIG1_READTYPE_SYNC; + if (p->sync_write) + config1 |= GPMC_CONFIG1_WRITETYPE_SYNC; + if (p->wait_on_read) + config1 |= GPMC_CONFIG1_WAIT_READ_MON; + if (p->wait_on_write) + config1 |= GPMC_CONFIG1_WAIT_WRITE_MON; + if (p->wait_on_read || p->wait_on_write) + config1 |= GPMC_CONFIG1_WAIT_PIN_SEL(p->wait_pin); + if (p->device_nand) + config1 |= GPMC_CONFIG1_DEVICETYPE(GPMC_DEVICETYPE_NAND); + if (p->mux_add_data) + config1 |= GPMC_CONFIG1_MUXTYPE(p->mux_add_data); + if (p->burst_read) + config1 |= GPMC_CONFIG1_READMULTIPLE_SUPP; + if (p->burst_write) + config1 |= GPMC_CONFIG1_WRITEMULTIPLE_SUPP; + if (p->burst_read || p->burst_write) { + config1 |= GPMC_CONFIG1_PAGE_LEN(p->burst_len >> 3); + config1 |= p->burst_wrap ? GPMC_CONFIG1_WRAPBURST_SUPP : 0; + } + + gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, config1); + + return 0; +} + +#ifdef CONFIG_OF +static struct of_device_id gpmc_dt_ids[] = { + { .compatible = "ti,omap2420-gpmc" }, + { .compatible = "ti,omap2430-gpmc" }, + { .compatible = "ti,omap3430-gpmc" }, /* omap3430 & omap3630 */ + { .compatible = "ti,omap4430-gpmc" }, /* omap4430 & omap4460 & omap543x */ + { .compatible = "ti,am3352-gpmc" }, /* am335x devices */ + { } +}; +MODULE_DEVICE_TABLE(of, gpmc_dt_ids); + +/** + * gpmc_read_settings_dt - read gpmc settings from device-tree + * @np: pointer to device-tree node for a gpmc child device + * @p: pointer to gpmc settings structure + * + * Reads the GPMC settings for a GPMC child device from device-tree and + * stores them in the GPMC settings structure passed. The GPMC settings + * structure is initialised to zero by this function and so any + * previously stored settings will be cleared. + */ +void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p) +{ + memset(p, 0, sizeof(struct gpmc_settings)); + + p->sync_read = of_property_read_bool(np, "gpmc,sync-read"); + p->sync_write = of_property_read_bool(np, "gpmc,sync-write"); + of_property_read_u32(np, "gpmc,device-width", &p->device_width); + of_property_read_u32(np, "gpmc,mux-add-data", &p->mux_add_data); + + if (!of_property_read_u32(np, "gpmc,burst-length", &p->burst_len)) { + p->burst_wrap = of_property_read_bool(np, "gpmc,burst-wrap"); + p->burst_read = of_property_read_bool(np, "gpmc,burst-read"); + p->burst_write = of_property_read_bool(np, "gpmc,burst-write"); + if (!p->burst_read && !p->burst_write) + pr_warn("%s: page/burst-length set but not used!\n", + __func__); + } + + if (!of_property_read_u32(np, "gpmc,wait-pin", &p->wait_pin)) { + p->wait_on_read = of_property_read_bool(np, + "gpmc,wait-on-read"); + p->wait_on_write = of_property_read_bool(np, + "gpmc,wait-on-write"); + if (!p->wait_on_read && !p->wait_on_write) + pr_warn("%s: read/write wait monitoring not enabled!\n", + __func__); + } +} + +static void __maybe_unused gpmc_read_timings_dt(struct device_node *np, + struct gpmc_timings *gpmc_t) +{ + struct gpmc_bool_timings *p; + + if (!np || !gpmc_t) + return; + + memset(gpmc_t, 0, sizeof(*gpmc_t)); + + /* minimum clock period for syncronous mode */ + of_property_read_u32(np, "gpmc,sync-clk-ps", &gpmc_t->sync_clk); + + /* chip select timtings */ + of_property_read_u32(np, "gpmc,cs-on-ns", &gpmc_t->cs_on); + of_property_read_u32(np, "gpmc,cs-rd-off-ns", &gpmc_t->cs_rd_off); + of_property_read_u32(np, "gpmc,cs-wr-off-ns", &gpmc_t->cs_wr_off); + + /* ADV signal timings */ + of_property_read_u32(np, "gpmc,adv-on-ns", &gpmc_t->adv_on); + of_property_read_u32(np, "gpmc,adv-rd-off-ns", &gpmc_t->adv_rd_off); + of_property_read_u32(np, "gpmc,adv-wr-off-ns", &gpmc_t->adv_wr_off); + + /* WE signal timings */ + of_property_read_u32(np, "gpmc,we-on-ns", &gpmc_t->we_on); + of_property_read_u32(np, "gpmc,we-off-ns", &gpmc_t->we_off); + + /* OE signal timings */ + of_property_read_u32(np, "gpmc,oe-on-ns", &gpmc_t->oe_on); + of_property_read_u32(np, "gpmc,oe-off-ns", &gpmc_t->oe_off); + + /* access and cycle timings */ + of_property_read_u32(np, "gpmc,page-burst-access-ns", + &gpmc_t->page_burst_access); + of_property_read_u32(np, "gpmc,access-ns", &gpmc_t->access); + of_property_read_u32(np, "gpmc,rd-cycle-ns", &gpmc_t->rd_cycle); + of_property_read_u32(np, "gpmc,wr-cycle-ns", &gpmc_t->wr_cycle); + of_property_read_u32(np, "gpmc,bus-turnaround-ns", + &gpmc_t->bus_turnaround); + of_property_read_u32(np, "gpmc,cycle2cycle-delay-ns", + &gpmc_t->cycle2cycle_delay); + of_property_read_u32(np, "gpmc,wait-monitoring-ns", + &gpmc_t->wait_monitoring); + of_property_read_u32(np, "gpmc,clk-activation-ns", + &gpmc_t->clk_activation); + + /* only applicable to OMAP3+ */ + of_property_read_u32(np, "gpmc,wr-access-ns", &gpmc_t->wr_access); + of_property_read_u32(np, "gpmc,wr-data-mux-bus-ns", + &gpmc_t->wr_data_mux_bus); + + /* bool timing parameters */ + p = &gpmc_t->bool_timings; + + p->cycle2cyclediffcsen = + of_property_read_bool(np, "gpmc,cycle2cycle-diffcsen"); + p->cycle2cyclesamecsen = + of_property_read_bool(np, "gpmc,cycle2cycle-samecsen"); + p->we_extra_delay = of_property_read_bool(np, "gpmc,we-extra-delay"); + p->oe_extra_delay = of_property_read_bool(np, "gpmc,oe-extra-delay"); + p->adv_extra_delay = of_property_read_bool(np, "gpmc,adv-extra-delay"); + p->cs_extra_delay = of_property_read_bool(np, "gpmc,cs-extra-delay"); + p->time_para_granularity = + of_property_read_bool(np, "gpmc,time-para-granularity"); +} + +#if IS_ENABLED(CONFIG_MTD_NAND) + +static const char * const nand_xfer_types[] = { + [NAND_OMAP_PREFETCH_POLLED] = "prefetch-polled", + [NAND_OMAP_POLLED] = "polled", + [NAND_OMAP_PREFETCH_DMA] = "prefetch-dma", + [NAND_OMAP_PREFETCH_IRQ] = "prefetch-irq", +}; + +static int gpmc_probe_nand_child(struct platform_device *pdev, + struct device_node *child) +{ + u32 val; + const char *s; + struct gpmc_timings gpmc_t; + struct omap_nand_platform_data *gpmc_nand_data; + + if (of_property_read_u32(child, "reg", &val) < 0) { + dev_err(&pdev->dev, "%s has no 'reg' property\n", + child->full_name); + return -ENODEV; + } + + gpmc_nand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_nand_data), + GFP_KERNEL); + if (!gpmc_nand_data) + return -ENOMEM; + + gpmc_nand_data->cs = val; + gpmc_nand_data->of_node = child; + + /* Detect availability of ELM module */ + gpmc_nand_data->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0); + if (gpmc_nand_data->elm_of_node == NULL) + gpmc_nand_data->elm_of_node = + of_parse_phandle(child, "elm_id", 0); + if (gpmc_nand_data->elm_of_node == NULL) + pr_warn("%s: ti,elm-id property not found\n", __func__); + + /* select ecc-scheme for NAND */ + if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) { + pr_err("%s: ti,nand-ecc-opt not found\n", __func__); + return -ENODEV; + } + if (!strcmp(s, "ham1") || !strcmp(s, "sw") || + !strcmp(s, "hw") || !strcmp(s, "hw-romcode")) + gpmc_nand_data->ecc_opt = + OMAP_ECC_HAM1_CODE_HW; + else if (!strcmp(s, "bch4")) + if (gpmc_nand_data->elm_of_node) + gpmc_nand_data->ecc_opt = + OMAP_ECC_BCH4_CODE_HW; + else + gpmc_nand_data->ecc_opt = + OMAP_ECC_BCH4_CODE_HW_DETECTION_SW; + else if (!strcmp(s, "bch8")) + if (gpmc_nand_data->elm_of_node) + gpmc_nand_data->ecc_opt = + OMAP_ECC_BCH8_CODE_HW; + else + gpmc_nand_data->ecc_opt = + OMAP_ECC_BCH8_CODE_HW_DETECTION_SW; + else if (!strcmp(s, "bch16")) + if (gpmc_nand_data->elm_of_node) + gpmc_nand_data->ecc_opt = + OMAP_ECC_BCH16_CODE_HW; else - l = OMAP34XX_GPMC_BASE; - } else if (cpu_is_omap34xx()) { - ck = "gpmc_fck"; - l = OMAP34XX_GPMC_BASE; + pr_err("%s: BCH16 requires ELM support\n", __func__); + else + pr_err("%s: ti,nand-ecc-opt invalid value\n", __func__); + + /* select data transfer mode for NAND controller */ + if (!of_property_read_string(child, "ti,nand-xfer-type", &s)) + for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++) + if (!strcasecmp(s, nand_xfer_types[val])) { + gpmc_nand_data->xfer_type = val; + break; + } + + val = of_get_nand_bus_width(child); + if (val == 16) + gpmc_nand_data->devsize = NAND_BUSWIDTH_16; + + gpmc_read_timings_dt(child, &gpmc_t); + gpmc_nand_init(gpmc_nand_data, &gpmc_t); + + return 0; +} +#else +static int gpmc_probe_nand_child(struct platform_device *pdev, + struct device_node *child) +{ + return 0; +} +#endif + +#if IS_ENABLED(CONFIG_MTD_ONENAND) +static int gpmc_probe_onenand_child(struct platform_device *pdev, + struct device_node *child) +{ + u32 val; + struct omap_onenand_platform_data *gpmc_onenand_data; + + if (of_property_read_u32(child, "reg", &val) < 0) { + dev_err(&pdev->dev, "%s has no 'reg' property\n", + child->full_name); + return -ENODEV; } - gpmc_l3_clk = clk_get(NULL, ck); - if (IS_ERR(gpmc_l3_clk)) { - printk(KERN_ERR "Could not get GPMC clock %s\n", ck); - BUG(); + gpmc_onenand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_onenand_data), + GFP_KERNEL); + if (!gpmc_onenand_data) + return -ENOMEM; + + gpmc_onenand_data->cs = val; + gpmc_onenand_data->of_node = child; + gpmc_onenand_data->dma_channel = -1; + + if (!of_property_read_u32(child, "dma-channel", &val)) + gpmc_onenand_data->dma_channel = val; + + gpmc_onenand_init(gpmc_onenand_data); + + return 0; +} +#else +static int gpmc_probe_onenand_child(struct platform_device *pdev, + struct device_node *child) +{ + return 0; +} +#endif + +/** + * gpmc_probe_generic_child - configures the gpmc for a child device + * @pdev: pointer to gpmc platform device + * @child: pointer to device-tree node for child device + * + * Allocates and configures a GPMC chip-select for a child device. + * Returns 0 on success and appropriate negative error code on failure. + */ +static int gpmc_probe_generic_child(struct platform_device *pdev, + struct device_node *child) +{ + struct gpmc_settings gpmc_s; + struct gpmc_timings gpmc_t; + struct resource res; + unsigned long base; + int ret, cs; + + if (of_property_read_u32(child, "reg", &cs) < 0) { + dev_err(&pdev->dev, "%s has no 'reg' property\n", + child->full_name); + return -ENODEV; } - gpmc_base = ioremap(l, SZ_4K); - if (!gpmc_base) { - clk_put(gpmc_l3_clk); - printk(KERN_ERR "Could not get GPMC register memory\n"); - BUG(); + if (of_address_to_resource(child, 0, &res) < 0) { + dev_err(&pdev->dev, "%s has malformed 'reg' property\n", + child->full_name); + return -ENODEV; + } + + ret = gpmc_cs_request(cs, resource_size(&res), &base); + if (ret < 0) { + dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs); + return ret; + } + + /* + * For some GPMC devices we still need to rely on the bootloader + * timings because the devices can be connected via FPGA. So far + * the list is smc91x on the omap2 SDP boards, and 8250 on zooms. + * REVISIT: Add timing support from slls644g.pdf and from the + * lan91c96 manual. + */ + if (of_device_is_compatible(child, "ns16550a") || + of_device_is_compatible(child, "smsc,lan91c94") || + of_device_is_compatible(child, "smsc,lan91c111")) { + dev_warn(&pdev->dev, + "%s using bootloader timings on CS%d\n", + child->name, cs); + goto no_timings; + } + + /* + * FIXME: gpmc_cs_request() will map the CS to an arbitary + * location in the gpmc address space. When booting with + * device-tree we want the NOR flash to be mapped to the + * location specified in the device-tree blob. So remap the + * CS to this location. Once DT migration is complete should + * just make gpmc_cs_request() map a specific address. + */ + ret = gpmc_cs_remap(cs, res.start); + if (ret < 0) { + dev_err(&pdev->dev, "cannot remap GPMC CS %d to %pa\n", + cs, &res.start); + goto err; } + gpmc_read_settings_dt(child, &gpmc_s); + + ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width); + if (ret < 0) + goto err; + + ret = gpmc_cs_program_settings(cs, &gpmc_s); + if (ret < 0) + goto err; + + gpmc_read_timings_dt(child, &gpmc_t); + gpmc_cs_set_timings(cs, &gpmc_t); + +no_timings: + if (of_platform_device_create(child, NULL, &pdev->dev)) + return 0; + + dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name); + ret = -ENODEV; + +err: + gpmc_cs_free(cs); + + return ret; +} + +static int gpmc_probe_dt(struct platform_device *pdev) +{ + int ret; + struct device_node *child; + const struct of_device_id *of_id = + of_match_device(gpmc_dt_ids, &pdev->dev); + + if (!of_id) + return 0; + + ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-cs", + &gpmc_cs_num); + if (ret < 0) { + pr_err("%s: number of chip-selects not defined\n", __func__); + return ret; + } else if (gpmc_cs_num < 1) { + pr_err("%s: all chip-selects are disabled\n", __func__); + return -EINVAL; + } else if (gpmc_cs_num > GPMC_CS_NUM) { + pr_err("%s: number of supported chip-selects cannot be > %d\n", + __func__, GPMC_CS_NUM); + return -EINVAL; + } + + ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-waitpins", + &gpmc_nr_waitpins); + if (ret < 0) { + pr_err("%s: number of wait pins not found!\n", __func__); + return ret; + } + + for_each_available_child_of_node(pdev->dev.of_node, child) { + + if (!child->name) + continue; + + if (of_node_cmp(child->name, "nand") == 0) + ret = gpmc_probe_nand_child(pdev, child); + else if (of_node_cmp(child->name, "onenand") == 0) + ret = gpmc_probe_onenand_child(pdev, child); + else if (of_node_cmp(child->name, "ethernet") == 0 || + of_node_cmp(child->name, "nor") == 0 || + of_node_cmp(child->name, "uart") == 0) + ret = gpmc_probe_generic_child(pdev, child); + + if (WARN(ret < 0, "%s: probing gpmc child %s failed\n", + __func__, child->full_name)) + of_node_put(child); + } + + return 0; +} +#else +static int gpmc_probe_dt(struct platform_device *pdev) +{ + return 0; +} +#endif + +static int gpmc_probe(struct platform_device *pdev) +{ + int rc; + u32 l; + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) + return -ENOENT; + + phys_base = res->start; + mem_size = resource_size(res); + + gpmc_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(gpmc_base)) + return PTR_ERR(gpmc_base); + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (res == NULL) + dev_warn(&pdev->dev, "Failed to get resource: irq\n"); + else + gpmc_irq = res->start; + + gpmc_l3_clk = clk_get(&pdev->dev, "fck"); + if (IS_ERR(gpmc_l3_clk)) { + dev_err(&pdev->dev, "error: clk_get\n"); + gpmc_irq = 0; + return PTR_ERR(gpmc_l3_clk); + } + + pm_runtime_enable(&pdev->dev); + pm_runtime_get_sync(&pdev->dev); + + gpmc_dev = &pdev->dev; + l = gpmc_read_reg(GPMC_REVISION); - printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f); - /* Set smart idle mode and automatic L3 clock gating */ - l = gpmc_read_reg(GPMC_SYSCONFIG); - l &= 0x03 << 3; - l |= (0x02 << 3) | (1 << 0); - gpmc_write_reg(GPMC_SYSCONFIG, l); + + /* + * FIXME: Once device-tree migration is complete the below flags + * should be populated based upon the device-tree compatible + * string. For now just use the IP revision. OMAP3+ devices have + * the wr_access and wr_data_mux_bus register fields. OMAP4+ + * devices support the addr-addr-data multiplex protocol. + * + * GPMC IP revisions: + * - OMAP24xx = 2.0 + * - OMAP3xxx = 5.0 + * - OMAP44xx/54xx/AM335x = 6.0 + */ + if (GPMC_REVISION_MAJOR(l) > 0x4) + gpmc_capability = GPMC_HAS_WR_ACCESS | GPMC_HAS_WR_DATA_MUX_BUS; + if (GPMC_REVISION_MAJOR(l) > 0x5) + gpmc_capability |= GPMC_HAS_MUX_AAD; + dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l), + GPMC_REVISION_MINOR(l)); gpmc_mem_init(); + + if (gpmc_setup_irq() < 0) + dev_warn(gpmc_dev, "gpmc_setup_irq failed\n"); + + /* Now the GPMC is initialised, unreserve the chip-selects */ + gpmc_cs_map = 0; + + if (!pdev->dev.of_node) { + gpmc_cs_num = GPMC_CS_NUM; + gpmc_nr_waitpins = GPMC_NR_WAITPINS; + } + + rc = gpmc_probe_dt(pdev); + if (rc < 0) { + pm_runtime_put_sync(&pdev->dev); + clk_put(gpmc_l3_clk); + dev_err(gpmc_dev, "failed to probe DT parameters\n"); + return rc; + } + + return 0; +} + +static int gpmc_remove(struct platform_device *pdev) +{ + gpmc_free_irq(); + gpmc_mem_exit(); + pm_runtime_put_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); + gpmc_dev = NULL; + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int gpmc_suspend(struct device *dev) +{ + omap3_gpmc_save_context(); + pm_runtime_put_sync(dev); + return 0; +} + +static int gpmc_resume(struct device *dev) +{ + pm_runtime_get_sync(dev); + omap3_gpmc_restore_context(); + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(gpmc_pm_ops, gpmc_suspend, gpmc_resume); + +static struct platform_driver gpmc_driver = { + .probe = gpmc_probe, + .remove = gpmc_remove, + .driver = { + .name = DEVICE_NAME, + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(gpmc_dt_ids), + .pm = &gpmc_pm_ops, + }, +}; + +static __init int gpmc_init(void) +{ + return platform_driver_register(&gpmc_driver); +} + +static __exit void gpmc_exit(void) +{ + platform_driver_unregister(&gpmc_driver); + +} + +omap_postcore_initcall(gpmc_init); +module_exit(gpmc_exit); + +static int __init omap_gpmc_init(void) +{ + struct omap_hwmod *oh; + struct platform_device *pdev; + char *oh_name = "gpmc"; + + /* + * if the board boots up with a populated DT, do not + * manually add the device from this initcall + */ + if (of_have_populated_dt()) + return -ENODEV; + + oh = omap_hwmod_lookup(oh_name); + if (!oh) { + pr_err("Could not look up %s\n", oh_name); + return -ENODEV; + } + + pdev = omap_device_build(DEVICE_NAME, -1, oh, NULL, 0); + WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); + + return PTR_RET(pdev); +} +omap_postcore_initcall(omap_gpmc_init); + +static irqreturn_t gpmc_handle_irq(int irq, void *dev) +{ + int i; + u32 regval; + + regval = gpmc_read_reg(GPMC_IRQSTATUS); + + if (!regval) + return IRQ_NONE; + + for (i = 0; i < GPMC_NR_IRQ; i++) + if (regval & gpmc_client_irq[i].bitmask) + generic_handle_irq(gpmc_client_irq[i].irq); + + gpmc_write_reg(GPMC_IRQSTATUS, regval); + + return IRQ_HANDLED; +} + +static struct omap3_gpmc_regs gpmc_context; + +void omap3_gpmc_save_context(void) +{ + int i; + + gpmc_context.sysconfig = gpmc_read_reg(GPMC_SYSCONFIG); + gpmc_context.irqenable = gpmc_read_reg(GPMC_IRQENABLE); + gpmc_context.timeout_ctrl = gpmc_read_reg(GPMC_TIMEOUT_CONTROL); + gpmc_context.config = gpmc_read_reg(GPMC_CONFIG); + gpmc_context.prefetch_config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1); + gpmc_context.prefetch_config2 = gpmc_read_reg(GPMC_PREFETCH_CONFIG2); + gpmc_context.prefetch_control = gpmc_read_reg(GPMC_PREFETCH_CONTROL); + for (i = 0; i < gpmc_cs_num; i++) { + gpmc_context.cs_context[i].is_valid = gpmc_cs_mem_enabled(i); + if (gpmc_context.cs_context[i].is_valid) { + gpmc_context.cs_context[i].config1 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG1); + gpmc_context.cs_context[i].config2 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG2); + gpmc_context.cs_context[i].config3 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG3); + gpmc_context.cs_context[i].config4 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG4); + gpmc_context.cs_context[i].config5 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG5); + gpmc_context.cs_context[i].config6 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG6); + gpmc_context.cs_context[i].config7 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG7); + } + } +} + +void omap3_gpmc_restore_context(void) +{ + int i; + + gpmc_write_reg(GPMC_SYSCONFIG, gpmc_context.sysconfig); + gpmc_write_reg(GPMC_IRQENABLE, gpmc_context.irqenable); + gpmc_write_reg(GPMC_TIMEOUT_CONTROL, gpmc_context.timeout_ctrl); + gpmc_write_reg(GPMC_CONFIG, gpmc_context.config); + gpmc_write_reg(GPMC_PREFETCH_CONFIG1, gpmc_context.prefetch_config1); + gpmc_write_reg(GPMC_PREFETCH_CONFIG2, gpmc_context.prefetch_config2); + gpmc_write_reg(GPMC_PREFETCH_CONTROL, gpmc_context.prefetch_control); + for (i = 0; i < gpmc_cs_num; i++) { + if (gpmc_context.cs_context[i].is_valid) { + gpmc_cs_write_reg(i, GPMC_CS_CONFIG1, + gpmc_context.cs_context[i].config1); + gpmc_cs_write_reg(i, GPMC_CS_CONFIG2, + gpmc_context.cs_context[i].config2); + gpmc_cs_write_reg(i, GPMC_CS_CONFIG3, + gpmc_context.cs_context[i].config3); + gpmc_cs_write_reg(i, GPMC_CS_CONFIG4, + gpmc_context.cs_context[i].config4); + gpmc_cs_write_reg(i, GPMC_CS_CONFIG5, + gpmc_context.cs_context[i].config5); + gpmc_cs_write_reg(i, GPMC_CS_CONFIG6, + gpmc_context.cs_context[i].config6); + gpmc_cs_write_reg(i, GPMC_CS_CONFIG7, + gpmc_context.cs_context[i].config7); + } + } } diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h new file mode 100644 index 00000000000..707f6d58edd --- /dev/null +++ b/arch/arm/mach-omap2/gpmc.h @@ -0,0 +1,231 @@ +/* + * General-Purpose Memory Controller for OMAP2 + * + * Copyright (C) 2005-2006 Nokia Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __OMAP2_GPMC_H +#define __OMAP2_GPMC_H + +#include <linux/platform_data/mtd-nand-omap2.h> + +/* Maximum Number of Chip Selects */ +#define GPMC_CS_NUM 8 + +#define GPMC_CS_CONFIG1 0x00 +#define GPMC_CS_CONFIG2 0x04 +#define GPMC_CS_CONFIG3 0x08 +#define GPMC_CS_CONFIG4 0x0c +#define GPMC_CS_CONFIG5 0x10 +#define GPMC_CS_CONFIG6 0x14 +#define GPMC_CS_CONFIG7 0x18 +#define GPMC_CS_NAND_COMMAND 0x1c +#define GPMC_CS_NAND_ADDRESS 0x20 +#define GPMC_CS_NAND_DATA 0x24 + +/* Control Commands */ +#define GPMC_CONFIG_RDY_BSY 0x00000001 +#define GPMC_CONFIG_DEV_SIZE 0x00000002 +#define GPMC_CONFIG_DEV_TYPE 0x00000003 +#define GPMC_SET_IRQ_STATUS 0x00000004 +#define GPMC_CONFIG_WP 0x00000005 + +#define GPMC_ENABLE_IRQ 0x0000000d + +/* ECC commands */ +#define GPMC_ECC_READ 0 /* Reset Hardware ECC for read */ +#define GPMC_ECC_WRITE 1 /* Reset Hardware ECC for write */ +#define GPMC_ECC_READSYN 2 /* Reset before syndrom is read back */ + +#define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31) +#define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 30) +#define GPMC_CONFIG1_READTYPE_ASYNC (0 << 29) +#define GPMC_CONFIG1_READTYPE_SYNC (1 << 29) +#define GPMC_CONFIG1_WRITEMULTIPLE_SUPP (1 << 28) +#define GPMC_CONFIG1_WRITETYPE_ASYNC (0 << 27) +#define GPMC_CONFIG1_WRITETYPE_SYNC (1 << 27) +#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25) +#define GPMC_CONFIG1_PAGE_LEN(val) ((val & 3) << 23) +#define GPMC_CONFIG1_WAIT_READ_MON (1 << 22) +#define GPMC_CONFIG1_WAIT_WRITE_MON (1 << 21) +#define GPMC_CONFIG1_WAIT_MON_IIME(val) ((val & 3) << 18) +#define GPMC_CONFIG1_WAIT_PIN_SEL(val) ((val & 3) << 16) +#define GPMC_CONFIG1_DEVICESIZE(val) ((val & 3) << 12) +#define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1) +#define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10) +#define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0) +#define GPMC_CONFIG1_MUXTYPE(val) ((val & 3) << 8) +#define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4) +#define GPMC_CONFIG1_FCLK_DIV(val) (val & 3) +#define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1)) +#define GPMC_CONFIG1_FCLK_DIV3 (GPMC_CONFIG1_FCLK_DIV(2)) +#define GPMC_CONFIG1_FCLK_DIV4 (GPMC_CONFIG1_FCLK_DIV(3)) +#define GPMC_CONFIG7_CSVALID (1 << 6) + +#define GPMC_DEVICETYPE_NOR 0 +#define GPMC_DEVICETYPE_NAND 2 +#define GPMC_CONFIG_WRITEPROTECT 0x00000010 +#define WR_RD_PIN_MONITORING 0x00600000 +#define GPMC_IRQ_FIFOEVENTENABLE 0x01 +#define GPMC_IRQ_COUNT_EVENT 0x02 + +#define GPMC_BURST_4 4 /* 4 word burst */ +#define GPMC_BURST_8 8 /* 8 word burst */ +#define GPMC_BURST_16 16 /* 16 word burst */ +#define GPMC_DEVWIDTH_8BIT 1 /* 8-bit device width */ +#define GPMC_DEVWIDTH_16BIT 2 /* 16-bit device width */ +#define GPMC_MUX_AAD 1 /* Addr-Addr-Data multiplex */ +#define GPMC_MUX_AD 2 /* Addr-Data multiplex */ + +/* bool type time settings */ +struct gpmc_bool_timings { + bool cycle2cyclediffcsen; + bool cycle2cyclesamecsen; + bool we_extra_delay; + bool oe_extra_delay; + bool adv_extra_delay; + bool cs_extra_delay; + bool time_para_granularity; +}; + +/* + * Note that all values in this struct are in nanoseconds except sync_clk + * (which is in picoseconds), while the register values are in gpmc_fck cycles. + */ +struct gpmc_timings { + /* Minimum clock period for synchronous mode (in picoseconds) */ + u32 sync_clk; + + /* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */ + u32 cs_on; /* Assertion time */ + u32 cs_rd_off; /* Read deassertion time */ + u32 cs_wr_off; /* Write deassertion time */ + + /* ADV signal timings corresponding to GPMC_CONFIG3 */ + u32 adv_on; /* Assertion time */ + u32 adv_rd_off; /* Read deassertion time */ + u32 adv_wr_off; /* Write deassertion time */ + + /* WE signals timings corresponding to GPMC_CONFIG4 */ + u32 we_on; /* WE assertion time */ + u32 we_off; /* WE deassertion time */ + + /* OE signals timings corresponding to GPMC_CONFIG4 */ + u32 oe_on; /* OE assertion time */ + u32 oe_off; /* OE deassertion time */ + + /* Access time and cycle time timings corresponding to GPMC_CONFIG5 */ + u32 page_burst_access; /* Multiple access word delay */ + u32 access; /* Start-cycle to first data valid delay */ + u32 rd_cycle; /* Total read cycle time */ + u32 wr_cycle; /* Total write cycle time */ + + u32 bus_turnaround; + u32 cycle2cycle_delay; + + u32 wait_monitoring; + u32 clk_activation; + + /* The following are only on OMAP3430 */ + u32 wr_access; /* WRACCESSTIME */ + u32 wr_data_mux_bus; /* WRDATAONADMUXBUS */ + + struct gpmc_bool_timings bool_timings; +}; + +/* Device timings in picoseconds */ +struct gpmc_device_timings { + u32 t_ceasu; /* address setup to CS valid */ + u32 t_avdasu; /* address setup to ADV valid */ + /* XXX: try to combine t_avdp_r & t_avdp_w. Issue is + * of tusb using these timings even for sync whilst + * ideally for adv_rd/(wr)_off it should have considered + * t_avdh instead. This indirectly necessitates r/w + * variations of t_avdp as it is possible to have one + * sync & other async + */ + u32 t_avdp_r; /* ADV low time (what about t_cer ?) */ + u32 t_avdp_w; + u32 t_aavdh; /* address hold time */ + u32 t_oeasu; /* address setup to OE valid */ + u32 t_aa; /* access time from ADV assertion */ + u32 t_iaa; /* initial access time */ + u32 t_oe; /* access time from OE assertion */ + u32 t_ce; /* access time from CS asertion */ + u32 t_rd_cycle; /* read cycle time */ + u32 t_cez_r; /* read CS deassertion to high Z */ + u32 t_cez_w; /* write CS deassertion to high Z */ + u32 t_oez; /* OE deassertion to high Z */ + u32 t_weasu; /* address setup to WE valid */ + u32 t_wpl; /* write assertion time */ + u32 t_wph; /* write deassertion time */ + u32 t_wr_cycle; /* write cycle time */ + + u32 clk; + u32 t_bacc; /* burst access valid clock to output delay */ + u32 t_ces; /* CS setup time to clk */ + u32 t_avds; /* ADV setup time to clk */ + u32 t_avdh; /* ADV hold time from clk */ + u32 t_ach; /* address hold time from clk */ + u32 t_rdyo; /* clk to ready valid */ + + u32 t_ce_rdyz; /* XXX: description ?, or use t_cez instead */ + u32 t_ce_avd; /* CS on to ADV on delay */ + + /* XXX: check the possibility of combining + * cyc_aavhd_oe & cyc_aavdh_we + */ + u8 cyc_aavdh_oe;/* read address hold time in cycles */ + u8 cyc_aavdh_we;/* write address hold time in cycles */ + u8 cyc_oe; /* access time from OE assertion in cycles */ + u8 cyc_wpl; /* write deassertion time in cycles */ + u32 cyc_iaa; /* initial access time in cycles */ + + /* extra delays */ + bool ce_xdelay; + bool avd_xdelay; + bool oe_xdelay; + bool we_xdelay; +}; + +struct gpmc_settings { + bool burst_wrap; /* enables wrap bursting */ + bool burst_read; /* enables read page/burst mode */ + bool burst_write; /* enables write page/burst mode */ + bool device_nand; /* device is NAND */ + bool sync_read; /* enables synchronous reads */ + bool sync_write; /* enables synchronous writes */ + bool wait_on_read; /* monitor wait on reads */ + bool wait_on_write; /* monitor wait on writes */ + u32 burst_len; /* page/burst length */ + u32 device_width; /* device bus width (8 or 16 bit) */ + u32 mux_add_data; /* multiplex address & data */ + u32 wait_pin; /* wait-pin to be used */ +}; + +extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t, + struct gpmc_settings *gpmc_s, + struct gpmc_device_timings *dev_t); + +extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs); +extern int gpmc_get_client_irq(unsigned irq_config); + +extern unsigned int gpmc_ticks_to_ns(unsigned int ticks); + +extern void gpmc_cs_write_reg(int cs, int idx, u32 val); +extern int gpmc_calc_divider(unsigned int sync_clk); +extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t); +extern int gpmc_cs_program_settings(int cs, struct gpmc_settings *p); +extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base); +extern void gpmc_cs_free(int cs); +extern void omap3_gpmc_save_context(void); +extern void omap3_gpmc_restore_context(void); +extern int gpmc_configure(int cmd, int wval); +extern void gpmc_read_settings_dt(struct device_node *np, + struct gpmc_settings *p); + +#endif diff --git a/arch/arm/mach-omap2/hdq1w.c b/arch/arm/mach-omap2/hdq1w.c new file mode 100644 index 00000000000..f78b4a16195 --- /dev/null +++ b/arch/arm/mach-omap2/hdq1w.c @@ -0,0 +1,99 @@ +/* + * IP block integration code for the HDQ1W/1-wire IP block + * + * Copyright (C) 2012 Texas Instruments, Inc. + * Paul Walmsley + * + * Based on the I2C reset code in arch/arm/mach-omap2/i2c.c by + * Avinash.H.M <avinashhm@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/err.h> +#include <linux/platform_device.h> + +#include "soc.h" +#include "omap_hwmod.h" +#include "omap_device.h" +#include "hdq1w.h" + +#include "prm.h" +#include "common.h" + +/** + * omap_hdq1w_reset - reset the OMAP HDQ1W module + * @oh: struct omap_hwmod * + * + * OCP soft reset the HDQ1W IP block. Section 20.6.1.4 "HDQ1W/1-Wire + * Software Reset" of the OMAP34xx Technical Reference Manual Revision + * ZR (SWPU223R) does not include the rather important fact that, for + * the reset to succeed, the HDQ1W module's internal clock gate must be + * programmed to allow the clock to propagate to the rest of the + * module. In this sense, it's rather similar to the I2C custom reset + * function. Returns 0. + */ +int omap_hdq1w_reset(struct omap_hwmod *oh) +{ + u32 v; + int c = 0; + + /* Write to the SOFTRESET bit */ + omap_hwmod_softreset(oh); + + /* Enable the module's internal clocks */ + v = omap_hwmod_read(oh, HDQ_CTRL_STATUS_OFFSET); + v |= 1 << HDQ_CTRL_STATUS_CLOCKENABLE_SHIFT; + omap_hwmod_write(v, oh, HDQ_CTRL_STATUS_OFFSET); + + /* Poll on RESETDONE bit */ + omap_test_timeout((omap_hwmod_read(oh, + oh->class->sysc->syss_offs) + & SYSS_RESETDONE_MASK), + MAX_MODULE_SOFTRESET_WAIT, c); + + if (c == MAX_MODULE_SOFTRESET_WAIT) + pr_warning("%s: %s: softreset failed (waited %d usec)\n", + __func__, oh->name, MAX_MODULE_SOFTRESET_WAIT); + else + pr_debug("%s: %s: softreset in %d usec\n", __func__, + oh->name, c); + + return 0; +} + +#ifndef CONFIG_OF +static int __init omap_init_hdq(void) +{ + int id = -1; + struct platform_device *pdev; + struct omap_hwmod *oh; + char *oh_name = "hdq1w"; + char *devname = "omap_hdq"; + + oh = omap_hwmod_lookup(oh_name); + if (!oh) + return 0; + + pdev = omap_device_build(devname, id, oh, NULL, 0); + WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", + devname, oh->name); + + return 0; +} +omap_arch_initcall(omap_init_hdq); +#endif diff --git a/arch/arm/mach-omap2/hdq1w.h b/arch/arm/mach-omap2/hdq1w.h new file mode 100644 index 00000000000..c7e08d2a7a4 --- /dev/null +++ b/arch/arm/mach-omap2/hdq1w.h @@ -0,0 +1,36 @@ +/* + * Shared macros and function prototypes for the HDQ1W/1-wire IP block + * + * Copyright (C) 2012 Texas Instruments, Inc. + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef ARCH_ARM_MACH_OMAP2_HDQ1W_H +#define ARCH_ARM_MACH_OMAP2_HDQ1W_H + +#include "omap_hwmod.h" + +/* + * XXX A future cleanup patch should modify + * drivers/w1/masters/omap_hdq.c to use these macros + */ +#define HDQ_CTRL_STATUS_OFFSET 0x0c +#define HDQ_CTRL_STATUS_CLOCKENABLE_SHIFT 5 + + +extern int omap_hdq1w_reset(struct omap_hwmod *oh); + +#endif diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c new file mode 100644 index 00000000000..07d4c7b3575 --- /dev/null +++ b/arch/arm/mach-omap2/hsmmc.c @@ -0,0 +1,518 @@ +/* + * linux/arch/arm/mach-omap2/hsmmc.c + * + * Copyright (C) 2007-2008 Texas Instruments + * Copyright (C) 2008 Nokia Corporation + * Author: Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/string.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/platform_data/gpio-omap.h> + +#include "soc.h" +#include "omap_device.h" +#include "omap-pm.h" + +#include "mux.h" +#include "mmc.h" +#include "hsmmc.h" +#include "control.h" + +#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) + +static u16 control_pbias_offset; +static u16 control_devconf1_offset; + +#define HSMMC_NAME_LEN 9 + +#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) + +static int hsmmc_get_context_loss(struct device *dev) +{ + return omap_pm_get_dev_context_loss_count(dev); +} + +#else +#define hsmmc_get_context_loss NULL +#endif + +static void omap_hsmmc1_before_set_reg(struct device *dev, int slot, + int power_on, int vdd) +{ + u32 reg, prog_io; + struct omap_mmc_platform_data *mmc = dev->platform_data; + + if (mmc->slots[0].remux) + mmc->slots[0].remux(dev, slot, power_on); + + /* + * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the + * card with Vcc regulator (from twl4030 or whatever). OMAP has both + * 1.8V and 3.0V modes, controlled by the PBIAS register. + * + * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which + * is most naturally TWL VSIM; those pins also use PBIAS. + * + * FIXME handle VMMC1A as needed ... + */ + if (power_on) { + if (cpu_is_omap2430()) { + reg = omap_ctrl_readl(OMAP243X_CONTROL_DEVCONF1); + if ((1 << vdd) >= MMC_VDD_30_31) + reg |= OMAP243X_MMC1_ACTIVE_OVERWRITE; + else + reg &= ~OMAP243X_MMC1_ACTIVE_OVERWRITE; + omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1); + } + + if (mmc->slots[0].internal_clock) { + reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); + reg |= OMAP2_MMCSDIO1ADPCLKISEL; + omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0); + } + + reg = omap_ctrl_readl(control_pbias_offset); + if (cpu_is_omap3630()) { + /* Set MMC I/O to 52Mhz */ + prog_io = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO1); + prog_io |= OMAP3630_PRG_SDMMC1_SPEEDCTRL; + omap_ctrl_writel(prog_io, OMAP343X_CONTROL_PROG_IO1); + } else { + reg |= OMAP2_PBIASSPEEDCTRL0; + } + reg &= ~OMAP2_PBIASLITEPWRDNZ0; + omap_ctrl_writel(reg, control_pbias_offset); + } else { + reg = omap_ctrl_readl(control_pbias_offset); + reg &= ~OMAP2_PBIASLITEPWRDNZ0; + omap_ctrl_writel(reg, control_pbias_offset); + } +} + +static void omap_hsmmc1_after_set_reg(struct device *dev, int slot, + int power_on, int vdd) +{ + u32 reg; + + /* 100ms delay required for PBIAS configuration */ + msleep(100); + + if (power_on) { + reg = omap_ctrl_readl(control_pbias_offset); + reg |= (OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0); + if ((1 << vdd) <= MMC_VDD_165_195) + reg &= ~OMAP2_PBIASLITEVMODE0; + else + reg |= OMAP2_PBIASLITEVMODE0; + omap_ctrl_writel(reg, control_pbias_offset); + } else { + reg = omap_ctrl_readl(control_pbias_offset); + reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 | + OMAP2_PBIASLITEVMODE0); + omap_ctrl_writel(reg, control_pbias_offset); + } +} + +static void hsmmc2_select_input_clk_src(struct omap_mmc_platform_data *mmc) +{ + u32 reg; + + reg = omap_ctrl_readl(control_devconf1_offset); + if (mmc->slots[0].internal_clock) + reg |= OMAP2_MMCSDIO2ADPCLKISEL; + else + reg &= ~OMAP2_MMCSDIO2ADPCLKISEL; + omap_ctrl_writel(reg, control_devconf1_offset); +} + +static void hsmmc2_before_set_reg(struct device *dev, int slot, + int power_on, int vdd) +{ + struct omap_mmc_platform_data *mmc = dev->platform_data; + + if (mmc->slots[0].remux) + mmc->slots[0].remux(dev, slot, power_on); + + if (power_on) + hsmmc2_select_input_clk_src(mmc); +} + +static int am35x_hsmmc2_set_power(struct device *dev, int slot, + int power_on, int vdd) +{ + struct omap_mmc_platform_data *mmc = dev->platform_data; + + if (power_on) + hsmmc2_select_input_clk_src(mmc); + + return 0; +} + +static int nop_mmc_set_power(struct device *dev, int slot, int power_on, + int vdd) +{ + return 0; +} + +static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller, + int controller_nr) +{ + if (gpio_is_valid(mmc_controller->slots[0].switch_pin) && + (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES)) + omap_mux_init_gpio(mmc_controller->slots[0].switch_pin, + OMAP_PIN_INPUT_PULLUP); + if (gpio_is_valid(mmc_controller->slots[0].gpio_wp) && + (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES)) + omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp, + OMAP_PIN_INPUT_PULLUP); + if (cpu_is_omap34xx()) { + if (controller_nr == 0) { + omap_mux_init_signal("sdmmc1_clk", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc1_cmd", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc1_dat0", + OMAP_PIN_INPUT_PULLUP); + if (mmc_controller->slots[0].caps & + (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) { + omap_mux_init_signal("sdmmc1_dat1", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc1_dat2", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc1_dat3", + OMAP_PIN_INPUT_PULLUP); + } + if (mmc_controller->slots[0].caps & + MMC_CAP_8_BIT_DATA) { + omap_mux_init_signal("sdmmc1_dat4", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc1_dat5", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc1_dat6", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc1_dat7", + OMAP_PIN_INPUT_PULLUP); + } + } + if (controller_nr == 1) { + /* MMC2 */ + omap_mux_init_signal("sdmmc2_clk", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc2_cmd", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc2_dat0", + OMAP_PIN_INPUT_PULLUP); + + /* + * For 8 wire configurations, Lines DAT4, 5, 6 and 7 + * need to be muxed in the board-*.c files + */ + if (mmc_controller->slots[0].caps & + (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) { + omap_mux_init_signal("sdmmc2_dat1", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc2_dat2", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc2_dat3", + OMAP_PIN_INPUT_PULLUP); + } + if (mmc_controller->slots[0].caps & + MMC_CAP_8_BIT_DATA) { + omap_mux_init_signal("sdmmc2_dat4.sdmmc2_dat4", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc2_dat5.sdmmc2_dat5", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc2_dat6.sdmmc2_dat6", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc2_dat7.sdmmc2_dat7", + OMAP_PIN_INPUT_PULLUP); + } + } + + /* + * For MMC3 the pins need to be muxed in the board-*.c files + */ + } +} + +static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, + struct omap_mmc_platform_data *mmc) +{ + char *hc_name; + + hc_name = kzalloc(sizeof(char) * (HSMMC_NAME_LEN + 1), GFP_KERNEL); + if (!hc_name) { + pr_err("Cannot allocate memory for controller slot name\n"); + kfree(hc_name); + return -ENOMEM; + } + + if (c->name) + strncpy(hc_name, c->name, HSMMC_NAME_LEN); + else + snprintf(hc_name, (HSMMC_NAME_LEN + 1), "mmc%islot%i", + c->mmc, 1); + mmc->slots[0].name = hc_name; + mmc->nr_slots = 1; + mmc->slots[0].caps = c->caps; + mmc->slots[0].pm_caps = c->pm_caps; + mmc->slots[0].internal_clock = !c->ext_clock; + mmc->max_freq = c->max_freq; + mmc->reg_offset = 0; + mmc->get_context_loss_count = hsmmc_get_context_loss; + + mmc->slots[0].switch_pin = c->gpio_cd; + mmc->slots[0].gpio_wp = c->gpio_wp; + + mmc->slots[0].remux = c->remux; + mmc->slots[0].init_card = c->init_card; + + if (c->cover_only) + mmc->slots[0].cover = 1; + + if (c->nonremovable) + mmc->slots[0].nonremovable = 1; + + if (c->power_saving) + mmc->slots[0].power_saving = 1; + + if (c->no_off) + mmc->slots[0].no_off = 1; + + if (c->no_off_init) + mmc->slots[0].no_regulator_off_init = c->no_off_init; + + if (c->vcc_aux_disable_is_sleep) + mmc->slots[0].vcc_aux_disable_is_sleep = 1; + + /* + * NOTE: MMC slots should have a Vcc regulator set up. + * This may be from a TWL4030-family chip, another + * controllable regulator, or a fixed supply. + * + * temporary HACK: ocr_mask instead of fixed supply + */ + if (soc_is_am35xx()) + mmc->slots[0].ocr_mask = MMC_VDD_165_195 | + MMC_VDD_26_27 | + MMC_VDD_27_28 | + MMC_VDD_29_30 | + MMC_VDD_30_31 | + MMC_VDD_31_32; + else + mmc->slots[0].ocr_mask = c->ocr_mask; + + if (!soc_is_am35xx()) + mmc->slots[0].features |= HSMMC_HAS_PBIAS; + + switch (c->mmc) { + case 1: + if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { + /* on-chip level shifting via PBIAS0/PBIAS1 */ + mmc->slots[0].before_set_reg = + omap_hsmmc1_before_set_reg; + mmc->slots[0].after_set_reg = + omap_hsmmc1_after_set_reg; + } + + if (soc_is_am35xx()) + mmc->slots[0].set_power = nop_mmc_set_power; + + /* OMAP3630 HSMMC1 supports only 4-bit */ + if (cpu_is_omap3630() && + (c->caps & MMC_CAP_8_BIT_DATA)) { + c->caps &= ~MMC_CAP_8_BIT_DATA; + c->caps |= MMC_CAP_4_BIT_DATA; + mmc->slots[0].caps = c->caps; + } + break; + case 2: + if (soc_is_am35xx()) + mmc->slots[0].set_power = am35x_hsmmc2_set_power; + + if (c->ext_clock) + c->transceiver = 1; + if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) { + c->caps &= ~MMC_CAP_8_BIT_DATA; + c->caps |= MMC_CAP_4_BIT_DATA; + } + if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { + /* off-chip level shifting, or none */ + mmc->slots[0].before_set_reg = hsmmc2_before_set_reg; + mmc->slots[0].after_set_reg = NULL; + } + break; + case 3: + case 4: + case 5: + mmc->slots[0].before_set_reg = NULL; + mmc->slots[0].after_set_reg = NULL; + break; + default: + pr_err("MMC%d configuration not supported!\n", c->mmc); + kfree(hc_name); + return -ENODEV; + } + return 0; +} + +static int omap_hsmmc_done; + +void omap_hsmmc_late_init(struct omap2_hsmmc_info *c) +{ + struct platform_device *pdev; + struct omap_mmc_platform_data *mmc_pdata; + int res; + + if (omap_hsmmc_done != 1) + return; + + omap_hsmmc_done++; + + for (; c->mmc; c++) { + if (!c->deferred) + continue; + + pdev = c->pdev; + if (!pdev) + continue; + + mmc_pdata = pdev->dev.platform_data; + if (!mmc_pdata) + continue; + + mmc_pdata->slots[0].switch_pin = c->gpio_cd; + mmc_pdata->slots[0].gpio_wp = c->gpio_wp; + + res = omap_device_register(pdev); + if (res) + pr_err("Could not late init MMC %s\n", + c->name); + } +} + +#define MAX_OMAP_MMC_HWMOD_NAME_LEN 16 + +static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo, + int ctrl_nr) +{ + struct omap_hwmod *oh; + struct omap_hwmod *ohs[1]; + struct omap_device *od; + struct platform_device *pdev; + char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN]; + struct omap_mmc_platform_data *mmc_data; + struct omap_mmc_dev_attr *mmc_dev_attr; + char *name; + int res; + + mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL); + if (!mmc_data) { + pr_err("Cannot allocate memory for mmc device!\n"); + return; + } + + res = omap_hsmmc_pdata_init(hsmmcinfo, mmc_data); + if (res < 0) + goto free_mmc; + + omap_hsmmc_mux(mmc_data, (ctrl_nr - 1)); + + name = "omap_hsmmc"; + res = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN, + "mmc%d", ctrl_nr); + WARN(res >= MAX_OMAP_MMC_HWMOD_NAME_LEN, + "String buffer overflow in MMC%d device setup\n", ctrl_nr); + + oh = omap_hwmod_lookup(oh_name); + if (!oh) { + pr_err("Could not look up %s\n", oh_name); + goto free_name; + } + ohs[0] = oh; + if (oh->dev_attr != NULL) { + mmc_dev_attr = oh->dev_attr; + mmc_data->controller_flags = mmc_dev_attr->flags; + /* + * erratum 2.1.1.128 doesn't apply if board has + * a transceiver is attached + */ + if (hsmmcinfo->transceiver) + mmc_data->controller_flags &= + ~OMAP_HSMMC_BROKEN_MULTIBLOCK_READ; + } + + pdev = platform_device_alloc(name, ctrl_nr - 1); + if (!pdev) { + pr_err("Could not allocate pdev for %s\n", name); + goto free_name; + } + dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); + + od = omap_device_alloc(pdev, ohs, 1); + if (IS_ERR(od)) { + pr_err("Could not allocate od for %s\n", name); + goto put_pdev; + } + + res = platform_device_add_data(pdev, mmc_data, + sizeof(struct omap_mmc_platform_data)); + if (res) { + pr_err("Could not add pdata for %s\n", name); + goto put_pdev; + } + + hsmmcinfo->pdev = pdev; + + if (hsmmcinfo->deferred) + goto free_mmc; + + res = omap_device_register(pdev); + if (res) { + pr_err("Could not register od for %s\n", name); + goto free_od; + } + + goto free_mmc; + +free_od: + omap_device_delete(od); + +put_pdev: + platform_device_put(pdev); + +free_name: + kfree(mmc_data->slots[0].name); + +free_mmc: + kfree(mmc_data); +} + +void __init omap_hsmmc_init(struct omap2_hsmmc_info *controllers) +{ + if (omap_hsmmc_done) + return; + + omap_hsmmc_done = 1; + + if (cpu_is_omap2430()) { + control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE; + control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1; + } else { + control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE; + control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1; + } + + for (; controllers->mmc; controllers++) + omap_hsmmc_init_one(controllers, controllers->mmc); + +} + +#endif diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h new file mode 100644 index 00000000000..7f2e790e092 --- /dev/null +++ b/arch/arm/mach-omap2/hsmmc.h @@ -0,0 +1,53 @@ +/* + * MMC definitions for OMAP2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +struct mmc_card; + +struct omap2_hsmmc_info { + u8 mmc; /* controller 1/2/3 */ + u32 caps; /* 4/8 wires and any additional host + * capabilities OR'd (ref. linux/mmc/host.h) */ + u32 pm_caps; /* PM capabilities */ + bool transceiver; /* MMC-2 option */ + bool ext_clock; /* use external pin for input clock */ + bool cover_only; /* No card detect - just cover switch */ + bool nonremovable; /* Nonremovable e.g. eMMC */ + bool power_saving; /* Try to sleep or power off when possible */ + bool no_off; /* power_saving and power is not to go off */ + bool no_off_init; /* no power off when not in MMC sleep state */ + bool vcc_aux_disable_is_sleep; /* Regulator off remapped to sleep */ + bool deferred; /* mmc needs a deferred probe */ + int gpio_cd; /* or -EINVAL */ + int gpio_wp; /* or -EINVAL */ + char *name; /* or NULL for default */ + struct platform_device *pdev; /* mmc controller instance */ + int ocr_mask; /* temporary HACK */ + int max_freq; /* maximum clock, if constrained by external + * circuitry, or 0 for default */ + /* Remux (pad configuration) when powering on/off */ + void (*remux)(struct device *dev, int slot, int power_on); + /* init some special card */ + void (*init_card)(struct mmc_card *card); +}; + +#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) + +void omap_hsmmc_init(struct omap2_hsmmc_info *); +void omap_hsmmc_late_init(struct omap2_hsmmc_info *); + +#else + +static inline void omap_hsmmc_init(struct omap2_hsmmc_info *info) +{ +} + +static inline void omap_hsmmc_late_init(struct omap2_hsmmc_info *info) +{ +} + +#endif diff --git a/arch/arm/mach-omap2/hwspinlock.c b/arch/arm/mach-omap2/hwspinlock.c new file mode 100644 index 00000000000..ef175acaeaa --- /dev/null +++ b/arch/arm/mach-omap2/hwspinlock.c @@ -0,0 +1,60 @@ +/* + * OMAP hardware spinlock device initialization + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com + * + * Contact: Simon Que <sque@ti.com> + * Hari Kanigeri <h-kanigeri2@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/err.h> +#include <linux/hwspinlock.h> + +#include "soc.h" +#include "omap_hwmod.h" +#include "omap_device.h" + +static struct hwspinlock_pdata omap_hwspinlock_pdata __initdata = { + .base_id = 0, +}; + +static int __init hwspinlocks_init(void) +{ + int retval = 0; + struct omap_hwmod *oh; + struct platform_device *pdev; + const char *oh_name = "spinlock"; + const char *dev_name = "omap_hwspinlock"; + + /* + * Hwmod lookup will fail in case our platform doesn't support the + * hardware spinlock module, so it is safe to run this initcall + * on all omaps + */ + oh = omap_hwmod_lookup(oh_name); + if (oh == NULL) + return -EINVAL; + + pdev = omap_device_build(dev_name, 0, oh, &omap_hwspinlock_pdata, + sizeof(struct hwspinlock_pdata)); + if (IS_ERR(pdev)) { + pr_err("Can't build omap_device for %s:%s\n", dev_name, + oh_name); + retval = PTR_ERR(pdev); + } + + return retval; +} +/* early board code might need to reserve specific hwspinlock instances */ +omap_postcore_initcall(hwspinlocks_init); diff --git a/arch/arm/mach-omap2/i2c.c b/arch/arm/mach-omap2/i2c.c new file mode 100644 index 00000000000..b456b4471f3 --- /dev/null +++ b/arch/arm/mach-omap2/i2c.c @@ -0,0 +1,191 @@ +/* + * Helper module for board specific I2C bus registration + * + * Copyright (C) 2009 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "soc.h" +#include "omap_hwmod.h" +#include "omap_device.h" +#include "omap-pm.h" + +#include "prm.h" +#include "common.h" +#include "mux.h" +#include "i2c.h" + +/* In register I2C_CON, Bit 15 is the I2C enable bit */ +#define I2C_EN BIT(15) +#define OMAP2_I2C_CON_OFFSET 0x24 +#define OMAP4_I2C_CON_OFFSET 0xA4 + +#define MAX_OMAP_I2C_HWMOD_NAME_LEN 16 + +static void __init omap2_i2c_mux_pins(int bus_id) +{ + char mux_name[sizeof("i2c2_scl.i2c2_scl")]; + + /* First I2C bus is not muxable */ + if (bus_id == 1) + return; + + sprintf(mux_name, "i2c%i_scl.i2c%i_scl", bus_id, bus_id); + omap_mux_init_signal(mux_name, OMAP_PIN_INPUT); + sprintf(mux_name, "i2c%i_sda.i2c%i_sda", bus_id, bus_id); + omap_mux_init_signal(mux_name, OMAP_PIN_INPUT); +} + +/** + * omap_i2c_reset - reset the omap i2c module. + * @oh: struct omap_hwmod * + * + * The i2c moudle in omap2, omap3 had a special sequence to reset. The + * sequence is: + * - Disable the I2C. + * - Write to SOFTRESET bit. + * - Enable the I2C. + * - Poll on the RESETDONE bit. + * The sequence is implemented in below function. This is called for 2420, + * 2430 and omap3. + */ +int omap_i2c_reset(struct omap_hwmod *oh) +{ + u32 v; + u16 i2c_con; + int c = 0; + + if (oh->class->rev == OMAP_I2C_IP_VERSION_2) { + i2c_con = OMAP4_I2C_CON_OFFSET; + } else if (oh->class->rev == OMAP_I2C_IP_VERSION_1) { + i2c_con = OMAP2_I2C_CON_OFFSET; + } else { + WARN(1, "Cannot reset I2C block %s: unsupported revision\n", + oh->name); + return -EINVAL; + } + + /* Disable I2C */ + v = omap_hwmod_read(oh, i2c_con); + v &= ~I2C_EN; + omap_hwmod_write(v, oh, i2c_con); + + /* Write to the SOFTRESET bit */ + omap_hwmod_softreset(oh); + + /* Enable I2C */ + v = omap_hwmod_read(oh, i2c_con); + v |= I2C_EN; + omap_hwmod_write(v, oh, i2c_con); + + /* Poll on RESETDONE bit */ + omap_test_timeout((omap_hwmod_read(oh, + oh->class->sysc->syss_offs) + & SYSS_RESETDONE_MASK), + MAX_MODULE_SOFTRESET_WAIT, c); + + if (c == MAX_MODULE_SOFTRESET_WAIT) + pr_warning("%s: %s: softreset failed (waited %d usec)\n", + __func__, oh->name, MAX_MODULE_SOFTRESET_WAIT); + else + pr_debug("%s: %s: softreset in %d usec\n", __func__, + oh->name, c); + + return 0; +} + +static int __init omap_i2c_nr_ports(void) +{ + int ports = 0; + + if (cpu_is_omap24xx()) + ports = 2; + else if (cpu_is_omap34xx()) + ports = 3; + else if (cpu_is_omap44xx()) + ports = 4; + return ports; +} + +/* + * XXX This function is a temporary compatibility wrapper - only + * needed until the I2C driver can be converted to call + * omap_pm_set_max_dev_wakeup_lat() and handle a return code. + */ +static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t) +{ + omap_pm_set_max_mpu_wakeup_lat(dev, t); +} + +static const char name[] = "omap_i2c"; + +int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *i2c_pdata, + int bus_id) +{ + int l; + struct omap_hwmod *oh; + struct platform_device *pdev; + char oh_name[MAX_OMAP_I2C_HWMOD_NAME_LEN]; + struct omap_i2c_bus_platform_data *pdata; + struct omap_i2c_dev_attr *dev_attr; + + if (bus_id > omap_i2c_nr_ports()) + return -EINVAL; + + omap2_i2c_mux_pins(bus_id); + + l = snprintf(oh_name, MAX_OMAP_I2C_HWMOD_NAME_LEN, "i2c%d", bus_id); + WARN(l >= MAX_OMAP_I2C_HWMOD_NAME_LEN, + "String buffer overflow in I2C%d device setup\n", bus_id); + oh = omap_hwmod_lookup(oh_name); + if (!oh) { + pr_err("Could not look up %s\n", oh_name); + return -EEXIST; + } + + pdata = i2c_pdata; + /* + * pass the hwmod class's CPU-specific knowledge of I2C IP revision in + * use, and functionality implementation flags, up to the OMAP I2C + * driver via platform data + */ + pdata->rev = oh->class->rev; + + dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr; + pdata->flags = dev_attr->flags; + + /* + * When waiting for completion of a i2c transfer, we need to + * set a wake up latency constraint for the MPU. This is to + * ensure quick enough wakeup from idle, when transfer + * completes. + * Only omap3 has support for constraints + */ + if (cpu_is_omap34xx()) + pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; + pdev = omap_device_build(name, bus_id, oh, pdata, + sizeof(struct omap_i2c_bus_platform_data)); + WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name); + + return PTR_ERR_OR_ZERO(pdev); +} + +static int __init omap_i2c_cmdline(void) +{ + return omap_register_i2c_bus_cmdline(); +} +omap_subsys_initcall(omap_i2c_cmdline); diff --git a/arch/arm/mach-omap2/i2c.h b/arch/arm/mach-omap2/i2c.h new file mode 100644 index 00000000000..42b6f2e7d19 --- /dev/null +++ b/arch/arm/mach-omap2/i2c.h @@ -0,0 +1,42 @@ +/* + * Helper module for board specific I2C bus registration + * + * Copyright (C) 2009 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include <plat/i2c.h> + +#ifndef __MACH_OMAP2_I2C_H +#define __MACH_OMAP2_I2C_H + +/** + * i2c_dev_attr - OMAP I2C controller device attributes for omap_hwmod + * @fifo_depth: total controller FIFO size (in bytes) + * @flags: differences in hardware support capability + * + * @fifo_depth represents what exists on the hardware, not what is + * actually configured at runtime by the device driver. + */ +struct omap_i2c_dev_attr { + u8 fifo_depth; + u32 flags; +}; + +int omap_i2c_reset(struct omap_hwmod *oh); + +#endif /* __MACH_OMAP2_I2C_H */ diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index b52a02fc7cd..d42022f2a71 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -6,6 +6,9 @@ * Copyright (C) 2005 Nokia Corporation * Written by Tony Lindgren <tony@atomide.com> * + * Copyright (C) 2009-11 Texas Instruments + * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. @@ -15,16 +18,31 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/random.h> +#include <linux/slab.h> + +#ifdef CONFIG_SOC_BUS +#include <linux/sys_soc.h> +#endif #include <asm/cputype.h> -#include <mach/common.h> -#include <mach/control.h> -#include <mach/cpu.h> +#include "common.h" -static struct omap_chip_id omap_chip; -static unsigned int omap_revision; +#include "id.h" + +#include "soc.h" +#include "control.h" +#define OMAP4_SILICON_TYPE_STANDARD 0x01 +#define OMAP4_SILICON_TYPE_PERFORMANCE 0x02 + +#define OMAP_SOC_MAX_NAME_LENGTH 16 + +static unsigned int omap_revision; +static char soc_name[OMAP_SOC_MAX_NAME_LENGTH]; +static char soc_rev[OMAP_SOC_MAX_NAME_LENGTH]; +u32 omap_features; unsigned int omap_rev(void) { @@ -32,18 +50,36 @@ unsigned int omap_rev(void) } EXPORT_SYMBOL(omap_rev); -/** - * omap_chip_is - test whether currently running OMAP matches a chip type - * @oc: omap_chip_t to test against - * - * Test whether the currently-running OMAP chip matches the supplied - * chip type 'oc'. Returns 1 upon a match; 0 upon failure. - */ -int omap_chip_is(struct omap_chip_id oci) +int omap_type(void) { - return (oci.oc & omap_chip.oc) ? 1 : 0; + u32 val = 0; + + if (cpu_is_omap24xx()) { + val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS); + } else if (soc_is_am33xx() || soc_is_am43xx()) { + val = omap_ctrl_readl(AM33XX_CONTROL_STATUS); + } else if (cpu_is_omap34xx()) { + val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS); + } else if (cpu_is_omap44xx()) { + val = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STATUS); + } else if (soc_is_omap54xx() || soc_is_dra7xx()) { + val = omap_ctrl_readl(OMAP5XXX_CONTROL_STATUS); + val &= OMAP5_DEVICETYPE_MASK; + val >>= 6; + goto out; + } else { + pr_err("Cannot detect omap type!\n"); + goto out; + } + + val &= OMAP2_DEVICETYPE_MASK; + val >>= 8; + +out: + return val; } -EXPORT_SYMBOL(omap_chip_is); +EXPORT_SYMBOL(omap_type); + /*----------------------------------------------------------------------------*/ @@ -53,7 +89,12 @@ EXPORT_SYMBOL(omap_chip_is); #define OMAP_TAP_DIE_ID_2 0x0220 #define OMAP_TAP_DIE_ID_3 0x0224 -#define read_tap_reg(reg) __raw_readl(tap_base + (reg)) +#define OMAP_TAP_DIE_ID_44XX_0 0x0200 +#define OMAP_TAP_DIE_ID_44XX_1 0x0208 +#define OMAP_TAP_DIE_ID_44XX_2 0x020c +#define OMAP_TAP_DIE_ID_44XX_3 0x0210 + +#define read_tap_reg(reg) readl_relaxed(tap_base + (reg)) struct omap_id { u16 hawkeye; /* Silicon type (Hawkeye id) */ @@ -74,30 +115,55 @@ static struct omap_id omap_ids[] __initdata = { static void __iomem *tap_base; static u16 tap_prod_id; -void __init omap24xx_check_revision(void) +void omap_get_die_id(struct omap_die_id *odi) +{ + if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) { + odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_0); + odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_1); + odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_2); + odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_3); + + return; + } + odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_0); + odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_1); + odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_2); + odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_3); +} + +static int __init omap_feed_randpool(void) +{ + struct omap_die_id odi; + + /* Throw the die ID into the entropy pool at boot */ + omap_get_die_id(&odi); + add_device_randomness(&odi, sizeof(odi)); + return 0; +} +omap_device_initcall(omap_feed_randpool); + +void __init omap2xxx_check_revision(void) { int i, j; u32 idcode, prod_id; u16 hawkeye; u8 dev_type, rev; + struct omap_die_id odi; idcode = read_tap_reg(OMAP_TAP_IDCODE); prod_id = read_tap_reg(tap_prod_id); hawkeye = (idcode >> 12) & 0xffff; rev = (idcode >> 28) & 0x0f; dev_type = (prod_id >> 16) & 0x0f; + omap_get_die_id(&odi); pr_debug("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n", idcode, rev, hawkeye, (idcode >> 1) & 0x7ff); - pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n", - read_tap_reg(OMAP_TAP_DIE_ID_0)); + pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n", odi.id_0); pr_debug("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n", - read_tap_reg(OMAP_TAP_DIE_ID_1), - (read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf); - pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n", - read_tap_reg(OMAP_TAP_DIE_ID_2)); - pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n", - read_tap_reg(OMAP_TAP_DIE_ID_3)); + odi.id_1, (odi.id_1 >> 28) & 0xf); + pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n", odi.id_2); + pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n", odi.id_3); pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n", prod_id, dev_type); @@ -118,34 +184,168 @@ void __init omap24xx_check_revision(void) } if (j == ARRAY_SIZE(omap_ids)) { - printk(KERN_ERR "Unknown OMAP device type. " - "Handling it as OMAP%04x\n", - omap_ids[i].type >> 16); + pr_err("Unknown OMAP device type. Handling it as OMAP%04x\n", + omap_ids[i].type >> 16); j = i; } - pr_info("OMAP%04x", omap_rev() >> 16); + sprintf(soc_name, "OMAP%04x", omap_rev() >> 16); + sprintf(soc_rev, "ES%x", (omap_rev() >> 12) & 0xf); + + pr_info("%s", soc_name); if ((omap_rev() >> 8) & 0x0f) - pr_info("ES%x", (omap_rev() >> 12) & 0xf); + pr_info("%s", soc_rev); pr_info("\n"); } -void __init omap34xx_check_revision(void) +#define OMAP3_SHOW_FEATURE(feat) \ + if (omap3_has_ ##feat()) \ + printk(#feat" "); + +static void __init omap3_cpuinfo(void) +{ + const char *cpu_name; + + /* + * OMAP3430 and OMAP3530 are assumed to be same. + * + * OMAP3525, OMAP3515 and OMAP3503 can be detected only based + * on available features. Upon detection, update the CPU id + * and CPU class bits. + */ + if (cpu_is_omap3630()) { + cpu_name = "OMAP3630"; + } else if (soc_is_am35xx()) { + cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505"; + } else if (cpu_is_ti816x()) { + cpu_name = "TI816X"; + } else if (soc_is_am335x()) { + cpu_name = "AM335X"; + } else if (soc_is_am437x()) { + cpu_name = "AM437x"; + } else if (cpu_is_ti814x()) { + cpu_name = "TI814X"; + } else if (omap3_has_iva() && omap3_has_sgx()) { + /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */ + cpu_name = "OMAP3430/3530"; + } else if (omap3_has_iva()) { + cpu_name = "OMAP3525"; + } else if (omap3_has_sgx()) { + cpu_name = "OMAP3515"; + } else { + cpu_name = "OMAP3503"; + } + + sprintf(soc_name, "%s", cpu_name); + + /* Print verbose information */ + pr_info("%s %s (", soc_name, soc_rev); + + OMAP3_SHOW_FEATURE(l2cache); + OMAP3_SHOW_FEATURE(iva); + OMAP3_SHOW_FEATURE(sgx); + OMAP3_SHOW_FEATURE(neon); + OMAP3_SHOW_FEATURE(isp); + OMAP3_SHOW_FEATURE(192mhz_clk); + + printk(")\n"); +} + +#define OMAP3_CHECK_FEATURE(status,feat) \ + if (((status & OMAP3_ ##feat## _MASK) \ + >> OMAP3_ ##feat## _SHIFT) != FEAT_ ##feat## _NONE) { \ + omap_features |= OMAP3_HAS_ ##feat; \ + } + +void __init omap3xxx_check_features(void) +{ + u32 status; + + omap_features = 0; + + status = omap_ctrl_readl(OMAP3_CONTROL_OMAP_STATUS); + + OMAP3_CHECK_FEATURE(status, L2CACHE); + OMAP3_CHECK_FEATURE(status, IVA); + OMAP3_CHECK_FEATURE(status, SGX); + OMAP3_CHECK_FEATURE(status, NEON); + OMAP3_CHECK_FEATURE(status, ISP); + if (cpu_is_omap3630()) + omap_features |= OMAP3_HAS_192MHZ_CLK; + if (cpu_is_omap3430() || cpu_is_omap3630()) + omap_features |= OMAP3_HAS_IO_WAKEUP; + if (cpu_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 || + omap_rev() == OMAP3430_REV_ES3_1_2) + omap_features |= OMAP3_HAS_IO_CHAIN_CTRL; + + omap_features |= OMAP3_HAS_SDRC; + + /* + * am35x fixups: + * - The am35x Chip ID register has bits 12, 7:5, and 3:2 marked as + * reserved and therefore return 0 when read. Unfortunately, + * OMAP3_CHECK_FEATURE() will interpret some of those zeroes to + * mean that a feature is present even though it isn't so clear + * the incorrectly set feature bits. + */ + if (soc_is_am35xx()) + omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP); + + /* + * TODO: Get additional info (where applicable) + * e.g. Size of L2 cache. + */ + + omap3_cpuinfo(); +} + +void __init omap4xxx_check_features(void) +{ + u32 si_type; + + si_type = + (read_tap_reg(OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1) >> 16) & 0x03; + + if (si_type == OMAP4_SILICON_TYPE_PERFORMANCE) + omap_features = OMAP4_HAS_PERF_SILICON; +} + +void __init ti81xx_check_features(void) +{ + omap_features = OMAP3_HAS_NEON; + omap3_cpuinfo(); +} + +void __init am33xx_check_features(void) +{ + u32 status; + + omap_features = OMAP3_HAS_NEON; + + status = omap_ctrl_readl(AM33XX_DEV_FEATURE); + if (status & AM33XX_SGX_MASK) + omap_features |= OMAP3_HAS_SGX; + + omap3_cpuinfo(); +} + +void __init omap3xxx_check_revision(void) { + const char *cpu_rev; u32 cpuid, idcode; u16 hawkeye; u8 rev; - char *rev_name = "ES1.0"; /* * We cannot access revision registers on ES1.0. * If the processor type is Cortex-A8 and the revision is 0x0 * it means its Cortex r0p0 which is 3430 ES1.0. */ - cpuid = read_cpuid(CPUID_ID); + cpuid = read_cpuid_id(); if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) { omap_revision = OMAP3430_REV_ES1_0; - goto out; + cpu_rev = "1.0"; + return; } /* @@ -158,70 +358,321 @@ void __init omap34xx_check_revision(void) hawkeye = (idcode >> 12) & 0xffff; rev = (idcode >> 28) & 0xff; - if (hawkeye == 0xb7ae) { + switch (hawkeye) { + case 0xb7ae: + /* Handle 34xx/35xx devices */ switch (rev) { - case 0: + case 0: /* Take care of early samples */ + case 1: omap_revision = OMAP3430_REV_ES2_0; - rev_name = "ES2.0"; + cpu_rev = "2.0"; break; case 2: omap_revision = OMAP3430_REV_ES2_1; - rev_name = "ES2.1"; + cpu_rev = "2.1"; break; case 3: omap_revision = OMAP3430_REV_ES3_0; - rev_name = "ES3.0"; + cpu_rev = "3.0"; break; case 4: omap_revision = OMAP3430_REV_ES3_1; - rev_name = "ES3.1"; + cpu_rev = "3.1"; break; + case 7: + /* FALLTHROUGH */ default: /* Use the latest known revision as default */ - omap_revision = OMAP3430_REV_ES3_1; - rev_name = "Unknown revision\n"; + omap_revision = OMAP3430_REV_ES3_1_2; + cpu_rev = "3.1.2"; } - } + break; + case 0xb868: + /* + * Handle OMAP/AM 3505/3517 devices + * + * Set the device to be OMAP3517 here. Actual device + * is identified later based on the features. + */ + switch (rev) { + case 0: + omap_revision = AM35XX_REV_ES1_0; + cpu_rev = "1.0"; + break; + case 1: + /* FALLTHROUGH */ + default: + omap_revision = AM35XX_REV_ES1_1; + cpu_rev = "1.1"; + } + break; + case 0xb891: + /* Handle 36xx devices */ -out: - pr_info("OMAP%04x %s\n", omap_rev() >> 16, rev_name); + switch(rev) { + case 0: /* Take care of early samples */ + omap_revision = OMAP3630_REV_ES1_0; + cpu_rev = "1.0"; + break; + case 1: + omap_revision = OMAP3630_REV_ES1_1; + cpu_rev = "1.1"; + break; + case 2: + /* FALLTHROUGH */ + default: + omap_revision = OMAP3630_REV_ES1_2; + cpu_rev = "1.2"; + } + break; + case 0xb81e: + switch (rev) { + case 0: + omap_revision = TI8168_REV_ES1_0; + cpu_rev = "1.0"; + break; + case 1: + omap_revision = TI8168_REV_ES1_1; + cpu_rev = "1.1"; + break; + case 2: + omap_revision = TI8168_REV_ES2_0; + cpu_rev = "2.0"; + break; + case 3: + /* FALLTHROUGH */ + default: + omap_revision = TI8168_REV_ES2_1; + cpu_rev = "2.1"; + } + break; + case 0xb944: + switch (rev) { + case 0: + omap_revision = AM335X_REV_ES1_0; + cpu_rev = "1.0"; + break; + case 1: + omap_revision = AM335X_REV_ES2_0; + cpu_rev = "2.0"; + break; + case 2: + /* FALLTHROUGH */ + default: + omap_revision = AM335X_REV_ES2_1; + cpu_rev = "2.1"; + break; + } + break; + case 0xb98c: + switch (rev) { + case 0: + omap_revision = AM437X_REV_ES1_0; + cpu_rev = "1.0"; + break; + case 1: + /* FALLTHROUGH */ + default: + omap_revision = AM437X_REV_ES1_1; + cpu_rev = "1.1"; + break; + } + break; + case 0xb8f2: + switch (rev) { + case 0: + /* FALLTHROUGH */ + case 1: + omap_revision = TI8148_REV_ES1_0; + cpu_rev = "1.0"; + break; + case 2: + omap_revision = TI8148_REV_ES2_0; + cpu_rev = "2.0"; + break; + case 3: + /* FALLTHROUGH */ + default: + omap_revision = TI8148_REV_ES2_1; + cpu_rev = "2.1"; + break; + } + break; + default: + /* Unknown default to latest silicon rev as default */ + omap_revision = OMAP3630_REV_ES1_2; + cpu_rev = "1.2"; + pr_warn("Warning: unknown chip type; assuming OMAP3630ES1.2\n"); + } + sprintf(soc_rev, "ES%s", cpu_rev); } -/* - * Try to detect the exact revision of the omap we're running on - */ -void __init omap2_check_revision(void) +void __init omap4xxx_check_revision(void) { + u32 idcode; + u16 hawkeye; + u8 rev; + /* - * At this point we have an idea about the processor revision set - * earlier with omap2_set_globals_tap(). + * The IC rev detection is done with hawkeye and rev. + * Note that rev does not map directly to defined processor + * revision numbers as ES1.0 uses value 0. */ - if (cpu_is_omap24xx()) - omap24xx_check_revision(); - else if (cpu_is_omap34xx()) - omap34xx_check_revision(); - else - pr_err("OMAP revision unknown, please fix!\n"); + idcode = read_tap_reg(OMAP_TAP_IDCODE); + hawkeye = (idcode >> 12) & 0xffff; + rev = (idcode >> 28) & 0xf; /* - * OK, now we know the exact revision. Initialize omap_chip bits - * for powerdowmain and clockdomain code. + * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0 + * Use ARM register to detect the correct ES version */ - if (cpu_is_omap243x()) { - /* Currently only supports 2430ES2.1 and 2430-all */ - omap_chip.oc |= CHIP_IS_OMAP2430; - } else if (cpu_is_omap242x()) { - /* Currently only supports 2420ES2.1.1 and 2420-all */ - omap_chip.oc |= CHIP_IS_OMAP2420; - } else if (cpu_is_omap343x()) { - omap_chip.oc = CHIP_IS_OMAP3430; - if (omap_rev() == OMAP3430_REV_ES1_0) - omap_chip.oc |= CHIP_IS_OMAP3430ES1; - else if (omap_rev() > OMAP3430_REV_ES1_0) - omap_chip.oc |= CHIP_IS_OMAP3430ES2; - } else { - pr_err("Uninitialized omap_chip, please fix!\n"); + if (!rev && (hawkeye != 0xb94e) && (hawkeye != 0xb975)) { + idcode = read_cpuid_id(); + rev = (idcode & 0xf) - 1; + } + + switch (hawkeye) { + case 0xb852: + switch (rev) { + case 0: + omap_revision = OMAP4430_REV_ES1_0; + break; + case 1: + default: + omap_revision = OMAP4430_REV_ES2_0; + } + break; + case 0xb95c: + switch (rev) { + case 3: + omap_revision = OMAP4430_REV_ES2_1; + break; + case 4: + omap_revision = OMAP4430_REV_ES2_2; + break; + case 6: + default: + omap_revision = OMAP4430_REV_ES2_3; + } + break; + case 0xb94e: + switch (rev) { + case 0: + omap_revision = OMAP4460_REV_ES1_0; + break; + case 2: + default: + omap_revision = OMAP4460_REV_ES1_1; + break; + } + break; + case 0xb975: + switch (rev) { + case 0: + default: + omap_revision = OMAP4470_REV_ES1_0; + break; + } + break; + default: + /* Unknown default to latest silicon rev as default */ + omap_revision = OMAP4430_REV_ES2_3; } + + sprintf(soc_name, "OMAP%04x", omap_rev() >> 16); + sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf, + (omap_rev() >> 8) & 0xf); + pr_info("%s %s\n", soc_name, soc_rev); +} + +void __init omap5xxx_check_revision(void) +{ + u32 idcode; + u16 hawkeye; + u8 rev; + + idcode = read_tap_reg(OMAP_TAP_IDCODE); + hawkeye = (idcode >> 12) & 0xffff; + rev = (idcode >> 28) & 0xff; + switch (hawkeye) { + case 0xb942: + switch (rev) { + case 0: + /* No support for ES1.0 Test chip */ + BUG(); + case 1: + default: + omap_revision = OMAP5430_REV_ES2_0; + } + break; + + case 0xb998: + switch (rev) { + case 0: + /* No support for ES1.0 Test chip */ + BUG(); + case 1: + default: + omap_revision = OMAP5432_REV_ES2_0; + } + break; + + default: + /* Unknown default to latest silicon rev as default*/ + omap_revision = OMAP5430_REV_ES2_0; + } + + sprintf(soc_name, "OMAP%04x", omap_rev() >> 16); + sprintf(soc_rev, "ES%d.0", (omap_rev() >> 12) & 0xf); + + pr_info("%s %s\n", soc_name, soc_rev); +} + +void __init dra7xxx_check_revision(void) +{ + u32 idcode; + u16 hawkeye; + u8 rev; + + idcode = read_tap_reg(OMAP_TAP_IDCODE); + hawkeye = (idcode >> 12) & 0xffff; + rev = (idcode >> 28) & 0xff; + switch (hawkeye) { + case 0xb990: + switch (rev) { + case 0: + omap_revision = DRA752_REV_ES1_0; + break; + case 1: + default: + omap_revision = DRA752_REV_ES1_1; + } + break; + + case 0xb9bc: + switch (rev) { + case 0: + omap_revision = DRA722_REV_ES1_0; + break; + default: + /* If we have no new revisions */ + omap_revision = DRA722_REV_ES1_0; + break; + } + break; + + default: + /* Unknown default to latest silicon rev as default*/ + pr_warn("%s: unknown idcode=0x%08x (hawkeye=0x%08x,rev=0x%d)\n", + __func__, idcode, hawkeye, rev); + omap_revision = DRA752_REV_ES1_1; + } + + sprintf(soc_name, "DRA%03x", omap_rev() >> 16); + sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf, + (omap_rev() >> 8) & 0xf); + + pr_info("%s %s\n", soc_name, soc_rev); } /* @@ -231,13 +682,77 @@ void __init omap2_check_revision(void) * detect the exact revision later on in omap2_detect_revision() once map_io * is done. */ -void __init omap2_set_globals_tap(struct omap_globals *omap2_globals) +void __init omap2_set_globals_tap(u32 class, void __iomem *tap) { - omap_revision = omap2_globals->class; - tap_base = omap2_globals->tap; + omap_revision = class; + tap_base = tap; + /* XXX What is this intended to do? */ if (cpu_is_omap34xx()) tap_prod_id = 0x0210; else tap_prod_id = 0x0208; } + +#ifdef CONFIG_SOC_BUS + +static const char * const omap_types[] = { + [OMAP2_DEVICE_TYPE_TEST] = "TST", + [OMAP2_DEVICE_TYPE_EMU] = "EMU", + [OMAP2_DEVICE_TYPE_SEC] = "HS", + [OMAP2_DEVICE_TYPE_GP] = "GP", + [OMAP2_DEVICE_TYPE_BAD] = "BAD", +}; + +static const char * __init omap_get_family(void) +{ + if (cpu_is_omap24xx()) + return kasprintf(GFP_KERNEL, "OMAP2"); + else if (cpu_is_omap34xx()) + return kasprintf(GFP_KERNEL, "OMAP3"); + else if (cpu_is_omap44xx()) + return kasprintf(GFP_KERNEL, "OMAP4"); + else if (soc_is_omap54xx()) + return kasprintf(GFP_KERNEL, "OMAP5"); + else if (soc_is_am43xx()) + return kasprintf(GFP_KERNEL, "AM43xx"); + else if (soc_is_dra7xx()) + return kasprintf(GFP_KERNEL, "DRA7"); + else + return kasprintf(GFP_KERNEL, "Unknown"); +} + +static ssize_t omap_get_type(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%s\n", omap_types[omap_type()]); +} + +static struct device_attribute omap_soc_attr = + __ATTR(type, S_IRUGO, omap_get_type, NULL); + +void __init omap_soc_device_init(void) +{ + struct device *parent; + struct soc_device *soc_dev; + struct soc_device_attribute *soc_dev_attr; + + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) + return; + + soc_dev_attr->machine = soc_name; + soc_dev_attr->family = omap_get_family(); + soc_dev_attr->revision = soc_rev; + + soc_dev = soc_device_register(soc_dev_attr); + if (IS_ERR(soc_dev)) { + kfree(soc_dev_attr); + return; + } + + parent = soc_device_to_device(soc_dev); + device_create_file(parent, &omap_soc_attr); +} +#endif /* CONFIG_SOC_BUS */ diff --git a/arch/arm/mach-omap2/id.h b/arch/arm/mach-omap2/id.h new file mode 100644 index 00000000000..02ed3aa56f1 --- /dev/null +++ b/arch/arm/mach-omap2/id.h @@ -0,0 +1,22 @@ +/* + * OMAP2 CPU identification code + * + * Copyright (C) 2010 Kan-Ru Chen <kanru@0xlab.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef OMAP2_ARCH_ID_H +#define OMAP2_ARCH_ID_H + +struct omap_die_id { + u32 id_0; + u32 id_1; + u32 id_2; + u32 id_3; +}; + +void omap_get_die_id(struct omap_die_id *odi); + +#endif diff --git a/arch/arm/mach-omap2/include/mach/barriers.h b/arch/arm/mach-omap2/include/mach/barriers.h new file mode 100644 index 00000000000..1c582a8592b --- /dev/null +++ b/arch/arm/mach-omap2/include/mach/barriers.h @@ -0,0 +1,33 @@ +/* + * OMAP memory barrier header. + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __MACH_BARRIERS_H +#define __MACH_BARRIERS_H + +#include <asm/outercache.h> + +extern void omap_bus_sync(void); + +#define rmb() dsb() +#define wmb() do { dsb(); outer_sync(); omap_bus_sync(); } while (0) +#define mb() wmb() + +#endif /* __MACH_BARRIERS_H */ diff --git a/arch/arm/mach-omap2/include/mach/hardware.h b/arch/arm/mach-omap2/include/mach/hardware.h new file mode 100644 index 00000000000..54492dbf697 --- /dev/null +++ b/arch/arm/mach-omap2/include/mach/hardware.h @@ -0,0 +1,3 @@ +/* + * arch/arm/mach-omap2/include/mach/hardware.h + */ diff --git a/arch/arm/mach-omap2/include/mach/irqs.h b/arch/arm/mach-omap2/include/mach/irqs.h new file mode 100644 index 00000000000..ba5282cafa4 --- /dev/null +++ b/arch/arm/mach-omap2/include/mach/irqs.h @@ -0,0 +1,3 @@ +/* + * arch/arm/mach-omap2/include/mach/irqs.h + */ diff --git a/arch/arm/mach-omap2/include/mach/serial.h b/arch/arm/mach-omap2/include/mach/serial.h new file mode 100644 index 00000000000..7ca1fcff453 --- /dev/null +++ b/arch/arm/mach-omap2/include/mach/serial.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2009 Texas Instruments + * Added OMAP4 support- Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* OMAP2 serial ports */ +#define OMAP2_UART1_BASE 0x4806a000 +#define OMAP2_UART2_BASE 0x4806c000 +#define OMAP2_UART3_BASE 0x4806e000 + +/* OMAP3 serial ports */ +#define OMAP3_UART1_BASE OMAP2_UART1_BASE +#define OMAP3_UART2_BASE OMAP2_UART2_BASE +#define OMAP3_UART3_BASE 0x49020000 +#define OMAP3_UART4_BASE 0x49042000 /* Only on 36xx */ +#define OMAP3_UART4_AM35XX_BASE 0x4809E000 /* Only on AM35xx */ + +/* OMAP4 serial ports */ +#define OMAP4_UART1_BASE OMAP2_UART1_BASE +#define OMAP4_UART2_BASE OMAP2_UART2_BASE +#define OMAP4_UART3_BASE 0x48020000 +#define OMAP4_UART4_BASE 0x4806e000 + +/* TI81XX serial ports */ +#define TI81XX_UART1_BASE 0x48020000 +#define TI81XX_UART2_BASE 0x48022000 +#define TI81XX_UART3_BASE 0x48024000 + +/* AM3505/3517 UART4 */ +#define AM35XX_UART4_BASE 0x4809E000 /* Only on AM3505/3517 */ + +/* AM33XX serial port */ +#define AM33XX_UART1_BASE 0x44E09000 + +/* OMAP5 serial ports */ +#define OMAP5_UART1_BASE OMAP2_UART1_BASE +#define OMAP5_UART2_BASE OMAP2_UART2_BASE +#define OMAP5_UART3_BASE OMAP4_UART3_BASE +#define OMAP5_UART4_BASE OMAP4_UART4_BASE +#define OMAP5_UART5_BASE 0x48066000 +#define OMAP5_UART6_BASE 0x48068000 + +/* External port on Zoom2/3 */ +#define ZOOM_UART_BASE 0x10000000 +#define ZOOM_UART_VIRT 0xfa400000 + +#define OMAP_PORT_SHIFT 2 +#define ZOOM_PORT_SHIFT 1 + +#define OMAP24XX_BASE_BAUD (48000000/16) + +#ifndef __ASSEMBLER__ + +struct omap_board_data; +struct omap_uart_port_info; + +extern void omap_serial_init(void); +extern void omap_serial_board_init(struct omap_uart_port_info *platform_data); +extern void omap_serial_init_port(struct omap_board_data *bdata, + struct omap_uart_port_info *platform_data); +#endif diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 5ea64f926ed..8f559450c87 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -4,47 +4,68 @@ * OMAP2 I/O mapping code * * Copyright (C) 2005 Nokia Corporation - * Copyright (C) 2007 Texas Instruments + * Copyright (C) 2007-2009 Texas Instruments * * Author: * Juha Yrjola <juha.yrjola@nokia.com> * Syed Khasim <x0khasim@ti.com> * + * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ - #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/clk.h> #include <asm/tlb.h> - #include <asm/mach/map.h> -#include <mach/mux.h> -#include <mach/omapfb.h> -#include <mach/sram.h> - -#include "memory.h" +#include <linux/omap-dma.h> +#include "omap_hwmod.h" +#include "soc.h" +#include "iomap.h" +#include "voltage.h" +#include "powerdomain.h" +#include "clockdomain.h" +#include "common.h" #include "clock.h" +#include "clock2xxx.h" +#include "clock3xxx.h" +#include "clock44xx.h" +#include "omap-pm.h" +#include "sdrc.h" +#include "control.h" +#include "serial.h" +#include "sram.h" +#include "cm2xxx.h" +#include "cm3xxx.h" +#include "prm.h" +#include "cm.h" +#include "prcm_mpu44xx.h" +#include "prminst44xx.h" +#include "cminst44xx.h" +#include "prm2xxx.h" +#include "prm3xxx.h" +#include "prm44xx.h" -#include <mach/powerdomain.h> - -#include "powerdomains.h" - -#include <mach/clockdomain.h> -#include "clockdomains.h" +/* + * omap_clk_soc_init: points to a function that does the SoC-specific + * clock initializations + */ +static int (*omap_clk_soc_init)(void); /* * The machine specific code may provide the extra mapping besides the * default mapping provided here. */ -#ifdef CONFIG_ARCH_OMAP24XX +#if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430) static struct map_desc omap24xx_io_desc[] __initdata = { { .virtual = L3_24XX_VIRT, @@ -60,31 +81,31 @@ static struct map_desc omap24xx_io_desc[] __initdata = { }, }; -#ifdef CONFIG_ARCH_OMAP2420 +#ifdef CONFIG_SOC_OMAP2420 static struct map_desc omap242x_io_desc[] __initdata = { { - .virtual = DSP_MEM_24XX_VIRT, - .pfn = __phys_to_pfn(DSP_MEM_24XX_PHYS), - .length = DSP_MEM_24XX_SIZE, + .virtual = DSP_MEM_2420_VIRT, + .pfn = __phys_to_pfn(DSP_MEM_2420_PHYS), + .length = DSP_MEM_2420_SIZE, .type = MT_DEVICE }, { - .virtual = DSP_IPI_24XX_VIRT, - .pfn = __phys_to_pfn(DSP_IPI_24XX_PHYS), - .length = DSP_IPI_24XX_SIZE, + .virtual = DSP_IPI_2420_VIRT, + .pfn = __phys_to_pfn(DSP_IPI_2420_PHYS), + .length = DSP_IPI_2420_SIZE, .type = MT_DEVICE }, { - .virtual = DSP_MMU_24XX_VIRT, - .pfn = __phys_to_pfn(DSP_MMU_24XX_PHYS), - .length = DSP_MMU_24XX_SIZE, + .virtual = DSP_MMU_2420_VIRT, + .pfn = __phys_to_pfn(DSP_MMU_2420_PHYS), + .length = DSP_MMU_2420_SIZE, .type = MT_DEVICE }, }; #endif -#ifdef CONFIG_ARCH_OMAP2430 +#ifdef CONFIG_SOC_OMAP2430 static struct map_desc omap243x_io_desc[] __initdata = { { .virtual = L4_WK_243X_VIRT, @@ -114,7 +135,7 @@ static struct map_desc omap243x_io_desc[] __initdata = { #endif #endif -#ifdef CONFIG_ARCH_OMAP34XX +#ifdef CONFIG_ARCH_OMAP3 static struct map_desc omap34xx_io_desc[] __initdata = { { .virtual = L3_34XX_VIRT, @@ -129,12 +150,6 @@ static struct map_desc omap34xx_io_desc[] __initdata = { .type = MT_DEVICE }, { - .virtual = L4_WK_34XX_VIRT, - .pfn = __phys_to_pfn(L4_WK_34XX_PHYS), - .length = L4_WK_34XX_SIZE, - .type = MT_DEVICE - }, - { .virtual = OMAP34XX_GPMC_VIRT, .pfn = __phys_to_pfn(OMAP34XX_GPMC_PHYS), .length = OMAP34XX_GPMC_SIZE, @@ -167,40 +182,555 @@ static struct map_desc omap34xx_io_desc[] __initdata = { }; #endif -void __init omap2_map_common_io(void) +#ifdef CONFIG_SOC_TI81XX +static struct map_desc omapti81xx_io_desc[] __initdata = { + { + .virtual = L4_34XX_VIRT, + .pfn = __phys_to_pfn(L4_34XX_PHYS), + .length = L4_34XX_SIZE, + .type = MT_DEVICE + } +}; +#endif + +#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX) +static struct map_desc omapam33xx_io_desc[] __initdata = { + { + .virtual = L4_34XX_VIRT, + .pfn = __phys_to_pfn(L4_34XX_PHYS), + .length = L4_34XX_SIZE, + .type = MT_DEVICE + }, + { + .virtual = L4_WK_AM33XX_VIRT, + .pfn = __phys_to_pfn(L4_WK_AM33XX_PHYS), + .length = L4_WK_AM33XX_SIZE, + .type = MT_DEVICE + } +}; +#endif + +#ifdef CONFIG_ARCH_OMAP4 +static struct map_desc omap44xx_io_desc[] __initdata = { + { + .virtual = L3_44XX_VIRT, + .pfn = __phys_to_pfn(L3_44XX_PHYS), + .length = L3_44XX_SIZE, + .type = MT_DEVICE, + }, + { + .virtual = L4_44XX_VIRT, + .pfn = __phys_to_pfn(L4_44XX_PHYS), + .length = L4_44XX_SIZE, + .type = MT_DEVICE, + }, + { + .virtual = L4_PER_44XX_VIRT, + .pfn = __phys_to_pfn(L4_PER_44XX_PHYS), + .length = L4_PER_44XX_SIZE, + .type = MT_DEVICE, + }, +#ifdef CONFIG_OMAP4_ERRATA_I688 + { + .virtual = OMAP4_SRAM_VA, + .pfn = __phys_to_pfn(OMAP4_SRAM_PA), + .length = PAGE_SIZE, + .type = MT_MEMORY_RW_SO, + }, +#endif + +}; +#endif + +#if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) +static struct map_desc omap54xx_io_desc[] __initdata = { + { + .virtual = L3_54XX_VIRT, + .pfn = __phys_to_pfn(L3_54XX_PHYS), + .length = L3_54XX_SIZE, + .type = MT_DEVICE, + }, + { + .virtual = L4_54XX_VIRT, + .pfn = __phys_to_pfn(L4_54XX_PHYS), + .length = L4_54XX_SIZE, + .type = MT_DEVICE, + }, + { + .virtual = L4_WK_54XX_VIRT, + .pfn = __phys_to_pfn(L4_WK_54XX_PHYS), + .length = L4_WK_54XX_SIZE, + .type = MT_DEVICE, + }, + { + .virtual = L4_PER_54XX_VIRT, + .pfn = __phys_to_pfn(L4_PER_54XX_PHYS), + .length = L4_PER_54XX_SIZE, + .type = MT_DEVICE, + }, +#ifdef CONFIG_OMAP4_ERRATA_I688 + { + .virtual = OMAP4_SRAM_VA, + .pfn = __phys_to_pfn(OMAP4_SRAM_PA), + .length = PAGE_SIZE, + .type = MT_MEMORY_RW_SO, + }, +#endif +}; +#endif + +#ifdef CONFIG_SOC_OMAP2420 +void __init omap242x_map_io(void) { -#if defined(CONFIG_ARCH_OMAP2420) iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc)); iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc)); +} #endif -#if defined(CONFIG_ARCH_OMAP2430) +#ifdef CONFIG_SOC_OMAP2430 +void __init omap243x_map_io(void) +{ iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc)); iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc)); +} #endif -#if defined(CONFIG_ARCH_OMAP34XX) +#ifdef CONFIG_ARCH_OMAP3 +void __init omap3_map_io(void) +{ iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc)); +} +#endif + +#ifdef CONFIG_SOC_TI81XX +void __init ti81xx_map_io(void) +{ + iotable_init(omapti81xx_io_desc, ARRAY_SIZE(omapti81xx_io_desc)); +} +#endif + +#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX) +void __init am33xx_map_io(void) +{ + iotable_init(omapam33xx_io_desc, ARRAY_SIZE(omapam33xx_io_desc)); +} +#endif + +#ifdef CONFIG_ARCH_OMAP4 +void __init omap4_map_io(void) +{ + iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc)); + omap_barriers_init(); +} +#endif + +#if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) +void __init omap5_map_io(void) +{ + iotable_init(omap54xx_io_desc, ARRAY_SIZE(omap54xx_io_desc)); + omap_barriers_init(); +} +#endif +/* + * omap2_init_reprogram_sdrc - reprogram SDRC timing parameters + * + * Sets the CORE DPLL3 M2 divider to the same value that it's at + * currently. This has the effect of setting the SDRC SDRAM AC timing + * registers to the values currently defined by the kernel. Currently + * only defined for OMAP3; will return 0 if called on OMAP2. Returns + * -EINVAL if the dpll3_m2_ck cannot be found, 0 if called on OMAP2, + * or passes along the return value of clk_set_rate(). + */ +static int __init _omap2_init_reprogram_sdrc(void) +{ + struct clk *dpll3_m2_ck; + int v = -EINVAL; + long rate; + + if (!cpu_is_omap34xx()) + return 0; + + dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck"); + if (IS_ERR(dpll3_m2_ck)) + return -EINVAL; + + rate = clk_get_rate(dpll3_m2_ck); + pr_info("Reprogramming SDRC clock to %ld Hz\n", rate); + v = clk_set_rate(dpll3_m2_ck, rate); + if (v) + pr_err("dpll3_m2_clk rate change failed: %d\n", v); + + clk_put(dpll3_m2_ck); + + return v; +} + +static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data) +{ + return omap_hwmod_set_postsetup_state(oh, *(u8 *)data); +} + +static void __init omap_hwmod_init_postsetup(void) +{ + u8 postsetup_state; + + /* Set the default postsetup state for all hwmods */ +#ifdef CONFIG_PM_RUNTIME + postsetup_state = _HWMOD_STATE_IDLE; +#else + postsetup_state = _HWMOD_STATE_ENABLED; #endif + omap_hwmod_for_each(_set_hwmod_postsetup_state, &postsetup_state); - /* Normally devicemaps_init() would flush caches and tlb after - * mdesc->map_io(), but we must also do it here because of the CPU - * revision check below. - */ - local_flush_tlb_all(); - flush_cache_all(); + omap_pm_if_early_init(); +} - omap2_check_revision(); +static void __init __maybe_unused omap_common_late_init(void) +{ + omap_mux_late_init(); + omap2_common_pm_late_init(); + omap_soc_device_init(); +} + +#ifdef CONFIG_SOC_OMAP2420 +void __init omap2420_init_early(void) +{ + omap2_set_globals_tap(OMAP242X_CLASS, OMAP2_L4_IO_ADDRESS(0x48014000)); + omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP2420_SDRC_BASE), + OMAP2_L3_IO_ADDRESS(OMAP2420_SMS_BASE)); + omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE), + NULL); + omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE)); + omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE), NULL); + omap2xxx_check_revision(); + omap2xxx_prm_init(); + omap2xxx_cm_init(); + omap2xxx_voltagedomains_init(); + omap242x_powerdomains_init(); + omap242x_clockdomains_init(); + omap2420_hwmod_init(); + omap_hwmod_init_postsetup(); + omap_clk_soc_init = omap2420_clk_init; +} + +void __init omap2420_init_late(void) +{ + omap_common_late_init(); + omap2_pm_init(); + omap2_clk_enable_autoidle_all(); +} +#endif + +#ifdef CONFIG_SOC_OMAP2430 +void __init omap2430_init_early(void) +{ + omap2_set_globals_tap(OMAP243X_CLASS, OMAP2_L4_IO_ADDRESS(0x4900a000)); + omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP243X_SDRC_BASE), + OMAP2_L3_IO_ADDRESS(OMAP243X_SMS_BASE)); + omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE), + NULL); + omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE)); + omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE), NULL); + omap2xxx_check_revision(); + omap2xxx_prm_init(); + omap2xxx_cm_init(); + omap2xxx_voltagedomains_init(); + omap243x_powerdomains_init(); + omap243x_clockdomains_init(); + omap2430_hwmod_init(); + omap_hwmod_init_postsetup(); + omap_clk_soc_init = omap2430_clk_init; +} + +void __init omap2430_init_late(void) +{ + omap_common_late_init(); + omap2_pm_init(); + omap2_clk_enable_autoidle_all(); +} +#endif + +/* + * Currently only board-omap3beagle.c should call this because of the + * same machine_id for 34xx and 36xx beagle.. Will get fixed with DT. + */ +#ifdef CONFIG_ARCH_OMAP3 +void __init omap3_init_early(void) +{ + omap2_set_globals_tap(OMAP343X_CLASS, OMAP2_L4_IO_ADDRESS(0x4830A000)); + omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE), + OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE)); + omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE), + NULL); + omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE)); + omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE), NULL); + omap3xxx_check_revision(); + omap3xxx_check_features(); + omap3xxx_prm_init(); + omap3xxx_cm_init(); + omap3xxx_voltagedomains_init(); + omap3xxx_powerdomains_init(); + omap3xxx_clockdomains_init(); + omap3xxx_hwmod_init(); + omap_hwmod_init_postsetup(); + omap_clk_soc_init = omap3xxx_clk_init; +} + +void __init omap3430_init_early(void) +{ + omap3_init_early(); + if (of_have_populated_dt()) + omap_clk_soc_init = omap3430_dt_clk_init; +} + +void __init omap35xx_init_early(void) +{ + omap3_init_early(); + if (of_have_populated_dt()) + omap_clk_soc_init = omap3430_dt_clk_init; +} + +void __init omap3630_init_early(void) +{ + omap3_init_early(); + if (of_have_populated_dt()) + omap_clk_soc_init = omap3630_dt_clk_init; +} + +void __init am35xx_init_early(void) +{ + omap3_init_early(); + if (of_have_populated_dt()) + omap_clk_soc_init = am35xx_dt_clk_init; +} + +void __init ti81xx_init_early(void) +{ + omap2_set_globals_tap(OMAP343X_CLASS, + OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE)); + omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE), + NULL); + omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE)); + omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), NULL); + omap3xxx_check_revision(); + ti81xx_check_features(); + omap3xxx_voltagedomains_init(); + omap3xxx_powerdomains_init(); + omap3xxx_clockdomains_init(); + omap3xxx_hwmod_init(); + omap_hwmod_init_postsetup(); + if (of_have_populated_dt()) + omap_clk_soc_init = ti81xx_dt_clk_init; + else + omap_clk_soc_init = omap3xxx_clk_init; +} + +void __init omap3_init_late(void) +{ + omap_common_late_init(); + omap3_pm_init(); + omap2_clk_enable_autoidle_all(); +} + +void __init omap3430_init_late(void) +{ + omap_common_late_init(); + omap3_pm_init(); + omap2_clk_enable_autoidle_all(); +} + +void __init omap35xx_init_late(void) +{ + omap_common_late_init(); + omap3_pm_init(); + omap2_clk_enable_autoidle_all(); +} + +void __init omap3630_init_late(void) +{ + omap_common_late_init(); + omap3_pm_init(); + omap2_clk_enable_autoidle_all(); +} + +void __init am35xx_init_late(void) +{ + omap_common_late_init(); + omap3_pm_init(); + omap2_clk_enable_autoidle_all(); +} + +void __init ti81xx_init_late(void) +{ + omap_common_late_init(); + omap3_pm_init(); + omap2_clk_enable_autoidle_all(); +} +#endif + +#ifdef CONFIG_SOC_AM33XX +void __init am33xx_init_early(void) +{ + omap2_set_globals_tap(AM335X_CLASS, + AM33XX_L4_WK_IO_ADDRESS(AM33XX_TAP_BASE)); + omap2_set_globals_control(AM33XX_L4_WK_IO_ADDRESS(AM33XX_CTRL_BASE), + NULL); + omap2_set_globals_prm(AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE)); + omap2_set_globals_cm(AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE), NULL); + omap3xxx_check_revision(); + am33xx_check_features(); + am33xx_powerdomains_init(); + am33xx_clockdomains_init(); + am33xx_hwmod_init(); + omap_hwmod_init_postsetup(); + omap_clk_soc_init = am33xx_dt_clk_init; +} + +void __init am33xx_init_late(void) +{ + omap_common_late_init(); +} +#endif + +#ifdef CONFIG_SOC_AM43XX +void __init am43xx_init_early(void) +{ + omap2_set_globals_tap(AM335X_CLASS, + AM33XX_L4_WK_IO_ADDRESS(AM33XX_TAP_BASE)); + omap2_set_globals_control(AM33XX_L4_WK_IO_ADDRESS(AM33XX_CTRL_BASE), + NULL); + omap2_set_globals_prm(AM33XX_L4_WK_IO_ADDRESS(AM43XX_PRCM_BASE)); + omap2_set_globals_cm(AM33XX_L4_WK_IO_ADDRESS(AM43XX_PRCM_BASE), NULL); + omap_prm_base_init(); + omap_cm_base_init(); + omap3xxx_check_revision(); + am33xx_check_features(); + am43xx_powerdomains_init(); + am43xx_clockdomains_init(); + am43xx_hwmod_init(); + omap_hwmod_init_postsetup(); + omap_l2_cache_init(); + omap_clk_soc_init = am43xx_dt_clk_init; +} + +void __init am43xx_init_late(void) +{ + omap_common_late_init(); +} +#endif + +#ifdef CONFIG_ARCH_OMAP4 +void __init omap4430_init_early(void) +{ + omap2_set_globals_tap(OMAP443X_CLASS, + OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE)); + omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE), + OMAP2_L4_IO_ADDRESS(OMAP443X_CTRL_BASE)); + omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP4430_PRM_BASE)); + omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP4430_CM_BASE), + OMAP2_L4_IO_ADDRESS(OMAP4430_CM2_BASE)); + omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP4430_PRCM_MPU_BASE)); + omap_prm_base_init(); + omap_cm_base_init(); + omap4xxx_check_revision(); + omap4xxx_check_features(); + omap4_pm_init_early(); + omap44xx_prm_init(); + omap44xx_voltagedomains_init(); + omap44xx_powerdomains_init(); + omap44xx_clockdomains_init(); + omap44xx_hwmod_init(); + omap_hwmod_init_postsetup(); + omap_l2_cache_init(); + omap_clk_soc_init = omap4xxx_dt_clk_init; +} + +void __init omap4430_init_late(void) +{ + omap_common_late_init(); + omap4_pm_init(); + omap2_clk_enable_autoidle_all(); +} +#endif + +#ifdef CONFIG_SOC_OMAP5 +void __init omap5_init_early(void) +{ + omap2_set_globals_tap(OMAP54XX_CLASS, + OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE)); + omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE), + OMAP2_L4_IO_ADDRESS(OMAP54XX_CTRL_BASE)); + omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRM_BASE)); + omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_AON_BASE), + OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_BASE)); + omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE)); + omap_prm_base_init(); + omap_cm_base_init(); + omap44xx_prm_init(); + omap5xxx_check_revision(); + omap54xx_voltagedomains_init(); + omap54xx_powerdomains_init(); + omap54xx_clockdomains_init(); + omap54xx_hwmod_init(); + omap_hwmod_init_postsetup(); + omap_clk_soc_init = omap5xxx_dt_clk_init; +} + +void __init omap5_init_late(void) +{ + omap_common_late_init(); +} +#endif + +#ifdef CONFIG_SOC_DRA7XX +void __init dra7xx_init_early(void) +{ + omap2_set_globals_tap(-1, OMAP2_L4_IO_ADDRESS(DRA7XX_TAP_BASE)); + omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE), + OMAP2_L4_IO_ADDRESS(DRA7XX_CTRL_BASE)); + omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRM_BASE)); + omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(DRA7XX_CM_CORE_AON_BASE), + OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_BASE)); + omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE)); + omap_prm_base_init(); + omap_cm_base_init(); + omap44xx_prm_init(); + dra7xxx_check_revision(); + dra7xx_powerdomains_init(); + dra7xx_clockdomains_init(); + dra7xx_hwmod_init(); + omap_hwmod_init_postsetup(); + omap_clk_soc_init = dra7xx_dt_clk_init; +} + +void __init dra7xx_init_late(void) +{ + omap_common_late_init(); +} +#endif + + +void __init omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0, + struct omap_sdrc_params *sdrc_cs1) +{ omap_sram_init(); - omapfb_reserve_sdram(); + + if (cpu_is_omap24xx() || omap3_has_sdrc()) { + omap2_sdrc_init(sdrc_cs0, sdrc_cs1); + _omap2_init_reprogram_sdrc(); + } } -void __init omap2_init_common_hw(void) +int __init omap_clk_init(void) { - omap2_mux_init(); - pwrdm_init(powerdomains_omap); - clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps); - omap2_clk_init(); - omap2_init_memory(); - gpmc_init(); + int ret = 0; + + if (!omap_clk_soc_init) + return 0; + + ret = of_prcm_init(); + if (!ret) + ret = omap_clk_soc_init(); + + return ret; } diff --git a/arch/arm/mach-omap2/iomap.h b/arch/arm/mach-omap2/iomap.h new file mode 100644 index 00000000000..cce2b65039f --- /dev/null +++ b/arch/arm/mach-omap2/iomap.h @@ -0,0 +1,196 @@ +/* + * IO mappings for OMAP2+ + * + * IO definitions for TI OMAP processors and boards + * + * Copied from arch/arm/mach-sa1100/include/mach/io.h + * Copyright (C) 1997-1999 Russell King + * + * Copyright (C) 2009-2012 Texas Instruments + * Added OMAP4/5 support - Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define OMAP2_L3_IO_OFFSET 0x90000000 +#define OMAP2_L3_IO_ADDRESS(pa) IOMEM((pa) + OMAP2_L3_IO_OFFSET) /* L3 */ + +#define OMAP2_L4_IO_OFFSET 0xb2000000 +#define OMAP2_L4_IO_ADDRESS(pa) IOMEM((pa) + OMAP2_L4_IO_OFFSET) /* L4 */ + +#define OMAP4_L3_IO_OFFSET 0xb4000000 +#define OMAP4_L3_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_L3_IO_OFFSET) /* L3 */ + +#define AM33XX_L4_WK_IO_OFFSET 0xb5000000 +#define AM33XX_L4_WK_IO_ADDRESS(pa) IOMEM((pa) + AM33XX_L4_WK_IO_OFFSET) + +#define OMAP4_L3_PER_IO_OFFSET 0xb1100000 +#define OMAP4_L3_PER_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_L3_PER_IO_OFFSET) + +#define OMAP2_EMU_IO_OFFSET 0xaa800000 /* Emulation */ +#define OMAP2_EMU_IO_ADDRESS(pa) IOMEM((pa) + OMAP2_EMU_IO_OFFSET) + +/* + * ---------------------------------------------------------------------------- + * Omap2 specific IO mapping + * ---------------------------------------------------------------------------- + */ + +/* We map both L3 and L4 on OMAP2 */ +#define L3_24XX_PHYS L3_24XX_BASE /* 0x68000000 --> 0xf8000000*/ +#define L3_24XX_VIRT (L3_24XX_PHYS + OMAP2_L3_IO_OFFSET) +#define L3_24XX_SIZE SZ_1M /* 44kB of 128MB used, want 1MB sect */ +#define L4_24XX_PHYS L4_24XX_BASE /* 0x48000000 --> 0xfa000000 */ +#define L4_24XX_VIRT (L4_24XX_PHYS + OMAP2_L4_IO_OFFSET) +#define L4_24XX_SIZE SZ_1M /* 1MB of 128MB used, want 1MB sect */ + +#define L4_WK_243X_PHYS L4_WK_243X_BASE /* 0x49000000 --> 0xfb000000 */ +#define L4_WK_243X_VIRT (L4_WK_243X_PHYS + OMAP2_L4_IO_OFFSET) +#define L4_WK_243X_SIZE SZ_1M +#define OMAP243X_GPMC_PHYS OMAP243X_GPMC_BASE +#define OMAP243X_GPMC_VIRT (OMAP243X_GPMC_PHYS + OMAP2_L3_IO_OFFSET) + /* 0x6e000000 --> 0xfe000000 */ +#define OMAP243X_GPMC_SIZE SZ_1M +#define OMAP243X_SDRC_PHYS OMAP243X_SDRC_BASE + /* 0x6D000000 --> 0xfd000000 */ +#define OMAP243X_SDRC_VIRT (OMAP243X_SDRC_PHYS + OMAP2_L3_IO_OFFSET) +#define OMAP243X_SDRC_SIZE SZ_1M +#define OMAP243X_SMS_PHYS OMAP243X_SMS_BASE + /* 0x6c000000 --> 0xfc000000 */ +#define OMAP243X_SMS_VIRT (OMAP243X_SMS_PHYS + OMAP2_L3_IO_OFFSET) +#define OMAP243X_SMS_SIZE SZ_1M + +/* 2420 IVA */ +#define DSP_MEM_2420_PHYS OMAP2420_DSP_MEM_BASE + /* 0x58000000 --> 0xfc100000 */ +#define DSP_MEM_2420_VIRT 0xfc100000 +#define DSP_MEM_2420_SIZE 0x28000 +#define DSP_IPI_2420_PHYS OMAP2420_DSP_IPI_BASE + /* 0x59000000 --> 0xfc128000 */ +#define DSP_IPI_2420_VIRT 0xfc128000 +#define DSP_IPI_2420_SIZE SZ_4K +#define DSP_MMU_2420_PHYS OMAP2420_DSP_MMU_BASE + /* 0x5a000000 --> 0xfc129000 */ +#define DSP_MMU_2420_VIRT 0xfc129000 +#define DSP_MMU_2420_SIZE SZ_4K + +/* 2430 IVA2.1 - currently unmapped */ + +/* + * ---------------------------------------------------------------------------- + * Omap3 specific IO mapping + * ---------------------------------------------------------------------------- + */ + +/* We map both L3 and L4 on OMAP3 */ +#define L3_34XX_PHYS L3_34XX_BASE /* 0x68000000 --> 0xf8000000 */ +#define L3_34XX_VIRT (L3_34XX_PHYS + OMAP2_L3_IO_OFFSET) +#define L3_34XX_SIZE SZ_1M /* 44kB of 128MB used, want 1MB sect */ + +#define L4_34XX_PHYS L4_34XX_BASE /* 0x48000000 --> 0xfa000000 */ +#define L4_34XX_VIRT (L4_34XX_PHYS + OMAP2_L4_IO_OFFSET) +#define L4_34XX_SIZE SZ_4M /* 1MB of 128MB used, want 1MB sect */ + +/* + * ---------------------------------------------------------------------------- + * AM33XX specific IO mapping + * ---------------------------------------------------------------------------- + */ +#define L4_WK_AM33XX_PHYS L4_WK_AM33XX_BASE +#define L4_WK_AM33XX_VIRT (L4_WK_AM33XX_PHYS + AM33XX_L4_WK_IO_OFFSET) +#define L4_WK_AM33XX_SIZE SZ_4M /* 1MB of 128MB used, want 1MB sect */ + +/* + * Need to look at the Size 4M for L4. + * VPOM3430 was not working for Int controller + */ + +#define L4_PER_34XX_PHYS L4_PER_34XX_BASE + /* 0x49000000 --> 0xfb000000 */ +#define L4_PER_34XX_VIRT (L4_PER_34XX_PHYS + OMAP2_L4_IO_OFFSET) +#define L4_PER_34XX_SIZE SZ_1M + +#define L4_EMU_34XX_PHYS L4_EMU_34XX_BASE + /* 0x54000000 --> 0xfe800000 */ +#define L4_EMU_34XX_VIRT (L4_EMU_34XX_PHYS + OMAP2_EMU_IO_OFFSET) +#define L4_EMU_34XX_SIZE SZ_8M + +#define OMAP34XX_GPMC_PHYS OMAP34XX_GPMC_BASE + /* 0x6e000000 --> 0xfe000000 */ +#define OMAP34XX_GPMC_VIRT (OMAP34XX_GPMC_PHYS + OMAP2_L3_IO_OFFSET) +#define OMAP34XX_GPMC_SIZE SZ_1M + +#define OMAP343X_SMS_PHYS OMAP343X_SMS_BASE + /* 0x6c000000 --> 0xfc000000 */ +#define OMAP343X_SMS_VIRT (OMAP343X_SMS_PHYS + OMAP2_L3_IO_OFFSET) +#define OMAP343X_SMS_SIZE SZ_1M + +#define OMAP343X_SDRC_PHYS OMAP343X_SDRC_BASE + /* 0x6D000000 --> 0xfd000000 */ +#define OMAP343X_SDRC_VIRT (OMAP343X_SDRC_PHYS + OMAP2_L3_IO_OFFSET) +#define OMAP343X_SDRC_SIZE SZ_1M + +/* 3430 IVA - currently unmapped */ + +/* + * ---------------------------------------------------------------------------- + * Omap4 specific IO mapping + * ---------------------------------------------------------------------------- + */ + +/* We map both L3 and L4 on OMAP4 */ +#define L3_44XX_PHYS L3_44XX_BASE /* 0x44000000 --> 0xf8000000 */ +#define L3_44XX_VIRT (L3_44XX_PHYS + OMAP4_L3_IO_OFFSET) +#define L3_44XX_SIZE SZ_1M + +#define L4_44XX_PHYS L4_44XX_BASE /* 0x4a000000 --> 0xfc000000 */ +#define L4_44XX_VIRT (L4_44XX_PHYS + OMAP2_L4_IO_OFFSET) +#define L4_44XX_SIZE SZ_4M + +#define L4_PER_44XX_PHYS L4_PER_44XX_BASE + /* 0x48000000 --> 0xfa000000 */ +#define L4_PER_44XX_VIRT (L4_PER_44XX_PHYS + OMAP2_L4_IO_OFFSET) +#define L4_PER_44XX_SIZE SZ_4M + +#define L4_ABE_44XX_PHYS L4_ABE_44XX_BASE + /* 0x49000000 --> 0xfb000000 */ +#define L4_ABE_44XX_VIRT (L4_ABE_44XX_PHYS + OMAP2_L4_IO_OFFSET) +#define L4_ABE_44XX_SIZE SZ_1M +/* + * ---------------------------------------------------------------------------- + * Omap5 specific IO mapping + * ---------------------------------------------------------------------------- + */ +#define L3_54XX_PHYS L3_54XX_BASE /* 0x44000000 --> 0xf8000000 */ +#define L3_54XX_VIRT (L3_54XX_PHYS + OMAP4_L3_IO_OFFSET) +#define L3_54XX_SIZE SZ_1M + +#define L4_54XX_PHYS L4_54XX_BASE /* 0x4a000000 --> 0xfc000000 */ +#define L4_54XX_VIRT (L4_54XX_PHYS + OMAP2_L4_IO_OFFSET) +#define L4_54XX_SIZE SZ_4M + +#define L4_WK_54XX_PHYS L4_WK_54XX_BASE /* 0x4ae00000 --> 0xfce00000 */ +#define L4_WK_54XX_VIRT (L4_WK_54XX_PHYS + OMAP2_L4_IO_OFFSET) +#define L4_WK_54XX_SIZE SZ_2M + +#define L4_PER_54XX_PHYS L4_PER_54XX_BASE /* 0x48000000 --> 0xfa000000 */ +#define L4_PER_54XX_VIRT (L4_PER_54XX_PHYS + OMAP2_L4_IO_OFFSET) +#define L4_PER_54XX_SIZE SZ_4M diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index 9ba20d985dd..35b8590c322 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -11,12 +11,21 @@ * for more details. */ #include <linux/kernel.h> +#include <linux/module.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/io.h> -#include <mach/hardware.h> + +#include <asm/exception.h> #include <asm/mach/irq.h> +#include <linux/irqdomain.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include "soc.h" +#include "iomap.h" +#include "common.h" /* selected INTC register offsets */ @@ -25,13 +34,23 @@ #define INTC_SYSSTATUS 0x0014 #define INTC_SIR 0x0040 #define INTC_CONTROL 0x0048 +#define INTC_PROTECTION 0x004C +#define INTC_IDLE 0x0050 +#define INTC_THRESHOLD 0x0068 +#define INTC_MIR0 0x0084 #define INTC_MIR_CLEAR0 0x0088 #define INTC_MIR_SET0 0x008c #define INTC_PENDING_IRQ0 0x0098 - /* Number of IRQ state bits in each MIR register */ #define IRQ_BITS_PER_REG 32 +#define OMAP2_IRQ_BASE OMAP2_L4_IO_ADDRESS(OMAP24XX_IC_BASE) +#define OMAP3_IRQ_BASE OMAP2_L4_IO_ADDRESS(OMAP34XX_IC_BASE) +#define INTCPS_SIR_IRQ_OFFSET 0x0040 /* omap2/3 active interrupt offset */ +#define ACTIVEIRQ_MASK 0x7f /* omap2/3 active interrupt bits */ +#define INTCPS_NR_MIR_REGS 3 +#define INTCPS_NR_IRQS 96 + /* * OMAP2 has a number of different interrupt controllers, each interrupt * controller is identified as its own "bank". Register definitions are @@ -44,146 +63,318 @@ static struct omap_irq_bank { } __attribute__ ((aligned(4))) irq_banks[] = { { /* MPU INTC */ - .base_reg = 0, .nr_irqs = 96, }, }; +static struct irq_domain *domain; + +/* Structure to save interrupt controller context */ +struct omap3_intc_regs { + u32 sysconfig; + u32 protection; + u32 idle; + u32 threshold; + u32 ilr[INTCPS_NR_IRQS]; + u32 mir[INTCPS_NR_MIR_REGS]; +}; + /* INTC bank register get/set */ static void intc_bank_write_reg(u32 val, struct omap_irq_bank *bank, u16 reg) { - __raw_writel(val, bank->base_reg + reg); + writel_relaxed(val, bank->base_reg + reg); } static u32 intc_bank_read_reg(struct omap_irq_bank *bank, u16 reg) { - return __raw_readl(bank->base_reg + reg); + return readl_relaxed(bank->base_reg + reg); } -static int previous_irq; +/* XXX: FIQ and additional INTC support (only MPU at the moment) */ +static void omap_ack_irq(struct irq_data *d) +{ + intc_bank_write_reg(0x1, &irq_banks[0], INTC_CONTROL); +} -/* - * On 34xx we can get occasional spurious interrupts if the ack from - * an interrupt handler does not get posted before we unmask. Warn about - * the interrupt handlers that need to flush posted writes. - */ -static int omap_check_spurious(unsigned int irq) +static void omap_mask_ack_irq(struct irq_data *d) { - u32 sir, spurious; + irq_gc_mask_disable_reg(d); + omap_ack_irq(d); +} - sir = intc_bank_read_reg(&irq_banks[0], INTC_SIR); - spurious = sir >> 6; +static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank) +{ + unsigned long tmp; - if (spurious > 1) { - printk(KERN_WARNING "Spurious irq %i: 0x%08x, please flush " - "posted write for irq %i\n", - irq, sir, previous_irq); - return spurious; - } + tmp = intc_bank_read_reg(bank, INTC_REVISION) & 0xff; + pr_info("IRQ: Found an INTC at 0x%p (revision %ld.%ld) with %d interrupts\n", + bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs); - return 0; + tmp = intc_bank_read_reg(bank, INTC_SYSCONFIG); + tmp |= 1 << 1; /* soft reset */ + intc_bank_write_reg(tmp, bank, INTC_SYSCONFIG); + + while (!(intc_bank_read_reg(bank, INTC_SYSSTATUS) & 0x1)) + /* Wait for reset to complete */; + + /* Enable autoidle */ + intc_bank_write_reg(1 << 0, bank, INTC_SYSCONFIG); } -/* XXX: FIQ and additional INTC support (only MPU at the moment) */ -static void omap_ack_irq(unsigned int irq) +int omap_irq_pending(void) { - intc_bank_write_reg(0x1, &irq_banks[0], INTC_CONTROL); + int i; + + for (i = 0; i < ARRAY_SIZE(irq_banks); i++) { + struct omap_irq_bank *bank = irq_banks + i; + int irq; + + for (irq = 0; irq < bank->nr_irqs; irq += 32) + if (intc_bank_read_reg(bank, INTC_PENDING_IRQ0 + + ((irq >> 5) << 5))) + return 1; + } + return 0; } -static void omap_mask_irq(unsigned int irq) +static __init void +omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) { - int offset = irq & (~(IRQ_BITS_PER_REG - 1)); + struct irq_chip_generic *gc; + struct irq_chip_type *ct; + + gc = irq_alloc_generic_chip("INTC", 1, irq_start, base, + handle_level_irq); + ct = gc->chip_types; + ct->chip.irq_ack = omap_mask_ack_irq; + ct->chip.irq_mask = irq_gc_mask_disable_reg; + ct->chip.irq_unmask = irq_gc_unmask_enable_reg; + ct->chip.flags |= IRQCHIP_SKIP_SET_WAKE; + + ct->regs.enable = INTC_MIR_CLEAR0; + ct->regs.disable = INTC_MIR_SET0; + irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, + IRQ_NOREQUEST | IRQ_NOPROBE, 0); +} - if (cpu_is_omap34xx()) { - int spurious = 0; +static void __init omap_init_irq(u32 base, int nr_irqs, + struct device_node *node) +{ + void __iomem *omap_irq_base; + unsigned long nr_of_irqs = 0; + unsigned int nr_banks = 0; + int i, j, irq_base; - /* - * INT_34XX_GPT12_IRQ is also the spurious irq. Maybe because - * it is the highest irq number? - */ - if (irq == INT_34XX_GPT12_IRQ) - spurious = omap_check_spurious(irq); + omap_irq_base = ioremap(base, SZ_4K); + if (WARN_ON(!omap_irq_base)) + return; - if (!spurious) - previous_irq = irq; + irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0); + if (irq_base < 0) { + pr_warn("Couldn't allocate IRQ numbers\n"); + irq_base = 0; } - irq &= (IRQ_BITS_PER_REG - 1); + domain = irq_domain_add_legacy(node, nr_irqs, irq_base, 0, + &irq_domain_simple_ops, NULL); + + for (i = 0; i < ARRAY_SIZE(irq_banks); i++) { + struct omap_irq_bank *bank = irq_banks + i; + + bank->nr_irqs = nr_irqs; + + /* Static mapping, never released */ + bank->base_reg = ioremap(base, SZ_4K); + if (!bank->base_reg) { + pr_err("Could not ioremap irq bank%i\n", i); + continue; + } + + omap_irq_bank_init_one(bank); + + for (j = 0; j < bank->nr_irqs; j += 32) + omap_alloc_gc(bank->base_reg + j, j + irq_base, 32); - intc_bank_write_reg(1 << irq, &irq_banks[0], INTC_MIR_SET0 + offset); + nr_of_irqs += bank->nr_irqs; + nr_banks++; + } + + pr_info("Total of %ld interrupts on %d active controller%s\n", + nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : ""); } -static void omap_unmask_irq(unsigned int irq) +void __init omap2_init_irq(void) { - int offset = irq & (~(IRQ_BITS_PER_REG - 1)); + omap_init_irq(OMAP24XX_IC_BASE, 96, NULL); +} - irq &= (IRQ_BITS_PER_REG - 1); +void __init omap3_init_irq(void) +{ + omap_init_irq(OMAP34XX_IC_BASE, 96, NULL); +} - intc_bank_write_reg(1 << irq, &irq_banks[0], INTC_MIR_CLEAR0 + offset); +void __init ti81xx_init_irq(void) +{ + omap_init_irq(OMAP34XX_IC_BASE, 128, NULL); } -static void omap_mask_ack_irq(unsigned int irq) +static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs) { - omap_mask_irq(irq); - omap_ack_irq(irq); + u32 irqnr; + int handled_irq = 0; + + do { + irqnr = readl_relaxed(base_addr + 0x98); + if (irqnr) + goto out; + + irqnr = readl_relaxed(base_addr + 0xb8); + if (irqnr) + goto out; + + irqnr = readl_relaxed(base_addr + 0xd8); +#if IS_ENABLED(CONFIG_SOC_TI81XX) || IS_ENABLED(CONFIG_SOC_AM33XX) + if (irqnr) + goto out; + irqnr = readl_relaxed(base_addr + 0xf8); +#endif + +out: + if (!irqnr) + break; + + irqnr = readl_relaxed(base_addr + INTCPS_SIR_IRQ_OFFSET); + irqnr &= ACTIVEIRQ_MASK; + + if (irqnr) { + irqnr = irq_find_mapping(domain, irqnr); + handle_IRQ(irqnr, regs); + handled_irq = 1; + } + } while (irqnr); + + /* If an irq is masked or deasserted while active, we will + * keep ending up here with no irq handled. So remove it from + * the INTC with an ack.*/ + if (!handled_irq) + omap_ack_irq(NULL); } -static struct irq_chip omap_irq_chip = { - .name = "INTC", - .ack = omap_mask_ack_irq, - .mask = omap_mask_irq, - .unmask = omap_unmask_irq, - .disable = omap_mask_irq, -}; +asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs *regs) +{ + void __iomem *base_addr = OMAP2_IRQ_BASE; + omap_intc_handle_irq(base_addr, regs); +} -static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank) +int __init intc_of_init(struct device_node *node, + struct device_node *parent) { - unsigned long tmp; + struct resource res; + u32 nr_irq = 96; - tmp = intc_bank_read_reg(bank, INTC_REVISION) & 0xff; - printk(KERN_INFO "IRQ: Found an INTC at 0x%p " - "(revision %ld.%ld) with %d interrupts\n", - bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs); + if (WARN_ON(!node)) + return -ENODEV; - tmp = intc_bank_read_reg(bank, INTC_SYSCONFIG); - tmp |= 1 << 1; /* soft reset */ - intc_bank_write_reg(tmp, bank, INTC_SYSCONFIG); + if (of_address_to_resource(node, 0, &res)) { + WARN(1, "unable to get intc registers\n"); + return -EINVAL; + } - while (!(intc_bank_read_reg(bank, INTC_SYSSTATUS) & 0x1)) - /* Wait for reset to complete */; + if (of_property_read_u32(node, "ti,intc-size", &nr_irq)) + pr_warn("unable to get intc-size, default to %d\n", nr_irq); - /* Enable autoidle */ - intc_bank_write_reg(1 << 0, bank, INTC_SYSCONFIG); + omap_init_irq(res.start, nr_irq, of_node_get(node)); + + return 0; } -void __init omap_init_irq(void) -{ - unsigned long nr_of_irqs = 0; - unsigned int nr_banks = 0; - int i; +static struct of_device_id irq_match[] __initdata = { + { .compatible = "ti,omap2-intc", .data = intc_of_init, }, + { } +}; - for (i = 0; i < ARRAY_SIZE(irq_banks); i++) { - struct omap_irq_bank *bank = irq_banks + i; +void __init omap_intc_of_init(void) +{ + of_irq_init(irq_match); +} - if (cpu_is_omap24xx()) - bank->base_reg = OMAP2_IO_ADDRESS(OMAP24XX_IC_BASE); - else if (cpu_is_omap34xx()) - bank->base_reg = OMAP2_IO_ADDRESS(OMAP34XX_IC_BASE); +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) +static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)]; - omap_irq_bank_init_one(bank); +void omap_intc_save_context(void) +{ + int ind = 0, i = 0; + for (ind = 0; ind < ARRAY_SIZE(irq_banks); ind++) { + struct omap_irq_bank *bank = irq_banks + ind; + intc_context[ind].sysconfig = + intc_bank_read_reg(bank, INTC_SYSCONFIG); + intc_context[ind].protection = + intc_bank_read_reg(bank, INTC_PROTECTION); + intc_context[ind].idle = + intc_bank_read_reg(bank, INTC_IDLE); + intc_context[ind].threshold = + intc_bank_read_reg(bank, INTC_THRESHOLD); + for (i = 0; i < INTCPS_NR_IRQS; i++) + intc_context[ind].ilr[i] = + intc_bank_read_reg(bank, (0x100 + 0x4*i)); + for (i = 0; i < INTCPS_NR_MIR_REGS; i++) + intc_context[ind].mir[i] = + intc_bank_read_reg(&irq_banks[0], INTC_MIR0 + + (0x20 * i)); + } +} - nr_of_irqs += bank->nr_irqs; - nr_banks++; +void omap_intc_restore_context(void) +{ + int ind = 0, i = 0; + + for (ind = 0; ind < ARRAY_SIZE(irq_banks); ind++) { + struct omap_irq_bank *bank = irq_banks + ind; + intc_bank_write_reg(intc_context[ind].sysconfig, + bank, INTC_SYSCONFIG); + intc_bank_write_reg(intc_context[ind].sysconfig, + bank, INTC_SYSCONFIG); + intc_bank_write_reg(intc_context[ind].protection, + bank, INTC_PROTECTION); + intc_bank_write_reg(intc_context[ind].idle, + bank, INTC_IDLE); + intc_bank_write_reg(intc_context[ind].threshold, + bank, INTC_THRESHOLD); + for (i = 0; i < INTCPS_NR_IRQS; i++) + intc_bank_write_reg(intc_context[ind].ilr[i], + bank, (0x100 + 0x4*i)); + for (i = 0; i < INTCPS_NR_MIR_REGS; i++) + intc_bank_write_reg(intc_context[ind].mir[i], + &irq_banks[0], INTC_MIR0 + (0x20 * i)); } + /* MIRs are saved and restore with other PRCM registers */ +} - printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n", - nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : ""); +void omap3_intc_suspend(void) +{ + /* A pending interrupt would prevent OMAP from entering suspend */ + omap_ack_irq(NULL); +} - for (i = 0; i < nr_of_irqs; i++) { - set_irq_chip(i, &omap_irq_chip); - set_irq_handler(i, handle_level_irq); - set_irq_flags(i, IRQF_VALID); - } +void omap3_intc_prepare_idle(void) +{ + /* + * Disable autoidle as it can stall interrupt controller, + * cf. errata ID i540 for 3430 (all revisions up to 3.1.x) + */ + intc_bank_write_reg(0, &irq_banks[0], INTC_SYSCONFIG); +} + +void omap3_intc_resume_idle(void) +{ + /* Re-enable autoidle */ + intc_bank_write_reg(1, &irq_banks[0], INTC_SYSCONFIG); } +asmlinkage void __exception_irq_entry omap3_intc_handle_irq(struct pt_regs *regs) +{ + void __iomem *base_addr = OMAP3_IRQ_BASE; + omap_intc_handle_irq(base_addr, regs); +} +#endif /* CONFIG_ARCH_OMAP3 */ diff --git a/arch/arm/mach-omap2/l3_2xxx.h b/arch/arm/mach-omap2/l3_2xxx.h new file mode 100644 index 00000000000..b8b5641379b --- /dev/null +++ b/arch/arm/mach-omap2/l3_2xxx.h @@ -0,0 +1,20 @@ +/* + * arch/arm/plat-omap/include/plat/l3_2xxx.h - L3 firewall definitions + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * Sumit Semwal + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_2XXX_H +#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_2XXX_H + +/* L3 CONNIDs */ +/* Display Sub system (DSS) */ +#define OMAP2_L3_CORE_FW_CONNID_DSS 8 + +#endif diff --git a/arch/arm/mach-omap2/l3_3xxx.h b/arch/arm/mach-omap2/l3_3xxx.h new file mode 100644 index 00000000000..cde1938c5f8 --- /dev/null +++ b/arch/arm/mach-omap2/l3_3xxx.h @@ -0,0 +1,20 @@ +/* + * arch/arm/plat-omap/include/plat/l3_3xxx.h - L3 firewall definitions + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * Sumit Semwal + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_3XXX_H +#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_3XXX_H + +/* L3 Initiator IDs */ +/* Display Sub system (DSS) */ +#define OMAP3_L3_CORE_FW_INIT_ID_DSS 29 + +#endif diff --git a/arch/arm/mach-omap2/l4_2xxx.h b/arch/arm/mach-omap2/l4_2xxx.h new file mode 100644 index 00000000000..3f39cf8a35c --- /dev/null +++ b/arch/arm/mach-omap2/l4_2xxx.h @@ -0,0 +1,24 @@ +/* + * arch/arm/plat-omap/include/plat/l4_2xxx.h - L4 firewall definitions + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * Sumit Semwal + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L4_2XXX_H +#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L4_2XXX_H + +/* L4 CORE */ +/* Display Sub system (DSS) */ +#define OMAP2420_L4_CORE_FW_DSS_CORE_REGION 28 +#define OMAP2420_L4_CORE_FW_DSS_DISPC_REGION 29 +#define OMAP2420_L4_CORE_FW_DSS_RFBI_REGION 30 +#define OMAP2420_L4_CORE_FW_DSS_VENC_REGION 31 +#define OMAP2420_L4_CORE_FW_DSS_TA_REGION 32 + +#endif diff --git a/arch/arm/mach-omap2/l4_3xxx.h b/arch/arm/mach-omap2/l4_3xxx.h new file mode 100644 index 00000000000..881a858b1ff --- /dev/null +++ b/arch/arm/mach-omap2/l4_3xxx.h @@ -0,0 +1,34 @@ +/* + * arch/arm/plat-omap/include/mach/l4_3xxx.h - L4 firewall definitions + * + * Copyright (C) 2009 Nokia Corporation + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_L4_3XXX_H +#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_L4_3XXX_H + +/* L4 CORE */ +#define OMAP3_L4_CORE_FW_I2C1_REGION 21 +#define OMAP3_L4_CORE_FW_I2C1_TA_REGION 22 +#define OMAP3_L4_CORE_FW_I2C2_REGION 23 +#define OMAP3_L4_CORE_FW_I2C2_TA_REGION 24 +#define OMAP3_L4_CORE_FW_I2C3_REGION 73 +#define OMAP3_L4_CORE_FW_I2C3_TA_REGION 74 + +/* Display Sub system (DSS) */ +#define OMAP3_L4_CORE_FW_DSS_PROT_GROUP 2 + +#define OMAP3_L4_CORE_FW_DSS_DSI_REGION 104 +#define OMAP3ES1_L4_CORE_FW_DSS_CORE_REGION 3 +#define OMAP3_L4_CORE_FW_DSS_CORE_REGION 4 +#define OMAP3_L4_CORE_FW_DSS_DISPC_REGION 4 +#define OMAP3_L4_CORE_FW_DSS_RFBI_REGION 5 +#define OMAP3_L4_CORE_FW_DSS_VENC_REGION 6 +#define OMAP3_L4_CORE_FW_DSS_TA_REGION 7 +#endif diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c deleted file mode 100644 index 32b7af3c610..00000000000 --- a/arch/arm/mach-omap2/mailbox.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Mailbox reservation modules for OMAP2 - * - * Copyright (C) 2006 Nokia Corporation - * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> - * and Paul Mundt <paul.mundt@nokia.com> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ - -#include <linux/kernel.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/platform_device.h> -#include <linux/io.h> -#include <mach/mailbox.h> -#include <mach/irqs.h> - -#define MAILBOX_REVISION 0x00 -#define MAILBOX_SYSCONFIG 0x10 -#define MAILBOX_SYSSTATUS 0x14 -#define MAILBOX_MESSAGE_0 0x40 -#define MAILBOX_MESSAGE_1 0x44 -#define MAILBOX_MESSAGE_2 0x48 -#define MAILBOX_MESSAGE_3 0x4c -#define MAILBOX_MESSAGE_4 0x50 -#define MAILBOX_MESSAGE_5 0x54 -#define MAILBOX_FIFOSTATUS_0 0x80 -#define MAILBOX_FIFOSTATUS_1 0x84 -#define MAILBOX_FIFOSTATUS_2 0x88 -#define MAILBOX_FIFOSTATUS_3 0x8c -#define MAILBOX_FIFOSTATUS_4 0x90 -#define MAILBOX_FIFOSTATUS_5 0x94 -#define MAILBOX_MSGSTATUS_0 0xc0 -#define MAILBOX_MSGSTATUS_1 0xc4 -#define MAILBOX_MSGSTATUS_2 0xc8 -#define MAILBOX_MSGSTATUS_3 0xcc -#define MAILBOX_MSGSTATUS_4 0xd0 -#define MAILBOX_MSGSTATUS_5 0xd4 -#define MAILBOX_IRQSTATUS_0 0x100 -#define MAILBOX_IRQENABLE_0 0x104 -#define MAILBOX_IRQSTATUS_1 0x108 -#define MAILBOX_IRQENABLE_1 0x10c -#define MAILBOX_IRQSTATUS_2 0x110 -#define MAILBOX_IRQENABLE_2 0x114 -#define MAILBOX_IRQSTATUS_3 0x118 -#define MAILBOX_IRQENABLE_3 0x11c - -static unsigned long mbox_base; - -#define MAILBOX_IRQ_NOTFULL(n) (1 << (2 * (n) + 1)) -#define MAILBOX_IRQ_NEWMSG(n) (1 << (2 * (n))) - -struct omap_mbox2_fifo { - unsigned long msg; - unsigned long fifo_stat; - unsigned long msg_stat; -}; - -struct omap_mbox2_priv { - struct omap_mbox2_fifo tx_fifo; - struct omap_mbox2_fifo rx_fifo; - unsigned long irqenable; - unsigned long irqstatus; - u32 newmsg_bit; - u32 notfull_bit; -}; - -static struct clk *mbox_ick_handle; - -static void omap2_mbox_enable_irq(struct omap_mbox *mbox, - omap_mbox_type_t irq); - -static inline unsigned int mbox_read_reg(unsigned int reg) -{ - return __raw_readl(mbox_base + reg); -} - -static inline void mbox_write_reg(unsigned int val, unsigned int reg) -{ - __raw_writel(val, mbox_base + reg); -} - -/* Mailbox H/W preparations */ -static int omap2_mbox_startup(struct omap_mbox *mbox) -{ - unsigned int l; - - mbox_ick_handle = clk_get(NULL, "mailboxes_ick"); - if (IS_ERR(mbox_ick_handle)) { - printk("Could not get mailboxes_ick\n"); - return -ENODEV; - } - clk_enable(mbox_ick_handle); - - /* set smart-idle & autoidle */ - l = mbox_read_reg(MAILBOX_SYSCONFIG); - l |= 0x00000011; - mbox_write_reg(l, MAILBOX_SYSCONFIG); - - omap2_mbox_enable_irq(mbox, IRQ_RX); - - return 0; -} - -static void omap2_mbox_shutdown(struct omap_mbox *mbox) -{ - clk_disable(mbox_ick_handle); - clk_put(mbox_ick_handle); -} - -/* Mailbox FIFO handle functions */ -static mbox_msg_t omap2_mbox_fifo_read(struct omap_mbox *mbox) -{ - struct omap_mbox2_fifo *fifo = - &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo; - return (mbox_msg_t) mbox_read_reg(fifo->msg); -} - -static void omap2_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg) -{ - struct omap_mbox2_fifo *fifo = - &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo; - mbox_write_reg(msg, fifo->msg); -} - -static int omap2_mbox_fifo_empty(struct omap_mbox *mbox) -{ - struct omap_mbox2_fifo *fifo = - &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo; - return (mbox_read_reg(fifo->msg_stat) == 0); -} - -static int omap2_mbox_fifo_full(struct omap_mbox *mbox) -{ - struct omap_mbox2_fifo *fifo = - &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo; - return (mbox_read_reg(fifo->fifo_stat)); -} - -/* Mailbox IRQ handle functions */ -static void omap2_mbox_enable_irq(struct omap_mbox *mbox, - omap_mbox_type_t irq) -{ - struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv; - u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; - - l = mbox_read_reg(p->irqenable); - l |= bit; - mbox_write_reg(l, p->irqenable); -} - -static void omap2_mbox_disable_irq(struct omap_mbox *mbox, - omap_mbox_type_t irq) -{ - struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv; - u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; - - l = mbox_read_reg(p->irqenable); - l &= ~bit; - mbox_write_reg(l, p->irqenable); -} - -static void omap2_mbox_ack_irq(struct omap_mbox *mbox, - omap_mbox_type_t irq) -{ - struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv; - u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; - - mbox_write_reg(bit, p->irqstatus); -} - -static int omap2_mbox_is_irq(struct omap_mbox *mbox, - omap_mbox_type_t irq) -{ - struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv; - u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; - u32 enable = mbox_read_reg(p->irqenable); - u32 status = mbox_read_reg(p->irqstatus); - - return (enable & status & bit); -} - -static struct omap_mbox_ops omap2_mbox_ops = { - .type = OMAP_MBOX_TYPE2, - .startup = omap2_mbox_startup, - .shutdown = omap2_mbox_shutdown, - .fifo_read = omap2_mbox_fifo_read, - .fifo_write = omap2_mbox_fifo_write, - .fifo_empty = omap2_mbox_fifo_empty, - .fifo_full = omap2_mbox_fifo_full, - .enable_irq = omap2_mbox_enable_irq, - .disable_irq = omap2_mbox_disable_irq, - .ack_irq = omap2_mbox_ack_irq, - .is_irq = omap2_mbox_is_irq, -}; - -/* - * MAILBOX 0: ARM -> DSP, - * MAILBOX 1: ARM <- DSP. - * MAILBOX 2: ARM -> IVA, - * MAILBOX 3: ARM <- IVA. - */ - -/* FIXME: the following structs should be filled automatically by the user id */ - -/* DSP */ -static struct omap_mbox2_priv omap2_mbox_dsp_priv = { - .tx_fifo = { - .msg = MAILBOX_MESSAGE_0, - .fifo_stat = MAILBOX_FIFOSTATUS_0, - }, - .rx_fifo = { - .msg = MAILBOX_MESSAGE_1, - .msg_stat = MAILBOX_MSGSTATUS_1, - }, - .irqenable = MAILBOX_IRQENABLE_0, - .irqstatus = MAILBOX_IRQSTATUS_0, - .notfull_bit = MAILBOX_IRQ_NOTFULL(0), - .newmsg_bit = MAILBOX_IRQ_NEWMSG(1), -}; - -struct omap_mbox mbox_dsp_info = { - .name = "dsp", - .ops = &omap2_mbox_ops, - .priv = &omap2_mbox_dsp_priv, -}; -EXPORT_SYMBOL(mbox_dsp_info); - -/* IVA */ -static struct omap_mbox2_priv omap2_mbox_iva_priv = { - .tx_fifo = { - .msg = MAILBOX_MESSAGE_2, - .fifo_stat = MAILBOX_FIFOSTATUS_2, - }, - .rx_fifo = { - .msg = MAILBOX_MESSAGE_3, - .msg_stat = MAILBOX_MSGSTATUS_3, - }, - .irqenable = MAILBOX_IRQENABLE_3, - .irqstatus = MAILBOX_IRQSTATUS_3, - .notfull_bit = MAILBOX_IRQ_NOTFULL(2), - .newmsg_bit = MAILBOX_IRQ_NEWMSG(3), -}; - -static struct omap_mbox mbox_iva_info = { - .name = "iva", - .ops = &omap2_mbox_ops, - .priv = &omap2_mbox_iva_priv, -}; - -static int __init omap2_mbox_probe(struct platform_device *pdev) -{ - struct resource *res; - int ret = 0; - - if (pdev->num_resources != 3) { - dev_err(&pdev->dev, "invalid number of resources: %d\n", - pdev->num_resources); - return -ENODEV; - } - - /* MBOX base */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (unlikely(!res)) { - dev_err(&pdev->dev, "invalid mem resource\n"); - return -ENODEV; - } - mbox_base = res->start; - - /* DSP IRQ */ - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (unlikely(!res)) { - dev_err(&pdev->dev, "invalid irq resource\n"); - return -ENODEV; - } - mbox_dsp_info.irq = res->start; - - ret = omap_mbox_register(&mbox_dsp_info); - - /* IVA IRQ */ - res = platform_get_resource(pdev, IORESOURCE_IRQ, 1); - if (unlikely(!res)) { - dev_err(&pdev->dev, "invalid irq resource\n"); - return -ENODEV; - } - mbox_iva_info.irq = res->start; - - ret = omap_mbox_register(&mbox_iva_info); - - return ret; -} - -static int omap2_mbox_remove(struct platform_device *pdev) -{ - omap_mbox_unregister(&mbox_dsp_info); - return 0; -} - -static struct platform_driver omap2_mbox_driver = { - .probe = omap2_mbox_probe, - .remove = omap2_mbox_remove, - .driver = { - .name = "mailbox", - }, -}; - -static int __init omap2_mbox_init(void) -{ - return platform_driver_register(&omap2_mbox_driver); -} - -static void __exit omap2_mbox_exit(void) -{ - platform_driver_unregister(&omap2_mbox_driver); -} - -module_init(omap2_mbox_init); -module_exit(omap2_mbox_exit); - -MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index a9e631fc113..b4ac3af1160 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c @@ -15,210 +15,108 @@ #include <linux/clk.h> #include <linux/err.h> #include <linux/io.h> +#include <linux/of.h> #include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/platform_data/asoc-ti-mcbsp.h> +#include <linux/pm_runtime.h> -#include <mach/irqs.h> -#include <mach/dma.h> -#include <mach/irqs.h> -#include <mach/mux.h> -#include <mach/cpu.h> -#include <mach/mcbsp.h> +#include <linux/omap-dma.h> -const char *clk_names[] = { "mcbsp_ick", "mcbsp_fck" }; +#include "soc.h" +#include "omap_device.h" +#include "clock.h" -static void omap2_mcbsp2_mux_setup(void) +/* + * FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle. + * Sidetone needs non-gated ICLK and sidetone autoidle is broken. + */ +#include "cm3xxx.h" +#include "cm-regbits-34xx.h" + +static struct clk *mcbsp_iclks[5]; + +static int omap3_enable_st_clock(unsigned int id, bool enable) { - omap_cfg_reg(Y15_24XX_MCBSP2_CLKX); - omap_cfg_reg(R14_24XX_MCBSP2_FSX); - omap_cfg_reg(W15_24XX_MCBSP2_DR); - omap_cfg_reg(V15_24XX_MCBSP2_DX); - omap_cfg_reg(V14_24XX_GPIO117); /* - * TODO: Need to add MUX settings for OMAP 2430 SDP + * Sidetone uses McBSP ICLK - which must not idle when sidetones + * are enabled or sidetones start sounding ugly. */ + if (enable) + return omap2_clk_deny_idle(mcbsp_iclks[id]); + else + return omap2_clk_allow_idle(mcbsp_iclks[id]); } -static void omap2_mcbsp_request(unsigned int id) +static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused) { - if (cpu_is_omap2420() && (id == OMAP_MCBSP2)) - omap2_mcbsp2_mux_setup(); -} + int id, count = 1; + char *name = "omap-mcbsp"; + struct omap_hwmod *oh_device[2]; + struct omap_mcbsp_platform_data *pdata = NULL; + struct platform_device *pdev; + char clk_name[11]; -static struct omap_mcbsp_ops omap2_mcbsp_ops = { - .request = omap2_mcbsp_request, -}; + sscanf(oh->name, "mcbsp%d", &id); -#ifdef CONFIG_ARCH_OMAP2420 -static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = { - { - .phys_base = OMAP24XX_MCBSP1_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, - .rx_irq = INT_24XX_MCBSP1_IRQ_RX, - .tx_irq = INT_24XX_MCBSP1_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, - }, - { - .phys_base = OMAP24XX_MCBSP2_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, - .rx_irq = INT_24XX_MCBSP2_IRQ_RX, - .tx_irq = INT_24XX_MCBSP2_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, - }, -}; -#define OMAP2420_MCBSP_PDATA_SZ ARRAY_SIZE(omap2420_mcbsp_pdata) -#else -#define omap2420_mcbsp_pdata NULL -#define OMAP2420_MCBSP_PDATA_SZ 0 -#endif + pdata = kzalloc(sizeof(struct omap_mcbsp_platform_data), GFP_KERNEL); + if (!pdata) { + pr_err("%s: No memory for mcbsp\n", __func__); + return -ENOMEM; + } -#ifdef CONFIG_ARCH_OMAP2430 -static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = { - { - .phys_base = OMAP24XX_MCBSP1_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, - .rx_irq = INT_24XX_MCBSP1_IRQ_RX, - .tx_irq = INT_24XX_MCBSP1_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, - }, - { - .phys_base = OMAP24XX_MCBSP2_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, - .rx_irq = INT_24XX_MCBSP2_IRQ_RX, - .tx_irq = INT_24XX_MCBSP2_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, - }, - { - .phys_base = OMAP2430_MCBSP3_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX, - .rx_irq = INT_24XX_MCBSP3_IRQ_RX, - .tx_irq = INT_24XX_MCBSP3_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, - }, - { - .phys_base = OMAP2430_MCBSP4_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX, - .rx_irq = INT_24XX_MCBSP4_IRQ_RX, - .tx_irq = INT_24XX_MCBSP4_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, - }, - { - .phys_base = OMAP2430_MCBSP5_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX, - .rx_irq = INT_24XX_MCBSP5_IRQ_RX, - .tx_irq = INT_24XX_MCBSP5_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, - }, -}; -#define OMAP2430_MCBSP_PDATA_SZ ARRAY_SIZE(omap2430_mcbsp_pdata) -#else -#define omap2430_mcbsp_pdata NULL -#define OMAP2430_MCBSP_PDATA_SZ 0 -#endif + pdata->reg_step = 4; + if (oh->class->rev < MCBSP_CONFIG_TYPE2) { + pdata->reg_size = 2; + } else { + pdata->reg_size = 4; + pdata->has_ccr = true; + } -#ifdef CONFIG_ARCH_OMAP34XX -static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { - { - .phys_base = OMAP34XX_MCBSP1_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, - .rx_irq = INT_24XX_MCBSP1_IRQ_RX, - .tx_irq = INT_24XX_MCBSP1_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, - }, - { - .phys_base = OMAP34XX_MCBSP2_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, - .rx_irq = INT_24XX_MCBSP2_IRQ_RX, - .tx_irq = INT_24XX_MCBSP2_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, - }, - { - .phys_base = OMAP34XX_MCBSP3_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX, - .rx_irq = INT_24XX_MCBSP3_IRQ_RX, - .tx_irq = INT_24XX_MCBSP3_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, - }, - { - .phys_base = OMAP34XX_MCBSP4_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX, - .rx_irq = INT_24XX_MCBSP4_IRQ_RX, - .tx_irq = INT_24XX_MCBSP4_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, - }, - { - .phys_base = OMAP34XX_MCBSP5_BASE, - .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX, - .rx_irq = INT_24XX_MCBSP5_IRQ_RX, - .tx_irq = INT_24XX_MCBSP5_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_names = clk_names, - .num_clks = 2, - }, -}; -#define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) -#else -#define omap34xx_mcbsp_pdata NULL -#define OMAP34XX_MCBSP_PDATA_SZ 0 -#endif + if (oh->class->rev == MCBSP_CONFIG_TYPE2) { + /* The FIFO has 128 locations */ + pdata->buffer_size = 0x80; + } else if (oh->class->rev == MCBSP_CONFIG_TYPE3) { + if (id == 2) + /* The FIFO has 1024 + 256 locations */ + pdata->buffer_size = 0x500; + else + /* The FIFO has 128 locations */ + pdata->buffer_size = 0x80; + } else if (oh->class->rev == MCBSP_CONFIG_TYPE4) { + /* The FIFO has 128 locations for all instances */ + pdata->buffer_size = 0x80; + } -static int __init omap2_mcbsp_init(void) -{ - if (cpu_is_omap2420()) - omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ; - if (cpu_is_omap2430()) - omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ; - if (cpu_is_omap34xx()) - omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ; + if (oh->class->rev >= MCBSP_CONFIG_TYPE3) + pdata->has_wakeup = true; - mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *), - GFP_KERNEL); - if (!mcbsp_ptr) - return -ENOMEM; + oh_device[0] = oh; + + if (oh->dev_attr) { + oh_device[1] = omap_hwmod_lookup(( + (struct omap_mcbsp_dev_attr *)(oh->dev_attr))->sidetone); + pdata->enable_st_clock = omap3_enable_st_clock; + sprintf(clk_name, "mcbsp%d_ick", id); + mcbsp_iclks[id] = clk_get(NULL, clk_name); + count++; + } + pdev = omap_device_build_ss(name, id, oh_device, count, pdata, + sizeof(*pdata)); + kfree(pdata); + if (IS_ERR(pdev)) { + pr_err("%s: Can't build omap_device for %s:%s.\n", __func__, + name, oh->name); + return PTR_ERR(pdev); + } + return 0; +} - if (cpu_is_omap2420()) - omap_mcbsp_register_board_cfg(omap2420_mcbsp_pdata, - OMAP2420_MCBSP_PDATA_SZ); - if (cpu_is_omap2430()) - omap_mcbsp_register_board_cfg(omap2430_mcbsp_pdata, - OMAP2430_MCBSP_PDATA_SZ); - if (cpu_is_omap34xx()) - omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata, - OMAP34XX_MCBSP_PDATA_SZ); +static int __init omap2_mcbsp_init(void) +{ + if (!of_have_populated_dt()) + omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL); - return omap_mcbsp_init(); + return 0; } -arch_initcall(omap2_mcbsp_init); +omap_arch_initcall(omap2_mcbsp_init); diff --git a/arch/arm/mach-omap2/memory.h b/arch/arm/mach-omap2/memory.h deleted file mode 100644 index bb3db80a7c4..00000000000 --- a/arch/arm/mach-omap2/memory.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/memory.h - * - * Interface for memory timing related functions for OMAP24XX - * - * Copyright (C) 2005 Texas Instruments Inc. - * Richard Woodruff <r-woodruff2@ti.com> - * - * Copyright (C) 2005 Nokia Corporation - * Tony Lindgren <tony@atomide.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef ARCH_ARM_MACH_OMAP2_MEMORY_H -#define ARCH_ARM_MACH_OMAP2_MEMORY_H - -/* Memory timings */ -#define M_DDR 1 -#define M_LOCK_CTRL (1 << 2) -#define M_UNLOCK 0 -#define M_LOCK 1 - -struct memory_timings { - u32 m_type; /* ddr = 1, sdr = 0 */ - u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */ - u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */ - u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */ - u32 base_cs; /* base chip select to use for calculations */ -}; - -extern void omap2_init_memory_params(u32 force_lock_to_unlock_mode); -extern u32 omap2_memory_get_slow_dll_ctrl(void); -extern u32 omap2_memory_get_fast_dll_ctrl(void); -extern u32 omap2_memory_get_type(void); -u32 omap2_dll_force_needed(void); -u32 omap2_reprogram_sdrc(u32 level, u32 force); -void __init omap2_init_memory(void); -void __init gpmc_init(void); - -#endif diff --git a/arch/arm/mach-omap2/mmc-twl4030.c b/arch/arm/mach-omap2/mmc-twl4030.c deleted file mode 100644 index 437f52073f6..00000000000 --- a/arch/arm/mach-omap2/mmc-twl4030.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/mmc-twl4030.c - * - * Copyright (C) 2007-2008 Texas Instruments - * Copyright (C) 2008 Nokia Corporation - * Author: Texas Instruments - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/err.h> -#include <linux/io.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/gpio.h> -#include <linux/i2c/twl4030.h> - -#include <mach/hardware.h> -#include <mach/control.h> -#include <mach/mmc.h> -#include <mach/board.h> - -#include "mmc-twl4030.h" - -#if defined(CONFIG_TWL4030_CORE) && \ - (defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)) - -#define LDO_CLR 0x00 -#define VSEL_S2_CLR 0x40 - -#define VMMC1_DEV_GRP 0x27 -#define VMMC1_CLR 0x00 -#define VMMC1_315V 0x03 -#define VMMC1_300V 0x02 -#define VMMC1_285V 0x01 -#define VMMC1_185V 0x00 -#define VMMC1_DEDICATED 0x2A - -#define VMMC2_DEV_GRP 0x2B -#define VMMC2_CLR 0x40 -#define VMMC2_315V 0x0c -#define VMMC2_300V 0x0b -#define VMMC2_285V 0x0a -#define VMMC2_260V 0x08 -#define VMMC2_185V 0x06 -#define VMMC2_DEDICATED 0x2E - -#define VMMC_DEV_GRP_P1 0x20 - -static u16 control_pbias_offset; -static u16 control_devconf1_offset; - -#define HSMMC_NAME_LEN 9 - -static struct twl_mmc_controller { - struct omap_mmc_platform_data *mmc; - u8 twl_vmmc_dev_grp; - u8 twl_mmc_dedicated; - char name[HSMMC_NAME_LEN]; -} hsmmc[] = { - { - .twl_vmmc_dev_grp = VMMC1_DEV_GRP, - .twl_mmc_dedicated = VMMC1_DEDICATED, - }, - { - .twl_vmmc_dev_grp = VMMC2_DEV_GRP, - .twl_mmc_dedicated = VMMC2_DEDICATED, - }, -}; - -static int twl_mmc_card_detect(int irq) -{ - unsigned i; - - for (i = 0; i < ARRAY_SIZE(hsmmc); i++) { - struct omap_mmc_platform_data *mmc; - - mmc = hsmmc[i].mmc; - if (!mmc) - continue; - if (irq != mmc->slots[0].card_detect_irq) - continue; - - /* NOTE: assumes card detect signal is active-low */ - return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); - } - return -ENOSYS; -} - -static int twl_mmc_get_ro(struct device *dev, int slot) -{ - struct omap_mmc_platform_data *mmc = dev->platform_data; - - /* NOTE: assumes write protect signal is active-high */ - return gpio_get_value_cansleep(mmc->slots[0].gpio_wp); -} - -/* - * MMC Slot Initialization. - */ -static int twl_mmc_late_init(struct device *dev) -{ - struct omap_mmc_platform_data *mmc = dev->platform_data; - int ret = 0; - int i; - - ret = gpio_request(mmc->slots[0].switch_pin, "mmc_cd"); - if (ret) - goto done; - ret = gpio_direction_input(mmc->slots[0].switch_pin); - if (ret) - goto err; - - for (i = 0; i < ARRAY_SIZE(hsmmc); i++) { - if (hsmmc[i].name == mmc->slots[0].name) { - hsmmc[i].mmc = mmc; - break; - } - } - - return 0; - -err: - gpio_free(mmc->slots[0].switch_pin); -done: - mmc->slots[0].card_detect_irq = 0; - mmc->slots[0].card_detect = NULL; - - dev_err(dev, "err %d configuring card detect\n", ret); - return ret; -} - -static void twl_mmc_cleanup(struct device *dev) -{ - struct omap_mmc_platform_data *mmc = dev->platform_data; - - gpio_free(mmc->slots[0].switch_pin); -} - -#ifdef CONFIG_PM - -static int twl_mmc_suspend(struct device *dev, int slot) -{ - struct omap_mmc_platform_data *mmc = dev->platform_data; - - disable_irq(mmc->slots[0].card_detect_irq); - return 0; -} - -static int twl_mmc_resume(struct device *dev, int slot) -{ - struct omap_mmc_platform_data *mmc = dev->platform_data; - - enable_irq(mmc->slots[0].card_detect_irq); - return 0; -} - -#else -#define twl_mmc_suspend NULL -#define twl_mmc_resume NULL -#endif - -/* - * Sets the MMC voltage in twl4030 - */ -static int twl_mmc_set_voltage(struct twl_mmc_controller *c, int vdd) -{ - int ret; - u8 vmmc, dev_grp_val; - - switch (1 << vdd) { - case MMC_VDD_35_36: - case MMC_VDD_34_35: - case MMC_VDD_33_34: - case MMC_VDD_32_33: - case MMC_VDD_31_32: - case MMC_VDD_30_31: - if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) - vmmc = VMMC1_315V; - else - vmmc = VMMC2_315V; - break; - case MMC_VDD_29_30: - if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) - vmmc = VMMC1_315V; - else - vmmc = VMMC2_300V; - break; - case MMC_VDD_27_28: - case MMC_VDD_26_27: - if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) - vmmc = VMMC1_285V; - else - vmmc = VMMC2_285V; - break; - case MMC_VDD_25_26: - case MMC_VDD_24_25: - case MMC_VDD_23_24: - case MMC_VDD_22_23: - case MMC_VDD_21_22: - case MMC_VDD_20_21: - if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) - vmmc = VMMC1_285V; - else - vmmc = VMMC2_260V; - break; - case MMC_VDD_165_195: - if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) - vmmc = VMMC1_185V; - else - vmmc = VMMC2_185V; - break; - default: - vmmc = 0; - break; - } - - if (vmmc) - dev_grp_val = VMMC_DEV_GRP_P1; /* Power up */ - else - dev_grp_val = LDO_CLR; /* Power down */ - - ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, - dev_grp_val, c->twl_vmmc_dev_grp); - if (ret) - return ret; - - ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, - vmmc, c->twl_mmc_dedicated); - - return ret; -} - -static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, - int vdd) -{ - u32 reg; - int ret = 0; - struct twl_mmc_controller *c = &hsmmc[0]; - struct omap_mmc_platform_data *mmc = dev->platform_data; - - if (power_on) { - if (cpu_is_omap2430()) { - reg = omap_ctrl_readl(OMAP243X_CONTROL_DEVCONF1); - if ((1 << vdd) >= MMC_VDD_30_31) - reg |= OMAP243X_MMC1_ACTIVE_OVERWRITE; - else - reg &= ~OMAP243X_MMC1_ACTIVE_OVERWRITE; - omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1); - } - - if (mmc->slots[0].internal_clock) { - reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); - reg |= OMAP2_MMCSDIO1ADPCLKISEL; - omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0); - } - - reg = omap_ctrl_readl(control_pbias_offset); - reg |= OMAP2_PBIASSPEEDCTRL0; - reg &= ~OMAP2_PBIASLITEPWRDNZ0; - omap_ctrl_writel(reg, control_pbias_offset); - - ret = twl_mmc_set_voltage(c, vdd); - - /* 100ms delay required for PBIAS configuration */ - msleep(100); - reg = omap_ctrl_readl(control_pbias_offset); - reg |= (OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0); - if ((1 << vdd) <= MMC_VDD_165_195) - reg &= ~OMAP2_PBIASLITEVMODE0; - else - reg |= OMAP2_PBIASLITEVMODE0; - omap_ctrl_writel(reg, control_pbias_offset); - } else { - reg = omap_ctrl_readl(control_pbias_offset); - reg &= ~OMAP2_PBIASLITEPWRDNZ0; - omap_ctrl_writel(reg, control_pbias_offset); - - ret = twl_mmc_set_voltage(c, 0); - - /* 100ms delay required for PBIAS configuration */ - msleep(100); - reg = omap_ctrl_readl(control_pbias_offset); - reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 | - OMAP2_PBIASLITEVMODE0); - omap_ctrl_writel(reg, control_pbias_offset); - } - - return ret; -} - -static int twl_mmc2_set_power(struct device *dev, int slot, int power_on, int vdd) -{ - int ret; - struct twl_mmc_controller *c = &hsmmc[1]; - struct omap_mmc_platform_data *mmc = dev->platform_data; - - if (power_on) { - if (mmc->slots[0].internal_clock) { - u32 reg; - - reg = omap_ctrl_readl(control_devconf1_offset); - reg |= OMAP2_MMCSDIO2ADPCLKISEL; - omap_ctrl_writel(reg, control_devconf1_offset); - } - ret = twl_mmc_set_voltage(c, vdd); - } else { - ret = twl_mmc_set_voltage(c, 0); - } - - return ret; -} - -static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata; - -void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) -{ - struct twl4030_hsmmc_info *c; - int nr_hsmmc = ARRAY_SIZE(hsmmc_data); - - if (cpu_is_omap2430()) { - control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE; - control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1; - nr_hsmmc = 2; - } else { - control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE; - control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1; - } - - for (c = controllers; c->mmc; c++) { - struct twl_mmc_controller *twl = hsmmc + c->mmc - 1; - struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1]; - - if (!c->mmc || c->mmc > nr_hsmmc) { - pr_debug("MMC%d: no such controller\n", c->mmc); - continue; - } - if (mmc) { - pr_debug("MMC%d: already configured\n", c->mmc); - continue; - } - - mmc = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL); - if (!mmc) { - pr_err("Cannot allocate memory for mmc device!\n"); - return; - } - - sprintf(twl->name, "mmc%islot%i", c->mmc, 1); - mmc->slots[0].name = twl->name; - mmc->nr_slots = 1; - mmc->slots[0].ocr_mask = MMC_VDD_165_195 | - MMC_VDD_26_27 | MMC_VDD_27_28 | - MMC_VDD_29_30 | - MMC_VDD_30_31 | MMC_VDD_31_32; - mmc->slots[0].wires = c->wires; - mmc->slots[0].internal_clock = !c->ext_clock; - mmc->dma_mask = 0xffffffff; - - /* note: twl4030 card detect GPIOs normally switch VMMCx ... */ - if (gpio_is_valid(c->gpio_cd)) { - mmc->init = twl_mmc_late_init; - mmc->cleanup = twl_mmc_cleanup; - mmc->suspend = twl_mmc_suspend; - mmc->resume = twl_mmc_resume; - - mmc->slots[0].switch_pin = c->gpio_cd; - mmc->slots[0].card_detect_irq = gpio_to_irq(c->gpio_cd); - mmc->slots[0].card_detect = twl_mmc_card_detect; - } else - mmc->slots[0].switch_pin = -EINVAL; - - /* write protect normally uses an OMAP gpio */ - if (gpio_is_valid(c->gpio_wp)) { - gpio_request(c->gpio_wp, "mmc_wp"); - gpio_direction_input(c->gpio_wp); - - mmc->slots[0].gpio_wp = c->gpio_wp; - mmc->slots[0].get_ro = twl_mmc_get_ro; - } else - mmc->slots[0].gpio_wp = -EINVAL; - - /* NOTE: we assume OMAP's MMC1 and MMC2 use - * the TWL4030's VMMC1 and VMMC2, respectively; - * and that OMAP's MMC3 isn't used. - */ - - switch (c->mmc) { - case 1: - mmc->slots[0].set_power = twl_mmc1_set_power; - break; - case 2: - mmc->slots[0].set_power = twl_mmc2_set_power; - break; - default: - pr_err("MMC%d configuration not supported!\n", c->mmc); - continue; - } - hsmmc_data[c->mmc - 1] = mmc; - } - - omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC); -} - -#endif diff --git a/arch/arm/mach-omap2/mmc-twl4030.h b/arch/arm/mach-omap2/mmc-twl4030.h deleted file mode 100644 index e1c8076400c..00000000000 --- a/arch/arm/mach-omap2/mmc-twl4030.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * MMC definitions for OMAP2 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -struct twl4030_hsmmc_info { - u8 mmc; /* controller 1/2/3 */ - u8 wires; /* 1/4/8 wires */ - int gpio_cd; /* or -EINVAL */ - int gpio_wp; /* or -EINVAL */ - int ext_clock:1; /* use external pin for input clock */ -}; - -#if defined(CONFIG_TWL4030_CORE) && \ - (defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ - defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)) - -void twl4030_mmc_init(struct twl4030_hsmmc_info *); - -#else - -static inline void twl4030_mmc_init(struct twl4030_hsmmc_info *info) -{ -} - -#endif diff --git a/arch/arm/mach-omap2/mmc.h b/arch/arm/mach-omap2/mmc.h new file mode 100644 index 00000000000..0cd4b089da9 --- /dev/null +++ b/arch/arm/mach-omap2/mmc.h @@ -0,0 +1,23 @@ +#include <linux/mmc/host.h> +#include <linux/platform_data/mmc-omap.h> + +#define OMAP24XX_NR_MMC 2 +#define OMAP2420_MMC_SIZE OMAP1_MMC_SIZE +#define OMAP2_MMC1_BASE 0x4809c000 + +#define OMAP4_MMC_REG_OFFSET 0x100 + +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) +void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data); +#else +static inline void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data) +{ +} +#endif + +struct omap_hwmod; +int omap_msdi_reset(struct omap_hwmod *oh); + +/* called from board-specific card detection service routine */ +extern void omap_mmc_notify_cover_event(struct device *dev, int slot, + int is_closed); diff --git a/arch/arm/mach-omap2/msdi.c b/arch/arm/mach-omap2/msdi.c new file mode 100644 index 00000000000..828e0db3d94 --- /dev/null +++ b/arch/arm/mach-omap2/msdi.c @@ -0,0 +1,90 @@ +/* + * MSDI IP block reset + * + * Copyright (C) 2012 Texas Instruments, Inc. + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * XXX What about pad muxing? + */ + +#include <linux/kernel.h> +#include <linux/err.h> +#include <linux/platform_data/gpio-omap.h> + +#include "prm.h" +#include "common.h" +#include "control.h" +#include "omap_hwmod.h" +#include "omap_device.h" +#include "mux.h" +#include "mmc.h" + +/* + * MSDI_CON_OFFSET: offset in bytes of the MSDI IP block's CON register + * from the IP block's base address + */ +#define MSDI_CON_OFFSET 0x0c + +/* Register bitfields in the CON register */ +#define MSDI_CON_POW_MASK BIT(11) +#define MSDI_CON_CLKD_MASK (0x3f << 0) +#define MSDI_CON_CLKD_SHIFT 0 + +/* MSDI_TARGET_RESET_CLKD: clock divisor to use throughout the reset */ +#define MSDI_TARGET_RESET_CLKD 0x3ff + +/** + * omap_msdi_reset - reset the MSDI IP block + * @oh: struct omap_hwmod * + * + * The MSDI IP block on OMAP2420 has to have both the POW and CLKD + * fields set inside its CON register for a reset to complete + * successfully. This is not documented in the TRM. For CLKD, we use + * the value that results in the lowest possible clock rate, to attempt + * to avoid disturbing any cards. + */ +int omap_msdi_reset(struct omap_hwmod *oh) +{ + u16 v = 0; + int c = 0; + + /* Write to the SOFTRESET bit */ + omap_hwmod_softreset(oh); + + /* Enable the MSDI core and internal clock */ + v |= MSDI_CON_POW_MASK; + v |= MSDI_TARGET_RESET_CLKD << MSDI_CON_CLKD_SHIFT; + omap_hwmod_write(v, oh, MSDI_CON_OFFSET); + + /* Poll on RESETDONE bit */ + omap_test_timeout((omap_hwmod_read(oh, oh->class->sysc->syss_offs) + & SYSS_RESETDONE_MASK), + MAX_MODULE_SOFTRESET_WAIT, c); + + if (c == MAX_MODULE_SOFTRESET_WAIT) + pr_warning("%s: %s: softreset failed (waited %d usec)\n", + __func__, oh->name, MAX_MODULE_SOFTRESET_WAIT); + else + pr_debug("%s: %s: softreset in %d usec\n", __func__, + oh->name, c); + + /* Disable the MSDI internal clock */ + v &= ~MSDI_CON_CLKD_MASK; + omap_hwmod_write(v, oh, MSDI_CON_OFFSET); + + return 0; +} diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index dacb41f130c..f62f7537d89 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -1,9 +1,9 @@ /* * linux/arch/arm/mach-omap2/mux.c * - * OMAP2 and OMAP3 pin multiplexing configurations + * OMAP2, OMAP3 and OMAP4 pin multiplexing configurations * - * Copyright (C) 2004 - 2008 Texas Instruments Inc. + * Copyright (C) 2004 - 2010 Texas Instruments Inc. * Copyright (C) 2003 - 2008 Nokia Corporation * * Written by Tony Lindgren @@ -23,531 +23,1141 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include <linux/module.h> +#include <linux/kernel.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/spinlock.h> +#include <linux/list.h> +#include <linux/slab.h> +#include <linux/ctype.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#include <linux/uaccess.h> +#include <linux/irq.h> +#include <linux/interrupt.h> -#include <asm/system.h> -#include <mach/control.h> -#include <mach/mux.h> +#include "omap_hwmod.h" + +#include "soc.h" +#include "control.h" +#include "mux.h" +#include "prm.h" +#include "common.h" + +#define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */ +#define OMAP_MUX_BASE_SZ 0x5ca + +struct omap_mux_entry { + struct omap_mux mux; + struct list_head node; +}; + +static LIST_HEAD(mux_partitions); +static DEFINE_MUTEX(muxmode_mutex); + +struct omap_mux_partition *omap_mux_get(const char *name) +{ + struct omap_mux_partition *partition; + + list_for_each_entry(partition, &mux_partitions, node) { + if (!strcmp(name, partition->name)) + return partition; + } + + return NULL; +} + +u16 omap_mux_read(struct omap_mux_partition *partition, u16 reg) +{ + if (partition->flags & OMAP_MUX_REG_8BIT) + return readb_relaxed(partition->base + reg); + else + return readw_relaxed(partition->base + reg); +} + +void omap_mux_write(struct omap_mux_partition *partition, u16 val, + u16 reg) +{ + if (partition->flags & OMAP_MUX_REG_8BIT) + writeb_relaxed(val, partition->base + reg); + else + writew_relaxed(val, partition->base + reg); +} + +void omap_mux_write_array(struct omap_mux_partition *partition, + struct omap_board_mux *board_mux) +{ + if (!board_mux) + return; + + while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) { + omap_mux_write(partition, board_mux->value, + board_mux->reg_offset); + board_mux++; + } +} #ifdef CONFIG_OMAP_MUX -static struct omap_mux_cfg arch_mux_cfg; +static char *omap_mux_options; -/* NOTE: See mux.h for the enumeration */ +static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition, + int gpio, int val) +{ + struct omap_mux_entry *e; + struct omap_mux *gpio_mux = NULL; + u16 old_mode; + u16 mux_mode; + int found = 0; + struct list_head *muxmodes = &partition->muxmodes; -#ifdef CONFIG_ARCH_OMAP24XX -static struct pin_config __initdata_or_module omap24xx_pins[] = { -/* - * description mux mux pull pull debug - * offset mode ena type + if (!gpio) + return -EINVAL; + + list_for_each_entry(e, muxmodes, node) { + struct omap_mux *m = &e->mux; + if (gpio == m->gpio) { + gpio_mux = m; + found++; + } + } + + if (found == 0) { + pr_err("%s: Could not set gpio%i\n", __func__, gpio); + return -ENODEV; + } + + if (found > 1) { + pr_info("%s: Multiple gpio paths (%d) for gpio%i\n", __func__, + found, gpio); + return -EINVAL; + } + + old_mode = omap_mux_read(partition, gpio_mux->reg_offset); + mux_mode = val & ~(OMAP_MUX_NR_MODES - 1); + mux_mode |= partition->gpio; + pr_debug("%s: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n", __func__, + gpio_mux->muxnames[0], gpio, old_mode, mux_mode); + omap_mux_write(partition, mux_mode, gpio_mux->reg_offset); + + return 0; +} + +int __init omap_mux_init_gpio(int gpio, int val) +{ + struct omap_mux_partition *partition; + int ret; + + list_for_each_entry(partition, &mux_partitions, node) { + ret = _omap_mux_init_gpio(partition, gpio, val); + if (!ret) + return ret; + } + + return -ENODEV; +} + +static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition, + const char *muxname, + struct omap_mux **found_mux) +{ + struct omap_mux *mux = NULL; + struct omap_mux_entry *e; + const char *mode_name; + int found = 0, found_mode = 0, mode0_len = 0; + struct list_head *muxmodes = &partition->muxmodes; + + mode_name = strchr(muxname, '.'); + if (mode_name) { + mode0_len = strlen(muxname) - strlen(mode_name); + mode_name++; + } else { + mode_name = muxname; + } + + list_for_each_entry(e, muxmodes, node) { + char *m0_entry; + int i; + + mux = &e->mux; + m0_entry = mux->muxnames[0]; + + /* First check for full name in mode0.muxmode format */ + if (mode0_len) + if (strncmp(muxname, m0_entry, mode0_len) || + (strlen(m0_entry) != mode0_len)) + continue; + + /* Then check for muxmode only */ + for (i = 0; i < OMAP_MUX_NR_MODES; i++) { + char *mode_cur = mux->muxnames[i]; + + if (!mode_cur) + continue; + + if (!strcmp(mode_name, mode_cur)) { + *found_mux = mux; + found++; + found_mode = i; + } + } + } + + if (found == 1) { + return found_mode; + } + + if (found > 1) { + pr_err("%s: Multiple signal paths (%i) for %s\n", __func__, + found, muxname); + return -EINVAL; + } + + return -ENODEV; +} + +int __init omap_mux_get_by_name(const char *muxname, + struct omap_mux_partition **found_partition, + struct omap_mux **found_mux) +{ + struct omap_mux_partition *partition; + + list_for_each_entry(partition, &mux_partitions, node) { + struct omap_mux *mux = NULL; + int mux_mode = _omap_mux_get_by_name(partition, muxname, &mux); + if (mux_mode < 0) + continue; + + *found_partition = partition; + *found_mux = mux; + + return mux_mode; + } + + pr_err("%s: Could not find signal %s\n", __func__, muxname); + + return -ENODEV; +} + +int __init omap_mux_init_signal(const char *muxname, int val) +{ + struct omap_mux_partition *partition = NULL; + struct omap_mux *mux = NULL; + u16 old_mode; + int mux_mode; + + mux_mode = omap_mux_get_by_name(muxname, &partition, &mux); + if (mux_mode < 0 || !mux) + return mux_mode; + + old_mode = omap_mux_read(partition, mux->reg_offset); + mux_mode |= val; + pr_debug("%s: Setting signal %s 0x%04x -> 0x%04x\n", + __func__, muxname, old_mode, mux_mode); + omap_mux_write(partition, mux_mode, mux->reg_offset); + + return 0; +} + +struct omap_hwmod_mux_info * __init +omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads) +{ + struct omap_hwmod_mux_info *hmux; + int i, nr_pads_dynamic = 0; + + if (!bpads || nr_pads < 1) + return NULL; + + hmux = kzalloc(sizeof(struct omap_hwmod_mux_info), GFP_KERNEL); + if (!hmux) + goto err1; + + hmux->nr_pads = nr_pads; + + hmux->pads = kzalloc(sizeof(struct omap_device_pad) * + nr_pads, GFP_KERNEL); + if (!hmux->pads) + goto err2; + + for (i = 0; i < hmux->nr_pads; i++) { + struct omap_mux_partition *partition; + struct omap_device_pad *bpad = &bpads[i], *pad = &hmux->pads[i]; + struct omap_mux *mux; + int mux_mode; + + mux_mode = omap_mux_get_by_name(bpad->name, &partition, &mux); + if (mux_mode < 0) + goto err3; + if (!pad->partition) + pad->partition = partition; + if (!pad->mux) + pad->mux = mux; + + pad->name = kzalloc(strlen(bpad->name) + 1, GFP_KERNEL); + if (!pad->name) { + int j; + + for (j = i - 1; j >= 0; j--) + kfree(hmux->pads[j].name); + goto err3; + } + strcpy(pad->name, bpad->name); + + pad->flags = bpad->flags; + pad->enable = bpad->enable; + pad->idle = bpad->idle; + pad->off = bpad->off; + + if (pad->flags & + (OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP)) + nr_pads_dynamic++; + + pr_debug("%s: Initialized %s\n", __func__, pad->name); + } + + if (!nr_pads_dynamic) + return hmux; + + /* + * Add pads that need dynamic muxing into a separate list + */ + + hmux->nr_pads_dynamic = nr_pads_dynamic; + hmux->pads_dynamic = kzalloc(sizeof(struct omap_device_pad *) * + nr_pads_dynamic, GFP_KERNEL); + if (!hmux->pads_dynamic) { + pr_err("%s: Could not allocate dynamic pads\n", __func__); + return hmux; + } + + nr_pads_dynamic = 0; + for (i = 0; i < hmux->nr_pads; i++) { + struct omap_device_pad *pad = &hmux->pads[i]; + + if (pad->flags & + (OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP)) { + pr_debug("%s: pad %s tagged dynamic\n", + __func__, pad->name); + hmux->pads_dynamic[nr_pads_dynamic] = pad; + nr_pads_dynamic++; + } + } + + return hmux; + +err3: + kfree(hmux->pads); +err2: + kfree(hmux); +err1: + pr_err("%s: Could not allocate device mux entry\n", __func__); + + return NULL; +} + +/** + * omap_hwmod_mux_scan_wakeups - omap hwmod scan wakeup pads + * @hmux: Pads for a hwmod + * @mpu_irqs: MPU irq array for a hwmod + * + * Scans the wakeup status of pads for a single hwmod. If an irq + * array is defined for this mux, the parser will call the registered + * ISRs for corresponding pads, otherwise the parser will stop at the + * first wakeup active pad and return. Returns true if there is a + * pending and non-served wakeup event for the mux, otherwise false. */ +static bool omap_hwmod_mux_scan_wakeups(struct omap_hwmod_mux_info *hmux, + struct omap_hwmod_irq_info *mpu_irqs) +{ + int i, irq; + unsigned int val; + u32 handled_irqs = 0; -/* 24xx I2C */ -MUX_CFG_24XX("M19_24XX_I2C1_SCL", 0x111, 0, 0, 0, 1) -MUX_CFG_24XX("L15_24XX_I2C1_SDA", 0x112, 0, 0, 0, 1) -MUX_CFG_24XX("J15_24XX_I2C2_SCL", 0x113, 0, 0, 1, 1) -MUX_CFG_24XX("H19_24XX_I2C2_SDA", 0x114, 0, 0, 0, 1) - -/* Menelaus interrupt */ -MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1) - -/* 24xx clocks */ -MUX_CFG_24XX("W14_24XX_SYS_CLKOUT", 0x137, 0, 1, 1, 1) - -/* 24xx GPMC chipselects, wait pin monitoring */ -MUX_CFG_24XX("E2_GPMC_NCS2", 0x08e, 0, 1, 1, 1) -MUX_CFG_24XX("L2_GPMC_NCS7", 0x093, 0, 1, 1, 1) -MUX_CFG_24XX("L3_GPMC_WAIT0", 0x09a, 0, 1, 1, 1) -MUX_CFG_24XX("N7_GPMC_WAIT1", 0x09b, 0, 1, 1, 1) -MUX_CFG_24XX("M1_GPMC_WAIT2", 0x09c, 0, 1, 1, 1) -MUX_CFG_24XX("P1_GPMC_WAIT3", 0x09d, 0, 1, 1, 1) - -/* 24xx McBSP */ -MUX_CFG_24XX("Y15_24XX_MCBSP2_CLKX", 0x124, 1, 1, 0, 1) -MUX_CFG_24XX("R14_24XX_MCBSP2_FSX", 0x125, 1, 1, 0, 1) -MUX_CFG_24XX("W15_24XX_MCBSP2_DR", 0x126, 1, 1, 0, 1) -MUX_CFG_24XX("V15_24XX_MCBSP2_DX", 0x127, 1, 1, 0, 1) - -/* 24xx GPIO */ -MUX_CFG_24XX("M21_242X_GPIO11", 0x0c9, 3, 1, 1, 1) -MUX_CFG_24XX("P21_242X_GPIO12", 0x0ca, 3, 0, 0, 1) -MUX_CFG_24XX("AA10_242X_GPIO13", 0x0e5, 3, 0, 0, 1) -MUX_CFG_24XX("AA6_242X_GPIO14", 0x0e6, 3, 0, 0, 1) -MUX_CFG_24XX("AA4_242X_GPIO15", 0x0e7, 3, 0, 0, 1) -MUX_CFG_24XX("Y11_242X_GPIO16", 0x0e8, 3, 0, 0, 1) -MUX_CFG_24XX("AA12_242X_GPIO17", 0x0e9, 3, 0, 0, 1) -MUX_CFG_24XX("AA8_242X_GPIO58", 0x0ea, 3, 0, 0, 1) -MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1) -MUX_CFG_24XX("W4__24XX_GPIO74", 0x0f2, 3, 0, 0, 1) -MUX_CFG_24XX("N15_24XX_GPIO85", 0x103, 3, 0, 0, 1) -MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1) -MUX_CFG_24XX("P20_24XX_GPIO93", 0x10b, 3, 0, 0, 1) -MUX_CFG_24XX("P18_24XX_GPIO95", 0x10d, 3, 0, 0, 1) -MUX_CFG_24XX("M18_24XX_GPIO96", 0x10e, 3, 0, 0, 1) -MUX_CFG_24XX("L14_24XX_GPIO97", 0x10f, 3, 0, 0, 1) -MUX_CFG_24XX("J15_24XX_GPIO99", 0x113, 3, 1, 1, 1) -MUX_CFG_24XX("V14_24XX_GPIO117", 0x128, 3, 1, 0, 1) -MUX_CFG_24XX("P14_24XX_GPIO125", 0x140, 3, 1, 1, 1) - -/* 242x DBG GPIO */ -MUX_CFG_24XX("V4_242X_GPIO49", 0xd3, 3, 0, 0, 1) -MUX_CFG_24XX("W2_242X_GPIO50", 0xd4, 3, 0, 0, 1) -MUX_CFG_24XX("U4_242X_GPIO51", 0xd5, 3, 0, 0, 1) -MUX_CFG_24XX("V3_242X_GPIO52", 0xd6, 3, 0, 0, 1) -MUX_CFG_24XX("V2_242X_GPIO53", 0xd7, 3, 0, 0, 1) -MUX_CFG_24XX("V6_242X_GPIO53", 0xcf, 3, 0, 0, 1) -MUX_CFG_24XX("T4_242X_GPIO54", 0xd8, 3, 0, 0, 1) -MUX_CFG_24XX("Y4_242X_GPIO54", 0xd0, 3, 0, 0, 1) -MUX_CFG_24XX("T3_242X_GPIO55", 0xd9, 3, 0, 0, 1) -MUX_CFG_24XX("U2_242X_GPIO56", 0xda, 3, 0, 0, 1) - -/* 24xx external DMA requests */ -MUX_CFG_24XX("AA10_242X_DMAREQ0", 0x0e5, 2, 0, 0, 1) -MUX_CFG_24XX("AA6_242X_DMAREQ1", 0x0e6, 2, 0, 0, 1) -MUX_CFG_24XX("E4_242X_DMAREQ2", 0x074, 2, 0, 0, 1) -MUX_CFG_24XX("G4_242X_DMAREQ3", 0x073, 2, 0, 0, 1) -MUX_CFG_24XX("D3_242X_DMAREQ4", 0x072, 2, 0, 0, 1) -MUX_CFG_24XX("E3_242X_DMAREQ5", 0x071, 2, 0, 0, 1) - -/* UART3 */ -MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1) -MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1) - -/* MMC/SDIO */ -MUX_CFG_24XX("G19_24XX_MMC_CLKO", 0x0f3, 0, 0, 0, 1) -MUX_CFG_24XX("H18_24XX_MMC_CMD", 0x0f4, 0, 0, 0, 1) -MUX_CFG_24XX("F20_24XX_MMC_DAT0", 0x0f5, 0, 0, 0, 1) -MUX_CFG_24XX("H14_24XX_MMC_DAT1", 0x0f6, 0, 0, 0, 1) -MUX_CFG_24XX("E19_24XX_MMC_DAT2", 0x0f7, 0, 0, 0, 1) -MUX_CFG_24XX("D19_24XX_MMC_DAT3", 0x0f8, 0, 0, 0, 1) -MUX_CFG_24XX("F19_24XX_MMC_DAT_DIR0", 0x0f9, 0, 0, 0, 1) -MUX_CFG_24XX("E20_24XX_MMC_DAT_DIR1", 0x0fa, 0, 0, 0, 1) -MUX_CFG_24XX("F18_24XX_MMC_DAT_DIR2", 0x0fb, 0, 0, 0, 1) -MUX_CFG_24XX("E18_24XX_MMC_DAT_DIR3", 0x0fc, 0, 0, 0, 1) -MUX_CFG_24XX("G18_24XX_MMC_CMD_DIR", 0x0fd, 0, 0, 0, 1) -MUX_CFG_24XX("H15_24XX_MMC_CLKI", 0x0fe, 0, 0, 0, 1) - -/* Full speed USB */ -MUX_CFG_24XX("J20_24XX_USB0_PUEN", 0x11d, 0, 0, 0, 1) -MUX_CFG_24XX("J19_24XX_USB0_VP", 0x11e, 0, 0, 0, 1) -MUX_CFG_24XX("K20_24XX_USB0_VM", 0x11f, 0, 0, 0, 1) -MUX_CFG_24XX("J18_24XX_USB0_RCV", 0x120, 0, 0, 0, 1) -MUX_CFG_24XX("K19_24XX_USB0_TXEN", 0x121, 0, 0, 0, 1) -MUX_CFG_24XX("J14_24XX_USB0_SE0", 0x122, 0, 0, 0, 1) -MUX_CFG_24XX("K18_24XX_USB0_DAT", 0x123, 0, 0, 0, 1) - -MUX_CFG_24XX("N14_24XX_USB1_SE0", 0x0ed, 2, 0, 0, 1) -MUX_CFG_24XX("W12_24XX_USB1_SE0", 0x0dd, 3, 0, 0, 1) -MUX_CFG_24XX("P15_24XX_USB1_DAT", 0x0ee, 2, 0, 0, 1) -MUX_CFG_24XX("R13_24XX_USB1_DAT", 0x0e0, 3, 0, 0, 1) -MUX_CFG_24XX("W20_24XX_USB1_TXEN", 0x0ec, 2, 0, 0, 1) -MUX_CFG_24XX("P13_24XX_USB1_TXEN", 0x0df, 3, 0, 0, 1) -MUX_CFG_24XX("V19_24XX_USB1_RCV", 0x0eb, 2, 0, 0, 1) -MUX_CFG_24XX("V12_24XX_USB1_RCV", 0x0de, 3, 0, 0, 1) - -MUX_CFG_24XX("AA10_24XX_USB2_SE0", 0x0e5, 2, 0, 0, 1) -MUX_CFG_24XX("Y11_24XX_USB2_DAT", 0x0e8, 2, 0, 0, 1) -MUX_CFG_24XX("AA12_24XX_USB2_TXEN", 0x0e9, 2, 0, 0, 1) -MUX_CFG_24XX("AA6_24XX_USB2_RCV", 0x0e6, 2, 0, 0, 1) -MUX_CFG_24XX("AA4_24XX_USB2_TLLSE0", 0x0e7, 2, 0, 0, 1) - -/* Keypad GPIO*/ -MUX_CFG_24XX("T19_24XX_KBR0", 0x106, 3, 1, 1, 1) -MUX_CFG_24XX("R19_24XX_KBR1", 0x107, 3, 1, 1, 1) -MUX_CFG_24XX("V18_24XX_KBR2", 0x139, 3, 1, 1, 1) -MUX_CFG_24XX("M21_24XX_KBR3", 0xc9, 3, 1, 1, 1) -MUX_CFG_24XX("E5__24XX_KBR4", 0x138, 3, 1, 1, 1) -MUX_CFG_24XX("M18_24XX_KBR5", 0x10e, 3, 1, 1, 1) -MUX_CFG_24XX("R20_24XX_KBC0", 0x108, 3, 0, 0, 1) -MUX_CFG_24XX("M14_24XX_KBC1", 0x109, 3, 0, 0, 1) -MUX_CFG_24XX("H19_24XX_KBC2", 0x114, 3, 0, 0, 1) -MUX_CFG_24XX("V17_24XX_KBC3", 0x135, 3, 0, 0, 1) -MUX_CFG_24XX("P21_24XX_KBC4", 0xca, 3, 0, 0, 1) -MUX_CFG_24XX("L14_24XX_KBC5", 0x10f, 3, 0, 0, 1) -MUX_CFG_24XX("N19_24XX_KBC6", 0x110, 3, 0, 0, 1) - -/* 24xx Menelaus Keypad GPIO */ -MUX_CFG_24XX("B3__24XX_KBR5", 0x30, 3, 1, 1, 1) -MUX_CFG_24XX("AA4_24XX_KBC2", 0xe7, 3, 0, 0, 1) -MUX_CFG_24XX("B13_24XX_KBC6", 0x110, 3, 0, 0, 1) - -/* 2430 USB */ -MUX_CFG_24XX("AD9_2430_USB0_PUEN", 0x133, 4, 0, 0, 1) -MUX_CFG_24XX("Y11_2430_USB0_VP", 0x134, 4, 0, 0, 1) -MUX_CFG_24XX("AD7_2430_USB0_VM", 0x135, 4, 0, 0, 1) -MUX_CFG_24XX("AE7_2430_USB0_RCV", 0x136, 4, 0, 0, 1) -MUX_CFG_24XX("AD4_2430_USB0_TXEN", 0x137, 4, 0, 0, 1) -MUX_CFG_24XX("AF9_2430_USB0_SE0", 0x138, 4, 0, 0, 1) -MUX_CFG_24XX("AE6_2430_USB0_DAT", 0x139, 4, 0, 0, 1) -MUX_CFG_24XX("AD24_2430_USB1_SE0", 0x107, 2, 0, 0, 1) -MUX_CFG_24XX("AB24_2430_USB1_RCV", 0x108, 2, 0, 0, 1) -MUX_CFG_24XX("Y25_2430_USB1_TXEN", 0x109, 2, 0, 0, 1) -MUX_CFG_24XX("AA26_2430_USB1_DAT", 0x10A, 2, 0, 0, 1) - -/* 2430 HS-USB */ -MUX_CFG_24XX("AD9_2430_USB0HS_DATA3", 0x133, 0, 0, 0, 1) -MUX_CFG_24XX("Y11_2430_USB0HS_DATA4", 0x134, 0, 0, 0, 1) -MUX_CFG_24XX("AD7_2430_USB0HS_DATA5", 0x135, 0, 0, 0, 1) -MUX_CFG_24XX("AE7_2430_USB0HS_DATA6", 0x136, 0, 0, 0, 1) -MUX_CFG_24XX("AD4_2430_USB0HS_DATA2", 0x137, 0, 0, 0, 1) -MUX_CFG_24XX("AF9_2430_USB0HS_DATA0", 0x138, 0, 0, 0, 1) -MUX_CFG_24XX("AE6_2430_USB0HS_DATA1", 0x139, 0, 0, 0, 1) -MUX_CFG_24XX("AE8_2430_USB0HS_CLK", 0x13A, 0, 0, 0, 1) -MUX_CFG_24XX("AD8_2430_USB0HS_DIR", 0x13B, 0, 0, 0, 1) -MUX_CFG_24XX("AE5_2430_USB0HS_STP", 0x13c, 0, 1, 1, 1) -MUX_CFG_24XX("AE9_2430_USB0HS_NXT", 0x13D, 0, 0, 0, 1) -MUX_CFG_24XX("AC7_2430_USB0HS_DATA7", 0x13E, 0, 0, 0, 1) - -/* 2430 McBSP */ -MUX_CFG_24XX("AD6_2430_MCBSP_CLKS", 0x011E, 0, 0, 0, 1) - -MUX_CFG_24XX("AB2_2430_MCBSP1_CLKR", 0x011A, 0, 0, 0, 1) -MUX_CFG_24XX("AD5_2430_MCBSP1_FSR", 0x011B, 0, 0, 0, 1) -MUX_CFG_24XX("AA1_2430_MCBSP1_DX", 0x011C, 0, 0, 0, 1) -MUX_CFG_24XX("AF3_2430_MCBSP1_DR", 0x011D, 0, 0, 0, 1) -MUX_CFG_24XX("AB3_2430_MCBSP1_FSX", 0x011F, 0, 0, 0, 1) -MUX_CFG_24XX("Y9_2430_MCBSP1_CLKX", 0x0120, 0, 0, 0, 1) - -MUX_CFG_24XX("AC10_2430_MCBSP2_FSX", 0x012E, 1, 0, 0, 1) -MUX_CFG_24XX("AD16_2430_MCBSP2_CLX", 0x012F, 1, 0, 0, 1) -MUX_CFG_24XX("AE13_2430_MCBSP2_DX", 0x0130, 1, 0, 0, 1) -MUX_CFG_24XX("AD13_2430_MCBSP2_DR", 0x0131, 1, 0, 0, 1) -MUX_CFG_24XX("AC10_2430_MCBSP2_FSX_OFF",0x012E, 0, 0, 0, 1) -MUX_CFG_24XX("AD16_2430_MCBSP2_CLX_OFF",0x012F, 0, 0, 0, 1) -MUX_CFG_24XX("AE13_2430_MCBSP2_DX_OFF", 0x0130, 0, 0, 0, 1) -MUX_CFG_24XX("AD13_2430_MCBSP2_DR_OFF", 0x0131, 0, 0, 0, 1) - -MUX_CFG_24XX("AC9_2430_MCBSP3_CLKX", 0x0103, 0, 0, 0, 1) -MUX_CFG_24XX("AE4_2430_MCBSP3_FSX", 0x0104, 0, 0, 0, 1) -MUX_CFG_24XX("AE2_2430_MCBSP3_DR", 0x0105, 0, 0, 0, 1) -MUX_CFG_24XX("AF4_2430_MCBSP3_DX", 0x0106, 0, 0, 0, 1) - -MUX_CFG_24XX("N3_2430_MCBSP4_CLKX", 0x010B, 1, 0, 0, 1) -MUX_CFG_24XX("AD23_2430_MCBSP4_DR", 0x010C, 1, 0, 0, 1) -MUX_CFG_24XX("AB25_2430_MCBSP4_DX", 0x010D, 1, 0, 0, 1) -MUX_CFG_24XX("AC25_2430_MCBSP4_FSX", 0x010E, 1, 0, 0, 1) - -MUX_CFG_24XX("AE16_2430_MCBSP5_CLKX", 0x00ED, 1, 0, 0, 1) -MUX_CFG_24XX("AF12_2430_MCBSP5_FSX", 0x00ED, 1, 0, 0, 1) -MUX_CFG_24XX("K7_2430_MCBSP5_DX", 0x00EF, 1, 0, 0, 1) -MUX_CFG_24XX("M1_2430_MCBSP5_DR", 0x00F0, 1, 0, 0, 1) - -/* 2430 MCSPI1 */ -MUX_CFG_24XX("Y18_2430_MCSPI1_CLK", 0x010F, 0, 0, 0, 1) -MUX_CFG_24XX("AD15_2430_MCSPI1_SIMO", 0x0110, 0, 0, 0, 1) -MUX_CFG_24XX("AE17_2430_MCSPI1_SOMI", 0x0111, 0, 0, 0, 1) -MUX_CFG_24XX("U1_2430_MCSPI1_CS0", 0x0112, 0, 0, 0, 1) - -/* Touchscreen GPIO */ -MUX_CFG_24XX("AF19_2430_GPIO_85", 0x0113, 3, 0, 0, 1) + for (i = 0; i < hmux->nr_pads_dynamic; i++) { + struct omap_device_pad *pad = hmux->pads_dynamic[i]; -}; + if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP) || + !(pad->idle & OMAP_WAKEUP_EN)) + continue; -#define OMAP24XX_PINS_SZ ARRAY_SIZE(omap24xx_pins) + val = omap_mux_read(pad->partition, pad->mux->reg_offset); + if (!(val & OMAP_WAKEUP_EVENT)) + continue; -#else -#define omap24xx_pins NULL -#define OMAP24XX_PINS_SZ 0 -#endif /* CONFIG_ARCH_OMAP24XX */ + if (!hmux->irqs) + return true; -#ifdef CONFIG_ARCH_OMAP34XX -static struct pin_config __initdata_or_module omap34xx_pins[] = { -/* - * Name, reg-offset, - * mux-mode | [active-mode | off-mode] + irq = hmux->irqs[i]; + /* make sure we only handle each irq once */ + if (handled_irqs & 1 << irq) + continue; + + handled_irqs |= 1 << irq; + + generic_handle_irq(mpu_irqs[irq].irq); + } + + return false; +} + +/** + * _omap_hwmod_mux_handle_irq - Process wakeup events for a single hwmod + * + * Checks a single hwmod for every wakeup capable pad to see if there is an + * active wakeup event. If this is the case, call the corresponding ISR. */ +static int _omap_hwmod_mux_handle_irq(struct omap_hwmod *oh, void *data) +{ + if (!oh->mux || !oh->mux->enabled) + return 0; + if (omap_hwmod_mux_scan_wakeups(oh->mux, oh->mpu_irqs)) + generic_handle_irq(oh->mpu_irqs[0].irq); + return 0; +} -/* 34xx I2C */ -MUX_CFG_34XX("K21_34XX_I2C1_SCL", 0x1ba, - OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("J21_34XX_I2C1_SDA", 0x1bc, - OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("AF15_34XX_I2C2_SCL", 0x1be, - OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("AE15_34XX_I2C2_SDA", 0x1c0, - OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("AF14_34XX_I2C3_SCL", 0x1c2, - OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("AG14_34XX_I2C3_SDA", 0x1c4, - OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("AD26_34XX_I2C4_SCL", 0xa00, - OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("AE26_34XX_I2C4_SDA", 0xa02, - OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) - -/* PHY - HSUSB: 12-pin ULPI PHY: Port 1*/ -MUX_CFG_34XX("Y8_3430_USB1HS_PHY_CLK", 0x5da, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT) -MUX_CFG_34XX("Y9_3430_USB1HS_PHY_STP", 0x5d8, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT) -MUX_CFG_34XX("AA14_3430_USB1HS_PHY_DIR", 0x5ec, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AA11_3430_USB1HS_PHY_NXT", 0x5ee, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W13_3430_USB1HS_PHY_D0", 0x5dc, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W12_3430_USB1HS_PHY_D1", 0x5de, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W11_3430_USB1HS_PHY_D2", 0x5e0, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y11_3430_USB1HS_PHY_D3", 0x5ea, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W9_3430_USB1HS_PHY_D4", 0x5e4, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y12_3430_USB1HS_PHY_D5", 0x5e6, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W8_3430_USB1HS_PHY_D6", 0x5e8, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y13_3430_USB1HS_PHY_D7", 0x5e2, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) - -/* PHY - HSUSB: 12-pin ULPI PHY: Port 2*/ -MUX_CFG_34XX("AA8_3430_USB2HS_PHY_CLK", 0x5f0, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT) -MUX_CFG_34XX("AA10_3430_USB2HS_PHY_STP", 0x5f2, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT) -MUX_CFG_34XX("AA9_3430_USB2HS_PHY_DIR", 0x5f4, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB11_3430_USB2HS_PHY_NXT", 0x5f6, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB10_3430_USB2HS_PHY_D0", 0x5f8, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB9_3430_USB2HS_PHY_D1", 0x5fa, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W3_3430_USB2HS_PHY_D2", 0x1d4, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("T4_3430_USB2HS_PHY_D3", 0x1de, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("T3_3430_USB2HS_PHY_D4", 0x1d8, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("R3_3430_USB2HS_PHY_D5", 0x1da, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("R4_3430_USB2HS_PHY_D6", 0x1dc, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("T2_3430_USB2HS_PHY_D7", 0x1d6, - OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) - -/* TLL - HSUSB: 12-pin TLL Port 1*/ -MUX_CFG_34XX("Y8_3430_USB1HS_TLL_CLK", 0x5da, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y9_3430_USB1HS_TLL_STP", 0x5d8, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("AA14_3430_USB1HS_TLL_DIR", 0x5ec, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AA11_3430_USB1HS_TLL_NXT", 0x5ee, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W13_3430_USB1HS_TLL_D0", 0x5dc, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W12_3430_USB1HS_TLL_D1", 0x5de, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W11_3430_USB1HS_TLL_D2", 0x5e0, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y11_3430_USB1HS_TLL_D3", 0x5ea, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W9_3430_USB1HS_TLL_D4", 0x5e4, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y12_3430_USB1HS_TLL_D5", 0x5e6, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W8_3430_USB1HS_TLL_D6", 0x5e8, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y13_3430_USB1HS_TLL_D7", 0x5e2, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) - -/* TLL - HSUSB: 12-pin TLL Port 2*/ -MUX_CFG_34XX("AA8_3430_USB2HS_TLL_CLK", 0x5f0, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AA10_3430_USB2HS_TLL_STP", 0x5f2, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("AA9_3430_USB2HS_TLL_DIR", 0x5f4, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB11_3430_USB2HS_TLL_NXT", 0x5f6, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB10_3430_USB2HS_TLL_D0", 0x5f8, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB9_3430_USB2HS_TLL_D1", 0x5fa, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W3_3430_USB2HS_TLL_D2", 0x1d4, - OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("T4_3430_USB2HS_TLL_D3", 0x1de, - OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("T3_3430_USB2HS_TLL_D4", 0x1d8, - OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("R3_3430_USB2HS_TLL_D5", 0x1da, - OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("R4_3430_USB2HS_TLL_D6", 0x1dc, - OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("T2_3430_USB2HS_TLL_D7", 0x1d6, - OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN) - -/* TLL - HSUSB: 12-pin TLL Port 3*/ -MUX_CFG_34XX("AA6_3430_USB3HS_TLL_CLK", 0x180, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB3_3430_USB3HS_TLL_STP", 0x166, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLUP) -MUX_CFG_34XX("AA3_3430_USB3HS_TLL_DIR", 0x168, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y3_3430_USB3HS_TLL_NXT", 0x16a, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AA5_3430_USB3HS_TLL_D0", 0x186, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y4_3430_USB3HS_TLL_D1", 0x184, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y5_3430_USB3HS_TLL_D2", 0x188, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W5_3430_USB3HS_TLL_D3", 0x18a, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB12_3430_USB3HS_TLL_D4", 0x16c, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB13_3430_USB3HS_TLL_D5", 0x16e, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AA13_3430_USB3HS_TLL_D6", 0x170, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AA12_3430_USB3HS_TLL_D7", 0x172, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) - -/* PHY FSUSB: FS Serial for Port 1 (multiple PHY modes supported) */ -MUX_CFG_34XX("AF10_3430_USB1FS_PHY_MM1_RXDP", 0x5d8, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AG9_3430_USB1FS_PHY_MM1_RXDM", 0x5ee, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W13_3430_USB1FS_PHY_MM1_RXRCV", 0x5dc, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W12_3430_USB1FS_PHY_MM1_TXSE0", 0x5de, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W11_3430_USB1FS_PHY_MM1_TXDAT", 0x5e0, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("Y11_3430_USB1FS_PHY_MM1_TXEN_N", 0x5ea, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_OUTPUT) - -/* PHY FSUSB: FS Serial for Port 2 (multiple PHY modes supported) */ -MUX_CFG_34XX("AF7_3430_USB2FS_PHY_MM2_RXDP", 0x5f2, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AH7_3430_USB2FS_PHY_MM2_RXDM", 0x5f6, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB10_3430_USB2FS_PHY_MM2_RXRCV", 0x5f8, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AB9_3430_USB2FS_PHY_MM2_TXSE0", 0x5fa, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("W3_3430_USB2FS_PHY_MM2_TXDAT", 0x1d4, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("T4_3430_USB2FS_PHY_MM2_TXEN_N", 0x1de, - OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_OUTPUT) - -/* PHY FSUSB: FS Serial for Port 3 (multiple PHY modes supported) */ -MUX_CFG_34XX("AH3_3430_USB3FS_PHY_MM3_RXDP", 0x166, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AE3_3430_USB3FS_PHY_MM3_RXDM", 0x16a, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AD1_3430_USB3FS_PHY_MM3_RXRCV", 0x186, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AE1_3430_USB3FS_PHY_MM3_TXSE0", 0x184, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AD2_3430_USB3FS_PHY_MM3_TXDAT", 0x188, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN) -MUX_CFG_34XX("AC1_3430_USB3FS_PHY_MM3_TXEN_N", 0x18a, - OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_OUTPUT) - - -/* 34XX GPIO - bidirectional, unless the name has an "_OUT" suffix. - * No internal pullup/pulldown without "_UP" or "_DOWN" suffix. +/** + * omap_hwmod_mux_handle_irq - Process pad wakeup irqs. + * + * Calls a function for each registered omap_hwmod to check + * pad wakeup statuses. */ -MUX_CFG_34XX("AH8_34XX_GPIO29", 0x5fa, - OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) -MUX_CFG_34XX("J25_34XX_GPIO170", 0x1c6, - OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) +static irqreturn_t omap_hwmod_mux_handle_irq(int irq, void *unused) +{ + omap_hwmod_for_each(_omap_hwmod_mux_handle_irq, NULL); + return IRQ_HANDLED; +} + +/* Assumes the calling function takes care of locking */ +void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state) +{ + int i; + + /* Runtime idling of dynamic pads */ + if (state == _HWMOD_STATE_IDLE && hmux->enabled) { + for (i = 0; i < hmux->nr_pads_dynamic; i++) { + struct omap_device_pad *pad = hmux->pads_dynamic[i]; + int val = -EINVAL; + + val = pad->idle; + omap_mux_write(pad->partition, val, + pad->mux->reg_offset); + } + + return; + } + + /* Runtime enabling of dynamic pads */ + if ((state == _HWMOD_STATE_ENABLED) && hmux->pads_dynamic + && hmux->enabled) { + for (i = 0; i < hmux->nr_pads_dynamic; i++) { + struct omap_device_pad *pad = hmux->pads_dynamic[i]; + int val = -EINVAL; + + val = pad->enable; + omap_mux_write(pad->partition, val, + pad->mux->reg_offset); + } + + return; + } + + /* Enabling or disabling of all pads */ + for (i = 0; i < hmux->nr_pads; i++) { + struct omap_device_pad *pad = &hmux->pads[i]; + int flags, val = -EINVAL; + + flags = pad->flags; + + switch (state) { + case _HWMOD_STATE_ENABLED: + val = pad->enable; + pr_debug("%s: Enabling %s %x\n", __func__, + pad->name, val); + break; + case _HWMOD_STATE_DISABLED: + /* Use safe mode unless OMAP_DEVICE_PAD_REMUX */ + if (flags & OMAP_DEVICE_PAD_REMUX) + val = pad->off; + else + val = OMAP_MUX_MODE7; + pr_debug("%s: Disabling %s %x\n", __func__, + pad->name, val); + break; + default: + /* Nothing to be done */ + break; + } + + if (val >= 0) { + omap_mux_write(pad->partition, val, + pad->mux->reg_offset); + pad->flags = flags; + } + } + + if (state == _HWMOD_STATE_ENABLED) + hmux->enabled = true; + else + hmux->enabled = false; +} + +#ifdef CONFIG_DEBUG_FS + +#define OMAP_MUX_MAX_NR_FLAGS 10 +#define OMAP_MUX_TEST_FLAG(val, mask) \ + if (((val) & (mask)) == (mask)) { \ + i++; \ + flags[i] = #mask; \ + } + +/* REVISIT: Add checking for non-optimal mux settings */ +static inline void omap_mux_decode(struct seq_file *s, u16 val) +{ + char *flags[OMAP_MUX_MAX_NR_FLAGS]; + char mode[sizeof("OMAP_MUX_MODE") + 1]; + int i = -1; + + sprintf(mode, "OMAP_MUX_MODE%d", val & 0x7); + i++; + flags[i] = mode; + + OMAP_MUX_TEST_FLAG(val, OMAP_PIN_OFF_WAKEUPENABLE); + if (val & OMAP_OFF_EN) { + if (!(val & OMAP_OFFOUT_EN)) { + if (!(val & OMAP_OFF_PULL_UP)) { + OMAP_MUX_TEST_FLAG(val, + OMAP_PIN_OFF_INPUT_PULLDOWN); + } else { + OMAP_MUX_TEST_FLAG(val, + OMAP_PIN_OFF_INPUT_PULLUP); + } + } else { + if (!(val & OMAP_OFFOUT_VAL)) { + OMAP_MUX_TEST_FLAG(val, + OMAP_PIN_OFF_OUTPUT_LOW); + } else { + OMAP_MUX_TEST_FLAG(val, + OMAP_PIN_OFF_OUTPUT_HIGH); + } + } + } + + if (val & OMAP_INPUT_EN) { + if (val & OMAP_PULL_ENA) { + if (!(val & OMAP_PULL_UP)) { + OMAP_MUX_TEST_FLAG(val, + OMAP_PIN_INPUT_PULLDOWN); + } else { + OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT_PULLUP); + } + } else { + OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT); + } + } else { + i++; + flags[i] = "OMAP_PIN_OUTPUT"; + } + + do { + seq_printf(s, "%s", flags[i]); + if (i > 0) + seq_printf(s, " | "); + } while (i-- > 0); +} + +#define OMAP_MUX_DEFNAME_LEN 32 + +static int omap_mux_dbg_board_show(struct seq_file *s, void *unused) +{ + struct omap_mux_partition *partition = s->private; + struct omap_mux_entry *e; + u8 omap_gen = omap_rev() >> 28; + + list_for_each_entry(e, &partition->muxmodes, node) { + struct omap_mux *m = &e->mux; + char m0_def[OMAP_MUX_DEFNAME_LEN]; + char *m0_name = m->muxnames[0]; + u16 val; + int i, mode; + + if (!m0_name) + continue; + + /* REVISIT: Needs to be updated if mode0 names get longer */ + for (i = 0; i < OMAP_MUX_DEFNAME_LEN; i++) { + if (m0_name[i] == '\0') { + m0_def[i] = m0_name[i]; + break; + } + m0_def[i] = toupper(m0_name[i]); + } + val = omap_mux_read(partition, m->reg_offset); + mode = val & OMAP_MUX_MODE7; + if (mode != 0) + seq_printf(s, "/* %s */\n", m->muxnames[mode]); + + /* + * XXX: Might be revisited to support differences across + * same OMAP generation. + */ + seq_printf(s, "OMAP%d_MUX(%s, ", omap_gen, m0_def); + omap_mux_decode(s, val); + seq_printf(s, "),\n"); + } + + return 0; +} + +static int omap_mux_dbg_board_open(struct inode *inode, struct file *file) +{ + return single_open(file, omap_mux_dbg_board_show, inode->i_private); +} + +static const struct file_operations omap_mux_dbg_board_fops = { + .open = omap_mux_dbg_board_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static struct omap_mux_partition *omap_mux_get_partition(struct omap_mux *mux) +{ + struct omap_mux_partition *partition; + + list_for_each_entry(partition, &mux_partitions, node) { + struct list_head *muxmodes = &partition->muxmodes; + struct omap_mux_entry *e; + + list_for_each_entry(e, muxmodes, node) { + struct omap_mux *m = &e->mux; + + if (m == mux) + return partition; + } + } + + return NULL; +} + +static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused) +{ + struct omap_mux *m = s->private; + struct omap_mux_partition *partition; + const char *none = "NA"; + u16 val; + int mode; + + partition = omap_mux_get_partition(m); + if (!partition) + return 0; + + val = omap_mux_read(partition, m->reg_offset); + mode = val & OMAP_MUX_MODE7; + + seq_printf(s, "name: %s.%s (0x%08x/0x%03x = 0x%04x), b %s, t %s\n", + m->muxnames[0], m->muxnames[mode], + partition->phys + m->reg_offset, m->reg_offset, val, + m->balls[0] ? m->balls[0] : none, + m->balls[1] ? m->balls[1] : none); + seq_printf(s, "mode: "); + omap_mux_decode(s, val); + seq_printf(s, "\n"); + seq_printf(s, "signals: %s | %s | %s | %s | %s | %s | %s | %s\n", + m->muxnames[0] ? m->muxnames[0] : none, + m->muxnames[1] ? m->muxnames[1] : none, + m->muxnames[2] ? m->muxnames[2] : none, + m->muxnames[3] ? m->muxnames[3] : none, + m->muxnames[4] ? m->muxnames[4] : none, + m->muxnames[5] ? m->muxnames[5] : none, + m->muxnames[6] ? m->muxnames[6] : none, + m->muxnames[7] ? m->muxnames[7] : none); + + return 0; +} + +#define OMAP_MUX_MAX_ARG_CHAR 7 + +static ssize_t omap_mux_dbg_signal_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + char buf[OMAP_MUX_MAX_ARG_CHAR]; + struct seq_file *seqf; + struct omap_mux *m; + unsigned long val; + int buf_size, ret; + struct omap_mux_partition *partition; + + if (count > OMAP_MUX_MAX_ARG_CHAR) + return -EINVAL; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + + ret = strict_strtoul(buf, 0x10, &val); + if (ret < 0) + return ret; + + if (val > 0xffff) + return -EINVAL; + + seqf = file->private_data; + m = seqf->private; + + partition = omap_mux_get_partition(m); + if (!partition) + return -ENODEV; + + omap_mux_write(partition, (u16)val, m->reg_offset); + *ppos += count; + + return count; +} + +static int omap_mux_dbg_signal_open(struct inode *inode, struct file *file) +{ + return single_open(file, omap_mux_dbg_signal_show, inode->i_private); +} + +static const struct file_operations omap_mux_dbg_signal_fops = { + .open = omap_mux_dbg_signal_open, + .read = seq_read, + .write = omap_mux_dbg_signal_write, + .llseek = seq_lseek, + .release = single_release, }; -#define OMAP34XX_PINS_SZ ARRAY_SIZE(omap34xx_pins) +static struct dentry *mux_dbg_dir; + +static void __init omap_mux_dbg_create_entry( + struct omap_mux_partition *partition, + struct dentry *mux_dbg_dir) +{ + struct omap_mux_entry *e; + + list_for_each_entry(e, &partition->muxmodes, node) { + struct omap_mux *m = &e->mux; + + (void)debugfs_create_file(m->muxnames[0], S_IWUSR | S_IRUGO, + mux_dbg_dir, m, + &omap_mux_dbg_signal_fops); + } +} + +static void __init omap_mux_dbg_init(void) +{ + struct omap_mux_partition *partition; + static struct dentry *mux_dbg_board_dir; + + mux_dbg_dir = debugfs_create_dir("omap_mux", NULL); + if (!mux_dbg_dir) + return; + + mux_dbg_board_dir = debugfs_create_dir("board", mux_dbg_dir); + if (!mux_dbg_board_dir) + return; + + list_for_each_entry(partition, &mux_partitions, node) { + omap_mux_dbg_create_entry(partition, mux_dbg_dir); + (void)debugfs_create_file(partition->name, S_IRUGO, + mux_dbg_board_dir, partition, + &omap_mux_dbg_board_fops); + } +} #else -#define omap34xx_pins NULL -#define OMAP34XX_PINS_SZ 0 -#endif /* CONFIG_ARCH_OMAP34XX */ +static inline void omap_mux_dbg_init(void) +{ +} +#endif /* CONFIG_DEBUG_FS */ -#if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS) -static void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u16 reg) +static void __init omap_mux_free_names(struct omap_mux *m) { - u16 orig; - u8 warn = 0, debug = 0; + int i; - if (cpu_is_omap24xx()) - orig = omap_ctrl_readb(cfg->mux_reg); - else - orig = omap_ctrl_readw(cfg->mux_reg); + for (i = 0; i < OMAP_MUX_NR_MODES; i++) + kfree(m->muxnames[i]); -#ifdef CONFIG_OMAP_MUX_DEBUG - debug = cfg->debug; +#ifdef CONFIG_DEBUG_FS + for (i = 0; i < OMAP_MUX_NR_SIDES; i++) + kfree(m->balls[i]); #endif - warn = (orig != reg); - if (debug || warn) - printk(KERN_WARNING - "MUX: setup %s (0x%p): 0x%04x -> 0x%04x\n", - cfg->name, omap_ctrl_base_get() + cfg->mux_reg, - orig, reg); + } -#else -#define omap2_cfg_debug(x, y) do {} while (0) + +/* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */ +int __init omap_mux_late_init(void) +{ + struct omap_mux_partition *partition; + int ret; + + list_for_each_entry(partition, &mux_partitions, node) { + struct omap_mux_entry *e, *tmp; + list_for_each_entry_safe(e, tmp, &partition->muxmodes, node) { + struct omap_mux *m = &e->mux; + u16 mode = omap_mux_read(partition, m->reg_offset); + + if (OMAP_MODE_GPIO(partition, mode)) + continue; + +#ifndef CONFIG_DEBUG_FS + mutex_lock(&muxmode_mutex); + list_del(&e->node); + mutex_unlock(&muxmode_mutex); + omap_mux_free_names(m); + kfree(m); #endif + } + } + + omap_mux_dbg_init(); + + /* see pinctrl-single-omap for the wake-up interrupt handling */ + if (of_have_populated_dt()) + return 0; + + ret = request_irq(omap_prcm_event_to_irq("io"), + omap_hwmod_mux_handle_irq, IRQF_SHARED | IRQF_NO_SUSPEND, + "hwmod_io", omap_mux_late_init); + + if (ret) + pr_warning("mux: Failed to setup hwmod io irq %d\n", ret); + + return 0; +} + +static void __init omap_mux_package_fixup(struct omap_mux *p, + struct omap_mux *superset) +{ + while (p->reg_offset != OMAP_MUX_TERMINATOR) { + struct omap_mux *s = superset; + int found = 0; + + while (s->reg_offset != OMAP_MUX_TERMINATOR) { + if (s->reg_offset == p->reg_offset) { + *s = *p; + found++; + break; + } + s++; + } + if (!found) + pr_err("%s: Unknown entry offset 0x%x\n", __func__, + p->reg_offset); + p++; + } +} + +#ifdef CONFIG_DEBUG_FS + +static void __init omap_mux_package_init_balls(struct omap_ball *b, + struct omap_mux *superset) +{ + while (b->reg_offset != OMAP_MUX_TERMINATOR) { + struct omap_mux *s = superset; + int found = 0; + + while (s->reg_offset != OMAP_MUX_TERMINATOR) { + if (s->reg_offset == b->reg_offset) { + s->balls[0] = b->balls[0]; + s->balls[1] = b->balls[1]; + found++; + break; + } + s++; + } + if (!found) + pr_err("%s: Unknown ball offset 0x%x\n", __func__, + b->reg_offset); + b++; + } +} + +#else /* CONFIG_DEBUG_FS */ + +static inline void omap_mux_package_init_balls(struct omap_ball *b, + struct omap_mux *superset) +{ +} + +#endif /* CONFIG_DEBUG_FS */ + +static int __init omap_mux_setup(char *options) +{ + if (!options) + return 0; + + omap_mux_options = options; + + return 1; +} +__setup("omap_mux=", omap_mux_setup); -#ifdef CONFIG_ARCH_OMAP24XX -static int __init_or_module omap24xx_cfg_reg(const struct pin_config *cfg) +/* + * Note that the omap_mux=some.signal1=0x1234,some.signal2=0x1234 + * cmdline options only override the bootloader values. + * During development, please enable CONFIG_DEBUG_FS, and use the + * signal specific entries under debugfs. + */ +static void __init omap_mux_set_cmdline_signals(void) { - static DEFINE_SPINLOCK(mux_spin_lock); - unsigned long flags; - u8 reg = 0; + char *options, *next_opt, *token; + + if (!omap_mux_options) + return; + + options = kstrdup(omap_mux_options, GFP_KERNEL); + if (!options) + return; + + next_opt = options; - spin_lock_irqsave(&mux_spin_lock, flags); - reg |= cfg->mask & 0x7; - if (cfg->pull_val) - reg |= OMAP2_PULL_ENA; - if (cfg->pu_pd_val) - reg |= OMAP2_PULL_UP; - omap2_cfg_debug(cfg, reg); - omap_ctrl_writeb(reg, cfg->mux_reg); - spin_unlock_irqrestore(&mux_spin_lock, flags); + while ((token = strsep(&next_opt, ",")) != NULL) { + char *keyval, *name; + unsigned long val; + + keyval = token; + name = strsep(&keyval, "="); + if (name) { + int res; + + res = strict_strtoul(keyval, 0x10, &val); + if (res < 0) + continue; + + omap_mux_init_signal(name, (u16)val); + } + } + + kfree(options); +} + +static int __init omap_mux_copy_names(struct omap_mux *src, + struct omap_mux *dst) +{ + int i; + + for (i = 0; i < OMAP_MUX_NR_MODES; i++) { + if (src->muxnames[i]) { + dst->muxnames[i] = kstrdup(src->muxnames[i], + GFP_KERNEL); + if (!dst->muxnames[i]) + goto free; + } + } + +#ifdef CONFIG_DEBUG_FS + for (i = 0; i < OMAP_MUX_NR_SIDES; i++) { + if (src->balls[i]) { + dst->balls[i] = kstrdup(src->balls[i], GFP_KERNEL); + if (!dst->balls[i]) + goto free; + } + } +#endif return 0; + +free: + omap_mux_free_names(dst); + return -ENOMEM; + } -#else -#define omap24xx_cfg_reg NULL + +#endif /* CONFIG_OMAP_MUX */ + +static struct omap_mux *omap_mux_get_by_gpio( + struct omap_mux_partition *partition, + int gpio) +{ + struct omap_mux_entry *e; + struct omap_mux *ret = NULL; + + list_for_each_entry(e, &partition->muxmodes, node) { + struct omap_mux *m = &e->mux; + if (m->gpio == gpio) { + ret = m; + break; + } + } + + return ret; +} + +/* Needed for dynamic muxing of GPIO pins for off-idle */ +u16 omap_mux_get_gpio(int gpio) +{ + struct omap_mux_partition *partition; + struct omap_mux *m = NULL; + + list_for_each_entry(partition, &mux_partitions, node) { + m = omap_mux_get_by_gpio(partition, gpio); + if (m) + return omap_mux_read(partition, m->reg_offset); + } + + if (!m || m->reg_offset == OMAP_MUX_TERMINATOR) + pr_err("%s: Could not get gpio%i\n", __func__, gpio); + + return OMAP_MUX_TERMINATOR; +} + +/* Needed for dynamic muxing of GPIO pins for off-idle */ +void omap_mux_set_gpio(u16 val, int gpio) +{ + struct omap_mux_partition *partition; + struct omap_mux *m = NULL; + + list_for_each_entry(partition, &mux_partitions, node) { + m = omap_mux_get_by_gpio(partition, gpio); + if (m) { + omap_mux_write(partition, val, m->reg_offset); + return; + } + } + + if (!m || m->reg_offset == OMAP_MUX_TERMINATOR) + pr_err("%s: Could not set gpio%i\n", __func__, gpio); +} + +static struct omap_mux * __init omap_mux_list_add( + struct omap_mux_partition *partition, + struct omap_mux *src) +{ + struct omap_mux_entry *entry; + struct omap_mux *m; + + entry = kzalloc(sizeof(struct omap_mux_entry), GFP_KERNEL); + if (!entry) + return NULL; + + m = &entry->mux; + entry->mux = *src; + +#ifdef CONFIG_OMAP_MUX + if (omap_mux_copy_names(src, m)) { + kfree(entry); + return NULL; + } #endif -#ifdef CONFIG_ARCH_OMAP34XX -static int __init_or_module omap34xx_cfg_reg(const struct pin_config *cfg) + mutex_lock(&muxmode_mutex); + list_add_tail(&entry->node, &partition->muxmodes); + mutex_unlock(&muxmode_mutex); + + return m; +} + +/* + * Note if CONFIG_OMAP_MUX is not selected, we will only initialize + * the GPIO to mux offset mapping that is needed for dynamic muxing + * of GPIO pins for off-idle. + */ +static void __init omap_mux_init_list(struct omap_mux_partition *partition, + struct omap_mux *superset) { - static DEFINE_SPINLOCK(mux_spin_lock); - unsigned long flags; - u16 reg = 0; + while (superset->reg_offset != OMAP_MUX_TERMINATOR) { + struct omap_mux *entry; - spin_lock_irqsave(&mux_spin_lock, flags); - reg |= cfg->mux_val; - omap2_cfg_debug(cfg, reg); - omap_ctrl_writew(reg, cfg->mux_reg); - spin_unlock_irqrestore(&mux_spin_lock, flags); +#ifdef CONFIG_OMAP_MUX + if (!superset->muxnames || !superset->muxnames[0]) { + superset++; + continue; + } +#else + /* Skip pins that are not muxed as GPIO by bootloader */ + if (!OMAP_MODE_GPIO(partition, omap_mux_read(partition, + superset->reg_offset))) { + superset++; + continue; + } +#endif - return 0; + entry = omap_mux_list_add(partition, superset); + if (!entry) { + pr_err("%s: Could not add entry\n", __func__); + return; + } + superset++; + } } + +#ifdef CONFIG_OMAP_MUX + +static void omap_mux_init_package(struct omap_mux *superset, + struct omap_mux *package_subset, + struct omap_ball *package_balls) +{ + if (package_subset) + omap_mux_package_fixup(package_subset, superset); + if (package_balls) + omap_mux_package_init_balls(package_balls, superset); +} + +static void __init omap_mux_init_signals(struct omap_mux_partition *partition, + struct omap_board_mux *board_mux) +{ + omap_mux_set_cmdline_signals(); + omap_mux_write_array(partition, board_mux); +} + #else -#define omap34xx_cfg_reg NULL + +static void omap_mux_init_package(struct omap_mux *superset, + struct omap_mux *package_subset, + struct omap_ball *package_balls) +{ +} + +static void __init omap_mux_init_signals(struct omap_mux_partition *partition, + struct omap_board_mux *board_mux) +{ +} + #endif -int __init omap2_mux_init(void) +static u32 mux_partitions_cnt; + +int __init omap_mux_init(const char *name, u32 flags, + u32 mux_pbase, u32 mux_size, + struct omap_mux *superset, + struct omap_mux *package_subset, + struct omap_board_mux *board_mux, + struct omap_ball *package_balls) { - if (cpu_is_omap24xx()) { - arch_mux_cfg.pins = omap24xx_pins; - arch_mux_cfg.size = OMAP24XX_PINS_SZ; - arch_mux_cfg.cfg_reg = omap24xx_cfg_reg; - } else if (cpu_is_omap34xx()) { - arch_mux_cfg.pins = omap34xx_pins; - arch_mux_cfg.size = OMAP34XX_PINS_SZ; - arch_mux_cfg.cfg_reg = omap34xx_cfg_reg; + struct omap_mux_partition *partition; + + partition = kzalloc(sizeof(struct omap_mux_partition), GFP_KERNEL); + if (!partition) + return -ENOMEM; + + partition->name = name; + partition->flags = flags; + partition->gpio = flags & OMAP_MUX_MODE7; + partition->size = mux_size; + partition->phys = mux_pbase; + partition->base = ioremap(mux_pbase, mux_size); + if (!partition->base) { + pr_err("%s: Could not ioremap mux partition at 0x%08x\n", + __func__, partition->phys); + kfree(partition); + return -ENODEV; } - return omap_mux_register(&arch_mux_cfg); + INIT_LIST_HEAD(&partition->muxmodes); + + list_add_tail(&partition->node, &mux_partitions); + mux_partitions_cnt++; + pr_info("%s: Add partition: #%d: %s, flags: %x\n", __func__, + mux_partitions_cnt, partition->name, partition->flags); + + omap_mux_init_package(superset, package_subset, package_balls); + omap_mux_init_list(partition, superset); + omap_mux_init_signals(partition, board_mux); + + return 0; } -#endif diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h new file mode 100644 index 00000000000..d121fb6df4e --- /dev/null +++ b/arch/arm/mach-omap2/mux.h @@ -0,0 +1,352 @@ +/* + * Copyright (C) 2009 Nokia + * Copyright (C) 2009-2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "mux34xx.h" + +#define OMAP_MUX_TERMINATOR 0xffff + +/* 34xx mux mode options for each pin. See TRM for options */ +#define OMAP_MUX_MODE0 0 +#define OMAP_MUX_MODE1 1 +#define OMAP_MUX_MODE2 2 +#define OMAP_MUX_MODE3 3 +#define OMAP_MUX_MODE4 4 +#define OMAP_MUX_MODE5 5 +#define OMAP_MUX_MODE6 6 +#define OMAP_MUX_MODE7 7 + +/* 24xx/34xx mux bit defines */ +#define OMAP_PULL_ENA (1 << 3) +#define OMAP_PULL_UP (1 << 4) +#define OMAP_ALTELECTRICALSEL (1 << 5) + +/* omap3/4/5 specific mux bit defines */ +#define OMAP_INPUT_EN (1 << 8) +#define OMAP_OFF_EN (1 << 9) +#define OMAP_OFFOUT_EN (1 << 10) +#define OMAP_OFFOUT_VAL (1 << 11) +#define OMAP_OFF_PULL_EN (1 << 12) +#define OMAP_OFF_PULL_UP (1 << 13) +#define OMAP_WAKEUP_EN (1 << 14) +#define OMAP_WAKEUP_EVENT (1 << 15) + +/* Active pin states */ +#define OMAP_PIN_OUTPUT 0 +#define OMAP_PIN_INPUT OMAP_INPUT_EN +#define OMAP_PIN_INPUT_PULLUP (OMAP_PULL_ENA | OMAP_INPUT_EN \ + | OMAP_PULL_UP) +#define OMAP_PIN_INPUT_PULLDOWN (OMAP_PULL_ENA | OMAP_INPUT_EN) + +/* Off mode states */ +#define OMAP_PIN_OFF_NONE 0 +#define OMAP_PIN_OFF_OUTPUT_HIGH (OMAP_OFF_EN | OMAP_OFFOUT_EN \ + | OMAP_OFFOUT_VAL) +#define OMAP_PIN_OFF_OUTPUT_LOW (OMAP_OFF_EN | OMAP_OFFOUT_EN) +#define OMAP_PIN_OFF_INPUT_PULLUP (OMAP_OFF_EN | OMAP_OFF_PULL_EN \ + | OMAP_OFF_PULL_UP) +#define OMAP_PIN_OFF_INPUT_PULLDOWN (OMAP_OFF_EN | OMAP_OFF_PULL_EN) +#define OMAP_PIN_OFF_WAKEUPENABLE OMAP_WAKEUP_EN + +#define OMAP_MODE_GPIO(partition, x) (((x) & OMAP_MUX_MODE7) == \ + partition->gpio) +#define OMAP_MODE_UART(x) (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE0) + +/* Flags for omapX_mux_init */ +#define OMAP_PACKAGE_MASK 0xffff +#define OMAP_PACKAGE_CBP 6 /* 515-pin 0.40 0.50 */ +#define OMAP_PACKAGE_CUS 5 /* 423-pin 0.65 */ +#define OMAP_PACKAGE_CBB 4 /* 515-pin 0.40 0.50 */ +#define OMAP_PACKAGE_CBC 3 /* 515-pin 0.50 0.65 */ + +#define OMAP_MUX_NR_MODES 8 /* Available modes */ +#define OMAP_MUX_NR_SIDES 2 /* Bottom & top */ + +/* + * omap_mux_init flags definition: + * + * OMAP_GPIO_MUX_MODE, bits 0-2: gpio muxing mode, same like pad control + * register which includes values from 0-7. + * OMAP_MUX_REG_8BIT: Ensure that access to padconf is done in 8 bits. + * The default value is 16 bits. + */ +#define OMAP_MUX_GPIO_IN_MODE0 OMAP_MUX_MODE0 +#define OMAP_MUX_GPIO_IN_MODE1 OMAP_MUX_MODE1 +#define OMAP_MUX_GPIO_IN_MODE2 OMAP_MUX_MODE2 +#define OMAP_MUX_GPIO_IN_MODE3 OMAP_MUX_MODE3 +#define OMAP_MUX_GPIO_IN_MODE4 OMAP_MUX_MODE4 +#define OMAP_MUX_GPIO_IN_MODE5 OMAP_MUX_MODE5 +#define OMAP_MUX_GPIO_IN_MODE6 OMAP_MUX_MODE6 +#define OMAP_MUX_GPIO_IN_MODE7 OMAP_MUX_MODE7 +#define OMAP_MUX_REG_8BIT (1 << 3) + +/** + * struct omap_board_data - board specific device data + * @id: instance id + * @flags: additional flags for platform init code + * @pads: array of device specific pads + * @pads_cnt: ARRAY_SIZE() of pads + */ +struct omap_board_data { + int id; + u32 flags; + struct omap_device_pad *pads; + int pads_cnt; +}; + +/** + * struct mux_partition - contain partition related information + * @name: name of the current partition + * @flags: flags specific to this partition + * @gpio: gpio mux mode + * @phys: physical address + * @size: partition size + * @base: virtual address after ioremap + * @muxmodes: list of nodes that belong to a partition + * @node: list node for the partitions linked list + */ +struct omap_mux_partition { + const char *name; + u32 flags; + u32 gpio; + u32 phys; + u32 size; + void __iomem *base; + struct list_head muxmodes; + struct list_head node; +}; + +/** + * struct omap_mux - data for omap mux register offset and it's value + * @reg_offset: mux register offset from the mux base + * @gpio: GPIO number + * @muxnames: available signal modes for a ball + * @balls: available balls on the package + */ +struct omap_mux { + u16 reg_offset; + u16 gpio; +#ifdef CONFIG_OMAP_MUX + char *muxnames[OMAP_MUX_NR_MODES]; +#ifdef CONFIG_DEBUG_FS + char *balls[OMAP_MUX_NR_SIDES]; +#endif +#endif +}; + +/** + * struct omap_ball - data for balls on omap package + * @reg_offset: mux register offset from the mux base + * @balls: available balls on the package + */ +struct omap_ball { + u16 reg_offset; + char *balls[OMAP_MUX_NR_SIDES]; +}; + +/** + * struct omap_board_mux - data for initializing mux registers + * @reg_offset: mux register offset from the mux base + * @mux_value: desired mux value to set + */ +struct omap_board_mux { + u16 reg_offset; + u16 value; +}; + +#define OMAP_DEVICE_PAD_REMUX BIT(1) /* Dynamically remux a pad, + needs enable, idle and off + values */ +#define OMAP_DEVICE_PAD_WAKEUP BIT(0) /* Pad is wake-up capable */ + +/** + * struct omap_device_pad - device specific pad configuration + * @name: signal name + * @flags: pad specific runtime flags + * @enable: runtime value for a pad + * @idle: idle value for a pad + * @off: off value for a pad, defaults to safe mode + * @partition: mux partition + * @mux: mux register + */ +struct omap_device_pad { + char *name; + u8 flags; + u16 enable; + u16 idle; + u16 off; + struct omap_mux_partition *partition; + struct omap_mux *mux; +}; + +struct omap_hwmod_mux_info; + +#define OMAP_MUX_STATIC(signal, mode) \ +{ \ + .name = (signal), \ + .enable = (mode), \ +} + +#if defined(CONFIG_OMAP_MUX) + +/** + * omap_mux_init_gpio - initialize a signal based on the GPIO number + * @gpio: GPIO number + * @val: Options for the mux register value + */ +int omap_mux_init_gpio(int gpio, int val); + +/** + * omap_mux_init_signal - initialize a signal based on the signal name + * @muxname: Mux name in mode0_name.signal_name format + * @val: Options for the mux register value + */ +int omap_mux_init_signal(const char *muxname, int val); + +/** + * omap_hwmod_mux_init - initialize hwmod specific mux data + * @bpads: Board specific device signal names + * @nr_pads: Number of signal names for the device + */ +extern struct omap_hwmod_mux_info * +omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads); + +/** + * omap_hwmod_mux - omap hwmod specific pin muxing + * @hmux: Pads for a hwmod + * @state: Desired _HWMOD_STATE + * + * Called only from omap_hwmod.c, do not use. + */ +void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state); + +int omap_mux_get_by_name(const char *muxname, + struct omap_mux_partition **found_partition, + struct omap_mux **found_mux); +#else + +static inline int omap_mux_get_by_name(const char *muxname, + struct omap_mux_partition **found_partition, + struct omap_mux **found_mux) +{ + return 0; +} + +static inline int omap_mux_init_gpio(int gpio, int val) +{ + return 0; +} +static inline int omap_mux_init_signal(char *muxname, int val) +{ + return 0; +} + +static inline struct omap_hwmod_mux_info * +omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads) +{ + return NULL; +} + +static inline void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state) +{ +} + +static struct omap_board_mux *board_mux __maybe_unused; + +#endif + +/** + * omap_mux_get_gpio() - get mux register value based on GPIO number + * @gpio: GPIO number + * + */ +u16 omap_mux_get_gpio(int gpio); + +/** + * omap_mux_set_gpio() - set mux register value based on GPIO number + * @val: New mux register value + * @gpio: GPIO number + * + */ +void omap_mux_set_gpio(u16 val, int gpio); + +/** + * omap_mux_get() - get a mux partition by name + * @name: Name of the mux partition + * + */ +struct omap_mux_partition *omap_mux_get(const char *name); + +/** + * omap_mux_read() - read mux register + * @partition: Mux partition + * @mux_offset: Offset of the mux register + * + */ +u16 omap_mux_read(struct omap_mux_partition *p, u16 mux_offset); + +/** + * omap_mux_write() - write mux register + * @partition: Mux partition + * @val: New mux register value + * @mux_offset: Offset of the mux register + * + * This should be only needed for dynamic remuxing of non-gpio signals. + */ +void omap_mux_write(struct omap_mux_partition *p, u16 val, u16 mux_offset); + +/** + * omap_mux_write_array() - write an array of mux registers + * @partition: Mux partition + * @board_mux: Array of mux registers terminated by MAP_MUX_TERMINATOR + * + * This should be only needed for dynamic remuxing of non-gpio signals. + */ +void omap_mux_write_array(struct omap_mux_partition *p, + struct omap_board_mux *board_mux); + +/** + * omap2420_mux_init() - initialize mux system with board specific set + * @board_mux: Board specific mux table + * @flags: OMAP package type used for the board + */ +int omap2420_mux_init(struct omap_board_mux *board_mux, int flags); + +/** + * omap2430_mux_init() - initialize mux system with board specific set + * @board_mux: Board specific mux table + * @flags: OMAP package type used for the board + */ +int omap2430_mux_init(struct omap_board_mux *board_mux, int flags); + +/** + * omap3_mux_init() - initialize mux system with board specific set + * @board_mux: Board specific mux table + * @flags: OMAP package type used for the board + */ +int omap3_mux_init(struct omap_board_mux *board_mux, int flags); + +/** + * omap4_mux_init() - initialize mux system with board specific set + * @board_subset: Board specific mux table + * @board_wkup_subset: Board specific mux table for wakeup instance + * @flags: OMAP package type used for the board + */ +int omap4_mux_init(struct omap_board_mux *board_subset, + struct omap_board_mux *board_wkup_subset, int flags); + +/** + * omap_mux_init - private mux init function, do not call + */ +int omap_mux_init(const char *name, u32 flags, + u32 mux_pbase, u32 mux_size, + struct omap_mux *superset, + struct omap_mux *package_subset, + struct omap_board_mux *board_mux, + struct omap_ball *package_balls); + diff --git a/arch/arm/mach-omap2/mux34xx.c b/arch/arm/mach-omap2/mux34xx.c new file mode 100644 index 00000000000..be271f1d585 --- /dev/null +++ b/arch/arm/mach-omap2/mux34xx.c @@ -0,0 +1,2061 @@ +/* + * Copyright (C) 2009 Nokia + * Copyright (C) 2009 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/init.h> + +#include "mux.h" + +#ifdef CONFIG_OMAP_MUX + +#define _OMAP3_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \ +{ \ + .reg_offset = (OMAP3_CONTROL_PADCONF_##M0##_OFFSET), \ + .gpio = (g), \ + .muxnames = { m0, m1, m2, m3, m4, m5, m6, m7 }, \ +} + +#else + +#define _OMAP3_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \ +{ \ + .reg_offset = (OMAP3_CONTROL_PADCONF_##M0##_OFFSET), \ + .gpio = (g), \ +} + +#endif + +#define _OMAP3_BALLENTRY(M0, bb, bt) \ +{ \ + .reg_offset = (OMAP3_CONTROL_PADCONF_##M0##_OFFSET), \ + .balls = { bb, bt }, \ +} + +/* + * Superset of all mux modes for omap3 + */ +static struct omap_mux __initdata omap3_muxmodes[] = { + _OMAP3_MUXENTRY(CAM_D0, 99, + "cam_d0", NULL, NULL, NULL, + "gpio_99", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D1, 100, + "cam_d1", NULL, NULL, NULL, + "gpio_100", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D10, 109, + "cam_d10", NULL, NULL, NULL, + "gpio_109", "hw_dbg8", NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D11, 110, + "cam_d11", NULL, NULL, NULL, + "gpio_110", "hw_dbg9", NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D2, 101, + "cam_d2", NULL, NULL, NULL, + "gpio_101", "hw_dbg4", NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D3, 102, + "cam_d3", NULL, NULL, NULL, + "gpio_102", "hw_dbg5", NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D4, 103, + "cam_d4", NULL, NULL, NULL, + "gpio_103", "hw_dbg6", NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D5, 104, + "cam_d5", NULL, NULL, NULL, + "gpio_104", "hw_dbg7", NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D6, 105, + "cam_d6", NULL, NULL, NULL, + "gpio_105", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D7, 106, + "cam_d7", NULL, NULL, NULL, + "gpio_106", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D8, 107, + "cam_d8", NULL, NULL, NULL, + "gpio_107", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D9, 108, + "cam_d9", NULL, NULL, NULL, + "gpio_108", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_FLD, 98, + "cam_fld", NULL, "cam_global_reset", NULL, + "gpio_98", "hw_dbg3", NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_HS, 94, + "cam_hs", NULL, NULL, NULL, + "gpio_94", "hw_dbg0", NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_PCLK, 97, + "cam_pclk", NULL, NULL, NULL, + "gpio_97", "hw_dbg2", NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_STROBE, 126, + "cam_strobe", NULL, NULL, NULL, + "gpio_126", "hw_dbg11", NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_VS, 95, + "cam_vs", NULL, NULL, NULL, + "gpio_95", "hw_dbg1", NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_WEN, 167, + "cam_wen", NULL, "cam_shutter", NULL, + "gpio_167", "hw_dbg10", NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_XCLKA, 96, + "cam_xclka", NULL, NULL, NULL, + "gpio_96", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_XCLKB, 111, + "cam_xclkb", NULL, NULL, NULL, + "gpio_111", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CSI2_DX0, 112, + "csi2_dx0", NULL, NULL, NULL, + "gpio_112", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CSI2_DX1, 114, + "csi2_dx1", NULL, NULL, NULL, + "gpio_114", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CSI2_DY0, 113, + "csi2_dy0", NULL, NULL, NULL, + "gpio_113", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CSI2_DY1, 115, + "csi2_dy1", NULL, NULL, NULL, + "gpio_115", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_ACBIAS, 69, + "dss_acbias", NULL, NULL, NULL, + "gpio_69", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA0, 70, + "dss_data0", NULL, "uart1_cts", NULL, + "gpio_70", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA1, 71, + "dss_data1", NULL, "uart1_rts", NULL, + "gpio_71", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA10, 80, + "dss_data10", NULL, NULL, NULL, + "gpio_80", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA11, 81, + "dss_data11", NULL, NULL, NULL, + "gpio_81", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA12, 82, + "dss_data12", NULL, NULL, NULL, + "gpio_82", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA13, 83, + "dss_data13", NULL, NULL, NULL, + "gpio_83", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA14, 84, + "dss_data14", NULL, NULL, NULL, + "gpio_84", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA15, 85, + "dss_data15", NULL, NULL, NULL, + "gpio_85", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA16, 86, + "dss_data16", NULL, NULL, NULL, + "gpio_86", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA17, 87, + "dss_data17", NULL, NULL, NULL, + "gpio_87", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA18, 88, + "dss_data18", NULL, "mcspi3_clk", "dss_data0", + "gpio_88", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA19, 89, + "dss_data19", NULL, "mcspi3_simo", "dss_data1", + "gpio_89", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA20, 90, + "dss_data20", NULL, "mcspi3_somi", "dss_data2", + "gpio_90", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA21, 91, + "dss_data21", NULL, "mcspi3_cs0", "dss_data3", + "gpio_91", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA22, 92, + "dss_data22", NULL, "mcspi3_cs1", "dss_data4", + "gpio_92", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA23, 93, + "dss_data23", NULL, NULL, "dss_data5", + "gpio_93", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA2, 72, + "dss_data2", NULL, NULL, NULL, + "gpio_72", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA3, 73, + "dss_data3", NULL, NULL, NULL, + "gpio_73", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA4, 74, + "dss_data4", NULL, "uart3_rx_irrx", NULL, + "gpio_74", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA5, 75, + "dss_data5", NULL, "uart3_tx_irtx", NULL, + "gpio_75", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA6, 76, + "dss_data6", NULL, "uart1_tx", NULL, + "gpio_76", "hw_dbg14", NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA7, 77, + "dss_data7", NULL, "uart1_rx", NULL, + "gpio_77", "hw_dbg15", NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA8, 78, + "dss_data8", NULL, NULL, NULL, + "gpio_78", "hw_dbg16", NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA9, 79, + "dss_data9", NULL, NULL, NULL, + "gpio_79", "hw_dbg17", NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_HSYNC, 67, + "dss_hsync", NULL, NULL, NULL, + "gpio_67", "hw_dbg13", NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_PCLK, 66, + "dss_pclk", NULL, NULL, NULL, + "gpio_66", "hw_dbg12", NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_VSYNC, 68, + "dss_vsync", NULL, NULL, NULL, + "gpio_68", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(ETK_CLK, 12, + "etk_clk", "mcbsp5_clkx", "sdmmc3_clk", "hsusb1_stp", + "gpio_12", "mm1_rxdp", "hsusb1_tll_stp", "hw_dbg0"), + _OMAP3_MUXENTRY(ETK_CTL, 13, + "etk_ctl", NULL, "sdmmc3_cmd", "hsusb1_clk", + "gpio_13", NULL, "hsusb1_tll_clk", "hw_dbg1"), + _OMAP3_MUXENTRY(ETK_D0, 14, + "etk_d0", "mcspi3_simo", "sdmmc3_dat4", "hsusb1_data0", + "gpio_14", "mm1_rxrcv", "hsusb1_tll_data0", "hw_dbg2"), + _OMAP3_MUXENTRY(ETK_D1, 15, + "etk_d1", "mcspi3_somi", NULL, "hsusb1_data1", + "gpio_15", "mm1_txse0", "hsusb1_tll_data1", "hw_dbg3"), + _OMAP3_MUXENTRY(ETK_D10, 24, + "etk_d10", NULL, "uart1_rx", "hsusb2_clk", + "gpio_24", NULL, "hsusb2_tll_clk", "hw_dbg12"), + _OMAP3_MUXENTRY(ETK_D11, 25, + "etk_d11", NULL, NULL, "hsusb2_stp", + "gpio_25", "mm2_rxdp", "hsusb2_tll_stp", "hw_dbg13"), + _OMAP3_MUXENTRY(ETK_D12, 26, + "etk_d12", NULL, NULL, "hsusb2_dir", + "gpio_26", NULL, "hsusb2_tll_dir", "hw_dbg14"), + _OMAP3_MUXENTRY(ETK_D13, 27, + "etk_d13", NULL, NULL, "hsusb2_nxt", + "gpio_27", "mm2_rxdm", "hsusb2_tll_nxt", "hw_dbg15"), + _OMAP3_MUXENTRY(ETK_D14, 28, + "etk_d14", NULL, NULL, "hsusb2_data0", + "gpio_28", "mm2_rxrcv", "hsusb2_tll_data0", "hw_dbg16"), + _OMAP3_MUXENTRY(ETK_D15, 29, + "etk_d15", NULL, NULL, "hsusb2_data1", + "gpio_29", "mm2_txse0", "hsusb2_tll_data1", "hw_dbg17"), + _OMAP3_MUXENTRY(ETK_D2, 16, + "etk_d2", "mcspi3_cs0", NULL, "hsusb1_data2", + "gpio_16", "mm1_txdat", "hsusb1_tll_data2", "hw_dbg4"), + _OMAP3_MUXENTRY(ETK_D3, 17, + "etk_d3", "mcspi3_clk", "sdmmc3_dat3", "hsusb1_data7", + "gpio_17", NULL, "hsusb1_tll_data7", "hw_dbg5"), + _OMAP3_MUXENTRY(ETK_D4, 18, + "etk_d4", "mcbsp5_dr", "sdmmc3_dat0", "hsusb1_data4", + "gpio_18", NULL, "hsusb1_tll_data4", "hw_dbg6"), + _OMAP3_MUXENTRY(ETK_D5, 19, + "etk_d5", "mcbsp5_fsx", "sdmmc3_dat1", "hsusb1_data5", + "gpio_19", NULL, "hsusb1_tll_data5", "hw_dbg7"), + _OMAP3_MUXENTRY(ETK_D6, 20, + "etk_d6", "mcbsp5_dx", "sdmmc3_dat2", "hsusb1_data6", + "gpio_20", NULL, "hsusb1_tll_data6", "hw_dbg8"), + _OMAP3_MUXENTRY(ETK_D7, 21, + "etk_d7", "mcspi3_cs1", "sdmmc3_dat7", "hsusb1_data3", + "gpio_21", "mm1_txen_n", "hsusb1_tll_data3", "hw_dbg9"), + _OMAP3_MUXENTRY(ETK_D8, 22, + "etk_d8", "sys_drm_msecure", "sdmmc3_dat6", "hsusb1_dir", + "gpio_22", NULL, "hsusb1_tll_dir", "hw_dbg10"), + _OMAP3_MUXENTRY(ETK_D9, 23, + "etk_d9", "sys_secure_indicator", "sdmmc3_dat5", "hsusb1_nxt", + "gpio_23", "mm1_rxdm", "hsusb1_tll_nxt", "hw_dbg11"), + _OMAP3_MUXENTRY(GPMC_A1, 34, + "gpmc_a1", NULL, NULL, NULL, + "gpio_34", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_A10, 43, + "gpmc_a10", "sys_ndmareq3", NULL, NULL, + "gpio_43", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_A2, 35, + "gpmc_a2", NULL, NULL, NULL, + "gpio_35", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_A3, 36, + "gpmc_a3", NULL, NULL, NULL, + "gpio_36", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_A4, 37, + "gpmc_a4", NULL, NULL, NULL, + "gpio_37", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_A5, 38, + "gpmc_a5", NULL, NULL, NULL, + "gpio_38", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_A6, 39, + "gpmc_a6", NULL, NULL, NULL, + "gpio_39", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_A7, 40, + "gpmc_a7", NULL, NULL, NULL, + "gpio_40", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_A8, 41, + "gpmc_a8", NULL, NULL, NULL, + "gpio_41", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_A9, 42, + "gpmc_a9", "sys_ndmareq2", NULL, NULL, + "gpio_42", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_CLK, 59, + "gpmc_clk", NULL, NULL, NULL, + "gpio_59", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_D10, 46, + "gpmc_d10", NULL, NULL, NULL, + "gpio_46", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_D11, 47, + "gpmc_d11", NULL, NULL, NULL, + "gpio_47", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_D12, 48, + "gpmc_d12", NULL, NULL, NULL, + "gpio_48", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_D13, 49, + "gpmc_d13", NULL, NULL, NULL, + "gpio_49", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_D14, 50, + "gpmc_d14", NULL, NULL, NULL, + "gpio_50", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_D15, 51, + "gpmc_d15", NULL, NULL, NULL, + "gpio_51", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_D8, 44, + "gpmc_d8", NULL, NULL, NULL, + "gpio_44", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_D9, 45, + "gpmc_d9", NULL, NULL, NULL, + "gpio_45", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_NBE0_CLE, 60, + "gpmc_nbe0_cle", NULL, NULL, NULL, + "gpio_60", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_NBE1, 61, + "gpmc_nbe1", NULL, NULL, NULL, + "gpio_61", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_NCS1, 52, + "gpmc_ncs1", NULL, NULL, NULL, + "gpio_52", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_NCS2, 53, + "gpmc_ncs2", NULL, NULL, NULL, + "gpio_53", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_NCS3, 54, + "gpmc_ncs3", "sys_ndmareq0", NULL, NULL, + "gpio_54", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_NCS4, 55, + "gpmc_ncs4", "sys_ndmareq1", "mcbsp4_clkx", "gpt9_pwm_evt", + "gpio_55", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_NCS5, 56, + "gpmc_ncs5", "sys_ndmareq2", "mcbsp4_dr", "gpt10_pwm_evt", + "gpio_56", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_NCS6, 57, + "gpmc_ncs6", "sys_ndmareq3", "mcbsp4_dx", "gpt11_pwm_evt", + "gpio_57", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_NCS7, 58, + "gpmc_ncs7", "gpmc_io_dir", "mcbsp4_fsx", "gpt8_pwm_evt", + "gpio_58", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_NWP, 62, + "gpmc_nwp", NULL, NULL, NULL, + "gpio_62", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_WAIT1, 63, + "gpmc_wait1", NULL, NULL, NULL, + "gpio_63", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_WAIT2, 64, + "gpmc_wait2", NULL, NULL, NULL, + "gpio_64", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_WAIT3, 65, + "gpmc_wait3", "sys_ndmareq1", NULL, NULL, + "gpio_65", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(HDQ_SIO, 170, + "hdq_sio", "sys_altclk", "i2c2_sccbe", "i2c3_sccbe", + "gpio_170", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(HSUSB0_CLK, 120, + "hsusb0_clk", NULL, NULL, NULL, + "gpio_120", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(HSUSB0_DATA0, 125, + "hsusb0_data0", NULL, "uart3_tx_irtx", NULL, + "gpio_125", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(HSUSB0_DATA1, 130, + "hsusb0_data1", NULL, "uart3_rx_irrx", NULL, + "gpio_130", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(HSUSB0_DATA2, 131, + "hsusb0_data2", NULL, "uart3_rts_sd", NULL, + "gpio_131", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(HSUSB0_DATA3, 169, + "hsusb0_data3", NULL, "uart3_cts_rctx", NULL, + "gpio_169", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(HSUSB0_DATA4, 188, + "hsusb0_data4", NULL, NULL, NULL, + "gpio_188", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(HSUSB0_DATA5, 189, + "hsusb0_data5", NULL, NULL, NULL, + "gpio_189", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(HSUSB0_DATA6, 190, + "hsusb0_data6", NULL, NULL, NULL, + "gpio_190", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(HSUSB0_DATA7, 191, + "hsusb0_data7", NULL, NULL, NULL, + "gpio_191", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(HSUSB0_DIR, 122, + "hsusb0_dir", NULL, NULL, NULL, + "gpio_122", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(HSUSB0_NXT, 124, + "hsusb0_nxt", NULL, NULL, NULL, + "gpio_124", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(HSUSB0_STP, 121, + "hsusb0_stp", NULL, NULL, NULL, + "gpio_121", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(I2C2_SCL, 168, + "i2c2_scl", NULL, NULL, NULL, + "gpio_168", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(I2C2_SDA, 183, + "i2c2_sda", NULL, NULL, NULL, + "gpio_183", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(I2C3_SCL, 184, + "i2c3_scl", NULL, NULL, NULL, + "gpio_184", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(I2C3_SDA, 185, + "i2c3_sda", NULL, NULL, NULL, + "gpio_185", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(I2C4_SCL, 0, + "i2c4_scl", "sys_nvmode1", NULL, NULL, + NULL, NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(I2C4_SDA, 0, + "i2c4_sda", "sys_nvmode2", NULL, NULL, + NULL, NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(JTAG_EMU0, 11, + "jtag_emu0", NULL, NULL, NULL, + "gpio_11", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(JTAG_EMU1, 31, + "jtag_emu1", NULL, NULL, NULL, + "gpio_31", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP1_CLKR, 156, + "mcbsp1_clkr", "mcspi4_clk", NULL, NULL, + "gpio_156", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP1_CLKX, 162, + "mcbsp1_clkx", NULL, "mcbsp3_clkx", NULL, + "gpio_162", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP1_DR, 159, + "mcbsp1_dr", "mcspi4_somi", "mcbsp3_dr", NULL, + "gpio_159", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP1_DX, 158, + "mcbsp1_dx", "mcspi4_simo", "mcbsp3_dx", NULL, + "gpio_158", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP1_FSR, 157, + "mcbsp1_fsr", NULL, "cam_global_reset", NULL, + "gpio_157", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP1_FSX, 161, + "mcbsp1_fsx", "mcspi4_cs0", "mcbsp3_fsx", NULL, + "gpio_161", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP2_CLKX, 117, + "mcbsp2_clkx", NULL, NULL, NULL, + "gpio_117", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP2_DR, 118, + "mcbsp2_dr", NULL, NULL, NULL, + "gpio_118", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP2_DX, 119, + "mcbsp2_dx", NULL, NULL, NULL, + "gpio_119", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP2_FSX, 116, + "mcbsp2_fsx", NULL, NULL, NULL, + "gpio_116", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP3_CLKX, 142, + "mcbsp3_clkx", "uart2_tx", NULL, NULL, + "gpio_142", "hsusb3_tll_data6", NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP3_DR, 141, + "mcbsp3_dr", "uart2_rts", NULL, NULL, + "gpio_141", "hsusb3_tll_data5", NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP3_DX, 140, + "mcbsp3_dx", "uart2_cts", NULL, NULL, + "gpio_140", "hsusb3_tll_data4", NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP3_FSX, 143, + "mcbsp3_fsx", "uart2_rx", NULL, NULL, + "gpio_143", "hsusb3_tll_data7", NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP4_CLKX, 152, + "mcbsp4_clkx", NULL, NULL, NULL, + "gpio_152", "hsusb3_tll_data1", "mm3_txse0", "safe_mode"), + _OMAP3_MUXENTRY(MCBSP4_DR, 153, + "mcbsp4_dr", NULL, NULL, NULL, + "gpio_153", "hsusb3_tll_data0", "mm3_rxrcv", "safe_mode"), + _OMAP3_MUXENTRY(MCBSP4_DX, 154, + "mcbsp4_dx", NULL, NULL, NULL, + "gpio_154", "hsusb3_tll_data2", "mm3_txdat", "safe_mode"), + _OMAP3_MUXENTRY(MCBSP4_FSX, 155, + "mcbsp4_fsx", NULL, NULL, NULL, + "gpio_155", "hsusb3_tll_data3", "mm3_txen_n", "safe_mode"), + _OMAP3_MUXENTRY(MCBSP_CLKS, 160, + "mcbsp_clks", NULL, "cam_shutter", NULL, + "gpio_160", "uart1_cts", NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCSPI1_CLK, 171, + "mcspi1_clk", "sdmmc2_dat4", NULL, NULL, + "gpio_171", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCSPI1_CS0, 174, + "mcspi1_cs0", "sdmmc2_dat7", NULL, NULL, + "gpio_174", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCSPI1_CS1, 175, + "mcspi1_cs1", NULL, NULL, "sdmmc3_cmd", + "gpio_175", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCSPI1_CS2, 176, + "mcspi1_cs2", NULL, NULL, "sdmmc3_clk", + "gpio_176", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCSPI1_CS3, 177, + "mcspi1_cs3", NULL, "hsusb2_tll_data2", "hsusb2_data2", + "gpio_177", "mm2_txdat", NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCSPI1_SIMO, 172, + "mcspi1_simo", "sdmmc2_dat5", NULL, NULL, + "gpio_172", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCSPI1_SOMI, 173, + "mcspi1_somi", "sdmmc2_dat6", NULL, NULL, + "gpio_173", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCSPI2_CLK, 178, + "mcspi2_clk", NULL, "hsusb2_tll_data7", "hsusb2_data7", + "gpio_178", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCSPI2_CS0, 181, + "mcspi2_cs0", "gpt11_pwm_evt", + "hsusb2_tll_data6", "hsusb2_data6", + "gpio_181", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCSPI2_CS1, 182, + "mcspi2_cs1", "gpt8_pwm_evt", + "hsusb2_tll_data3", "hsusb2_data3", + "gpio_182", "mm2_txen_n", NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCSPI2_SIMO, 179, + "mcspi2_simo", "gpt9_pwm_evt", + "hsusb2_tll_data4", "hsusb2_data4", + "gpio_179", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCSPI2_SOMI, 180, + "mcspi2_somi", "gpt10_pwm_evt", + "hsusb2_tll_data5", "hsusb2_data5", + "gpio_180", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC1_CLK, 120, + "sdmmc1_clk", NULL, NULL, NULL, + "gpio_120", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC1_CMD, 121, + "sdmmc1_cmd", NULL, NULL, NULL, + "gpio_121", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC1_DAT0, 122, + "sdmmc1_dat0", NULL, NULL, NULL, + "gpio_122", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC1_DAT1, 123, + "sdmmc1_dat1", NULL, NULL, NULL, + "gpio_123", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC1_DAT2, 124, + "sdmmc1_dat2", NULL, NULL, NULL, + "gpio_124", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC1_DAT3, 125, + "sdmmc1_dat3", NULL, NULL, NULL, + "gpio_125", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC1_DAT4, 126, + "sdmmc1_dat4", NULL, "sim_io", NULL, + "gpio_126", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC1_DAT5, 127, + "sdmmc1_dat5", NULL, "sim_clk", NULL, + "gpio_127", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC1_DAT6, 128, + "sdmmc1_dat6", NULL, "sim_pwrctrl", NULL, + "gpio_128", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC1_DAT7, 129, + "sdmmc1_dat7", NULL, "sim_rst", NULL, + "gpio_129", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC2_CLK, 130, + "sdmmc2_clk", "mcspi3_clk", NULL, NULL, + "gpio_130", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC2_CMD, 131, + "sdmmc2_cmd", "mcspi3_simo", NULL, NULL, + "gpio_131", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC2_DAT0, 132, + "sdmmc2_dat0", "mcspi3_somi", NULL, NULL, + "gpio_132", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC2_DAT1, 133, + "sdmmc2_dat1", NULL, NULL, NULL, + "gpio_133", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC2_DAT2, 134, + "sdmmc2_dat2", "mcspi3_cs1", NULL, NULL, + "gpio_134", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC2_DAT3, 135, + "sdmmc2_dat3", "mcspi3_cs0", NULL, NULL, + "gpio_135", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC2_DAT4, 136, + "sdmmc2_dat4", "sdmmc2_dir_dat0", NULL, "sdmmc3_dat0", + "gpio_136", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC2_DAT5, 137, + "sdmmc2_dat5", "sdmmc2_dir_dat1", + "cam_global_reset", "sdmmc3_dat1", + "gpio_137", "hsusb3_tll_stp", "mm3_rxdp", "safe_mode"), + _OMAP3_MUXENTRY(SDMMC2_DAT6, 138, + "sdmmc2_dat6", "sdmmc2_dir_cmd", "cam_shutter", "sdmmc3_dat2", + "gpio_138", "hsusb3_tll_dir", NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC2_DAT7, 139, + "sdmmc2_dat7", "sdmmc2_clkin", NULL, "sdmmc3_dat3", + "gpio_139", "hsusb3_tll_nxt", "mm3_rxdm", "safe_mode"), + _OMAP3_MUXENTRY(SDRC_CKE0, 0, + "sdrc_cke0", NULL, NULL, NULL, + NULL, NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDRC_CKE1, 0, + "sdrc_cke1", NULL, NULL, NULL, + NULL, NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_BOOT0, 2, + "sys_boot0", NULL, NULL, NULL, + "gpio_2", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_BOOT1, 3, + "sys_boot1", NULL, NULL, NULL, + "gpio_3", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_BOOT2, 4, + "sys_boot2", NULL, NULL, NULL, + "gpio_4", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_BOOT3, 5, + "sys_boot3", NULL, NULL, NULL, + "gpio_5", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_BOOT4, 6, + "sys_boot4", "sdmmc2_dir_dat2", NULL, NULL, + "gpio_6", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_BOOT5, 7, + "sys_boot5", "sdmmc2_dir_dat3", NULL, NULL, + "gpio_7", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_BOOT6, 8, + "sys_boot6", NULL, NULL, NULL, + "gpio_8", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_CLKOUT1, 10, + "sys_clkout1", NULL, NULL, NULL, + "gpio_10", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_CLKOUT2, 186, + "sys_clkout2", NULL, NULL, NULL, + "gpio_186", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_CLKREQ, 1, + "sys_clkreq", NULL, NULL, NULL, + "gpio_1", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_NIRQ, 0, + "sys_nirq", NULL, NULL, NULL, + "gpio_0", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_NRESWARM, 30, + "sys_nreswarm", NULL, NULL, NULL, + "gpio_30", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_OFF_MODE, 9, + "sys_off_mode", NULL, NULL, NULL, + "gpio_9", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(UART1_CTS, 150, + "uart1_cts", "ssi1_rdy_tx", NULL, NULL, + "gpio_150", "hsusb3_tll_clk", NULL, "safe_mode"), + _OMAP3_MUXENTRY(UART1_RTS, 149, + "uart1_rts", "ssi1_flag_tx", NULL, NULL, + "gpio_149", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(UART1_RX, 151, + "uart1_rx", "ssi1_wake_tx", "mcbsp1_clkr", "mcspi4_clk", + "gpio_151", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(UART1_TX, 148, + "uart1_tx", "ssi1_dat_tx", NULL, NULL, + "gpio_148", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(UART2_CTS, 144, + "uart2_cts", "mcbsp3_dx", "gpt9_pwm_evt", NULL, + "gpio_144", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(UART2_RTS, 145, + "uart2_rts", "mcbsp3_dr", "gpt10_pwm_evt", NULL, + "gpio_145", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(UART2_RX, 147, + "uart2_rx", "mcbsp3_fsx", "gpt8_pwm_evt", NULL, + "gpio_147", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(UART2_TX, 146, + "uart2_tx", "mcbsp3_clkx", "gpt11_pwm_evt", NULL, + "gpio_146", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(UART3_CTS_RCTX, 163, + "uart3_cts_rctx", NULL, NULL, NULL, + "gpio_163", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(UART3_RTS_SD, 164, + "uart3_rts_sd", NULL, NULL, NULL, + "gpio_164", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(UART3_RX_IRRX, 165, + "uart3_rx_irrx", NULL, NULL, NULL, + "gpio_165", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(UART3_TX_IRTX, 166, + "uart3_tx_irtx", NULL, NULL, NULL, + "gpio_166", NULL, NULL, "safe_mode"), + + /* Only on 3630, see omap36xx_cbp_subset for the signals */ + _OMAP3_MUXENTRY(GPMC_A11, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MBUSFLAG, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MREAD, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MWRITE, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_SBUSFLAG, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_SREAD, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_SWRITE, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(GPMC_A11, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MCAD28, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MCAD29, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MCAD32, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MCAD33, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MCAD34, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MCAD35, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MCAD36, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL), + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; + +/* + * Signals different on CBC package compared to the superset + */ +#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBC) +static struct omap_mux __initdata omap3_cbc_subset[] = { + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#else +#define omap3_cbc_subset NULL +#endif + +/* + * Balls for CBC package + * 515-pin s-PBGA Package, 0.65mm Ball Pitch (Top), 0.50mm Ball Pitch (Bottom) + * + * FIXME: What's up with the outdated TI documentation? See: + * + * http://wiki.davincidsp.com/index.php/Datasheet_Errata_for_OMAP35x_CBC_Package + * http://community.ti.com/forums/t/10982.aspx + */ +#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \ + && defined(CONFIG_OMAP_PACKAGE_CBC) +static struct omap_ball __initdata omap3_cbc_ball[] = { + _OMAP3_BALLENTRY(CAM_D0, "ae16", NULL), + _OMAP3_BALLENTRY(CAM_D1, "ae15", NULL), + _OMAP3_BALLENTRY(CAM_D10, "d25", NULL), + _OMAP3_BALLENTRY(CAM_D11, "e26", NULL), + _OMAP3_BALLENTRY(CAM_D2, "a24", NULL), + _OMAP3_BALLENTRY(CAM_D3, "b24", NULL), + _OMAP3_BALLENTRY(CAM_D4, "d24", NULL), + _OMAP3_BALLENTRY(CAM_D5, "c24", NULL), + _OMAP3_BALLENTRY(CAM_D6, "p25", NULL), + _OMAP3_BALLENTRY(CAM_D7, "p26", NULL), + _OMAP3_BALLENTRY(CAM_D8, "n25", NULL), + _OMAP3_BALLENTRY(CAM_D9, "n26", NULL), + _OMAP3_BALLENTRY(CAM_FLD, "b23", NULL), + _OMAP3_BALLENTRY(CAM_HS, "c23", NULL), + _OMAP3_BALLENTRY(CAM_PCLK, "c26", NULL), + _OMAP3_BALLENTRY(CAM_STROBE, "d26", NULL), + _OMAP3_BALLENTRY(CAM_VS, "d23", NULL), + _OMAP3_BALLENTRY(CAM_WEN, "a23", NULL), + _OMAP3_BALLENTRY(CAM_XCLKA, "c25", NULL), + _OMAP3_BALLENTRY(CAM_XCLKB, "e25", NULL), + _OMAP3_BALLENTRY(CSI2_DX0, "ad17", NULL), + _OMAP3_BALLENTRY(CSI2_DX1, "ae18", NULL), + _OMAP3_BALLENTRY(CSI2_DY0, "ad16", NULL), + _OMAP3_BALLENTRY(CSI2_DY1, "ae17", NULL), + _OMAP3_BALLENTRY(DSS_ACBIAS, "f26", NULL), + _OMAP3_BALLENTRY(DSS_DATA0, "ae21", NULL), + _OMAP3_BALLENTRY(DSS_DATA1, "ae22", NULL), + _OMAP3_BALLENTRY(DSS_DATA10, "ac26", NULL), + _OMAP3_BALLENTRY(DSS_DATA11, "ad26", NULL), + _OMAP3_BALLENTRY(DSS_DATA12, "aa25", NULL), + _OMAP3_BALLENTRY(DSS_DATA13, "y25", NULL), + _OMAP3_BALLENTRY(DSS_DATA14, "aa26", NULL), + _OMAP3_BALLENTRY(DSS_DATA15, "ab26", NULL), + _OMAP3_BALLENTRY(DSS_DATA16, "l25", NULL), + _OMAP3_BALLENTRY(DSS_DATA17, "l26", NULL), + _OMAP3_BALLENTRY(DSS_DATA18, "m24", NULL), + _OMAP3_BALLENTRY(DSS_DATA19, "m26", NULL), + _OMAP3_BALLENTRY(DSS_DATA2, "ae23", NULL), + _OMAP3_BALLENTRY(DSS_DATA20, "f25", NULL), + _OMAP3_BALLENTRY(DSS_DATA21, "n24", NULL), + _OMAP3_BALLENTRY(DSS_DATA22, "ac25", NULL), + _OMAP3_BALLENTRY(DSS_DATA23, "ab25", NULL), + _OMAP3_BALLENTRY(DSS_DATA3, "ae24", NULL), + _OMAP3_BALLENTRY(DSS_DATA4, "ad23", NULL), + _OMAP3_BALLENTRY(DSS_DATA5, "ad24", NULL), + _OMAP3_BALLENTRY(DSS_DATA6, "g26", NULL), + _OMAP3_BALLENTRY(DSS_DATA7, "h25", NULL), + _OMAP3_BALLENTRY(DSS_DATA8, "h26", NULL), + _OMAP3_BALLENTRY(DSS_DATA9, "j26", NULL), + _OMAP3_BALLENTRY(DSS_HSYNC, "k24", NULL), + _OMAP3_BALLENTRY(DSS_PCLK, "g25", NULL), + _OMAP3_BALLENTRY(DSS_VSYNC, "m25", NULL), + _OMAP3_BALLENTRY(ETK_CLK, "ab2", NULL), + _OMAP3_BALLENTRY(ETK_CTL, "ab3", NULL), + _OMAP3_BALLENTRY(ETK_D0, "ac3", NULL), + _OMAP3_BALLENTRY(ETK_D1, "ad4", NULL), + _OMAP3_BALLENTRY(ETK_D10, "ae4", NULL), + _OMAP3_BALLENTRY(ETK_D11, "af6", NULL), + _OMAP3_BALLENTRY(ETK_D12, "ae6", NULL), + _OMAP3_BALLENTRY(ETK_D13, "af7", NULL), + _OMAP3_BALLENTRY(ETK_D14, "af9", NULL), + _OMAP3_BALLENTRY(ETK_D15, "ae9", NULL), + _OMAP3_BALLENTRY(ETK_D2, "ad3", NULL), + _OMAP3_BALLENTRY(ETK_D3, "aa3", NULL), + _OMAP3_BALLENTRY(ETK_D4, "y3", NULL), + _OMAP3_BALLENTRY(ETK_D5, "ab1", NULL), + _OMAP3_BALLENTRY(ETK_D6, "ae3", NULL), + _OMAP3_BALLENTRY(ETK_D7, "ad2", NULL), + _OMAP3_BALLENTRY(ETK_D8, "aa4", NULL), + _OMAP3_BALLENTRY(ETK_D9, "v2", NULL), + _OMAP3_BALLENTRY(GPMC_A1, "j2", NULL), + _OMAP3_BALLENTRY(GPMC_A10, "d2", NULL), + _OMAP3_BALLENTRY(GPMC_A2, "h1", NULL), + _OMAP3_BALLENTRY(GPMC_A3, "h2", NULL), + _OMAP3_BALLENTRY(GPMC_A4, "g2", NULL), + _OMAP3_BALLENTRY(GPMC_A5, "f1", NULL), + _OMAP3_BALLENTRY(GPMC_A6, "f2", NULL), + _OMAP3_BALLENTRY(GPMC_A7, "e1", NULL), + _OMAP3_BALLENTRY(GPMC_A8, "e2", NULL), + _OMAP3_BALLENTRY(GPMC_A9, "d1", NULL), + _OMAP3_BALLENTRY(GPMC_CLK, "n1", "l1"), + _OMAP3_BALLENTRY(GPMC_D10, "t1", "n1"), + _OMAP3_BALLENTRY(GPMC_D11, "u2", "p2"), + _OMAP3_BALLENTRY(GPMC_D12, "u1", "p1"), + _OMAP3_BALLENTRY(GPMC_D13, "p1", "m1"), + _OMAP3_BALLENTRY(GPMC_D14, "l2", "j2"), + _OMAP3_BALLENTRY(GPMC_D15, "m2", "k2"), + _OMAP3_BALLENTRY(GPMC_D8, "v1", "r1"), + _OMAP3_BALLENTRY(GPMC_D9, "y1", "t1"), + _OMAP3_BALLENTRY(GPMC_NBE0_CLE, "k2", NULL), + _OMAP3_BALLENTRY(GPMC_NBE1, "j1", NULL), + _OMAP3_BALLENTRY(GPMC_NCS1, "ad1", "w1"), + _OMAP3_BALLENTRY(GPMC_NCS2, "a3", NULL), + _OMAP3_BALLENTRY(GPMC_NCS3, "b6", NULL), + _OMAP3_BALLENTRY(GPMC_NCS4, "b4", NULL), + _OMAP3_BALLENTRY(GPMC_NCS5, "c4", NULL), + _OMAP3_BALLENTRY(GPMC_NCS6, "b5", NULL), + _OMAP3_BALLENTRY(GPMC_NCS7, "c5", NULL), + _OMAP3_BALLENTRY(GPMC_NWP, "ac6", "y5"), + _OMAP3_BALLENTRY(GPMC_WAIT1, "ac8", "y8"), + _OMAP3_BALLENTRY(GPMC_WAIT2, "b3", NULL), + _OMAP3_BALLENTRY(GPMC_WAIT3, "c6", NULL), + _OMAP3_BALLENTRY(HDQ_SIO, "j23", NULL), + _OMAP3_BALLENTRY(HSUSB0_CLK, "w19", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA0, "v20", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA1, "y20", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA2, "v18", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA3, "w20", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA4, "w17", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA5, "y18", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA6, "y19", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA7, "y17", NULL), + _OMAP3_BALLENTRY(HSUSB0_DIR, "v19", NULL), + _OMAP3_BALLENTRY(HSUSB0_NXT, "w18", NULL), + _OMAP3_BALLENTRY(HSUSB0_STP, "u20", NULL), + _OMAP3_BALLENTRY(I2C2_SCL, "c2", NULL), + _OMAP3_BALLENTRY(I2C2_SDA, "c1", NULL), + _OMAP3_BALLENTRY(I2C3_SCL, "ab4", NULL), + _OMAP3_BALLENTRY(I2C3_SDA, "ac4", NULL), + _OMAP3_BALLENTRY(I2C4_SCL, "ad15", NULL), + _OMAP3_BALLENTRY(I2C4_SDA, "w16", NULL), + _OMAP3_BALLENTRY(JTAG_EMU0, "y15", NULL), + _OMAP3_BALLENTRY(JTAG_EMU1, "y14", NULL), + _OMAP3_BALLENTRY(MCBSP1_CLKR, "u19", NULL), + _OMAP3_BALLENTRY(MCBSP1_CLKX, "t17", NULL), + _OMAP3_BALLENTRY(MCBSP1_DR, "t20", NULL), + _OMAP3_BALLENTRY(MCBSP1_DX, "u17", NULL), + _OMAP3_BALLENTRY(MCBSP1_FSR, "v17", NULL), + _OMAP3_BALLENTRY(MCBSP1_FSX, "p20", NULL), + _OMAP3_BALLENTRY(MCBSP2_CLKX, "r18", NULL), + _OMAP3_BALLENTRY(MCBSP2_DR, "t18", NULL), + _OMAP3_BALLENTRY(MCBSP2_DX, "r19", NULL), + _OMAP3_BALLENTRY(MCBSP2_FSX, "u18", NULL), + _OMAP3_BALLENTRY(MCBSP3_CLKX, "u3", NULL), + _OMAP3_BALLENTRY(MCBSP3_DR, "n3", NULL), + _OMAP3_BALLENTRY(MCBSP3_DX, "p3", NULL), + _OMAP3_BALLENTRY(MCBSP3_FSX, "w3", NULL), + _OMAP3_BALLENTRY(MCBSP4_CLKX, "v3", NULL), + _OMAP3_BALLENTRY(MCBSP4_DR, "u4", NULL), + _OMAP3_BALLENTRY(MCBSP4_DX, "r3", NULL), + _OMAP3_BALLENTRY(MCBSP4_FSX, "t3", NULL), + _OMAP3_BALLENTRY(MCBSP_CLKS, "t19", NULL), + _OMAP3_BALLENTRY(MCSPI1_CLK, "p9", NULL), + _OMAP3_BALLENTRY(MCSPI1_CS0, "r7", NULL), + _OMAP3_BALLENTRY(MCSPI1_CS1, "r8", NULL), + _OMAP3_BALLENTRY(MCSPI1_CS2, "r9", NULL), + _OMAP3_BALLENTRY(MCSPI1_CS3, "t8", NULL), + _OMAP3_BALLENTRY(MCSPI1_SIMO, "p8", NULL), + _OMAP3_BALLENTRY(MCSPI1_SOMI, "p7", NULL), + _OMAP3_BALLENTRY(MCSPI2_CLK, "w7", NULL), + _OMAP3_BALLENTRY(MCSPI2_CS0, "v8", NULL), + _OMAP3_BALLENTRY(MCSPI2_CS1, "v9", NULL), + _OMAP3_BALLENTRY(MCSPI2_SIMO, "w8", NULL), + _OMAP3_BALLENTRY(MCSPI2_SOMI, "u8", NULL), + _OMAP3_BALLENTRY(SDMMC1_CLK, "n19", NULL), + _OMAP3_BALLENTRY(SDMMC1_CMD, "l18", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT0, "m19", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT1, "m18", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT2, "k18", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT3, "n20", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT4, "m20", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT5, "p17", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT6, "p18", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT7, "p19", NULL), + _OMAP3_BALLENTRY(SDMMC2_CLK, "w10", NULL), + _OMAP3_BALLENTRY(SDMMC2_CMD, "r10", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT0, "t10", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT1, "t9", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT2, "u10", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT3, "u9", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT4, "v10", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT5, "m3", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT6, "l3", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT7, "k3", NULL), + _OMAP3_BALLENTRY(SYS_BOOT0, "f3", NULL), + _OMAP3_BALLENTRY(SYS_BOOT1, "d3", NULL), + _OMAP3_BALLENTRY(SYS_BOOT2, "c3", NULL), + _OMAP3_BALLENTRY(SYS_BOOT3, "e3", NULL), + _OMAP3_BALLENTRY(SYS_BOOT4, "e4", NULL), + _OMAP3_BALLENTRY(SYS_BOOT5, "g3", NULL), + _OMAP3_BALLENTRY(SYS_BOOT6, "d4", NULL), + _OMAP3_BALLENTRY(SYS_CLKOUT1, "ae14", NULL), + _OMAP3_BALLENTRY(SYS_CLKOUT2, "w11", NULL), + _OMAP3_BALLENTRY(SYS_CLKREQ, "w15", NULL), + _OMAP3_BALLENTRY(SYS_NIRQ, "v16", NULL), + _OMAP3_BALLENTRY(SYS_NRESWARM, "ad7", "aa5"), + _OMAP3_BALLENTRY(SYS_OFF_MODE, "v12", NULL), + _OMAP3_BALLENTRY(UART1_CTS, "w2", NULL), + _OMAP3_BALLENTRY(UART1_RTS, "r2", NULL), + _OMAP3_BALLENTRY(UART1_RX, "h3", NULL), + _OMAP3_BALLENTRY(UART1_TX, "l4", NULL), + _OMAP3_BALLENTRY(UART2_CTS, "y24", NULL), + _OMAP3_BALLENTRY(UART2_RTS, "aa24", NULL), + _OMAP3_BALLENTRY(UART2_RX, "ad21", NULL), + _OMAP3_BALLENTRY(UART2_TX, "ad22", NULL), + _OMAP3_BALLENTRY(UART3_CTS_RCTX, "f23", NULL), + _OMAP3_BALLENTRY(UART3_RTS_SD, "f24", NULL), + _OMAP3_BALLENTRY(UART3_RX_IRRX, "h24", NULL), + _OMAP3_BALLENTRY(UART3_TX_IRTX, "g24", NULL), + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#else +#define omap3_cbc_ball NULL +#endif + +/* + * Signals different on CUS package compared to superset + */ +#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CUS) +static struct omap_mux __initdata omap3_cus_subset[] = { + _OMAP3_MUXENTRY(CAM_D10, 109, + "cam_d10", NULL, NULL, NULL, + "gpio_109", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D11, 110, + "cam_d11", NULL, NULL, NULL, + "gpio_110", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D2, 101, + "cam_d2", NULL, NULL, NULL, + "gpio_101", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D3, 102, + "cam_d3", NULL, NULL, NULL, + "gpio_102", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D4, 103, + "cam_d4", NULL, NULL, NULL, + "gpio_103", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D5, 104, + "cam_d5", NULL, NULL, NULL, + "gpio_104", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_FLD, 98, + "cam_fld", NULL, "cam_global_reset", NULL, + "gpio_98", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_HS, 94, + "cam_hs", NULL, NULL, NULL, + "gpio_94", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_PCLK, 97, + "cam_pclk", NULL, NULL, NULL, + "gpio_97", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_STROBE, 126, + "cam_strobe", NULL, NULL, NULL, + "gpio_126", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_VS, 95, + "cam_vs", NULL, NULL, NULL, + "gpio_95", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_WEN, 167, + "cam_wen", NULL, "cam_shutter", NULL, + "gpio_167", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA6, 76, + "dss_data6", NULL, "uart1_tx", NULL, + "gpio_76", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA7, 77, + "dss_data7", NULL, "uart1_rx", NULL, + "gpio_77", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA8, 78, + "dss_data8", NULL, NULL, NULL, + "gpio_78", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA9, 79, + "dss_data9", NULL, NULL, NULL, + "gpio_79", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_HSYNC, 67, + "dss_hsync", NULL, NULL, NULL, + "gpio_67", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_PCLK, 66, + "dss_pclk", NULL, NULL, NULL, + "gpio_66", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(ETK_CLK, 12, + "etk_clk", "mcbsp5_clkx", "sdmmc3_clk", "hsusb1_stp", + "gpio_12", "mm1_rxdp", "hsusb1_tll_stp", NULL), + _OMAP3_MUXENTRY(ETK_CTL, 13, + "etk_ctl", NULL, "sdmmc3_cmd", "hsusb1_clk", + "gpio_13", NULL, "hsusb1_tll_clk", NULL), + _OMAP3_MUXENTRY(ETK_D0, 14, + "etk_d0", "mcspi3_simo", "sdmmc3_dat4", "hsusb1_data0", + "gpio_14", "mm1_rxrcv", "hsusb1_tll_data0", NULL), + _OMAP3_MUXENTRY(ETK_D1, 15, + "etk_d1", "mcspi3_somi", NULL, "hsusb1_data1", + "gpio_15", "mm1_txse0", "hsusb1_tll_data1", NULL), + _OMAP3_MUXENTRY(ETK_D10, 24, + "etk_d10", NULL, "uart1_rx", "hsusb2_clk", + "gpio_24", NULL, "hsusb2_tll_clk", NULL), + _OMAP3_MUXENTRY(ETK_D11, 25, + "etk_d11", NULL, NULL, "hsusb2_stp", + "gpio_25", "mm2_rxdp", "hsusb2_tll_stp", NULL), + _OMAP3_MUXENTRY(ETK_D12, 26, + "etk_d12", NULL, NULL, "hsusb2_dir", + "gpio_26", NULL, "hsusb2_tll_dir", NULL), + _OMAP3_MUXENTRY(ETK_D13, 27, + "etk_d13", NULL, NULL, "hsusb2_nxt", + "gpio_27", "mm2_rxdm", "hsusb2_tll_nxt", NULL), + _OMAP3_MUXENTRY(ETK_D14, 28, + "etk_d14", NULL, NULL, "hsusb2_data0", + "gpio_28", "mm2_rxrcv", "hsusb2_tll_data0", NULL), + _OMAP3_MUXENTRY(ETK_D15, 29, + "etk_d15", NULL, NULL, "hsusb2_data1", + "gpio_29", "mm2_txse0", "hsusb2_tll_data1", NULL), + _OMAP3_MUXENTRY(ETK_D2, 16, + "etk_d2", "mcspi3_cs0", NULL, "hsusb1_data2", + "gpio_16", "mm1_txdat", "hsusb1_tll_data2", NULL), + _OMAP3_MUXENTRY(ETK_D3, 17, + "etk_d3", "mcspi3_clk", "sdmmc3_dat3", "hsusb1_data7", + "gpio_17", NULL, "hsusb1_tll_data7", NULL), + _OMAP3_MUXENTRY(ETK_D4, 18, + "etk_d4", "mcbsp5_dr", "sdmmc3_dat0", "hsusb1_data4", + "gpio_18", NULL, "hsusb1_tll_data4", NULL), + _OMAP3_MUXENTRY(ETK_D5, 19, + "etk_d5", "mcbsp5_fsx", "sdmmc3_dat1", "hsusb1_data5", + "gpio_19", NULL, "hsusb1_tll_data5", NULL), + _OMAP3_MUXENTRY(ETK_D6, 20, + "etk_d6", "mcbsp5_dx", "sdmmc3_dat2", "hsusb1_data6", + "gpio_20", NULL, "hsusb1_tll_data6", NULL), + _OMAP3_MUXENTRY(ETK_D7, 21, + "etk_d7", "mcspi3_cs1", "sdmmc3_dat7", "hsusb1_data3", + "gpio_21", "mm1_txen_n", "hsusb1_tll_data3", NULL), + _OMAP3_MUXENTRY(ETK_D8, 22, + "etk_d8", "sys_drm_msecure", "sdmmc3_dat6", "hsusb1_dir", + "gpio_22", NULL, "hsusb1_tll_dir", NULL), + _OMAP3_MUXENTRY(ETK_D9, 23, + "etk_d9", "sys_secure_indicator", "sdmmc3_dat5", "hsusb1_nxt", + "gpio_23", "mm1_rxdm", "hsusb1_tll_nxt", NULL), + _OMAP3_MUXENTRY(MCBSP3_CLKX, 142, + "mcbsp3_clkx", "uart2_tx", NULL, NULL, + "gpio_142", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP3_DR, 141, + "mcbsp3_dr", "uart2_rts", NULL, NULL, + "gpio_141", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP3_DX, 140, + "mcbsp3_dx", "uart2_cts", NULL, NULL, + "gpio_140", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP3_FSX, 143, + "mcbsp3_fsx", "uart2_rx", NULL, NULL, + "gpio_143", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC2_DAT5, 137, + "sdmmc2_dat5", "sdmmc2_dir_dat1", + "cam_global_reset", "sdmmc3_dat1", + "gpio_137", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC2_DAT6, 138, + "sdmmc2_dat6", "sdmmc2_dir_cmd", "cam_shutter", "sdmmc3_dat2", + "gpio_138", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC2_DAT7, 139, + "sdmmc2_dat7", "sdmmc2_clkin", NULL, "sdmmc3_dat3", + "gpio_139", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(UART1_CTS, 150, + "uart1_cts", NULL, NULL, NULL, + "gpio_150", NULL, NULL, "safe_mode"), + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#else +#define omap3_cus_subset NULL +#endif + +/* + * Balls for CUS package + * 423-pin s-PBGA Package, 0.65mm Ball Pitch (Bottom) + */ +#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \ + && defined(CONFIG_OMAP_PACKAGE_CUS) +static struct omap_ball __initdata omap3_cus_ball[] = { + _OMAP3_BALLENTRY(CAM_D0, "ab18", NULL), + _OMAP3_BALLENTRY(CAM_D1, "ac18", NULL), + _OMAP3_BALLENTRY(CAM_D10, "f21", NULL), + _OMAP3_BALLENTRY(CAM_D11, "g21", NULL), + _OMAP3_BALLENTRY(CAM_D2, "g19", NULL), + _OMAP3_BALLENTRY(CAM_D3, "f19", NULL), + _OMAP3_BALLENTRY(CAM_D4, "g20", NULL), + _OMAP3_BALLENTRY(CAM_D5, "b21", NULL), + _OMAP3_BALLENTRY(CAM_D6, "l24", NULL), + _OMAP3_BALLENTRY(CAM_D7, "k24", NULL), + _OMAP3_BALLENTRY(CAM_D8, "j23", NULL), + _OMAP3_BALLENTRY(CAM_D9, "k23", NULL), + _OMAP3_BALLENTRY(CAM_FLD, "h24", NULL), + _OMAP3_BALLENTRY(CAM_HS, "a22", NULL), + _OMAP3_BALLENTRY(CAM_PCLK, "j19", NULL), + _OMAP3_BALLENTRY(CAM_STROBE, "j20", NULL), + _OMAP3_BALLENTRY(CAM_VS, "e18", NULL), + _OMAP3_BALLENTRY(CAM_WEN, "f18", NULL), + _OMAP3_BALLENTRY(CAM_XCLKA, "b22", NULL), + _OMAP3_BALLENTRY(CAM_XCLKB, "c22", NULL), + _OMAP3_BALLENTRY(DSS_ACBIAS, "j21", NULL), + _OMAP3_BALLENTRY(DSS_DATA0, "ac19", NULL), + _OMAP3_BALLENTRY(DSS_DATA1, "ab19", NULL), + _OMAP3_BALLENTRY(DSS_DATA10, "ac22", NULL), + _OMAP3_BALLENTRY(DSS_DATA11, "ac23", NULL), + _OMAP3_BALLENTRY(DSS_DATA12, "ab22", NULL), + _OMAP3_BALLENTRY(DSS_DATA13, "y22", NULL), + _OMAP3_BALLENTRY(DSS_DATA14, "w22", NULL), + _OMAP3_BALLENTRY(DSS_DATA15, "v22", NULL), + _OMAP3_BALLENTRY(DSS_DATA16, "j22", NULL), + _OMAP3_BALLENTRY(DSS_DATA17, "g23", NULL), + _OMAP3_BALLENTRY(DSS_DATA18, "g24", NULL), + _OMAP3_BALLENTRY(DSS_DATA19, "h23", NULL), + _OMAP3_BALLENTRY(DSS_DATA2, "ad20", NULL), + _OMAP3_BALLENTRY(DSS_DATA20, "d23", NULL), + _OMAP3_BALLENTRY(DSS_DATA21, "k22", NULL), + _OMAP3_BALLENTRY(DSS_DATA22, "v21", NULL), + _OMAP3_BALLENTRY(DSS_DATA23, "w21", NULL), + _OMAP3_BALLENTRY(DSS_DATA3, "ac20", NULL), + _OMAP3_BALLENTRY(DSS_DATA4, "ad21", NULL), + _OMAP3_BALLENTRY(DSS_DATA5, "ac21", NULL), + _OMAP3_BALLENTRY(DSS_DATA6, "d24", NULL), + _OMAP3_BALLENTRY(DSS_DATA7, "e23", NULL), + _OMAP3_BALLENTRY(DSS_DATA8, "e24", NULL), + _OMAP3_BALLENTRY(DSS_DATA9, "f23", NULL), + _OMAP3_BALLENTRY(DSS_HSYNC, "e22", NULL), + _OMAP3_BALLENTRY(DSS_PCLK, "g22", NULL), + _OMAP3_BALLENTRY(DSS_VSYNC, "f22", NULL), + _OMAP3_BALLENTRY(ETK_CLK, "ac1", NULL), + _OMAP3_BALLENTRY(ETK_CTL, "ad3", NULL), + _OMAP3_BALLENTRY(ETK_D0, "ad6", NULL), + _OMAP3_BALLENTRY(ETK_D1, "ac6", NULL), + _OMAP3_BALLENTRY(ETK_D10, "ac3", NULL), + _OMAP3_BALLENTRY(ETK_D11, "ac9", NULL), + _OMAP3_BALLENTRY(ETK_D12, "ac10", NULL), + _OMAP3_BALLENTRY(ETK_D13, "ad11", NULL), + _OMAP3_BALLENTRY(ETK_D14, "ac11", NULL), + _OMAP3_BALLENTRY(ETK_D15, "ad12", NULL), + _OMAP3_BALLENTRY(ETK_D2, "ac7", NULL), + _OMAP3_BALLENTRY(ETK_D3, "ad8", NULL), + _OMAP3_BALLENTRY(ETK_D4, "ac5", NULL), + _OMAP3_BALLENTRY(ETK_D5, "ad2", NULL), + _OMAP3_BALLENTRY(ETK_D6, "ac8", NULL), + _OMAP3_BALLENTRY(ETK_D7, "ad9", NULL), + _OMAP3_BALLENTRY(ETK_D8, "ac4", NULL), + _OMAP3_BALLENTRY(ETK_D9, "ad5", NULL), + _OMAP3_BALLENTRY(GPMC_A1, "k4", NULL), + _OMAP3_BALLENTRY(GPMC_A10, "g2", NULL), + _OMAP3_BALLENTRY(GPMC_A2, "k3", NULL), + _OMAP3_BALLENTRY(GPMC_A3, "k2", NULL), + _OMAP3_BALLENTRY(GPMC_A4, "j4", NULL), + _OMAP3_BALLENTRY(GPMC_A5, "j3", NULL), + _OMAP3_BALLENTRY(GPMC_A6, "j2", NULL), + _OMAP3_BALLENTRY(GPMC_A7, "j1", NULL), + _OMAP3_BALLENTRY(GPMC_A8, "h1", NULL), + _OMAP3_BALLENTRY(GPMC_A9, "h2", NULL), + _OMAP3_BALLENTRY(GPMC_CLK, "w2", NULL), + _OMAP3_BALLENTRY(GPMC_D10, "u1", NULL), + _OMAP3_BALLENTRY(GPMC_D11, "r3", NULL), + _OMAP3_BALLENTRY(GPMC_D12, "t3", NULL), + _OMAP3_BALLENTRY(GPMC_D13, "u2", NULL), + _OMAP3_BALLENTRY(GPMC_D14, "v1", NULL), + _OMAP3_BALLENTRY(GPMC_D15, "v2", NULL), + _OMAP3_BALLENTRY(GPMC_D8, "r2", NULL), + _OMAP3_BALLENTRY(GPMC_D9, "t2", NULL), + _OMAP3_BALLENTRY(GPMC_NBE0_CLE, "k5", NULL), + _OMAP3_BALLENTRY(GPMC_NBE1, "l1", NULL), + _OMAP3_BALLENTRY(GPMC_NCS3, "d2", NULL), + _OMAP3_BALLENTRY(GPMC_NCS4, "f4", NULL), + _OMAP3_BALLENTRY(GPMC_NCS5, "g5", NULL), + _OMAP3_BALLENTRY(GPMC_NCS6, "f3", NULL), + _OMAP3_BALLENTRY(GPMC_NCS7, "g4", NULL), + _OMAP3_BALLENTRY(GPMC_NWP, "e1", NULL), + _OMAP3_BALLENTRY(GPMC_WAIT3, "c2", NULL), + _OMAP3_BALLENTRY(HDQ_SIO, "a24", NULL), + _OMAP3_BALLENTRY(HSUSB0_CLK, "r21", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA0, "t24", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA1, "t23", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA2, "u24", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA3, "u23", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA4, "w24", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA5, "v23", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA6, "w23", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA7, "t22", NULL), + _OMAP3_BALLENTRY(HSUSB0_DIR, "p23", NULL), + _OMAP3_BALLENTRY(HSUSB0_NXT, "r22", NULL), + _OMAP3_BALLENTRY(HSUSB0_STP, "r23", NULL), + _OMAP3_BALLENTRY(I2C2_SCL, "ac15", NULL), + _OMAP3_BALLENTRY(I2C2_SDA, "ac14", NULL), + _OMAP3_BALLENTRY(I2C3_SCL, "ac13", NULL), + _OMAP3_BALLENTRY(I2C3_SDA, "ac12", NULL), + _OMAP3_BALLENTRY(I2C4_SCL, "y16", NULL), + _OMAP3_BALLENTRY(I2C4_SDA, "y15", NULL), + _OMAP3_BALLENTRY(JTAG_EMU0, "ac24", NULL), + _OMAP3_BALLENTRY(JTAG_EMU1, "ad24", NULL), + _OMAP3_BALLENTRY(MCBSP1_CLKR, "w19", NULL), + _OMAP3_BALLENTRY(MCBSP1_CLKX, "v18", NULL), + _OMAP3_BALLENTRY(MCBSP1_DR, "y18", NULL), + _OMAP3_BALLENTRY(MCBSP1_DX, "w18", NULL), + _OMAP3_BALLENTRY(MCBSP1_FSR, "ab20", NULL), + _OMAP3_BALLENTRY(MCBSP1_FSX, "aa19", NULL), + _OMAP3_BALLENTRY(MCBSP2_CLKX, "t21", NULL), + _OMAP3_BALLENTRY(MCBSP2_DR, "v19", NULL), + _OMAP3_BALLENTRY(MCBSP2_DX, "r20", NULL), + _OMAP3_BALLENTRY(MCBSP2_FSX, "v20", NULL), + _OMAP3_BALLENTRY(MCBSP3_CLKX, "w4", NULL), + _OMAP3_BALLENTRY(MCBSP3_DR, "v5", NULL), + _OMAP3_BALLENTRY(MCBSP3_DX, "v6", NULL), + _OMAP3_BALLENTRY(MCBSP3_FSX, "v4", NULL), + _OMAP3_BALLENTRY(MCBSP_CLKS, "aa18", NULL), + _OMAP3_BALLENTRY(MCSPI1_CLK, "t5", NULL), + _OMAP3_BALLENTRY(MCSPI1_CS0, "t6", NULL), + _OMAP3_BALLENTRY(MCSPI1_CS3, "r5", NULL), + _OMAP3_BALLENTRY(MCSPI1_SIMO, "r4", NULL), + _OMAP3_BALLENTRY(MCSPI1_SOMI, "t4", NULL), + _OMAP3_BALLENTRY(MCSPI2_CLK, "n5", NULL), + _OMAP3_BALLENTRY(MCSPI2_CS0, "m5", NULL), + _OMAP3_BALLENTRY(MCSPI2_CS1, "m4", NULL), + _OMAP3_BALLENTRY(MCSPI2_SIMO, "n4", NULL), + _OMAP3_BALLENTRY(MCSPI2_SOMI, "n3", NULL), + _OMAP3_BALLENTRY(SDMMC1_CLK, "m23", NULL), + _OMAP3_BALLENTRY(SDMMC1_CMD, "l23", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT0, "m22", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT1, "m21", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT2, "m20", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT3, "n23", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT4, "n22", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT5, "n21", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT6, "n20", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT7, "p24", NULL), + _OMAP3_BALLENTRY(SDMMC2_CLK, "y1", NULL), + _OMAP3_BALLENTRY(SDMMC2_CMD, "ab5", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT0, "ab3", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT1, "y3", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT2, "w3", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT3, "v3", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT4, "ab2", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT5, "aa2", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT6, "y2", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT7, "aa1", NULL), + _OMAP3_BALLENTRY(SYS_BOOT0, "ab12", NULL), + _OMAP3_BALLENTRY(SYS_BOOT1, "ac16", NULL), + _OMAP3_BALLENTRY(SYS_BOOT2, "ad17", NULL), + _OMAP3_BALLENTRY(SYS_BOOT3, "ad18", NULL), + _OMAP3_BALLENTRY(SYS_BOOT4, "ac17", NULL), + _OMAP3_BALLENTRY(SYS_BOOT5, "ab16", NULL), + _OMAP3_BALLENTRY(SYS_BOOT6, "aa15", NULL), + _OMAP3_BALLENTRY(SYS_CLKOUT1, "y7", NULL), + _OMAP3_BALLENTRY(SYS_CLKOUT2, "aa6", NULL), + _OMAP3_BALLENTRY(SYS_CLKREQ, "y13", NULL), + _OMAP3_BALLENTRY(SYS_NIRQ, "w16", NULL), + _OMAP3_BALLENTRY(SYS_NRESWARM, "y10", NULL), + _OMAP3_BALLENTRY(SYS_OFF_MODE, "ad23", NULL), + _OMAP3_BALLENTRY(UART1_CTS, "ac2", NULL), + _OMAP3_BALLENTRY(UART1_RTS, "w6", NULL), + _OMAP3_BALLENTRY(UART1_RX, "v7", NULL), + _OMAP3_BALLENTRY(UART1_TX, "w7", NULL), + _OMAP3_BALLENTRY(UART3_CTS_RCTX, "a23", NULL), + _OMAP3_BALLENTRY(UART3_RTS_SD, "b23", NULL), + _OMAP3_BALLENTRY(UART3_RX_IRRX, "b24", NULL), + _OMAP3_BALLENTRY(UART3_TX_IRTX, "c23", NULL), + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#else +#define omap3_cus_ball NULL +#endif + +/* + * Signals different on CBB package comapared to superset + */ +#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBB) +static struct omap_mux __initdata omap3_cbb_subset[] = { + _OMAP3_MUXENTRY(CAM_D10, 109, + "cam_d10", NULL, NULL, NULL, + "gpio_109", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D11, 110, + "cam_d11", NULL, NULL, NULL, + "gpio_110", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D2, 101, + "cam_d2", NULL, NULL, NULL, + "gpio_101", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D3, 102, + "cam_d3", NULL, NULL, NULL, + "gpio_102", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D4, 103, + "cam_d4", NULL, NULL, NULL, + "gpio_103", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D5, 104, + "cam_d5", NULL, NULL, NULL, + "gpio_104", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_FLD, 98, + "cam_fld", NULL, "cam_global_reset", NULL, + "gpio_98", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_HS, 94, + "cam_hs", NULL, NULL, NULL, + "gpio_94", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_PCLK, 97, + "cam_pclk", NULL, NULL, NULL, + "gpio_97", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_STROBE, 126, + "cam_strobe", NULL, NULL, NULL, + "gpio_126", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_VS, 95, + "cam_vs", NULL, NULL, NULL, + "gpio_95", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_WEN, 167, + "cam_wen", NULL, "cam_shutter", NULL, + "gpio_167", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA6, 76, + "dss_data6", NULL, "uart1_tx", NULL, + "gpio_76", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA7, 77, + "dss_data7", NULL, "uart1_rx", NULL, + "gpio_77", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA8, 78, + "dss_data8", NULL, NULL, NULL, + "gpio_78", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA9, 79, + "dss_data9", NULL, NULL, NULL, + "gpio_79", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_HSYNC, 67, + "dss_hsync", NULL, NULL, NULL, + "gpio_67", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_PCLK, 66, + "dss_pclk", NULL, NULL, NULL, + "gpio_66", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(ETK_CLK, 12, + "etk_clk", "mcbsp5_clkx", "sdmmc3_clk", "hsusb1_stp", + "gpio_12", "mm1_rxdp", "hsusb1_tll_stp", NULL), + _OMAP3_MUXENTRY(ETK_CTL, 13, + "etk_ctl", NULL, "sdmmc3_cmd", "hsusb1_clk", + "gpio_13", NULL, "hsusb1_tll_clk", NULL), + _OMAP3_MUXENTRY(ETK_D0, 14, + "etk_d0", "mcspi3_simo", "sdmmc3_dat4", "hsusb1_data0", + "gpio_14", "mm1_rxrcv", "hsusb1_tll_data0", NULL), + _OMAP3_MUXENTRY(ETK_D1, 15, + "etk_d1", "mcspi3_somi", NULL, "hsusb1_data1", + "gpio_15", "mm1_txse0", "hsusb1_tll_data1", NULL), + _OMAP3_MUXENTRY(ETK_D10, 24, + "etk_d10", NULL, "uart1_rx", "hsusb2_clk", + "gpio_24", NULL, "hsusb2_tll_clk", NULL), + _OMAP3_MUXENTRY(ETK_D11, 25, + "etk_d11", NULL, NULL, "hsusb2_stp", + "gpio_25", "mm2_rxdp", "hsusb2_tll_stp", NULL), + _OMAP3_MUXENTRY(ETK_D12, 26, + "etk_d12", NULL, NULL, "hsusb2_dir", + "gpio_26", NULL, "hsusb2_tll_dir", NULL), + _OMAP3_MUXENTRY(ETK_D13, 27, + "etk_d13", NULL, NULL, "hsusb2_nxt", + "gpio_27", "mm2_rxdm", "hsusb2_tll_nxt", NULL), + _OMAP3_MUXENTRY(ETK_D14, 28, + "etk_d14", NULL, NULL, "hsusb2_data0", + "gpio_28", "mm2_rxrcv", "hsusb2_tll_data0", NULL), + _OMAP3_MUXENTRY(ETK_D15, 29, + "etk_d15", NULL, NULL, "hsusb2_data1", + "gpio_29", "mm2_txse0", "hsusb2_tll_data1", NULL), + _OMAP3_MUXENTRY(ETK_D2, 16, + "etk_d2", "mcspi3_cs0", NULL, "hsusb1_data2", + "gpio_16", "mm1_txdat", "hsusb1_tll_data2", NULL), + _OMAP3_MUXENTRY(ETK_D3, 17, + "etk_d3", "mcspi3_clk", "sdmmc3_dat3", "hsusb1_data7", + "gpio_17", NULL, "hsusb1_tll_data7", NULL), + _OMAP3_MUXENTRY(ETK_D4, 18, + "etk_d4", "mcbsp5_dr", "sdmmc3_dat0", "hsusb1_data4", + "gpio_18", NULL, "hsusb1_tll_data4", NULL), + _OMAP3_MUXENTRY(ETK_D5, 19, + "etk_d5", "mcbsp5_fsx", "sdmmc3_dat1", "hsusb1_data5", + "gpio_19", NULL, "hsusb1_tll_data5", NULL), + _OMAP3_MUXENTRY(ETK_D6, 20, + "etk_d6", "mcbsp5_dx", "sdmmc3_dat2", "hsusb1_data6", + "gpio_20", NULL, "hsusb1_tll_data6", NULL), + _OMAP3_MUXENTRY(ETK_D7, 21, + "etk_d7", "mcspi3_cs1", "sdmmc3_dat7", "hsusb1_data3", + "gpio_21", "mm1_txen_n", "hsusb1_tll_data3", NULL), + _OMAP3_MUXENTRY(ETK_D8, 22, + "etk_d8", "sys_drm_msecure", "sdmmc3_dat6", "hsusb1_dir", + "gpio_22", NULL, "hsusb1_tll_dir", NULL), + _OMAP3_MUXENTRY(ETK_D9, 23, + "etk_d9", "sys_secure_indicator", "sdmmc3_dat5", "hsusb1_nxt", + "gpio_23", "mm1_rxdm", "hsusb1_tll_nxt", NULL), + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#else +#define omap3_cbb_subset NULL +#endif + +/* + * Balls for CBB package + * 515-pin s-PBGA Package, 0.50mm Ball Pitch (Top), 0.40mm Ball Pitch (Bottom) + */ +#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \ + && defined(CONFIG_OMAP_PACKAGE_CBB) +static struct omap_ball __initdata omap3_cbb_ball[] = { + _OMAP3_BALLENTRY(CAM_D0, "ag17", NULL), + _OMAP3_BALLENTRY(CAM_D1, "ah17", NULL), + _OMAP3_BALLENTRY(CAM_D10, "b25", NULL), + _OMAP3_BALLENTRY(CAM_D11, "c26", NULL), + _OMAP3_BALLENTRY(CAM_D2, "b24", NULL), + _OMAP3_BALLENTRY(CAM_D3, "c24", NULL), + _OMAP3_BALLENTRY(CAM_D4, "d24", NULL), + _OMAP3_BALLENTRY(CAM_D5, "a25", NULL), + _OMAP3_BALLENTRY(CAM_D6, "k28", NULL), + _OMAP3_BALLENTRY(CAM_D7, "l28", NULL), + _OMAP3_BALLENTRY(CAM_D8, "k27", NULL), + _OMAP3_BALLENTRY(CAM_D9, "l27", NULL), + _OMAP3_BALLENTRY(CAM_FLD, "c23", NULL), + _OMAP3_BALLENTRY(CAM_HS, "a24", NULL), + _OMAP3_BALLENTRY(CAM_PCLK, "c27", NULL), + _OMAP3_BALLENTRY(CAM_STROBE, "d25", NULL), + _OMAP3_BALLENTRY(CAM_VS, "a23", NULL), + _OMAP3_BALLENTRY(CAM_WEN, "b23", NULL), + _OMAP3_BALLENTRY(CAM_XCLKA, "c25", NULL), + _OMAP3_BALLENTRY(CAM_XCLKB, "b26", NULL), + _OMAP3_BALLENTRY(CSI2_DX0, "ag19", NULL), + _OMAP3_BALLENTRY(CSI2_DX1, "ag18", NULL), + _OMAP3_BALLENTRY(CSI2_DY0, "ah19", NULL), + _OMAP3_BALLENTRY(CSI2_DY1, "ah18", NULL), + _OMAP3_BALLENTRY(DSS_ACBIAS, "e27", NULL), + _OMAP3_BALLENTRY(DSS_DATA0, "ag22", NULL), + _OMAP3_BALLENTRY(DSS_DATA1, "ah22", NULL), + _OMAP3_BALLENTRY(DSS_DATA10, "ad28", NULL), + _OMAP3_BALLENTRY(DSS_DATA11, "ad27", NULL), + _OMAP3_BALLENTRY(DSS_DATA12, "ab28", NULL), + _OMAP3_BALLENTRY(DSS_DATA13, "ab27", NULL), + _OMAP3_BALLENTRY(DSS_DATA14, "aa28", NULL), + _OMAP3_BALLENTRY(DSS_DATA15, "aa27", NULL), + _OMAP3_BALLENTRY(DSS_DATA16, "g25", NULL), + _OMAP3_BALLENTRY(DSS_DATA17, "h27", NULL), + _OMAP3_BALLENTRY(DSS_DATA18, "h26", NULL), + _OMAP3_BALLENTRY(DSS_DATA19, "h25", NULL), + _OMAP3_BALLENTRY(DSS_DATA2, "ag23", NULL), + _OMAP3_BALLENTRY(DSS_DATA20, "e28", NULL), + _OMAP3_BALLENTRY(DSS_DATA21, "j26", NULL), + _OMAP3_BALLENTRY(DSS_DATA22, "ac27", NULL), + _OMAP3_BALLENTRY(DSS_DATA23, "ac28", NULL), + _OMAP3_BALLENTRY(DSS_DATA3, "ah23", NULL), + _OMAP3_BALLENTRY(DSS_DATA4, "ag24", NULL), + _OMAP3_BALLENTRY(DSS_DATA5, "ah24", NULL), + _OMAP3_BALLENTRY(DSS_DATA6, "e26", NULL), + _OMAP3_BALLENTRY(DSS_DATA7, "f28", NULL), + _OMAP3_BALLENTRY(DSS_DATA8, "f27", NULL), + _OMAP3_BALLENTRY(DSS_DATA9, "g26", NULL), + _OMAP3_BALLENTRY(DSS_HSYNC, "d26", NULL), + _OMAP3_BALLENTRY(DSS_PCLK, "d28", NULL), + _OMAP3_BALLENTRY(DSS_VSYNC, "d27", NULL), + _OMAP3_BALLENTRY(ETK_CLK, "af10", NULL), + _OMAP3_BALLENTRY(ETK_CTL, "ae10", NULL), + _OMAP3_BALLENTRY(ETK_D0, "af11", NULL), + _OMAP3_BALLENTRY(ETK_D1, "ag12", NULL), + _OMAP3_BALLENTRY(ETK_D10, "ae7", NULL), + _OMAP3_BALLENTRY(ETK_D11, "af7", NULL), + _OMAP3_BALLENTRY(ETK_D12, "ag7", NULL), + _OMAP3_BALLENTRY(ETK_D13, "ah7", NULL), + _OMAP3_BALLENTRY(ETK_D14, "ag8", NULL), + _OMAP3_BALLENTRY(ETK_D15, "ah8", NULL), + _OMAP3_BALLENTRY(ETK_D2, "ah12", NULL), + _OMAP3_BALLENTRY(ETK_D3, "ae13", NULL), + _OMAP3_BALLENTRY(ETK_D4, "ae11", NULL), + _OMAP3_BALLENTRY(ETK_D5, "ah9", NULL), + _OMAP3_BALLENTRY(ETK_D6, "af13", NULL), + _OMAP3_BALLENTRY(ETK_D7, "ah14", NULL), + _OMAP3_BALLENTRY(ETK_D8, "af9", NULL), + _OMAP3_BALLENTRY(ETK_D9, "ag9", NULL), + _OMAP3_BALLENTRY(GPMC_A1, "n4", "ac15"), + _OMAP3_BALLENTRY(GPMC_A10, "k3", "ab19"), + _OMAP3_BALLENTRY(GPMC_A2, "m4", "ab15"), + _OMAP3_BALLENTRY(GPMC_A3, "l4", "ac16"), + _OMAP3_BALLENTRY(GPMC_A4, "k4", "ab16"), + _OMAP3_BALLENTRY(GPMC_A5, "t3", "ac17"), + _OMAP3_BALLENTRY(GPMC_A6, "r3", "ab17"), + _OMAP3_BALLENTRY(GPMC_A7, "n3", "ac18"), + _OMAP3_BALLENTRY(GPMC_A8, "m3", "ab18"), + _OMAP3_BALLENTRY(GPMC_A9, "l3", "ac19"), + _OMAP3_BALLENTRY(GPMC_CLK, "t4", "w2"), + _OMAP3_BALLENTRY(GPMC_D10, "p1", "ab4"), + _OMAP3_BALLENTRY(GPMC_D11, "r1", "ac4"), + _OMAP3_BALLENTRY(GPMC_D12, "r2", "ab6"), + _OMAP3_BALLENTRY(GPMC_D13, "t2", "ac6"), + _OMAP3_BALLENTRY(GPMC_D14, "w1", "ab7"), + _OMAP3_BALLENTRY(GPMC_D15, "y1", "ac7"), + _OMAP3_BALLENTRY(GPMC_D8, "h2", "ab3"), + _OMAP3_BALLENTRY(GPMC_D9, "k2", "ac3"), + _OMAP3_BALLENTRY(GPMC_NBE0_CLE, "g3", "ac12"), + _OMAP3_BALLENTRY(GPMC_NBE1, "u3", NULL), + _OMAP3_BALLENTRY(GPMC_NCS1, "h3", "y1"), + _OMAP3_BALLENTRY(GPMC_NCS2, "v8", NULL), + _OMAP3_BALLENTRY(GPMC_NCS3, "u8", NULL), + _OMAP3_BALLENTRY(GPMC_NCS4, "t8", NULL), + _OMAP3_BALLENTRY(GPMC_NCS5, "r8", NULL), + _OMAP3_BALLENTRY(GPMC_NCS6, "p8", NULL), + _OMAP3_BALLENTRY(GPMC_NCS7, "n8", NULL), + _OMAP3_BALLENTRY(GPMC_NWP, "h1", "ab10"), + _OMAP3_BALLENTRY(GPMC_WAIT1, "l8", "ac10"), + _OMAP3_BALLENTRY(GPMC_WAIT2, "k8", NULL), + _OMAP3_BALLENTRY(GPMC_WAIT3, "j8", NULL), + _OMAP3_BALLENTRY(HDQ_SIO, "j25", NULL), + _OMAP3_BALLENTRY(HSUSB0_CLK, "t28", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA0, "t27", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA1, "u28", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA2, "u27", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA3, "u26", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA4, "u25", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA5, "v28", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA6, "v27", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA7, "v26", NULL), + _OMAP3_BALLENTRY(HSUSB0_DIR, "r28", NULL), + _OMAP3_BALLENTRY(HSUSB0_NXT, "t26", NULL), + _OMAP3_BALLENTRY(HSUSB0_STP, "t25", NULL), + _OMAP3_BALLENTRY(I2C2_SCL, "af15", NULL), + _OMAP3_BALLENTRY(I2C2_SDA, "ae15", NULL), + _OMAP3_BALLENTRY(I2C3_SCL, "af14", NULL), + _OMAP3_BALLENTRY(I2C3_SDA, "ag14", NULL), + _OMAP3_BALLENTRY(I2C4_SCL, "ad26", NULL), + _OMAP3_BALLENTRY(I2C4_SDA, "ae26", NULL), + _OMAP3_BALLENTRY(JTAG_EMU0, "aa11", NULL), + _OMAP3_BALLENTRY(JTAG_EMU1, "aa10", NULL), + _OMAP3_BALLENTRY(MCBSP1_CLKR, "y21", NULL), + _OMAP3_BALLENTRY(MCBSP1_CLKX, "w21", NULL), + _OMAP3_BALLENTRY(MCBSP1_DR, "u21", NULL), + _OMAP3_BALLENTRY(MCBSP1_DX, "v21", NULL), + _OMAP3_BALLENTRY(MCBSP1_FSR, "aa21", NULL), + _OMAP3_BALLENTRY(MCBSP1_FSX, "k26", NULL), + _OMAP3_BALLENTRY(MCBSP2_CLKX, "n21", NULL), + _OMAP3_BALLENTRY(MCBSP2_DR, "r21", NULL), + _OMAP3_BALLENTRY(MCBSP2_DX, "m21", NULL), + _OMAP3_BALLENTRY(MCBSP2_FSX, "p21", NULL), + _OMAP3_BALLENTRY(MCBSP3_CLKX, "af5", NULL), + _OMAP3_BALLENTRY(MCBSP3_DR, "ae6", NULL), + _OMAP3_BALLENTRY(MCBSP3_DX, "af6", NULL), + _OMAP3_BALLENTRY(MCBSP3_FSX, "ae5", NULL), + _OMAP3_BALLENTRY(MCBSP4_CLKX, "ae1", NULL), + _OMAP3_BALLENTRY(MCBSP4_DR, "ad1", NULL), + _OMAP3_BALLENTRY(MCBSP4_DX, "ad2", NULL), + _OMAP3_BALLENTRY(MCBSP4_FSX, "ac1", NULL), + _OMAP3_BALLENTRY(MCBSP_CLKS, "t21", NULL), + _OMAP3_BALLENTRY(MCSPI1_CLK, "ab3", NULL), + _OMAP3_BALLENTRY(MCSPI1_CS0, "ac2", NULL), + _OMAP3_BALLENTRY(MCSPI1_CS1, "ac3", NULL), + _OMAP3_BALLENTRY(MCSPI1_CS2, "ab1", NULL), + _OMAP3_BALLENTRY(MCSPI1_CS3, "ab2", NULL), + _OMAP3_BALLENTRY(MCSPI1_SIMO, "ab4", NULL), + _OMAP3_BALLENTRY(MCSPI1_SOMI, "aa4", NULL), + _OMAP3_BALLENTRY(MCSPI2_CLK, "aa3", NULL), + _OMAP3_BALLENTRY(MCSPI2_CS0, "y4", NULL), + _OMAP3_BALLENTRY(MCSPI2_CS1, "v3", NULL), + _OMAP3_BALLENTRY(MCSPI2_SIMO, "y2", NULL), + _OMAP3_BALLENTRY(MCSPI2_SOMI, "y3", NULL), + _OMAP3_BALLENTRY(SDMMC1_CLK, "n28", NULL), + _OMAP3_BALLENTRY(SDMMC1_CMD, "m27", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT0, "n27", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT1, "n26", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT2, "n25", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT3, "p28", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT4, "p27", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT5, "p26", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT6, "r27", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT7, "r25", NULL), + _OMAP3_BALLENTRY(SDMMC2_CLK, "ae2", NULL), + _OMAP3_BALLENTRY(SDMMC2_CMD, "ag5", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT0, "ah5", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT1, "ah4", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT2, "ag4", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT3, "af4", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT4, "ae4", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT5, "ah3", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT6, "af3", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT7, "ae3", NULL), + _OMAP3_BALLENTRY(SYS_BOOT0, "ah26", NULL), + _OMAP3_BALLENTRY(SYS_BOOT1, "ag26", NULL), + _OMAP3_BALLENTRY(SYS_BOOT2, "ae14", NULL), + _OMAP3_BALLENTRY(SYS_BOOT3, "af18", NULL), + _OMAP3_BALLENTRY(SYS_BOOT4, "af19", NULL), + _OMAP3_BALLENTRY(SYS_BOOT5, "ae21", NULL), + _OMAP3_BALLENTRY(SYS_BOOT6, "af21", NULL), + _OMAP3_BALLENTRY(SYS_CLKOUT1, "ag25", NULL), + _OMAP3_BALLENTRY(SYS_CLKOUT2, "ae22", NULL), + _OMAP3_BALLENTRY(SYS_CLKREQ, "af25", NULL), + _OMAP3_BALLENTRY(SYS_NIRQ, "af26", NULL), + _OMAP3_BALLENTRY(SYS_NRESWARM, "af24", NULL), + _OMAP3_BALLENTRY(SYS_OFF_MODE, "af22", NULL), + _OMAP3_BALLENTRY(UART1_CTS, "w8", NULL), + _OMAP3_BALLENTRY(UART1_RTS, "aa9", NULL), + _OMAP3_BALLENTRY(UART1_RX, "y8", NULL), + _OMAP3_BALLENTRY(UART1_TX, "aa8", NULL), + _OMAP3_BALLENTRY(UART2_CTS, "ab26", NULL), + _OMAP3_BALLENTRY(UART2_RTS, "ab25", NULL), + _OMAP3_BALLENTRY(UART2_RX, "ad25", NULL), + _OMAP3_BALLENTRY(UART2_TX, "aa25", NULL), + _OMAP3_BALLENTRY(UART3_CTS_RCTX, "h18", NULL), + _OMAP3_BALLENTRY(UART3_RTS_SD, "h19", NULL), + _OMAP3_BALLENTRY(UART3_RX_IRRX, "h20", NULL), + _OMAP3_BALLENTRY(UART3_TX_IRTX, "h21", NULL), + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#else +#define omap3_cbb_ball NULL +#endif + +/* + * Signals different on 36XX CBP package comapared to 34XX CBC package + */ +#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBP) +static struct omap_mux __initdata omap36xx_cbp_subset[] = { + _OMAP3_MUXENTRY(CAM_D0, 99, + "cam_d0", NULL, "csi2_dx2", NULL, + "gpio_99", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D1, 100, + "cam_d1", NULL, "csi2_dy2", NULL, + "gpio_100", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D10, 109, + "cam_d10", "ssi2_wake", NULL, NULL, + "gpio_109", "hw_dbg8", NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D2, 101, + "cam_d2", "ssi2_rdy_tx", NULL, NULL, + "gpio_101", "hw_dbg4", NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D3, 102, + "cam_d3", "ssi2_dat_rx", NULL, NULL, + "gpio_102", "hw_dbg5", NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D4, 103, + "cam_d4", "ssi2_flag_rx", NULL, NULL, + "gpio_103", "hw_dbg6", NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_D5, 104, + "cam_d5", "ssi2_rdy_rx", NULL, NULL, + "gpio_104", "hw_dbg7", NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_HS, 94, + "cam_hs", "ssi2_dat_tx", NULL, NULL, + "gpio_94", "hw_dbg0", NULL, "safe_mode"), + _OMAP3_MUXENTRY(CAM_VS, 95, + "cam_vs", "ssi2_flag_tx", NULL, NULL, + "gpio_95", "hw_dbg1", NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA0, 70, + "dss_data0", "dsi_dx0", "uart1_cts", NULL, + "gpio_70", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA1, 71, + "dss_data1", "dsi_dy0", "uart1_rts", NULL, + "gpio_71", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA2, 72, + "dss_data2", "dsi_dx1", NULL, NULL, + "gpio_72", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA3, 73, + "dss_data3", "dsi_dy1", NULL, NULL, + "gpio_73", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA4, 74, + "dss_data4", "dsi_dx2", "uart3_rx_irrx", NULL, + "gpio_74", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA5, 75, + "dss_data5", "dsi_dy2", "uart3_tx_irtx", NULL, + "gpio_75", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA6, 76, + "dss_data6", NULL, "uart1_tx", "dssvenc656_data6", + "gpio_76", "hw_dbg14", NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA7, 77, + "dss_data7", NULL, "uart1_rx", "dssvenc656_data7", + "gpio_77", "hw_dbg15", NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA8, 78, + "dss_data8", NULL, "uart3_rx_irrx", NULL, + "gpio_78", "hw_dbg16", NULL, "safe_mode"), + _OMAP3_MUXENTRY(DSS_DATA9, 79, + "dss_data9", NULL, "uart3_tx_irtx", NULL, + "gpio_79", "hw_dbg17", NULL, "safe_mode"), + _OMAP3_MUXENTRY(ETK_D12, 26, + "etk_d12", "sys_drm_msecure", NULL, "hsusb2_dir", + "gpio_26", NULL, "hsusb2_tll_dir", "hw_dbg14"), + _OMAP3_MUXENTRY(GPMC_A11, 0, + "gpmc_a11", NULL, NULL, NULL, + NULL, NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_WAIT2, 64, + "gpmc_wait2", NULL, "uart4_tx", NULL, + "gpio_64", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(GPMC_WAIT3, 65, + "gpmc_wait3", "sys_ndmareq1", "uart4_rx", NULL, + "gpio_65", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(HSUSB0_DATA0, 125, + "hsusb0_data0", NULL, "uart3_tx_irtx", NULL, + "gpio_125", "uart2_tx", NULL, "safe_mode"), + _OMAP3_MUXENTRY(HSUSB0_DATA1, 130, + "hsusb0_data1", NULL, "uart3_rx_irrx", NULL, + "gpio_130", "uart2_rx", NULL, "safe_mode"), + _OMAP3_MUXENTRY(HSUSB0_DATA2, 131, + "hsusb0_data2", NULL, "uart3_rts_sd", NULL, + "gpio_131", "uart2_rts", NULL, "safe_mode"), + _OMAP3_MUXENTRY(HSUSB0_DATA3, 169, + "hsusb0_data3", NULL, "uart3_cts_rctx", NULL, + "gpio_169", "uart2_cts", NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP1_CLKR, 156, + "mcbsp1_clkr", "mcspi4_clk", "sim_cd", NULL, + "gpio_156", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP1_FSR, 157, + "mcbsp1_fsr", "adpllv2d_dithering_en1", + "cam_global_reset", NULL, + "gpio_157", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(MCBSP4_CLKX, 152, + "mcbsp4_clkx", "ssi1_dat_rx", NULL, NULL, + "gpio_152", "hsusb3_tll_data1", "mm3_txse0", "safe_mode"), + _OMAP3_MUXENTRY(MCBSP4_DR, 153, + "mcbsp4_dr", "ssi1_flag_rx", NULL, NULL, + "gpio_153", "hsusb3_tll_data0", "mm3_rxrcv", "safe_mode"), + _OMAP3_MUXENTRY(MCBSP4_DX, 154, + "mcbsp4_dx", "ssi1_rdy_rx", NULL, NULL, + "gpio_154", "hsusb3_tll_data2", "mm3_txdat", "safe_mode"), + _OMAP3_MUXENTRY(MCBSP4_FSX, 155, + "mcbsp4_fsx", "ssi1_wake", NULL, NULL, + "gpio_155", "hsusb3_tll_data3", "mm3_txen_n", "safe_mode"), + _OMAP3_MUXENTRY(MCSPI1_CS1, 175, + "mcspi1_cs1", "adpllv2d_dithering_en2", NULL, "sdmmc3_cmd", + "gpio_175", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SAD2D_MBUSFLAG, 0, + "sad2d_mbusflag", "mad2d_sbusflag", NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MCAD28, 0, + "sad2d_mcad28", "mad2d_mcad28", NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MCAD29, 0, + "sad2d_mcad29", "mad2d_mcad29", NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MCAD32, 0, + "sad2d_mcad32", "mad2d_mcad32", NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MCAD33, 0, + "sad2d_mcad33", "mad2d_mcad33", NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MCAD34, 0, + "sad2d_mcad34", "mad2d_mcad34", NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MCAD35, 0, + "sad2d_mcad35", "mad2d_mcad35", NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MCAD36, 0, + "sad2d_mcad36", "mad2d_mcad36", NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MREAD, 0, + "sad2d_mread", "mad2d_sread", NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_MWRITE, 0, + "sad2d_mwrite", "mad2d_swrite", NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_SBUSFLAG, 0, + "sad2d_sbusflag", "mad2d_mbusflag", NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_SREAD, 0, + "sad2d_sread", "mad2d_mread", NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SAD2D_SWRITE, 0, + "sad2d_swrite", "mad2d_mwrite", NULL, NULL, + NULL, NULL, NULL, NULL), + _OMAP3_MUXENTRY(SDMMC1_CLK, 120, + "sdmmc1_clk", "ms_clk", NULL, NULL, + "gpio_120", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC1_CMD, 121, + "sdmmc1_cmd", "ms_bs", NULL, NULL, + "gpio_121", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC1_DAT0, 122, + "sdmmc1_dat0", "ms_dat0", NULL, NULL, + "gpio_122", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC1_DAT1, 123, + "sdmmc1_dat1", "ms_dat1", NULL, NULL, + "gpio_123", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC1_DAT2, 124, + "sdmmc1_dat2", "ms_dat2", NULL, NULL, + "gpio_124", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDMMC1_DAT3, 125, + "sdmmc1_dat3", "ms_dat3", NULL, NULL, + "gpio_125", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SDRC_CKE0, 0, + "sdrc_cke0", NULL, NULL, NULL, + NULL, NULL, NULL, "safe_mode_out1"), + _OMAP3_MUXENTRY(SDRC_CKE1, 0, + "sdrc_cke1", NULL, NULL, NULL, + NULL, NULL, NULL, "safe_mode_out1"), + _OMAP3_MUXENTRY(SIM_IO, 126, + "sim_io", "sim_io_low_impedance", NULL, NULL, + "gpio_126", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SIM_CLK, 127, + "sim_clk", NULL, NULL, NULL, + "gpio_127", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SIM_PWRCTRL, 128, + "sim_pwrctrl", NULL, NULL, NULL, + "gpio_128", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SIM_RST, 129, + "sim_rst", NULL, NULL, NULL, + "gpio_129", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_BOOT0, 2, + "sys_boot0", NULL, NULL, "dss_data18", + "gpio_2", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_BOOT1, 3, + "sys_boot1", NULL, NULL, "dss_data19", + "gpio_3", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_BOOT3, 5, + "sys_boot3", NULL, NULL, "dss_data20", + "gpio_5", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_BOOT4, 6, + "sys_boot4", "sdmmc2_dir_dat2", NULL, "dss_data21", + "gpio_6", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_BOOT5, 7, + "sys_boot5", "sdmmc2_dir_dat3", NULL, "dss_data22", + "gpio_7", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(SYS_BOOT6, 8, + "sys_boot6", NULL, NULL, "dss_data23", + "gpio_8", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(UART1_CTS, 150, + "uart1_cts", "ssi1_rdy_tx", NULL, NULL, + "gpio_150", "hsusb3_tll_clk", NULL, "safe_mode"), + _OMAP3_MUXENTRY(UART1_RTS, 149, + "uart1_rts", "ssi1_flag_tx", NULL, NULL, + "gpio_149", NULL, NULL, "safe_mode"), + _OMAP3_MUXENTRY(UART1_TX, 148, + "uart1_tx", "ssi1_dat_tx", NULL, NULL, + "gpio_148", NULL, NULL, "safe_mode"), + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#else +#define omap36xx_cbp_subset NULL +#endif + +/* + * Balls for 36XX CBP package + * 515-pin s-PBGA Package, 0.50mm Ball Pitch (Top), 0.40mm Ball Pitch (Bottom) + */ +#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \ + && defined (CONFIG_OMAP_PACKAGE_CBP) +static struct omap_ball __initdata omap36xx_cbp_ball[] = { + _OMAP3_BALLENTRY(CAM_D0, "ag17", NULL), + _OMAP3_BALLENTRY(CAM_D1, "ah17", NULL), + _OMAP3_BALLENTRY(CAM_D10, "b25", NULL), + _OMAP3_BALLENTRY(CAM_D11, "c26", NULL), + _OMAP3_BALLENTRY(CAM_D2, "b24", NULL), + _OMAP3_BALLENTRY(CAM_D3, "c24", NULL), + _OMAP3_BALLENTRY(CAM_D4, "d24", NULL), + _OMAP3_BALLENTRY(CAM_D5, "a25", NULL), + _OMAP3_BALLENTRY(CAM_D6, "k28", NULL), + _OMAP3_BALLENTRY(CAM_D7, "l28", NULL), + _OMAP3_BALLENTRY(CAM_D8, "k27", NULL), + _OMAP3_BALLENTRY(CAM_D9, "l27", NULL), + _OMAP3_BALLENTRY(CAM_FLD, "c23", NULL), + _OMAP3_BALLENTRY(CAM_HS, "a24", NULL), + _OMAP3_BALLENTRY(CAM_PCLK, "c27", NULL), + _OMAP3_BALLENTRY(CAM_STROBE, "d25", NULL), + _OMAP3_BALLENTRY(CAM_VS, "a23", NULL), + _OMAP3_BALLENTRY(CAM_WEN, "b23", NULL), + _OMAP3_BALLENTRY(CAM_XCLKA, "c25", NULL), + _OMAP3_BALLENTRY(CAM_XCLKB, "b26", NULL), + _OMAP3_BALLENTRY(CSI2_DX0, "ag19", NULL), + _OMAP3_BALLENTRY(CSI2_DX1, "ag18", NULL), + _OMAP3_BALLENTRY(CSI2_DY0, "ah19", NULL), + _OMAP3_BALLENTRY(CSI2_DY1, "ah18", NULL), + _OMAP3_BALLENTRY(DSS_ACBIAS, "e27", NULL), + _OMAP3_BALLENTRY(DSS_DATA0, "ag22", NULL), + _OMAP3_BALLENTRY(DSS_DATA1, "ah22", NULL), + _OMAP3_BALLENTRY(DSS_DATA10, "ad28", NULL), + _OMAP3_BALLENTRY(DSS_DATA11, "ad27", NULL), + _OMAP3_BALLENTRY(DSS_DATA12, "ab28", NULL), + _OMAP3_BALLENTRY(DSS_DATA13, "ab27", NULL), + _OMAP3_BALLENTRY(DSS_DATA14, "aa28", NULL), + _OMAP3_BALLENTRY(DSS_DATA15, "aa27", NULL), + _OMAP3_BALLENTRY(DSS_DATA16, "g25", NULL), + _OMAP3_BALLENTRY(DSS_DATA17, "h27", NULL), + _OMAP3_BALLENTRY(DSS_DATA18, "h26", NULL), + _OMAP3_BALLENTRY(DSS_DATA19, "h25", NULL), + _OMAP3_BALLENTRY(DSS_DATA2, "ag23", NULL), + _OMAP3_BALLENTRY(DSS_DATA20, "e28", NULL), + _OMAP3_BALLENTRY(DSS_DATA21, "j26", NULL), + _OMAP3_BALLENTRY(DSS_DATA22, "ac27", NULL), + _OMAP3_BALLENTRY(DSS_DATA23, "ac28", NULL), + _OMAP3_BALLENTRY(DSS_DATA3, "ah23", NULL), + _OMAP3_BALLENTRY(DSS_DATA4, "ag24", NULL), + _OMAP3_BALLENTRY(DSS_DATA5, "ah24", NULL), + _OMAP3_BALLENTRY(DSS_DATA6, "e26", NULL), + _OMAP3_BALLENTRY(DSS_DATA7, "f28", NULL), + _OMAP3_BALLENTRY(DSS_DATA8, "f27", NULL), + _OMAP3_BALLENTRY(DSS_DATA9, "g26", NULL), + _OMAP3_BALLENTRY(DSS_HSYNC, "d26", NULL), + _OMAP3_BALLENTRY(DSS_PCLK, "d28", NULL), + _OMAP3_BALLENTRY(DSS_VSYNC, "d27", NULL), + _OMAP3_BALLENTRY(ETK_CLK, "af10", NULL), + _OMAP3_BALLENTRY(ETK_CTL, "ae10", NULL), + _OMAP3_BALLENTRY(ETK_D0, "af11", NULL), + _OMAP3_BALLENTRY(ETK_D1, "ag12", NULL), + _OMAP3_BALLENTRY(ETK_D10, "ae7", NULL), + _OMAP3_BALLENTRY(ETK_D11, "af7", NULL), + _OMAP3_BALLENTRY(ETK_D12, "ag7", NULL), + _OMAP3_BALLENTRY(ETK_D13, "ah7", NULL), + _OMAP3_BALLENTRY(ETK_D14, "ag8", NULL), + _OMAP3_BALLENTRY(ETK_D15, "ah8", NULL), + _OMAP3_BALLENTRY(ETK_D2, "ah12", NULL), + _OMAP3_BALLENTRY(ETK_D3, "ae13", NULL), + _OMAP3_BALLENTRY(ETK_D4, "ae11", NULL), + _OMAP3_BALLENTRY(ETK_D5, "ah9", NULL), + _OMAP3_BALLENTRY(ETK_D6, "af13", NULL), + _OMAP3_BALLENTRY(ETK_D7, "ah14", NULL), + _OMAP3_BALLENTRY(ETK_D8, "af9", NULL), + _OMAP3_BALLENTRY(ETK_D9, "ag9", NULL), + _OMAP3_BALLENTRY(GPMC_A1, "n4", "ac15"), + _OMAP3_BALLENTRY(GPMC_A10, "k3", "ab19"), + _OMAP3_BALLENTRY(GPMC_A11, NULL, "ac20"), + _OMAP3_BALLENTRY(GPMC_A2, "m4", "ab15"), + _OMAP3_BALLENTRY(GPMC_A3, "l4", "ac16"), + _OMAP3_BALLENTRY(GPMC_A4, "k4", "ab16"), + _OMAP3_BALLENTRY(GPMC_A5, "t3", "ac17"), + _OMAP3_BALLENTRY(GPMC_A6, "r3", "ab17"), + _OMAP3_BALLENTRY(GPMC_A7, "n3", "ac18"), + _OMAP3_BALLENTRY(GPMC_A8, "m3", "ab18"), + _OMAP3_BALLENTRY(GPMC_A9, "l3", "ac19"), + _OMAP3_BALLENTRY(GPMC_CLK, "t4", "w2"), + _OMAP3_BALLENTRY(GPMC_D10, "p1", "ab4"), + _OMAP3_BALLENTRY(GPMC_D11, "r1", "ac4"), + _OMAP3_BALLENTRY(GPMC_D12, "r2", "ab6"), + _OMAP3_BALLENTRY(GPMC_D13, "t2", "ac6"), + _OMAP3_BALLENTRY(GPMC_D14, "w1", "ab7"), + _OMAP3_BALLENTRY(GPMC_D15, "y1", "ac7"), + _OMAP3_BALLENTRY(GPMC_D9, "k2", "ac3"), + _OMAP3_BALLENTRY(GPMC_NBE0_CLE, "g3", "ac12"), + _OMAP3_BALLENTRY(GPMC_NBE1, "u3", NULL), + _OMAP3_BALLENTRY(GPMC_NCS1, "h3", "y1"), + _OMAP3_BALLENTRY(GPMC_NCS2, "v8", NULL), + _OMAP3_BALLENTRY(GPMC_NCS3, "u8", NULL), + _OMAP3_BALLENTRY(GPMC_NCS4, "t8", NULL), + _OMAP3_BALLENTRY(GPMC_NCS5, "r8", NULL), + _OMAP3_BALLENTRY(GPMC_NCS6, "p8", NULL), + _OMAP3_BALLENTRY(GPMC_NCS7, "n8", NULL), + _OMAP3_BALLENTRY(GPMC_NWP, "h1", "ab10"), + _OMAP3_BALLENTRY(GPMC_WAIT1, "l8", "ac10"), + _OMAP3_BALLENTRY(GPMC_WAIT2, "k8", NULL), + _OMAP3_BALLENTRY(GPMC_WAIT3, "j8", NULL), + _OMAP3_BALLENTRY(HDQ_SIO, "j25", NULL), + _OMAP3_BALLENTRY(HSUSB0_CLK, "t28", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA0, "t27", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA1, "u28", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA2, "u27", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA3, "u26", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA4, "u25", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA5, "v28", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA6, "v27", NULL), + _OMAP3_BALLENTRY(HSUSB0_DATA7, "v26", NULL), + _OMAP3_BALLENTRY(HSUSB0_DIR, "r28", NULL), + _OMAP3_BALLENTRY(HSUSB0_NXT, "t26", NULL), + _OMAP3_BALLENTRY(HSUSB0_STP, "t25", NULL), + _OMAP3_BALLENTRY(I2C2_SCL, "af15", NULL), + _OMAP3_BALLENTRY(I2C2_SDA, "ae15", NULL), + _OMAP3_BALLENTRY(I2C3_SCL, "af14", NULL), + _OMAP3_BALLENTRY(I2C3_SDA, "ag14", NULL), + _OMAP3_BALLENTRY(I2C4_SCL, "ad26", NULL), + _OMAP3_BALLENTRY(I2C4_SDA, "ae26", NULL), + _OMAP3_BALLENTRY(JTAG_EMU0, "aa11", NULL), + _OMAP3_BALLENTRY(JTAG_EMU1, "aa10", NULL), + _OMAP3_BALLENTRY(MCBSP1_CLKR, "y21", NULL), + _OMAP3_BALLENTRY(MCBSP1_CLKX, "w21", NULL), + _OMAP3_BALLENTRY(MCBSP1_DR, "u21", NULL), + _OMAP3_BALLENTRY(MCBSP1_DX, "v21", NULL), + _OMAP3_BALLENTRY(MCBSP1_FSR, "aa21", NULL), + _OMAP3_BALLENTRY(MCBSP1_FSX, "k26", NULL), + _OMAP3_BALLENTRY(MCBSP2_CLKX, "n21", NULL), + _OMAP3_BALLENTRY(MCBSP2_DR, "r21", NULL), + _OMAP3_BALLENTRY(MCBSP2_DX, "m21", NULL), + _OMAP3_BALLENTRY(MCBSP2_FSX, "p21", NULL), + _OMAP3_BALLENTRY(MCBSP3_CLKX, "af5", NULL), + _OMAP3_BALLENTRY(MCBSP3_DR, "ae6", NULL), + _OMAP3_BALLENTRY(MCBSP3_DX, "af6", NULL), + _OMAP3_BALLENTRY(MCBSP3_FSX, "ae5", NULL), + _OMAP3_BALLENTRY(MCBSP4_CLKX, "ae1", NULL), + _OMAP3_BALLENTRY(MCBSP4_DR, "ad1", NULL), + _OMAP3_BALLENTRY(MCBSP4_DX, "ad2", NULL), + _OMAP3_BALLENTRY(MCBSP4_FSX, "ac1", NULL), + _OMAP3_BALLENTRY(MCBSP_CLKS, "t21", NULL), + _OMAP3_BALLENTRY(MCSPI1_CLK, "ab3", NULL), + _OMAP3_BALLENTRY(MCSPI1_CS0, "ac2", NULL), + _OMAP3_BALLENTRY(MCSPI1_CS1, "ac3", NULL), + _OMAP3_BALLENTRY(MCSPI1_CS2, "ab1", NULL), + _OMAP3_BALLENTRY(MCSPI1_CS3, "ab2", NULL), + _OMAP3_BALLENTRY(MCSPI1_SIMO, "ab4", NULL), + _OMAP3_BALLENTRY(MCSPI1_SOMI, "aa4", NULL), + _OMAP3_BALLENTRY(MCSPI2_CLK, "aa3", NULL), + _OMAP3_BALLENTRY(MCSPI2_CS0, "y4", NULL), + _OMAP3_BALLENTRY(MCSPI2_CS1, "v3", NULL), + _OMAP3_BALLENTRY(MCSPI2_SIMO, "y2", NULL), + _OMAP3_BALLENTRY(MCSPI2_SOMI, "y3", NULL), + _OMAP3_BALLENTRY(SDMMC1_CLK, "n28", NULL), + _OMAP3_BALLENTRY(SDMMC1_CMD, "m27", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT0, "n27", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT1, "n26", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT2, "n25", NULL), + _OMAP3_BALLENTRY(SDMMC1_DAT3, "p28", NULL), + _OMAP3_BALLENTRY(SDMMC2_CLK, "ae2", NULL), + _OMAP3_BALLENTRY(SDMMC2_CMD, "ag5", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT0, "ah5", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT1, "ah4", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT2, "ag4", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT3, "af4", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT4, "ae4", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT5, "ah3", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT6, "af3", NULL), + _OMAP3_BALLENTRY(SDMMC2_DAT7, "ae3", NULL), + _OMAP3_BALLENTRY(SDRC_CKE0, "h16", "j22"), + _OMAP3_BALLENTRY(SDRC_CKE1, "h17", "j23"), + _OMAP3_BALLENTRY(SIM_CLK, "p26", NULL), + _OMAP3_BALLENTRY(SIM_IO, "p27", NULL), + _OMAP3_BALLENTRY(SIM_PWRCTRL, "r27", NULL), + _OMAP3_BALLENTRY(SIM_RST, "r25", NULL), + _OMAP3_BALLENTRY(SYS_BOOT0, "ah26", NULL), + _OMAP3_BALLENTRY(SYS_BOOT1, "ag26", NULL), + _OMAP3_BALLENTRY(SYS_BOOT2, "ae14", NULL), + _OMAP3_BALLENTRY(SYS_BOOT3, "af18", NULL), + _OMAP3_BALLENTRY(SYS_BOOT4, "af19", NULL), + _OMAP3_BALLENTRY(SYS_BOOT5, "ae21", NULL), + _OMAP3_BALLENTRY(SYS_BOOT6, "af21", NULL), + _OMAP3_BALLENTRY(SYS_CLKOUT1, "ag25", NULL), + _OMAP3_BALLENTRY(SYS_CLKOUT2, "ae22", NULL), + _OMAP3_BALLENTRY(SYS_CLKREQ, "af25", NULL), + _OMAP3_BALLENTRY(SYS_NIRQ, "af26", NULL), + _OMAP3_BALLENTRY(SYS_NRESWARM, "af24", NULL), + _OMAP3_BALLENTRY(SYS_OFF_MODE, "af22", NULL), + _OMAP3_BALLENTRY(UART1_CTS, "w8", NULL), + _OMAP3_BALLENTRY(UART1_RTS, "aa9", NULL), + _OMAP3_BALLENTRY(UART1_RX, "y8", NULL), + _OMAP3_BALLENTRY(UART1_TX, "aa8", NULL), + _OMAP3_BALLENTRY(UART2_CTS, "ab26", NULL), + _OMAP3_BALLENTRY(UART2_RTS, "ab25", NULL), + _OMAP3_BALLENTRY(UART2_RX, "ad25", NULL), + _OMAP3_BALLENTRY(UART2_TX, "aa25", NULL), + _OMAP3_BALLENTRY(UART3_CTS_RCTX, "h18", NULL), + _OMAP3_BALLENTRY(UART3_RTS_SD, "h19", NULL), + _OMAP3_BALLENTRY(UART3_RX_IRRX, "h20", NULL), + _OMAP3_BALLENTRY(UART3_TX_IRTX, "h21", NULL), + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#else +#define omap36xx_cbp_ball NULL +#endif + +int __init omap3_mux_init(struct omap_board_mux *board_subset, int flags) +{ + struct omap_mux *package_subset; + struct omap_ball *package_balls; + + switch (flags & OMAP_PACKAGE_MASK) { + case OMAP_PACKAGE_CBC: + package_subset = omap3_cbc_subset; + package_balls = omap3_cbc_ball; + break; + case OMAP_PACKAGE_CBB: + package_subset = omap3_cbb_subset; + package_balls = omap3_cbb_ball; + break; + case OMAP_PACKAGE_CUS: + package_subset = omap3_cus_subset; + package_balls = omap3_cus_ball; + break; + case OMAP_PACKAGE_CBP: + package_subset = omap36xx_cbp_subset; + package_balls = omap36xx_cbp_ball; + break; + default: + pr_err("%s Unknown omap package, mux disabled\n", __func__); + return -EINVAL; + } + + return omap_mux_init("core", OMAP_MUX_GPIO_IN_MODE4, + OMAP3_CONTROL_PADCONF_MUX_PBASE, + OMAP3_CONTROL_PADCONF_MUX_SIZE, + omap3_muxmodes, package_subset, board_subset, + package_balls); +} diff --git a/arch/arm/mach-omap2/mux34xx.h b/arch/arm/mach-omap2/mux34xx.h new file mode 100644 index 00000000000..3f26d297c08 --- /dev/null +++ b/arch/arm/mach-omap2/mux34xx.h @@ -0,0 +1,402 @@ +/* + * Copyright (C) 2009 Nokia + * Copyright (C) 2009 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#define OMAP3_CONTROL_PADCONF_MUX_PBASE 0x48002030LU + +#define OMAP3_MUX(mode0, mux_value) \ +{ \ + .reg_offset = (OMAP3_CONTROL_PADCONF_##mode0##_OFFSET), \ + .value = (mux_value), \ +} + +/* + * OMAP3 CONTROL_PADCONF* register offsets for pin-muxing + * + * Extracted from the TRM. Add 0x48002030 to these values to get the + * absolute addresses. The name in the macro is the mode-0 name of + * the pin. NOTE: These registers are 16-bits wide. + * + * Note that 34XX TRM uses MMC instead of SDMMC and SAD2D instead + * of CHASSIS for some registers. For the defines, we follow the + * 36XX naming, and use SDMMC and CHASSIS. + */ +#define OMAP3_CONTROL_PADCONF_SDRC_D0_OFFSET 0x000 +#define OMAP3_CONTROL_PADCONF_SDRC_D1_OFFSET 0x002 +#define OMAP3_CONTROL_PADCONF_SDRC_D2_OFFSET 0x004 +#define OMAP3_CONTROL_PADCONF_SDRC_D3_OFFSET 0x006 +#define OMAP3_CONTROL_PADCONF_SDRC_D4_OFFSET 0x008 +#define OMAP3_CONTROL_PADCONF_SDRC_D5_OFFSET 0x00a +#define OMAP3_CONTROL_PADCONF_SDRC_D6_OFFSET 0x00c +#define OMAP3_CONTROL_PADCONF_SDRC_D7_OFFSET 0x00e +#define OMAP3_CONTROL_PADCONF_SDRC_D8_OFFSET 0x010 +#define OMAP3_CONTROL_PADCONF_SDRC_D9_OFFSET 0x012 +#define OMAP3_CONTROL_PADCONF_SDRC_D10_OFFSET 0x014 +#define OMAP3_CONTROL_PADCONF_SDRC_D11_OFFSET 0x016 +#define OMAP3_CONTROL_PADCONF_SDRC_D12_OFFSET 0x018 +#define OMAP3_CONTROL_PADCONF_SDRC_D13_OFFSET 0x01a +#define OMAP3_CONTROL_PADCONF_SDRC_D14_OFFSET 0x01c +#define OMAP3_CONTROL_PADCONF_SDRC_D15_OFFSET 0x01e +#define OMAP3_CONTROL_PADCONF_SDRC_D16_OFFSET 0x020 +#define OMAP3_CONTROL_PADCONF_SDRC_D17_OFFSET 0x022 +#define OMAP3_CONTROL_PADCONF_SDRC_D18_OFFSET 0x024 +#define OMAP3_CONTROL_PADCONF_SDRC_D19_OFFSET 0x026 +#define OMAP3_CONTROL_PADCONF_SDRC_D20_OFFSET 0x028 +#define OMAP3_CONTROL_PADCONF_SDRC_D21_OFFSET 0x02a +#define OMAP3_CONTROL_PADCONF_SDRC_D22_OFFSET 0x02c +#define OMAP3_CONTROL_PADCONF_SDRC_D23_OFFSET 0x02e +#define OMAP3_CONTROL_PADCONF_SDRC_D24_OFFSET 0x030 +#define OMAP3_CONTROL_PADCONF_SDRC_D25_OFFSET 0x032 +#define OMAP3_CONTROL_PADCONF_SDRC_D26_OFFSET 0x034 +#define OMAP3_CONTROL_PADCONF_SDRC_D27_OFFSET 0x036 +#define OMAP3_CONTROL_PADCONF_SDRC_D28_OFFSET 0x038 +#define OMAP3_CONTROL_PADCONF_SDRC_D29_OFFSET 0x03a +#define OMAP3_CONTROL_PADCONF_SDRC_D30_OFFSET 0x03c +#define OMAP3_CONTROL_PADCONF_SDRC_D31_OFFSET 0x03e +#define OMAP3_CONTROL_PADCONF_SDRC_CLK_OFFSET 0x040 +#define OMAP3_CONTROL_PADCONF_SDRC_DQS0_OFFSET 0x042 +#define OMAP3_CONTROL_PADCONF_SDRC_DQS1_OFFSET 0x044 +#define OMAP3_CONTROL_PADCONF_SDRC_DQS2_OFFSET 0x046 +#define OMAP3_CONTROL_PADCONF_SDRC_DQS3_OFFSET 0x048 +#define OMAP3_CONTROL_PADCONF_GPMC_A1_OFFSET 0x04a +#define OMAP3_CONTROL_PADCONF_GPMC_A2_OFFSET 0x04c +#define OMAP3_CONTROL_PADCONF_GPMC_A3_OFFSET 0x04e +#define OMAP3_CONTROL_PADCONF_GPMC_A4_OFFSET 0x050 +#define OMAP3_CONTROL_PADCONF_GPMC_A5_OFFSET 0x052 +#define OMAP3_CONTROL_PADCONF_GPMC_A6_OFFSET 0x054 +#define OMAP3_CONTROL_PADCONF_GPMC_A7_OFFSET 0x056 +#define OMAP3_CONTROL_PADCONF_GPMC_A8_OFFSET 0x058 +#define OMAP3_CONTROL_PADCONF_GPMC_A9_OFFSET 0x05a +#define OMAP3_CONTROL_PADCONF_GPMC_A10_OFFSET 0x05c +#define OMAP3_CONTROL_PADCONF_GPMC_D0_OFFSET 0x05e +#define OMAP3_CONTROL_PADCONF_GPMC_D1_OFFSET 0x060 +#define OMAP3_CONTROL_PADCONF_GPMC_D2_OFFSET 0x062 +#define OMAP3_CONTROL_PADCONF_GPMC_D3_OFFSET 0x064 +#define OMAP3_CONTROL_PADCONF_GPMC_D4_OFFSET 0x066 +#define OMAP3_CONTROL_PADCONF_GPMC_D5_OFFSET 0x068 +#define OMAP3_CONTROL_PADCONF_GPMC_D6_OFFSET 0x06a +#define OMAP3_CONTROL_PADCONF_GPMC_D7_OFFSET 0x06c +#define OMAP3_CONTROL_PADCONF_GPMC_D8_OFFSET 0x06e +#define OMAP3_CONTROL_PADCONF_GPMC_D9_OFFSET 0x070 +#define OMAP3_CONTROL_PADCONF_GPMC_D10_OFFSET 0x072 +#define OMAP3_CONTROL_PADCONF_GPMC_D11_OFFSET 0x074 +#define OMAP3_CONTROL_PADCONF_GPMC_D12_OFFSET 0x076 +#define OMAP3_CONTROL_PADCONF_GPMC_D13_OFFSET 0x078 +#define OMAP3_CONTROL_PADCONF_GPMC_D14_OFFSET 0x07a +#define OMAP3_CONTROL_PADCONF_GPMC_D15_OFFSET 0x07c +#define OMAP3_CONTROL_PADCONF_GPMC_NCS0_OFFSET 0x07e +#define OMAP3_CONTROL_PADCONF_GPMC_NCS1_OFFSET 0x080 +#define OMAP3_CONTROL_PADCONF_GPMC_NCS2_OFFSET 0x082 +#define OMAP3_CONTROL_PADCONF_GPMC_NCS3_OFFSET 0x084 +#define OMAP3_CONTROL_PADCONF_GPMC_NCS4_OFFSET 0x086 +#define OMAP3_CONTROL_PADCONF_GPMC_NCS5_OFFSET 0x088 +#define OMAP3_CONTROL_PADCONF_GPMC_NCS6_OFFSET 0x08a +#define OMAP3_CONTROL_PADCONF_GPMC_NCS7_OFFSET 0x08c +#define OMAP3_CONTROL_PADCONF_GPMC_CLK_OFFSET 0x08e +#define OMAP3_CONTROL_PADCONF_GPMC_NADV_ALE_OFFSET 0x090 +#define OMAP3_CONTROL_PADCONF_GPMC_NOE_OFFSET 0x092 +#define OMAP3_CONTROL_PADCONF_GPMC_NWE_OFFSET 0x094 +#define OMAP3_CONTROL_PADCONF_GPMC_NBE0_CLE_OFFSET 0x096 +#define OMAP3_CONTROL_PADCONF_GPMC_NBE1_OFFSET 0x098 +#define OMAP3_CONTROL_PADCONF_GPMC_NWP_OFFSET 0x09a +#define OMAP3_CONTROL_PADCONF_GPMC_WAIT0_OFFSET 0x09c +#define OMAP3_CONTROL_PADCONF_GPMC_WAIT1_OFFSET 0x09e +#define OMAP3_CONTROL_PADCONF_GPMC_WAIT2_OFFSET 0x0a0 +#define OMAP3_CONTROL_PADCONF_GPMC_WAIT3_OFFSET 0x0a2 +#define OMAP3_CONTROL_PADCONF_DSS_PCLK_OFFSET 0x0a4 +#define OMAP3_CONTROL_PADCONF_DSS_HSYNC_OFFSET 0x0a6 +#define OMAP3_CONTROL_PADCONF_DSS_VSYNC_OFFSET 0x0a8 +#define OMAP3_CONTROL_PADCONF_DSS_ACBIAS_OFFSET 0x0aa +#define OMAP3_CONTROL_PADCONF_DSS_DATA0_OFFSET 0x0ac +#define OMAP3_CONTROL_PADCONF_DSS_DATA1_OFFSET 0x0ae +#define OMAP3_CONTROL_PADCONF_DSS_DATA2_OFFSET 0x0b0 +#define OMAP3_CONTROL_PADCONF_DSS_DATA3_OFFSET 0x0b2 +#define OMAP3_CONTROL_PADCONF_DSS_DATA4_OFFSET 0x0b4 +#define OMAP3_CONTROL_PADCONF_DSS_DATA5_OFFSET 0x0b6 +#define OMAP3_CONTROL_PADCONF_DSS_DATA6_OFFSET 0x0b8 +#define OMAP3_CONTROL_PADCONF_DSS_DATA7_OFFSET 0x0ba +#define OMAP3_CONTROL_PADCONF_DSS_DATA8_OFFSET 0x0bc +#define OMAP3_CONTROL_PADCONF_DSS_DATA9_OFFSET 0x0be +#define OMAP3_CONTROL_PADCONF_DSS_DATA10_OFFSET 0x0c0 +#define OMAP3_CONTROL_PADCONF_DSS_DATA11_OFFSET 0x0c2 +#define OMAP3_CONTROL_PADCONF_DSS_DATA12_OFFSET 0x0c4 +#define OMAP3_CONTROL_PADCONF_DSS_DATA13_OFFSET 0x0c6 +#define OMAP3_CONTROL_PADCONF_DSS_DATA14_OFFSET 0x0c8 +#define OMAP3_CONTROL_PADCONF_DSS_DATA15_OFFSET 0x0ca +#define OMAP3_CONTROL_PADCONF_DSS_DATA16_OFFSET 0x0cc +#define OMAP3_CONTROL_PADCONF_DSS_DATA17_OFFSET 0x0ce +#define OMAP3_CONTROL_PADCONF_DSS_DATA18_OFFSET 0x0d0 +#define OMAP3_CONTROL_PADCONF_DSS_DATA19_OFFSET 0x0d2 +#define OMAP3_CONTROL_PADCONF_DSS_DATA20_OFFSET 0x0d4 +#define OMAP3_CONTROL_PADCONF_DSS_DATA21_OFFSET 0x0d6 +#define OMAP3_CONTROL_PADCONF_DSS_DATA22_OFFSET 0x0d8 +#define OMAP3_CONTROL_PADCONF_DSS_DATA23_OFFSET 0x0da +#define OMAP3_CONTROL_PADCONF_CAM_HS_OFFSET 0x0dc +#define OMAP3_CONTROL_PADCONF_CAM_VS_OFFSET 0x0de +#define OMAP3_CONTROL_PADCONF_CAM_XCLKA_OFFSET 0x0e0 +#define OMAP3_CONTROL_PADCONF_CAM_PCLK_OFFSET 0x0e2 +#define OMAP3_CONTROL_PADCONF_CAM_FLD_OFFSET 0x0e4 +#define OMAP3_CONTROL_PADCONF_CAM_D0_OFFSET 0x0e6 +#define OMAP3_CONTROL_PADCONF_CAM_D1_OFFSET 0x0e8 +#define OMAP3_CONTROL_PADCONF_CAM_D2_OFFSET 0x0ea +#define OMAP3_CONTROL_PADCONF_CAM_D3_OFFSET 0x0ec +#define OMAP3_CONTROL_PADCONF_CAM_D4_OFFSET 0x0ee +#define OMAP3_CONTROL_PADCONF_CAM_D5_OFFSET 0x0f0 +#define OMAP3_CONTROL_PADCONF_CAM_D6_OFFSET 0x0f2 +#define OMAP3_CONTROL_PADCONF_CAM_D7_OFFSET 0x0f4 +#define OMAP3_CONTROL_PADCONF_CAM_D8_OFFSET 0x0f6 +#define OMAP3_CONTROL_PADCONF_CAM_D9_OFFSET 0x0f8 +#define OMAP3_CONTROL_PADCONF_CAM_D10_OFFSET 0x0fa +#define OMAP3_CONTROL_PADCONF_CAM_D11_OFFSET 0x0fc +#define OMAP3_CONTROL_PADCONF_CAM_XCLKB_OFFSET 0x0fe +#define OMAP3_CONTROL_PADCONF_CAM_WEN_OFFSET 0x100 +#define OMAP3_CONTROL_PADCONF_CAM_STROBE_OFFSET 0x102 +#define OMAP3_CONTROL_PADCONF_CSI2_DX0_OFFSET 0x104 +#define OMAP3_CONTROL_PADCONF_CSI2_DY0_OFFSET 0x106 +#define OMAP3_CONTROL_PADCONF_CSI2_DX1_OFFSET 0x108 +#define OMAP3_CONTROL_PADCONF_CSI2_DY1_OFFSET 0x10a +#define OMAP3_CONTROL_PADCONF_MCBSP2_FSX_OFFSET 0x10c +#define OMAP3_CONTROL_PADCONF_MCBSP2_CLKX_OFFSET 0x10e +#define OMAP3_CONTROL_PADCONF_MCBSP2_DR_OFFSET 0x110 +#define OMAP3_CONTROL_PADCONF_MCBSP2_DX_OFFSET 0x112 +#define OMAP3_CONTROL_PADCONF_SDMMC1_CLK_OFFSET 0x114 +#define OMAP3_CONTROL_PADCONF_SDMMC1_CMD_OFFSET 0x116 +#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT0_OFFSET 0x118 +#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT1_OFFSET 0x11a +#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT2_OFFSET 0x11c +#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT3_OFFSET 0x11e + +/* SDMMC1_DAT4 - DAT7 are SIM_IO SIM_CLK SIM_PWRCTRL and SIM_RST on 36xx */ +#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT4_OFFSET 0x120 +#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT5_OFFSET 0x122 +#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT6_OFFSET 0x124 +#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT7_OFFSET 0x126 + +#define OMAP3_CONTROL_PADCONF_SDMMC2_CLK_OFFSET 0x128 +#define OMAP3_CONTROL_PADCONF_SDMMC2_CMD_OFFSET 0x12a +#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT0_OFFSET 0x12c +#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT1_OFFSET 0x12e +#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT2_OFFSET 0x130 +#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT3_OFFSET 0x132 +#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT4_OFFSET 0x134 +#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT5_OFFSET 0x136 +#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT6_OFFSET 0x138 +#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT7_OFFSET 0x13a +#define OMAP3_CONTROL_PADCONF_MCBSP3_DX_OFFSET 0x13c +#define OMAP3_CONTROL_PADCONF_MCBSP3_DR_OFFSET 0x13e +#define OMAP3_CONTROL_PADCONF_MCBSP3_CLKX_OFFSET 0x140 +#define OMAP3_CONTROL_PADCONF_MCBSP3_FSX_OFFSET 0x142 +#define OMAP3_CONTROL_PADCONF_UART2_CTS_OFFSET 0x144 +#define OMAP3_CONTROL_PADCONF_UART2_RTS_OFFSET 0x146 +#define OMAP3_CONTROL_PADCONF_UART2_TX_OFFSET 0x148 +#define OMAP3_CONTROL_PADCONF_UART2_RX_OFFSET 0x14a +#define OMAP3_CONTROL_PADCONF_UART1_TX_OFFSET 0x14c +#define OMAP3_CONTROL_PADCONF_UART1_RTS_OFFSET 0x14e +#define OMAP3_CONTROL_PADCONF_UART1_CTS_OFFSET 0x150 +#define OMAP3_CONTROL_PADCONF_UART1_RX_OFFSET 0x152 +#define OMAP3_CONTROL_PADCONF_MCBSP4_CLKX_OFFSET 0x154 +#define OMAP3_CONTROL_PADCONF_MCBSP4_DR_OFFSET 0x156 +#define OMAP3_CONTROL_PADCONF_MCBSP4_DX_OFFSET 0x158 +#define OMAP3_CONTROL_PADCONF_MCBSP4_FSX_OFFSET 0x15a +#define OMAP3_CONTROL_PADCONF_MCBSP1_CLKR_OFFSET 0x15c +#define OMAP3_CONTROL_PADCONF_MCBSP1_FSR_OFFSET 0x15e +#define OMAP3_CONTROL_PADCONF_MCBSP1_DX_OFFSET 0x160 +#define OMAP3_CONTROL_PADCONF_MCBSP1_DR_OFFSET 0x162 +#define OMAP3_CONTROL_PADCONF_MCBSP_CLKS_OFFSET 0x164 +#define OMAP3_CONTROL_PADCONF_MCBSP1_FSX_OFFSET 0x166 +#define OMAP3_CONTROL_PADCONF_MCBSP1_CLKX_OFFSET 0x168 +#define OMAP3_CONTROL_PADCONF_UART3_CTS_RCTX_OFFSET 0x16a +#define OMAP3_CONTROL_PADCONF_UART3_RTS_SD_OFFSET 0x16c +#define OMAP3_CONTROL_PADCONF_UART3_RX_IRRX_OFFSET 0x16e +#define OMAP3_CONTROL_PADCONF_UART3_TX_IRTX_OFFSET 0x170 +#define OMAP3_CONTROL_PADCONF_HSUSB0_CLK_OFFSET 0x172 +#define OMAP3_CONTROL_PADCONF_HSUSB0_STP_OFFSET 0x174 +#define OMAP3_CONTROL_PADCONF_HSUSB0_DIR_OFFSET 0x176 +#define OMAP3_CONTROL_PADCONF_HSUSB0_NXT_OFFSET 0x178 +#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA0_OFFSET 0x17a +#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA1_OFFSET 0x17c +#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA2_OFFSET 0x17e +#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA3_OFFSET 0x180 +#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA4_OFFSET 0x182 +#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA5_OFFSET 0x184 +#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA6_OFFSET 0x186 +#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA7_OFFSET 0x188 +#define OMAP3_CONTROL_PADCONF_I2C1_SCL_OFFSET 0x18a +#define OMAP3_CONTROL_PADCONF_I2C1_SDA_OFFSET 0x18c +#define OMAP3_CONTROL_PADCONF_I2C2_SCL_OFFSET 0x18e +#define OMAP3_CONTROL_PADCONF_I2C2_SDA_OFFSET 0x190 +#define OMAP3_CONTROL_PADCONF_I2C3_SCL_OFFSET 0x192 +#define OMAP3_CONTROL_PADCONF_I2C3_SDA_OFFSET 0x194 +#define OMAP3_CONTROL_PADCONF_HDQ_SIO_OFFSET 0x196 +#define OMAP3_CONTROL_PADCONF_MCSPI1_CLK_OFFSET 0x198 +#define OMAP3_CONTROL_PADCONF_MCSPI1_SIMO_OFFSET 0x19a +#define OMAP3_CONTROL_PADCONF_MCSPI1_SOMI_OFFSET 0x19c +#define OMAP3_CONTROL_PADCONF_MCSPI1_CS0_OFFSET 0x19e +#define OMAP3_CONTROL_PADCONF_MCSPI1_CS1_OFFSET 0x1a0 +#define OMAP3_CONTROL_PADCONF_MCSPI1_CS2_OFFSET 0x1a2 +#define OMAP3_CONTROL_PADCONF_MCSPI1_CS3_OFFSET 0x1a4 +#define OMAP3_CONTROL_PADCONF_MCSPI2_CLK_OFFSET 0x1a6 +#define OMAP3_CONTROL_PADCONF_MCSPI2_SIMO_OFFSET 0x1a8 +#define OMAP3_CONTROL_PADCONF_MCSPI2_SOMI_OFFSET 0x1aa +#define OMAP3_CONTROL_PADCONF_MCSPI2_CS0_OFFSET 0x1ac +#define OMAP3_CONTROL_PADCONF_MCSPI2_CS1_OFFSET 0x1ae +#define OMAP3_CONTROL_PADCONF_SYS_NIRQ_OFFSET 0x1b0 +#define OMAP3_CONTROL_PADCONF_SYS_CLKOUT2_OFFSET 0x1b2 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD0_OFFSET 0x1b4 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD1_OFFSET 0x1b6 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD2_OFFSET 0x1b8 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD3_OFFSET 0x1ba +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD4_OFFSET 0x1bc +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD5_OFFSET 0x1be +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD6_OFFSET 0x1c0 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD7_OFFSET 0x1c2 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD8_OFFSET 0x1c4 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD9_OFFSET 0x1c6 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD10_OFFSET 0x1c8 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD11_OFFSET 0x1ca +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD12_OFFSET 0x1cc +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD13_OFFSET 0x1ce +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD14_OFFSET 0x1d0 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD15_OFFSET 0x1d2 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD16_OFFSET 0x1d4 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD17_OFFSET 0x1d6 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD18_OFFSET 0x1d8 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD19_OFFSET 0x1da +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD20_OFFSET 0x1dc +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD21_OFFSET 0x1de +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD22_OFFSET 0x1e0 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD23_OFFSET 0x1e2 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD24_OFFSET 0x1e4 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD25_OFFSET 0x1e6 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD26_OFFSET 0x1e8 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD27_OFFSET 0x1ea +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD28_OFFSET 0x1ec +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD29_OFFSET 0x1ee +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD30_OFFSET 0x1f0 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD31_OFFSET 0x1f2 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD32_OFFSET 0x1f4 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD33_OFFSET 0x1f6 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD34_OFFSET 0x1f8 +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD35_OFFSET 0x1fa +#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD36_OFFSET 0x1fc + +/* Note that 34xx TRM has SAD2D instead of CHASSIS for these */ +#define OMAP3_CONTROL_PADCONF_CHASSIS_CLK26MI_OFFSET 0x1fe +#define OMAP3_CONTROL_PADCONF_CHASSIS_NRESPWRON_OFFSET 0x200 +#define OMAP3_CONTROL_PADCONF_CHASSIS_NRESWARW_OFFSET 0x202 +#define OMAP3_CONTROL_PADCONF_CHASSIS_NIRQ_OFFSET 0x204 +#define OMAP3_CONTROL_PADCONF_CHASSIS_FIQ_OFFSET 0x206 +#define OMAP3_CONTROL_PADCONF_CHASSIS_ARMIRQ_OFFSET 0x208 +#define OMAP3_CONTROL_PADCONF_CHASSIS_IVAIRQ_OFFSET 0x20a +#define OMAP3_CONTROL_PADCONF_CHASSIS_DMAREQ0_OFFSET 0x20c +#define OMAP3_CONTROL_PADCONF_CHASSIS_DMAREQ1_OFFSET 0x20e +#define OMAP3_CONTROL_PADCONF_CHASSIS_DMAREQ2_OFFSET 0x210 +#define OMAP3_CONTROL_PADCONF_CHASSIS_DMAREQ3_OFFSET 0x212 +#define OMAP3_CONTROL_PADCONF_CHASSIS_NTRST_OFFSET 0x214 +#define OMAP3_CONTROL_PADCONF_CHASSIS_TDI_OFFSET 0x216 +#define OMAP3_CONTROL_PADCONF_CHASSIS_TDO_OFFSET 0x218 +#define OMAP3_CONTROL_PADCONF_CHASSIS_TMS_OFFSET 0x21a +#define OMAP3_CONTROL_PADCONF_CHASSIS_TCK_OFFSET 0x21c +#define OMAP3_CONTROL_PADCONF_CHASSIS_RTCK_OFFSET 0x21e +#define OMAP3_CONTROL_PADCONF_CHASSIS_MSTDBY_OFFSET 0x220 +#define OMAP3_CONTROL_PADCONF_CHASSIS_IDLEREQ_OFFSET 0x222 +#define OMAP3_CONTROL_PADCONF_CHASSIS_IDLEACK_OFFSET 0x224 + +#define OMAP3_CONTROL_PADCONF_SAD2D_MWRITE_OFFSET 0x226 +#define OMAP3_CONTROL_PADCONF_SAD2D_SWRITE_OFFSET 0x228 +#define OMAP3_CONTROL_PADCONF_SAD2D_MREAD_OFFSET 0x22a +#define OMAP3_CONTROL_PADCONF_SAD2D_SREAD_OFFSET 0x22c +#define OMAP3_CONTROL_PADCONF_SAD2D_MBUSFLAG_OFFSET 0x22e +#define OMAP3_CONTROL_PADCONF_SAD2D_SBUSFLAG_OFFSET 0x230 +#define OMAP3_CONTROL_PADCONF_SDRC_CKE0_OFFSET 0x232 +#define OMAP3_CONTROL_PADCONF_SDRC_CKE1_OFFSET 0x234 + +/* 36xx only */ +#define OMAP3_CONTROL_PADCONF_GPMC_A11_OFFSET 0x236 +#define OMAP3_CONTROL_PADCONF_SDRC_BA0_OFFSET 0x570 +#define OMAP3_CONTROL_PADCONF_SDRC_BA1_OFFSET 0x572 +#define OMAP3_CONTROL_PADCONF_SDRC_A0_OFFSET 0x574 +#define OMAP3_CONTROL_PADCONF_SDRC_A1_OFFSET 0x576 +#define OMAP3_CONTROL_PADCONF_SDRC_A2_OFFSET 0x578 +#define OMAP3_CONTROL_PADCONF_SDRC_A3_OFFSET 0x57a +#define OMAP3_CONTROL_PADCONF_SDRC_A4_OFFSET 0x57c +#define OMAP3_CONTROL_PADCONF_SDRC_A5_OFFSET 0x57e +#define OMAP3_CONTROL_PADCONF_SDRC_A6_OFFSET 0x580 +#define OMAP3_CONTROL_PADCONF_SDRC_A7_OFFSET 0x582 +#define OMAP3_CONTROL_PADCONF_SDRC_A8_OFFSET 0x584 +#define OMAP3_CONTROL_PADCONF_SDRC_A9_OFFSET 0x586 +#define OMAP3_CONTROL_PADCONF_SDRC_A10_OFFSET 0x588 +#define OMAP3_CONTROL_PADCONF_SDRC_A11_OFFSET 0x58a +#define OMAP3_CONTROL_PADCONF_SDRC_A12_OFFSET 0x58c +#define OMAP3_CONTROL_PADCONF_SDRC_A13_OFFSET 0x58e +#define OMAP3_CONTROL_PADCONF_SDRC_A14_OFFSET 0x590 +#define OMAP3_CONTROL_PADCONF_SDRC_NCS0_OFFSET 0x592 +#define OMAP3_CONTROL_PADCONF_SDRC_NCS1_OFFSET 0x594 +#define OMAP3_CONTROL_PADCONF_SDRC_NCLK_OFFSET 0x596 +#define OMAP3_CONTROL_PADCONF_SDRC_NRAS_OFFSET 0x598 +#define OMAP3_CONTROL_PADCONF_SDRC_NCAS_OFFSET 0x59a +#define OMAP3_CONTROL_PADCONF_SDRC_NWE_OFFSET 0x59c +#define OMAP3_CONTROL_PADCONF_SDRC_DM0_OFFSET 0x59e +#define OMAP3_CONTROL_PADCONF_SDRC_DM1_OFFSET 0x5a0 +#define OMAP3_CONTROL_PADCONF_SDRC_DM2_OFFSET 0x5a2 +#define OMAP3_CONTROL_PADCONF_SDRC_DM3_OFFSET 0x5a4 + +/* 36xx only, these are SDMMC1_DAT4 - DAT7 on 34xx */ +#define OMAP3_CONTROL_PADCONF_SIM_IO_OFFSET 0x120 +#define OMAP3_CONTROL_PADCONF_SIM_CLK_OFFSET 0x122 +#define OMAP3_CONTROL_PADCONF_SIM_PWRCTRL_OFFSET 0x124 +#define OMAP3_CONTROL_PADCONF_SIM_RST_OFFSET 0x126 + +#define OMAP3_CONTROL_PADCONF_ETK_CLK_OFFSET 0x5a8 +#define OMAP3_CONTROL_PADCONF_ETK_CTL_OFFSET 0x5aa +#define OMAP3_CONTROL_PADCONF_ETK_D0_OFFSET 0x5ac +#define OMAP3_CONTROL_PADCONF_ETK_D1_OFFSET 0x5ae +#define OMAP3_CONTROL_PADCONF_ETK_D2_OFFSET 0x5b0 +#define OMAP3_CONTROL_PADCONF_ETK_D3_OFFSET 0x5b2 +#define OMAP3_CONTROL_PADCONF_ETK_D4_OFFSET 0x5b4 +#define OMAP3_CONTROL_PADCONF_ETK_D5_OFFSET 0x5b6 +#define OMAP3_CONTROL_PADCONF_ETK_D6_OFFSET 0x5b8 +#define OMAP3_CONTROL_PADCONF_ETK_D7_OFFSET 0x5ba +#define OMAP3_CONTROL_PADCONF_ETK_D8_OFFSET 0x5bc +#define OMAP3_CONTROL_PADCONF_ETK_D9_OFFSET 0x5be +#define OMAP3_CONTROL_PADCONF_ETK_D10_OFFSET 0x5c0 +#define OMAP3_CONTROL_PADCONF_ETK_D11_OFFSET 0x5c2 +#define OMAP3_CONTROL_PADCONF_ETK_D12_OFFSET 0x5c4 +#define OMAP3_CONTROL_PADCONF_ETK_D13_OFFSET 0x5c6 +#define OMAP3_CONTROL_PADCONF_ETK_D14_OFFSET 0x5c8 +#define OMAP3_CONTROL_PADCONF_ETK_D15_OFFSET 0x5ca +#define OMAP3_CONTROL_PADCONF_I2C4_SCL_OFFSET 0x9d0 +#define OMAP3_CONTROL_PADCONF_I2C4_SDA_OFFSET 0x9d2 +#define OMAP3_CONTROL_PADCONF_SYS_32K_OFFSET 0x9d4 +#define OMAP3_CONTROL_PADCONF_SYS_CLKREQ_OFFSET 0x9d6 +#define OMAP3_CONTROL_PADCONF_SYS_NRESWARM_OFFSET 0x9d8 +#define OMAP3_CONTROL_PADCONF_SYS_BOOT0_OFFSET 0x9da +#define OMAP3_CONTROL_PADCONF_SYS_BOOT1_OFFSET 0x9dc +#define OMAP3_CONTROL_PADCONF_SYS_BOOT2_OFFSET 0x9de +#define OMAP3_CONTROL_PADCONF_SYS_BOOT3_OFFSET 0x9e0 +#define OMAP3_CONTROL_PADCONF_SYS_BOOT4_OFFSET 0x9e2 +#define OMAP3_CONTROL_PADCONF_SYS_BOOT5_OFFSET 0x9e4 +#define OMAP3_CONTROL_PADCONF_SYS_BOOT6_OFFSET 0x9e6 +#define OMAP3_CONTROL_PADCONF_SYS_OFF_MODE_OFFSET 0x9e8 +#define OMAP3_CONTROL_PADCONF_SYS_CLKOUT1_OFFSET 0x9ea +#define OMAP3_CONTROL_PADCONF_JTAG_NTRST_OFFSET 0x9ec +#define OMAP3_CONTROL_PADCONF_JTAG_TCK_OFFSET 0x9ee +#define OMAP3_CONTROL_PADCONF_JTAG_TMS_TMSC_OFFSET 0x9f0 +#define OMAP3_CONTROL_PADCONF_JTAG_TDI_OFFSET 0x9f2 +#define OMAP3_CONTROL_PADCONF_JTAG_EMU0_OFFSET 0x9f4 +#define OMAP3_CONTROL_PADCONF_JTAG_EMU1_OFFSET 0x9f6 +#define OMAP3_CONTROL_PADCONF_SAD2D_SWAKEUP_OFFSET 0xa1c +#define OMAP3_CONTROL_PADCONF_JTAG_RTCK_OFFSET 0xa1e +#define OMAP3_CONTROL_PADCONF_JTAG_TDO_OFFSET 0xa20 +#define OMAP3_CONTROL_PADCONF_GPIO_127 0xa24 +#define OMAP3_CONTROL_PADCONF_GPIO_126 0xa26 +#define OMAP3_CONTROL_PADCONF_GPIO_128 0xa28 +#define OMAP3_CONTROL_PADCONF_GPIO_129 0xa2a + +#define OMAP3_CONTROL_PADCONF_MUX_SIZE \ + (OMAP3_CONTROL_PADCONF_GPIO_129 + 0x2) diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S new file mode 100644 index 00000000000..4993d4bfe9b --- /dev/null +++ b/arch/arm/mach-omap2/omap-headsmp.S @@ -0,0 +1,102 @@ +/* + * Secondary CPU startup routine source file. + * + * Copyright (C) 2009-2014 Texas Instruments, Inc. + * + * Author: + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * Interface functions needed for the SMP. This file is based on arm + * realview smp platform. + * Copyright (c) 2003 ARM Limited. + * + * This program is free software,you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/linkage.h> +#include <linux/init.h> + +#include "omap44xx.h" + +/* Physical address needed since MMU not enabled yet on secondary core */ +#define AUX_CORE_BOOT0_PA 0x48281800 + +/* + * OMAP5 specific entry point for secondary CPU to jump from ROM + * code. This routine also provides a holding flag into which + * secondary core is held until we're ready for it to initialise. + * The primary core will update this flag using a hardware + * register AuxCoreBoot0. + */ +ENTRY(omap5_secondary_startup) +wait: ldr r2, =AUX_CORE_BOOT0_PA @ read from AuxCoreBoot0 + ldr r0, [r2] + mov r0, r0, lsr #5 + mrc p15, 0, r4, c0, c0, 5 + and r4, r4, #0x0f + cmp r0, r4 + bne wait + b secondary_startup +ENDPROC(omap5_secondary_startup) +/* + * OMAP4 specific entry point for secondary CPU to jump from ROM + * code. This routine also provides a holding flag into which + * secondary core is held until we're ready for it to initialise. + * The primary core will update this flag using a hardware + * register AuxCoreBoot0. + */ +ENTRY(omap4_secondary_startup) +hold: ldr r12,=0x103 + dsb + smc #0 @ read from AuxCoreBoot0 + mov r0, r0, lsr #9 + mrc p15, 0, r4, c0, c0, 5 + and r4, r4, #0x0f + cmp r0, r4 + bne hold + + /* + * we've been released from the wait loop,secondary_stack + * should now contain the SVC stack for this core + */ + b secondary_startup +ENDPROC(omap4_secondary_startup) + +ENTRY(omap4460_secondary_startup) +hold_2: ldr r12,=0x103 + dsb + smc #0 @ read from AuxCoreBoot0 + mov r0, r0, lsr #9 + mrc p15, 0, r4, c0, c0, 5 + and r4, r4, #0x0f + cmp r0, r4 + bne hold_2 + + /* + * GIC distributor control register has changed between + * CortexA9 r1pX and r2pX. The Control Register secure + * banked version is now composed of 2 bits: + * bit 0 == Secure Enable + * bit 1 == Non-Secure Enable + * The Non-Secure banked register has not changed + * Because the ROM Code is based on the r1pX GIC, the CPU1 + * GIC restoration will cause a problem to CPU0 Non-Secure SW. + * The workaround must be: + * 1) Before doing the CPU1 wakeup, CPU0 must disable + * the GIC distributor + * 2) CPU1 must re-enable the GIC distributor on + * it's wakeup path. + */ + ldr r1, =OMAP44XX_GIC_DIST_BASE + ldr r0, [r1] + orr r0, #1 + str r0, [r1] + + /* + * we've been released from the wait loop,secondary_stack + * should now contain the SVC stack for this core + */ + b secondary_startup +ENDPROC(omap4460_secondary_startup) diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c new file mode 100644 index 00000000000..971791fe9a3 --- /dev/null +++ b/arch/arm/mach-omap2/omap-hotplug.c @@ -0,0 +1,66 @@ +/* + * OMAP4 SMP cpu-hotplug support + * + * Copyright (C) 2010 Texas Instruments, Inc. + * Author: + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * Platform file needed for the OMAP4 SMP. This file is based on arm + * realview smp platform. + * Copyright (c) 2002 ARM Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/smp.h> +#include <linux/io.h> + +#include "omap-wakeupgen.h" +#include "common.h" +#include "powerdomain.h" + +/* + * platform-specific code to shutdown a CPU + * Called with IRQs disabled + */ +void __ref omap4_cpu_die(unsigned int cpu) +{ + unsigned int boot_cpu = 0; + void __iomem *base = omap_get_wakeupgen_base(); + + /* + * we're ready for shutdown now, so do it + */ + if (omap_secure_apis_support()) { + if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0) + pr_err("Secure clear status failed\n"); + } else { + writel_relaxed(0, base + OMAP_AUX_CORE_BOOT_0); + } + + + for (;;) { + /* + * Enter into low power state + */ + omap4_hotplug_cpu(cpu, PWRDM_POWER_OFF); + + if (omap_secure_apis_support()) + boot_cpu = omap_read_auxcoreboot0(); + else + boot_cpu = + readl_relaxed(base + OMAP_AUX_CORE_BOOT_0) >> 5; + + if (boot_cpu == smp_processor_id()) { + /* + * OK, proper wakeup, we're done + */ + break; + } + pr_debug("CPU%u: spurious wakeup call\n", cpu); + } +} diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c new file mode 100644 index 00000000000..f1fab5684a2 --- /dev/null +++ b/arch/arm/mach-omap2/omap-iommu.c @@ -0,0 +1,79 @@ +/* + * omap iommu: omap device registration + * + * Copyright (C) 2008-2009 Nokia Corporation + * + * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/of.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/err.h> +#include <linux/slab.h> + +#include <linux/platform_data/iommu-omap.h> +#include "soc.h" +#include "omap_hwmod.h" +#include "omap_device.h" + +static int __init omap_iommu_dev_init(struct omap_hwmod *oh, void *unused) +{ + struct platform_device *pdev; + struct iommu_platform_data *pdata; + struct omap_mmu_dev_attr *a = (struct omap_mmu_dev_attr *)oh->dev_attr; + static int i; + + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + pdata->name = oh->name; + pdata->nr_tlb_entries = a->nr_tlb_entries; + pdata->da_start = a->da_start; + pdata->da_end = a->da_end; + + if (oh->rst_lines_cnt == 1) { + pdata->reset_name = oh->rst_lines->name; + pdata->assert_reset = omap_device_assert_hardreset; + pdata->deassert_reset = omap_device_deassert_hardreset; + } + + pdev = omap_device_build("omap-iommu", i, oh, pdata, sizeof(*pdata)); + + kfree(pdata); + + if (IS_ERR(pdev)) { + pr_err("%s: device build err: %ld\n", __func__, PTR_ERR(pdev)); + return PTR_ERR(pdev); + } + + i++; + + return 0; +} + +static int __init omap_iommu_init(void) +{ + /* If dtb is there, the devices will be created dynamically */ + if (of_have_populated_dt()) + return -ENODEV; + + return omap_hwmod_for_each_by_class("mmu", omap_iommu_dev_init, NULL); +} +/* must be ready before omap3isp is probed */ +omap_subsys_initcall(omap_iommu_init); + +static void __exit omap_iommu_exit(void) +{ + /* Do nothing */ +} +module_exit(omap_iommu_exit); + +MODULE_AUTHOR("Hiroshi DOYU"); +MODULE_DESCRIPTION("omap iommu: omap device registration"); +MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c new file mode 100644 index 00000000000..4001325f90f --- /dev/null +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -0,0 +1,400 @@ +/* + * OMAP MPUSS low power code + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * OMAP4430 MPUSS mainly consists of dual Cortex-A9 with per-CPU + * Local timer and Watchdog, GIC, SCU, PL310 L2 cache controller, + * CPU0 and CPU1 LPRM modules. + * CPU0, CPU1 and MPUSS each have there own power domain and + * hence multiple low power combinations of MPUSS are possible. + * + * The CPU0 and CPU1 can't support Closed switch Retention (CSWR) + * because the mode is not supported by hw constraints of dormant + * mode. While waking up from the dormant mode, a reset signal + * to the Cortex-A9 processor must be asserted by the external + * power controller. + * + * With architectural inputs and hardware recommendations, only + * below modes are supported from power gain vs latency point of view. + * + * CPU0 CPU1 MPUSS + * ---------------------------------------------- + * ON ON ON + * ON(Inactive) OFF ON(Inactive) + * OFF OFF CSWR + * OFF OFF OSWR + * OFF OFF OFF(Device OFF *TBD) + * ---------------------------------------------- + * + * Note: CPU0 is the master core and it is the last CPU to go down + * and first to wake-up when MPUSS low power states are excercised + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/errno.h> +#include <linux/linkage.h> +#include <linux/smp.h> + +#include <asm/cacheflush.h> +#include <asm/tlbflush.h> +#include <asm/smp_scu.h> +#include <asm/pgalloc.h> +#include <asm/suspend.h> +#include <asm/hardware/cache-l2x0.h> + +#include "soc.h" +#include "common.h" +#include "omap44xx.h" +#include "omap4-sar-layout.h" +#include "pm.h" +#include "prcm_mpu44xx.h" +#include "prminst44xx.h" +#include "prcm44xx.h" +#include "prm44xx.h" +#include "prm-regbits-44xx.h" + +#ifdef CONFIG_SMP + +struct omap4_cpu_pm_info { + struct powerdomain *pwrdm; + void __iomem *scu_sar_addr; + void __iomem *wkup_sar_addr; + void __iomem *l2x0_sar_addr; + void (*secondary_startup)(void); +}; + +/** + * struct cpu_pm_ops - CPU pm operations + * @finish_suspend: CPU suspend finisher function pointer + * @resume: CPU resume function pointer + * @scu_prepare: CPU Snoop Control program function pointer + * + * Structure holds functions pointer for CPU low power operations like + * suspend, resume and scu programming. + */ +struct cpu_pm_ops { + int (*finish_suspend)(unsigned long cpu_state); + void (*resume)(void); + void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state); +}; + +static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); +static struct powerdomain *mpuss_pd; +static void __iomem *sar_base; + +static int default_finish_suspend(unsigned long cpu_state) +{ + omap_do_wfi(); + return 0; +} + +static void dummy_cpu_resume(void) +{} + +static void dummy_scu_prepare(unsigned int cpu_id, unsigned int cpu_state) +{} + +struct cpu_pm_ops omap_pm_ops = { + .finish_suspend = default_finish_suspend, + .resume = dummy_cpu_resume, + .scu_prepare = dummy_scu_prepare, +}; + +/* + * Program the wakeup routine address for the CPU0 and CPU1 + * used for OFF or DORMANT wakeup. + */ +static inline void set_cpu_wakeup_addr(unsigned int cpu_id, u32 addr) +{ + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); + + writel_relaxed(addr, pm_info->wkup_sar_addr); +} + +/* + * Store the SCU power status value to scratchpad memory + */ +static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state) +{ + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); + u32 scu_pwr_st; + + switch (cpu_state) { + case PWRDM_POWER_RET: + scu_pwr_st = SCU_PM_DORMANT; + break; + case PWRDM_POWER_OFF: + scu_pwr_st = SCU_PM_POWEROFF; + break; + case PWRDM_POWER_ON: + case PWRDM_POWER_INACTIVE: + default: + scu_pwr_st = SCU_PM_NORMAL; + break; + } + + writel_relaxed(scu_pwr_st, pm_info->scu_sar_addr); +} + +/* Helper functions for MPUSS OSWR */ +static inline void mpuss_clear_prev_logic_pwrst(void) +{ + u32 reg; + + reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, + OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET); + omap4_prminst_write_inst_reg(reg, OMAP4430_PRM_PARTITION, + OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET); +} + +static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id) +{ + u32 reg; + + if (cpu_id) { + reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU1_INST, + OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET); + omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU1_INST, + OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET); + } else { + reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU0_INST, + OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET); + omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU0_INST, + OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET); + } +} + +/* + * Store the CPU cluster state for L2X0 low power operations. + */ +static void l2x0_pwrst_prepare(unsigned int cpu_id, unsigned int save_state) +{ + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); + + writel_relaxed(save_state, pm_info->l2x0_sar_addr); +} + +/* + * Save the L2X0 AUXCTRL and POR value to SAR memory. Its used to + * in every restore MPUSS OFF path. + */ +#ifdef CONFIG_CACHE_L2X0 +static void __init save_l2x0_context(void) +{ + writel_relaxed(l2x0_saved_regs.aux_ctrl, + sar_base + L2X0_AUXCTRL_OFFSET); + writel_relaxed(l2x0_saved_regs.prefetch_ctrl, + sar_base + L2X0_PREFETCH_CTRL_OFFSET); +} +#else +static void __init save_l2x0_context(void) +{} +#endif + +/** + * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function + * The purpose of this function is to manage low power programming + * of OMAP4 MPUSS subsystem + * @cpu : CPU ID + * @power_state: Low power state. + * + * MPUSS states for the context save: + * save_state = + * 0 - Nothing lost and no need to save: MPUSS INACTIVE + * 1 - CPUx L1 and logic lost: MPUSS CSWR + * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR + * 3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF + */ +int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) +{ + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); + unsigned int save_state = 0; + unsigned int wakeup_cpu; + + if (omap_rev() == OMAP4430_REV_ES1_0) + return -ENXIO; + + switch (power_state) { + case PWRDM_POWER_ON: + case PWRDM_POWER_INACTIVE: + save_state = 0; + break; + case PWRDM_POWER_OFF: + save_state = 1; + break; + case PWRDM_POWER_RET: + default: + /* + * CPUx CSWR is invalid hardware state. Also CPUx OSWR + * doesn't make much scense, since logic is lost and $L1 + * needs to be cleaned because of coherency. This makes + * CPUx OSWR equivalent to CPUX OFF and hence not supported + */ + WARN_ON(1); + return -ENXIO; + } + + pwrdm_pre_transition(NULL); + + /* + * Check MPUSS next state and save interrupt controller if needed. + * In MPUSS OSWR or device OFF, interrupt controller contest is lost. + */ + mpuss_clear_prev_logic_pwrst(); + if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) && + (pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF)) + save_state = 2; + + cpu_clear_prev_logic_pwrst(cpu); + pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); + set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.resume)); + omap_pm_ops.scu_prepare(cpu, power_state); + l2x0_pwrst_prepare(cpu, save_state); + + /* + * Call low level function with targeted low power state. + */ + if (save_state) + cpu_suspend(save_state, omap_pm_ops.finish_suspend); + else + omap_pm_ops.finish_suspend(save_state); + + if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD) && cpu) + gic_dist_enable(); + + /* + * Restore the CPUx power state to ON otherwise CPUx + * power domain can transitions to programmed low power + * state while doing WFI outside the low powe code. On + * secure devices, CPUx does WFI which can result in + * domain transition + */ + wakeup_cpu = smp_processor_id(); + pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); + + pwrdm_post_transition(NULL); + + return 0; +} + +/** + * omap4_hotplug_cpu: OMAP4 CPU hotplug entry + * @cpu : CPU ID + * @power_state: CPU low power state. + */ +int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) +{ + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); + unsigned int cpu_state = 0; + + if (omap_rev() == OMAP4430_REV_ES1_0) + return -ENXIO; + + if (power_state == PWRDM_POWER_OFF) + cpu_state = 1; + + pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); + pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); + set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); + omap_pm_ops.scu_prepare(cpu, power_state); + + /* + * CPU never retuns back if targeted power state is OFF mode. + * CPU ONLINE follows normal CPU ONLINE ptah via + * omap4_secondary_startup(). + */ + omap_pm_ops.finish_suspend(cpu_state); + + pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); + return 0; +} + + +/* + * Initialise OMAP4 MPUSS + */ +int __init omap4_mpuss_init(void) +{ + struct omap4_cpu_pm_info *pm_info; + + if (omap_rev() == OMAP4430_REV_ES1_0) { + WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); + return -ENODEV; + } + + sar_base = omap4_get_sar_ram_base(); + + /* Initilaise per CPU PM information */ + pm_info = &per_cpu(omap4_pm_info, 0x0); + pm_info->scu_sar_addr = sar_base + SCU_OFFSET0; + pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET; + pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0; + pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm"); + if (!pm_info->pwrdm) { + pr_err("Lookup failed for CPU0 pwrdm\n"); + return -ENODEV; + } + + /* Clear CPU previous power domain state */ + pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); + cpu_clear_prev_logic_pwrst(0); + + /* Initialise CPU0 power domain state to ON */ + pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); + + pm_info = &per_cpu(omap4_pm_info, 0x1); + pm_info->scu_sar_addr = sar_base + SCU_OFFSET1; + pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; + pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; + if (cpu_is_omap446x()) + pm_info->secondary_startup = omap4460_secondary_startup; + else + pm_info->secondary_startup = omap4_secondary_startup; + + pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); + if (!pm_info->pwrdm) { + pr_err("Lookup failed for CPU1 pwrdm\n"); + return -ENODEV; + } + + /* Clear CPU previous power domain state */ + pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); + cpu_clear_prev_logic_pwrst(1); + + /* Initialise CPU1 power domain state to ON */ + pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); + + mpuss_pd = pwrdm_lookup("mpu_pwrdm"); + if (!mpuss_pd) { + pr_err("Failed to lookup MPUSS power domain\n"); + return -ENODEV; + } + pwrdm_clear_all_prev_pwrst(mpuss_pd); + mpuss_clear_prev_logic_pwrst(); + + /* Save device type on scratchpad for low level code to use */ + if (omap_type() != OMAP2_DEVICE_TYPE_GP) + writel_relaxed(1, sar_base + OMAP_TYPE_OFFSET); + else + writel_relaxed(0, sar_base + OMAP_TYPE_OFFSET); + + save_l2x0_context(); + + if (cpu_is_omap44xx()) { + omap_pm_ops.finish_suspend = omap4_finish_suspend; + omap_pm_ops.resume = omap4_cpu_resume; + omap_pm_ops.scu_prepare = scu_pwrst_prepare; + } + + return 0; +} + +#endif diff --git a/arch/arm/mach-omap2/omap-pm-noop.c b/arch/arm/mach-omap2/omap-pm-noop.c new file mode 100644 index 00000000000..6a3be2bebdd --- /dev/null +++ b/arch/arm/mach-omap2/omap-pm-noop.c @@ -0,0 +1,371 @@ +/* + * omap-pm-noop.c - OMAP power management interface - dummy version + * + * This code implements the OMAP power management interface to + * drivers, CPUIdle, CPUFreq, and DSP Bridge. It is strictly for + * debug/demonstration use, as it does nothing but printk() whenever a + * function is called (when DEBUG is defined, below) + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * Copyright (C) 2008-2009 Nokia Corporation + * Paul Walmsley + * + * Interface developed by (in alphabetical order): + * Karthik Dasu, Tony Lindgren, Rajendra Nayak, Sakari Poussa, Veeramanikandan + * Raju, Anand Sawant, Igor Stoppa, Paul Walmsley, Richard Woodruff + */ + +#undef DEBUG + +#include <linux/init.h> +#include <linux/cpufreq.h> +#include <linux/device.h> +#include <linux/platform_device.h> + +#include "omap_device.h" +#include "omap-pm.h" + +static bool off_mode_enabled; +static int dummy_context_loss_counter; + +/* + * Device-driver-originated constraints (via board-*.c files) + */ + +int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t) +{ + if (!dev || t < -1) { + WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__); + return -EINVAL; + } + + if (t == -1) + pr_debug("OMAP PM: remove max MPU wakeup latency constraint: dev %s\n", + dev_name(dev)); + else + pr_debug("OMAP PM: add max MPU wakeup latency constraint: dev %s, t = %ld usec\n", + dev_name(dev), t); + + /* + * For current Linux, this needs to map the MPU to a + * powerdomain, then go through the list of current max lat + * constraints on the MPU and find the smallest. If + * the latency constraint has changed, the code should + * recompute the state to enter for the next powerdomain + * state. + * + * TI CDP code can call constraint_set here. + */ + + return 0; +} + +int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r) +{ + if (!dev || (agent_id != OCP_INITIATOR_AGENT && + agent_id != OCP_TARGET_AGENT)) { + WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__); + return -EINVAL; + } + + if (r == 0) + pr_debug("OMAP PM: remove min bus tput constraint: dev %s for agent_id %d\n", + dev_name(dev), agent_id); + else + pr_debug("OMAP PM: add min bus tput constraint: dev %s for agent_id %d: rate %ld KiB\n", + dev_name(dev), agent_id, r); + + /* + * This code should model the interconnect and compute the + * required clock frequency, convert that to a VDD2 OPP ID, then + * set the VDD2 OPP appropriately. + * + * TI CDP code can call constraint_set here on the VDD2 OPP. + */ + + return 0; +} + +int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev, + long t) +{ + if (!req_dev || !dev || t < -1) { + WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__); + return -EINVAL; + } + + if (t == -1) + pr_debug("OMAP PM: remove max device latency constraint: dev %s\n", + dev_name(dev)); + else + pr_debug("OMAP PM: add max device latency constraint: dev %s, t = %ld usec\n", + dev_name(dev), t); + + /* + * For current Linux, this needs to map the device to a + * powerdomain, then go through the list of current max lat + * constraints on that powerdomain and find the smallest. If + * the latency constraint has changed, the code should + * recompute the state to enter for the next powerdomain + * state. Conceivably, this code should also determine + * whether to actually disable the device clocks or not, + * depending on how long it takes to re-enable the clocks. + * + * TI CDP code can call constraint_set here. + */ + + return 0; +} + +int omap_pm_set_max_sdma_lat(struct device *dev, long t) +{ + if (!dev || t < -1) { + WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__); + return -EINVAL; + } + + if (t == -1) + pr_debug("OMAP PM: remove max DMA latency constraint: dev %s\n", + dev_name(dev)); + else + pr_debug("OMAP PM: add max DMA latency constraint: dev %s, t = %ld usec\n", + dev_name(dev), t); + + /* + * For current Linux PM QOS params, this code should scan the + * list of maximum CPU and DMA latencies and select the + * smallest, then set cpu_dma_latency pm_qos_param + * accordingly. + * + * For future Linux PM QOS params, with separate CPU and DMA + * latency params, this code should just set the dma_latency param. + * + * TI CDP code can call constraint_set here. + */ + + return 0; +} + +int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r) +{ + if (!dev || !c || r < 0) { + WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__); + return -EINVAL; + } + + if (r == 0) + pr_debug("OMAP PM: remove min clk rate constraint: dev %s\n", + dev_name(dev)); + else + pr_debug("OMAP PM: add min clk rate constraint: dev %s, rate = %ld Hz\n", + dev_name(dev), r); + + /* + * Code in a real implementation should keep track of these + * constraints on the clock, and determine the highest minimum + * clock rate. It should iterate over each OPP and determine + * whether the OPP will result in a clock rate that would + * satisfy this constraint (and any other PM constraint in effect + * at that time). Once it finds the lowest-voltage OPP that + * meets those conditions, it should switch to it, or return + * an error if the code is not capable of doing so. + */ + + return 0; +} + +/* + * DSP Bridge-specific constraints + */ + +const struct omap_opp *omap_pm_dsp_get_opp_table(void) +{ + pr_debug("OMAP PM: DSP request for OPP table\n"); + + /* + * Return DSP frequency table here: The final item in the + * array should have .rate = .opp_id = 0. + */ + + return NULL; +} + +void omap_pm_dsp_set_min_opp(u8 opp_id) +{ + if (opp_id == 0) { + WARN_ON(1); + return; + } + + pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id); + + /* + * + * For l-o dev tree, our VDD1 clk is keyed on OPP ID, so we + * can just test to see which is higher, the CPU's desired OPP + * ID or the DSP's desired OPP ID, and use whichever is + * highest. + * + * In CDP12.14+, the VDD1 OPP custom clock that controls the DSP + * rate is keyed on MPU speed, not the OPP ID. So we need to + * map the OPP ID to the MPU speed for use with clk_set_rate() + * if it is higher than the current OPP clock rate. + * + */ +} + + +u8 omap_pm_dsp_get_opp(void) +{ + pr_debug("OMAP PM: DSP requests current DSP OPP ID\n"); + + /* + * For l-o dev tree, call clk_get_rate() on VDD1 OPP clock + * + * CDP12.14+: + * Call clk_get_rate() on the OPP custom clock, map that to an + * OPP ID using the tables defined in board-*.c/chip-*.c files. + */ + + return 0; +} + +/* + * CPUFreq-originated constraint + * + * In the future, this should be handled by custom OPP clocktype + * functions. + */ + +struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void) +{ + pr_debug("OMAP PM: CPUFreq request for frequency table\n"); + + /* + * Return CPUFreq frequency table here: loop over + * all VDD1 clkrates, pull out the mpu_ck frequencies, build + * table + */ + + return NULL; +} + +void omap_pm_cpu_set_freq(unsigned long f) +{ + if (f == 0) { + WARN_ON(1); + return; + } + + pr_debug("OMAP PM: CPUFreq requests CPU frequency to be set to %lu\n", + f); + + /* + * For l-o dev tree, determine whether MPU freq or DSP OPP id + * freq is higher. Find the OPP ID corresponding to the + * higher frequency. Call clk_round_rate() and clk_set_rate() + * on the OPP custom clock. + * + * CDP should just be able to set the VDD1 OPP clock rate here. + */ +} + +unsigned long omap_pm_cpu_get_freq(void) +{ + pr_debug("OMAP PM: CPUFreq requests current CPU frequency\n"); + + /* + * Call clk_get_rate() on the mpu_ck. + */ + + return 0; +} + +/** + * omap_pm_enable_off_mode - notify OMAP PM that off-mode is enabled + * + * Intended for use only by OMAP PM core code to notify this layer + * that off mode has been enabled. + */ +void omap_pm_enable_off_mode(void) +{ + off_mode_enabled = true; +} + +/** + * omap_pm_disable_off_mode - notify OMAP PM that off-mode is disabled + * + * Intended for use only by OMAP PM core code to notify this layer + * that off mode has been disabled. + */ +void omap_pm_disable_off_mode(void) +{ + off_mode_enabled = false; +} + +/* + * Device context loss tracking + */ + +#ifdef CONFIG_ARCH_OMAP2PLUS + +int omap_pm_get_dev_context_loss_count(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + int count; + + if (WARN_ON(!dev)) + return -ENODEV; + + if (dev->pm_domain == &omap_device_pm_domain) { + count = omap_device_get_context_loss_count(pdev); + } else { + WARN_ONCE(off_mode_enabled, "omap_pm: using dummy context loss counter; device %s should be converted to omap_device", + dev_name(dev)); + + count = dummy_context_loss_counter; + + if (off_mode_enabled) { + count++; + /* + * Context loss count has to be a non-negative value. + * Clear the sign bit to get a value range from 0 to + * INT_MAX. + */ + count &= INT_MAX; + dummy_context_loss_counter = count; + } + } + + pr_debug("OMAP PM: context loss count for dev %s = %d\n", + dev_name(dev), count); + + return count; +} + +#else + +int omap_pm_get_dev_context_loss_count(struct device *dev) +{ + return dummy_context_loss_counter; +} + +#endif + +/* Should be called before clk framework init */ +int __init omap_pm_if_early_init(void) +{ + return 0; +} + +/* Must be called after clock framework is initialized */ +int __init omap_pm_if_init(void) +{ + return 0; +} + +void omap_pm_if_exit(void) +{ + /* Deallocate CPUFreq frequency table here */ +} + diff --git a/arch/arm/mach-omap2/omap-pm.h b/arch/arm/mach-omap2/omap-pm.h new file mode 100644 index 00000000000..1d777e63e05 --- /dev/null +++ b/arch/arm/mach-omap2/omap-pm.h @@ -0,0 +1,352 @@ +/* + * omap-pm.h - OMAP power management interface + * + * Copyright (C) 2008-2010 Texas Instruments, Inc. + * Copyright (C) 2008-2010 Nokia Corporation + * Paul Walmsley + * + * Interface developed by (in alphabetical order): Karthik Dasu, Jouni + * Högander, Tony Lindgren, Rajendra Nayak, Sakari Poussa, + * Veeramanikandan Raju, Anand Sawant, Igor Stoppa, Paul Walmsley, + * Richard Woodruff + */ + +#ifndef ASM_ARM_ARCH_OMAP_OMAP_PM_H +#define ASM_ARM_ARCH_OMAP_OMAP_PM_H + +#include <linux/device.h> +#include <linux/cpufreq.h> +#include <linux/clk.h> +#include <linux/pm_opp.h> + +/* + * agent_id values for use with omap_pm_set_min_bus_tput(): + * + * OCP_INITIATOR_AGENT is only valid for devices that can act as + * initiators -- it represents the device's L3 interconnect + * connection. OCP_TARGET_AGENT represents the device's L4 + * interconnect connection. + */ +#define OCP_TARGET_AGENT 1 +#define OCP_INITIATOR_AGENT 2 + +/** + * omap_pm_if_early_init - OMAP PM init code called before clock fw init + * @mpu_opp_table: array ptr to struct omap_opp for MPU + * @dsp_opp_table: array ptr to struct omap_opp for DSP + * @l3_opp_table : array ptr to struct omap_opp for CORE + * + * Initialize anything that must be configured before the clock + * framework starts. The "_if_" is to avoid name collisions with the + * PM idle-loop code. + */ +int __init omap_pm_if_early_init(void); + +/** + * omap_pm_if_init - OMAP PM init code called after clock fw init + * + * The main initialization code. OPP tables are passed in here. The + * "_if_" is to avoid name collisions with the PM idle-loop code. + */ +int __init omap_pm_if_init(void); + +/** + * omap_pm_if_exit - OMAP PM exit code + * + * Exit code; currently unused. The "_if_" is to avoid name + * collisions with the PM idle-loop code. + */ +void omap_pm_if_exit(void); + +/* + * Device-driver-originated constraints (via board-*.c files, platform_data) + */ + + +/** + * omap_pm_set_max_mpu_wakeup_lat - set the maximum MPU wakeup latency + * @dev: struct device * requesting the constraint + * @t: maximum MPU wakeup latency in microseconds + * + * Request that the maximum interrupt latency for the MPU to be no + * greater than @t microseconds. "Interrupt latency" in this case is + * defined as the elapsed time from the occurrence of a hardware or + * timer interrupt to the time when the device driver's interrupt + * service routine has been entered by the MPU. + * + * It is intended that underlying PM code will use this information to + * determine what power state to put the MPU powerdomain into, and + * possibly the CORE powerdomain as well, since interrupt handling + * code currently runs from SDRAM. Advanced PM or board*.c code may + * also configure interrupt controller priorities, OCP bus priorities, + * CPU speed(s), etc. + * + * This function will not affect device wakeup latency, e.g., time + * elapsed from when a device driver enables a hardware device with + * clk_enable(), to when the device is ready for register access or + * other use. To control this device wakeup latency, use + * omap_pm_set_max_dev_wakeup_lat() + * + * Multiple calls to omap_pm_set_max_mpu_wakeup_lat() will replace the + * previous t value. To remove the latency target for the MPU, call + * with t = -1. + * + * XXX This constraint will be deprecated soon in favor of the more + * general omap_pm_set_max_dev_wakeup_lat() + * + * Returns -EINVAL for an invalid argument, -ERANGE if the constraint + * is not satisfiable, or 0 upon success. + */ +int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t); + + +/** + * omap_pm_set_min_bus_tput - set minimum bus throughput needed by device + * @dev: struct device * requesting the constraint + * @tbus_id: interconnect to operate on (OCP_{INITIATOR,TARGET}_AGENT) + * @r: minimum throughput (in KiB/s) + * + * Request that the minimum data throughput on the OCP interconnect + * attached to device @dev interconnect agent @tbus_id be no less + * than @r KiB/s. + * + * It is expected that the OMAP PM or bus code will use this + * information to set the interconnect clock to run at the lowest + * possible speed that satisfies all current system users. The PM or + * bus code will adjust the estimate based on its model of the bus, so + * device driver authors should attempt to specify an accurate + * quantity for their device use case, and let the PM or bus code + * overestimate the numbers as necessary to handle request/response + * latency, other competing users on the system, etc. On OMAP2/3, if + * a driver requests a minimum L4 interconnect speed constraint, the + * code will also need to add an minimum L3 interconnect speed + * constraint, + * + * Multiple calls to omap_pm_set_min_bus_tput() will replace the + * previous rate value for this device. To remove the interconnect + * throughput restriction for this device, call with r = 0. + * + * Returns -EINVAL for an invalid argument, -ERANGE if the constraint + * is not satisfiable, or 0 upon success. + */ +int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r); + + +/** + * omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency + * @req_dev: struct device * requesting the constraint, or NULL if none + * @dev: struct device * to set the constraint one + * @t: maximum device wakeup latency in microseconds + * + * Request that the maximum amount of time necessary for a device @dev + * to become accessible after its clocks are enabled should be no + * greater than @t microseconds. Specifically, this represents the + * time from when a device driver enables device clocks with + * clk_enable(), to when the register reads and writes on the device + * will succeed. This function should be called before clk_disable() + * is called, since the power state transition decision may be made + * during clk_disable(). + * + * It is intended that underlying PM code will use this information to + * determine what power state to put the powerdomain enclosing this + * device into. + * + * Multiple calls to omap_pm_set_max_dev_wakeup_lat() will replace the + * previous wakeup latency values for this device. To remove the + * wakeup latency restriction for this device, call with t = -1. + * + * Returns -EINVAL for an invalid argument, -ERANGE if the constraint + * is not satisfiable, or 0 upon success. + */ +int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev, + long t); + + +/** + * omap_pm_set_max_sdma_lat - set the maximum system DMA transfer start latency + * @dev: struct device * + * @t: maximum DMA transfer start latency in microseconds + * + * Request that the maximum system DMA transfer start latency for this + * device 'dev' should be no greater than 't' microseconds. "DMA + * transfer start latency" here is defined as the elapsed time from + * when a device (e.g., McBSP) requests that a system DMA transfer + * start or continue, to the time at which data starts to flow into + * that device from the system DMA controller. + * + * It is intended that underlying PM code will use this information to + * determine what power state to put the CORE powerdomain into. + * + * Since system DMA transfers may not involve the MPU, this function + * will not affect MPU wakeup latency. Use set_max_cpu_lat() to do + * so. Similarly, this function will not affect device wakeup latency + * -- use set_max_dev_wakeup_lat() to affect that. + * + * Multiple calls to set_max_sdma_lat() will replace the previous t + * value for this device. To remove the maximum DMA latency for this + * device, call with t = -1. + * + * Returns -EINVAL for an invalid argument, -ERANGE if the constraint + * is not satisfiable, or 0 upon success. + */ +int omap_pm_set_max_sdma_lat(struct device *dev, long t); + + +/** + * omap_pm_set_min_clk_rate - set minimum clock rate requested by @dev + * @dev: struct device * requesting the constraint + * @clk: struct clk * to set the minimum rate constraint on + * @r: minimum rate in Hz + * + * Request that the minimum clock rate on the device @dev's clk @clk + * be no less than @r Hz. + * + * It is expected that the OMAP PM code will use this information to + * find an OPP or clock setting that will satisfy this clock rate + * constraint, along with any other applicable system constraints on + * the clock rate or corresponding voltage, etc. + * + * omap_pm_set_min_clk_rate() differs from the clock code's + * clk_set_rate() in that it considers other constraints before taking + * any hardware action, and may change a system OPP rather than just a + * clock rate. clk_set_rate() is intended to be a low-level + * interface. + * + * omap_pm_set_min_clk_rate() is easily open to abuse. A better API + * would be something like "omap_pm_set_min_dev_performance()"; + * however, there is no easily-generalizable concept of performance + * that applies to all devices. Only a device (and possibly the + * device subsystem) has both the subsystem-specific knowledge, and + * the hardware IP block-specific knowledge, to translate a constraint + * on "touchscreen sampling accuracy" or "number of pixels or polygons + * rendered per second" to a clock rate. This translation can be + * dependent on the hardware IP block's revision, or firmware version, + * and the driver is the only code on the system that has this + * information and can know how to translate that into a clock rate. + * + * The intended use-case for this function is for userspace or other + * kernel code to communicate a particular performance requirement to + * a subsystem; then for the subsystem to communicate that requirement + * to something that is meaningful to the device driver; then for the + * device driver to convert that requirement to a clock rate, and to + * then call omap_pm_set_min_clk_rate(). + * + * Users of this function (such as device drivers) should not simply + * call this function with some high clock rate to ensure "high + * performance." Rather, the device driver should take a performance + * constraint from its subsystem, such as "render at least X polygons + * per second," and use some formula or table to convert that into a + * clock rate constraint given the hardware type and hardware + * revision. Device drivers or subsystems should not assume that they + * know how to make a power/performance tradeoff - some device use + * cases may tolerate a lower-fidelity device function for lower power + * consumption; others may demand a higher-fidelity device function, + * no matter what the power consumption. + * + * Multiple calls to omap_pm_set_min_clk_rate() will replace the + * previous rate value for the device @dev. To remove the minimum clock + * rate constraint for the device, call with r = 0. + * + * Returns -EINVAL for an invalid argument, -ERANGE if the constraint + * is not satisfiable, or 0 upon success. + */ +int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r); + +/* + * DSP Bridge-specific constraints + */ + +/** + * omap_pm_dsp_get_opp_table - get OPP->DSP clock frequency table + * + * Intended for use by DSPBridge. Returns an array of OPP->DSP clock + * frequency entries. The final item in the array should have .rate = + * .opp_id = 0. + */ +const struct omap_opp *omap_pm_dsp_get_opp_table(void); + +/** + * omap_pm_dsp_set_min_opp - receive desired OPP target ID from DSP Bridge + * @opp_id: target DSP OPP ID + * + * Set a minimum OPP ID for the DSP. This is intended to be called + * only from the DSP Bridge MPU-side driver. Unfortunately, the only + * information that code receives from the DSP/BIOS load estimator is the + * target OPP ID; hence, this interface. No return value. + */ +void omap_pm_dsp_set_min_opp(u8 opp_id); + +/** + * omap_pm_dsp_get_opp - report the current DSP OPP ID + * + * Report the current OPP for the DSP. Since on OMAP3, the DSP and + * MPU share a single voltage domain, the OPP ID returned back may + * represent a higher DSP speed than the OPP requested via + * omap_pm_dsp_set_min_opp(). + * + * Returns the current VDD1 OPP ID, or 0 upon error. + */ +u8 omap_pm_dsp_get_opp(void); + + +/* + * CPUFreq-originated constraint + * + * In the future, this should be handled by custom OPP clocktype + * functions. + */ + +/** + * omap_pm_cpu_get_freq_table - return a cpufreq_frequency_table array ptr + * + * Provide a frequency table usable by CPUFreq for the current chip/board. + * Returns a pointer to a struct cpufreq_frequency_table array or NULL + * upon error. + */ +struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void); + +/** + * omap_pm_cpu_set_freq - set the current minimum MPU frequency + * @f: MPU frequency in Hz + * + * Set the current minimum CPU frequency. The actual CPU frequency + * used could end up higher if the DSP requested a higher OPP. + * Intended to be called by plat-omap/cpu_omap.c:omap_target(). No + * return value. + */ +void omap_pm_cpu_set_freq(unsigned long f); + +/** + * omap_pm_cpu_get_freq - report the current CPU frequency + * + * Returns the current MPU frequency, or 0 upon error. + */ +unsigned long omap_pm_cpu_get_freq(void); + + +/* + * Device context loss tracking + */ + +/** + * omap_pm_get_dev_context_loss_count - return count of times dev has lost ctx + * @dev: struct device * + * + * This function returns the number of times that the device @dev has + * lost its internal context. This generally occurs on a powerdomain + * transition to OFF. Drivers use this as an optimization to avoid restoring + * context if the device hasn't lost it. To use, drivers should initially + * call this in their context save functions and store the result. Early in + * the driver's context restore function, the driver should call this function + * again, and compare the result to the stored counter. If they differ, the + * driver must restore device context. If the number of context losses + * exceeds the maximum positive integer, the function will wrap to 0 and + * continue counting. Returns the number of context losses for this device, + * or negative value upon error. + */ +int omap_pm_get_dev_context_loss_count(struct device *dev); + +void omap_pm_enable_off_mode(void); +void omap_pm_disable_off_mode(void); + +#endif diff --git a/arch/arm/mach-omap2/omap-secure.c b/arch/arm/mach-omap2/omap-secure.c new file mode 100644 index 00000000000..5ac122e88f6 --- /dev/null +++ b/arch/arm/mach-omap2/omap-secure.c @@ -0,0 +1,148 @@ +/* + * OMAP Secure API infrastructure. + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg> + * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com> + * + * + * This program is free software,you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/memblock.h> + +#include <asm/cacheflush.h> +#include <asm/memblock.h> + +#include "omap-secure.h" + +static phys_addr_t omap_secure_memblock_base; + +/** + * omap_sec_dispatcher: Routine to dispatch low power secure + * service routines + * @idx: The HAL API index + * @flag: The flag indicating criticality of operation + * @nargs: Number of valid arguments out of four. + * @arg1, arg2, arg3 args4: Parameters passed to secure API + * + * Return the non-zero error value on failure. + */ +u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2, + u32 arg3, u32 arg4) +{ + u32 ret; + u32 param[5]; + + param[0] = nargs; + param[1] = arg1; + param[2] = arg2; + param[3] = arg3; + param[4] = arg4; + + /* + * Secure API needs physical address + * pointer for the parameters + */ + flush_cache_all(); + outer_clean_range(__pa(param), __pa(param + 5)); + ret = omap_smc2(idx, flag, __pa(param)); + + return ret; +} + +/* Allocate the memory to save secure ram */ +int __init omap_secure_ram_reserve_memblock(void) +{ + u32 size = OMAP_SECURE_RAM_STORAGE; + + size = ALIGN(size, SECTION_SIZE); + omap_secure_memblock_base = arm_memblock_steal(size, SECTION_SIZE); + + return 0; +} + +phys_addr_t omap_secure_ram_mempool_base(void) +{ + return omap_secure_memblock_base; +} + +/** + * rx51_secure_dispatcher: Routine to dispatch secure PPA API calls + * @idx: The PPA API index + * @process: Process ID + * @flag: The flag indicating criticality of operation + * @nargs: Number of valid arguments out of four. + * @arg1, arg2, arg3 args4: Parameters passed to secure API + * + * Return the non-zero error value on failure. + * + * NOTE: rx51_secure_dispatcher differs from omap_secure_dispatcher because + * it calling omap_smc3() instead omap_smc2() and param[0] is nargs+1 + */ +u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs, + u32 arg1, u32 arg2, u32 arg3, u32 arg4) +{ + u32 ret; + u32 param[5]; + + param[0] = nargs+1; /* RX-51 needs number of arguments + 1 */ + param[1] = arg1; + param[2] = arg2; + param[3] = arg3; + param[4] = arg4; + + /* + * Secure API needs physical address + * pointer for the parameters + */ + local_irq_disable(); + local_fiq_disable(); + flush_cache_all(); + outer_clean_range(__pa(param), __pa(param + 5)); + ret = omap_smc3(idx, process, flag, __pa(param)); + flush_cache_all(); + local_fiq_enable(); + local_irq_enable(); + + return ret; +} + +/** + * rx51_secure_update_aux_cr: Routine to modify the contents of Auxiliary Control Register + * @set_bits: bits to set in ACR + * @clr_bits: bits to clear in ACR + * + * Return the non-zero error value on failure. +*/ +u32 rx51_secure_update_aux_cr(u32 set_bits, u32 clear_bits) +{ + u32 acr; + + /* Read ACR */ + asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr)); + acr &= ~clear_bits; + acr |= set_bits; + + return rx51_secure_dispatcher(RX51_PPA_WRITE_ACR, + 0, + FLAG_START_CRITICAL, + 1, acr, 0, 0, 0); +} + +/** + * rx51_secure_rng_call: Routine for HW random generator + */ +u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag) +{ + return rx51_secure_dispatcher(RX51_PPA_HWRNG, + 0, + NO_FLAG, + 3, ptr, count, flag, 0); +} diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h new file mode 100644 index 00000000000..3e97c6c8ecf --- /dev/null +++ b/arch/arm/mach-omap2/omap-secure.h @@ -0,0 +1,88 @@ +/* + * omap-secure.h: OMAP Secure infrastructure header. + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg> + * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef OMAP_ARCH_OMAP_SECURE_H +#define OMAP_ARCH_OMAP_SECURE_H + +/* Monitor error code */ +#define API_HAL_RET_VALUE_NS2S_CONVERSION_ERROR 0xFFFFFFFE +#define API_HAL_RET_VALUE_SERVICE_UNKNWON 0xFFFFFFFF + +/* HAL API error codes */ +#define API_HAL_RET_VALUE_OK 0x00 +#define API_HAL_RET_VALUE_FAIL 0x01 + +/* Secure HAL API flags */ +#define FLAG_START_CRITICAL 0x4 +#define FLAG_IRQFIQ_MASK 0x3 +#define FLAG_IRQ_ENABLE 0x2 +#define FLAG_FIQ_ENABLE 0x1 +#define NO_FLAG 0x0 + +/* Maximum Secure memory storage size */ +#define OMAP_SECURE_RAM_STORAGE (88 * SZ_1K) + +/* Secure low power HAL API index */ +#define OMAP4_HAL_SAVESECURERAM_INDEX 0x1a +#define OMAP4_HAL_SAVEHW_INDEX 0x1b +#define OMAP4_HAL_SAVEALL_INDEX 0x1c +#define OMAP4_HAL_SAVEGIC_INDEX 0x1d + +/* Secure Monitor mode APIs */ +#define OMAP4_MON_SCU_PWR_INDEX 0x108 +#define OMAP4_MON_L2X0_DBG_CTRL_INDEX 0x100 +#define OMAP4_MON_L2X0_CTRL_INDEX 0x102 +#define OMAP4_MON_L2X0_AUXCTRL_INDEX 0x109 +#define OMAP4_MON_L2X0_PREFETCH_INDEX 0x113 + +#define OMAP5_DRA7_MON_SET_CNTFRQ_INDEX 0x109 + +/* Secure PPA(Primary Protected Application) APIs */ +#define OMAP4_PPA_L2_POR_INDEX 0x23 +#define OMAP4_PPA_CPU_ACTRL_SMP_INDEX 0x25 + +/* Secure RX-51 PPA (Primary Protected Application) APIs */ +#define RX51_PPA_HWRNG 29 +#define RX51_PPA_L2_INVAL 40 +#define RX51_PPA_WRITE_ACR 42 + +#ifndef __ASSEMBLER__ + +extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, + u32 arg1, u32 arg2, u32 arg3, u32 arg4); +extern u32 omap_smc2(u32 id, u32 falg, u32 pargs); +extern u32 omap_smc3(u32 id, u32 process, u32 flag, u32 pargs); +extern phys_addr_t omap_secure_ram_mempool_base(void); +extern int omap_secure_ram_reserve_memblock(void); + +extern u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs, + u32 arg1, u32 arg2, u32 arg3, u32 arg4); +extern u32 rx51_secure_update_aux_cr(u32 set_bits, u32 clear_bits); +extern u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag); + +#ifdef CONFIG_OMAP4_ERRATA_I688 +extern int omap_barrier_reserve_memblock(void); +#else +static inline void omap_barrier_reserve_memblock(void) +{ } +#endif + +#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER +void set_cntfreq(void); +#else +static inline void set_cntfreq(void) +{ +} +#endif + +#endif /* __ASSEMBLER__ */ +#endif /* OMAP_ARCH_OMAP_SECURE_H */ diff --git a/arch/arm/mach-omap2/omap-smc.S b/arch/arm/mach-omap2/omap-smc.S new file mode 100644 index 00000000000..fd90125bffc --- /dev/null +++ b/arch/arm/mach-omap2/omap-smc.S @@ -0,0 +1,99 @@ +/* + * OMAP34xx and OMAP44xx secure APIs file. + * + * Copyright (C) 2010 Texas Instruments, Inc. + * Written by Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * Copyright (C) 2012 Ivaylo Dimitrov <freemangordon@abv.bg> + * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com> + * + * This program is free software,you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/linkage.h> + +/* + * This is common routine to manage secure monitor API + * used to modify the PL310 secure registers. + * 'r0' contains the value to be modified and 'r12' contains + * the monitor API number. It uses few CPU registers + * internally and hence they need be backed up including + * link register "lr". + * Function signature : void omap_smc1(u32 fn, u32 arg) + */ + +ENTRY(omap_smc1) + stmfd sp!, {r2-r12, lr} + mov r12, r0 + mov r0, r1 + dsb + smc #0 + ldmfd sp!, {r2-r12, pc} +ENDPROC(omap_smc1) + +/** + * u32 omap_smc2(u32 id, u32 falg, u32 pargs) + * Low level common routine for secure HAL and PPA APIs. + * @id: Application ID of HAL APIs + * @flag: Flag to indicate the criticality of operation + * @pargs: Physical address of parameter list starting + * with number of parametrs + */ +ENTRY(omap_smc2) + stmfd sp!, {r4-r12, lr} + mov r3, r2 + mov r2, r1 + mov r1, #0x0 @ Process ID + mov r6, #0xff + mov r12, #0x00 @ Secure Service ID + mov r7, #0 + mcr p15, 0, r7, c7, c5, 6 + dsb + dmb + smc #0 + ldmfd sp!, {r4-r12, pc} +ENDPROC(omap_smc2) + +/** + * u32 omap_smc3(u32 service_id, u32 process_id, u32 flag, u32 pargs) + * Low level common routine for secure HAL and PPA APIs via smc #1 + * r0 - @service_id: Secure Service ID + * r1 - @process_id: Process ID + * r2 - @flag: Flag to indicate the criticality of operation + * r3 - @pargs: Physical address of parameter list + */ +ENTRY(omap_smc3) + stmfd sp!, {r4-r11, lr} + mov r12, r0 @ Copy the secure service ID + mov r6, #0xff @ Indicate new Task call + dsb @ Memory Barrier (not sure if needed, copied from omap_smc2) + smc #1 @ Call PPA service + ldmfd sp!, {r4-r11, pc} +ENDPROC(omap_smc3) + +ENTRY(omap_modify_auxcoreboot0) + stmfd sp!, {r1-r12, lr} + ldr r12, =0x104 + dsb + smc #0 + ldmfd sp!, {r1-r12, pc} +ENDPROC(omap_modify_auxcoreboot0) + +ENTRY(omap_auxcoreboot_addr) + stmfd sp!, {r2-r12, lr} + ldr r12, =0x105 + dsb + smc #0 + ldmfd sp!, {r2-r12, pc} +ENDPROC(omap_auxcoreboot_addr) + +ENTRY(omap_read_auxcoreboot0) + stmfd sp!, {r2-r12, lr} + ldr r12, =0x103 + dsb + smc #0 + mov r0, r0, lsr #9 + ldmfd sp!, {r2-r12, pc} +ENDPROC(omap_read_auxcoreboot0) diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c new file mode 100644 index 00000000000..256e84ef0f6 --- /dev/null +++ b/arch/arm/mach-omap2/omap-smp.c @@ -0,0 +1,243 @@ +/* + * OMAP4 SMP source file. It contains platform specific functions + * needed for the linux smp kernel. + * + * Copyright (C) 2009 Texas Instruments, Inc. + * + * Author: + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * Platform file needed for the OMAP4 SMP. This file is based on arm + * realview smp platform. + * * Copyright (c) 2002 ARM Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/init.h> +#include <linux/device.h> +#include <linux/smp.h> +#include <linux/io.h> +#include <linux/irqchip/arm-gic.h> + +#include <asm/smp_scu.h> + +#include "omap-secure.h" +#include "omap-wakeupgen.h" +#include <asm/cputype.h> + +#include "soc.h" +#include "iomap.h" +#include "common.h" +#include "clockdomain.h" +#include "pm.h" + +#define CPU_MASK 0xff0ffff0 +#define CPU_CORTEX_A9 0x410FC090 +#define CPU_CORTEX_A15 0x410FC0F0 + +#define OMAP5_CORE_COUNT 0x2 + +/* SCU base address */ +static void __iomem *scu_base; + +static DEFINE_SPINLOCK(boot_lock); + +void __iomem *omap4_get_scu_base(void) +{ + return scu_base; +} + +static void omap4_secondary_init(unsigned int cpu) +{ + /* + * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device. + * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA + * init and for CPU1, a secure PPA API provided. CPU0 must be ON + * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+. + * OMAP443X GP devices- SMP bit isn't accessible. + * OMAP446X GP devices - SMP bit access is enabled on both CPUs. + */ + if (cpu_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) + omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX, + 4, 0, 0, 0, 0, 0); + + /* + * Configure the CNTFRQ register for the secondary cpu's which + * indicates the frequency of the cpu local timers. + */ + if (soc_is_omap54xx() || soc_is_dra7xx()) + set_cntfreq(); + + /* + * Synchronise with the boot thread. + */ + spin_lock(&boot_lock); + spin_unlock(&boot_lock); +} + +static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + static struct clockdomain *cpu1_clkdm; + static bool booted; + static struct powerdomain *cpu1_pwrdm; + void __iomem *base = omap_get_wakeupgen_base(); + + /* + * Set synchronisation state between this boot processor + * and the secondary one + */ + spin_lock(&boot_lock); + + /* + * Update the AuxCoreBoot0 with boot state for secondary core. + * omap4_secondary_startup() routine will hold the secondary core till + * the AuxCoreBoot1 register is updated with cpu state + * A barrier is added to ensure that write buffer is drained + */ + if (omap_secure_apis_support()) + omap_modify_auxcoreboot0(0x200, 0xfffffdff); + else + writel_relaxed(0x20, base + OMAP_AUX_CORE_BOOT_0); + + if (!cpu1_clkdm && !cpu1_pwrdm) { + cpu1_clkdm = clkdm_lookup("mpu1_clkdm"); + cpu1_pwrdm = pwrdm_lookup("cpu1_pwrdm"); + } + + /* + * The SGI(Software Generated Interrupts) are not wakeup capable + * from low power states. This is known limitation on OMAP4 and + * needs to be worked around by using software forced clockdomain + * wake-up. To wakeup CPU1, CPU0 forces the CPU1 clockdomain to + * software force wakeup. The clockdomain is then put back to + * hardware supervised mode. + * More details can be found in OMAP4430 TRM - Version J + * Section : + * 4.3.4.2 Power States of CPU0 and CPU1 + */ + if (booted && cpu1_pwrdm && cpu1_clkdm) { + /* + * GIC distributor control register has changed between + * CortexA9 r1pX and r2pX. The Control Register secure + * banked version is now composed of 2 bits: + * bit 0 == Secure Enable + * bit 1 == Non-Secure Enable + * The Non-Secure banked register has not changed + * Because the ROM Code is based on the r1pX GIC, the CPU1 + * GIC restoration will cause a problem to CPU0 Non-Secure SW. + * The workaround must be: + * 1) Before doing the CPU1 wakeup, CPU0 must disable + * the GIC distributor + * 2) CPU1 must re-enable the GIC distributor on + * it's wakeup path. + */ + if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) { + local_irq_disable(); + gic_dist_disable(); + } + + /* + * Ensure that CPU power state is set to ON to avoid CPU + * powerdomain transition on wfi + */ + clkdm_wakeup(cpu1_clkdm); + omap_set_pwrdm_state(cpu1_pwrdm, PWRDM_POWER_ON); + clkdm_allow_idle(cpu1_clkdm); + + if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) { + while (gic_dist_disabled()) { + udelay(1); + cpu_relax(); + } + gic_timer_retrigger(); + local_irq_enable(); + } + } else { + dsb_sev(); + booted = true; + } + + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); + + /* + * Now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ + spin_unlock(&boot_lock); + + return 0; +} + +/* + * Initialise the CPU possible map early - this describes the CPUs + * which may be present or become present in the system. + */ +static void __init omap4_smp_init_cpus(void) +{ + unsigned int i = 0, ncores = 1, cpu_id; + + /* Use ARM cpuid check here, as SoC detection will not work so early */ + cpu_id = read_cpuid_id() & CPU_MASK; + if (cpu_id == CPU_CORTEX_A9) { + /* + * Currently we can't call ioremap here because + * SoC detection won't work until after init_early. + */ + scu_base = OMAP2_L4_IO_ADDRESS(scu_a9_get_base()); + BUG_ON(!scu_base); + ncores = scu_get_core_count(scu_base); + } else if (cpu_id == CPU_CORTEX_A15) { + ncores = OMAP5_CORE_COUNT; + } + + /* sanity check */ + if (ncores > nr_cpu_ids) { + pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", + ncores, nr_cpu_ids); + ncores = nr_cpu_ids; + } + + for (i = 0; i < ncores; i++) + set_cpu_possible(i, true); +} + +static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) +{ + void *startup_addr = omap4_secondary_startup; + void __iomem *base = omap_get_wakeupgen_base(); + + /* + * Initialise the SCU and wake up the secondary core using + * wakeup_secondary(). + */ + if (scu_base) + scu_enable(scu_base); + + if (cpu_is_omap446x()) + startup_addr = omap4460_secondary_startup; + + /* + * Write the address of secondary startup routine into the + * AuxCoreBoot1 where ROM code will jump and start executing + * on secondary core once out of WFE + * A barrier is added to ensure that write buffer is drained + */ + if (omap_secure_apis_support()) + omap_auxcoreboot_addr(virt_to_phys(startup_addr)); + else + writel_relaxed(virt_to_phys(omap5_secondary_startup), + base + OMAP_AUX_CORE_BOOT_1); + +} + +struct smp_operations omap4_smp_ops __initdata = { + .smp_init_cpus = omap4_smp_init_cpus, + .smp_prepare_cpus = omap4_smp_prepare_cpus, + .smp_secondary_init = omap4_secondary_init, + .smp_boot_secondary = omap4_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_die = omap4_cpu_die, +#endif +}; diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c new file mode 100644 index 00000000000..37843a7d363 --- /dev/null +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -0,0 +1,458 @@ +/* + * OMAP WakeupGen Source file + * + * OMAP WakeupGen is the interrupt controller extension used along + * with ARM GIC to wake the CPU out from low power states on + * external interrupts. It is responsible for generating wakeup + * event from the incoming interrupts and enable bits. It is + * implemented in MPU always ON power domain. During normal operation, + * WakeupGen delivers external interrupts directly to the GIC. + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/platform_device.h> +#include <linux/cpu.h> +#include <linux/notifier.h> +#include <linux/cpu_pm.h> +#include <linux/irqchip/arm-gic.h> + +#include "omap-wakeupgen.h" +#include "omap-secure.h" + +#include "soc.h" +#include "omap4-sar-layout.h" +#include "common.h" + +#define AM43XX_NR_REG_BANKS 7 +#define AM43XX_IRQS 224 +#define MAX_NR_REG_BANKS AM43XX_NR_REG_BANKS +#define MAX_IRQS AM43XX_IRQS +#define DEFAULT_NR_REG_BANKS 5 +#define DEFAULT_IRQS 160 +#define WKG_MASK_ALL 0x00000000 +#define WKG_UNMASK_ALL 0xffffffff +#define CPU_ENA_OFFSET 0x400 +#define CPU0_ID 0x0 +#define CPU1_ID 0x1 +#define OMAP4_NR_BANKS 4 +#define OMAP4_NR_IRQS 128 + +static void __iomem *wakeupgen_base; +static void __iomem *sar_base; +static DEFINE_RAW_SPINLOCK(wakeupgen_lock); +static unsigned int irq_target_cpu[MAX_IRQS]; +static unsigned int irq_banks = DEFAULT_NR_REG_BANKS; +static unsigned int max_irqs = DEFAULT_IRQS; +static unsigned int omap_secure_apis; + +/* + * Static helper functions. + */ +static inline u32 wakeupgen_readl(u8 idx, u32 cpu) +{ + return readl_relaxed(wakeupgen_base + OMAP_WKG_ENB_A_0 + + (cpu * CPU_ENA_OFFSET) + (idx * 4)); +} + +static inline void wakeupgen_writel(u32 val, u8 idx, u32 cpu) +{ + writel_relaxed(val, wakeupgen_base + OMAP_WKG_ENB_A_0 + + (cpu * CPU_ENA_OFFSET) + (idx * 4)); +} + +static inline void sar_writel(u32 val, u32 offset, u8 idx) +{ + writel_relaxed(val, sar_base + offset + (idx * 4)); +} + +static inline int _wakeupgen_get_irq_info(u32 irq, u32 *bit_posn, u8 *reg_index) +{ + unsigned int spi_irq; + + /* + * PPIs and SGIs are not supported. + */ + if (irq < OMAP44XX_IRQ_GIC_START) + return -EINVAL; + + /* + * Subtract the GIC offset. + */ + spi_irq = irq - OMAP44XX_IRQ_GIC_START; + if (spi_irq > MAX_IRQS) { + pr_err("omap wakeupGen: Invalid IRQ%d\n", irq); + return -EINVAL; + } + + /* + * Each WakeupGen register controls 32 interrupt. + * i.e. 1 bit per SPI IRQ + */ + *reg_index = spi_irq >> 5; + *bit_posn = spi_irq %= 32; + + return 0; +} + +static void _wakeupgen_clear(unsigned int irq, unsigned int cpu) +{ + u32 val, bit_number; + u8 i; + + if (_wakeupgen_get_irq_info(irq, &bit_number, &i)) + return; + + val = wakeupgen_readl(i, cpu); + val &= ~BIT(bit_number); + wakeupgen_writel(val, i, cpu); +} + +static void _wakeupgen_set(unsigned int irq, unsigned int cpu) +{ + u32 val, bit_number; + u8 i; + + if (_wakeupgen_get_irq_info(irq, &bit_number, &i)) + return; + + val = wakeupgen_readl(i, cpu); + val |= BIT(bit_number); + wakeupgen_writel(val, i, cpu); +} + +/* + * Architecture specific Mask extension + */ +static void wakeupgen_mask(struct irq_data *d) +{ + unsigned long flags; + + raw_spin_lock_irqsave(&wakeupgen_lock, flags); + _wakeupgen_clear(d->hwirq, irq_target_cpu[d->hwirq]); + raw_spin_unlock_irqrestore(&wakeupgen_lock, flags); +} + +/* + * Architecture specific Unmask extension + */ +static void wakeupgen_unmask(struct irq_data *d) +{ + unsigned long flags; + + raw_spin_lock_irqsave(&wakeupgen_lock, flags); + _wakeupgen_set(d->hwirq, irq_target_cpu[d->hwirq]); + raw_spin_unlock_irqrestore(&wakeupgen_lock, flags); +} + +#ifdef CONFIG_HOTPLUG_CPU +static DEFINE_PER_CPU(u32 [MAX_NR_REG_BANKS], irqmasks); + +static void _wakeupgen_save_masks(unsigned int cpu) +{ + u8 i; + + for (i = 0; i < irq_banks; i++) + per_cpu(irqmasks, cpu)[i] = wakeupgen_readl(i, cpu); +} + +static void _wakeupgen_restore_masks(unsigned int cpu) +{ + u8 i; + + for (i = 0; i < irq_banks; i++) + wakeupgen_writel(per_cpu(irqmasks, cpu)[i], i, cpu); +} + +static void _wakeupgen_set_all(unsigned int cpu, unsigned int reg) +{ + u8 i; + + for (i = 0; i < irq_banks; i++) + wakeupgen_writel(reg, i, cpu); +} + +/* + * Mask or unmask all interrupts on given CPU. + * 0 = Mask all interrupts on the 'cpu' + * 1 = Unmask all interrupts on the 'cpu' + * Ensure that the initial mask is maintained. This is faster than + * iterating through GIC registers to arrive at the correct masks. + */ +static void wakeupgen_irqmask_all(unsigned int cpu, unsigned int set) +{ + unsigned long flags; + + raw_spin_lock_irqsave(&wakeupgen_lock, flags); + if (set) { + _wakeupgen_save_masks(cpu); + _wakeupgen_set_all(cpu, WKG_MASK_ALL); + } else { + _wakeupgen_set_all(cpu, WKG_UNMASK_ALL); + _wakeupgen_restore_masks(cpu); + } + raw_spin_unlock_irqrestore(&wakeupgen_lock, flags); +} +#endif + +#ifdef CONFIG_CPU_PM +static inline void omap4_irq_save_context(void) +{ + u32 i, val; + + if (omap_rev() == OMAP4430_REV_ES1_0) + return; + + for (i = 0; i < irq_banks; i++) { + /* Save the CPUx interrupt mask for IRQ 0 to 127 */ + val = wakeupgen_readl(i, 0); + sar_writel(val, WAKEUPGENENB_OFFSET_CPU0, i); + val = wakeupgen_readl(i, 1); + sar_writel(val, WAKEUPGENENB_OFFSET_CPU1, i); + + /* + * Disable the secure interrupts for CPUx. The restore + * code blindly restores secure and non-secure interrupt + * masks from SAR RAM. Secure interrupts are not suppose + * to be enabled from HLOS. So overwrite the SAR location + * so that the secure interrupt remains disabled. + */ + sar_writel(0x0, WAKEUPGENENB_SECURE_OFFSET_CPU0, i); + sar_writel(0x0, WAKEUPGENENB_SECURE_OFFSET_CPU1, i); + } + + /* Save AuxBoot* registers */ + val = readl_relaxed(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); + writel_relaxed(val, sar_base + AUXCOREBOOT0_OFFSET); + val = readl_relaxed(wakeupgen_base + OMAP_AUX_CORE_BOOT_1); + writel_relaxed(val, sar_base + AUXCOREBOOT1_OFFSET); + + /* Save SyncReq generation logic */ + val = readl_relaxed(wakeupgen_base + OMAP_PTMSYNCREQ_MASK); + writel_relaxed(val, sar_base + PTMSYNCREQ_MASK_OFFSET); + val = readl_relaxed(wakeupgen_base + OMAP_PTMSYNCREQ_EN); + writel_relaxed(val, sar_base + PTMSYNCREQ_EN_OFFSET); + + /* Set the Backup Bit Mask status */ + val = readl_relaxed(sar_base + SAR_BACKUP_STATUS_OFFSET); + val |= SAR_BACKUP_STATUS_WAKEUPGEN; + writel_relaxed(val, sar_base + SAR_BACKUP_STATUS_OFFSET); + +} + +static inline void omap5_irq_save_context(void) +{ + u32 i, val; + + for (i = 0; i < irq_banks; i++) { + /* Save the CPUx interrupt mask for IRQ 0 to 159 */ + val = wakeupgen_readl(i, 0); + sar_writel(val, OMAP5_WAKEUPGENENB_OFFSET_CPU0, i); + val = wakeupgen_readl(i, 1); + sar_writel(val, OMAP5_WAKEUPGENENB_OFFSET_CPU1, i); + sar_writel(0x0, OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU0, i); + sar_writel(0x0, OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU1, i); + } + + /* Save AuxBoot* registers */ + val = readl_relaxed(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); + writel_relaxed(val, sar_base + OMAP5_AUXCOREBOOT0_OFFSET); + val = readl_relaxed(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); + writel_relaxed(val, sar_base + OMAP5_AUXCOREBOOT1_OFFSET); + + /* Set the Backup Bit Mask status */ + val = readl_relaxed(sar_base + OMAP5_SAR_BACKUP_STATUS_OFFSET); + val |= SAR_BACKUP_STATUS_WAKEUPGEN; + writel_relaxed(val, sar_base + OMAP5_SAR_BACKUP_STATUS_OFFSET); + +} + +/* + * Save WakeupGen interrupt context in SAR BANK3. Restore is done by + * ROM code. WakeupGen IP is integrated along with GIC to manage the + * interrupt wakeups from CPU low power states. It manages + * masking/unmasking of Shared peripheral interrupts(SPI). So the + * interrupt enable/disable control should be in sync and consistent + * at WakeupGen and GIC so that interrupts are not lost. + */ +static void irq_save_context(void) +{ + if (!sar_base) + sar_base = omap4_get_sar_ram_base(); + + if (soc_is_omap54xx()) + omap5_irq_save_context(); + else + omap4_irq_save_context(); +} + +/* + * Clear WakeupGen SAR backup status. + */ +static void irq_sar_clear(void) +{ + u32 val; + u32 offset = SAR_BACKUP_STATUS_OFFSET; + + if (soc_is_omap54xx()) + offset = OMAP5_SAR_BACKUP_STATUS_OFFSET; + + val = readl_relaxed(sar_base + offset); + val &= ~SAR_BACKUP_STATUS_WAKEUPGEN; + writel_relaxed(val, sar_base + offset); +} + +/* + * Save GIC and Wakeupgen interrupt context using secure API + * for HS/EMU devices. + */ +static void irq_save_secure_context(void) +{ + u32 ret; + ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX, + FLAG_START_CRITICAL, + 0, 0, 0, 0, 0); + if (ret != API_HAL_RET_VALUE_OK) + pr_err("GIC and Wakeupgen context save failed\n"); +} +#endif + +#ifdef CONFIG_HOTPLUG_CPU +static int irq_cpu_hotplug_notify(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + unsigned int cpu = (unsigned int)hcpu; + + switch (action) { + case CPU_ONLINE: + wakeupgen_irqmask_all(cpu, 0); + break; + case CPU_DEAD: + wakeupgen_irqmask_all(cpu, 1); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block __refdata irq_hotplug_notifier = { + .notifier_call = irq_cpu_hotplug_notify, +}; + +static void __init irq_hotplug_init(void) +{ + register_hotcpu_notifier(&irq_hotplug_notifier); +} +#else +static void __init irq_hotplug_init(void) +{} +#endif + +#ifdef CONFIG_CPU_PM +static int irq_notifier(struct notifier_block *self, unsigned long cmd, void *v) +{ + switch (cmd) { + case CPU_CLUSTER_PM_ENTER: + if (omap_type() == OMAP2_DEVICE_TYPE_GP) + irq_save_context(); + else + irq_save_secure_context(); + break; + case CPU_CLUSTER_PM_EXIT: + if (omap_type() == OMAP2_DEVICE_TYPE_GP) + irq_sar_clear(); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block irq_notifier_block = { + .notifier_call = irq_notifier, +}; + +static void __init irq_pm_init(void) +{ + /* FIXME: Remove this when MPU OSWR support is added */ + if (!soc_is_omap54xx()) + cpu_pm_register_notifier(&irq_notifier_block); +} +#else +static void __init irq_pm_init(void) +{} +#endif + +void __iomem *omap_get_wakeupgen_base(void) +{ + return wakeupgen_base; +} + +int omap_secure_apis_support(void) +{ + return omap_secure_apis; +} + +/* + * Initialise the wakeupgen module. + */ +int __init omap_wakeupgen_init(void) +{ + int i; + unsigned int boot_cpu = smp_processor_id(); + + /* Not supported on OMAP4 ES1.0 silicon */ + if (omap_rev() == OMAP4430_REV_ES1_0) { + WARN(1, "WakeupGen: Not supported on OMAP4430 ES1.0\n"); + return -EPERM; + } + + /* Static mapping, never released */ + wakeupgen_base = ioremap(OMAP_WKUPGEN_BASE, SZ_4K); + if (WARN_ON(!wakeupgen_base)) + return -ENOMEM; + + if (cpu_is_omap44xx()) { + irq_banks = OMAP4_NR_BANKS; + max_irqs = OMAP4_NR_IRQS; + omap_secure_apis = 1; + } else if (soc_is_am43xx()) { + irq_banks = AM43XX_NR_REG_BANKS; + max_irqs = AM43XX_IRQS; + } + + /* Clear all IRQ bitmasks at wakeupGen level */ + for (i = 0; i < irq_banks; i++) { + wakeupgen_writel(0, i, CPU0_ID); + if (!soc_is_am43xx()) + wakeupgen_writel(0, i, CPU1_ID); + } + + /* + * Override GIC architecture specific functions to add + * OMAP WakeupGen interrupt controller along with GIC + */ + gic_arch_extn.irq_mask = wakeupgen_mask; + gic_arch_extn.irq_unmask = wakeupgen_unmask; + gic_arch_extn.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE; + + /* + * FIXME: Add support to set_smp_affinity() once the core + * GIC code has necessary hooks in place. + */ + + /* Associate all the IRQs to boot CPU like GIC init does. */ + for (i = 0; i < max_irqs; i++) + irq_target_cpu[i] = boot_cpu; + + irq_hotplug_init(); + irq_pm_init(); + + return 0; +} diff --git a/arch/arm/mach-omap2/omap-wakeupgen.h b/arch/arm/mach-omap2/omap-wakeupgen.h new file mode 100644 index 00000000000..b0fd16f5c39 --- /dev/null +++ b/arch/arm/mach-omap2/omap-wakeupgen.h @@ -0,0 +1,38 @@ +/* + * OMAP WakeupGen header file + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef OMAP_ARCH_WAKEUPGEN_H +#define OMAP_ARCH_WAKEUPGEN_H + +/* OMAP4 and OMAP5 has same base address */ +#define OMAP_WKUPGEN_BASE 0x48281000 + +#define OMAP_WKG_CONTROL_0 0x00 +#define OMAP_WKG_ENB_A_0 0x10 +#define OMAP_WKG_ENB_B_0 0x14 +#define OMAP_WKG_ENB_C_0 0x18 +#define OMAP_WKG_ENB_D_0 0x1c +#define OMAP_WKG_ENB_E_0 0x20 +#define OMAP_WKG_ENB_A_1 0x410 +#define OMAP_WKG_ENB_B_1 0x414 +#define OMAP_WKG_ENB_C_1 0x418 +#define OMAP_WKG_ENB_D_1 0x41c +#define OMAP_WKG_ENB_E_1 0x420 +#define OMAP_AUX_CORE_BOOT_0 0x800 +#define OMAP_AUX_CORE_BOOT_1 0x804 +#define OMAP_PTMSYNCREQ_MASK 0xc00 +#define OMAP_PTMSYNCREQ_EN 0xc04 +#define OMAP_TIMESTAMPCYCLELO 0xc08 +#define OMAP_TIMESTAMPCYCLEHI 0xc0c + +extern int __init omap_wakeupgen_init(void); +extern void __iomem *omap_get_wakeupgen_base(void); +extern int omap_secure_apis_support(void); +#endif diff --git a/arch/arm/mach-omap2/omap2-restart.c b/arch/arm/mach-omap2/omap2-restart.c new file mode 100644 index 00000000000..68423e26399 --- /dev/null +++ b/arch/arm/mach-omap2/omap2-restart.c @@ -0,0 +1,66 @@ +/* + * omap2-restart.c - code common to all OMAP2xxx machines. + * + * Copyright (C) 2012 Texas Instruments + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/clk.h> +#include <linux/io.h> + +#include "soc.h" +#include "common.h" +#include "prm2xxx.h" + +/* + * reset_virt_prcm_set_ck, reset_sys_ck: pointers to the virt_prcm_set + * clock and the sys_ck. Used during the reset process + */ +static struct clk *reset_virt_prcm_set_ck, *reset_sys_ck; + +/* Reboot handling */ + +/** + * omap2xxx_restart - Set DPLL to bypass mode for reboot to work + * + * Set the DPLL to bypass so that reboot completes successfully. No + * return value. + */ +void omap2xxx_restart(enum reboot_mode mode, const char *cmd) +{ + u32 rate; + + rate = clk_get_rate(reset_sys_ck); + clk_set_rate(reset_virt_prcm_set_ck, rate); + + /* XXX Should save the cmd argument for use after the reboot */ + + omap2xxx_prm_dpll_reset(); /* never returns */ + while (1); +} + +/** + * omap2xxx_common_look_up_clks_for_reset - look up clocks needed for restart + * + * Some clocks need to be looked up in advance for the SoC restart + * operation to work - see omap2xxx_restart(). Returns -EINVAL upon + * error or 0 upon success. + */ +static int __init omap2xxx_common_look_up_clks_for_reset(void) +{ + reset_virt_prcm_set_ck = clk_get(NULL, "virt_prcm_set"); + if (IS_ERR(reset_virt_prcm_set_ck)) + return -EINVAL; + + reset_sys_ck = clk_get(NULL, "sys_ck"); + if (IS_ERR(reset_sys_ck)) + return -EINVAL; + + return 0; +} +omap_core_initcall(omap2xxx_common_look_up_clks_for_reset); diff --git a/arch/arm/mach-omap2/omap24xx.h b/arch/arm/mach-omap2/omap24xx.h new file mode 100644 index 00000000000..641a2c8d2ee --- /dev/null +++ b/arch/arm/mach-omap2/omap24xx.h @@ -0,0 +1,87 @@ +/* + * This file contains the processor specific definitions + * of the TI OMAP24XX. + * + * Copyright (C) 2007 Texas Instruments. + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARCH_OMAP2_H +#define __ASM_ARCH_OMAP2_H + +/* + * Please place only base defines here and put the rest in device + * specific headers. Note also that some of these defines are needed + * for omap1 to compile without adding ifdefs. + */ + +#define L4_24XX_BASE 0x48000000 +#define L4_WK_243X_BASE 0x49000000 +#define L3_24XX_BASE 0x68000000 + +/* interrupt controller */ +#define OMAP24XX_IC_BASE (L4_24XX_BASE + 0xfe000) +#define OMAP24XX_IVA_INTC_BASE 0x40000000 + +#define OMAP242X_CTRL_BASE L4_24XX_BASE +#define OMAP2420_32KSYNCT_BASE (L4_24XX_BASE + 0x4000) +#define OMAP2420_PRCM_BASE (L4_24XX_BASE + 0x8000) +#define OMAP2420_CM_BASE (L4_24XX_BASE + 0x8000) +#define OMAP2420_PRM_BASE OMAP2420_CM_BASE +#define OMAP2420_SDRC_BASE (L3_24XX_BASE + 0x9000) +#define OMAP2420_SMS_BASE 0x68008000 +#define OMAP2420_GPMC_BASE 0x6800a000 + +#define OMAP2430_32KSYNCT_BASE (L4_WK_243X_BASE + 0x20000) +#define OMAP2430_PRCM_BASE (L4_WK_243X_BASE + 0x6000) +#define OMAP2430_CM_BASE (L4_WK_243X_BASE + 0x6000) +#define OMAP2430_PRM_BASE OMAP2430_CM_BASE + +#define OMAP243X_SMS_BASE 0x6C000000 +#define OMAP243X_SDRC_BASE 0x6D000000 +#define OMAP243X_GPMC_BASE 0x6E000000 +#define OMAP243X_SCM_BASE (L4_WK_243X_BASE + 0x2000) +#define OMAP243X_CTRL_BASE OMAP243X_SCM_BASE +#define OMAP243X_HS_BASE (L4_24XX_BASE + 0x000ac000) + +/* DSP SS */ +#define OMAP2420_DSP_BASE 0x58000000 +#define OMAP2420_DSP_MEM_BASE (OMAP2420_DSP_BASE + 0x0) +#define OMAP2420_DSP_IPI_BASE (OMAP2420_DSP_BASE + 0x1000000) +#define OMAP2420_DSP_MMU_BASE (OMAP2420_DSP_BASE + 0x2000000) + +#define OMAP243X_DSP_BASE 0x5C000000 +#define OMAP243X_DSP_MEM_BASE (OMAP243X_DSP_BASE + 0x0) +#define OMAP243X_DSP_MMU_BASE (OMAP243X_DSP_BASE + 0x1000000) + +/* Mailbox */ +#define OMAP24XX_MAILBOX_BASE (L4_24XX_BASE + 0x94000) + +/* Camera */ +#define OMAP24XX_CAMERA_BASE (L4_24XX_BASE + 0x52000) + +/* Security */ +#define OMAP24XX_SEC_BASE (L4_24XX_BASE + 0xA0000) +#define OMAP24XX_SEC_RNG_BASE (OMAP24XX_SEC_BASE + 0x0000) +#define OMAP24XX_SEC_DES_BASE (OMAP24XX_SEC_BASE + 0x2000) +#define OMAP24XX_SEC_SHA1MD5_BASE (OMAP24XX_SEC_BASE + 0x4000) +#define OMAP24XX_SEC_AES_BASE (OMAP24XX_SEC_BASE + 0x6000) +#define OMAP24XX_SEC_PKA_BASE (OMAP24XX_SEC_BASE + 0x8000) + +#endif /* __ASM_ARCH_OMAP2_H */ + diff --git a/arch/arm/mach-omap2/omap3-restart.c b/arch/arm/mach-omap2/omap3-restart.c new file mode 100644 index 00000000000..5de2a0c2979 --- /dev/null +++ b/arch/arm/mach-omap2/omap3-restart.c @@ -0,0 +1,37 @@ +/* + * omap3-restart.c - Code common to all OMAP3xxx machines. + * + * Copyright (C) 2009, 2012 Texas Instruments + * Copyright (C) 2010 Nokia Corporation + * Tony Lindgren <tony@atomide.com> + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/reboot.h> + +#include "iomap.h" +#include "common.h" +#include "control.h" +#include "prm3xxx.h" + +/* Global address base setup code */ + +/** + * omap3xxx_restart - trigger a software restart of the SoC + * @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c + * @cmd: passed from the userspace program rebooting the system (if provided) + * + * Resets the SoC. For @cmd, see the 'reboot' syscall in + * kernel/sys.c. No return value. + */ +void omap3xxx_restart(enum reboot_mode mode, const char *cmd) +{ + omap3_ctrl_write_boot_mode((cmd ? (u8)*cmd : 0)); + omap3xxx_prm_dpll3_reset(); /* never returns */ + while (1); +} diff --git a/arch/arm/mach-omap2/omap34xx.h b/arch/arm/mach-omap2/omap34xx.h new file mode 100644 index 00000000000..c0d1b4b1653 --- /dev/null +++ b/arch/arm/mach-omap2/omap34xx.h @@ -0,0 +1,99 @@ +/* + * This file contains the processor specific definitions of the TI OMAP34XX. + * + * Copyright (C) 2007 Texas Instruments. + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_OMAP3_H +#define __ASM_ARCH_OMAP3_H + +/* + * Please place only base defines here and put the rest in device + * specific headers. + */ + +#define L4_34XX_BASE 0x48000000 +#define L4_WK_34XX_BASE 0x48300000 +#define L4_PER_34XX_BASE 0x49000000 +#define L4_EMU_34XX_BASE 0x54000000 +#define L3_34XX_BASE 0x68000000 + +#define L4_WK_AM33XX_BASE 0x44C00000 + +#define OMAP3430_32KSYNCT_BASE 0x48320000 +#define OMAP3430_CM_BASE 0x48004800 +#define OMAP3430_PRM_BASE 0x48306800 +#define OMAP343X_SMS_BASE 0x6C000000 +#define OMAP343X_SDRC_BASE 0x6D000000 +#define OMAP34XX_GPMC_BASE 0x6E000000 +#define OMAP343X_SCM_BASE 0x48002000 +#define OMAP343X_CTRL_BASE OMAP343X_SCM_BASE + +#define OMAP34XX_IC_BASE 0x48200000 + +#define OMAP3430_ISP_BASE (L4_34XX_BASE + 0xBC000) +#define OMAP3430_ISP_CBUFF_BASE (OMAP3430_ISP_BASE + 0x0100) +#define OMAP3430_ISP_CCP2_BASE (OMAP3430_ISP_BASE + 0x0400) +#define OMAP3430_ISP_CCDC_BASE (OMAP3430_ISP_BASE + 0x0600) +#define OMAP3430_ISP_HIST_BASE (OMAP3430_ISP_BASE + 0x0A00) +#define OMAP3430_ISP_H3A_BASE (OMAP3430_ISP_BASE + 0x0C00) +#define OMAP3430_ISP_PREV_BASE (OMAP3430_ISP_BASE + 0x0E00) +#define OMAP3430_ISP_RESZ_BASE (OMAP3430_ISP_BASE + 0x1000) +#define OMAP3430_ISP_SBL_BASE (OMAP3430_ISP_BASE + 0x1200) +#define OMAP3430_ISP_MMU_BASE (OMAP3430_ISP_BASE + 0x1400) +#define OMAP3430_ISP_CSI2A_REGS1_BASE (OMAP3430_ISP_BASE + 0x1800) +#define OMAP3430_ISP_CSIPHY2_BASE (OMAP3430_ISP_BASE + 0x1970) +#define OMAP3630_ISP_CSI2A_REGS2_BASE (OMAP3430_ISP_BASE + 0x19C0) +#define OMAP3630_ISP_CSI2C_REGS1_BASE (OMAP3430_ISP_BASE + 0x1C00) +#define OMAP3630_ISP_CSIPHY1_BASE (OMAP3430_ISP_BASE + 0x1D70) +#define OMAP3630_ISP_CSI2C_REGS2_BASE (OMAP3430_ISP_BASE + 0x1DC0) + +#define OMAP3430_ISP_END (OMAP3430_ISP_BASE + 0x06F) +#define OMAP3430_ISP_CBUFF_END (OMAP3430_ISP_CBUFF_BASE + 0x077) +#define OMAP3430_ISP_CCP2_END (OMAP3430_ISP_CCP2_BASE + 0x1EF) +#define OMAP3430_ISP_CCDC_END (OMAP3430_ISP_CCDC_BASE + 0x0A7) +#define OMAP3430_ISP_HIST_END (OMAP3430_ISP_HIST_BASE + 0x047) +#define OMAP3430_ISP_H3A_END (OMAP3430_ISP_H3A_BASE + 0x05F) +#define OMAP3430_ISP_PREV_END (OMAP3430_ISP_PREV_BASE + 0x09F) +#define OMAP3430_ISP_RESZ_END (OMAP3430_ISP_RESZ_BASE + 0x0AB) +#define OMAP3430_ISP_SBL_END (OMAP3430_ISP_SBL_BASE + 0x0FB) +#define OMAP3430_ISP_MMU_END (OMAP3430_ISP_MMU_BASE + 0x06F) +#define OMAP3430_ISP_CSI2A_REGS1_END (OMAP3430_ISP_CSI2A_REGS1_BASE + 0x16F) +#define OMAP3430_ISP_CSIPHY2_END (OMAP3430_ISP_CSIPHY2_BASE + 0x00B) +#define OMAP3630_ISP_CSI2A_REGS2_END (OMAP3630_ISP_CSI2A_REGS2_BASE + 0x3F) +#define OMAP3630_ISP_CSI2C_REGS1_END (OMAP3630_ISP_CSI2C_REGS1_BASE + 0x16F) +#define OMAP3630_ISP_CSIPHY1_END (OMAP3630_ISP_CSIPHY1_BASE + 0x00B) +#define OMAP3630_ISP_CSI2C_REGS2_END (OMAP3630_ISP_CSI2C_REGS2_BASE + 0x3F) + +#define OMAP34XX_HSUSB_OTG_BASE (L4_34XX_BASE + 0xAB000) +#define OMAP34XX_USBTLL_BASE (L4_34XX_BASE + 0x62000) +#define OMAP34XX_UHH_CONFIG_BASE (L4_34XX_BASE + 0x64000) +#define OMAP34XX_OHCI_BASE (L4_34XX_BASE + 0x64400) +#define OMAP34XX_EHCI_BASE (L4_34XX_BASE + 0x64800) +#define OMAP34XX_SR1_BASE 0x480C9000 +#define OMAP34XX_SR2_BASE 0x480CB000 + +#define OMAP34XX_MAILBOX_BASE (L4_34XX_BASE + 0x94000) + +/* Security */ +#define OMAP34XX_SEC_BASE (L4_34XX_BASE + 0xA0000) +#define OMAP34XX_SEC_SHA1MD5_BASE (OMAP34XX_SEC_BASE + 0x23000) +#define OMAP34XX_SEC_AES_BASE (OMAP34XX_SEC_BASE + 0x25000) + +#endif /* __ASM_ARCH_OMAP3_H */ + diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c new file mode 100644 index 00000000000..a0fe747634c --- /dev/null +++ b/arch/arm/mach-omap2/omap4-common.c @@ -0,0 +1,262 @@ +/* + * OMAP4 specific common source file. + * + * Copyright (C) 2010 Texas Instruments, Inc. + * Author: + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * + * This program is free software,you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/irqchip.h> +#include <linux/platform_device.h> +#include <linux/memblock.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> +#include <linux/export.h> +#include <linux/irqchip/arm-gic.h> +#include <linux/irqchip/irq-crossbar.h> +#include <linux/of_address.h> +#include <linux/reboot.h> + +#include <asm/hardware/cache-l2x0.h> +#include <asm/mach/map.h> +#include <asm/memblock.h> +#include <asm/smp_twd.h> + +#include "omap-wakeupgen.h" +#include "soc.h" +#include "iomap.h" +#include "common.h" +#include "mmc.h" +#include "prminst44xx.h" +#include "prcm_mpu44xx.h" +#include "omap4-sar-layout.h" +#include "omap-secure.h" +#include "sram.h" + +#ifdef CONFIG_CACHE_L2X0 +static void __iomem *l2cache_base; +#endif + +static void __iomem *sar_ram_base; +static void __iomem *gic_dist_base_addr; +static void __iomem *twd_base; + +#define IRQ_LOCALTIMER 29 + +#ifdef CONFIG_OMAP4_ERRATA_I688 +/* Used to implement memory barrier on DRAM path */ +#define OMAP4_DRAM_BARRIER_VA 0xfe600000 + +void __iomem *dram_sync, *sram_sync; + +static phys_addr_t paddr; +static u32 size; + +void omap_bus_sync(void) +{ + if (dram_sync && sram_sync) { + writel_relaxed(readl_relaxed(dram_sync), dram_sync); + writel_relaxed(readl_relaxed(sram_sync), sram_sync); + isb(); + } +} +EXPORT_SYMBOL(omap_bus_sync); + +/* Steal one page physical memory for barrier implementation */ +int __init omap_barrier_reserve_memblock(void) +{ + + size = ALIGN(PAGE_SIZE, SZ_1M); + paddr = arm_memblock_steal(size, SZ_1M); + + return 0; +} + +void __init omap_barriers_init(void) +{ + struct map_desc dram_io_desc[1]; + + dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA; + dram_io_desc[0].pfn = __phys_to_pfn(paddr); + dram_io_desc[0].length = size; + dram_io_desc[0].type = MT_MEMORY_RW_SO; + iotable_init(dram_io_desc, ARRAY_SIZE(dram_io_desc)); + dram_sync = (void __iomem *) dram_io_desc[0].virtual; + sram_sync = (void __iomem *) OMAP4_SRAM_VA; + + pr_info("OMAP4: Map 0x%08llx to 0x%08lx for dram barrier\n", + (long long) paddr, dram_io_desc[0].virtual); + +} +#else +void __init omap_barriers_init(void) +{} +#endif + +void gic_dist_disable(void) +{ + if (gic_dist_base_addr) + writel_relaxed(0x0, gic_dist_base_addr + GIC_DIST_CTRL); +} + +void gic_dist_enable(void) +{ + if (gic_dist_base_addr) + writel_relaxed(0x1, gic_dist_base_addr + GIC_DIST_CTRL); +} + +bool gic_dist_disabled(void) +{ + return !(readl_relaxed(gic_dist_base_addr + GIC_DIST_CTRL) & 0x1); +} + +void gic_timer_retrigger(void) +{ + u32 twd_int = readl_relaxed(twd_base + TWD_TIMER_INTSTAT); + u32 gic_int = readl_relaxed(gic_dist_base_addr + GIC_DIST_PENDING_SET); + u32 twd_ctrl = readl_relaxed(twd_base + TWD_TIMER_CONTROL); + + if (twd_int && !(gic_int & BIT(IRQ_LOCALTIMER))) { + /* + * The local timer interrupt got lost while the distributor was + * disabled. Ack the pending interrupt, and retrigger it. + */ + pr_warn("%s: lost localtimer interrupt\n", __func__); + writel_relaxed(1, twd_base + TWD_TIMER_INTSTAT); + if (!(twd_ctrl & TWD_TIMER_CONTROL_PERIODIC)) { + writel_relaxed(1, twd_base + TWD_TIMER_COUNTER); + twd_ctrl |= TWD_TIMER_CONTROL_ENABLE; + writel_relaxed(twd_ctrl, twd_base + TWD_TIMER_CONTROL); + } + } +} + +#ifdef CONFIG_CACHE_L2X0 + +void __iomem *omap4_get_l2cache_base(void) +{ + return l2cache_base; +} + +static void omap4_l2c310_write_sec(unsigned long val, unsigned reg) +{ + unsigned smc_op; + + switch (reg) { + case L2X0_CTRL: + smc_op = OMAP4_MON_L2X0_CTRL_INDEX; + break; + + case L2X0_AUX_CTRL: + smc_op = OMAP4_MON_L2X0_AUXCTRL_INDEX; + break; + + case L2X0_DEBUG_CTRL: + smc_op = OMAP4_MON_L2X0_DBG_CTRL_INDEX; + break; + + case L310_PREFETCH_CTRL: + smc_op = OMAP4_MON_L2X0_PREFETCH_INDEX; + break; + + case L310_POWER_CTRL: + pr_info_once("OMAP L2C310: ROM does not support power control setting\n"); + return; + + default: + WARN_ONCE(1, "OMAP L2C310: ignoring write to reg 0x%x\n", reg); + return; + } + + omap_smc1(smc_op, val); +} + +int __init omap_l2_cache_init(void) +{ + u32 aux_ctrl; + + /* Static mapping, never released */ + l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K); + if (WARN_ON(!l2cache_base)) + return -ENOMEM; + + /* 16-way associativity, parity disabled, way size - 64KB (es2.0 +) */ + aux_ctrl = L2C_AUX_CTRL_SHARED_OVERRIDE | + L310_AUX_CTRL_DATA_PREFETCH | + L310_AUX_CTRL_INSTR_PREFETCH; + + outer_cache.write_sec = omap4_l2c310_write_sec; + if (of_have_populated_dt()) + l2x0_of_init(aux_ctrl, 0xcf9fffff); + else + l2x0_init(l2cache_base, aux_ctrl, 0xcf9fffff); + + return 0; +} +#endif + +void __iomem *omap4_get_sar_ram_base(void) +{ + return sar_ram_base; +} + +/* + * SAR RAM used to save and restore the HW + * context in low power modes + */ +static int __init omap4_sar_ram_init(void) +{ + unsigned long sar_base; + + /* + * To avoid code running on other OMAPs in + * multi-omap builds + */ + if (cpu_is_omap44xx()) + sar_base = OMAP44XX_SAR_RAM_BASE; + else if (soc_is_omap54xx()) + sar_base = OMAP54XX_SAR_RAM_BASE; + else + return -ENOMEM; + + /* Static mapping, never released */ + sar_ram_base = ioremap(sar_base, SZ_16K); + if (WARN_ON(!sar_ram_base)) + return -ENOMEM; + + return 0; +} +omap_early_initcall(omap4_sar_ram_init); + +void __init omap_gic_of_init(void) +{ + struct device_node *np; + + /* Extract GIC distributor and TWD bases for OMAP4460 ROM Errata WA */ + if (!cpu_is_omap446x()) + goto skip_errata_init; + + np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-gic"); + gic_dist_base_addr = of_iomap(np, 0); + WARN_ON(!gic_dist_base_addr); + + np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-twd-timer"); + twd_base = of_iomap(np, 0); + WARN_ON(!twd_base); + +skip_errata_init: + omap_wakeupgen_init(); +#ifdef CONFIG_IRQ_CROSSBAR + irqcrossbar_init(); +#endif + irqchip_init(); +} diff --git a/arch/arm/mach-omap2/omap4-restart.c b/arch/arm/mach-omap2/omap4-restart.c new file mode 100644 index 00000000000..41dfd7da817 --- /dev/null +++ b/arch/arm/mach-omap2/omap4-restart.c @@ -0,0 +1,28 @@ +/* + * omap4-restart.c - Common to OMAP4 and OMAP5 + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/types.h> +#include <linux/reboot.h> +#include "prminst44xx.h" + +/** + * omap44xx_restart - trigger a software restart of the SoC + * @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c + * @cmd: passed from the userspace program rebooting the system (if provided) + * + * Resets the SoC. For @cmd, see the 'reboot' syscall in + * kernel/sys.c. No return value. + */ +void omap44xx_restart(enum reboot_mode mode, const char *cmd) +{ + /* XXX Should save 'cmd' into scratchpad for use after reboot */ + omap4_prminst_global_warm_sw_reset(); /* never returns */ + while (1) + ; +} diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h new file mode 100644 index 00000000000..792b1069f72 --- /dev/null +++ b/arch/arm/mach-omap2/omap4-sar-layout.h @@ -0,0 +1,60 @@ +/* + * omap4-sar-layout.h: OMAP4 SAR RAM layout header file + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef OMAP_ARCH_OMAP4_SAR_LAYOUT_H +#define OMAP_ARCH_OMAP4_SAR_LAYOUT_H + +/* + * SAR BANK offsets from base address OMAP44XX/54XX_SAR_RAM_BASE + */ +#define SAR_BANK1_OFFSET 0x0000 +#define SAR_BANK2_OFFSET 0x1000 +#define SAR_BANK3_OFFSET 0x2000 +#define SAR_BANK4_OFFSET 0x3000 + +/* Scratch pad memory offsets from SAR_BANK1 */ +#define SCU_OFFSET0 0xfe4 +#define SCU_OFFSET1 0xfe8 +#define OMAP_TYPE_OFFSET 0xfec +#define L2X0_SAVE_OFFSET0 0xff0 +#define L2X0_SAVE_OFFSET1 0xff4 +#define L2X0_AUXCTRL_OFFSET 0xff8 +#define L2X0_PREFETCH_CTRL_OFFSET 0xffc + +/* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */ +#define CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xa04 +#define CPU1_WAKEUP_NS_PA_ADDR_OFFSET 0xa08 + +#define SAR_BACKUP_STATUS_OFFSET (SAR_BANK3_OFFSET + 0x500) +#define SAR_SECURE_RAM_SIZE_OFFSET (SAR_BANK3_OFFSET + 0x504) +#define SAR_SECRAM_SAVED_AT_OFFSET (SAR_BANK3_OFFSET + 0x508) + +/* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */ +#define WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x684) +#define WAKEUPGENENB_SECURE_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x694) +#define WAKEUPGENENB_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0x6a4) +#define WAKEUPGENENB_SECURE_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0x6b4) +#define AUXCOREBOOT0_OFFSET (SAR_BANK3_OFFSET + 0x6c4) +#define AUXCOREBOOT1_OFFSET (SAR_BANK3_OFFSET + 0x6c8) +#define PTMSYNCREQ_MASK_OFFSET (SAR_BANK3_OFFSET + 0x6cc) +#define PTMSYNCREQ_EN_OFFSET (SAR_BANK3_OFFSET + 0x6d0) +#define SAR_BACKUP_STATUS_WAKEUPGEN 0x10 + +/* WakeUpGen save restore offset from OMAP54XX_SAR_RAM_BASE */ +#define OMAP5_WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x9dc) +#define OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x9f0) +#define OMAP5_WAKEUPGENENB_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0xa04) +#define OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0xa18) +#define OMAP5_AUXCOREBOOT0_OFFSET (SAR_BANK3_OFFSET + 0xa2c) +#define OMAP5_AUXCOREBOOT1_OFFSET (SAR_BANK3_OFFSET + 0x930) +#define OMAP5_AMBA_IF_MODE_OFFSET (SAR_BANK3_OFFSET + 0xa34) +#define OMAP5_SAR_BACKUP_STATUS_OFFSET (SAR_BANK3_OFFSET + 0x800) + +#endif diff --git a/arch/arm/mach-omap2/omap44xx.h b/arch/arm/mach-omap2/omap44xx.h new file mode 100644 index 00000000000..8a515bb7463 --- /dev/null +++ b/arch/arm/mach-omap2/omap44xx.h @@ -0,0 +1,61 @@ +/*: + * Address mappings and base address for OMAP4 interconnects + * and peripherals. + * + * Copyright (C) 2009 Texas Instruments + * + * Author: Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_ARCH_OMAP44XX_H +#define __ASM_ARCH_OMAP44XX_H + +/* + * Please place only base defines here and put the rest in device + * specific headers. + */ +#define L4_44XX_BASE 0x4a000000 +#define L4_WK_44XX_BASE 0x4a300000 +#define L4_PER_44XX_BASE 0x48000000 +#define L4_EMU_44XX_BASE 0x54000000 +#define L3_44XX_BASE 0x44000000 +#define OMAP44XX_EMIF1_BASE 0x4c000000 +#define OMAP44XX_EMIF2_BASE 0x4d000000 +#define OMAP44XX_DMM_BASE 0x4e000000 +#define OMAP4430_32KSYNCT_BASE 0x4a304000 +#define OMAP4430_CM1_BASE 0x4a004000 +#define OMAP4430_CM_BASE OMAP4430_CM1_BASE +#define OMAP4430_CM2_BASE 0x4a008000 +#define OMAP4430_PRM_BASE 0x4a306000 +#define OMAP4430_PRCM_MPU_BASE 0x48243000 +#define OMAP44XX_GPMC_BASE 0x50000000 +#define OMAP443X_SCM_BASE 0x4a002000 +#define OMAP443X_CTRL_BASE 0x4a100000 +#define OMAP44XX_IC_BASE 0x48200000 +#define OMAP44XX_IVA_INTC_BASE 0x40000000 +#define IRQ_SIR_IRQ 0x0040 +#define OMAP44XX_GIC_DIST_BASE 0x48241000 +#define OMAP44XX_GIC_CPU_BASE 0x48240100 +#define OMAP44XX_IRQ_GIC_START 32 +#define OMAP44XX_LOCAL_TWD_BASE 0x48240600 +#define OMAP44XX_L2CACHE_BASE 0x48242000 +#define OMAP44XX_WKUPGEN_BASE 0x48281000 +#define OMAP44XX_MCPDM_BASE 0x40132000 +#define OMAP44XX_SAR_RAM_BASE 0x4a326000 + +#define OMAP44XX_MAILBOX_BASE (L4_44XX_BASE + 0xF4000) +#define OMAP44XX_HSUSB_OTG_BASE (L4_44XX_BASE + 0xAB000) + +#define OMAP4_MMU1_BASE 0x55082000 +#define OMAP4_MMU2_BASE 0x4A066000 + +#define OMAP44XX_USBTLL_BASE (L4_44XX_BASE + 0x62000) +#define OMAP44XX_UHH_CONFIG_BASE (L4_44XX_BASE + 0x64000) +#define OMAP44XX_HSUSB_OHCI_BASE (L4_44XX_BASE + 0x64800) +#define OMAP44XX_HSUSB_EHCI_BASE (L4_44XX_BASE + 0x64C00) + +#endif /* __ASM_ARCH_OMAP44XX_H */ + diff --git a/arch/arm/mach-omap2/omap54xx.h b/arch/arm/mach-omap2/omap54xx.h new file mode 100644 index 00000000000..2d35c570940 --- /dev/null +++ b/arch/arm/mach-omap2/omap54xx.h @@ -0,0 +1,37 @@ +/*: + * Address mappings and base address for OMAP5 interconnects + * and peripherals. + * + * Copyright (C) 2012 Texas Instruments + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * Sricharan <r.sricharan@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_SOC_OMAP54XX_H +#define __ASM_SOC_OMAP54XX_H + +/* + * Please place only base defines here and put the rest in device + * specific headers. + */ +#define L4_54XX_BASE 0x4a000000 +#define L4_WK_54XX_BASE 0x4ae00000 +#define L4_PER_54XX_BASE 0x48000000 +#define L3_54XX_BASE 0x44000000 +#define OMAP54XX_32KSYNCT_BASE 0x4ae04000 +#define OMAP54XX_CM_CORE_AON_BASE 0x4a004000 +#define OMAP54XX_CM_CORE_BASE 0x4a008000 +#define OMAP54XX_PRM_BASE 0x4ae06000 +#define OMAP54XX_PRCM_MPU_BASE 0x48243000 +#define OMAP54XX_SCM_BASE 0x4a002000 +#define OMAP54XX_CTRL_BASE 0x4a002800 +#define OMAP54XX_SAR_RAM_BASE 0x4ae26000 + +#define DRA7XX_CM_CORE_AON_BASE 0x4a005000 +#define DRA7XX_CTRL_BASE 0x4a003400 +#define DRA7XX_TAP_BASE 0x4ae0c000 + +#endif /* __ASM_SOC_OMAP555554XX_H */ diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c new file mode 100644 index 00000000000..01ef59def44 --- /dev/null +++ b/arch/arm/mach-omap2/omap_device.c @@ -0,0 +1,922 @@ +/* + * omap_device implementation + * + * Copyright (C) 2009-2010 Nokia Corporation + * Paul Walmsley, Kevin Hilman + * + * Developed in collaboration with (alphabetical order): Benoit + * Cousson, Thara Gopinath, Tony Lindgren, Rajendra Nayak, Vikram + * Pandita, Sakari Poussa, Anand Sawant, Santosh Shilimkar, Richard + * Woodruff + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This code provides a consistent interface for OMAP device drivers + * to control power management and interconnect properties of their + * devices. + * + * In the medium- to long-term, this code should be implemented as a + * proper omap_bus/omap_device in Linux, no more platform_data func + * pointers + * + * + */ +#undef DEBUG + +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clkdev.h> +#include <linux/pm_runtime.h> +#include <linux/of.h> +#include <linux/notifier.h> + +#include "common.h" +#include "soc.h" +#include "omap_device.h" +#include "omap_hwmod.h" + +/* Private functions */ + +static void _add_clkdev(struct omap_device *od, const char *clk_alias, + const char *clk_name) +{ + struct clk *r; + struct clk_lookup *l; + + if (!clk_alias || !clk_name) + return; + + dev_dbg(&od->pdev->dev, "Creating %s -> %s\n", clk_alias, clk_name); + + r = clk_get_sys(dev_name(&od->pdev->dev), clk_alias); + if (!IS_ERR(r)) { + dev_warn(&od->pdev->dev, + "alias %s already exists\n", clk_alias); + clk_put(r); + return; + } + + r = clk_get(NULL, clk_name); + if (IS_ERR(r)) { + dev_err(&od->pdev->dev, + "clk_get for %s failed\n", clk_name); + return; + } + + l = clkdev_alloc(r, clk_alias, dev_name(&od->pdev->dev)); + if (!l) { + dev_err(&od->pdev->dev, + "clkdev_alloc for %s failed\n", clk_alias); + return; + } + + clkdev_add(l); +} + +/** + * _add_hwmod_clocks_clkdev - Add clkdev entry for hwmod optional clocks + * and main clock + * @od: struct omap_device *od + * @oh: struct omap_hwmod *oh + * + * For the main clock and every optional clock present per hwmod per + * omap_device, this function adds an entry in the clkdev table of the + * form <dev-id=dev_name, con-id=role> if it does not exist already. + * + * The function is called from inside omap_device_build_ss(), after + * omap_device_register. + * + * This allows drivers to get a pointer to its optional clocks based on its role + * by calling clk_get(<dev*>, <role>). + * In the case of the main clock, a "fck" alias is used. + * + * No return value. + */ +static void _add_hwmod_clocks_clkdev(struct omap_device *od, + struct omap_hwmod *oh) +{ + int i; + + _add_clkdev(od, "fck", oh->main_clk); + + for (i = 0; i < oh->opt_clks_cnt; i++) + _add_clkdev(od, oh->opt_clks[i].role, oh->opt_clks[i].clk); +} + + +/** + * omap_device_build_from_dt - build an omap_device with multiple hwmods + * @pdev_name: name of the platform_device driver to use + * @pdev_id: this platform_device's connection ID + * @oh: ptr to the single omap_hwmod that backs this omap_device + * @pdata: platform_data ptr to associate with the platform_device + * @pdata_len: amount of memory pointed to by @pdata + * + * Function for building an omap_device already registered from device-tree + * + * Returns 0 or PTR_ERR() on error. + */ +static int omap_device_build_from_dt(struct platform_device *pdev) +{ + struct omap_hwmod **hwmods; + struct omap_device *od; + struct omap_hwmod *oh; + struct device_node *node = pdev->dev.of_node; + const char *oh_name; + int oh_cnt, i, ret = 0; + bool device_active = false; + + oh_cnt = of_property_count_strings(node, "ti,hwmods"); + if (oh_cnt <= 0) { + dev_dbg(&pdev->dev, "No 'hwmods' to build omap_device\n"); + return -ENODEV; + } + + hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL); + if (!hwmods) { + ret = -ENOMEM; + goto odbfd_exit; + } + + for (i = 0; i < oh_cnt; i++) { + of_property_read_string_index(node, "ti,hwmods", i, &oh_name); + oh = omap_hwmod_lookup(oh_name); + if (!oh) { + dev_err(&pdev->dev, "Cannot lookup hwmod '%s'\n", + oh_name); + ret = -EINVAL; + goto odbfd_exit1; + } + hwmods[i] = oh; + if (oh->flags & HWMOD_INIT_NO_IDLE) + device_active = true; + } + + od = omap_device_alloc(pdev, hwmods, oh_cnt); + if (IS_ERR(od)) { + dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n", + oh_name); + ret = PTR_ERR(od); + goto odbfd_exit1; + } + + /* Fix up missing resource names */ + for (i = 0; i < pdev->num_resources; i++) { + struct resource *r = &pdev->resource[i]; + + if (r->name == NULL) + r->name = dev_name(&pdev->dev); + } + + pdev->dev.pm_domain = &omap_device_pm_domain; + + if (device_active) { + omap_device_enable(pdev); + pm_runtime_set_active(&pdev->dev); + } + +odbfd_exit1: + kfree(hwmods); +odbfd_exit: + /* if data/we are at fault.. load up a fail handler */ + if (ret) + pdev->dev.pm_domain = &omap_device_fail_pm_domain; + + return ret; +} + +static int _omap_device_notifier_call(struct notifier_block *nb, + unsigned long event, void *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct omap_device *od; + + switch (event) { + case BUS_NOTIFY_DEL_DEVICE: + if (pdev->archdata.od) + omap_device_delete(pdev->archdata.od); + break; + case BUS_NOTIFY_ADD_DEVICE: + if (pdev->dev.of_node) + omap_device_build_from_dt(pdev); + omap_auxdata_legacy_init(dev); + /* fall through */ + default: + od = to_omap_device(pdev); + if (od) + od->_driver_status = event; + } + + return NOTIFY_DONE; +} + +/** + * _omap_device_enable_hwmods - call omap_hwmod_enable() on all hwmods + * @od: struct omap_device *od + * + * Enable all underlying hwmods. Returns 0. + */ +static int _omap_device_enable_hwmods(struct omap_device *od) +{ + int i; + + for (i = 0; i < od->hwmods_cnt; i++) + omap_hwmod_enable(od->hwmods[i]); + + /* XXX pass along return value here? */ + return 0; +} + +/** + * _omap_device_idle_hwmods - call omap_hwmod_idle() on all hwmods + * @od: struct omap_device *od + * + * Idle all underlying hwmods. Returns 0. + */ +static int _omap_device_idle_hwmods(struct omap_device *od) +{ + int i; + + for (i = 0; i < od->hwmods_cnt; i++) + omap_hwmod_idle(od->hwmods[i]); + + /* XXX pass along return value here? */ + return 0; +} + +/* Public functions for use by core code */ + +/** + * omap_device_get_context_loss_count - get lost context count + * @od: struct omap_device * + * + * Using the primary hwmod, query the context loss count for this + * device. + * + * Callers should consider context for this device lost any time this + * function returns a value different than the value the caller got + * the last time it called this function. + * + * If any hwmods exist for the omap_device assoiated with @pdev, + * return the context loss counter for that hwmod, otherwise return + * zero. + */ +int omap_device_get_context_loss_count(struct platform_device *pdev) +{ + struct omap_device *od; + u32 ret = 0; + + od = to_omap_device(pdev); + + if (od->hwmods_cnt) + ret = omap_hwmod_get_context_loss_count(od->hwmods[0]); + + return ret; +} + +/** + * omap_device_count_resources - count number of struct resource entries needed + * @od: struct omap_device * + * @flags: Type of resources to include when counting (IRQ/DMA/MEM) + * + * Count the number of struct resource entries needed for this + * omap_device @od. Used by omap_device_build_ss() to determine how + * much memory to allocate before calling + * omap_device_fill_resources(). Returns the count. + */ +static int omap_device_count_resources(struct omap_device *od, + unsigned long flags) +{ + int c = 0; + int i; + + for (i = 0; i < od->hwmods_cnt; i++) + c += omap_hwmod_count_resources(od->hwmods[i], flags); + + pr_debug("omap_device: %s: counted %d total resources across %d hwmods\n", + od->pdev->name, c, od->hwmods_cnt); + + return c; +} + +/** + * omap_device_fill_resources - fill in array of struct resource + * @od: struct omap_device * + * @res: pointer to an array of struct resource to be filled in + * + * Populate one or more empty struct resource pointed to by @res with + * the resource data for this omap_device @od. Used by + * omap_device_build_ss() after calling omap_device_count_resources(). + * Ideally this function would not be needed at all. If omap_device + * replaces platform_device, then we can specify our own + * get_resource()/ get_irq()/etc functions that use the underlying + * omap_hwmod information. Or if platform_device is extended to use + * subarchitecture-specific function pointers, the various + * platform_device functions can simply call omap_device internal + * functions to get device resources. Hacking around the existing + * platform_device code wastes memory. Returns 0. + */ +static int omap_device_fill_resources(struct omap_device *od, + struct resource *res) +{ + int i, r; + + for (i = 0; i < od->hwmods_cnt; i++) { + r = omap_hwmod_fill_resources(od->hwmods[i], res); + res += r; + } + + return 0; +} + +/** + * _od_fill_dma_resources - fill in array of struct resource with dma resources + * @od: struct omap_device * + * @res: pointer to an array of struct resource to be filled in + * + * Populate one or more empty struct resource pointed to by @res with + * the dma resource data for this omap_device @od. Used by + * omap_device_alloc() after calling omap_device_count_resources(). + * + * Ideally this function would not be needed at all. If we have + * mechanism to get dma resources from DT. + * + * Returns 0. + */ +static int _od_fill_dma_resources(struct omap_device *od, + struct resource *res) +{ + int i, r; + + for (i = 0; i < od->hwmods_cnt; i++) { + r = omap_hwmod_fill_dma_resources(od->hwmods[i], res); + res += r; + } + + return 0; +} + +/** + * omap_device_alloc - allocate an omap_device + * @pdev: platform_device that will be included in this omap_device + * @oh: ptr to the single omap_hwmod that backs this omap_device + * @pdata: platform_data ptr to associate with the platform_device + * @pdata_len: amount of memory pointed to by @pdata + * + * Convenience function for allocating an omap_device structure and filling + * hwmods, and resources. + * + * Returns an struct omap_device pointer or ERR_PTR() on error; + */ +struct omap_device *omap_device_alloc(struct platform_device *pdev, + struct omap_hwmod **ohs, int oh_cnt) +{ + int ret = -ENOMEM; + struct omap_device *od; + struct resource *res = NULL; + int i, res_count; + struct omap_hwmod **hwmods; + + od = kzalloc(sizeof(struct omap_device), GFP_KERNEL); + if (!od) { + ret = -ENOMEM; + goto oda_exit1; + } + od->hwmods_cnt = oh_cnt; + + hwmods = kmemdup(ohs, sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL); + if (!hwmods) + goto oda_exit2; + + od->hwmods = hwmods; + od->pdev = pdev; + + /* + * Non-DT Boot: + * Here, pdev->num_resources = 0, and we should get all the + * resources from hwmod. + * + * DT Boot: + * OF framework will construct the resource structure (currently + * does for MEM & IRQ resource) and we should respect/use these + * resources, killing hwmod dependency. + * If pdev->num_resources > 0, we assume that MEM & IRQ resources + * have been allocated by OF layer already (through DTB). + * As preparation for the future we examine the OF provided resources + * to see if we have DMA resources provided already. In this case + * there is no need to update the resources for the device, we use the + * OF provided ones. + * + * TODO: Once DMA resource is available from OF layer, we should + * kill filling any resources from hwmod. + */ + if (!pdev->num_resources) { + /* Count all resources for the device */ + res_count = omap_device_count_resources(od, IORESOURCE_IRQ | + IORESOURCE_DMA | + IORESOURCE_MEM); + } else { + /* Take a look if we already have DMA resource via DT */ + for (i = 0; i < pdev->num_resources; i++) { + struct resource *r = &pdev->resource[i]; + + /* We have it, no need to touch the resources */ + if (r->flags == IORESOURCE_DMA) + goto have_everything; + } + /* Count only DMA resources for the device */ + res_count = omap_device_count_resources(od, IORESOURCE_DMA); + /* The device has no DMA resource, no need for update */ + if (!res_count) + goto have_everything; + + res_count += pdev->num_resources; + } + + /* Allocate resources memory to account for new resources */ + res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL); + if (!res) + goto oda_exit3; + + if (!pdev->num_resources) { + dev_dbg(&pdev->dev, "%s: using %d resources from hwmod\n", + __func__, res_count); + omap_device_fill_resources(od, res); + } else { + dev_dbg(&pdev->dev, + "%s: appending %d DMA resources from hwmod\n", + __func__, res_count - pdev->num_resources); + memcpy(res, pdev->resource, + sizeof(struct resource) * pdev->num_resources); + _od_fill_dma_resources(od, &res[pdev->num_resources]); + } + + ret = platform_device_add_resources(pdev, res, res_count); + kfree(res); + + if (ret) + goto oda_exit3; + +have_everything: + pdev->archdata.od = od; + + for (i = 0; i < oh_cnt; i++) { + hwmods[i]->od = od; + _add_hwmod_clocks_clkdev(od, hwmods[i]); + } + + return od; + +oda_exit3: + kfree(hwmods); +oda_exit2: + kfree(od); +oda_exit1: + dev_err(&pdev->dev, "omap_device: build failed (%d)\n", ret); + + return ERR_PTR(ret); +} + +void omap_device_delete(struct omap_device *od) +{ + if (!od) + return; + + od->pdev->archdata.od = NULL; + kfree(od->hwmods); + kfree(od); +} + +/** + * omap_device_build - build and register an omap_device with one omap_hwmod + * @pdev_name: name of the platform_device driver to use + * @pdev_id: this platform_device's connection ID + * @oh: ptr to the single omap_hwmod that backs this omap_device + * @pdata: platform_data ptr to associate with the platform_device + * @pdata_len: amount of memory pointed to by @pdata + * + * Convenience function for building and registering a single + * omap_device record, which in turn builds and registers a + * platform_device record. See omap_device_build_ss() for more + * information. Returns ERR_PTR(-EINVAL) if @oh is NULL; otherwise, + * passes along the return value of omap_device_build_ss(). + */ +struct platform_device __init *omap_device_build(const char *pdev_name, + int pdev_id, + struct omap_hwmod *oh, + void *pdata, int pdata_len) +{ + struct omap_hwmod *ohs[] = { oh }; + + if (!oh) + return ERR_PTR(-EINVAL); + + return omap_device_build_ss(pdev_name, pdev_id, ohs, 1, pdata, + pdata_len); +} + +/** + * omap_device_build_ss - build and register an omap_device with multiple hwmods + * @pdev_name: name of the platform_device driver to use + * @pdev_id: this platform_device's connection ID + * @oh: ptr to the single omap_hwmod that backs this omap_device + * @pdata: platform_data ptr to associate with the platform_device + * @pdata_len: amount of memory pointed to by @pdata + * + * Convenience function for building and registering an omap_device + * subsystem record. Subsystem records consist of multiple + * omap_hwmods. This function in turn builds and registers a + * platform_device record. Returns an ERR_PTR() on error, or passes + * along the return value of omap_device_register(). + */ +struct platform_device __init *omap_device_build_ss(const char *pdev_name, + int pdev_id, + struct omap_hwmod **ohs, + int oh_cnt, void *pdata, + int pdata_len) +{ + int ret = -ENOMEM; + struct platform_device *pdev; + struct omap_device *od; + + if (!ohs || oh_cnt == 0 || !pdev_name) + return ERR_PTR(-EINVAL); + + if (!pdata && pdata_len > 0) + return ERR_PTR(-EINVAL); + + pdev = platform_device_alloc(pdev_name, pdev_id); + if (!pdev) { + ret = -ENOMEM; + goto odbs_exit; + } + + /* Set the dev_name early to allow dev_xxx in omap_device_alloc */ + if (pdev->id != -1) + dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); + else + dev_set_name(&pdev->dev, "%s", pdev->name); + + od = omap_device_alloc(pdev, ohs, oh_cnt); + if (IS_ERR(od)) + goto odbs_exit1; + + ret = platform_device_add_data(pdev, pdata, pdata_len); + if (ret) + goto odbs_exit2; + + ret = omap_device_register(pdev); + if (ret) + goto odbs_exit2; + + return pdev; + +odbs_exit2: + omap_device_delete(od); +odbs_exit1: + platform_device_put(pdev); +odbs_exit: + + pr_err("omap_device: %s: build failed (%d)\n", pdev_name, ret); + + return ERR_PTR(ret); +} + +#ifdef CONFIG_PM_RUNTIME +static int _od_runtime_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + int ret; + + ret = pm_generic_runtime_suspend(dev); + + if (!ret) + omap_device_idle(pdev); + + return ret; +} + +static int _od_runtime_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + + omap_device_enable(pdev); + + return pm_generic_runtime_resume(dev); +} + +static int _od_fail_runtime_suspend(struct device *dev) +{ + dev_warn(dev, "%s: FIXME: missing hwmod/omap_dev info\n", __func__); + return -ENODEV; +} + +static int _od_fail_runtime_resume(struct device *dev) +{ + dev_warn(dev, "%s: FIXME: missing hwmod/omap_dev info\n", __func__); + return -ENODEV; +} + +#endif + +#ifdef CONFIG_SUSPEND +static int _od_suspend_noirq(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct omap_device *od = to_omap_device(pdev); + int ret; + + /* Don't attempt late suspend on a driver that is not bound */ + if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) + return 0; + + ret = pm_generic_suspend_noirq(dev); + + if (!ret && !pm_runtime_status_suspended(dev)) { + if (pm_generic_runtime_suspend(dev) == 0) { + pm_runtime_set_suspended(dev); + omap_device_idle(pdev); + od->flags |= OMAP_DEVICE_SUSPENDED; + } + } + + return ret; +} + +static int _od_resume_noirq(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct omap_device *od = to_omap_device(pdev); + + if (od->flags & OMAP_DEVICE_SUSPENDED) { + od->flags &= ~OMAP_DEVICE_SUSPENDED; + omap_device_enable(pdev); + /* + * XXX: we run before core runtime pm has resumed itself. At + * this point in time, we just restore the runtime pm state and + * considering symmetric operations in resume, we donot expect + * to fail. If we failed, something changed in core runtime_pm + * framework OR some device driver messed things up, hence, WARN + */ + WARN(pm_runtime_set_active(dev), + "Could not set %s runtime state active\n", dev_name(dev)); + pm_generic_runtime_resume(dev); + } + + return pm_generic_resume_noirq(dev); +} +#else +#define _od_suspend_noirq NULL +#define _od_resume_noirq NULL +#endif + +struct dev_pm_domain omap_device_fail_pm_domain = { + .ops = { + SET_RUNTIME_PM_OPS(_od_fail_runtime_suspend, + _od_fail_runtime_resume, NULL) + } +}; + +struct dev_pm_domain omap_device_pm_domain = { + .ops = { + SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume, + NULL) + USE_PLATFORM_PM_SLEEP_OPS + .suspend_noirq = _od_suspend_noirq, + .resume_noirq = _od_resume_noirq, + } +}; + +/** + * omap_device_register - register an omap_device with one omap_hwmod + * @od: struct omap_device * to register + * + * Register the omap_device structure. This currently just calls + * platform_device_register() on the underlying platform_device. + * Returns the return value of platform_device_register(). + */ +int omap_device_register(struct platform_device *pdev) +{ + pr_debug("omap_device: %s: registering\n", pdev->name); + + pdev->dev.pm_domain = &omap_device_pm_domain; + return platform_device_add(pdev); +} + + +/* Public functions for use by device drivers through struct platform_data */ + +/** + * omap_device_enable - fully activate an omap_device + * @od: struct omap_device * to activate + * + * Do whatever is necessary for the hwmods underlying omap_device @od + * to be accessible and ready to operate. This generally involves + * enabling clocks, setting SYSCONFIG registers; and in the future may + * involve remuxing pins. Device drivers should call this function + * indirectly via pm_runtime_get*(). Returns -EINVAL if called when + * the omap_device is already enabled, or passes along the return + * value of _omap_device_enable_hwmods(). + */ +int omap_device_enable(struct platform_device *pdev) +{ + int ret; + struct omap_device *od; + + od = to_omap_device(pdev); + + if (od->_state == OMAP_DEVICE_STATE_ENABLED) { + dev_warn(&pdev->dev, + "omap_device: %s() called from invalid state %d\n", + __func__, od->_state); + return -EINVAL; + } + + ret = _omap_device_enable_hwmods(od); + + od->_state = OMAP_DEVICE_STATE_ENABLED; + + return ret; +} + +/** + * omap_device_idle - idle an omap_device + * @od: struct omap_device * to idle + * + * Idle omap_device @od. Device drivers call this function indirectly + * via pm_runtime_put*(). Returns -EINVAL if the omap_device is not + * currently enabled, or passes along the return value of + * _omap_device_idle_hwmods(). + */ +int omap_device_idle(struct platform_device *pdev) +{ + int ret; + struct omap_device *od; + + od = to_omap_device(pdev); + + if (od->_state != OMAP_DEVICE_STATE_ENABLED) { + dev_warn(&pdev->dev, + "omap_device: %s() called from invalid state %d\n", + __func__, od->_state); + return -EINVAL; + } + + ret = _omap_device_idle_hwmods(od); + + od->_state = OMAP_DEVICE_STATE_IDLE; + + return ret; +} + +/** + * omap_device_assert_hardreset - set a device's hardreset line + * @pdev: struct platform_device * to reset + * @name: const char * name of the reset line + * + * Set the hardreset line identified by @name on the IP blocks + * associated with the hwmods backing the platform_device @pdev. All + * of the hwmods associated with @pdev must have the same hardreset + * line linked to them for this to work. Passes along the return value + * of omap_hwmod_assert_hardreset() in the event of any failure, or + * returns 0 upon success. + */ +int omap_device_assert_hardreset(struct platform_device *pdev, const char *name) +{ + struct omap_device *od = to_omap_device(pdev); + int ret = 0; + int i; + + for (i = 0; i < od->hwmods_cnt; i++) { + ret = omap_hwmod_assert_hardreset(od->hwmods[i], name); + if (ret) + break; + } + + return ret; +} + +/** + * omap_device_deassert_hardreset - release a device's hardreset line + * @pdev: struct platform_device * to reset + * @name: const char * name of the reset line + * + * Release the hardreset line identified by @name on the IP blocks + * associated with the hwmods backing the platform_device @pdev. All + * of the hwmods associated with @pdev must have the same hardreset + * line linked to them for this to work. Passes along the return + * value of omap_hwmod_deassert_hardreset() in the event of any + * failure, or returns 0 upon success. + */ +int omap_device_deassert_hardreset(struct platform_device *pdev, + const char *name) +{ + struct omap_device *od = to_omap_device(pdev); + int ret = 0; + int i; + + for (i = 0; i < od->hwmods_cnt; i++) { + ret = omap_hwmod_deassert_hardreset(od->hwmods[i], name); + if (ret) + break; + } + + return ret; +} + +/** + * omap_device_get_by_hwmod_name() - convert a hwmod name to + * device pointer. + * @oh_name: name of the hwmod device + * + * Returns back a struct device * pointer associated with a hwmod + * device represented by a hwmod_name + */ +struct device *omap_device_get_by_hwmod_name(const char *oh_name) +{ + struct omap_hwmod *oh; + + if (!oh_name) { + WARN(1, "%s: no hwmod name!\n", __func__); + return ERR_PTR(-EINVAL); + } + + oh = omap_hwmod_lookup(oh_name); + if (!oh) { + WARN(1, "%s: no hwmod for %s\n", __func__, + oh_name); + return ERR_PTR(-ENODEV); + } + if (!oh->od) { + WARN(1, "%s: no omap_device for %s\n", __func__, + oh_name); + return ERR_PTR(-ENODEV); + } + + return &oh->od->pdev->dev; +} + +static struct notifier_block platform_nb = { + .notifier_call = _omap_device_notifier_call, +}; + +static int __init omap_device_init(void) +{ + bus_register_notifier(&platform_bus_type, &platform_nb); + return 0; +} +omap_core_initcall(omap_device_init); + +/** + * omap_device_late_idle - idle devices without drivers + * @dev: struct device * associated with omap_device + * @data: unused + * + * Check the driver bound status of this device, and idle it + * if there is no driver attached. + */ +static int __init omap_device_late_idle(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct omap_device *od = to_omap_device(pdev); + int i; + + if (!od) + return 0; + + /* + * If omap_device state is enabled, but has no driver bound, + * idle it. + */ + + /* + * Some devices (like memory controllers) are always kept + * enabled, and should not be idled even with no drivers. + */ + for (i = 0; i < od->hwmods_cnt; i++) + if (od->hwmods[i]->flags & HWMOD_INIT_NO_IDLE) + return 0; + + if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) { + if (od->_state == OMAP_DEVICE_STATE_ENABLED) { + dev_warn(dev, "%s: enabled but no driver. Idling\n", + __func__); + omap_device_idle(pdev); + } + } + + return 0; +} + +static int __init omap_device_late_init(void) +{ + bus_for_each_dev(&platform_bus_type, NULL, NULL, omap_device_late_idle); + return 0; +} +omap_late_initcall_sync(omap_device_late_init); diff --git a/arch/arm/mach-omap2/omap_device.h b/arch/arm/mach-omap2/omap_device.h new file mode 100644 index 00000000000..78c02b35517 --- /dev/null +++ b/arch/arm/mach-omap2/omap_device.h @@ -0,0 +1,104 @@ +/* + * omap_device headers + * + * Copyright (C) 2009 Nokia Corporation + * Paul Walmsley + * + * Developed in collaboration with (alphabetical order): Benoit + * Cousson, Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram + * Pandita, Sakari Poussa, Anand Sawant, Santosh Shilimkar, Richard + * Woodruff + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This type of functionality should be implemented as a proper + * omap_bus/omap_device in Linux. + * + * omap_device differs from omap_hwmod in that it includes external + * (e.g., board- and system-level) integration details. omap_hwmod + * stores hardware data that is invariant for a given OMAP chip. + */ +#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H +#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H + +#include <linux/kernel.h> +#include <linux/platform_device.h> + +#include "omap_hwmod.h" + +extern struct dev_pm_domain omap_device_pm_domain; +extern struct dev_pm_domain omap_device_fail_pm_domain; + +/* omap_device._state values */ +#define OMAP_DEVICE_STATE_UNKNOWN 0 +#define OMAP_DEVICE_STATE_ENABLED 1 +#define OMAP_DEVICE_STATE_IDLE 2 +#define OMAP_DEVICE_STATE_SHUTDOWN 3 + +/* omap_device.flags values */ +#define OMAP_DEVICE_SUSPENDED BIT(0) + +/** + * struct omap_device - omap_device wrapper for platform_devices + * @pdev: platform_device + * @hwmods: (one .. many per omap_device) + * @hwmods_cnt: ARRAY_SIZE() of @hwmods + * @_state: one of OMAP_DEVICE_STATE_* (see above) + * @flags: device flags + * @_driver_status: one of BUS_NOTIFY_*_DRIVER from <linux/device.h> + * + * Integrates omap_hwmod data into Linux platform_device. + * + * Field names beginning with underscores are for the internal use of + * the omap_device code. + * + */ +struct omap_device { + struct platform_device *pdev; + struct omap_hwmod **hwmods; + unsigned long _driver_status; + u8 hwmods_cnt; + u8 _state; + u8 flags; +}; + +/* Device driver interface (call via platform_data fn ptrs) */ + +int omap_device_enable(struct platform_device *pdev); +int omap_device_idle(struct platform_device *pdev); + +/* Core code interface */ + +struct platform_device *omap_device_build(const char *pdev_name, int pdev_id, + struct omap_hwmod *oh, void *pdata, + int pdata_len); + +struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id, + struct omap_hwmod **oh, int oh_cnt, + void *pdata, int pdata_len); + +struct omap_device *omap_device_alloc(struct platform_device *pdev, + struct omap_hwmod **ohs, int oh_cnt); +void omap_device_delete(struct omap_device *od); +int omap_device_register(struct platform_device *pdev); + +struct device *omap_device_get_by_hwmod_name(const char *oh_name); + +/* OMAP PM interface */ +int omap_device_get_context_loss_count(struct platform_device *pdev); + +/* Other */ + +int omap_device_assert_hardreset(struct platform_device *pdev, + const char *name); +int omap_device_deassert_hardreset(struct platform_device *pdev, + const char *name); + +/* Get omap_device pointer from platform_device pointer */ +static inline struct omap_device *to_omap_device(struct platform_device *pdev) +{ + return pdev ? pdev->archdata.od : NULL; +} +#endif diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c new file mode 100644 index 00000000000..6c074f37cdd --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -0,0 +1,4286 @@ +/* + * omap_hwmod implementation for OMAP2/3/4 + * + * Copyright (C) 2009-2011 Nokia Corporation + * Copyright (C) 2011-2012 Texas Instruments, Inc. + * + * Paul Walmsley, Benoît Cousson, Kevin Hilman + * + * Created in collaboration with (alphabetical order): Thara Gopinath, + * Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari Poussa, Anand + * Sawant, Santosh Shilimkar, Richard Woodruff + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Introduction + * ------------ + * One way to view an OMAP SoC is as a collection of largely unrelated + * IP blocks connected by interconnects. The IP blocks include + * devices such as ARM processors, audio serial interfaces, UARTs, + * etc. Some of these devices, like the DSP, are created by TI; + * others, like the SGX, largely originate from external vendors. In + * TI's documentation, on-chip devices are referred to as "OMAP + * modules." Some of these IP blocks are identical across several + * OMAP versions. Others are revised frequently. + * + * These OMAP modules are tied together by various interconnects. + * Most of the address and data flow between modules is via OCP-based + * interconnects such as the L3 and L4 buses; but there are other + * interconnects that distribute the hardware clock tree, handle idle + * and reset signaling, supply power, and connect the modules to + * various pads or balls on the OMAP package. + * + * OMAP hwmod provides a consistent way to describe the on-chip + * hardware blocks and their integration into the rest of the chip. + * This description can be automatically generated from the TI + * hardware database. OMAP hwmod provides a standard, consistent API + * to reset, enable, idle, and disable these hardware blocks. And + * hwmod provides a way for other core code, such as the Linux device + * code or the OMAP power management and address space mapping code, + * to query the hardware database. + * + * Using hwmod + * ----------- + * Drivers won't call hwmod functions directly. That is done by the + * omap_device code, and in rare occasions, by custom integration code + * in arch/arm/ *omap*. The omap_device code includes functions to + * build a struct platform_device using omap_hwmod data, and that is + * currently how hwmod data is communicated to drivers and to the + * Linux driver model. Most drivers will call omap_hwmod functions only + * indirectly, via pm_runtime*() functions. + * + * From a layering perspective, here is where the OMAP hwmod code + * fits into the kernel software stack: + * + * +-------------------------------+ + * | Device driver code | + * | (e.g., drivers/) | + * +-------------------------------+ + * | Linux driver model | + * | (platform_device / | + * | platform_driver data/code) | + * +-------------------------------+ + * | OMAP core-driver integration | + * |(arch/arm/mach-omap2/devices.c)| + * +-------------------------------+ + * | omap_device code | + * | (../plat-omap/omap_device.c) | + * +-------------------------------+ + * ----> | omap_hwmod code/data | <----- + * | (../mach-omap2/omap_hwmod*) | + * +-------------------------------+ + * | OMAP clock/PRCM/register fns | + * | ({read,write}l_relaxed, clk*) | + * +-------------------------------+ + * + * Device drivers should not contain any OMAP-specific code or data in + * them. They should only contain code to operate the IP block that + * the driver is responsible for. This is because these IP blocks can + * also appear in other SoCs, either from TI (such as DaVinci) or from + * other manufacturers; and drivers should be reusable across other + * platforms. + * + * The OMAP hwmod code also will attempt to reset and idle all on-chip + * devices upon boot. The goal here is for the kernel to be + * completely self-reliant and independent from bootloaders. This is + * to ensure a repeatable configuration, both to ensure consistent + * runtime behavior, and to make it easier for others to reproduce + * bugs. + * + * OMAP module activity states + * --------------------------- + * The hwmod code considers modules to be in one of several activity + * states. IP blocks start out in an UNKNOWN state, then once they + * are registered via the hwmod code, proceed to the REGISTERED state. + * Once their clock names are resolved to clock pointers, the module + * enters the CLKS_INITED state; and finally, once the module has been + * reset and the integration registers programmed, the INITIALIZED state + * is entered. The hwmod code will then place the module into either + * the IDLE state to save power, or in the case of a critical system + * module, the ENABLED state. + * + * OMAP core integration code can then call omap_hwmod*() functions + * directly to move the module between the IDLE, ENABLED, and DISABLED + * states, as needed. This is done during both the PM idle loop, and + * in the OMAP core integration code's implementation of the PM runtime + * functions. + * + * References + * ---------- + * This is a partial list. + * - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064) + * - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090) + * - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108) + * - OMAP4430 Multimedia Device Silicon Revision 1.0 (SWPU140) + * - Open Core Protocol Specification 2.2 + * + * To do: + * - handle IO mapping + * - bus throughput & module latency measurement code + * + * XXX add tests at the beginning of each function to ensure the hwmod is + * in the appropriate state + * XXX error return values should be checked to ensure that they are + * appropriate + */ +#undef DEBUG + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/io.h> +#include <linux/clk-provider.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/list.h> +#include <linux/mutex.h> +#include <linux/spinlock.h> +#include <linux/slab.h> +#include <linux/bootmem.h> +#include <linux/cpu.h> +#include <linux/of.h> +#include <linux/of_address.h> + +#include <asm/system_misc.h> + +#include "clock.h" +#include "omap_hwmod.h" + +#include "soc.h" +#include "common.h" +#include "clockdomain.h" +#include "powerdomain.h" +#include "cm2xxx.h" +#include "cm3xxx.h" +#include "cminst44xx.h" +#include "cm33xx.h" +#include "prm.h" +#include "prm3xxx.h" +#include "prm44xx.h" +#include "prm33xx.h" +#include "prminst44xx.h" +#include "mux.h" +#include "pm.h" + +/* Name of the OMAP hwmod for the MPU */ +#define MPU_INITIATOR_NAME "mpu" + +/* + * Number of struct omap_hwmod_link records per struct + * omap_hwmod_ocp_if record (master->slave and slave->master) + */ +#define LINKS_PER_OCP_IF 2 + +/** + * struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations + * @enable_module: function to enable a module (via MODULEMODE) + * @disable_module: function to disable a module (via MODULEMODE) + * + * XXX Eventually this functionality will be hidden inside the PRM/CM + * device drivers. Until then, this should avoid huge blocks of cpu_is_*() + * conditionals in this code. + */ +struct omap_hwmod_soc_ops { + void (*enable_module)(struct omap_hwmod *oh); + int (*disable_module)(struct omap_hwmod *oh); + int (*wait_target_ready)(struct omap_hwmod *oh); + int (*assert_hardreset)(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri); + int (*deassert_hardreset)(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri); + int (*is_hardreset_asserted)(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri); + int (*init_clkdm)(struct omap_hwmod *oh); + void (*update_context_lost)(struct omap_hwmod *oh); + int (*get_context_lost)(struct omap_hwmod *oh); +}; + +/* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */ +static struct omap_hwmod_soc_ops soc_ops; + +/* omap_hwmod_list contains all registered struct omap_hwmods */ +static LIST_HEAD(omap_hwmod_list); + +/* mpu_oh: used to add/remove MPU initiator from sleepdep list */ +static struct omap_hwmod *mpu_oh; + +/* io_chain_lock: used to serialize reconfigurations of the I/O chain */ +static DEFINE_SPINLOCK(io_chain_lock); + +/* + * linkspace: ptr to a buffer that struct omap_hwmod_link records are + * allocated from - used to reduce the number of small memory + * allocations, which has a significant impact on performance + */ +static struct omap_hwmod_link *linkspace; + +/* + * free_ls, max_ls: array indexes into linkspace; representing the + * next free struct omap_hwmod_link index, and the maximum number of + * struct omap_hwmod_link records allocated (respectively) + */ +static unsigned short free_ls, max_ls, ls_supp; + +/* inited: set to true once the hwmod code is initialized */ +static bool inited; + +/* Private functions */ + +/** + * _fetch_next_ocp_if - return the next OCP interface in a list + * @p: ptr to a ptr to the list_head inside the ocp_if to return + * @i: pointer to the index of the element pointed to by @p in the list + * + * Return a pointer to the struct omap_hwmod_ocp_if record + * containing the struct list_head pointed to by @p, and increment + * @p such that a future call to this routine will return the next + * record. + */ +static struct omap_hwmod_ocp_if *_fetch_next_ocp_if(struct list_head **p, + int *i) +{ + struct omap_hwmod_ocp_if *oi; + + oi = list_entry(*p, struct omap_hwmod_link, node)->ocp_if; + *p = (*p)->next; + + *i = *i + 1; + + return oi; +} + +/** + * _update_sysc_cache - return the module OCP_SYSCONFIG register, keep copy + * @oh: struct omap_hwmod * + * + * Load the current value of the hwmod OCP_SYSCONFIG register into the + * struct omap_hwmod for later use. Returns -EINVAL if the hwmod has no + * OCP_SYSCONFIG register or 0 upon success. + */ +static int _update_sysc_cache(struct omap_hwmod *oh) +{ + if (!oh->class->sysc) { + WARN(1, "omap_hwmod: %s: cannot read OCP_SYSCONFIG: not defined on hwmod's class\n", oh->name); + return -EINVAL; + } + + /* XXX ensure module interface clock is up */ + + oh->_sysc_cache = omap_hwmod_read(oh, oh->class->sysc->sysc_offs); + + if (!(oh->class->sysc->sysc_flags & SYSC_NO_CACHE)) + oh->_int_flags |= _HWMOD_SYSCONFIG_LOADED; + + return 0; +} + +/** + * _write_sysconfig - write a value to the module's OCP_SYSCONFIG register + * @v: OCP_SYSCONFIG value to write + * @oh: struct omap_hwmod * + * + * Write @v into the module class' OCP_SYSCONFIG register, if it has + * one. No return value. + */ +static void _write_sysconfig(u32 v, struct omap_hwmod *oh) +{ + if (!oh->class->sysc) { + WARN(1, "omap_hwmod: %s: cannot write OCP_SYSCONFIG: not defined on hwmod's class\n", oh->name); + return; + } + + /* XXX ensure module interface clock is up */ + + /* Module might have lost context, always update cache and register */ + oh->_sysc_cache = v; + omap_hwmod_write(v, oh, oh->class->sysc->sysc_offs); +} + +/** + * _set_master_standbymode: set the OCP_SYSCONFIG MIDLEMODE field in @v + * @oh: struct omap_hwmod * + * @standbymode: MIDLEMODE field bits + * @v: pointer to register contents to modify + * + * Update the master standby mode bits in @v to be @standbymode for + * the @oh hwmod. Does not write to the hardware. Returns -EINVAL + * upon error or 0 upon success. + */ +static int _set_master_standbymode(struct omap_hwmod *oh, u8 standbymode, + u32 *v) +{ + u32 mstandby_mask; + u8 mstandby_shift; + + if (!oh->class->sysc || + !(oh->class->sysc->sysc_flags & SYSC_HAS_MIDLEMODE)) + return -EINVAL; + + if (!oh->class->sysc->sysc_fields) { + WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name); + return -EINVAL; + } + + mstandby_shift = oh->class->sysc->sysc_fields->midle_shift; + mstandby_mask = (0x3 << mstandby_shift); + + *v &= ~mstandby_mask; + *v |= __ffs(standbymode) << mstandby_shift; + + return 0; +} + +/** + * _set_slave_idlemode: set the OCP_SYSCONFIG SIDLEMODE field in @v + * @oh: struct omap_hwmod * + * @idlemode: SIDLEMODE field bits + * @v: pointer to register contents to modify + * + * Update the slave idle mode bits in @v to be @idlemode for the @oh + * hwmod. Does not write to the hardware. Returns -EINVAL upon error + * or 0 upon success. + */ +static int _set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode, u32 *v) +{ + u32 sidle_mask; + u8 sidle_shift; + + if (!oh->class->sysc || + !(oh->class->sysc->sysc_flags & SYSC_HAS_SIDLEMODE)) + return -EINVAL; + + if (!oh->class->sysc->sysc_fields) { + WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name); + return -EINVAL; + } + + sidle_shift = oh->class->sysc->sysc_fields->sidle_shift; + sidle_mask = (0x3 << sidle_shift); + + *v &= ~sidle_mask; + *v |= __ffs(idlemode) << sidle_shift; + + return 0; +} + +/** + * _set_clockactivity: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v + * @oh: struct omap_hwmod * + * @clockact: CLOCKACTIVITY field bits + * @v: pointer to register contents to modify + * + * Update the clockactivity mode bits in @v to be @clockact for the + * @oh hwmod. Used for additional powersaving on some modules. Does + * not write to the hardware. Returns -EINVAL upon error or 0 upon + * success. + */ +static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v) +{ + u32 clkact_mask; + u8 clkact_shift; + + if (!oh->class->sysc || + !(oh->class->sysc->sysc_flags & SYSC_HAS_CLOCKACTIVITY)) + return -EINVAL; + + if (!oh->class->sysc->sysc_fields) { + WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name); + return -EINVAL; + } + + clkact_shift = oh->class->sysc->sysc_fields->clkact_shift; + clkact_mask = (0x3 << clkact_shift); + + *v &= ~clkact_mask; + *v |= clockact << clkact_shift; + + return 0; +} + +/** + * _set_softreset: set OCP_SYSCONFIG.SOFTRESET bit in @v + * @oh: struct omap_hwmod * + * @v: pointer to register contents to modify + * + * Set the SOFTRESET bit in @v for hwmod @oh. Returns -EINVAL upon + * error or 0 upon success. + */ +static int _set_softreset(struct omap_hwmod *oh, u32 *v) +{ + u32 softrst_mask; + + if (!oh->class->sysc || + !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET)) + return -EINVAL; + + if (!oh->class->sysc->sysc_fields) { + WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name); + return -EINVAL; + } + + softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift); + + *v |= softrst_mask; + + return 0; +} + +/** + * _clear_softreset: clear OCP_SYSCONFIG.SOFTRESET bit in @v + * @oh: struct omap_hwmod * + * @v: pointer to register contents to modify + * + * Clear the SOFTRESET bit in @v for hwmod @oh. Returns -EINVAL upon + * error or 0 upon success. + */ +static int _clear_softreset(struct omap_hwmod *oh, u32 *v) +{ + u32 softrst_mask; + + if (!oh->class->sysc || + !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET)) + return -EINVAL; + + if (!oh->class->sysc->sysc_fields) { + WARN(1, + "omap_hwmod: %s: sysc_fields absent for sysconfig class\n", + oh->name); + return -EINVAL; + } + + softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift); + + *v &= ~softrst_mask; + + return 0; +} + +/** + * _wait_softreset_complete - wait for an OCP softreset to complete + * @oh: struct omap_hwmod * to wait on + * + * Wait until the IP block represented by @oh reports that its OCP + * softreset is complete. This can be triggered by software (see + * _ocp_softreset()) or by hardware upon returning from off-mode (one + * example is HSMMC). Waits for up to MAX_MODULE_SOFTRESET_WAIT + * microseconds. Returns the number of microseconds waited. + */ +static int _wait_softreset_complete(struct omap_hwmod *oh) +{ + struct omap_hwmod_class_sysconfig *sysc; + u32 softrst_mask; + int c = 0; + + sysc = oh->class->sysc; + + if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS) + omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs) + & SYSS_RESETDONE_MASK), + MAX_MODULE_SOFTRESET_WAIT, c); + else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { + softrst_mask = (0x1 << sysc->sysc_fields->srst_shift); + omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs) + & softrst_mask), + MAX_MODULE_SOFTRESET_WAIT, c); + } + + return c; +} + +/** + * _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v + * @oh: struct omap_hwmod * + * + * The DMADISABLE bit is a semi-automatic bit present in sysconfig register + * of some modules. When the DMA must perform read/write accesses, the + * DMADISABLE bit is cleared by the hardware. But when the DMA must stop + * for power management, software must set the DMADISABLE bit back to 1. + * + * Set the DMADISABLE bit in @v for hwmod @oh. Returns -EINVAL upon + * error or 0 upon success. + */ +static int _set_dmadisable(struct omap_hwmod *oh) +{ + u32 v; + u32 dmadisable_mask; + + if (!oh->class->sysc || + !(oh->class->sysc->sysc_flags & SYSC_HAS_DMADISABLE)) + return -EINVAL; + + if (!oh->class->sysc->sysc_fields) { + WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name); + return -EINVAL; + } + + /* clocks must be on for this operation */ + if (oh->_state != _HWMOD_STATE_ENABLED) { + pr_warn("omap_hwmod: %s: dma can be disabled only from enabled state\n", oh->name); + return -EINVAL; + } + + pr_debug("omap_hwmod: %s: setting DMADISABLE\n", oh->name); + + v = oh->_sysc_cache; + dmadisable_mask = + (0x1 << oh->class->sysc->sysc_fields->dmadisable_shift); + v |= dmadisable_mask; + _write_sysconfig(v, oh); + + return 0; +} + +/** + * _set_module_autoidle: set the OCP_SYSCONFIG AUTOIDLE field in @v + * @oh: struct omap_hwmod * + * @autoidle: desired AUTOIDLE bitfield value (0 or 1) + * @v: pointer to register contents to modify + * + * Update the module autoidle bit in @v to be @autoidle for the @oh + * hwmod. The autoidle bit controls whether the module can gate + * internal clocks automatically when it isn't doing anything; the + * exact function of this bit varies on a per-module basis. This + * function does not write to the hardware. Returns -EINVAL upon + * error or 0 upon success. + */ +static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle, + u32 *v) +{ + u32 autoidle_mask; + u8 autoidle_shift; + + if (!oh->class->sysc || + !(oh->class->sysc->sysc_flags & SYSC_HAS_AUTOIDLE)) + return -EINVAL; + + if (!oh->class->sysc->sysc_fields) { + WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name); + return -EINVAL; + } + + autoidle_shift = oh->class->sysc->sysc_fields->autoidle_shift; + autoidle_mask = (0x1 << autoidle_shift); + + *v &= ~autoidle_mask; + *v |= autoidle << autoidle_shift; + + return 0; +} + +/** + * _set_idle_ioring_wakeup - enable/disable IO pad wakeup on hwmod idle for mux + * @oh: struct omap_hwmod * + * @set_wake: bool value indicating to set (true) or clear (false) wakeup enable + * + * Set or clear the I/O pad wakeup flag in the mux entries for the + * hwmod @oh. This function changes the @oh->mux->pads_dynamic array + * in memory. If the hwmod is currently idled, and the new idle + * values don't match the previous ones, this function will also + * update the SCM PADCTRL registers. Otherwise, if the hwmod is not + * currently idled, this function won't touch the hardware: the new + * mux settings are written to the SCM PADCTRL registers when the + * hwmod is idled. No return value. + */ +static void _set_idle_ioring_wakeup(struct omap_hwmod *oh, bool set_wake) +{ + struct omap_device_pad *pad; + bool change = false; + u16 prev_idle; + int j; + + if (!oh->mux || !oh->mux->enabled) + return; + + for (j = 0; j < oh->mux->nr_pads_dynamic; j++) { + pad = oh->mux->pads_dynamic[j]; + + if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP)) + continue; + + prev_idle = pad->idle; + + if (set_wake) + pad->idle |= OMAP_WAKEUP_EN; + else + pad->idle &= ~OMAP_WAKEUP_EN; + + if (prev_idle != pad->idle) + change = true; + } + + if (change && oh->_state == _HWMOD_STATE_IDLE) + omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE); +} + +/** + * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware + * @oh: struct omap_hwmod * + * + * Allow the hardware module @oh to send wakeups. Returns -EINVAL + * upon error or 0 upon success. + */ +static int _enable_wakeup(struct omap_hwmod *oh, u32 *v) +{ + if (!oh->class->sysc || + !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) || + (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) || + (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP))) + return -EINVAL; + + if (!oh->class->sysc->sysc_fields) { + WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name); + return -EINVAL; + } + + if (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) + *v |= 0x1 << oh->class->sysc->sysc_fields->enwkup_shift; + + if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) + _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART_WKUP, v); + if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP) + _set_master_standbymode(oh, HWMOD_IDLEMODE_SMART_WKUP, v); + + /* XXX test pwrdm_get_wken for this hwmod's subsystem */ + + return 0; +} + +/** + * _disable_wakeup: clear OCP_SYSCONFIG.ENAWAKEUP bit in the hardware + * @oh: struct omap_hwmod * + * + * Prevent the hardware module @oh to send wakeups. Returns -EINVAL + * upon error or 0 upon success. + */ +static int _disable_wakeup(struct omap_hwmod *oh, u32 *v) +{ + if (!oh->class->sysc || + !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) || + (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) || + (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP))) + return -EINVAL; + + if (!oh->class->sysc->sysc_fields) { + WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name); + return -EINVAL; + } + + if (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) + *v &= ~(0x1 << oh->class->sysc->sysc_fields->enwkup_shift); + + if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) + _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART, v); + if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP) + _set_master_standbymode(oh, HWMOD_IDLEMODE_SMART, v); + + /* XXX test pwrdm_get_wken for this hwmod's subsystem */ + + return 0; +} + +static struct clockdomain *_get_clkdm(struct omap_hwmod *oh) +{ + struct clk_hw_omap *clk; + + if (oh->clkdm) { + return oh->clkdm; + } else if (oh->_clk) { + if (__clk_get_flags(oh->_clk) & CLK_IS_BASIC) + return NULL; + clk = to_clk_hw_omap(__clk_get_hw(oh->_clk)); + return clk->clkdm; + } + return NULL; +} + +/** + * _add_initiator_dep: prevent @oh from smart-idling while @init_oh is active + * @oh: struct omap_hwmod * + * + * Prevent the hardware module @oh from entering idle while the + * hardare module initiator @init_oh is active. Useful when a module + * will be accessed by a particular initiator (e.g., if a module will + * be accessed by the IVA, there should be a sleepdep between the IVA + * initiator and the module). Only applies to modules in smart-idle + * mode. If the clockdomain is marked as not needing autodeps, return + * 0 without doing anything. Otherwise, returns -EINVAL upon error or + * passes along clkdm_add_sleepdep() value upon success. + */ +static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) +{ + struct clockdomain *clkdm, *init_clkdm; + + clkdm = _get_clkdm(oh); + init_clkdm = _get_clkdm(init_oh); + + if (!clkdm || !init_clkdm) + return -EINVAL; + + if (clkdm && clkdm->flags & CLKDM_NO_AUTODEPS) + return 0; + + return clkdm_add_sleepdep(clkdm, init_clkdm); +} + +/** + * _del_initiator_dep: allow @oh to smart-idle even if @init_oh is active + * @oh: struct omap_hwmod * + * + * Allow the hardware module @oh to enter idle while the hardare + * module initiator @init_oh is active. Useful when a module will not + * be accessed by a particular initiator (e.g., if a module will not + * be accessed by the IVA, there should be no sleepdep between the IVA + * initiator and the module). Only applies to modules in smart-idle + * mode. If the clockdomain is marked as not needing autodeps, return + * 0 without doing anything. Returns -EINVAL upon error or passes + * along clkdm_del_sleepdep() value upon success. + */ +static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) +{ + struct clockdomain *clkdm, *init_clkdm; + + clkdm = _get_clkdm(oh); + init_clkdm = _get_clkdm(init_oh); + + if (!clkdm || !init_clkdm) + return -EINVAL; + + if (clkdm && clkdm->flags & CLKDM_NO_AUTODEPS) + return 0; + + return clkdm_del_sleepdep(clkdm, init_clkdm); +} + +/** + * _init_main_clk - get a struct clk * for the the hwmod's main functional clk + * @oh: struct omap_hwmod * + * + * Called from _init_clocks(). Populates the @oh _clk (main + * functional clock pointer) if a main_clk is present. Returns 0 on + * success or -EINVAL on error. + */ +static int _init_main_clk(struct omap_hwmod *oh) +{ + int ret = 0; + + if (!oh->main_clk) + return 0; + + oh->_clk = clk_get(NULL, oh->main_clk); + if (IS_ERR(oh->_clk)) { + pr_warning("omap_hwmod: %s: cannot clk_get main_clk %s\n", + oh->name, oh->main_clk); + return -EINVAL; + } + /* + * HACK: This needs a re-visit once clk_prepare() is implemented + * to do something meaningful. Today its just a no-op. + * If clk_prepare() is used at some point to do things like + * voltage scaling etc, then this would have to be moved to + * some point where subsystems like i2c and pmic become + * available. + */ + clk_prepare(oh->_clk); + + if (!_get_clkdm(oh)) + pr_debug("omap_hwmod: %s: missing clockdomain for %s.\n", + oh->name, oh->main_clk); + + return ret; +} + +/** + * _init_interface_clks - get a struct clk * for the the hwmod's interface clks + * @oh: struct omap_hwmod * + * + * Called from _init_clocks(). Populates the @oh OCP slave interface + * clock pointers. Returns 0 on success or -EINVAL on error. + */ +static int _init_interface_clks(struct omap_hwmod *oh) +{ + struct omap_hwmod_ocp_if *os; + struct list_head *p; + struct clk *c; + int i = 0; + int ret = 0; + + p = oh->slave_ports.next; + + while (i < oh->slaves_cnt) { + os = _fetch_next_ocp_if(&p, &i); + if (!os->clk) + continue; + + c = clk_get(NULL, os->clk); + if (IS_ERR(c)) { + pr_warning("omap_hwmod: %s: cannot clk_get interface_clk %s\n", + oh->name, os->clk); + ret = -EINVAL; + continue; + } + os->_clk = c; + /* + * HACK: This needs a re-visit once clk_prepare() is implemented + * to do something meaningful. Today its just a no-op. + * If clk_prepare() is used at some point to do things like + * voltage scaling etc, then this would have to be moved to + * some point where subsystems like i2c and pmic become + * available. + */ + clk_prepare(os->_clk); + } + + return ret; +} + +/** + * _init_opt_clk - get a struct clk * for the the hwmod's optional clocks + * @oh: struct omap_hwmod * + * + * Called from _init_clocks(). Populates the @oh omap_hwmod_opt_clk + * clock pointers. Returns 0 on success or -EINVAL on error. + */ +static int _init_opt_clks(struct omap_hwmod *oh) +{ + struct omap_hwmod_opt_clk *oc; + struct clk *c; + int i; + int ret = 0; + + for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) { + c = clk_get(NULL, oc->clk); + if (IS_ERR(c)) { + pr_warning("omap_hwmod: %s: cannot clk_get opt_clk %s\n", + oh->name, oc->clk); + ret = -EINVAL; + continue; + } + oc->_clk = c; + /* + * HACK: This needs a re-visit once clk_prepare() is implemented + * to do something meaningful. Today its just a no-op. + * If clk_prepare() is used at some point to do things like + * voltage scaling etc, then this would have to be moved to + * some point where subsystems like i2c and pmic become + * available. + */ + clk_prepare(oc->_clk); + } + + return ret; +} + +/** + * _enable_clocks - enable hwmod main clock and interface clocks + * @oh: struct omap_hwmod * + * + * Enables all clocks necessary for register reads and writes to succeed + * on the hwmod @oh. Returns 0. + */ +static int _enable_clocks(struct omap_hwmod *oh) +{ + struct omap_hwmod_ocp_if *os; + struct list_head *p; + int i = 0; + + pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name); + + if (oh->_clk) + clk_enable(oh->_clk); + + p = oh->slave_ports.next; + + while (i < oh->slaves_cnt) { + os = _fetch_next_ocp_if(&p, &i); + + if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) + clk_enable(os->_clk); + } + + /* The opt clocks are controlled by the device driver. */ + + return 0; +} + +/** + * _disable_clocks - disable hwmod main clock and interface clocks + * @oh: struct omap_hwmod * + * + * Disables the hwmod @oh main functional and interface clocks. Returns 0. + */ +static int _disable_clocks(struct omap_hwmod *oh) +{ + struct omap_hwmod_ocp_if *os; + struct list_head *p; + int i = 0; + + pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name); + + if (oh->_clk) + clk_disable(oh->_clk); + + p = oh->slave_ports.next; + + while (i < oh->slaves_cnt) { + os = _fetch_next_ocp_if(&p, &i); + + if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) + clk_disable(os->_clk); + } + + /* The opt clocks are controlled by the device driver. */ + + return 0; +} + +static void _enable_optional_clocks(struct omap_hwmod *oh) +{ + struct omap_hwmod_opt_clk *oc; + int i; + + pr_debug("omap_hwmod: %s: enabling optional clocks\n", oh->name); + + for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) + if (oc->_clk) { + pr_debug("omap_hwmod: enable %s:%s\n", oc->role, + __clk_get_name(oc->_clk)); + clk_enable(oc->_clk); + } +} + +static void _disable_optional_clocks(struct omap_hwmod *oh) +{ + struct omap_hwmod_opt_clk *oc; + int i; + + pr_debug("omap_hwmod: %s: disabling optional clocks\n", oh->name); + + for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) + if (oc->_clk) { + pr_debug("omap_hwmod: disable %s:%s\n", oc->role, + __clk_get_name(oc->_clk)); + clk_disable(oc->_clk); + } +} + +/** + * _omap4_enable_module - enable CLKCTRL modulemode on OMAP4 + * @oh: struct omap_hwmod * + * + * Enables the PRCM module mode related to the hwmod @oh. + * No return value. + */ +static void _omap4_enable_module(struct omap_hwmod *oh) +{ + if (!oh->clkdm || !oh->prcm.omap4.modulemode) + return; + + pr_debug("omap_hwmod: %s: %s: %d\n", + oh->name, __func__, oh->prcm.omap4.modulemode); + + omap4_cminst_module_enable(oh->prcm.omap4.modulemode, + oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); +} + +/** + * _am33xx_enable_module - enable CLKCTRL modulemode on AM33XX + * @oh: struct omap_hwmod * + * + * Enables the PRCM module mode related to the hwmod @oh. + * No return value. + */ +static void _am33xx_enable_module(struct omap_hwmod *oh) +{ + if (!oh->clkdm || !oh->prcm.omap4.modulemode) + return; + + pr_debug("omap_hwmod: %s: %s: %d\n", + oh->name, __func__, oh->prcm.omap4.modulemode); + + am33xx_cm_module_enable(oh->prcm.omap4.modulemode, oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); +} + +/** + * _omap4_wait_target_disable - wait for a module to be disabled on OMAP4 + * @oh: struct omap_hwmod * + * + * Wait for a module @oh to enter slave idle. Returns 0 if the module + * does not have an IDLEST bit or if the module successfully enters + * slave idle; otherwise, pass along the return value of the + * appropriate *_cm*_wait_module_idle() function. + */ +static int _omap4_wait_target_disable(struct omap_hwmod *oh) +{ + if (!oh) + return -EINVAL; + + if (oh->_int_flags & _HWMOD_NO_MPU_PORT || !oh->clkdm) + return 0; + + if (oh->flags & HWMOD_NO_IDLEST) + return 0; + + return omap4_cminst_wait_module_idle(oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); +} + +/** + * _am33xx_wait_target_disable - wait for a module to be disabled on AM33XX + * @oh: struct omap_hwmod * + * + * Wait for a module @oh to enter slave idle. Returns 0 if the module + * does not have an IDLEST bit or if the module successfully enters + * slave idle; otherwise, pass along the return value of the + * appropriate *_cm*_wait_module_idle() function. + */ +static int _am33xx_wait_target_disable(struct omap_hwmod *oh) +{ + if (!oh) + return -EINVAL; + + if (oh->_int_flags & _HWMOD_NO_MPU_PORT) + return 0; + + if (oh->flags & HWMOD_NO_IDLEST) + return 0; + + return am33xx_cm_wait_module_idle(oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); +} + +/** + * _count_mpu_irqs - count the number of MPU IRQ lines associated with @oh + * @oh: struct omap_hwmod *oh + * + * Count and return the number of MPU IRQs associated with the hwmod + * @oh. Used to allocate struct resource data. Returns 0 if @oh is + * NULL. + */ +static int _count_mpu_irqs(struct omap_hwmod *oh) +{ + struct omap_hwmod_irq_info *ohii; + int i = 0; + + if (!oh || !oh->mpu_irqs) + return 0; + + do { + ohii = &oh->mpu_irqs[i++]; + } while (ohii->irq != -1); + + return i-1; +} + +/** + * _count_sdma_reqs - count the number of SDMA request lines associated with @oh + * @oh: struct omap_hwmod *oh + * + * Count and return the number of SDMA request lines associated with + * the hwmod @oh. Used to allocate struct resource data. Returns 0 + * if @oh is NULL. + */ +static int _count_sdma_reqs(struct omap_hwmod *oh) +{ + struct omap_hwmod_dma_info *ohdi; + int i = 0; + + if (!oh || !oh->sdma_reqs) + return 0; + + do { + ohdi = &oh->sdma_reqs[i++]; + } while (ohdi->dma_req != -1); + + return i-1; +} + +/** + * _count_ocp_if_addr_spaces - count the number of address space entries for @oh + * @oh: struct omap_hwmod *oh + * + * Count and return the number of address space ranges associated with + * the hwmod @oh. Used to allocate struct resource data. Returns 0 + * if @oh is NULL. + */ +static int _count_ocp_if_addr_spaces(struct omap_hwmod_ocp_if *os) +{ + struct omap_hwmod_addr_space *mem; + int i = 0; + + if (!os || !os->addr) + return 0; + + do { + mem = &os->addr[i++]; + } while (mem->pa_start != mem->pa_end); + + return i-1; +} + +/** + * _get_mpu_irq_by_name - fetch MPU interrupt line number by name + * @oh: struct omap_hwmod * to operate on + * @name: pointer to the name of the MPU interrupt number to fetch (optional) + * @irq: pointer to an unsigned int to store the MPU IRQ number to + * + * Retrieve a MPU hardware IRQ line number named by @name associated + * with the IP block pointed to by @oh. The IRQ number will be filled + * into the address pointed to by @dma. When @name is non-null, the + * IRQ line number associated with the named entry will be returned. + * If @name is null, the first matching entry will be returned. Data + * order is not meaningful in hwmod data, so callers are strongly + * encouraged to use a non-null @name whenever possible to avoid + * unpredictable effects if hwmod data is later added that causes data + * ordering to change. Returns 0 upon success or a negative error + * code upon error. + */ +static int _get_mpu_irq_by_name(struct omap_hwmod *oh, const char *name, + unsigned int *irq) +{ + int i; + bool found = false; + + if (!oh->mpu_irqs) + return -ENOENT; + + i = 0; + while (oh->mpu_irqs[i].irq != -1) { + if (name == oh->mpu_irqs[i].name || + !strcmp(name, oh->mpu_irqs[i].name)) { + found = true; + break; + } + i++; + } + + if (!found) + return -ENOENT; + + *irq = oh->mpu_irqs[i].irq; + + return 0; +} + +/** + * _get_sdma_req_by_name - fetch SDMA request line ID by name + * @oh: struct omap_hwmod * to operate on + * @name: pointer to the name of the SDMA request line to fetch (optional) + * @dma: pointer to an unsigned int to store the request line ID to + * + * Retrieve an SDMA request line ID named by @name on the IP block + * pointed to by @oh. The ID will be filled into the address pointed + * to by @dma. When @name is non-null, the request line ID associated + * with the named entry will be returned. If @name is null, the first + * matching entry will be returned. Data order is not meaningful in + * hwmod data, so callers are strongly encouraged to use a non-null + * @name whenever possible to avoid unpredictable effects if hwmod + * data is later added that causes data ordering to change. Returns 0 + * upon success or a negative error code upon error. + */ +static int _get_sdma_req_by_name(struct omap_hwmod *oh, const char *name, + unsigned int *dma) +{ + int i; + bool found = false; + + if (!oh->sdma_reqs) + return -ENOENT; + + i = 0; + while (oh->sdma_reqs[i].dma_req != -1) { + if (name == oh->sdma_reqs[i].name || + !strcmp(name, oh->sdma_reqs[i].name)) { + found = true; + break; + } + i++; + } + + if (!found) + return -ENOENT; + + *dma = oh->sdma_reqs[i].dma_req; + + return 0; +} + +/** + * _get_addr_space_by_name - fetch address space start & end by name + * @oh: struct omap_hwmod * to operate on + * @name: pointer to the name of the address space to fetch (optional) + * @pa_start: pointer to a u32 to store the starting address to + * @pa_end: pointer to a u32 to store the ending address to + * + * Retrieve address space start and end addresses for the IP block + * pointed to by @oh. The data will be filled into the addresses + * pointed to by @pa_start and @pa_end. When @name is non-null, the + * address space data associated with the named entry will be + * returned. If @name is null, the first matching entry will be + * returned. Data order is not meaningful in hwmod data, so callers + * are strongly encouraged to use a non-null @name whenever possible + * to avoid unpredictable effects if hwmod data is later added that + * causes data ordering to change. Returns 0 upon success or a + * negative error code upon error. + */ +static int _get_addr_space_by_name(struct omap_hwmod *oh, const char *name, + u32 *pa_start, u32 *pa_end) +{ + int i, j; + struct omap_hwmod_ocp_if *os; + struct list_head *p = NULL; + bool found = false; + + p = oh->slave_ports.next; + + i = 0; + while (i < oh->slaves_cnt) { + os = _fetch_next_ocp_if(&p, &i); + + if (!os->addr) + return -ENOENT; + + j = 0; + while (os->addr[j].pa_start != os->addr[j].pa_end) { + if (name == os->addr[j].name || + !strcmp(name, os->addr[j].name)) { + found = true; + break; + } + j++; + } + + if (found) + break; + } + + if (!found) + return -ENOENT; + + *pa_start = os->addr[j].pa_start; + *pa_end = os->addr[j].pa_end; + + return 0; +} + +/** + * _save_mpu_port_index - find and save the index to @oh's MPU port + * @oh: struct omap_hwmod * + * + * Determines the array index of the OCP slave port that the MPU uses + * to address the device, and saves it into the struct omap_hwmod. + * Intended to be called during hwmod registration only. No return + * value. + */ +static void __init _save_mpu_port_index(struct omap_hwmod *oh) +{ + struct omap_hwmod_ocp_if *os = NULL; + struct list_head *p; + int i = 0; + + if (!oh) + return; + + oh->_int_flags |= _HWMOD_NO_MPU_PORT; + + p = oh->slave_ports.next; + + while (i < oh->slaves_cnt) { + os = _fetch_next_ocp_if(&p, &i); + if (os->user & OCP_USER_MPU) { + oh->_mpu_port = os; + oh->_int_flags &= ~_HWMOD_NO_MPU_PORT; + break; + } + } + + return; +} + +/** + * _find_mpu_rt_port - return omap_hwmod_ocp_if accessible by the MPU + * @oh: struct omap_hwmod * + * + * Given a pointer to a struct omap_hwmod record @oh, return a pointer + * to the struct omap_hwmod_ocp_if record that is used by the MPU to + * communicate with the IP block. This interface need not be directly + * connected to the MPU (and almost certainly is not), but is directly + * connected to the IP block represented by @oh. Returns a pointer + * to the struct omap_hwmod_ocp_if * upon success, or returns NULL upon + * error or if there does not appear to be a path from the MPU to this + * IP block. + */ +static struct omap_hwmod_ocp_if *_find_mpu_rt_port(struct omap_hwmod *oh) +{ + if (!oh || oh->_int_flags & _HWMOD_NO_MPU_PORT || oh->slaves_cnt == 0) + return NULL; + + return oh->_mpu_port; +}; + +/** + * _find_mpu_rt_addr_space - return MPU register target address space for @oh + * @oh: struct omap_hwmod * + * + * Returns a pointer to the struct omap_hwmod_addr_space record representing + * the register target MPU address space; or returns NULL upon error. + */ +static struct omap_hwmod_addr_space * __init _find_mpu_rt_addr_space(struct omap_hwmod *oh) +{ + struct omap_hwmod_ocp_if *os; + struct omap_hwmod_addr_space *mem; + int found = 0, i = 0; + + os = _find_mpu_rt_port(oh); + if (!os || !os->addr) + return NULL; + + do { + mem = &os->addr[i++]; + if (mem->flags & ADDR_TYPE_RT) + found = 1; + } while (!found && mem->pa_start != mem->pa_end); + + return (found) ? mem : NULL; +} + +/** + * _enable_sysc - try to bring a module out of idle via OCP_SYSCONFIG + * @oh: struct omap_hwmod * + * + * Ensure that the OCP_SYSCONFIG register for the IP block represented + * by @oh is set to indicate to the PRCM that the IP block is active. + * Usually this means placing the module into smart-idle mode and + * smart-standby, but if there is a bug in the automatic idle handling + * for the IP block, it may need to be placed into the force-idle or + * no-idle variants of these modes. No return value. + */ +static void _enable_sysc(struct omap_hwmod *oh) +{ + u8 idlemode, sf; + u32 v; + bool clkdm_act; + struct clockdomain *clkdm; + + if (!oh->class->sysc) + return; + + /* + * Wait until reset has completed, this is needed as the IP + * block is reset automatically by hardware in some cases + * (off-mode for example), and the drivers require the + * IP to be ready when they access it + */ + if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) + _enable_optional_clocks(oh); + _wait_softreset_complete(oh); + if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) + _disable_optional_clocks(oh); + + v = oh->_sysc_cache; + sf = oh->class->sysc->sysc_flags; + + clkdm = _get_clkdm(oh); + if (sf & SYSC_HAS_SIDLEMODE) { + if (oh->flags & HWMOD_SWSUP_SIDLE || + oh->flags & HWMOD_SWSUP_SIDLE_ACT) { + idlemode = HWMOD_IDLEMODE_NO; + } else { + if (sf & SYSC_HAS_ENAWAKEUP) + _enable_wakeup(oh, &v); + if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) + idlemode = HWMOD_IDLEMODE_SMART_WKUP; + else + idlemode = HWMOD_IDLEMODE_SMART; + } + + /* + * This is special handling for some IPs like + * 32k sync timer. Force them to idle! + */ + clkdm_act = (clkdm && clkdm->flags & CLKDM_ACTIVE_WITH_MPU); + if (clkdm_act && !(oh->class->sysc->idlemodes & + (SIDLE_SMART | SIDLE_SMART_WKUP))) + idlemode = HWMOD_IDLEMODE_FORCE; + + _set_slave_idlemode(oh, idlemode, &v); + } + + if (sf & SYSC_HAS_MIDLEMODE) { + if (oh->flags & HWMOD_FORCE_MSTANDBY) { + idlemode = HWMOD_IDLEMODE_FORCE; + } else if (oh->flags & HWMOD_SWSUP_MSTANDBY) { + idlemode = HWMOD_IDLEMODE_NO; + } else { + if (sf & SYSC_HAS_ENAWAKEUP) + _enable_wakeup(oh, &v); + if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP) + idlemode = HWMOD_IDLEMODE_SMART_WKUP; + else + idlemode = HWMOD_IDLEMODE_SMART; + } + _set_master_standbymode(oh, idlemode, &v); + } + + /* + * XXX The clock framework should handle this, by + * calling into this code. But this must wait until the + * clock structures are tagged with omap_hwmod entries + */ + if ((oh->flags & HWMOD_SET_DEFAULT_CLOCKACT) && + (sf & SYSC_HAS_CLOCKACTIVITY)) + _set_clockactivity(oh, oh->class->sysc->clockact, &v); + + /* If the cached value is the same as the new value, skip the write */ + if (oh->_sysc_cache != v) + _write_sysconfig(v, oh); + + /* + * Set the autoidle bit only after setting the smartidle bit + * Setting this will not have any impact on the other modules. + */ + if (sf & SYSC_HAS_AUTOIDLE) { + idlemode = (oh->flags & HWMOD_NO_OCP_AUTOIDLE) ? + 0 : 1; + _set_module_autoidle(oh, idlemode, &v); + _write_sysconfig(v, oh); + } +} + +/** + * _idle_sysc - try to put a module into idle via OCP_SYSCONFIG + * @oh: struct omap_hwmod * + * + * If module is marked as SWSUP_SIDLE, force the module into slave + * idle; otherwise, configure it for smart-idle. If module is marked + * as SWSUP_MSUSPEND, force the module into master standby; otherwise, + * configure it for smart-standby. No return value. + */ +static void _idle_sysc(struct omap_hwmod *oh) +{ + u8 idlemode, sf; + u32 v; + + if (!oh->class->sysc) + return; + + v = oh->_sysc_cache; + sf = oh->class->sysc->sysc_flags; + + if (sf & SYSC_HAS_SIDLEMODE) { + if (oh->flags & HWMOD_SWSUP_SIDLE) { + idlemode = HWMOD_IDLEMODE_FORCE; + } else { + if (sf & SYSC_HAS_ENAWAKEUP) + _enable_wakeup(oh, &v); + if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) + idlemode = HWMOD_IDLEMODE_SMART_WKUP; + else + idlemode = HWMOD_IDLEMODE_SMART; + } + _set_slave_idlemode(oh, idlemode, &v); + } + + if (sf & SYSC_HAS_MIDLEMODE) { + if ((oh->flags & HWMOD_SWSUP_MSTANDBY) || + (oh->flags & HWMOD_FORCE_MSTANDBY)) { + idlemode = HWMOD_IDLEMODE_FORCE; + } else { + if (sf & SYSC_HAS_ENAWAKEUP) + _enable_wakeup(oh, &v); + if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP) + idlemode = HWMOD_IDLEMODE_SMART_WKUP; + else + idlemode = HWMOD_IDLEMODE_SMART; + } + _set_master_standbymode(oh, idlemode, &v); + } + + _write_sysconfig(v, oh); +} + +/** + * _shutdown_sysc - force a module into idle via OCP_SYSCONFIG + * @oh: struct omap_hwmod * + * + * Force the module into slave idle and master suspend. No return + * value. + */ +static void _shutdown_sysc(struct omap_hwmod *oh) +{ + u32 v; + u8 sf; + + if (!oh->class->sysc) + return; + + v = oh->_sysc_cache; + sf = oh->class->sysc->sysc_flags; + + if (sf & SYSC_HAS_SIDLEMODE) + _set_slave_idlemode(oh, HWMOD_IDLEMODE_FORCE, &v); + + if (sf & SYSC_HAS_MIDLEMODE) + _set_master_standbymode(oh, HWMOD_IDLEMODE_FORCE, &v); + + if (sf & SYSC_HAS_AUTOIDLE) + _set_module_autoidle(oh, 1, &v); + + _write_sysconfig(v, oh); +} + +/** + * _lookup - find an omap_hwmod by name + * @name: find an omap_hwmod by name + * + * Return a pointer to an omap_hwmod by name, or NULL if not found. + */ +static struct omap_hwmod *_lookup(const char *name) +{ + struct omap_hwmod *oh, *temp_oh; + + oh = NULL; + + list_for_each_entry(temp_oh, &omap_hwmod_list, node) { + if (!strcmp(name, temp_oh->name)) { + oh = temp_oh; + break; + } + } + + return oh; +} + +/** + * _init_clkdm - look up a clockdomain name, store pointer in omap_hwmod + * @oh: struct omap_hwmod * + * + * Convert a clockdomain name stored in a struct omap_hwmod into a + * clockdomain pointer, and save it into the struct omap_hwmod. + * Return -EINVAL if the clkdm_name lookup failed. + */ +static int _init_clkdm(struct omap_hwmod *oh) +{ + if (!oh->clkdm_name) { + pr_debug("omap_hwmod: %s: missing clockdomain\n", oh->name); + return 0; + } + + oh->clkdm = clkdm_lookup(oh->clkdm_name); + if (!oh->clkdm) { + pr_warning("omap_hwmod: %s: could not associate to clkdm %s\n", + oh->name, oh->clkdm_name); + return 0; + } + + pr_debug("omap_hwmod: %s: associated to clkdm %s\n", + oh->name, oh->clkdm_name); + + return 0; +} + +/** + * _init_clocks - clk_get() all clocks associated with this hwmod. Retrieve as + * well the clockdomain. + * @oh: struct omap_hwmod * + * @data: not used; pass NULL + * + * Called by omap_hwmod_setup_*() (after omap2_clk_init()). + * Resolves all clock names embedded in the hwmod. Returns 0 on + * success, or a negative error code on failure. + */ +static int _init_clocks(struct omap_hwmod *oh, void *data) +{ + int ret = 0; + + if (oh->_state != _HWMOD_STATE_REGISTERED) + return 0; + + pr_debug("omap_hwmod: %s: looking up clocks\n", oh->name); + + if (soc_ops.init_clkdm) + ret |= soc_ops.init_clkdm(oh); + + ret |= _init_main_clk(oh); + ret |= _init_interface_clks(oh); + ret |= _init_opt_clks(oh); + + if (!ret) + oh->_state = _HWMOD_STATE_CLKS_INITED; + else + pr_warning("omap_hwmod: %s: cannot _init_clocks\n", oh->name); + + return ret; +} + +/** + * _lookup_hardreset - fill register bit info for this hwmod/reset line + * @oh: struct omap_hwmod * + * @name: name of the reset line in the context of this hwmod + * @ohri: struct omap_hwmod_rst_info * that this function will fill in + * + * Return the bit position of the reset line that match the + * input name. Return -ENOENT if not found. + */ +static int _lookup_hardreset(struct omap_hwmod *oh, const char *name, + struct omap_hwmod_rst_info *ohri) +{ + int i; + + for (i = 0; i < oh->rst_lines_cnt; i++) { + const char *rst_line = oh->rst_lines[i].name; + if (!strcmp(rst_line, name)) { + ohri->rst_shift = oh->rst_lines[i].rst_shift; + ohri->st_shift = oh->rst_lines[i].st_shift; + pr_debug("omap_hwmod: %s: %s: %s: rst %d st %d\n", + oh->name, __func__, rst_line, ohri->rst_shift, + ohri->st_shift); + + return 0; + } + } + + return -ENOENT; +} + +/** + * _assert_hardreset - assert the HW reset line of submodules + * contained in the hwmod module. + * @oh: struct omap_hwmod * + * @name: name of the reset line to lookup and assert + * + * Some IP like dsp, ipu or iva contain processor that require an HW + * reset line to be assert / deassert in order to enable fully the IP. + * Returns -EINVAL if @oh is null, -ENOSYS if we have no way of + * asserting the hardreset line on the currently-booted SoC, or passes + * along the return value from _lookup_hardreset() or the SoC's + * assert_hardreset code. + */ +static int _assert_hardreset(struct omap_hwmod *oh, const char *name) +{ + struct omap_hwmod_rst_info ohri; + int ret = -EINVAL; + + if (!oh) + return -EINVAL; + + if (!soc_ops.assert_hardreset) + return -ENOSYS; + + ret = _lookup_hardreset(oh, name, &ohri); + if (ret < 0) + return ret; + + ret = soc_ops.assert_hardreset(oh, &ohri); + + return ret; +} + +/** + * _deassert_hardreset - deassert the HW reset line of submodules contained + * in the hwmod module. + * @oh: struct omap_hwmod * + * @name: name of the reset line to look up and deassert + * + * Some IP like dsp, ipu or iva contain processor that require an HW + * reset line to be assert / deassert in order to enable fully the IP. + * Returns -EINVAL if @oh is null, -ENOSYS if we have no way of + * deasserting the hardreset line on the currently-booted SoC, or passes + * along the return value from _lookup_hardreset() or the SoC's + * deassert_hardreset code. + */ +static int _deassert_hardreset(struct omap_hwmod *oh, const char *name) +{ + struct omap_hwmod_rst_info ohri; + int ret = -EINVAL; + int hwsup = 0; + + if (!oh) + return -EINVAL; + + if (!soc_ops.deassert_hardreset) + return -ENOSYS; + + ret = _lookup_hardreset(oh, name, &ohri); + if (ret < 0) + return ret; + + if (oh->clkdm) { + /* + * A clockdomain must be in SW_SUP otherwise reset + * might not be completed. The clockdomain can be set + * in HW_AUTO only when the module become ready. + */ + hwsup = clkdm_in_hwsup(oh->clkdm); + ret = clkdm_hwmod_enable(oh->clkdm, oh); + if (ret) { + WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n", + oh->name, oh->clkdm->name, ret); + return ret; + } + } + + _enable_clocks(oh); + if (soc_ops.enable_module) + soc_ops.enable_module(oh); + + ret = soc_ops.deassert_hardreset(oh, &ohri); + + if (soc_ops.disable_module) + soc_ops.disable_module(oh); + _disable_clocks(oh); + + if (ret == -EBUSY) + pr_warning("omap_hwmod: %s: failed to hardreset\n", oh->name); + + if (!ret) { + /* + * Set the clockdomain to HW_AUTO, assuming that the + * previous state was HW_AUTO. + */ + if (oh->clkdm && hwsup) + clkdm_allow_idle(oh->clkdm); + } else { + if (oh->clkdm) + clkdm_hwmod_disable(oh->clkdm, oh); + } + + return ret; +} + +/** + * _read_hardreset - read the HW reset line state of submodules + * contained in the hwmod module + * @oh: struct omap_hwmod * + * @name: name of the reset line to look up and read + * + * Return the state of the reset line. Returns -EINVAL if @oh is + * null, -ENOSYS if we have no way of reading the hardreset line + * status on the currently-booted SoC, or passes along the return + * value from _lookup_hardreset() or the SoC's is_hardreset_asserted + * code. + */ +static int _read_hardreset(struct omap_hwmod *oh, const char *name) +{ + struct omap_hwmod_rst_info ohri; + int ret = -EINVAL; + + if (!oh) + return -EINVAL; + + if (!soc_ops.is_hardreset_asserted) + return -ENOSYS; + + ret = _lookup_hardreset(oh, name, &ohri); + if (ret < 0) + return ret; + + return soc_ops.is_hardreset_asserted(oh, &ohri); +} + +/** + * _are_all_hardreset_lines_asserted - return true if the @oh is hard-reset + * @oh: struct omap_hwmod * + * + * If all hardreset lines associated with @oh are asserted, then return true. + * Otherwise, if part of @oh is out hardreset or if no hardreset lines + * associated with @oh are asserted, then return false. + * This function is used to avoid executing some parts of the IP block + * enable/disable sequence if its hardreset line is set. + */ +static bool _are_all_hardreset_lines_asserted(struct omap_hwmod *oh) +{ + int i, rst_cnt = 0; + + if (oh->rst_lines_cnt == 0) + return false; + + for (i = 0; i < oh->rst_lines_cnt; i++) + if (_read_hardreset(oh, oh->rst_lines[i].name) > 0) + rst_cnt++; + + if (oh->rst_lines_cnt == rst_cnt) + return true; + + return false; +} + +/** + * _are_any_hardreset_lines_asserted - return true if any part of @oh is + * hard-reset + * @oh: struct omap_hwmod * + * + * If any hardreset lines associated with @oh are asserted, then + * return true. Otherwise, if no hardreset lines associated with @oh + * are asserted, or if @oh has no hardreset lines, then return false. + * This function is used to avoid executing some parts of the IP block + * enable/disable sequence if any hardreset line is set. + */ +static bool _are_any_hardreset_lines_asserted(struct omap_hwmod *oh) +{ + int rst_cnt = 0; + int i; + + for (i = 0; i < oh->rst_lines_cnt && rst_cnt == 0; i++) + if (_read_hardreset(oh, oh->rst_lines[i].name) > 0) + rst_cnt++; + + return (rst_cnt) ? true : false; +} + +/** + * _omap4_disable_module - enable CLKCTRL modulemode on OMAP4 + * @oh: struct omap_hwmod * + * + * Disable the PRCM module mode related to the hwmod @oh. + * Return EINVAL if the modulemode is not supported and 0 in case of success. + */ +static int _omap4_disable_module(struct omap_hwmod *oh) +{ + int v; + + if (!oh->clkdm || !oh->prcm.omap4.modulemode) + return -EINVAL; + + /* + * Since integration code might still be doing something, only + * disable if all lines are under hardreset. + */ + if (_are_any_hardreset_lines_asserted(oh)) + return 0; + + pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__); + + omap4_cminst_module_disable(oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); + + v = _omap4_wait_target_disable(oh); + if (v) + pr_warn("omap_hwmod: %s: _wait_target_disable failed\n", + oh->name); + + return 0; +} + +/** + * _am33xx_disable_module - enable CLKCTRL modulemode on AM33XX + * @oh: struct omap_hwmod * + * + * Disable the PRCM module mode related to the hwmod @oh. + * Return EINVAL if the modulemode is not supported and 0 in case of success. + */ +static int _am33xx_disable_module(struct omap_hwmod *oh) +{ + int v; + + if (!oh->clkdm || !oh->prcm.omap4.modulemode) + return -EINVAL; + + pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__); + + if (_are_any_hardreset_lines_asserted(oh)) + return 0; + + am33xx_cm_module_disable(oh->clkdm->cm_inst, oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); + + v = _am33xx_wait_target_disable(oh); + if (v) + pr_warn("omap_hwmod: %s: _wait_target_disable failed\n", + oh->name); + + return 0; +} + +/** + * _ocp_softreset - reset an omap_hwmod via the OCP_SYSCONFIG bit + * @oh: struct omap_hwmod * + * + * Resets an omap_hwmod @oh via the OCP_SYSCONFIG bit. hwmod must be + * enabled for this to work. Returns -ENOENT if the hwmod cannot be + * reset this way, -EINVAL if the hwmod is in the wrong state, + * -ETIMEDOUT if the module did not reset in time, or 0 upon success. + * + * In OMAP3 a specific SYSSTATUS register is used to get the reset status. + * Starting in OMAP4, some IPs do not have SYSSTATUS registers and instead + * use the SYSCONFIG softreset bit to provide the status. + * + * Note that some IP like McBSP do have reset control but don't have + * reset status. + */ +static int _ocp_softreset(struct omap_hwmod *oh) +{ + u32 v; + int c = 0; + int ret = 0; + + if (!oh->class->sysc || + !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET)) + return -ENOENT; + + /* clocks must be on for this operation */ + if (oh->_state != _HWMOD_STATE_ENABLED) { + pr_warn("omap_hwmod: %s: reset can only be entered from enabled state\n", + oh->name); + return -EINVAL; + } + + /* For some modules, all optionnal clocks need to be enabled as well */ + if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) + _enable_optional_clocks(oh); + + pr_debug("omap_hwmod: %s: resetting via OCP SOFTRESET\n", oh->name); + + v = oh->_sysc_cache; + ret = _set_softreset(oh, &v); + if (ret) + goto dis_opt_clks; + + _write_sysconfig(v, oh); + + if (oh->class->sysc->srst_udelay) + udelay(oh->class->sysc->srst_udelay); + + c = _wait_softreset_complete(oh); + if (c == MAX_MODULE_SOFTRESET_WAIT) { + pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", + oh->name, MAX_MODULE_SOFTRESET_WAIT); + ret = -ETIMEDOUT; + goto dis_opt_clks; + } else { + pr_debug("omap_hwmod: %s: softreset in %d usec\n", oh->name, c); + } + + ret = _clear_softreset(oh, &v); + if (ret) + goto dis_opt_clks; + + _write_sysconfig(v, oh); + + /* + * XXX add _HWMOD_STATE_WEDGED for modules that don't come back from + * _wait_target_ready() or _reset() + */ + +dis_opt_clks: + if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) + _disable_optional_clocks(oh); + + return ret; +} + +/** + * _reset - reset an omap_hwmod + * @oh: struct omap_hwmod * + * + * Resets an omap_hwmod @oh. If the module has a custom reset + * function pointer defined, then call it to reset the IP block, and + * pass along its return value to the caller. Otherwise, if the IP + * block has an OCP_SYSCONFIG register with a SOFTRESET bitfield + * associated with it, call a function to reset the IP block via that + * method, and pass along the return value to the caller. Finally, if + * the IP block has some hardreset lines associated with it, assert + * all of those, but do _not_ deassert them. (This is because driver + * authors have expressed an apparent requirement to control the + * deassertion of the hardreset lines themselves.) + * + * The default software reset mechanism for most OMAP IP blocks is + * triggered via the OCP_SYSCONFIG.SOFTRESET bit. However, some + * hwmods cannot be reset via this method. Some are not targets and + * therefore have no OCP header registers to access. Others (like the + * IVA) have idiosyncratic reset sequences. So for these relatively + * rare cases, custom reset code can be supplied in the struct + * omap_hwmod_class .reset function pointer. + * + * _set_dmadisable() is called to set the DMADISABLE bit so that it + * does not prevent idling of the system. This is necessary for cases + * where ROMCODE/BOOTLOADER uses dma and transfers control to the + * kernel without disabling dma. + * + * Passes along the return value from either _ocp_softreset() or the + * custom reset function - these must return -EINVAL if the hwmod + * cannot be reset this way or if the hwmod is in the wrong state, + * -ETIMEDOUT if the module did not reset in time, or 0 upon success. + */ +static int _reset(struct omap_hwmod *oh) +{ + int i, r; + + pr_debug("omap_hwmod: %s: resetting\n", oh->name); + + if (oh->class->reset) { + r = oh->class->reset(oh); + } else { + if (oh->rst_lines_cnt > 0) { + for (i = 0; i < oh->rst_lines_cnt; i++) + _assert_hardreset(oh, oh->rst_lines[i].name); + return 0; + } else { + r = _ocp_softreset(oh); + if (r == -ENOENT) + r = 0; + } + } + + _set_dmadisable(oh); + + /* + * OCP_SYSCONFIG bits need to be reprogrammed after a + * softreset. The _enable() function should be split to avoid + * the rewrite of the OCP_SYSCONFIG register. + */ + if (oh->class->sysc) { + _update_sysc_cache(oh); + _enable_sysc(oh); + } + + return r; +} + +/** + * _reconfigure_io_chain - clear any I/O chain wakeups and reconfigure chain + * + * Call the appropriate PRM function to clear any logged I/O chain + * wakeups and to reconfigure the chain. This apparently needs to be + * done upon every mux change. Since hwmods can be concurrently + * enabled and idled, hold a spinlock around the I/O chain + * reconfiguration sequence. No return value. + * + * XXX When the PRM code is moved to drivers, this function can be removed, + * as the PRM infrastructure should abstract this. + */ +static void _reconfigure_io_chain(void) +{ + unsigned long flags; + + spin_lock_irqsave(&io_chain_lock, flags); + + if (cpu_is_omap34xx() && omap3_has_io_chain_ctrl()) + omap3xxx_prm_reconfigure_io_chain(); + else if (cpu_is_omap44xx()) + omap44xx_prm_reconfigure_io_chain(); + + spin_unlock_irqrestore(&io_chain_lock, flags); +} + +/** + * _omap4_update_context_lost - increment hwmod context loss counter if + * hwmod context was lost, and clear hardware context loss reg + * @oh: hwmod to check for context loss + * + * If the PRCM indicates that the hwmod @oh lost context, increment + * our in-memory context loss counter, and clear the RM_*_CONTEXT + * bits. No return value. + */ +static void _omap4_update_context_lost(struct omap_hwmod *oh) +{ + if (oh->prcm.omap4.flags & HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT) + return; + + if (!prm_was_any_context_lost_old(oh->clkdm->pwrdm.ptr->prcm_partition, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.context_offs)) + return; + + oh->prcm.omap4.context_lost_counter++; + prm_clear_context_loss_flags_old(oh->clkdm->pwrdm.ptr->prcm_partition, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.context_offs); +} + +/** + * _omap4_get_context_lost - get context loss counter for a hwmod + * @oh: hwmod to get context loss counter for + * + * Returns the in-memory context loss counter for a hwmod. + */ +static int _omap4_get_context_lost(struct omap_hwmod *oh) +{ + return oh->prcm.omap4.context_lost_counter; +} + +/** + * _enable_preprogram - Pre-program an IP block during the _enable() process + * @oh: struct omap_hwmod * + * + * Some IP blocks (such as AESS) require some additional programming + * after enable before they can enter idle. If a function pointer to + * do so is present in the hwmod data, then call it and pass along the + * return value; otherwise, return 0. + */ +static int _enable_preprogram(struct omap_hwmod *oh) +{ + if (!oh->class->enable_preprogram) + return 0; + + return oh->class->enable_preprogram(oh); +} + +/** + * _enable - enable an omap_hwmod + * @oh: struct omap_hwmod * + * + * Enables an omap_hwmod @oh such that the MPU can access the hwmod's + * register target. Returns -EINVAL if the hwmod is in the wrong + * state or passes along the return value of _wait_target_ready(). + */ +static int _enable(struct omap_hwmod *oh) +{ + int r; + int hwsup = 0; + + pr_debug("omap_hwmod: %s: enabling\n", oh->name); + + /* + * hwmods with HWMOD_INIT_NO_IDLE flag set are left in enabled + * state at init. Now that someone is really trying to enable + * them, just ensure that the hwmod mux is set. + */ + if (oh->_int_flags & _HWMOD_SKIP_ENABLE) { + /* + * If the caller has mux data populated, do the mux'ing + * which wouldn't have been done as part of the _enable() + * done during setup. + */ + if (oh->mux) + omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED); + + oh->_int_flags &= ~_HWMOD_SKIP_ENABLE; + return 0; + } + + if (oh->_state != _HWMOD_STATE_INITIALIZED && + oh->_state != _HWMOD_STATE_IDLE && + oh->_state != _HWMOD_STATE_DISABLED) { + WARN(1, "omap_hwmod: %s: enabled state can only be entered from initialized, idle, or disabled state\n", + oh->name); + return -EINVAL; + } + + /* + * If an IP block contains HW reset lines and all of them are + * asserted, we let integration code associated with that + * block handle the enable. We've received very little + * information on what those driver authors need, and until + * detailed information is provided and the driver code is + * posted to the public lists, this is probably the best we + * can do. + */ + if (_are_all_hardreset_lines_asserted(oh)) + return 0; + + /* Mux pins for device runtime if populated */ + if (oh->mux && (!oh->mux->enabled || + ((oh->_state == _HWMOD_STATE_IDLE) && + oh->mux->pads_dynamic))) { + omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED); + _reconfigure_io_chain(); + } + + _add_initiator_dep(oh, mpu_oh); + + if (oh->clkdm) { + /* + * A clockdomain must be in SW_SUP before enabling + * completely the module. The clockdomain can be set + * in HW_AUTO only when the module become ready. + */ + hwsup = clkdm_in_hwsup(oh->clkdm) && + !clkdm_missing_idle_reporting(oh->clkdm); + r = clkdm_hwmod_enable(oh->clkdm, oh); + if (r) { + WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n", + oh->name, oh->clkdm->name, r); + return r; + } + } + + _enable_clocks(oh); + if (soc_ops.enable_module) + soc_ops.enable_module(oh); + if (oh->flags & HWMOD_BLOCK_WFI) + cpu_idle_poll_ctrl(true); + + if (soc_ops.update_context_lost) + soc_ops.update_context_lost(oh); + + r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) : + -EINVAL; + if (!r) { + /* + * Set the clockdomain to HW_AUTO only if the target is ready, + * assuming that the previous state was HW_AUTO + */ + if (oh->clkdm && hwsup) + clkdm_allow_idle(oh->clkdm); + + oh->_state = _HWMOD_STATE_ENABLED; + + /* Access the sysconfig only if the target is ready */ + if (oh->class->sysc) { + if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED)) + _update_sysc_cache(oh); + _enable_sysc(oh); + } + r = _enable_preprogram(oh); + } else { + if (soc_ops.disable_module) + soc_ops.disable_module(oh); + _disable_clocks(oh); + pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n", + oh->name, r); + + if (oh->clkdm) + clkdm_hwmod_disable(oh->clkdm, oh); + } + + return r; +} + +/** + * _idle - idle an omap_hwmod + * @oh: struct omap_hwmod * + * + * Idles an omap_hwmod @oh. This should be called once the hwmod has + * no further work. Returns -EINVAL if the hwmod is in the wrong + * state or returns 0. + */ +static int _idle(struct omap_hwmod *oh) +{ + pr_debug("omap_hwmod: %s: idling\n", oh->name); + + if (oh->_state != _HWMOD_STATE_ENABLED) { + WARN(1, "omap_hwmod: %s: idle state can only be entered from enabled state\n", + oh->name); + return -EINVAL; + } + + if (_are_all_hardreset_lines_asserted(oh)) + return 0; + + if (oh->class->sysc) + _idle_sysc(oh); + _del_initiator_dep(oh, mpu_oh); + + if (oh->flags & HWMOD_BLOCK_WFI) + cpu_idle_poll_ctrl(false); + if (soc_ops.disable_module) + soc_ops.disable_module(oh); + + /* + * The module must be in idle mode before disabling any parents + * clocks. Otherwise, the parent clock might be disabled before + * the module transition is done, and thus will prevent the + * transition to complete properly. + */ + _disable_clocks(oh); + if (oh->clkdm) + clkdm_hwmod_disable(oh->clkdm, oh); + + /* Mux pins for device idle if populated */ + if (oh->mux && oh->mux->pads_dynamic) { + omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE); + _reconfigure_io_chain(); + } + + oh->_state = _HWMOD_STATE_IDLE; + + return 0; +} + +/** + * _shutdown - shutdown an omap_hwmod + * @oh: struct omap_hwmod * + * + * Shut down an omap_hwmod @oh. This should be called when the driver + * used for the hwmod is removed or unloaded or if the driver is not + * used by the system. Returns -EINVAL if the hwmod is in the wrong + * state or returns 0. + */ +static int _shutdown(struct omap_hwmod *oh) +{ + int ret, i; + u8 prev_state; + + if (oh->_state != _HWMOD_STATE_IDLE && + oh->_state != _HWMOD_STATE_ENABLED) { + WARN(1, "omap_hwmod: %s: disabled state can only be entered from idle, or enabled state\n", + oh->name); + return -EINVAL; + } + + if (_are_all_hardreset_lines_asserted(oh)) + return 0; + + pr_debug("omap_hwmod: %s: disabling\n", oh->name); + + if (oh->class->pre_shutdown) { + prev_state = oh->_state; + if (oh->_state == _HWMOD_STATE_IDLE) + _enable(oh); + ret = oh->class->pre_shutdown(oh); + if (ret) { + if (prev_state == _HWMOD_STATE_IDLE) + _idle(oh); + return ret; + } + } + + if (oh->class->sysc) { + if (oh->_state == _HWMOD_STATE_IDLE) + _enable(oh); + _shutdown_sysc(oh); + } + + /* clocks and deps are already disabled in idle */ + if (oh->_state == _HWMOD_STATE_ENABLED) { + _del_initiator_dep(oh, mpu_oh); + /* XXX what about the other system initiators here? dma, dsp */ + if (oh->flags & HWMOD_BLOCK_WFI) + cpu_idle_poll_ctrl(false); + if (soc_ops.disable_module) + soc_ops.disable_module(oh); + _disable_clocks(oh); + if (oh->clkdm) + clkdm_hwmod_disable(oh->clkdm, oh); + } + /* XXX Should this code also force-disable the optional clocks? */ + + for (i = 0; i < oh->rst_lines_cnt; i++) + _assert_hardreset(oh, oh->rst_lines[i].name); + + /* Mux pins to safe mode or use populated off mode values */ + if (oh->mux) + omap_hwmod_mux(oh->mux, _HWMOD_STATE_DISABLED); + + oh->_state = _HWMOD_STATE_DISABLED; + + return 0; +} + +static int of_dev_find_hwmod(struct device_node *np, + struct omap_hwmod *oh) +{ + int count, i, res; + const char *p; + + count = of_property_count_strings(np, "ti,hwmods"); + if (count < 1) + return -ENODEV; + + for (i = 0; i < count; i++) { + res = of_property_read_string_index(np, "ti,hwmods", + i, &p); + if (res) + continue; + if (!strcmp(p, oh->name)) { + pr_debug("omap_hwmod: dt %s[%i] uses hwmod %s\n", + np->name, i, oh->name); + return i; + } + } + + return -ENODEV; +} + +/** + * of_dev_hwmod_lookup - look up needed hwmod from dt blob + * @np: struct device_node * + * @oh: struct omap_hwmod * + * @index: index of the entry found + * @found: struct device_node * found or NULL + * + * Parse the dt blob and find out needed hwmod. Recursive function is + * implemented to take care hierarchical dt blob parsing. + * Return: Returns 0 on success, -ENODEV when not found. + */ +static int of_dev_hwmod_lookup(struct device_node *np, + struct omap_hwmod *oh, + int *index, + struct device_node **found) +{ + struct device_node *np0 = NULL; + int res; + + res = of_dev_find_hwmod(np, oh); + if (res >= 0) { + *found = np; + *index = res; + return 0; + } + + for_each_child_of_node(np, np0) { + struct device_node *fc; + int i; + + res = of_dev_hwmod_lookup(np0, oh, &i, &fc); + if (res == 0) { + *found = fc; + *index = i; + return 0; + } + } + + *found = NULL; + *index = 0; + + return -ENODEV; +} + +/** + * _init_mpu_rt_base - populate the virtual address for a hwmod + * @oh: struct omap_hwmod * to locate the virtual address + * @data: (unused, caller should pass NULL) + * @index: index of the reg entry iospace in device tree + * @np: struct device_node * of the IP block's device node in the DT data + * + * Cache the virtual address used by the MPU to access this IP block's + * registers. This address is needed early so the OCP registers that + * are part of the device's address space can be ioremapped properly. + * + * Returns 0 on success, -EINVAL if an invalid hwmod is passed, and + * -ENXIO on absent or invalid register target address space. + */ +static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data, + int index, struct device_node *np) +{ + struct omap_hwmod_addr_space *mem; + void __iomem *va_start = NULL; + + if (!oh) + return -EINVAL; + + _save_mpu_port_index(oh); + + if (oh->_int_flags & _HWMOD_NO_MPU_PORT) + return -ENXIO; + + mem = _find_mpu_rt_addr_space(oh); + if (!mem) { + pr_debug("omap_hwmod: %s: no MPU register target found\n", + oh->name); + + /* Extract the IO space from device tree blob */ + if (!np) + return -ENXIO; + + va_start = of_iomap(np, index + oh->mpu_rt_idx); + } else { + va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start); + } + + if (!va_start) { + if (mem) + pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name); + else + pr_err("omap_hwmod: %s: Missing dt reg%i for %s\n", + oh->name, index, np->full_name); + return -ENXIO; + } + + pr_debug("omap_hwmod: %s: MPU register target at va %p\n", + oh->name, va_start); + + oh->_mpu_rt_va = va_start; + return 0; +} + +/** + * _init - initialize internal data for the hwmod @oh + * @oh: struct omap_hwmod * + * @n: (unused) + * + * Look up the clocks and the address space used by the MPU to access + * registers belonging to the hwmod @oh. @oh must already be + * registered at this point. This is the first of two phases for + * hwmod initialization. Code called here does not touch any hardware + * registers, it simply prepares internal data structures. Returns 0 + * upon success or if the hwmod isn't registered or if the hwmod's + * address space is not defined, or -EINVAL upon failure. + */ +static int __init _init(struct omap_hwmod *oh, void *data) +{ + int r, index; + struct device_node *np = NULL; + + if (oh->_state != _HWMOD_STATE_REGISTERED) + return 0; + + if (of_have_populated_dt()) { + struct device_node *bus; + + bus = of_find_node_by_name(NULL, "ocp"); + if (!bus) + return -ENODEV; + + r = of_dev_hwmod_lookup(bus, oh, &index, &np); + if (r) + pr_debug("omap_hwmod: %s missing dt data\n", oh->name); + else if (np && index) + pr_warn("omap_hwmod: %s using broken dt data from %s\n", + oh->name, np->name); + } + + if (oh->class->sysc) { + r = _init_mpu_rt_base(oh, NULL, index, np); + if (r < 0) { + WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n", + oh->name); + return 0; + } + } + + r = _init_clocks(oh, NULL); + if (r < 0) { + WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name); + return -EINVAL; + } + + if (np) { + if (of_find_property(np, "ti,no-reset-on-init", NULL)) + oh->flags |= HWMOD_INIT_NO_RESET; + if (of_find_property(np, "ti,no-idle-on-init", NULL)) + oh->flags |= HWMOD_INIT_NO_IDLE; + } + + oh->_state = _HWMOD_STATE_INITIALIZED; + + return 0; +} + +/** + * _setup_iclk_autoidle - configure an IP block's interface clocks + * @oh: struct omap_hwmod * + * + * Set up the module's interface clocks. XXX This function is still mostly + * a stub; implementing this properly requires iclk autoidle usecounting in + * the clock code. No return value. + */ +static void __init _setup_iclk_autoidle(struct omap_hwmod *oh) +{ + struct omap_hwmod_ocp_if *os; + struct list_head *p; + int i = 0; + if (oh->_state != _HWMOD_STATE_INITIALIZED) + return; + + p = oh->slave_ports.next; + + while (i < oh->slaves_cnt) { + os = _fetch_next_ocp_if(&p, &i); + if (!os->_clk) + continue; + + if (os->flags & OCPIF_SWSUP_IDLE) { + /* XXX omap_iclk_deny_idle(c); */ + } else { + /* XXX omap_iclk_allow_idle(c); */ + clk_enable(os->_clk); + } + } + + return; +} + +/** + * _setup_reset - reset an IP block during the setup process + * @oh: struct omap_hwmod * + * + * Reset the IP block corresponding to the hwmod @oh during the setup + * process. The IP block is first enabled so it can be successfully + * reset. Returns 0 upon success or a negative error code upon + * failure. + */ +static int __init _setup_reset(struct omap_hwmod *oh) +{ + int r; + + if (oh->_state != _HWMOD_STATE_INITIALIZED) + return -EINVAL; + + if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK) + return -EPERM; + + if (oh->rst_lines_cnt == 0) { + r = _enable(oh); + if (r) { + pr_warning("omap_hwmod: %s: cannot be enabled for reset (%d)\n", + oh->name, oh->_state); + return -EINVAL; + } + } + + if (!(oh->flags & HWMOD_INIT_NO_RESET)) + r = _reset(oh); + + return r; +} + +/** + * _setup_postsetup - transition to the appropriate state after _setup + * @oh: struct omap_hwmod * + * + * Place an IP block represented by @oh into a "post-setup" state -- + * either IDLE, ENABLED, or DISABLED. ("post-setup" simply means that + * this function is called at the end of _setup().) The postsetup + * state for an IP block can be changed by calling + * omap_hwmod_enter_postsetup_state() early in the boot process, + * before one of the omap_hwmod_setup*() functions are called for the + * IP block. + * + * The IP block stays in this state until a PM runtime-based driver is + * loaded for that IP block. A post-setup state of IDLE is + * appropriate for almost all IP blocks with runtime PM-enabled + * drivers, since those drivers are able to enable the IP block. A + * post-setup state of ENABLED is appropriate for kernels with PM + * runtime disabled. The DISABLED state is appropriate for unusual IP + * blocks such as the MPU WDTIMER on kernels without WDTIMER drivers + * included, since the WDTIMER starts running on reset and will reset + * the MPU if left active. + * + * This post-setup mechanism is deprecated. Once all of the OMAP + * drivers have been converted to use PM runtime, and all of the IP + * block data and interconnect data is available to the hwmod code, it + * should be possible to replace this mechanism with a "lazy reset" + * arrangement. In a "lazy reset" setup, each IP block is enabled + * when the driver first probes, then all remaining IP blocks without + * drivers are either shut down or enabled after the drivers have + * loaded. However, this cannot take place until the above + * preconditions have been met, since otherwise the late reset code + * has no way of knowing which IP blocks are in use by drivers, and + * which ones are unused. + * + * No return value. + */ +static void __init _setup_postsetup(struct omap_hwmod *oh) +{ + u8 postsetup_state; + + if (oh->rst_lines_cnt > 0) + return; + + postsetup_state = oh->_postsetup_state; + if (postsetup_state == _HWMOD_STATE_UNKNOWN) + postsetup_state = _HWMOD_STATE_ENABLED; + + /* + * XXX HWMOD_INIT_NO_IDLE does not belong in hwmod data - + * it should be set by the core code as a runtime flag during startup + */ + if ((oh->flags & HWMOD_INIT_NO_IDLE) && + (postsetup_state == _HWMOD_STATE_IDLE)) { + oh->_int_flags |= _HWMOD_SKIP_ENABLE; + postsetup_state = _HWMOD_STATE_ENABLED; + } + + if (postsetup_state == _HWMOD_STATE_IDLE) + _idle(oh); + else if (postsetup_state == _HWMOD_STATE_DISABLED) + _shutdown(oh); + else if (postsetup_state != _HWMOD_STATE_ENABLED) + WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n", + oh->name, postsetup_state); + + return; +} + +/** + * _setup - prepare IP block hardware for use + * @oh: struct omap_hwmod * + * @n: (unused, pass NULL) + * + * Configure the IP block represented by @oh. This may include + * enabling the IP block, resetting it, and placing it into a + * post-setup state, depending on the type of IP block and applicable + * flags. IP blocks are reset to prevent any previous configuration + * by the bootloader or previous operating system from interfering + * with power management or other parts of the system. The reset can + * be avoided; see omap_hwmod_no_setup_reset(). This is the second of + * two phases for hwmod initialization. Code called here generally + * affects the IP block hardware, or system integration hardware + * associated with the IP block. Returns 0. + */ +static int __init _setup(struct omap_hwmod *oh, void *data) +{ + if (oh->_state != _HWMOD_STATE_INITIALIZED) + return 0; + + _setup_iclk_autoidle(oh); + + if (!_setup_reset(oh)) + _setup_postsetup(oh); + + return 0; +} + +/** + * _register - register a struct omap_hwmod + * @oh: struct omap_hwmod * + * + * Registers the omap_hwmod @oh. Returns -EEXIST if an omap_hwmod + * already has been registered by the same name; -EINVAL if the + * omap_hwmod is in the wrong state, if @oh is NULL, if the + * omap_hwmod's class field is NULL; if the omap_hwmod is missing a + * name, or if the omap_hwmod's class is missing a name; or 0 upon + * success. + * + * XXX The data should be copied into bootmem, so the original data + * should be marked __initdata and freed after init. This would allow + * unneeded omap_hwmods to be freed on multi-OMAP configurations. Note + * that the copy process would be relatively complex due to the large number + * of substructures. + */ +static int __init _register(struct omap_hwmod *oh) +{ + if (!oh || !oh->name || !oh->class || !oh->class->name || + (oh->_state != _HWMOD_STATE_UNKNOWN)) + return -EINVAL; + + pr_debug("omap_hwmod: %s: registering\n", oh->name); + + if (_lookup(oh->name)) + return -EEXIST; + + list_add_tail(&oh->node, &omap_hwmod_list); + + INIT_LIST_HEAD(&oh->master_ports); + INIT_LIST_HEAD(&oh->slave_ports); + spin_lock_init(&oh->_lock); + + oh->_state = _HWMOD_STATE_REGISTERED; + + /* + * XXX Rather than doing a strcmp(), this should test a flag + * set in the hwmod data, inserted by the autogenerator code. + */ + if (!strcmp(oh->name, MPU_INITIATOR_NAME)) + mpu_oh = oh; + + return 0; +} + +/** + * _alloc_links - return allocated memory for hwmod links + * @ml: pointer to a struct omap_hwmod_link * for the master link + * @sl: pointer to a struct omap_hwmod_link * for the slave link + * + * Return pointers to two struct omap_hwmod_link records, via the + * addresses pointed to by @ml and @sl. Will first attempt to return + * memory allocated as part of a large initial block, but if that has + * been exhausted, will allocate memory itself. Since ideally this + * second allocation path will never occur, the number of these + * 'supplemental' allocations will be logged when debugging is + * enabled. Returns 0. + */ +static int __init _alloc_links(struct omap_hwmod_link **ml, + struct omap_hwmod_link **sl) +{ + unsigned int sz; + + if ((free_ls + LINKS_PER_OCP_IF) <= max_ls) { + *ml = &linkspace[free_ls++]; + *sl = &linkspace[free_ls++]; + return 0; + } + + sz = sizeof(struct omap_hwmod_link) * LINKS_PER_OCP_IF; + + *sl = NULL; + *ml = memblock_virt_alloc(sz, 0); + + *sl = (void *)(*ml) + sizeof(struct omap_hwmod_link); + + ls_supp++; + pr_debug("omap_hwmod: supplemental link allocations needed: %d\n", + ls_supp * LINKS_PER_OCP_IF); + + return 0; +}; + +/** + * _add_link - add an interconnect between two IP blocks + * @oi: pointer to a struct omap_hwmod_ocp_if record + * + * Add struct omap_hwmod_link records connecting the master IP block + * specified in @oi->master to @oi, and connecting the slave IP block + * specified in @oi->slave to @oi. This code is assumed to run before + * preemption or SMP has been enabled, thus avoiding the need for + * locking in this code. Changes to this assumption will require + * additional locking. Returns 0. + */ +static int __init _add_link(struct omap_hwmod_ocp_if *oi) +{ + struct omap_hwmod_link *ml, *sl; + + pr_debug("omap_hwmod: %s -> %s: adding link\n", oi->master->name, + oi->slave->name); + + _alloc_links(&ml, &sl); + + ml->ocp_if = oi; + INIT_LIST_HEAD(&ml->node); + list_add(&ml->node, &oi->master->master_ports); + oi->master->masters_cnt++; + + sl->ocp_if = oi; + INIT_LIST_HEAD(&sl->node); + list_add(&sl->node, &oi->slave->slave_ports); + oi->slave->slaves_cnt++; + + return 0; +} + +/** + * _register_link - register a struct omap_hwmod_ocp_if + * @oi: struct omap_hwmod_ocp_if * + * + * Registers the omap_hwmod_ocp_if record @oi. Returns -EEXIST if it + * has already been registered; -EINVAL if @oi is NULL or if the + * record pointed to by @oi is missing required fields; or 0 upon + * success. + * + * XXX The data should be copied into bootmem, so the original data + * should be marked __initdata and freed after init. This would allow + * unneeded omap_hwmods to be freed on multi-OMAP configurations. + */ +static int __init _register_link(struct omap_hwmod_ocp_if *oi) +{ + if (!oi || !oi->master || !oi->slave || !oi->user) + return -EINVAL; + + if (oi->_int_flags & _OCPIF_INT_FLAGS_REGISTERED) + return -EEXIST; + + pr_debug("omap_hwmod: registering link from %s to %s\n", + oi->master->name, oi->slave->name); + + /* + * Register the connected hwmods, if they haven't been + * registered already + */ + if (oi->master->_state != _HWMOD_STATE_REGISTERED) + _register(oi->master); + + if (oi->slave->_state != _HWMOD_STATE_REGISTERED) + _register(oi->slave); + + _add_link(oi); + + oi->_int_flags |= _OCPIF_INT_FLAGS_REGISTERED; + + return 0; +} + +/** + * _alloc_linkspace - allocate large block of hwmod links + * @ois: pointer to an array of struct omap_hwmod_ocp_if records to count + * + * Allocate a large block of struct omap_hwmod_link records. This + * improves boot time significantly by avoiding the need to allocate + * individual records one by one. If the number of records to + * allocate in the block hasn't been manually specified, this function + * will count the number of struct omap_hwmod_ocp_if records in @ois + * and use that to determine the allocation size. For SoC families + * that require multiple list registrations, such as OMAP3xxx, this + * estimation process isn't optimal, so manual estimation is advised + * in those cases. Returns -EEXIST if the allocation has already occurred + * or 0 upon success. + */ +static int __init _alloc_linkspace(struct omap_hwmod_ocp_if **ois) +{ + unsigned int i = 0; + unsigned int sz; + + if (linkspace) { + WARN(1, "linkspace already allocated\n"); + return -EEXIST; + } + + if (max_ls == 0) + while (ois[i++]) + max_ls += LINKS_PER_OCP_IF; + + sz = sizeof(struct omap_hwmod_link) * max_ls; + + pr_debug("omap_hwmod: %s: allocating %d byte linkspace (%d links)\n", + __func__, sz, max_ls); + + linkspace = memblock_virt_alloc(sz, 0); + + return 0; +} + +/* Static functions intended only for use in soc_ops field function pointers */ + +/** + * _omap2xxx_wait_target_ready - wait for a module to leave slave idle + * @oh: struct omap_hwmod * + * + * Wait for a module @oh to leave slave idle. Returns 0 if the module + * does not have an IDLEST bit or if the module successfully leaves + * slave idle; otherwise, pass along the return value of the + * appropriate *_cm*_wait_module_ready() function. + */ +static int _omap2xxx_wait_target_ready(struct omap_hwmod *oh) +{ + if (!oh) + return -EINVAL; + + if (oh->flags & HWMOD_NO_IDLEST) + return 0; + + if (!_find_mpu_rt_port(oh)) + return 0; + + /* XXX check module SIDLEMODE, hardreset status, enabled clocks */ + + return omap2xxx_cm_wait_module_ready(oh->prcm.omap2.module_offs, + oh->prcm.omap2.idlest_reg_id, + oh->prcm.omap2.idlest_idle_bit); +} + +/** + * _omap3xxx_wait_target_ready - wait for a module to leave slave idle + * @oh: struct omap_hwmod * + * + * Wait for a module @oh to leave slave idle. Returns 0 if the module + * does not have an IDLEST bit or if the module successfully leaves + * slave idle; otherwise, pass along the return value of the + * appropriate *_cm*_wait_module_ready() function. + */ +static int _omap3xxx_wait_target_ready(struct omap_hwmod *oh) +{ + if (!oh) + return -EINVAL; + + if (oh->flags & HWMOD_NO_IDLEST) + return 0; + + if (!_find_mpu_rt_port(oh)) + return 0; + + /* XXX check module SIDLEMODE, hardreset status, enabled clocks */ + + return omap3xxx_cm_wait_module_ready(oh->prcm.omap2.module_offs, + oh->prcm.omap2.idlest_reg_id, + oh->prcm.omap2.idlest_idle_bit); +} + +/** + * _omap4_wait_target_ready - wait for a module to leave slave idle + * @oh: struct omap_hwmod * + * + * Wait for a module @oh to leave slave idle. Returns 0 if the module + * does not have an IDLEST bit or if the module successfully leaves + * slave idle; otherwise, pass along the return value of the + * appropriate *_cm*_wait_module_ready() function. + */ +static int _omap4_wait_target_ready(struct omap_hwmod *oh) +{ + if (!oh) + return -EINVAL; + + if (oh->flags & HWMOD_NO_IDLEST || !oh->clkdm) + return 0; + + if (!_find_mpu_rt_port(oh)) + return 0; + + /* XXX check module SIDLEMODE, hardreset status */ + + return omap4_cminst_wait_module_ready(oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); +} + +/** + * _am33xx_wait_target_ready - wait for a module to leave slave idle + * @oh: struct omap_hwmod * + * + * Wait for a module @oh to leave slave idle. Returns 0 if the module + * does not have an IDLEST bit or if the module successfully leaves + * slave idle; otherwise, pass along the return value of the + * appropriate *_cm*_wait_module_ready() function. + */ +static int _am33xx_wait_target_ready(struct omap_hwmod *oh) +{ + if (!oh || !oh->clkdm) + return -EINVAL; + + if (oh->flags & HWMOD_NO_IDLEST) + return 0; + + if (!_find_mpu_rt_port(oh)) + return 0; + + /* XXX check module SIDLEMODE, hardreset status */ + + return am33xx_cm_wait_module_ready(oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); +} + +/** + * _omap2_assert_hardreset - call OMAP2 PRM hardreset fn with hwmod args + * @oh: struct omap_hwmod * to assert hardreset + * @ohri: hardreset line data + * + * Call omap2_prm_assert_hardreset() with parameters extracted from + * the hwmod @oh and the hardreset line data @ohri. Only intended for + * use as an soc_ops function pointer. Passes along the return value + * from omap2_prm_assert_hardreset(). XXX This function is scheduled + * for removal when the PRM code is moved into drivers/. + */ +static int _omap2_assert_hardreset(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri) +{ + return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs, + ohri->rst_shift); +} + +/** + * _omap2_deassert_hardreset - call OMAP2 PRM hardreset fn with hwmod args + * @oh: struct omap_hwmod * to deassert hardreset + * @ohri: hardreset line data + * + * Call omap2_prm_deassert_hardreset() with parameters extracted from + * the hwmod @oh and the hardreset line data @ohri. Only intended for + * use as an soc_ops function pointer. Passes along the return value + * from omap2_prm_deassert_hardreset(). XXX This function is + * scheduled for removal when the PRM code is moved into drivers/. + */ +static int _omap2_deassert_hardreset(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri) +{ + return omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs, + ohri->rst_shift, + ohri->st_shift); +} + +/** + * _omap2_is_hardreset_asserted - call OMAP2 PRM hardreset fn with hwmod args + * @oh: struct omap_hwmod * to test hardreset + * @ohri: hardreset line data + * + * Call omap2_prm_is_hardreset_asserted() with parameters extracted + * from the hwmod @oh and the hardreset line data @ohri. Only + * intended for use as an soc_ops function pointer. Passes along the + * return value from omap2_prm_is_hardreset_asserted(). XXX This + * function is scheduled for removal when the PRM code is moved into + * drivers/. + */ +static int _omap2_is_hardreset_asserted(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri) +{ + return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs, + ohri->st_shift); +} + +/** + * _omap4_assert_hardreset - call OMAP4 PRM hardreset fn with hwmod args + * @oh: struct omap_hwmod * to assert hardreset + * @ohri: hardreset line data + * + * Call omap4_prminst_assert_hardreset() with parameters extracted + * from the hwmod @oh and the hardreset line data @ohri. Only + * intended for use as an soc_ops function pointer. Passes along the + * return value from omap4_prminst_assert_hardreset(). XXX This + * function is scheduled for removal when the PRM code is moved into + * drivers/. + */ +static int _omap4_assert_hardreset(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri) +{ + if (!oh->clkdm) + return -EINVAL; + + return omap4_prminst_assert_hardreset(ohri->rst_shift, + oh->clkdm->pwrdm.ptr->prcm_partition, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.rstctrl_offs); +} + +/** + * _omap4_deassert_hardreset - call OMAP4 PRM hardreset fn with hwmod args + * @oh: struct omap_hwmod * to deassert hardreset + * @ohri: hardreset line data + * + * Call omap4_prminst_deassert_hardreset() with parameters extracted + * from the hwmod @oh and the hardreset line data @ohri. Only + * intended for use as an soc_ops function pointer. Passes along the + * return value from omap4_prminst_deassert_hardreset(). XXX This + * function is scheduled for removal when the PRM code is moved into + * drivers/. + */ +static int _omap4_deassert_hardreset(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri) +{ + if (!oh->clkdm) + return -EINVAL; + + if (ohri->st_shift) + pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n", + oh->name, ohri->name); + return omap4_prminst_deassert_hardreset(ohri->rst_shift, + oh->clkdm->pwrdm.ptr->prcm_partition, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.rstctrl_offs); +} + +/** + * _omap4_is_hardreset_asserted - call OMAP4 PRM hardreset fn with hwmod args + * @oh: struct omap_hwmod * to test hardreset + * @ohri: hardreset line data + * + * Call omap4_prminst_is_hardreset_asserted() with parameters + * extracted from the hwmod @oh and the hardreset line data @ohri. + * Only intended for use as an soc_ops function pointer. Passes along + * the return value from omap4_prminst_is_hardreset_asserted(). XXX + * This function is scheduled for removal when the PRM code is moved + * into drivers/. + */ +static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri) +{ + if (!oh->clkdm) + return -EINVAL; + + return omap4_prminst_is_hardreset_asserted(ohri->rst_shift, + oh->clkdm->pwrdm.ptr->prcm_partition, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.rstctrl_offs); +} + +/** + * _am33xx_assert_hardreset - call AM33XX PRM hardreset fn with hwmod args + * @oh: struct omap_hwmod * to assert hardreset + * @ohri: hardreset line data + * + * Call am33xx_prminst_assert_hardreset() with parameters extracted + * from the hwmod @oh and the hardreset line data @ohri. Only + * intended for use as an soc_ops function pointer. Passes along the + * return value from am33xx_prminst_assert_hardreset(). XXX This + * function is scheduled for removal when the PRM code is moved into + * drivers/. + */ +static int _am33xx_assert_hardreset(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri) + +{ + return am33xx_prm_assert_hardreset(ohri->rst_shift, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.rstctrl_offs); +} + +/** + * _am33xx_deassert_hardreset - call AM33XX PRM hardreset fn with hwmod args + * @oh: struct omap_hwmod * to deassert hardreset + * @ohri: hardreset line data + * + * Call am33xx_prminst_deassert_hardreset() with parameters extracted + * from the hwmod @oh and the hardreset line data @ohri. Only + * intended for use as an soc_ops function pointer. Passes along the + * return value from am33xx_prminst_deassert_hardreset(). XXX This + * function is scheduled for removal when the PRM code is moved into + * drivers/. + */ +static int _am33xx_deassert_hardreset(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri) +{ + return am33xx_prm_deassert_hardreset(ohri->rst_shift, + ohri->st_shift, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.rstctrl_offs, + oh->prcm.omap4.rstst_offs); +} + +/** + * _am33xx_is_hardreset_asserted - call AM33XX PRM hardreset fn with hwmod args + * @oh: struct omap_hwmod * to test hardreset + * @ohri: hardreset line data + * + * Call am33xx_prminst_is_hardreset_asserted() with parameters + * extracted from the hwmod @oh and the hardreset line data @ohri. + * Only intended for use as an soc_ops function pointer. Passes along + * the return value from am33xx_prminst_is_hardreset_asserted(). XXX + * This function is scheduled for removal when the PRM code is moved + * into drivers/. + */ +static int _am33xx_is_hardreset_asserted(struct omap_hwmod *oh, + struct omap_hwmod_rst_info *ohri) +{ + return am33xx_prm_is_hardreset_asserted(ohri->rst_shift, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.rstctrl_offs); +} + +/* Public functions */ + +u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs) +{ + if (oh->flags & HWMOD_16BIT_REG) + return readw_relaxed(oh->_mpu_rt_va + reg_offs); + else + return readl_relaxed(oh->_mpu_rt_va + reg_offs); +} + +void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs) +{ + if (oh->flags & HWMOD_16BIT_REG) + writew_relaxed(v, oh->_mpu_rt_va + reg_offs); + else + writel_relaxed(v, oh->_mpu_rt_va + reg_offs); +} + +/** + * omap_hwmod_softreset - reset a module via SYSCONFIG.SOFTRESET bit + * @oh: struct omap_hwmod * + * + * This is a public function exposed to drivers. Some drivers may need to do + * some settings before and after resetting the device. Those drivers after + * doing the necessary settings could use this function to start a reset by + * setting the SYSCONFIG.SOFTRESET bit. + */ +int omap_hwmod_softreset(struct omap_hwmod *oh) +{ + u32 v; + int ret; + + if (!oh || !(oh->_sysc_cache)) + return -EINVAL; + + v = oh->_sysc_cache; + ret = _set_softreset(oh, &v); + if (ret) + goto error; + _write_sysconfig(v, oh); + + ret = _clear_softreset(oh, &v); + if (ret) + goto error; + _write_sysconfig(v, oh); + +error: + return ret; +} + +/** + * omap_hwmod_lookup - look up a registered omap_hwmod by name + * @name: name of the omap_hwmod to look up + * + * Given a @name of an omap_hwmod, return a pointer to the registered + * struct omap_hwmod *, or NULL upon error. + */ +struct omap_hwmod *omap_hwmod_lookup(const char *name) +{ + struct omap_hwmod *oh; + + if (!name) + return NULL; + + oh = _lookup(name); + + return oh; +} + +/** + * omap_hwmod_for_each - call function for each registered omap_hwmod + * @fn: pointer to a callback function + * @data: void * data to pass to callback function + * + * Call @fn for each registered omap_hwmod, passing @data to each + * function. @fn must return 0 for success or any other value for + * failure. If @fn returns non-zero, the iteration across omap_hwmods + * will stop and the non-zero return value will be passed to the + * caller of omap_hwmod_for_each(). @fn is called with + * omap_hwmod_for_each() held. + */ +int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data), + void *data) +{ + struct omap_hwmod *temp_oh; + int ret = 0; + + if (!fn) + return -EINVAL; + + list_for_each_entry(temp_oh, &omap_hwmod_list, node) { + ret = (*fn)(temp_oh, data); + if (ret) + break; + } + + return ret; +} + +/** + * omap_hwmod_register_links - register an array of hwmod links + * @ois: pointer to an array of omap_hwmod_ocp_if to register + * + * Intended to be called early in boot before the clock framework is + * initialized. If @ois is not null, will register all omap_hwmods + * listed in @ois that are valid for this chip. Returns -EINVAL if + * omap_hwmod_init() hasn't been called before calling this function, + * -ENOMEM if the link memory area can't be allocated, or 0 upon + * success. + */ +int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois) +{ + int r, i; + + if (!inited) + return -EINVAL; + + if (!ois) + return 0; + + if (!linkspace) { + if (_alloc_linkspace(ois)) { + pr_err("omap_hwmod: could not allocate link space\n"); + return -ENOMEM; + } + } + + i = 0; + do { + r = _register_link(ois[i]); + WARN(r && r != -EEXIST, + "omap_hwmod: _register_link(%s -> %s) returned %d\n", + ois[i]->master->name, ois[i]->slave->name, r); + } while (ois[++i]); + + return 0; +} + +/** + * _ensure_mpu_hwmod_is_setup - ensure the MPU SS hwmod is init'ed and set up + * @oh: pointer to the hwmod currently being set up (usually not the MPU) + * + * If the hwmod data corresponding to the MPU subsystem IP block + * hasn't been initialized and set up yet, do so now. This must be + * done first since sleep dependencies may be added from other hwmods + * to the MPU. Intended to be called only by omap_hwmod_setup*(). No + * return value. + */ +static void __init _ensure_mpu_hwmod_is_setup(struct omap_hwmod *oh) +{ + if (!mpu_oh || mpu_oh->_state == _HWMOD_STATE_UNKNOWN) + pr_err("omap_hwmod: %s: MPU initiator hwmod %s not yet registered\n", + __func__, MPU_INITIATOR_NAME); + else if (mpu_oh->_state == _HWMOD_STATE_REGISTERED && oh != mpu_oh) + omap_hwmod_setup_one(MPU_INITIATOR_NAME); +} + +/** + * omap_hwmod_setup_one - set up a single hwmod + * @oh_name: const char * name of the already-registered hwmod to set up + * + * Initialize and set up a single hwmod. Intended to be used for a + * small number of early devices, such as the timer IP blocks used for + * the scheduler clock. Must be called after omap2_clk_init(). + * Resolves the struct clk names to struct clk pointers for each + * registered omap_hwmod. Also calls _setup() on each hwmod. Returns + * -EINVAL upon error or 0 upon success. + */ +int __init omap_hwmod_setup_one(const char *oh_name) +{ + struct omap_hwmod *oh; + + pr_debug("omap_hwmod: %s: %s\n", oh_name, __func__); + + oh = _lookup(oh_name); + if (!oh) { + WARN(1, "omap_hwmod: %s: hwmod not yet registered\n", oh_name); + return -EINVAL; + } + + _ensure_mpu_hwmod_is_setup(oh); + + _init(oh, NULL); + _setup(oh, NULL); + + return 0; +} + +/** + * omap_hwmod_setup_all - set up all registered IP blocks + * + * Initialize and set up all IP blocks registered with the hwmod code. + * Must be called after omap2_clk_init(). Resolves the struct clk + * names to struct clk pointers for each registered omap_hwmod. Also + * calls _setup() on each hwmod. Returns 0 upon success. + */ +static int __init omap_hwmod_setup_all(void) +{ + _ensure_mpu_hwmod_is_setup(NULL); + + omap_hwmod_for_each(_init, NULL); + omap_hwmod_for_each(_setup, NULL); + + return 0; +} +omap_core_initcall(omap_hwmod_setup_all); + +/** + * omap_hwmod_enable - enable an omap_hwmod + * @oh: struct omap_hwmod * + * + * Enable an omap_hwmod @oh. Intended to be called by omap_device_enable(). + * Returns -EINVAL on error or passes along the return value from _enable(). + */ +int omap_hwmod_enable(struct omap_hwmod *oh) +{ + int r; + unsigned long flags; + + if (!oh) + return -EINVAL; + + spin_lock_irqsave(&oh->_lock, flags); + r = _enable(oh); + spin_unlock_irqrestore(&oh->_lock, flags); + + return r; +} + +/** + * omap_hwmod_idle - idle an omap_hwmod + * @oh: struct omap_hwmod * + * + * Idle an omap_hwmod @oh. Intended to be called by omap_device_idle(). + * Returns -EINVAL on error or passes along the return value from _idle(). + */ +int omap_hwmod_idle(struct omap_hwmod *oh) +{ + unsigned long flags; + + if (!oh) + return -EINVAL; + + spin_lock_irqsave(&oh->_lock, flags); + _idle(oh); + spin_unlock_irqrestore(&oh->_lock, flags); + + return 0; +} + +/** + * omap_hwmod_shutdown - shutdown an omap_hwmod + * @oh: struct omap_hwmod * + * + * Shutdown an omap_hwmod @oh. Intended to be called by + * omap_device_shutdown(). Returns -EINVAL on error or passes along + * the return value from _shutdown(). + */ +int omap_hwmod_shutdown(struct omap_hwmod *oh) +{ + unsigned long flags; + + if (!oh) + return -EINVAL; + + spin_lock_irqsave(&oh->_lock, flags); + _shutdown(oh); + spin_unlock_irqrestore(&oh->_lock, flags); + + return 0; +} + +/** + * omap_hwmod_enable_clocks - enable main_clk, all interface clocks + * @oh: struct omap_hwmod *oh + * + * Intended to be called by the omap_device code. + */ +int omap_hwmod_enable_clocks(struct omap_hwmod *oh) +{ + unsigned long flags; + + spin_lock_irqsave(&oh->_lock, flags); + _enable_clocks(oh); + spin_unlock_irqrestore(&oh->_lock, flags); + + return 0; +} + +/** + * omap_hwmod_disable_clocks - disable main_clk, all interface clocks + * @oh: struct omap_hwmod *oh + * + * Intended to be called by the omap_device code. + */ +int omap_hwmod_disable_clocks(struct omap_hwmod *oh) +{ + unsigned long flags; + + spin_lock_irqsave(&oh->_lock, flags); + _disable_clocks(oh); + spin_unlock_irqrestore(&oh->_lock, flags); + + return 0; +} + +/** + * omap_hwmod_ocp_barrier - wait for posted writes against the hwmod to complete + * @oh: struct omap_hwmod *oh + * + * Intended to be called by drivers and core code when all posted + * writes to a device must complete before continuing further + * execution (for example, after clearing some device IRQSTATUS + * register bits) + * + * XXX what about targets with multiple OCP threads? + */ +void omap_hwmod_ocp_barrier(struct omap_hwmod *oh) +{ + BUG_ON(!oh); + + if (!oh->class->sysc || !oh->class->sysc->sysc_flags) { + WARN(1, "omap_device: %s: OCP barrier impossible due to device configuration\n", + oh->name); + return; + } + + /* + * Forces posted writes to complete on the OCP thread handling + * register writes + */ + omap_hwmod_read(oh, oh->class->sysc->sysc_offs); +} + +/** + * omap_hwmod_reset - reset the hwmod + * @oh: struct omap_hwmod * + * + * Under some conditions, a driver may wish to reset the entire device. + * Called from omap_device code. Returns -EINVAL on error or passes along + * the return value from _reset(). + */ +int omap_hwmod_reset(struct omap_hwmod *oh) +{ + int r; + unsigned long flags; + + if (!oh) + return -EINVAL; + + spin_lock_irqsave(&oh->_lock, flags); + r = _reset(oh); + spin_unlock_irqrestore(&oh->_lock, flags); + + return r; +} + +/* + * IP block data retrieval functions + */ + +/** + * omap_hwmod_count_resources - count number of struct resources needed by hwmod + * @oh: struct omap_hwmod * + * @flags: Type of resources to include when counting (IRQ/DMA/MEM) + * + * Count the number of struct resource array elements necessary to + * contain omap_hwmod @oh resources. Intended to be called by code + * that registers omap_devices. Intended to be used to determine the + * size of a dynamically-allocated struct resource array, before + * calling omap_hwmod_fill_resources(). Returns the number of struct + * resource array elements needed. + * + * XXX This code is not optimized. It could attempt to merge adjacent + * resource IDs. + * + */ +int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags) +{ + int ret = 0; + + if (flags & IORESOURCE_IRQ) + ret += _count_mpu_irqs(oh); + + if (flags & IORESOURCE_DMA) + ret += _count_sdma_reqs(oh); + + if (flags & IORESOURCE_MEM) { + int i = 0; + struct omap_hwmod_ocp_if *os; + struct list_head *p = oh->slave_ports.next; + + while (i < oh->slaves_cnt) { + os = _fetch_next_ocp_if(&p, &i); + ret += _count_ocp_if_addr_spaces(os); + } + } + + return ret; +} + +/** + * omap_hwmod_fill_resources - fill struct resource array with hwmod data + * @oh: struct omap_hwmod * + * @res: pointer to the first element of an array of struct resource to fill + * + * Fill the struct resource array @res with resource data from the + * omap_hwmod @oh. Intended to be called by code that registers + * omap_devices. See also omap_hwmod_count_resources(). Returns the + * number of array elements filled. + */ +int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) +{ + struct omap_hwmod_ocp_if *os; + struct list_head *p; + int i, j, mpu_irqs_cnt, sdma_reqs_cnt, addr_cnt; + int r = 0; + + /* For each IRQ, DMA, memory area, fill in array.*/ + + mpu_irqs_cnt = _count_mpu_irqs(oh); + for (i = 0; i < mpu_irqs_cnt; i++) { + (res + r)->name = (oh->mpu_irqs + i)->name; + (res + r)->start = (oh->mpu_irqs + i)->irq; + (res + r)->end = (oh->mpu_irqs + i)->irq; + (res + r)->flags = IORESOURCE_IRQ; + r++; + } + + sdma_reqs_cnt = _count_sdma_reqs(oh); + for (i = 0; i < sdma_reqs_cnt; i++) { + (res + r)->name = (oh->sdma_reqs + i)->name; + (res + r)->start = (oh->sdma_reqs + i)->dma_req; + (res + r)->end = (oh->sdma_reqs + i)->dma_req; + (res + r)->flags = IORESOURCE_DMA; + r++; + } + + p = oh->slave_ports.next; + + i = 0; + while (i < oh->slaves_cnt) { + os = _fetch_next_ocp_if(&p, &i); + addr_cnt = _count_ocp_if_addr_spaces(os); + + for (j = 0; j < addr_cnt; j++) { + (res + r)->name = (os->addr + j)->name; + (res + r)->start = (os->addr + j)->pa_start; + (res + r)->end = (os->addr + j)->pa_end; + (res + r)->flags = IORESOURCE_MEM; + r++; + } + } + + return r; +} + +/** + * omap_hwmod_fill_dma_resources - fill struct resource array with dma data + * @oh: struct omap_hwmod * + * @res: pointer to the array of struct resource to fill + * + * Fill the struct resource array @res with dma resource data from the + * omap_hwmod @oh. Intended to be called by code that registers + * omap_devices. See also omap_hwmod_count_resources(). Returns the + * number of array elements filled. + */ +int omap_hwmod_fill_dma_resources(struct omap_hwmod *oh, struct resource *res) +{ + int i, sdma_reqs_cnt; + int r = 0; + + sdma_reqs_cnt = _count_sdma_reqs(oh); + for (i = 0; i < sdma_reqs_cnt; i++) { + (res + r)->name = (oh->sdma_reqs + i)->name; + (res + r)->start = (oh->sdma_reqs + i)->dma_req; + (res + r)->end = (oh->sdma_reqs + i)->dma_req; + (res + r)->flags = IORESOURCE_DMA; + r++; + } + + return r; +} + +/** + * omap_hwmod_get_resource_byname - fetch IP block integration data by name + * @oh: struct omap_hwmod * to operate on + * @type: one of the IORESOURCE_* constants from include/linux/ioport.h + * @name: pointer to the name of the data to fetch (optional) + * @rsrc: pointer to a struct resource, allocated by the caller + * + * Retrieve MPU IRQ, SDMA request line, or address space start/end + * data for the IP block pointed to by @oh. The data will be filled + * into a struct resource record pointed to by @rsrc. The struct + * resource must be allocated by the caller. When @name is non-null, + * the data associated with the matching entry in the IRQ/SDMA/address + * space hwmod data arrays will be returned. If @name is null, the + * first array entry will be returned. Data order is not meaningful + * in hwmod data, so callers are strongly encouraged to use a non-null + * @name whenever possible to avoid unpredictable effects if hwmod + * data is later added that causes data ordering to change. This + * function is only intended for use by OMAP core code. Device + * drivers should not call this function - the appropriate bus-related + * data accessor functions should be used instead. Returns 0 upon + * success or a negative error code upon error. + */ +int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type, + const char *name, struct resource *rsrc) +{ + int r; + unsigned int irq, dma; + u32 pa_start, pa_end; + + if (!oh || !rsrc) + return -EINVAL; + + if (type == IORESOURCE_IRQ) { + r = _get_mpu_irq_by_name(oh, name, &irq); + if (r) + return r; + + rsrc->start = irq; + rsrc->end = irq; + } else if (type == IORESOURCE_DMA) { + r = _get_sdma_req_by_name(oh, name, &dma); + if (r) + return r; + + rsrc->start = dma; + rsrc->end = dma; + } else if (type == IORESOURCE_MEM) { + r = _get_addr_space_by_name(oh, name, &pa_start, &pa_end); + if (r) + return r; + + rsrc->start = pa_start; + rsrc->end = pa_end; + } else { + return -EINVAL; + } + + rsrc->flags = type; + rsrc->name = name; + + return 0; +} + +/** + * omap_hwmod_get_pwrdm - return pointer to this module's main powerdomain + * @oh: struct omap_hwmod * + * + * Return the powerdomain pointer associated with the OMAP module + * @oh's main clock. If @oh does not have a main clk, return the + * powerdomain associated with the interface clock associated with the + * module's MPU port. (XXX Perhaps this should use the SDMA port + * instead?) Returns NULL on error, or a struct powerdomain * on + * success. + */ +struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh) +{ + struct clk *c; + struct omap_hwmod_ocp_if *oi; + struct clockdomain *clkdm; + struct clk_hw_omap *clk; + + if (!oh) + return NULL; + + if (oh->clkdm) + return oh->clkdm->pwrdm.ptr; + + if (oh->_clk) { + c = oh->_clk; + } else { + oi = _find_mpu_rt_port(oh); + if (!oi) + return NULL; + c = oi->_clk; + } + + clk = to_clk_hw_omap(__clk_get_hw(c)); + clkdm = clk->clkdm; + if (!clkdm) + return NULL; + + return clkdm->pwrdm.ptr; +} + +/** + * omap_hwmod_get_mpu_rt_va - return the module's base address (for the MPU) + * @oh: struct omap_hwmod * + * + * Returns the virtual address corresponding to the beginning of the + * module's register target, in the address range that is intended to + * be used by the MPU. Returns the virtual address upon success or NULL + * upon error. + */ +void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh) +{ + if (!oh) + return NULL; + + if (oh->_int_flags & _HWMOD_NO_MPU_PORT) + return NULL; + + if (oh->_state == _HWMOD_STATE_UNKNOWN) + return NULL; + + return oh->_mpu_rt_va; +} + +/** + * omap_hwmod_add_initiator_dep - add sleepdep from @init_oh to @oh + * @oh: struct omap_hwmod * + * @init_oh: struct omap_hwmod * (initiator) + * + * Add a sleep dependency between the initiator @init_oh and @oh. + * Intended to be called by DSP/Bridge code via platform_data for the + * DSP case; and by the DMA code in the sDMA case. DMA code, *Bridge + * code needs to add/del initiator dependencies dynamically + * before/after accessing a device. Returns the return value from + * _add_initiator_dep(). + * + * XXX Keep a usecount in the clockdomain code + */ +int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh, + struct omap_hwmod *init_oh) +{ + return _add_initiator_dep(oh, init_oh); +} + +/* + * XXX what about functions for drivers to save/restore ocp_sysconfig + * for context save/restore operations? + */ + +/** + * omap_hwmod_del_initiator_dep - remove sleepdep from @init_oh to @oh + * @oh: struct omap_hwmod * + * @init_oh: struct omap_hwmod * (initiator) + * + * Remove a sleep dependency between the initiator @init_oh and @oh. + * Intended to be called by DSP/Bridge code via platform_data for the + * DSP case; and by the DMA code in the sDMA case. DMA code, *Bridge + * code needs to add/del initiator dependencies dynamically + * before/after accessing a device. Returns the return value from + * _del_initiator_dep(). + * + * XXX Keep a usecount in the clockdomain code + */ +int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh, + struct omap_hwmod *init_oh) +{ + return _del_initiator_dep(oh, init_oh); +} + +/** + * omap_hwmod_enable_wakeup - allow device to wake up the system + * @oh: struct omap_hwmod * + * + * Sets the module OCP socket ENAWAKEUP bit to allow the module to + * send wakeups to the PRCM, and enable I/O ring wakeup events for + * this IP block if it has dynamic mux entries. Eventually this + * should set PRCM wakeup registers to cause the PRCM to receive + * wakeup events from the module. Does not set any wakeup routing + * registers beyond this point - if the module is to wake up any other + * module or subsystem, that must be set separately. Called by + * omap_device code. Returns -EINVAL on error or 0 upon success. + */ +int omap_hwmod_enable_wakeup(struct omap_hwmod *oh) +{ + unsigned long flags; + u32 v; + + spin_lock_irqsave(&oh->_lock, flags); + + if (oh->class->sysc && + (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) { + v = oh->_sysc_cache; + _enable_wakeup(oh, &v); + _write_sysconfig(v, oh); + } + + _set_idle_ioring_wakeup(oh, true); + spin_unlock_irqrestore(&oh->_lock, flags); + + return 0; +} + +/** + * omap_hwmod_disable_wakeup - prevent device from waking the system + * @oh: struct omap_hwmod * + * + * Clears the module OCP socket ENAWAKEUP bit to prevent the module + * from sending wakeups to the PRCM, and disable I/O ring wakeup + * events for this IP block if it has dynamic mux entries. Eventually + * this should clear PRCM wakeup registers to cause the PRCM to ignore + * wakeup events from the module. Does not set any wakeup routing + * registers beyond this point - if the module is to wake up any other + * module or subsystem, that must be set separately. Called by + * omap_device code. Returns -EINVAL on error or 0 upon success. + */ +int omap_hwmod_disable_wakeup(struct omap_hwmod *oh) +{ + unsigned long flags; + u32 v; + + spin_lock_irqsave(&oh->_lock, flags); + + if (oh->class->sysc && + (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) { + v = oh->_sysc_cache; + _disable_wakeup(oh, &v); + _write_sysconfig(v, oh); + } + + _set_idle_ioring_wakeup(oh, false); + spin_unlock_irqrestore(&oh->_lock, flags); + + return 0; +} + +/** + * omap_hwmod_assert_hardreset - assert the HW reset line of submodules + * contained in the hwmod module. + * @oh: struct omap_hwmod * + * @name: name of the reset line to lookup and assert + * + * Some IP like dsp, ipu or iva contain processor that require + * an HW reset line to be assert / deassert in order to enable fully + * the IP. Returns -EINVAL if @oh is null or if the operation is not + * yet supported on this OMAP; otherwise, passes along the return value + * from _assert_hardreset(). + */ +int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name) +{ + int ret; + unsigned long flags; + + if (!oh) + return -EINVAL; + + spin_lock_irqsave(&oh->_lock, flags); + ret = _assert_hardreset(oh, name); + spin_unlock_irqrestore(&oh->_lock, flags); + + return ret; +} + +/** + * omap_hwmod_deassert_hardreset - deassert the HW reset line of submodules + * contained in the hwmod module. + * @oh: struct omap_hwmod * + * @name: name of the reset line to look up and deassert + * + * Some IP like dsp, ipu or iva contain processor that require + * an HW reset line to be assert / deassert in order to enable fully + * the IP. Returns -EINVAL if @oh is null or if the operation is not + * yet supported on this OMAP; otherwise, passes along the return value + * from _deassert_hardreset(). + */ +int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name) +{ + int ret; + unsigned long flags; + + if (!oh) + return -EINVAL; + + spin_lock_irqsave(&oh->_lock, flags); + ret = _deassert_hardreset(oh, name); + spin_unlock_irqrestore(&oh->_lock, flags); + + return ret; +} + +/** + * omap_hwmod_read_hardreset - read the HW reset line state of submodules + * contained in the hwmod module + * @oh: struct omap_hwmod * + * @name: name of the reset line to look up and read + * + * Return the current state of the hwmod @oh's reset line named @name: + * returns -EINVAL upon parameter error or if this operation + * is unsupported on the current OMAP; otherwise, passes along the return + * value from _read_hardreset(). + */ +int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name) +{ + int ret; + unsigned long flags; + + if (!oh) + return -EINVAL; + + spin_lock_irqsave(&oh->_lock, flags); + ret = _read_hardreset(oh, name); + spin_unlock_irqrestore(&oh->_lock, flags); + + return ret; +} + + +/** + * omap_hwmod_for_each_by_class - call @fn for each hwmod of class @classname + * @classname: struct omap_hwmod_class name to search for + * @fn: callback function pointer to call for each hwmod in class @classname + * @user: arbitrary context data to pass to the callback function + * + * For each omap_hwmod of class @classname, call @fn. + * If the callback function returns something other than + * zero, the iterator is terminated, and the callback function's return + * value is passed back to the caller. Returns 0 upon success, -EINVAL + * if @classname or @fn are NULL, or passes back the error code from @fn. + */ +int omap_hwmod_for_each_by_class(const char *classname, + int (*fn)(struct omap_hwmod *oh, + void *user), + void *user) +{ + struct omap_hwmod *temp_oh; + int ret = 0; + + if (!classname || !fn) + return -EINVAL; + + pr_debug("omap_hwmod: %s: looking for modules of class %s\n", + __func__, classname); + + list_for_each_entry(temp_oh, &omap_hwmod_list, node) { + if (!strcmp(temp_oh->class->name, classname)) { + pr_debug("omap_hwmod: %s: %s: calling callback fn\n", + __func__, temp_oh->name); + ret = (*fn)(temp_oh, user); + if (ret) + break; + } + } + + if (ret) + pr_debug("omap_hwmod: %s: iterator terminated early: %d\n", + __func__, ret); + + return ret; +} + +/** + * omap_hwmod_set_postsetup_state - set the post-_setup() state for this hwmod + * @oh: struct omap_hwmod * + * @state: state that _setup() should leave the hwmod in + * + * Sets the hwmod state that @oh will enter at the end of _setup() + * (called by omap_hwmod_setup_*()). See also the documentation + * for _setup_postsetup(), above. Returns 0 upon success or + * -EINVAL if there is a problem with the arguments or if the hwmod is + * in the wrong state. + */ +int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state) +{ + int ret; + unsigned long flags; + + if (!oh) + return -EINVAL; + + if (state != _HWMOD_STATE_DISABLED && + state != _HWMOD_STATE_ENABLED && + state != _HWMOD_STATE_IDLE) + return -EINVAL; + + spin_lock_irqsave(&oh->_lock, flags); + + if (oh->_state != _HWMOD_STATE_REGISTERED) { + ret = -EINVAL; + goto ohsps_unlock; + } + + oh->_postsetup_state = state; + ret = 0; + +ohsps_unlock: + spin_unlock_irqrestore(&oh->_lock, flags); + + return ret; +} + +/** + * omap_hwmod_get_context_loss_count - get lost context count + * @oh: struct omap_hwmod * + * + * Returns the context loss count of associated @oh + * upon success, or zero if no context loss data is available. + * + * On OMAP4, this queries the per-hwmod context loss register, + * assuming one exists. If not, or on OMAP2/3, this queries the + * enclosing powerdomain context loss count. + */ +int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh) +{ + struct powerdomain *pwrdm; + int ret = 0; + + if (soc_ops.get_context_lost) + return soc_ops.get_context_lost(oh); + + pwrdm = omap_hwmod_get_pwrdm(oh); + if (pwrdm) + ret = pwrdm_get_context_loss_count(pwrdm); + + return ret; +} + +/** + * omap_hwmod_no_setup_reset - prevent a hwmod from being reset upon setup + * @oh: struct omap_hwmod * + * + * Prevent the hwmod @oh from being reset during the setup process. + * Intended for use by board-*.c files on boards with devices that + * cannot tolerate being reset. Must be called before the hwmod has + * been set up. Returns 0 upon success or negative error code upon + * failure. + */ +int omap_hwmod_no_setup_reset(struct omap_hwmod *oh) +{ + if (!oh) + return -EINVAL; + + if (oh->_state != _HWMOD_STATE_REGISTERED) { + pr_err("omap_hwmod: %s: cannot prevent setup reset; in wrong state\n", + oh->name); + return -EINVAL; + } + + oh->flags |= HWMOD_INIT_NO_RESET; + + return 0; +} + +/** + * omap_hwmod_pad_route_irq - route an I/O pad wakeup to a particular MPU IRQ + * @oh: struct omap_hwmod * containing hwmod mux entries + * @pad_idx: array index in oh->mux of the hwmod mux entry to route wakeup + * @irq_idx: the hwmod mpu_irqs array index of the IRQ to trigger on wakeup + * + * When an I/O pad wakeup arrives for the dynamic or wakeup hwmod mux + * entry number @pad_idx for the hwmod @oh, trigger the interrupt + * service routine for the hwmod's mpu_irqs array index @irq_idx. If + * this function is not called for a given pad_idx, then the ISR + * associated with @oh's first MPU IRQ will be triggered when an I/O + * pad wakeup occurs on that pad. Note that @pad_idx is the index of + * the _dynamic or wakeup_ entry: if there are other entries not + * marked with OMAP_DEVICE_PAD_WAKEUP or OMAP_DEVICE_PAD_REMUX, these + * entries are NOT COUNTED in the dynamic pad index. This function + * must be called separately for each pad that requires its interrupt + * to be re-routed this way. Returns -EINVAL if there is an argument + * problem or if @oh does not have hwmod mux entries or MPU IRQs; + * returns -ENOMEM if memory cannot be allocated; or 0 upon success. + * + * XXX This function interface is fragile. Rather than using array + * indexes, which are subject to unpredictable change, it should be + * using hwmod IRQ names, and some other stable key for the hwmod mux + * pad records. + */ +int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx) +{ + int nr_irqs; + + might_sleep(); + + if (!oh || !oh->mux || !oh->mpu_irqs || pad_idx < 0 || + pad_idx >= oh->mux->nr_pads_dynamic) + return -EINVAL; + + /* Check the number of available mpu_irqs */ + for (nr_irqs = 0; oh->mpu_irqs[nr_irqs].irq >= 0; nr_irqs++) + ; + + if (irq_idx >= nr_irqs) + return -EINVAL; + + if (!oh->mux->irqs) { + /* XXX What frees this? */ + oh->mux->irqs = kzalloc(sizeof(int) * oh->mux->nr_pads_dynamic, + GFP_KERNEL); + if (!oh->mux->irqs) + return -ENOMEM; + } + oh->mux->irqs[pad_idx] = irq_idx; + + return 0; +} + +/** + * omap_hwmod_init - initialize the hwmod code + * + * Sets up some function pointers needed by the hwmod code to operate on the + * currently-booted SoC. Intended to be called once during kernel init + * before any hwmods are registered. No return value. + */ +void __init omap_hwmod_init(void) +{ + if (cpu_is_omap24xx()) { + soc_ops.wait_target_ready = _omap2xxx_wait_target_ready; + soc_ops.assert_hardreset = _omap2_assert_hardreset; + soc_ops.deassert_hardreset = _omap2_deassert_hardreset; + soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted; + } else if (cpu_is_omap34xx()) { + soc_ops.wait_target_ready = _omap3xxx_wait_target_ready; + soc_ops.assert_hardreset = _omap2_assert_hardreset; + soc_ops.deassert_hardreset = _omap2_deassert_hardreset; + soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted; + soc_ops.init_clkdm = _init_clkdm; + } else if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) { + soc_ops.enable_module = _omap4_enable_module; + soc_ops.disable_module = _omap4_disable_module; + soc_ops.wait_target_ready = _omap4_wait_target_ready; + soc_ops.assert_hardreset = _omap4_assert_hardreset; + soc_ops.deassert_hardreset = _omap4_deassert_hardreset; + soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted; + soc_ops.init_clkdm = _init_clkdm; + soc_ops.update_context_lost = _omap4_update_context_lost; + soc_ops.get_context_lost = _omap4_get_context_lost; + } else if (soc_is_am43xx()) { + soc_ops.enable_module = _omap4_enable_module; + soc_ops.disable_module = _omap4_disable_module; + soc_ops.wait_target_ready = _omap4_wait_target_ready; + soc_ops.assert_hardreset = _am33xx_assert_hardreset; + soc_ops.deassert_hardreset = _am33xx_deassert_hardreset; + soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted; + soc_ops.init_clkdm = _init_clkdm; + } else if (soc_is_am33xx()) { + soc_ops.enable_module = _am33xx_enable_module; + soc_ops.disable_module = _am33xx_disable_module; + soc_ops.wait_target_ready = _am33xx_wait_target_ready; + soc_ops.assert_hardreset = _am33xx_assert_hardreset; + soc_ops.deassert_hardreset = _am33xx_deassert_hardreset; + soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted; + soc_ops.init_clkdm = _init_clkdm; + } else { + WARN(1, "omap_hwmod: unknown SoC type\n"); + } + + inited = true; +} + +/** + * omap_hwmod_get_main_clk - get pointer to main clock name + * @oh: struct omap_hwmod * + * + * Returns the main clock name assocated with @oh upon success, + * or NULL if @oh is NULL. + */ +const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh) +{ + if (!oh) + return NULL; + + return oh->main_clk; +} diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h new file mode 100644 index 00000000000..0f97d635ff9 --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -0,0 +1,759 @@ +/* + * omap_hwmod macros, structures + * + * Copyright (C) 2009-2011 Nokia Corporation + * Copyright (C) 2011-2012 Texas Instruments, Inc. + * Paul Walmsley + * + * Created in collaboration with (alphabetical order): Benoît Cousson, + * Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari + * Poussa, Anand Sawant, Santosh Shilimkar, Richard Woodruff + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * These headers and macros are used to define OMAP on-chip module + * data and their integration with other OMAP modules and Linux. + * Copious documentation and references can also be found in the + * omap_hwmod code, in arch/arm/mach-omap2/omap_hwmod.c (as of this + * writing). + * + * To do: + * - add interconnect error log structures + * - add pinmuxing + * - init_conn_id_bit (CONNID_BIT_VECTOR) + * - implement default hwmod SMS/SDRC flags? + * - move Linux-specific data ("non-ROM data") out + * + */ +#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H +#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/list.h> +#include <linux/ioport.h> +#include <linux/spinlock.h> + +struct omap_device; + +extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type1; +extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2; +extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type3; + +/* + * OCP SYSCONFIG bit shifts/masks TYPE1. These are for IPs compliant + * with the original PRCM protocol defined for OMAP2420 + */ +#define SYSC_TYPE1_MIDLEMODE_SHIFT 12 +#define SYSC_TYPE1_MIDLEMODE_MASK (0x3 << SYSC_TYPE1_MIDLEMODE_SHIFT) +#define SYSC_TYPE1_CLOCKACTIVITY_SHIFT 8 +#define SYSC_TYPE1_CLOCKACTIVITY_MASK (0x3 << SYSC_TYPE1_CLOCKACTIVITY_SHIFT) +#define SYSC_TYPE1_SIDLEMODE_SHIFT 3 +#define SYSC_TYPE1_SIDLEMODE_MASK (0x3 << SYSC_TYPE1_SIDLEMODE_SHIFT) +#define SYSC_TYPE1_ENAWAKEUP_SHIFT 2 +#define SYSC_TYPE1_ENAWAKEUP_MASK (1 << SYSC_TYPE1_ENAWAKEUP_SHIFT) +#define SYSC_TYPE1_SOFTRESET_SHIFT 1 +#define SYSC_TYPE1_SOFTRESET_MASK (1 << SYSC_TYPE1_SOFTRESET_SHIFT) +#define SYSC_TYPE1_AUTOIDLE_SHIFT 0 +#define SYSC_TYPE1_AUTOIDLE_MASK (1 << SYSC_TYPE1_AUTOIDLE_SHIFT) + +/* + * OCP SYSCONFIG bit shifts/masks TYPE2. These are for IPs compliant + * with the new PRCM protocol defined for new OMAP4 IPs. + */ +#define SYSC_TYPE2_SOFTRESET_SHIFT 0 +#define SYSC_TYPE2_SOFTRESET_MASK (1 << SYSC_TYPE2_SOFTRESET_SHIFT) +#define SYSC_TYPE2_SIDLEMODE_SHIFT 2 +#define SYSC_TYPE2_SIDLEMODE_MASK (0x3 << SYSC_TYPE2_SIDLEMODE_SHIFT) +#define SYSC_TYPE2_MIDLEMODE_SHIFT 4 +#define SYSC_TYPE2_MIDLEMODE_MASK (0x3 << SYSC_TYPE2_MIDLEMODE_SHIFT) +#define SYSC_TYPE2_DMADISABLE_SHIFT 16 +#define SYSC_TYPE2_DMADISABLE_MASK (0x1 << SYSC_TYPE2_DMADISABLE_SHIFT) + +/* + * OCP SYSCONFIG bit shifts/masks TYPE3. + * This is applicable for some IPs present in AM33XX + */ +#define SYSC_TYPE3_SIDLEMODE_SHIFT 0 +#define SYSC_TYPE3_SIDLEMODE_MASK (0x3 << SYSC_TYPE3_SIDLEMODE_SHIFT) +#define SYSC_TYPE3_MIDLEMODE_SHIFT 2 +#define SYSC_TYPE3_MIDLEMODE_MASK (0x3 << SYSC_TYPE3_MIDLEMODE_SHIFT) + +/* OCP SYSSTATUS bit shifts/masks */ +#define SYSS_RESETDONE_SHIFT 0 +#define SYSS_RESETDONE_MASK (1 << SYSS_RESETDONE_SHIFT) + +/* Master standby/slave idle mode flags */ +#define HWMOD_IDLEMODE_FORCE (1 << 0) +#define HWMOD_IDLEMODE_NO (1 << 1) +#define HWMOD_IDLEMODE_SMART (1 << 2) +#define HWMOD_IDLEMODE_SMART_WKUP (1 << 3) + +/* modulemode control type (SW or HW) */ +#define MODULEMODE_HWCTRL 1 +#define MODULEMODE_SWCTRL 2 + +#define DEBUG_OMAP2UART1_FLAGS 0 +#define DEBUG_OMAP2UART2_FLAGS 0 +#define DEBUG_OMAP2UART3_FLAGS 0 +#define DEBUG_OMAP3UART3_FLAGS 0 +#define DEBUG_OMAP3UART4_FLAGS 0 +#define DEBUG_OMAP4UART3_FLAGS 0 +#define DEBUG_OMAP4UART4_FLAGS 0 +#define DEBUG_TI81XXUART1_FLAGS 0 +#define DEBUG_TI81XXUART2_FLAGS 0 +#define DEBUG_TI81XXUART3_FLAGS 0 +#define DEBUG_AM33XXUART1_FLAGS 0 + +#define DEBUG_OMAPUART_FLAGS (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET) + +#if defined(CONFIG_DEBUG_OMAP2UART1) +#undef DEBUG_OMAP2UART1_FLAGS +#define DEBUG_OMAP2UART1_FLAGS DEBUG_OMAPUART_FLAGS +#elif defined(CONFIG_DEBUG_OMAP2UART2) +#undef DEBUG_OMAP2UART2_FLAGS +#define DEBUG_OMAP2UART2_FLAGS DEBUG_OMAPUART_FLAGS +#elif defined(CONFIG_DEBUG_OMAP2UART3) +#undef DEBUG_OMAP2UART3_FLAGS +#define DEBUG_OMAP2UART3_FLAGS DEBUG_OMAPUART_FLAGS +#elif defined(CONFIG_DEBUG_OMAP3UART3) +#undef DEBUG_OMAP3UART3_FLAGS +#define DEBUG_OMAP3UART3_FLAGS DEBUG_OMAPUART_FLAGS +#elif defined(CONFIG_DEBUG_OMAP3UART4) +#undef DEBUG_OMAP3UART4_FLAGS +#define DEBUG_OMAP3UART4_FLAGS DEBUG_OMAPUART_FLAGS +#elif defined(CONFIG_DEBUG_OMAP4UART3) +#undef DEBUG_OMAP4UART3_FLAGS +#define DEBUG_OMAP4UART3_FLAGS DEBUG_OMAPUART_FLAGS +#elif defined(CONFIG_DEBUG_OMAP4UART4) +#undef DEBUG_OMAP4UART4_FLAGS +#define DEBUG_OMAP4UART4_FLAGS DEBUG_OMAPUART_FLAGS +#elif defined(CONFIG_DEBUG_TI81XXUART1) +#undef DEBUG_TI81XXUART1_FLAGS +#define DEBUG_TI81XXUART1_FLAGS DEBUG_OMAPUART_FLAGS +#elif defined(CONFIG_DEBUG_TI81XXUART2) +#undef DEBUG_TI81XXUART2_FLAGS +#define DEBUG_TI81XXUART2_FLAGS DEBUG_OMAPUART_FLAGS +#elif defined(CONFIG_DEBUG_TI81XXUART3) +#undef DEBUG_TI81XXUART3_FLAGS +#define DEBUG_TI81XXUART3_FLAGS DEBUG_OMAPUART_FLAGS +#elif defined(CONFIG_DEBUG_AM33XXUART1) +#undef DEBUG_AM33XXUART1_FLAGS +#define DEBUG_AM33XXUART1_FLAGS DEBUG_OMAPUART_FLAGS +#endif + +/** + * struct omap_hwmod_mux_info - hwmod specific mux configuration + * @pads: array of omap_device_pad entries + * @nr_pads: number of omap_device_pad entries + * + * Note that this is currently built during init as needed. + */ +struct omap_hwmod_mux_info { + int nr_pads; + struct omap_device_pad *pads; + int nr_pads_dynamic; + struct omap_device_pad **pads_dynamic; + int *irqs; + bool enabled; +}; + +/** + * struct omap_hwmod_irq_info - MPU IRQs used by the hwmod + * @name: name of the IRQ channel (module local name) + * @irq: IRQ channel ID (should be non-negative except -1 = terminator) + * + * @name should be something short, e.g., "tx" or "rx". It is for use + * by platform_get_resource_byname(). It is defined locally to the + * hwmod. + */ +struct omap_hwmod_irq_info { + const char *name; + s16 irq; +}; + +/** + * struct omap_hwmod_dma_info - DMA channels used by the hwmod + * @name: name of the DMA channel (module local name) + * @dma_req: DMA request ID (should be non-negative except -1 = terminator) + * + * @name should be something short, e.g., "tx" or "rx". It is for use + * by platform_get_resource_byname(). It is defined locally to the + * hwmod. + */ +struct omap_hwmod_dma_info { + const char *name; + s16 dma_req; +}; + +/** + * struct omap_hwmod_rst_info - IPs reset lines use by hwmod + * @name: name of the reset line (module local name) + * @rst_shift: Offset of the reset bit + * @st_shift: Offset of the reset status bit (OMAP2/3 only) + * + * @name should be something short, e.g., "cpu0" or "rst". It is defined + * locally to the hwmod. + */ +struct omap_hwmod_rst_info { + const char *name; + u8 rst_shift; + u8 st_shift; +}; + +/** + * struct omap_hwmod_opt_clk - optional clocks used by this hwmod + * @role: "sys", "32k", "tv", etc -- for use in clk_get() + * @clk: opt clock: OMAP clock name + * @_clk: pointer to the struct clk (filled in at runtime) + * + * The module's interface clock and main functional clock should not + * be added as optional clocks. + */ +struct omap_hwmod_opt_clk { + const char *role; + const char *clk; + struct clk *_clk; +}; + + +/* omap_hwmod_omap2_firewall.flags bits */ +#define OMAP_FIREWALL_L3 (1 << 0) +#define OMAP_FIREWALL_L4 (1 << 1) + +/** + * struct omap_hwmod_omap2_firewall - OMAP2/3 device firewall data + * @l3_perm_bit: bit shift for L3_PM_*_PERMISSION_* + * @l4_fw_region: L4 firewall region ID + * @l4_prot_group: L4 protection group ID + * @flags: (see omap_hwmod_omap2_firewall.flags macros above) + */ +struct omap_hwmod_omap2_firewall { + u8 l3_perm_bit; + u8 l4_fw_region; + u8 l4_prot_group; + u8 flags; +}; + + +/* + * omap_hwmod_addr_space.flags bits + * + * ADDR_MAP_ON_INIT: Map this address space during omap_hwmod init. + * ADDR_TYPE_RT: Address space contains module register target data. + */ +#define ADDR_MAP_ON_INIT (1 << 0) /* XXX does not belong */ +#define ADDR_TYPE_RT (1 << 1) + +/** + * struct omap_hwmod_addr_space - address space handled by the hwmod + * @name: name of the address space + * @pa_start: starting physical address + * @pa_end: ending physical address + * @flags: (see omap_hwmod_addr_space.flags macros above) + * + * Address space doesn't necessarily follow physical interconnect + * structure. GPMC is one example. + */ +struct omap_hwmod_addr_space { + const char *name; + u32 pa_start; + u32 pa_end; + u8 flags; +}; + + +/* + * omap_hwmod_ocp_if.user bits: these indicate the initiators that use this + * interface to interact with the hwmod. Used to add sleep dependencies + * when the module is enabled or disabled. + */ +#define OCP_USER_MPU (1 << 0) +#define OCP_USER_SDMA (1 << 1) +#define OCP_USER_DSP (1 << 2) +#define OCP_USER_IVA (1 << 3) + +/* omap_hwmod_ocp_if.flags bits */ +#define OCPIF_SWSUP_IDLE (1 << 0) +#define OCPIF_CAN_BURST (1 << 1) + +/* omap_hwmod_ocp_if._int_flags possibilities */ +#define _OCPIF_INT_FLAGS_REGISTERED (1 << 0) + + +/** + * struct omap_hwmod_ocp_if - OCP interface data + * @master: struct omap_hwmod that initiates OCP transactions on this link + * @slave: struct omap_hwmod that responds to OCP transactions on this link + * @addr: address space associated with this link + * @clk: interface clock: OMAP clock name + * @_clk: pointer to the interface struct clk (filled in at runtime) + * @fw: interface firewall data + * @width: OCP data width + * @user: initiators using this interface (see OCP_USER_* macros above) + * @flags: OCP interface flags (see OCPIF_* macros above) + * @_int_flags: internal flags (see _OCPIF_INT_FLAGS* macros above) + * + * It may also be useful to add a tag_cnt field for OCP2.x devices. + * + * Parameter names beginning with an underscore are managed internally by + * the omap_hwmod code and should not be set during initialization. + */ +struct omap_hwmod_ocp_if { + struct omap_hwmod *master; + struct omap_hwmod *slave; + struct omap_hwmod_addr_space *addr; + const char *clk; + struct clk *_clk; + union { + struct omap_hwmod_omap2_firewall omap2; + } fw; + u8 width; + u8 user; + u8 flags; + u8 _int_flags; +}; + + +/* Macros for use in struct omap_hwmod_sysconfig */ + +/* Flags for use in omap_hwmod_sysconfig.idlemodes */ +#define MASTER_STANDBY_SHIFT 4 +#define SLAVE_IDLE_SHIFT 0 +#define SIDLE_FORCE (HWMOD_IDLEMODE_FORCE << SLAVE_IDLE_SHIFT) +#define SIDLE_NO (HWMOD_IDLEMODE_NO << SLAVE_IDLE_SHIFT) +#define SIDLE_SMART (HWMOD_IDLEMODE_SMART << SLAVE_IDLE_SHIFT) +#define SIDLE_SMART_WKUP (HWMOD_IDLEMODE_SMART_WKUP << SLAVE_IDLE_SHIFT) +#define MSTANDBY_FORCE (HWMOD_IDLEMODE_FORCE << MASTER_STANDBY_SHIFT) +#define MSTANDBY_NO (HWMOD_IDLEMODE_NO << MASTER_STANDBY_SHIFT) +#define MSTANDBY_SMART (HWMOD_IDLEMODE_SMART << MASTER_STANDBY_SHIFT) +#define MSTANDBY_SMART_WKUP (HWMOD_IDLEMODE_SMART_WKUP << MASTER_STANDBY_SHIFT) + +/* omap_hwmod_sysconfig.sysc_flags capability flags */ +#define SYSC_HAS_AUTOIDLE (1 << 0) +#define SYSC_HAS_SOFTRESET (1 << 1) +#define SYSC_HAS_ENAWAKEUP (1 << 2) +#define SYSC_HAS_EMUFREE (1 << 3) +#define SYSC_HAS_CLOCKACTIVITY (1 << 4) +#define SYSC_HAS_SIDLEMODE (1 << 5) +#define SYSC_HAS_MIDLEMODE (1 << 6) +#define SYSS_HAS_RESET_STATUS (1 << 7) +#define SYSC_NO_CACHE (1 << 8) /* XXX SW flag, belongs elsewhere */ +#define SYSC_HAS_RESET_STATUS (1 << 9) +#define SYSC_HAS_DMADISABLE (1 << 10) + +/* omap_hwmod_sysconfig.clockact flags */ +#define CLOCKACT_TEST_BOTH 0x0 +#define CLOCKACT_TEST_MAIN 0x1 +#define CLOCKACT_TEST_ICLK 0x2 +#define CLOCKACT_TEST_NONE 0x3 + +/** + * struct omap_hwmod_sysc_fields - hwmod OCP_SYSCONFIG register field offsets. + * @midle_shift: Offset of the midle bit + * @clkact_shift: Offset of the clockactivity bit + * @sidle_shift: Offset of the sidle bit + * @enwkup_shift: Offset of the enawakeup bit + * @srst_shift: Offset of the softreset bit + * @autoidle_shift: Offset of the autoidle bit + * @dmadisable_shift: Offset of the dmadisable bit + */ +struct omap_hwmod_sysc_fields { + u8 midle_shift; + u8 clkact_shift; + u8 sidle_shift; + u8 enwkup_shift; + u8 srst_shift; + u8 autoidle_shift; + u8 dmadisable_shift; +}; + +/** + * struct omap_hwmod_class_sysconfig - hwmod class OCP_SYS* data + * @rev_offs: IP block revision register offset (from module base addr) + * @sysc_offs: OCP_SYSCONFIG register offset (from module base addr) + * @syss_offs: OCP_SYSSTATUS register offset (from module base addr) + * @srst_udelay: Delay needed after doing a softreset in usecs + * @idlemodes: One or more of {SIDLE,MSTANDBY}_{OFF,FORCE,SMART} + * @sysc_flags: SYS{C,S}_HAS* flags indicating SYSCONFIG bits supported + * @clockact: the default value of the module CLOCKACTIVITY bits + * + * @clockact describes to the module which clocks are likely to be + * disabled when the PRCM issues its idle request to the module. Some + * modules have separate clockdomains for the interface clock and main + * functional clock, and can check whether they should acknowledge the + * idle request based on the internal module functionality that has + * been associated with the clocks marked in @clockact. This field is + * only used if HWMOD_SET_DEFAULT_CLOCKACT is set (see below) + * + * @sysc_fields: structure containing the offset positions of various bits in + * SYSCONFIG register. This can be populated using omap_hwmod_sysc_type1 or + * omap_hwmod_sysc_type2 defined in omap_hwmod_common_data.c depending on + * whether the device ip is compliant with the original PRCM protocol + * defined for OMAP2420 or the new PRCM protocol for new OMAP4 IPs. + * If the device follows a different scheme for the sysconfig register , + * then this field has to be populated with the correct offset structure. + */ +struct omap_hwmod_class_sysconfig { + u32 rev_offs; + u32 sysc_offs; + u32 syss_offs; + u16 sysc_flags; + struct omap_hwmod_sysc_fields *sysc_fields; + u8 srst_udelay; + u8 idlemodes; + u8 clockact; +}; + +/** + * struct omap_hwmod_omap2_prcm - OMAP2/3-specific PRCM data + * @module_offs: PRCM submodule offset from the start of the PRM/CM + * @prcm_reg_id: PRCM register ID (e.g., 3 for CM_AUTOIDLE3) + * @module_bit: register bit shift for AUTOIDLE, WKST, WKEN, GRPSEL regs + * @idlest_reg_id: IDLEST register ID (e.g., 3 for CM_IDLEST3) + * @idlest_idle_bit: register bit shift for CM_IDLEST slave idle bit + * @idlest_stdby_bit: register bit shift for CM_IDLEST master standby bit + * + * @prcm_reg_id and @module_bit are specific to the AUTOIDLE, WKST, + * WKEN, GRPSEL registers. In an ideal world, no extra information + * would be needed for IDLEST information, but alas, there are some + * exceptions, so @idlest_reg_id, @idlest_idle_bit, @idlest_stdby_bit + * are needed for the IDLEST registers (c.f. 2430 I2CHS, 3430 USBHOST) + */ +struct omap_hwmod_omap2_prcm { + s16 module_offs; + u8 prcm_reg_id; + u8 module_bit; + u8 idlest_reg_id; + u8 idlest_idle_bit; + u8 idlest_stdby_bit; +}; + +/* + * Possible values for struct omap_hwmod_omap4_prcm.flags + * + * HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT: Some IP blocks don't have a PRCM + * module-level context loss register associated with them; this + * flag bit should be set in those cases + */ +#define HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT (1 << 0) + +/** + * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data + * @clkctrl_offs: offset of the PRCM clock control register + * @rstctrl_offs: offset of the XXX_RSTCTRL register located in the PRM + * @context_offs: offset of the RM_*_CONTEXT register + * @lostcontext_mask: bitmask for selecting bits from RM_*_CONTEXT register + * @rstst_reg: (AM33XX only) address of the XXX_RSTST register in the PRM + * @submodule_wkdep_bit: bit shift of the WKDEP range + * @flags: PRCM register capabilities for this IP block + * @modulemode: allowable modulemodes + * @context_lost_counter: Count of module level context lost + * + * If @lostcontext_mask is not defined, context loss check code uses + * whole register without masking. @lostcontext_mask should only be + * defined in cases where @context_offs register is shared by two or + * more hwmods. + */ +struct omap_hwmod_omap4_prcm { + u16 clkctrl_offs; + u16 rstctrl_offs; + u16 rstst_offs; + u16 context_offs; + u32 lostcontext_mask; + u8 submodule_wkdep_bit; + u8 modulemode; + u8 flags; + int context_lost_counter; +}; + + +/* + * omap_hwmod.flags definitions + * + * HWMOD_SWSUP_SIDLE: omap_hwmod code should manually bring module in and out + * of idle, rather than relying on module smart-idle + * HWMOD_SWSUP_MSTANDBY: omap_hwmod code should manually bring module in and + * out of standby, rather than relying on module smart-standby + * HWMOD_INIT_NO_RESET: don't reset this module at boot - important for + * SDRAM controller, etc. XXX probably belongs outside the main hwmod file + * XXX Should be HWMOD_SETUP_NO_RESET + * HWMOD_INIT_NO_IDLE: don't idle this module at boot - important for SDRAM + * controller, etc. XXX probably belongs outside the main hwmod file + * XXX Should be HWMOD_SETUP_NO_IDLE + * HWMOD_NO_OCP_AUTOIDLE: disable module autoidle (OCP_SYSCONFIG.AUTOIDLE) + * when module is enabled, rather than the default, which is to + * enable autoidle + * HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits at startup + * HWMOD_NO_IDLEST: this module does not have idle status - this is the case + * only for few initiator modules on OMAP2 & 3. + * HWMOD_CONTROL_OPT_CLKS_IN_RESET: Enable all optional clocks during reset. + * This is needed for devices like DSS that require optional clocks enabled + * in order to complete the reset. Optional clocks will be disabled + * again after the reset. + * HWMOD_16BIT_REG: Module has 16bit registers + * HWMOD_EXT_OPT_MAIN_CLK: The only main functional clock source for + * this IP block comes from an off-chip source and is not always + * enabled. This prevents the hwmod code from being able to + * enable and reset the IP block early. XXX Eventually it should + * be possible to query the clock framework for this information. + * HWMOD_BLOCK_WFI: Some OMAP peripherals apparently don't work + * correctly if the MPU is allowed to go idle while the + * peripherals are active. This is apparently true for the I2C on + * OMAP2420, and also the EMAC on AM3517/3505. It's unlikely that + * this is really true -- we're probably not configuring something + * correctly, or this is being abused to deal with some PM latency + * issues -- but we're currently suffering from a shortage of + * folks who are able to track these issues down properly. + * HWMOD_FORCE_MSTANDBY: Always keep MIDLEMODE bits cleared so that device + * is kept in force-standby mode. Failing to do so causes PM problems + * with musb on OMAP3630 at least. Note that musb has a dedicated register + * to control MSTANDBY signal when MIDLEMODE is set to force-standby. + * HWMOD_SWSUP_SIDLE_ACT: omap_hwmod code should manually bring the module + * out of idle, but rely on smart-idle to the put it back in idle, + * so the wakeups are still functional (Only known case for now is UART) + */ +#define HWMOD_SWSUP_SIDLE (1 << 0) +#define HWMOD_SWSUP_MSTANDBY (1 << 1) +#define HWMOD_INIT_NO_RESET (1 << 2) +#define HWMOD_INIT_NO_IDLE (1 << 3) +#define HWMOD_NO_OCP_AUTOIDLE (1 << 4) +#define HWMOD_SET_DEFAULT_CLOCKACT (1 << 5) +#define HWMOD_NO_IDLEST (1 << 6) +#define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7) +#define HWMOD_16BIT_REG (1 << 8) +#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9) +#define HWMOD_BLOCK_WFI (1 << 10) +#define HWMOD_FORCE_MSTANDBY (1 << 11) +#define HWMOD_SWSUP_SIDLE_ACT (1 << 12) + +/* + * omap_hwmod._int_flags definitions + * These are for internal use only and are managed by the omap_hwmod code. + * + * _HWMOD_NO_MPU_PORT: no path exists for the MPU to write to this module + * _HWMOD_SYSCONFIG_LOADED: set when the OCP_SYSCONFIG value has been cached + * _HWMOD_SKIP_ENABLE: set if hwmod enabled during init (HWMOD_INIT_NO_IDLE) - + * causes the first call to _enable() to only update the pinmux + */ +#define _HWMOD_NO_MPU_PORT (1 << 0) +#define _HWMOD_SYSCONFIG_LOADED (1 << 1) +#define _HWMOD_SKIP_ENABLE (1 << 2) + +/* + * omap_hwmod._state definitions + * + * INITIALIZED: reset (optionally), initialized, enabled, disabled + * (optionally) + * + * + */ +#define _HWMOD_STATE_UNKNOWN 0 +#define _HWMOD_STATE_REGISTERED 1 +#define _HWMOD_STATE_CLKS_INITED 2 +#define _HWMOD_STATE_INITIALIZED 3 +#define _HWMOD_STATE_ENABLED 4 +#define _HWMOD_STATE_IDLE 5 +#define _HWMOD_STATE_DISABLED 6 + +/** + * struct omap_hwmod_class - the type of an IP block + * @name: name of the hwmod_class + * @sysc: device SYSCONFIG/SYSSTATUS register data + * @rev: revision of the IP class + * @pre_shutdown: ptr to fn to be executed immediately prior to device shutdown + * @reset: ptr to fn to be executed in place of the standard hwmod reset fn + * @enable_preprogram: ptr to fn to be executed during device enable + * + * Represent the class of a OMAP hardware "modules" (e.g. timer, + * smartreflex, gpio, uart...) + * + * @pre_shutdown is a function that will be run immediately before + * hwmod clocks are disabled, etc. It is intended for use for hwmods + * like the MPU watchdog, which cannot be disabled with the standard + * omap_hwmod_shutdown(). The function should return 0 upon success, + * or some negative error upon failure. Returning an error will cause + * omap_hwmod_shutdown() to abort the device shutdown and return an + * error. + * + * If @reset is defined, then the function it points to will be + * executed in place of the standard hwmod _reset() code in + * mach-omap2/omap_hwmod.c. This is needed for IP blocks which have + * unusual reset sequences - usually processor IP blocks like the IVA. + */ +struct omap_hwmod_class { + const char *name; + struct omap_hwmod_class_sysconfig *sysc; + u32 rev; + int (*pre_shutdown)(struct omap_hwmod *oh); + int (*reset)(struct omap_hwmod *oh); + int (*enable_preprogram)(struct omap_hwmod *oh); +}; + +/** + * struct omap_hwmod_link - internal structure linking hwmods with ocp_ifs + * @ocp_if: OCP interface structure record pointer + * @node: list_head pointing to next struct omap_hwmod_link in a list + */ +struct omap_hwmod_link { + struct omap_hwmod_ocp_if *ocp_if; + struct list_head node; +}; + +/** + * struct omap_hwmod - integration data for OMAP hardware "modules" (IP blocks) + * @name: name of the hwmod + * @class: struct omap_hwmod_class * to the class of this hwmod + * @od: struct omap_device currently associated with this hwmod (internal use) + * @mpu_irqs: ptr to an array of MPU IRQs + * @sdma_reqs: ptr to an array of System DMA request IDs + * @prcm: PRCM data pertaining to this hwmod + * @main_clk: main clock: OMAP clock name + * @_clk: pointer to the main struct clk (filled in at runtime) + * @opt_clks: other device clocks that drivers can request (0..*) + * @voltdm: pointer to voltage domain (filled in at runtime) + * @dev_attr: arbitrary device attributes that can be passed to the driver + * @_sysc_cache: internal-use hwmod flags + * @mpu_rt_idx: index of device address space for register target (for DT boot) + * @_mpu_rt_va: cached register target start address (internal use) + * @_mpu_port: cached MPU register target slave (internal use) + * @opt_clks_cnt: number of @opt_clks + * @master_cnt: number of @master entries + * @slaves_cnt: number of @slave entries + * @response_lat: device OCP response latency (in interface clock cycles) + * @_int_flags: internal-use hwmod flags + * @_state: internal-use hwmod state + * @_postsetup_state: internal-use state to leave the hwmod in after _setup() + * @flags: hwmod flags (documented below) + * @_lock: spinlock serializing operations on this hwmod + * @node: list node for hwmod list (internal use) + * + * @main_clk refers to this module's "main clock," which for our + * purposes is defined as "the functional clock needed for register + * accesses to complete." Modules may not have a main clock if the + * interface clock also serves as a main clock. + * + * Parameter names beginning with an underscore are managed internally by + * the omap_hwmod code and should not be set during initialization. + * + * @masters and @slaves are now deprecated. + */ +struct omap_hwmod { + const char *name; + struct omap_hwmod_class *class; + struct omap_device *od; + struct omap_hwmod_mux_info *mux; + struct omap_hwmod_irq_info *mpu_irqs; + struct omap_hwmod_dma_info *sdma_reqs; + struct omap_hwmod_rst_info *rst_lines; + union { + struct omap_hwmod_omap2_prcm omap2; + struct omap_hwmod_omap4_prcm omap4; + } prcm; + const char *main_clk; + struct clk *_clk; + struct omap_hwmod_opt_clk *opt_clks; + char *clkdm_name; + struct clockdomain *clkdm; + struct list_head master_ports; /* connect to *_IA */ + struct list_head slave_ports; /* connect to *_TA */ + void *dev_attr; + u32 _sysc_cache; + void __iomem *_mpu_rt_va; + spinlock_t _lock; + struct list_head node; + struct omap_hwmod_ocp_if *_mpu_port; + u16 flags; + u8 mpu_rt_idx; + u8 response_lat; + u8 rst_lines_cnt; + u8 opt_clks_cnt; + u8 masters_cnt; + u8 slaves_cnt; + u8 hwmods_cnt; + u8 _int_flags; + u8 _state; + u8 _postsetup_state; +}; + +struct omap_hwmod *omap_hwmod_lookup(const char *name); +int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data), + void *data); + +int __init omap_hwmod_setup_one(const char *name); + +int omap_hwmod_enable(struct omap_hwmod *oh); +int omap_hwmod_idle(struct omap_hwmod *oh); +int omap_hwmod_shutdown(struct omap_hwmod *oh); + +int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name); +int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name); +int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name); + +int omap_hwmod_enable_clocks(struct omap_hwmod *oh); +int omap_hwmod_disable_clocks(struct omap_hwmod *oh); + +int omap_hwmod_reset(struct omap_hwmod *oh); +void omap_hwmod_ocp_barrier(struct omap_hwmod *oh); + +void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs); +u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs); +int omap_hwmod_softreset(struct omap_hwmod *oh); + +int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags); +int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res); +int omap_hwmod_fill_dma_resources(struct omap_hwmod *oh, struct resource *res); +int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type, + const char *name, struct resource *res); + +struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh); +void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh); + +int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh, + struct omap_hwmod *init_oh); +int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh, + struct omap_hwmod *init_oh); + +int omap_hwmod_enable_wakeup(struct omap_hwmod *oh); +int omap_hwmod_disable_wakeup(struct omap_hwmod *oh); + +int omap_hwmod_for_each_by_class(const char *classname, + int (*fn)(struct omap_hwmod *oh, + void *user), + void *user); + +int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state); +int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh); + +int omap_hwmod_no_setup_reset(struct omap_hwmod *oh); + +int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx); + +extern void __init omap_hwmod_init(void); + +const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh); + +/* + * + */ + +extern int omap_hwmod_aess_preprogram(struct omap_hwmod *oh); + +/* + * Chip variant-specific hwmod init routines - XXX should be converted + * to use initcalls once the initial boot ordering is straightened out + */ +extern int omap2420_hwmod_init(void); +extern int omap2430_hwmod_init(void); +extern int omap3xxx_hwmod_init(void); +extern int omap44xx_hwmod_init(void); +extern int omap54xx_hwmod_init(void); +extern int am33xx_hwmod_init(void); +extern int dra7xx_hwmod_init(void); +int am43xx_hwmod_init(void); + +extern int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois); + +#endif diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c new file mode 100644 index 00000000000..2f15979c2e9 --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -0,0 +1,502 @@ +/* + * omap_hwmod_2420_data.c - hardware modules present on the OMAP2420 chips + * + * Copyright (C) 2009-2011 Nokia Corporation + * Copyright (C) 2012 Texas Instruments, Inc. + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * XXX handle crossbar/shared link difference for L3? + * XXX these should be marked initdata for multi-OMAP kernels + */ + +#include <linux/i2c-omap.h> +#include <linux/platform_data/spi-omap2-mcspi.h> +#include <linux/omap-dma.h> +#include <linux/platform_data/mailbox-omap.h> +#include <plat/dmtimer.h> + +#include "omap_hwmod.h" +#include "l3_2xxx.h" +#include "l4_2xxx.h" + +#include "omap_hwmod_common_data.h" + +#include "cm-regbits-24xx.h" +#include "prm-regbits-24xx.h" +#include "i2c.h" +#include "mmc.h" +#include "serial.h" +#include "wd_timer.h" + +/* + * OMAP2420 hardware module integration data + * + * All of the data in this section should be autogeneratable from the + * TI hardware database or other technical documentation. Data that + * is driver-specific or driver-kernel integration-specific belongs + * elsewhere. + */ + +/* + * IP blocks + */ + +/* IVA1 (IVA1) */ +static struct omap_hwmod_class iva1_hwmod_class = { + .name = "iva1", +}; + +static struct omap_hwmod_rst_info omap2420_iva_resets[] = { + { .name = "iva", .rst_shift = 8 }, +}; + +static struct omap_hwmod omap2420_iva_hwmod = { + .name = "iva", + .class = &iva1_hwmod_class, + .clkdm_name = "iva1_clkdm", + .rst_lines = omap2420_iva_resets, + .rst_lines_cnt = ARRAY_SIZE(omap2420_iva_resets), + .main_clk = "iva1_ifck", +}; + +/* DSP */ +static struct omap_hwmod_class dsp_hwmod_class = { + .name = "dsp", +}; + +static struct omap_hwmod_rst_info omap2420_dsp_resets[] = { + { .name = "logic", .rst_shift = 0 }, + { .name = "mmu", .rst_shift = 1 }, +}; + +static struct omap_hwmod omap2420_dsp_hwmod = { + .name = "dsp", + .class = &dsp_hwmod_class, + .clkdm_name = "dsp_clkdm", + .rst_lines = omap2420_dsp_resets, + .rst_lines_cnt = ARRAY_SIZE(omap2420_dsp_resets), + .main_clk = "dsp_fck", +}; + +/* I2C common */ +static struct omap_hwmod_class_sysconfig i2c_sysc = { + .rev_offs = 0x00, + .sysc_offs = 0x20, + .syss_offs = 0x10, + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class i2c_class = { + .name = "i2c", + .sysc = &i2c_sysc, + .rev = OMAP_I2C_IP_VERSION_1, + .reset = &omap_i2c_reset, +}; + +static struct omap_i2c_dev_attr i2c_dev_attr = { + .flags = OMAP_I2C_FLAG_NO_FIFO | + OMAP_I2C_FLAG_SIMPLE_CLOCK | + OMAP_I2C_FLAG_16BIT_DATA_REG | + OMAP_I2C_FLAG_BUS_SHIFT_2, +}; + +/* I2C1 */ +static struct omap_hwmod omap2420_i2c1_hwmod = { + .name = "i2c1", + .main_clk = "i2c1_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP2420_EN_I2C1_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP2420_ST_I2C1_SHIFT, + }, + }, + .class = &i2c_class, + .dev_attr = &i2c_dev_attr, + /* + * From mach-omap2/pm24xx.c: "Putting MPU into the WFI state + * while a transfer is active seems to cause the I2C block to + * timeout. Why? Good question." + */ + .flags = (HWMOD_16BIT_REG | HWMOD_BLOCK_WFI), +}; + +/* I2C2 */ +static struct omap_hwmod omap2420_i2c2_hwmod = { + .name = "i2c2", + .main_clk = "i2c2_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP2420_EN_I2C2_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP2420_ST_I2C2_SHIFT, + }, + }, + .class = &i2c_class, + .dev_attr = &i2c_dev_attr, + .flags = HWMOD_16BIT_REG, +}; + +/* dma attributes */ +static struct omap_dma_dev_attr dma_dev_attr = { + .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY | + IS_CSSA_32 | IS_CDSA_32, + .lch_count = 32, +}; + +static struct omap_hwmod omap2420_dma_system_hwmod = { + .name = "dma", + .class = &omap2xxx_dma_hwmod_class, + .mpu_irqs = omap2_dma_system_irqs, + .main_clk = "core_l3_ck", + .dev_attr = &dma_dev_attr, + .flags = HWMOD_NO_IDLEST, +}; + +/* mailbox */ +static struct omap_mbox_dev_info omap2420_mailbox_info[] = { + { .name = "dsp", .tx_id = 0, .rx_id = 1, .irq_id = 0, .usr_id = 0 }, + { .name = "iva", .tx_id = 2, .rx_id = 3, .irq_id = 1, .usr_id = 3 }, +}; + +static struct omap_mbox_pdata omap2420_mailbox_attrs = { + .num_users = 4, + .num_fifos = 6, + .info_cnt = ARRAY_SIZE(omap2420_mailbox_info), + .info = omap2420_mailbox_info, +}; + +static struct omap_hwmod omap2420_mailbox_hwmod = { + .name = "mailbox", + .class = &omap2xxx_mailbox_hwmod_class, + .main_clk = "mailboxes_ick", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_MAILBOXES_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_MAILBOXES_SHIFT, + }, + }, + .dev_attr = &omap2420_mailbox_attrs, +}; + +/* + * 'mcbsp' class + * multi channel buffered serial port controller + */ + +static struct omap_hwmod_class omap2420_mcbsp_hwmod_class = { + .name = "mcbsp", +}; + +static struct omap_hwmod_opt_clk mcbsp_opt_clks[] = { + { .role = "pad_fck", .clk = "mcbsp_clks" }, + { .role = "prcm_fck", .clk = "func_96m_ck" }, +}; + +/* mcbsp1 */ +static struct omap_hwmod omap2420_mcbsp1_hwmod = { + .name = "mcbsp1", + .class = &omap2420_mcbsp_hwmod_class, + .main_clk = "mcbsp1_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_MCBSP1_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_MCBSP1_SHIFT, + }, + }, + .opt_clks = mcbsp_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks), +}; + +/* mcbsp2 */ +static struct omap_hwmod omap2420_mcbsp2_hwmod = { + .name = "mcbsp2", + .class = &omap2420_mcbsp_hwmod_class, + .main_clk = "mcbsp2_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_MCBSP2_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_MCBSP2_SHIFT, + }, + }, + .opt_clks = mcbsp_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks), +}; + +static struct omap_hwmod_class_sysconfig omap2420_msdi_sysc = { + .rev_offs = 0x3c, + .sysc_offs = 0x64, + .syss_offs = 0x68, + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap2420_msdi_hwmod_class = { + .name = "msdi", + .sysc = &omap2420_msdi_sysc, + .reset = &omap_msdi_reset, +}; + +/* msdi1 */ +static struct omap_hwmod omap2420_msdi1_hwmod = { + .name = "msdi1", + .class = &omap2420_msdi_hwmod_class, + .main_clk = "mmc_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP2420_EN_MMC_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP2420_ST_MMC_SHIFT, + }, + }, + .flags = HWMOD_16BIT_REG, +}; + +/* HDQ1W/1-wire */ +static struct omap_hwmod omap2420_hdq1w_hwmod = { + .name = "hdq1w", + .main_clk = "hdq_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_HDQ_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_HDQ_SHIFT, + }, + }, + .class = &omap2_hdq1w_class, +}; + +/* + * interfaces + */ + +/* L4 CORE -> I2C1 interface */ +static struct omap_hwmod_ocp_if omap2420_l4_core__i2c1 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2420_i2c1_hwmod, + .clk = "i2c1_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 CORE -> I2C2 interface */ +static struct omap_hwmod_ocp_if omap2420_l4_core__i2c2 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2420_i2c2_hwmod, + .clk = "i2c2_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* IVA <- L3 interface */ +static struct omap_hwmod_ocp_if omap2420_l3__iva = { + .master = &omap2xxx_l3_main_hwmod, + .slave = &omap2420_iva_hwmod, + .clk = "core_l3_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* DSP <- L3 interface */ +static struct omap_hwmod_ocp_if omap2420_l3__dsp = { + .master = &omap2xxx_l3_main_hwmod, + .slave = &omap2420_dsp_hwmod, + .clk = "dsp_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> timer1 */ +static struct omap_hwmod_ocp_if omap2420_l4_wkup__timer1 = { + .master = &omap2xxx_l4_wkup_hwmod, + .slave = &omap2xxx_timer1_hwmod, + .clk = "gpt1_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> wd_timer2 */ +static struct omap_hwmod_ocp_if omap2420_l4_wkup__wd_timer2 = { + .master = &omap2xxx_l4_wkup_hwmod, + .slave = &omap2xxx_wd_timer2_hwmod, + .clk = "mpu_wdt_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> gpio1 */ +static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio1 = { + .master = &omap2xxx_l4_wkup_hwmod, + .slave = &omap2xxx_gpio1_hwmod, + .clk = "gpios_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> gpio2 */ +static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio2 = { + .master = &omap2xxx_l4_wkup_hwmod, + .slave = &omap2xxx_gpio2_hwmod, + .clk = "gpios_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> gpio3 */ +static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio3 = { + .master = &omap2xxx_l4_wkup_hwmod, + .slave = &omap2xxx_gpio3_hwmod, + .clk = "gpios_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> gpio4 */ +static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio4 = { + .master = &omap2xxx_l4_wkup_hwmod, + .slave = &omap2xxx_gpio4_hwmod, + .clk = "gpios_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dma_system -> L3 */ +static struct omap_hwmod_ocp_if omap2420_dma_system__l3 = { + .master = &omap2420_dma_system_hwmod, + .slave = &omap2xxx_l3_main_hwmod, + .clk = "core_l3_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> dma_system */ +static struct omap_hwmod_ocp_if omap2420_l4_core__dma_system = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2420_dma_system_hwmod, + .clk = "sdma_ick", + .addr = omap2_dma_system_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> mailbox */ +static struct omap_hwmod_ocp_if omap2420_l4_core__mailbox = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2420_mailbox_hwmod, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> mcbsp1 */ +static struct omap_hwmod_ocp_if omap2420_l4_core__mcbsp1 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2420_mcbsp1_hwmod, + .clk = "mcbsp1_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> mcbsp2 */ +static struct omap_hwmod_ocp_if omap2420_l4_core__mcbsp2 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2420_mcbsp2_hwmod, + .clk = "mcbsp2_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> msdi1 */ +static struct omap_hwmod_ocp_if omap2420_l4_core__msdi1 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2420_msdi1_hwmod, + .clk = "mmc_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> hdq1w interface */ +static struct omap_hwmod_ocp_if omap2420_l4_core__hdq1w = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2420_hdq1w_hwmod, + .clk = "hdq_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, + .flags = OMAP_FIREWALL_L4 | OCPIF_SWSUP_IDLE, +}; + + +/* l4_wkup -> 32ksync_counter */ +static struct omap_hwmod_ocp_if omap2420_l4_wkup__counter_32k = { + .master = &omap2xxx_l4_wkup_hwmod, + .slave = &omap2xxx_counter_32k_hwmod, + .clk = "sync_32k_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if omap2420_l3__gpmc = { + .master = &omap2xxx_l3_main_hwmod, + .slave = &omap2xxx_gpmc_hwmod, + .clk = "core_l3_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if *omap2420_hwmod_ocp_ifs[] __initdata = { + &omap2xxx_l3_main__l4_core, + &omap2xxx_mpu__l3_main, + &omap2xxx_dss__l3, + &omap2xxx_l4_core__mcspi1, + &omap2xxx_l4_core__mcspi2, + &omap2xxx_l4_core__l4_wkup, + &omap2_l4_core__uart1, + &omap2_l4_core__uart2, + &omap2_l4_core__uart3, + &omap2420_l4_core__i2c1, + &omap2420_l4_core__i2c2, + &omap2420_l3__iva, + &omap2420_l3__dsp, + &omap2420_l4_wkup__timer1, + &omap2xxx_l4_core__timer2, + &omap2xxx_l4_core__timer3, + &omap2xxx_l4_core__timer4, + &omap2xxx_l4_core__timer5, + &omap2xxx_l4_core__timer6, + &omap2xxx_l4_core__timer7, + &omap2xxx_l4_core__timer8, + &omap2xxx_l4_core__timer9, + &omap2xxx_l4_core__timer10, + &omap2xxx_l4_core__timer11, + &omap2xxx_l4_core__timer12, + &omap2420_l4_wkup__wd_timer2, + &omap2xxx_l4_core__dss, + &omap2xxx_l4_core__dss_dispc, + &omap2xxx_l4_core__dss_rfbi, + &omap2xxx_l4_core__dss_venc, + &omap2420_l4_wkup__gpio1, + &omap2420_l4_wkup__gpio2, + &omap2420_l4_wkup__gpio3, + &omap2420_l4_wkup__gpio4, + &omap2420_dma_system__l3, + &omap2420_l4_core__dma_system, + &omap2420_l4_core__mailbox, + &omap2420_l4_core__mcbsp1, + &omap2420_l4_core__mcbsp2, + &omap2420_l4_core__msdi1, + &omap2xxx_l4_core__rng, + &omap2xxx_l4_core__sham, + &omap2xxx_l4_core__aes, + &omap2420_l4_core__hdq1w, + &omap2420_l4_wkup__counter_32k, + &omap2420_l3__gpmc, + NULL, +}; + +int __init omap2420_hwmod_init(void) +{ + omap_hwmod_init(); + return omap_hwmod_register_links(omap2420_hwmod_ocp_ifs); +} diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c new file mode 100644 index 00000000000..6d1b6090217 --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -0,0 +1,724 @@ +/* + * omap_hwmod_2430_data.c - hardware modules present on the OMAP2430 chips + * + * Copyright (C) 2009-2011 Nokia Corporation + * Copyright (C) 2012 Texas Instruments, Inc. + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * XXX handle crossbar/shared link difference for L3? + * XXX these should be marked initdata for multi-OMAP kernels + */ + +#include <linux/i2c-omap.h> +#include <linux/platform_data/asoc-ti-mcbsp.h> +#include <linux/platform_data/spi-omap2-mcspi.h> +#include <linux/omap-dma.h> +#include <linux/platform_data/mailbox-omap.h> +#include <plat/dmtimer.h> + +#include "omap_hwmod.h" +#include "mmc.h" +#include "l3_2xxx.h" + +#include "soc.h" +#include "omap_hwmod_common_data.h" +#include "prm-regbits-24xx.h" +#include "cm-regbits-24xx.h" +#include "i2c.h" +#include "wd_timer.h" + +/* + * OMAP2430 hardware module integration data + * + * All of the data in this section should be autogeneratable from the + * TI hardware database or other technical documentation. Data that + * is driver-specific or driver-kernel integration-specific belongs + * elsewhere. + */ + +/* + * IP blocks + */ + +/* IVA2 (IVA2) */ +static struct omap_hwmod_rst_info omap2430_iva_resets[] = { + { .name = "logic", .rst_shift = 0 }, + { .name = "mmu", .rst_shift = 1 }, +}; + +static struct omap_hwmod omap2430_iva_hwmod = { + .name = "iva", + .class = &iva_hwmod_class, + .clkdm_name = "dsp_clkdm", + .rst_lines = omap2430_iva_resets, + .rst_lines_cnt = ARRAY_SIZE(omap2430_iva_resets), + .main_clk = "dsp_fck", +}; + +/* I2C common */ +static struct omap_hwmod_class_sysconfig i2c_sysc = { + .rev_offs = 0x00, + .sysc_offs = 0x20, + .syss_offs = 0x10, + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class i2c_class = { + .name = "i2c", + .sysc = &i2c_sysc, + .rev = OMAP_I2C_IP_VERSION_1, + .reset = &omap_i2c_reset, +}; + +static struct omap_i2c_dev_attr i2c_dev_attr = { + .fifo_depth = 8, /* bytes */ + .flags = OMAP_I2C_FLAG_BUS_SHIFT_2 | + OMAP_I2C_FLAG_FORCE_19200_INT_CLK, +}; + +/* I2C1 */ +static struct omap_hwmod omap2430_i2c1_hwmod = { + .name = "i2c1", + .flags = HWMOD_16BIT_REG, + .main_clk = "i2chs1_fck", + .prcm = { + .omap2 = { + /* + * NOTE: The CM_FCLKEN* and CM_ICLKEN* for + * I2CHS IP's do not follow the usual pattern. + * prcm_reg_id alone cannot be used to program + * the iclk and fclk. Needs to be handled using + * additional flags when clk handling is moved + * to hwmod framework. + */ + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP2430_EN_I2CHS1_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP2430_ST_I2CHS1_SHIFT, + }, + }, + .class = &i2c_class, + .dev_attr = &i2c_dev_attr, +}; + +/* I2C2 */ +static struct omap_hwmod omap2430_i2c2_hwmod = { + .name = "i2c2", + .flags = HWMOD_16BIT_REG, + .main_clk = "i2chs2_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP2430_EN_I2CHS2_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP2430_ST_I2CHS2_SHIFT, + }, + }, + .class = &i2c_class, + .dev_attr = &i2c_dev_attr, +}; + +/* gpio5 */ +static struct omap_hwmod omap2430_gpio5_hwmod = { + .name = "gpio5", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "gpio5_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 2, + .module_bit = OMAP2430_EN_GPIO5_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 2, + .idlest_idle_bit = OMAP2430_ST_GPIO5_SHIFT, + }, + }, + .class = &omap2xxx_gpio_hwmod_class, + .dev_attr = &omap2xxx_gpio_dev_attr, +}; + +/* dma attributes */ +static struct omap_dma_dev_attr dma_dev_attr = { + .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY | + IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY, + .lch_count = 32, +}; + +static struct omap_hwmod omap2430_dma_system_hwmod = { + .name = "dma", + .class = &omap2xxx_dma_hwmod_class, + .mpu_irqs = omap2_dma_system_irqs, + .main_clk = "core_l3_ck", + .dev_attr = &dma_dev_attr, + .flags = HWMOD_NO_IDLEST, +}; + +/* mailbox */ +static struct omap_mbox_dev_info omap2430_mailbox_info[] = { + { .name = "dsp", .tx_id = 0, .rx_id = 1 }, +}; + +static struct omap_mbox_pdata omap2430_mailbox_attrs = { + .num_users = 4, + .num_fifos = 6, + .info_cnt = ARRAY_SIZE(omap2430_mailbox_info), + .info = omap2430_mailbox_info, +}; + +static struct omap_hwmod omap2430_mailbox_hwmod = { + .name = "mailbox", + .class = &omap2xxx_mailbox_hwmod_class, + .main_clk = "mailboxes_ick", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_MAILBOXES_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_MAILBOXES_SHIFT, + }, + }, + .dev_attr = &omap2430_mailbox_attrs, +}; + +/* mcspi3 */ +static struct omap2_mcspi_dev_attr omap_mcspi3_dev_attr = { + .num_chipselect = 2, +}; + +static struct omap_hwmod omap2430_mcspi3_hwmod = { + .name = "mcspi3", + .main_clk = "mcspi3_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 2, + .module_bit = OMAP2430_EN_MCSPI3_SHIFT, + .idlest_reg_id = 2, + .idlest_idle_bit = OMAP2430_ST_MCSPI3_SHIFT, + }, + }, + .class = &omap2xxx_mcspi_class, + .dev_attr = &omap_mcspi3_dev_attr, +}; + +/* usbhsotg */ +static struct omap_hwmod_class_sysconfig omap2430_usbhsotg_sysc = { + .rev_offs = 0x0400, + .sysc_offs = 0x0404, + .syss_offs = 0x0408, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE| + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class usbotg_class = { + .name = "usbotg", + .sysc = &omap2430_usbhsotg_sysc, +}; + +/* usb_otg_hs */ +static struct omap_hwmod omap2430_usbhsotg_hwmod = { + .name = "usb_otg_hs", + .main_clk = "usbhs_ick", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP2430_EN_USBHS_MASK, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP2430_ST_USBHS_SHIFT, + }, + }, + .class = &usbotg_class, + /* + * Erratum ID: i479 idle_req / idle_ack mechanism potentially + * broken when autoidle is enabled + * workaround is to disable the autoidle bit at module level. + */ + .flags = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE + | HWMOD_SWSUP_MSTANDBY, +}; + +/* + * 'mcbsp' class + * multi channel buffered serial port controller + */ + +static struct omap_hwmod_class_sysconfig omap2430_mcbsp_sysc = { + .rev_offs = 0x007C, + .sysc_offs = 0x008C, + .sysc_flags = (SYSC_HAS_SOFTRESET), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap2430_mcbsp_hwmod_class = { + .name = "mcbsp", + .sysc = &omap2430_mcbsp_sysc, + .rev = MCBSP_CONFIG_TYPE2, +}; + +static struct omap_hwmod_opt_clk mcbsp_opt_clks[] = { + { .role = "pad_fck", .clk = "mcbsp_clks" }, + { .role = "prcm_fck", .clk = "func_96m_ck" }, +}; + +/* mcbsp1 */ +static struct omap_hwmod omap2430_mcbsp1_hwmod = { + .name = "mcbsp1", + .class = &omap2430_mcbsp_hwmod_class, + .main_clk = "mcbsp1_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_MCBSP1_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_MCBSP1_SHIFT, + }, + }, + .opt_clks = mcbsp_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks), +}; + +/* mcbsp2 */ +static struct omap_hwmod omap2430_mcbsp2_hwmod = { + .name = "mcbsp2", + .class = &omap2430_mcbsp_hwmod_class, + .main_clk = "mcbsp2_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_MCBSP2_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_MCBSP2_SHIFT, + }, + }, + .opt_clks = mcbsp_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks), +}; + +/* mcbsp3 */ +static struct omap_hwmod omap2430_mcbsp3_hwmod = { + .name = "mcbsp3", + .class = &omap2430_mcbsp_hwmod_class, + .main_clk = "mcbsp3_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP2430_EN_MCBSP3_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 2, + .idlest_idle_bit = OMAP2430_ST_MCBSP3_SHIFT, + }, + }, + .opt_clks = mcbsp_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks), +}; + +/* mcbsp4 */ +static struct omap_hwmod omap2430_mcbsp4_hwmod = { + .name = "mcbsp4", + .class = &omap2430_mcbsp_hwmod_class, + .main_clk = "mcbsp4_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP2430_EN_MCBSP4_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 2, + .idlest_idle_bit = OMAP2430_ST_MCBSP4_SHIFT, + }, + }, + .opt_clks = mcbsp_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks), +}; + +/* mcbsp5 */ +static struct omap_hwmod omap2430_mcbsp5_hwmod = { + .name = "mcbsp5", + .class = &omap2430_mcbsp_hwmod_class, + .main_clk = "mcbsp5_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP2430_EN_MCBSP5_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 2, + .idlest_idle_bit = OMAP2430_ST_MCBSP5_SHIFT, + }, + }, + .opt_clks = mcbsp_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp_opt_clks), +}; + +/* MMC/SD/SDIO common */ +static struct omap_hwmod_class_sysconfig omap2430_mmc_sysc = { + .rev_offs = 0x1fc, + .sysc_offs = 0x10, + .syss_offs = 0x14, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap2430_mmc_class = { + .name = "mmc", + .sysc = &omap2430_mmc_sysc, +}; + +/* MMC/SD/SDIO1 */ +static struct omap_hwmod_opt_clk omap2430_mmc1_opt_clks[] = { + { .role = "dbck", .clk = "mmchsdb1_fck" }, +}; + +static struct omap_mmc_dev_attr mmc1_dev_attr = { + .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, +}; + +static struct omap_hwmod omap2430_mmc1_hwmod = { + .name = "mmc1", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .opt_clks = omap2430_mmc1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(omap2430_mmc1_opt_clks), + .main_clk = "mmchs1_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 2, + .module_bit = OMAP2430_EN_MMCHS1_SHIFT, + .idlest_reg_id = 2, + .idlest_idle_bit = OMAP2430_ST_MMCHS1_SHIFT, + }, + }, + .dev_attr = &mmc1_dev_attr, + .class = &omap2430_mmc_class, +}; + +/* MMC/SD/SDIO2 */ +static struct omap_hwmod_opt_clk omap2430_mmc2_opt_clks[] = { + { .role = "dbck", .clk = "mmchsdb2_fck" }, +}; + +static struct omap_hwmod omap2430_mmc2_hwmod = { + .name = "mmc2", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .opt_clks = omap2430_mmc2_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(omap2430_mmc2_opt_clks), + .main_clk = "mmchs2_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 2, + .module_bit = OMAP2430_EN_MMCHS2_SHIFT, + .idlest_reg_id = 2, + .idlest_idle_bit = OMAP2430_ST_MMCHS2_SHIFT, + }, + }, + .class = &omap2430_mmc_class, +}; + +/* HDQ1W/1-wire */ +static struct omap_hwmod omap2430_hdq1w_hwmod = { + .name = "hdq1w", + .main_clk = "hdq_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_HDQ_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_HDQ_SHIFT, + }, + }, + .class = &omap2_hdq1w_class, +}; + +/* + * interfaces + */ + +/* L3 -> L4_CORE interface */ +/* l3_core -> usbhsotg interface */ +static struct omap_hwmod_ocp_if omap2430_usbhsotg__l3 = { + .master = &omap2430_usbhsotg_hwmod, + .slave = &omap2xxx_l3_main_hwmod, + .clk = "core_l3_ck", + .user = OCP_USER_MPU, +}; + +/* L4 CORE -> I2C1 interface */ +static struct omap_hwmod_ocp_if omap2430_l4_core__i2c1 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2430_i2c1_hwmod, + .clk = "i2c1_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 CORE -> I2C2 interface */ +static struct omap_hwmod_ocp_if omap2430_l4_core__i2c2 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2430_i2c2_hwmod, + .clk = "i2c2_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core ->usbhsotg interface */ +static struct omap_hwmod_ocp_if omap2430_l4_core__usbhsotg = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2430_usbhsotg_hwmod, + .clk = "usb_l4_ick", + .user = OCP_USER_MPU, +}; + +/* L4 CORE -> MMC1 interface */ +static struct omap_hwmod_ocp_if omap2430_l4_core__mmc1 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2430_mmc1_hwmod, + .clk = "mmchs1_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 CORE -> MMC2 interface */ +static struct omap_hwmod_ocp_if omap2430_l4_core__mmc2 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2430_mmc2_hwmod, + .clk = "mmchs2_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 core -> mcspi3 interface */ +static struct omap_hwmod_ocp_if omap2430_l4_core__mcspi3 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2430_mcspi3_hwmod, + .clk = "mcspi3_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* IVA2 <- L3 interface */ +static struct omap_hwmod_ocp_if omap2430_l3__iva = { + .master = &omap2xxx_l3_main_hwmod, + .slave = &omap2430_iva_hwmod, + .clk = "core_l3_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> timer1 */ +static struct omap_hwmod_ocp_if omap2430_l4_wkup__timer1 = { + .master = &omap2xxx_l4_wkup_hwmod, + .slave = &omap2xxx_timer1_hwmod, + .clk = "gpt1_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> wd_timer2 */ +static struct omap_hwmod_ocp_if omap2430_l4_wkup__wd_timer2 = { + .master = &omap2xxx_l4_wkup_hwmod, + .slave = &omap2xxx_wd_timer2_hwmod, + .clk = "mpu_wdt_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> gpio1 */ +static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio1 = { + .master = &omap2xxx_l4_wkup_hwmod, + .slave = &omap2xxx_gpio1_hwmod, + .clk = "gpios_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> gpio2 */ +static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio2 = { + .master = &omap2xxx_l4_wkup_hwmod, + .slave = &omap2xxx_gpio2_hwmod, + .clk = "gpios_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> gpio3 */ +static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio3 = { + .master = &omap2xxx_l4_wkup_hwmod, + .slave = &omap2xxx_gpio3_hwmod, + .clk = "gpios_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> gpio4 */ +static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio4 = { + .master = &omap2xxx_l4_wkup_hwmod, + .slave = &omap2xxx_gpio4_hwmod, + .clk = "gpios_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> gpio5 */ +static struct omap_hwmod_ocp_if omap2430_l4_core__gpio5 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2430_gpio5_hwmod, + .clk = "gpio5_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dma_system -> L3 */ +static struct omap_hwmod_ocp_if omap2430_dma_system__l3 = { + .master = &omap2430_dma_system_hwmod, + .slave = &omap2xxx_l3_main_hwmod, + .clk = "core_l3_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> dma_system */ +static struct omap_hwmod_ocp_if omap2430_l4_core__dma_system = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2430_dma_system_hwmod, + .clk = "sdma_ick", + .addr = omap2_dma_system_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> mailbox */ +static struct omap_hwmod_ocp_if omap2430_l4_core__mailbox = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2430_mailbox_hwmod, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> mcbsp1 */ +static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp1 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2430_mcbsp1_hwmod, + .clk = "mcbsp1_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> mcbsp2 */ +static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp2 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2430_mcbsp2_hwmod, + .clk = "mcbsp2_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> mcbsp3 */ +static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp3 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2430_mcbsp3_hwmod, + .clk = "mcbsp3_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> mcbsp4 */ +static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp4 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2430_mcbsp4_hwmod, + .clk = "mcbsp4_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> mcbsp5 */ +static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp5 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2430_mcbsp5_hwmod, + .clk = "mcbsp5_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> hdq1w */ +static struct omap_hwmod_ocp_if omap2430_l4_core__hdq1w = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2430_hdq1w_hwmod, + .clk = "hdq_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, + .flags = OMAP_FIREWALL_L4 | OCPIF_SWSUP_IDLE, +}; + +/* l4_wkup -> 32ksync_counter */ +static struct omap_hwmod_ocp_if omap2430_l4_wkup__counter_32k = { + .master = &omap2xxx_l4_wkup_hwmod, + .slave = &omap2xxx_counter_32k_hwmod, + .clk = "sync_32k_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if omap2430_l3__gpmc = { + .master = &omap2xxx_l3_main_hwmod, + .slave = &omap2xxx_gpmc_hwmod, + .clk = "core_l3_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if *omap2430_hwmod_ocp_ifs[] __initdata = { + &omap2xxx_l3_main__l4_core, + &omap2xxx_mpu__l3_main, + &omap2xxx_dss__l3, + &omap2430_usbhsotg__l3, + &omap2430_l4_core__i2c1, + &omap2430_l4_core__i2c2, + &omap2xxx_l4_core__l4_wkup, + &omap2_l4_core__uart1, + &omap2_l4_core__uart2, + &omap2_l4_core__uart3, + &omap2430_l4_core__usbhsotg, + &omap2430_l4_core__mmc1, + &omap2430_l4_core__mmc2, + &omap2xxx_l4_core__mcspi1, + &omap2xxx_l4_core__mcspi2, + &omap2430_l4_core__mcspi3, + &omap2430_l3__iva, + &omap2430_l4_wkup__timer1, + &omap2xxx_l4_core__timer2, + &omap2xxx_l4_core__timer3, + &omap2xxx_l4_core__timer4, + &omap2xxx_l4_core__timer5, + &omap2xxx_l4_core__timer6, + &omap2xxx_l4_core__timer7, + &omap2xxx_l4_core__timer8, + &omap2xxx_l4_core__timer9, + &omap2xxx_l4_core__timer10, + &omap2xxx_l4_core__timer11, + &omap2xxx_l4_core__timer12, + &omap2430_l4_wkup__wd_timer2, + &omap2xxx_l4_core__dss, + &omap2xxx_l4_core__dss_dispc, + &omap2xxx_l4_core__dss_rfbi, + &omap2xxx_l4_core__dss_venc, + &omap2430_l4_wkup__gpio1, + &omap2430_l4_wkup__gpio2, + &omap2430_l4_wkup__gpio3, + &omap2430_l4_wkup__gpio4, + &omap2430_l4_core__gpio5, + &omap2430_dma_system__l3, + &omap2430_l4_core__dma_system, + &omap2430_l4_core__mailbox, + &omap2430_l4_core__mcbsp1, + &omap2430_l4_core__mcbsp2, + &omap2430_l4_core__mcbsp3, + &omap2430_l4_core__mcbsp4, + &omap2430_l4_core__mcbsp5, + &omap2430_l4_core__hdq1w, + &omap2xxx_l4_core__rng, + &omap2xxx_l4_core__sham, + &omap2xxx_l4_core__aes, + &omap2430_l4_wkup__counter_32k, + &omap2430_l3__gpmc, + NULL, +}; + +int __init omap2430_hwmod_init(void) +{ + omap_hwmod_init(); + return omap_hwmod_register_links(omap2430_hwmod_ocp_ifs); +} diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.c new file mode 100644 index 00000000000..0413daba2db --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.c @@ -0,0 +1,181 @@ +/* + * omap_hwmod_2xxx_3xxx_interconnect_data.c - common interconnect data, OMAP2/3 + * + * Copyright (C) 2009-2011 Nokia Corporation + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * XXX handle crossbar/shared link difference for L3? + * XXX these should be marked initdata for multi-OMAP kernels + */ +#include <asm/sizes.h> + +#include "omap_hwmod.h" + +#include "omap_hwmod_common_data.h" + +struct omap_hwmod_addr_space omap2430_mmc1_addr_space[] = { + { + .pa_start = 0x4809c000, + .pa_end = 0x4809c1ff, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_addr_space omap2430_mmc2_addr_space[] = { + { + .pa_start = 0x480b4000, + .pa_end = 0x480b41ff, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_addr_space omap2_i2c1_addr_space[] = { + { + .pa_start = 0x48070000, + .pa_end = 0x48070000 + SZ_128 - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_addr_space omap2_i2c2_addr_space[] = { + { + .pa_start = 0x48072000, + .pa_end = 0x48072000 + SZ_128 - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_addr_space omap2_dss_addrs[] = { + { + .pa_start = 0x48050000, + .pa_end = 0x48050000 + SZ_1K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_addr_space omap2_dss_dispc_addrs[] = { + { + .pa_start = 0x48050400, + .pa_end = 0x48050400 + SZ_1K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_addr_space omap2_dss_rfbi_addrs[] = { + { + .pa_start = 0x48050800, + .pa_end = 0x48050800 + SZ_1K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_addr_space omap2_dss_venc_addrs[] = { + { + .pa_start = 0x48050C00, + .pa_end = 0x48050C00 + SZ_1K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_addr_space omap2_timer10_addrs[] = { + { + .pa_start = 0x48086000, + .pa_end = 0x48086000 + SZ_1K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_addr_space omap2_timer11_addrs[] = { + { + .pa_start = 0x48088000, + .pa_end = 0x48088000 + SZ_1K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_addr_space omap2xxx_timer12_addrs[] = { + { + .pa_start = 0x4808a000, + .pa_end = 0x4808a000 + SZ_1K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_addr_space omap2_mcspi1_addr_space[] = { + { + .pa_start = 0x48098000, + .pa_end = 0x48098000 + SZ_256 - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_addr_space omap2_mcspi2_addr_space[] = { + { + .pa_start = 0x4809a000, + .pa_end = 0x4809a000 + SZ_256 - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_addr_space omap2430_mcspi3_addr_space[] = { + { + .pa_start = 0x480b8000, + .pa_end = 0x480b8000 + SZ_256 - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_addr_space omap2_dma_system_addrs[] = { + { + .pa_start = 0x48056000, + .pa_end = 0x48056000 + SZ_4K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_addr_space omap2_mailbox_addrs[] = { + { + .pa_start = 0x48094000, + .pa_end = 0x48094000 + SZ_512 - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_addr_space omap2_mcbsp1_addrs[] = { + { + .name = "mpu", + .pa_start = 0x48074000, + .pa_end = 0x480740ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_addr_space omap2_hdq1w_addr_space[] = { + { + .pa_start = 0x480b2000, + .pa_end = 0x480b2fff, + .flags = ADDR_TYPE_RT, + }, + { } +}; diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c new file mode 100644 index 00000000000..5da7a42a6d9 --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c @@ -0,0 +1,325 @@ +/* + * omap_hwmod_2xxx_3xxx_ipblock_data.c - common IP block data for OMAP2/3 + * + * Copyright (C) 2011 Nokia Corporation + * Copyright (C) 2012 Texas Instruments, Inc. + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/dmaengine.h> +#include <linux/omap-dma.h> + +#include "omap_hwmod.h" +#include "hdq1w.h" + +#include "omap_hwmod_common_data.h" + +/* UART */ + +static struct omap_hwmod_class_sysconfig omap2_uart_sysc = { + .rev_offs = 0x50, + .sysc_offs = 0x54, + .syss_offs = 0x58, + .sysc_flags = (SYSC_HAS_SIDLEMODE | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +struct omap_hwmod_class omap2_uart_class = { + .name = "uart", + .sysc = &omap2_uart_sysc, +}; + +/* + * 'dss' class + * display sub-system + */ + +static struct omap_hwmod_class_sysconfig omap2_dss_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +struct omap_hwmod_class omap2_dss_hwmod_class = { + .name = "dss", + .sysc = &omap2_dss_sysc, + .reset = omap_dss_reset, +}; + +/* + * 'rfbi' class + * remote frame buffer interface + */ + +static struct omap_hwmod_class_sysconfig omap2_rfbi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +struct omap_hwmod_class omap2_rfbi_hwmod_class = { + .name = "rfbi", + .sysc = &omap2_rfbi_sysc, +}; + +/* + * 'venc' class + * video encoder + */ + +struct omap_hwmod_class omap2_venc_hwmod_class = { + .name = "venc", +}; + + +/* Common DMA request line data */ +struct omap_hwmod_dma_info omap2_uart1_sdma_reqs[] = { + { .name = "rx", .dma_req = 50, }, + { .name = "tx", .dma_req = 49, }, + { .dma_req = -1 } +}; + +struct omap_hwmod_dma_info omap2_uart2_sdma_reqs[] = { + { .name = "rx", .dma_req = 52, }, + { .name = "tx", .dma_req = 51, }, + { .dma_req = -1 } +}; + +struct omap_hwmod_dma_info omap2_uart3_sdma_reqs[] = { + { .name = "rx", .dma_req = 54, }, + { .name = "tx", .dma_req = 53, }, + { .dma_req = -1 } +}; + +struct omap_hwmod_dma_info omap2_i2c1_sdma_reqs[] = { + { .name = "tx", .dma_req = 27 }, + { .name = "rx", .dma_req = 28 }, + { .dma_req = -1 } +}; + +struct omap_hwmod_dma_info omap2_i2c2_sdma_reqs[] = { + { .name = "tx", .dma_req = 29 }, + { .name = "rx", .dma_req = 30 }, + { .dma_req = -1 } +}; + +struct omap_hwmod_dma_info omap2_mcspi1_sdma_reqs[] = { + { .name = "tx0", .dma_req = 35 }, /* DMA_SPI1_TX0 */ + { .name = "rx0", .dma_req = 36 }, /* DMA_SPI1_RX0 */ + { .name = "tx1", .dma_req = 37 }, /* DMA_SPI1_TX1 */ + { .name = "rx1", .dma_req = 38 }, /* DMA_SPI1_RX1 */ + { .name = "tx2", .dma_req = 39 }, /* DMA_SPI1_TX2 */ + { .name = "rx2", .dma_req = 40 }, /* DMA_SPI1_RX2 */ + { .name = "tx3", .dma_req = 41 }, /* DMA_SPI1_TX3 */ + { .name = "rx3", .dma_req = 42 }, /* DMA_SPI1_RX3 */ + { .dma_req = -1 } +}; + +struct omap_hwmod_dma_info omap2_mcspi2_sdma_reqs[] = { + { .name = "tx0", .dma_req = 43 }, /* DMA_SPI2_TX0 */ + { .name = "rx0", .dma_req = 44 }, /* DMA_SPI2_RX0 */ + { .name = "tx1", .dma_req = 45 }, /* DMA_SPI2_TX1 */ + { .name = "rx1", .dma_req = 46 }, /* DMA_SPI2_RX1 */ + { .dma_req = -1 } +}; + +struct omap_hwmod_dma_info omap2_mcbsp1_sdma_reqs[] = { + { .name = "rx", .dma_req = 32 }, + { .name = "tx", .dma_req = 31 }, + { .dma_req = -1 } +}; + +struct omap_hwmod_dma_info omap2_mcbsp2_sdma_reqs[] = { + { .name = "rx", .dma_req = 34 }, + { .name = "tx", .dma_req = 33 }, + { .dma_req = -1 } +}; + +struct omap_hwmod_dma_info omap2_mcbsp3_sdma_reqs[] = { + { .name = "rx", .dma_req = 18 }, + { .name = "tx", .dma_req = 17 }, + { .dma_req = -1 } +}; + +/* Other IP block data */ + + +/* + * omap_hwmod class data + */ + +struct omap_hwmod_class l3_hwmod_class = { + .name = "l3" +}; + +struct omap_hwmod_class l4_hwmod_class = { + .name = "l4" +}; + +struct omap_hwmod_class mpu_hwmod_class = { + .name = "mpu" +}; + +struct omap_hwmod_class iva_hwmod_class = { + .name = "iva" +}; + +/* Common MPU IRQ line data */ + +struct omap_hwmod_irq_info omap2_timer1_mpu_irqs[] = { + { .irq = 37 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_timer2_mpu_irqs[] = { + { .irq = 38 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_timer3_mpu_irqs[] = { + { .irq = 39 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_timer4_mpu_irqs[] = { + { .irq = 40 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_timer5_mpu_irqs[] = { + { .irq = 41 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_timer6_mpu_irqs[] = { + { .irq = 42 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_timer7_mpu_irqs[] = { + { .irq = 43 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_timer8_mpu_irqs[] = { + { .irq = 44 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_timer9_mpu_irqs[] = { + { .irq = 45 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_timer10_mpu_irqs[] = { + { .irq = 46 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_timer11_mpu_irqs[] = { + { .irq = 47 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_uart1_mpu_irqs[] = { + { .irq = 72 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_uart2_mpu_irqs[] = { + { .irq = 73 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_uart3_mpu_irqs[] = { + { .irq = 74 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_dispc_irqs[] = { + { .irq = 25 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_i2c1_mpu_irqs[] = { + { .irq = 56 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_i2c2_mpu_irqs[] = { + { .irq = 57 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_gpio1_irqs[] = { + { .irq = 29 + OMAP_INTC_START, }, /* INT_24XX_GPIO_BANK1 */ + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_gpio2_irqs[] = { + { .irq = 30 + OMAP_INTC_START, }, /* INT_24XX_GPIO_BANK2 */ + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_gpio3_irqs[] = { + { .irq = 31 + OMAP_INTC_START, }, /* INT_24XX_GPIO_BANK3 */ + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_gpio4_irqs[] = { + { .irq = 32 + OMAP_INTC_START, }, /* INT_24XX_GPIO_BANK4 */ + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_dma_system_irqs[] = { + { .name = "0", .irq = 12 + OMAP_INTC_START, }, /* INT_24XX_SDMA_IRQ0 */ + { .name = "1", .irq = 13 + OMAP_INTC_START, }, /* INT_24XX_SDMA_IRQ1 */ + { .name = "2", .irq = 14 + OMAP_INTC_START, }, /* INT_24XX_SDMA_IRQ2 */ + { .name = "3", .irq = 15 + OMAP_INTC_START, }, /* INT_24XX_SDMA_IRQ3 */ + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_mcspi1_mpu_irqs[] = { + { .irq = 65 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_irq_info omap2_mcspi2_mpu_irqs[] = { + { .irq = 66 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +struct omap_hwmod_class_sysconfig omap2_hdq1w_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x14, + .syss_offs = 0x18, + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +struct omap_hwmod_class omap2_hdq1w_class = { + .name = "hdq1w", + .sysc = &omap2_hdq1w_sysc, + .reset = &omap_hdq1w_reset, +}; + +struct omap_hwmod_irq_info omap2_hdq1w_mpu_irqs[] = { + { .irq = 58 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c new file mode 100644 index 00000000000..656861c29d5 --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c @@ -0,0 +1,272 @@ +/* + * omap_hwmod_2xxx_interconnect_data.c - common interconnect data for OMAP2xxx + * + * Copyright (C) 2009-2011 Nokia Corporation + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * XXX handle crossbar/shared link difference for L3? + * XXX these should be marked initdata for multi-OMAP kernels + */ +#include <asm/sizes.h> + +#include "omap_hwmod.h" +#include "l3_2xxx.h" +#include "l4_2xxx.h" +#include "serial.h" + +#include "omap_hwmod_common_data.h" + +/* + * Common interconnect data + */ + +/* L3 -> L4_CORE interface */ +struct omap_hwmod_ocp_if omap2xxx_l3_main__l4_core = { + .master = &omap2xxx_l3_main_hwmod, + .slave = &omap2xxx_l4_core_hwmod, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* MPU -> L3 interface */ +struct omap_hwmod_ocp_if omap2xxx_mpu__l3_main = { + .master = &omap2xxx_mpu_hwmod, + .slave = &omap2xxx_l3_main_hwmod, + .user = OCP_USER_MPU, +}; + +/* DSS -> l3 */ +struct omap_hwmod_ocp_if omap2xxx_dss__l3 = { + .master = &omap2xxx_dss_core_hwmod, + .slave = &omap2xxx_l3_main_hwmod, + .fw = { + .omap2 = { + .l3_perm_bit = OMAP2_L3_CORE_FW_CONNID_DSS, + .flags = OMAP_FIREWALL_L3, + }, + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4_CORE -> L4_WKUP interface */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__l4_wkup = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_l4_wkup_hwmod, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 CORE -> UART1 interface */ +struct omap_hwmod_ocp_if omap2_l4_core__uart1 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_uart1_hwmod, + .clk = "uart1_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 CORE -> UART2 interface */ +struct omap_hwmod_ocp_if omap2_l4_core__uart2 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_uart2_hwmod, + .clk = "uart2_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 PER -> UART3 interface */ +struct omap_hwmod_ocp_if omap2_l4_core__uart3 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_uart3_hwmod, + .clk = "uart3_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 core -> mcspi1 interface */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__mcspi1 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_mcspi1_hwmod, + .clk = "mcspi1_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 core -> mcspi2 interface */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__mcspi2 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_mcspi2_hwmod, + .clk = "mcspi2_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> timer2 */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__timer2 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_timer2_hwmod, + .clk = "gpt2_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> timer3 */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__timer3 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_timer3_hwmod, + .clk = "gpt3_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> timer4 */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__timer4 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_timer4_hwmod, + .clk = "gpt4_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> timer5 */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__timer5 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_timer5_hwmod, + .clk = "gpt5_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> timer6 */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__timer6 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_timer6_hwmod, + .clk = "gpt6_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> timer7 */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__timer7 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_timer7_hwmod, + .clk = "gpt7_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> timer8 */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__timer8 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_timer8_hwmod, + .clk = "gpt8_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> timer9 */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__timer9 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_timer9_hwmod, + .clk = "gpt9_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> timer10 */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__timer10 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_timer10_hwmod, + .clk = "gpt10_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> timer11 */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__timer11 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_timer11_hwmod, + .clk = "gpt11_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> timer12 */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__timer12 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_timer12_hwmod, + .clk = "gpt12_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> dss */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__dss = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_dss_core_hwmod, + .clk = "dss_ick", + .addr = omap2_dss_addrs, + .fw = { + .omap2 = { + .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_CORE_REGION, + .flags = OMAP_FIREWALL_L4, + }, + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> dss_dispc */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_dispc = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_dss_dispc_hwmod, + .clk = "dss_ick", + .addr = omap2_dss_dispc_addrs, + .fw = { + .omap2 = { + .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_DISPC_REGION, + .flags = OMAP_FIREWALL_L4, + }, + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> dss_rfbi */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_rfbi = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_dss_rfbi_hwmod, + .clk = "dss_ick", + .addr = omap2_dss_rfbi_addrs, + .fw = { + .omap2 = { + .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_CORE_REGION, + .flags = OMAP_FIREWALL_L4, + }, + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> dss_venc */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_venc = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_dss_venc_hwmod, + .clk = "dss_ick", + .addr = omap2_dss_venc_addrs, + .fw = { + .omap2 = { + .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_VENC_REGION, + .flags = OMAP_FIREWALL_L4, + }, + }, + .flags = OCPIF_SWSUP_IDLE, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> rng */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__rng = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_rng_hwmod, + .clk = "rng_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 core -> sham interface */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__sham = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_sham_hwmod, + .clk = "sha_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 core -> aes interface */ +struct omap_hwmod_ocp_if omap2xxx_l4_core__aes = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2xxx_aes_hwmod, + .clk = "aes_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c new file mode 100644 index 00000000000..8821b9d6bae --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c @@ -0,0 +1,882 @@ +/* + * omap_hwmod_2xxx_ipblock_data.c - common IP block data for OMAP2xxx + * + * Copyright (C) 2011 Nokia Corporation + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/platform_data/gpio-omap.h> +#include <linux/omap-dma.h> +#include <plat/dmtimer.h> +#include <linux/platform_data/spi-omap2-mcspi.h> + +#include "omap_hwmod.h" +#include "omap_hwmod_common_data.h" +#include "cm-regbits-24xx.h" +#include "prm-regbits-24xx.h" +#include "wd_timer.h" + +struct omap_hwmod_dma_info omap2xxx_dss_sdma_chs[] = { + { .name = "dispc", .dma_req = 5 }, + { .dma_req = -1, }, +}; + +/* + * 'dispc' class + * display controller + */ + +static struct omap_hwmod_class_sysconfig omap2_dispc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +struct omap_hwmod_class omap2_dispc_hwmod_class = { + .name = "dispc", + .sysc = &omap2_dispc_sysc, +}; + +/* OMAP2xxx Timer Common */ +static struct omap_hwmod_class_sysconfig omap2xxx_timer_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .clockact = CLOCKACT_TEST_ICLK, + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +struct omap_hwmod_class omap2xxx_timer_hwmod_class = { + .name = "timer", + .sysc = &omap2xxx_timer_sysc, +}; + +/* + * 'wd_timer' class + * 32-bit watchdog upward counter that generates a pulse on the reset pin on + * overflow condition + */ + +static struct omap_hwmod_class_sysconfig omap2xxx_wd_timer_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +struct omap_hwmod_class omap2xxx_wd_timer_hwmod_class = { + .name = "wd_timer", + .sysc = &omap2xxx_wd_timer_sysc, + .pre_shutdown = &omap2_wd_timer_disable, + .reset = &omap2_wd_timer_reset, +}; + +/* + * 'gpio' class + * general purpose io module + */ +static struct omap_hwmod_class_sysconfig omap2xxx_gpio_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +struct omap_hwmod_class omap2xxx_gpio_hwmod_class = { + .name = "gpio", + .sysc = &omap2xxx_gpio_sysc, + .rev = 0, +}; + +/* system dma */ +static struct omap_hwmod_class_sysconfig omap2xxx_dma_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x002c, + .syss_offs = 0x0028, + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE | + SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_EMUFREE | + SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), + .idlemodes = (MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +struct omap_hwmod_class omap2xxx_dma_hwmod_class = { + .name = "dma", + .sysc = &omap2xxx_dma_sysc, +}; + +/* + * 'mailbox' class + * mailbox module allowing communication between the on-chip processors + * using a queued mailbox-interrupt mechanism. + */ + +static struct omap_hwmod_class_sysconfig omap2xxx_mailbox_sysc = { + .rev_offs = 0x000, + .sysc_offs = 0x010, + .syss_offs = 0x014, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +struct omap_hwmod_class omap2xxx_mailbox_hwmod_class = { + .name = "mailbox", + .sysc = &omap2xxx_mailbox_sysc, +}; + +/* + * 'mcspi' class + * multichannel serial port interface (mcspi) / master/slave synchronous serial + * bus + */ + +static struct omap_hwmod_class_sysconfig omap2xxx_mcspi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +struct omap_hwmod_class omap2xxx_mcspi_class = { + .name = "mcspi", + .sysc = &omap2xxx_mcspi_sysc, + .rev = OMAP2_MCSPI_REV, +}; + +/* + * 'gpmc' class + * general purpose memory controller + */ + +static struct omap_hwmod_class_sysconfig omap2xxx_gpmc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap2xxx_gpmc_hwmod_class = { + .name = "gpmc", + .sysc = &omap2xxx_gpmc_sysc, +}; + +/* + * IP blocks + */ + +/* L3 */ +struct omap_hwmod omap2xxx_l3_main_hwmod = { + .name = "l3_main", + .class = &l3_hwmod_class, + .flags = HWMOD_NO_IDLEST, +}; + +/* L4 CORE */ +struct omap_hwmod omap2xxx_l4_core_hwmod = { + .name = "l4_core", + .class = &l4_hwmod_class, + .flags = HWMOD_NO_IDLEST, +}; + +/* L4 WKUP */ +struct omap_hwmod omap2xxx_l4_wkup_hwmod = { + .name = "l4_wkup", + .class = &l4_hwmod_class, + .flags = HWMOD_NO_IDLEST, +}; + +/* MPU */ +struct omap_hwmod omap2xxx_mpu_hwmod = { + .name = "mpu", + .class = &mpu_hwmod_class, + .main_clk = "mpu_ck", +}; + +/* IVA2 */ +struct omap_hwmod omap2xxx_iva_hwmod = { + .name = "iva", + .class = &iva_hwmod_class, +}; + +/* always-on timers dev attribute */ +static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = { + .timer_capability = OMAP_TIMER_ALWON, +}; + +/* pwm timers dev attribute */ +static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = { + .timer_capability = OMAP_TIMER_HAS_PWM, +}; + +/* timers with DSP interrupt dev attribute */ +static struct omap_timer_capability_dev_attr capability_dsp_dev_attr = { + .timer_capability = OMAP_TIMER_HAS_DSP_IRQ, +}; + +/* timer1 */ + +struct omap_hwmod omap2xxx_timer1_hwmod = { + .name = "timer1", + .main_clk = "gpt1_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_GPT1_SHIFT, + .module_offs = WKUP_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_GPT1_SHIFT, + }, + }, + .dev_attr = &capability_alwon_dev_attr, + .class = &omap2xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer2 */ + +struct omap_hwmod omap2xxx_timer2_hwmod = { + .name = "timer2", + .main_clk = "gpt2_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_GPT2_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_GPT2_SHIFT, + }, + }, + .class = &omap2xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer3 */ + +struct omap_hwmod omap2xxx_timer3_hwmod = { + .name = "timer3", + .main_clk = "gpt3_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_GPT3_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_GPT3_SHIFT, + }, + }, + .class = &omap2xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer4 */ + +struct omap_hwmod omap2xxx_timer4_hwmod = { + .name = "timer4", + .main_clk = "gpt4_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_GPT4_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_GPT4_SHIFT, + }, + }, + .class = &omap2xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer5 */ + +struct omap_hwmod omap2xxx_timer5_hwmod = { + .name = "timer5", + .main_clk = "gpt5_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_GPT5_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_GPT5_SHIFT, + }, + }, + .dev_attr = &capability_dsp_dev_attr, + .class = &omap2xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer6 */ + +struct omap_hwmod omap2xxx_timer6_hwmod = { + .name = "timer6", + .main_clk = "gpt6_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_GPT6_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_GPT6_SHIFT, + }, + }, + .dev_attr = &capability_dsp_dev_attr, + .class = &omap2xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer7 */ + +struct omap_hwmod omap2xxx_timer7_hwmod = { + .name = "timer7", + .main_clk = "gpt7_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_GPT7_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_GPT7_SHIFT, + }, + }, + .dev_attr = &capability_dsp_dev_attr, + .class = &omap2xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer8 */ + +struct omap_hwmod omap2xxx_timer8_hwmod = { + .name = "timer8", + .main_clk = "gpt8_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_GPT8_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_GPT8_SHIFT, + }, + }, + .dev_attr = &capability_dsp_dev_attr, + .class = &omap2xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer9 */ + +struct omap_hwmod omap2xxx_timer9_hwmod = { + .name = "timer9", + .main_clk = "gpt9_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_GPT9_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_GPT9_SHIFT, + }, + }, + .dev_attr = &capability_pwm_dev_attr, + .class = &omap2xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer10 */ + +struct omap_hwmod omap2xxx_timer10_hwmod = { + .name = "timer10", + .main_clk = "gpt10_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_GPT10_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_GPT10_SHIFT, + }, + }, + .dev_attr = &capability_pwm_dev_attr, + .class = &omap2xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer11 */ + +struct omap_hwmod omap2xxx_timer11_hwmod = { + .name = "timer11", + .main_clk = "gpt11_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_GPT11_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_GPT11_SHIFT, + }, + }, + .dev_attr = &capability_pwm_dev_attr, + .class = &omap2xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer12 */ + +struct omap_hwmod omap2xxx_timer12_hwmod = { + .name = "timer12", + .main_clk = "gpt12_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_GPT12_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_GPT12_SHIFT, + }, + }, + .dev_attr = &capability_pwm_dev_attr, + .class = &omap2xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* wd_timer2 */ +struct omap_hwmod omap2xxx_wd_timer2_hwmod = { + .name = "wd_timer2", + .class = &omap2xxx_wd_timer_hwmod_class, + .main_clk = "mpu_wdt_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_MPU_WDT_SHIFT, + .module_offs = WKUP_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_MPU_WDT_SHIFT, + }, + }, +}; + +/* UART1 */ + +struct omap_hwmod omap2xxx_uart1_hwmod = { + .name = "uart1", + .main_clk = "uart1_fck", + .flags = DEBUG_OMAP2UART1_FLAGS | HWMOD_SWSUP_SIDLE_ACT, + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_UART1_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_EN_UART1_SHIFT, + }, + }, + .class = &omap2_uart_class, +}; + +/* UART2 */ + +struct omap_hwmod omap2xxx_uart2_hwmod = { + .name = "uart2", + .main_clk = "uart2_fck", + .flags = DEBUG_OMAP2UART2_FLAGS | HWMOD_SWSUP_SIDLE_ACT, + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_UART2_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_EN_UART2_SHIFT, + }, + }, + .class = &omap2_uart_class, +}; + +/* UART3 */ + +struct omap_hwmod omap2xxx_uart3_hwmod = { + .name = "uart3", + .main_clk = "uart3_fck", + .flags = DEBUG_OMAP2UART3_FLAGS | HWMOD_SWSUP_SIDLE_ACT, + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 2, + .module_bit = OMAP24XX_EN_UART3_SHIFT, + .idlest_reg_id = 2, + .idlest_idle_bit = OMAP24XX_EN_UART3_SHIFT, + }, + }, + .class = &omap2_uart_class, +}; + +/* dss */ + +static struct omap_hwmod_opt_clk dss_opt_clks[] = { + /* + * The DSS HW needs all DSS clocks enabled during reset. The dss_core + * driver does not use these clocks. + */ + { .role = "tv_clk", .clk = "dss_54m_fck" }, + { .role = "sys_clk", .clk = "dss2_fck" }, +}; + +struct omap_hwmod omap2xxx_dss_core_hwmod = { + .name = "dss_core", + .class = &omap2_dss_hwmod_class, + .main_clk = "dss1_fck", /* instead of dss_fck */ + .sdma_reqs = omap2xxx_dss_sdma_chs, + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_DSS1_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT, + }, + }, + .opt_clks = dss_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), + .flags = HWMOD_NO_IDLEST | HWMOD_CONTROL_OPT_CLKS_IN_RESET, +}; + +struct omap_hwmod omap2xxx_dss_dispc_hwmod = { + .name = "dss_dispc", + .class = &omap2_dispc_hwmod_class, + .mpu_irqs = omap2_dispc_irqs, + .main_clk = "dss1_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_DSS1_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT, + }, + }, + .flags = HWMOD_NO_IDLEST, + .dev_attr = &omap2_3_dss_dispc_dev_attr, +}; + +static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = { + { .role = "ick", .clk = "dss_ick" }, +}; + +struct omap_hwmod omap2xxx_dss_rfbi_hwmod = { + .name = "dss_rfbi", + .class = &omap2_rfbi_hwmod_class, + .main_clk = "dss1_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_DSS1_SHIFT, + .module_offs = CORE_MOD, + }, + }, + .opt_clks = dss_rfbi_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), + .flags = HWMOD_NO_IDLEST, +}; + +struct omap_hwmod omap2xxx_dss_venc_hwmod = { + .name = "dss_venc", + .class = &omap2_venc_hwmod_class, + .main_clk = "dss_54m_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_DSS1_SHIFT, + .module_offs = CORE_MOD, + }, + }, + .flags = HWMOD_NO_IDLEST, +}; + +/* gpio dev_attr */ +struct omap_gpio_dev_attr omap2xxx_gpio_dev_attr = { + .bank_width = 32, + .dbck_flag = false, +}; + +/* gpio1 */ +struct omap_hwmod omap2xxx_gpio1_hwmod = { + .name = "gpio1", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "gpios_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_GPIOS_SHIFT, + .module_offs = WKUP_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT, + }, + }, + .class = &omap2xxx_gpio_hwmod_class, + .dev_attr = &omap2xxx_gpio_dev_attr, +}; + +/* gpio2 */ +struct omap_hwmod omap2xxx_gpio2_hwmod = { + .name = "gpio2", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "gpios_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_GPIOS_SHIFT, + .module_offs = WKUP_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT, + }, + }, + .class = &omap2xxx_gpio_hwmod_class, + .dev_attr = &omap2xxx_gpio_dev_attr, +}; + +/* gpio3 */ +struct omap_hwmod omap2xxx_gpio3_hwmod = { + .name = "gpio3", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "gpios_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_GPIOS_SHIFT, + .module_offs = WKUP_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT, + }, + }, + .class = &omap2xxx_gpio_hwmod_class, + .dev_attr = &omap2xxx_gpio_dev_attr, +}; + +/* gpio4 */ +struct omap_hwmod omap2xxx_gpio4_hwmod = { + .name = "gpio4", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "gpios_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_GPIOS_SHIFT, + .module_offs = WKUP_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT, + }, + }, + .class = &omap2xxx_gpio_hwmod_class, + .dev_attr = &omap2xxx_gpio_dev_attr, +}; + +/* mcspi1 */ +static struct omap2_mcspi_dev_attr omap_mcspi1_dev_attr = { + .num_chipselect = 4, +}; + +struct omap_hwmod omap2xxx_mcspi1_hwmod = { + .name = "mcspi1", + .main_clk = "mcspi1_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_MCSPI1_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_MCSPI1_SHIFT, + }, + }, + .class = &omap2xxx_mcspi_class, + .dev_attr = &omap_mcspi1_dev_attr, +}; + +/* mcspi2 */ +static struct omap2_mcspi_dev_attr omap_mcspi2_dev_attr = { + .num_chipselect = 2, +}; + +struct omap_hwmod omap2xxx_mcspi2_hwmod = { + .name = "mcspi2", + .main_clk = "mcspi2_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_MCSPI2_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_MCSPI2_SHIFT, + }, + }, + .class = &omap2xxx_mcspi_class, + .dev_attr = &omap_mcspi2_dev_attr, +}; + +static struct omap_hwmod_class omap2xxx_counter_hwmod_class = { + .name = "counter", +}; + +struct omap_hwmod omap2xxx_counter_32k_hwmod = { + .name = "counter_32k", + .main_clk = "func_32k_ck", + .prcm = { + .omap2 = { + .module_offs = WKUP_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP24XX_ST_32KSYNC_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_32KSYNC_SHIFT, + }, + }, + .class = &omap2xxx_counter_hwmod_class, +}; + +/* gpmc */ +struct omap_hwmod omap2xxx_gpmc_hwmod = { + .name = "gpmc", + .class = &omap2xxx_gpmc_hwmod_class, + .main_clk = "gpmc_fck", + /* + * XXX HWMOD_INIT_NO_RESET should not be needed for this IP + * block. It is not being added due to any known bugs with + * resetting the GPMC IP block, but rather because any timings + * set by the bootloader are not being correctly programmed by + * the kernel from the board file or DT data. + * HWMOD_INIT_NO_RESET should be removed ASAP. + */ + .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET | + HWMOD_NO_IDLEST), + .prcm = { + .omap2 = { + .prcm_reg_id = 3, + .module_bit = OMAP24XX_EN_GPMC_MASK, + .module_offs = CORE_MOD, + }, + }, +}; + +/* RNG */ + +static struct omap_hwmod_class_sysconfig omap2_rng_sysc = { + .rev_offs = 0x3c, + .sysc_offs = 0x40, + .syss_offs = 0x44, + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap2_rng_hwmod_class = { + .name = "rng", + .sysc = &omap2_rng_sysc, +}; + +struct omap_hwmod omap2xxx_rng_hwmod = { + .name = "rng", + .main_clk = "l4_ck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 4, + .module_bit = OMAP24XX_EN_RNG_SHIFT, + .idlest_reg_id = 4, + .idlest_idle_bit = OMAP24XX_ST_RNG_SHIFT, + }, + }, + /* + * XXX The first read from the SYSSTATUS register of the RNG + * after the SYSCONFIG SOFTRESET bit is set triggers an + * imprecise external abort. It's unclear why this happens. + * Until this is analyzed, skip the IP block reset. + */ + .flags = HWMOD_INIT_NO_RESET, + .class = &omap2_rng_hwmod_class, +}; + +/* SHAM */ + +static struct omap_hwmod_class_sysconfig omap2_sham_sysc = { + .rev_offs = 0x5c, + .sysc_offs = 0x60, + .syss_offs = 0x64, + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap2xxx_sham_class = { + .name = "sham", + .sysc = &omap2_sham_sysc, +}; + +struct omap_hwmod omap2xxx_sham_hwmod = { + .name = "sham", + .main_clk = "l4_ck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 4, + .module_bit = OMAP24XX_EN_SHA_SHIFT, + .idlest_reg_id = 4, + .idlest_idle_bit = OMAP24XX_ST_SHA_SHIFT, + }, + }, + .class = &omap2xxx_sham_class, +}; + +/* AES */ + +static struct omap_hwmod_class_sysconfig omap2_aes_sysc = { + .rev_offs = 0x44, + .sysc_offs = 0x48, + .syss_offs = 0x4c, + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap2xxx_aes_class = { + .name = "aes", + .sysc = &omap2_aes_sysc, +}; + +struct omap_hwmod omap2xxx_aes_hwmod = { + .name = "aes", + .main_clk = "l4_ck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 4, + .module_bit = OMAP24XX_EN_AES_SHIFT, + .idlest_reg_id = 4, + .idlest_idle_bit = OMAP24XX_ST_AES_SHIFT, + }, + }, + .class = &omap2xxx_aes_class, +}; diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h new file mode 100644 index 00000000000..130332c0534 --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h @@ -0,0 +1,163 @@ +/* + * + * Copyright (C) 2013 Texas Instruments Incorporated + * + * Data common for AM335x and AM43x + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_OMAP_HWMOD_33XX_43XX_COMMON_DATA_H +#define __ARCH_ARM_MACH_OMAP2_OMAP_HWMOD_33XX_43XX_COMMON_DATA_H + +extern struct omap_hwmod_ocp_if am33xx_mpu__l3_main; +extern struct omap_hwmod_ocp_if am33xx_l3_main__l3_s; +extern struct omap_hwmod_ocp_if am33xx_l3_s__l4_ls; +extern struct omap_hwmod_ocp_if am33xx_l3_s__l4_wkup; +extern struct omap_hwmod_ocp_if am33xx_l3_main__l3_instr; +extern struct omap_hwmod_ocp_if am33xx_mpu__prcm; +extern struct omap_hwmod_ocp_if am33xx_l3_s__l3_main; +extern struct omap_hwmod_ocp_if am33xx_pruss__l3_main; +extern struct omap_hwmod_ocp_if am33xx_gfx__l3_main; +extern struct omap_hwmod_ocp_if am33xx_l3_main__gfx; +extern struct omap_hwmod_ocp_if am33xx_l4_wkup__rtc; +extern struct omap_hwmod_ocp_if am33xx_l4_per__dcan0; +extern struct omap_hwmod_ocp_if am33xx_l4_per__dcan1; +extern struct omap_hwmod_ocp_if am33xx_l4_per__gpio1; +extern struct omap_hwmod_ocp_if am33xx_l4_per__gpio2; +extern struct omap_hwmod_ocp_if am33xx_l4_per__gpio3; +extern struct omap_hwmod_ocp_if am33xx_cpgmac0__mdio; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__elm; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss0; +extern struct omap_hwmod_ocp_if am33xx_epwmss0__ecap0; +extern struct omap_hwmod_ocp_if am33xx_epwmss0__eqep0; +extern struct omap_hwmod_ocp_if am33xx_epwmss0__ehrpwm0; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss1; +extern struct omap_hwmod_ocp_if am33xx_epwmss1__ecap1; +extern struct omap_hwmod_ocp_if am33xx_epwmss1__eqep1; +extern struct omap_hwmod_ocp_if am33xx_epwmss1__ehrpwm1; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss2; +extern struct omap_hwmod_ocp_if am33xx_epwmss2__ecap2; +extern struct omap_hwmod_ocp_if am33xx_epwmss2__eqep2; +extern struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2; +extern struct omap_hwmod_ocp_if am33xx_l3_s__gpmc; +extern struct omap_hwmod_ocp_if am33xx_l4_per__i2c2; +extern struct omap_hwmod_ocp_if am33xx_l4_per__i2c3; +extern struct omap_hwmod_ocp_if am33xx_l4_per__mailbox; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__spinlock; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp0; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp1; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__mmc0; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__mmc1; +extern struct omap_hwmod_ocp_if am33xx_l3_s__mmc2; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi0; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi1; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer2; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer3; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer4; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer5; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer6; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer7; +extern struct omap_hwmod_ocp_if am33xx_l3_main__tpcc; +extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc0; +extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc1; +extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc2; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart2; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart3; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart4; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart5; +extern struct omap_hwmod_ocp_if am33xx_l4_ls__uart6; +extern struct omap_hwmod_ocp_if am33xx_l3_main__ocmc; +extern struct omap_hwmod_ocp_if am33xx_l3_main__sha0; +extern struct omap_hwmod_ocp_if am33xx_l3_main__aes0; + +extern struct omap_hwmod am33xx_l3_main_hwmod; +extern struct omap_hwmod am33xx_l3_s_hwmod; +extern struct omap_hwmod am33xx_l3_instr_hwmod; +extern struct omap_hwmod am33xx_l4_ls_hwmod; +extern struct omap_hwmod am33xx_l4_wkup_hwmod; +extern struct omap_hwmod am33xx_mpu_hwmod; +extern struct omap_hwmod am33xx_pruss_hwmod; +extern struct omap_hwmod am33xx_gfx_hwmod; +extern struct omap_hwmod am33xx_prcm_hwmod; +extern struct omap_hwmod am33xx_aes0_hwmod; +extern struct omap_hwmod am33xx_sha0_hwmod; +extern struct omap_hwmod am33xx_ocmcram_hwmod; +extern struct omap_hwmod am33xx_smartreflex0_hwmod; +extern struct omap_hwmod am33xx_smartreflex1_hwmod; +extern struct omap_hwmod am33xx_cpgmac0_hwmod; +extern struct omap_hwmod am33xx_mdio_hwmod; +extern struct omap_hwmod am33xx_dcan0_hwmod; +extern struct omap_hwmod am33xx_dcan1_hwmod; +extern struct omap_hwmod am33xx_elm_hwmod; +extern struct omap_hwmod am33xx_epwmss0_hwmod; +extern struct omap_hwmod am33xx_ecap0_hwmod; +extern struct omap_hwmod am33xx_eqep0_hwmod; +extern struct omap_hwmod am33xx_ehrpwm0_hwmod; +extern struct omap_hwmod am33xx_epwmss1_hwmod; +extern struct omap_hwmod am33xx_ecap1_hwmod; +extern struct omap_hwmod am33xx_eqep1_hwmod; +extern struct omap_hwmod am33xx_ehrpwm1_hwmod; +extern struct omap_hwmod am33xx_epwmss2_hwmod; +extern struct omap_hwmod am33xx_ecap2_hwmod; +extern struct omap_hwmod am33xx_eqep2_hwmod; +extern struct omap_hwmod am33xx_ehrpwm2_hwmod; +extern struct omap_hwmod am33xx_gpio1_hwmod; +extern struct omap_hwmod am33xx_gpio2_hwmod; +extern struct omap_hwmod am33xx_gpio3_hwmod; +extern struct omap_hwmod am33xx_gpmc_hwmod; +extern struct omap_hwmod am33xx_i2c1_hwmod; +extern struct omap_hwmod am33xx_i2c2_hwmod; +extern struct omap_hwmod am33xx_i2c3_hwmod; +extern struct omap_hwmod am33xx_mailbox_hwmod; +extern struct omap_hwmod am33xx_mcasp0_hwmod; +extern struct omap_hwmod am33xx_mcasp1_hwmod; +extern struct omap_hwmod am33xx_mmc0_hwmod; +extern struct omap_hwmod am33xx_mmc1_hwmod; +extern struct omap_hwmod am33xx_mmc2_hwmod; +extern struct omap_hwmod am33xx_rtc_hwmod; +extern struct omap_hwmod am33xx_spi0_hwmod; +extern struct omap_hwmod am33xx_spi1_hwmod; +extern struct omap_hwmod am33xx_spinlock_hwmod; +extern struct omap_hwmod am33xx_timer1_hwmod; +extern struct omap_hwmod am33xx_timer2_hwmod; +extern struct omap_hwmod am33xx_timer3_hwmod; +extern struct omap_hwmod am33xx_timer4_hwmod; +extern struct omap_hwmod am33xx_timer5_hwmod; +extern struct omap_hwmod am33xx_timer6_hwmod; +extern struct omap_hwmod am33xx_timer7_hwmod; +extern struct omap_hwmod am33xx_tpcc_hwmod; +extern struct omap_hwmod am33xx_tptc0_hwmod; +extern struct omap_hwmod am33xx_tptc1_hwmod; +extern struct omap_hwmod am33xx_tptc2_hwmod; +extern struct omap_hwmod am33xx_uart1_hwmod; +extern struct omap_hwmod am33xx_uart2_hwmod; +extern struct omap_hwmod am33xx_uart3_hwmod; +extern struct omap_hwmod am33xx_uart4_hwmod; +extern struct omap_hwmod am33xx_uart5_hwmod; +extern struct omap_hwmod am33xx_uart6_hwmod; +extern struct omap_hwmod am33xx_wd_timer1_hwmod; + +extern struct omap_hwmod_class am33xx_l4_hwmod_class; +extern struct omap_hwmod_class am33xx_wkup_m3_hwmod_class; +extern struct omap_hwmod_class am33xx_control_hwmod_class; +extern struct omap_hwmod_class am33xx_gpio_hwmod_class; +extern struct omap_hwmod_class am33xx_timer_hwmod_class; +extern struct omap_hwmod_class am33xx_epwmss_hwmod_class; +extern struct omap_hwmod_class am33xx_ehrpwm_hwmod_class; +extern struct omap_hwmod_class am33xx_spi_hwmod_class; + +extern struct omap_gpio_dev_attr gpio_dev_attr; +extern struct omap2_mcspi_dev_attr mcspi_attrib; + +void omap_hwmod_am33xx_reg(void); +void omap_hwmod_am43xx_reg(void); + +#endif diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c new file mode 100644 index 00000000000..e2db378b849 --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c @@ -0,0 +1,643 @@ +/* + * + * Copyright (C) 2013 Texas Instruments Incorporated + * + * Interconnects common for AM335x and AM43x + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/sizes.h> +#include "omap_hwmod.h" +#include "omap_hwmod_33xx_43xx_common_data.h" + +/* mpu -> l3 main */ +struct omap_hwmod_ocp_if am33xx_mpu__l3_main = { + .master = &am33xx_mpu_hwmod, + .slave = &am33xx_l3_main_hwmod, + .clk = "dpll_mpu_m2_ck", + .user = OCP_USER_MPU, +}; + +/* l3 main -> l3 s */ +struct omap_hwmod_ocp_if am33xx_l3_main__l3_s = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_l3_s_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3 s -> l4 per/ls */ +struct omap_hwmod_ocp_if am33xx_l3_s__l4_ls = { + .master = &am33xx_l3_s_hwmod, + .slave = &am33xx_l4_ls_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3 s -> l4 wkup */ +struct omap_hwmod_ocp_if am33xx_l3_s__l4_wkup = { + .master = &am33xx_l3_s_hwmod, + .slave = &am33xx_l4_wkup_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3 main -> l3 instr */ +struct omap_hwmod_ocp_if am33xx_l3_main__l3_instr = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_l3_instr_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* mpu -> prcm */ +struct omap_hwmod_ocp_if am33xx_mpu__prcm = { + .master = &am33xx_mpu_hwmod, + .slave = &am33xx_prcm_hwmod, + .clk = "dpll_mpu_m2_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3 s -> l3 main*/ +struct omap_hwmod_ocp_if am33xx_l3_s__l3_main = { + .master = &am33xx_l3_s_hwmod, + .slave = &am33xx_l3_main_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* pru-icss -> l3 main */ +struct omap_hwmod_ocp_if am33xx_pruss__l3_main = { + .master = &am33xx_pruss_hwmod, + .slave = &am33xx_l3_main_hwmod, + .clk = "l3_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* gfx -> l3 main */ +struct omap_hwmod_ocp_if am33xx_gfx__l3_main = { + .master = &am33xx_gfx_hwmod, + .slave = &am33xx_l3_main_hwmod, + .clk = "dpll_core_m4_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3 main -> gfx */ +struct omap_hwmod_ocp_if am33xx_l3_main__gfx = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_gfx_hwmod, + .clk = "dpll_core_m4_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 wkup -> rtc */ +struct omap_hwmod_ocp_if am33xx_l4_wkup__rtc = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_rtc_hwmod, + .clk = "clkdiv32k_ick", + .user = OCP_USER_MPU, +}; + +/* l4 per/ls -> DCAN0 */ +struct omap_hwmod_ocp_if am33xx_l4_per__dcan0 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_dcan0_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 per/ls -> DCAN1 */ +struct omap_hwmod_ocp_if am33xx_l4_per__dcan1 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_dcan1_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 per/ls -> GPIO2 */ +struct omap_hwmod_ocp_if am33xx_l4_per__gpio1 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_gpio1_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 per/ls -> gpio3 */ +struct omap_hwmod_ocp_if am33xx_l4_per__gpio2 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_gpio2_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 per/ls -> gpio4 */ +struct omap_hwmod_ocp_if am33xx_l4_per__gpio3 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_gpio3_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +struct omap_hwmod_ocp_if am33xx_cpgmac0__mdio = { + .master = &am33xx_cpgmac0_hwmod, + .slave = &am33xx_mdio_hwmod, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space am33xx_elm_addr_space[] = { + { + .pa_start = 0x48080000, + .pa_end = 0x48080000 + SZ_8K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l4_ls__elm = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_elm_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_elm_addr_space, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space am33xx_epwmss0_addr_space[] = { + { + .pa_start = 0x48300000, + .pa_end = 0x48300000 + SZ_16 - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss0 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_epwmss0_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_epwmss0_addr_space, + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_epwmss0__ecap0 = { + .master = &am33xx_epwmss0_hwmod, + .slave = &am33xx_ecap0_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_epwmss0__eqep0 = { + .master = &am33xx_epwmss0_hwmod, + .slave = &am33xx_eqep0_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_epwmss0__ehrpwm0 = { + .master = &am33xx_epwmss0_hwmod, + .slave = &am33xx_ehrpwm0_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + + +static struct omap_hwmod_addr_space am33xx_epwmss1_addr_space[] = { + { + .pa_start = 0x48302000, + .pa_end = 0x48302000 + SZ_16 - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss1 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_epwmss1_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_epwmss1_addr_space, + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_epwmss1__ecap1 = { + .master = &am33xx_epwmss1_hwmod, + .slave = &am33xx_ecap1_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_epwmss1__eqep1 = { + .master = &am33xx_epwmss1_hwmod, + .slave = &am33xx_eqep1_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_epwmss1__ehrpwm1 = { + .master = &am33xx_epwmss1_hwmod, + .slave = &am33xx_ehrpwm1_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space am33xx_epwmss2_addr_space[] = { + { + .pa_start = 0x48304000, + .pa_end = 0x48304000 + SZ_16 - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss2 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_epwmss2_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_epwmss2_addr_space, + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_epwmss2__ecap2 = { + .master = &am33xx_epwmss2_hwmod, + .slave = &am33xx_ecap2_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_epwmss2__eqep2 = { + .master = &am33xx_epwmss2_hwmod, + .slave = &am33xx_eqep2_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2 = { + .master = &am33xx_epwmss2_hwmod, + .slave = &am33xx_ehrpwm2_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l3s cfg -> gpmc */ +static struct omap_hwmod_addr_space am33xx_gpmc_addr_space[] = { + { + .pa_start = 0x50000000, + .pa_end = 0x50000000 + SZ_8K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l3_s__gpmc = { + .master = &am33xx_l3_s_hwmod, + .slave = &am33xx_gpmc_hwmod, + .clk = "l3s_gclk", + .addr = am33xx_gpmc_addr_space, + .user = OCP_USER_MPU, +}; + +/* i2c2 */ +struct omap_hwmod_ocp_if am33xx_l4_per__i2c2 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_i2c2_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if am33xx_l4_per__i2c3 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_i2c3_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space am33xx_mailbox_addrs[] = { + { + .pa_start = 0x480C8000, + .pa_end = 0x480C8000 + (SZ_4K - 1), + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4 ls -> mailbox */ +struct omap_hwmod_ocp_if am33xx_l4_per__mailbox = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_mailbox_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_mailbox_addrs, + .user = OCP_USER_MPU, +}; + +/* l4 ls -> spinlock */ +struct omap_hwmod_ocp_if am33xx_l4_ls__spinlock = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_spinlock_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 ls -> mcasp0 */ +static struct omap_hwmod_addr_space am33xx_mcasp0_addr_space[] = { + { + .pa_start = 0x48038000, + .pa_end = 0x48038000 + SZ_8K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp0 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_mcasp0_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_mcasp0_addr_space, + .user = OCP_USER_MPU, +}; + +/* l4 ls -> mcasp1 */ +static struct omap_hwmod_addr_space am33xx_mcasp1_addr_space[] = { + { + .pa_start = 0x4803C000, + .pa_end = 0x4803C000 + SZ_8K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l4_ls__mcasp1 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_mcasp1_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_mcasp1_addr_space, + .user = OCP_USER_MPU, +}; + +/* l4 ls -> mmc0 */ +static struct omap_hwmod_addr_space am33xx_mmc0_addr_space[] = { + { + .pa_start = 0x48060100, + .pa_end = 0x48060100 + SZ_4K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l4_ls__mmc0 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_mmc0_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_mmc0_addr_space, + .user = OCP_USER_MPU, +}; + +/* l4 ls -> mmc1 */ +static struct omap_hwmod_addr_space am33xx_mmc1_addr_space[] = { + { + .pa_start = 0x481d8100, + .pa_end = 0x481d8100 + SZ_4K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l4_ls__mmc1 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_mmc1_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_mmc1_addr_space, + .user = OCP_USER_MPU, +}; + +/* l3 s -> mmc2 */ +static struct omap_hwmod_addr_space am33xx_mmc2_addr_space[] = { + { + .pa_start = 0x47810100, + .pa_end = 0x47810100 + SZ_64K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l3_s__mmc2 = { + .master = &am33xx_l3_s_hwmod, + .slave = &am33xx_mmc2_hwmod, + .clk = "l3s_gclk", + .addr = am33xx_mmc2_addr_space, + .user = OCP_USER_MPU, +}; + +/* l4 ls -> mcspi0 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi0 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_spi0_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 ls -> mcspi1 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi1 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_spi1_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 per -> timer2 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__timer2 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_timer2_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 per -> timer3 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__timer3 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_timer3_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 per -> timer4 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__timer4 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_timer4_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 per -> timer5 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__timer5 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_timer5_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 per -> timer6 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__timer6 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_timer6_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 per -> timer7 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__timer7 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_timer7_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l3 main -> tpcc */ +struct omap_hwmod_ocp_if am33xx_l3_main__tpcc = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_tpcc_hwmod, + .clk = "l3_gclk", + .user = OCP_USER_MPU, +}; + +/* l3 main -> tpcc0 */ +static struct omap_hwmod_addr_space am33xx_tptc0_addr_space[] = { + { + .pa_start = 0x49800000, + .pa_end = 0x49800000 + SZ_8K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l3_main__tptc0 = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_tptc0_hwmod, + .clk = "l3_gclk", + .addr = am33xx_tptc0_addr_space, + .user = OCP_USER_MPU, +}; + +/* l3 main -> tpcc1 */ +static struct omap_hwmod_addr_space am33xx_tptc1_addr_space[] = { + { + .pa_start = 0x49900000, + .pa_end = 0x49900000 + SZ_8K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l3_main__tptc1 = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_tptc1_hwmod, + .clk = "l3_gclk", + .addr = am33xx_tptc1_addr_space, + .user = OCP_USER_MPU, +}; + +/* l3 main -> tpcc2 */ +static struct omap_hwmod_addr_space am33xx_tptc2_addr_space[] = { + { + .pa_start = 0x49a00000, + .pa_end = 0x49a00000 + SZ_8K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l3_main__tptc2 = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_tptc2_hwmod, + .clk = "l3_gclk", + .addr = am33xx_tptc2_addr_space, + .user = OCP_USER_MPU, +}; + +/* l4 ls -> uart2 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__uart2 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_uart2_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 ls -> uart3 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__uart3 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_uart3_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 ls -> uart4 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__uart4 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_uart4_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 ls -> uart5 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__uart5 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_uart5_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l4 ls -> uart6 */ +struct omap_hwmod_ocp_if am33xx_l4_ls__uart6 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_uart6_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +/* l3 main -> ocmc */ +struct omap_hwmod_ocp_if am33xx_l3_main__ocmc = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_ocmcram_hwmod, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3 main -> sha0 HIB2 */ +static struct omap_hwmod_addr_space am33xx_sha0_addrs[] = { + { + .pa_start = 0x53100000, + .pa_end = 0x53100000 + SZ_512 - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l3_main__sha0 = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_sha0_hwmod, + .clk = "sha0_fck", + .addr = am33xx_sha0_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3 main -> AES0 HIB2 */ +static struct omap_hwmod_addr_space am33xx_aes0_addrs[] = { + { + .pa_start = 0x53500000, + .pa_end = 0x53500000 + SZ_1M - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +struct omap_hwmod_ocp_if am33xx_l3_main__aes0 = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_aes0_hwmod, + .clk = "aes0_fck", + .addr = am33xx_aes0_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c new file mode 100644 index 00000000000..a579b89ce9b --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c @@ -0,0 +1,1470 @@ +/* + * + * Copyright (C) 2013 Texas Instruments Incorporated + * + * Hwmod common for AM335x and AM43x + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/platform_data/gpio-omap.h> +#include <linux/platform_data/spi-omap2-mcspi.h> +#include "omap_hwmod.h" +#include "i2c.h" +#include "mmc.h" +#include "wd_timer.h" +#include "cm33xx.h" +#include "prm33xx.h" +#include "omap_hwmod_33xx_43xx_common_data.h" +#include "prcm43xx.h" +#include "common.h" + +#define CLKCTRL(oh, clkctrl) ((oh).prcm.omap4.clkctrl_offs = (clkctrl)) +#define RSTCTRL(oh, rstctrl) ((oh).prcm.omap4.rstctrl_offs = (rstctrl)) +#define RSTST(oh, rstst) ((oh).prcm.omap4.rstst_offs = (rstst)) + +/* + * 'l3' class + * instance(s): l3_main, l3_s, l3_instr + */ +static struct omap_hwmod_class am33xx_l3_hwmod_class = { + .name = "l3", +}; + +struct omap_hwmod am33xx_l3_main_hwmod = { + .name = "l3_main", + .class = &am33xx_l3_hwmod_class, + .clkdm_name = "l3_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* l3_s */ +struct omap_hwmod am33xx_l3_s_hwmod = { + .name = "l3_s", + .class = &am33xx_l3_hwmod_class, + .clkdm_name = "l3s_clkdm", +}; + +/* l3_instr */ +struct omap_hwmod am33xx_l3_instr_hwmod = { + .name = "l3_instr", + .class = &am33xx_l3_hwmod_class, + .clkdm_name = "l3_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'l4' class + * instance(s): l4_ls, l4_hs, l4_wkup, l4_fw + */ +struct omap_hwmod_class am33xx_l4_hwmod_class = { + .name = "l4", +}; + +/* l4_ls */ +struct omap_hwmod am33xx_l4_ls_hwmod = { + .name = "l4_ls", + .class = &am33xx_l4_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* l4_wkup */ +struct omap_hwmod am33xx_l4_wkup_hwmod = { + .name = "l4_wkup", + .class = &am33xx_l4_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'mpu' class + */ +static struct omap_hwmod_class am33xx_mpu_hwmod_class = { + .name = "mpu", +}; + +struct omap_hwmod am33xx_mpu_hwmod = { + .name = "mpu", + .class = &am33xx_mpu_hwmod_class, + .clkdm_name = "mpu_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "dpll_mpu_m2_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'wakeup m3' class + * Wakeup controller sub-system under wakeup domain + */ +struct omap_hwmod_class am33xx_wkup_m3_hwmod_class = { + .name = "wkup_m3", +}; + +/* + * 'pru-icss' class + * Programmable Real-Time Unit and Industrial Communication Subsystem + */ +static struct omap_hwmod_class am33xx_pruss_hwmod_class = { + .name = "pruss", +}; + +static struct omap_hwmod_rst_info am33xx_pruss_resets[] = { + { .name = "pruss", .rst_shift = 1 }, +}; + +/* pru-icss */ +/* Pseudo hwmod for reset control purpose only */ +struct omap_hwmod am33xx_pruss_hwmod = { + .name = "pruss", + .class = &am33xx_pruss_hwmod_class, + .clkdm_name = "pruss_ocp_clkdm", + .main_clk = "pruss_ocp_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .rst_lines = am33xx_pruss_resets, + .rst_lines_cnt = ARRAY_SIZE(am33xx_pruss_resets), +}; + +/* gfx */ +/* Pseudo hwmod for reset control purpose only */ +static struct omap_hwmod_class am33xx_gfx_hwmod_class = { + .name = "gfx", +}; + +static struct omap_hwmod_rst_info am33xx_gfx_resets[] = { + { .name = "gfx", .rst_shift = 0, .st_shift = 0}, +}; + +struct omap_hwmod am33xx_gfx_hwmod = { + .name = "gfx", + .class = &am33xx_gfx_hwmod_class, + .clkdm_name = "gfx_l3_clkdm", + .main_clk = "gfx_fck_div_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .rst_lines = am33xx_gfx_resets, + .rst_lines_cnt = ARRAY_SIZE(am33xx_gfx_resets), +}; + +/* + * 'prcm' class + * power and reset manager (whole prcm infrastructure) + */ +static struct omap_hwmod_class am33xx_prcm_hwmod_class = { + .name = "prcm", +}; + +/* prcm */ +struct omap_hwmod am33xx_prcm_hwmod = { + .name = "prcm", + .class = &am33xx_prcm_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", +}; + +/* + * 'aes0' class + */ +static struct omap_hwmod_class_sysconfig am33xx_aes0_sysc = { + .rev_offs = 0x80, + .sysc_offs = 0x84, + .syss_offs = 0x88, + .sysc_flags = SYSS_HAS_RESET_STATUS, +}; + +static struct omap_hwmod_class am33xx_aes0_hwmod_class = { + .name = "aes0", + .sysc = &am33xx_aes0_sysc, +}; + +struct omap_hwmod am33xx_aes0_hwmod = { + .name = "aes", + .class = &am33xx_aes0_hwmod_class, + .clkdm_name = "l3_clkdm", + .main_clk = "aes0_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* sha0 HIB2 (the 'P' (public) device) */ +static struct omap_hwmod_class_sysconfig am33xx_sha0_sysc = { + .rev_offs = 0x100, + .sysc_offs = 0x110, + .syss_offs = 0x114, + .sysc_flags = SYSS_HAS_RESET_STATUS, +}; + +static struct omap_hwmod_class am33xx_sha0_hwmod_class = { + .name = "sha0", + .sysc = &am33xx_sha0_sysc, +}; + +struct omap_hwmod am33xx_sha0_hwmod = { + .name = "sham", + .class = &am33xx_sha0_hwmod_class, + .clkdm_name = "l3_clkdm", + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* ocmcram */ +static struct omap_hwmod_class am33xx_ocmcram_hwmod_class = { + .name = "ocmcram", +}; + +struct omap_hwmod am33xx_ocmcram_hwmod = { + .name = "ocmcram", + .class = &am33xx_ocmcram_hwmod_class, + .clkdm_name = "l3_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* 'smartreflex' class */ +static struct omap_hwmod_class am33xx_smartreflex_hwmod_class = { + .name = "smartreflex", +}; + +/* smartreflex0 */ +struct omap_hwmod am33xx_smartreflex0_hwmod = { + .name = "smartreflex0", + .class = &am33xx_smartreflex_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .main_clk = "smartreflex0_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* smartreflex1 */ +struct omap_hwmod am33xx_smartreflex1_hwmod = { + .name = "smartreflex1", + .class = &am33xx_smartreflex_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .main_clk = "smartreflex1_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'control' module class + */ +struct omap_hwmod_class am33xx_control_hwmod_class = { + .name = "control", +}; + +/* + * 'cpgmac' class + * cpsw/cpgmac sub system + */ +static struct omap_hwmod_class_sysconfig am33xx_cpgmac_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x8, + .syss_offs = 0x4, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | MSTANDBY_FORCE | + MSTANDBY_NO), + .sysc_fields = &omap_hwmod_sysc_type3, +}; + +static struct omap_hwmod_class am33xx_cpgmac0_hwmod_class = { + .name = "cpgmac0", + .sysc = &am33xx_cpgmac_sysc, +}; + +struct omap_hwmod am33xx_cpgmac0_hwmod = { + .name = "cpgmac0", + .class = &am33xx_cpgmac0_hwmod_class, + .clkdm_name = "cpsw_125mhz_clkdm", + .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY), + .main_clk = "cpsw_125mhz_gclk", + .mpu_rt_idx = 1, + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * mdio class + */ +static struct omap_hwmod_class am33xx_mdio_hwmod_class = { + .name = "davinci_mdio", +}; + +struct omap_hwmod am33xx_mdio_hwmod = { + .name = "davinci_mdio", + .class = &am33xx_mdio_hwmod_class, + .clkdm_name = "cpsw_125mhz_clkdm", + .main_clk = "cpsw_125mhz_gclk", +}; + +/* + * dcan class + */ +static struct omap_hwmod_class am33xx_dcan_hwmod_class = { + .name = "d_can", +}; + +/* dcan0 */ +struct omap_hwmod am33xx_dcan0_hwmod = { + .name = "d_can0", + .class = &am33xx_dcan_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "dcan0_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* dcan1 */ +struct omap_hwmod am33xx_dcan1_hwmod = { + .name = "d_can1", + .class = &am33xx_dcan_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "dcan1_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* elm */ +static struct omap_hwmod_class_sysconfig am33xx_elm_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class am33xx_elm_hwmod_class = { + .name = "elm", + .sysc = &am33xx_elm_sysc, +}; + +struct omap_hwmod am33xx_elm_hwmod = { + .name = "elm", + .class = &am33xx_elm_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* pwmss */ +static struct omap_hwmod_class_sysconfig am33xx_epwmss_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x4, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +struct omap_hwmod_class am33xx_epwmss_hwmod_class = { + .name = "epwmss", + .sysc = &am33xx_epwmss_sysc, +}; + +static struct omap_hwmod_class am33xx_ecap_hwmod_class = { + .name = "ecap", +}; + +static struct omap_hwmod_class am33xx_eqep_hwmod_class = { + .name = "eqep", +}; + +struct omap_hwmod_class am33xx_ehrpwm_hwmod_class = { + .name = "ehrpwm", +}; + +/* epwmss0 */ +struct omap_hwmod am33xx_epwmss0_hwmod = { + .name = "epwmss0", + .class = &am33xx_epwmss_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* ecap0 */ +struct omap_hwmod am33xx_ecap0_hwmod = { + .name = "ecap0", + .class = &am33xx_ecap_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +/* eqep0 */ +struct omap_hwmod am33xx_eqep0_hwmod = { + .name = "eqep0", + .class = &am33xx_eqep_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +/* ehrpwm0 */ +struct omap_hwmod am33xx_ehrpwm0_hwmod = { + .name = "ehrpwm0", + .class = &am33xx_ehrpwm_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +/* epwmss1 */ +struct omap_hwmod am33xx_epwmss1_hwmod = { + .name = "epwmss1", + .class = &am33xx_epwmss_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* ecap1 */ +struct omap_hwmod am33xx_ecap1_hwmod = { + .name = "ecap1", + .class = &am33xx_ecap_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +/* eqep1 */ +struct omap_hwmod am33xx_eqep1_hwmod = { + .name = "eqep1", + .class = &am33xx_eqep_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +/* ehrpwm1 */ +struct omap_hwmod am33xx_ehrpwm1_hwmod = { + .name = "ehrpwm1", + .class = &am33xx_ehrpwm_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +/* epwmss2 */ +struct omap_hwmod am33xx_epwmss2_hwmod = { + .name = "epwmss2", + .class = &am33xx_epwmss_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* ecap2 */ +struct omap_hwmod am33xx_ecap2_hwmod = { + .name = "ecap2", + .class = &am33xx_ecap_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +/* eqep2 */ +struct omap_hwmod am33xx_eqep2_hwmod = { + .name = "eqep2", + .class = &am33xx_eqep_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +/* ehrpwm2 */ +struct omap_hwmod am33xx_ehrpwm2_hwmod = { + .name = "ehrpwm2", + .class = &am33xx_ehrpwm_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +/* + * 'gpio' class: for gpio 0,1,2,3 + */ +static struct omap_hwmod_class_sysconfig am33xx_gpio_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0114, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +struct omap_hwmod_class am33xx_gpio_hwmod_class = { + .name = "gpio", + .sysc = &am33xx_gpio_sysc, + .rev = 2, +}; + +struct omap_gpio_dev_attr gpio_dev_attr = { + .bank_width = 32, + .dbck_flag = true, +}; + +/* gpio1 */ +static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { + { .role = "dbclk", .clk = "gpio1_dbclk" }, +}; + +struct omap_hwmod am33xx_gpio1_hwmod = { + .name = "gpio2", + .class = &am33xx_gpio_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = gpio1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio2 */ +static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { + { .role = "dbclk", .clk = "gpio2_dbclk" }, +}; + +struct omap_hwmod am33xx_gpio2_hwmod = { + .name = "gpio3", + .class = &am33xx_gpio_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = gpio2_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio3 */ +static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { + { .role = "dbclk", .clk = "gpio3_dbclk" }, +}; + +struct omap_hwmod am33xx_gpio3_hwmod = { + .name = "gpio4", + .class = &am33xx_gpio_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = gpio3_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpmc */ +static struct omap_hwmod_class_sysconfig gpmc_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x10, + .syss_offs = 0x14, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class am33xx_gpmc_hwmod_class = { + .name = "gpmc", + .sysc = &gpmc_sysc, +}; + +struct omap_hwmod am33xx_gpmc_hwmod = { + .name = "gpmc", + .class = &am33xx_gpmc_hwmod_class, + .clkdm_name = "l3s_clkdm", + .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), + .main_clk = "l3s_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* 'i2c' class */ +static struct omap_hwmod_class_sysconfig am33xx_i2c_sysc = { + .sysc_offs = 0x0010, + .syss_offs = 0x0090, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class i2c_class = { + .name = "i2c", + .sysc = &am33xx_i2c_sysc, + .rev = OMAP_I2C_IP_VERSION_2, + .reset = &omap_i2c_reset, +}; + +static struct omap_i2c_dev_attr i2c_dev_attr = { + .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE, +}; + +/* i2c1 */ +struct omap_hwmod am33xx_i2c1_hwmod = { + .name = "i2c1", + .class = &i2c_class, + .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "dpll_per_m2_div4_wkupdm_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* i2c1 */ +struct omap_hwmod am33xx_i2c2_hwmod = { + .name = "i2c2", + .class = &i2c_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* i2c3 */ +struct omap_hwmod am33xx_i2c3_hwmod = { + .name = "i2c3", + .class = &i2c_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* + * 'mailbox' class + * mailbox module allowing communication between the on-chip processors using a + * queued mailbox-interrupt mechanism. + */ +static struct omap_hwmod_class_sysconfig am33xx_mailbox_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class am33xx_mailbox_hwmod_class = { + .name = "mailbox", + .sysc = &am33xx_mailbox_sysc, +}; + +struct omap_hwmod am33xx_mailbox_hwmod = { + .name = "mailbox", + .class = &am33xx_mailbox_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'mcasp' class + */ +static struct omap_hwmod_class_sysconfig am33xx_mcasp_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x4, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type3, +}; + +static struct omap_hwmod_class am33xx_mcasp_hwmod_class = { + .name = "mcasp", + .sysc = &am33xx_mcasp_sysc, +}; + +/* mcasp0 */ +struct omap_hwmod am33xx_mcasp0_hwmod = { + .name = "mcasp0", + .class = &am33xx_mcasp_hwmod_class, + .clkdm_name = "l3s_clkdm", + .main_clk = "mcasp0_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* mcasp1 */ +struct omap_hwmod am33xx_mcasp1_hwmod = { + .name = "mcasp1", + .class = &am33xx_mcasp_hwmod_class, + .clkdm_name = "l3s_clkdm", + .main_clk = "mcasp1_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* 'mmc' class */ +static struct omap_hwmod_class_sysconfig am33xx_mmc_sysc = { + .rev_offs = 0x1fc, + .sysc_offs = 0x10, + .syss_offs = 0x14, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class am33xx_mmc_hwmod_class = { + .name = "mmc", + .sysc = &am33xx_mmc_sysc, +}; + +/* mmc0 */ +static struct omap_mmc_dev_attr am33xx_mmc0_dev_attr = { + .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, +}; + +struct omap_hwmod am33xx_mmc0_hwmod = { + .name = "mmc1", + .class = &am33xx_mmc_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "mmc_clk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &am33xx_mmc0_dev_attr, +}; + +/* mmc1 */ +static struct omap_mmc_dev_attr am33xx_mmc1_dev_attr = { + .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, +}; + +struct omap_hwmod am33xx_mmc1_hwmod = { + .name = "mmc2", + .class = &am33xx_mmc_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "mmc_clk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &am33xx_mmc1_dev_attr, +}; + +/* mmc2 */ +static struct omap_mmc_dev_attr am33xx_mmc2_dev_attr = { + .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, +}; +struct omap_hwmod am33xx_mmc2_hwmod = { + .name = "mmc3", + .class = &am33xx_mmc_hwmod_class, + .clkdm_name = "l3s_clkdm", + .main_clk = "mmc_clk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &am33xx_mmc2_dev_attr, +}; + +/* + * 'rtc' class + * rtc subsystem + */ +static struct omap_hwmod_class_sysconfig am33xx_rtc_sysc = { + .rev_offs = 0x0074, + .sysc_offs = 0x0078, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | + SIDLE_SMART | SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type3, +}; + +static struct omap_hwmod_class am33xx_rtc_hwmod_class = { + .name = "rtc", + .sysc = &am33xx_rtc_sysc, +}; + +struct omap_hwmod am33xx_rtc_hwmod = { + .name = "rtc", + .class = &am33xx_rtc_hwmod_class, + .clkdm_name = "l4_rtc_clkdm", + .main_clk = "clk_32768_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* 'spi' class */ +static struct omap_hwmod_class_sysconfig am33xx_mcspi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0110, + .syss_offs = 0x0114, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +struct omap_hwmod_class am33xx_spi_hwmod_class = { + .name = "mcspi", + .sysc = &am33xx_mcspi_sysc, + .rev = OMAP4_MCSPI_REV, +}; + +/* spi0 */ +struct omap2_mcspi_dev_attr mcspi_attrib = { + .num_chipselect = 2, +}; +struct omap_hwmod am33xx_spi0_hwmod = { + .name = "spi0", + .class = &am33xx_spi_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi_attrib, +}; + +/* spi1 */ +struct omap_hwmod am33xx_spi1_hwmod = { + .name = "spi1", + .class = &am33xx_spi_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi_attrib, +}; + +/* + * 'spinlock' class + * spinlock provides hardware assistance for synchronizing the + * processes running on multiple processors + */ + +static struct omap_hwmod_class_sysconfig am33xx_spinlock_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class am33xx_spinlock_hwmod_class = { + .name = "spinlock", + .sysc = &am33xx_spinlock_sysc, +}; + +struct omap_hwmod am33xx_spinlock_hwmod = { + .name = "spinlock", + .class = &am33xx_spinlock_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* 'timer 2-7' class */ +static struct omap_hwmod_class_sysconfig am33xx_timer_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +struct omap_hwmod_class am33xx_timer_hwmod_class = { + .name = "timer", + .sysc = &am33xx_timer_sysc, +}; + +/* timer1 1ms */ +static struct omap_hwmod_class_sysconfig am33xx_timer1ms_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class am33xx_timer1ms_hwmod_class = { + .name = "timer", + .sysc = &am33xx_timer1ms_sysc, +}; + +struct omap_hwmod am33xx_timer1_hwmod = { + .name = "timer1", + .class = &am33xx_timer1ms_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .main_clk = "timer1_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_timer2_hwmod = { + .name = "timer2", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer2_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_timer3_hwmod = { + .name = "timer3", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer3_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_timer4_hwmod = { + .name = "timer4", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer4_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_timer5_hwmod = { + .name = "timer5", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer5_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_timer6_hwmod = { + .name = "timer6", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer6_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_timer7_hwmod = { + .name = "timer7", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer7_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* tpcc */ +static struct omap_hwmod_class am33xx_tpcc_hwmod_class = { + .name = "tpcc", +}; + +struct omap_hwmod am33xx_tpcc_hwmod = { + .name = "tpcc", + .class = &am33xx_tpcc_hwmod_class, + .clkdm_name = "l3_clkdm", + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_class_sysconfig am33xx_tptc_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x10, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSC_HAS_MIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_SMART | MSTANDBY_FORCE), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +/* 'tptc' class */ +static struct omap_hwmod_class am33xx_tptc_hwmod_class = { + .name = "tptc", + .sysc = &am33xx_tptc_sysc, +}; + +/* tptc0 */ +struct omap_hwmod am33xx_tptc0_hwmod = { + .name = "tptc0", + .class = &am33xx_tptc_hwmod_class, + .clkdm_name = "l3_clkdm", + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* tptc1 */ +struct omap_hwmod am33xx_tptc1_hwmod = { + .name = "tptc1", + .class = &am33xx_tptc_hwmod_class, + .clkdm_name = "l3_clkdm", + .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY), + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* tptc2 */ +struct omap_hwmod am33xx_tptc2_hwmod = { + .name = "tptc2", + .class = &am33xx_tptc_hwmod_class, + .clkdm_name = "l3_clkdm", + .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY), + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* 'uart' class */ +static struct omap_hwmod_class_sysconfig uart_sysc = { + .rev_offs = 0x50, + .sysc_offs = 0x54, + .syss_offs = 0x58, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class uart_class = { + .name = "uart", + .sysc = &uart_sysc, +}; + +struct omap_hwmod am33xx_uart1_hwmod = { + .name = "uart1", + .class = &uart_class, + .clkdm_name = "l4_wkup_clkdm", + .flags = DEBUG_AM33XXUART1_FLAGS | HWMOD_SWSUP_SIDLE_ACT, + .main_clk = "dpll_per_m2_div4_wkupdm_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_uart2_hwmod = { + .name = "uart2", + .class = &uart_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* uart3 */ +struct omap_hwmod am33xx_uart3_hwmod = { + .name = "uart3", + .class = &uart_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_uart4_hwmod = { + .name = "uart4", + .class = &uart_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_uart5_hwmod = { + .name = "uart5", + .class = &uart_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod am33xx_uart6_hwmod = { + .name = "uart6", + .class = &uart_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* 'wd_timer' class */ +static struct omap_hwmod_class_sysconfig wdt_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x10, + .syss_offs = 0x14, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class am33xx_wd_timer_hwmod_class = { + .name = "wd_timer", + .sysc = &wdt_sysc, + .pre_shutdown = &omap2_wd_timer_disable, +}; + +/* + * XXX: device.c file uses hardcoded name for watchdog timer + * driver "wd_timer2, so we are also using same name as of now... + */ +struct omap_hwmod am33xx_wd_timer1_hwmod = { + .name = "wd_timer2", + .class = &am33xx_wd_timer_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_SWSUP_SIDLE, + .main_clk = "wdt1_fck", + .prcm = { + .omap4 = { + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static void omap_hwmod_am33xx_clkctrl(void) +{ + CLKCTRL(am33xx_uart2_hwmod, AM33XX_CM_PER_UART1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart3_hwmod, AM33XX_CM_PER_UART2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart4_hwmod, AM33XX_CM_PER_UART3_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart5_hwmod, AM33XX_CM_PER_UART4_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart6_hwmod, AM33XX_CM_PER_UART5_CLKCTRL_OFFSET); + CLKCTRL(am33xx_dcan0_hwmod, AM33XX_CM_PER_DCAN0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_dcan1_hwmod, AM33XX_CM_PER_DCAN1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_elm_hwmod, AM33XX_CM_PER_ELM_CLKCTRL_OFFSET); + CLKCTRL(am33xx_epwmss0_hwmod, AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_epwmss1_hwmod, AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_epwmss2_hwmod, AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gpio1_hwmod, AM33XX_CM_PER_GPIO1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gpio2_hwmod, AM33XX_CM_PER_GPIO2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gpio3_hwmod, AM33XX_CM_PER_GPIO3_CLKCTRL_OFFSET); + CLKCTRL(am33xx_i2c2_hwmod, AM33XX_CM_PER_I2C1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_i2c3_hwmod, AM33XX_CM_PER_I2C2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mailbox_hwmod, AM33XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mcasp0_hwmod, AM33XX_CM_PER_MCASP0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mcasp1_hwmod, AM33XX_CM_PER_MCASP1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mmc0_hwmod, AM33XX_CM_PER_MMC0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mmc1_hwmod, AM33XX_CM_PER_MMC1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_spi0_hwmod, AM33XX_CM_PER_SPI0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_spi1_hwmod, AM33XX_CM_PER_SPI1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_spinlock_hwmod, AM33XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer2_hwmod, AM33XX_CM_PER_TIMER2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer3_hwmod, AM33XX_CM_PER_TIMER3_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer4_hwmod, AM33XX_CM_PER_TIMER4_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer5_hwmod, AM33XX_CM_PER_TIMER5_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer6_hwmod, AM33XX_CM_PER_TIMER6_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer7_hwmod, AM33XX_CM_PER_TIMER7_CLKCTRL_OFFSET); + CLKCTRL(am33xx_smartreflex0_hwmod, + AM33XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_smartreflex1_hwmod, + AM33XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart1_hwmod, AM33XX_CM_WKUP_UART0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer1_hwmod, AM33XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_i2c1_hwmod, AM33XX_CM_WKUP_I2C0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_wd_timer1_hwmod, AM33XX_CM_WKUP_WDT1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_rtc_hwmod, AM33XX_CM_RTC_RTC_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mmc2_hwmod, AM33XX_CM_PER_MMC2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gpmc_hwmod, AM33XX_CM_PER_GPMC_CLKCTRL_OFFSET); + CLKCTRL(am33xx_l4_ls_hwmod, AM33XX_CM_PER_L4LS_CLKCTRL_OFFSET); + CLKCTRL(am33xx_l4_wkup_hwmod, AM33XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET); + CLKCTRL(am33xx_l3_main_hwmod, AM33XX_CM_PER_L3_CLKCTRL_OFFSET); + CLKCTRL(am33xx_tpcc_hwmod, AM33XX_CM_PER_TPCC_CLKCTRL_OFFSET); + CLKCTRL(am33xx_tptc0_hwmod, AM33XX_CM_PER_TPTC0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_tptc1_hwmod, AM33XX_CM_PER_TPTC1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_tptc2_hwmod, AM33XX_CM_PER_TPTC2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gfx_hwmod, AM33XX_CM_GFX_GFX_CLKCTRL_OFFSET); + CLKCTRL(am33xx_cpgmac0_hwmod, AM33XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_pruss_hwmod, AM33XX_CM_PER_PRUSS_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mpu_hwmod , AM33XX_CM_MPU_MPU_CLKCTRL_OFFSET); + CLKCTRL(am33xx_l3_instr_hwmod , AM33XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET); + CLKCTRL(am33xx_ocmcram_hwmod , AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET); + CLKCTRL(am33xx_sha0_hwmod , AM33XX_CM_PER_SHA0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_aes0_hwmod , AM33XX_CM_PER_AES0_CLKCTRL_OFFSET); +} + +static void omap_hwmod_am33xx_rst(void) +{ + RSTCTRL(am33xx_pruss_hwmod, AM33XX_RM_PER_RSTCTRL_OFFSET); + RSTCTRL(am33xx_gfx_hwmod, AM33XX_RM_GFX_RSTCTRL_OFFSET); + RSTST(am33xx_gfx_hwmod, AM33XX_RM_GFX_RSTST_OFFSET); +} + +void omap_hwmod_am33xx_reg(void) +{ + omap_hwmod_am33xx_clkctrl(); + omap_hwmod_am33xx_rst(); +} + +static void omap_hwmod_am43xx_clkctrl(void) +{ + CLKCTRL(am33xx_uart2_hwmod, AM43XX_CM_PER_UART1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart3_hwmod, AM43XX_CM_PER_UART2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart4_hwmod, AM43XX_CM_PER_UART3_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart5_hwmod, AM43XX_CM_PER_UART4_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart6_hwmod, AM43XX_CM_PER_UART5_CLKCTRL_OFFSET); + CLKCTRL(am33xx_dcan0_hwmod, AM43XX_CM_PER_DCAN0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_dcan1_hwmod, AM43XX_CM_PER_DCAN1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_elm_hwmod, AM43XX_CM_PER_ELM_CLKCTRL_OFFSET); + CLKCTRL(am33xx_epwmss0_hwmod, AM43XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_epwmss1_hwmod, AM43XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_epwmss2_hwmod, AM43XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gpio1_hwmod, AM43XX_CM_PER_GPIO1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gpio2_hwmod, AM43XX_CM_PER_GPIO2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gpio3_hwmod, AM43XX_CM_PER_GPIO3_CLKCTRL_OFFSET); + CLKCTRL(am33xx_i2c2_hwmod, AM43XX_CM_PER_I2C1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_i2c3_hwmod, AM43XX_CM_PER_I2C2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mailbox_hwmod, AM43XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mcasp0_hwmod, AM43XX_CM_PER_MCASP0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mcasp1_hwmod, AM43XX_CM_PER_MCASP1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mmc0_hwmod, AM43XX_CM_PER_MMC0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mmc1_hwmod, AM43XX_CM_PER_MMC1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_spi0_hwmod, AM43XX_CM_PER_SPI0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_spi1_hwmod, AM43XX_CM_PER_SPI1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_spinlock_hwmod, AM43XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer2_hwmod, AM43XX_CM_PER_TIMER2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer3_hwmod, AM43XX_CM_PER_TIMER3_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer4_hwmod, AM43XX_CM_PER_TIMER4_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer5_hwmod, AM43XX_CM_PER_TIMER5_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer6_hwmod, AM43XX_CM_PER_TIMER6_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer7_hwmod, AM43XX_CM_PER_TIMER7_CLKCTRL_OFFSET); + CLKCTRL(am33xx_smartreflex0_hwmod, + AM43XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_smartreflex1_hwmod, + AM43XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_uart1_hwmod, AM43XX_CM_WKUP_UART0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_timer1_hwmod, AM43XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_i2c1_hwmod, AM43XX_CM_WKUP_I2C0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_wd_timer1_hwmod, AM43XX_CM_WKUP_WDT1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_rtc_hwmod, AM43XX_CM_RTC_RTC_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mmc2_hwmod, AM43XX_CM_PER_MMC2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gpmc_hwmod, AM43XX_CM_PER_GPMC_CLKCTRL_OFFSET); + CLKCTRL(am33xx_l4_ls_hwmod, AM43XX_CM_PER_L4LS_CLKCTRL_OFFSET); + CLKCTRL(am33xx_l4_wkup_hwmod, AM43XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET); + CLKCTRL(am33xx_l3_main_hwmod, AM43XX_CM_PER_L3_CLKCTRL_OFFSET); + CLKCTRL(am33xx_tpcc_hwmod, AM43XX_CM_PER_TPCC_CLKCTRL_OFFSET); + CLKCTRL(am33xx_tptc0_hwmod, AM43XX_CM_PER_TPTC0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_tptc1_hwmod, AM43XX_CM_PER_TPTC1_CLKCTRL_OFFSET); + CLKCTRL(am33xx_tptc2_hwmod, AM43XX_CM_PER_TPTC2_CLKCTRL_OFFSET); + CLKCTRL(am33xx_gfx_hwmod, AM43XX_CM_GFX_GFX_CLKCTRL_OFFSET); + CLKCTRL(am33xx_cpgmac0_hwmod, AM43XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_pruss_hwmod, AM43XX_CM_PER_PRUSS_CLKCTRL_OFFSET); + CLKCTRL(am33xx_mpu_hwmod , AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET); + CLKCTRL(am33xx_l3_instr_hwmod , AM43XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET); + CLKCTRL(am33xx_ocmcram_hwmod , AM43XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET); + CLKCTRL(am33xx_sha0_hwmod , AM43XX_CM_PER_SHA0_CLKCTRL_OFFSET); + CLKCTRL(am33xx_aes0_hwmod , AM43XX_CM_PER_AES0_CLKCTRL_OFFSET); +} + +static void omap_hwmod_am43xx_rst(void) +{ + RSTCTRL(am33xx_pruss_hwmod, AM43XX_RM_PER_RSTCTRL_OFFSET); + RSTCTRL(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTCTRL_OFFSET); + RSTST(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTST_OFFSET); +} + +void omap_hwmod_am43xx_reg(void) +{ + omap_hwmod_am43xx_clkctrl(); + omap_hwmod_am43xx_rst(); +} diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c new file mode 100644 index 00000000000..6b406ca4bd3 --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -0,0 +1,643 @@ +/* + * omap_hwmod_33xx_data.c: Hardware modules present on the AM33XX chips + * + * Copyright (C) {2012} Texas Instruments Incorporated - http://www.ti.com/ + * + * This file is automatically generated from the AM33XX hardware databases. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/i2c-omap.h> + +#include "omap_hwmod.h" +#include <linux/platform_data/gpio-omap.h> +#include <linux/platform_data/spi-omap2-mcspi.h> + +#include "omap_hwmod_common_data.h" + +#include "control.h" +#include "cm33xx.h" +#include "prm33xx.h" +#include "prm-regbits-33xx.h" +#include "i2c.h" +#include "mmc.h" +#include "wd_timer.h" +#include "omap_hwmod_33xx_43xx_common_data.h" + +/* + * IP blocks + */ + +/* + * 'emif' class + * instance(s): emif + */ +static struct omap_hwmod_class_sysconfig am33xx_emif_sysc = { + .rev_offs = 0x0000, +}; + +static struct omap_hwmod_class am33xx_emif_hwmod_class = { + .name = "emif", + .sysc = &am33xx_emif_sysc, +}; + +/* emif */ +static struct omap_hwmod am33xx_emif_hwmod = { + .name = "emif", + .class = &am33xx_emif_hwmod_class, + .clkdm_name = "l3_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "dpll_ddr_m2_div2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_PER_EMIF_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* l4_hs */ +static struct omap_hwmod am33xx_l4_hs_hwmod = { + .name = "l4_hs", + .class = &am33xx_l4_hwmod_class, + .clkdm_name = "l4hs_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "l4hs_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_PER_L4HS_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_rst_info am33xx_wkup_m3_resets[] = { + { .name = "wkup_m3", .rst_shift = 3, .st_shift = 5 }, +}; + +/* wkup_m3 */ +static struct omap_hwmod am33xx_wkup_m3_hwmod = { + .name = "wkup_m3", + .class = &am33xx_wkup_m3_hwmod_class, + .clkdm_name = "l4_wkup_aon_clkdm", + /* Keep hardreset asserted */ + .flags = HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST, + .main_clk = "dpll_core_m4_div2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET, + .rstctrl_offs = AM33XX_RM_WKUP_RSTCTRL_OFFSET, + .rstst_offs = AM33XX_RM_WKUP_RSTST_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .rst_lines = am33xx_wkup_m3_resets, + .rst_lines_cnt = ARRAY_SIZE(am33xx_wkup_m3_resets), +}; + +/* + * 'adc/tsc' class + * TouchScreen Controller (Anolog-To-Digital Converter) + */ +static struct omap_hwmod_class_sysconfig am33xx_adc_tsc_sysc = { + .rev_offs = 0x00, + .sysc_offs = 0x10, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class am33xx_adc_tsc_hwmod_class = { + .name = "adc_tsc", + .sysc = &am33xx_adc_tsc_sysc, +}; + +static struct omap_hwmod am33xx_adc_tsc_hwmod = { + .name = "adc_tsc", + .class = &am33xx_adc_tsc_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .main_clk = "adc_tsc_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * Modules omap_hwmod structures + * + * The following IPs are excluded for the moment because: + * - They do not need an explicit SW control using omap_hwmod API. + * - They still need to be validated with the driver + * properly adapted to omap_hwmod / omap_device + * + * - cEFUSE (doesn't fall under any ocp_if) + * - clkdiv32k + * - ocp watch point + */ +#if 0 +/* + * 'cefuse' class + */ +static struct omap_hwmod_class am33xx_cefuse_hwmod_class = { + .name = "cefuse", +}; + +static struct omap_hwmod am33xx_cefuse_hwmod = { + .name = "cefuse", + .class = &am33xx_cefuse_hwmod_class, + .clkdm_name = "l4_cefuse_clkdm", + .main_clk = "cefuse_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'clkdiv32k' class + */ +static struct omap_hwmod_class am33xx_clkdiv32k_hwmod_class = { + .name = "clkdiv32k", +}; + +static struct omap_hwmod am33xx_clkdiv32k_hwmod = { + .name = "clkdiv32k", + .class = &am33xx_clkdiv32k_hwmod_class, + .clkdm_name = "clk_24mhz_clkdm", + .main_clk = "clkdiv32k_ick", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_PER_CLKDIV32K_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* ocpwp */ +static struct omap_hwmod_class am33xx_ocpwp_hwmod_class = { + .name = "ocpwp", +}; + +static struct omap_hwmod am33xx_ocpwp_hwmod = { + .name = "ocpwp", + .class = &am33xx_ocpwp_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_PER_OCPWP_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; +#endif + +/* + * 'debugss' class + * debug sub system + */ +static struct omap_hwmod_opt_clk debugss_opt_clks[] = { + { .role = "dbg_sysclk", .clk = "dbg_sysclk_ck" }, + { .role = "dbg_clka", .clk = "dbg_clka_ck" }, +}; + +static struct omap_hwmod_class am33xx_debugss_hwmod_class = { + .name = "debugss", +}; + +static struct omap_hwmod am33xx_debugss_hwmod = { + .name = "debugss", + .class = &am33xx_debugss_hwmod_class, + .clkdm_name = "l3_aon_clkdm", + .main_clk = "trace_clk_div_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_WKUP_DEBUGSS_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = debugss_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(debugss_opt_clks), +}; + +static struct omap_hwmod am33xx_control_hwmod = { + .name = "control", + .class = &am33xx_control_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "dpll_core_m4_div2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* gpio0 */ +static struct omap_hwmod_opt_clk gpio0_opt_clks[] = { + { .role = "dbclk", .clk = "gpio0_dbclk" }, +}; + +static struct omap_hwmod am33xx_gpio0_hwmod = { + .name = "gpio1", + .class = &am33xx_gpio_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "dpll_core_m4_div2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = gpio0_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio0_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* lcdc */ +static struct omap_hwmod_class_sysconfig lcdc_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x54, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class am33xx_lcdc_hwmod_class = { + .name = "lcdc", + .sysc = &lcdc_sysc, +}; + +static struct omap_hwmod am33xx_lcdc_hwmod = { + .name = "lcdc", + .class = &am33xx_lcdc_hwmod_class, + .clkdm_name = "lcdc_clkdm", + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, + .main_clk = "lcd_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_PER_LCDC_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'usb_otg' class + * high-speed on-the-go universal serial bus (usb_otg) controller + */ +static struct omap_hwmod_class_sysconfig am33xx_usbhsotg_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x10, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class am33xx_usbotg_class = { + .name = "usbotg", + .sysc = &am33xx_usbhsotg_sysc, +}; + +static struct omap_hwmod am33xx_usbss_hwmod = { + .name = "usb_otg_hs", + .class = &am33xx_usbotg_class, + .clkdm_name = "l3s_clkdm", + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, + .main_clk = "usbotg_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_PER_USB0_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + + +/* + * Interfaces + */ + +static struct omap_hwmod_addr_space am33xx_emif_addrs[] = { + { + .pa_start = 0x4c000000, + .pa_end = 0x4c000fff, + .flags = ADDR_TYPE_RT + }, + { } +}; +/* l3 main -> emif */ +static struct omap_hwmod_ocp_if am33xx_l3_main__emif = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_emif_hwmod, + .clk = "dpll_core_m4_ck", + .addr = am33xx_emif_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3 main -> l4 hs */ +static struct omap_hwmod_ocp_if am33xx_l3_main__l4_hs = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_l4_hs_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* wkup m3 -> l4 wkup */ +static struct omap_hwmod_ocp_if am33xx_wkup_m3__l4_wkup = { + .master = &am33xx_wkup_m3_hwmod, + .slave = &am33xx_l4_wkup_hwmod, + .clk = "dpll_core_m4_div2_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 wkup -> wkup m3 */ +static struct omap_hwmod_ocp_if am33xx_l4_wkup__wkup_m3 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_wkup_m3_hwmod, + .clk = "dpll_core_m4_div2_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 hs -> pru-icss */ +static struct omap_hwmod_ocp_if am33xx_l4_hs__pruss = { + .master = &am33xx_l4_hs_hwmod, + .slave = &am33xx_pruss_hwmod, + .clk = "dpll_core_m4_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main -> debugss */ +static struct omap_hwmod_addr_space am33xx_debugss_addrs[] = { + { + .pa_start = 0x4b000000, + .pa_end = 0x4b000000 + SZ_16M - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +static struct omap_hwmod_ocp_if am33xx_l3_main__debugss = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_debugss_hwmod, + .clk = "dpll_core_m4_ck", + .addr = am33xx_debugss_addrs, + .user = OCP_USER_MPU, +}; + +/* l4 wkup -> smartreflex0 */ +static struct omap_hwmod_ocp_if am33xx_l4_wkup__smartreflex0 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_smartreflex0_hwmod, + .clk = "dpll_core_m4_div2_ck", + .user = OCP_USER_MPU, +}; + +/* l4 wkup -> smartreflex1 */ +static struct omap_hwmod_ocp_if am33xx_l4_wkup__smartreflex1 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_smartreflex1_hwmod, + .clk = "dpll_core_m4_div2_ck", + .user = OCP_USER_MPU, +}; + +/* l4 wkup -> control */ +static struct omap_hwmod_ocp_if am33xx_l4_wkup__control = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_control_hwmod, + .clk = "dpll_core_m4_div2_ck", + .user = OCP_USER_MPU, +}; + +/* L4 WKUP -> I2C1 */ +static struct omap_hwmod_ocp_if am33xx_l4_wkup__i2c1 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_i2c1_hwmod, + .clk = "dpll_core_m4_div2_ck", + .user = OCP_USER_MPU, +}; + +/* L4 WKUP -> GPIO1 */ +static struct omap_hwmod_ocp_if am33xx_l4_wkup__gpio0 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_gpio0_hwmod, + .clk = "dpll_core_m4_div2_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 WKUP -> ADC_TSC */ +static struct omap_hwmod_addr_space am33xx_adc_tsc_addrs[] = { + { + .pa_start = 0x44E0D000, + .pa_end = 0x44E0D000 + SZ_8K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +static struct omap_hwmod_ocp_if am33xx_l4_wkup__adc_tsc = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_adc_tsc_hwmod, + .clk = "dpll_core_m4_div2_ck", + .addr = am33xx_adc_tsc_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am33xx_l4_hs__cpgmac0 = { + .master = &am33xx_l4_hs_hwmod, + .slave = &am33xx_cpgmac0_hwmod, + .clk = "cpsw_125mhz_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space am33xx_lcdc_addr_space[] = { + { + .pa_start = 0x4830E000, + .pa_end = 0x4830E000 + SZ_8K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +static struct omap_hwmod_ocp_if am33xx_l3_main__lcdc = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_lcdc_hwmod, + .clk = "dpll_core_m4_ck", + .addr = am33xx_lcdc_addr_space, + .user = OCP_USER_MPU, +}; + +/* l4 wkup -> timer1 */ +static struct omap_hwmod_ocp_if am33xx_l4_wkup__timer1 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_timer1_hwmod, + .clk = "dpll_core_m4_div2_ck", + .user = OCP_USER_MPU, +}; + +/* l4 wkup -> uart1 */ +static struct omap_hwmod_ocp_if am33xx_l4_wkup__uart1 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_uart1_hwmod, + .clk = "dpll_core_m4_div2_ck", + .user = OCP_USER_MPU, +}; + +/* l4 wkup -> wd_timer1 */ +static struct omap_hwmod_ocp_if am33xx_l4_wkup__wd_timer1 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_wd_timer1_hwmod, + .clk = "dpll_core_m4_div2_ck", + .user = OCP_USER_MPU, +}; + +/* usbss */ +/* l3 s -> USBSS interface */ +static struct omap_hwmod_ocp_if am33xx_l3_s__usbss = { + .master = &am33xx_l3_s_hwmod, + .slave = &am33xx_usbss_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU, + .flags = OCPIF_SWSUP_IDLE, +}; + +/* rng */ +static struct omap_hwmod_class_sysconfig am33xx_rng_sysc = { + .rev_offs = 0x1fe0, + .sysc_offs = 0x1fe4, + .sysc_flags = SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE, + .idlemodes = SIDLE_FORCE | SIDLE_NO, + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class am33xx_rng_hwmod_class = { + .name = "rng", + .sysc = &am33xx_rng_sysc, +}; + +static struct omap_hwmod am33xx_rng_hwmod = { + .name = "rng", + .class = &am33xx_rng_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_SWSUP_SIDLE, + .main_clk = "rng_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_PER_RNG_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_ocp_if am33xx_l4_per__rng = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_rng_hwmod, + .clk = "rng_fck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { + &am33xx_l3_main__emif, + &am33xx_mpu__l3_main, + &am33xx_mpu__prcm, + &am33xx_l3_s__l4_ls, + &am33xx_l3_s__l4_wkup, + &am33xx_l3_main__l4_hs, + &am33xx_l3_main__l3_s, + &am33xx_l3_main__l3_instr, + &am33xx_l3_main__gfx, + &am33xx_l3_s__l3_main, + &am33xx_pruss__l3_main, + &am33xx_wkup_m3__l4_wkup, + &am33xx_gfx__l3_main, + &am33xx_l3_main__debugss, + &am33xx_l4_wkup__wkup_m3, + &am33xx_l4_wkup__control, + &am33xx_l4_wkup__smartreflex0, + &am33xx_l4_wkup__smartreflex1, + &am33xx_l4_wkup__uart1, + &am33xx_l4_wkup__timer1, + &am33xx_l4_wkup__rtc, + &am33xx_l4_wkup__i2c1, + &am33xx_l4_wkup__gpio0, + &am33xx_l4_wkup__adc_tsc, + &am33xx_l4_wkup__wd_timer1, + &am33xx_l4_hs__pruss, + &am33xx_l4_per__dcan0, + &am33xx_l4_per__dcan1, + &am33xx_l4_per__gpio1, + &am33xx_l4_per__gpio2, + &am33xx_l4_per__gpio3, + &am33xx_l4_per__i2c2, + &am33xx_l4_per__i2c3, + &am33xx_l4_per__mailbox, + &am33xx_l4_ls__mcasp0, + &am33xx_l4_ls__mcasp1, + &am33xx_l4_ls__mmc0, + &am33xx_l4_ls__mmc1, + &am33xx_l3_s__mmc2, + &am33xx_l4_ls__timer2, + &am33xx_l4_ls__timer3, + &am33xx_l4_ls__timer4, + &am33xx_l4_ls__timer5, + &am33xx_l4_ls__timer6, + &am33xx_l4_ls__timer7, + &am33xx_l3_main__tpcc, + &am33xx_l4_ls__uart2, + &am33xx_l4_ls__uart3, + &am33xx_l4_ls__uart4, + &am33xx_l4_ls__uart5, + &am33xx_l4_ls__uart6, + &am33xx_l4_ls__spinlock, + &am33xx_l4_ls__elm, + &am33xx_l4_ls__epwmss0, + &am33xx_epwmss0__ecap0, + &am33xx_epwmss0__eqep0, + &am33xx_epwmss0__ehrpwm0, + &am33xx_l4_ls__epwmss1, + &am33xx_epwmss1__ecap1, + &am33xx_epwmss1__eqep1, + &am33xx_epwmss1__ehrpwm1, + &am33xx_l4_ls__epwmss2, + &am33xx_epwmss2__ecap2, + &am33xx_epwmss2__eqep2, + &am33xx_epwmss2__ehrpwm2, + &am33xx_l3_s__gpmc, + &am33xx_l3_main__lcdc, + &am33xx_l4_ls__mcspi0, + &am33xx_l4_ls__mcspi1, + &am33xx_l3_main__tptc0, + &am33xx_l3_main__tptc1, + &am33xx_l3_main__tptc2, + &am33xx_l3_main__ocmc, + &am33xx_l3_s__usbss, + &am33xx_l4_hs__cpgmac0, + &am33xx_cpgmac0__mdio, + &am33xx_l3_main__sha0, + &am33xx_l3_main__aes0, + &am33xx_l4_per__rng, + NULL, +}; + +int __init am33xx_hwmod_init(void) +{ + omap_hwmod_am33xx_reg(); + omap_hwmod_init(); + return omap_hwmod_register_links(am33xx_hwmod_ocp_ifs); +} diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c new file mode 100644 index 00000000000..1cd0cfdc03e --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -0,0 +1,4000 @@ +/* + * omap_hwmod_3xxx_data.c - hardware modules present on the OMAP3xxx chips + * + * Copyright (C) 2009-2011 Nokia Corporation + * Copyright (C) 2012 Texas Instruments, Inc. + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * The data in this file should be completely autogeneratable from + * the TI hardware database or other technical documentation. + * + * XXX these should be marked initdata for multi-OMAP kernels + */ + +#include <linux/i2c-omap.h> +#include <linux/power/smartreflex.h> +#include <linux/platform_data/gpio-omap.h> + +#include <linux/omap-dma.h> +#include "l3_3xxx.h" +#include "l4_3xxx.h" +#include <linux/platform_data/asoc-ti-mcbsp.h> +#include <linux/platform_data/spi-omap2-mcspi.h> +#include <linux/platform_data/iommu-omap.h> +#include <linux/platform_data/mailbox-omap.h> +#include <plat/dmtimer.h> + +#include "am35xx.h" + +#include "soc.h" +#include "omap_hwmod.h" +#include "omap_hwmod_common_data.h" +#include "prm-regbits-34xx.h" +#include "cm-regbits-34xx.h" + +#include "i2c.h" +#include "mmc.h" +#include "wd_timer.h" +#include "serial.h" + +/* + * OMAP3xxx hardware module integration data + * + * All of the data in this section should be autogeneratable from the + * TI hardware database or other technical documentation. Data that + * is driver-specific or driver-kernel integration-specific belongs + * elsewhere. + */ + +/* + * IP blocks + */ + +/* L3 */ +static struct omap_hwmod_irq_info omap3xxx_l3_main_irqs[] = { + { .irq = 9 + OMAP_INTC_START, }, + { .irq = 10 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod omap3xxx_l3_main_hwmod = { + .name = "l3_main", + .class = &l3_hwmod_class, + .mpu_irqs = omap3xxx_l3_main_irqs, + .flags = HWMOD_NO_IDLEST, +}; + +/* L4 CORE */ +static struct omap_hwmod omap3xxx_l4_core_hwmod = { + .name = "l4_core", + .class = &l4_hwmod_class, + .flags = HWMOD_NO_IDLEST, +}; + +/* L4 PER */ +static struct omap_hwmod omap3xxx_l4_per_hwmod = { + .name = "l4_per", + .class = &l4_hwmod_class, + .flags = HWMOD_NO_IDLEST, +}; + +/* L4 WKUP */ +static struct omap_hwmod omap3xxx_l4_wkup_hwmod = { + .name = "l4_wkup", + .class = &l4_hwmod_class, + .flags = HWMOD_NO_IDLEST, +}; + +/* L4 SEC */ +static struct omap_hwmod omap3xxx_l4_sec_hwmod = { + .name = "l4_sec", + .class = &l4_hwmod_class, + .flags = HWMOD_NO_IDLEST, +}; + +/* MPU */ +static struct omap_hwmod_irq_info omap3xxx_mpu_irqs[] = { + { .name = "pmu", .irq = 3 + OMAP_INTC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod omap3xxx_mpu_hwmod = { + .name = "mpu", + .mpu_irqs = omap3xxx_mpu_irqs, + .class = &mpu_hwmod_class, + .main_clk = "arm_fck", +}; + +/* IVA2 (IVA2) */ +static struct omap_hwmod_rst_info omap3xxx_iva_resets[] = { + { .name = "logic", .rst_shift = 0, .st_shift = 8 }, + { .name = "seq0", .rst_shift = 1, .st_shift = 9 }, + { .name = "seq1", .rst_shift = 2, .st_shift = 10 }, +}; + +static struct omap_hwmod omap3xxx_iva_hwmod = { + .name = "iva", + .class = &iva_hwmod_class, + .clkdm_name = "iva2_clkdm", + .rst_lines = omap3xxx_iva_resets, + .rst_lines_cnt = ARRAY_SIZE(omap3xxx_iva_resets), + .main_clk = "iva2_ck", + .prcm = { + .omap2 = { + .module_offs = OMAP3430_IVA2_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_IVA2_SHIFT, + } + }, +}; + +/* + * 'debugss' class + * debug and emulation sub system + */ + +static struct omap_hwmod_class omap3xxx_debugss_hwmod_class = { + .name = "debugss", +}; + +/* debugss */ +static struct omap_hwmod omap3xxx_debugss_hwmod = { + .name = "debugss", + .class = &omap3xxx_debugss_hwmod_class, + .clkdm_name = "emu_clkdm", + .main_clk = "emu_src_ck", + .flags = HWMOD_NO_IDLEST, +}; + +/* timer class */ +static struct omap_hwmod_class_sysconfig omap3xxx_timer_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .clockact = CLOCKACT_TEST_ICLK, + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap3xxx_timer_hwmod_class = { + .name = "timer", + .sysc = &omap3xxx_timer_sysc, +}; + +/* secure timers dev attribute */ +static struct omap_timer_capability_dev_attr capability_secure_dev_attr = { + .timer_capability = OMAP_TIMER_ALWON | OMAP_TIMER_SECURE, +}; + +/* always-on timers dev attribute */ +static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = { + .timer_capability = OMAP_TIMER_ALWON, +}; + +/* pwm timers dev attribute */ +static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = { + .timer_capability = OMAP_TIMER_HAS_PWM, +}; + +/* timers with DSP interrupt dev attribute */ +static struct omap_timer_capability_dev_attr capability_dsp_dev_attr = { + .timer_capability = OMAP_TIMER_HAS_DSP_IRQ, +}; + +/* pwm timers with DSP interrupt dev attribute */ +static struct omap_timer_capability_dev_attr capability_dsp_pwm_dev_attr = { + .timer_capability = OMAP_TIMER_HAS_DSP_IRQ | OMAP_TIMER_HAS_PWM, +}; + +/* timer1 */ +static struct omap_hwmod omap3xxx_timer1_hwmod = { + .name = "timer1", + .mpu_irqs = omap2_timer1_mpu_irqs, + .main_clk = "gpt1_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_GPT1_SHIFT, + .module_offs = WKUP_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_GPT1_SHIFT, + }, + }, + .dev_attr = &capability_alwon_dev_attr, + .class = &omap3xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer2 */ +static struct omap_hwmod omap3xxx_timer2_hwmod = { + .name = "timer2", + .mpu_irqs = omap2_timer2_mpu_irqs, + .main_clk = "gpt2_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_GPT2_SHIFT, + .module_offs = OMAP3430_PER_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_GPT2_SHIFT, + }, + }, + .class = &omap3xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer3 */ +static struct omap_hwmod omap3xxx_timer3_hwmod = { + .name = "timer3", + .mpu_irqs = omap2_timer3_mpu_irqs, + .main_clk = "gpt3_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_GPT3_SHIFT, + .module_offs = OMAP3430_PER_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_GPT3_SHIFT, + }, + }, + .class = &omap3xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer4 */ +static struct omap_hwmod omap3xxx_timer4_hwmod = { + .name = "timer4", + .mpu_irqs = omap2_timer4_mpu_irqs, + .main_clk = "gpt4_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_GPT4_SHIFT, + .module_offs = OMAP3430_PER_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_GPT4_SHIFT, + }, + }, + .class = &omap3xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer5 */ +static struct omap_hwmod omap3xxx_timer5_hwmod = { + .name = "timer5", + .mpu_irqs = omap2_timer5_mpu_irqs, + .main_clk = "gpt5_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_GPT5_SHIFT, + .module_offs = OMAP3430_PER_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_GPT5_SHIFT, + }, + }, + .dev_attr = &capability_dsp_dev_attr, + .class = &omap3xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer6 */ +static struct omap_hwmod omap3xxx_timer6_hwmod = { + .name = "timer6", + .mpu_irqs = omap2_timer6_mpu_irqs, + .main_clk = "gpt6_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_GPT6_SHIFT, + .module_offs = OMAP3430_PER_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_GPT6_SHIFT, + }, + }, + .dev_attr = &capability_dsp_dev_attr, + .class = &omap3xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer7 */ +static struct omap_hwmod omap3xxx_timer7_hwmod = { + .name = "timer7", + .mpu_irqs = omap2_timer7_mpu_irqs, + .main_clk = "gpt7_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_GPT7_SHIFT, + .module_offs = OMAP3430_PER_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_GPT7_SHIFT, + }, + }, + .dev_attr = &capability_dsp_dev_attr, + .class = &omap3xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer8 */ +static struct omap_hwmod omap3xxx_timer8_hwmod = { + .name = "timer8", + .mpu_irqs = omap2_timer8_mpu_irqs, + .main_clk = "gpt8_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_GPT8_SHIFT, + .module_offs = OMAP3430_PER_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_GPT8_SHIFT, + }, + }, + .dev_attr = &capability_dsp_pwm_dev_attr, + .class = &omap3xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer9 */ +static struct omap_hwmod omap3xxx_timer9_hwmod = { + .name = "timer9", + .mpu_irqs = omap2_timer9_mpu_irqs, + .main_clk = "gpt9_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_GPT9_SHIFT, + .module_offs = OMAP3430_PER_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_GPT9_SHIFT, + }, + }, + .dev_attr = &capability_pwm_dev_attr, + .class = &omap3xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer10 */ +static struct omap_hwmod omap3xxx_timer10_hwmod = { + .name = "timer10", + .mpu_irqs = omap2_timer10_mpu_irqs, + .main_clk = "gpt10_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_GPT10_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_GPT10_SHIFT, + }, + }, + .dev_attr = &capability_pwm_dev_attr, + .class = &omap3xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer11 */ +static struct omap_hwmod omap3xxx_timer11_hwmod = { + .name = "timer11", + .mpu_irqs = omap2_timer11_mpu_irqs, + .main_clk = "gpt11_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_GPT11_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_GPT11_SHIFT, + }, + }, + .dev_attr = &capability_pwm_dev_attr, + .class = &omap3xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* timer12 */ +static struct omap_hwmod_irq_info omap3xxx_timer12_mpu_irqs[] = { + { .irq = 95 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod omap3xxx_timer12_hwmod = { + .name = "timer12", + .mpu_irqs = omap3xxx_timer12_mpu_irqs, + .main_clk = "gpt12_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_GPT12_SHIFT, + .module_offs = WKUP_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_GPT12_SHIFT, + }, + }, + .dev_attr = &capability_secure_dev_attr, + .class = &omap3xxx_timer_hwmod_class, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +/* + * 'wd_timer' class + * 32-bit watchdog upward counter that generates a pulse on the reset pin on + * overflow condition + */ + +static struct omap_hwmod_class_sysconfig omap3xxx_wd_timer_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +/* I2C common */ +static struct omap_hwmod_class_sysconfig i2c_sysc = { + .rev_offs = 0x00, + .sysc_offs = 0x20, + .syss_offs = 0x10, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .clockact = CLOCKACT_TEST_ICLK, + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap3xxx_wd_timer_hwmod_class = { + .name = "wd_timer", + .sysc = &omap3xxx_wd_timer_sysc, + .pre_shutdown = &omap2_wd_timer_disable, + .reset = &omap2_wd_timer_reset, +}; + +static struct omap_hwmod omap3xxx_wd_timer2_hwmod = { + .name = "wd_timer2", + .class = &omap3xxx_wd_timer_hwmod_class, + .main_clk = "wdt2_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_WDT2_SHIFT, + .module_offs = WKUP_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_WDT2_SHIFT, + }, + }, + /* + * XXX: Use software supervised mode, HW supervised smartidle seems to + * block CORE power domain idle transitions. Maybe a HW bug in wdt2? + */ + .flags = HWMOD_SWSUP_SIDLE, +}; + +/* UART1 */ +static struct omap_hwmod omap3xxx_uart1_hwmod = { + .name = "uart1", + .mpu_irqs = omap2_uart1_mpu_irqs, + .sdma_reqs = omap2_uart1_sdma_reqs, + .main_clk = "uart1_fck", + .flags = DEBUG_TI81XXUART1_FLAGS | HWMOD_SWSUP_SIDLE_ACT, + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_UART1_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_EN_UART1_SHIFT, + }, + }, + .class = &omap2_uart_class, +}; + +/* UART2 */ +static struct omap_hwmod omap3xxx_uart2_hwmod = { + .name = "uart2", + .mpu_irqs = omap2_uart2_mpu_irqs, + .sdma_reqs = omap2_uart2_sdma_reqs, + .main_clk = "uart2_fck", + .flags = DEBUG_TI81XXUART2_FLAGS | HWMOD_SWSUP_SIDLE_ACT, + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_UART2_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_EN_UART2_SHIFT, + }, + }, + .class = &omap2_uart_class, +}; + +/* UART3 */ +static struct omap_hwmod omap3xxx_uart3_hwmod = { + .name = "uart3", + .mpu_irqs = omap2_uart3_mpu_irqs, + .sdma_reqs = omap2_uart3_sdma_reqs, + .main_clk = "uart3_fck", + .flags = DEBUG_OMAP3UART3_FLAGS | DEBUG_TI81XXUART3_FLAGS | + HWMOD_SWSUP_SIDLE_ACT, + .prcm = { + .omap2 = { + .module_offs = OMAP3430_PER_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_UART3_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_EN_UART3_SHIFT, + }, + }, + .class = &omap2_uart_class, +}; + +/* UART4 */ +static struct omap_hwmod_irq_info uart4_mpu_irqs[] = { + { .irq = 80 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod_dma_info uart4_sdma_reqs[] = { + { .name = "rx", .dma_req = 82, }, + { .name = "tx", .dma_req = 81, }, + { .dma_req = -1 } +}; + +static struct omap_hwmod omap36xx_uart4_hwmod = { + .name = "uart4", + .mpu_irqs = uart4_mpu_irqs, + .sdma_reqs = uart4_sdma_reqs, + .main_clk = "uart4_fck", + .flags = DEBUG_OMAP3UART4_FLAGS | HWMOD_SWSUP_SIDLE_ACT, + .prcm = { + .omap2 = { + .module_offs = OMAP3430_PER_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3630_EN_UART4_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3630_EN_UART4_SHIFT, + }, + }, + .class = &omap2_uart_class, +}; + +static struct omap_hwmod_irq_info am35xx_uart4_mpu_irqs[] = { + { .irq = 84 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod_dma_info am35xx_uart4_sdma_reqs[] = { + { .name = "rx", .dma_req = 55, }, + { .name = "tx", .dma_req = 54, }, + { .dma_req = -1 } +}; + +/* + * XXX AM35xx UART4 cannot complete its softreset without uart1_fck or + * uart2_fck being enabled. So we add uart1_fck as an optional clock, + * below, and set the HWMOD_CONTROL_OPT_CLKS_IN_RESET. This really + * should not be needed. The functional clock structure of the AM35xx + * UART4 is extremely unclear and opaque; it is unclear what the role + * of uart1/2_fck is for the UART4. Any clarification from either + * empirical testing or the AM3505/3517 hardware designers would be + * most welcome. + */ +static struct omap_hwmod_opt_clk am35xx_uart4_opt_clks[] = { + { .role = "softreset_uart1_fck", .clk = "uart1_fck" }, +}; + +static struct omap_hwmod am35xx_uart4_hwmod = { + .name = "uart4", + .mpu_irqs = am35xx_uart4_mpu_irqs, + .sdma_reqs = am35xx_uart4_sdma_reqs, + .main_clk = "uart4_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = AM35XX_EN_UART4_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = AM35XX_ST_UART4_SHIFT, + }, + }, + .opt_clks = am35xx_uart4_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(am35xx_uart4_opt_clks), + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .class = &omap2_uart_class, +}; + +static struct omap_hwmod_class i2c_class = { + .name = "i2c", + .sysc = &i2c_sysc, + .rev = OMAP_I2C_IP_VERSION_1, + .reset = &omap_i2c_reset, +}; + +static struct omap_hwmod_dma_info omap3xxx_dss_sdma_chs[] = { + { .name = "dispc", .dma_req = 5 }, + { .name = "dsi1", .dma_req = 74 }, + { .dma_req = -1 } +}; + +/* dss */ +static struct omap_hwmod_opt_clk dss_opt_clks[] = { + /* + * The DSS HW needs all DSS clocks enabled during reset. The dss_core + * driver does not use these clocks. + */ + { .role = "sys_clk", .clk = "dss2_alwon_fck" }, + { .role = "tv_clk", .clk = "dss_tv_fck" }, + /* required only on OMAP3430 */ + { .role = "tv_dac_clk", .clk = "dss_96m_fck" }, +}; + +static struct omap_hwmod omap3430es1_dss_core_hwmod = { + .name = "dss_core", + .class = &omap2_dss_hwmod_class, + .main_clk = "dss1_alwon_fck", /* instead of dss_fck */ + .sdma_reqs = omap3xxx_dss_sdma_chs, + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_DSS1_SHIFT, + .module_offs = OMAP3430_DSS_MOD, + .idlest_reg_id = 1, + .idlest_stdby_bit = OMAP3430ES1_ST_DSS_SHIFT, + }, + }, + .opt_clks = dss_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), + .flags = HWMOD_NO_IDLEST | HWMOD_CONTROL_OPT_CLKS_IN_RESET, +}; + +static struct omap_hwmod omap3xxx_dss_core_hwmod = { + .name = "dss_core", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .class = &omap2_dss_hwmod_class, + .main_clk = "dss1_alwon_fck", /* instead of dss_fck */ + .sdma_reqs = omap3xxx_dss_sdma_chs, + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_DSS1_SHIFT, + .module_offs = OMAP3430_DSS_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT, + .idlest_stdby_bit = OMAP3430ES2_ST_DSS_STDBY_SHIFT, + }, + }, + .opt_clks = dss_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), +}; + +/* + * 'dispc' class + * display controller + */ + +static struct omap_hwmod_class_sysconfig omap3_dispc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | + SYSC_HAS_ENAWAKEUP), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap3_dispc_hwmod_class = { + .name = "dispc", + .sysc = &omap3_dispc_sysc, +}; + +static struct omap_hwmod omap3xxx_dss_dispc_hwmod = { + .name = "dss_dispc", + .class = &omap3_dispc_hwmod_class, + .mpu_irqs = omap2_dispc_irqs, + .main_clk = "dss1_alwon_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_DSS1_SHIFT, + .module_offs = OMAP3430_DSS_MOD, + }, + }, + .flags = HWMOD_NO_IDLEST, + .dev_attr = &omap2_3_dss_dispc_dev_attr +}; + +/* + * 'dsi' class + * display serial interface controller + */ + +static struct omap_hwmod_class omap3xxx_dsi_hwmod_class = { + .name = "dsi", +}; + +static struct omap_hwmod_irq_info omap3xxx_dsi1_irqs[] = { + { .irq = 25 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +/* dss_dsi1 */ +static struct omap_hwmod_opt_clk dss_dsi1_opt_clks[] = { + { .role = "sys_clk", .clk = "dss2_alwon_fck" }, +}; + +static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = { + .name = "dss_dsi1", + .class = &omap3xxx_dsi_hwmod_class, + .mpu_irqs = omap3xxx_dsi1_irqs, + .main_clk = "dss1_alwon_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_DSS1_SHIFT, + .module_offs = OMAP3430_DSS_MOD, + }, + }, + .opt_clks = dss_dsi1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_opt_clks), + .flags = HWMOD_NO_IDLEST, +}; + +static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = { + { .role = "ick", .clk = "dss_ick" }, +}; + +static struct omap_hwmod omap3xxx_dss_rfbi_hwmod = { + .name = "dss_rfbi", + .class = &omap2_rfbi_hwmod_class, + .main_clk = "dss1_alwon_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_DSS1_SHIFT, + .module_offs = OMAP3430_DSS_MOD, + }, + }, + .opt_clks = dss_rfbi_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), + .flags = HWMOD_NO_IDLEST, +}; + +static struct omap_hwmod_opt_clk dss_venc_opt_clks[] = { + /* required only on OMAP3430 */ + { .role = "tv_dac_clk", .clk = "dss_96m_fck" }, +}; + +static struct omap_hwmod omap3xxx_dss_venc_hwmod = { + .name = "dss_venc", + .class = &omap2_venc_hwmod_class, + .main_clk = "dss_tv_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_DSS1_SHIFT, + .module_offs = OMAP3430_DSS_MOD, + }, + }, + .opt_clks = dss_venc_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_venc_opt_clks), + .flags = HWMOD_NO_IDLEST, +}; + +/* I2C1 */ +static struct omap_i2c_dev_attr i2c1_dev_attr = { + .fifo_depth = 8, /* bytes */ + .flags = OMAP_I2C_FLAG_BUS_SHIFT_2, +}; + +static struct omap_hwmod omap3xxx_i2c1_hwmod = { + .name = "i2c1", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .mpu_irqs = omap2_i2c1_mpu_irqs, + .sdma_reqs = omap2_i2c1_sdma_reqs, + .main_clk = "i2c1_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_I2C1_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_I2C1_SHIFT, + }, + }, + .class = &i2c_class, + .dev_attr = &i2c1_dev_attr, +}; + +/* I2C2 */ +static struct omap_i2c_dev_attr i2c2_dev_attr = { + .fifo_depth = 8, /* bytes */ + .flags = OMAP_I2C_FLAG_BUS_SHIFT_2, +}; + +static struct omap_hwmod omap3xxx_i2c2_hwmod = { + .name = "i2c2", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .mpu_irqs = omap2_i2c2_mpu_irqs, + .sdma_reqs = omap2_i2c2_sdma_reqs, + .main_clk = "i2c2_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_I2C2_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_I2C2_SHIFT, + }, + }, + .class = &i2c_class, + .dev_attr = &i2c2_dev_attr, +}; + +/* I2C3 */ +static struct omap_i2c_dev_attr i2c3_dev_attr = { + .fifo_depth = 64, /* bytes */ + .flags = OMAP_I2C_FLAG_BUS_SHIFT_2, +}; + +static struct omap_hwmod_irq_info i2c3_mpu_irqs[] = { + { .irq = 61 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod_dma_info i2c3_sdma_reqs[] = { + { .name = "tx", .dma_req = 25 }, + { .name = "rx", .dma_req = 26 }, + { .dma_req = -1 } +}; + +static struct omap_hwmod omap3xxx_i2c3_hwmod = { + .name = "i2c3", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .mpu_irqs = i2c3_mpu_irqs, + .sdma_reqs = i2c3_sdma_reqs, + .main_clk = "i2c3_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_I2C3_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_I2C3_SHIFT, + }, + }, + .class = &i2c_class, + .dev_attr = &i2c3_dev_attr, +}; + +/* + * 'gpio' class + * general purpose io module + */ + +static struct omap_hwmod_class_sysconfig omap3xxx_gpio_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap3xxx_gpio_hwmod_class = { + .name = "gpio", + .sysc = &omap3xxx_gpio_sysc, + .rev = 1, +}; + +/* gpio_dev_attr */ +static struct omap_gpio_dev_attr gpio_dev_attr = { + .bank_width = 32, + .dbck_flag = true, +}; + +/* gpio1 */ +static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { + { .role = "dbclk", .clk = "gpio1_dbck", }, +}; + +static struct omap_hwmod omap3xxx_gpio1_hwmod = { + .name = "gpio1", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .mpu_irqs = omap2_gpio1_irqs, + .main_clk = "gpio1_ick", + .opt_clks = gpio1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_GPIO1_SHIFT, + .module_offs = WKUP_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_GPIO1_SHIFT, + }, + }, + .class = &omap3xxx_gpio_hwmod_class, + .dev_attr = &gpio_dev_attr, +}; + +/* gpio2 */ +static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { + { .role = "dbclk", .clk = "gpio2_dbck", }, +}; + +static struct omap_hwmod omap3xxx_gpio2_hwmod = { + .name = "gpio2", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .mpu_irqs = omap2_gpio2_irqs, + .main_clk = "gpio2_ick", + .opt_clks = gpio2_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_GPIO2_SHIFT, + .module_offs = OMAP3430_PER_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_GPIO2_SHIFT, + }, + }, + .class = &omap3xxx_gpio_hwmod_class, + .dev_attr = &gpio_dev_attr, +}; + +/* gpio3 */ +static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { + { .role = "dbclk", .clk = "gpio3_dbck", }, +}; + +static struct omap_hwmod omap3xxx_gpio3_hwmod = { + .name = "gpio3", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .mpu_irqs = omap2_gpio3_irqs, + .main_clk = "gpio3_ick", + .opt_clks = gpio3_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_GPIO3_SHIFT, + .module_offs = OMAP3430_PER_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_GPIO3_SHIFT, + }, + }, + .class = &omap3xxx_gpio_hwmod_class, + .dev_attr = &gpio_dev_attr, +}; + +/* gpio4 */ +static struct omap_hwmod_opt_clk gpio4_opt_clks[] = { + { .role = "dbclk", .clk = "gpio4_dbck", }, +}; + +static struct omap_hwmod omap3xxx_gpio4_hwmod = { + .name = "gpio4", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .mpu_irqs = omap2_gpio4_irqs, + .main_clk = "gpio4_ick", + .opt_clks = gpio4_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks), + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_GPIO4_SHIFT, + .module_offs = OMAP3430_PER_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_GPIO4_SHIFT, + }, + }, + .class = &omap3xxx_gpio_hwmod_class, + .dev_attr = &gpio_dev_attr, +}; + +/* gpio5 */ +static struct omap_hwmod_irq_info omap3xxx_gpio5_irqs[] = { + { .irq = 33 + OMAP_INTC_START, }, /* INT_34XX_GPIO_BANK5 */ + { .irq = -1 }, +}; + +static struct omap_hwmod_opt_clk gpio5_opt_clks[] = { + { .role = "dbclk", .clk = "gpio5_dbck", }, +}; + +static struct omap_hwmod omap3xxx_gpio5_hwmod = { + .name = "gpio5", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .mpu_irqs = omap3xxx_gpio5_irqs, + .main_clk = "gpio5_ick", + .opt_clks = gpio5_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks), + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_GPIO5_SHIFT, + .module_offs = OMAP3430_PER_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_GPIO5_SHIFT, + }, + }, + .class = &omap3xxx_gpio_hwmod_class, + .dev_attr = &gpio_dev_attr, +}; + +/* gpio6 */ +static struct omap_hwmod_irq_info omap3xxx_gpio6_irqs[] = { + { .irq = 34 + OMAP_INTC_START, }, /* INT_34XX_GPIO_BANK6 */ + { .irq = -1 }, +}; + +static struct omap_hwmod_opt_clk gpio6_opt_clks[] = { + { .role = "dbclk", .clk = "gpio6_dbck", }, +}; + +static struct omap_hwmod omap3xxx_gpio6_hwmod = { + .name = "gpio6", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .mpu_irqs = omap3xxx_gpio6_irqs, + .main_clk = "gpio6_ick", + .opt_clks = gpio6_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks), + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_GPIO6_SHIFT, + .module_offs = OMAP3430_PER_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_GPIO6_SHIFT, + }, + }, + .class = &omap3xxx_gpio_hwmod_class, + .dev_attr = &gpio_dev_attr, +}; + +/* dma attributes */ +static struct omap_dma_dev_attr dma_dev_attr = { + .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY | + IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY, + .lch_count = 32, +}; + +static struct omap_hwmod_class_sysconfig omap3xxx_dma_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x002c, + .syss_offs = 0x0028, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSC_HAS_MIDLEMODE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap3xxx_dma_hwmod_class = { + .name = "dma", + .sysc = &omap3xxx_dma_sysc, +}; + +/* dma_system */ +static struct omap_hwmod omap3xxx_dma_system_hwmod = { + .name = "dma", + .class = &omap3xxx_dma_hwmod_class, + .mpu_irqs = omap2_dma_system_irqs, + .main_clk = "core_l3_ick", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_ST_SDMA_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_SDMA_SHIFT, + }, + }, + .dev_attr = &dma_dev_attr, + .flags = HWMOD_NO_IDLEST, +}; + +/* + * 'mcbsp' class + * multi channel buffered serial port controller + */ + +static struct omap_hwmod_class_sysconfig omap3xxx_mcbsp_sysc = { + .sysc_offs = 0x008c, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, + .clockact = 0x2, +}; + +static struct omap_hwmod_class omap3xxx_mcbsp_hwmod_class = { + .name = "mcbsp", + .sysc = &omap3xxx_mcbsp_sysc, + .rev = MCBSP_CONFIG_TYPE3, +}; + +/* McBSP functional clock mapping */ +static struct omap_hwmod_opt_clk mcbsp15_opt_clks[] = { + { .role = "pad_fck", .clk = "mcbsp_clks" }, + { .role = "prcm_fck", .clk = "core_96m_fck" }, +}; + +static struct omap_hwmod_opt_clk mcbsp234_opt_clks[] = { + { .role = "pad_fck", .clk = "mcbsp_clks" }, + { .role = "prcm_fck", .clk = "per_96m_fck" }, +}; + +/* mcbsp1 */ +static struct omap_hwmod_irq_info omap3xxx_mcbsp1_irqs[] = { + { .name = "common", .irq = 16 + OMAP_INTC_START, }, + { .name = "tx", .irq = 59 + OMAP_INTC_START, }, + { .name = "rx", .irq = 60 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod omap3xxx_mcbsp1_hwmod = { + .name = "mcbsp1", + .class = &omap3xxx_mcbsp_hwmod_class, + .mpu_irqs = omap3xxx_mcbsp1_irqs, + .sdma_reqs = omap2_mcbsp1_sdma_reqs, + .main_clk = "mcbsp1_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MCBSP1_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MCBSP1_SHIFT, + }, + }, + .opt_clks = mcbsp15_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp15_opt_clks), +}; + +/* mcbsp2 */ +static struct omap_hwmod_irq_info omap3xxx_mcbsp2_irqs[] = { + { .name = "common", .irq = 17 + OMAP_INTC_START, }, + { .name = "tx", .irq = 62 + OMAP_INTC_START, }, + { .name = "rx", .irq = 63 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_mcbsp_dev_attr omap34xx_mcbsp2_dev_attr = { + .sidetone = "mcbsp2_sidetone", +}; + +static struct omap_hwmod omap3xxx_mcbsp2_hwmod = { + .name = "mcbsp2", + .class = &omap3xxx_mcbsp_hwmod_class, + .mpu_irqs = omap3xxx_mcbsp2_irqs, + .sdma_reqs = omap2_mcbsp2_sdma_reqs, + .main_clk = "mcbsp2_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MCBSP2_SHIFT, + .module_offs = OMAP3430_PER_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MCBSP2_SHIFT, + }, + }, + .opt_clks = mcbsp234_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp234_opt_clks), + .dev_attr = &omap34xx_mcbsp2_dev_attr, +}; + +/* mcbsp3 */ +static struct omap_hwmod_irq_info omap3xxx_mcbsp3_irqs[] = { + { .name = "common", .irq = 22 + OMAP_INTC_START, }, + { .name = "tx", .irq = 89 + OMAP_INTC_START, }, + { .name = "rx", .irq = 90 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_mcbsp_dev_attr omap34xx_mcbsp3_dev_attr = { + .sidetone = "mcbsp3_sidetone", +}; + +static struct omap_hwmod omap3xxx_mcbsp3_hwmod = { + .name = "mcbsp3", + .class = &omap3xxx_mcbsp_hwmod_class, + .mpu_irqs = omap3xxx_mcbsp3_irqs, + .sdma_reqs = omap2_mcbsp3_sdma_reqs, + .main_clk = "mcbsp3_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MCBSP3_SHIFT, + .module_offs = OMAP3430_PER_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MCBSP3_SHIFT, + }, + }, + .opt_clks = mcbsp234_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp234_opt_clks), + .dev_attr = &omap34xx_mcbsp3_dev_attr, +}; + +/* mcbsp4 */ +static struct omap_hwmod_irq_info omap3xxx_mcbsp4_irqs[] = { + { .name = "common", .irq = 23 + OMAP_INTC_START, }, + { .name = "tx", .irq = 54 + OMAP_INTC_START, }, + { .name = "rx", .irq = 55 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod_dma_info omap3xxx_mcbsp4_sdma_chs[] = { + { .name = "rx", .dma_req = 20 }, + { .name = "tx", .dma_req = 19 }, + { .dma_req = -1 } +}; + +static struct omap_hwmod omap3xxx_mcbsp4_hwmod = { + .name = "mcbsp4", + .class = &omap3xxx_mcbsp_hwmod_class, + .mpu_irqs = omap3xxx_mcbsp4_irqs, + .sdma_reqs = omap3xxx_mcbsp4_sdma_chs, + .main_clk = "mcbsp4_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MCBSP4_SHIFT, + .module_offs = OMAP3430_PER_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MCBSP4_SHIFT, + }, + }, + .opt_clks = mcbsp234_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp234_opt_clks), +}; + +/* mcbsp5 */ +static struct omap_hwmod_irq_info omap3xxx_mcbsp5_irqs[] = { + { .name = "common", .irq = 27 + OMAP_INTC_START, }, + { .name = "tx", .irq = 81 + OMAP_INTC_START, }, + { .name = "rx", .irq = 82 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod_dma_info omap3xxx_mcbsp5_sdma_chs[] = { + { .name = "rx", .dma_req = 22 }, + { .name = "tx", .dma_req = 21 }, + { .dma_req = -1 } +}; + +static struct omap_hwmod omap3xxx_mcbsp5_hwmod = { + .name = "mcbsp5", + .class = &omap3xxx_mcbsp_hwmod_class, + .mpu_irqs = omap3xxx_mcbsp5_irqs, + .sdma_reqs = omap3xxx_mcbsp5_sdma_chs, + .main_clk = "mcbsp5_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MCBSP5_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MCBSP5_SHIFT, + }, + }, + .opt_clks = mcbsp15_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp15_opt_clks), +}; + +/* 'mcbsp sidetone' class */ +static struct omap_hwmod_class_sysconfig omap3xxx_mcbsp_sidetone_sysc = { + .sysc_offs = 0x0010, + .sysc_flags = SYSC_HAS_AUTOIDLE, + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap3xxx_mcbsp_sidetone_hwmod_class = { + .name = "mcbsp_sidetone", + .sysc = &omap3xxx_mcbsp_sidetone_sysc, +}; + +/* mcbsp2_sidetone */ +static struct omap_hwmod_irq_info omap3xxx_mcbsp2_sidetone_irqs[] = { + { .name = "irq", .irq = 4 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod = { + .name = "mcbsp2_sidetone", + .class = &omap3xxx_mcbsp_sidetone_hwmod_class, + .mpu_irqs = omap3xxx_mcbsp2_sidetone_irqs, + .main_clk = "mcbsp2_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MCBSP2_SHIFT, + .module_offs = OMAP3430_PER_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MCBSP2_SHIFT, + }, + }, +}; + +/* mcbsp3_sidetone */ +static struct omap_hwmod_irq_info omap3xxx_mcbsp3_sidetone_irqs[] = { + { .name = "irq", .irq = 5 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod = { + .name = "mcbsp3_sidetone", + .class = &omap3xxx_mcbsp_sidetone_hwmod_class, + .mpu_irqs = omap3xxx_mcbsp3_sidetone_irqs, + .main_clk = "mcbsp3_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MCBSP3_SHIFT, + .module_offs = OMAP3430_PER_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MCBSP3_SHIFT, + }, + }, +}; + +/* SR common */ +static struct omap_hwmod_sysc_fields omap34xx_sr_sysc_fields = { + .clkact_shift = 20, +}; + +static struct omap_hwmod_class_sysconfig omap34xx_sr_sysc = { + .sysc_offs = 0x24, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_NO_CACHE), + .clockact = CLOCKACT_TEST_ICLK, + .sysc_fields = &omap34xx_sr_sysc_fields, +}; + +static struct omap_hwmod_class omap34xx_smartreflex_hwmod_class = { + .name = "smartreflex", + .sysc = &omap34xx_sr_sysc, + .rev = 1, +}; + +static struct omap_hwmod_sysc_fields omap36xx_sr_sysc_fields = { + .sidle_shift = 24, + .enwkup_shift = 26, +}; + +static struct omap_hwmod_class_sysconfig omap36xx_sr_sysc = { + .sysc_offs = 0x38, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP | + SYSC_NO_CACHE), + .sysc_fields = &omap36xx_sr_sysc_fields, +}; + +static struct omap_hwmod_class omap36xx_smartreflex_hwmod_class = { + .name = "smartreflex", + .sysc = &omap36xx_sr_sysc, + .rev = 2, +}; + +/* SR1 */ +static struct omap_smartreflex_dev_attr sr1_dev_attr = { + .sensor_voltdm_name = "mpu_iva", +}; + +static struct omap_hwmod_irq_info omap3_smartreflex_mpu_irqs[] = { + { .irq = 18 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod omap34xx_sr1_hwmod = { + .name = "smartreflex_mpu_iva", + .class = &omap34xx_smartreflex_hwmod_class, + .main_clk = "sr1_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_SR1_SHIFT, + .module_offs = WKUP_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_EN_SR1_SHIFT, + }, + }, + .dev_attr = &sr1_dev_attr, + .mpu_irqs = omap3_smartreflex_mpu_irqs, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +static struct omap_hwmod omap36xx_sr1_hwmod = { + .name = "smartreflex_mpu_iva", + .class = &omap36xx_smartreflex_hwmod_class, + .main_clk = "sr1_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_SR1_SHIFT, + .module_offs = WKUP_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_EN_SR1_SHIFT, + }, + }, + .dev_attr = &sr1_dev_attr, + .mpu_irqs = omap3_smartreflex_mpu_irqs, +}; + +/* SR2 */ +static struct omap_smartreflex_dev_attr sr2_dev_attr = { + .sensor_voltdm_name = "core", +}; + +static struct omap_hwmod_irq_info omap3_smartreflex_core_irqs[] = { + { .irq = 19 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod omap34xx_sr2_hwmod = { + .name = "smartreflex_core", + .class = &omap34xx_smartreflex_hwmod_class, + .main_clk = "sr2_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_SR2_SHIFT, + .module_offs = WKUP_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_EN_SR2_SHIFT, + }, + }, + .dev_attr = &sr2_dev_attr, + .mpu_irqs = omap3_smartreflex_core_irqs, + .flags = HWMOD_SET_DEFAULT_CLOCKACT, +}; + +static struct omap_hwmod omap36xx_sr2_hwmod = { + .name = "smartreflex_core", + .class = &omap36xx_smartreflex_hwmod_class, + .main_clk = "sr2_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_SR2_SHIFT, + .module_offs = WKUP_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_EN_SR2_SHIFT, + }, + }, + .dev_attr = &sr2_dev_attr, + .mpu_irqs = omap3_smartreflex_core_irqs, +}; + +/* + * 'mailbox' class + * mailbox module allowing communication between the on-chip processors + * using a queued mailbox-interrupt mechanism. + */ + +static struct omap_hwmod_class_sysconfig omap3xxx_mailbox_sysc = { + .rev_offs = 0x000, + .sysc_offs = 0x010, + .syss_offs = 0x014, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap3xxx_mailbox_hwmod_class = { + .name = "mailbox", + .sysc = &omap3xxx_mailbox_sysc, +}; + +static struct omap_mbox_dev_info omap3xxx_mailbox_info[] = { + { .name = "dsp", .tx_id = 0, .rx_id = 1 }, +}; + +static struct omap_mbox_pdata omap3xxx_mailbox_attrs = { + .num_users = 2, + .num_fifos = 2, + .info_cnt = ARRAY_SIZE(omap3xxx_mailbox_info), + .info = omap3xxx_mailbox_info, +}; + +static struct omap_hwmod_irq_info omap3xxx_mailbox_irqs[] = { + { .irq = 26 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod omap3xxx_mailbox_hwmod = { + .name = "mailbox", + .class = &omap3xxx_mailbox_hwmod_class, + .mpu_irqs = omap3xxx_mailbox_irqs, + .main_clk = "mailboxes_ick", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MAILBOXES_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MAILBOXES_SHIFT, + }, + }, + .dev_attr = &omap3xxx_mailbox_attrs, +}; + +/* + * 'mcspi' class + * multichannel serial port interface (mcspi) / master/slave synchronous serial + * bus + */ + +static struct omap_hwmod_class_sysconfig omap34xx_mcspi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap34xx_mcspi_class = { + .name = "mcspi", + .sysc = &omap34xx_mcspi_sysc, + .rev = OMAP3_MCSPI_REV, +}; + +/* mcspi1 */ +static struct omap2_mcspi_dev_attr omap_mcspi1_dev_attr = { + .num_chipselect = 4, +}; + +static struct omap_hwmod omap34xx_mcspi1 = { + .name = "mcspi1", + .mpu_irqs = omap2_mcspi1_mpu_irqs, + .sdma_reqs = omap2_mcspi1_sdma_reqs, + .main_clk = "mcspi1_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MCSPI1_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MCSPI1_SHIFT, + }, + }, + .class = &omap34xx_mcspi_class, + .dev_attr = &omap_mcspi1_dev_attr, +}; + +/* mcspi2 */ +static struct omap2_mcspi_dev_attr omap_mcspi2_dev_attr = { + .num_chipselect = 2, +}; + +static struct omap_hwmod omap34xx_mcspi2 = { + .name = "mcspi2", + .mpu_irqs = omap2_mcspi2_mpu_irqs, + .sdma_reqs = omap2_mcspi2_sdma_reqs, + .main_clk = "mcspi2_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MCSPI2_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MCSPI2_SHIFT, + }, + }, + .class = &omap34xx_mcspi_class, + .dev_attr = &omap_mcspi2_dev_attr, +}; + +/* mcspi3 */ +static struct omap_hwmod_irq_info omap34xx_mcspi3_mpu_irqs[] = { + { .name = "irq", .irq = 91 + OMAP_INTC_START, }, /* 91 */ + { .irq = -1 }, +}; + +static struct omap_hwmod_dma_info omap34xx_mcspi3_sdma_reqs[] = { + { .name = "tx0", .dma_req = 15 }, + { .name = "rx0", .dma_req = 16 }, + { .name = "tx1", .dma_req = 23 }, + { .name = "rx1", .dma_req = 24 }, + { .dma_req = -1 } +}; + +static struct omap2_mcspi_dev_attr omap_mcspi3_dev_attr = { + .num_chipselect = 2, +}; + +static struct omap_hwmod omap34xx_mcspi3 = { + .name = "mcspi3", + .mpu_irqs = omap34xx_mcspi3_mpu_irqs, + .sdma_reqs = omap34xx_mcspi3_sdma_reqs, + .main_clk = "mcspi3_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MCSPI3_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MCSPI3_SHIFT, + }, + }, + .class = &omap34xx_mcspi_class, + .dev_attr = &omap_mcspi3_dev_attr, +}; + +/* mcspi4 */ +static struct omap_hwmod_irq_info omap34xx_mcspi4_mpu_irqs[] = { + { .name = "irq", .irq = 48 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod_dma_info omap34xx_mcspi4_sdma_reqs[] = { + { .name = "tx0", .dma_req = 70 }, /* DMA_SPI4_TX0 */ + { .name = "rx0", .dma_req = 71 }, /* DMA_SPI4_RX0 */ + { .dma_req = -1 } +}; + +static struct omap2_mcspi_dev_attr omap_mcspi4_dev_attr = { + .num_chipselect = 1, +}; + +static struct omap_hwmod omap34xx_mcspi4 = { + .name = "mcspi4", + .mpu_irqs = omap34xx_mcspi4_mpu_irqs, + .sdma_reqs = omap34xx_mcspi4_sdma_reqs, + .main_clk = "mcspi4_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MCSPI4_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MCSPI4_SHIFT, + }, + }, + .class = &omap34xx_mcspi_class, + .dev_attr = &omap_mcspi4_dev_attr, +}; + +/* usbhsotg */ +static struct omap_hwmod_class_sysconfig omap3xxx_usbhsotg_sysc = { + .rev_offs = 0x0400, + .sysc_offs = 0x0404, + .syss_offs = 0x0408, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE| + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class usbotg_class = { + .name = "usbotg", + .sysc = &omap3xxx_usbhsotg_sysc, +}; + +/* usb_otg_hs */ +static struct omap_hwmod_irq_info omap3xxx_usbhsotg_mpu_irqs[] = { + + { .name = "mc", .irq = 92 + OMAP_INTC_START, }, + { .name = "dma", .irq = 93 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod omap3xxx_usbhsotg_hwmod = { + .name = "usb_otg_hs", + .mpu_irqs = omap3xxx_usbhsotg_mpu_irqs, + .main_clk = "hsotgusb_ick", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_HSOTGUSB_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT, + .idlest_stdby_bit = OMAP3430ES2_ST_HSOTGUSB_STDBY_SHIFT + }, + }, + .class = &usbotg_class, + + /* + * Erratum ID: i479 idle_req / idle_ack mechanism potentially + * broken when autoidle is enabled + * workaround is to disable the autoidle bit at module level. + * + * Enabling the device in any other MIDLEMODE setting but force-idle + * causes core_pwrdm not enter idle states at least on OMAP3630. + * Note that musb has OTG_FORCESTDBY register that controls MSTANDBY + * signal when MIDLEMODE is set to force-idle. + */ + .flags = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE + | HWMOD_FORCE_MSTANDBY, +}; + +/* usb_otg_hs */ +static struct omap_hwmod_irq_info am35xx_usbhsotg_mpu_irqs[] = { + { .name = "mc", .irq = 71 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod_class am35xx_usbotg_class = { + .name = "am35xx_usbotg", +}; + +static struct omap_hwmod am35xx_usbhsotg_hwmod = { + .name = "am35x_otg_hs", + .mpu_irqs = am35xx_usbhsotg_mpu_irqs, + .main_clk = "hsotgusb_fck", + .class = &am35xx_usbotg_class, + .flags = HWMOD_NO_IDLEST, +}; + +/* MMC/SD/SDIO common */ +static struct omap_hwmod_class_sysconfig omap34xx_mmc_sysc = { + .rev_offs = 0x1fc, + .sysc_offs = 0x10, + .syss_offs = 0x14, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap34xx_mmc_class = { + .name = "mmc", + .sysc = &omap34xx_mmc_sysc, +}; + +/* MMC/SD/SDIO1 */ + +static struct omap_hwmod_irq_info omap34xx_mmc1_mpu_irqs[] = { + { .irq = 83 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod_dma_info omap34xx_mmc1_sdma_reqs[] = { + { .name = "tx", .dma_req = 61, }, + { .name = "rx", .dma_req = 62, }, + { .dma_req = -1 } +}; + +static struct omap_hwmod_opt_clk omap34xx_mmc1_opt_clks[] = { + { .role = "dbck", .clk = "omap_32k_fck", }, +}; + +static struct omap_mmc_dev_attr mmc1_dev_attr = { + .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, +}; + +/* See 35xx errata 2.1.1.128 in SPRZ278F */ +static struct omap_mmc_dev_attr mmc1_pre_es3_dev_attr = { + .flags = (OMAP_HSMMC_SUPPORTS_DUAL_VOLT | + OMAP_HSMMC_BROKEN_MULTIBLOCK_READ), +}; + +static struct omap_hwmod omap3xxx_pre_es3_mmc1_hwmod = { + .name = "mmc1", + .mpu_irqs = omap34xx_mmc1_mpu_irqs, + .sdma_reqs = omap34xx_mmc1_sdma_reqs, + .opt_clks = omap34xx_mmc1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc1_opt_clks), + .main_clk = "mmchs1_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MMC1_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MMC1_SHIFT, + }, + }, + .dev_attr = &mmc1_pre_es3_dev_attr, + .class = &omap34xx_mmc_class, +}; + +static struct omap_hwmod omap3xxx_es3plus_mmc1_hwmod = { + .name = "mmc1", + .mpu_irqs = omap34xx_mmc1_mpu_irqs, + .sdma_reqs = omap34xx_mmc1_sdma_reqs, + .opt_clks = omap34xx_mmc1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc1_opt_clks), + .main_clk = "mmchs1_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MMC1_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MMC1_SHIFT, + }, + }, + .dev_attr = &mmc1_dev_attr, + .class = &omap34xx_mmc_class, +}; + +/* MMC/SD/SDIO2 */ + +static struct omap_hwmod_irq_info omap34xx_mmc2_mpu_irqs[] = { + { .irq = 86 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod_dma_info omap34xx_mmc2_sdma_reqs[] = { + { .name = "tx", .dma_req = 47, }, + { .name = "rx", .dma_req = 48, }, + { .dma_req = -1 } +}; + +static struct omap_hwmod_opt_clk omap34xx_mmc2_opt_clks[] = { + { .role = "dbck", .clk = "omap_32k_fck", }, +}; + +/* See 35xx errata 2.1.1.128 in SPRZ278F */ +static struct omap_mmc_dev_attr mmc2_pre_es3_dev_attr = { + .flags = OMAP_HSMMC_BROKEN_MULTIBLOCK_READ, +}; + +static struct omap_hwmod omap3xxx_pre_es3_mmc2_hwmod = { + .name = "mmc2", + .mpu_irqs = omap34xx_mmc2_mpu_irqs, + .sdma_reqs = omap34xx_mmc2_sdma_reqs, + .opt_clks = omap34xx_mmc2_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc2_opt_clks), + .main_clk = "mmchs2_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MMC2_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MMC2_SHIFT, + }, + }, + .dev_attr = &mmc2_pre_es3_dev_attr, + .class = &omap34xx_mmc_class, +}; + +static struct omap_hwmod omap3xxx_es3plus_mmc2_hwmod = { + .name = "mmc2", + .mpu_irqs = omap34xx_mmc2_mpu_irqs, + .sdma_reqs = omap34xx_mmc2_sdma_reqs, + .opt_clks = omap34xx_mmc2_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc2_opt_clks), + .main_clk = "mmchs2_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MMC2_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MMC2_SHIFT, + }, + }, + .class = &omap34xx_mmc_class, +}; + +/* MMC/SD/SDIO3 */ + +static struct omap_hwmod_irq_info omap34xx_mmc3_mpu_irqs[] = { + { .irq = 94 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod_dma_info omap34xx_mmc3_sdma_reqs[] = { + { .name = "tx", .dma_req = 77, }, + { .name = "rx", .dma_req = 78, }, + { .dma_req = -1 } +}; + +static struct omap_hwmod_opt_clk omap34xx_mmc3_opt_clks[] = { + { .role = "dbck", .clk = "omap_32k_fck", }, +}; + +static struct omap_hwmod omap3xxx_mmc3_hwmod = { + .name = "mmc3", + .mpu_irqs = omap34xx_mmc3_mpu_irqs, + .sdma_reqs = omap34xx_mmc3_sdma_reqs, + .opt_clks = omap34xx_mmc3_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc3_opt_clks), + .main_clk = "mmchs3_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MMC3_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MMC3_SHIFT, + }, + }, + .class = &omap34xx_mmc_class, +}; + +/* + * 'usb_host_hs' class + * high-speed multi-port usb host controller + */ + +static struct omap_hwmod_class_sysconfig omap3xxx_usb_host_hs_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap3xxx_usb_host_hs_hwmod_class = { + .name = "usb_host_hs", + .sysc = &omap3xxx_usb_host_hs_sysc, +}; + +static struct omap_hwmod_irq_info omap3xxx_usb_host_hs_irqs[] = { + { .name = "ohci-irq", .irq = 76 + OMAP_INTC_START, }, + { .name = "ehci-irq", .irq = 77 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod omap3xxx_usb_host_hs_hwmod = { + .name = "usb_host_hs", + .class = &omap3xxx_usb_host_hs_hwmod_class, + .clkdm_name = "usbhost_clkdm", + .mpu_irqs = omap3xxx_usb_host_hs_irqs, + .main_clk = "usbhost_48m_fck", + .prcm = { + .omap2 = { + .module_offs = OMAP3430ES2_USBHOST_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430ES2_EN_USBHOST1_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430ES2_ST_USBHOST_IDLE_SHIFT, + .idlest_stdby_bit = OMAP3430ES2_ST_USBHOST_STDBY_SHIFT, + }, + }, + + /* + * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock + * id: i660 + * + * Description: + * In the following configuration : + * - USBHOST module is set to smart-idle mode + * - PRCM asserts idle_req to the USBHOST module ( This typically + * happens when the system is going to a low power mode : all ports + * have been suspended, the master part of the USBHOST module has + * entered the standby state, and SW has cut the functional clocks) + * - an USBHOST interrupt occurs before the module is able to answer + * idle_ack, typically a remote wakeup IRQ. + * Then the USB HOST module will enter a deadlock situation where it + * is no more accessible nor functional. + * + * Workaround: + * Don't use smart idle; use only force idle, hence HWMOD_SWSUP_SIDLE + */ + + /* + * Errata: USB host EHCI may stall when entering smart-standby mode + * Id: i571 + * + * Description: + * When the USBHOST module is set to smart-standby mode, and when it is + * ready to enter the standby state (i.e. all ports are suspended and + * all attached devices are in suspend mode), then it can wrongly assert + * the Mstandby signal too early while there are still some residual OCP + * transactions ongoing. If this condition occurs, the internal state + * machine may go to an undefined state and the USB link may be stuck + * upon the next resume. + * + * Workaround: + * Don't use smart standby; use only force standby, + * hence HWMOD_SWSUP_MSTANDBY + */ + + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, +}; + +/* + * 'usb_tll_hs' class + * usb_tll_hs module is the adapter on the usb_host_hs ports + */ +static struct omap_hwmod_class_sysconfig omap3xxx_usb_tll_hs_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap3xxx_usb_tll_hs_hwmod_class = { + .name = "usb_tll_hs", + .sysc = &omap3xxx_usb_tll_hs_sysc, +}; + +static struct omap_hwmod_irq_info omap3xxx_usb_tll_hs_irqs[] = { + { .name = "tll-irq", .irq = 78 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod omap3xxx_usb_tll_hs_hwmod = { + .name = "usb_tll_hs", + .class = &omap3xxx_usb_tll_hs_hwmod_class, + .clkdm_name = "core_l4_clkdm", + .mpu_irqs = omap3xxx_usb_tll_hs_irqs, + .main_clk = "usbtll_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 3, + .module_bit = OMAP3430ES2_EN_USBTLL_SHIFT, + .idlest_reg_id = 3, + .idlest_idle_bit = OMAP3430ES2_ST_USBTLL_SHIFT, + }, + }, +}; + +static struct omap_hwmod omap3xxx_hdq1w_hwmod = { + .name = "hdq1w", + .mpu_irqs = omap2_hdq1w_mpu_irqs, + .main_clk = "hdq_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_HDQ_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_HDQ_SHIFT, + }, + }, + .class = &omap2_hdq1w_class, +}; + +/* SAD2D */ +static struct omap_hwmod_rst_info omap3xxx_sad2d_resets[] = { + { .name = "rst_modem_pwron_sw", .rst_shift = 0 }, + { .name = "rst_modem_sw", .rst_shift = 1 }, +}; + +static struct omap_hwmod_class omap3xxx_sad2d_class = { + .name = "sad2d", +}; + +static struct omap_hwmod omap3xxx_sad2d_hwmod = { + .name = "sad2d", + .rst_lines = omap3xxx_sad2d_resets, + .rst_lines_cnt = ARRAY_SIZE(omap3xxx_sad2d_resets), + .main_clk = "sad2d_ick", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_SAD2D_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_SAD2D_SHIFT, + }, + }, + .class = &omap3xxx_sad2d_class, +}; + +/* + * '32K sync counter' class + * 32-bit ordinary counter, clocked by the falling edge of the 32 khz clock + */ +static struct omap_hwmod_class_sysconfig omap3xxx_counter_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0004, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap3xxx_counter_hwmod_class = { + .name = "counter", + .sysc = &omap3xxx_counter_sysc, +}; + +static struct omap_hwmod omap3xxx_counter_32k_hwmod = { + .name = "counter_32k", + .class = &omap3xxx_counter_hwmod_class, + .clkdm_name = "wkup_clkdm", + .flags = HWMOD_SWSUP_SIDLE, + .main_clk = "wkup_32k_fck", + .prcm = { + .omap2 = { + .module_offs = WKUP_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_ST_32KSYNC_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_32KSYNC_SHIFT, + }, + }, +}; + +/* + * 'gpmc' class + * general purpose memory controller + */ + +static struct omap_hwmod_class_sysconfig omap3xxx_gpmc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap3xxx_gpmc_hwmod_class = { + .name = "gpmc", + .sysc = &omap3xxx_gpmc_sysc, +}; + +static struct omap_hwmod_irq_info omap3xxx_gpmc_irqs[] = { + { .irq = 20 + OMAP_INTC_START, }, + { .irq = -1 } +}; + +static struct omap_hwmod omap3xxx_gpmc_hwmod = { + .name = "gpmc", + .class = &omap3xxx_gpmc_hwmod_class, + .clkdm_name = "core_l3_clkdm", + .mpu_irqs = omap3xxx_gpmc_irqs, + .main_clk = "gpmc_fck", + /* + * XXX HWMOD_INIT_NO_RESET should not be needed for this IP + * block. It is not being added due to any known bugs with + * resetting the GPMC IP block, but rather because any timings + * set by the bootloader are not being correctly programmed by + * the kernel from the board file or DT data. + * HWMOD_INIT_NO_RESET should be removed ASAP. + */ + .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET | + HWMOD_NO_IDLEST), +}; + +/* + * interfaces + */ + +/* L3 -> L4_CORE interface */ +static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = { + .master = &omap3xxx_l3_main_hwmod, + .slave = &omap3xxx_l4_core_hwmod, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L3 -> L4_PER interface */ +static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_per = { + .master = &omap3xxx_l3_main_hwmod, + .slave = &omap3xxx_l4_per_hwmod, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_l3_main_addrs[] = { + { + .pa_start = 0x68000000, + .pa_end = 0x6800ffff, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +/* MPU -> L3 interface */ +static struct omap_hwmod_ocp_if omap3xxx_mpu__l3_main = { + .master = &omap3xxx_mpu_hwmod, + .slave = &omap3xxx_l3_main_hwmod, + .addr = omap3xxx_l3_main_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap3xxx_l4_emu_addrs[] = { + { + .pa_start = 0x54000000, + .pa_end = 0x547fffff, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +/* l3 -> debugss */ +static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_debugss = { + .master = &omap3xxx_l3_main_hwmod, + .slave = &omap3xxx_debugss_hwmod, + .addr = omap3xxx_l4_emu_addrs, + .user = OCP_USER_MPU, +}; + +/* DSS -> l3 */ +static struct omap_hwmod_ocp_if omap3430es1_dss__l3 = { + .master = &omap3430es1_dss_core_hwmod, + .slave = &omap3xxx_l3_main_hwmod, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if omap3xxx_dss__l3 = { + .master = &omap3xxx_dss_core_hwmod, + .slave = &omap3xxx_l3_main_hwmod, + .fw = { + .omap2 = { + .l3_perm_bit = OMAP3_L3_CORE_FW_INIT_ID_DSS, + .flags = OMAP_FIREWALL_L3, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_core -> usbhsotg interface */ +static struct omap_hwmod_ocp_if omap3xxx_usbhsotg__l3 = { + .master = &omap3xxx_usbhsotg_hwmod, + .slave = &omap3xxx_l3_main_hwmod, + .clk = "core_l3_ick", + .user = OCP_USER_MPU, +}; + +/* l3_core -> am35xx_usbhsotg interface */ +static struct omap_hwmod_ocp_if am35xx_usbhsotg__l3 = { + .master = &am35xx_usbhsotg_hwmod, + .slave = &omap3xxx_l3_main_hwmod, + .clk = "hsotgusb_ick", + .user = OCP_USER_MPU, +}; + +/* l3_core -> sad2d interface */ +static struct omap_hwmod_ocp_if omap3xxx_sad2d__l3 = { + .master = &omap3xxx_sad2d_hwmod, + .slave = &omap3xxx_l3_main_hwmod, + .clk = "core_l3_ick", + .user = OCP_USER_MPU, +}; + +/* L4_CORE -> L4_WKUP interface */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_l4_wkup_hwmod, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 CORE -> MMC1 interface */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__pre_es3_mmc1 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_pre_es3_mmc1_hwmod, + .clk = "mmchs1_ick", + .addr = omap2430_mmc1_addr_space, + .user = OCP_USER_MPU | OCP_USER_SDMA, + .flags = OMAP_FIREWALL_L4 +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_core__es3plus_mmc1 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_es3plus_mmc1_hwmod, + .clk = "mmchs1_ick", + .addr = omap2430_mmc1_addr_space, + .user = OCP_USER_MPU | OCP_USER_SDMA, + .flags = OMAP_FIREWALL_L4 +}; + +/* L4 CORE -> MMC2 interface */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__pre_es3_mmc2 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_pre_es3_mmc2_hwmod, + .clk = "mmchs2_ick", + .addr = omap2430_mmc2_addr_space, + .user = OCP_USER_MPU | OCP_USER_SDMA, + .flags = OMAP_FIREWALL_L4 +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_core__es3plus_mmc2 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_es3plus_mmc2_hwmod, + .clk = "mmchs2_ick", + .addr = omap2430_mmc2_addr_space, + .user = OCP_USER_MPU | OCP_USER_SDMA, + .flags = OMAP_FIREWALL_L4 +}; + +/* L4 CORE -> MMC3 interface */ +static struct omap_hwmod_addr_space omap3xxx_mmc3_addr_space[] = { + { + .pa_start = 0x480ad000, + .pa_end = 0x480ad1ff, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_core__mmc3 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_mmc3_hwmod, + .clk = "mmchs3_ick", + .addr = omap3xxx_mmc3_addr_space, + .user = OCP_USER_MPU | OCP_USER_SDMA, + .flags = OMAP_FIREWALL_L4 +}; + +/* L4 CORE -> UART1 interface */ +static struct omap_hwmod_addr_space omap3xxx_uart1_addr_space[] = { + { + .pa_start = OMAP3_UART1_BASE, + .pa_end = OMAP3_UART1_BASE + SZ_8K - 1, + .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT, + }, + { } +}; + +static struct omap_hwmod_ocp_if omap3_l4_core__uart1 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_uart1_hwmod, + .clk = "uart1_ick", + .addr = omap3xxx_uart1_addr_space, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 CORE -> UART2 interface */ +static struct omap_hwmod_addr_space omap3xxx_uart2_addr_space[] = { + { + .pa_start = OMAP3_UART2_BASE, + .pa_end = OMAP3_UART2_BASE + SZ_1K - 1, + .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT, + }, + { } +}; + +static struct omap_hwmod_ocp_if omap3_l4_core__uart2 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_uart2_hwmod, + .clk = "uart2_ick", + .addr = omap3xxx_uart2_addr_space, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 PER -> UART3 interface */ +static struct omap_hwmod_addr_space omap3xxx_uart3_addr_space[] = { + { + .pa_start = OMAP3_UART3_BASE, + .pa_end = OMAP3_UART3_BASE + SZ_1K - 1, + .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT, + }, + { } +}; + +static struct omap_hwmod_ocp_if omap3_l4_per__uart3 = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_uart3_hwmod, + .clk = "uart3_ick", + .addr = omap3xxx_uart3_addr_space, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 PER -> UART4 interface */ +static struct omap_hwmod_addr_space omap36xx_uart4_addr_space[] = { + { + .pa_start = OMAP3_UART4_BASE, + .pa_end = OMAP3_UART4_BASE + SZ_1K - 1, + .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT, + }, + { } +}; + +static struct omap_hwmod_ocp_if omap36xx_l4_per__uart4 = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap36xx_uart4_hwmod, + .clk = "uart4_ick", + .addr = omap36xx_uart4_addr_space, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* AM35xx: L4 CORE -> UART4 interface */ +static struct omap_hwmod_addr_space am35xx_uart4_addr_space[] = { + { + .pa_start = OMAP3_UART4_AM35XX_BASE, + .pa_end = OMAP3_UART4_AM35XX_BASE + SZ_1K - 1, + .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT, + }, + { } +}; + +static struct omap_hwmod_ocp_if am35xx_l4_core__uart4 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &am35xx_uart4_hwmod, + .clk = "uart4_ick", + .addr = am35xx_uart4_addr_space, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 CORE -> I2C1 interface */ +static struct omap_hwmod_ocp_if omap3_l4_core__i2c1 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_i2c1_hwmod, + .clk = "i2c1_ick", + .addr = omap2_i2c1_addr_space, + .fw = { + .omap2 = { + .l4_fw_region = OMAP3_L4_CORE_FW_I2C1_REGION, + .l4_prot_group = 7, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 CORE -> I2C2 interface */ +static struct omap_hwmod_ocp_if omap3_l4_core__i2c2 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_i2c2_hwmod, + .clk = "i2c2_ick", + .addr = omap2_i2c2_addr_space, + .fw = { + .omap2 = { + .l4_fw_region = OMAP3_L4_CORE_FW_I2C2_REGION, + .l4_prot_group = 7, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 CORE -> I2C3 interface */ +static struct omap_hwmod_addr_space omap3xxx_i2c3_addr_space[] = { + { + .pa_start = 0x48060000, + .pa_end = 0x48060000 + SZ_128 - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +static struct omap_hwmod_ocp_if omap3_l4_core__i2c3 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_i2c3_hwmod, + .clk = "i2c3_ick", + .addr = omap3xxx_i2c3_addr_space, + .fw = { + .omap2 = { + .l4_fw_region = OMAP3_L4_CORE_FW_I2C3_REGION, + .l4_prot_group = 7, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 CORE -> SR1 interface */ +static struct omap_hwmod_addr_space omap3_sr1_addr_space[] = { + { + .pa_start = OMAP34XX_SR1_BASE, + .pa_end = OMAP34XX_SR1_BASE + SZ_1K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +static struct omap_hwmod_ocp_if omap34xx_l4_core__sr1 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap34xx_sr1_hwmod, + .clk = "sr_l4_ick", + .addr = omap3_sr1_addr_space, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if omap36xx_l4_core__sr1 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap36xx_sr1_hwmod, + .clk = "sr_l4_ick", + .addr = omap3_sr1_addr_space, + .user = OCP_USER_MPU, +}; + +/* L4 CORE -> SR1 interface */ +static struct omap_hwmod_addr_space omap3_sr2_addr_space[] = { + { + .pa_start = OMAP34XX_SR2_BASE, + .pa_end = OMAP34XX_SR2_BASE + SZ_1K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +static struct omap_hwmod_ocp_if omap34xx_l4_core__sr2 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap34xx_sr2_hwmod, + .clk = "sr_l4_ick", + .addr = omap3_sr2_addr_space, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if omap36xx_l4_core__sr2 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap36xx_sr2_hwmod, + .clk = "sr_l4_ick", + .addr = omap3_sr2_addr_space, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap3xxx_usbhsotg_addrs[] = { + { + .pa_start = OMAP34XX_HSUSB_OTG_BASE, + .pa_end = OMAP34XX_HSUSB_OTG_BASE + SZ_4K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_core -> usbhsotg */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__usbhsotg = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_usbhsotg_hwmod, + .clk = "l4_ick", + .addr = omap3xxx_usbhsotg_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space am35xx_usbhsotg_addrs[] = { + { + .pa_start = AM35XX_IPSS_USBOTGSS_BASE, + .pa_end = AM35XX_IPSS_USBOTGSS_BASE + SZ_4K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_core -> usbhsotg */ +static struct omap_hwmod_ocp_if am35xx_l4_core__usbhsotg = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &am35xx_usbhsotg_hwmod, + .clk = "hsotgusb_ick", + .addr = am35xx_usbhsotg_addrs, + .user = OCP_USER_MPU, +}; + +/* L4_WKUP -> L4_SEC interface */ +static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__l4_sec = { + .master = &omap3xxx_l4_wkup_hwmod, + .slave = &omap3xxx_l4_sec_hwmod, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* IVA2 <- L3 interface */ +static struct omap_hwmod_ocp_if omap3xxx_l3__iva = { + .master = &omap3xxx_l3_main_hwmod, + .slave = &omap3xxx_iva_hwmod, + .clk = "core_l3_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_timer1_addrs[] = { + { + .pa_start = 0x48318000, + .pa_end = 0x48318000 + SZ_1K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_wkup -> timer1 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__timer1 = { + .master = &omap3xxx_l4_wkup_hwmod, + .slave = &omap3xxx_timer1_hwmod, + .clk = "gpt1_ick", + .addr = omap3xxx_timer1_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_timer2_addrs[] = { + { + .pa_start = 0x49032000, + .pa_end = 0x49032000 + SZ_1K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> timer2 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer2 = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_timer2_hwmod, + .clk = "gpt2_ick", + .addr = omap3xxx_timer2_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_timer3_addrs[] = { + { + .pa_start = 0x49034000, + .pa_end = 0x49034000 + SZ_1K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> timer3 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer3 = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_timer3_hwmod, + .clk = "gpt3_ick", + .addr = omap3xxx_timer3_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_timer4_addrs[] = { + { + .pa_start = 0x49036000, + .pa_end = 0x49036000 + SZ_1K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> timer4 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer4 = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_timer4_hwmod, + .clk = "gpt4_ick", + .addr = omap3xxx_timer4_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_timer5_addrs[] = { + { + .pa_start = 0x49038000, + .pa_end = 0x49038000 + SZ_1K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> timer5 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer5 = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_timer5_hwmod, + .clk = "gpt5_ick", + .addr = omap3xxx_timer5_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_timer6_addrs[] = { + { + .pa_start = 0x4903A000, + .pa_end = 0x4903A000 + SZ_1K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> timer6 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer6 = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_timer6_hwmod, + .clk = "gpt6_ick", + .addr = omap3xxx_timer6_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_timer7_addrs[] = { + { + .pa_start = 0x4903C000, + .pa_end = 0x4903C000 + SZ_1K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> timer7 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer7 = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_timer7_hwmod, + .clk = "gpt7_ick", + .addr = omap3xxx_timer7_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_timer8_addrs[] = { + { + .pa_start = 0x4903E000, + .pa_end = 0x4903E000 + SZ_1K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> timer8 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer8 = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_timer8_hwmod, + .clk = "gpt8_ick", + .addr = omap3xxx_timer8_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_timer9_addrs[] = { + { + .pa_start = 0x49040000, + .pa_end = 0x49040000 + SZ_1K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> timer9 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer9 = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_timer9_hwmod, + .clk = "gpt9_ick", + .addr = omap3xxx_timer9_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> timer10 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__timer10 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_timer10_hwmod, + .clk = "gpt10_ick", + .addr = omap2_timer10_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> timer11 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__timer11 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_timer11_hwmod, + .clk = "gpt11_ick", + .addr = omap2_timer11_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_timer12_addrs[] = { + { + .pa_start = 0x48304000, + .pa_end = 0x48304000 + SZ_1K - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_core -> timer12 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_sec__timer12 = { + .master = &omap3xxx_l4_sec_hwmod, + .slave = &omap3xxx_timer12_hwmod, + .clk = "gpt12_ick", + .addr = omap3xxx_timer12_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> wd_timer2 */ +static struct omap_hwmod_addr_space omap3xxx_wd_timer2_addrs[] = { + { + .pa_start = 0x48314000, + .pa_end = 0x4831407f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__wd_timer2 = { + .master = &omap3xxx_l4_wkup_hwmod, + .slave = &omap3xxx_wd_timer2_hwmod, + .clk = "wdt2_ick", + .addr = omap3xxx_wd_timer2_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> dss */ +static struct omap_hwmod_ocp_if omap3430es1_l4_core__dss = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3430es1_dss_core_hwmod, + .clk = "dss_ick", + .addr = omap2_dss_addrs, + .fw = { + .omap2 = { + .l4_fw_region = OMAP3ES1_L4_CORE_FW_DSS_CORE_REGION, + .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_dss_core_hwmod, + .clk = "dss_ick", + .addr = omap2_dss_addrs, + .fw = { + .omap2 = { + .l4_fw_region = OMAP3_L4_CORE_FW_DSS_CORE_REGION, + .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> dss_dispc */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dispc = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_dss_dispc_hwmod, + .clk = "dss_ick", + .addr = omap2_dss_dispc_addrs, + .fw = { + .omap2 = { + .l4_fw_region = OMAP3_L4_CORE_FW_DSS_DISPC_REGION, + .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_dss_dsi1_addrs[] = { + { + .pa_start = 0x4804FC00, + .pa_end = 0x4804FFFF, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_core -> dss_dsi1 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dsi1 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_dss_dsi1_hwmod, + .clk = "dss_ick", + .addr = omap3xxx_dss_dsi1_addrs, + .fw = { + .omap2 = { + .l4_fw_region = OMAP3_L4_CORE_FW_DSS_DSI_REGION, + .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> dss_rfbi */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_rfbi = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_dss_rfbi_hwmod, + .clk = "dss_ick", + .addr = omap2_dss_rfbi_addrs, + .fw = { + .omap2 = { + .l4_fw_region = OMAP3_L4_CORE_FW_DSS_RFBI_REGION, + .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP , + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> dss_venc */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_venc = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_dss_venc_hwmod, + .clk = "dss_ick", + .addr = omap2_dss_venc_addrs, + .fw = { + .omap2 = { + .l4_fw_region = OMAP3_L4_CORE_FW_DSS_VENC_REGION, + .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP, + .flags = OMAP_FIREWALL_L4, + } + }, + .flags = OCPIF_SWSUP_IDLE, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> gpio1 */ +static struct omap_hwmod_addr_space omap3xxx_gpio1_addrs[] = { + { + .pa_start = 0x48310000, + .pa_end = 0x483101ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__gpio1 = { + .master = &omap3xxx_l4_wkup_hwmod, + .slave = &omap3xxx_gpio1_hwmod, + .addr = omap3xxx_gpio1_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio2 */ +static struct omap_hwmod_addr_space omap3xxx_gpio2_addrs[] = { + { + .pa_start = 0x49050000, + .pa_end = 0x490501ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio2 = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_gpio2_hwmod, + .addr = omap3xxx_gpio2_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio3 */ +static struct omap_hwmod_addr_space omap3xxx_gpio3_addrs[] = { + { + .pa_start = 0x49052000, + .pa_end = 0x490521ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio3 = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_gpio3_hwmod, + .addr = omap3xxx_gpio3_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* + * 'mmu' class + * The memory management unit performs virtual to physical address translation + * for its requestors. + */ + +static struct omap_hwmod_class_sysconfig mmu_sysc = { + .rev_offs = 0x000, + .sysc_offs = 0x010, + .syss_offs = 0x014, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap3xxx_mmu_hwmod_class = { + .name = "mmu", + .sysc = &mmu_sysc, +}; + +/* mmu isp */ + +static struct omap_mmu_dev_attr mmu_isp_dev_attr = { + .da_start = 0x0, + .da_end = 0xfffff000, + .nr_tlb_entries = 8, +}; + +static struct omap_hwmod omap3xxx_mmu_isp_hwmod; +static struct omap_hwmod_irq_info omap3xxx_mmu_isp_irqs[] = { + { .irq = 24 + OMAP_INTC_START, }, + { .irq = -1 } +}; + +static struct omap_hwmod_addr_space omap3xxx_mmu_isp_addrs[] = { + { + .pa_start = 0x480bd400, + .pa_end = 0x480bd47f, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +/* l4_core -> mmu isp */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__mmu_isp = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_mmu_isp_hwmod, + .addr = omap3xxx_mmu_isp_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod omap3xxx_mmu_isp_hwmod = { + .name = "mmu_isp", + .class = &omap3xxx_mmu_hwmod_class, + .mpu_irqs = omap3xxx_mmu_isp_irqs, + .main_clk = "cam_ick", + .dev_attr = &mmu_isp_dev_attr, + .flags = HWMOD_NO_IDLEST, +}; + +/* mmu iva */ + +static struct omap_mmu_dev_attr mmu_iva_dev_attr = { + .da_start = 0x11000000, + .da_end = 0xfffff000, + .nr_tlb_entries = 32, +}; + +static struct omap_hwmod omap3xxx_mmu_iva_hwmod; +static struct omap_hwmod_irq_info omap3xxx_mmu_iva_irqs[] = { + { .irq = 28 + OMAP_INTC_START, }, + { .irq = -1 } +}; + +static struct omap_hwmod_rst_info omap3xxx_mmu_iva_resets[] = { + { .name = "mmu", .rst_shift = 1, .st_shift = 9 }, +}; + +static struct omap_hwmod_addr_space omap3xxx_mmu_iva_addrs[] = { + { + .pa_start = 0x5d000000, + .pa_end = 0x5d00007f, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +/* l3_main -> iva mmu */ +static struct omap_hwmod_ocp_if omap3xxx_l3_main__mmu_iva = { + .master = &omap3xxx_l3_main_hwmod, + .slave = &omap3xxx_mmu_iva_hwmod, + .addr = omap3xxx_mmu_iva_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod omap3xxx_mmu_iva_hwmod = { + .name = "mmu_iva", + .class = &omap3xxx_mmu_hwmod_class, + .mpu_irqs = omap3xxx_mmu_iva_irqs, + .clkdm_name = "iva2_clkdm", + .rst_lines = omap3xxx_mmu_iva_resets, + .rst_lines_cnt = ARRAY_SIZE(omap3xxx_mmu_iva_resets), + .main_clk = "iva2_ck", + .prcm = { + .omap2 = { + .module_offs = OMAP3430_IVA2_MOD, + .module_bit = OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_IVA2_SHIFT, + }, + }, + .dev_attr = &mmu_iva_dev_attr, + .flags = HWMOD_NO_IDLEST, +}; + +/* l4_per -> gpio4 */ +static struct omap_hwmod_addr_space omap3xxx_gpio4_addrs[] = { + { + .pa_start = 0x49054000, + .pa_end = 0x490541ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio4 = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_gpio4_hwmod, + .addr = omap3xxx_gpio4_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio5 */ +static struct omap_hwmod_addr_space omap3xxx_gpio5_addrs[] = { + { + .pa_start = 0x49056000, + .pa_end = 0x490561ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio5 = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_gpio5_hwmod, + .addr = omap3xxx_gpio5_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio6 */ +static struct omap_hwmod_addr_space omap3xxx_gpio6_addrs[] = { + { + .pa_start = 0x49058000, + .pa_end = 0x490581ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio6 = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_gpio6_hwmod, + .addr = omap3xxx_gpio6_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dma_system -> L3 */ +static struct omap_hwmod_ocp_if omap3xxx_dma_system__l3 = { + .master = &omap3xxx_dma_system_hwmod, + .slave = &omap3xxx_l3_main_hwmod, + .clk = "core_l3_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_dma_system_addrs[] = { + { + .pa_start = 0x48056000, + .pa_end = 0x48056fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> dma_system */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__dma_system = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_dma_system_hwmod, + .clk = "core_l4_ick", + .addr = omap3xxx_dma_system_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_mcbsp1_addrs[] = { + { + .name = "mpu", + .pa_start = 0x48074000, + .pa_end = 0x480740ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_core -> mcbsp1 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__mcbsp1 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_mcbsp1_hwmod, + .clk = "mcbsp1_ick", + .addr = omap3xxx_mcbsp1_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_mcbsp2_addrs[] = { + { + .name = "mpu", + .pa_start = 0x49022000, + .pa_end = 0x490220ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> mcbsp2 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp2 = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_mcbsp2_hwmod, + .clk = "mcbsp2_ick", + .addr = omap3xxx_mcbsp2_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_mcbsp3_addrs[] = { + { + .name = "mpu", + .pa_start = 0x49024000, + .pa_end = 0x490240ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> mcbsp3 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp3 = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_mcbsp3_hwmod, + .clk = "mcbsp3_ick", + .addr = omap3xxx_mcbsp3_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_mcbsp4_addrs[] = { + { + .name = "mpu", + .pa_start = 0x49026000, + .pa_end = 0x490260ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> mcbsp4 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp4 = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_mcbsp4_hwmod, + .clk = "mcbsp4_ick", + .addr = omap3xxx_mcbsp4_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_mcbsp5_addrs[] = { + { + .name = "mpu", + .pa_start = 0x48096000, + .pa_end = 0x480960ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_core -> mcbsp5 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__mcbsp5 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_mcbsp5_hwmod, + .clk = "mcbsp5_ick", + .addr = omap3xxx_mcbsp5_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_mcbsp2_sidetone_addrs[] = { + { + .name = "sidetone", + .pa_start = 0x49028000, + .pa_end = 0x490280ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> mcbsp2_sidetone */ +static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp2_sidetone = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_mcbsp2_sidetone_hwmod, + .clk = "mcbsp2_ick", + .addr = omap3xxx_mcbsp2_sidetone_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap3xxx_mcbsp3_sidetone_addrs[] = { + { + .name = "sidetone", + .pa_start = 0x4902A000, + .pa_end = 0x4902A0ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> mcbsp3_sidetone */ +static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp3_sidetone = { + .master = &omap3xxx_l4_per_hwmod, + .slave = &omap3xxx_mcbsp3_sidetone_hwmod, + .clk = "mcbsp3_ick", + .addr = omap3xxx_mcbsp3_sidetone_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap3xxx_mailbox_addrs[] = { + { + .pa_start = 0x48094000, + .pa_end = 0x480941ff, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +/* l4_core -> mailbox */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__mailbox = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_mailbox_hwmod, + .addr = omap3xxx_mailbox_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 core -> mcspi1 interface */ +static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi1 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap34xx_mcspi1, + .clk = "mcspi1_ick", + .addr = omap2_mcspi1_addr_space, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 core -> mcspi2 interface */ +static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi2 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap34xx_mcspi2, + .clk = "mcspi2_ick", + .addr = omap2_mcspi2_addr_space, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 core -> mcspi3 interface */ +static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi3 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap34xx_mcspi3, + .clk = "mcspi3_ick", + .addr = omap2430_mcspi3_addr_space, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 core -> mcspi4 interface */ +static struct omap_hwmod_addr_space omap34xx_mcspi4_addr_space[] = { + { + .pa_start = 0x480ba000, + .pa_end = 0x480ba0ff, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi4 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap34xx_mcspi4, + .clk = "mcspi4_ick", + .addr = omap34xx_mcspi4_addr_space, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if omap3xxx_usb_host_hs__l3_main_2 = { + .master = &omap3xxx_usb_host_hs_hwmod, + .slave = &omap3xxx_l3_main_hwmod, + .clk = "core_l3_ick", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap3xxx_usb_host_hs_addrs[] = { + { + .name = "uhh", + .pa_start = 0x48064000, + .pa_end = 0x480643ff, + .flags = ADDR_TYPE_RT + }, + { + .name = "ohci", + .pa_start = 0x48064400, + .pa_end = 0x480647ff, + }, + { + .name = "ehci", + .pa_start = 0x48064800, + .pa_end = 0x48064cff, + }, + {} +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_core__usb_host_hs = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_usb_host_hs_hwmod, + .clk = "usbhost_ick", + .addr = omap3xxx_usb_host_hs_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap3xxx_usb_tll_hs_addrs[] = { + { + .name = "tll", + .pa_start = 0x48062000, + .pa_end = 0x48062fff, + .flags = ADDR_TYPE_RT + }, + {} +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_core__usb_tll_hs = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_usb_tll_hs_hwmod, + .clk = "usbtll_ick", + .addr = omap3xxx_usb_tll_hs_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> hdq1w interface */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__hdq1w = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_hdq1w_hwmod, + .clk = "hdq_ick", + .addr = omap2_hdq1w_addr_space, + .user = OCP_USER_MPU | OCP_USER_SDMA, + .flags = OMAP_FIREWALL_L4 | OCPIF_SWSUP_IDLE, +}; + +/* l4_wkup -> 32ksync_counter */ +static struct omap_hwmod_addr_space omap3xxx_counter_32k_addrs[] = { + { + .pa_start = 0x48320000, + .pa_end = 0x4832001f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +static struct omap_hwmod_addr_space omap3xxx_gpmc_addrs[] = { + { + .pa_start = 0x6e000000, + .pa_end = 0x6e000fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__counter_32k = { + .master = &omap3xxx_l4_wkup_hwmod, + .slave = &omap3xxx_counter_32k_hwmod, + .clk = "omap_32ksync_ick", + .addr = omap3xxx_counter_32k_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* am35xx has Davinci MDIO & EMAC */ +static struct omap_hwmod_class am35xx_mdio_class = { + .name = "davinci_mdio", +}; + +static struct omap_hwmod am35xx_mdio_hwmod = { + .name = "davinci_mdio", + .class = &am35xx_mdio_class, + .flags = HWMOD_NO_IDLEST, +}; + +/* + * XXX Should be connected to an IPSS hwmod, not the L3 directly; + * but this will probably require some additional hwmod core support, + * so is left as a future to-do item. + */ +static struct omap_hwmod_ocp_if am35xx_mdio__l3 = { + .master = &am35xx_mdio_hwmod, + .slave = &omap3xxx_l3_main_hwmod, + .clk = "emac_fck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space am35xx_mdio_addrs[] = { + { + .pa_start = AM35XX_IPSS_MDIO_BASE, + .pa_end = AM35XX_IPSS_MDIO_BASE + SZ_4K - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +/* l4_core -> davinci mdio */ +/* + * XXX Should be connected to an IPSS hwmod, not the L4_CORE directly; + * but this will probably require some additional hwmod core support, + * so is left as a future to-do item. + */ +static struct omap_hwmod_ocp_if am35xx_l4_core__mdio = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &am35xx_mdio_hwmod, + .clk = "emac_fck", + .addr = am35xx_mdio_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_irq_info am35xx_emac_mpu_irqs[] = { + { .name = "rxthresh", .irq = 67 + OMAP_INTC_START, }, + { .name = "rx_pulse", .irq = 68 + OMAP_INTC_START, }, + { .name = "tx_pulse", .irq = 69 + OMAP_INTC_START }, + { .name = "misc_pulse", .irq = 70 + OMAP_INTC_START }, + { .irq = -1 }, +}; + +static struct omap_hwmod_class am35xx_emac_class = { + .name = "davinci_emac", +}; + +static struct omap_hwmod am35xx_emac_hwmod = { + .name = "davinci_emac", + .mpu_irqs = am35xx_emac_mpu_irqs, + .class = &am35xx_emac_class, + /* + * According to Mark Greer, the MPU will not return from WFI + * when the EMAC signals an interrupt. + * http://www.spinics.net/lists/arm-kernel/msg174734.html + */ + .flags = (HWMOD_NO_IDLEST | HWMOD_BLOCK_WFI), +}; + +/* l3_core -> davinci emac interface */ +/* + * XXX Should be connected to an IPSS hwmod, not the L3 directly; + * but this will probably require some additional hwmod core support, + * so is left as a future to-do item. + */ +static struct omap_hwmod_ocp_if am35xx_emac__l3 = { + .master = &am35xx_emac_hwmod, + .slave = &omap3xxx_l3_main_hwmod, + .clk = "emac_ick", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space am35xx_emac_addrs[] = { + { + .pa_start = AM35XX_IPSS_EMAC_BASE, + .pa_end = AM35XX_IPSS_EMAC_BASE + 0x30000 - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +/* l4_core -> davinci emac */ +/* + * XXX Should be connected to an IPSS hwmod, not the L4_CORE directly; + * but this will probably require some additional hwmod core support, + * so is left as a future to-do item. + */ +static struct omap_hwmod_ocp_if am35xx_l4_core__emac = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &am35xx_emac_hwmod, + .clk = "emac_ick", + .addr = am35xx_emac_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if omap3xxx_l3_main__gpmc = { + .master = &omap3xxx_l3_main_hwmod, + .slave = &omap3xxx_gpmc_hwmod, + .clk = "core_l3_ick", + .addr = omap3xxx_gpmc_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> SHAM2 (SHA1/MD5) (similar to omap24xx) */ +static struct omap_hwmod_sysc_fields omap3_sham_sysc_fields = { + .sidle_shift = 4, + .srst_shift = 1, + .autoidle_shift = 0, +}; + +static struct omap_hwmod_class_sysconfig omap3_sham_sysc = { + .rev_offs = 0x5c, + .sysc_offs = 0x60, + .syss_offs = 0x64, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), + .sysc_fields = &omap3_sham_sysc_fields, +}; + +static struct omap_hwmod_class omap3xxx_sham_class = { + .name = "sham", + .sysc = &omap3_sham_sysc, +}; + +static struct omap_hwmod_irq_info omap3_sham_mpu_irqs[] = { + { .irq = 49 + OMAP_INTC_START, }, + { .irq = -1 } +}; + +static struct omap_hwmod_dma_info omap3_sham_sdma_reqs[] = { + { .name = "rx", .dma_req = 69, }, + { .dma_req = -1 } +}; + +static struct omap_hwmod omap3xxx_sham_hwmod = { + .name = "sham", + .mpu_irqs = omap3_sham_mpu_irqs, + .sdma_reqs = omap3_sham_sdma_reqs, + .main_clk = "sha12_ick", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_SHA12_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_SHA12_SHIFT, + }, + }, + .class = &omap3xxx_sham_class, +}; + +static struct omap_hwmod_addr_space omap3xxx_sham_addrs[] = { + { + .pa_start = 0x480c3000, + .pa_end = 0x480c3000 + 0x64 - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_core__sham = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_sham_hwmod, + .clk = "sha12_ick", + .addr = omap3xxx_sham_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> AES */ +static struct omap_hwmod_sysc_fields omap3xxx_aes_sysc_fields = { + .sidle_shift = 6, + .srst_shift = 1, + .autoidle_shift = 0, +}; + +static struct omap_hwmod_class_sysconfig omap3_aes_sysc = { + .rev_offs = 0x44, + .sysc_offs = 0x48, + .syss_offs = 0x4c, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap3xxx_aes_sysc_fields, +}; + +static struct omap_hwmod_class omap3xxx_aes_class = { + .name = "aes", + .sysc = &omap3_aes_sysc, +}; + +static struct omap_hwmod_dma_info omap3_aes_sdma_reqs[] = { + { .name = "tx", .dma_req = 65, }, + { .name = "rx", .dma_req = 66, }, + { .dma_req = -1 } +}; + +static struct omap_hwmod omap3xxx_aes_hwmod = { + .name = "aes", + .sdma_reqs = omap3_aes_sdma_reqs, + .main_clk = "aes2_ick", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_AES2_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_AES2_SHIFT, + }, + }, + .class = &omap3xxx_aes_class, +}; + +static struct omap_hwmod_addr_space omap3xxx_aes_addrs[] = { + { + .pa_start = 0x480c5000, + .pa_end = 0x480c5000 + 0x50 - 1, + .flags = ADDR_TYPE_RT + }, + { } +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_core__aes = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_aes_hwmod, + .clk = "aes2_ick", + .addr = omap3xxx_aes_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* + * 'ssi' class + * synchronous serial interface (multichannel and full-duplex serial if) + */ + +static struct omap_hwmod_class_sysconfig omap34xx_ssi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_MIDLEMODE | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap34xx_ssi_hwmod_class = { + .name = "ssi", + .sysc = &omap34xx_ssi_sysc, +}; + +static struct omap_hwmod omap34xx_ssi_hwmod = { + .name = "ssi", + .class = &omap34xx_ssi_hwmod_class, + .clkdm_name = "core_l4_clkdm", + .main_clk = "ssi_ssr_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_SSI_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT, + }, + }, +}; + +/* L4 CORE -> SSI */ +static struct omap_hwmod_ocp_if omap34xx_l4_core__ssi = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap34xx_ssi_hwmod, + .clk = "ssi_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = { + &omap3xxx_l3_main__l4_core, + &omap3xxx_l3_main__l4_per, + &omap3xxx_mpu__l3_main, + &omap3xxx_l3_main__l4_debugss, + &omap3xxx_l4_core__l4_wkup, + &omap3xxx_l4_core__mmc3, + &omap3_l4_core__uart1, + &omap3_l4_core__uart2, + &omap3_l4_per__uart3, + &omap3_l4_core__i2c1, + &omap3_l4_core__i2c2, + &omap3_l4_core__i2c3, + &omap3xxx_l4_wkup__l4_sec, + &omap3xxx_l4_wkup__timer1, + &omap3xxx_l4_per__timer2, + &omap3xxx_l4_per__timer3, + &omap3xxx_l4_per__timer4, + &omap3xxx_l4_per__timer5, + &omap3xxx_l4_per__timer6, + &omap3xxx_l4_per__timer7, + &omap3xxx_l4_per__timer8, + &omap3xxx_l4_per__timer9, + &omap3xxx_l4_core__timer10, + &omap3xxx_l4_core__timer11, + &omap3xxx_l4_wkup__wd_timer2, + &omap3xxx_l4_wkup__gpio1, + &omap3xxx_l4_per__gpio2, + &omap3xxx_l4_per__gpio3, + &omap3xxx_l4_per__gpio4, + &omap3xxx_l4_per__gpio5, + &omap3xxx_l4_per__gpio6, + &omap3xxx_dma_system__l3, + &omap3xxx_l4_core__dma_system, + &omap3xxx_l4_core__mcbsp1, + &omap3xxx_l4_per__mcbsp2, + &omap3xxx_l4_per__mcbsp3, + &omap3xxx_l4_per__mcbsp4, + &omap3xxx_l4_core__mcbsp5, + &omap3xxx_l4_per__mcbsp2_sidetone, + &omap3xxx_l4_per__mcbsp3_sidetone, + &omap34xx_l4_core__mcspi1, + &omap34xx_l4_core__mcspi2, + &omap34xx_l4_core__mcspi3, + &omap34xx_l4_core__mcspi4, + &omap3xxx_l4_wkup__counter_32k, + &omap3xxx_l3_main__gpmc, + NULL, +}; + +/* GP-only hwmod links */ +static struct omap_hwmod_ocp_if *omap34xx_gp_hwmod_ocp_ifs[] __initdata = { + &omap3xxx_l4_sec__timer12, + &omap3xxx_l4_core__sham, + &omap3xxx_l4_core__aes, + NULL +}; + +static struct omap_hwmod_ocp_if *omap36xx_gp_hwmod_ocp_ifs[] __initdata = { + &omap3xxx_l4_sec__timer12, + &omap3xxx_l4_core__sham, + &omap3xxx_l4_core__aes, + NULL +}; + +static struct omap_hwmod_ocp_if *am35xx_gp_hwmod_ocp_ifs[] __initdata = { + &omap3xxx_l4_sec__timer12, + /* + * Apparently the SHA/MD5 and AES accelerator IP blocks are + * only present on some AM35xx chips, and no one knows which + * ones. See + * http://www.spinics.net/lists/arm-kernel/msg215466.html So + * if you need these IP blocks on an AM35xx, try uncommenting + * the following lines. + */ + /* &omap3xxx_l4_core__sham, */ + /* &omap3xxx_l4_core__aes, */ + NULL +}; + +/* 3430ES1-only hwmod links */ +static struct omap_hwmod_ocp_if *omap3430es1_hwmod_ocp_ifs[] __initdata = { + &omap3430es1_dss__l3, + &omap3430es1_l4_core__dss, + NULL +}; + +/* 3430ES2+-only hwmod links */ +static struct omap_hwmod_ocp_if *omap3430es2plus_hwmod_ocp_ifs[] __initdata = { + &omap3xxx_dss__l3, + &omap3xxx_l4_core__dss, + &omap3xxx_usbhsotg__l3, + &omap3xxx_l4_core__usbhsotg, + &omap3xxx_usb_host_hs__l3_main_2, + &omap3xxx_l4_core__usb_host_hs, + &omap3xxx_l4_core__usb_tll_hs, + NULL +}; + +/* <= 3430ES3-only hwmod links */ +static struct omap_hwmod_ocp_if *omap3430_pre_es3_hwmod_ocp_ifs[] __initdata = { + &omap3xxx_l4_core__pre_es3_mmc1, + &omap3xxx_l4_core__pre_es3_mmc2, + NULL +}; + +/* 3430ES3+-only hwmod links */ +static struct omap_hwmod_ocp_if *omap3430_es3plus_hwmod_ocp_ifs[] __initdata = { + &omap3xxx_l4_core__es3plus_mmc1, + &omap3xxx_l4_core__es3plus_mmc2, + NULL +}; + +/* 34xx-only hwmod links (all ES revisions) */ +static struct omap_hwmod_ocp_if *omap34xx_hwmod_ocp_ifs[] __initdata = { + &omap3xxx_l3__iva, + &omap34xx_l4_core__sr1, + &omap34xx_l4_core__sr2, + &omap3xxx_l4_core__mailbox, + &omap3xxx_l4_core__hdq1w, + &omap3xxx_sad2d__l3, + &omap3xxx_l4_core__mmu_isp, + &omap3xxx_l3_main__mmu_iva, + &omap34xx_l4_core__ssi, + NULL +}; + +/* 36xx-only hwmod links (all ES revisions) */ +static struct omap_hwmod_ocp_if *omap36xx_hwmod_ocp_ifs[] __initdata = { + &omap3xxx_l3__iva, + &omap36xx_l4_per__uart4, + &omap3xxx_dss__l3, + &omap3xxx_l4_core__dss, + &omap36xx_l4_core__sr1, + &omap36xx_l4_core__sr2, + &omap3xxx_usbhsotg__l3, + &omap3xxx_l4_core__usbhsotg, + &omap3xxx_l4_core__mailbox, + &omap3xxx_usb_host_hs__l3_main_2, + &omap3xxx_l4_core__usb_host_hs, + &omap3xxx_l4_core__usb_tll_hs, + &omap3xxx_l4_core__es3plus_mmc1, + &omap3xxx_l4_core__es3plus_mmc2, + &omap3xxx_l4_core__hdq1w, + &omap3xxx_sad2d__l3, + &omap3xxx_l4_core__mmu_isp, + &omap3xxx_l3_main__mmu_iva, + NULL +}; + +static struct omap_hwmod_ocp_if *am35xx_hwmod_ocp_ifs[] __initdata = { + &omap3xxx_dss__l3, + &omap3xxx_l4_core__dss, + &am35xx_usbhsotg__l3, + &am35xx_l4_core__usbhsotg, + &am35xx_l4_core__uart4, + &omap3xxx_usb_host_hs__l3_main_2, + &omap3xxx_l4_core__usb_host_hs, + &omap3xxx_l4_core__usb_tll_hs, + &omap3xxx_l4_core__es3plus_mmc1, + &omap3xxx_l4_core__es3plus_mmc2, + &omap3xxx_l4_core__hdq1w, + &am35xx_mdio__l3, + &am35xx_l4_core__mdio, + &am35xx_emac__l3, + &am35xx_l4_core__emac, + NULL +}; + +static struct omap_hwmod_ocp_if *omap3xxx_dss_hwmod_ocp_ifs[] __initdata = { + &omap3xxx_l4_core__dss_dispc, + &omap3xxx_l4_core__dss_dsi1, + &omap3xxx_l4_core__dss_rfbi, + &omap3xxx_l4_core__dss_venc, + NULL +}; + +int __init omap3xxx_hwmod_init(void) +{ + int r; + struct omap_hwmod_ocp_if **h = NULL, **h_gp = NULL; + unsigned int rev; + + omap_hwmod_init(); + + /* Register hwmod links common to all OMAP3 */ + r = omap_hwmod_register_links(omap3xxx_hwmod_ocp_ifs); + if (r < 0) + return r; + + rev = omap_rev(); + + /* + * Register hwmod links common to individual OMAP3 families, all + * silicon revisions (e.g., 34xx, or AM3505/3517, or 36xx) + * All possible revisions should be included in this conditional. + */ + if (rev == OMAP3430_REV_ES1_0 || rev == OMAP3430_REV_ES2_0 || + rev == OMAP3430_REV_ES2_1 || rev == OMAP3430_REV_ES3_0 || + rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2) { + h = omap34xx_hwmod_ocp_ifs; + h_gp = omap34xx_gp_hwmod_ocp_ifs; + } else if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) { + h = am35xx_hwmod_ocp_ifs; + h_gp = am35xx_gp_hwmod_ocp_ifs; + } else if (rev == OMAP3630_REV_ES1_0 || rev == OMAP3630_REV_ES1_1 || + rev == OMAP3630_REV_ES1_2) { + h = omap36xx_hwmod_ocp_ifs; + h_gp = omap36xx_gp_hwmod_ocp_ifs; + } else { + WARN(1, "OMAP3 hwmod family init: unknown chip type\n"); + return -EINVAL; + } + + r = omap_hwmod_register_links(h); + if (r < 0) + return r; + + /* Register GP-only hwmod links. */ + if (h_gp && omap_type() == OMAP2_DEVICE_TYPE_GP) { + r = omap_hwmod_register_links(h_gp); + if (r < 0) + return r; + } + + + /* + * Register hwmod links specific to certain ES levels of a + * particular family of silicon (e.g., 34xx ES1.0) + */ + h = NULL; + if (rev == OMAP3430_REV_ES1_0) { + h = omap3430es1_hwmod_ocp_ifs; + } else if (rev == OMAP3430_REV_ES2_0 || rev == OMAP3430_REV_ES2_1 || + rev == OMAP3430_REV_ES3_0 || rev == OMAP3430_REV_ES3_1 || + rev == OMAP3430_REV_ES3_1_2) { + h = omap3430es2plus_hwmod_ocp_ifs; + } + + if (h) { + r = omap_hwmod_register_links(h); + if (r < 0) + return r; + } + + h = NULL; + if (rev == OMAP3430_REV_ES1_0 || rev == OMAP3430_REV_ES2_0 || + rev == OMAP3430_REV_ES2_1) { + h = omap3430_pre_es3_hwmod_ocp_ifs; + } else if (rev == OMAP3430_REV_ES3_0 || rev == OMAP3430_REV_ES3_1 || + rev == OMAP3430_REV_ES3_1_2) { + h = omap3430_es3plus_hwmod_ocp_ifs; + } + + if (h) + r = omap_hwmod_register_links(h); + if (r < 0) + return r; + + /* + * DSS code presumes that dss_core hwmod is handled first, + * _before_ any other DSS related hwmods so register common + * DSS hwmod links last to ensure that dss_core is already + * registered. Otherwise some change things may happen, for + * ex. if dispc is handled before dss_core and DSS is enabled + * in bootloader DISPC will be reset with outputs enabled + * which sometimes leads to unrecoverable L3 error. XXX The + * long-term fix to this is to ensure hwmods are set up in + * dependency order in the hwmod core code. + */ + r = omap_hwmod_register_links(omap3xxx_dss_hwmod_ocp_ifs); + + return r; +} diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c new file mode 100644 index 00000000000..5c2cc8083fd --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c @@ -0,0 +1,759 @@ +/* + * Copyright (C) 2013 Texas Instruments Incorporated + * + * Hwmod present only in AM43x and those that differ other than register + * offsets as compared to AM335x. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/platform_data/gpio-omap.h> +#include <linux/platform_data/spi-omap2-mcspi.h> +#include "omap_hwmod.h" +#include "omap_hwmod_33xx_43xx_common_data.h" +#include "prcm43xx.h" + +/* IP blocks */ +static struct omap_hwmod am43xx_l4_hs_hwmod = { + .name = "l4_hs", + .class = &am33xx_l4_hwmod_class, + .clkdm_name = "l3_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "l4hs_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_L4HS_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_rst_info am33xx_wkup_m3_resets[] = { + { .name = "wkup_m3", .rst_shift = 3, .st_shift = 5 }, +}; + +static struct omap_hwmod am43xx_wkup_m3_hwmod = { + .name = "wkup_m3", + .class = &am33xx_wkup_m3_hwmod_class, + .clkdm_name = "l4_wkup_aon_clkdm", + /* Keep hardreset asserted */ + .flags = HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST, + .main_clk = "sys_clkin_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET, + .rstctrl_offs = AM43XX_RM_WKUP_RSTCTRL_OFFSET, + .rstst_offs = AM43XX_RM_WKUP_RSTST_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .rst_lines = am33xx_wkup_m3_resets, + .rst_lines_cnt = ARRAY_SIZE(am33xx_wkup_m3_resets), +}; + +static struct omap_hwmod am43xx_control_hwmod = { + .name = "control", + .class = &am33xx_control_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "sys_clkin_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_opt_clk gpio0_opt_clks[] = { + { .role = "dbclk", .clk = "gpio0_dbclk" }, +}; + +static struct omap_hwmod am43xx_gpio0_hwmod = { + .name = "gpio1", + .class = &am33xx_gpio_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "sys_clkin_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = gpio0_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio0_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +static struct omap_hwmod_class_sysconfig am43xx_synctimer_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x4, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class am43xx_synctimer_hwmod_class = { + .name = "synctimer", + .sysc = &am43xx_synctimer_sysc, +}; + +static struct omap_hwmod am43xx_synctimer_hwmod = { + .name = "counter_32k", + .class = &am43xx_synctimer_hwmod_class, + .clkdm_name = "l4_wkup_aon_clkdm", + .flags = HWMOD_SWSUP_SIDLE, + .main_clk = "synctimer_32kclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_timer8_hwmod = { + .name = "timer8", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer8_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_TIMER8_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_timer9_hwmod = { + .name = "timer9", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer9_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_TIMER9_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_timer10_hwmod = { + .name = "timer10", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer10_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_TIMER10_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_timer11_hwmod = { + .name = "timer11", + .class = &am33xx_timer_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "timer11_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_TIMER11_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_epwmss3_hwmod = { + .name = "epwmss3", + .class = &am33xx_epwmss_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_EPWMSS3_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_ehrpwm3_hwmod = { + .name = "ehrpwm3", + .class = &am33xx_ehrpwm_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +static struct omap_hwmod am43xx_epwmss4_hwmod = { + .name = "epwmss4", + .class = &am33xx_epwmss_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_EPWMSS4_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_ehrpwm4_hwmod = { + .name = "ehrpwm4", + .class = &am33xx_ehrpwm_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +static struct omap_hwmod am43xx_epwmss5_hwmod = { + .name = "epwmss5", + .class = &am33xx_epwmss_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_EPWMSS5_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_ehrpwm5_hwmod = { + .name = "ehrpwm5", + .class = &am33xx_ehrpwm_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", +}; + +static struct omap_hwmod am43xx_spi2_hwmod = { + .name = "spi2", + .class = &am33xx_spi_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_SPI2_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi_attrib, +}; + +static struct omap_hwmod am43xx_spi3_hwmod = { + .name = "spi3", + .class = &am33xx_spi_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_SPI3_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi_attrib, +}; + +static struct omap_hwmod am43xx_spi4_hwmod = { + .name = "spi4", + .class = &am33xx_spi_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "dpll_per_m2_div4_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_SPI4_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi_attrib, +}; + +static struct omap_hwmod_opt_clk gpio4_opt_clks[] = { + { .role = "dbclk", .clk = "gpio4_dbclk" }, +}; + +static struct omap_hwmod am43xx_gpio4_hwmod = { + .name = "gpio5", + .class = &am33xx_gpio_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_GPIO4_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = gpio4_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +static struct omap_hwmod_opt_clk gpio5_opt_clks[] = { + { .role = "dbclk", .clk = "gpio5_dbclk" }, +}; + +static struct omap_hwmod am43xx_gpio5_hwmod = { + .name = "gpio6", + .class = &am33xx_gpio_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_GPIO5_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = gpio5_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +static struct omap_hwmod_class am43xx_ocp2scp_hwmod_class = { + .name = "ocp2scp", +}; + +static struct omap_hwmod am43xx_ocp2scp0_hwmod = { + .name = "ocp2scp0", + .class = &am43xx_ocp2scp_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_USBPHYOCP2SCP0_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_ocp2scp1_hwmod = { + .name = "ocp2scp1", + .class = &am43xx_ocp2scp_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_USBPHYOCP2SCP1_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_class_sysconfig am43xx_usb_otg_ss_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_DMADISABLE | SYSC_HAS_MIDLEMODE | + SYSC_HAS_SIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | + MSTANDBY_NO | MSTANDBY_SMART | + MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class am43xx_usb_otg_ss_hwmod_class = { + .name = "usb_otg_ss", + .sysc = &am43xx_usb_otg_ss_sysc, +}; + +static struct omap_hwmod am43xx_usb_otg_ss0_hwmod = { + .name = "usb_otg_ss0", + .class = &am43xx_usb_otg_ss_hwmod_class, + .clkdm_name = "l3s_clkdm", + .main_clk = "l3s_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_USB_OTG_SS0_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod am43xx_usb_otg_ss1_hwmod = { + .name = "usb_otg_ss1", + .class = &am43xx_usb_otg_ss_hwmod_class, + .clkdm_name = "l3s_clkdm", + .main_clk = "l3s_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_USB_OTG_SS1_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_class_sysconfig am43xx_qspi_sysc = { + .sysc_offs = 0x0010, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class am43xx_qspi_hwmod_class = { + .name = "qspi", + .sysc = &am43xx_qspi_sysc, +}; + +static struct omap_hwmod am43xx_qspi_hwmod = { + .name = "qspi", + .class = &am43xx_qspi_hwmod_class, + .clkdm_name = "l3s_clkdm", + .main_clk = "l3s_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_QSPI_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* Interfaces */ +static struct omap_hwmod_ocp_if am43xx_l3_main__l4_hs = { + .master = &am33xx_l3_main_hwmod, + .slave = &am43xx_l4_hs_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_wkup_m3__l4_wkup = { + .master = &am43xx_wkup_m3_hwmod, + .slave = &am33xx_l4_wkup_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_wkup__wkup_m3 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am43xx_wkup_m3_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_l3_main__pruss = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_pruss_hwmod, + .clk = "dpll_core_m4_ck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_wkup__smartreflex0 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_smartreflex0_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_wkup__smartreflex1 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_smartreflex1_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_wkup__control = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am43xx_control_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_wkup__i2c1 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_i2c1_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_wkup__gpio0 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am43xx_gpio0_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_hs__cpgmac0 = { + .master = &am43xx_l4_hs_hwmod, + .slave = &am33xx_cpgmac0_hwmod, + .clk = "cpsw_125mhz_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_wkup__timer1 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_timer1_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_wkup__uart1 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_uart1_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_wkup__wd_timer1 = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am33xx_wd_timer1_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am33xx_l4_wkup__synctimer = { + .master = &am33xx_l4_wkup_hwmod, + .slave = &am43xx_synctimer_hwmod, + .clk = "sys_clkin_ck", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__timer8 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_timer8_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__timer9 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_timer9_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__timer10 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_timer10_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__timer11 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_timer11_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss3 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_epwmss3_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_epwmss3__ehrpwm3 = { + .master = &am43xx_epwmss3_hwmod, + .slave = &am43xx_ehrpwm3_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss4 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_epwmss4_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_epwmss4__ehrpwm4 = { + .master = &am43xx_epwmss4_hwmod, + .slave = &am43xx_ehrpwm4_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss5 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_epwmss5_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_epwmss5__ehrpwm5 = { + .master = &am43xx_epwmss5_hwmod, + .slave = &am43xx_ehrpwm5_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi2 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_spi2_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi3 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_spi3_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi4 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_spi4_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__gpio4 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_gpio4_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__gpio5 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_gpio5_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__ocp2scp0 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_ocp2scp0_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l4_ls__ocp2scp1 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am43xx_ocp2scp1_hwmod, + .clk = "l4ls_gclk", + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if am43xx_l3_s__usbotgss0 = { + .master = &am33xx_l3_s_hwmod, + .slave = &am43xx_usb_otg_ss0_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_l3_s__usbotgss1 = { + .master = &am33xx_l3_s_hwmod, + .slave = &am43xx_usb_otg_ss1_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if am43xx_l3_s__qspi = { + .master = &am33xx_l3_s_hwmod, + .slave = &am43xx_qspi_hwmod, + .clk = "l3s_gclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { + &am33xx_l4_wkup__synctimer, + &am43xx_l4_ls__timer8, + &am43xx_l4_ls__timer9, + &am43xx_l4_ls__timer10, + &am43xx_l4_ls__timer11, + &am43xx_l4_ls__epwmss3, + &am43xx_epwmss3__ehrpwm3, + &am43xx_l4_ls__epwmss4, + &am43xx_epwmss4__ehrpwm4, + &am43xx_l4_ls__epwmss5, + &am43xx_epwmss5__ehrpwm5, + &am43xx_l4_ls__mcspi2, + &am43xx_l4_ls__mcspi3, + &am43xx_l4_ls__mcspi4, + &am43xx_l4_ls__gpio4, + &am43xx_l4_ls__gpio5, + &am43xx_l3_main__pruss, + &am33xx_mpu__l3_main, + &am33xx_mpu__prcm, + &am33xx_l3_s__l4_ls, + &am33xx_l3_s__l4_wkup, + &am43xx_l3_main__l4_hs, + &am33xx_l3_main__l3_s, + &am33xx_l3_main__l3_instr, + &am33xx_l3_main__gfx, + &am33xx_l3_s__l3_main, + &am33xx_pruss__l3_main, + &am43xx_wkup_m3__l4_wkup, + &am33xx_gfx__l3_main, + &am43xx_l4_wkup__wkup_m3, + &am43xx_l4_wkup__control, + &am43xx_l4_wkup__smartreflex0, + &am43xx_l4_wkup__smartreflex1, + &am43xx_l4_wkup__uart1, + &am43xx_l4_wkup__timer1, + &am43xx_l4_wkup__i2c1, + &am43xx_l4_wkup__gpio0, + &am43xx_l4_wkup__wd_timer1, + &am43xx_l3_s__qspi, + &am33xx_l4_per__dcan0, + &am33xx_l4_per__dcan1, + &am33xx_l4_per__gpio1, + &am33xx_l4_per__gpio2, + &am33xx_l4_per__gpio3, + &am33xx_l4_per__i2c2, + &am33xx_l4_per__i2c3, + &am33xx_l4_per__mailbox, + &am33xx_l4_ls__mcasp0, + &am33xx_l4_ls__mcasp1, + &am33xx_l4_ls__mmc0, + &am33xx_l4_ls__mmc1, + &am33xx_l3_s__mmc2, + &am33xx_l4_ls__timer2, + &am33xx_l4_ls__timer3, + &am33xx_l4_ls__timer4, + &am33xx_l4_ls__timer5, + &am33xx_l4_ls__timer6, + &am33xx_l4_ls__timer7, + &am33xx_l3_main__tpcc, + &am33xx_l4_ls__uart2, + &am33xx_l4_ls__uart3, + &am33xx_l4_ls__uart4, + &am33xx_l4_ls__uart5, + &am33xx_l4_ls__uart6, + &am33xx_l4_ls__spinlock, + &am33xx_l4_ls__elm, + &am33xx_l4_ls__epwmss0, + &am33xx_epwmss0__ecap0, + &am33xx_epwmss0__eqep0, + &am33xx_epwmss0__ehrpwm0, + &am33xx_l4_ls__epwmss1, + &am33xx_epwmss1__ecap1, + &am33xx_epwmss1__eqep1, + &am33xx_epwmss1__ehrpwm1, + &am33xx_l4_ls__epwmss2, + &am33xx_epwmss2__ecap2, + &am33xx_epwmss2__eqep2, + &am33xx_epwmss2__ehrpwm2, + &am33xx_l3_s__gpmc, + &am33xx_l4_ls__mcspi0, + &am33xx_l4_ls__mcspi1, + &am33xx_l3_main__tptc0, + &am33xx_l3_main__tptc1, + &am33xx_l3_main__tptc2, + &am33xx_l3_main__ocmc, + &am43xx_l4_hs__cpgmac0, + &am33xx_cpgmac0__mdio, + &am33xx_l3_main__sha0, + &am33xx_l3_main__aes0, + &am43xx_l4_ls__ocp2scp0, + &am43xx_l4_ls__ocp2scp1, + &am43xx_l3_s__usbotgss0, + &am43xx_l3_s__usbotgss1, + NULL, +}; + +int __init am43xx_hwmod_init(void) +{ + omap_hwmod_am43xx_reg(); + omap_hwmod_init(); + return omap_hwmod_register_links(am43xx_hwmod_ocp_ifs); +} diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c new file mode 100644 index 00000000000..41e54f75993 --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -0,0 +1,4866 @@ +/* + * Hardware modules present on the OMAP44xx chips + * + * Copyright (C) 2009-2012 Texas Instruments, Inc. + * Copyright (C) 2009-2010 Nokia Corporation + * + * Paul Walmsley + * Benoit Cousson + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * Note that this file is currently not in sync with autogeneration scripts. + * The above note to be removed, once it is synced up. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/io.h> +#include <linux/platform_data/gpio-omap.h> +#include <linux/power/smartreflex.h> +#include <linux/i2c-omap.h> + +#include <linux/omap-dma.h> + +#include <linux/platform_data/spi-omap2-mcspi.h> +#include <linux/platform_data/asoc-ti-mcbsp.h> +#include <linux/platform_data/iommu-omap.h> +#include <plat/dmtimer.h> + +#include "omap_hwmod.h" +#include "omap_hwmod_common_data.h" +#include "cm1_44xx.h" +#include "cm2_44xx.h" +#include "prm44xx.h" +#include "prm-regbits-44xx.h" +#include "i2c.h" +#include "mmc.h" +#include "wd_timer.h" + +/* Base offset for all OMAP4 interrupts external to MPUSS */ +#define OMAP44XX_IRQ_GIC_START 32 + +/* Base offset for all OMAP4 dma requests */ +#define OMAP44XX_DMA_REQ_START 1 + +/* + * IP blocks + */ + +/* + * 'dmm' class + * instance(s): dmm + */ +static struct omap_hwmod_class omap44xx_dmm_hwmod_class = { + .name = "dmm", +}; + +/* dmm */ +static struct omap_hwmod omap44xx_dmm_hwmod = { + .name = "dmm", + .class = &omap44xx_dmm_hwmod_class, + .clkdm_name = "l3_emif_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_MEMIF_DMM_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'l3' class + * instance(s): l3_instr, l3_main_1, l3_main_2, l3_main_3 + */ +static struct omap_hwmod_class omap44xx_l3_hwmod_class = { + .name = "l3", +}; + +/* l3_instr */ +static struct omap_hwmod omap44xx_l3_instr_hwmod = { + .name = "l3_instr", + .class = &omap44xx_l3_hwmod_class, + .clkdm_name = "l3_instr_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* l3_main_1 */ +static struct omap_hwmod omap44xx_l3_main_1_hwmod = { + .name = "l3_main_1", + .class = &omap44xx_l3_hwmod_class, + .clkdm_name = "l3_1_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3_1_L3_1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET, + }, + }, +}; + +/* l3_main_2 */ +static struct omap_hwmod omap44xx_l3_main_2_hwmod = { + .name = "l3_main_2", + .class = &omap44xx_l3_hwmod_class, + .clkdm_name = "l3_2_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3_2_L3_2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3_2_L3_2_CONTEXT_OFFSET, + }, + }, +}; + +/* l3_main_3 */ +static struct omap_hwmod omap44xx_l3_main_3_hwmod = { + .name = "l3_main_3", + .class = &omap44xx_l3_hwmod_class, + .clkdm_name = "l3_instr_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3INSTR_L3_3_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INSTR_L3_3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'l4' class + * instance(s): l4_abe, l4_cfg, l4_per, l4_wkup + */ +static struct omap_hwmod_class omap44xx_l4_hwmod_class = { + .name = "l4", +}; + +/* l4_abe */ +static struct omap_hwmod omap44xx_l4_abe_hwmod = { + .name = "l4_abe", + .class = &omap44xx_l4_hwmod_class, + .clkdm_name = "abe_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM1_ABE_L4ABE_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_AESS_CONTEXT_OFFSET, + .lostcontext_mask = OMAP4430_LOSTMEM_AESSMEM_MASK, + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, +}; + +/* l4_cfg */ +static struct omap_hwmod omap44xx_l4_cfg_hwmod = { + .name = "l4_cfg", + .class = &omap44xx_l4_hwmod_class, + .clkdm_name = "l4_cfg_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4CFG_L4_CFG_CONTEXT_OFFSET, + }, + }, +}; + +/* l4_per */ +static struct omap_hwmod omap44xx_l4_per_hwmod = { + .name = "l4_per", + .class = &omap44xx_l4_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_L4PER_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_L4_PER_CONTEXT_OFFSET, + }, + }, +}; + +/* l4_wkup */ +static struct omap_hwmod omap44xx_l4_wkup_hwmod = { + .name = "l4_wkup", + .class = &omap44xx_l4_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_WKUP_L4WKUP_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_WKUP_L4WKUP_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'mpu_bus' class + * instance(s): mpu_private + */ +static struct omap_hwmod_class omap44xx_mpu_bus_hwmod_class = { + .name = "mpu_bus", +}; + +/* mpu_private */ +static struct omap_hwmod omap44xx_mpu_private_hwmod = { + .name = "mpu_private", + .class = &omap44xx_mpu_bus_hwmod_class, + .clkdm_name = "mpuss_clkdm", + .prcm = { + .omap4 = { + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, +}; + +/* + * 'ocp_wp_noc' class + * instance(s): ocp_wp_noc + */ +static struct omap_hwmod_class omap44xx_ocp_wp_noc_hwmod_class = { + .name = "ocp_wp_noc", +}; + +/* ocp_wp_noc */ +static struct omap_hwmod omap44xx_ocp_wp_noc_hwmod = { + .name = "ocp_wp_noc", + .class = &omap44xx_ocp_wp_noc_hwmod_class, + .clkdm_name = "l3_instr_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INSTR_OCP_WP1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * Modules omap_hwmod structures + * + * The following IPs are excluded for the moment because: + * - They do not need an explicit SW control using omap_hwmod API. + * - They still need to be validated with the driver + * properly adapted to omap_hwmod / omap_device + * + * usim + */ + +/* + * 'aess' class + * audio engine sub system + */ + +static struct omap_hwmod_class_sysconfig omap44xx_aess_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART | + MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap44xx_aess_hwmod_class = { + .name = "aess", + .sysc = &omap44xx_aess_sysc, + .enable_preprogram = omap_hwmod_aess_preprogram, +}; + +/* aess */ +static struct omap_hwmod omap44xx_aess_hwmod = { + .name = "aess", + .class = &omap44xx_aess_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "aess_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_AESS_CONTEXT_OFFSET, + .lostcontext_mask = OMAP4430_LOSTCONTEXT_DFF_MASK, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'c2c' class + * chip 2 chip interface used to plug the ape soc (omap) with an external modem + * soc + */ + +static struct omap_hwmod_class omap44xx_c2c_hwmod_class = { + .name = "c2c", +}; + +/* c2c */ +static struct omap_hwmod omap44xx_c2c_hwmod = { + .name = "c2c", + .class = &omap44xx_c2c_hwmod_class, + .clkdm_name = "d2d_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_D2D_SAD2D_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_D2D_SAD2D_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'counter' class + * 32-bit ordinary counter, clocked by the falling edge of the 32 khz clock + */ + +static struct omap_hwmod_class_sysconfig omap44xx_counter_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0004, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_counter_hwmod_class = { + .name = "counter", + .sysc = &omap44xx_counter_sysc, +}; + +/* counter_32k */ +static struct omap_hwmod omap44xx_counter_32k_hwmod = { + .name = "counter_32k", + .class = &omap44xx_counter_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_SWSUP_SIDLE, + .main_clk = "sys_32k_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_WKUP_SYNCTIMER_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'ctrl_module' class + * attila core control module + core pad control module + wkup pad control + * module + attila wkup control module + */ + +static struct omap_hwmod_class_sysconfig omap44xx_ctrl_module_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap44xx_ctrl_module_hwmod_class = { + .name = "ctrl_module", + .sysc = &omap44xx_ctrl_module_sysc, +}; + +/* ctrl_module_core */ +static struct omap_hwmod omap44xx_ctrl_module_core_hwmod = { + .name = "ctrl_module_core", + .class = &omap44xx_ctrl_module_hwmod_class, + .clkdm_name = "l4_cfg_clkdm", + .prcm = { + .omap4 = { + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, +}; + +/* ctrl_module_pad_core */ +static struct omap_hwmod omap44xx_ctrl_module_pad_core_hwmod = { + .name = "ctrl_module_pad_core", + .class = &omap44xx_ctrl_module_hwmod_class, + .clkdm_name = "l4_cfg_clkdm", + .prcm = { + .omap4 = { + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, +}; + +/* ctrl_module_wkup */ +static struct omap_hwmod omap44xx_ctrl_module_wkup_hwmod = { + .name = "ctrl_module_wkup", + .class = &omap44xx_ctrl_module_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .prcm = { + .omap4 = { + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, +}; + +/* ctrl_module_pad_wkup */ +static struct omap_hwmod omap44xx_ctrl_module_pad_wkup_hwmod = { + .name = "ctrl_module_pad_wkup", + .class = &omap44xx_ctrl_module_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .prcm = { + .omap4 = { + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, +}; + +/* + * 'debugss' class + * debug and emulation sub system + */ + +static struct omap_hwmod_class omap44xx_debugss_hwmod_class = { + .name = "debugss", +}; + +/* debugss */ +static struct omap_hwmod omap44xx_debugss_hwmod = { + .name = "debugss", + .class = &omap44xx_debugss_hwmod_class, + .clkdm_name = "emu_sys_clkdm", + .main_clk = "trace_clk_div_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_EMU_DEBUGSS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_EMU_DEBUGSS_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'dma' class + * dma controller for data exchange between memory to memory (i.e. internal or + * external memory) and gp peripherals to memory or memory to gp peripherals + */ + +static struct omap_hwmod_class_sysconfig omap44xx_dma_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x002c, + .syss_offs = 0x0028, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_EMUFREE | SYSC_HAS_MIDLEMODE | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_dma_hwmod_class = { + .name = "dma", + .sysc = &omap44xx_dma_sysc, +}; + +/* dma dev_attr */ +static struct omap_dma_dev_attr dma_dev_attr = { + .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY | + IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY, + .lch_count = 32, +}; + +/* dma_system */ +static struct omap_hwmod_irq_info omap44xx_dma_system_irqs[] = { + { .name = "0", .irq = 12 + OMAP44XX_IRQ_GIC_START }, + { .name = "1", .irq = 13 + OMAP44XX_IRQ_GIC_START }, + { .name = "2", .irq = 14 + OMAP44XX_IRQ_GIC_START }, + { .name = "3", .irq = 15 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod omap44xx_dma_system_hwmod = { + .name = "dma_system", + .class = &omap44xx_dma_hwmod_class, + .clkdm_name = "l3_dma_clkdm", + .mpu_irqs = omap44xx_dma_system_irqs, + .main_clk = "l3_div_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_SDMA_SDMA_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_SDMA_SDMA_CONTEXT_OFFSET, + }, + }, + .dev_attr = &dma_dev_attr, +}; + +/* + * 'dmic' class + * digital microphone controller + */ + +static struct omap_hwmod_class_sysconfig omap44xx_dmic_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap44xx_dmic_hwmod_class = { + .name = "dmic", + .sysc = &omap44xx_dmic_sysc, +}; + +/* dmic */ +static struct omap_hwmod omap44xx_dmic_hwmod = { + .name = "dmic", + .class = &omap44xx_dmic_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "func_dmic_abe_gfclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_DMIC_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'dsp' class + * dsp sub-system + */ + +static struct omap_hwmod_class omap44xx_dsp_hwmod_class = { + .name = "dsp", +}; + +/* dsp */ +static struct omap_hwmod_rst_info omap44xx_dsp_resets[] = { + { .name = "dsp", .rst_shift = 0 }, +}; + +static struct omap_hwmod omap44xx_dsp_hwmod = { + .name = "dsp", + .class = &omap44xx_dsp_hwmod_class, + .clkdm_name = "tesla_clkdm", + .rst_lines = omap44xx_dsp_resets, + .rst_lines_cnt = ARRAY_SIZE(omap44xx_dsp_resets), + .main_clk = "dpll_iva_m4x2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET, + .rstctrl_offs = OMAP4_RM_TESLA_RSTCTRL_OFFSET, + .context_offs = OMAP4_RM_TESLA_TESLA_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'dss' class + * display sub-system + */ + +static struct omap_hwmod_class_sysconfig omap44xx_dss_sysc = { + .rev_offs = 0x0000, + .syss_offs = 0x0014, + .sysc_flags = SYSS_HAS_RESET_STATUS, +}; + +static struct omap_hwmod_class omap44xx_dss_hwmod_class = { + .name = "dss", + .sysc = &omap44xx_dss_sysc, + .reset = omap_dss_reset, +}; + +/* dss */ +static struct omap_hwmod_opt_clk dss_opt_clks[] = { + { .role = "sys_clk", .clk = "dss_sys_clk" }, + { .role = "tv_clk", .clk = "dss_tv_clk" }, + { .role = "hdmi_clk", .clk = "dss_48mhz_clk" }, +}; + +static struct omap_hwmod omap44xx_dss_hwmod = { + .name = "dss_core", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .class = &omap44xx_dss_hwmod_class, + .clkdm_name = "l3_dss_clkdm", + .main_clk = "dss_dss_clk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, + }, + }, + .opt_clks = dss_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), +}; + +/* + * 'dispc' class + * display controller + */ + +static struct omap_hwmod_class_sysconfig omap44xx_dispc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_MIDLEMODE | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_dispc_hwmod_class = { + .name = "dispc", + .sysc = &omap44xx_dispc_sysc, +}; + +/* dss_dispc */ +static struct omap_hwmod_irq_info omap44xx_dss_dispc_irqs[] = { + { .irq = 25 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod_dma_info omap44xx_dss_dispc_sdma_reqs[] = { + { .dma_req = 5 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +static struct omap_dss_dispc_dev_attr omap44xx_dss_dispc_dev_attr = { + .manager_count = 3, + .has_framedonetv_irq = 1 +}; + +static struct omap_hwmod omap44xx_dss_dispc_hwmod = { + .name = "dss_dispc", + .class = &omap44xx_dispc_hwmod_class, + .clkdm_name = "l3_dss_clkdm", + .mpu_irqs = omap44xx_dss_dispc_irqs, + .sdma_reqs = omap44xx_dss_dispc_sdma_reqs, + .main_clk = "dss_dss_clk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, + }, + }, + .dev_attr = &omap44xx_dss_dispc_dev_attr +}; + +/* + * 'dsi' class + * display serial interface controller + */ + +static struct omap_hwmod_class_sysconfig omap44xx_dsi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_dsi_hwmod_class = { + .name = "dsi", + .sysc = &omap44xx_dsi_sysc, +}; + +/* dss_dsi1 */ +static struct omap_hwmod_irq_info omap44xx_dss_dsi1_irqs[] = { + { .irq = 53 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod_dma_info omap44xx_dss_dsi1_sdma_reqs[] = { + { .dma_req = 74 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +static struct omap_hwmod_opt_clk dss_dsi1_opt_clks[] = { + { .role = "sys_clk", .clk = "dss_sys_clk" }, +}; + +static struct omap_hwmod omap44xx_dss_dsi1_hwmod = { + .name = "dss_dsi1", + .class = &omap44xx_dsi_hwmod_class, + .clkdm_name = "l3_dss_clkdm", + .mpu_irqs = omap44xx_dss_dsi1_irqs, + .sdma_reqs = omap44xx_dss_dsi1_sdma_reqs, + .main_clk = "dss_dss_clk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, + }, + }, + .opt_clks = dss_dsi1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_opt_clks), +}; + +/* dss_dsi2 */ +static struct omap_hwmod_irq_info omap44xx_dss_dsi2_irqs[] = { + { .irq = 84 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod_dma_info omap44xx_dss_dsi2_sdma_reqs[] = { + { .dma_req = 83 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +static struct omap_hwmod_opt_clk dss_dsi2_opt_clks[] = { + { .role = "sys_clk", .clk = "dss_sys_clk" }, +}; + +static struct omap_hwmod omap44xx_dss_dsi2_hwmod = { + .name = "dss_dsi2", + .class = &omap44xx_dsi_hwmod_class, + .clkdm_name = "l3_dss_clkdm", + .mpu_irqs = omap44xx_dss_dsi2_irqs, + .sdma_reqs = omap44xx_dss_dsi2_sdma_reqs, + .main_clk = "dss_dss_clk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, + }, + }, + .opt_clks = dss_dsi2_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_dsi2_opt_clks), +}; + +/* + * 'hdmi' class + * hdmi controller + */ + +static struct omap_hwmod_class_sysconfig omap44xx_hdmi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap44xx_hdmi_hwmod_class = { + .name = "hdmi", + .sysc = &omap44xx_hdmi_sysc, +}; + +/* dss_hdmi */ +static struct omap_hwmod_irq_info omap44xx_dss_hdmi_irqs[] = { + { .irq = 101 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod_dma_info omap44xx_dss_hdmi_sdma_reqs[] = { + { .dma_req = 75 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +static struct omap_hwmod_opt_clk dss_hdmi_opt_clks[] = { + { .role = "sys_clk", .clk = "dss_sys_clk" }, +}; + +static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { + .name = "dss_hdmi", + .class = &omap44xx_hdmi_hwmod_class, + .clkdm_name = "l3_dss_clkdm", + /* + * HDMI audio requires to use no-idle mode. Hence, + * set idle mode by software. + */ + .flags = HWMOD_SWSUP_SIDLE, + .mpu_irqs = omap44xx_dss_hdmi_irqs, + .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs, + .main_clk = "dss_48mhz_clk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, + }, + }, + .opt_clks = dss_hdmi_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks), +}; + +/* + * 'rfbi' class + * remote frame buffer interface + */ + +static struct omap_hwmod_class_sysconfig omap44xx_rfbi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_rfbi_hwmod_class = { + .name = "rfbi", + .sysc = &omap44xx_rfbi_sysc, +}; + +/* dss_rfbi */ +static struct omap_hwmod_dma_info omap44xx_dss_rfbi_sdma_reqs[] = { + { .dma_req = 13 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = { + { .role = "ick", .clk = "dss_fck" }, +}; + +static struct omap_hwmod omap44xx_dss_rfbi_hwmod = { + .name = "dss_rfbi", + .class = &omap44xx_rfbi_hwmod_class, + .clkdm_name = "l3_dss_clkdm", + .sdma_reqs = omap44xx_dss_rfbi_sdma_reqs, + .main_clk = "dss_dss_clk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, + }, + }, + .opt_clks = dss_rfbi_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), +}; + +/* + * 'venc' class + * video encoder + */ + +static struct omap_hwmod_class omap44xx_venc_hwmod_class = { + .name = "venc", +}; + +/* dss_venc */ +static struct omap_hwmod omap44xx_dss_venc_hwmod = { + .name = "dss_venc", + .class = &omap44xx_venc_hwmod_class, + .clkdm_name = "l3_dss_clkdm", + .main_clk = "dss_tv_clk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'elm' class + * bch error location module + */ + +static struct omap_hwmod_class_sysconfig omap44xx_elm_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_elm_hwmod_class = { + .name = "elm", + .sysc = &omap44xx_elm_sysc, +}; + +/* elm */ +static struct omap_hwmod omap44xx_elm_hwmod = { + .name = "elm", + .class = &omap44xx_elm_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_ELM_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_ELM_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'emif' class + * external memory interface no1 + */ + +static struct omap_hwmod_class_sysconfig omap44xx_emif_sysc = { + .rev_offs = 0x0000, +}; + +static struct omap_hwmod_class omap44xx_emif_hwmod_class = { + .name = "emif", + .sysc = &omap44xx_emif_sysc, +}; + +/* emif1 */ +static struct omap_hwmod omap44xx_emif1_hwmod = { + .name = "emif1", + .class = &omap44xx_emif_hwmod_class, + .clkdm_name = "l3_emif_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "ddrphy_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_MEMIF_EMIF_1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_MEMIF_EMIF_1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* emif2 */ +static struct omap_hwmod omap44xx_emif2_hwmod = { + .name = "emif2", + .class = &omap44xx_emif_hwmod_class, + .clkdm_name = "l3_emif_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "ddrphy_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_MEMIF_EMIF_2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_MEMIF_EMIF_2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'fdif' class + * face detection hw accelerator module + */ + +static struct omap_hwmod_class_sysconfig omap44xx_fdif_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + /* + * FDIF needs 100 OCP clk cycles delay after a softreset before + * accessing sysconfig again. + * The lowest frequency at the moment for L3 bus is 100 MHz, so + * 1usec delay is needed. Add an x2 margin to be safe (2 usecs). + * + * TODO: Indicate errata when available. + */ + .srst_udelay = 2, + .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap44xx_fdif_hwmod_class = { + .name = "fdif", + .sysc = &omap44xx_fdif_sysc, +}; + +/* fdif */ +static struct omap_hwmod omap44xx_fdif_hwmod = { + .name = "fdif", + .class = &omap44xx_fdif_hwmod_class, + .clkdm_name = "iss_clkdm", + .main_clk = "fdif_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_CAM_FDIF_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_CAM_FDIF_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'gpio' class + * general purpose io module + */ + +static struct omap_hwmod_class_sysconfig omap44xx_gpio_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0114, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_gpio_hwmod_class = { + .name = "gpio", + .sysc = &omap44xx_gpio_sysc, + .rev = 2, +}; + +/* gpio dev_attr */ +static struct omap_gpio_dev_attr gpio_dev_attr = { + .bank_width = 32, + .dbck_flag = true, +}; + +/* gpio1 */ +static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { + { .role = "dbclk", .clk = "gpio1_dbclk" }, +}; + +static struct omap_hwmod omap44xx_gpio1_hwmod = { + .name = "gpio1", + .class = &omap44xx_gpio_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .main_clk = "l4_wkup_clk_mux_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_WKUP_GPIO1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_WKUP_GPIO1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio2 */ +static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { + { .role = "dbclk", .clk = "gpio2_dbclk" }, +}; + +static struct omap_hwmod omap44xx_gpio2_hwmod = { + .name = "gpio2", + .class = &omap44xx_gpio_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4_div_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_GPIO2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio2_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio3 */ +static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { + { .role = "dbclk", .clk = "gpio3_dbclk" }, +}; + +static struct omap_hwmod omap44xx_gpio3_hwmod = { + .name = "gpio3", + .class = &omap44xx_gpio_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4_div_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_GPIO3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio3_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio4 */ +static struct omap_hwmod_opt_clk gpio4_opt_clks[] = { + { .role = "dbclk", .clk = "gpio4_dbclk" }, +}; + +static struct omap_hwmod omap44xx_gpio4_hwmod = { + .name = "gpio4", + .class = &omap44xx_gpio_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4_div_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_GPIO4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio4_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio5 */ +static struct omap_hwmod_opt_clk gpio5_opt_clks[] = { + { .role = "dbclk", .clk = "gpio5_dbclk" }, +}; + +static struct omap_hwmod omap44xx_gpio5_hwmod = { + .name = "gpio5", + .class = &omap44xx_gpio_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4_div_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_GPIO5_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio5_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio6 */ +static struct omap_hwmod_opt_clk gpio6_opt_clks[] = { + { .role = "dbclk", .clk = "gpio6_dbclk" }, +}; + +static struct omap_hwmod omap44xx_gpio6_hwmod = { + .name = "gpio6", + .class = &omap44xx_gpio_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4_div_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_GPIO6_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio6_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* + * 'gpmc' class + * general purpose memory controller + */ + +static struct omap_hwmod_class_sysconfig omap44xx_gpmc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_gpmc_hwmod_class = { + .name = "gpmc", + .sysc = &omap44xx_gpmc_sysc, +}; + +/* gpmc */ +static struct omap_hwmod omap44xx_gpmc_hwmod = { + .name = "gpmc", + .class = &omap44xx_gpmc_hwmod_class, + .clkdm_name = "l3_2_clkdm", + /* + * XXX HWMOD_INIT_NO_RESET should not be needed for this IP + * block. It is not being added due to any known bugs with + * resetting the GPMC IP block, but rather because any timings + * set by the bootloader are not being correctly programmed by + * the kernel from the board file or DT data. + * HWMOD_INIT_NO_RESET should be removed ASAP. + */ + .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3_2_GPMC_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'gpu' class + * 2d/3d graphics accelerator + */ + +static struct omap_hwmod_class_sysconfig omap44xx_gpu_sysc = { + .rev_offs = 0x1fc00, + .sysc_offs = 0x1fc10, + .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap44xx_gpu_hwmod_class = { + .name = "gpu", + .sysc = &omap44xx_gpu_sysc, +}; + +/* gpu */ +static struct omap_hwmod omap44xx_gpu_hwmod = { + .name = "gpu", + .class = &omap44xx_gpu_hwmod_class, + .clkdm_name = "l3_gfx_clkdm", + .main_clk = "sgx_clk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_GFX_GFX_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_GFX_GFX_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'hdq1w' class + * hdq / 1-wire serial interface controller + */ + +static struct omap_hwmod_class_sysconfig omap44xx_hdq1w_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0014, + .syss_offs = 0x0018, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_hdq1w_hwmod_class = { + .name = "hdq1w", + .sysc = &omap44xx_hdq1w_sysc, +}; + +/* hdq1w */ +static struct omap_hwmod omap44xx_hdq1w_hwmod = { + .name = "hdq1w", + .class = &omap44xx_hdq1w_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_INIT_NO_RESET, /* XXX temporary */ + .main_clk = "func_12m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_HDQ1W_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'hsi' class + * mipi high-speed synchronous serial interface (multichannel and full-duplex + * serial if) + */ + +static struct omap_hwmod_class_sysconfig omap44xx_hsi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_EMUFREE | + SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_hsi_hwmod_class = { + .name = "hsi", + .sysc = &omap44xx_hsi_sysc, +}; + +/* hsi */ +static struct omap_hwmod omap44xx_hsi_hwmod = { + .name = "hsi", + .class = &omap44xx_hsi_hwmod_class, + .clkdm_name = "l3_init_clkdm", + .main_clk = "hsi_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3INIT_HSI_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INIT_HSI_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'i2c' class + * multimaster high-speed i2c controller + */ + +static struct omap_hwmod_class_sysconfig omap44xx_i2c_sysc = { + .sysc_offs = 0x0010, + .syss_offs = 0x0090, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .clockact = CLOCKACT_TEST_ICLK, + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_i2c_hwmod_class = { + .name = "i2c", + .sysc = &omap44xx_i2c_sysc, + .rev = OMAP_I2C_IP_VERSION_2, + .reset = &omap_i2c_reset, +}; + +static struct omap_i2c_dev_attr i2c_dev_attr = { + .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE, +}; + +/* i2c1 */ +static struct omap_hwmod omap44xx_i2c1_hwmod = { + .name = "i2c1", + .class = &omap44xx_i2c_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "func_96m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_I2C1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* i2c2 */ +static struct omap_hwmod omap44xx_i2c2_hwmod = { + .name = "i2c2", + .class = &omap44xx_i2c_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "func_96m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_I2C2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* i2c3 */ +static struct omap_hwmod omap44xx_i2c3_hwmod = { + .name = "i2c3", + .class = &omap44xx_i2c_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "func_96m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_I2C3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* i2c4 */ +static struct omap_hwmod omap44xx_i2c4_hwmod = { + .name = "i2c4", + .class = &omap44xx_i2c_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "func_96m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_I2C4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* + * 'ipu' class + * imaging processor unit + */ + +static struct omap_hwmod_class omap44xx_ipu_hwmod_class = { + .name = "ipu", +}; + +/* ipu */ +static struct omap_hwmod_rst_info omap44xx_ipu_resets[] = { + { .name = "cpu0", .rst_shift = 0 }, + { .name = "cpu1", .rst_shift = 1 }, +}; + +static struct omap_hwmod omap44xx_ipu_hwmod = { + .name = "ipu", + .class = &omap44xx_ipu_hwmod_class, + .clkdm_name = "ducati_clkdm", + .rst_lines = omap44xx_ipu_resets, + .rst_lines_cnt = ARRAY_SIZE(omap44xx_ipu_resets), + .main_clk = "ducati_clk_mux_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET, + .rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET, + .context_offs = OMAP4_RM_DUCATI_DUCATI_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'iss' class + * external images sensor pixel data processor + */ + +static struct omap_hwmod_class_sysconfig omap44xx_iss_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + /* + * ISS needs 100 OCP clk cycles delay after a softreset before + * accessing sysconfig again. + * The lowest frequency at the moment for L3 bus is 100 MHz, so + * 1usec delay is needed. Add an x2 margin to be safe (2 usecs). + * + * TODO: Indicate errata when available. + */ + .srst_udelay = 2, + .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap44xx_iss_hwmod_class = { + .name = "iss", + .sysc = &omap44xx_iss_sysc, +}; + +/* iss */ +static struct omap_hwmod_opt_clk iss_opt_clks[] = { + { .role = "ctrlclk", .clk = "iss_ctrlclk" }, +}; + +static struct omap_hwmod omap44xx_iss_hwmod = { + .name = "iss", + .class = &omap44xx_iss_hwmod_class, + .clkdm_name = "iss_clkdm", + .main_clk = "ducati_clk_mux_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_CAM_ISS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = iss_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(iss_opt_clks), +}; + +/* + * 'iva' class + * multi-standard video encoder/decoder hardware accelerator + */ + +static struct omap_hwmod_class omap44xx_iva_hwmod_class = { + .name = "iva", +}; + +/* iva */ +static struct omap_hwmod_rst_info omap44xx_iva_resets[] = { + { .name = "seq0", .rst_shift = 0 }, + { .name = "seq1", .rst_shift = 1 }, + { .name = "logic", .rst_shift = 2 }, +}; + +static struct omap_hwmod omap44xx_iva_hwmod = { + .name = "iva", + .class = &omap44xx_iva_hwmod_class, + .clkdm_name = "ivahd_clkdm", + .rst_lines = omap44xx_iva_resets, + .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_resets), + .main_clk = "dpll_iva_m5x2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET, + .rstctrl_offs = OMAP4_RM_IVAHD_RSTCTRL_OFFSET, + .context_offs = OMAP4_RM_IVAHD_IVAHD_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'kbd' class + * keyboard controller + */ + +static struct omap_hwmod_class_sysconfig omap44xx_kbd_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_EMUFREE | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_kbd_hwmod_class = { + .name = "kbd", + .sysc = &omap44xx_kbd_sysc, +}; + +/* kbd */ +static struct omap_hwmod omap44xx_kbd_hwmod = { + .name = "kbd", + .class = &omap44xx_kbd_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .main_clk = "sys_32k_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_WKUP_KEYBOARD_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_WKUP_KEYBOARD_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'mailbox' class + * mailbox module allowing communication between the on-chip processors using a + * queued mailbox-interrupt mechanism. + */ + +static struct omap_hwmod_class_sysconfig omap44xx_mailbox_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap44xx_mailbox_hwmod_class = { + .name = "mailbox", + .sysc = &omap44xx_mailbox_sysc, +}; + +/* mailbox */ +static struct omap_hwmod omap44xx_mailbox_hwmod = { + .name = "mailbox", + .class = &omap44xx_mailbox_hwmod_class, + .clkdm_name = "l4_cfg_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4CFG_MAILBOX_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'mcasp' class + * multi-channel audio serial port controller + */ + +/* The IP is not compliant to type1 / type2 scheme */ +static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_mcasp = { + .sidle_shift = 0, +}; + +static struct omap_hwmod_class_sysconfig omap44xx_mcasp_sysc = { + .sysc_offs = 0x0004, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type_mcasp, +}; + +static struct omap_hwmod_class omap44xx_mcasp_hwmod_class = { + .name = "mcasp", + .sysc = &omap44xx_mcasp_sysc, +}; + +/* mcasp */ +static struct omap_hwmod omap44xx_mcasp_hwmod = { + .name = "mcasp", + .class = &omap44xx_mcasp_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "func_mcasp_abe_gfclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_MCASP_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'mcbsp' class + * multi channel buffered serial port controller + */ + +static struct omap_hwmod_class_sysconfig omap44xx_mcbsp_sysc = { + .sysc_offs = 0x008c, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_mcbsp_hwmod_class = { + .name = "mcbsp", + .sysc = &omap44xx_mcbsp_sysc, + .rev = MCBSP_CONFIG_TYPE4, +}; + +/* mcbsp1 */ +static struct omap_hwmod_opt_clk mcbsp1_opt_clks[] = { + { .role = "pad_fck", .clk = "pad_clks_ck" }, + { .role = "prcm_fck", .clk = "mcbsp1_sync_mux_ck" }, +}; + +static struct omap_hwmod omap44xx_mcbsp1_hwmod = { + .name = "mcbsp1", + .class = &omap44xx_mcbsp_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "func_mcbsp1_gfclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_MCBSP1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = mcbsp1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp1_opt_clks), +}; + +/* mcbsp2 */ +static struct omap_hwmod_opt_clk mcbsp2_opt_clks[] = { + { .role = "pad_fck", .clk = "pad_clks_ck" }, + { .role = "prcm_fck", .clk = "mcbsp2_sync_mux_ck" }, +}; + +static struct omap_hwmod omap44xx_mcbsp2_hwmod = { + .name = "mcbsp2", + .class = &omap44xx_mcbsp_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "func_mcbsp2_gfclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_MCBSP2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = mcbsp2_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp2_opt_clks), +}; + +/* mcbsp3 */ +static struct omap_hwmod_opt_clk mcbsp3_opt_clks[] = { + { .role = "pad_fck", .clk = "pad_clks_ck" }, + { .role = "prcm_fck", .clk = "mcbsp3_sync_mux_ck" }, +}; + +static struct omap_hwmod omap44xx_mcbsp3_hwmod = { + .name = "mcbsp3", + .class = &omap44xx_mcbsp_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "func_mcbsp3_gfclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_MCBSP3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = mcbsp3_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp3_opt_clks), +}; + +/* mcbsp4 */ +static struct omap_hwmod_opt_clk mcbsp4_opt_clks[] = { + { .role = "pad_fck", .clk = "pad_clks_ck" }, + { .role = "prcm_fck", .clk = "mcbsp4_sync_mux_ck" }, +}; + +static struct omap_hwmod omap44xx_mcbsp4_hwmod = { + .name = "mcbsp4", + .class = &omap44xx_mcbsp_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .main_clk = "per_mcbsp4_gfclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_MCBSP4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = mcbsp4_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp4_opt_clks), +}; + +/* + * 'mcpdm' class + * multi channel pdm controller (proprietary interface with phoenix power + * ic) + */ + +static struct omap_hwmod_class_sysconfig omap44xx_mcpdm_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap44xx_mcpdm_hwmod_class = { + .name = "mcpdm", + .sysc = &omap44xx_mcpdm_sysc, +}; + +/* mcpdm */ +static struct omap_hwmod omap44xx_mcpdm_hwmod = { + .name = "mcpdm", + .class = &omap44xx_mcpdm_hwmod_class, + .clkdm_name = "abe_clkdm", + /* + * It's suspected that the McPDM requires an off-chip main + * functional clock, controlled via I2C. This IP block is + * currently reset very early during boot, before I2C is + * available, so it doesn't seem that we have any choice in + * the kernel other than to avoid resetting it. + * + * Also, McPDM needs to be configured to NO_IDLE mode when it + * is in used otherwise vital clocks will be gated which + * results 'slow motion' audio playback. + */ + .flags = HWMOD_EXT_OPT_MAIN_CLK | HWMOD_SWSUP_SIDLE, + .main_clk = "pad_clks_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_PDM_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'mcspi' class + * multichannel serial port interface (mcspi) / master/slave synchronous serial + * bus + */ + +static struct omap_hwmod_class_sysconfig omap44xx_mcspi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap44xx_mcspi_hwmod_class = { + .name = "mcspi", + .sysc = &omap44xx_mcspi_sysc, + .rev = OMAP4_MCSPI_REV, +}; + +/* mcspi1 */ +static struct omap_hwmod_dma_info omap44xx_mcspi1_sdma_reqs[] = { + { .name = "tx0", .dma_req = 34 + OMAP44XX_DMA_REQ_START }, + { .name = "rx0", .dma_req = 35 + OMAP44XX_DMA_REQ_START }, + { .name = "tx1", .dma_req = 36 + OMAP44XX_DMA_REQ_START }, + { .name = "rx1", .dma_req = 37 + OMAP44XX_DMA_REQ_START }, + { .name = "tx2", .dma_req = 38 + OMAP44XX_DMA_REQ_START }, + { .name = "rx2", .dma_req = 39 + OMAP44XX_DMA_REQ_START }, + { .name = "tx3", .dma_req = 40 + OMAP44XX_DMA_REQ_START }, + { .name = "rx3", .dma_req = 41 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +/* mcspi1 dev_attr */ +static struct omap2_mcspi_dev_attr mcspi1_dev_attr = { + .num_chipselect = 4, +}; + +static struct omap_hwmod omap44xx_mcspi1_hwmod = { + .name = "mcspi1", + .class = &omap44xx_mcspi_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .sdma_reqs = omap44xx_mcspi1_sdma_reqs, + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_MCSPI1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi1_dev_attr, +}; + +/* mcspi2 */ +static struct omap_hwmod_dma_info omap44xx_mcspi2_sdma_reqs[] = { + { .name = "tx0", .dma_req = 42 + OMAP44XX_DMA_REQ_START }, + { .name = "rx0", .dma_req = 43 + OMAP44XX_DMA_REQ_START }, + { .name = "tx1", .dma_req = 44 + OMAP44XX_DMA_REQ_START }, + { .name = "rx1", .dma_req = 45 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +/* mcspi2 dev_attr */ +static struct omap2_mcspi_dev_attr mcspi2_dev_attr = { + .num_chipselect = 2, +}; + +static struct omap_hwmod omap44xx_mcspi2_hwmod = { + .name = "mcspi2", + .class = &omap44xx_mcspi_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .sdma_reqs = omap44xx_mcspi2_sdma_reqs, + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_MCSPI2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi2_dev_attr, +}; + +/* mcspi3 */ +static struct omap_hwmod_dma_info omap44xx_mcspi3_sdma_reqs[] = { + { .name = "tx0", .dma_req = 14 + OMAP44XX_DMA_REQ_START }, + { .name = "rx0", .dma_req = 15 + OMAP44XX_DMA_REQ_START }, + { .name = "tx1", .dma_req = 22 + OMAP44XX_DMA_REQ_START }, + { .name = "rx1", .dma_req = 23 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +/* mcspi3 dev_attr */ +static struct omap2_mcspi_dev_attr mcspi3_dev_attr = { + .num_chipselect = 2, +}; + +static struct omap_hwmod omap44xx_mcspi3_hwmod = { + .name = "mcspi3", + .class = &omap44xx_mcspi_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .sdma_reqs = omap44xx_mcspi3_sdma_reqs, + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_MCSPI3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi3_dev_attr, +}; + +/* mcspi4 */ +static struct omap_hwmod_dma_info omap44xx_mcspi4_sdma_reqs[] = { + { .name = "tx0", .dma_req = 69 + OMAP44XX_DMA_REQ_START }, + { .name = "rx0", .dma_req = 70 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +/* mcspi4 dev_attr */ +static struct omap2_mcspi_dev_attr mcspi4_dev_attr = { + .num_chipselect = 1, +}; + +static struct omap_hwmod omap44xx_mcspi4_hwmod = { + .name = "mcspi4", + .class = &omap44xx_mcspi_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .sdma_reqs = omap44xx_mcspi4_sdma_reqs, + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_MCSPI4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi4_dev_attr, +}; + +/* + * 'mmc' class + * multimedia card high-speed/sd/sdio (mmc/sd/sdio) host controller + */ + +static struct omap_hwmod_class_sysconfig omap44xx_mmc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_MIDLEMODE | + SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap44xx_mmc_hwmod_class = { + .name = "mmc", + .sysc = &omap44xx_mmc_sysc, +}; + +/* mmc1 */ +static struct omap_hwmod_dma_info omap44xx_mmc1_sdma_reqs[] = { + { .name = "tx", .dma_req = 60 + OMAP44XX_DMA_REQ_START }, + { .name = "rx", .dma_req = 61 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +/* mmc1 dev_attr */ +static struct omap_mmc_dev_attr mmc1_dev_attr = { + .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, +}; + +static struct omap_hwmod omap44xx_mmc1_hwmod = { + .name = "mmc1", + .class = &omap44xx_mmc_hwmod_class, + .clkdm_name = "l3_init_clkdm", + .sdma_reqs = omap44xx_mmc1_sdma_reqs, + .main_clk = "hsmmc1_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INIT_MMC1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mmc1_dev_attr, +}; + +/* mmc2 */ +static struct omap_hwmod_dma_info omap44xx_mmc2_sdma_reqs[] = { + { .name = "tx", .dma_req = 46 + OMAP44XX_DMA_REQ_START }, + { .name = "rx", .dma_req = 47 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +static struct omap_hwmod omap44xx_mmc2_hwmod = { + .name = "mmc2", + .class = &omap44xx_mmc_hwmod_class, + .clkdm_name = "l3_init_clkdm", + .sdma_reqs = omap44xx_mmc2_sdma_reqs, + .main_clk = "hsmmc2_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INIT_MMC2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* mmc3 */ +static struct omap_hwmod_dma_info omap44xx_mmc3_sdma_reqs[] = { + { .name = "tx", .dma_req = 76 + OMAP44XX_DMA_REQ_START }, + { .name = "rx", .dma_req = 77 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +static struct omap_hwmod omap44xx_mmc3_hwmod = { + .name = "mmc3", + .class = &omap44xx_mmc_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .sdma_reqs = omap44xx_mmc3_sdma_reqs, + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_MMCSD3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* mmc4 */ +static struct omap_hwmod_dma_info omap44xx_mmc4_sdma_reqs[] = { + { .name = "tx", .dma_req = 56 + OMAP44XX_DMA_REQ_START }, + { .name = "rx", .dma_req = 57 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +static struct omap_hwmod omap44xx_mmc4_hwmod = { + .name = "mmc4", + .class = &omap44xx_mmc_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .sdma_reqs = omap44xx_mmc4_sdma_reqs, + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_MMCSD4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* mmc5 */ +static struct omap_hwmod_dma_info omap44xx_mmc5_sdma_reqs[] = { + { .name = "tx", .dma_req = 58 + OMAP44XX_DMA_REQ_START }, + { .name = "rx", .dma_req = 59 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +static struct omap_hwmod omap44xx_mmc5_hwmod = { + .name = "mmc5", + .class = &omap44xx_mmc_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .sdma_reqs = omap44xx_mmc5_sdma_reqs, + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_MMCSD5_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'mmu' class + * The memory management unit performs virtual to physical address translation + * for its requestors. + */ + +static struct omap_hwmod_class_sysconfig mmu_sysc = { + .rev_offs = 0x000, + .sysc_offs = 0x010, + .syss_offs = 0x014, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_mmu_hwmod_class = { + .name = "mmu", + .sysc = &mmu_sysc, +}; + +/* mmu ipu */ + +static struct omap_mmu_dev_attr mmu_ipu_dev_attr = { + .da_start = 0x0, + .da_end = 0xfffff000, + .nr_tlb_entries = 32, +}; + +static struct omap_hwmod omap44xx_mmu_ipu_hwmod; +static struct omap_hwmod_rst_info omap44xx_mmu_ipu_resets[] = { + { .name = "mmu_cache", .rst_shift = 2 }, +}; + +static struct omap_hwmod_addr_space omap44xx_mmu_ipu_addrs[] = { + { + .pa_start = 0x55082000, + .pa_end = 0x550820ff, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +/* l3_main_2 -> mmu_ipu */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__mmu_ipu = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_mmu_ipu_hwmod, + .clk = "l3_div_ck", + .addr = omap44xx_mmu_ipu_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod omap44xx_mmu_ipu_hwmod = { + .name = "mmu_ipu", + .class = &omap44xx_mmu_hwmod_class, + .clkdm_name = "ducati_clkdm", + .rst_lines = omap44xx_mmu_ipu_resets, + .rst_lines_cnt = ARRAY_SIZE(omap44xx_mmu_ipu_resets), + .main_clk = "ducati_clk_mux_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET, + .rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET, + .context_offs = OMAP4_RM_DUCATI_DUCATI_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .dev_attr = &mmu_ipu_dev_attr, +}; + +/* mmu dsp */ + +static struct omap_mmu_dev_attr mmu_dsp_dev_attr = { + .da_start = 0x0, + .da_end = 0xfffff000, + .nr_tlb_entries = 32, +}; + +static struct omap_hwmod omap44xx_mmu_dsp_hwmod; +static struct omap_hwmod_rst_info omap44xx_mmu_dsp_resets[] = { + { .name = "mmu_cache", .rst_shift = 1 }, +}; + +static struct omap_hwmod_addr_space omap44xx_mmu_dsp_addrs[] = { + { + .pa_start = 0x4a066000, + .pa_end = 0x4a0660ff, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +/* l4_cfg -> dsp */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__mmu_dsp = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_mmu_dsp_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_mmu_dsp_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod omap44xx_mmu_dsp_hwmod = { + .name = "mmu_dsp", + .class = &omap44xx_mmu_hwmod_class, + .clkdm_name = "tesla_clkdm", + .rst_lines = omap44xx_mmu_dsp_resets, + .rst_lines_cnt = ARRAY_SIZE(omap44xx_mmu_dsp_resets), + .main_clk = "dpll_iva_m4x2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET, + .rstctrl_offs = OMAP4_RM_TESLA_RSTCTRL_OFFSET, + .context_offs = OMAP4_RM_TESLA_TESLA_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .dev_attr = &mmu_dsp_dev_attr, +}; + +/* + * 'mpu' class + * mpu sub-system + */ + +static struct omap_hwmod_class omap44xx_mpu_hwmod_class = { + .name = "mpu", +}; + +/* mpu */ +static struct omap_hwmod omap44xx_mpu_hwmod = { + .name = "mpu", + .class = &omap44xx_mpu_hwmod_class, + .clkdm_name = "mpuss_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "dpll_mpu_m2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_MPU_MPU_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_MPU_MPU_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'ocmc_ram' class + * top-level core on-chip ram + */ + +static struct omap_hwmod_class omap44xx_ocmc_ram_hwmod_class = { + .name = "ocmc_ram", +}; + +/* ocmc_ram */ +static struct omap_hwmod omap44xx_ocmc_ram_hwmod = { + .name = "ocmc_ram", + .class = &omap44xx_ocmc_ram_hwmod_class, + .clkdm_name = "l3_2_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3_2_OCMC_RAM_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3_2_OCMC_RAM_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'ocp2scp' class + * bridge to transform ocp interface protocol to scp (serial control port) + * protocol + */ + +static struct omap_hwmod_class_sysconfig omap44xx_ocp2scp_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_ocp2scp_hwmod_class = { + .name = "ocp2scp", + .sysc = &omap44xx_ocp2scp_sysc, +}; + +/* ocp2scp_usb_phy */ +static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { + .name = "ocp2scp_usb_phy", + .class = &omap44xx_ocp2scp_hwmod_class, + .clkdm_name = "l3_init_clkdm", + /* + * ocp2scp_usb_phy_phy_48m is provided by the OMAP4 PRCM IP + * block as an "optional clock," and normally should never be + * specified as the main_clk for an OMAP IP block. However it + * turns out that this clock is actually the main clock for + * the ocp2scp_usb_phy IP block: + * http://lists.infradead.org/pipermail/linux-arm-kernel/2012-September/119943.html + * So listing ocp2scp_usb_phy_phy_48m as a main_clk here seems + * to be the best workaround. + */ + .main_clk = "ocp2scp_usb_phy_phy_48m", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INIT_USBPHYOCP2SCP_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'prcm' class + * power and reset manager (part of the prcm infrastructure) + clock manager 2 + * + clock manager 1 (in always on power domain) + local prm in mpu + */ + +static struct omap_hwmod_class omap44xx_prcm_hwmod_class = { + .name = "prcm", +}; + +/* prcm_mpu */ +static struct omap_hwmod omap44xx_prcm_mpu_hwmod = { + .name = "prcm_mpu", + .class = &omap44xx_prcm_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_NO_IDLEST, + .prcm = { + .omap4 = { + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, +}; + +/* cm_core_aon */ +static struct omap_hwmod omap44xx_cm_core_aon_hwmod = { + .name = "cm_core_aon", + .class = &omap44xx_prcm_hwmod_class, + .flags = HWMOD_NO_IDLEST, + .prcm = { + .omap4 = { + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, +}; + +/* cm_core */ +static struct omap_hwmod omap44xx_cm_core_hwmod = { + .name = "cm_core", + .class = &omap44xx_prcm_hwmod_class, + .flags = HWMOD_NO_IDLEST, + .prcm = { + .omap4 = { + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, +}; + +/* prm */ +static struct omap_hwmod_rst_info omap44xx_prm_resets[] = { + { .name = "rst_global_warm_sw", .rst_shift = 0 }, + { .name = "rst_global_cold_sw", .rst_shift = 1 }, +}; + +static struct omap_hwmod omap44xx_prm_hwmod = { + .name = "prm", + .class = &omap44xx_prcm_hwmod_class, + .rst_lines = omap44xx_prm_resets, + .rst_lines_cnt = ARRAY_SIZE(omap44xx_prm_resets), +}; + +/* + * 'scrm' class + * system clock and reset manager + */ + +static struct omap_hwmod_class omap44xx_scrm_hwmod_class = { + .name = "scrm", +}; + +/* scrm */ +static struct omap_hwmod omap44xx_scrm_hwmod = { + .name = "scrm", + .class = &omap44xx_scrm_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .prcm = { + .omap4 = { + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, +}; + +/* + * 'sl2if' class + * shared level 2 memory interface + */ + +static struct omap_hwmod_class omap44xx_sl2if_hwmod_class = { + .name = "sl2if", +}; + +/* sl2if */ +static struct omap_hwmod omap44xx_sl2if_hwmod = { + .name = "sl2if", + .class = &omap44xx_sl2if_hwmod_class, + .clkdm_name = "ivahd_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_IVAHD_SL2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_IVAHD_SL2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'slimbus' class + * bidirectional, multi-drop, multi-channel two-line serial interface between + * the device and external components + */ + +static struct omap_hwmod_class_sysconfig omap44xx_slimbus_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap44xx_slimbus_hwmod_class = { + .name = "slimbus", + .sysc = &omap44xx_slimbus_sysc, +}; + +/* slimbus1 */ +static struct omap_hwmod_opt_clk slimbus1_opt_clks[] = { + { .role = "fclk_1", .clk = "slimbus1_fclk_1" }, + { .role = "fclk_0", .clk = "slimbus1_fclk_0" }, + { .role = "fclk_2", .clk = "slimbus1_fclk_2" }, + { .role = "slimbus_clk", .clk = "slimbus1_slimbus_clk" }, +}; + +static struct omap_hwmod omap44xx_slimbus1_hwmod = { + .name = "slimbus1", + .class = &omap44xx_slimbus_hwmod_class, + .clkdm_name = "abe_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM1_ABE_SLIMBUS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_SLIMBUS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = slimbus1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(slimbus1_opt_clks), +}; + +/* slimbus2 */ +static struct omap_hwmod_opt_clk slimbus2_opt_clks[] = { + { .role = "fclk_1", .clk = "slimbus2_fclk_1" }, + { .role = "fclk_0", .clk = "slimbus2_fclk_0" }, + { .role = "slimbus_clk", .clk = "slimbus2_slimbus_clk" }, +}; + +static struct omap_hwmod omap44xx_slimbus2_hwmod = { + .name = "slimbus2", + .class = &omap44xx_slimbus_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_SLIMBUS2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_SLIMBUS2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = slimbus2_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(slimbus2_opt_clks), +}; + +/* + * 'smartreflex' class + * smartreflex module (monitor silicon performance and outputs a measure of + * performance error) + */ + +/* The IP is not compliant to type1 / type2 scheme */ +static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_smartreflex = { + .sidle_shift = 24, + .enwkup_shift = 26, +}; + +static struct omap_hwmod_class_sysconfig omap44xx_smartreflex_sysc = { + .sysc_offs = 0x0038, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type_smartreflex, +}; + +static struct omap_hwmod_class omap44xx_smartreflex_hwmod_class = { + .name = "smartreflex", + .sysc = &omap44xx_smartreflex_sysc, + .rev = 2, +}; + +/* smartreflex_core */ +static struct omap_smartreflex_dev_attr smartreflex_core_dev_attr = { + .sensor_voltdm_name = "core", +}; + +static struct omap_hwmod omap44xx_smartreflex_core_hwmod = { + .name = "smartreflex_core", + .class = &omap44xx_smartreflex_hwmod_class, + .clkdm_name = "l4_ao_clkdm", + + .main_clk = "smartreflex_core_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ALWON_SR_CORE_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &smartreflex_core_dev_attr, +}; + +/* smartreflex_iva */ +static struct omap_smartreflex_dev_attr smartreflex_iva_dev_attr = { + .sensor_voltdm_name = "iva", +}; + +static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = { + .name = "smartreflex_iva", + .class = &omap44xx_smartreflex_hwmod_class, + .clkdm_name = "l4_ao_clkdm", + .main_clk = "smartreflex_iva_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ALWON_SR_IVA_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &smartreflex_iva_dev_attr, +}; + +/* smartreflex_mpu */ +static struct omap_smartreflex_dev_attr smartreflex_mpu_dev_attr = { + .sensor_voltdm_name = "mpu", +}; + +static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = { + .name = "smartreflex_mpu", + .class = &omap44xx_smartreflex_hwmod_class, + .clkdm_name = "l4_ao_clkdm", + .main_clk = "smartreflex_mpu_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ALWON_SR_MPU_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &smartreflex_mpu_dev_attr, +}; + +/* + * 'spinlock' class + * spinlock provides hardware assistance for synchronizing the processes + * running on multiple processors + */ + +static struct omap_hwmod_class_sysconfig omap44xx_spinlock_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_spinlock_hwmod_class = { + .name = "spinlock", + .sysc = &omap44xx_spinlock_sysc, +}; + +/* spinlock */ +static struct omap_hwmod omap44xx_spinlock_hwmod = { + .name = "spinlock", + .class = &omap44xx_spinlock_hwmod_class, + .clkdm_name = "l4_cfg_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4CFG_HW_SEM_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4CFG_HW_SEM_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'timer' class + * general purpose timer module with accurate 1ms tick + * This class contains several variants: ['timer_1ms', 'timer'] + */ + +static struct omap_hwmod_class_sysconfig omap44xx_timer_1ms_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_EMUFREE | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .clockact = CLOCKACT_TEST_ICLK, + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_timer_1ms_hwmod_class = { + .name = "timer", + .sysc = &omap44xx_timer_1ms_sysc, +}; + +static struct omap_hwmod_class_sysconfig omap44xx_timer_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap44xx_timer_hwmod_class = { + .name = "timer", + .sysc = &omap44xx_timer_sysc, +}; + +/* always-on timers dev attribute */ +static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = { + .timer_capability = OMAP_TIMER_ALWON, +}; + +/* pwm timers dev attribute */ +static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = { + .timer_capability = OMAP_TIMER_HAS_PWM, +}; + +/* timers with DSP interrupt dev attribute */ +static struct omap_timer_capability_dev_attr capability_dsp_dev_attr = { + .timer_capability = OMAP_TIMER_HAS_DSP_IRQ, +}; + +/* pwm timers with DSP interrupt dev attribute */ +static struct omap_timer_capability_dev_attr capability_dsp_pwm_dev_attr = { + .timer_capability = OMAP_TIMER_HAS_DSP_IRQ | OMAP_TIMER_HAS_PWM, +}; + +/* timer1 */ +static struct omap_hwmod omap44xx_timer1_hwmod = { + .name = "timer1", + .class = &omap44xx_timer_1ms_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "dmt1_clk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_WKUP_TIMER1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_WKUP_TIMER1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &capability_alwon_dev_attr, +}; + +/* timer2 */ +static struct omap_hwmod omap44xx_timer2_hwmod = { + .name = "timer2", + .class = &omap44xx_timer_1ms_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "cm2_dm2_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_DMTIMER2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer3 */ +static struct omap_hwmod omap44xx_timer3_hwmod = { + .name = "timer3", + .class = &omap44xx_timer_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .main_clk = "cm2_dm3_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_DMTIMER3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer4 */ +static struct omap_hwmod omap44xx_timer4_hwmod = { + .name = "timer4", + .class = &omap44xx_timer_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .main_clk = "cm2_dm4_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_DMTIMER4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer5 */ +static struct omap_hwmod omap44xx_timer5_hwmod = { + .name = "timer5", + .class = &omap44xx_timer_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "timer5_sync_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_TIMER5_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &capability_dsp_dev_attr, +}; + +/* timer6 */ +static struct omap_hwmod omap44xx_timer6_hwmod = { + .name = "timer6", + .class = &omap44xx_timer_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "timer6_sync_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_TIMER6_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &capability_dsp_dev_attr, +}; + +/* timer7 */ +static struct omap_hwmod omap44xx_timer7_hwmod = { + .name = "timer7", + .class = &omap44xx_timer_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "timer7_sync_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_TIMER7_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &capability_dsp_dev_attr, +}; + +/* timer8 */ +static struct omap_hwmod omap44xx_timer8_hwmod = { + .name = "timer8", + .class = &omap44xx_timer_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "timer8_sync_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_TIMER8_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &capability_dsp_pwm_dev_attr, +}; + +/* timer9 */ +static struct omap_hwmod omap44xx_timer9_hwmod = { + .name = "timer9", + .class = &omap44xx_timer_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .main_clk = "cm2_dm9_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_DMTIMER9_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &capability_pwm_dev_attr, +}; + +/* timer10 */ +static struct omap_hwmod omap44xx_timer10_hwmod = { + .name = "timer10", + .class = &omap44xx_timer_1ms_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "cm2_dm10_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_DMTIMER10_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &capability_pwm_dev_attr, +}; + +/* timer11 */ +static struct omap_hwmod omap44xx_timer11_hwmod = { + .name = "timer11", + .class = &omap44xx_timer_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .main_clk = "cm2_dm11_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_DMTIMER11_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &capability_pwm_dev_attr, +}; + +/* + * 'uart' class + * universal asynchronous receiver/transmitter (uart) + */ + +static struct omap_hwmod_class_sysconfig omap44xx_uart_sysc = { + .rev_offs = 0x0050, + .sysc_offs = 0x0054, + .syss_offs = 0x0058, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_uart_hwmod_class = { + .name = "uart", + .sysc = &omap44xx_uart_sysc, +}; + +/* uart1 */ +static struct omap_hwmod omap44xx_uart1_hwmod = { + .name = "uart1", + .class = &omap44xx_uart_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_UART1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* uart2 */ +static struct omap_hwmod omap44xx_uart2_hwmod = { + .name = "uart2", + .class = &omap44xx_uart_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_UART2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* uart3 */ +static struct omap_hwmod omap44xx_uart3_hwmod = { + .name = "uart3", + .class = &omap44xx_uart_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .flags = DEBUG_OMAP4UART3_FLAGS | HWMOD_SWSUP_SIDLE_ACT, + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_UART3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* uart4 */ +static struct omap_hwmod omap44xx_uart4_hwmod = { + .name = "uart4", + .class = &omap44xx_uart_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .flags = DEBUG_OMAP4UART4_FLAGS | HWMOD_SWSUP_SIDLE_ACT, + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_UART4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'usb_host_fs' class + * full-speed usb host controller + */ + +/* The IP is not compliant to type1 / type2 scheme */ +static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_usb_host_fs = { + .midle_shift = 4, + .sidle_shift = 2, + .srst_shift = 1, +}; + +static struct omap_hwmod_class_sysconfig omap44xx_usb_host_fs_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0210, + .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type_usb_host_fs, +}; + +static struct omap_hwmod_class omap44xx_usb_host_fs_hwmod_class = { + .name = "usb_host_fs", + .sysc = &omap44xx_usb_host_fs_sysc, +}; + +/* usb_host_fs */ +static struct omap_hwmod omap44xx_usb_host_fs_hwmod = { + .name = "usb_host_fs", + .class = &omap44xx_usb_host_fs_hwmod_class, + .clkdm_name = "l3_init_clkdm", + .main_clk = "usb_host_fs_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3INIT_USB_HOST_FS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INIT_USB_HOST_FS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'usb_host_hs' class + * high-speed multi-port usb host controller + */ + +static struct omap_hwmod_class_sysconfig omap44xx_usb_host_hs_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap44xx_usb_host_hs_hwmod_class = { + .name = "usb_host_hs", + .sysc = &omap44xx_usb_host_hs_sysc, +}; + +/* usb_host_hs */ +static struct omap_hwmod omap44xx_usb_host_hs_hwmod = { + .name = "usb_host_hs", + .class = &omap44xx_usb_host_hs_hwmod_class, + .clkdm_name = "l3_init_clkdm", + .main_clk = "usb_host_hs_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INIT_USB_HOST_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + + /* + * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock + * id: i660 + * + * Description: + * In the following configuration : + * - USBHOST module is set to smart-idle mode + * - PRCM asserts idle_req to the USBHOST module ( This typically + * happens when the system is going to a low power mode : all ports + * have been suspended, the master part of the USBHOST module has + * entered the standby state, and SW has cut the functional clocks) + * - an USBHOST interrupt occurs before the module is able to answer + * idle_ack, typically a remote wakeup IRQ. + * Then the USB HOST module will enter a deadlock situation where it + * is no more accessible nor functional. + * + * Workaround: + * Don't use smart idle; use only force idle, hence HWMOD_SWSUP_SIDLE + */ + + /* + * Errata: USB host EHCI may stall when entering smart-standby mode + * Id: i571 + * + * Description: + * When the USBHOST module is set to smart-standby mode, and when it is + * ready to enter the standby state (i.e. all ports are suspended and + * all attached devices are in suspend mode), then it can wrongly assert + * the Mstandby signal too early while there are still some residual OCP + * transactions ongoing. If this condition occurs, the internal state + * machine may go to an undefined state and the USB link may be stuck + * upon the next resume. + * + * Workaround: + * Don't use smart standby; use only force standby, + * hence HWMOD_SWSUP_MSTANDBY + */ + + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, +}; + +/* + * 'usb_otg_hs' class + * high-speed on-the-go universal serial bus (usb_otg_hs) controller + */ + +static struct omap_hwmod_class_sysconfig omap44xx_usb_otg_hs_sysc = { + .rev_offs = 0x0400, + .sysc_offs = 0x0404, + .syss_offs = 0x0408, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_usb_otg_hs_hwmod_class = { + .name = "usb_otg_hs", + .sysc = &omap44xx_usb_otg_hs_sysc, +}; + +/* usb_otg_hs */ +static struct omap_hwmod_opt_clk usb_otg_hs_opt_clks[] = { + { .role = "xclk", .clk = "usb_otg_hs_xclk" }, +}; + +static struct omap_hwmod omap44xx_usb_otg_hs_hwmod = { + .name = "usb_otg_hs", + .class = &omap44xx_usb_otg_hs_hwmod_class, + .clkdm_name = "l3_init_clkdm", + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, + .main_clk = "usb_otg_hs_ick", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3INIT_USB_OTG_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INIT_USB_OTG_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = usb_otg_hs_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(usb_otg_hs_opt_clks), +}; + +/* + * 'usb_tll_hs' class + * usb_tll_hs module is the adapter on the usb_host_hs ports + */ + +static struct omap_hwmod_class_sysconfig omap44xx_usb_tll_hs_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_usb_tll_hs_hwmod_class = { + .name = "usb_tll_hs", + .sysc = &omap44xx_usb_tll_hs_sysc, +}; + +static struct omap_hwmod omap44xx_usb_tll_hs_hwmod = { + .name = "usb_tll_hs", + .class = &omap44xx_usb_tll_hs_hwmod_class, + .clkdm_name = "l3_init_clkdm", + .main_clk = "usb_tll_hs_ick", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INIT_USB_TLL_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'wd_timer' class + * 32-bit watchdog upward counter that generates a pulse on the reset pin on + * overflow condition + */ + +static struct omap_hwmod_class_sysconfig omap44xx_wd_timer_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_wd_timer_hwmod_class = { + .name = "wd_timer", + .sysc = &omap44xx_wd_timer_sysc, + .pre_shutdown = &omap2_wd_timer_disable, + .reset = &omap2_wd_timer_reset, +}; + +/* wd_timer2 */ +static struct omap_hwmod omap44xx_wd_timer2_hwmod = { + .name = "wd_timer2", + .class = &omap44xx_wd_timer_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .main_clk = "sys_32k_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_WKUP_WDT2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_WKUP_WDT2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* wd_timer3 */ +static struct omap_hwmod omap44xx_wd_timer3_hwmod = { + .name = "wd_timer3", + .class = &omap44xx_wd_timer_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "sys_32k_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_WDT3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + + +/* + * interfaces + */ + +/* l3_main_1 -> dmm */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_1__dmm = { + .master = &omap44xx_l3_main_1_hwmod, + .slave = &omap44xx_dmm_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_SDMA, +}; + +/* mpu -> dmm */ +static struct omap_hwmod_ocp_if omap44xx_mpu__dmm = { + .master = &omap44xx_mpu_hwmod, + .slave = &omap44xx_dmm_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU, +}; + +/* iva -> l3_instr */ +static struct omap_hwmod_ocp_if omap44xx_iva__l3_instr = { + .master = &omap44xx_iva_hwmod, + .slave = &omap44xx_l3_instr_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_3 -> l3_instr */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_3__l3_instr = { + .master = &omap44xx_l3_main_3_hwmod, + .slave = &omap44xx_l3_instr_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* ocp_wp_noc -> l3_instr */ +static struct omap_hwmod_ocp_if omap44xx_ocp_wp_noc__l3_instr = { + .master = &omap44xx_ocp_wp_noc_hwmod, + .slave = &omap44xx_l3_instr_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dsp -> l3_main_1 */ +static struct omap_hwmod_ocp_if omap44xx_dsp__l3_main_1 = { + .master = &omap44xx_dsp_hwmod, + .slave = &omap44xx_l3_main_1_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dss -> l3_main_1 */ +static struct omap_hwmod_ocp_if omap44xx_dss__l3_main_1 = { + .master = &omap44xx_dss_hwmod, + .slave = &omap44xx_l3_main_1_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_2 -> l3_main_1 */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l3_main_1 = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_l3_main_1_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> l3_main_1 */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_1 = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_l3_main_1_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* mmc1 -> l3_main_1 */ +static struct omap_hwmod_ocp_if omap44xx_mmc1__l3_main_1 = { + .master = &omap44xx_mmc1_hwmod, + .slave = &omap44xx_l3_main_1_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* mmc2 -> l3_main_1 */ +static struct omap_hwmod_ocp_if omap44xx_mmc2__l3_main_1 = { + .master = &omap44xx_mmc2_hwmod, + .slave = &omap44xx_l3_main_1_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* mpu -> l3_main_1 */ +static struct omap_hwmod_ocp_if omap44xx_mpu__l3_main_1 = { + .master = &omap44xx_mpu_hwmod, + .slave = &omap44xx_l3_main_1_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU, +}; + +/* debugss -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_debugss__l3_main_2 = { + .master = &omap44xx_debugss_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "dbgclk_mux_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dma_system -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_dma_system__l3_main_2 = { + .master = &omap44xx_dma_system_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* fdif -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_fdif__l3_main_2 = { + .master = &omap44xx_fdif_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* gpu -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_gpu__l3_main_2 = { + .master = &omap44xx_gpu_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* hsi -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_hsi__l3_main_2 = { + .master = &omap44xx_hsi_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* ipu -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_ipu__l3_main_2 = { + .master = &omap44xx_ipu_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* iss -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_iss__l3_main_2 = { + .master = &omap44xx_iss_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* iva -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_iva__l3_main_2 = { + .master = &omap44xx_iva_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_1 -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_2 = { + .master = &omap44xx_l3_main_1_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU, +}; + +/* l4_cfg -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_2 = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* usb_host_fs -> l3_main_2 */ +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_usb_host_fs__l3_main_2 = { + .master = &omap44xx_usb_host_fs_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* usb_host_hs -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_usb_host_hs__l3_main_2 = { + .master = &omap44xx_usb_host_hs_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* usb_otg_hs -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_usb_otg_hs__l3_main_2 = { + .master = &omap44xx_usb_otg_hs_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_1 -> l3_main_3 */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_3 = { + .master = &omap44xx_l3_main_1_hwmod, + .slave = &omap44xx_l3_main_3_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU, +}; + +/* l3_main_2 -> l3_main_3 */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l3_main_3 = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_l3_main_3_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> l3_main_3 */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_3 = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_l3_main_3_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* aess -> l4_abe */ +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_aess__l4_abe = { + .master = &omap44xx_aess_hwmod, + .slave = &omap44xx_l4_abe_hwmod, + .clk = "ocp_abe_iclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dsp -> l4_abe */ +static struct omap_hwmod_ocp_if omap44xx_dsp__l4_abe = { + .master = &omap44xx_dsp_hwmod, + .slave = &omap44xx_l4_abe_hwmod, + .clk = "ocp_abe_iclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_1 -> l4_abe */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l4_abe = { + .master = &omap44xx_l3_main_1_hwmod, + .slave = &omap44xx_l4_abe_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* mpu -> l4_abe */ +static struct omap_hwmod_ocp_if omap44xx_mpu__l4_abe = { + .master = &omap44xx_mpu_hwmod, + .slave = &omap44xx_l4_abe_hwmod, + .clk = "ocp_abe_iclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_1 -> l4_cfg */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l4_cfg = { + .master = &omap44xx_l3_main_1_hwmod, + .slave = &omap44xx_l4_cfg_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_2 -> l4_per */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l4_per = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_l4_per_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> l4_wkup */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l4_wkup = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_l4_wkup_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* mpu -> mpu_private */ +static struct omap_hwmod_ocp_if omap44xx_mpu__mpu_private = { + .master = &omap44xx_mpu_hwmod, + .slave = &omap44xx_mpu_private_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> ocp_wp_noc */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ocp_wp_noc = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_ocp_wp_noc_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_aess_addrs[] = { + { + .name = "dmem", + .pa_start = 0x40180000, + .pa_end = 0x4018ffff + }, + { + .name = "cmem", + .pa_start = 0x401a0000, + .pa_end = 0x401a1fff + }, + { + .name = "smem", + .pa_start = 0x401c0000, + .pa_end = 0x401c5fff + }, + { + .name = "pmem", + .pa_start = 0x401e0000, + .pa_end = 0x401e1fff + }, + { + .name = "mpu", + .pa_start = 0x401f1000, + .pa_end = 0x401f13ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_abe -> aess */ +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_abe__aess = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_aess_hwmod, + .clk = "ocp_abe_iclk", + .addr = omap44xx_aess_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_aess_dma_addrs[] = { + { + .name = "dmem_dma", + .pa_start = 0x49080000, + .pa_end = 0x4908ffff + }, + { + .name = "cmem_dma", + .pa_start = 0x490a0000, + .pa_end = 0x490a1fff + }, + { + .name = "smem_dma", + .pa_start = 0x490c0000, + .pa_end = 0x490c5fff + }, + { + .name = "pmem_dma", + .pa_start = 0x490e0000, + .pa_end = 0x490e1fff + }, + { + .name = "dma", + .pa_start = 0x490f1000, + .pa_end = 0x490f13ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_abe -> aess (dma) */ +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_abe__aess_dma = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_aess_hwmod, + .clk = "ocp_abe_iclk", + .addr = omap44xx_aess_dma_addrs, + .user = OCP_USER_SDMA, +}; + +/* l3_main_2 -> c2c */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__c2c = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_c2c_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> counter_32k */ +static struct omap_hwmod_ocp_if omap44xx_l4_wkup__counter_32k = { + .master = &omap44xx_l4_wkup_hwmod, + .slave = &omap44xx_counter_32k_hwmod, + .clk = "l4_wkup_clk_mux_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_ctrl_module_core_addrs[] = { + { + .pa_start = 0x4a002000, + .pa_end = 0x4a0027ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> ctrl_module_core */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ctrl_module_core = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_ctrl_module_core_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_ctrl_module_core_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_ctrl_module_pad_core_addrs[] = { + { + .pa_start = 0x4a100000, + .pa_end = 0x4a1007ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> ctrl_module_pad_core */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ctrl_module_pad_core = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_ctrl_module_pad_core_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_ctrl_module_pad_core_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_ctrl_module_wkup_addrs[] = { + { + .pa_start = 0x4a30c000, + .pa_end = 0x4a30c7ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_wkup -> ctrl_module_wkup */ +static struct omap_hwmod_ocp_if omap44xx_l4_wkup__ctrl_module_wkup = { + .master = &omap44xx_l4_wkup_hwmod, + .slave = &omap44xx_ctrl_module_wkup_hwmod, + .clk = "l4_wkup_clk_mux_ck", + .addr = omap44xx_ctrl_module_wkup_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_ctrl_module_pad_wkup_addrs[] = { + { + .pa_start = 0x4a31e000, + .pa_end = 0x4a31e7ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_wkup -> ctrl_module_pad_wkup */ +static struct omap_hwmod_ocp_if omap44xx_l4_wkup__ctrl_module_pad_wkup = { + .master = &omap44xx_l4_wkup_hwmod, + .slave = &omap44xx_ctrl_module_pad_wkup_hwmod, + .clk = "l4_wkup_clk_mux_ck", + .addr = omap44xx_ctrl_module_pad_wkup_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_instr -> debugss */ +static struct omap_hwmod_ocp_if omap44xx_l3_instr__debugss = { + .master = &omap44xx_l3_instr_hwmod, + .slave = &omap44xx_debugss_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_dma_system_addrs[] = { + { + .pa_start = 0x4a056000, + .pa_end = 0x4a056fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> dma_system */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__dma_system = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_dma_system_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_dma_system_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_abe -> dmic */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__dmic = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_dmic_hwmod, + .clk = "ocp_abe_iclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dsp -> iva */ +static struct omap_hwmod_ocp_if omap44xx_dsp__iva = { + .master = &omap44xx_dsp_hwmod, + .slave = &omap44xx_iva_hwmod, + .clk = "dpll_iva_m5x2_ck", + .user = OCP_USER_DSP, +}; + +/* dsp -> sl2if */ +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_dsp__sl2if = { + .master = &omap44xx_dsp_hwmod, + .slave = &omap44xx_sl2if_hwmod, + .clk = "dpll_iva_m5x2_ck", + .user = OCP_USER_DSP, +}; + +/* l4_cfg -> dsp */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__dsp = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_dsp_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_dma_addrs[] = { + { + .pa_start = 0x58000000, + .pa_end = 0x5800007f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l3_main_2 -> dss */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_dss_hwmod, + .clk = "dss_fck", + .addr = omap44xx_dss_dma_addrs, + .user = OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_addrs[] = { + { + .pa_start = 0x48040000, + .pa_end = 0x4804007f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> dss */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__dss = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_dss_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_dss_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_dispc_dma_addrs[] = { + { + .pa_start = 0x58001000, + .pa_end = 0x58001fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l3_main_2 -> dss_dispc */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dispc = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_dss_dispc_hwmod, + .clk = "dss_fck", + .addr = omap44xx_dss_dispc_dma_addrs, + .user = OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_dispc_addrs[] = { + { + .pa_start = 0x48041000, + .pa_end = 0x48041fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> dss_dispc */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dispc = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_dss_dispc_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_dss_dispc_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_dsi1_dma_addrs[] = { + { + .pa_start = 0x58004000, + .pa_end = 0x580041ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l3_main_2 -> dss_dsi1 */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi1 = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_dss_dsi1_hwmod, + .clk = "dss_fck", + .addr = omap44xx_dss_dsi1_dma_addrs, + .user = OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_dsi1_addrs[] = { + { + .pa_start = 0x48044000, + .pa_end = 0x480441ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> dss_dsi1 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dsi1 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_dss_dsi1_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_dss_dsi1_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_dsi2_dma_addrs[] = { + { + .pa_start = 0x58005000, + .pa_end = 0x580051ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l3_main_2 -> dss_dsi2 */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi2 = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_dss_dsi2_hwmod, + .clk = "dss_fck", + .addr = omap44xx_dss_dsi2_dma_addrs, + .user = OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_dsi2_addrs[] = { + { + .pa_start = 0x48045000, + .pa_end = 0x480451ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> dss_dsi2 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dsi2 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_dss_dsi2_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_dss_dsi2_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_hdmi_dma_addrs[] = { + { + .pa_start = 0x58006000, + .pa_end = 0x58006fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l3_main_2 -> dss_hdmi */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_hdmi = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_dss_hdmi_hwmod, + .clk = "dss_fck", + .addr = omap44xx_dss_hdmi_dma_addrs, + .user = OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_hdmi_addrs[] = { + { + .pa_start = 0x48046000, + .pa_end = 0x48046fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> dss_hdmi */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_hdmi = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_dss_hdmi_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_dss_hdmi_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_rfbi_dma_addrs[] = { + { + .pa_start = 0x58002000, + .pa_end = 0x580020ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l3_main_2 -> dss_rfbi */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_rfbi = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_dss_rfbi_hwmod, + .clk = "dss_fck", + .addr = omap44xx_dss_rfbi_dma_addrs, + .user = OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_rfbi_addrs[] = { + { + .pa_start = 0x48042000, + .pa_end = 0x480420ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> dss_rfbi */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_rfbi = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_dss_rfbi_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_dss_rfbi_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_venc_dma_addrs[] = { + { + .pa_start = 0x58003000, + .pa_end = 0x580030ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l3_main_2 -> dss_venc */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_venc = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_dss_venc_hwmod, + .clk = "dss_fck", + .addr = omap44xx_dss_venc_dma_addrs, + .user = OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_venc_addrs[] = { + { + .pa_start = 0x48043000, + .pa_end = 0x480430ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> dss_venc */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_venc = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_dss_venc_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_dss_venc_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_elm_addrs[] = { + { + .pa_start = 0x48078000, + .pa_end = 0x48078fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> elm */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__elm = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_elm_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_elm_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_fdif_addrs[] = { + { + .pa_start = 0x4a10a000, + .pa_end = 0x4a10a1ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> fdif */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__fdif = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_fdif_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_fdif_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> gpio1 */ +static struct omap_hwmod_ocp_if omap44xx_l4_wkup__gpio1 = { + .master = &omap44xx_l4_wkup_hwmod, + .slave = &omap44xx_gpio1_hwmod, + .clk = "l4_wkup_clk_mux_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio2 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio2 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_gpio2_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio3 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio3 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_gpio3_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio4 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio4 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_gpio4_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio5 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio5 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_gpio5_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio6 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio6 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_gpio6_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_2 -> gpmc */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__gpmc = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_gpmc_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_gpu_addrs[] = { + { + .pa_start = 0x56000000, + .pa_end = 0x5600ffff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l3_main_2 -> gpu */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__gpu = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_gpu_hwmod, + .clk = "l3_div_ck", + .addr = omap44xx_gpu_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_hdq1w_addrs[] = { + { + .pa_start = 0x480b2000, + .pa_end = 0x480b201f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> hdq1w */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__hdq1w = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_hdq1w_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_hdq1w_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_hsi_addrs[] = { + { + .pa_start = 0x4a058000, + .pa_end = 0x4a05bfff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> hsi */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__hsi = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_hsi_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_hsi_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> i2c1 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c1 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_i2c1_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> i2c2 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c2 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_i2c2_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> i2c3 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c3 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_i2c3_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> i2c4 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c4 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_i2c4_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_2 -> ipu */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__ipu = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_ipu_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_iss_addrs[] = { + { + .pa_start = 0x52000000, + .pa_end = 0x520000ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l3_main_2 -> iss */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iss = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_iss_hwmod, + .clk = "l3_div_ck", + .addr = omap44xx_iss_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* iva -> sl2if */ +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_iva__sl2if = { + .master = &omap44xx_iva_hwmod, + .slave = &omap44xx_sl2if_hwmod, + .clk = "dpll_iva_m5x2_ck", + .user = OCP_USER_IVA, +}; + +/* l3_main_2 -> iva */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iva = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_iva_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU, +}; + +/* l4_wkup -> kbd */ +static struct omap_hwmod_ocp_if omap44xx_l4_wkup__kbd = { + .master = &omap44xx_l4_wkup_hwmod, + .slave = &omap44xx_kbd_hwmod, + .clk = "l4_wkup_clk_mux_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_mailbox_addrs[] = { + { + .pa_start = 0x4a0f4000, + .pa_end = 0x4a0f41ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> mailbox */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__mailbox = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_mailbox_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_mailbox_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_mcasp_addrs[] = { + { + .pa_start = 0x40128000, + .pa_end = 0x401283ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_abe -> mcasp */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcasp = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_mcasp_hwmod, + .clk = "ocp_abe_iclk", + .addr = omap44xx_mcasp_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_mcasp_dma_addrs[] = { + { + .pa_start = 0x49028000, + .pa_end = 0x490283ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_abe -> mcasp (dma) */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcasp_dma = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_mcasp_hwmod, + .clk = "ocp_abe_iclk", + .addr = omap44xx_mcasp_dma_addrs, + .user = OCP_USER_SDMA, +}; + +/* l4_abe -> mcbsp1 */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp1 = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_mcbsp1_hwmod, + .clk = "ocp_abe_iclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_abe -> mcbsp2 */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp2 = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_mcbsp2_hwmod, + .clk = "ocp_abe_iclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_abe -> mcbsp3 */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp3 = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_mcbsp3_hwmod, + .clk = "ocp_abe_iclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> mcbsp4 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__mcbsp4 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_mcbsp4_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_abe -> mcpdm */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcpdm = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_mcpdm_hwmod, + .clk = "ocp_abe_iclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> mcspi1 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__mcspi1 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_mcspi1_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> mcspi2 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__mcspi2 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_mcspi2_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> mcspi3 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__mcspi3 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_mcspi3_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> mcspi4 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__mcspi4 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_mcspi4_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> mmc1 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc1 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_mmc1_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> mmc2 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc2 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_mmc2_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> mmc3 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc3 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_mmc3_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> mmc4 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc4 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_mmc4_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> mmc5 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc5 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_mmc5_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_2 -> ocmc_ram */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__ocmc_ram = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_ocmc_ram_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> ocp2scp_usb_phy */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ocp2scp_usb_phy = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_ocp2scp_usb_phy_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* mpu_private -> prcm_mpu */ +static struct omap_hwmod_ocp_if omap44xx_mpu_private__prcm_mpu = { + .master = &omap44xx_mpu_private_hwmod, + .slave = &omap44xx_prcm_mpu_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> cm_core_aon */ +static struct omap_hwmod_ocp_if omap44xx_l4_wkup__cm_core_aon = { + .master = &omap44xx_l4_wkup_hwmod, + .slave = &omap44xx_cm_core_aon_hwmod, + .clk = "l4_wkup_clk_mux_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> cm_core */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__cm_core = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_cm_core_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> prm */ +static struct omap_hwmod_ocp_if omap44xx_l4_wkup__prm = { + .master = &omap44xx_l4_wkup_hwmod, + .slave = &omap44xx_prm_hwmod, + .clk = "l4_wkup_clk_mux_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> scrm */ +static struct omap_hwmod_ocp_if omap44xx_l4_wkup__scrm = { + .master = &omap44xx_l4_wkup_hwmod, + .slave = &omap44xx_scrm_hwmod, + .clk = "l4_wkup_clk_mux_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_2 -> sl2if */ +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l3_main_2__sl2if = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_sl2if_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_slimbus1_addrs[] = { + { + .pa_start = 0x4012c000, + .pa_end = 0x4012c3ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_abe -> slimbus1 */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__slimbus1 = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_slimbus1_hwmod, + .clk = "ocp_abe_iclk", + .addr = omap44xx_slimbus1_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_slimbus1_dma_addrs[] = { + { + .pa_start = 0x4902c000, + .pa_end = 0x4902c3ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_abe -> slimbus1 (dma) */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__slimbus1_dma = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_slimbus1_hwmod, + .clk = "ocp_abe_iclk", + .addr = omap44xx_slimbus1_dma_addrs, + .user = OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_slimbus2_addrs[] = { + { + .pa_start = 0x48076000, + .pa_end = 0x480763ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> slimbus2 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__slimbus2 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_slimbus2_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_slimbus2_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_smartreflex_core_addrs[] = { + { + .pa_start = 0x4a0dd000, + .pa_end = 0x4a0dd03f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> smartreflex_core */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_core = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_smartreflex_core_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_smartreflex_core_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_smartreflex_iva_addrs[] = { + { + .pa_start = 0x4a0db000, + .pa_end = 0x4a0db03f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> smartreflex_iva */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_iva = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_smartreflex_iva_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_smartreflex_iva_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_smartreflex_mpu_addrs[] = { + { + .pa_start = 0x4a0d9000, + .pa_end = 0x4a0d903f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> smartreflex_mpu */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_mpu = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_smartreflex_mpu_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_smartreflex_mpu_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_spinlock_addrs[] = { + { + .pa_start = 0x4a0f6000, + .pa_end = 0x4a0f6fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> spinlock */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__spinlock = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_spinlock_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_spinlock_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> timer1 */ +static struct omap_hwmod_ocp_if omap44xx_l4_wkup__timer1 = { + .master = &omap44xx_l4_wkup_hwmod, + .slave = &omap44xx_timer1_hwmod, + .clk = "l4_wkup_clk_mux_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> timer2 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__timer2 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_timer2_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> timer3 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__timer3 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_timer3_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> timer4 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__timer4 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_timer4_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_abe -> timer5 */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer5 = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_timer5_hwmod, + .clk = "ocp_abe_iclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_abe -> timer6 */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer6 = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_timer6_hwmod, + .clk = "ocp_abe_iclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_abe -> timer7 */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer7 = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_timer7_hwmod, + .clk = "ocp_abe_iclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_abe -> timer8 */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer8 = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_timer8_hwmod, + .clk = "ocp_abe_iclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> timer9 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__timer9 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_timer9_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> timer10 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__timer10 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_timer10_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> timer11 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__timer11 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_timer11_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> uart1 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__uart1 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_uart1_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> uart2 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__uart2 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_uart2_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> uart3 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__uart3 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_uart3_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> uart4 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__uart4 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_uart4_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> usb_host_fs */ +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_cfg__usb_host_fs = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_usb_host_fs_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> usb_host_hs */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_host_hs = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_usb_host_hs_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> usb_otg_hs */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_otg_hs = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_usb_otg_hs_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> usb_tll_hs */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_tll_hs = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_usb_tll_hs_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> wd_timer2 */ +static struct omap_hwmod_ocp_if omap44xx_l4_wkup__wd_timer2 = { + .master = &omap44xx_l4_wkup_hwmod, + .slave = &omap44xx_wd_timer2_hwmod, + .clk = "l4_wkup_clk_mux_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_wd_timer3_addrs[] = { + { + .pa_start = 0x40130000, + .pa_end = 0x4013007f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_abe -> wd_timer3 */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__wd_timer3 = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_wd_timer3_hwmod, + .clk = "ocp_abe_iclk", + .addr = omap44xx_wd_timer3_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_wd_timer3_dma_addrs[] = { + { + .pa_start = 0x49030000, + .pa_end = 0x4903007f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_abe -> wd_timer3 (dma) */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__wd_timer3_dma = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_wd_timer3_hwmod, + .clk = "ocp_abe_iclk", + .addr = omap44xx_wd_timer3_dma_addrs, + .user = OCP_USER_SDMA, +}; + +/* mpu -> emif1 */ +static struct omap_hwmod_ocp_if omap44xx_mpu__emif1 = { + .master = &omap44xx_mpu_hwmod, + .slave = &omap44xx_emif1_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* mpu -> emif2 */ +static struct omap_hwmod_ocp_if omap44xx_mpu__emif2 = { + .master = &omap44xx_mpu_hwmod, + .slave = &omap44xx_emif2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { + &omap44xx_l3_main_1__dmm, + &omap44xx_mpu__dmm, + &omap44xx_iva__l3_instr, + &omap44xx_l3_main_3__l3_instr, + &omap44xx_ocp_wp_noc__l3_instr, + &omap44xx_dsp__l3_main_1, + &omap44xx_dss__l3_main_1, + &omap44xx_l3_main_2__l3_main_1, + &omap44xx_l4_cfg__l3_main_1, + &omap44xx_mmc1__l3_main_1, + &omap44xx_mmc2__l3_main_1, + &omap44xx_mpu__l3_main_1, + &omap44xx_debugss__l3_main_2, + &omap44xx_dma_system__l3_main_2, + &omap44xx_fdif__l3_main_2, + &omap44xx_gpu__l3_main_2, + &omap44xx_hsi__l3_main_2, + &omap44xx_ipu__l3_main_2, + &omap44xx_iss__l3_main_2, + &omap44xx_iva__l3_main_2, + &omap44xx_l3_main_1__l3_main_2, + &omap44xx_l4_cfg__l3_main_2, + /* &omap44xx_usb_host_fs__l3_main_2, */ + &omap44xx_usb_host_hs__l3_main_2, + &omap44xx_usb_otg_hs__l3_main_2, + &omap44xx_l3_main_1__l3_main_3, + &omap44xx_l3_main_2__l3_main_3, + &omap44xx_l4_cfg__l3_main_3, + &omap44xx_aess__l4_abe, + &omap44xx_dsp__l4_abe, + &omap44xx_l3_main_1__l4_abe, + &omap44xx_mpu__l4_abe, + &omap44xx_l3_main_1__l4_cfg, + &omap44xx_l3_main_2__l4_per, + &omap44xx_l4_cfg__l4_wkup, + &omap44xx_mpu__mpu_private, + &omap44xx_l4_cfg__ocp_wp_noc, + &omap44xx_l4_abe__aess, + &omap44xx_l4_abe__aess_dma, + &omap44xx_l3_main_2__c2c, + &omap44xx_l4_wkup__counter_32k, + &omap44xx_l4_cfg__ctrl_module_core, + &omap44xx_l4_cfg__ctrl_module_pad_core, + &omap44xx_l4_wkup__ctrl_module_wkup, + &omap44xx_l4_wkup__ctrl_module_pad_wkup, + &omap44xx_l3_instr__debugss, + &omap44xx_l4_cfg__dma_system, + &omap44xx_l4_abe__dmic, + &omap44xx_dsp__iva, + /* &omap44xx_dsp__sl2if, */ + &omap44xx_l4_cfg__dsp, + &omap44xx_l3_main_2__dss, + &omap44xx_l4_per__dss, + &omap44xx_l3_main_2__dss_dispc, + &omap44xx_l4_per__dss_dispc, + &omap44xx_l3_main_2__dss_dsi1, + &omap44xx_l4_per__dss_dsi1, + &omap44xx_l3_main_2__dss_dsi2, + &omap44xx_l4_per__dss_dsi2, + &omap44xx_l3_main_2__dss_hdmi, + &omap44xx_l4_per__dss_hdmi, + &omap44xx_l3_main_2__dss_rfbi, + &omap44xx_l4_per__dss_rfbi, + &omap44xx_l3_main_2__dss_venc, + &omap44xx_l4_per__dss_venc, + &omap44xx_l4_per__elm, + &omap44xx_l4_cfg__fdif, + &omap44xx_l4_wkup__gpio1, + &omap44xx_l4_per__gpio2, + &omap44xx_l4_per__gpio3, + &omap44xx_l4_per__gpio4, + &omap44xx_l4_per__gpio5, + &omap44xx_l4_per__gpio6, + &omap44xx_l3_main_2__gpmc, + &omap44xx_l3_main_2__gpu, + &omap44xx_l4_per__hdq1w, + &omap44xx_l4_cfg__hsi, + &omap44xx_l4_per__i2c1, + &omap44xx_l4_per__i2c2, + &omap44xx_l4_per__i2c3, + &omap44xx_l4_per__i2c4, + &omap44xx_l3_main_2__ipu, + &omap44xx_l3_main_2__iss, + /* &omap44xx_iva__sl2if, */ + &omap44xx_l3_main_2__iva, + &omap44xx_l4_wkup__kbd, + &omap44xx_l4_cfg__mailbox, + &omap44xx_l4_abe__mcasp, + &omap44xx_l4_abe__mcasp_dma, + &omap44xx_l4_abe__mcbsp1, + &omap44xx_l4_abe__mcbsp2, + &omap44xx_l4_abe__mcbsp3, + &omap44xx_l4_per__mcbsp4, + &omap44xx_l4_abe__mcpdm, + &omap44xx_l4_per__mcspi1, + &omap44xx_l4_per__mcspi2, + &omap44xx_l4_per__mcspi3, + &omap44xx_l4_per__mcspi4, + &omap44xx_l4_per__mmc1, + &omap44xx_l4_per__mmc2, + &omap44xx_l4_per__mmc3, + &omap44xx_l4_per__mmc4, + &omap44xx_l4_per__mmc5, + &omap44xx_l3_main_2__mmu_ipu, + &omap44xx_l4_cfg__mmu_dsp, + &omap44xx_l3_main_2__ocmc_ram, + &omap44xx_l4_cfg__ocp2scp_usb_phy, + &omap44xx_mpu_private__prcm_mpu, + &omap44xx_l4_wkup__cm_core_aon, + &omap44xx_l4_cfg__cm_core, + &omap44xx_l4_wkup__prm, + &omap44xx_l4_wkup__scrm, + /* &omap44xx_l3_main_2__sl2if, */ + &omap44xx_l4_abe__slimbus1, + &omap44xx_l4_abe__slimbus1_dma, + &omap44xx_l4_per__slimbus2, + &omap44xx_l4_cfg__smartreflex_core, + &omap44xx_l4_cfg__smartreflex_iva, + &omap44xx_l4_cfg__smartreflex_mpu, + &omap44xx_l4_cfg__spinlock, + &omap44xx_l4_wkup__timer1, + &omap44xx_l4_per__timer2, + &omap44xx_l4_per__timer3, + &omap44xx_l4_per__timer4, + &omap44xx_l4_abe__timer5, + &omap44xx_l4_abe__timer6, + &omap44xx_l4_abe__timer7, + &omap44xx_l4_abe__timer8, + &omap44xx_l4_per__timer9, + &omap44xx_l4_per__timer10, + &omap44xx_l4_per__timer11, + &omap44xx_l4_per__uart1, + &omap44xx_l4_per__uart2, + &omap44xx_l4_per__uart3, + &omap44xx_l4_per__uart4, + /* &omap44xx_l4_cfg__usb_host_fs, */ + &omap44xx_l4_cfg__usb_host_hs, + &omap44xx_l4_cfg__usb_otg_hs, + &omap44xx_l4_cfg__usb_tll_hs, + &omap44xx_l4_wkup__wd_timer2, + &omap44xx_l4_abe__wd_timer3, + &omap44xx_l4_abe__wd_timer3_dma, + &omap44xx_mpu__emif1, + &omap44xx_mpu__emif2, + NULL, +}; + +int __init omap44xx_hwmod_init(void) +{ + omap_hwmod_init(); + return omap_hwmod_register_links(omap44xx_hwmod_ocp_ifs); +} + diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c new file mode 100644 index 00000000000..1103aa0e0d2 --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c @@ -0,0 +1,2848 @@ +/* + * Hardware modules present on the OMAP54xx chips + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * + * Paul Walmsley + * Benoit Cousson + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/io.h> +#include <linux/platform_data/gpio-omap.h> +#include <linux/power/smartreflex.h> +#include <linux/i2c-omap.h> + +#include <linux/omap-dma.h> +#include <linux/platform_data/spi-omap2-mcspi.h> +#include <linux/platform_data/asoc-ti-mcbsp.h> +#include <plat/dmtimer.h> + +#include "omap_hwmod.h" +#include "omap_hwmod_common_data.h" +#include "cm1_54xx.h" +#include "cm2_54xx.h" +#include "prm54xx.h" +#include "i2c.h" +#include "mmc.h" +#include "wd_timer.h" + +/* Base offset for all OMAP5 interrupts external to MPUSS */ +#define OMAP54XX_IRQ_GIC_START 32 + +/* Base offset for all OMAP5 dma requests */ +#define OMAP54XX_DMA_REQ_START 1 + + +/* + * IP blocks + */ + +/* + * 'dmm' class + * instance(s): dmm + */ +static struct omap_hwmod_class omap54xx_dmm_hwmod_class = { + .name = "dmm", +}; + +/* dmm */ +static struct omap_hwmod omap54xx_dmm_hwmod = { + .name = "dmm", + .class = &omap54xx_dmm_hwmod_class, + .clkdm_name = "emif_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_EMIF_DMM_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_EMIF_DMM_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'l3' class + * instance(s): l3_instr, l3_main_1, l3_main_2, l3_main_3 + */ +static struct omap_hwmod_class omap54xx_l3_hwmod_class = { + .name = "l3", +}; + +/* l3_instr */ +static struct omap_hwmod omap54xx_l3_instr_hwmod = { + .name = "l3_instr", + .class = &omap54xx_l3_hwmod_class, + .clkdm_name = "l3instr_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* l3_main_1 */ +static struct omap_hwmod omap54xx_l3_main_1_hwmod = { + .name = "l3_main_1", + .class = &omap54xx_l3_hwmod_class, + .clkdm_name = "l3main1_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L3MAIN1_L3_MAIN_1_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L3MAIN1_L3_MAIN_1_CONTEXT_OFFSET, + }, + }, +}; + +/* l3_main_2 */ +static struct omap_hwmod omap54xx_l3_main_2_hwmod = { + .name = "l3_main_2", + .class = &omap54xx_l3_hwmod_class, + .clkdm_name = "l3main2_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L3MAIN2_L3_MAIN_2_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L3MAIN2_L3_MAIN_2_CONTEXT_OFFSET, + }, + }, +}; + +/* l3_main_3 */ +static struct omap_hwmod omap54xx_l3_main_3_hwmod = { + .name = "l3_main_3", + .class = &omap54xx_l3_hwmod_class, + .clkdm_name = "l3instr_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L3INSTR_L3_MAIN_3_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L3INSTR_L3_MAIN_3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'l4' class + * instance(s): l4_abe, l4_cfg, l4_per, l4_wkup + */ +static struct omap_hwmod_class omap54xx_l4_hwmod_class = { + .name = "l4", +}; + +/* l4_abe */ +static struct omap_hwmod omap54xx_l4_abe_hwmod = { + .name = "l4_abe", + .class = &omap54xx_l4_hwmod_class, + .clkdm_name = "abe_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_ABE_L4_ABE_CLKCTRL_OFFSET, + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, +}; + +/* l4_cfg */ +static struct omap_hwmod omap54xx_l4_cfg_hwmod = { + .name = "l4_cfg", + .class = &omap54xx_l4_hwmod_class, + .clkdm_name = "l4cfg_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4CFG_L4_CFG_CONTEXT_OFFSET, + }, + }, +}; + +/* l4_per */ +static struct omap_hwmod omap54xx_l4_per_hwmod = { + .name = "l4_per", + .class = &omap54xx_l4_hwmod_class, + .clkdm_name = "l4per_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_L4_PER_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_L4_PER_CONTEXT_OFFSET, + }, + }, +}; + +/* l4_wkup */ +static struct omap_hwmod omap54xx_l4_wkup_hwmod = { + .name = "l4_wkup", + .class = &omap54xx_l4_hwmod_class, + .clkdm_name = "wkupaon_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_WKUPAON_L4_WKUP_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_WKUPAON_L4_WKUP_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'mpu_bus' class + * instance(s): mpu_private + */ +static struct omap_hwmod_class omap54xx_mpu_bus_hwmod_class = { + .name = "mpu_bus", +}; + +/* mpu_private */ +static struct omap_hwmod omap54xx_mpu_private_hwmod = { + .name = "mpu_private", + .class = &omap54xx_mpu_bus_hwmod_class, + .clkdm_name = "mpu_clkdm", + .prcm = { + .omap4 = { + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, +}; + +/* + * 'counter' class + * 32-bit ordinary counter, clocked by the falling edge of the 32 khz clock + */ + +static struct omap_hwmod_class_sysconfig omap54xx_counter_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_counter_hwmod_class = { + .name = "counter", + .sysc = &omap54xx_counter_sysc, +}; + +/* counter_32k */ +static struct omap_hwmod omap54xx_counter_32k_hwmod = { + .name = "counter_32k", + .class = &omap54xx_counter_hwmod_class, + .clkdm_name = "wkupaon_clkdm", + .flags = HWMOD_SWSUP_SIDLE, + .main_clk = "wkupaon_iclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_WKUPAON_COUNTER_32K_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_WKUPAON_COUNTER_32K_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'dma' class + * dma controller for data exchange between memory to memory (i.e. internal or + * external memory) and gp peripherals to memory or memory to gp peripherals + */ + +static struct omap_hwmod_class_sysconfig omap54xx_dma_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x002c, + .syss_offs = 0x0028, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_EMUFREE | SYSC_HAS_MIDLEMODE | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_dma_hwmod_class = { + .name = "dma", + .sysc = &omap54xx_dma_sysc, +}; + +/* dma dev_attr */ +static struct omap_dma_dev_attr dma_dev_attr = { + .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY | + IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY, + .lch_count = 32, +}; + +/* dma_system */ +static struct omap_hwmod_irq_info omap54xx_dma_system_irqs[] = { + { .name = "0", .irq = 12 + OMAP54XX_IRQ_GIC_START }, + { .name = "1", .irq = 13 + OMAP54XX_IRQ_GIC_START }, + { .name = "2", .irq = 14 + OMAP54XX_IRQ_GIC_START }, + { .name = "3", .irq = 15 + OMAP54XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod omap54xx_dma_system_hwmod = { + .name = "dma_system", + .class = &omap54xx_dma_hwmod_class, + .clkdm_name = "dma_clkdm", + .mpu_irqs = omap54xx_dma_system_irqs, + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_DMA_DMA_SYSTEM_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_DMA_DMA_SYSTEM_CONTEXT_OFFSET, + }, + }, + .dev_attr = &dma_dev_attr, +}; + +/* + * 'dmic' class + * digital microphone controller + */ + +static struct omap_hwmod_class_sysconfig omap54xx_dmic_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap54xx_dmic_hwmod_class = { + .name = "dmic", + .sysc = &omap54xx_dmic_sysc, +}; + +/* dmic */ +static struct omap_hwmod omap54xx_dmic_hwmod = { + .name = "dmic", + .class = &omap54xx_dmic_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "dmic_gfclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_ABE_DMIC_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_ABE_DMIC_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'dss' class + * display sub-system + */ +static struct omap_hwmod_class_sysconfig omap54xx_dss_sysc = { + .rev_offs = 0x0000, + .syss_offs = 0x0014, + .sysc_flags = SYSS_HAS_RESET_STATUS, +}; + +static struct omap_hwmod_class omap54xx_dss_hwmod_class = { + .name = "dss", + .sysc = &omap54xx_dss_sysc, + .reset = omap_dss_reset, +}; + +/* dss */ +static struct omap_hwmod_opt_clk dss_opt_clks[] = { + { .role = "32khz_clk", .clk = "dss_32khz_clk" }, + { .role = "sys_clk", .clk = "dss_sys_clk" }, + { .role = "hdmi_clk", .clk = "dss_48mhz_clk" }, +}; + +static struct omap_hwmod omap54xx_dss_hwmod = { + .name = "dss_core", + .class = &omap54xx_dss_hwmod_class, + .clkdm_name = "dss_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "dss_dss_clk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_DSS_DSS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = dss_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), +}; + +/* + * 'dispc' class + * display controller + */ + +static struct omap_hwmod_class_sysconfig omap54xx_dispc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_MIDLEMODE | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_dispc_hwmod_class = { + .name = "dispc", + .sysc = &omap54xx_dispc_sysc, +}; + +/* dss_dispc */ +static struct omap_hwmod_opt_clk dss_dispc_opt_clks[] = { + { .role = "sys_clk", .clk = "dss_sys_clk" }, +}; + +/* dss_dispc dev_attr */ +static struct omap_dss_dispc_dev_attr dss_dispc_dev_attr = { + .has_framedonetv_irq = 1, + .manager_count = 4, +}; + +static struct omap_hwmod omap54xx_dss_dispc_hwmod = { + .name = "dss_dispc", + .class = &omap54xx_dispc_hwmod_class, + .clkdm_name = "dss_clkdm", + .main_clk = "dss_dss_clk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, + .opt_clks = dss_dispc_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_dispc_opt_clks), + .dev_attr = &dss_dispc_dev_attr, +}; + +/* + * 'dsi1' class + * display serial interface controller + */ + +static struct omap_hwmod_class_sysconfig omap54xx_dsi1_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_dsi1_hwmod_class = { + .name = "dsi1", + .sysc = &omap54xx_dsi1_sysc, +}; + +/* dss_dsi1_a */ +static struct omap_hwmod_opt_clk dss_dsi1_a_opt_clks[] = { + { .role = "sys_clk", .clk = "dss_sys_clk" }, +}; + +static struct omap_hwmod omap54xx_dss_dsi1_a_hwmod = { + .name = "dss_dsi1", + .class = &omap54xx_dsi1_hwmod_class, + .clkdm_name = "dss_clkdm", + .main_clk = "dss_dss_clk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, + .opt_clks = dss_dsi1_a_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_a_opt_clks), +}; + +/* dss_dsi1_c */ +static struct omap_hwmod_opt_clk dss_dsi1_c_opt_clks[] = { + { .role = "sys_clk", .clk = "dss_sys_clk" }, +}; + +static struct omap_hwmod omap54xx_dss_dsi1_c_hwmod = { + .name = "dss_dsi2", + .class = &omap54xx_dsi1_hwmod_class, + .clkdm_name = "dss_clkdm", + .main_clk = "dss_dss_clk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, + .opt_clks = dss_dsi1_c_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_c_opt_clks), +}; + +/* + * 'hdmi' class + * hdmi controller + */ + +static struct omap_hwmod_class_sysconfig omap54xx_hdmi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap54xx_hdmi_hwmod_class = { + .name = "hdmi", + .sysc = &omap54xx_hdmi_sysc, +}; + +static struct omap_hwmod_opt_clk dss_hdmi_opt_clks[] = { + { .role = "sys_clk", .clk = "dss_sys_clk" }, +}; + +static struct omap_hwmod omap54xx_dss_hdmi_hwmod = { + .name = "dss_hdmi", + .class = &omap54xx_hdmi_hwmod_class, + .clkdm_name = "dss_clkdm", + .main_clk = "dss_48mhz_clk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, + .opt_clks = dss_hdmi_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks), +}; + +/* + * 'rfbi' class + * remote frame buffer interface + */ + +static struct omap_hwmod_class_sysconfig omap54xx_rfbi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_rfbi_hwmod_class = { + .name = "rfbi", + .sysc = &omap54xx_rfbi_sysc, +}; + +/* dss_rfbi */ +static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = { + { .role = "ick", .clk = "l3_iclk_div" }, +}; + +static struct omap_hwmod omap54xx_dss_rfbi_hwmod = { + .name = "dss_rfbi", + .class = &omap54xx_rfbi_hwmod_class, + .clkdm_name = "dss_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, + .opt_clks = dss_rfbi_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), +}; + +/* + * 'emif' class + * external memory interface no1 (wrapper) + */ + +static struct omap_hwmod_class_sysconfig omap54xx_emif_sysc = { + .rev_offs = 0x0000, +}; + +static struct omap_hwmod_class omap54xx_emif_hwmod_class = { + .name = "emif", + .sysc = &omap54xx_emif_sysc, +}; + +/* emif1 */ +static struct omap_hwmod omap54xx_emif1_hwmod = { + .name = "emif1", + .class = &omap54xx_emif_hwmod_class, + .clkdm_name = "emif_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "dpll_core_h11x2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_EMIF_EMIF1_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_EMIF_EMIF1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* emif2 */ +static struct omap_hwmod omap54xx_emif2_hwmod = { + .name = "emif2", + .class = &omap54xx_emif_hwmod_class, + .clkdm_name = "emif_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "dpll_core_h11x2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_EMIF_EMIF2_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_EMIF_EMIF2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'gpio' class + * general purpose io module + */ + +static struct omap_hwmod_class_sysconfig omap54xx_gpio_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0114, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_gpio_hwmod_class = { + .name = "gpio", + .sysc = &omap54xx_gpio_sysc, + .rev = 2, +}; + +/* gpio dev_attr */ +static struct omap_gpio_dev_attr gpio_dev_attr = { + .bank_width = 32, + .dbck_flag = true, +}; + +/* gpio1 */ +static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { + { .role = "dbclk", .clk = "gpio1_dbclk" }, +}; + +static struct omap_hwmod omap54xx_gpio1_hwmod = { + .name = "gpio1", + .class = &omap54xx_gpio_hwmod_class, + .clkdm_name = "wkupaon_clkdm", + .main_clk = "wkupaon_iclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_WKUPAON_GPIO1_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_WKUPAON_GPIO1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio2 */ +static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { + { .role = "dbclk", .clk = "gpio2_dbclk" }, +}; + +static struct omap_hwmod omap54xx_gpio2_hwmod = { + .name = "gpio2", + .class = &omap54xx_gpio_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4_root_clk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO2_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_GPIO2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio2_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio3 */ +static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { + { .role = "dbclk", .clk = "gpio3_dbclk" }, +}; + +static struct omap_hwmod omap54xx_gpio3_hwmod = { + .name = "gpio3", + .class = &omap54xx_gpio_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4_root_clk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO3_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_GPIO3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio3_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio4 */ +static struct omap_hwmod_opt_clk gpio4_opt_clks[] = { + { .role = "dbclk", .clk = "gpio4_dbclk" }, +}; + +static struct omap_hwmod omap54xx_gpio4_hwmod = { + .name = "gpio4", + .class = &omap54xx_gpio_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4_root_clk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO4_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_GPIO4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio4_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio5 */ +static struct omap_hwmod_opt_clk gpio5_opt_clks[] = { + { .role = "dbclk", .clk = "gpio5_dbclk" }, +}; + +static struct omap_hwmod omap54xx_gpio5_hwmod = { + .name = "gpio5", + .class = &omap54xx_gpio_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4_root_clk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO5_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_GPIO5_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio5_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio6 */ +static struct omap_hwmod_opt_clk gpio6_opt_clks[] = { + { .role = "dbclk", .clk = "gpio6_dbclk" }, +}; + +static struct omap_hwmod omap54xx_gpio6_hwmod = { + .name = "gpio6", + .class = &omap54xx_gpio_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4_root_clk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO6_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_GPIO6_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio6_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio7 */ +static struct omap_hwmod_opt_clk gpio7_opt_clks[] = { + { .role = "dbclk", .clk = "gpio7_dbclk" }, +}; + +static struct omap_hwmod omap54xx_gpio7_hwmod = { + .name = "gpio7", + .class = &omap54xx_gpio_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4_root_clk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO7_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_GPIO7_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio7_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio7_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio8 */ +static struct omap_hwmod_opt_clk gpio8_opt_clks[] = { + { .role = "dbclk", .clk = "gpio8_dbclk" }, +}; + +static struct omap_hwmod omap54xx_gpio8_hwmod = { + .name = "gpio8", + .class = &omap54xx_gpio_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l4_root_clk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO8_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_GPIO8_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio8_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio8_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* + * 'i2c' class + * multimaster high-speed i2c controller + */ + +static struct omap_hwmod_class_sysconfig omap54xx_i2c_sysc = { + .sysc_offs = 0x0010, + .syss_offs = 0x0090, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .clockact = CLOCKACT_TEST_ICLK, + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_i2c_hwmod_class = { + .name = "i2c", + .sysc = &omap54xx_i2c_sysc, + .reset = &omap_i2c_reset, + .rev = OMAP_I2C_IP_VERSION_2, +}; + +/* i2c dev_attr */ +static struct omap_i2c_dev_attr i2c_dev_attr = { + .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE, +}; + +/* i2c1 */ +static struct omap_hwmod omap54xx_i2c1_hwmod = { + .name = "i2c1", + .class = &omap54xx_i2c_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "func_96m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_I2C1_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_I2C1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* i2c2 */ +static struct omap_hwmod omap54xx_i2c2_hwmod = { + .name = "i2c2", + .class = &omap54xx_i2c_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "func_96m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_I2C2_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_I2C2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* i2c3 */ +static struct omap_hwmod omap54xx_i2c3_hwmod = { + .name = "i2c3", + .class = &omap54xx_i2c_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "func_96m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_I2C3_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_I2C3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* i2c4 */ +static struct omap_hwmod omap54xx_i2c4_hwmod = { + .name = "i2c4", + .class = &omap54xx_i2c_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "func_96m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_I2C4_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_I2C4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* i2c5 */ +static struct omap_hwmod omap54xx_i2c5_hwmod = { + .name = "i2c5", + .class = &omap54xx_i2c_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "func_96m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_I2C5_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_I2C5_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* + * 'kbd' class + * keyboard controller + */ + +static struct omap_hwmod_class_sysconfig omap54xx_kbd_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_kbd_hwmod_class = { + .name = "kbd", + .sysc = &omap54xx_kbd_sysc, +}; + +/* kbd */ +static struct omap_hwmod omap54xx_kbd_hwmod = { + .name = "kbd", + .class = &omap54xx_kbd_hwmod_class, + .clkdm_name = "wkupaon_clkdm", + .main_clk = "sys_32k_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_WKUPAON_KBD_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_WKUPAON_KBD_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'mailbox' class + * mailbox module allowing communication between the on-chip processors using a + * queued mailbox-interrupt mechanism. + */ + +static struct omap_hwmod_class_sysconfig omap54xx_mailbox_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap54xx_mailbox_hwmod_class = { + .name = "mailbox", + .sysc = &omap54xx_mailbox_sysc, +}; + +/* mailbox */ +static struct omap_hwmod omap54xx_mailbox_hwmod = { + .name = "mailbox", + .class = &omap54xx_mailbox_hwmod_class, + .clkdm_name = "l4cfg_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4CFG_MAILBOX_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'mcbsp' class + * multi channel buffered serial port controller + */ + +static struct omap_hwmod_class_sysconfig omap54xx_mcbsp_sysc = { + .sysc_offs = 0x008c, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_mcbsp_hwmod_class = { + .name = "mcbsp", + .sysc = &omap54xx_mcbsp_sysc, + .rev = MCBSP_CONFIG_TYPE4, +}; + +/* mcbsp1 */ +static struct omap_hwmod_opt_clk mcbsp1_opt_clks[] = { + { .role = "pad_fck", .clk = "pad_clks_ck" }, + { .role = "prcm_fck", .clk = "mcbsp1_sync_mux_ck" }, +}; + +static struct omap_hwmod omap54xx_mcbsp1_hwmod = { + .name = "mcbsp1", + .class = &omap54xx_mcbsp_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "mcbsp1_gfclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_ABE_MCBSP1_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_ABE_MCBSP1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = mcbsp1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp1_opt_clks), +}; + +/* mcbsp2 */ +static struct omap_hwmod_opt_clk mcbsp2_opt_clks[] = { + { .role = "pad_fck", .clk = "pad_clks_ck" }, + { .role = "prcm_fck", .clk = "mcbsp2_sync_mux_ck" }, +}; + +static struct omap_hwmod omap54xx_mcbsp2_hwmod = { + .name = "mcbsp2", + .class = &omap54xx_mcbsp_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "mcbsp2_gfclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_ABE_MCBSP2_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_ABE_MCBSP2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = mcbsp2_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp2_opt_clks), +}; + +/* mcbsp3 */ +static struct omap_hwmod_opt_clk mcbsp3_opt_clks[] = { + { .role = "pad_fck", .clk = "pad_clks_ck" }, + { .role = "prcm_fck", .clk = "mcbsp3_sync_mux_ck" }, +}; + +static struct omap_hwmod omap54xx_mcbsp3_hwmod = { + .name = "mcbsp3", + .class = &omap54xx_mcbsp_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "mcbsp3_gfclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_ABE_MCBSP3_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_ABE_MCBSP3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = mcbsp3_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp3_opt_clks), +}; + +/* + * 'mcpdm' class + * multi channel pdm controller (proprietary interface with phoenix power + * ic) + */ + +static struct omap_hwmod_class_sysconfig omap54xx_mcpdm_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap54xx_mcpdm_hwmod_class = { + .name = "mcpdm", + .sysc = &omap54xx_mcpdm_sysc, +}; + +/* mcpdm */ +static struct omap_hwmod omap54xx_mcpdm_hwmod = { + .name = "mcpdm", + .class = &omap54xx_mcpdm_hwmod_class, + .clkdm_name = "abe_clkdm", + /* + * It's suspected that the McPDM requires an off-chip main + * functional clock, controlled via I2C. This IP block is + * currently reset very early during boot, before I2C is + * available, so it doesn't seem that we have any choice in + * the kernel other than to avoid resetting it. XXX This is + * really a hardware issue workaround: every IP block should + * be able to source its main functional clock from either + * on-chip or off-chip sources. McPDM seems to be the only + * current exception. + */ + + .flags = HWMOD_EXT_OPT_MAIN_CLK | HWMOD_SWSUP_SIDLE, + .main_clk = "pad_clks_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_ABE_MCPDM_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_ABE_MCPDM_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'mcspi' class + * multichannel serial port interface (mcspi) / master/slave synchronous serial + * bus + */ + +static struct omap_hwmod_class_sysconfig omap54xx_mcspi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap54xx_mcspi_hwmod_class = { + .name = "mcspi", + .sysc = &omap54xx_mcspi_sysc, + .rev = OMAP4_MCSPI_REV, +}; + +/* mcspi1 */ +/* mcspi1 dev_attr */ +static struct omap2_mcspi_dev_attr mcspi1_dev_attr = { + .num_chipselect = 4, +}; + +static struct omap_hwmod omap54xx_mcspi1_hwmod = { + .name = "mcspi1", + .class = &omap54xx_mcspi_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI1_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_MCSPI1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi1_dev_attr, +}; + +/* mcspi2 */ +/* mcspi2 dev_attr */ +static struct omap2_mcspi_dev_attr mcspi2_dev_attr = { + .num_chipselect = 2, +}; + +static struct omap_hwmod omap54xx_mcspi2_hwmod = { + .name = "mcspi2", + .class = &omap54xx_mcspi_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI2_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_MCSPI2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi2_dev_attr, +}; + +/* mcspi3 */ +/* mcspi3 dev_attr */ +static struct omap2_mcspi_dev_attr mcspi3_dev_attr = { + .num_chipselect = 2, +}; + +static struct omap_hwmod omap54xx_mcspi3_hwmod = { + .name = "mcspi3", + .class = &omap54xx_mcspi_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI3_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_MCSPI3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi3_dev_attr, +}; + +/* mcspi4 */ +/* mcspi4 dev_attr */ +static struct omap2_mcspi_dev_attr mcspi4_dev_attr = { + .num_chipselect = 1, +}; + +static struct omap_hwmod omap54xx_mcspi4_hwmod = { + .name = "mcspi4", + .class = &omap54xx_mcspi_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI4_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_MCSPI4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi4_dev_attr, +}; + +/* + * 'mmc' class + * multimedia card high-speed/sd/sdio (mmc/sd/sdio) host controller + */ + +static struct omap_hwmod_class_sysconfig omap54xx_mmc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_MIDLEMODE | + SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap54xx_mmc_hwmod_class = { + .name = "mmc", + .sysc = &omap54xx_mmc_sysc, +}; + +/* mmc1 */ +static struct omap_hwmod_opt_clk mmc1_opt_clks[] = { + { .role = "32khz_clk", .clk = "mmc1_32khz_clk" }, +}; + +/* mmc1 dev_attr */ +static struct omap_mmc_dev_attr mmc1_dev_attr = { + .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, +}; + +static struct omap_hwmod omap54xx_mmc1_hwmod = { + .name = "mmc1", + .class = &omap54xx_mmc_hwmod_class, + .clkdm_name = "l3init_clkdm", + .main_clk = "mmc1_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L3INIT_MMC1_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L3INIT_MMC1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = mmc1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mmc1_opt_clks), + .dev_attr = &mmc1_dev_attr, +}; + +/* mmc2 */ +static struct omap_hwmod omap54xx_mmc2_hwmod = { + .name = "mmc2", + .class = &omap54xx_mmc_hwmod_class, + .clkdm_name = "l3init_clkdm", + .main_clk = "mmc2_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L3INIT_MMC2_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L3INIT_MMC2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* mmc3 */ +static struct omap_hwmod omap54xx_mmc3_hwmod = { + .name = "mmc3", + .class = &omap54xx_mmc_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_MMC3_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_MMC3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* mmc4 */ +static struct omap_hwmod omap54xx_mmc4_hwmod = { + .name = "mmc4", + .class = &omap54xx_mmc_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_MMC4_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_MMC4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* mmc5 */ +static struct omap_hwmod omap54xx_mmc5_hwmod = { + .name = "mmc5", + .class = &omap54xx_mmc_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "func_96m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_MMC5_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_MMC5_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'mmu' class + * The memory management unit performs virtual to physical address translation + * for its requestors. + */ + +static struct omap_hwmod_class_sysconfig omap54xx_mmu_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_mmu_hwmod_class = { + .name = "mmu", + .sysc = &omap54xx_mmu_sysc, +}; + +static struct omap_hwmod_rst_info omap54xx_mmu_dsp_resets[] = { + { .name = "mmu_cache", .rst_shift = 1 }, +}; + +static struct omap_hwmod omap54xx_mmu_dsp_hwmod = { + .name = "mmu_dsp", + .class = &omap54xx_mmu_hwmod_class, + .clkdm_name = "dsp_clkdm", + .rst_lines = omap54xx_mmu_dsp_resets, + .rst_lines_cnt = ARRAY_SIZE(omap54xx_mmu_dsp_resets), + .main_clk = "dpll_iva_h11x2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_DSP_DSP_CLKCTRL_OFFSET, + .rstctrl_offs = OMAP54XX_RM_DSP_RSTCTRL_OFFSET, + .context_offs = OMAP54XX_RM_DSP_DSP_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* mmu ipu */ +static struct omap_hwmod_rst_info omap54xx_mmu_ipu_resets[] = { + { .name = "mmu_cache", .rst_shift = 2 }, +}; + +static struct omap_hwmod omap54xx_mmu_ipu_hwmod = { + .name = "mmu_ipu", + .class = &omap54xx_mmu_hwmod_class, + .clkdm_name = "ipu_clkdm", + .rst_lines = omap54xx_mmu_ipu_resets, + .rst_lines_cnt = ARRAY_SIZE(omap54xx_mmu_ipu_resets), + .main_clk = "dpll_core_h22x2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_IPU_IPU_CLKCTRL_OFFSET, + .rstctrl_offs = OMAP54XX_RM_IPU_RSTCTRL_OFFSET, + .context_offs = OMAP54XX_RM_IPU_IPU_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'mpu' class + * mpu sub-system + */ + +static struct omap_hwmod_class omap54xx_mpu_hwmod_class = { + .name = "mpu", +}; + +/* mpu */ +static struct omap_hwmod omap54xx_mpu_hwmod = { + .name = "mpu", + .class = &omap54xx_mpu_hwmod_class, + .clkdm_name = "mpu_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "dpll_mpu_m2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_MPU_MPU_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_MPU_MPU_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'spinlock' class + * spinlock provides hardware assistance for synchronizing the processes + * running on multiple processors + */ + +static struct omap_hwmod_class_sysconfig omap54xx_spinlock_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_spinlock_hwmod_class = { + .name = "spinlock", + .sysc = &omap54xx_spinlock_sysc, +}; + +/* spinlock */ +static struct omap_hwmod omap54xx_spinlock_hwmod = { + .name = "spinlock", + .class = &omap54xx_spinlock_hwmod_class, + .clkdm_name = "l4cfg_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4CFG_SPINLOCK_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4CFG_SPINLOCK_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'ocp2scp' class + * bridge to transform ocp interface protocol to scp (serial control port) + * protocol + */ + +static struct omap_hwmod_class_sysconfig omap54xx_ocp2scp_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_ocp2scp_hwmod_class = { + .name = "ocp2scp", + .sysc = &omap54xx_ocp2scp_sysc, +}; + +/* ocp2scp1 */ +static struct omap_hwmod omap54xx_ocp2scp1_hwmod = { + .name = "ocp2scp1", + .class = &omap54xx_ocp2scp_hwmod_class, + .clkdm_name = "l3init_clkdm", + .main_clk = "l4_root_clk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L3INIT_OCP2SCP1_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L3INIT_OCP2SCP1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'timer' class + * general purpose timer module with accurate 1ms tick + * This class contains several variants: ['timer_1ms', 'timer'] + */ + +static struct omap_hwmod_class_sysconfig omap54xx_timer_1ms_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, + .clockact = CLOCKACT_TEST_ICLK, +}; + +static struct omap_hwmod_class omap54xx_timer_1ms_hwmod_class = { + .name = "timer", + .sysc = &omap54xx_timer_1ms_sysc, +}; + +static struct omap_hwmod_class_sysconfig omap54xx_timer_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap54xx_timer_hwmod_class = { + .name = "timer", + .sysc = &omap54xx_timer_sysc, +}; + +/* timer1 */ +static struct omap_hwmod omap54xx_timer1_hwmod = { + .name = "timer1", + .class = &omap54xx_timer_1ms_hwmod_class, + .clkdm_name = "wkupaon_clkdm", + .main_clk = "timer1_gfclk_mux", + .flags = HWMOD_SET_DEFAULT_CLOCKACT, + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_WKUPAON_TIMER1_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_WKUPAON_TIMER1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer2 */ +static struct omap_hwmod omap54xx_timer2_hwmod = { + .name = "timer2", + .class = &omap54xx_timer_1ms_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "timer2_gfclk_mux", + .flags = HWMOD_SET_DEFAULT_CLOCKACT, + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER2_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_TIMER2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer3 */ +static struct omap_hwmod omap54xx_timer3_hwmod = { + .name = "timer3", + .class = &omap54xx_timer_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "timer3_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER3_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_TIMER3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer4 */ +static struct omap_hwmod omap54xx_timer4_hwmod = { + .name = "timer4", + .class = &omap54xx_timer_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "timer4_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER4_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_TIMER4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer5 */ +static struct omap_hwmod omap54xx_timer5_hwmod = { + .name = "timer5", + .class = &omap54xx_timer_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "timer5_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_ABE_TIMER5_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_ABE_TIMER5_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer6 */ +static struct omap_hwmod omap54xx_timer6_hwmod = { + .name = "timer6", + .class = &omap54xx_timer_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "timer6_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_ABE_TIMER6_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_ABE_TIMER6_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer7 */ +static struct omap_hwmod omap54xx_timer7_hwmod = { + .name = "timer7", + .class = &omap54xx_timer_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "timer7_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_ABE_TIMER7_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_ABE_TIMER7_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer8 */ +static struct omap_hwmod omap54xx_timer8_hwmod = { + .name = "timer8", + .class = &omap54xx_timer_hwmod_class, + .clkdm_name = "abe_clkdm", + .main_clk = "timer8_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_ABE_TIMER8_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_ABE_TIMER8_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer9 */ +static struct omap_hwmod omap54xx_timer9_hwmod = { + .name = "timer9", + .class = &omap54xx_timer_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "timer9_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER9_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_TIMER9_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer10 */ +static struct omap_hwmod omap54xx_timer10_hwmod = { + .name = "timer10", + .class = &omap54xx_timer_1ms_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "timer10_gfclk_mux", + .flags = HWMOD_SET_DEFAULT_CLOCKACT, + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER10_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_TIMER10_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer11 */ +static struct omap_hwmod omap54xx_timer11_hwmod = { + .name = "timer11", + .class = &omap54xx_timer_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "timer11_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER11_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_TIMER11_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'uart' class + * universal asynchronous receiver/transmitter (uart) + */ + +static struct omap_hwmod_class_sysconfig omap54xx_uart_sysc = { + .rev_offs = 0x0050, + .sysc_offs = 0x0054, + .syss_offs = 0x0058, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_uart_hwmod_class = { + .name = "uart", + .sysc = &omap54xx_uart_sysc, +}; + +/* uart1 */ +static struct omap_hwmod omap54xx_uart1_hwmod = { + .name = "uart1", + .class = &omap54xx_uart_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_UART1_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_UART1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* uart2 */ +static struct omap_hwmod omap54xx_uart2_hwmod = { + .name = "uart2", + .class = &omap54xx_uart_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_UART2_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_UART2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* uart3 */ +static struct omap_hwmod omap54xx_uart3_hwmod = { + .name = "uart3", + .class = &omap54xx_uart_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = DEBUG_OMAP4UART3_FLAGS, + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_UART3_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_UART3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* uart4 */ +static struct omap_hwmod omap54xx_uart4_hwmod = { + .name = "uart4", + .class = &omap54xx_uart_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = DEBUG_OMAP4UART4_FLAGS, + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_UART4_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_UART4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* uart5 */ +static struct omap_hwmod omap54xx_uart5_hwmod = { + .name = "uart5", + .class = &omap54xx_uart_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_UART5_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_UART5_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* uart6 */ +static struct omap_hwmod omap54xx_uart6_hwmod = { + .name = "uart6", + .class = &omap54xx_uart_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4PER_UART6_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4PER_UART6_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'usb_host_hs' class + * high-speed multi-port usb host controller + */ + +static struct omap_hwmod_class_sysconfig omap54xx_usb_host_hs_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSC_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap54xx_usb_host_hs_hwmod_class = { + .name = "usb_host_hs", + .sysc = &omap54xx_usb_host_hs_sysc, +}; + +static struct omap_hwmod omap54xx_usb_host_hs_hwmod = { + .name = "usb_host_hs", + .class = &omap54xx_usb_host_hs_hwmod_class, + .clkdm_name = "l3init_clkdm", + /* + * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock + * id: i660 + * + * Description: + * In the following configuration : + * - USBHOST module is set to smart-idle mode + * - PRCM asserts idle_req to the USBHOST module ( This typically + * happens when the system is going to a low power mode : all ports + * have been suspended, the master part of the USBHOST module has + * entered the standby state, and SW has cut the functional clocks) + * - an USBHOST interrupt occurs before the module is able to answer + * idle_ack, typically a remote wakeup IRQ. + * Then the USB HOST module will enter a deadlock situation where it + * is no more accessible nor functional. + * + * Workaround: + * Don't use smart idle; use only force idle, hence HWMOD_SWSUP_SIDLE + */ + + /* + * Errata: USB host EHCI may stall when entering smart-standby mode + * Id: i571 + * + * Description: + * When the USBHOST module is set to smart-standby mode, and when it is + * ready to enter the standby state (i.e. all ports are suspended and + * all attached devices are in suspend mode), then it can wrongly assert + * the Mstandby signal too early while there are still some residual OCP + * transactions ongoing. If this condition occurs, the internal state + * machine may go to an undefined state and the USB link may be stuck + * upon the next resume. + * + * Workaround: + * Don't use smart standby; use only force standby, + * hence HWMOD_SWSUP_MSTANDBY + */ + + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, + .main_clk = "l3init_60m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L3INIT_USB_HOST_HS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'usb_tll_hs' class + * usb_tll_hs module is the adapter on the usb_host_hs ports + */ + +static struct omap_hwmod_class_sysconfig omap54xx_usb_tll_hs_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_usb_tll_hs_hwmod_class = { + .name = "usb_tll_hs", + .sysc = &omap54xx_usb_tll_hs_sysc, +}; + +static struct omap_hwmod omap54xx_usb_tll_hs_hwmod = { + .name = "usb_tll_hs", + .class = &omap54xx_usb_tll_hs_hwmod_class, + .clkdm_name = "l3init_clkdm", + .main_clk = "l4_root_clk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L3INIT_USB_TLL_HS_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L3INIT_USB_TLL_HS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'usb_otg_ss' class + * 2.0 super speed (usb_otg_ss) controller + */ + +static struct omap_hwmod_class_sysconfig omap54xx_usb_otg_ss_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_DMADISABLE | SYSC_HAS_MIDLEMODE | + SYSC_HAS_SIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap54xx_usb_otg_ss_hwmod_class = { + .name = "usb_otg_ss", + .sysc = &omap54xx_usb_otg_ss_sysc, +}; + +/* usb_otg_ss */ +static struct omap_hwmod_opt_clk usb_otg_ss_opt_clks[] = { + { .role = "refclk960m", .clk = "usb_otg_ss_refclk960m" }, +}; + +static struct omap_hwmod omap54xx_usb_otg_ss_hwmod = { + .name = "usb_otg_ss", + .class = &omap54xx_usb_otg_ss_hwmod_class, + .clkdm_name = "l3init_clkdm", + .flags = HWMOD_SWSUP_SIDLE, + .main_clk = "dpll_core_h13x2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L3INIT_USB_OTG_SS_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L3INIT_USB_OTG_SS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = usb_otg_ss_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(usb_otg_ss_opt_clks), +}; + +/* + * 'wd_timer' class + * 32-bit watchdog upward counter that generates a pulse on the reset pin on + * overflow condition + */ + +static struct omap_hwmod_class_sysconfig omap54xx_wd_timer_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_wd_timer_hwmod_class = { + .name = "wd_timer", + .sysc = &omap54xx_wd_timer_sysc, + .pre_shutdown = &omap2_wd_timer_disable, +}; + +/* wd_timer2 */ +static struct omap_hwmod omap54xx_wd_timer2_hwmod = { + .name = "wd_timer2", + .class = &omap54xx_wd_timer_hwmod_class, + .clkdm_name = "wkupaon_clkdm", + .main_clk = "sys_32k_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_WKUPAON_WD_TIMER2_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_WKUPAON_WD_TIMER2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'ocp2scp' class + * bridge to transform ocp interface protocol to scp (serial control port) + * protocol + */ +/* ocp2scp3 */ +static struct omap_hwmod omap54xx_ocp2scp3_hwmod; +/* l4_cfg -> ocp2scp3 */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__ocp2scp3 = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_ocp2scp3_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod omap54xx_ocp2scp3_hwmod = { + .name = "ocp2scp3", + .class = &omap54xx_ocp2scp_hwmod_class, + .clkdm_name = "l3init_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L3INIT_OCP2SCP3_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L3INIT_OCP2SCP3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'sata' class + * sata: serial ata interface gen2 compliant ( 1 rx/ 1 tx) + */ + +static struct omap_hwmod_class_sysconfig omap54xx_sata_sysc = { + .sysc_offs = 0x0000, + .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap54xx_sata_hwmod_class = { + .name = "sata", + .sysc = &omap54xx_sata_sysc, +}; + +/* sata */ +static struct omap_hwmod omap54xx_sata_hwmod = { + .name = "sata", + .class = &omap54xx_sata_hwmod_class, + .clkdm_name = "l3init_clkdm", + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, + .main_clk = "func_48m_fclk", + .mpu_rt_idx = 1, + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L3INIT_SATA_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L3INIT_SATA_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* l4_cfg -> sata */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__sata = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_sata_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* + * Interfaces + */ + +/* l3_main_1 -> dmm */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_1__dmm = { + .master = &omap54xx_l3_main_1_hwmod, + .slave = &omap54xx_dmm_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_SDMA, +}; + +/* l3_main_3 -> l3_instr */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_3__l3_instr = { + .master = &omap54xx_l3_main_3_hwmod, + .slave = &omap54xx_l3_instr_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_2 -> l3_main_1 */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_2__l3_main_1 = { + .master = &omap54xx_l3_main_2_hwmod, + .slave = &omap54xx_l3_main_1_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> l3_main_1 */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__l3_main_1 = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_l3_main_1_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> mmu_dsp */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__mmu_dsp = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_mmu_dsp_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* mpu -> l3_main_1 */ +static struct omap_hwmod_ocp_if omap54xx_mpu__l3_main_1 = { + .master = &omap54xx_mpu_hwmod, + .slave = &omap54xx_l3_main_1_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU, +}; + +/* l3_main_1 -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l3_main_2 = { + .master = &omap54xx_l3_main_1_hwmod, + .slave = &omap54xx_l3_main_2_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU, +}; + +/* l4_cfg -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__l3_main_2 = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_l3_main_2_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_2 -> mmu_ipu */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_2__mmu_ipu = { + .master = &omap54xx_l3_main_2_hwmod, + .slave = &omap54xx_mmu_ipu_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_1 -> l3_main_3 */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l3_main_3 = { + .master = &omap54xx_l3_main_1_hwmod, + .slave = &omap54xx_l3_main_3_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU, +}; + +/* l3_main_2 -> l3_main_3 */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_2__l3_main_3 = { + .master = &omap54xx_l3_main_2_hwmod, + .slave = &omap54xx_l3_main_3_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> l3_main_3 */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__l3_main_3 = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_l3_main_3_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_1 -> l4_abe */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l4_abe = { + .master = &omap54xx_l3_main_1_hwmod, + .slave = &omap54xx_l4_abe_hwmod, + .clk = "abe_iclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* mpu -> l4_abe */ +static struct omap_hwmod_ocp_if omap54xx_mpu__l4_abe = { + .master = &omap54xx_mpu_hwmod, + .slave = &omap54xx_l4_abe_hwmod, + .clk = "abe_iclk", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_1 -> l4_cfg */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l4_cfg = { + .master = &omap54xx_l3_main_1_hwmod, + .slave = &omap54xx_l4_cfg_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_2 -> l4_per */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_2__l4_per = { + .master = &omap54xx_l3_main_2_hwmod, + .slave = &omap54xx_l4_per_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_1 -> l4_wkup */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l4_wkup = { + .master = &omap54xx_l3_main_1_hwmod, + .slave = &omap54xx_l4_wkup_hwmod, + .clk = "wkupaon_iclk_mux", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* mpu -> mpu_private */ +static struct omap_hwmod_ocp_if omap54xx_mpu__mpu_private = { + .master = &omap54xx_mpu_hwmod, + .slave = &omap54xx_mpu_private_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> counter_32k */ +static struct omap_hwmod_ocp_if omap54xx_l4_wkup__counter_32k = { + .master = &omap54xx_l4_wkup_hwmod, + .slave = &omap54xx_counter_32k_hwmod, + .clk = "wkupaon_iclk_mux", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap54xx_dma_system_addrs[] = { + { + .pa_start = 0x4a056000, + .pa_end = 0x4a056fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> dma_system */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__dma_system = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_dma_system_hwmod, + .clk = "l4_root_clk_div", + .addr = omap54xx_dma_system_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_abe -> dmic */ +static struct omap_hwmod_ocp_if omap54xx_l4_abe__dmic = { + .master = &omap54xx_l4_abe_hwmod, + .slave = &omap54xx_dmic_hwmod, + .clk = "abe_iclk", + .user = OCP_USER_MPU, +}; + +/* l3_main_2 -> dss */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss = { + .master = &omap54xx_l3_main_2_hwmod, + .slave = &omap54xx_dss_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_2 -> dss_dispc */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_dispc = { + .master = &omap54xx_l3_main_2_hwmod, + .slave = &omap54xx_dss_dispc_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_2 -> dss_dsi1_a */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_dsi1_a = { + .master = &omap54xx_l3_main_2_hwmod, + .slave = &omap54xx_dss_dsi1_a_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_2 -> dss_dsi1_c */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_dsi1_c = { + .master = &omap54xx_l3_main_2_hwmod, + .slave = &omap54xx_dss_dsi1_c_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_2 -> dss_hdmi */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_hdmi = { + .master = &omap54xx_l3_main_2_hwmod, + .slave = &omap54xx_dss_hdmi_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_2 -> dss_rfbi */ +static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_rfbi = { + .master = &omap54xx_l3_main_2_hwmod, + .slave = &omap54xx_dss_rfbi_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* mpu -> emif1 */ +static struct omap_hwmod_ocp_if omap54xx_mpu__emif1 = { + .master = &omap54xx_mpu_hwmod, + .slave = &omap54xx_emif1_hwmod, + .clk = "dpll_core_h11x2_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* mpu -> emif2 */ +static struct omap_hwmod_ocp_if omap54xx_mpu__emif2 = { + .master = &omap54xx_mpu_hwmod, + .slave = &omap54xx_emif2_hwmod, + .clk = "dpll_core_h11x2_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> gpio1 */ +static struct omap_hwmod_ocp_if omap54xx_l4_wkup__gpio1 = { + .master = &omap54xx_l4_wkup_hwmod, + .slave = &omap54xx_gpio1_hwmod, + .clk = "wkupaon_iclk_mux", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio2 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio2 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_gpio2_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio3 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio3 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_gpio3_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio4 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio4 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_gpio4_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio5 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio5 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_gpio5_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio6 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio6 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_gpio6_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio7 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio7 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_gpio7_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio8 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio8 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_gpio8_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> i2c1 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__i2c1 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_i2c1_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> i2c2 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__i2c2 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_i2c2_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> i2c3 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__i2c3 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_i2c3_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> i2c4 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__i2c4 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_i2c4_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> i2c5 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__i2c5 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_i2c5_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> kbd */ +static struct omap_hwmod_ocp_if omap54xx_l4_wkup__kbd = { + .master = &omap54xx_l4_wkup_hwmod, + .slave = &omap54xx_kbd_hwmod, + .clk = "wkupaon_iclk_mux", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> mailbox */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__mailbox = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_mailbox_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_abe -> mcbsp1 */ +static struct omap_hwmod_ocp_if omap54xx_l4_abe__mcbsp1 = { + .master = &omap54xx_l4_abe_hwmod, + .slave = &omap54xx_mcbsp1_hwmod, + .clk = "abe_iclk", + .user = OCP_USER_MPU, +}; + +/* l4_abe -> mcbsp2 */ +static struct omap_hwmod_ocp_if omap54xx_l4_abe__mcbsp2 = { + .master = &omap54xx_l4_abe_hwmod, + .slave = &omap54xx_mcbsp2_hwmod, + .clk = "abe_iclk", + .user = OCP_USER_MPU, +}; + +/* l4_abe -> mcbsp3 */ +static struct omap_hwmod_ocp_if omap54xx_l4_abe__mcbsp3 = { + .master = &omap54xx_l4_abe_hwmod, + .slave = &omap54xx_mcbsp3_hwmod, + .clk = "abe_iclk", + .user = OCP_USER_MPU, +}; + +/* l4_abe -> mcpdm */ +static struct omap_hwmod_ocp_if omap54xx_l4_abe__mcpdm = { + .master = &omap54xx_l4_abe_hwmod, + .slave = &omap54xx_mcpdm_hwmod, + .clk = "abe_iclk", + .user = OCP_USER_MPU, +}; + +/* l4_per -> mcspi1 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__mcspi1 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_mcspi1_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> mcspi2 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__mcspi2 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_mcspi2_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> mcspi3 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__mcspi3 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_mcspi3_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> mcspi4 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__mcspi4 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_mcspi4_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> mmc1 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__mmc1 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_mmc1_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> mmc2 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__mmc2 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_mmc2_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> mmc3 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__mmc3 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_mmc3_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> mmc4 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__mmc4 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_mmc4_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> mmc5 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__mmc5 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_mmc5_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> mpu */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__mpu = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_mpu_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> spinlock */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__spinlock = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_spinlock_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> ocp2scp1 */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__ocp2scp1 = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_ocp2scp1_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> timer1 */ +static struct omap_hwmod_ocp_if omap54xx_l4_wkup__timer1 = { + .master = &omap54xx_l4_wkup_hwmod, + .slave = &omap54xx_timer1_hwmod, + .clk = "wkupaon_iclk_mux", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> timer2 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__timer2 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_timer2_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> timer3 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__timer3 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_timer3_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> timer4 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__timer4 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_timer4_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_abe -> timer5 */ +static struct omap_hwmod_ocp_if omap54xx_l4_abe__timer5 = { + .master = &omap54xx_l4_abe_hwmod, + .slave = &omap54xx_timer5_hwmod, + .clk = "abe_iclk", + .user = OCP_USER_MPU, +}; + +/* l4_abe -> timer6 */ +static struct omap_hwmod_ocp_if omap54xx_l4_abe__timer6 = { + .master = &omap54xx_l4_abe_hwmod, + .slave = &omap54xx_timer6_hwmod, + .clk = "abe_iclk", + .user = OCP_USER_MPU, +}; + +/* l4_abe -> timer7 */ +static struct omap_hwmod_ocp_if omap54xx_l4_abe__timer7 = { + .master = &omap54xx_l4_abe_hwmod, + .slave = &omap54xx_timer7_hwmod, + .clk = "abe_iclk", + .user = OCP_USER_MPU, +}; + +/* l4_abe -> timer8 */ +static struct omap_hwmod_ocp_if omap54xx_l4_abe__timer8 = { + .master = &omap54xx_l4_abe_hwmod, + .slave = &omap54xx_timer8_hwmod, + .clk = "abe_iclk", + .user = OCP_USER_MPU, +}; + +/* l4_per -> timer9 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__timer9 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_timer9_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> timer10 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__timer10 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_timer10_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> timer11 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__timer11 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_timer11_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> uart1 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__uart1 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_uart1_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> uart2 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__uart2 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_uart2_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> uart3 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__uart3 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_uart3_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> uart4 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__uart4 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_uart4_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> uart5 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__uart5 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_uart5_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> uart6 */ +static struct omap_hwmod_ocp_if omap54xx_l4_per__uart6 = { + .master = &omap54xx_l4_per_hwmod, + .slave = &omap54xx_uart6_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> usb_host_hs */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_host_hs = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_usb_host_hs_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> usb_tll_hs */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_tll_hs = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_usb_tll_hs_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> usb_otg_ss */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_otg_ss = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_usb_otg_ss_hwmod, + .clk = "dpll_core_h13x2_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> wd_timer2 */ +static struct omap_hwmod_ocp_if omap54xx_l4_wkup__wd_timer2 = { + .master = &omap54xx_l4_wkup_hwmod, + .slave = &omap54xx_wd_timer2_hwmod, + .clk = "wkupaon_iclk_mux", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = { + &omap54xx_l3_main_1__dmm, + &omap54xx_l3_main_3__l3_instr, + &omap54xx_l3_main_2__l3_main_1, + &omap54xx_l4_cfg__l3_main_1, + &omap54xx_mpu__l3_main_1, + &omap54xx_l3_main_1__l3_main_2, + &omap54xx_l4_cfg__l3_main_2, + &omap54xx_l3_main_1__l3_main_3, + &omap54xx_l3_main_2__l3_main_3, + &omap54xx_l4_cfg__l3_main_3, + &omap54xx_l3_main_1__l4_abe, + &omap54xx_mpu__l4_abe, + &omap54xx_l3_main_1__l4_cfg, + &omap54xx_l3_main_2__l4_per, + &omap54xx_l3_main_1__l4_wkup, + &omap54xx_mpu__mpu_private, + &omap54xx_l4_wkup__counter_32k, + &omap54xx_l4_cfg__dma_system, + &omap54xx_l4_abe__dmic, + &omap54xx_l4_cfg__mmu_dsp, + &omap54xx_l3_main_2__dss, + &omap54xx_l3_main_2__dss_dispc, + &omap54xx_l3_main_2__dss_dsi1_a, + &omap54xx_l3_main_2__dss_dsi1_c, + &omap54xx_l3_main_2__dss_hdmi, + &omap54xx_l3_main_2__dss_rfbi, + &omap54xx_mpu__emif1, + &omap54xx_mpu__emif2, + &omap54xx_l4_wkup__gpio1, + &omap54xx_l4_per__gpio2, + &omap54xx_l4_per__gpio3, + &omap54xx_l4_per__gpio4, + &omap54xx_l4_per__gpio5, + &omap54xx_l4_per__gpio6, + &omap54xx_l4_per__gpio7, + &omap54xx_l4_per__gpio8, + &omap54xx_l4_per__i2c1, + &omap54xx_l4_per__i2c2, + &omap54xx_l4_per__i2c3, + &omap54xx_l4_per__i2c4, + &omap54xx_l4_per__i2c5, + &omap54xx_l3_main_2__mmu_ipu, + &omap54xx_l4_wkup__kbd, + &omap54xx_l4_cfg__mailbox, + &omap54xx_l4_abe__mcbsp1, + &omap54xx_l4_abe__mcbsp2, + &omap54xx_l4_abe__mcbsp3, + &omap54xx_l4_abe__mcpdm, + &omap54xx_l4_per__mcspi1, + &omap54xx_l4_per__mcspi2, + &omap54xx_l4_per__mcspi3, + &omap54xx_l4_per__mcspi4, + &omap54xx_l4_per__mmc1, + &omap54xx_l4_per__mmc2, + &omap54xx_l4_per__mmc3, + &omap54xx_l4_per__mmc4, + &omap54xx_l4_per__mmc5, + &omap54xx_l4_cfg__mpu, + &omap54xx_l4_cfg__spinlock, + &omap54xx_l4_cfg__ocp2scp1, + &omap54xx_l4_wkup__timer1, + &omap54xx_l4_per__timer2, + &omap54xx_l4_per__timer3, + &omap54xx_l4_per__timer4, + &omap54xx_l4_abe__timer5, + &omap54xx_l4_abe__timer6, + &omap54xx_l4_abe__timer7, + &omap54xx_l4_abe__timer8, + &omap54xx_l4_per__timer9, + &omap54xx_l4_per__timer10, + &omap54xx_l4_per__timer11, + &omap54xx_l4_per__uart1, + &omap54xx_l4_per__uart2, + &omap54xx_l4_per__uart3, + &omap54xx_l4_per__uart4, + &omap54xx_l4_per__uart5, + &omap54xx_l4_per__uart6, + &omap54xx_l4_cfg__usb_host_hs, + &omap54xx_l4_cfg__usb_tll_hs, + &omap54xx_l4_cfg__usb_otg_ss, + &omap54xx_l4_wkup__wd_timer2, + &omap54xx_l4_cfg__ocp2scp3, + &omap54xx_l4_cfg__sata, + NULL, +}; + +int __init omap54xx_hwmod_init(void) +{ + omap_hwmod_init(); + return omap_hwmod_register_links(omap54xx_hwmod_ocp_ifs); +} diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c new file mode 100644 index 00000000000..284324f2b98 --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -0,0 +1,2721 @@ +/* + * Hardware modules present on the DRA7xx chips + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * + * Paul Walmsley + * Benoit Cousson + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/io.h> +#include <linux/platform_data/gpio-omap.h> +#include <linux/power/smartreflex.h> +#include <linux/i2c-omap.h> + +#include <linux/omap-dma.h> +#include <linux/platform_data/spi-omap2-mcspi.h> +#include <linux/platform_data/asoc-ti-mcbsp.h> +#include <plat/dmtimer.h> + +#include "omap_hwmod.h" +#include "omap_hwmod_common_data.h" +#include "cm1_7xx.h" +#include "cm2_7xx.h" +#include "prm7xx.h" +#include "i2c.h" +#include "mmc.h" +#include "wd_timer.h" + +/* Base offset for all DRA7XX interrupts external to MPUSS */ +#define DRA7XX_IRQ_GIC_START 32 + +/* Base offset for all DRA7XX dma requests */ +#define DRA7XX_DMA_REQ_START 1 + + +/* + * IP blocks + */ + +/* + * 'l3' class + * instance(s): l3_instr, l3_main_1, l3_main_2 + */ +static struct omap_hwmod_class dra7xx_l3_hwmod_class = { + .name = "l3", +}; + +/* l3_instr */ +static struct omap_hwmod dra7xx_l3_instr_hwmod = { + .name = "l3_instr", + .class = &dra7xx_l3_hwmod_class, + .clkdm_name = "l3instr_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* l3_main_1 */ +static struct omap_hwmod dra7xx_l3_main_1_hwmod = { + .name = "l3_main_1", + .class = &dra7xx_l3_hwmod_class, + .clkdm_name = "l3main1_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3MAIN1_L3_MAIN_1_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3MAIN1_L3_MAIN_1_CONTEXT_OFFSET, + }, + }, +}; + +/* l3_main_2 */ +static struct omap_hwmod dra7xx_l3_main_2_hwmod = { + .name = "l3_main_2", + .class = &dra7xx_l3_hwmod_class, + .clkdm_name = "l3instr_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3INSTR_L3_MAIN_2_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3INSTR_L3_MAIN_2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'l4' class + * instance(s): l4_cfg, l4_per1, l4_per2, l4_per3, l4_wkup + */ +static struct omap_hwmod_class dra7xx_l4_hwmod_class = { + .name = "l4", +}; + +/* l4_cfg */ +static struct omap_hwmod dra7xx_l4_cfg_hwmod = { + .name = "l4_cfg", + .class = &dra7xx_l4_hwmod_class, + .clkdm_name = "l4cfg_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4CFG_L4_CFG_CONTEXT_OFFSET, + }, + }, +}; + +/* l4_per1 */ +static struct omap_hwmod dra7xx_l4_per1_hwmod = { + .name = "l4_per1", + .class = &dra7xx_l4_hwmod_class, + .clkdm_name = "l4per_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_L4_PER1_CLKCTRL_OFFSET, + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, +}; + +/* l4_per2 */ +static struct omap_hwmod dra7xx_l4_per2_hwmod = { + .name = "l4_per2", + .class = &dra7xx_l4_hwmod_class, + .clkdm_name = "l4per2_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER2_L4_PER2_CLKCTRL_OFFSET, + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, +}; + +/* l4_per3 */ +static struct omap_hwmod dra7xx_l4_per3_hwmod = { + .name = "l4_per3", + .class = &dra7xx_l4_hwmod_class, + .clkdm_name = "l4per3_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER3_L4_PER3_CLKCTRL_OFFSET, + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, +}; + +/* l4_wkup */ +static struct omap_hwmod dra7xx_l4_wkup_hwmod = { + .name = "l4_wkup", + .class = &dra7xx_l4_hwmod_class, + .clkdm_name = "wkupaon_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_WKUPAON_L4_WKUP_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_WKUPAON_L4_WKUP_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'atl' class + * + */ + +static struct omap_hwmod_class dra7xx_atl_hwmod_class = { + .name = "atl", +}; + +/* atl */ +static struct omap_hwmod dra7xx_atl_hwmod = { + .name = "atl", + .class = &dra7xx_atl_hwmod_class, + .clkdm_name = "atl_clkdm", + .main_clk = "atl_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_ATL_ATL_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_ATL_ATL_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'bb2d' class + * + */ + +static struct omap_hwmod_class dra7xx_bb2d_hwmod_class = { + .name = "bb2d", +}; + +/* bb2d */ +static struct omap_hwmod dra7xx_bb2d_hwmod = { + .name = "bb2d", + .class = &dra7xx_bb2d_hwmod_class, + .clkdm_name = "dss_clkdm", + .main_clk = "dpll_core_h24x2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_DSS_BB2D_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_DSS_BB2D_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'counter' class + * + */ + +static struct omap_hwmod_class_sysconfig dra7xx_counter_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class dra7xx_counter_hwmod_class = { + .name = "counter", + .sysc = &dra7xx_counter_sysc, +}; + +/* counter_32k */ +static struct omap_hwmod dra7xx_counter_32k_hwmod = { + .name = "counter_32k", + .class = &dra7xx_counter_hwmod_class, + .clkdm_name = "wkupaon_clkdm", + .flags = HWMOD_SWSUP_SIDLE, + .main_clk = "wkupaon_iclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_WKUPAON_COUNTER_32K_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_WKUPAON_COUNTER_32K_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'ctrl_module' class + * + */ + +static struct omap_hwmod_class dra7xx_ctrl_module_hwmod_class = { + .name = "ctrl_module", +}; + +/* ctrl_module_wkup */ +static struct omap_hwmod dra7xx_ctrl_module_wkup_hwmod = { + .name = "ctrl_module_wkup", + .class = &dra7xx_ctrl_module_hwmod_class, + .clkdm_name = "wkupaon_clkdm", + .prcm = { + .omap4 = { + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, +}; + +/* + * 'dcan' class + * + */ + +static struct omap_hwmod_class dra7xx_dcan_hwmod_class = { + .name = "dcan", +}; + +/* dcan1 */ +static struct omap_hwmod dra7xx_dcan1_hwmod = { + .name = "dcan1", + .class = &dra7xx_dcan_hwmod_class, + .clkdm_name = "wkupaon_clkdm", + .main_clk = "dcan1_sys_clk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_WKUPAON_DCAN1_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_WKUPAON_DCAN1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* dcan2 */ +static struct omap_hwmod dra7xx_dcan2_hwmod = { + .name = "dcan2", + .class = &dra7xx_dcan_hwmod_class, + .clkdm_name = "l4per2_clkdm", + .main_clk = "sys_clkin1", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER2_DCAN2_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER2_DCAN2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'dma' class + * + */ + +static struct omap_hwmod_class_sysconfig dra7xx_dma_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x002c, + .syss_offs = 0x0028, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_EMUFREE | SYSC_HAS_MIDLEMODE | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class dra7xx_dma_hwmod_class = { + .name = "dma", + .sysc = &dra7xx_dma_sysc, +}; + +/* dma dev_attr */ +static struct omap_dma_dev_attr dma_dev_attr = { + .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY | + IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY, + .lch_count = 32, +}; + +/* dma_system */ +static struct omap_hwmod_irq_info dra7xx_dma_system_irqs[] = { + { .name = "0", .irq = 12 + DRA7XX_IRQ_GIC_START }, + { .name = "1", .irq = 13 + DRA7XX_IRQ_GIC_START }, + { .name = "2", .irq = 14 + DRA7XX_IRQ_GIC_START }, + { .name = "3", .irq = 15 + DRA7XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod dra7xx_dma_system_hwmod = { + .name = "dma_system", + .class = &dra7xx_dma_hwmod_class, + .clkdm_name = "dma_clkdm", + .mpu_irqs = dra7xx_dma_system_irqs, + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_DMA_DMA_SYSTEM_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_DMA_DMA_SYSTEM_CONTEXT_OFFSET, + }, + }, + .dev_attr = &dma_dev_attr, +}; + +/* + * 'dss' class + * + */ + +static struct omap_hwmod_class_sysconfig dra7xx_dss_sysc = { + .rev_offs = 0x0000, + .syss_offs = 0x0014, + .sysc_flags = SYSS_HAS_RESET_STATUS, +}; + +static struct omap_hwmod_class dra7xx_dss_hwmod_class = { + .name = "dss", + .sysc = &dra7xx_dss_sysc, + .reset = omap_dss_reset, +}; + +/* dss */ +static struct omap_hwmod_dma_info dra7xx_dss_sdma_reqs[] = { + { .dma_req = 75 + DRA7XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +static struct omap_hwmod_opt_clk dss_opt_clks[] = { + { .role = "dss_clk", .clk = "dss_dss_clk" }, + { .role = "hdmi_phy_clk", .clk = "dss_48mhz_clk" }, + { .role = "32khz_clk", .clk = "dss_32khz_clk" }, + { .role = "video2_clk", .clk = "dss_video2_clk" }, + { .role = "video1_clk", .clk = "dss_video1_clk" }, + { .role = "hdmi_clk", .clk = "dss_hdmi_clk" }, +}; + +static struct omap_hwmod dra7xx_dss_hwmod = { + .name = "dss_core", + .class = &dra7xx_dss_hwmod_class, + .clkdm_name = "dss_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .sdma_reqs = dra7xx_dss_sdma_reqs, + .main_clk = "dss_dss_clk", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_DSS_DSS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = dss_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), +}; + +/* + * 'dispc' class + * display controller + */ + +static struct omap_hwmod_class_sysconfig dra7xx_dispc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_MIDLEMODE | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class dra7xx_dispc_hwmod_class = { + .name = "dispc", + .sysc = &dra7xx_dispc_sysc, +}; + +/* dss_dispc */ +/* dss_dispc dev_attr */ +static struct omap_dss_dispc_dev_attr dss_dispc_dev_attr = { + .has_framedonetv_irq = 1, + .manager_count = 4, +}; + +static struct omap_hwmod dra7xx_dss_dispc_hwmod = { + .name = "dss_dispc", + .class = &dra7xx_dispc_hwmod_class, + .clkdm_name = "dss_clkdm", + .main_clk = "dss_dss_clk", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, + .dev_attr = &dss_dispc_dev_attr, +}; + +/* + * 'hdmi' class + * hdmi controller + */ + +static struct omap_hwmod_class_sysconfig dra7xx_hdmi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class dra7xx_hdmi_hwmod_class = { + .name = "hdmi", + .sysc = &dra7xx_hdmi_sysc, +}; + +/* dss_hdmi */ + +static struct omap_hwmod_opt_clk dss_hdmi_opt_clks[] = { + { .role = "sys_clk", .clk = "dss_hdmi_clk" }, +}; + +static struct omap_hwmod dra7xx_dss_hdmi_hwmod = { + .name = "dss_hdmi", + .class = &dra7xx_hdmi_hwmod_class, + .clkdm_name = "dss_clkdm", + .main_clk = "dss_48mhz_clk", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_DSS_DSS_CLKCTRL_OFFSET, + .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, + }, + }, + .opt_clks = dss_hdmi_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks), +}; + +/* + * 'elm' class + * + */ + +static struct omap_hwmod_class_sysconfig dra7xx_elm_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class dra7xx_elm_hwmod_class = { + .name = "elm", + .sysc = &dra7xx_elm_sysc, +}; + +/* elm */ + +static struct omap_hwmod dra7xx_elm_hwmod = { + .name = "elm", + .class = &dra7xx_elm_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_ELM_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_ELM_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'gpio' class + * + */ + +static struct omap_hwmod_class_sysconfig dra7xx_gpio_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0114, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class dra7xx_gpio_hwmod_class = { + .name = "gpio", + .sysc = &dra7xx_gpio_sysc, + .rev = 2, +}; + +/* gpio dev_attr */ +static struct omap_gpio_dev_attr gpio_dev_attr = { + .bank_width = 32, + .dbck_flag = true, +}; + +/* gpio1 */ +static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { + { .role = "dbclk", .clk = "gpio1_dbclk" }, +}; + +static struct omap_hwmod dra7xx_gpio1_hwmod = { + .name = "gpio1", + .class = &dra7xx_gpio_hwmod_class, + .clkdm_name = "wkupaon_clkdm", + .main_clk = "wkupaon_iclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_WKUPAON_GPIO1_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_WKUPAON_GPIO1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio2 */ +static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { + { .role = "dbclk", .clk = "gpio2_dbclk" }, +}; + +static struct omap_hwmod dra7xx_gpio2_hwmod = { + .name = "gpio2", + .class = &dra7xx_gpio_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_GPIO2_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_GPIO2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio2_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio3 */ +static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { + { .role = "dbclk", .clk = "gpio3_dbclk" }, +}; + +static struct omap_hwmod dra7xx_gpio3_hwmod = { + .name = "gpio3", + .class = &dra7xx_gpio_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_GPIO3_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_GPIO3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio3_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio4 */ +static struct omap_hwmod_opt_clk gpio4_opt_clks[] = { + { .role = "dbclk", .clk = "gpio4_dbclk" }, +}; + +static struct omap_hwmod dra7xx_gpio4_hwmod = { + .name = "gpio4", + .class = &dra7xx_gpio_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_GPIO4_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_GPIO4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio4_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio5 */ +static struct omap_hwmod_opt_clk gpio5_opt_clks[] = { + { .role = "dbclk", .clk = "gpio5_dbclk" }, +}; + +static struct omap_hwmod dra7xx_gpio5_hwmod = { + .name = "gpio5", + .class = &dra7xx_gpio_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_GPIO5_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_GPIO5_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio5_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio6 */ +static struct omap_hwmod_opt_clk gpio6_opt_clks[] = { + { .role = "dbclk", .clk = "gpio6_dbclk" }, +}; + +static struct omap_hwmod dra7xx_gpio6_hwmod = { + .name = "gpio6", + .class = &dra7xx_gpio_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_GPIO6_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_GPIO6_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio6_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio7 */ +static struct omap_hwmod_opt_clk gpio7_opt_clks[] = { + { .role = "dbclk", .clk = "gpio7_dbclk" }, +}; + +static struct omap_hwmod dra7xx_gpio7_hwmod = { + .name = "gpio7", + .class = &dra7xx_gpio_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_GPIO7_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_GPIO7_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio7_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio7_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* gpio8 */ +static struct omap_hwmod_opt_clk gpio8_opt_clks[] = { + { .role = "dbclk", .clk = "gpio8_dbclk" }, +}; + +static struct omap_hwmod dra7xx_gpio8_hwmod = { + .name = "gpio8", + .class = &dra7xx_gpio_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_GPIO8_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_GPIO8_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = gpio8_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(gpio8_opt_clks), + .dev_attr = &gpio_dev_attr, +}; + +/* + * 'gpmc' class + * + */ + +static struct omap_hwmod_class_sysconfig dra7xx_gpmc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class dra7xx_gpmc_hwmod_class = { + .name = "gpmc", + .sysc = &dra7xx_gpmc_sysc, +}; + +/* gpmc */ + +static struct omap_hwmod dra7xx_gpmc_hwmod = { + .name = "gpmc", + .class = &dra7xx_gpmc_hwmod_class, + .clkdm_name = "l3main1_clkdm", + .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3MAIN1_GPMC_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3MAIN1_GPMC_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'hdq1w' class + * + */ + +static struct omap_hwmod_class_sysconfig dra7xx_hdq1w_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0014, + .syss_offs = 0x0018, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class dra7xx_hdq1w_hwmod_class = { + .name = "hdq1w", + .sysc = &dra7xx_hdq1w_sysc, +}; + +/* hdq1w */ + +static struct omap_hwmod dra7xx_hdq1w_hwmod = { + .name = "hdq1w", + .class = &dra7xx_hdq1w_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_INIT_NO_RESET, + .main_clk = "func_12m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_HDQ1W_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_HDQ1W_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'i2c' class + * + */ + +static struct omap_hwmod_class_sysconfig dra7xx_i2c_sysc = { + .sysc_offs = 0x0010, + .syss_offs = 0x0090, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .clockact = CLOCKACT_TEST_ICLK, + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class dra7xx_i2c_hwmod_class = { + .name = "i2c", + .sysc = &dra7xx_i2c_sysc, + .reset = &omap_i2c_reset, + .rev = OMAP_I2C_IP_VERSION_2, +}; + +/* i2c dev_attr */ +static struct omap_i2c_dev_attr i2c_dev_attr = { + .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE, +}; + +/* i2c1 */ +static struct omap_hwmod dra7xx_i2c1_hwmod = { + .name = "i2c1", + .class = &dra7xx_i2c_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "func_96m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_I2C1_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_I2C1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* i2c2 */ +static struct omap_hwmod dra7xx_i2c2_hwmod = { + .name = "i2c2", + .class = &dra7xx_i2c_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "func_96m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_I2C2_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_I2C2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* i2c3 */ +static struct omap_hwmod dra7xx_i2c3_hwmod = { + .name = "i2c3", + .class = &dra7xx_i2c_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "func_96m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_I2C3_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_I2C3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* i2c4 */ +static struct omap_hwmod dra7xx_i2c4_hwmod = { + .name = "i2c4", + .class = &dra7xx_i2c_hwmod_class, + .clkdm_name = "l4per_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "func_96m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_I2C4_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_I2C4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* i2c5 */ +static struct omap_hwmod dra7xx_i2c5_hwmod = { + .name = "i2c5", + .class = &dra7xx_i2c_hwmod_class, + .clkdm_name = "ipu_clkdm", + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, + .main_clk = "func_96m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_IPU_I2C5_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_IPU_I2C5_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &i2c_dev_attr, +}; + +/* + * 'mcspi' class + * + */ + +static struct omap_hwmod_class_sysconfig dra7xx_mcspi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class dra7xx_mcspi_hwmod_class = { + .name = "mcspi", + .sysc = &dra7xx_mcspi_sysc, + .rev = OMAP4_MCSPI_REV, +}; + +/* mcspi1 */ +/* mcspi1 dev_attr */ +static struct omap2_mcspi_dev_attr mcspi1_dev_attr = { + .num_chipselect = 4, +}; + +static struct omap_hwmod dra7xx_mcspi1_hwmod = { + .name = "mcspi1", + .class = &dra7xx_mcspi_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_MCSPI1_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_MCSPI1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi1_dev_attr, +}; + +/* mcspi2 */ +/* mcspi2 dev_attr */ +static struct omap2_mcspi_dev_attr mcspi2_dev_attr = { + .num_chipselect = 2, +}; + +static struct omap_hwmod dra7xx_mcspi2_hwmod = { + .name = "mcspi2", + .class = &dra7xx_mcspi_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_MCSPI2_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_MCSPI2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi2_dev_attr, +}; + +/* mcspi3 */ +/* mcspi3 dev_attr */ +static struct omap2_mcspi_dev_attr mcspi3_dev_attr = { + .num_chipselect = 2, +}; + +static struct omap_hwmod dra7xx_mcspi3_hwmod = { + .name = "mcspi3", + .class = &dra7xx_mcspi_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_MCSPI3_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_MCSPI3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi3_dev_attr, +}; + +/* mcspi4 */ +/* mcspi4 dev_attr */ +static struct omap2_mcspi_dev_attr mcspi4_dev_attr = { + .num_chipselect = 1, +}; + +static struct omap_hwmod dra7xx_mcspi4_hwmod = { + .name = "mcspi4", + .class = &dra7xx_mcspi_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "func_48m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_MCSPI4_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_MCSPI4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &mcspi4_dev_attr, +}; + +/* + * 'mmc' class + * + */ + +static struct omap_hwmod_class_sysconfig dra7xx_mmc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_MIDLEMODE | + SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class dra7xx_mmc_hwmod_class = { + .name = "mmc", + .sysc = &dra7xx_mmc_sysc, +}; + +/* mmc1 */ +static struct omap_hwmod_opt_clk mmc1_opt_clks[] = { + { .role = "clk32k", .clk = "mmc1_clk32k" }, +}; + +/* mmc1 dev_attr */ +static struct omap_mmc_dev_attr mmc1_dev_attr = { + .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, +}; + +static struct omap_hwmod dra7xx_mmc1_hwmod = { + .name = "mmc1", + .class = &dra7xx_mmc_hwmod_class, + .clkdm_name = "l3init_clkdm", + .main_clk = "mmc1_fclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3INIT_MMC1_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3INIT_MMC1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = mmc1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mmc1_opt_clks), + .dev_attr = &mmc1_dev_attr, +}; + +/* mmc2 */ +static struct omap_hwmod_opt_clk mmc2_opt_clks[] = { + { .role = "clk32k", .clk = "mmc2_clk32k" }, +}; + +static struct omap_hwmod dra7xx_mmc2_hwmod = { + .name = "mmc2", + .class = &dra7xx_mmc_hwmod_class, + .clkdm_name = "l3init_clkdm", + .main_clk = "mmc2_fclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3INIT_MMC2_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3INIT_MMC2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = mmc2_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mmc2_opt_clks), +}; + +/* mmc3 */ +static struct omap_hwmod_opt_clk mmc3_opt_clks[] = { + { .role = "clk32k", .clk = "mmc3_clk32k" }, +}; + +static struct omap_hwmod dra7xx_mmc3_hwmod = { + .name = "mmc3", + .class = &dra7xx_mmc_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "mmc3_gfclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_MMC3_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_MMC3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = mmc3_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mmc3_opt_clks), +}; + +/* mmc4 */ +static struct omap_hwmod_opt_clk mmc4_opt_clks[] = { + { .role = "clk32k", .clk = "mmc4_clk32k" }, +}; + +static struct omap_hwmod dra7xx_mmc4_hwmod = { + .name = "mmc4", + .class = &dra7xx_mmc_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "mmc4_gfclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_MMC4_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_MMC4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = mmc4_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mmc4_opt_clks), +}; + +/* + * 'mpu' class + * + */ + +static struct omap_hwmod_class dra7xx_mpu_hwmod_class = { + .name = "mpu", +}; + +/* mpu */ +static struct omap_hwmod dra7xx_mpu_hwmod = { + .name = "mpu", + .class = &dra7xx_mpu_hwmod_class, + .clkdm_name = "mpu_clkdm", + .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .main_clk = "dpll_mpu_m2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_MPU_MPU_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_MPU_MPU_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'ocp2scp' class + * + */ + +static struct omap_hwmod_class_sysconfig dra7xx_ocp2scp_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class dra7xx_ocp2scp_hwmod_class = { + .name = "ocp2scp", + .sysc = &dra7xx_ocp2scp_sysc, +}; + +/* ocp2scp1 */ +static struct omap_hwmod dra7xx_ocp2scp1_hwmod = { + .name = "ocp2scp1", + .class = &dra7xx_ocp2scp_hwmod_class, + .clkdm_name = "l3init_clkdm", + .main_clk = "l4_root_clk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3INIT_OCP2SCP1_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3INIT_OCP2SCP1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'qspi' class + * + */ + +static struct omap_hwmod_class_sysconfig dra7xx_qspi_sysc = { + .sysc_offs = 0x0010, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class dra7xx_qspi_hwmod_class = { + .name = "qspi", + .sysc = &dra7xx_qspi_sysc, +}; + +/* qspi */ +static struct omap_hwmod dra7xx_qspi_hwmod = { + .name = "qspi", + .class = &dra7xx_qspi_hwmod_class, + .clkdm_name = "l4per2_clkdm", + .main_clk = "qspi_gfclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER2_QSPI_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER2_QSPI_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'sata' class + * + */ + +static struct omap_hwmod_class_sysconfig dra7xx_sata_sysc = { + .sysc_offs = 0x0000, + .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class dra7xx_sata_hwmod_class = { + .name = "sata", + .sysc = &dra7xx_sata_sysc, +}; + +/* sata */ + +static struct omap_hwmod dra7xx_sata_hwmod = { + .name = "sata", + .class = &dra7xx_sata_hwmod_class, + .clkdm_name = "l3init_clkdm", + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, + .main_clk = "func_48m_fclk", + .mpu_rt_idx = 1, + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3INIT_SATA_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3INIT_SATA_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'smartreflex' class + * + */ + +/* The IP is not compliant to type1 / type2 scheme */ +static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_smartreflex = { + .sidle_shift = 24, + .enwkup_shift = 26, +}; + +static struct omap_hwmod_class_sysconfig dra7xx_smartreflex_sysc = { + .sysc_offs = 0x0038, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type_smartreflex, +}; + +static struct omap_hwmod_class dra7xx_smartreflex_hwmod_class = { + .name = "smartreflex", + .sysc = &dra7xx_smartreflex_sysc, + .rev = 2, +}; + +/* smartreflex_core */ +/* smartreflex_core dev_attr */ +static struct omap_smartreflex_dev_attr smartreflex_core_dev_attr = { + .sensor_voltdm_name = "core", +}; + +static struct omap_hwmod dra7xx_smartreflex_core_hwmod = { + .name = "smartreflex_core", + .class = &dra7xx_smartreflex_hwmod_class, + .clkdm_name = "coreaon_clkdm", + .main_clk = "wkupaon_iclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_COREAON_SMARTREFLEX_CORE_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_COREAON_SMARTREFLEX_CORE_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &smartreflex_core_dev_attr, +}; + +/* smartreflex_mpu */ +/* smartreflex_mpu dev_attr */ +static struct omap_smartreflex_dev_attr smartreflex_mpu_dev_attr = { + .sensor_voltdm_name = "mpu", +}; + +static struct omap_hwmod dra7xx_smartreflex_mpu_hwmod = { + .name = "smartreflex_mpu", + .class = &dra7xx_smartreflex_hwmod_class, + .clkdm_name = "coreaon_clkdm", + .main_clk = "wkupaon_iclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_COREAON_SMARTREFLEX_MPU_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_COREAON_SMARTREFLEX_MPU_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .dev_attr = &smartreflex_mpu_dev_attr, +}; + +/* + * 'spinlock' class + * + */ + +static struct omap_hwmod_class_sysconfig dra7xx_spinlock_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class dra7xx_spinlock_hwmod_class = { + .name = "spinlock", + .sysc = &dra7xx_spinlock_sysc, +}; + +/* spinlock */ +static struct omap_hwmod dra7xx_spinlock_hwmod = { + .name = "spinlock", + .class = &dra7xx_spinlock_hwmod_class, + .clkdm_name = "l4cfg_clkdm", + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4CFG_SPINLOCK_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4CFG_SPINLOCK_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'timer' class + * + * This class contains several variants: ['timer_1ms', 'timer_secure', + * 'timer'] + */ + +static struct omap_hwmod_class_sysconfig dra7xx_timer_1ms_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class dra7xx_timer_1ms_hwmod_class = { + .name = "timer", + .sysc = &dra7xx_timer_1ms_sysc, +}; + +static struct omap_hwmod_class_sysconfig dra7xx_timer_secure_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class dra7xx_timer_secure_hwmod_class = { + .name = "timer", + .sysc = &dra7xx_timer_secure_sysc, +}; + +static struct omap_hwmod_class_sysconfig dra7xx_timer_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class dra7xx_timer_hwmod_class = { + .name = "timer", + .sysc = &dra7xx_timer_sysc, +}; + +/* timer1 */ +static struct omap_hwmod dra7xx_timer1_hwmod = { + .name = "timer1", + .class = &dra7xx_timer_1ms_hwmod_class, + .clkdm_name = "wkupaon_clkdm", + .main_clk = "timer1_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_WKUPAON_TIMER1_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_WKUPAON_TIMER1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer2 */ +static struct omap_hwmod dra7xx_timer2_hwmod = { + .name = "timer2", + .class = &dra7xx_timer_1ms_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "timer2_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_TIMER2_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_TIMER2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer3 */ +static struct omap_hwmod dra7xx_timer3_hwmod = { + .name = "timer3", + .class = &dra7xx_timer_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "timer3_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_TIMER3_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_TIMER3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer4 */ +static struct omap_hwmod dra7xx_timer4_hwmod = { + .name = "timer4", + .class = &dra7xx_timer_secure_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "timer4_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_TIMER4_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_TIMER4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer5 */ +static struct omap_hwmod dra7xx_timer5_hwmod = { + .name = "timer5", + .class = &dra7xx_timer_hwmod_class, + .clkdm_name = "ipu_clkdm", + .main_clk = "timer5_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_IPU_TIMER5_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_IPU_TIMER5_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer6 */ +static struct omap_hwmod dra7xx_timer6_hwmod = { + .name = "timer6", + .class = &dra7xx_timer_hwmod_class, + .clkdm_name = "ipu_clkdm", + .main_clk = "timer6_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_IPU_TIMER6_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_IPU_TIMER6_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer7 */ +static struct omap_hwmod dra7xx_timer7_hwmod = { + .name = "timer7", + .class = &dra7xx_timer_hwmod_class, + .clkdm_name = "ipu_clkdm", + .main_clk = "timer7_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_IPU_TIMER7_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_IPU_TIMER7_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer8 */ +static struct omap_hwmod dra7xx_timer8_hwmod = { + .name = "timer8", + .class = &dra7xx_timer_hwmod_class, + .clkdm_name = "ipu_clkdm", + .main_clk = "timer8_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_IPU_TIMER8_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_IPU_TIMER8_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer9 */ +static struct omap_hwmod dra7xx_timer9_hwmod = { + .name = "timer9", + .class = &dra7xx_timer_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "timer9_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_TIMER9_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_TIMER9_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer10 */ +static struct omap_hwmod dra7xx_timer10_hwmod = { + .name = "timer10", + .class = &dra7xx_timer_1ms_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "timer10_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_TIMER10_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_TIMER10_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* timer11 */ +static struct omap_hwmod dra7xx_timer11_hwmod = { + .name = "timer11", + .class = &dra7xx_timer_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "timer11_gfclk_mux", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_TIMER11_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_TIMER11_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'uart' class + * + */ + +static struct omap_hwmod_class_sysconfig dra7xx_uart_sysc = { + .rev_offs = 0x0050, + .sysc_offs = 0x0054, + .syss_offs = 0x0058, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class dra7xx_uart_hwmod_class = { + .name = "uart", + .sysc = &dra7xx_uart_sysc, +}; + +/* uart1 */ +static struct omap_hwmod dra7xx_uart1_hwmod = { + .name = "uart1", + .class = &dra7xx_uart_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "uart1_gfclk_mux", + .flags = HWMOD_SWSUP_SIDLE_ACT | DEBUG_OMAP2UART1_FLAGS, + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_UART1_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_UART1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* uart2 */ +static struct omap_hwmod dra7xx_uart2_hwmod = { + .name = "uart2", + .class = &dra7xx_uart_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "uart2_gfclk_mux", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_UART2_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_UART2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* uart3 */ +static struct omap_hwmod dra7xx_uart3_hwmod = { + .name = "uart3", + .class = &dra7xx_uart_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "uart3_gfclk_mux", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_UART3_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_UART3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* uart4 */ +static struct omap_hwmod dra7xx_uart4_hwmod = { + .name = "uart4", + .class = &dra7xx_uart_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "uart4_gfclk_mux", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_UART4_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_UART4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* uart5 */ +static struct omap_hwmod dra7xx_uart5_hwmod = { + .name = "uart5", + .class = &dra7xx_uart_hwmod_class, + .clkdm_name = "l4per_clkdm", + .main_clk = "uart5_gfclk_mux", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L4PER_UART5_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L4PER_UART5_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* uart6 */ +static struct omap_hwmod dra7xx_uart6_hwmod = { + .name = "uart6", + .class = &dra7xx_uart_hwmod_class, + .clkdm_name = "ipu_clkdm", + .main_clk = "uart6_gfclk_mux", + .flags = HWMOD_SWSUP_SIDLE_ACT, + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_IPU_UART6_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_IPU_UART6_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'usb_otg_ss' class + * + */ + +static struct omap_hwmod_class_sysconfig dra7xx_usb_otg_ss_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_DMADISABLE | SYSC_HAS_MIDLEMODE | + SYSC_HAS_SIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class dra7xx_usb_otg_ss_hwmod_class = { + .name = "usb_otg_ss", + .sysc = &dra7xx_usb_otg_ss_sysc, +}; + +/* usb_otg_ss1 */ +static struct omap_hwmod_opt_clk usb_otg_ss1_opt_clks[] = { + { .role = "refclk960m", .clk = "usb_otg_ss1_refclk960m" }, +}; + +static struct omap_hwmod dra7xx_usb_otg_ss1_hwmod = { + .name = "usb_otg_ss1", + .class = &dra7xx_usb_otg_ss_hwmod_class, + .clkdm_name = "l3init_clkdm", + .main_clk = "dpll_core_h13x2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3INIT_USB_OTG_SS1_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3INIT_USB_OTG_SS1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = usb_otg_ss1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(usb_otg_ss1_opt_clks), +}; + +/* usb_otg_ss2 */ +static struct omap_hwmod_opt_clk usb_otg_ss2_opt_clks[] = { + { .role = "refclk960m", .clk = "usb_otg_ss2_refclk960m" }, +}; + +static struct omap_hwmod dra7xx_usb_otg_ss2_hwmod = { + .name = "usb_otg_ss2", + .class = &dra7xx_usb_otg_ss_hwmod_class, + .clkdm_name = "l3init_clkdm", + .main_clk = "dpll_core_h13x2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3INIT_USB_OTG_SS2_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3INIT_USB_OTG_SS2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = usb_otg_ss2_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(usb_otg_ss2_opt_clks), +}; + +/* usb_otg_ss3 */ +static struct omap_hwmod dra7xx_usb_otg_ss3_hwmod = { + .name = "usb_otg_ss3", + .class = &dra7xx_usb_otg_ss_hwmod_class, + .clkdm_name = "l3init_clkdm", + .main_clk = "dpll_core_h13x2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3INIT_USB_OTG_SS3_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3INIT_USB_OTG_SS3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* usb_otg_ss4 */ +static struct omap_hwmod dra7xx_usb_otg_ss4_hwmod = { + .name = "usb_otg_ss4", + .class = &dra7xx_usb_otg_ss_hwmod_class, + .clkdm_name = "l3init_clkdm", + .main_clk = "dpll_core_h13x2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3INIT_USB_OTG_SS4_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3INIT_USB_OTG_SS4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'vcp' class + * + */ + +static struct omap_hwmod_class dra7xx_vcp_hwmod_class = { + .name = "vcp", +}; + +/* vcp1 */ +static struct omap_hwmod dra7xx_vcp1_hwmod = { + .name = "vcp1", + .class = &dra7xx_vcp_hwmod_class, + .clkdm_name = "l3main1_clkdm", + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3MAIN1_VCP1_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3MAIN1_VCP1_CONTEXT_OFFSET, + }, + }, +}; + +/* vcp2 */ +static struct omap_hwmod dra7xx_vcp2_hwmod = { + .name = "vcp2", + .class = &dra7xx_vcp_hwmod_class, + .clkdm_name = "l3main1_clkdm", + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3MAIN1_VCP2_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3MAIN1_VCP2_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'wd_timer' class + * + */ + +static struct omap_hwmod_class_sysconfig dra7xx_wd_timer_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class dra7xx_wd_timer_hwmod_class = { + .name = "wd_timer", + .sysc = &dra7xx_wd_timer_sysc, + .pre_shutdown = &omap2_wd_timer_disable, + .reset = &omap2_wd_timer_reset, +}; + +/* wd_timer2 */ +static struct omap_hwmod dra7xx_wd_timer2_hwmod = { + .name = "wd_timer2", + .class = &dra7xx_wd_timer_hwmod_class, + .clkdm_name = "wkupaon_clkdm", + .main_clk = "sys_32k_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_WKUPAON_WD_TIMER2_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_WKUPAON_WD_TIMER2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + + +/* + * Interfaces + */ + +/* l3_main_2 -> l3_instr */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_2__l3_instr = { + .master = &dra7xx_l3_main_2_hwmod, + .slave = &dra7xx_l3_instr_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> l3_main_1 */ +static struct omap_hwmod_ocp_if dra7xx_l4_cfg__l3_main_1 = { + .master = &dra7xx_l4_cfg_hwmod, + .slave = &dra7xx_l3_main_1_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* mpu -> l3_main_1 */ +static struct omap_hwmod_ocp_if dra7xx_mpu__l3_main_1 = { + .master = &dra7xx_mpu_hwmod, + .slave = &dra7xx_l3_main_1_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU, +}; + +/* l3_main_1 -> l3_main_2 */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__l3_main_2 = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_l3_main_2_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU, +}; + +/* l4_cfg -> l3_main_2 */ +static struct omap_hwmod_ocp_if dra7xx_l4_cfg__l3_main_2 = { + .master = &dra7xx_l4_cfg_hwmod, + .slave = &dra7xx_l3_main_2_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_1 -> l4_cfg */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__l4_cfg = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_l4_cfg_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_1 -> l4_per1 */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__l4_per1 = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_l4_per1_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_1 -> l4_per2 */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__l4_per2 = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_l4_per2_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_1 -> l4_per3 */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__l4_per3 = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_l4_per3_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_1 -> l4_wkup */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__l4_wkup = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_l4_wkup_hwmod, + .clk = "wkupaon_iclk_mux", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per2 -> atl */ +static struct omap_hwmod_ocp_if dra7xx_l4_per2__atl = { + .master = &dra7xx_l4_per2_hwmod, + .slave = &dra7xx_atl_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_1 -> bb2d */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__bb2d = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_bb2d_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> counter_32k */ +static struct omap_hwmod_ocp_if dra7xx_l4_wkup__counter_32k = { + .master = &dra7xx_l4_wkup_hwmod, + .slave = &dra7xx_counter_32k_hwmod, + .clk = "wkupaon_iclk_mux", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> ctrl_module_wkup */ +static struct omap_hwmod_ocp_if dra7xx_l4_wkup__ctrl_module_wkup = { + .master = &dra7xx_l4_wkup_hwmod, + .slave = &dra7xx_ctrl_module_wkup_hwmod, + .clk = "wkupaon_iclk_mux", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> dcan1 */ +static struct omap_hwmod_ocp_if dra7xx_l4_wkup__dcan1 = { + .master = &dra7xx_l4_wkup_hwmod, + .slave = &dra7xx_dcan1_hwmod, + .clk = "wkupaon_iclk_mux", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per2 -> dcan2 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per2__dcan2 = { + .master = &dra7xx_l4_per2_hwmod, + .slave = &dra7xx_dcan2_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space dra7xx_dma_system_addrs[] = { + { + .pa_start = 0x4a056000, + .pa_end = 0x4a056fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> dma_system */ +static struct omap_hwmod_ocp_if dra7xx_l4_cfg__dma_system = { + .master = &dra7xx_l4_cfg_hwmod, + .slave = &dra7xx_dma_system_hwmod, + .clk = "l3_iclk_div", + .addr = dra7xx_dma_system_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space dra7xx_dss_addrs[] = { + { + .name = "family", + .pa_start = 0x58000000, + .pa_end = 0x5800007f, + .flags = ADDR_TYPE_RT + }, +}; + +/* l3_main_1 -> dss */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__dss = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_dss_hwmod, + .clk = "l3_iclk_div", + .addr = dra7xx_dss_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space dra7xx_dss_dispc_addrs[] = { + { + .name = "dispc", + .pa_start = 0x58001000, + .pa_end = 0x58001fff, + .flags = ADDR_TYPE_RT + }, +}; + +/* l3_main_1 -> dispc */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__dispc = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_dss_dispc_hwmod, + .clk = "l3_iclk_div", + .addr = dra7xx_dss_dispc_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space dra7xx_dss_hdmi_addrs[] = { + { + .name = "hdmi_wp", + .pa_start = 0x58040000, + .pa_end = 0x580400ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l3_main_1 -> dispc */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__hdmi = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_dss_hdmi_hwmod, + .clk = "l3_iclk_div", + .addr = dra7xx_dss_hdmi_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space dra7xx_elm_addrs[] = { + { + .pa_start = 0x48078000, + .pa_end = 0x48078fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per1 -> elm */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__elm = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_elm_hwmod, + .clk = "l3_iclk_div", + .addr = dra7xx_elm_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> gpio1 */ +static struct omap_hwmod_ocp_if dra7xx_l4_wkup__gpio1 = { + .master = &dra7xx_l4_wkup_hwmod, + .slave = &dra7xx_gpio1_hwmod, + .clk = "wkupaon_iclk_mux", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> gpio2 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__gpio2 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_gpio2_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> gpio3 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__gpio3 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_gpio3_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> gpio4 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__gpio4 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_gpio4_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> gpio5 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__gpio5 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_gpio5_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> gpio6 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__gpio6 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_gpio6_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> gpio7 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__gpio7 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_gpio7_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> gpio8 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__gpio8 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_gpio8_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space dra7xx_gpmc_addrs[] = { + { + .pa_start = 0x50000000, + .pa_end = 0x500003ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l3_main_1 -> gpmc */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__gpmc = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_gpmc_hwmod, + .clk = "l3_iclk_div", + .addr = dra7xx_gpmc_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space dra7xx_hdq1w_addrs[] = { + { + .pa_start = 0x480b2000, + .pa_end = 0x480b201f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per1 -> hdq1w */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__hdq1w = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_hdq1w_hwmod, + .clk = "l3_iclk_div", + .addr = dra7xx_hdq1w_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> i2c1 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__i2c1 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_i2c1_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> i2c2 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__i2c2 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_i2c2_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> i2c3 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__i2c3 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_i2c3_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> i2c4 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__i2c4 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_i2c4_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> i2c5 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__i2c5 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_i2c5_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> mcspi1 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__mcspi1 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_mcspi1_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> mcspi2 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__mcspi2 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_mcspi2_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> mcspi3 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__mcspi3 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_mcspi3_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> mcspi4 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__mcspi4 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_mcspi4_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> mmc1 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__mmc1 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_mmc1_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> mmc2 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__mmc2 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_mmc2_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> mmc3 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__mmc3 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_mmc3_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> mmc4 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__mmc4 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_mmc4_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> mpu */ +static struct omap_hwmod_ocp_if dra7xx_l4_cfg__mpu = { + .master = &dra7xx_l4_cfg_hwmod, + .slave = &dra7xx_mpu_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> ocp2scp1 */ +static struct omap_hwmod_ocp_if dra7xx_l4_cfg__ocp2scp1 = { + .master = &dra7xx_l4_cfg_hwmod, + .slave = &dra7xx_ocp2scp1_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space dra7xx_qspi_addrs[] = { + { + .pa_start = 0x4b300000, + .pa_end = 0x4b30007f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l3_main_1 -> qspi */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__qspi = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_qspi_hwmod, + .clk = "l3_iclk_div", + .addr = dra7xx_qspi_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space dra7xx_sata_addrs[] = { + { + .name = "sysc", + .pa_start = 0x4a141100, + .pa_end = 0x4a141107, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> sata */ +static struct omap_hwmod_ocp_if dra7xx_l4_cfg__sata = { + .master = &dra7xx_l4_cfg_hwmod, + .slave = &dra7xx_sata_hwmod, + .clk = "l3_iclk_div", + .addr = dra7xx_sata_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space dra7xx_smartreflex_core_addrs[] = { + { + .pa_start = 0x4a0dd000, + .pa_end = 0x4a0dd07f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> smartreflex_core */ +static struct omap_hwmod_ocp_if dra7xx_l4_cfg__smartreflex_core = { + .master = &dra7xx_l4_cfg_hwmod, + .slave = &dra7xx_smartreflex_core_hwmod, + .clk = "l4_root_clk_div", + .addr = dra7xx_smartreflex_core_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space dra7xx_smartreflex_mpu_addrs[] = { + { + .pa_start = 0x4a0d9000, + .pa_end = 0x4a0d907f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> smartreflex_mpu */ +static struct omap_hwmod_ocp_if dra7xx_l4_cfg__smartreflex_mpu = { + .master = &dra7xx_l4_cfg_hwmod, + .slave = &dra7xx_smartreflex_mpu_hwmod, + .clk = "l4_root_clk_div", + .addr = dra7xx_smartreflex_mpu_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space dra7xx_spinlock_addrs[] = { + { + .pa_start = 0x4a0f6000, + .pa_end = 0x4a0f6fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> spinlock */ +static struct omap_hwmod_ocp_if dra7xx_l4_cfg__spinlock = { + .master = &dra7xx_l4_cfg_hwmod, + .slave = &dra7xx_spinlock_hwmod, + .clk = "l3_iclk_div", + .addr = dra7xx_spinlock_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> timer1 */ +static struct omap_hwmod_ocp_if dra7xx_l4_wkup__timer1 = { + .master = &dra7xx_l4_wkup_hwmod, + .slave = &dra7xx_timer1_hwmod, + .clk = "wkupaon_iclk_mux", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> timer2 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer2 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_timer2_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> timer3 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer3 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_timer3_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> timer4 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer4 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_timer4_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per3 -> timer5 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer5 = { + .master = &dra7xx_l4_per3_hwmod, + .slave = &dra7xx_timer5_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per3 -> timer6 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer6 = { + .master = &dra7xx_l4_per3_hwmod, + .slave = &dra7xx_timer6_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per3 -> timer7 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer7 = { + .master = &dra7xx_l4_per3_hwmod, + .slave = &dra7xx_timer7_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per3 -> timer8 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer8 = { + .master = &dra7xx_l4_per3_hwmod, + .slave = &dra7xx_timer8_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> timer9 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer9 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_timer9_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> timer10 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer10 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_timer10_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> timer11 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer11 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_timer11_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> uart1 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__uart1 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_uart1_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> uart2 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__uart2 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_uart2_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> uart3 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__uart3 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_uart3_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> uart4 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__uart4 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_uart4_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> uart5 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__uart5 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_uart5_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per1 -> uart6 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per1__uart6 = { + .master = &dra7xx_l4_per1_hwmod, + .slave = &dra7xx_uart6_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per3 -> usb_otg_ss1 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per3__usb_otg_ss1 = { + .master = &dra7xx_l4_per3_hwmod, + .slave = &dra7xx_usb_otg_ss1_hwmod, + .clk = "dpll_core_h13x2_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per3 -> usb_otg_ss2 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per3__usb_otg_ss2 = { + .master = &dra7xx_l4_per3_hwmod, + .slave = &dra7xx_usb_otg_ss2_hwmod, + .clk = "dpll_core_h13x2_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per3 -> usb_otg_ss3 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per3__usb_otg_ss3 = { + .master = &dra7xx_l4_per3_hwmod, + .slave = &dra7xx_usb_otg_ss3_hwmod, + .clk = "dpll_core_h13x2_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per3 -> usb_otg_ss4 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per3__usb_otg_ss4 = { + .master = &dra7xx_l4_per3_hwmod, + .slave = &dra7xx_usb_otg_ss4_hwmod, + .clk = "dpll_core_h13x2_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_1 -> vcp1 */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__vcp1 = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_vcp1_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per2 -> vcp1 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per2__vcp1 = { + .master = &dra7xx_l4_per2_hwmod, + .slave = &dra7xx_vcp1_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_1 -> vcp2 */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__vcp2 = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_vcp2_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per2 -> vcp2 */ +static struct omap_hwmod_ocp_if dra7xx_l4_per2__vcp2 = { + .master = &dra7xx_l4_per2_hwmod, + .slave = &dra7xx_vcp2_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> wd_timer2 */ +static struct omap_hwmod_ocp_if dra7xx_l4_wkup__wd_timer2 = { + .master = &dra7xx_l4_wkup_hwmod, + .slave = &dra7xx_wd_timer2_hwmod, + .clk = "wkupaon_iclk_mux", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = { + &dra7xx_l3_main_2__l3_instr, + &dra7xx_l4_cfg__l3_main_1, + &dra7xx_mpu__l3_main_1, + &dra7xx_l3_main_1__l3_main_2, + &dra7xx_l4_cfg__l3_main_2, + &dra7xx_l3_main_1__l4_cfg, + &dra7xx_l3_main_1__l4_per1, + &dra7xx_l3_main_1__l4_per2, + &dra7xx_l3_main_1__l4_per3, + &dra7xx_l3_main_1__l4_wkup, + &dra7xx_l4_per2__atl, + &dra7xx_l3_main_1__bb2d, + &dra7xx_l4_wkup__counter_32k, + &dra7xx_l4_wkup__ctrl_module_wkup, + &dra7xx_l4_wkup__dcan1, + &dra7xx_l4_per2__dcan2, + &dra7xx_l4_cfg__dma_system, + &dra7xx_l3_main_1__dss, + &dra7xx_l3_main_1__dispc, + &dra7xx_l3_main_1__hdmi, + &dra7xx_l4_per1__elm, + &dra7xx_l4_wkup__gpio1, + &dra7xx_l4_per1__gpio2, + &dra7xx_l4_per1__gpio3, + &dra7xx_l4_per1__gpio4, + &dra7xx_l4_per1__gpio5, + &dra7xx_l4_per1__gpio6, + &dra7xx_l4_per1__gpio7, + &dra7xx_l4_per1__gpio8, + &dra7xx_l3_main_1__gpmc, + &dra7xx_l4_per1__hdq1w, + &dra7xx_l4_per1__i2c1, + &dra7xx_l4_per1__i2c2, + &dra7xx_l4_per1__i2c3, + &dra7xx_l4_per1__i2c4, + &dra7xx_l4_per1__i2c5, + &dra7xx_l4_per1__mcspi1, + &dra7xx_l4_per1__mcspi2, + &dra7xx_l4_per1__mcspi3, + &dra7xx_l4_per1__mcspi4, + &dra7xx_l4_per1__mmc1, + &dra7xx_l4_per1__mmc2, + &dra7xx_l4_per1__mmc3, + &dra7xx_l4_per1__mmc4, + &dra7xx_l4_cfg__mpu, + &dra7xx_l4_cfg__ocp2scp1, + &dra7xx_l3_main_1__qspi, + &dra7xx_l4_cfg__sata, + &dra7xx_l4_cfg__smartreflex_core, + &dra7xx_l4_cfg__smartreflex_mpu, + &dra7xx_l4_cfg__spinlock, + &dra7xx_l4_wkup__timer1, + &dra7xx_l4_per1__timer2, + &dra7xx_l4_per1__timer3, + &dra7xx_l4_per1__timer4, + &dra7xx_l4_per3__timer5, + &dra7xx_l4_per3__timer6, + &dra7xx_l4_per3__timer7, + &dra7xx_l4_per3__timer8, + &dra7xx_l4_per1__timer9, + &dra7xx_l4_per1__timer10, + &dra7xx_l4_per1__timer11, + &dra7xx_l4_per1__uart1, + &dra7xx_l4_per1__uart2, + &dra7xx_l4_per1__uart3, + &dra7xx_l4_per1__uart4, + &dra7xx_l4_per1__uart5, + &dra7xx_l4_per1__uart6, + &dra7xx_l4_per3__usb_otg_ss1, + &dra7xx_l4_per3__usb_otg_ss2, + &dra7xx_l4_per3__usb_otg_ss3, + &dra7xx_l4_per3__usb_otg_ss4, + &dra7xx_l3_main_1__vcp1, + &dra7xx_l4_per2__vcp1, + &dra7xx_l3_main_1__vcp2, + &dra7xx_l4_per2__vcp2, + &dra7xx_l4_wkup__wd_timer2, + NULL, +}; + +int __init dra7xx_hwmod_init(void) +{ + omap_hwmod_init(); + return omap_hwmod_register_links(dra7xx_hwmod_ocp_ifs); +} diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.c b/arch/arm/mach-omap2/omap_hwmod_common_data.c new file mode 100644 index 00000000000..79d623b83e4 --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_common_data.c @@ -0,0 +1,65 @@ +/* + * omap_hwmod common data structures + * + * Copyright (C) 2010 Texas Instruments, Inc. + * Thara Gopinath <thara@ti.com> + * Benoît Cousson + * + * Copyright (C) 2010 Nokia Corporation + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This data/structures are to be used while defining OMAP on-chip module + * data and their integration with other OMAP modules and Linux. + */ + +#include "omap_hwmod.h" + +#include "omap_hwmod_common_data.h" + +/** + * struct omap_hwmod_sysc_type1 - TYPE1 sysconfig scheme. + * + * To be used by hwmod structure to specify the sysconfig offsets + * if the device ip is compliant with the original PRCM protocol + * defined for OMAP2420. + */ +struct omap_hwmod_sysc_fields omap_hwmod_sysc_type1 = { + .midle_shift = SYSC_TYPE1_MIDLEMODE_SHIFT, + .clkact_shift = SYSC_TYPE1_CLOCKACTIVITY_SHIFT, + .sidle_shift = SYSC_TYPE1_SIDLEMODE_SHIFT, + .enwkup_shift = SYSC_TYPE1_ENAWAKEUP_SHIFT, + .srst_shift = SYSC_TYPE1_SOFTRESET_SHIFT, + .autoidle_shift = SYSC_TYPE1_AUTOIDLE_SHIFT, +}; + +/** + * struct omap_hwmod_sysc_type2 - TYPE2 sysconfig scheme. + * + * To be used by hwmod structure to specify the sysconfig offsets if the + * device ip is compliant with the new PRCM protocol defined for new + * OMAP4 IPs. + */ +struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2 = { + .midle_shift = SYSC_TYPE2_MIDLEMODE_SHIFT, + .sidle_shift = SYSC_TYPE2_SIDLEMODE_SHIFT, + .srst_shift = SYSC_TYPE2_SOFTRESET_SHIFT, + .dmadisable_shift = SYSC_TYPE2_DMADISABLE_SHIFT, +}; + +/** + * struct omap_hwmod_sysc_type3 - TYPE3 sysconfig scheme. + * Used by some IPs on AM33xx + */ +struct omap_hwmod_sysc_fields omap_hwmod_sysc_type3 = { + .midle_shift = SYSC_TYPE3_MIDLEMODE_SHIFT, + .sidle_shift = SYSC_TYPE3_SIDLEMODE_SHIFT, +}; + +struct omap_dss_dispc_dev_attr omap2_3_dss_dispc_dev_attr = { + .manager_count = 2, + .has_framedonetv_irq = 0 +}; diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.h b/arch/arm/mach-omap2/omap_hwmod_common_data.h new file mode 100644 index 00000000000..2c38c6b0ee0 --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_common_data.h @@ -0,0 +1,172 @@ +/* + * omap_hwmod_common_data.h - OMAP hwmod common macros and declarations + * + * Copyright (C) 2010-2011 Nokia Corporation + * Copyright (C) 2010-2012 Texas Instruments, Inc. + * Paul Walmsley + * Benoît Cousson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ARCH_ARM_MACH_OMAP2_OMAP_HWMOD_COMMON_DATA_H +#define __ARCH_ARM_MACH_OMAP2_OMAP_HWMOD_COMMON_DATA_H + +#include "omap_hwmod.h" + +#include "common.h" +#include "display.h" + +/* Common address space across OMAP2xxx/3xxx */ +extern struct omap_hwmod_addr_space omap2_i2c1_addr_space[]; +extern struct omap_hwmod_addr_space omap2_i2c2_addr_space[]; +extern struct omap_hwmod_addr_space omap2_dss_addrs[]; +extern struct omap_hwmod_addr_space omap2_dss_dispc_addrs[]; +extern struct omap_hwmod_addr_space omap2_dss_rfbi_addrs[]; +extern struct omap_hwmod_addr_space omap2_dss_venc_addrs[]; +extern struct omap_hwmod_addr_space omap2_timer10_addrs[]; +extern struct omap_hwmod_addr_space omap2_timer11_addrs[]; +extern struct omap_hwmod_addr_space omap2430_mmc1_addr_space[]; +extern struct omap_hwmod_addr_space omap2430_mmc2_addr_space[]; +extern struct omap_hwmod_addr_space omap2_mcspi1_addr_space[]; +extern struct omap_hwmod_addr_space omap2_mcspi2_addr_space[]; +extern struct omap_hwmod_addr_space omap2430_mcspi3_addr_space[]; +extern struct omap_hwmod_addr_space omap2_dma_system_addrs[]; +extern struct omap_hwmod_addr_space omap2_mailbox_addrs[]; +extern struct omap_hwmod_addr_space omap2_mcbsp1_addrs[]; +extern struct omap_hwmod_addr_space omap2_hdq1w_addr_space[]; + +/* Common IP block data across OMAP2xxx */ +extern struct omap_gpio_dev_attr omap2xxx_gpio_dev_attr; +extern struct omap_hwmod omap2xxx_l3_main_hwmod; +extern struct omap_hwmod omap2xxx_l4_core_hwmod; +extern struct omap_hwmod omap2xxx_l4_wkup_hwmod; +extern struct omap_hwmod omap2xxx_mpu_hwmod; +extern struct omap_hwmod omap2xxx_iva_hwmod; +extern struct omap_hwmod omap2xxx_timer1_hwmod; +extern struct omap_hwmod omap2xxx_timer2_hwmod; +extern struct omap_hwmod omap2xxx_timer3_hwmod; +extern struct omap_hwmod omap2xxx_timer4_hwmod; +extern struct omap_hwmod omap2xxx_timer5_hwmod; +extern struct omap_hwmod omap2xxx_timer6_hwmod; +extern struct omap_hwmod omap2xxx_timer7_hwmod; +extern struct omap_hwmod omap2xxx_timer8_hwmod; +extern struct omap_hwmod omap2xxx_timer9_hwmod; +extern struct omap_hwmod omap2xxx_timer10_hwmod; +extern struct omap_hwmod omap2xxx_timer11_hwmod; +extern struct omap_hwmod omap2xxx_timer12_hwmod; +extern struct omap_hwmod omap2xxx_wd_timer2_hwmod; +extern struct omap_hwmod omap2xxx_uart1_hwmod; +extern struct omap_hwmod omap2xxx_uart2_hwmod; +extern struct omap_hwmod omap2xxx_uart3_hwmod; +extern struct omap_hwmod omap2xxx_dss_core_hwmod; +extern struct omap_hwmod omap2xxx_dss_dispc_hwmod; +extern struct omap_hwmod omap2xxx_dss_rfbi_hwmod; +extern struct omap_hwmod omap2xxx_dss_venc_hwmod; +extern struct omap_hwmod omap2xxx_gpio1_hwmod; +extern struct omap_hwmod omap2xxx_gpio2_hwmod; +extern struct omap_hwmod omap2xxx_gpio3_hwmod; +extern struct omap_hwmod omap2xxx_gpio4_hwmod; +extern struct omap_hwmod omap2xxx_mcspi1_hwmod; +extern struct omap_hwmod omap2xxx_mcspi2_hwmod; +extern struct omap_hwmod omap2xxx_counter_32k_hwmod; +extern struct omap_hwmod omap2xxx_gpmc_hwmod; +extern struct omap_hwmod omap2xxx_rng_hwmod; +extern struct omap_hwmod omap2xxx_sham_hwmod; +extern struct omap_hwmod omap2xxx_aes_hwmod; + +/* Common interface data across OMAP2xxx */ +extern struct omap_hwmod_ocp_if omap2xxx_l3_main__l4_core; +extern struct omap_hwmod_ocp_if omap2xxx_mpu__l3_main; +extern struct omap_hwmod_ocp_if omap2xxx_dss__l3; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__l4_wkup; +extern struct omap_hwmod_ocp_if omap2_l4_core__uart1; +extern struct omap_hwmod_ocp_if omap2_l4_core__uart2; +extern struct omap_hwmod_ocp_if omap2_l4_core__uart3; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__mcspi1; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__mcspi2; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer2; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer3; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer4; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer5; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer6; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer7; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer8; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer9; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer10; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer11; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__timer12; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__dss; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_dispc; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_rfbi; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_venc; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__rng; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__sham; +extern struct omap_hwmod_ocp_if omap2xxx_l4_core__aes; + +/* Common IP block data */ +extern struct omap_hwmod_dma_info omap2_uart1_sdma_reqs[]; +extern struct omap_hwmod_dma_info omap2_uart2_sdma_reqs[]; +extern struct omap_hwmod_dma_info omap2_uart3_sdma_reqs[]; +extern struct omap_hwmod_dma_info omap2_i2c1_sdma_reqs[]; +extern struct omap_hwmod_dma_info omap2_i2c2_sdma_reqs[]; +extern struct omap_hwmod_dma_info omap2_mcspi1_sdma_reqs[]; +extern struct omap_hwmod_dma_info omap2_mcspi2_sdma_reqs[]; +extern struct omap_hwmod_dma_info omap2_mcbsp1_sdma_reqs[]; +extern struct omap_hwmod_dma_info omap2_mcbsp2_sdma_reqs[]; + +/* Common IP block data on OMAP2430/OMAP3 */ +extern struct omap_hwmod_dma_info omap2_mcbsp3_sdma_reqs[]; + +/* Common IP block data across OMAP2/3 */ +extern struct omap_hwmod_irq_info omap2_timer1_mpu_irqs[]; +extern struct omap_hwmod_irq_info omap2_timer2_mpu_irqs[]; +extern struct omap_hwmod_irq_info omap2_timer3_mpu_irqs[]; +extern struct omap_hwmod_irq_info omap2_timer4_mpu_irqs[]; +extern struct omap_hwmod_irq_info omap2_timer5_mpu_irqs[]; +extern struct omap_hwmod_irq_info omap2_timer6_mpu_irqs[]; +extern struct omap_hwmod_irq_info omap2_timer7_mpu_irqs[]; +extern struct omap_hwmod_irq_info omap2_timer8_mpu_irqs[]; +extern struct omap_hwmod_irq_info omap2_timer9_mpu_irqs[]; +extern struct omap_hwmod_irq_info omap2_timer10_mpu_irqs[]; +extern struct omap_hwmod_irq_info omap2_timer11_mpu_irqs[]; +extern struct omap_hwmod_irq_info omap2_uart1_mpu_irqs[]; +extern struct omap_hwmod_irq_info omap2_uart2_mpu_irqs[]; +extern struct omap_hwmod_irq_info omap2_uart3_mpu_irqs[]; +extern struct omap_hwmod_irq_info omap2_dispc_irqs[]; +extern struct omap_hwmod_irq_info omap2_i2c1_mpu_irqs[]; +extern struct omap_hwmod_irq_info omap2_i2c2_mpu_irqs[]; +extern struct omap_hwmod_irq_info omap2_gpio1_irqs[]; +extern struct omap_hwmod_irq_info omap2_gpio2_irqs[]; +extern struct omap_hwmod_irq_info omap2_gpio3_irqs[]; +extern struct omap_hwmod_irq_info omap2_gpio4_irqs[]; +extern struct omap_hwmod_irq_info omap2_dma_system_irqs[]; +extern struct omap_hwmod_irq_info omap2_mcspi1_mpu_irqs[]; +extern struct omap_hwmod_irq_info omap2_mcspi2_mpu_irqs[]; +extern struct omap_hwmod_addr_space omap2xxx_timer12_addrs[]; +extern struct omap_hwmod_irq_info omap2_hdq1w_mpu_irqs[]; + +/* OMAP hwmod classes - forward declarations */ +extern struct omap_hwmod_class l3_hwmod_class; +extern struct omap_hwmod_class l4_hwmod_class; +extern struct omap_hwmod_class mpu_hwmod_class; +extern struct omap_hwmod_class iva_hwmod_class; +extern struct omap_hwmod_class omap2_uart_class; +extern struct omap_hwmod_class omap2_dss_hwmod_class; +extern struct omap_hwmod_class omap2_dispc_hwmod_class; +extern struct omap_hwmod_class omap2_rfbi_hwmod_class; +extern struct omap_hwmod_class omap2_venc_hwmod_class; +extern struct omap_hwmod_class_sysconfig omap2_hdq1w_sysc; +extern struct omap_hwmod_class omap2_hdq1w_class; + +extern struct omap_hwmod_class omap2xxx_timer_hwmod_class; +extern struct omap_hwmod_class omap2xxx_wd_timer_hwmod_class; +extern struct omap_hwmod_class omap2xxx_gpio_hwmod_class; +extern struct omap_hwmod_class omap2xxx_dma_hwmod_class; +extern struct omap_hwmod_class omap2xxx_mailbox_hwmod_class; +extern struct omap_hwmod_class omap2xxx_mcspi_class; + +extern struct omap_dss_dispc_dev_attr omap2_3_dss_dispc_dev_attr; + +#endif diff --git a/arch/arm/mach-omap2/omap_hwmod_reset.c b/arch/arm/mach-omap2/omap_hwmod_reset.c new file mode 100644 index 00000000000..65e186c9df5 --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_reset.c @@ -0,0 +1,53 @@ +/* + * OMAP IP block custom reset and preprogramming stubs + * + * Copyright (C) 2012 Texas Instruments, Inc. + * Paul Walmsley + * + * A small number of IP blocks need custom reset and preprogramming + * functions. The stubs in this file provide a standard way for the + * hwmod code to call these functions, which are to be located under + * drivers/. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#include <linux/kernel.h> +#include <linux/errno.h> + +#include <sound/aess.h> + +#include "omap_hwmod.h" + +/** + * omap_hwmod_aess_preprogram - enable AESS internal autogating + * @oh: struct omap_hwmod * + * + * The AESS will not IdleAck to the PRCM until its internal autogating + * is enabled. Since internal autogating is disabled by default after + * AESS reset, we must enable autogating after the hwmod code resets + * the AESS. Returns 0. + */ +int omap_hwmod_aess_preprogram(struct omap_hwmod *oh) +{ + void __iomem *va; + + va = omap_hwmod_get_mpu_rt_va(oh); + if (!va) + return -EINVAL; + + aess_enable_autogating(va); + + return 0; +} diff --git a/arch/arm/mach-omap2/omap_opp_data.h b/arch/arm/mach-omap2/omap_opp_data.h new file mode 100644 index 00000000000..336fdfcf88b --- /dev/null +++ b/arch/arm/mach-omap2/omap_opp_data.h @@ -0,0 +1,99 @@ +/* + * OMAP SoC specific OPP Data helpers + * + * Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/ + * Nishanth Menon + * Kevin Hilman + * Copyright (C) 2010 Nokia Corporation. + * Eduardo Valentin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H +#define __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H + +#include "omap_hwmod.h" + +#include "voltage.h" + +/* + * *BIG FAT WARNING*: + * USE the following ONLY in opp data initialization common to an SoC. + * DO NOT USE these in board files/pm core etc. + */ + +/** + * struct omap_opp_def - OMAP OPP Definition + * @hwmod_name: Name of the hwmod for this domain + * @freq: Frequency in hertz corresponding to this OPP + * @u_volt: Nominal voltage in microvolts corresponding to this OPP + * @default_available: True/false - is this OPP available by default + * + * OMAP SOCs have a standard set of tuples consisting of frequency and voltage + * pairs that the device will support per voltage domain. This is called + * Operating Points or OPP. The actual definitions of OMAP Operating Points + * varies over silicon within the same family of devices. For a specific + * domain, you can have a set of {frequency, voltage} pairs and this is denoted + * by an array of omap_opp_def. As the kernel boots and more information is + * available, a set of these are activated based on the precise nature of + * device the kernel boots up on. It is interesting to remember that each IP + * which belongs to a voltage domain may define their own set of OPPs on top + * of this - but this is handled by the appropriate driver. + */ +struct omap_opp_def { + char *hwmod_name; + + unsigned long freq; + unsigned long u_volt; + + bool default_available; +}; + +/* + * Initialization wrapper used to define an OPP for OMAP variants. + */ +#define OPP_INITIALIZER(_hwmod_name, _enabled, _freq, _uv) \ +{ \ + .hwmod_name = _hwmod_name, \ + .default_available = _enabled, \ + .freq = _freq, \ + .u_volt = _uv, \ +} + +/* + * Initialization wrapper used to define SmartReflex process data + * XXX Is this needed? Just use C99 initializers in data files? + */ +#define VOLT_DATA_DEFINE(_v_nom, _efuse_offs, _errminlimit, _errgain) \ +{ \ + .volt_nominal = _v_nom, \ + .sr_efuse_offs = _efuse_offs, \ + .sr_errminlimit = _errminlimit, \ + .vp_errgain = _errgain \ +} + +/* Use this to initialize the default table */ +extern int __init omap_init_opp_table(struct omap_opp_def *opp_def, + u32 opp_def_size); + + +extern struct omap_volt_data omap34xx_vddmpu_volt_data[]; +extern struct omap_volt_data omap34xx_vddcore_volt_data[]; +extern struct omap_volt_data omap36xx_vddmpu_volt_data[]; +extern struct omap_volt_data omap36xx_vddcore_volt_data[]; + +extern struct omap_volt_data omap443x_vdd_mpu_volt_data[]; +extern struct omap_volt_data omap443x_vdd_iva_volt_data[]; +extern struct omap_volt_data omap443x_vdd_core_volt_data[]; +extern struct omap_volt_data omap446x_vdd_mpu_volt_data[]; +extern struct omap_volt_data omap446x_vdd_iva_volt_data[]; +extern struct omap_volt_data omap446x_vdd_core_volt_data[]; + +#endif /* __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H */ diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c new file mode 100644 index 00000000000..50640b38f0b --- /dev/null +++ b/arch/arm/mach-omap2/omap_phy_internal.c @@ -0,0 +1,187 @@ +/* + * This file configures the internal USB PHY in OMAP4430. Used + * with TWL6030 transceiver and MUSB on OMAP4430. + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Author: Hema HK <hemahk@ti.com> + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <linux/types.h> +#include <linux/delay.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/usb.h> +#include <linux/usb/musb.h> + +#include "soc.h" +#include "control.h" +#include "usb.h" + +#define CONTROL_DEV_CONF 0x300 +#define PHY_PD 0x1 + +/** + * omap4430_phy_power_down: disable MUSB PHY during early init + * + * OMAP4 MUSB PHY module is enabled by default on reset, but this will + * prevent core retention if not disabled by SW. USB driver will + * later on enable this, once and if the driver needs it. + */ +static int __init omap4430_phy_power_down(void) +{ + void __iomem *ctrl_base; + + if (!cpu_is_omap44xx()) + return 0; + + ctrl_base = ioremap(OMAP443X_SCM_BASE, SZ_1K); + if (!ctrl_base) { + pr_err("control module ioremap failed\n"); + return -ENOMEM; + } + + /* Power down the phy */ + writel_relaxed(PHY_PD, ctrl_base + CONTROL_DEV_CONF); + + iounmap(ctrl_base); + + return 0; +} +omap_early_initcall(omap4430_phy_power_down); + +void am35x_musb_reset(void) +{ + u32 regval; + + /* Reset the musb interface */ + regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); + + regval |= AM35XX_USBOTGSS_SW_RST; + omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET); + + regval &= ~AM35XX_USBOTGSS_SW_RST; + omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET); + + regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); +} + +void am35x_musb_phy_power(u8 on) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(100); + u32 devconf2; + + if (on) { + /* + * Start the on-chip PHY and its PLL. + */ + devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); + + devconf2 &= ~(CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN); + devconf2 |= CONF2_PHY_PLLON; + + omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); + + pr_info(KERN_INFO "Waiting for PHY clock good...\n"); + while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2) + & CONF2_PHYCLKGD)) { + cpu_relax(); + + if (time_after(jiffies, timeout)) { + pr_err(KERN_ERR "musb PHY clock good timed out\n"); + break; + } + } + } else { + /* + * Power down the on-chip PHY. + */ + devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); + + devconf2 &= ~CONF2_PHY_PLLON; + devconf2 |= CONF2_PHYPWRDN | CONF2_OTGPWRDN; + omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); + } +} + +void am35x_musb_clear_irq(void) +{ + u32 regval; + + regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); + regval |= AM35XX_USBOTGSS_INT_CLR; + omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR); + regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); +} + +void am35x_set_mode(u8 musb_mode) +{ + u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); + + devconf2 &= ~CONF2_OTGMODE; + switch (musb_mode) { + case MUSB_HOST: /* Force VBUS valid, ID = 0 */ + devconf2 |= CONF2_FORCE_HOST; + break; + case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */ + devconf2 |= CONF2_FORCE_DEVICE; + break; + case MUSB_OTG: /* Don't override the VBUS/ID comparators */ + devconf2 |= CONF2_NO_OVERRIDE; + break; + default: + pr_info(KERN_INFO "Unsupported mode %u\n", musb_mode); + } + + omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); +} + +void ti81xx_musb_phy_power(u8 on) +{ + void __iomem *scm_base = NULL; + u32 usbphycfg; + + scm_base = ioremap(TI81XX_SCM_BASE, SZ_2K); + if (!scm_base) { + pr_err("system control module ioremap failed\n"); + return; + } + + usbphycfg = readl_relaxed(scm_base + USBCTRL0); + + if (on) { + if (cpu_is_ti816x()) { + usbphycfg |= TI816X_USBPHY0_NORMAL_MODE; + usbphycfg &= ~TI816X_USBPHY_REFCLK_OSC; + } else if (cpu_is_ti814x()) { + usbphycfg &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN + | USBPHY_DPINPUT | USBPHY_DMINPUT); + usbphycfg |= (USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN + | USBPHY_DPOPBUFCTL | USBPHY_DMOPBUFCTL); + } + } else { + if (cpu_is_ti816x()) + usbphycfg &= ~TI816X_USBPHY0_NORMAL_MODE; + else if (cpu_is_ti814x()) + usbphycfg |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN; + + } + writel_relaxed(usbphycfg, scm_base + USBCTRL0); + + iounmap(scm_base); +} diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c new file mode 100644 index 00000000000..6bf62670055 --- /dev/null +++ b/arch/arm/mach-omap2/omap_twl.c @@ -0,0 +1,254 @@ +/** + * OMAP and TWL PMIC specific intializations. + * + * Copyright (C) 2010 Texas Instruments Incorporated. + * Thara Gopinath + * Copyright (C) 2009 Texas Instruments Incorporated. + * Nishanth Menon + * Copyright (C) 2009 Nokia Corporation + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/err.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/i2c/twl.h> + +#include "soc.h" +#include "voltage.h" + +#include "pm.h" + +#define OMAP3_SRI2C_SLAVE_ADDR 0x12 +#define OMAP3_VDD_MPU_SR_CONTROL_REG 0x00 +#define OMAP3_VDD_CORE_SR_CONTROL_REG 0x01 +#define OMAP3_VP_CONFIG_ERROROFFSET 0x00 +#define OMAP3_VP_VSTEPMIN_VSTEPMIN 0x1 +#define OMAP3_VP_VSTEPMAX_VSTEPMAX 0x04 +#define OMAP3_VP_VLIMITTO_TIMEOUT_US 200 + +#define OMAP4_SRI2C_SLAVE_ADDR 0x12 +#define OMAP4_VDD_MPU_SR_VOLT_REG 0x55 +#define OMAP4_VDD_MPU_SR_CMD_REG 0x56 +#define OMAP4_VDD_IVA_SR_VOLT_REG 0x5B +#define OMAP4_VDD_IVA_SR_CMD_REG 0x5C +#define OMAP4_VDD_CORE_SR_VOLT_REG 0x61 +#define OMAP4_VDD_CORE_SR_CMD_REG 0x62 + +#define OMAP4_VP_CONFIG_ERROROFFSET 0x00 +#define OMAP4_VP_VSTEPMIN_VSTEPMIN 0x01 +#define OMAP4_VP_VSTEPMAX_VSTEPMAX 0x04 +#define OMAP4_VP_VLIMITTO_TIMEOUT_US 200 + +static bool is_offset_valid; +static u8 smps_offset; + +#define REG_SMPS_OFFSET 0xE0 + +static unsigned long twl4030_vsel_to_uv(const u8 vsel) +{ + return (((vsel * 125) + 6000)) * 100; +} + +static u8 twl4030_uv_to_vsel(unsigned long uv) +{ + return DIV_ROUND_UP(uv - 600000, 12500); +} + +static unsigned long twl6030_vsel_to_uv(const u8 vsel) +{ + /* + * In TWL6030 depending on the value of SMPS_OFFSET + * efuse register the voltage range supported in + * standard mode can be either between 0.6V - 1.3V or + * 0.7V - 1.4V. In TWL6030 ES1.0 SMPS_OFFSET efuse + * is programmed to all 0's where as starting from + * TWL6030 ES1.1 the efuse is programmed to 1 + */ + if (!is_offset_valid) { + twl_i2c_read_u8(TWL6030_MODULE_ID0, &smps_offset, + REG_SMPS_OFFSET); + is_offset_valid = true; + } + + if (!vsel) + return 0; + /* + * There is no specific formula for voltage to vsel + * conversion above 1.3V. There are special hardcoded + * values for voltages above 1.3V. Currently we are + * hardcoding only for 1.35 V which is used for 1GH OPP for + * OMAP4430. + */ + if (vsel == 0x3A) + return 1350000; + + if (smps_offset & 0x8) + return ((((vsel - 1) * 1266) + 70900)) * 10; + else + return ((((vsel - 1) * 1266) + 60770)) * 10; +} + +static u8 twl6030_uv_to_vsel(unsigned long uv) +{ + /* + * In TWL6030 depending on the value of SMPS_OFFSET + * efuse register the voltage range supported in + * standard mode can be either between 0.6V - 1.3V or + * 0.7V - 1.4V. In TWL6030 ES1.0 SMPS_OFFSET efuse + * is programmed to all 0's where as starting from + * TWL6030 ES1.1 the efuse is programmed to 1 + */ + if (!is_offset_valid) { + twl_i2c_read_u8(TWL6030_MODULE_ID0, &smps_offset, + REG_SMPS_OFFSET); + is_offset_valid = true; + } + + if (!uv) + return 0x00; + /* + * There is no specific formula for voltage to vsel + * conversion above 1.3V. There are special hardcoded + * values for voltages above 1.3V. Currently we are + * hardcoding only for 1.35 V which is used for 1GH OPP for + * OMAP4430. + */ + if (uv > twl6030_vsel_to_uv(0x39)) { + if (uv == 1350000) + return 0x3A; + pr_err("%s:OUT OF RANGE! non mapped vsel for %ld Vs max %ld\n", + __func__, uv, twl6030_vsel_to_uv(0x39)); + return 0x3A; + } + + if (smps_offset & 0x8) + return DIV_ROUND_UP(uv - 709000, 12660) + 1; + else + return DIV_ROUND_UP(uv - 607700, 12660) + 1; +} + +static struct omap_voltdm_pmic omap3_mpu_pmic = { + .slew_rate = 4000, + .step_size = 12500, + .vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET, + .vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN, + .vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX, + .vddmin = 600000, + .vddmax = 1450000, + .vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US, + .i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR, + .volt_reg_addr = OMAP3_VDD_MPU_SR_CONTROL_REG, + .i2c_high_speed = true, + .vsel_to_uv = twl4030_vsel_to_uv, + .uv_to_vsel = twl4030_uv_to_vsel, +}; + +static struct omap_voltdm_pmic omap3_core_pmic = { + .slew_rate = 4000, + .step_size = 12500, + .vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET, + .vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN, + .vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX, + .vddmin = 600000, + .vddmax = 1450000, + .vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US, + .i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR, + .volt_reg_addr = OMAP3_VDD_CORE_SR_CONTROL_REG, + .i2c_high_speed = true, + .vsel_to_uv = twl4030_vsel_to_uv, + .uv_to_vsel = twl4030_uv_to_vsel, +}; + +static struct omap_voltdm_pmic omap4_mpu_pmic = { + .slew_rate = 4000, + .step_size = 12660, + .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET, + .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN, + .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX, + .vddmin = 0, + .vddmax = 2100000, + .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US, + .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR, + .volt_reg_addr = OMAP4_VDD_MPU_SR_VOLT_REG, + .cmd_reg_addr = OMAP4_VDD_MPU_SR_CMD_REG, + .i2c_high_speed = true, + .i2c_pad_load = 3, + .vsel_to_uv = twl6030_vsel_to_uv, + .uv_to_vsel = twl6030_uv_to_vsel, +}; + +static struct omap_voltdm_pmic omap4_iva_pmic = { + .slew_rate = 4000, + .step_size = 12660, + .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET, + .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN, + .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX, + .vddmin = 0, + .vddmax = 2100000, + .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US, + .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR, + .volt_reg_addr = OMAP4_VDD_IVA_SR_VOLT_REG, + .cmd_reg_addr = OMAP4_VDD_IVA_SR_CMD_REG, + .i2c_high_speed = true, + .i2c_pad_load = 3, + .vsel_to_uv = twl6030_vsel_to_uv, + .uv_to_vsel = twl6030_uv_to_vsel, +}; + +static struct omap_voltdm_pmic omap4_core_pmic = { + .slew_rate = 4000, + .step_size = 12660, + .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET, + .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN, + .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX, + .vddmin = 0, + .vddmax = 2100000, + .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US, + .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR, + .volt_reg_addr = OMAP4_VDD_CORE_SR_VOLT_REG, + .cmd_reg_addr = OMAP4_VDD_CORE_SR_CMD_REG, + .i2c_high_speed = true, + .i2c_pad_load = 3, + .vsel_to_uv = twl6030_vsel_to_uv, + .uv_to_vsel = twl6030_uv_to_vsel, +}; + +int __init omap4_twl_init(void) +{ + struct voltagedomain *voltdm; + + if (!cpu_is_omap44xx()) + return -ENODEV; + + voltdm = voltdm_lookup("mpu"); + omap_voltage_register_pmic(voltdm, &omap4_mpu_pmic); + + voltdm = voltdm_lookup("iva"); + omap_voltage_register_pmic(voltdm, &omap4_iva_pmic); + + voltdm = voltdm_lookup("core"); + omap_voltage_register_pmic(voltdm, &omap4_core_pmic); + + return 0; +} + +int __init omap3_twl_init(void) +{ + struct voltagedomain *voltdm; + + if (!cpu_is_omap34xx()) + return -ENODEV; + + voltdm = voltdm_lookup("mpu_iva"); + omap_voltage_register_pmic(voltdm, &omap3_mpu_pmic); + + voltdm = voltdm_lookup("core"); + omap_voltage_register_pmic(voltdm, &omap3_core_pmic); + + return 0; +} diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c new file mode 100644 index 00000000000..a358a07e18f --- /dev/null +++ b/arch/arm/mach-omap2/opp.c @@ -0,0 +1,104 @@ +/* + * OMAP SoC specific OPP wrapper function + * + * Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/ + * Nishanth Menon + * Kevin Hilman + * Copyright (C) 2010 Nokia Corporation. + * Eduardo Valentin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include <linux/module.h> +#include <linux/of.h> +#include <linux/pm_opp.h> +#include <linux/cpu.h> + +#include "omap_device.h" + +#include "omap_opp_data.h" + +/* Temp variable to allow multiple calls */ +static u8 __initdata omap_table_init; + +/** + * omap_init_opp_table() - Initialize opp table as per the CPU type + * @opp_def: opp default list for this silicon + * @opp_def_size: number of opp entries for this silicon + * + * Register the initial OPP table with the OPP library based on the CPU + * type. This is meant to be used only by SoC specific registration. + */ +int __init omap_init_opp_table(struct omap_opp_def *opp_def, + u32 opp_def_size) +{ + int i, r; + + if (of_have_populated_dt()) + return -EINVAL; + + if (!opp_def || !opp_def_size) { + pr_err("%s: invalid params!\n", __func__); + return -EINVAL; + } + + /* + * Initialize only if not already initialized even if the previous + * call failed, because, no reason we'd succeed again. + */ + if (omap_table_init) + return -EEXIST; + omap_table_init = 1; + + /* Lets now register with OPP library */ + for (i = 0; i < opp_def_size; i++, opp_def++) { + struct omap_hwmod *oh; + struct device *dev; + + if (!opp_def->hwmod_name) { + pr_err("%s: NULL name of omap_hwmod, failing [%d].\n", + __func__, i); + return -EINVAL; + } + + if (!strncmp(opp_def->hwmod_name, "mpu", 3)) { + /* + * All current OMAPs share voltage rail and + * clock source, so CPU0 is used to represent + * the MPU-SS. + */ + dev = get_cpu_device(0); + } else { + oh = omap_hwmod_lookup(opp_def->hwmod_name); + if (!oh || !oh->od) { + pr_debug("%s: no hwmod or odev for %s, [%d] cannot add OPPs.\n", + __func__, opp_def->hwmod_name, i); + continue; + } + dev = &oh->od->pdev->dev; + } + + r = dev_pm_opp_add(dev, opp_def->freq, opp_def->u_volt); + if (r) { + dev_err(dev, "%s: add OPP %ld failed for %s [%d] result=%d\n", + __func__, opp_def->freq, + opp_def->hwmod_name, i, r); + } else { + if (!opp_def->default_available) + r = dev_pm_opp_disable(dev, opp_def->freq); + if (r) + dev_err(dev, "%s: disable %ld failed for %s [%d] result=%d\n", + __func__, opp_def->freq, + opp_def->hwmod_name, i, r); + } + } + + return 0; +} diff --git a/arch/arm/mach-omap2/opp2420_data.c b/arch/arm/mach-omap2/opp2420_data.c new file mode 100644 index 00000000000..a9e8cf21705 --- /dev/null +++ b/arch/arm/mach-omap2/opp2420_data.c @@ -0,0 +1,130 @@ +/* + * opp2420_data.c - old-style "OPP" table for OMAP2420 + * + * Copyright (C) 2005-2009 Texas Instruments, Inc. + * Copyright (C) 2004-2009 Nokia Corporation + * + * Richard Woodruff <r-woodruff2@ti.com> + * + * The OMAP2 processor can be run at several discrete 'PRCM configurations'. + * These configurations are characterized by voltage and speed for clocks. + * The device is only validated for certain combinations. One way to express + * these combinations is via the 'ratios' which the clocks operate with + * respect to each other. These ratio sets are for a given voltage/DPLL + * setting. All configurations can be described by a DPLL setting and a ratio. + * + * XXX Missing voltage data. + * XXX Missing 19.2MHz sys_clk rate sets (needed for N800/N810) + * + * THe format described in this file is deprecated. Once a reasonable + * OPP API exists, the data in this file should be converted to use it. + * + * This is technically part of the OMAP2xxx clock code. + * + * Considerable work is still needed to fully support dynamic frequency + * changes on OMAP2xxx-series chips. Readers interested in such a + * project are encouraged to review the Maemo Diablo RX-34 and RX-44 + * kernel source at: + * http://repository.maemo.org/pool/diablo/free/k/kernel-source-diablo/ + */ + +#include <linux/kernel.h> + +#include "opp2xxx.h" +#include "sdrc.h" +#include "clock.h" + +/* + * Key dividers which make up a PRCM set. Ratios for a PRCM are mandated. + * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU, + * CM_CLKSEL_DSP, CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL, + * CM_CLKSEL2_PLL, CM_CLKSEL_MDM + * + * Filling in table based on H4 boards available. There are quite a + * few more rate combinations which could be defined. + * + * When multiple values are defined the start up will try and choose + * the fastest one. If a 'fast' value is defined, then automatically, + * the /2 one should be included as it can be used. Generally having + * more than one fast set does not make sense, as static timings need + * to be changed to change the set. The exception is the bypass + * setting which is available for low power bypass. + * + * Note: This table needs to be sorted, fastest to slowest. + **/ +const struct prcm_config omap2420_rate_table[] = { + /* PRCM I - FAST */ + {S12M, S660M, S330M, RI_CM_CLKSEL_MPU_VAL, /* 330MHz ARM */ + RI_CM_CLKSEL_DSP_VAL, RI_CM_CLKSEL_GFX_VAL, + RI_CM_CLKSEL1_CORE_VAL, MI_CM_CLKSEL1_PLL_12_VAL, + MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_165MHz, + RATE_IN_242X}, + + /* PRCM II - FAST */ + {S12M, S600M, S300M, RII_CM_CLKSEL_MPU_VAL, /* 300MHz ARM */ + RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL, + RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_12_VAL, + MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz, + RATE_IN_242X}, + + {S13M, S600M, S300M, RII_CM_CLKSEL_MPU_VAL, /* 300MHz ARM */ + RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL, + RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_13_VAL, + MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz, + RATE_IN_242X}, + + /* PRCM III - FAST */ + {S12M, S532M, S266M, RIII_CM_CLKSEL_MPU_VAL, /* 266MHz ARM */ + RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL, + RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_12_VAL, + MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz, + RATE_IN_242X}, + + {S13M, S532M, S266M, RIII_CM_CLKSEL_MPU_VAL, /* 266MHz ARM */ + RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL, + RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_13_VAL, + MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz, + RATE_IN_242X}, + + /* PRCM II - SLOW */ + {S12M, S300M, S150M, RII_CM_CLKSEL_MPU_VAL, /* 150MHz ARM */ + RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL, + RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_12_VAL, + MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz, + RATE_IN_242X}, + + {S13M, S300M, S150M, RII_CM_CLKSEL_MPU_VAL, /* 150MHz ARM */ + RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL, + RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_13_VAL, + MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz, + RATE_IN_242X}, + + /* PRCM III - SLOW */ + {S12M, S266M, S133M, RIII_CM_CLKSEL_MPU_VAL, /* 133MHz ARM */ + RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL, + RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_12_VAL, + MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz, + RATE_IN_242X}, + + {S13M, S266M, S133M, RIII_CM_CLKSEL_MPU_VAL, /* 133MHz ARM */ + RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL, + RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_13_VAL, + MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz, + RATE_IN_242X}, + + /* PRCM-VII (boot-bypass) */ + {S12M, S12M, S12M, RVII_CM_CLKSEL_MPU_VAL, /* 12MHz ARM*/ + RVII_CM_CLKSEL_DSP_VAL, RVII_CM_CLKSEL_GFX_VAL, + RVII_CM_CLKSEL1_CORE_VAL, MVII_CM_CLKSEL1_PLL_12_VAL, + MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_BYPASS, + RATE_IN_242X}, + + /* PRCM-VII (boot-bypass) */ + {S13M, S13M, S13M, RVII_CM_CLKSEL_MPU_VAL, /* 13MHz ARM */ + RVII_CM_CLKSEL_DSP_VAL, RVII_CM_CLKSEL_GFX_VAL, + RVII_CM_CLKSEL1_CORE_VAL, MVII_CM_CLKSEL1_PLL_13_VAL, + MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_BYPASS, + RATE_IN_242X}, + + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +}; diff --git a/arch/arm/mach-omap2/opp2430_data.c b/arch/arm/mach-omap2/opp2430_data.c new file mode 100644 index 00000000000..0e75ec3e114 --- /dev/null +++ b/arch/arm/mach-omap2/opp2430_data.c @@ -0,0 +1,135 @@ +/* + * opp2430_data.c - old-style "OPP" table for OMAP2430 + * + * Copyright (C) 2005-2009 Texas Instruments, Inc. + * Copyright (C) 2004-2009 Nokia Corporation + * + * Richard Woodruff <r-woodruff2@ti.com> + * + * The OMAP2 processor can be run at several discrete 'PRCM configurations'. + * These configurations are characterized by voltage and speed for clocks. + * The device is only validated for certain combinations. One way to express + * these combinations is via the 'ratios' which the clocks operate with + * respect to each other. These ratio sets are for a given voltage/DPLL + * setting. All configurations can be described by a DPLL setting and a ratio. + * + * 2430 differs from 2420 in that there are no more phase synchronizers used. + * They both have a slightly different clock domain setup. 2420(iva1,dsp) vs + * 2430 (iva2.1, NOdsp, mdm) + * + * XXX Missing voltage data. + * XXX Missing 19.2MHz sys_clk rate sets. + * + * THe format described in this file is deprecated. Once a reasonable + * OPP API exists, the data in this file should be converted to use it. + * + * This is technically part of the OMAP2xxx clock code. + */ + +#include <linux/kernel.h> + +#include "opp2xxx.h" +#include "sdrc.h" +#include "clock.h" + +/* + * Key dividers which make up a PRCM set. Ratios for a PRCM are mandated. + * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU, + * CM_CLKSEL_DSP, CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL, + * CM_CLKSEL2_PLL, CM_CLKSEL_MDM + * + * Filling in table based on 2430-SDPs variants available. There are + * quite a few more rate combinations which could be defined. + * + * When multiple values are defined the start up will try and choose + * the fastest one. If a 'fast' value is defined, then automatically, + * the /2 one should be included as it can be used. Generally having + * more than one fast set does not make sense, as static timings need + * to be changed to change the set. The exception is the bypass + * setting which is available for low power bypass. + * + * Note: This table needs to be sorted, fastest to slowest. + */ +const struct prcm_config omap2430_rate_table[] = { + /* PRCM #4 - ratio2 (ES2.1) - FAST */ + {S13M, S798M, S399M, R2_CM_CLKSEL_MPU_VAL, /* 399MHz ARM */ + R2_CM_CLKSEL_DSP_VAL, R2_CM_CLKSEL_GFX_VAL, + R2_CM_CLKSEL1_CORE_VAL, M4_CM_CLKSEL1_PLL_13_VAL, + MX_CLKSEL2_PLL_2x_VAL, R2_CM_CLKSEL_MDM_VAL, + SDRC_RFR_CTRL_133MHz, + RATE_IN_243X}, + + /* PRCM #2 - ratio1 (ES2) - FAST */ + {S13M, S658M, S329M, R1_CM_CLKSEL_MPU_VAL, /* 330MHz ARM */ + R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL, + R1_CM_CLKSEL1_CORE_VAL, M2_CM_CLKSEL1_PLL_13_VAL, + MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL, + SDRC_RFR_CTRL_165MHz, + RATE_IN_243X}, + + /* PRCM #5a - ratio1 - FAST */ + {S13M, S532M, S266M, R1_CM_CLKSEL_MPU_VAL, /* 266MHz ARM */ + R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL, + R1_CM_CLKSEL1_CORE_VAL, M5A_CM_CLKSEL1_PLL_13_VAL, + MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL, + SDRC_RFR_CTRL_133MHz, + RATE_IN_243X}, + + /* PRCM #5b - ratio1 - FAST */ + {S13M, S400M, S200M, R1_CM_CLKSEL_MPU_VAL, /* 200MHz ARM */ + R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL, + R1_CM_CLKSEL1_CORE_VAL, M5B_CM_CLKSEL1_PLL_13_VAL, + MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL, + SDRC_RFR_CTRL_100MHz, + RATE_IN_243X}, + + /* PRCM #4 - ratio1 (ES2.1) - SLOW */ + {S13M, S399M, S199M, R2_CM_CLKSEL_MPU_VAL, /* 200MHz ARM */ + R2_CM_CLKSEL_DSP_VAL, R2_CM_CLKSEL_GFX_VAL, + R2_CM_CLKSEL1_CORE_VAL, M4_CM_CLKSEL1_PLL_13_VAL, + MX_CLKSEL2_PLL_1x_VAL, R2_CM_CLKSEL_MDM_VAL, + SDRC_RFR_CTRL_133MHz, + RATE_IN_243X}, + + /* PRCM #2 - ratio1 (ES2) - SLOW */ + {S13M, S329M, S164M, R1_CM_CLKSEL_MPU_VAL, /* 165MHz ARM */ + R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL, + R1_CM_CLKSEL1_CORE_VAL, M2_CM_CLKSEL1_PLL_13_VAL, + MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL, + SDRC_RFR_CTRL_165MHz, + RATE_IN_243X}, + + /* PRCM #5a - ratio1 - SLOW */ + {S13M, S266M, S133M, R1_CM_CLKSEL_MPU_VAL, /* 133MHz ARM */ + R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL, + R1_CM_CLKSEL1_CORE_VAL, M5A_CM_CLKSEL1_PLL_13_VAL, + MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL, + SDRC_RFR_CTRL_133MHz, + RATE_IN_243X}, + + /* PRCM #5b - ratio1 - SLOW*/ + {S13M, S200M, S100M, R1_CM_CLKSEL_MPU_VAL, /* 100MHz ARM */ + R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL, + R1_CM_CLKSEL1_CORE_VAL, M5B_CM_CLKSEL1_PLL_13_VAL, + MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL, + SDRC_RFR_CTRL_100MHz, + RATE_IN_243X}, + + /* PRCM-boot/bypass */ + {S13M, S13M, S13M, RB_CM_CLKSEL_MPU_VAL, /* 13Mhz */ + RB_CM_CLKSEL_DSP_VAL, RB_CM_CLKSEL_GFX_VAL, + RB_CM_CLKSEL1_CORE_VAL, MB_CM_CLKSEL1_PLL_13_VAL, + MX_CLKSEL2_PLL_2x_VAL, RB_CM_CLKSEL_MDM_VAL, + SDRC_RFR_CTRL_BYPASS, + RATE_IN_243X}, + + /* PRCM-boot/bypass */ + {S12M, S12M, S12M, RB_CM_CLKSEL_MPU_VAL, /* 12Mhz */ + RB_CM_CLKSEL_DSP_VAL, RB_CM_CLKSEL_GFX_VAL, + RB_CM_CLKSEL1_CORE_VAL, MB_CM_CLKSEL1_PLL_12_VAL, + MX_CLKSEL2_PLL_2x_VAL, RB_CM_CLKSEL_MDM_VAL, + SDRC_RFR_CTRL_BYPASS, + RATE_IN_243X}, + + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +}; diff --git a/arch/arm/mach-omap2/opp2xxx.h b/arch/arm/mach-omap2/opp2xxx.h new file mode 100644 index 00000000000..8fae534eb15 --- /dev/null +++ b/arch/arm/mach-omap2/opp2xxx.h @@ -0,0 +1,429 @@ +/* + * opp2xxx.h - macros for old-style OMAP2xxx "OPP" definitions + * + * Copyright (C) 2005-2009 Texas Instruments, Inc. + * Copyright (C) 2004-2009 Nokia Corporation + * + * Richard Woodruff <r-woodruff2@ti.com> + * + * The OMAP2 processor can be run at several discrete 'PRCM configurations'. + * These configurations are characterized by voltage and speed for clocks. + * The device is only validated for certain combinations. One way to express + * these combinations is via the 'ratio's' which the clocks operate with + * respect to each other. These ratio sets are for a given voltage/DPLL + * setting. All configurations can be described by a DPLL setting and a ratio + * There are 3 ratio sets for the 2430 and X ratio sets for 2420. + * + * 2430 differs from 2420 in that there are no more phase synchronizers used. + * They both have a slightly different clock domain setup. 2420(iva1,dsp) vs + * 2430 (iva2.1, NOdsp, mdm) + * + * XXX Missing voltage data. + * + * THe format described in this file is deprecated. Once a reasonable + * OPP API exists, the data in this file should be converted to use it. + * + * This is technically part of the OMAP2xxx clock code. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_OPP2XXX_H +#define __ARCH_ARM_MACH_OMAP2_OPP2XXX_H + +/** + * struct prcm_config - define clock rates on a per-OPP basis (24xx) + * + * Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated. + * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP + * CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL CM_CLKSEL2_PLL, CM_CLKSEL_MDM + * + * This is deprecated. As soon as we have a decent OPP API, we should + * move all this stuff to it. + */ +struct prcm_config { + unsigned long xtal_speed; /* crystal rate */ + unsigned long dpll_speed; /* dpll: out*xtal*M/(N-1)table_recalc */ + unsigned long mpu_speed; /* speed of MPU */ + unsigned long cm_clksel_mpu; /* mpu divider */ + unsigned long cm_clksel_dsp; /* dsp+iva1 div(2420), iva2.1(2430) */ + unsigned long cm_clksel_gfx; /* gfx dividers */ + unsigned long cm_clksel1_core; /* major subsystem dividers */ + unsigned long cm_clksel1_pll; /* m,n */ + unsigned long cm_clksel2_pll; /* dpllx1 or x2 out */ + unsigned long cm_clksel_mdm; /* modem dividers 2430 only */ + unsigned long base_sdrc_rfr; /* base refresh timing for a set */ + unsigned short flags; +}; + + +/* Core fields for cm_clksel, not ratio governed */ +#define RX_CLKSEL_DSS1 (0x10 << 8) +#define RX_CLKSEL_DSS2 (0x0 << 13) +#define RX_CLKSEL_SSI (0x5 << 20) + +/*------------------------------------------------------------------------- + * Voltage/DPLL ratios + *-------------------------------------------------------------------------*/ + +/* 2430 Ratio's, 2430-Ratio Config 1 */ +#define R1_CLKSEL_L3 (4 << 0) +#define R1_CLKSEL_L4 (2 << 5) +#define R1_CLKSEL_USB (4 << 25) +#define R1_CM_CLKSEL1_CORE_VAL (R1_CLKSEL_USB | RX_CLKSEL_SSI | \ + RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \ + R1_CLKSEL_L4 | R1_CLKSEL_L3) +#define R1_CLKSEL_MPU (2 << 0) +#define R1_CM_CLKSEL_MPU_VAL R1_CLKSEL_MPU +#define R1_CLKSEL_DSP (2 << 0) +#define R1_CLKSEL_DSP_IF (2 << 5) +#define R1_CM_CLKSEL_DSP_VAL (R1_CLKSEL_DSP | R1_CLKSEL_DSP_IF) +#define R1_CLKSEL_GFX (2 << 0) +#define R1_CM_CLKSEL_GFX_VAL R1_CLKSEL_GFX +#define R1_CLKSEL_MDM (4 << 0) +#define R1_CM_CLKSEL_MDM_VAL R1_CLKSEL_MDM + +/* 2430-Ratio Config 2 */ +#define R2_CLKSEL_L3 (6 << 0) +#define R2_CLKSEL_L4 (2 << 5) +#define R2_CLKSEL_USB (2 << 25) +#define R2_CM_CLKSEL1_CORE_VAL (R2_CLKSEL_USB | RX_CLKSEL_SSI | \ + RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \ + R2_CLKSEL_L4 | R2_CLKSEL_L3) +#define R2_CLKSEL_MPU (2 << 0) +#define R2_CM_CLKSEL_MPU_VAL R2_CLKSEL_MPU +#define R2_CLKSEL_DSP (2 << 0) +#define R2_CLKSEL_DSP_IF (3 << 5) +#define R2_CM_CLKSEL_DSP_VAL (R2_CLKSEL_DSP | R2_CLKSEL_DSP_IF) +#define R2_CLKSEL_GFX (2 << 0) +#define R2_CM_CLKSEL_GFX_VAL R2_CLKSEL_GFX +#define R2_CLKSEL_MDM (6 << 0) +#define R2_CM_CLKSEL_MDM_VAL R2_CLKSEL_MDM + +/* 2430-Ratio Bootm (BYPASS) */ +#define RB_CLKSEL_L3 (1 << 0) +#define RB_CLKSEL_L4 (1 << 5) +#define RB_CLKSEL_USB (1 << 25) +#define RB_CM_CLKSEL1_CORE_VAL (RB_CLKSEL_USB | RX_CLKSEL_SSI | \ + RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \ + RB_CLKSEL_L4 | RB_CLKSEL_L3) +#define RB_CLKSEL_MPU (1 << 0) +#define RB_CM_CLKSEL_MPU_VAL RB_CLKSEL_MPU +#define RB_CLKSEL_DSP (1 << 0) +#define RB_CLKSEL_DSP_IF (1 << 5) +#define RB_CM_CLKSEL_DSP_VAL (RB_CLKSEL_DSP | RB_CLKSEL_DSP_IF) +#define RB_CLKSEL_GFX (1 << 0) +#define RB_CM_CLKSEL_GFX_VAL RB_CLKSEL_GFX +#define RB_CLKSEL_MDM (1 << 0) +#define RB_CM_CLKSEL_MDM_VAL RB_CLKSEL_MDM + +/* 2420 Ratio Equivalents */ +#define RXX_CLKSEL_VLYNQ (0x12 << 15) +#define RXX_CLKSEL_SSI (0x8 << 20) + +/* 2420-PRCM III 532MHz core */ +#define RIII_CLKSEL_L3 (4 << 0) /* 133MHz */ +#define RIII_CLKSEL_L4 (2 << 5) /* 66.5MHz */ +#define RIII_CLKSEL_USB (4 << 25) /* 33.25MHz */ +#define RIII_CM_CLKSEL1_CORE_VAL (RIII_CLKSEL_USB | RXX_CLKSEL_SSI | \ + RXX_CLKSEL_VLYNQ | RX_CLKSEL_DSS2 | \ + RX_CLKSEL_DSS1 | RIII_CLKSEL_L4 | \ + RIII_CLKSEL_L3) +#define RIII_CLKSEL_MPU (2 << 0) /* 266MHz */ +#define RIII_CM_CLKSEL_MPU_VAL RIII_CLKSEL_MPU +#define RIII_CLKSEL_DSP (3 << 0) /* c5x - 177.3MHz */ +#define RIII_CLKSEL_DSP_IF (2 << 5) /* c5x - 88.67MHz */ +#define RIII_SYNC_DSP (1 << 7) /* Enable sync */ +#define RIII_CLKSEL_IVA (6 << 8) /* iva1 - 88.67MHz */ +#define RIII_SYNC_IVA (1 << 13) /* Enable sync */ +#define RIII_CM_CLKSEL_DSP_VAL (RIII_SYNC_IVA | RIII_CLKSEL_IVA | \ + RIII_SYNC_DSP | RIII_CLKSEL_DSP_IF | \ + RIII_CLKSEL_DSP) +#define RIII_CLKSEL_GFX (2 << 0) /* 66.5MHz */ +#define RIII_CM_CLKSEL_GFX_VAL RIII_CLKSEL_GFX + +/* 2420-PRCM II 600MHz core */ +#define RII_CLKSEL_L3 (6 << 0) /* 100MHz */ +#define RII_CLKSEL_L4 (2 << 5) /* 50MHz */ +#define RII_CLKSEL_USB (2 << 25) /* 50MHz */ +#define RII_CM_CLKSEL1_CORE_VAL (RII_CLKSEL_USB | RXX_CLKSEL_SSI | \ + RXX_CLKSEL_VLYNQ | RX_CLKSEL_DSS2 | \ + RX_CLKSEL_DSS1 | RII_CLKSEL_L4 | \ + RII_CLKSEL_L3) +#define RII_CLKSEL_MPU (2 << 0) /* 300MHz */ +#define RII_CM_CLKSEL_MPU_VAL RII_CLKSEL_MPU +#define RII_CLKSEL_DSP (3 << 0) /* c5x - 200MHz */ +#define RII_CLKSEL_DSP_IF (2 << 5) /* c5x - 100MHz */ +#define RII_SYNC_DSP (0 << 7) /* Bypass sync */ +#define RII_CLKSEL_IVA (3 << 8) /* iva1 - 200MHz */ +#define RII_SYNC_IVA (0 << 13) /* Bypass sync */ +#define RII_CM_CLKSEL_DSP_VAL (RII_SYNC_IVA | RII_CLKSEL_IVA | \ + RII_SYNC_DSP | RII_CLKSEL_DSP_IF | \ + RII_CLKSEL_DSP) +#define RII_CLKSEL_GFX (2 << 0) /* 50MHz */ +#define RII_CM_CLKSEL_GFX_VAL RII_CLKSEL_GFX + +/* 2420-PRCM I 660MHz core */ +#define RI_CLKSEL_L3 (4 << 0) /* 165MHz */ +#define RI_CLKSEL_L4 (2 << 5) /* 82.5MHz */ +#define RI_CLKSEL_USB (4 << 25) /* 41.25MHz */ +#define RI_CM_CLKSEL1_CORE_VAL (RI_CLKSEL_USB | \ + RXX_CLKSEL_SSI | RXX_CLKSEL_VLYNQ | \ + RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \ + RI_CLKSEL_L4 | RI_CLKSEL_L3) +#define RI_CLKSEL_MPU (2 << 0) /* 330MHz */ +#define RI_CM_CLKSEL_MPU_VAL RI_CLKSEL_MPU +#define RI_CLKSEL_DSP (3 << 0) /* c5x - 220MHz */ +#define RI_CLKSEL_DSP_IF (2 << 5) /* c5x - 110MHz */ +#define RI_SYNC_DSP (1 << 7) /* Activate sync */ +#define RI_CLKSEL_IVA (4 << 8) /* iva1 - 165MHz */ +#define RI_SYNC_IVA (0 << 13) /* Bypass sync */ +#define RI_CM_CLKSEL_DSP_VAL (RI_SYNC_IVA | RI_CLKSEL_IVA | \ + RI_SYNC_DSP | RI_CLKSEL_DSP_IF | \ + RI_CLKSEL_DSP) +#define RI_CLKSEL_GFX (1 << 0) /* 165MHz */ +#define RI_CM_CLKSEL_GFX_VAL RI_CLKSEL_GFX + +/* 2420-PRCM VII (boot) */ +#define RVII_CLKSEL_L3 (1 << 0) +#define RVII_CLKSEL_L4 (1 << 5) +#define RVII_CLKSEL_DSS1 (1 << 8) +#define RVII_CLKSEL_DSS2 (0 << 13) +#define RVII_CLKSEL_VLYNQ (1 << 15) +#define RVII_CLKSEL_SSI (1 << 20) +#define RVII_CLKSEL_USB (1 << 25) + +#define RVII_CM_CLKSEL1_CORE_VAL (RVII_CLKSEL_USB | RVII_CLKSEL_SSI | \ + RVII_CLKSEL_VLYNQ | \ + RVII_CLKSEL_DSS2 | RVII_CLKSEL_DSS1 | \ + RVII_CLKSEL_L4 | RVII_CLKSEL_L3) + +#define RVII_CLKSEL_MPU (1 << 0) /* all divide by 1 */ +#define RVII_CM_CLKSEL_MPU_VAL RVII_CLKSEL_MPU + +#define RVII_CLKSEL_DSP (1 << 0) +#define RVII_CLKSEL_DSP_IF (1 << 5) +#define RVII_SYNC_DSP (0 << 7) +#define RVII_CLKSEL_IVA (1 << 8) +#define RVII_SYNC_IVA (0 << 13) +#define RVII_CM_CLKSEL_DSP_VAL (RVII_SYNC_IVA | RVII_CLKSEL_IVA | \ + RVII_SYNC_DSP | RVII_CLKSEL_DSP_IF | \ + RVII_CLKSEL_DSP) + +#define RVII_CLKSEL_GFX (1 << 0) +#define RVII_CM_CLKSEL_GFX_VAL RVII_CLKSEL_GFX + +/*------------------------------------------------------------------------- + * 2430 Target modes: Along with each configuration the CPU has several + * modes which goes along with them. Modes mainly are the addition of + * describe DPLL combinations to go along with a ratio. + *-------------------------------------------------------------------------*/ + +/* Hardware governed */ +#define MX_48M_SRC (0 << 3) +#define MX_54M_SRC (0 << 5) +#define MX_APLLS_CLIKIN_12 (3 << 23) +#define MX_APLLS_CLIKIN_13 (2 << 23) +#define MX_APLLS_CLIKIN_19_2 (0 << 23) + +/* + * 2430 - standalone, 2*ref*M/(n+1), M/N is for exactness not relock speed + * #5a (ratio1) baseport-target, target DPLL = 266*2 = 532MHz + */ +#define M5A_DPLL_MULT_12 (133 << 12) +#define M5A_DPLL_DIV_12 (5 << 8) +#define M5A_CM_CLKSEL1_PLL_12_VAL (MX_48M_SRC | MX_54M_SRC | \ + M5A_DPLL_DIV_12 | M5A_DPLL_MULT_12 | \ + MX_APLLS_CLIKIN_12) +#define M5A_DPLL_MULT_13 (61 << 12) +#define M5A_DPLL_DIV_13 (2 << 8) +#define M5A_CM_CLKSEL1_PLL_13_VAL (MX_48M_SRC | MX_54M_SRC | \ + M5A_DPLL_DIV_13 | M5A_DPLL_MULT_13 | \ + MX_APLLS_CLIKIN_13) +#define M5A_DPLL_MULT_19 (55 << 12) +#define M5A_DPLL_DIV_19 (3 << 8) +#define M5A_CM_CLKSEL1_PLL_19_VAL (MX_48M_SRC | MX_54M_SRC | \ + M5A_DPLL_DIV_19 | M5A_DPLL_MULT_19 | \ + MX_APLLS_CLIKIN_19_2) +/* #5b (ratio1) target DPLL = 200*2 = 400MHz */ +#define M5B_DPLL_MULT_12 (50 << 12) +#define M5B_DPLL_DIV_12 (2 << 8) +#define M5B_CM_CLKSEL1_PLL_12_VAL (MX_48M_SRC | MX_54M_SRC | \ + M5B_DPLL_DIV_12 | M5B_DPLL_MULT_12 | \ + MX_APLLS_CLIKIN_12) +#define M5B_DPLL_MULT_13 (200 << 12) +#define M5B_DPLL_DIV_13 (12 << 8) + +#define M5B_CM_CLKSEL1_PLL_13_VAL (MX_48M_SRC | MX_54M_SRC | \ + M5B_DPLL_DIV_13 | M5B_DPLL_MULT_13 | \ + MX_APLLS_CLIKIN_13) +#define M5B_DPLL_MULT_19 (125 << 12) +#define M5B_DPLL_DIV_19 (31 << 8) +#define M5B_CM_CLKSEL1_PLL_19_VAL (MX_48M_SRC | MX_54M_SRC | \ + M5B_DPLL_DIV_19 | M5B_DPLL_MULT_19 | \ + MX_APLLS_CLIKIN_19_2) +/* + * #4 (ratio2), DPLL = 399*2 = 798MHz, L3=133MHz + */ +#define M4_DPLL_MULT_12 (133 << 12) +#define M4_DPLL_DIV_12 (3 << 8) +#define M4_CM_CLKSEL1_PLL_12_VAL (MX_48M_SRC | MX_54M_SRC | \ + M4_DPLL_DIV_12 | M4_DPLL_MULT_12 | \ + MX_APLLS_CLIKIN_12) + +#define M4_DPLL_MULT_13 (399 << 12) +#define M4_DPLL_DIV_13 (12 << 8) +#define M4_CM_CLKSEL1_PLL_13_VAL (MX_48M_SRC | MX_54M_SRC | \ + M4_DPLL_DIV_13 | M4_DPLL_MULT_13 | \ + MX_APLLS_CLIKIN_13) + +#define M4_DPLL_MULT_19 (145 << 12) +#define M4_DPLL_DIV_19 (6 << 8) +#define M4_CM_CLKSEL1_PLL_19_VAL (MX_48M_SRC | MX_54M_SRC | \ + M4_DPLL_DIV_19 | M4_DPLL_MULT_19 | \ + MX_APLLS_CLIKIN_19_2) + +/* + * #3 (ratio2) baseport-target, target DPLL = 330*2 = 660MHz + */ +#define M3_DPLL_MULT_12 (55 << 12) +#define M3_DPLL_DIV_12 (1 << 8) +#define M3_CM_CLKSEL1_PLL_12_VAL (MX_48M_SRC | MX_54M_SRC | \ + M3_DPLL_DIV_12 | M3_DPLL_MULT_12 | \ + MX_APLLS_CLIKIN_12) +#define M3_DPLL_MULT_13 (76 << 12) +#define M3_DPLL_DIV_13 (2 << 8) +#define M3_CM_CLKSEL1_PLL_13_VAL (MX_48M_SRC | MX_54M_SRC | \ + M3_DPLL_DIV_13 | M3_DPLL_MULT_13 | \ + MX_APLLS_CLIKIN_13) +#define M3_DPLL_MULT_19 (17 << 12) +#define M3_DPLL_DIV_19 (0 << 8) +#define M3_CM_CLKSEL1_PLL_19_VAL (MX_48M_SRC | MX_54M_SRC | \ + M3_DPLL_DIV_19 | M3_DPLL_MULT_19 | \ + MX_APLLS_CLIKIN_19_2) + +/* + * #2 (ratio1) DPLL = 330*2 = 660MHz, L3=165MHz + */ +#define M2_DPLL_MULT_12 (55 << 12) +#define M2_DPLL_DIV_12 (1 << 8) +#define M2_CM_CLKSEL1_PLL_12_VAL (MX_48M_SRC | MX_54M_SRC | \ + M2_DPLL_DIV_12 | M2_DPLL_MULT_12 | \ + MX_APLLS_CLIKIN_12) + +/* Speed changes - Used 658.7MHz instead of 660MHz for LP-Refresh M=76 N=2, + * relock time issue */ +/* Core frequency changed from 330/165 to 329/164 MHz*/ +#define M2_DPLL_MULT_13 (76 << 12) +#define M2_DPLL_DIV_13 (2 << 8) +#define M2_CM_CLKSEL1_PLL_13_VAL (MX_48M_SRC | MX_54M_SRC | \ + M2_DPLL_DIV_13 | M2_DPLL_MULT_13 | \ + MX_APLLS_CLIKIN_13) + +#define M2_DPLL_MULT_19 (17 << 12) +#define M2_DPLL_DIV_19 (0 << 8) +#define M2_CM_CLKSEL1_PLL_19_VAL (MX_48M_SRC | MX_54M_SRC | \ + M2_DPLL_DIV_19 | M2_DPLL_MULT_19 | \ + MX_APLLS_CLIKIN_19_2) + +/* boot (boot) */ +#define MB_DPLL_MULT (1 << 12) +#define MB_DPLL_DIV (0 << 8) +#define MB_CM_CLKSEL1_PLL_12_VAL (MX_48M_SRC | MX_54M_SRC | \ + MB_DPLL_DIV | MB_DPLL_MULT | \ + MX_APLLS_CLIKIN_12) + +#define MB_CM_CLKSEL1_PLL_13_VAL (MX_48M_SRC | MX_54M_SRC | \ + MB_DPLL_DIV | MB_DPLL_MULT | \ + MX_APLLS_CLIKIN_13) + +#define MB_CM_CLKSEL1_PLL_19_VAL (MX_48M_SRC | MX_54M_SRC | \ + MB_DPLL_DIV | MB_DPLL_MULT | \ + MX_APLLS_CLIKIN_19) + +/* + * 2430 - chassis (sedna) + * 165 (ratio1) same as above #2 + * 150 (ratio1) + * 133 (ratio2) same as above #4 + * 110 (ratio2) same as above #3 + * 104 (ratio2) + * boot (boot) + */ + +/* PRCM I target DPLL = 2*330MHz = 660MHz */ +#define MI_DPLL_MULT_12 (55 << 12) +#define MI_DPLL_DIV_12 (1 << 8) +#define MI_CM_CLKSEL1_PLL_12_VAL (MX_48M_SRC | MX_54M_SRC | \ + MI_DPLL_DIV_12 | MI_DPLL_MULT_12 | \ + MX_APLLS_CLIKIN_12) + +/* + * 2420 Equivalent - mode registers + * PRCM II , target DPLL = 2*300MHz = 600MHz + */ +#define MII_DPLL_MULT_12 (50 << 12) +#define MII_DPLL_DIV_12 (1 << 8) +#define MII_CM_CLKSEL1_PLL_12_VAL (MX_48M_SRC | MX_54M_SRC | \ + MII_DPLL_DIV_12 | MII_DPLL_MULT_12 | \ + MX_APLLS_CLIKIN_12) +#define MII_DPLL_MULT_13 (300 << 12) +#define MII_DPLL_DIV_13 (12 << 8) +#define MII_CM_CLKSEL1_PLL_13_VAL (MX_48M_SRC | MX_54M_SRC | \ + MII_DPLL_DIV_13 | MII_DPLL_MULT_13 | \ + MX_APLLS_CLIKIN_13) + +/* PRCM III target DPLL = 2*266 = 532MHz*/ +#define MIII_DPLL_MULT_12 (133 << 12) +#define MIII_DPLL_DIV_12 (5 << 8) +#define MIII_CM_CLKSEL1_PLL_12_VAL (MX_48M_SRC | MX_54M_SRC | \ + MIII_DPLL_DIV_12 | \ + MIII_DPLL_MULT_12 | MX_APLLS_CLIKIN_12) +#define MIII_DPLL_MULT_13 (266 << 12) +#define MIII_DPLL_DIV_13 (12 << 8) +#define MIII_CM_CLKSEL1_PLL_13_VAL (MX_48M_SRC | MX_54M_SRC | \ + MIII_DPLL_DIV_13 | \ + MIII_DPLL_MULT_13 | MX_APLLS_CLIKIN_13) + +/* PRCM VII (boot bypass) */ +#define MVII_CM_CLKSEL1_PLL_12_VAL MB_CM_CLKSEL1_PLL_12_VAL +#define MVII_CM_CLKSEL1_PLL_13_VAL MB_CM_CLKSEL1_PLL_13_VAL + +/* High and low operation value */ +#define MX_CLKSEL2_PLL_2x_VAL (2 << 0) +#define MX_CLKSEL2_PLL_1x_VAL (1 << 0) + +/* MPU speed defines */ +#define S12M 12000000 +#define S13M 13000000 +#define S19M 19200000 +#define S26M 26000000 +#define S100M 100000000 +#define S133M 133000000 +#define S150M 150000000 +#define S164M 164000000 +#define S165M 165000000 +#define S199M 199000000 +#define S200M 200000000 +#define S266M 266000000 +#define S300M 300000000 +#define S329M 329000000 +#define S330M 330000000 +#define S399M 399000000 +#define S400M 400000000 +#define S532M 532000000 +#define S600M 600000000 +#define S658M 658000000 +#define S660M 660000000 +#define S798M 798000000 + + +extern const struct prcm_config omap2420_rate_table[]; + +#ifdef CONFIG_SOC_OMAP2430 +extern const struct prcm_config omap2430_rate_table[]; +#else +#define omap2430_rate_table NULL +#endif +extern const struct prcm_config *rate_table; +extern const struct prcm_config *curr_prcm_set; + +#endif diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c new file mode 100644 index 00000000000..fc67add7644 --- /dev/null +++ b/arch/arm/mach-omap2/opp3xxx_data.c @@ -0,0 +1,171 @@ +/* + * OMAP3 OPP table definitions. + * + * Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/ + * Nishanth Menon + * Kevin Hilman + * Copyright (C) 2010-2011 Nokia Corporation. + * Eduardo Valentin + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include <linux/module.h> + +#include "soc.h" +#include "control.h" +#include "omap_opp_data.h" +#include "pm.h" + +/* 34xx */ + +/* VDD1 */ + +#define OMAP3430_VDD_MPU_OPP1_UV 975000 +#define OMAP3430_VDD_MPU_OPP2_UV 1075000 +#define OMAP3430_VDD_MPU_OPP3_UV 1200000 +#define OMAP3430_VDD_MPU_OPP4_UV 1270000 +#define OMAP3430_VDD_MPU_OPP5_UV 1350000 + +struct omap_volt_data omap34xx_vddmpu_volt_data[] = { + VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD1, 0xf4, 0x0c), + VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD1, 0xf4, 0x0c), + VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD1, 0xf9, 0x18), + VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP4_UV, OMAP343X_CONTROL_FUSE_OPP4_VDD1, 0xf9, 0x18), + VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP5_UV, OMAP343X_CONTROL_FUSE_OPP5_VDD1, 0xf9, 0x18), + VOLT_DATA_DEFINE(0, 0, 0, 0), +}; + +/* VDD2 */ + +#define OMAP3430_VDD_CORE_OPP1_UV 975000 +#define OMAP3430_VDD_CORE_OPP2_UV 1050000 +#define OMAP3430_VDD_CORE_OPP3_UV 1150000 + +struct omap_volt_data omap34xx_vddcore_volt_data[] = { + VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD2, 0xf4, 0x0c), + VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD2, 0xf4, 0x0c), + VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD2, 0xf9, 0x18), + VOLT_DATA_DEFINE(0, 0, 0, 0), +}; + +/* 36xx */ + +/* VDD1 */ + +#define OMAP3630_VDD_MPU_OPP50_UV 1012500 +#define OMAP3630_VDD_MPU_OPP100_UV 1200000 +#define OMAP3630_VDD_MPU_OPP120_UV 1325000 +#define OMAP3630_VDD_MPU_OPP1G_UV 1375000 + +struct omap_volt_data omap36xx_vddmpu_volt_data[] = { + VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD1, 0xf4, 0x0c), + VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD1, 0xf9, 0x16), + VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP120_UV, OMAP3630_CONTROL_FUSE_OPP120_VDD1, 0xfa, 0x23), + VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP1G_UV, OMAP3630_CONTROL_FUSE_OPP1G_VDD1, 0xfa, 0x27), + VOLT_DATA_DEFINE(0, 0, 0, 0), +}; + +/* VDD2 */ + +#define OMAP3630_VDD_CORE_OPP50_UV 1000000 +#define OMAP3630_VDD_CORE_OPP100_UV 1200000 + +struct omap_volt_data omap36xx_vddcore_volt_data[] = { + VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD2, 0xf4, 0x0c), + VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD2, 0xf9, 0x16), + VOLT_DATA_DEFINE(0, 0, 0, 0), +}; + +/* OPP data */ + +static struct omap_opp_def __initdata omap34xx_opp_def_list[] = { + /* MPU OPP1 */ + OPP_INITIALIZER("mpu", true, 125000000, OMAP3430_VDD_MPU_OPP1_UV), + /* MPU OPP2 */ + OPP_INITIALIZER("mpu", true, 250000000, OMAP3430_VDD_MPU_OPP2_UV), + /* MPU OPP3 */ + OPP_INITIALIZER("mpu", true, 500000000, OMAP3430_VDD_MPU_OPP3_UV), + /* MPU OPP4 */ + OPP_INITIALIZER("mpu", true, 550000000, OMAP3430_VDD_MPU_OPP4_UV), + /* MPU OPP5 */ + OPP_INITIALIZER("mpu", true, 600000000, OMAP3430_VDD_MPU_OPP5_UV), + + /* + * L3 OPP1 - 41.5 MHz is disabled because: The voltage for that OPP is + * almost the same than the one at 83MHz thus providing very little + * gain for the power point of view. In term of energy it will even + * increase the consumption due to the very negative performance + * impact that frequency will do to the MPU and the whole system in + * general. + */ + OPP_INITIALIZER("l3_main", false, 41500000, OMAP3430_VDD_CORE_OPP1_UV), + /* L3 OPP2 */ + OPP_INITIALIZER("l3_main", true, 83000000, OMAP3430_VDD_CORE_OPP2_UV), + /* L3 OPP3 */ + OPP_INITIALIZER("l3_main", true, 166000000, OMAP3430_VDD_CORE_OPP3_UV), + + /* DSP OPP1 */ + OPP_INITIALIZER("iva", true, 90000000, OMAP3430_VDD_MPU_OPP1_UV), + /* DSP OPP2 */ + OPP_INITIALIZER("iva", true, 180000000, OMAP3430_VDD_MPU_OPP2_UV), + /* DSP OPP3 */ + OPP_INITIALIZER("iva", true, 360000000, OMAP3430_VDD_MPU_OPP3_UV), + /* DSP OPP4 */ + OPP_INITIALIZER("iva", true, 400000000, OMAP3430_VDD_MPU_OPP4_UV), + /* DSP OPP5 */ + OPP_INITIALIZER("iva", true, 430000000, OMAP3430_VDD_MPU_OPP5_UV), +}; + +static struct omap_opp_def __initdata omap36xx_opp_def_list[] = { + /* MPU OPP1 - OPP50 */ + OPP_INITIALIZER("mpu", true, 300000000, OMAP3630_VDD_MPU_OPP50_UV), + /* MPU OPP2 - OPP100 */ + OPP_INITIALIZER("mpu", true, 600000000, OMAP3630_VDD_MPU_OPP100_UV), + /* MPU OPP3 - OPP-Turbo */ + OPP_INITIALIZER("mpu", false, 800000000, OMAP3630_VDD_MPU_OPP120_UV), + /* MPU OPP4 - OPP-SB */ + OPP_INITIALIZER("mpu", false, 1000000000, OMAP3630_VDD_MPU_OPP1G_UV), + + /* L3 OPP1 - OPP50 */ + OPP_INITIALIZER("l3_main", true, 100000000, OMAP3630_VDD_CORE_OPP50_UV), + /* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */ + OPP_INITIALIZER("l3_main", true, 200000000, OMAP3630_VDD_CORE_OPP100_UV), + + /* DSP OPP1 - OPP50 */ + OPP_INITIALIZER("iva", true, 260000000, OMAP3630_VDD_MPU_OPP50_UV), + /* DSP OPP2 - OPP100 */ + OPP_INITIALIZER("iva", true, 520000000, OMAP3630_VDD_MPU_OPP100_UV), + /* DSP OPP3 - OPP-Turbo */ + OPP_INITIALIZER("iva", false, 660000000, OMAP3630_VDD_MPU_OPP120_UV), + /* DSP OPP4 - OPP-SB */ + OPP_INITIALIZER("iva", false, 800000000, OMAP3630_VDD_MPU_OPP1G_UV), +}; + +/** + * omap3_opp_init() - initialize omap3 opp table + */ +int __init omap3_opp_init(void) +{ + int r = -ENODEV; + + if (!cpu_is_omap34xx()) + return r; + + if (cpu_is_omap3630()) + r = omap_init_opp_table(omap36xx_opp_def_list, + ARRAY_SIZE(omap36xx_opp_def_list)); + else + r = omap_init_opp_table(omap34xx_opp_def_list, + ARRAY_SIZE(omap34xx_opp_def_list)); + + return r; +} +omap_device_initcall(omap3_opp_init); diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c new file mode 100644 index 00000000000..1ef7a3e5ce4 --- /dev/null +++ b/arch/arm/mach-omap2/opp4xxx_data.c @@ -0,0 +1,180 @@ +/* + * OMAP4 OPP table definitions. + * + * Copyright (C) 2010-2012 Texas Instruments Incorporated - http://www.ti.com/ + * Nishanth Menon + * Kevin Hilman + * Thara Gopinath + * Copyright (C) 2010-2011 Nokia Corporation. + * Eduardo Valentin + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include <linux/module.h> + +#include "soc.h" +#include "control.h" +#include "omap_opp_data.h" +#include "pm.h" + +/* + * Structures containing OMAP4430 voltage supported and various + * voltage dependent data for each VDD. + */ + +#define OMAP4430_VDD_MPU_OPP50_UV 1025000 +#define OMAP4430_VDD_MPU_OPP100_UV 1200000 +#define OMAP4430_VDD_MPU_OPPTURBO_UV 1313000 +#define OMAP4430_VDD_MPU_OPPNITRO_UV 1375000 + +struct omap_volt_data omap443x_vdd_mpu_volt_data[] = { + VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c), + VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16), + VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23), + VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27), + VOLT_DATA_DEFINE(0, 0, 0, 0), +}; + +#define OMAP4430_VDD_IVA_OPP50_UV 1013000 +#define OMAP4430_VDD_IVA_OPP100_UV 1188000 +#define OMAP4430_VDD_IVA_OPPTURBO_UV 1300000 + +struct omap_volt_data omap443x_vdd_iva_volt_data[] = { + VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c), + VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16), + VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23), + VOLT_DATA_DEFINE(0, 0, 0, 0), +}; + +#define OMAP4430_VDD_CORE_OPP50_UV 1025000 +#define OMAP4430_VDD_CORE_OPP100_UV 1200000 + +struct omap_volt_data omap443x_vdd_core_volt_data[] = { + VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c), + VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16), + VOLT_DATA_DEFINE(0, 0, 0, 0), +}; + + +static struct omap_opp_def __initdata omap443x_opp_def_list[] = { + /* MPU OPP1 - OPP50 */ + OPP_INITIALIZER("mpu", true, 300000000, OMAP4430_VDD_MPU_OPP50_UV), + /* MPU OPP2 - OPP100 */ + OPP_INITIALIZER("mpu", true, 600000000, OMAP4430_VDD_MPU_OPP100_UV), + /* MPU OPP3 - OPP-Turbo */ + OPP_INITIALIZER("mpu", true, 800000000, OMAP4430_VDD_MPU_OPPTURBO_UV), + /* MPU OPP4 - OPP-SB */ + OPP_INITIALIZER("mpu", true, 1008000000, OMAP4430_VDD_MPU_OPPNITRO_UV), + /* L3 OPP1 - OPP50 */ + OPP_INITIALIZER("l3_main_1", true, 100000000, OMAP4430_VDD_CORE_OPP50_UV), + /* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */ + OPP_INITIALIZER("l3_main_1", true, 200000000, OMAP4430_VDD_CORE_OPP100_UV), + /* IVA OPP1 - OPP50 */ + OPP_INITIALIZER("iva", true, 133000000, OMAP4430_VDD_IVA_OPP50_UV), + /* IVA OPP2 - OPP100 */ + OPP_INITIALIZER("iva", true, 266100000, OMAP4430_VDD_IVA_OPP100_UV), + /* IVA OPP3 - OPP-Turbo */ + OPP_INITIALIZER("iva", false, 332000000, OMAP4430_VDD_IVA_OPPTURBO_UV), + /* TODO: add DSP, aess, fdif, gpu */ +}; + +#define OMAP4460_VDD_MPU_OPP50_UV 1025000 +#define OMAP4460_VDD_MPU_OPP100_UV 1200000 +#define OMAP4460_VDD_MPU_OPPTURBO_UV 1313000 +#define OMAP4460_VDD_MPU_OPPNITRO_UV 1375000 + +struct omap_volt_data omap446x_vdd_mpu_volt_data[] = { + VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c), + VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16), + VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23), + VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27), + VOLT_DATA_DEFINE(0, 0, 0, 0), +}; + +#define OMAP4460_VDD_IVA_OPP50_UV 1025000 +#define OMAP4460_VDD_IVA_OPP100_UV 1200000 +#define OMAP4460_VDD_IVA_OPPTURBO_UV 1313000 +#define OMAP4460_VDD_IVA_OPPNITRO_UV 1375000 + +struct omap_volt_data omap446x_vdd_iva_volt_data[] = { + VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c), + VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16), + VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23), + VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPNITRO, 0xfa, 0x23), + VOLT_DATA_DEFINE(0, 0, 0, 0), +}; + +#define OMAP4460_VDD_CORE_OPP50_UV 1025000 +#define OMAP4460_VDD_CORE_OPP100_UV 1200000 +#define OMAP4460_VDD_CORE_OPP100_OV_UV 1250000 + +struct omap_volt_data omap446x_vdd_core_volt_data[] = { + VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c), + VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16), + VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_OV_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100OV, 0xf9, 0x16), + VOLT_DATA_DEFINE(0, 0, 0, 0), +}; + +static struct omap_opp_def __initdata omap446x_opp_def_list[] = { + /* MPU OPP1 - OPP50 */ + OPP_INITIALIZER("mpu", true, 350000000, OMAP4460_VDD_MPU_OPP50_UV), + /* MPU OPP2 - OPP100 */ + OPP_INITIALIZER("mpu", true, 700000000, OMAP4460_VDD_MPU_OPP100_UV), + /* MPU OPP3 - OPP-Turbo */ + OPP_INITIALIZER("mpu", true, 920000000, OMAP4460_VDD_MPU_OPPTURBO_UV), + /* + * MPU OPP4 - OPP-Nitro + Disabled as the reference schematics + * recommends TPS623631 - confirm and enable the opp in board file + * XXX: May be we should enable these based on mpu capability and + * Exception board files disable it... + */ + OPP_INITIALIZER("mpu", false, 1200000000, OMAP4460_VDD_MPU_OPPNITRO_UV), + /* MPU OPP4 - OPP-Nitro SpeedBin */ + OPP_INITIALIZER("mpu", false, 1500000000, OMAP4460_VDD_MPU_OPPNITRO_UV), + /* L3 OPP1 - OPP50 */ + OPP_INITIALIZER("l3_main_1", true, 100000000, OMAP4460_VDD_CORE_OPP50_UV), + /* L3 OPP2 - OPP100 */ + OPP_INITIALIZER("l3_main_1", true, 200000000, OMAP4460_VDD_CORE_OPP100_UV), + /* IVA OPP1 - OPP50 */ + OPP_INITIALIZER("iva", true, 133000000, OMAP4460_VDD_IVA_OPP50_UV), + /* IVA OPP2 - OPP100 */ + OPP_INITIALIZER("iva", true, 266100000, OMAP4460_VDD_IVA_OPP100_UV), + /* + * IVA OPP3 - OPP-Turbo + Disabled as the reference schematics + * recommends Phoenix VCORE2 which can supply only 600mA - so the ones + * above this OPP frequency, even though OMAP is capable, should be + * enabled by board file which is sure of the chip power capability + */ + OPP_INITIALIZER("iva", false, 332000000, OMAP4460_VDD_IVA_OPPTURBO_UV), + /* IVA OPP4 - OPP-Nitro */ + OPP_INITIALIZER("iva", false, 430000000, OMAP4460_VDD_IVA_OPPNITRO_UV), + /* IVA OPP5 - OPP-Nitro SpeedBin*/ + OPP_INITIALIZER("iva", false, 500000000, OMAP4460_VDD_IVA_OPPNITRO_UV), + + /* TODO: add DSP, aess, fdif, gpu */ +}; + +/** + * omap4_opp_init() - initialize omap4 opp table + */ +int __init omap4_opp_init(void) +{ + int r = -ENODEV; + + if (cpu_is_omap443x()) + r = omap_init_opp_table(omap443x_opp_def_list, + ARRAY_SIZE(omap443x_opp_def_list)); + else if (cpu_is_omap446x()) + r = omap_init_opp_table(omap446x_opp_def_list, + ARRAY_SIZE(omap446x_opp_def_list)); + return r; +} +omap_device_initcall(omap4_opp_init); diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c new file mode 100644 index 00000000000..90c88d49848 --- /dev/null +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -0,0 +1,415 @@ +/* + * Legacy platform_data quirks + * + * Copyright (C) 2013 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/clk.h> +#include <linux/davinci_emac.h> +#include <linux/gpio.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/of_platform.h> +#include <linux/wl12xx.h> + +#include <linux/platform_data/pinctrl-single.h> +#include <linux/platform_data/iommu-omap.h> + +#include "am35xx.h" +#include "common.h" +#include "common-board-devices.h" +#include "dss-common.h" +#include "control.h" +#include "omap_device.h" +#include "omap-secure.h" +#include "soc.h" + +struct pdata_init { + const char *compatible; + void (*fn)(void); +}; + +struct of_dev_auxdata omap_auxdata_lookup[]; +static struct twl4030_gpio_platform_data twl_gpio_auxdata; + +#if IS_ENABLED(CONFIG_WL12XX) + +static struct wl12xx_platform_data wl12xx __initdata; + +static void __init __used legacy_init_wl12xx(unsigned ref_clock, + unsigned tcxo_clock, + int gpio) +{ + int res; + + wl12xx.board_ref_clock = ref_clock; + wl12xx.board_tcxo_clock = tcxo_clock; + wl12xx.irq = gpio_to_irq(gpio); + + res = wl12xx_set_platform_data(&wl12xx); + if (res) { + pr_err("error setting wl12xx data: %d\n", res); + return; + } +} +#else +static inline void legacy_init_wl12xx(unsigned ref_clock, + unsigned tcxo_clock, + int gpio) +{ +} +#endif + +#ifdef CONFIG_MACH_NOKIA_N8X0 +static void __init omap2420_n8x0_legacy_init(void) +{ + omap_auxdata_lookup[0].platform_data = n8x0_legacy_init(); +} +#else +#define omap2420_n8x0_legacy_init NULL +#endif + +#ifdef CONFIG_ARCH_OMAP3 +static void __init hsmmc2_internal_input_clk(void) +{ + u32 reg; + + reg = omap_ctrl_readl(OMAP343X_CONTROL_DEVCONF1); + reg |= OMAP2_MMCSDIO2ADPCLKISEL; + omap_ctrl_writel(reg, OMAP343X_CONTROL_DEVCONF1); +} + +static struct iommu_platform_data omap3_iommu_pdata = { + .reset_name = "mmu", + .assert_reset = omap_device_assert_hardreset, + .deassert_reset = omap_device_deassert_hardreset, +}; + +static int omap3_sbc_t3730_twl_callback(struct device *dev, + unsigned gpio, + unsigned ngpio) +{ + int res; + + res = gpio_request_one(gpio + 2, GPIOF_OUT_INIT_HIGH, + "wlan pwr"); + if (res) + return res; + + gpio_export(gpio, 0); + + return 0; +} + +static void __init omap3_sbc_t3x_usb_hub_init(int gpio, char *hub_name) +{ + int err = gpio_request_one(gpio, GPIOF_OUT_INIT_LOW, hub_name); + + if (err) { + pr_err("SBC-T3x: %s reset gpio request failed: %d\n", + hub_name, err); + return; + } + + gpio_export(gpio, 0); + + udelay(10); + gpio_set_value(gpio, 1); + msleep(1); +} + +static void __init omap3_sbc_t3730_twl_init(void) +{ + twl_gpio_auxdata.setup = omap3_sbc_t3730_twl_callback; +} + +static void __init omap3_sbc_t3730_legacy_init(void) +{ + omap3_sbc_t3x_usb_hub_init(167, "sb-t35 usb hub"); + legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 136); + omap_ads7846_init(1, 57, 0, NULL); +} + +static void __init omap3_sbc_t3530_legacy_init(void) +{ + omap3_sbc_t3x_usb_hub_init(167, "sb-t35 usb hub"); + omap_ads7846_init(1, 57, 0, NULL); +} + +static void __init omap3_igep0020_legacy_init(void) +{ +} + +static void __init omap3_evm_legacy_init(void) +{ + legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 149); +} + +static void __init omap3_zoom_legacy_init(void) +{ + legacy_init_wl12xx(WL12XX_REFCLOCK_26, 0, 162); +} + +static void am35xx_enable_emac_int(void) +{ + u32 v; + + v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); + v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR | + AM35XX_CPGMAC_C0_MISC_PULSE_CLR | AM35XX_CPGMAC_C0_RX_THRESH_CLR); + omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR); + omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */ +} + +static void am35xx_disable_emac_int(void) +{ + u32 v; + + v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); + v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR); + omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR); + omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */ +} + +static struct emac_platform_data am35xx_emac_pdata = { + .interrupt_enable = am35xx_enable_emac_int, + .interrupt_disable = am35xx_disable_emac_int, +}; + +static void __init am35xx_emac_reset(void) +{ + u32 v; + + v = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); + v &= ~AM35XX_CPGMACSS_SW_RST; + omap_ctrl_writel(v, AM35XX_CONTROL_IP_SW_RESET); + omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); /* OCP barrier */ +} + +static struct gpio cm_t3517_wlan_gpios[] __initdata = { + { 56, GPIOF_OUT_INIT_HIGH, "wlan pwr" }, + { 4, GPIOF_OUT_INIT_HIGH, "xcvr noe" }, +}; + +static void __init omap3_sbc_t3517_wifi_init(void) +{ + int err = gpio_request_array(cm_t3517_wlan_gpios, + ARRAY_SIZE(cm_t3517_wlan_gpios)); + if (err) { + pr_err("SBC-T3517: wl12xx gpios request failed: %d\n", err); + return; + } + + gpio_export(cm_t3517_wlan_gpios[0].gpio, 0); + gpio_export(cm_t3517_wlan_gpios[1].gpio, 0); + + msleep(100); + gpio_set_value(cm_t3517_wlan_gpios[1].gpio, 0); +} + +static void __init omap3_sbc_t3517_legacy_init(void) +{ + omap3_sbc_t3x_usb_hub_init(152, "cm-t3517 usb hub"); + omap3_sbc_t3x_usb_hub_init(98, "sb-t35 usb hub"); + am35xx_emac_reset(); + hsmmc2_internal_input_clk(); + omap3_sbc_t3517_wifi_init(); + legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 145); + omap_ads7846_init(1, 57, 0, NULL); +} + +static void __init am3517_evm_legacy_init(void) +{ + am35xx_emac_reset(); +} + +static struct platform_device omap3_rom_rng_device = { + .name = "omap3-rom-rng", + .id = -1, + .dev = { + .platform_data = rx51_secure_rng_call, + }, +}; + +static void __init nokia_n900_legacy_init(void) +{ + hsmmc2_internal_input_clk(); + + if (omap_type() == OMAP2_DEVICE_TYPE_SEC) { + if (IS_ENABLED(CONFIG_ARM_ERRATA_430973)) { + pr_info("RX-51: Enabling ARM errata 430973 workaround\n"); + /* set IBE to 1 */ + rx51_secure_update_aux_cr(BIT(6), 0); + } else { + pr_warning("RX-51: Not enabling ARM errata 430973 workaround\n"); + pr_warning("Thumb binaries may crash randomly without this workaround\n"); + } + + pr_info("RX-51: Registring OMAP3 HWRNG device\n"); + platform_device_register(&omap3_rom_rng_device); + + } +} +#endif /* CONFIG_ARCH_OMAP3 */ + +#ifdef CONFIG_ARCH_OMAP4 +static void __init omap4_sdp_legacy_init(void) +{ + legacy_init_wl12xx(WL12XX_REFCLOCK_26, + WL12XX_TCXOCLOCK_26, 53); +} + +static void __init omap4_panda_legacy_init(void) +{ + legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 53); +} + +static void __init var_som_om44_legacy_init(void) +{ + legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 41); +} +#endif + +#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) +static struct iommu_platform_data omap4_iommu_pdata = { + .reset_name = "mmu_cache", + .assert_reset = omap_device_assert_hardreset, + .deassert_reset = omap_device_deassert_hardreset, +}; +#endif + +#ifdef CONFIG_SOC_AM33XX +static void __init am335x_evmsk_legacy_init(void) +{ + legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 31); +} +#endif + +#ifdef CONFIG_SOC_OMAP5 +static void __init omap5_uevm_legacy_init(void) +{ +} +#endif + +static struct pcs_pdata pcs_pdata; + +void omap_pcs_legacy_init(int irq, void (*rearm)(void)) +{ + pcs_pdata.irq = irq; + pcs_pdata.rearm = rearm; +} + +/* + * GPIOs for TWL are initialized by the I2C bus and need custom + * handing until DSS has device tree bindings. + */ +void omap_auxdata_legacy_init(struct device *dev) +{ + if (dev->platform_data) + return; + + if (strcmp("twl4030-gpio", dev_name(dev))) + return; + + dev->platform_data = &twl_gpio_auxdata; +} + +/* + * Few boards still need auxdata populated before we populate + * the dev entries in of_platform_populate(). + */ +static struct pdata_init auxdata_quirks[] __initdata = { +#ifdef CONFIG_SOC_OMAP2420 + { "nokia,n800", omap2420_n8x0_legacy_init, }, + { "nokia,n810", omap2420_n8x0_legacy_init, }, + { "nokia,n810-wimax", omap2420_n8x0_legacy_init, }, +#endif +#ifdef CONFIG_ARCH_OMAP3 + { "compulab,omap3-sbc-t3730", omap3_sbc_t3730_twl_init, }, +#endif + { /* sentinel */ }, +}; + +struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { +#ifdef CONFIG_MACH_NOKIA_N8X0 + OF_DEV_AUXDATA("ti,omap2420-mmc", 0x4809c000, "mmci-omap.0", NULL), +#endif +#ifdef CONFIG_ARCH_OMAP3 + OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002030, "48002030.pinmux", &pcs_pdata), + OF_DEV_AUXDATA("ti,omap3-padconf", 0x480025a0, "480025a0.pinmux", &pcs_pdata), + OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002a00, "48002a00.pinmux", &pcs_pdata), + OF_DEV_AUXDATA("ti,omap2-iommu", 0x5d000000, "5d000000.mmu", + &omap3_iommu_pdata), + /* Only on am3517 */ + OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL), + OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0", + &am35xx_emac_pdata), +#endif +#ifdef CONFIG_ARCH_OMAP4 + OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a100040, "4a100040.pinmux", &pcs_pdata), + OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a31e040, "4a31e040.pinmux", &pcs_pdata), +#endif +#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) + OF_DEV_AUXDATA("ti,omap4-iommu", 0x4a066000, "4a066000.mmu", + &omap4_iommu_pdata), + OF_DEV_AUXDATA("ti,omap4-iommu", 0x55082000, "55082000.mmu", + &omap4_iommu_pdata), +#endif + { /* sentinel */ }, +}; + +/* + * Few boards still need to initialize some legacy devices with + * platform data until the drivers support device tree. + */ +static struct pdata_init pdata_quirks[] __initdata = { +#ifdef CONFIG_ARCH_OMAP3 + { "compulab,omap3-sbc-t3517", omap3_sbc_t3517_legacy_init, }, + { "compulab,omap3-sbc-t3530", omap3_sbc_t3530_legacy_init, }, + { "compulab,omap3-sbc-t3730", omap3_sbc_t3730_legacy_init, }, + { "nokia,omap3-n900", nokia_n900_legacy_init, }, + { "nokia,omap3-n9", hsmmc2_internal_input_clk, }, + { "nokia,omap3-n950", hsmmc2_internal_input_clk, }, + { "isee,omap3-igep0020", omap3_igep0020_legacy_init, }, + { "ti,omap3-evm-37xx", omap3_evm_legacy_init, }, + { "ti,omap3-zoom3", omap3_zoom_legacy_init, }, + { "ti,am3517-evm", am3517_evm_legacy_init, }, +#endif +#ifdef CONFIG_ARCH_OMAP4 + { "ti,omap4-sdp", omap4_sdp_legacy_init, }, + { "ti,omap4-panda", omap4_panda_legacy_init, }, + { "variscite,var-dvk-om44", var_som_om44_legacy_init, }, + { "variscite,var-stk-om44", var_som_om44_legacy_init, }, +#endif +#ifdef CONFIG_SOC_AM33XX + { "ti,am335x-evmsk", am335x_evmsk_legacy_init, }, +#endif +#ifdef CONFIG_SOC_OMAP5 + { "ti,omap5-uevm", omap5_uevm_legacy_init, }, +#endif + { /* sentinel */ }, +}; + +static void pdata_quirks_check(struct pdata_init *quirks) +{ + while (quirks->compatible) { + if (of_machine_is_compatible(quirks->compatible)) { + if (quirks->fn) + quirks->fn(); + break; + } + quirks++; + } +} + +void __init pdata_quirks_init(struct of_device_id *omap_dt_match_table) +{ + omap_sdrc_init(NULL, NULL); + pdata_quirks_check(auxdata_quirks); + of_platform_populate(NULL, omap_dt_match_table, + omap_auxdata_lookup, NULL); + pdata_quirks_check(pdata_quirks); +} diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c new file mode 100644 index 00000000000..0b339861d75 --- /dev/null +++ b/arch/arm/mach-omap2/pm-debug.c @@ -0,0 +1,282 @@ +/* + * OMAP Power Management debug routines + * + * Copyright (C) 2005 Texas Instruments, Inc. + * Copyright (C) 2006-2008 Nokia Corporation + * + * Written by: + * Richard Woodruff <r-woodruff2@ti.com> + * Tony Lindgren + * Juha Yrjola + * Amit Kucheria <amit.kucheria@nokia.com> + * Igor Stoppa <igor.stoppa@nokia.com> + * Jouni Hogander + * + * Based on pm.c for omap2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/slab.h> + +#include "clock.h" +#include "powerdomain.h" +#include "clockdomain.h" +#include "omap-pm.h" + +#include "soc.h" +#include "cm2xxx_3xxx.h" +#include "prm2xxx_3xxx.h" +#include "pm.h" + +u32 enable_off_mode; + +#ifdef CONFIG_DEBUG_FS +#include <linux/debugfs.h> +#include <linux/seq_file.h> + +static int pm_dbg_init_done; + +static int pm_dbg_init(void); + +enum { + DEBUG_FILE_COUNTERS = 0, + DEBUG_FILE_TIMERS, +}; + +static const char pwrdm_state_names[][PWRDM_MAX_PWRSTS] = { + "OFF", + "RET", + "INA", + "ON" +}; + +void pm_dbg_update_time(struct powerdomain *pwrdm, int prev) +{ + s64 t; + + if (!pm_dbg_init_done) + return ; + + /* Update timer for previous state */ + t = sched_clock(); + + pwrdm->state_timer[prev] += t - pwrdm->timer; + + pwrdm->timer = t; +} + +static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user) +{ + struct seq_file *s = (struct seq_file *)user; + + if (strcmp(clkdm->name, "emu_clkdm") == 0 || + strcmp(clkdm->name, "wkup_clkdm") == 0 || + strncmp(clkdm->name, "dpll", 4) == 0) + return 0; + + seq_printf(s, "%s->%s (%d)\n", clkdm->name, clkdm->pwrdm.ptr->name, + clkdm->usecount); + + return 0; +} + +static int pwrdm_dbg_show_counter(struct powerdomain *pwrdm, void *user) +{ + struct seq_file *s = (struct seq_file *)user; + int i; + + if (strcmp(pwrdm->name, "emu_pwrdm") == 0 || + strcmp(pwrdm->name, "wkup_pwrdm") == 0 || + strncmp(pwrdm->name, "dpll", 4) == 0) + return 0; + + if (pwrdm->state != pwrdm_read_pwrst(pwrdm)) + printk(KERN_ERR "pwrdm state mismatch(%s) %d != %d\n", + pwrdm->name, pwrdm->state, pwrdm_read_pwrst(pwrdm)); + + seq_printf(s, "%s (%s)", pwrdm->name, + pwrdm_state_names[pwrdm->state]); + for (i = 0; i < PWRDM_MAX_PWRSTS; i++) + seq_printf(s, ",%s:%d", pwrdm_state_names[i], + pwrdm->state_counter[i]); + + seq_printf(s, ",RET-LOGIC-OFF:%d", pwrdm->ret_logic_off_counter); + for (i = 0; i < pwrdm->banks; i++) + seq_printf(s, ",RET-MEMBANK%d-OFF:%d", i + 1, + pwrdm->ret_mem_off_counter[i]); + + seq_printf(s, "\n"); + + return 0; +} + +static int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *user) +{ + struct seq_file *s = (struct seq_file *)user; + int i; + + if (strcmp(pwrdm->name, "emu_pwrdm") == 0 || + strcmp(pwrdm->name, "wkup_pwrdm") == 0 || + strncmp(pwrdm->name, "dpll", 4) == 0) + return 0; + + pwrdm_state_switch(pwrdm); + + seq_printf(s, "%s (%s)", pwrdm->name, + pwrdm_state_names[pwrdm->state]); + + for (i = 0; i < 4; i++) + seq_printf(s, ",%s:%lld", pwrdm_state_names[i], + pwrdm->state_timer[i]); + + seq_printf(s, "\n"); + return 0; +} + +static int pm_dbg_show_counters(struct seq_file *s, void *unused) +{ + pwrdm_for_each(pwrdm_dbg_show_counter, s); + clkdm_for_each(clkdm_dbg_show_counter, s); + + return 0; +} + +static int pm_dbg_show_timers(struct seq_file *s, void *unused) +{ + pwrdm_for_each(pwrdm_dbg_show_timer, s); + return 0; +} + +static int pm_dbg_open(struct inode *inode, struct file *file) +{ + switch ((int)inode->i_private) { + case DEBUG_FILE_COUNTERS: + return single_open(file, pm_dbg_show_counters, + &inode->i_private); + case DEBUG_FILE_TIMERS: + default: + return single_open(file, pm_dbg_show_timers, + &inode->i_private); + } +} + +static const struct file_operations debug_fops = { + .open = pm_dbg_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int pwrdm_suspend_get(void *data, u64 *val) +{ + int ret = -EINVAL; + + if (cpu_is_omap34xx()) + ret = omap3_pm_get_suspend_state((struct powerdomain *)data); + *val = ret; + + if (ret >= 0) + return 0; + return *val; +} + +static int pwrdm_suspend_set(void *data, u64 val) +{ + if (cpu_is_omap34xx()) + return omap3_pm_set_suspend_state( + (struct powerdomain *)data, (int)val); + return -EINVAL; +} + +DEFINE_SIMPLE_ATTRIBUTE(pwrdm_suspend_fops, pwrdm_suspend_get, + pwrdm_suspend_set, "%llu\n"); + +static int __init pwrdms_setup(struct powerdomain *pwrdm, void *dir) +{ + int i; + s64 t; + struct dentry *d; + + t = sched_clock(); + + for (i = 0; i < 4; i++) + pwrdm->state_timer[i] = 0; + + pwrdm->timer = t; + + if (strncmp(pwrdm->name, "dpll", 4) == 0) + return 0; + + d = debugfs_create_dir(pwrdm->name, (struct dentry *)dir); + if (d) + (void) debugfs_create_file("suspend", S_IRUGO|S_IWUSR, d, + (void *)pwrdm, &pwrdm_suspend_fops); + + return 0; +} + +static int option_get(void *data, u64 *val) +{ + u32 *option = data; + + *val = *option; + + return 0; +} + +static int option_set(void *data, u64 val) +{ + u32 *option = data; + + *option = val; + + if (option == &enable_off_mode) { + if (val) + omap_pm_enable_off_mode(); + else + omap_pm_disable_off_mode(); + if (cpu_is_omap34xx()) + omap3_pm_off_mode_enable(val); + } + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n"); + +static int __init pm_dbg_init(void) +{ + struct dentry *d; + + if (pm_dbg_init_done) + return 0; + + d = debugfs_create_dir("pm_debug", NULL); + if (!d) + return -EINVAL; + + (void) debugfs_create_file("count", S_IRUGO, + d, (void *)DEBUG_FILE_COUNTERS, &debug_fops); + (void) debugfs_create_file("time", S_IRUGO, + d, (void *)DEBUG_FILE_TIMERS, &debug_fops); + + pwrdm_for_each(pwrdms_setup, (void *)d); + + (void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUSR, d, + &enable_off_mode, &pm_dbg_option_fops); + pm_dbg_init_done = 1; + + return 0; +} +omap_arch_initcall(pm_dbg_init); + +#endif diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 55361c16c9d..828aee9ea6a 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -1,88 +1,215 @@ /* - * linux/arch/arm/mach-omap2/pm.c + * pm.c - Common OMAP2+ power management-related code * - * OMAP2 Power Management Routines - * - * Copyright (C) 2006 Nokia Corporation - * Tony Lindgren <tony@atomide.com> - * - * Copyright (C) 2005 Texas Instruments, Inc. - * Richard Woodruff <r-woodruff2@ti.com> - * - * Based on pm.c for omap1 + * Copyright (C) 2010 Texas Instruments, Inc. + * Copyright (C) 2010 Nokia Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#include <linux/suspend.h> -#include <linux/sched.h> -#include <linux/proc_fs.h> -#include <linux/interrupt.h> -#include <linux/sysfs.h> -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/clk.h> +#include <linux/kernel.h> +#include <linux/init.h> #include <linux/io.h> +#include <linux/err.h> +#include <linux/pm_opp.h> +#include <linux/export.h> +#include <linux/suspend.h> +#include <linux/cpu.h> -#include <asm/irq.h> -#include <asm/atomic.h> -#include <asm/mach/time.h> -#include <asm/mach/irq.h> +#include <asm/system_misc.h> -#include <mach/irqs.h> -#include <mach/clock.h> -#include <mach/sram.h> -#include <mach/pm.h> +#include "omap-pm.h" +#include "omap_device.h" +#include "common.h" -static struct clk *vclk; -static void (*omap2_sram_idle)(void); -static void (*omap2_sram_suspend)(int dllctrl, int cpu_rev); -static void (*saved_idle)(void); +#include "soc.h" +#include "prcm-common.h" +#include "voltage.h" +#include "powerdomain.h" +#include "clockdomain.h" +#include "pm.h" +#include "twl-common.h" -extern void __init pmdomain_init(void); -extern void pmdomain_set_autoidle(void); +#ifdef CONFIG_SUSPEND +/* + * omap_pm_suspend: points to a function that does the SoC-specific + * suspend work + */ +static int (*omap_pm_suspend)(void); +#endif -static unsigned int omap24xx_sleep_save[OMAP24XX_SLEEP_SAVE_SIZE]; +#ifdef CONFIG_PM +/** + * struct omap2_oscillator - Describe the board main oscillator latencies + * @startup_time: oscillator startup latency + * @shutdown_time: oscillator shutdown latency + */ +struct omap2_oscillator { + u32 startup_time; + u32 shutdown_time; +}; + +static struct omap2_oscillator oscillator = { + .startup_time = ULONG_MAX, + .shutdown_time = ULONG_MAX, +}; -void omap2_pm_idle(void) +void omap_pm_setup_oscillator(u32 tstart, u32 tshut) { - local_irq_disable(); - local_fiq_disable(); - if (need_resched()) { - local_fiq_enable(); - local_irq_enable(); + oscillator.startup_time = tstart; + oscillator.shutdown_time = tshut; +} + +void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) +{ + if (!tstart || !tshut) return; - } - omap2_sram_idle(); - local_fiq_enable(); - local_irq_enable(); + *tstart = oscillator.startup_time; + *tshut = oscillator.shutdown_time; } +#endif -static int omap2_pm_prepare(void) +static int __init _init_omap_device(char *name) { - /* We cannot sleep in idle until we have resumed */ - saved_idle = pm_idle; - pm_idle = NULL; + struct omap_hwmod *oh; + struct platform_device *pdev; + + oh = omap_hwmod_lookup(name); + if (WARN(!oh, "%s: could not find omap_hwmod for %s\n", + __func__, name)) + return -ENODEV; + + pdev = omap_device_build(oh->name, 0, oh, NULL, 0); + if (WARN(IS_ERR(pdev), "%s: could not build omap_device for %s\n", + __func__, name)) + return -ENODEV; + return 0; } -static int omap2_pm_suspend(void) +/* + * Build omap_devices for processors and bus. + */ +static void __init omap2_init_processor_devices(void) +{ + _init_omap_device("mpu"); + if (omap3_has_iva()) + _init_omap_device("iva"); + + if (cpu_is_omap44xx()) { + _init_omap_device("l3_main_1"); + _init_omap_device("dsp"); + _init_omap_device("iva"); + } else { + _init_omap_device("l3_main"); + } +} + +int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused) { + /* XXX The usecount test is racy */ + if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) && + !(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING)) + clkdm_allow_idle(clkdm); + else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && + clkdm->usecount == 0) + clkdm_sleep(clkdm); return 0; } -static int omap2_pm_enter(suspend_state_t state) +/* + * This API is to be called during init to set the various voltage + * domains to the voltage as per the opp table. Typically we boot up + * at the nominal voltage. So this function finds out the rate of + * the clock associated with the voltage domain, finds out the correct + * opp entry and sets the voltage domain to the voltage specified + * in the opp entry + */ +static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, + const char *oh_name) +{ + struct voltagedomain *voltdm; + struct clk *clk; + struct dev_pm_opp *opp; + unsigned long freq, bootup_volt; + struct device *dev; + + if (!vdd_name || !clk_name || !oh_name) { + pr_err("%s: invalid parameters\n", __func__); + goto exit; + } + + if (!strncmp(oh_name, "mpu", 3)) + /* + * All current OMAPs share voltage rail and clock + * source, so CPU0 is used to represent the MPU-SS. + */ + dev = get_cpu_device(0); + else + dev = omap_device_get_by_hwmod_name(oh_name); + + if (IS_ERR(dev)) { + pr_err("%s: Unable to get dev pointer for hwmod %s\n", + __func__, oh_name); + goto exit; + } + + voltdm = voltdm_lookup(vdd_name); + if (!voltdm) { + pr_err("%s: unable to get vdd pointer for vdd_%s\n", + __func__, vdd_name); + goto exit; + } + + clk = clk_get(NULL, clk_name); + if (IS_ERR(clk)) { + pr_err("%s: unable to get clk %s\n", __func__, clk_name); + goto exit; + } + + freq = clk_get_rate(clk); + clk_put(clk); + + rcu_read_lock(); + opp = dev_pm_opp_find_freq_ceil(dev, &freq); + if (IS_ERR(opp)) { + rcu_read_unlock(); + pr_err("%s: unable to find boot up OPP for vdd_%s\n", + __func__, vdd_name); + goto exit; + } + + bootup_volt = dev_pm_opp_get_voltage(opp); + rcu_read_unlock(); + if (!bootup_volt) { + pr_err("%s: unable to find voltage corresponding to the bootup OPP for vdd_%s\n", + __func__, vdd_name); + goto exit; + } + + voltdm_scale(voltdm, bootup_volt); + return 0; + +exit: + pr_err("%s: unable to set vdd_%s\n", __func__, vdd_name); + return -EINVAL; +} + +#ifdef CONFIG_SUSPEND +static int omap_pm_enter(suspend_state_t suspend_state) { int ret = 0; - switch (state) - { + if (!omap_pm_suspend) + return -ENOENT; /* XXX doublecheck */ + + switch (suspend_state) { case PM_SUSPEND_STANDBY: case PM_SUSPEND_MEM: - ret = omap2_pm_suspend(); + ret = omap_pm_suspend(); break; default: ret = -EINVAL; @@ -91,21 +218,104 @@ static int omap2_pm_enter(suspend_state_t state) return ret; } -static void omap2_pm_finish(void) +static int omap_pm_begin(suspend_state_t state) { - pm_idle = saved_idle; + cpu_idle_poll_ctrl(true); + if (cpu_is_omap34xx()) + omap_prcm_irq_prepare(); + return 0; } -static struct platform_suspend_ops omap_pm_ops = { - .prepare = omap2_pm_prepare, - .enter = omap2_pm_enter, - .finish = omap2_pm_finish, +static void omap_pm_end(void) +{ + cpu_idle_poll_ctrl(false); +} + +static void omap_pm_finish(void) +{ + if (cpu_is_omap34xx()) + omap_prcm_irq_complete(); +} + +static const struct platform_suspend_ops omap_pm_ops = { + .begin = omap_pm_begin, + .end = omap_pm_end, + .enter = omap_pm_enter, + .finish = omap_pm_finish, .valid = suspend_valid_only_mem, }; -int __init omap2_pm_init(void) +/** + * omap_common_suspend_init - Set common suspend routines for OMAP SoCs + * @pm_suspend: function pointer to SoC specific suspend function + */ +void omap_common_suspend_init(void *pm_suspend) +{ + omap_pm_suspend = pm_suspend; + suspend_set_ops(&omap_pm_ops); +} +#endif /* CONFIG_SUSPEND */ + +static void __init omap3_init_voltages(void) { + if (!cpu_is_omap34xx()) + return; + + omap2_set_init_voltage("mpu_iva", "dpll1_ck", "mpu"); + omap2_set_init_voltage("core", "l3_ick", "l3_main"); +} + +static void __init omap4_init_voltages(void) +{ + if (!cpu_is_omap44xx()) + return; + + omap2_set_init_voltage("mpu", "dpll_mpu_ck", "mpu"); + omap2_set_init_voltage("core", "l3_div_ck", "l3_main_1"); + omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", "iva"); +} + +static inline void omap_init_cpufreq(void) +{ + struct platform_device_info devinfo = { }; + + if (!of_have_populated_dt()) + devinfo.name = "omap-cpufreq"; + else + devinfo.name = "cpufreq-cpu0"; + platform_device_register_full(&devinfo); +} + +static int __init omap2_common_pm_init(void) +{ + if (!of_have_populated_dt()) + omap2_init_processor_devices(); + omap_pm_if_init(); + return 0; } +omap_postcore_initcall(omap2_common_pm_init); + +int __init omap2_common_pm_late_init(void) +{ + if (of_have_populated_dt()) { + omap3_twl_init(); + omap4_twl_init(); + } + + /* Init the voltage layer */ + omap_pmic_late_init(); + omap_voltage_late_init(); -__initcall(omap2_pm_init); + /* Initialize the voltages */ + omap3_init_voltages(); + omap4_init_voltages(); + + /* Smartreflex device init */ + omap_devinit_smartreflex(); + + /* cpufreq dummy device instantiation */ + omap_init_cpufreq(); + + return 0; +} diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h new file mode 100644 index 00000000000..e150102d6c0 --- /dev/null +++ b/arch/arm/mach-omap2/pm.h @@ -0,0 +1,156 @@ +/* + * OMAP2/3 Power Management Routines + * + * Copyright (C) 2008 Nokia Corporation + * Jouni Hogander + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ARCH_ARM_MACH_OMAP2_PM_H +#define __ARCH_ARM_MACH_OMAP2_PM_H + +#include <linux/err.h> + +#include "powerdomain.h" + +#ifdef CONFIG_CPU_IDLE +extern int __init omap3_idle_init(void); +extern int __init omap4_idle_init(void); +#else +static inline int omap3_idle_init(void) +{ + return 0; +} + +static inline int omap4_idle_init(void) +{ + return 0; +} +#endif + +extern void *omap3_secure_ram_storage; +extern void omap3_pm_off_mode_enable(int); +extern void omap_sram_idle(void); +extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused); + +#if defined(CONFIG_PM_OPP) +extern int omap3_opp_init(void); +extern int omap4_opp_init(void); +#else +static inline int omap3_opp_init(void) +{ + return -EINVAL; +} +static inline int omap4_opp_init(void) +{ + return -EINVAL; +} +#endif + +extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); +extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); + +#ifdef CONFIG_PM_DEBUG +extern u32 enable_off_mode; +#else +#define enable_off_mode 0 +#endif + +#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) +extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev); +#else +#define pm_dbg_update_time(pwrdm, prev) do {} while (0); +#endif /* CONFIG_PM_DEBUG */ + +/* 24xx */ +extern void omap24xx_idle_loop_suspend(void); +extern unsigned int omap24xx_idle_loop_suspend_sz; + +extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl, + void __iomem *sdrc_power); +extern unsigned int omap24xx_cpu_suspend_sz; + +/* 3xxx */ +extern void omap34xx_cpu_suspend(int save_state); + +/* omap3_do_wfi function pointer and size, for copy to SRAM */ +extern void omap3_do_wfi(void); +extern unsigned int omap3_do_wfi_sz; +/* ... and its pointer from SRAM after copy */ +extern void (*omap3_do_wfi_sram)(void); + +/* save_secure_ram_context function pointer and size, for copy to SRAM */ +extern int save_secure_ram_context(u32 *addr); +extern unsigned int save_secure_ram_context_sz; + +extern void omap3_save_scratchpad_contents(void); + +#define PM_RTA_ERRATUM_i608 (1 << 0) +#define PM_SDRC_WAKEUP_ERRATUM_i583 (1 << 1) +#define PM_PER_MEMORIES_ERRATUM_i582 (1 << 2) + +#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) +extern u16 pm34xx_errata; +#define IS_PM34XX_ERRATUM(id) (pm34xx_errata & (id)) +extern void enable_omap3630_toggle_l2_on_restore(void); +#else +#define IS_PM34XX_ERRATUM(id) 0 +static inline void enable_omap3630_toggle_l2_on_restore(void) { } +#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ + +#define PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD (1 << 0) + +#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4) +extern u16 pm44xx_errata; +#define IS_PM44XX_ERRATUM(id) (pm44xx_errata & (id)) +#else +#define IS_PM44XX_ERRATUM(id) 0 +#endif + +#ifdef CONFIG_POWER_AVS_OMAP +extern int omap_devinit_smartreflex(void); +extern void omap_enable_smartreflex_on_init(void); +#else +static inline int omap_devinit_smartreflex(void) +{ + return -EINVAL; +} + +static inline void omap_enable_smartreflex_on_init(void) {} +#endif + +#ifdef CONFIG_TWL4030_CORE +extern int omap3_twl_init(void); +extern int omap4_twl_init(void); +extern int omap3_twl_set_sr_bit(bool enable); +#else +static inline int omap3_twl_init(void) +{ + return -EINVAL; +} +static inline int omap4_twl_init(void) +{ + return -EINVAL; +} +#endif + +#ifdef CONFIG_PM +extern void omap_pm_setup_oscillator(u32 tstart, u32 tshut); +extern void omap_pm_get_oscillator(u32 *tstart, u32 *tshut); +extern void omap_pm_setup_sr_i2c_pcb_length(u32 mm); +#else +static inline void omap_pm_setup_oscillator(u32 tstart, u32 tshut) { } +static inline void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) { *tstart = *tshut = 0; } +static inline void omap_pm_setup_sr_i2c_pcb_length(u32 mm) { } +#endif + +#ifdef CONFIG_SUSPEND +void omap_common_suspend_init(void *pm_suspend); +#else +static inline void omap_common_suspend_init(void *pm_suspend) +{ +} +#endif /* CONFIG_SUSPEND */ +#endif diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c new file mode 100644 index 00000000000..a5ea988ff34 --- /dev/null +++ b/arch/arm/mach-omap2/pm24xx.c @@ -0,0 +1,320 @@ +/* + * OMAP2 Power Management Routines + * + * Copyright (C) 2005 Texas Instruments, Inc. + * Copyright (C) 2006-2008 Nokia Corporation + * + * Written by: + * Richard Woodruff <r-woodruff2@ti.com> + * Tony Lindgren + * Juha Yrjola + * Amit Kucheria <amit.kucheria@nokia.com> + * Igor Stoppa <igor.stoppa@nokia.com> + * + * Based on pm.c for omap1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/suspend.h> +#include <linux/sched.h> +#include <linux/proc_fs.h> +#include <linux/interrupt.h> +#include <linux/sysfs.h> +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/clk-provider.h> +#include <linux/irq.h> +#include <linux/time.h> +#include <linux/gpio.h> +#include <linux/platform_data/gpio-omap.h> + +#include <asm/fncpy.h> + +#include <asm/mach/time.h> +#include <asm/mach/irq.h> +#include <asm/mach-types.h> +#include <asm/system_misc.h> + +#include <linux/omap-dma.h> + +#include "soc.h" +#include "common.h" +#include "clock.h" +#include "prm2xxx.h" +#include "prm-regbits-24xx.h" +#include "cm2xxx.h" +#include "cm-regbits-24xx.h" +#include "sdrc.h" +#include "sram.h" +#include "pm.h" +#include "control.h" +#include "powerdomain.h" +#include "clockdomain.h" + +static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl, + void __iomem *sdrc_power); + +static struct powerdomain *mpu_pwrdm, *core_pwrdm; +static struct clockdomain *dsp_clkdm, *mpu_clkdm, *wkup_clkdm, *gfx_clkdm; + +static struct clk *osc_ck, *emul_ck; + +static int omap2_enter_full_retention(void) +{ + u32 l; + + /* There is 1 reference hold for all children of the oscillator + * clock, the following will remove it. If no one else uses the + * oscillator itself it will be disabled if/when we enter retention + * mode. + */ + clk_disable(osc_ck); + + /* Clear old wake-up events */ + /* REVISIT: These write to reserved bits? */ + omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1); + omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2); + omap2_prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST); + + pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET); + pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET); + + /* Workaround to kill USB */ + l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) | OMAP24XX_USBSTANDBYCTRL; + omap_ctrl_writel(l, OMAP2_CONTROL_DEVCONF0); + + omap2_gpio_prepare_for_idle(0); + + /* One last check for pending IRQs to avoid extra latency due + * to sleeping unnecessarily. */ + if (omap_irq_pending()) + goto no_sleep; + + /* Jump to SRAM suspend code */ + omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL), + OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL), + OMAP_SDRC_REGADDR(SDRC_POWER)); + +no_sleep: + omap2_gpio_resume_after_idle(); + + clk_enable(osc_ck); + + /* clear CORE wake-up events */ + omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1); + omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2); + + /* wakeup domain events - bit 1: GPT1, bit5 GPIO */ + omap2_prm_clear_mod_reg_bits(0x4 | 0x1, WKUP_MOD, PM_WKST); + + /* MPU domain wake events */ + l = omap2_prm_read_mod_reg(OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET); + if (l & 0x01) + omap2_prm_write_mod_reg(0x01, OCP_MOD, + OMAP2_PRCM_IRQSTATUS_MPU_OFFSET); + if (l & 0x20) + omap2_prm_write_mod_reg(0x20, OCP_MOD, + OMAP2_PRCM_IRQSTATUS_MPU_OFFSET); + + /* Mask future PRCM-to-MPU interrupts */ + omap2_prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET); + + pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); + pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_ON); + + return 0; +} + +static int sti_console_enabled; + +static int omap2_allow_mpu_retention(void) +{ + if (!omap2xxx_cm_mpu_retention_allowed()) + return 0; + if (sti_console_enabled) + return 0; + + return 1; +} + +static void omap2_enter_mpu_retention(void) +{ + const int zero = 0; + + /* The peripherals seem not to be able to wake up the MPU when + * it is in retention mode. */ + if (omap2_allow_mpu_retention()) { + /* REVISIT: These write to reserved bits? */ + omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1); + omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2); + omap2_prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST); + + /* Try to enter MPU retention */ + pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET); + + } else { + /* Block MPU retention */ + pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); + } + + /* WFI */ + asm("mcr p15, 0, %0, c7, c0, 4" : : "r" (zero) : "memory", "cc"); + + pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); +} + +static int omap2_can_sleep(void) +{ + if (omap2xxx_cm_fclks_active()) + return 0; + if (__clk_is_enabled(osc_ck)) + return 0; + if (omap_dma_running()) + return 0; + + return 1; +} + +static void omap2_pm_idle(void) +{ + if (!omap2_can_sleep()) { + if (omap_irq_pending()) + return; + omap2_enter_mpu_retention(); + return; + } + + if (omap_irq_pending()) + return; + + omap2_enter_full_retention(); +} + +static void __init prcm_setup_regs(void) +{ + int i, num_mem_banks; + struct powerdomain *pwrdm; + + /* + * Enable autoidle + * XXX This should be handled by hwmod code or PRCM init code + */ + omap2_prm_write_mod_reg(OMAP24XX_AUTOIDLE_MASK, OCP_MOD, + OMAP2_PRCM_SYSCONFIG_OFFSET); + + /* + * Set CORE powerdomain memory banks to retain their contents + * during RETENTION + */ + num_mem_banks = pwrdm_get_mem_bank_count(core_pwrdm); + for (i = 0; i < num_mem_banks; i++) + pwrdm_set_mem_retst(core_pwrdm, i, PWRDM_POWER_RET); + + pwrdm_set_logic_retst(core_pwrdm, PWRDM_POWER_RET); + + pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET); + + /* Force-power down DSP, GFX powerdomains */ + + pwrdm = clkdm_get_pwrdm(dsp_clkdm); + pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF); + + pwrdm = clkdm_get_pwrdm(gfx_clkdm); + pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF); + + /* Enable hardware-supervised idle for all clkdms */ + clkdm_for_each(omap_pm_clkdms_setup, NULL); + clkdm_add_wkdep(mpu_clkdm, wkup_clkdm); + + omap_common_suspend_init(omap2_enter_full_retention); + + /* REVISIT: Configure number of 32 kHz clock cycles for sys_clk + * stabilisation */ + omap2_prm_write_mod_reg(15 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD, + OMAP2_PRCM_CLKSSETUP_OFFSET); + + /* Configure automatic voltage transition */ + omap2_prm_write_mod_reg(2 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD, + OMAP2_PRCM_VOLTSETUP_OFFSET); + omap2_prm_write_mod_reg(OMAP24XX_AUTO_EXTVOLT_MASK | + (0x1 << OMAP24XX_SETOFF_LEVEL_SHIFT) | + OMAP24XX_MEMRETCTRL_MASK | + (0x1 << OMAP24XX_SETRET_LEVEL_SHIFT) | + (0x0 << OMAP24XX_VOLT_LEVEL_SHIFT), + OMAP24XX_GR_MOD, OMAP2_PRCM_VOLTCTRL_OFFSET); + + /* Enable wake-up events */ + omap2_prm_write_mod_reg(OMAP24XX_EN_GPIOS_MASK | OMAP24XX_EN_GPT1_MASK, + WKUP_MOD, PM_WKEN); +} + +int __init omap2_pm_init(void) +{ + u32 l; + + printk(KERN_INFO "Power Management for OMAP2 initializing\n"); + l = omap2_prm_read_mod_reg(OCP_MOD, OMAP2_PRCM_REVISION_OFFSET); + printk(KERN_INFO "PRCM revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f); + + /* Look up important powerdomains */ + + mpu_pwrdm = pwrdm_lookup("mpu_pwrdm"); + if (!mpu_pwrdm) + pr_err("PM: mpu_pwrdm not found\n"); + + core_pwrdm = pwrdm_lookup("core_pwrdm"); + if (!core_pwrdm) + pr_err("PM: core_pwrdm not found\n"); + + /* Look up important clockdomains */ + + mpu_clkdm = clkdm_lookup("mpu_clkdm"); + if (!mpu_clkdm) + pr_err("PM: mpu_clkdm not found\n"); + + wkup_clkdm = clkdm_lookup("wkup_clkdm"); + if (!wkup_clkdm) + pr_err("PM: wkup_clkdm not found\n"); + + dsp_clkdm = clkdm_lookup("dsp_clkdm"); + if (!dsp_clkdm) + pr_err("PM: dsp_clkdm not found\n"); + + gfx_clkdm = clkdm_lookup("gfx_clkdm"); + if (!gfx_clkdm) + pr_err("PM: gfx_clkdm not found\n"); + + + osc_ck = clk_get(NULL, "osc_ck"); + if (IS_ERR(osc_ck)) { + printk(KERN_ERR "could not get osc_ck\n"); + return -ENODEV; + } + + if (cpu_is_omap242x()) { + emul_ck = clk_get(NULL, "emul_ck"); + if (IS_ERR(emul_ck)) { + printk(KERN_ERR "could not get emul_ck\n"); + clk_put(osc_ck); + return -ENODEV; + } + } + + prcm_setup_regs(); + + /* + * We copy the assembler sleep/wakeup routines to SRAM. + * These routines need to be in SRAM as that's the only + * memory the MPU can see when it wakes up after the entire + * chip enters idle. + */ + omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend, + omap24xx_cpu_suspend_sz); + + arm_pm_idle = omap2_pm_idle; + + return 0; +} diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c new file mode 100644 index 00000000000..507d8eeaab9 --- /dev/null +++ b/arch/arm/mach-omap2/pm34xx.c @@ -0,0 +1,776 @@ +/* + * OMAP3 Power Management Routines + * + * Copyright (C) 2006-2008 Nokia Corporation + * Tony Lindgren <tony@atomide.com> + * Jouni Hogander + * + * Copyright (C) 2007 Texas Instruments, Inc. + * Rajendra Nayak <rnayak@ti.com> + * + * Copyright (C) 2005 Texas Instruments, Inc. + * Richard Woodruff <r-woodruff2@ti.com> + * + * Based on pm.c for omap1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/pm.h> +#include <linux/suspend.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/list.h> +#include <linux/err.h> +#include <linux/gpio.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/slab.h> +#include <linux/omap-dma.h> +#include <linux/platform_data/gpio-omap.h> + +#include <trace/events/power.h> + +#include <asm/fncpy.h> +#include <asm/suspend.h> +#include <asm/system_misc.h> + +#include "clockdomain.h" +#include "powerdomain.h" +#include "soc.h" +#include "common.h" +#include "cm3xxx.h" +#include "cm-regbits-34xx.h" +#include "gpmc.h" +#include "prm-regbits-34xx.h" +#include "prm3xxx.h" +#include "pm.h" +#include "sdrc.h" +#include "sram.h" +#include "control.h" +#include "vc.h" + +/* pm34xx errata defined in pm.h */ +u16 pm34xx_errata; + +struct power_state { + struct powerdomain *pwrdm; + u32 next_state; +#ifdef CONFIG_SUSPEND + u32 saved_state; +#endif + struct list_head node; +}; + +static LIST_HEAD(pwrst_list); + +static int (*_omap_save_secure_sram)(u32 *addr); +void (*omap3_do_wfi_sram)(void); + +static struct powerdomain *mpu_pwrdm, *neon_pwrdm; +static struct powerdomain *core_pwrdm, *per_pwrdm; + +static void omap3_core_save_context(void) +{ + omap3_ctrl_save_padconf(); + + /* + * Force write last pad into memory, as this can fail in some + * cases according to errata 1.157, 1.185 + */ + omap_ctrl_writel(omap_ctrl_readl(OMAP343X_PADCONF_ETK_D14), + OMAP343X_CONTROL_MEM_WKUP + 0x2a0); + + /* Save the Interrupt controller context */ + omap_intc_save_context(); + /* Save the GPMC context */ + omap3_gpmc_save_context(); + /* Save the system control module context, padconf already save above*/ + omap3_control_save_context(); + omap_dma_global_context_save(); +} + +static void omap3_core_restore_context(void) +{ + /* Restore the control module context, padconf restored by h/w */ + omap3_control_restore_context(); + /* Restore the GPMC context */ + omap3_gpmc_restore_context(); + /* Restore the interrupt controller context */ + omap_intc_restore_context(); + omap_dma_global_context_restore(); +} + +/* + * FIXME: This function should be called before entering off-mode after + * OMAP3 secure services have been accessed. Currently it is only called + * once during boot sequence, but this works as we are not using secure + * services. + */ +static void omap3_save_secure_ram_context(void) +{ + u32 ret; + int mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm); + + if (omap_type() != OMAP2_DEVICE_TYPE_GP) { + /* + * MPU next state must be set to POWER_ON temporarily, + * otherwise the WFI executed inside the ROM code + * will hang the system. + */ + pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); + ret = _omap_save_secure_sram((u32 *)(unsigned long) + __pa(omap3_secure_ram_storage)); + pwrdm_set_next_pwrst(mpu_pwrdm, mpu_next_state); + /* Following is for error tracking, it should not happen */ + if (ret) { + pr_err("save_secure_sram() returns %08x\n", ret); + while (1) + ; + } + } +} + +/* + * PRCM Interrupt Handler Helper Function + * + * The purpose of this function is to clear any wake-up events latched + * in the PRCM PM_WKST_x registers. It is possible that a wake-up event + * may occur whilst attempting to clear a PM_WKST_x register and thus + * set another bit in this register. A while loop is used to ensure + * that any peripheral wake-up events occurring while attempting to + * clear the PM_WKST_x are detected and cleared. + */ +static int prcm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits) +{ + u32 wkst, fclk, iclk, clken; + u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1; + u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1; + u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1; + u16 grpsel_off = (regs == 3) ? + OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL; + int c = 0; + + wkst = omap2_prm_read_mod_reg(module, wkst_off); + wkst &= omap2_prm_read_mod_reg(module, grpsel_off); + wkst &= ~ignore_bits; + if (wkst) { + iclk = omap2_cm_read_mod_reg(module, iclk_off); + fclk = omap2_cm_read_mod_reg(module, fclk_off); + while (wkst) { + clken = wkst; + omap2_cm_set_mod_reg_bits(clken, module, iclk_off); + /* + * For USBHOST, we don't know whether HOST1 or + * HOST2 woke us up, so enable both f-clocks + */ + if (module == OMAP3430ES2_USBHOST_MOD) + clken |= 1 << OMAP3430ES2_EN_USBHOST2_SHIFT; + omap2_cm_set_mod_reg_bits(clken, module, fclk_off); + omap2_prm_write_mod_reg(wkst, module, wkst_off); + wkst = omap2_prm_read_mod_reg(module, wkst_off); + wkst &= ~ignore_bits; + c++; + } + omap2_cm_write_mod_reg(iclk, module, iclk_off); + omap2_cm_write_mod_reg(fclk, module, fclk_off); + } + + return c; +} + +static irqreturn_t _prcm_int_handle_io(int irq, void *unused) +{ + int c; + + c = prcm_clear_mod_irqs(WKUP_MOD, 1, + ~(OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK)); + + return c ? IRQ_HANDLED : IRQ_NONE; +} + +static irqreturn_t _prcm_int_handle_wakeup(int irq, void *unused) +{ + int c; + + /* + * Clear all except ST_IO and ST_IO_CHAIN for wkup module, + * these are handled in a separate handler to avoid acking + * IO events before parsing in mux code + */ + c = prcm_clear_mod_irqs(WKUP_MOD, 1, + OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK); + c += prcm_clear_mod_irqs(CORE_MOD, 1, 0); + c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1, 0); + if (omap_rev() > OMAP3430_REV_ES1_0) { + c += prcm_clear_mod_irqs(CORE_MOD, 3, 0); + c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, 0); + } + + return c ? IRQ_HANDLED : IRQ_NONE; +} + +static void omap34xx_save_context(u32 *save) +{ + u32 val; + + /* Read Auxiliary Control Register */ + asm("mrc p15, 0, %0, c1, c0, 1" : "=r" (val)); + *save++ = 1; + *save++ = val; + + /* Read L2 AUX ctrl register */ + asm("mrc p15, 1, %0, c9, c0, 2" : "=r" (val)); + *save++ = 1; + *save++ = val; +} + +static int omap34xx_do_sram_idle(unsigned long save_state) +{ + omap34xx_cpu_suspend(save_state); + return 0; +} + +void omap_sram_idle(void) +{ + /* Variable to tell what needs to be saved and restored + * in omap_sram_idle*/ + /* save_state = 0 => Nothing to save and restored */ + /* save_state = 1 => Only L1 and logic lost */ + /* save_state = 2 => Only L2 lost */ + /* save_state = 3 => L1, L2 and logic lost */ + int save_state = 0; + int mpu_next_state = PWRDM_POWER_ON; + int per_next_state = PWRDM_POWER_ON; + int core_next_state = PWRDM_POWER_ON; + int per_going_off; + int core_prev_state; + u32 sdrc_pwr = 0; + + mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm); + switch (mpu_next_state) { + case PWRDM_POWER_ON: + case PWRDM_POWER_RET: + /* No need to save context */ + save_state = 0; + break; + case PWRDM_POWER_OFF: + save_state = 3; + break; + default: + /* Invalid state */ + pr_err("Invalid mpu state in sram_idle\n"); + return; + } + + /* NEON control */ + if (pwrdm_read_pwrst(neon_pwrdm) == PWRDM_POWER_ON) + pwrdm_set_next_pwrst(neon_pwrdm, mpu_next_state); + + /* Enable IO-PAD and IO-CHAIN wakeups */ + per_next_state = pwrdm_read_next_pwrst(per_pwrdm); + core_next_state = pwrdm_read_next_pwrst(core_pwrdm); + + pwrdm_pre_transition(NULL); + + /* PER */ + if (per_next_state < PWRDM_POWER_ON) { + per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0; + omap2_gpio_prepare_for_idle(per_going_off); + } + + /* CORE */ + if (core_next_state < PWRDM_POWER_ON) { + if (core_next_state == PWRDM_POWER_OFF) { + omap3_core_save_context(); + omap3_cm_save_context(); + } + } + + /* Configure PMIC signaling for I2C4 or sys_off_mode */ + omap3_vc_set_pmic_signaling(core_next_state); + + omap3_intc_prepare_idle(); + + /* + * On EMU/HS devices ROM code restores a SRDC value + * from scratchpad which has automatic self refresh on timeout + * of AUTO_CNT = 1 enabled. This takes care of erratum ID i443. + * Hence store/restore the SDRC_POWER register here. + */ + if (cpu_is_omap3430() && omap_rev() >= OMAP3430_REV_ES3_0 && + (omap_type() == OMAP2_DEVICE_TYPE_EMU || + omap_type() == OMAP2_DEVICE_TYPE_SEC) && + core_next_state == PWRDM_POWER_OFF) + sdrc_pwr = sdrc_read_reg(SDRC_POWER); + + /* + * omap3_arm_context is the location where some ARM context + * get saved. The rest is placed on the stack, and restored + * from there before resuming. + */ + if (save_state) + omap34xx_save_context(omap3_arm_context); + if (save_state == 1 || save_state == 3) + cpu_suspend(save_state, omap34xx_do_sram_idle); + else + omap34xx_do_sram_idle(save_state); + + /* Restore normal SDRC POWER settings */ + if (cpu_is_omap3430() && omap_rev() >= OMAP3430_REV_ES3_0 && + (omap_type() == OMAP2_DEVICE_TYPE_EMU || + omap_type() == OMAP2_DEVICE_TYPE_SEC) && + core_next_state == PWRDM_POWER_OFF) + sdrc_write_reg(sdrc_pwr, SDRC_POWER); + + /* CORE */ + if (core_next_state < PWRDM_POWER_ON) { + core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm); + if (core_prev_state == PWRDM_POWER_OFF) { + omap3_core_restore_context(); + omap3_cm_restore_context(); + omap3_sram_restore_context(); + omap2_sms_restore_context(); + } + } + omap3_intc_resume_idle(); + + pwrdm_post_transition(NULL); + + /* PER */ + if (per_next_state < PWRDM_POWER_ON) + omap2_gpio_resume_after_idle(); +} + +static void omap3_pm_idle(void) +{ + if (omap_irq_pending()) + return; + + trace_cpu_idle(1, smp_processor_id()); + + omap_sram_idle(); + + trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id()); +} + +#ifdef CONFIG_SUSPEND +static int omap3_pm_suspend(void) +{ + struct power_state *pwrst; + int state, ret = 0; + + /* Read current next_pwrsts */ + list_for_each_entry(pwrst, &pwrst_list, node) + pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm); + /* Set ones wanted by suspend */ + list_for_each_entry(pwrst, &pwrst_list, node) { + if (omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state)) + goto restore; + if (pwrdm_clear_all_prev_pwrst(pwrst->pwrdm)) + goto restore; + } + + omap3_intc_suspend(); + + omap_sram_idle(); + +restore: + /* Restore next_pwrsts */ + list_for_each_entry(pwrst, &pwrst_list, node) { + state = pwrdm_read_prev_pwrst(pwrst->pwrdm); + if (state > pwrst->next_state) { + pr_info("Powerdomain (%s) didn't enter target state %d\n", + pwrst->pwrdm->name, pwrst->next_state); + ret = -1; + } + omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); + } + if (ret) + pr_err("Could not enter target state in pm_suspend\n"); + else + pr_info("Successfully put all powerdomains to target state\n"); + + return ret; +} +#else +#define omap3_pm_suspend NULL +#endif /* CONFIG_SUSPEND */ + + +/** + * omap3_iva_idle(): ensure IVA is in idle so it can be put into + * retention + * + * In cases where IVA2 is activated by bootcode, it may prevent + * full-chip retention or off-mode because it is not idle. This + * function forces the IVA2 into idle state so it can go + * into retention/off and thus allow full-chip retention/off. + * + **/ +static void __init omap3_iva_idle(void) +{ + /* ensure IVA2 clock is disabled */ + omap2_cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN); + + /* if no clock activity, nothing else to do */ + if (!(omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSTST) & + OMAP3430_CLKACTIVITY_IVA2_MASK)) + return; + + /* Reset IVA2 */ + omap2_prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK | + OMAP3430_RST2_IVA2_MASK | + OMAP3430_RST3_IVA2_MASK, + OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); + + /* Enable IVA2 clock */ + omap2_cm_write_mod_reg(OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_MASK, + OMAP3430_IVA2_MOD, CM_FCLKEN); + + /* Set IVA2 boot mode to 'idle' */ + omap3_ctrl_set_iva_bootmode_idle(); + + /* Un-reset IVA2 */ + omap2_prm_write_mod_reg(0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); + + /* Disable IVA2 clock */ + omap2_cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN); + + /* Reset IVA2 */ + omap2_prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK | + OMAP3430_RST2_IVA2_MASK | + OMAP3430_RST3_IVA2_MASK, + OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); +} + +static void __init omap3_d2d_idle(void) +{ + u16 mask, padconf; + + /* In a stand alone OMAP3430 where there is not a stacked + * modem for the D2D Idle Ack and D2D MStandby must be pulled + * high. S CONTROL_PADCONF_SAD2D_IDLEACK and + * CONTROL_PADCONF_SAD2D_MSTDBY to have a pull up. */ + mask = (1 << 4) | (1 << 3); /* pull-up, enabled */ + padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_MSTANDBY); + padconf |= mask; + omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_MSTANDBY); + + padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_IDLEACK); + padconf |= mask; + omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_IDLEACK); + + /* reset modem */ + omap2_prm_write_mod_reg(OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON_MASK | + OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST_MASK, + CORE_MOD, OMAP2_RM_RSTCTRL); + omap2_prm_write_mod_reg(0, CORE_MOD, OMAP2_RM_RSTCTRL); +} + +static void __init prcm_setup_regs(void) +{ + u32 omap3630_en_uart4_mask = cpu_is_omap3630() ? + OMAP3630_EN_UART4_MASK : 0; + u32 omap3630_grpsel_uart4_mask = cpu_is_omap3630() ? + OMAP3630_GRPSEL_UART4_MASK : 0; + + /* XXX This should be handled by hwmod code or SCM init code */ + omap_ctrl_writel(OMAP3430_AUTOIDLE_MASK, OMAP2_CONTROL_SYSCONFIG); + + /* + * Enable control of expternal oscillator through + * sys_clkreq. In the long run clock framework should + * take care of this. + */ + omap2_prm_rmw_mod_reg_bits(OMAP_AUTOEXTCLKMODE_MASK, + 1 << OMAP_AUTOEXTCLKMODE_SHIFT, + OMAP3430_GR_MOD, + OMAP3_PRM_CLKSRC_CTRL_OFFSET); + + /* setup wakup source */ + omap2_prm_write_mod_reg(OMAP3430_EN_IO_MASK | OMAP3430_EN_GPIO1_MASK | + OMAP3430_EN_GPT1_MASK | OMAP3430_EN_GPT12_MASK, + WKUP_MOD, PM_WKEN); + /* No need to write EN_IO, that is always enabled */ + omap2_prm_write_mod_reg(OMAP3430_GRPSEL_GPIO1_MASK | + OMAP3430_GRPSEL_GPT1_MASK | + OMAP3430_GRPSEL_GPT12_MASK, + WKUP_MOD, OMAP3430_PM_MPUGRPSEL); + + /* Enable PM_WKEN to support DSS LPR */ + omap2_prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS_MASK, + OMAP3430_DSS_MOD, PM_WKEN); + + /* Enable wakeups in PER */ + omap2_prm_write_mod_reg(omap3630_en_uart4_mask | + OMAP3430_EN_GPIO2_MASK | OMAP3430_EN_GPIO3_MASK | + OMAP3430_EN_GPIO4_MASK | OMAP3430_EN_GPIO5_MASK | + OMAP3430_EN_GPIO6_MASK | OMAP3430_EN_UART3_MASK | + OMAP3430_EN_MCBSP2_MASK | OMAP3430_EN_MCBSP3_MASK | + OMAP3430_EN_MCBSP4_MASK, + OMAP3430_PER_MOD, PM_WKEN); + /* and allow them to wake up MPU */ + omap2_prm_write_mod_reg(omap3630_grpsel_uart4_mask | + OMAP3430_GRPSEL_GPIO2_MASK | + OMAP3430_GRPSEL_GPIO3_MASK | + OMAP3430_GRPSEL_GPIO4_MASK | + OMAP3430_GRPSEL_GPIO5_MASK | + OMAP3430_GRPSEL_GPIO6_MASK | + OMAP3430_GRPSEL_UART3_MASK | + OMAP3430_GRPSEL_MCBSP2_MASK | + OMAP3430_GRPSEL_MCBSP3_MASK | + OMAP3430_GRPSEL_MCBSP4_MASK, + OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL); + + /* Don't attach IVA interrupts */ + if (omap3_has_iva()) { + omap2_prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL); + omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1); + omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3); + omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD, + OMAP3430_PM_IVAGRPSEL); + } + + /* Clear any pending 'reset' flags */ + omap2_prm_write_mod_reg(0xffffffff, MPU_MOD, OMAP2_RM_RSTST); + omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP2_RM_RSTST); + omap2_prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, OMAP2_RM_RSTST); + omap2_prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, OMAP2_RM_RSTST); + omap2_prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, OMAP2_RM_RSTST); + omap2_prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, OMAP2_RM_RSTST); + omap2_prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD, OMAP2_RM_RSTST); + + /* Clear any pending PRCM interrupts */ + omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); + + /* + * We need to idle iva2_pwrdm even on am3703 with no iva2. + */ + omap3_iva_idle(); + + omap3_d2d_idle(); +} + +void omap3_pm_off_mode_enable(int enable) +{ + struct power_state *pwrst; + u32 state; + + if (enable) + state = PWRDM_POWER_OFF; + else + state = PWRDM_POWER_RET; + + list_for_each_entry(pwrst, &pwrst_list, node) { + if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583) && + pwrst->pwrdm == core_pwrdm && + state == PWRDM_POWER_OFF) { + pwrst->next_state = PWRDM_POWER_RET; + pr_warn("%s: Core OFF disabled due to errata i583\n", + __func__); + } else { + pwrst->next_state = state; + } + omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); + } +} + +int omap3_pm_get_suspend_state(struct powerdomain *pwrdm) +{ + struct power_state *pwrst; + + list_for_each_entry(pwrst, &pwrst_list, node) { + if (pwrst->pwrdm == pwrdm) + return pwrst->next_state; + } + return -EINVAL; +} + +int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state) +{ + struct power_state *pwrst; + + list_for_each_entry(pwrst, &pwrst_list, node) { + if (pwrst->pwrdm == pwrdm) { + pwrst->next_state = state; + return 0; + } + } + return -EINVAL; +} + +static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) +{ + struct power_state *pwrst; + + if (!pwrdm->pwrsts) + return 0; + + pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); + if (!pwrst) + return -ENOMEM; + pwrst->pwrdm = pwrdm; + pwrst->next_state = PWRDM_POWER_RET; + list_add(&pwrst->node, &pwrst_list); + + if (pwrdm_has_hdwr_sar(pwrdm)) + pwrdm_enable_hdwr_sar(pwrdm); + + return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); +} + +/* + * Push functions to SRAM + * + * The minimum set of functions is pushed to SRAM for execution: + * - omap3_do_wfi for erratum i581 WA, + * - save_secure_ram_context for security extensions. + */ +void omap_push_sram_idle(void) +{ + omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi, omap3_do_wfi_sz); + + if (omap_type() != OMAP2_DEVICE_TYPE_GP) + _omap_save_secure_sram = omap_sram_push(save_secure_ram_context, + save_secure_ram_context_sz); +} + +static void __init pm_errata_configure(void) +{ + if (cpu_is_omap3630()) { + pm34xx_errata |= PM_RTA_ERRATUM_i608; + /* Enable the l2 cache toggling in sleep logic */ + enable_omap3630_toggle_l2_on_restore(); + if (omap_rev() < OMAP3630_REV_ES1_2) + pm34xx_errata |= (PM_SDRC_WAKEUP_ERRATUM_i583 | + PM_PER_MEMORIES_ERRATUM_i582); + } else if (cpu_is_omap34xx()) { + pm34xx_errata |= PM_PER_MEMORIES_ERRATUM_i582; + } +} + +int __init omap3_pm_init(void) +{ + struct power_state *pwrst, *tmp; + struct clockdomain *neon_clkdm, *mpu_clkdm, *per_clkdm, *wkup_clkdm; + int ret; + + if (!omap3_has_io_chain_ctrl()) + pr_warning("PM: no software I/O chain control; some wakeups may be lost\n"); + + pm_errata_configure(); + + /* XXX prcm_setup_regs needs to be before enabling hw + * supervised mode for powerdomains */ + prcm_setup_regs(); + + ret = request_irq(omap_prcm_event_to_irq("wkup"), + _prcm_int_handle_wakeup, IRQF_NO_SUSPEND, "pm_wkup", NULL); + + if (ret) { + pr_err("pm: Failed to request pm_wkup irq\n"); + goto err1; + } + + /* IO interrupt is shared with mux code */ + ret = request_irq(omap_prcm_event_to_irq("io"), + _prcm_int_handle_io, IRQF_SHARED | IRQF_NO_SUSPEND, "pm_io", + omap3_pm_init); + enable_irq(omap_prcm_event_to_irq("io")); + + if (ret) { + pr_err("pm: Failed to request pm_io irq\n"); + goto err2; + } + + ret = pwrdm_for_each(pwrdms_setup, NULL); + if (ret) { + pr_err("Failed to setup powerdomains\n"); + goto err3; + } + + (void) clkdm_for_each(omap_pm_clkdms_setup, NULL); + + mpu_pwrdm = pwrdm_lookup("mpu_pwrdm"); + if (mpu_pwrdm == NULL) { + pr_err("Failed to get mpu_pwrdm\n"); + ret = -EINVAL; + goto err3; + } + + neon_pwrdm = pwrdm_lookup("neon_pwrdm"); + per_pwrdm = pwrdm_lookup("per_pwrdm"); + core_pwrdm = pwrdm_lookup("core_pwrdm"); + + neon_clkdm = clkdm_lookup("neon_clkdm"); + mpu_clkdm = clkdm_lookup("mpu_clkdm"); + per_clkdm = clkdm_lookup("per_clkdm"); + wkup_clkdm = clkdm_lookup("wkup_clkdm"); + + omap_common_suspend_init(omap3_pm_suspend); + + arm_pm_idle = omap3_pm_idle; + omap3_idle_init(); + + /* + * RTA is disabled during initialization as per erratum i608 + * it is safer to disable RTA by the bootloader, but we would like + * to be doubly sure here and prevent any mishaps. + */ + if (IS_PM34XX_ERRATUM(PM_RTA_ERRATUM_i608)) + omap3630_ctrl_disable_rta(); + + /* + * The UART3/4 FIFO and the sidetone memory in McBSP2/3 are + * not correctly reset when the PER powerdomain comes back + * from OFF or OSWR when the CORE powerdomain is kept active. + * See OMAP36xx Erratum i582 "PER Domain reset issue after + * Domain-OFF/OSWR Wakeup". This wakeup dependency is not a + * complete workaround. The kernel must also prevent the PER + * powerdomain from going to OSWR/OFF while the CORE + * powerdomain is not going to OSWR/OFF. And if PER last + * power state was off while CORE last power state was ON, the + * UART3/4 and McBSP2/3 SIDETONE devices need to run a + * self-test using their loopback tests; if that fails, those + * devices are unusable until the PER/CORE can complete a transition + * from ON to OSWR/OFF and then back to ON. + * + * XXX Technically this workaround is only needed if off-mode + * or OSWR is enabled. + */ + if (IS_PM34XX_ERRATUM(PM_PER_MEMORIES_ERRATUM_i582)) + clkdm_add_wkdep(per_clkdm, wkup_clkdm); + + clkdm_add_wkdep(neon_clkdm, mpu_clkdm); + if (omap_type() != OMAP2_DEVICE_TYPE_GP) { + omap3_secure_ram_storage = + kmalloc(0x803F, GFP_KERNEL); + if (!omap3_secure_ram_storage) + pr_err("Memory allocation failed when allocating for secure sram context\n"); + + local_irq_disable(); + + omap_dma_global_context_save(); + omap3_save_secure_ram_context(); + omap_dma_global_context_restore(); + + local_irq_enable(); + } + + omap3_save_scratchpad_contents(); + return ret; + +err3: + list_for_each_entry_safe(pwrst, tmp, &pwrst_list, node) { + list_del(&pwrst->node); + kfree(pwrst); + } + free_irq(omap_prcm_event_to_irq("io"), omap3_pm_init); +err2: + free_irq(omap_prcm_event_to_irq("wkup"), NULL); +err1: + return ret; +} diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c new file mode 100644 index 00000000000..0dda6cf8b85 --- /dev/null +++ b/arch/arm/mach-omap2/pm44xx.c @@ -0,0 +1,266 @@ +/* + * OMAP4+ Power Management Routines + * + * Copyright (C) 2010-2013 Texas Instruments, Inc. + * Rajendra Nayak <rnayak@ti.com> + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/pm.h> +#include <linux/suspend.h> +#include <linux/module.h> +#include <linux/list.h> +#include <linux/err.h> +#include <linux/slab.h> +#include <asm/system_misc.h> + +#include "soc.h" +#include "common.h" +#include "clockdomain.h" +#include "powerdomain.h" +#include "pm.h" + +u16 pm44xx_errata; + +struct power_state { + struct powerdomain *pwrdm; + u32 next_state; +#ifdef CONFIG_SUSPEND + u32 saved_state; + u32 saved_logic_state; +#endif + struct list_head node; +}; + +static LIST_HEAD(pwrst_list); + +#ifdef CONFIG_SUSPEND +static int omap4_pm_suspend(void) +{ + struct power_state *pwrst; + int state, ret = 0; + u32 cpu_id = smp_processor_id(); + + /* Save current powerdomain state */ + list_for_each_entry(pwrst, &pwrst_list, node) { + pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm); + pwrst->saved_logic_state = pwrdm_read_logic_retst(pwrst->pwrdm); + } + + /* Set targeted power domain states by suspend */ + list_for_each_entry(pwrst, &pwrst_list, node) { + omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); + pwrdm_set_logic_retst(pwrst->pwrdm, PWRDM_POWER_OFF); + } + + /* + * For MPUSS to hit power domain retention(CSWR or OSWR), + * CPU0 and CPU1 power domains need to be in OFF or DORMANT state, + * since CPU power domain CSWR is not supported by hardware + * Only master CPU follows suspend path. All other CPUs follow + * CPU hotplug path in system wide suspend. On OMAP4, CPU power + * domain CSWR is not supported by hardware. + * More details can be found in OMAP4430 TRM section 4.3.4.2. + */ + omap4_enter_lowpower(cpu_id, PWRDM_POWER_OFF); + + /* Restore next powerdomain state */ + list_for_each_entry(pwrst, &pwrst_list, node) { + state = pwrdm_read_prev_pwrst(pwrst->pwrdm); + if (state > pwrst->next_state) { + pr_info("Powerdomain (%s) didn't enter target state %d\n", + pwrst->pwrdm->name, pwrst->next_state); + ret = -1; + } + omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); + pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->saved_logic_state); + } + if (ret) { + pr_crit("Could not enter target state in pm_suspend\n"); + /* + * OMAP4 chip PM currently works only with certain (newer) + * versions of bootloaders. This is due to missing code in the + * kernel to properly reset and initialize some devices. + * Warn the user about the bootloader version being one of the + * possible causes. + * http://www.spinics.net/lists/arm-kernel/msg218641.html + */ + pr_warn("A possible cause could be an old bootloader - try u-boot >= v2012.07\n"); + } else { + pr_info("Successfully put all powerdomains to target state\n"); + } + + return 0; +} +#else +#define omap4_pm_suspend NULL +#endif /* CONFIG_SUSPEND */ + +static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) +{ + struct power_state *pwrst; + + if (!pwrdm->pwrsts) + return 0; + + /* + * Skip CPU0 and CPU1 power domains. CPU1 is programmed + * through hotplug path and CPU0 explicitly programmed + * further down in the code path + */ + if (!strncmp(pwrdm->name, "cpu", 3)) + return 0; + + pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); + if (!pwrst) + return -ENOMEM; + + pwrst->pwrdm = pwrdm; + pwrst->next_state = PWRDM_POWER_RET; + list_add(&pwrst->node, &pwrst_list); + + return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); +} + +/** + * omap_default_idle - OMAP4 default ilde routine.' + * + * Implements OMAP4 memory, IO ordering requirements which can't be addressed + * with default cpu_do_idle() hook. Used by all CPUs with !CONFIG_CPU_IDLE and + * by secondary CPU with CONFIG_CPU_IDLE. + */ +static void omap_default_idle(void) +{ + omap_do_wfi(); +} + +/** + * omap4_init_static_deps - Add OMAP4 static dependencies + * + * Add needed static clockdomain dependencies on OMAP4 devices. + * Return: 0 on success or 'err' on failures + */ +static inline int omap4_init_static_deps(void) +{ + struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm; + struct clockdomain *ducati_clkdm, *l3_2_clkdm; + int ret = 0; + + if (omap_rev() == OMAP4430_REV_ES1_0) { + WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); + return -ENODEV; + } + + pr_err("Power Management for TI OMAP4.\n"); + /* + * OMAP4 chip PM currently works only with certain (newer) + * versions of bootloaders. This is due to missing code in the + * kernel to properly reset and initialize some devices. + * http://www.spinics.net/lists/arm-kernel/msg218641.html + */ + pr_warn("OMAP4 PM: u-boot >= v2012.07 is required for full PM support\n"); + + ret = pwrdm_for_each(pwrdms_setup, NULL); + if (ret) { + pr_err("Failed to setup powerdomains\n"); + return ret; + } + + /* + * The dynamic dependency between MPUSS -> MEMIF and + * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as + * expected. The hardware recommendation is to enable static + * dependencies for these to avoid system lock ups or random crashes. + * The L4 wakeup depedency is added to workaround the OCP sync hardware + * BUG with 32K synctimer which lead to incorrect timer value read + * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which + * are part of L4 wakeup clockdomain. + */ + mpuss_clkdm = clkdm_lookup("mpuss_clkdm"); + emif_clkdm = clkdm_lookup("l3_emif_clkdm"); + l3_1_clkdm = clkdm_lookup("l3_1_clkdm"); + l3_2_clkdm = clkdm_lookup("l3_2_clkdm"); + ducati_clkdm = clkdm_lookup("ducati_clkdm"); + if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || + (!l3_2_clkdm) || (!ducati_clkdm)) + return -EINVAL; + + ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm); + ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm); + ret |= clkdm_add_wkdep(mpuss_clkdm, l3_2_clkdm); + ret |= clkdm_add_wkdep(ducati_clkdm, l3_1_clkdm); + ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm); + if (ret) { + pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 wakeup dependency\n"); + return -EINVAL; + } + + return ret; +} + +/** + * omap4_pm_init_early - Does early initialization necessary for OMAP4+ devices + * + * Initializes basic stuff for power management functionality. + */ +int __init omap4_pm_init_early(void) +{ + if (cpu_is_omap446x()) + pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD; + + return 0; +} + +/** + * omap4_pm_init - Init routine for OMAP4+ devices + * + * Initializes all powerdomain and clockdomain target states + * and all PRCM settings. + * Return: Returns the error code returned by called functions. + */ +int __init omap4_pm_init(void) +{ + int ret = 0; + + if (omap_rev() == OMAP4430_REV_ES1_0) { + WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); + return -ENODEV; + } + + pr_info("Power Management for TI OMAP4+ devices.\n"); + + ret = pwrdm_for_each(pwrdms_setup, NULL); + if (ret) { + pr_err("Failed to setup powerdomains.\n"); + goto err2; + } + + if (cpu_is_omap44xx()) { + ret = omap4_init_static_deps(); + if (ret) + goto err2; + } + + ret = omap4_mpuss_init(); + if (ret) { + pr_err("Failed to initialise OMAP4 MPUSS\n"); + goto err2; + } + + (void) clkdm_for_each(omap_pm_clkdms_setup, NULL); + + omap_common_suspend_init(omap4_pm_suspend); + + /* Overwrite the default cpu_do_idle() */ + arm_pm_idle = omap_default_idle; + + if (cpu_is_omap44xx()) + omap4_idle_init(); + +err2: + return ret; +} diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c new file mode 100644 index 00000000000..33c8846b419 --- /dev/null +++ b/arch/arm/mach-omap2/pmu.c @@ -0,0 +1,96 @@ +/* + * OMAP2 ARM Performance Monitoring Unit (PMU) Support + * + * Copyright (C) 2012 Texas Instruments, Inc. + * + * Contacts: + * Jon Hunter <jon-hunter@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include <linux/of.h> + +#include <asm/pmu.h> + +#include "soc.h" +#include "omap_hwmod.h" +#include "omap_device.h" + +static char *omap2_pmu_oh_names[] = {"mpu"}; +static char *omap3_pmu_oh_names[] = {"mpu", "debugss"}; +static char *omap4430_pmu_oh_names[] = {"l3_main_3", "l3_instr", "debugss"}; +static struct platform_device *omap_pmu_dev; + +/** + * omap2_init_pmu - creates and registers PMU platform device + * @oh_num: Number of OMAP HWMODs required to create PMU device + * @oh_names: Array of OMAP HWMODS names required to create PMU device + * + * Uses OMAP HWMOD framework to create and register an ARM PMU device + * from a list of HWMOD names passed. Currently supports OMAP2, OMAP3 + * and OMAP4 devices. + */ +static int __init omap2_init_pmu(unsigned oh_num, char *oh_names[]) +{ + int i; + struct omap_hwmod *oh[3]; + char *dev_name = "arm-pmu"; + + if ((!oh_num) || (oh_num > 3)) + return -EINVAL; + + for (i = 0; i < oh_num; i++) { + oh[i] = omap_hwmod_lookup(oh_names[i]); + if (!oh[i]) { + pr_err("Could not look up %s hwmod\n", oh_names[i]); + return -ENODEV; + } + } + + omap_pmu_dev = omap_device_build_ss(dev_name, -1, oh, oh_num, NULL, 0); + WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n", + dev_name); + + return PTR_RET(omap_pmu_dev); +} + +static int __init omap_init_pmu(void) +{ + unsigned oh_num; + char **oh_names; + + /* XXX Remove this check when the CTI driver is available */ + if (cpu_is_omap443x()) { + pr_info("ARM PMU: not yet supported on OMAP4430 due to missing CTI driver\n"); + return 0; + } + + if (of_have_populated_dt()) + return 0; + + /* + * To create an ARM-PMU device the following HWMODs + * are required for the various OMAP2+ devices. + * + * OMAP24xx: mpu + * OMAP3xxx: mpu, debugss + * OMAP4430: l3_main_3, l3_instr, debugss + * OMAP4460/70: mpu, debugss + */ + if (cpu_is_omap443x()) { + oh_num = ARRAY_SIZE(omap4430_pmu_oh_names); + oh_names = omap4430_pmu_oh_names; + } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) { + oh_num = ARRAY_SIZE(omap3_pmu_oh_names); + oh_names = omap3_pmu_oh_names; + } else { + oh_num = ARRAY_SIZE(omap2_pmu_oh_names); + oh_names = omap2_pmu_oh_names; + } + + return omap2_init_pmu(oh_num, oh_names); +} +omap_subsys_initcall(omap_init_pmu); diff --git a/arch/arm/mach-omap2/powerdomain-common.c b/arch/arm/mach-omap2/powerdomain-common.c new file mode 100644 index 00000000000..c40e5f00982 --- /dev/null +++ b/arch/arm/mach-omap2/powerdomain-common.c @@ -0,0 +1,109 @@ +/* + * Common powerdomain framework functions + * + * Copyright (C) 2010-2011 Texas Instruments, Inc. + * Copyright (C) 2010 Nokia Corporation + * + * Derived from mach-omap2/powerdomain.c written by Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/bug.h> +#include "pm.h" +#include "cm.h" +#include "cm-regbits-34xx.h" +#include "prm-regbits-34xx.h" +#include "prm-regbits-44xx.h" + +/* + * OMAP3 and OMAP4 specific register bit initialisations + * Notice that the names here are not according to each power + * domain but the bit mapping used applies to all of them + */ +/* OMAP3 and OMAP4 Memory Onstate Masks (common across all power domains) */ +#define OMAP_MEM0_ONSTATE_MASK OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK +#define OMAP_MEM1_ONSTATE_MASK OMAP3430_L1FLATMEMONSTATE_MASK +#define OMAP_MEM2_ONSTATE_MASK OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK +#define OMAP_MEM3_ONSTATE_MASK OMAP3430_L2FLATMEMONSTATE_MASK +#define OMAP_MEM4_ONSTATE_MASK OMAP4430_OCP_NRET_BANK_ONSTATE_MASK + +/* OMAP3 and OMAP4 Memory Retstate Masks (common across all power domains) */ +#define OMAP_MEM0_RETSTATE_MASK OMAP3430_SHAREDL1CACHEFLATRETSTATE_MASK +#define OMAP_MEM1_RETSTATE_MASK OMAP3430_L1FLATMEMRETSTATE_MASK +#define OMAP_MEM2_RETSTATE_MASK OMAP3430_SHAREDL2CACHEFLATRETSTATE_MASK +#define OMAP_MEM3_RETSTATE_MASK OMAP3430_L2FLATMEMRETSTATE_MASK +#define OMAP_MEM4_RETSTATE_MASK OMAP4430_OCP_NRET_BANK_RETSTATE_MASK + +/* OMAP3 and OMAP4 Memory Status bits */ +#define OMAP_MEM0_STATEST_MASK OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK +#define OMAP_MEM1_STATEST_MASK OMAP3430_L1FLATMEMSTATEST_MASK +#define OMAP_MEM2_STATEST_MASK OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK +#define OMAP_MEM3_STATEST_MASK OMAP3430_L2FLATMEMSTATEST_MASK +#define OMAP_MEM4_STATEST_MASK OMAP4430_OCP_NRET_BANK_STATEST_MASK + +/* Common Internal functions used across OMAP rev's*/ +u32 omap2_pwrdm_get_mem_bank_onstate_mask(u8 bank) +{ + switch (bank) { + case 0: + return OMAP_MEM0_ONSTATE_MASK; + case 1: + return OMAP_MEM1_ONSTATE_MASK; + case 2: + return OMAP_MEM2_ONSTATE_MASK; + case 3: + return OMAP_MEM3_ONSTATE_MASK; + case 4: + return OMAP_MEM4_ONSTATE_MASK; + default: + WARN_ON(1); /* should never happen */ + return -EEXIST; + } + return 0; +} + +u32 omap2_pwrdm_get_mem_bank_retst_mask(u8 bank) +{ + switch (bank) { + case 0: + return OMAP_MEM0_RETSTATE_MASK; + case 1: + return OMAP_MEM1_RETSTATE_MASK; + case 2: + return OMAP_MEM2_RETSTATE_MASK; + case 3: + return OMAP_MEM3_RETSTATE_MASK; + case 4: + return OMAP_MEM4_RETSTATE_MASK; + default: + WARN_ON(1); /* should never happen */ + return -EEXIST; + } + return 0; +} + +u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank) +{ + switch (bank) { + case 0: + return OMAP_MEM0_STATEST_MASK; + case 1: + return OMAP_MEM1_STATEST_MASK; + case 2: + return OMAP_MEM2_STATEST_MASK; + case 3: + return OMAP_MEM3_STATEST_MASK; + case 4: + return OMAP_MEM4_STATEST_MASK; + default: + WARN_ON(1); /* should never happen */ + return -EEXIST; + } + return 0; +} + diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 73e2971b175..faebd5f076a 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -1,62 +1,65 @@ /* * OMAP powerdomain control * - * Copyright (C) 2007-2008 Texas Instruments, Inc. - * Copyright (C) 2007-2008 Nokia Corporation + * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc. + * Copyright (C) 2007-2011 Nokia Corporation * * Written by Paul Walmsley + * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com> + * State counting code by Tero Kristo <tero.kristo@nokia.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#ifdef CONFIG_OMAP_DEBUG_POWERDOMAIN -# define DEBUG -#endif +#undef DEBUG #include <linux/kernel.h> -#include <linux/module.h> #include <linux/types.h> -#include <linux/delay.h> -#include <linux/spinlock.h> #include <linux/list.h> #include <linux/errno.h> -#include <linux/err.h> -#include <linux/io.h> +#include <linux/string.h> +#include <linux/spinlock.h> +#include <trace/events/power.h> -#include <asm/atomic.h> +#include "cm2xxx_3xxx.h" +#include "prcm44xx.h" +#include "cm44xx.h" +#include "prm2xxx_3xxx.h" +#include "prm44xx.h" -#include "cm.h" -#include "cm-regbits-34xx.h" -#include "prm.h" -#include "prm-regbits-34xx.h" +#include <asm/cpu.h> -#include <mach/cpu.h> -#include <mach/powerdomain.h> -#include <mach/clockdomain.h> +#include "powerdomain.h" +#include "clockdomain.h" +#include "voltage.h" -/* pwrdm_list contains all registered struct powerdomains */ -static LIST_HEAD(pwrdm_list); +#include "soc.h" +#include "pm.h" -/* - * pwrdm_rwlock protects pwrdm_list add and del ops - also reused to - * protect pwrdm_clkdms[] during clkdm add/del ops - */ -static DEFINE_RWLOCK(pwrdm_rwlock); +#define PWRDM_TRACE_STATES_FLAG (1<<31) +enum { + PWRDM_STATE_NOW = 0, + PWRDM_STATE_PREV, +}; -/* Private functions */ +/* + * Types of sleep_switch used internally in omap_set_pwrdm_state() + * and its associated static functions + * + * XXX Better documentation is needed here + */ +#define ALREADYACTIVE_SWITCH 0 +#define FORCEWAKEUP_SWITCH 1 +#define LOWPOWERSTATE_SWITCH 2 -static u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask) -{ - u32 v; +/* pwrdm_list contains all registered struct powerdomains */ +static LIST_HEAD(pwrdm_list); - v = prm_read_mod_reg(domain, idx); - v &= mask; - v >>= __ffs(mask); +static struct pwrdm_ops *arch_pwrdm; - return v; -} +/* Private functions */ static struct powerdomain *_pwrdm_lookup(const char *name) { @@ -74,131 +77,332 @@ static struct powerdomain *_pwrdm_lookup(const char *name) return pwrdm; } -/* _pwrdm_deps_lookup - look up the specified powerdomain in a pwrdm list */ -static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm, - struct pwrdm_dep *deps) +/** + * _pwrdm_register - register a powerdomain + * @pwrdm: struct powerdomain * to register + * + * Adds a powerdomain to the internal powerdomain list. Returns + * -EINVAL if given a null pointer, -EEXIST if a powerdomain is + * already registered by the provided name, or 0 upon success. + */ +static int _pwrdm_register(struct powerdomain *pwrdm) +{ + int i; + struct voltagedomain *voltdm; + + if (!pwrdm || !pwrdm->name) + return -EINVAL; + + if (cpu_is_omap44xx() && + pwrdm->prcm_partition == OMAP4430_INVALID_PRCM_PARTITION) { + pr_err("powerdomain: %s: missing OMAP4 PRCM partition ID\n", + pwrdm->name); + return -EINVAL; + } + + if (_pwrdm_lookup(pwrdm->name)) + return -EEXIST; + + if (arch_pwrdm && arch_pwrdm->pwrdm_has_voltdm) + if (!arch_pwrdm->pwrdm_has_voltdm()) + goto skip_voltdm; + + voltdm = voltdm_lookup(pwrdm->voltdm.name); + if (!voltdm) { + pr_err("powerdomain: %s: voltagedomain %s does not exist\n", + pwrdm->name, pwrdm->voltdm.name); + return -EINVAL; + } + pwrdm->voltdm.ptr = voltdm; + INIT_LIST_HEAD(&pwrdm->voltdm_node); + voltdm_add_pwrdm(voltdm, pwrdm); +skip_voltdm: + spin_lock_init(&pwrdm->_lock); + + list_add(&pwrdm->node, &pwrdm_list); + + /* Initialize the powerdomain's state counter */ + for (i = 0; i < PWRDM_MAX_PWRSTS; i++) + pwrdm->state_counter[i] = 0; + + pwrdm->ret_logic_off_counter = 0; + for (i = 0; i < pwrdm->banks; i++) + pwrdm->ret_mem_off_counter[i] = 0; + + if (arch_pwrdm && arch_pwrdm->pwrdm_wait_transition) + arch_pwrdm->pwrdm_wait_transition(pwrdm); + pwrdm->state = pwrdm_read_pwrst(pwrdm); + pwrdm->state_counter[pwrdm->state] = 1; + + pr_debug("powerdomain: registered %s\n", pwrdm->name); + + return 0; +} + +static void _update_logic_membank_counters(struct powerdomain *pwrdm) { - struct pwrdm_dep *pd; + int i; + u8 prev_logic_pwrst, prev_mem_pwrst; - if (!pwrdm || !deps || !omap_chip_is(pwrdm->omap_chip)) - return ERR_PTR(-EINVAL); + prev_logic_pwrst = pwrdm_read_prev_logic_pwrst(pwrdm); + if ((pwrdm->pwrsts_logic_ret == PWRSTS_OFF_RET) && + (prev_logic_pwrst == PWRDM_POWER_OFF)) + pwrdm->ret_logic_off_counter++; - for (pd = deps; pd; pd++) { + for (i = 0; i < pwrdm->banks; i++) { + prev_mem_pwrst = pwrdm_read_prev_mem_pwrst(pwrdm, i); - if (!omap_chip_is(pd->omap_chip)) - continue; + if ((pwrdm->pwrsts_mem_ret[i] == PWRSTS_OFF_RET) && + (prev_mem_pwrst == PWRDM_POWER_OFF)) + pwrdm->ret_mem_off_counter[i]++; + } +} + +static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) +{ - if (!pd->pwrdm && pd->pwrdm_name) - pd->pwrdm = pwrdm_lookup(pd->pwrdm_name); + int prev, next, state, trace_state = 0; - if (pd->pwrdm == pwrdm) - break; + if (pwrdm == NULL) + return -EINVAL; + state = pwrdm_read_pwrst(pwrdm); + + switch (flag) { + case PWRDM_STATE_NOW: + prev = pwrdm->state; + break; + case PWRDM_STATE_PREV: + prev = pwrdm_read_prev_pwrst(pwrdm); + if (pwrdm->state != prev) + pwrdm->state_counter[prev]++; + if (prev == PWRDM_POWER_RET) + _update_logic_membank_counters(pwrdm); + /* + * If the power domain did not hit the desired state, + * generate a trace event with both the desired and hit states + */ + next = pwrdm_read_next_pwrst(pwrdm); + if (next != prev) { + trace_state = (PWRDM_TRACE_STATES_FLAG | + ((next & OMAP_POWERSTATE_MASK) << 8) | + ((prev & OMAP_POWERSTATE_MASK) << 0)); + trace_power_domain_target(pwrdm->name, trace_state, + smp_processor_id()); + } + break; + default: + return -EINVAL; } - if (!pd) - return ERR_PTR(-ENOENT); + if (state != prev) + pwrdm->state_counter[state]++; + + pm_dbg_update_time(pwrdm, prev); - return pd->pwrdm; + pwrdm->state = state; + + return 0; } +static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused) +{ + pwrdm_clear_all_prev_pwrst(pwrdm); + _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); + return 0; +} -/* Public functions */ +static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused) +{ + _pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV); + return 0; +} /** - * pwrdm_init - set up the powerdomain layer + * _pwrdm_save_clkdm_state_and_activate - prepare for power state change + * @pwrdm: struct powerdomain * to operate on + * @curr_pwrst: current power state of @pwrdm + * @pwrst: power state to switch to + * @hwsup: ptr to a bool to return whether the clkdm is hardware-supervised * - * Loop through the list of powerdomains, registering all that are - * available on the current CPU. If pwrdm_list is supplied and not - * null, all of the referenced powerdomains will be registered. No - * return value. + * Determine whether the powerdomain needs to be turned on before + * attempting to switch power states. Called by + * omap_set_pwrdm_state(). NOTE that if the powerdomain contains + * multiple clockdomains, this code assumes that the first clockdomain + * supports software-supervised wakeup mode - potentially a problem. + * Returns the power state switch mode currently in use (see the + * "Types of sleep_switch" comment above). */ -void pwrdm_init(struct powerdomain **pwrdm_list) +static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm, + u8 curr_pwrst, u8 pwrst, + bool *hwsup) { - struct powerdomain **p = NULL; + u8 sleep_switch; + + if (curr_pwrst < PWRDM_POWER_ON) { + if (curr_pwrst > pwrst && + pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE && + arch_pwrdm->pwrdm_set_lowpwrstchange) { + sleep_switch = LOWPOWERSTATE_SWITCH; + } else { + *hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]); + clkdm_wakeup_nolock(pwrdm->pwrdm_clkdms[0]); + sleep_switch = FORCEWAKEUP_SWITCH; + } + } else { + sleep_switch = ALREADYACTIVE_SWITCH; + } - if (pwrdm_list) - for (p = pwrdm_list; *p; p++) - pwrdm_register(*p); + return sleep_switch; } /** - * pwrdm_register - register a powerdomain - * @pwrdm: struct powerdomain * to register + * _pwrdm_restore_clkdm_state - restore the clkdm hwsup state after pwrst change + * @pwrdm: struct powerdomain * to operate on + * @sleep_switch: return value from _pwrdm_save_clkdm_state_and_activate() + * @hwsup: should @pwrdm's first clockdomain be set to hardware-supervised mode? * - * Adds a powerdomain to the internal powerdomain list. Returns - * -EINVAL if given a null pointer, -EEXIST if a powerdomain is - * already registered by the provided name, or 0 upon success. + * Restore the clockdomain state perturbed by + * _pwrdm_save_clkdm_state_and_activate(), and call the power state + * bookkeeping code. Called by omap_set_pwrdm_state(). NOTE that if + * the powerdomain contains multiple clockdomains, this assumes that + * the first associated clockdomain supports either + * hardware-supervised idle control in the register, or + * software-supervised sleep. No return value. */ -int pwrdm_register(struct powerdomain *pwrdm) +static void _pwrdm_restore_clkdm_state(struct powerdomain *pwrdm, + u8 sleep_switch, bool hwsup) { - unsigned long flags; - int ret = -EINVAL; + switch (sleep_switch) { + case FORCEWAKEUP_SWITCH: + if (hwsup) + clkdm_allow_idle_nolock(pwrdm->pwrdm_clkdms[0]); + else + clkdm_sleep_nolock(pwrdm->pwrdm_clkdms[0]); + break; + case LOWPOWERSTATE_SWITCH: + if (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE && + arch_pwrdm->pwrdm_set_lowpwrstchange) + arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm); + pwrdm_state_switch_nolock(pwrdm); + break; + } +} - if (!pwrdm) - return -EINVAL; +/* Public functions */ - if (!omap_chip_is(pwrdm->omap_chip)) +/** + * pwrdm_register_platform_funcs - register powerdomain implementation fns + * @po: func pointers for arch specific implementations + * + * Register the list of function pointers used to implement the + * powerdomain functions on different OMAP SoCs. Should be called + * before any other pwrdm_register*() function. Returns -EINVAL if + * @po is null, -EEXIST if platform functions have already been + * registered, or 0 upon success. + */ +int pwrdm_register_platform_funcs(struct pwrdm_ops *po) +{ + if (!po) return -EINVAL; - write_lock_irqsave(&pwrdm_rwlock, flags); - if (_pwrdm_lookup(pwrdm->name)) { - ret = -EEXIST; - goto pr_unlock; - } - - list_add(&pwrdm->node, &pwrdm_list); - - pr_debug("powerdomain: registered %s\n", pwrdm->name); - ret = 0; + if (arch_pwrdm) + return -EEXIST; -pr_unlock: - write_unlock_irqrestore(&pwrdm_rwlock, flags); + arch_pwrdm = po; - return ret; + return 0; } /** - * pwrdm_unregister - unregister a powerdomain - * @pwrdm: struct powerdomain * to unregister + * pwrdm_register_pwrdms - register SoC powerdomains + * @ps: pointer to an array of struct powerdomain to register * - * Removes a powerdomain from the internal powerdomain list. Returns - * -EINVAL if pwrdm argument is NULL. + * Register the powerdomains available on a particular OMAP SoC. Must + * be called after pwrdm_register_platform_funcs(). May be called + * multiple times. Returns -EACCES if called before + * pwrdm_register_platform_funcs(); -EINVAL if the argument @ps is + * null; or 0 upon success. */ -int pwrdm_unregister(struct powerdomain *pwrdm) +int pwrdm_register_pwrdms(struct powerdomain **ps) { - unsigned long flags; + struct powerdomain **p = NULL; - if (!pwrdm) + if (!arch_pwrdm) + return -EEXIST; + + if (!ps) return -EINVAL; - write_lock_irqsave(&pwrdm_rwlock, flags); - list_del(&pwrdm->node); - write_unlock_irqrestore(&pwrdm_rwlock, flags); + for (p = ps; *p; p++) + _pwrdm_register(*p); - pr_debug("powerdomain: unregistered %s\n", pwrdm->name); + return 0; +} + +/** + * pwrdm_complete_init - set up the powerdomain layer + * + * Do whatever is necessary to initialize registered powerdomains and + * powerdomain code. Currently, this programs the next power state + * for each powerdomain to ON. This prevents powerdomains from + * unexpectedly losing context or entering high wakeup latency modes + * with non-power-management-enabled kernels. Must be called after + * pwrdm_register_pwrdms(). Returns -EACCES if called before + * pwrdm_register_pwrdms(), or 0 upon success. + */ +int pwrdm_complete_init(void) +{ + struct powerdomain *temp_p; + + if (list_empty(&pwrdm_list)) + return -EACCES; + + list_for_each_entry(temp_p, &pwrdm_list, node) + pwrdm_set_next_pwrst(temp_p, PWRDM_POWER_ON); return 0; } /** + * pwrdm_lock - acquire a Linux spinlock on a powerdomain + * @pwrdm: struct powerdomain * to lock + * + * Acquire the powerdomain spinlock on @pwrdm. No return value. + */ +void pwrdm_lock(struct powerdomain *pwrdm) + __acquires(&pwrdm->_lock) +{ + spin_lock_irqsave(&pwrdm->_lock, pwrdm->_lock_flags); +} + +/** + * pwrdm_unlock - release a Linux spinlock on a powerdomain + * @pwrdm: struct powerdomain * to unlock + * + * Release the powerdomain spinlock on @pwrdm. No return value. + */ +void pwrdm_unlock(struct powerdomain *pwrdm) + __releases(&pwrdm->_lock) +{ + spin_unlock_irqrestore(&pwrdm->_lock, pwrdm->_lock_flags); +} + +/** * pwrdm_lookup - look up a powerdomain by name, return a pointer * @name: name of powerdomain * - * Find a registered powerdomain by its name. Returns a pointer to the - * struct powerdomain if found, or NULL otherwise. + * Find a registered powerdomain by its name @name. Returns a pointer + * to the struct powerdomain if found, or NULL otherwise. */ struct powerdomain *pwrdm_lookup(const char *name) { struct powerdomain *pwrdm; - unsigned long flags; if (!name) return NULL; - read_lock_irqsave(&pwrdm_rwlock, flags); pwrdm = _pwrdm_lookup(name); - read_unlock_irqrestore(&pwrdm_rwlock, flags); return pwrdm; } @@ -207,32 +411,26 @@ struct powerdomain *pwrdm_lookup(const char *name) * pwrdm_for_each - call function on each registered clockdomain * @fn: callback function * * - * Call the supplied function for each registered powerdomain. The - * callback function can return anything but 0 to bail out early from - * the iterator. The callback function is called with the pwrdm_rwlock - * held for reading, so no powerdomain structure manipulation - * functions should be called from the callback, although hardware - * powerdomain control functions are fine. Returns the last return - * value of the callback function, which should be 0 for success or - * anything else to indicate failure; or -EINVAL if the function - * pointer is null. + * Call the supplied function @fn for each registered powerdomain. + * The callback function @fn can return anything but 0 to bail out + * early from the iterator. Returns the last return value of the + * callback function, which should be 0 for success or anything else + * to indicate failure; or -EINVAL if the function pointer is null. */ -int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm)) +int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user), + void *user) { struct powerdomain *temp_pwrdm; - unsigned long flags; int ret = 0; if (!fn) return -EINVAL; - read_lock_irqsave(&pwrdm_rwlock, flags); list_for_each_entry(temp_pwrdm, &pwrdm_list, node) { - ret = (*fn)(temp_pwrdm); + ret = (*fn)(temp_pwrdm, user); if (ret) break; } - read_unlock_irqrestore(&pwrdm_rwlock, flags); return ret; } @@ -242,24 +440,21 @@ int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm)) * @pwrdm: struct powerdomain * to add the clockdomain to * @clkdm: struct clockdomain * to associate with a powerdomain * - * Associate the clockdomain 'clkdm' with a powerdomain 'pwrdm'. This + * Associate the clockdomain @clkdm with a powerdomain @pwrdm. This * enables the use of pwrdm_for_each_clkdm(). Returns -EINVAL if * presented with invalid pointers; -ENOMEM if memory could not be allocated; * or 0 upon success. */ int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) { - unsigned long flags; int i; int ret = -EINVAL; if (!pwrdm || !clkdm) return -EINVAL; - pr_debug("powerdomain: associating clockdomain %s with powerdomain " - "%s\n", clkdm->name, pwrdm->name); - - write_lock_irqsave(&pwrdm_rwlock, flags); + pr_debug("powerdomain: %s: associating clockdomain %s\n", + pwrdm->name, clkdm->name); for (i = 0; i < PWRDM_MAX_CLKDMS; i++) { if (!pwrdm->pwrdm_clkdms[i]) @@ -273,8 +468,8 @@ int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) } if (i == PWRDM_MAX_CLKDMS) { - pr_debug("powerdomain: increase PWRDM_MAX_CLKDMS for " - "pwrdm %s clkdm %s\n", pwrdm->name, clkdm->name); + pr_debug("powerdomain: %s: increase PWRDM_MAX_CLKDMS for clkdm %s\n", + pwrdm->name, clkdm->name); WARN_ON(1); ret = -ENOMEM; goto pac_exit; @@ -285,8 +480,6 @@ int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) ret = 0; pac_exit: - write_unlock_irqrestore(&pwrdm_rwlock, flags); - return ret; } @@ -295,32 +488,29 @@ pac_exit: * @pwrdm: struct powerdomain * to add the clockdomain to * @clkdm: struct clockdomain * to associate with a powerdomain * - * Dissociate the clockdomain 'clkdm' from the powerdomain - * 'pwrdm'. Returns -EINVAL if presented with invalid pointers; - * -ENOENT if the clkdm was not associated with the powerdomain, or 0 - * upon success. + * Dissociate the clockdomain @clkdm from the powerdomain + * @pwrdm. Returns -EINVAL if presented with invalid pointers; -ENOENT + * if @clkdm was not associated with the powerdomain, or 0 upon + * success. */ int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) { - unsigned long flags; int ret = -EINVAL; int i; if (!pwrdm || !clkdm) return -EINVAL; - pr_debug("powerdomain: dissociating clockdomain %s from powerdomain " - "%s\n", clkdm->name, pwrdm->name); - - write_lock_irqsave(&pwrdm_rwlock, flags); + pr_debug("powerdomain: %s: dissociating clockdomain %s\n", + pwrdm->name, clkdm->name); for (i = 0; i < PWRDM_MAX_CLKDMS; i++) if (pwrdm->pwrdm_clkdms[i] == clkdm) break; if (i == PWRDM_MAX_CLKDMS) { - pr_debug("powerdomain: clkdm %s not associated with pwrdm " - "%s ?!\n", clkdm->name, pwrdm->name); + pr_debug("powerdomain: %s: clkdm %s not associated?!\n", + pwrdm->name, clkdm->name); ret = -ENOENT; goto pdc_exit; } @@ -330,8 +520,6 @@ int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) ret = 0; pdc_exit: - write_unlock_irqrestore(&pwrdm_rwlock, flags); - return ret; } @@ -340,259 +528,46 @@ pdc_exit: * @pwrdm: struct powerdomain * to iterate over * @fn: callback function * * - * Call the supplied function for each clockdomain in the powerdomain - * 'pwrdm'. The callback function can return anything but 0 to bail - * out early from the iterator. The callback function is called with - * the pwrdm_rwlock held for reading, so no powerdomain structure - * manipulation functions should be called from the callback, although - * hardware powerdomain control functions are fine. Returns -EINVAL - * if presented with invalid pointers; or passes along the last return - * value of the callback function, which should be 0 for success or - * anything else to indicate failure. + * Call the supplied function @fn for each clockdomain in the powerdomain + * @pwrdm. The callback function can return anything but 0 to bail + * out early from the iterator. Returns -EINVAL if presented with + * invalid pointers; or passes along the last return value of the + * callback function, which should be 0 for success or anything else + * to indicate failure. */ int pwrdm_for_each_clkdm(struct powerdomain *pwrdm, int (*fn)(struct powerdomain *pwrdm, struct clockdomain *clkdm)) { - unsigned long flags; int ret = 0; int i; if (!fn) return -EINVAL; - read_lock_irqsave(&pwrdm_rwlock, flags); - for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++) ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]); - read_unlock_irqrestore(&pwrdm_rwlock, flags); - return ret; } - -/** - * pwrdm_add_wkdep - add a wakeup dependency from pwrdm2 to pwrdm1 - * @pwrdm1: wake this struct powerdomain * up (dependent) - * @pwrdm2: when this struct powerdomain * wakes up (source) - * - * When the powerdomain represented by pwrdm2 wakes up (due to an - * interrupt), wake up pwrdm1. Implemented in hardware on the OMAP, - * this feature is designed to reduce wakeup latency of the dependent - * powerdomain. Returns -EINVAL if presented with invalid powerdomain - * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or - * 0 upon success. - */ -int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2) -{ - struct powerdomain *p; - - if (!pwrdm1) - return -EINVAL; - - p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs); - if (IS_ERR(p)) { - pr_debug("powerdomain: hardware cannot set/clear wake up of " - "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name); - return IS_ERR(p); - } - - pr_debug("powerdomain: hardware will wake up %s when %s wakes up\n", - pwrdm1->name, pwrdm2->name); - - prm_set_mod_reg_bits((1 << pwrdm2->dep_bit), - pwrdm1->prcm_offs, PM_WKDEP); - - return 0; -} - /** - * pwrdm_del_wkdep - remove a wakeup dependency from pwrdm2 to pwrdm1 - * @pwrdm1: wake this struct powerdomain * up (dependent) - * @pwrdm2: when this struct powerdomain * wakes up (source) - * - * Remove a wakeup dependency that causes pwrdm1 to wake up when pwrdm2 - * wakes up. Returns -EINVAL if presented with invalid powerdomain - * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or - * 0 upon success. - */ -int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2) -{ - struct powerdomain *p; - - if (!pwrdm1) - return -EINVAL; - - p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs); - if (IS_ERR(p)) { - pr_debug("powerdomain: hardware cannot set/clear wake up of " - "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name); - return IS_ERR(p); - } - - pr_debug("powerdomain: hardware will no longer wake up %s after %s " - "wakes up\n", pwrdm1->name, pwrdm2->name); - - prm_clear_mod_reg_bits((1 << pwrdm2->dep_bit), - pwrdm1->prcm_offs, PM_WKDEP); - - return 0; -} - -/** - * pwrdm_read_wkdep - read wakeup dependency state from pwrdm2 to pwrdm1 - * @pwrdm1: wake this struct powerdomain * up (dependent) - * @pwrdm2: when this struct powerdomain * wakes up (source) - * - * Return 1 if a hardware wakeup dependency exists wherein pwrdm1 will be - * awoken when pwrdm2 wakes up; 0 if dependency is not set; -EINVAL - * if either powerdomain pointer is invalid; or -ENOENT if the hardware - * is incapable. - * - * REVISIT: Currently this function only represents software-controllable - * wakeup dependencies. Wakeup dependencies fixed in hardware are not - * yet handled here. - */ -int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2) -{ - struct powerdomain *p; - - if (!pwrdm1) - return -EINVAL; - - p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs); - if (IS_ERR(p)) { - pr_debug("powerdomain: hardware cannot set/clear wake up of " - "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name); - return IS_ERR(p); - } - - return prm_read_mod_bits_shift(pwrdm1->prcm_offs, PM_WKDEP, - (1 << pwrdm2->dep_bit)); -} - -/** - * pwrdm_add_sleepdep - add a sleep dependency from pwrdm2 to pwrdm1 - * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent) - * @pwrdm2: when this struct powerdomain * is active (source) - * - * Prevent pwrdm1 from automatically going inactive (and then to - * retention or off) if pwrdm2 is still active. Returns -EINVAL if - * presented with invalid powerdomain pointers or called on a machine - * that does not support software-configurable hardware sleep dependencies, - * -ENOENT if the specified dependency cannot be set in hardware, or - * 0 upon success. - */ -int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2) -{ - struct powerdomain *p; - - if (!pwrdm1) - return -EINVAL; - - if (!cpu_is_omap34xx()) - return -EINVAL; - - p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs); - if (IS_ERR(p)) { - pr_debug("powerdomain: hardware cannot set/clear sleep " - "dependency affecting %s from %s\n", pwrdm1->name, - pwrdm2->name); - return IS_ERR(p); - } - - pr_debug("powerdomain: will prevent %s from sleeping if %s is active\n", - pwrdm1->name, pwrdm2->name); - - cm_set_mod_reg_bits((1 << pwrdm2->dep_bit), - pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP); - - return 0; -} - -/** - * pwrdm_del_sleepdep - remove a sleep dependency from pwrdm2 to pwrdm1 - * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent) - * @pwrdm2: when this struct powerdomain * is active (source) - * - * Allow pwrdm1 to automatically go inactive (and then to retention or - * off), independent of the activity state of pwrdm2. Returns -EINVAL - * if presented with invalid powerdomain pointers or called on a machine - * that does not support software-configurable hardware sleep dependencies, - * -ENOENT if the specified dependency cannot be cleared in hardware, or - * 0 upon success. - */ -int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2) -{ - struct powerdomain *p; - - if (!pwrdm1) - return -EINVAL; - - if (!cpu_is_omap34xx()) - return -EINVAL; - - p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs); - if (IS_ERR(p)) { - pr_debug("powerdomain: hardware cannot set/clear sleep " - "dependency affecting %s from %s\n", pwrdm1->name, - pwrdm2->name); - return IS_ERR(p); - } - - pr_debug("powerdomain: will no longer prevent %s from sleeping if " - "%s is active\n", pwrdm1->name, pwrdm2->name); - - cm_clear_mod_reg_bits((1 << pwrdm2->dep_bit), - pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP); - - return 0; -} - -/** - * pwrdm_read_sleepdep - read sleep dependency state from pwrdm2 to pwrdm1 - * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent) - * @pwrdm2: when this struct powerdomain * is active (source) - * - * Return 1 if a hardware sleep dependency exists wherein pwrdm1 will - * not be allowed to automatically go inactive if pwrdm2 is active; - * 0 if pwrdm1's automatic power state inactivity transition is independent - * of pwrdm2's; -EINVAL if either powerdomain pointer is invalid or called - * on a machine that does not support software-configurable hardware sleep - * dependencies; or -ENOENT if the hardware is incapable. + * pwrdm_get_voltdm - return a ptr to the voltdm that this pwrdm resides in + * @pwrdm: struct powerdomain * * - * REVISIT: Currently this function only represents software-controllable - * sleep dependencies. Sleep dependencies fixed in hardware are not - * yet handled here. + * Return a pointer to the struct voltageomain that the specified powerdomain + * @pwrdm exists in. */ -int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2) +struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm) { - struct powerdomain *p; - - if (!pwrdm1) - return -EINVAL; - - if (!cpu_is_omap34xx()) - return -EINVAL; - - p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs); - if (IS_ERR(p)) { - pr_debug("powerdomain: hardware cannot set/clear sleep " - "dependency affecting %s from %s\n", pwrdm1->name, - pwrdm2->name); - return IS_ERR(p); - } - - return prm_read_mod_bits_shift(pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP, - (1 << pwrdm2->dep_bit)); + return pwrdm->voltdm.ptr; } /** * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain * @pwrdm: struct powerdomain * * - * Return the number of controllable memory banks in powerdomain pwrdm, + * Return the number of controllable memory banks in powerdomain @pwrdm, * starting with 1. Returns -EINVAL if the powerdomain pointer is null. */ int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm) @@ -608,7 +583,7 @@ int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm) * @pwrdm: struct powerdomain * to set * @pwrst: one of the PWRDM_POWER_* macros * - * Set the powerdomain pwrdm's next power state to pwrst. The powerdomain + * Set the powerdomain @pwrdm's next power state to @pwrst. The powerdomain * may not enter this state immediately if the preconditions for this state * have not been satisfied. Returns -EINVAL if the powerdomain pointer is * null or if the power state is invalid for the powerdomin, or returns 0 @@ -616,71 +591,93 @@ int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm) */ int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) { + int ret = -EINVAL; + if (!pwrdm) return -EINVAL; if (!(pwrdm->pwrsts & (1 << pwrst))) return -EINVAL; - pr_debug("powerdomain: setting next powerstate for %s to %0x\n", + pr_debug("powerdomain: %s: setting next powerstate to %0x\n", pwrdm->name, pwrst); - prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK, - (pwrst << OMAP_POWERSTATE_SHIFT), - pwrdm->prcm_offs, PM_PWSTCTRL); + if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst) { + /* Trace the pwrdm desired target state */ + trace_power_domain_target(pwrdm->name, pwrst, + smp_processor_id()); + /* Program the pwrdm desired target state */ + ret = arch_pwrdm->pwrdm_set_next_pwrst(pwrdm, pwrst); + } - return 0; + return ret; } /** * pwrdm_read_next_pwrst - get next powerdomain power state * @pwrdm: struct powerdomain * to get power state * - * Return the powerdomain pwrdm's next power state. Returns -EINVAL + * Return the powerdomain @pwrdm's next power state. Returns -EINVAL * if the powerdomain pointer is null or returns the next power state * upon success. */ int pwrdm_read_next_pwrst(struct powerdomain *pwrdm) { + int ret = -EINVAL; + if (!pwrdm) return -EINVAL; - return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTCTRL, - OMAP_POWERSTATE_MASK); + if (arch_pwrdm && arch_pwrdm->pwrdm_read_next_pwrst) + ret = arch_pwrdm->pwrdm_read_next_pwrst(pwrdm); + + return ret; } /** * pwrdm_read_pwrst - get current powerdomain power state * @pwrdm: struct powerdomain * to get power state * - * Return the powerdomain pwrdm's current power state. Returns -EINVAL + * Return the powerdomain @pwrdm's current power state. Returns -EINVAL * if the powerdomain pointer is null or returns the current power state - * upon success. + * upon success. Note that if the power domain only supports the ON state + * then just return ON as the current state. */ int pwrdm_read_pwrst(struct powerdomain *pwrdm) { + int ret = -EINVAL; + if (!pwrdm) return -EINVAL; - return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST, - OMAP_POWERSTATEST_MASK); + if (pwrdm->pwrsts == PWRSTS_ON) + return PWRDM_POWER_ON; + + if (arch_pwrdm && arch_pwrdm->pwrdm_read_pwrst) + ret = arch_pwrdm->pwrdm_read_pwrst(pwrdm); + + return ret; } /** * pwrdm_read_prev_pwrst - get previous powerdomain power state * @pwrdm: struct powerdomain * to get previous power state * - * Return the powerdomain pwrdm's previous power state. Returns -EINVAL + * Return the powerdomain @pwrdm's previous power state. Returns -EINVAL * if the powerdomain pointer is null or returns the previous power state * upon success. */ int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) { + int ret = -EINVAL; + if (!pwrdm) return -EINVAL; - return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST, - OMAP3430_LASTPOWERSTATEENTERED_MASK); + if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_pwrst) + ret = arch_pwrdm->pwrdm_read_prev_pwrst(pwrdm); + + return ret; } /** @@ -688,34 +685,29 @@ int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) * @pwrdm: struct powerdomain * to set * @pwrst: one of the PWRDM_POWER_* macros * - * Set the next power state that the logic portion of the powerdomain - * pwrdm will enter when the powerdomain enters retention. This will - * be either RETENTION or OFF, if supported. Returns -EINVAL if the - * powerdomain pointer is null or the target power state is not not - * supported, or returns 0 upon success. + * Set the next power state @pwrst that the logic portion of the + * powerdomain @pwrdm will enter when the powerdomain enters retention. + * This will be either RETENTION or OFF, if supported. Returns + * -EINVAL if the powerdomain pointer is null or the target power + * state is not not supported, or returns 0 upon success. */ int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) { + int ret = -EINVAL; + if (!pwrdm) return -EINVAL; if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst))) return -EINVAL; - pr_debug("powerdomain: setting next logic powerstate for %s to %0x\n", + pr_debug("powerdomain: %s: setting next logic powerstate to %0x\n", pwrdm->name, pwrst); - /* - * The register bit names below may not correspond to the - * actual names of the bits in each powerdomain's register, - * but the type of value returned is the same for each - * powerdomain. - */ - prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE, - (pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE)), - pwrdm->prcm_offs, PM_PWSTCTRL); + if (arch_pwrdm && arch_pwrdm->pwrdm_set_logic_retst) + ret = arch_pwrdm->pwrdm_set_logic_retst(pwrdm, pwrst); - return 0; + return ret; } /** @@ -724,17 +716,18 @@ int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) * @bank: memory bank number to set (0-3) * @pwrst: one of the PWRDM_POWER_* macros * - * Set the next power state that memory bank x of the powerdomain - * pwrdm will enter when the powerdomain enters the ON state. Bank - * will be a number from 0 to 3, and represents different types of - * memory, depending on the powerdomain. Returns -EINVAL if the - * powerdomain pointer is null or the target power state is not not - * supported for this memory bank, -EEXIST if the target memory bank - * does not exist or is not controllable, or returns 0 upon success. + * Set the next power state @pwrst that memory bank @bank of the + * powerdomain @pwrdm will enter when the powerdomain enters the ON + * state. @bank will be a number from 0 to 3, and represents different + * types of memory, depending on the powerdomain. Returns -EINVAL if + * the powerdomain pointer is null or the target power state is not + * not supported for this memory bank, -EEXIST if the target memory + * bank does not exist or is not controllable, or returns 0 upon + * success. */ int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) { - u32 m; + int ret = -EINVAL; if (!pwrdm) return -EINVAL; @@ -745,37 +738,13 @@ int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst))) return -EINVAL; - pr_debug("powerdomain: setting next memory powerstate for domain %s " - "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst); - - /* - * The register bit names below may not correspond to the - * actual names of the bits in each powerdomain's register, - * but the type of value returned is the same for each - * powerdomain. - */ - switch (bank) { - case 0: - m = OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK; - break; - case 1: - m = OMAP3430_L1FLATMEMONSTATE_MASK; - break; - case 2: - m = OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK; - break; - case 3: - m = OMAP3430_L2FLATMEMONSTATE_MASK; - break; - default: - WARN_ON(1); /* should never happen */ - return -EEXIST; - } + pr_debug("powerdomain: %s: setting next memory powerstate for bank %0x while pwrdm-ON to %0x\n", + pwrdm->name, bank, pwrst); - prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), - pwrdm->prcm_offs, PM_PWSTCTRL); + if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_onst) + ret = arch_pwrdm->pwrdm_set_mem_onst(pwrdm, bank, pwrst); - return 0; + return ret; } /** @@ -784,18 +753,19 @@ int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) * @bank: memory bank number to set (0-3) * @pwrst: one of the PWRDM_POWER_* macros * - * Set the next power state that memory bank x of the powerdomain - * pwrdm will enter when the powerdomain enters the RETENTION state. - * Bank will be a number from 0 to 3, and represents different types - * of memory, depending on the powerdomain. pwrst will be either - * RETENTION or OFF, if supported. Returns -EINVAL if the powerdomain - * pointer is null or the target power state is not not supported for - * this memory bank, -EEXIST if the target memory bank does not exist - * or is not controllable, or returns 0 upon success. + * Set the next power state @pwrst that memory bank @bank of the + * powerdomain @pwrdm will enter when the powerdomain enters the + * RETENTION state. Bank will be a number from 0 to 3, and represents + * different types of memory, depending on the powerdomain. @pwrst + * will be either RETENTION or OFF, if supported. Returns -EINVAL if + * the powerdomain pointer is null or the target power state is not + * not supported for this memory bank, -EEXIST if the target memory + * bank does not exist or is not controllable, or returns 0 upon + * success. */ int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) { - u32 m; + int ret = -EINVAL; if (!pwrdm) return -EINVAL; @@ -806,78 +776,77 @@ int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst) if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst))) return -EINVAL; - pr_debug("powerdomain: setting next memory powerstate for domain %s " - "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst); + pr_debug("powerdomain: %s: setting next memory powerstate for bank %0x while pwrdm-RET to %0x\n", + pwrdm->name, bank, pwrst); - /* - * The register bit names below may not correspond to the - * actual names of the bits in each powerdomain's register, - * but the type of value returned is the same for each - * powerdomain. - */ - switch (bank) { - case 0: - m = OMAP3430_SHAREDL1CACHEFLATRETSTATE; - break; - case 1: - m = OMAP3430_L1FLATMEMRETSTATE; - break; - case 2: - m = OMAP3430_SHAREDL2CACHEFLATRETSTATE; - break; - case 3: - m = OMAP3430_L2FLATMEMRETSTATE; - break; - default: - WARN_ON(1); /* should never happen */ - return -EEXIST; - } + if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_retst) + ret = arch_pwrdm->pwrdm_set_mem_retst(pwrdm, bank, pwrst); - prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs, - PM_PWSTCTRL); - - return 0; + return ret; } /** * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state * @pwrdm: struct powerdomain * to get current logic retention power state * - * Return the current power state that the logic portion of - * powerdomain pwrdm will enter - * Returns -EINVAL if the powerdomain pointer is null or returns the - * current logic retention power state upon success. + * Return the power state that the logic portion of powerdomain @pwrdm + * will enter when the powerdomain enters retention. Returns -EINVAL + * if the powerdomain pointer is null or returns the logic retention + * power state upon success. */ int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) { + int ret = -EINVAL; + if (!pwrdm) return -EINVAL; - return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST, - OMAP3430_LOGICSTATEST); + if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_pwrst) + ret = arch_pwrdm->pwrdm_read_logic_pwrst(pwrdm); + + return ret; } /** * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state * @pwrdm: struct powerdomain * to get previous logic power state * + * Return the powerdomain @pwrdm's previous logic power state. Returns + * -EINVAL if the powerdomain pointer is null or returns the previous + * logic power state upon success. + */ +int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) +{ + int ret = -EINVAL; + + if (!pwrdm) + return -EINVAL; + + if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_logic_pwrst) + ret = arch_pwrdm->pwrdm_read_prev_logic_pwrst(pwrdm); + + return ret; +} + +/** + * pwrdm_read_logic_retst - get next powerdomain logic power state + * @pwrdm: struct powerdomain * to get next logic power state + * * Return the powerdomain pwrdm's logic power state. Returns -EINVAL - * if the powerdomain pointer is null or returns the previous logic + * if the powerdomain pointer is null or returns the next logic * power state upon success. */ -int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) +int pwrdm_read_logic_retst(struct powerdomain *pwrdm) { + int ret = -EINVAL; + if (!pwrdm) return -EINVAL; - /* - * The register bit names below may not correspond to the - * actual names of the bits in each powerdomain's register, - * but the type of value returned is the same for each - * powerdomain. - */ - return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST, - OMAP3430_LASTLOGICSTATEENTERED); + if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_retst) + ret = arch_pwrdm->pwrdm_read_logic_retst(pwrdm); + + return ret; } /** @@ -885,46 +854,28 @@ int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) * @pwrdm: struct powerdomain * to get current memory bank power state * @bank: memory bank number (0-3) * - * Return the powerdomain pwrdm's current memory power state for bank - * x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if + * Return the powerdomain @pwrdm's current memory power state for bank + * @bank. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if * the target memory bank does not exist or is not controllable, or * returns the current memory power state upon success. */ int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) { - u32 m; + int ret = -EINVAL; if (!pwrdm) - return -EINVAL; + return ret; if (pwrdm->banks < (bank + 1)) - return -EEXIST; + return ret; - /* - * The register bit names below may not correspond to the - * actual names of the bits in each powerdomain's register, - * but the type of value returned is the same for each - * powerdomain. - */ - switch (bank) { - case 0: - m = OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK; - break; - case 1: - m = OMAP3430_L1FLATMEMSTATEST_MASK; - break; - case 2: - m = OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK; - break; - case 3: - m = OMAP3430_L2FLATMEMSTATEST_MASK; - break; - default: - WARN_ON(1); /* should never happen */ - return -EEXIST; - } + if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK) + bank = 1; + + if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_pwrst) + ret = arch_pwrdm->pwrdm_read_mem_pwrst(pwrdm, bank); - return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST, m); + return ret; } /** @@ -932,74 +883,85 @@ int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) * @pwrdm: struct powerdomain * to get previous memory bank power state * @bank: memory bank number (0-3) * - * Return the powerdomain pwrdm's previous memory power state for bank + * Return the powerdomain @pwrdm's previous memory power state for + * bank @bank. Returns -EINVAL if the powerdomain pointer is null, + * -EEXIST if the target memory bank does not exist or is not + * controllable, or returns the previous memory power state upon + * success. + */ +int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) +{ + int ret = -EINVAL; + + if (!pwrdm) + return ret; + + if (pwrdm->banks < (bank + 1)) + return ret; + + if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK) + bank = 1; + + if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_mem_pwrst) + ret = arch_pwrdm->pwrdm_read_prev_mem_pwrst(pwrdm, bank); + + return ret; +} + +/** + * pwrdm_read_mem_retst - get next memory bank power state + * @pwrdm: struct powerdomain * to get mext memory bank power state + * @bank: memory bank number (0-3) + * + * Return the powerdomain pwrdm's next memory power state for bank * x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if * the target memory bank does not exist or is not controllable, or - * returns the previous memory power state upon success. + * returns the next memory power state upon success. */ -int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) +int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) { - u32 m; + int ret = -EINVAL; if (!pwrdm) - return -EINVAL; + return ret; if (pwrdm->banks < (bank + 1)) - return -EEXIST; + return ret; - /* - * The register bit names below may not correspond to the - * actual names of the bits in each powerdomain's register, - * but the type of value returned is the same for each - * powerdomain. - */ - switch (bank) { - case 0: - m = OMAP3430_LASTMEM1STATEENTERED_MASK; - break; - case 1: - m = OMAP3430_LASTMEM2STATEENTERED_MASK; - break; - case 2: - m = OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK; - break; - case 3: - m = OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK; - break; - default: - WARN_ON(1); /* should never happen */ - return -EEXIST; - } + if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_retst) + ret = arch_pwrdm->pwrdm_read_mem_retst(pwrdm, bank); - return prm_read_mod_bits_shift(pwrdm->prcm_offs, - OMAP3430_PM_PREPWSTST, m); + return ret; } /** * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm * @pwrdm: struct powerdomain * to clear * - * Clear the powerdomain's previous power state register. Clears the - * entire register, including logic and memory bank previous power states. - * Returns -EINVAL if the powerdomain pointer is null, or returns 0 upon - * success. + * Clear the powerdomain's previous power state register @pwrdm. + * Clears the entire register, including logic and memory bank + * previous power states. Returns -EINVAL if the powerdomain pointer + * is null, or returns 0 upon success. */ int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) { + int ret = -EINVAL; + if (!pwrdm) - return -EINVAL; + return ret; /* * XXX should get the powerdomain's current state here; * warn & fail if it is not ON. */ - pr_debug("powerdomain: clearing previous power state reg for %s\n", + pr_debug("powerdomain: %s: clearing previous power state reg\n", pwrdm->name); - prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST); + if (arch_pwrdm && arch_pwrdm->pwrdm_clear_all_prev_pwrst) + ret = arch_pwrdm->pwrdm_clear_all_prev_pwrst(pwrdm); - return 0; + return ret; } /** @@ -1007,27 +969,28 @@ int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) * @pwrdm: struct powerdomain * * * Enable automatic context save-and-restore upon power state change - * for some devices in a powerdomain. Warning: this only affects a - * subset of devices in a powerdomain; check the TRM closely. Returns - * -EINVAL if the powerdomain pointer is null or if the powerdomain - * does not support automatic save-and-restore, or returns 0 upon - * success. + * for some devices in the powerdomain @pwrdm. Warning: this only + * affects a subset of devices in a powerdomain; check the TRM + * closely. Returns -EINVAL if the powerdomain pointer is null or if + * the powerdomain does not support automatic save-and-restore, or + * returns 0 upon success. */ int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm) { + int ret = -EINVAL; + if (!pwrdm) - return -EINVAL; + return ret; if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR)) - return -EINVAL; + return ret; - pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n", - pwrdm->name); + pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n", pwrdm->name); - prm_rmw_mod_reg_bits(0, 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, - pwrdm->prcm_offs, PM_PWSTCTRL); + if (arch_pwrdm && arch_pwrdm->pwrdm_enable_hdwr_sar) + ret = arch_pwrdm->pwrdm_enable_hdwr_sar(pwrdm); - return 0; + return ret; } /** @@ -1035,34 +998,35 @@ int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm) * @pwrdm: struct powerdomain * * * Disable automatic context save-and-restore upon power state change - * for some devices in a powerdomain. Warning: this only affects a - * subset of devices in a powerdomain; check the TRM closely. Returns - * -EINVAL if the powerdomain pointer is null or if the powerdomain - * does not support automatic save-and-restore, or returns 0 upon - * success. + * for some devices in the powerdomain @pwrdm. Warning: this only + * affects a subset of devices in a powerdomain; check the TRM + * closely. Returns -EINVAL if the powerdomain pointer is null or if + * the powerdomain does not support automatic save-and-restore, or + * returns 0 upon success. */ int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm) { + int ret = -EINVAL; + if (!pwrdm) - return -EINVAL; + return ret; if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR)) - return -EINVAL; + return ret; - pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n", - pwrdm->name); + pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n", pwrdm->name); - prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, 0, - pwrdm->prcm_offs, PM_PWSTCTRL); + if (arch_pwrdm && arch_pwrdm->pwrdm_disable_hdwr_sar) + ret = arch_pwrdm->pwrdm_disable_hdwr_sar(pwrdm); - return 0; + return ret; } /** * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR * @pwrdm: struct powerdomain * * - * Returns 1 if powerdomain 'pwrdm' supports hardware save-and-restore + * Returns 1 if powerdomain @pwrdm supports hardware save-and-restore * for some devices, or 0 if it does not. */ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm) @@ -1070,44 +1034,180 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm) return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0; } +int pwrdm_state_switch_nolock(struct powerdomain *pwrdm) +{ + int ret; + + if (!pwrdm || !arch_pwrdm) + return -EINVAL; + + ret = arch_pwrdm->pwrdm_wait_transition(pwrdm); + if (!ret) + ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); + + return ret; +} + +int __deprecated pwrdm_state_switch(struct powerdomain *pwrdm) +{ + int ret; + + pwrdm_lock(pwrdm); + ret = pwrdm_state_switch_nolock(pwrdm); + pwrdm_unlock(pwrdm); + + return ret; +} + +int pwrdm_pre_transition(struct powerdomain *pwrdm) +{ + if (pwrdm) + _pwrdm_pre_transition_cb(pwrdm, NULL); + else + pwrdm_for_each(_pwrdm_pre_transition_cb, NULL); + + return 0; +} + +int pwrdm_post_transition(struct powerdomain *pwrdm) +{ + if (pwrdm) + _pwrdm_post_transition_cb(pwrdm, NULL); + else + pwrdm_for_each(_pwrdm_post_transition_cb, NULL); + + return 0; +} + /** - * pwrdm_wait_transition - wait for powerdomain power transition to finish - * @pwrdm: struct powerdomain * to wait for + * omap_set_pwrdm_state - change a powerdomain's current power state + * @pwrdm: struct powerdomain * to change the power state of + * @pwrst: power state to change to * - * If the powerdomain pwrdm is in the process of a state transition, - * spin until it completes the power transition, or until an iteration - * bailout value is reached. Returns -EINVAL if the powerdomain - * pointer is null, -EAGAIN if the bailout value was reached, or - * returns 0 upon success. + * Change the current hardware power state of the powerdomain + * represented by @pwrdm to the power state represented by @pwrst. + * Returns -EINVAL if @pwrdm is null or invalid or if the + * powerdomain's current power state could not be read, or returns 0 + * upon success or if @pwrdm does not support @pwrst or any + * lower-power state. XXX Should not return 0 if the @pwrdm does not + * support @pwrst or any lower-power state: this should be an error. */ -int pwrdm_wait_transition(struct powerdomain *pwrdm) +int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst) { - u32 c = 0; + u8 next_pwrst, sleep_switch; + int curr_pwrst; + int ret = 0; + bool hwsup = false; - if (!pwrdm) + if (!pwrdm || IS_ERR(pwrdm)) return -EINVAL; + while (!(pwrdm->pwrsts & (1 << pwrst))) { + if (pwrst == PWRDM_POWER_OFF) + return ret; + pwrst--; + } + + pwrdm_lock(pwrdm); + + curr_pwrst = pwrdm_read_pwrst(pwrdm); + if (curr_pwrst < 0) { + ret = -EINVAL; + goto osps_out; + } + + next_pwrst = pwrdm_read_next_pwrst(pwrdm); + if (curr_pwrst == pwrst && next_pwrst == pwrst) + goto osps_out; + + sleep_switch = _pwrdm_save_clkdm_state_and_activate(pwrdm, curr_pwrst, + pwrst, &hwsup); + + ret = pwrdm_set_next_pwrst(pwrdm, pwrst); + if (ret) + pr_err("%s: unable to set power state of powerdomain: %s\n", + __func__, pwrdm->name); + + _pwrdm_restore_clkdm_state(pwrdm, sleep_switch, hwsup); + +osps_out: + pwrdm_unlock(pwrdm); + + return ret; +} + +/** + * pwrdm_get_context_loss_count - get powerdomain's context loss count + * @pwrdm: struct powerdomain * to wait for + * + * Context loss count is the sum of powerdomain off-mode counter, the + * logic off counter and the per-bank memory off counter. Returns negative + * (and WARNs) upon error, otherwise, returns the context loss count. + */ +int pwrdm_get_context_loss_count(struct powerdomain *pwrdm) +{ + int i, count; + + if (!pwrdm) { + WARN(1, "powerdomain: %s: pwrdm is null\n", __func__); + return -ENODEV; + } + + count = pwrdm->state_counter[PWRDM_POWER_OFF]; + count += pwrdm->ret_logic_off_counter; + + for (i = 0; i < pwrdm->banks; i++) + count += pwrdm->ret_mem_off_counter[i]; + /* - * REVISIT: pwrdm_wait_transition() may be better implemented - * via a callback and a periodic timer check -- how long do we expect - * powerdomain transitions to take? + * Context loss count has to be a non-negative value. Clear the sign + * bit to get a value range from 0 to INT_MAX. */ + count &= INT_MAX; + + pr_debug("powerdomain: %s: context loss count = %d\n", + pwrdm->name, count); + + return count; +} - /* XXX Is this udelay() value meaningful? */ - while ((prm_read_mod_reg(pwrdm->prcm_offs, PM_PWSTST) & - OMAP_INTRANSITION) && - (c++ < PWRDM_TRANSITION_BAILOUT)) - udelay(1); +/** + * pwrdm_can_ever_lose_context - can this powerdomain ever lose context? + * @pwrdm: struct powerdomain * + * + * Given a struct powerdomain * @pwrdm, returns 1 if the powerdomain + * can lose either memory or logic context or if @pwrdm is invalid, or + * returns 0 otherwise. This function is not concerned with how the + * powerdomain registers are programmed (i.e., to go off or not); it's + * concerned with whether it's ever possible for this powerdomain to + * go off while some other part of the chip is active. This function + * assumes that every powerdomain can go to either ON or INACTIVE. + */ +bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm) +{ + int i; - if (c >= PWRDM_TRANSITION_BAILOUT) { - printk(KERN_ERR "powerdomain: waited too long for " - "powerdomain %s to complete transition\n", pwrdm->name); - return -EAGAIN; + if (!pwrdm) { + pr_debug("powerdomain: %s: invalid powerdomain pointer\n", + __func__); + return 1; } - pr_debug("powerdomain: completed transition in %d loops\n", c); + if (pwrdm->pwrsts & PWRSTS_OFF) + return 1; - return 0; -} + if (pwrdm->pwrsts & PWRSTS_RET) { + if (pwrdm->pwrsts_logic_ret & PWRSTS_OFF) + return 1; + + for (i = 0; i < pwrdm->banks; i++) + if (pwrdm->pwrsts_mem_ret[i] & PWRSTS_OFF) + return 1; + } + for (i = 0; i < pwrdm->banks; i++) + if (pwrdm->pwrsts_mem_on[i] & PWRSTS_OFF) + return 1; + return 0; +} diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h new file mode 100644 index 00000000000..f4727117f6c --- /dev/null +++ b/arch/arm/mach-omap2/powerdomain.h @@ -0,0 +1,277 @@ +/* + * OMAP2/3/4 powerdomain control + * + * Copyright (C) 2007-2008, 2010 Texas Instruments, Inc. + * Copyright (C) 2007-2011 Nokia Corporation + * + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * XXX This should be moved to the mach-omap2/ directory at the earliest + * opportunity. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_POWERDOMAIN_H +#define __ARCH_ARM_MACH_OMAP2_POWERDOMAIN_H + +#include <linux/types.h> +#include <linux/list.h> +#include <linux/spinlock.h> + +/* Powerdomain basic power states */ +#define PWRDM_POWER_OFF 0x0 +#define PWRDM_POWER_RET 0x1 +#define PWRDM_POWER_INACTIVE 0x2 +#define PWRDM_POWER_ON 0x3 + +#define PWRDM_MAX_PWRSTS 4 + +/* Powerdomain allowable state bitfields */ +#define PWRSTS_ON (1 << PWRDM_POWER_ON) +#define PWRSTS_INACTIVE (1 << PWRDM_POWER_INACTIVE) +#define PWRSTS_RET (1 << PWRDM_POWER_RET) +#define PWRSTS_OFF (1 << PWRDM_POWER_OFF) + +#define PWRSTS_OFF_ON (PWRSTS_OFF | PWRSTS_ON) +#define PWRSTS_OFF_RET (PWRSTS_OFF | PWRSTS_RET) +#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON) +#define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | PWRSTS_ON) + + +/* + * Powerdomain flags (struct powerdomain.flags) + * + * PWRDM_HAS_HDWR_SAR - powerdomain has hardware save-and-restore support + * + * PWRDM_HAS_MPU_QUIRK - MPU pwr domain has MEM bank 0 bits in MEM + * bank 1 position. This is true for OMAP3430 + * + * PWRDM_HAS_LOWPOWERSTATECHANGE - can transition from a sleep state + * to a lower sleep state without waking up the powerdomain + */ +#define PWRDM_HAS_HDWR_SAR BIT(0) +#define PWRDM_HAS_MPU_QUIRK BIT(1) +#define PWRDM_HAS_LOWPOWERSTATECHANGE BIT(2) + +/* + * Number of memory banks that are power-controllable. On OMAP4430, the + * maximum is 5. + */ +#define PWRDM_MAX_MEM_BANKS 5 + +/* + * Maximum number of clockdomains that can be associated with a powerdomain. + * PER powerdomain on AM33XX is the worst case + */ +#define PWRDM_MAX_CLKDMS 11 + +/* XXX A completely arbitrary number. What is reasonable here? */ +#define PWRDM_TRANSITION_BAILOUT 100000 + +struct clockdomain; +struct powerdomain; +struct voltagedomain; + +/** + * struct powerdomain - OMAP powerdomain + * @name: Powerdomain name + * @voltdm: voltagedomain containing this powerdomain + * @prcm_offs: the address offset from CM_BASE/PRM_BASE + * @prcm_partition: (OMAP4 only) the PRCM partition ID containing @prcm_offs + * @pwrsts: Possible powerdomain power states + * @pwrsts_logic_ret: Possible logic power states when pwrdm in RETENTION + * @flags: Powerdomain flags + * @banks: Number of software-controllable memory banks in this powerdomain + * @pwrsts_mem_ret: Possible memory bank pwrstates when pwrdm in RETENTION + * @pwrsts_mem_on: Possible memory bank pwrstates when pwrdm in ON + * @pwrdm_clkdms: Clockdomains in this powerdomain + * @node: list_head linking all powerdomains + * @voltdm_node: list_head linking all powerdomains in a voltagedomain + * @pwrstctrl_offs: (AM33XX only) XXX_PWRSTCTRL reg offset from prcm_offs + * @pwrstst_offs: (AM33XX only) XXX_PWRSTST reg offset from prcm_offs + * @logicretstate_mask: (AM33XX only) mask for logic retention bitfield + * in @pwrstctrl_offs + * @mem_on_mask: (AM33XX only) mask for mem on bitfield in @pwrstctrl_offs + * @mem_ret_mask: (AM33XX only) mask for mem ret bitfield in @pwrstctrl_offs + * @mem_pwrst_mask: (AM33XX only) mask for mem state bitfield in @pwrstst_offs + * @mem_retst_mask: (AM33XX only) mask for mem retention state bitfield + * in @pwrstctrl_offs + * @state: + * @state_counter: + * @timer: + * @state_timer: + * @_lock: spinlock used to serialize powerdomain and some clockdomain ops + * @_lock_flags: stored flags when @_lock is taken + * + * @prcm_partition possible values are defined in mach-omap2/prcm44xx.h. + */ +struct powerdomain { + const char *name; + union { + const char *name; + struct voltagedomain *ptr; + } voltdm; + const s16 prcm_offs; + const u8 pwrsts; + const u8 pwrsts_logic_ret; + const u8 flags; + const u8 banks; + const u8 pwrsts_mem_ret[PWRDM_MAX_MEM_BANKS]; + const u8 pwrsts_mem_on[PWRDM_MAX_MEM_BANKS]; + const u8 prcm_partition; + struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS]; + struct list_head node; + struct list_head voltdm_node; + int state; + unsigned state_counter[PWRDM_MAX_PWRSTS]; + unsigned ret_logic_off_counter; + unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS]; + spinlock_t _lock; + unsigned long _lock_flags; + const u8 pwrstctrl_offs; + const u8 pwrstst_offs; + const u32 logicretstate_mask; + const u32 mem_on_mask[PWRDM_MAX_MEM_BANKS]; + const u32 mem_ret_mask[PWRDM_MAX_MEM_BANKS]; + const u32 mem_pwrst_mask[PWRDM_MAX_MEM_BANKS]; + const u32 mem_retst_mask[PWRDM_MAX_MEM_BANKS]; + +#ifdef CONFIG_PM_DEBUG + s64 timer; + s64 state_timer[PWRDM_MAX_PWRSTS]; +#endif +}; + +/** + * struct pwrdm_ops - Arch specific function implementations + * @pwrdm_set_next_pwrst: Set the target power state for a pd + * @pwrdm_read_next_pwrst: Read the target power state set for a pd + * @pwrdm_read_pwrst: Read the current power state of a pd + * @pwrdm_read_prev_pwrst: Read the prev power state entered by the pd + * @pwrdm_set_logic_retst: Set the logic state in RET for a pd + * @pwrdm_set_mem_onst: Set the Memory state in ON for a pd + * @pwrdm_set_mem_retst: Set the Memory state in RET for a pd + * @pwrdm_read_logic_pwrst: Read the current logic state of a pd + * @pwrdm_read_prev_logic_pwrst: Read the previous logic state entered by a pd + * @pwrdm_read_logic_retst: Read the logic state in RET for a pd + * @pwrdm_read_mem_pwrst: Read the current memory state of a pd + * @pwrdm_read_prev_mem_pwrst: Read the previous memory state entered by a pd + * @pwrdm_read_mem_retst: Read the memory state in RET for a pd + * @pwrdm_clear_all_prev_pwrst: Clear all previous power states logged for a pd + * @pwrdm_enable_hdwr_sar: Enable Hardware Save-Restore feature for the pd + * @pwrdm_disable_hdwr_sar: Disable Hardware Save-Restore feature for a pd + * @pwrdm_set_lowpwrstchange: Enable pd transitions from a shallow to deep sleep + * @pwrdm_wait_transition: Wait for a pd state transition to complete + * @pwrdm_has_voltdm: Check if a voltdm association is needed + * + * Regarding @pwrdm_set_lowpwrstchange: On the OMAP2 and 3-family + * chips, a powerdomain's power state is not allowed to directly + * transition from one low-power state (e.g., CSWR) to another + * low-power state (e.g., OFF) without first waking up the + * powerdomain. This wastes energy. So OMAP4 chips support the + * ability to transition a powerdomain power state directly from one + * low-power state to another. The function pointed to by + * @pwrdm_set_lowpwrstchange is intended to configure the OMAP4 + * hardware powerdomain state machine to enable this feature. + */ +struct pwrdm_ops { + int (*pwrdm_set_next_pwrst)(struct powerdomain *pwrdm, u8 pwrst); + int (*pwrdm_read_next_pwrst)(struct powerdomain *pwrdm); + int (*pwrdm_read_pwrst)(struct powerdomain *pwrdm); + int (*pwrdm_read_prev_pwrst)(struct powerdomain *pwrdm); + int (*pwrdm_set_logic_retst)(struct powerdomain *pwrdm, u8 pwrst); + int (*pwrdm_set_mem_onst)(struct powerdomain *pwrdm, u8 bank, u8 pwrst); + int (*pwrdm_set_mem_retst)(struct powerdomain *pwrdm, u8 bank, u8 pwrst); + int (*pwrdm_read_logic_pwrst)(struct powerdomain *pwrdm); + int (*pwrdm_read_prev_logic_pwrst)(struct powerdomain *pwrdm); + int (*pwrdm_read_logic_retst)(struct powerdomain *pwrdm); + int (*pwrdm_read_mem_pwrst)(struct powerdomain *pwrdm, u8 bank); + int (*pwrdm_read_prev_mem_pwrst)(struct powerdomain *pwrdm, u8 bank); + int (*pwrdm_read_mem_retst)(struct powerdomain *pwrdm, u8 bank); + int (*pwrdm_clear_all_prev_pwrst)(struct powerdomain *pwrdm); + int (*pwrdm_enable_hdwr_sar)(struct powerdomain *pwrdm); + int (*pwrdm_disable_hdwr_sar)(struct powerdomain *pwrdm); + int (*pwrdm_set_lowpwrstchange)(struct powerdomain *pwrdm); + int (*pwrdm_wait_transition)(struct powerdomain *pwrdm); + int (*pwrdm_has_voltdm)(void); +}; + +int pwrdm_register_platform_funcs(struct pwrdm_ops *custom_funcs); +int pwrdm_register_pwrdms(struct powerdomain **pwrdm_list); +int pwrdm_complete_init(void); + +struct powerdomain *pwrdm_lookup(const char *name); + +int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user), + void *user); +int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user), + void *user); + +int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm); +int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm); +int pwrdm_for_each_clkdm(struct powerdomain *pwrdm, + int (*fn)(struct powerdomain *pwrdm, + struct clockdomain *clkdm)); +struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm); + +int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm); + +int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst); +int pwrdm_read_next_pwrst(struct powerdomain *pwrdm); +int pwrdm_read_pwrst(struct powerdomain *pwrdm); +int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm); +int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm); + +int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst); +int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst); +int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst); + +int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm); +int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm); +int pwrdm_read_logic_retst(struct powerdomain *pwrdm); +int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank); +int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank); +int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank); + +int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm); +int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm); +bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm); + +int pwrdm_state_switch_nolock(struct powerdomain *pwrdm); +int pwrdm_state_switch(struct powerdomain *pwrdm); +int pwrdm_pre_transition(struct powerdomain *pwrdm); +int pwrdm_post_transition(struct powerdomain *pwrdm); +int pwrdm_get_context_loss_count(struct powerdomain *pwrdm); +bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm); + +extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 state); + +extern void omap242x_powerdomains_init(void); +extern void omap243x_powerdomains_init(void); +extern void omap3xxx_powerdomains_init(void); +extern void am33xx_powerdomains_init(void); +extern void omap44xx_powerdomains_init(void); +extern void omap54xx_powerdomains_init(void); +extern void dra7xx_powerdomains_init(void); +void am43xx_powerdomains_init(void); + +extern struct pwrdm_ops omap2_pwrdm_operations; +extern struct pwrdm_ops omap3_pwrdm_operations; +extern struct pwrdm_ops am33xx_pwrdm_operations; +extern struct pwrdm_ops omap4_pwrdm_operations; + +/* Common Internal functions used across OMAP rev's */ +extern u32 omap2_pwrdm_get_mem_bank_onstate_mask(u8 bank); +extern u32 omap2_pwrdm_get_mem_bank_retst_mask(u8 bank); +extern u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank); + +extern struct powerdomain wkup_omap2_pwrdm; +extern struct powerdomain gfx_omap2_pwrdm; + +extern void pwrdm_lock(struct powerdomain *pwrdm); +extern void pwrdm_unlock(struct powerdomain *pwrdm); + +#endif diff --git a/arch/arm/mach-omap2/powerdomains.h b/arch/arm/mach-omap2/powerdomains.h deleted file mode 100644 index 1e151faebbd..00000000000 --- a/arch/arm/mach-omap2/powerdomains.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * OMAP2/3 common powerdomain definitions - * - * Copyright (C) 2007-8 Texas Instruments, Inc. - * Copyright (C) 2007-8 Nokia Corporation - * - * Written by Paul Walmsley - * Debugging and integration fixes by Jouni Högander - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef ARCH_ARM_MACH_OMAP2_POWERDOMAINS -#define ARCH_ARM_MACH_OMAP2_POWERDOMAINS - -/* - * This file contains all of the powerdomains that have some element - * of software control for the OMAP24xx and OMAP34XX chips. - * - * A few notes: - * - * This is not an exhaustive listing of powerdomains on the chips; only - * powerdomains that can be controlled in software. - * - * A useful validation rule for struct powerdomain: - * Any powerdomain referenced by a wkdep_srcs or sleepdep_srcs array - * must have a dep_bit assigned. So wkdep_srcs/sleepdep_srcs are really - * just software-controllable dependencies. Non-software-controllable - * dependencies do exist, but they are not encoded below (yet). - * - * 24xx does not support programmable sleep dependencies (SLEEPDEP) - * - */ - -/* - * The names for the DSP/IVA2 powerdomains are confusing. - * - * Most OMAP chips have an on-board DSP. - * - * On the 2420, this is a 'C55 DSP called, simply, the DSP. Its - * powerdomain is called the "DSP power domain." On the 2430, the - * on-board DSP is a 'C64 DSP, now called the IVA2 or IVA2.1. Its - * powerdomain is still called the "DSP power domain." On the 3430, - * the DSP is a 'C64 DSP like the 2430, also known as the IVA2; but - * its powerdomain is now called the "IVA2 power domain." - * - * The 2420 also has something called the IVA, which is a separate ARM - * core, and has nothing to do with the DSP/IVA2. - * - * Ideally the DSP/IVA2 could just be the same powerdomain, but the PRCM - * address offset is different between the C55 and C64 DSPs. - * - * The overly-specific dep_bit names are due to a bit name collision - * with CM_FCLKEN_{DSP,IVA2}. The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift - * value are the same for all powerdomains: 2 - */ - -/* - * XXX should dep_bit be a mask, so we can test to see if it is 0 as a - * sanity check? - * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE - */ - -#include <mach/powerdomain.h> - -#include "prcm-common.h" -#include "prm.h" -#include "cm.h" - -/* OMAP2/3-common powerdomains and wakeup dependencies */ - -/* - * 2420/2430 PM_WKDEP_GFX: CORE, MPU, WKUP - * 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE - * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE - */ -static struct pwrdm_dep gfx_sgx_wkdeps[] = { - { - .pwrdm_name = "core_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "iva2_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | - CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "wkup_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | - CHIP_IS_OMAP3430) - }, - { NULL }, -}; - -/* - * 3430: CM_SLEEPDEP_CAM: MPU - * 3430ES1: CM_SLEEPDEP_GFX: MPU - * 3430ES2: CM_SLEEPDEP_SGX: MPU - */ -static struct pwrdm_dep cam_gfx_sleepdeps[] = { - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { NULL }, -}; - - -#include "powerdomains24xx.h" -#include "powerdomains34xx.h" - - -/* - * OMAP2/3 common powerdomains - */ - -/* - * The GFX powerdomain is not present on 3430ES2, but currently we do not - * have a macro to filter it out at compile-time. - */ -static struct powerdomain gfx_pwrdm = { - .name = "gfx_pwrdm", - .prcm_offs = GFX_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | - CHIP_IS_OMAP3430ES1), - .wkdep_srcs = gfx_sgx_wkdeps, - .sleepdep_srcs = cam_gfx_sleepdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ - }, -}; - -static struct powerdomain wkup_pwrdm = { - .name = "wkup_pwrdm", - .prcm_offs = WKUP_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430), - .dep_bit = OMAP_EN_WKUP_SHIFT, -}; - - - -/* As powerdomains are added or removed above, this list must also be changed */ -static struct powerdomain *powerdomains_omap[] __initdata = { - - &gfx_pwrdm, - &wkup_pwrdm, - -#ifdef CONFIG_ARCH_OMAP24XX - &dsp_pwrdm, - &mpu_24xx_pwrdm, - &core_24xx_pwrdm, -#endif - -#ifdef CONFIG_ARCH_OMAP2430 - &mdm_pwrdm, -#endif - -#ifdef CONFIG_ARCH_OMAP34XX - &iva2_pwrdm, - &mpu_34xx_pwrdm, - &neon_pwrdm, - &core_34xx_pwrdm, - &cam_pwrdm, - &dss_pwrdm, - &per_pwrdm, - &emu_pwrdm, - &sgx_pwrdm, - &usbhost_pwrdm, -#endif - - NULL -}; - - -#endif diff --git a/arch/arm/mach-omap2/powerdomains24xx.h b/arch/arm/mach-omap2/powerdomains24xx.h deleted file mode 100644 index 9f08dc3f7fd..00000000000 --- a/arch/arm/mach-omap2/powerdomains24xx.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * OMAP24XX powerdomain definitions - * - * Copyright (C) 2007-2008 Texas Instruments, Inc. - * Copyright (C) 2007-2008 Nokia Corporation - * - * Written by Paul Walmsley - * Debugging and integration fixes by Jouni Högander - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef ARCH_ARM_MACH_OMAP2_POWERDOMAINS24XX -#define ARCH_ARM_MACH_OMAP2_POWERDOMAINS24XX - -/* - * N.B. If powerdomains are added or removed from this file, update - * the array in mach-omap2/powerdomains.h. - */ - -#include <mach/powerdomain.h> - -#include "prcm-common.h" -#include "prm.h" -#include "prm-regbits-24xx.h" -#include "cm.h" -#include "cm-regbits-24xx.h" - -/* 24XX powerdomains and dependencies */ - -#ifdef CONFIG_ARCH_OMAP24XX - - -/* Wakeup dependency source arrays */ - -/* - * 2420/2430 PM_WKDEP_DSP: CORE, MPU, WKUP - * 2430 PM_WKDEP_MDM: same as above - */ -static struct pwrdm_dep dsp_mdm_24xx_wkdeps[] = { - { - .pwrdm_name = "core_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "wkup_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { NULL }, -}; - -/* - * 2420 PM_WKDEP_MPU: CORE, DSP, WKUP - * 2430 adds MDM - */ -static struct pwrdm_dep mpu_24xx_wkdeps[] = { - { - .pwrdm_name = "core_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "dsp_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "wkup_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "mdm_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) - }, - { NULL }, -}; - -/* - * 2420 PM_WKDEP_CORE: DSP, GFX, MPU, WKUP - * 2430 adds MDM - */ -static struct pwrdm_dep core_24xx_wkdeps[] = { - { - .pwrdm_name = "dsp_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "gfx_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "wkup_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX) - }, - { - .pwrdm_name = "mdm_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) - }, - { NULL }, -}; - - -/* Powerdomains */ - -static struct powerdomain dsp_pwrdm = { - .name = "dsp_pwrdm", - .prcm_offs = OMAP24XX_DSP_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), - .dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT, - .wkdep_srcs = dsp_mdm_24xx_wkdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, - }, -}; - -static struct powerdomain mpu_24xx_pwrdm = { - .name = "mpu_pwrdm", - .prcm_offs = MPU_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), - .dep_bit = OMAP24XX_EN_MPU_SHIFT, - .wkdep_srcs = mpu_24xx_wkdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRSTS_OFF_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, - }, -}; - -static struct powerdomain core_24xx_pwrdm = { - .name = "core_pwrdm", - .prcm_offs = CORE_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), - .wkdep_srcs = core_24xx_wkdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .dep_bit = OMAP24XX_EN_CORE_SHIFT, - .banks = 3, - .pwrsts_mem_ret = { - [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */ - [1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */ - [2] = PWRSTS_OFF_RET, /* MEM3RETSTATE */ - }, - .pwrsts_mem_on = { - [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */ - [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ - [2] = PWRSTS_OFF_RET_ON, /* MEM3ONSTATE */ - }, -}; - -#endif /* CONFIG_ARCH_OMAP24XX */ - - - -/* - * 2430-specific powerdomains - */ - -#ifdef CONFIG_ARCH_OMAP2430 - -/* XXX 2430 KILLDOMAINWKUP bit? No current users apparently */ - -/* Another case of bit name collisions between several registers: EN_MDM */ -static struct powerdomain mdm_pwrdm = { - .name = "mdm_pwrdm", - .prcm_offs = OMAP2430_MDM_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), - .dep_bit = OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT, - .wkdep_srcs = dsp_mdm_24xx_wkdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ - }, -}; - -#endif /* CONFIG_ARCH_OMAP2430 */ - - -#endif diff --git a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c new file mode 100644 index 00000000000..7b946f1005b --- /dev/null +++ b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c @@ -0,0 +1,65 @@ +/* + * OMAP2/3 common powerdomain definitions + * + * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc. + * Copyright (C) 2007-2011 Nokia Corporation + * + * Paul Walmsley, Jouni Högander + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * The names for the DSP/IVA2 powerdomains are confusing. + * + * Most OMAP chips have an on-board DSP. + * + * On the 2420, this is a 'C55 DSP called, simply, the DSP. Its + * powerdomain is called the "DSP power domain." On the 2430, the + * on-board DSP is a 'C64 DSP, now called (along with its hardware + * accelerators) the IVA2 or IVA2.1. Its powerdomain is still called + * the "DSP power domain." On the 3430, the DSP is a 'C64 DSP like the + * 2430, also known as the IVA2; but its powerdomain is now called the + * "IVA2 power domain." + * + * The 2420 also has something called the IVA, which is a separate ARM + * core, and has nothing to do with the DSP/IVA2. + * + * Ideally the DSP/IVA2 could just be the same powerdomain, but the PRCM + * address offset is different between the C55 and C64 DSPs. + */ + +#include "powerdomain.h" + +#include "prcm-common.h" +#include "prm.h" + +/* OMAP2/3-common powerdomains */ + +/* + * The GFX powerdomain is not present on 3430ES2, but currently we do not + * have a macro to filter it out at compile-time. + */ +struct powerdomain gfx_omap2_pwrdm = { + .name = "gfx_pwrdm", + .prcm_offs = GFX_MOD, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_RET, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_RET, /* MEMRETSTATE */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* MEMONSTATE */ + }, + .voltdm = { .name = "core" }, +}; + +struct powerdomain wkup_omap2_pwrdm = { + .name = "wkup_pwrdm", + .prcm_offs = WKUP_MOD, + .pwrsts = PWRSTS_ON, + .voltdm = { .name = "wakeup" }, +}; diff --git a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.h b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.h new file mode 100644 index 00000000000..fa311669d53 --- /dev/null +++ b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.h @@ -0,0 +1,22 @@ +/* + * OMAP2/3 common powerdomains - prototypes + * + * Copyright (C) 2008 Texas Instruments, Inc. + * Copyright (C) 2008-2010 Nokia Corporation + * + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_POWERDOMAINS2XXX_3XXX_DATA_H +#define __ARCH_ARM_MACH_OMAP2_POWERDOMAINS2XXX_3XXX_DATA_H + +#include "powerdomain.h" + +extern struct powerdomain gfx_omap2_pwrdm; +extern struct powerdomain wkup_omap2_pwrdm; + +#endif diff --git a/arch/arm/mach-omap2/powerdomains2xxx_data.c b/arch/arm/mach-omap2/powerdomains2xxx_data.c new file mode 100644 index 00000000000..578eef86fcf --- /dev/null +++ b/arch/arm/mach-omap2/powerdomains2xxx_data.c @@ -0,0 +1,137 @@ +/* + * OMAP2XXX powerdomain definitions + * + * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc. + * Copyright (C) 2007-2011 Nokia Corporation + * + * Paul Walmsley, Jouni Högander + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include "soc.h" +#include "powerdomain.h" +#include "powerdomains2xxx_3xxx_data.h" + +#include "prcm-common.h" +#include "prm2xxx_3xxx.h" +#include "prm-regbits-24xx.h" + +/* 24XX powerdomains and dependencies */ + +/* Powerdomains */ + +static struct powerdomain dsp_pwrdm = { + .name = "dsp_pwrdm", + .prcm_offs = OMAP24XX_DSP_MOD, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_RET, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_RET, + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, + }, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain mpu_24xx_pwrdm = { + .name = "mpu_pwrdm", + .prcm_offs = MPU_MOD, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_RET, + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, + }, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain core_24xx_pwrdm = { + .name = "core_pwrdm", + .prcm_offs = CORE_MOD, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_RET, + .banks = 3, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */ + [1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */ + [2] = PWRSTS_OFF_RET, /* MEM3RETSTATE */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */ + [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ + [2] = PWRSTS_OFF_RET_ON, /* MEM3ONSTATE */ + }, + .voltdm = { .name = "core" }, +}; + + +/* + * 2430-specific powerdomains + */ + +/* XXX 2430 KILLDOMAINWKUP bit? No current users apparently */ + +static struct powerdomain mdm_pwrdm = { + .name = "mdm_pwrdm", + .prcm_offs = OMAP2430_MDM_MOD, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_RET, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_RET, /* MEMRETSTATE */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* MEMONSTATE */ + }, + .voltdm = { .name = "core" }, +}; + +/* + * + */ + +static struct powerdomain *powerdomains_omap24xx[] __initdata = { + &wkup_omap2_pwrdm, + &gfx_omap2_pwrdm, + &dsp_pwrdm, + &mpu_24xx_pwrdm, + &core_24xx_pwrdm, + NULL +}; + +static struct powerdomain *powerdomains_omap2430[] __initdata = { + &mdm_pwrdm, + NULL +}; + +void __init omap242x_powerdomains_init(void) +{ + if (!cpu_is_omap2420()) + return; + + pwrdm_register_platform_funcs(&omap2_pwrdm_operations); + pwrdm_register_pwrdms(powerdomains_omap24xx); + pwrdm_complete_init(); +} + +void __init omap243x_powerdomains_init(void) +{ + if (!cpu_is_omap2430()) + return; + + pwrdm_register_platform_funcs(&omap2_pwrdm_operations); + pwrdm_register_pwrdms(powerdomains_omap24xx); + pwrdm_register_pwrdms(powerdomains_omap2430); + pwrdm_complete_init(); +} diff --git a/arch/arm/mach-omap2/powerdomains33xx_data.c b/arch/arm/mach-omap2/powerdomains33xx_data.c new file mode 100644 index 00000000000..869adb82569 --- /dev/null +++ b/arch/arm/mach-omap2/powerdomains33xx_data.c @@ -0,0 +1,185 @@ +/* + * AM33XX Power domain data + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include "powerdomain.h" +#include "prcm-common.h" +#include "prm-regbits-33xx.h" +#include "prm33xx.h" + +static struct powerdomain gfx_33xx_pwrdm = { + .name = "gfx_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = AM33XX_PRM_GFX_MOD, + .pwrstctrl_offs = AM33XX_PM_GFX_PWRSTCTRL_OFFSET, + .pwrstst_offs = AM33XX_PM_GFX_PWRSTST_OFFSET, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, + .banks = 1, + .logicretstate_mask = AM33XX_LOGICRETSTATE_MASK, + .mem_on_mask = { + [0] = AM33XX_GFX_MEM_ONSTATE_MASK, /* gfx_mem */ + }, + .mem_ret_mask = { + [0] = AM33XX_GFX_MEM_RETSTATE_MASK, /* gfx_mem */ + }, + .mem_pwrst_mask = { + [0] = AM33XX_GFX_MEM_STATEST_MASK, /* gfx_mem */ + }, + .mem_retst_mask = { + [0] = AM33XX_GFX_MEM_RETSTATE_MASK, /* gfx_mem */ + }, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* gfx_mem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* gfx_mem */ + }, +}; + +static struct powerdomain rtc_33xx_pwrdm = { + .name = "rtc_pwrdm", + .voltdm = { .name = "rtc" }, + .prcm_offs = AM33XX_PRM_RTC_MOD, + .pwrstctrl_offs = AM33XX_PM_RTC_PWRSTCTRL_OFFSET, + .pwrstst_offs = AM33XX_PM_RTC_PWRSTST_OFFSET, + .pwrsts = PWRSTS_ON, + .logicretstate_mask = AM33XX_LOGICRETSTATE_MASK, +}; + +static struct powerdomain wkup_33xx_pwrdm = { + .name = "wkup_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = AM33XX_PRM_WKUP_MOD, + .pwrstctrl_offs = AM33XX_PM_WKUP_PWRSTCTRL_OFFSET, + .pwrstst_offs = AM33XX_PM_WKUP_PWRSTST_OFFSET, + .pwrsts = PWRSTS_ON, + .logicretstate_mask = AM33XX_LOGICRETSTATE_3_3_MASK, +}; + +static struct powerdomain per_33xx_pwrdm = { + .name = "per_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = AM33XX_PRM_PER_MOD, + .pwrstctrl_offs = AM33XX_PM_PER_PWRSTCTRL_OFFSET, + .pwrstst_offs = AM33XX_PM_PER_PWRSTST_OFFSET, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, + .banks = 3, + .logicretstate_mask = AM33XX_LOGICRETSTATE_3_3_MASK, + .mem_on_mask = { + [0] = AM33XX_PRUSS_MEM_ONSTATE_MASK, /* pruss_mem */ + [1] = AM33XX_PER_MEM_ONSTATE_MASK, /* per_mem */ + [2] = AM33XX_RAM_MEM_ONSTATE_MASK, /* ram_mem */ + }, + .mem_ret_mask = { + [0] = AM33XX_PRUSS_MEM_RETSTATE_MASK, /* pruss_mem */ + [1] = AM33XX_PER_MEM_RETSTATE_MASK, /* per_mem */ + [2] = AM33XX_RAM_MEM_RETSTATE_MASK, /* ram_mem */ + }, + .mem_pwrst_mask = { + [0] = AM33XX_PRUSS_MEM_STATEST_MASK, /* pruss_mem */ + [1] = AM33XX_PER_MEM_STATEST_MASK, /* per_mem */ + [2] = AM33XX_RAM_MEM_STATEST_MASK, /* ram_mem */ + }, + .mem_retst_mask = { + [0] = AM33XX_PRUSS_MEM_RETSTATE_MASK, /* pruss_mem */ + [1] = AM33XX_PER_MEM_RETSTATE_MASK, /* per_mem */ + [2] = AM33XX_RAM_MEM_RETSTATE_MASK, /* ram_mem */ + }, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* pruss_mem */ + [1] = PWRSTS_OFF_RET, /* per_mem */ + [2] = PWRSTS_OFF_RET, /* ram_mem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* pruss_mem */ + [1] = PWRSTS_ON, /* per_mem */ + [2] = PWRSTS_ON, /* ram_mem */ + }, +}; + +static struct powerdomain mpu_33xx_pwrdm = { + .name = "mpu_pwrdm", + .voltdm = { .name = "mpu" }, + .prcm_offs = AM33XX_PRM_MPU_MOD, + .pwrstctrl_offs = AM33XX_PM_MPU_PWRSTCTRL_OFFSET, + .pwrstst_offs = AM33XX_PM_MPU_PWRSTST_OFFSET, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, + .banks = 3, + .logicretstate_mask = AM33XX_LOGICRETSTATE_MASK, + .mem_on_mask = { + [0] = AM33XX_MPU_L1_ONSTATE_MASK, /* mpu_l1 */ + [1] = AM33XX_MPU_L2_ONSTATE_MASK, /* mpu_l2 */ + [2] = AM33XX_MPU_RAM_ONSTATE_MASK, /* mpu_ram */ + }, + .mem_ret_mask = { + [0] = AM33XX_MPU_L1_RETSTATE_MASK, /* mpu_l1 */ + [1] = AM33XX_MPU_L2_RETSTATE_MASK, /* mpu_l2 */ + [2] = AM33XX_MPU_RAM_RETSTATE_MASK, /* mpu_ram */ + }, + .mem_pwrst_mask = { + [0] = AM33XX_MPU_L1_STATEST_MASK, /* mpu_l1 */ + [1] = AM33XX_MPU_L2_STATEST_MASK, /* mpu_l2 */ + [2] = AM33XX_MPU_RAM_STATEST_MASK, /* mpu_ram */ + }, + .mem_retst_mask = { + [0] = AM33XX_MPU_L1_RETSTATE_MASK, /* mpu_l1 */ + [1] = AM33XX_MPU_L2_RETSTATE_MASK, /* mpu_l2 */ + [2] = AM33XX_MPU_RAM_RETSTATE_MASK, /* mpu_ram */ + }, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* mpu_l1 */ + [1] = PWRSTS_OFF_RET, /* mpu_l2 */ + [2] = PWRSTS_OFF_RET, /* mpu_ram */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* mpu_l1 */ + [1] = PWRSTS_ON, /* mpu_l2 */ + [2] = PWRSTS_ON, /* mpu_ram */ + }, +}; + +static struct powerdomain cefuse_33xx_pwrdm = { + .name = "cefuse_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = AM33XX_PRM_CEFUSE_MOD, + .pwrstctrl_offs = AM33XX_PM_CEFUSE_PWRSTCTRL_OFFSET, + .pwrstst_offs = AM33XX_PM_CEFUSE_PWRSTST_OFFSET, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct powerdomain *powerdomains_am33xx[] __initdata = { + &gfx_33xx_pwrdm, + &rtc_33xx_pwrdm, + &wkup_33xx_pwrdm, + &per_33xx_pwrdm, + &mpu_33xx_pwrdm, + &cefuse_33xx_pwrdm, + NULL, +}; + +void __init am33xx_powerdomains_init(void) +{ + pwrdm_register_platform_funcs(&am33xx_pwrdm_operations); + pwrdm_register_pwrdms(powerdomains_am33xx); + pwrdm_complete_init(); +} diff --git a/arch/arm/mach-omap2/powerdomains34xx.h b/arch/arm/mach-omap2/powerdomains34xx.h deleted file mode 100644 index f573f710839..00000000000 --- a/arch/arm/mach-omap2/powerdomains34xx.h +++ /dev/null @@ -1,327 +0,0 @@ -/* - * OMAP34XX powerdomain definitions - * - * Copyright (C) 2007-2008 Texas Instruments, Inc. - * Copyright (C) 2007-2008 Nokia Corporation - * - * Written by Paul Walmsley - * Debugging and integration fixes by Jouni Högander - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef ARCH_ARM_MACH_OMAP2_POWERDOMAINS34XX -#define ARCH_ARM_MACH_OMAP2_POWERDOMAINS34XX - -/* - * N.B. If powerdomains are added or removed from this file, update - * the array in mach-omap2/powerdomains.h. - */ - -#include <mach/powerdomain.h> - -#include "prcm-common.h" -#include "prm.h" -#include "prm-regbits-34xx.h" -#include "cm.h" -#include "cm-regbits-34xx.h" - -/* - * 34XX-specific powerdomains, dependencies - */ - -#ifdef CONFIG_ARCH_OMAP34XX - -/* - * 3430: PM_WKDEP_{PER,USBHOST}: CORE, IVA2, MPU, WKUP - * (USBHOST is ES2 only) - */ -static struct pwrdm_dep per_usbhost_wkdeps[] = { - { - .pwrdm_name = "core_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "iva2_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "wkup_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { NULL }, -}; - -/* - * 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER - */ -static struct pwrdm_dep mpu_34xx_wkdeps[] = { - { - .pwrdm_name = "core_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "iva2_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "dss_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "per_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { NULL }, -}; - -/* - * 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER - */ -static struct pwrdm_dep iva2_wkdeps[] = { - { - .pwrdm_name = "core_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "wkup_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "dss_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "per_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { NULL }, -}; - - -/* 3430 PM_WKDEP_{CAM,DSS}: IVA2, MPU, WKUP */ -static struct pwrdm_dep cam_dss_wkdeps[] = { - { - .pwrdm_name = "iva2_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "wkup_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { NULL }, -}; - -/* 3430: PM_WKDEP_NEON: MPU */ -static struct pwrdm_dep neon_wkdeps[] = { - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { NULL }, -}; - - -/* Sleep dependency source arrays for 34xx-specific pwrdms - 34XX only */ - -/* - * 3430: CM_SLEEPDEP_{DSS,PER}: MPU, IVA - * 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA - */ -static struct pwrdm_dep dss_per_usbhost_sleepdeps[] = { - { - .pwrdm_name = "mpu_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { - .pwrdm_name = "iva2_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }, - { NULL }, -}; - - -/* - * Powerdomains - */ - -static struct powerdomain iva2_pwrdm = { - .name = "iva2_pwrdm", - .prcm_offs = OMAP3430_IVA2_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), - .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT, - .wkdep_srcs = iva2_wkdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRSTS_OFF_RET, - .banks = 4, - .pwrsts_mem_ret = { - [0] = PWRSTS_OFF_RET, - [1] = PWRSTS_OFF_RET, - [2] = PWRSTS_OFF_RET, - [3] = PWRSTS_OFF_RET, - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, - [1] = PWRDM_POWER_ON, - [2] = PWRSTS_OFF_ON, - [3] = PWRDM_POWER_ON, - }, -}; - -static struct powerdomain mpu_34xx_pwrdm = { - .name = "mpu_pwrdm", - .prcm_offs = MPU_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), - .dep_bit = OMAP3430_EN_MPU_SHIFT, - .wkdep_srcs = mpu_34xx_wkdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRSTS_OFF_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRSTS_OFF_RET, - }, - .pwrsts_mem_on = { - [0] = PWRSTS_OFF_ON, - }, -}; - -/* No wkdeps or sleepdeps for 34xx core apparently */ -static struct powerdomain core_34xx_pwrdm = { - .name = "core_pwrdm", - .prcm_offs = CORE_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), - .pwrsts = PWRSTS_OFF_RET_ON, - .dep_bit = OMAP3430_EN_CORE_SHIFT, - .banks = 2, - .pwrsts_mem_ret = { - [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */ - [1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */ - }, - .pwrsts_mem_on = { - [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */ - [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ - }, -}; - -/* Another case of bit name collisions between several registers: EN_DSS */ -static struct powerdomain dss_pwrdm = { - .name = "dss_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), - .prcm_offs = OMAP3430_DSS_MOD, - .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT, - .wkdep_srcs = cam_dss_wkdeps, - .sleepdep_srcs = dss_per_usbhost_sleepdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ - }, -}; - -static struct powerdomain sgx_pwrdm = { - .name = "sgx_pwrdm", - .prcm_offs = OMAP3430ES2_SGX_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2), - .wkdep_srcs = gfx_sgx_wkdeps, - .sleepdep_srcs = cam_gfx_sleepdeps, - /* XXX This is accurate for 3430 SGX, but what about GFX? */ - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ - }, -}; - -static struct powerdomain cam_pwrdm = { - .name = "cam_pwrdm", - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), - .prcm_offs = OMAP3430_CAM_MOD, - .wkdep_srcs = cam_dss_wkdeps, - .sleepdep_srcs = cam_gfx_sleepdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ - }, -}; - -static struct powerdomain per_pwrdm = { - .name = "per_pwrdm", - .prcm_offs = OMAP3430_PER_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), - .dep_bit = OMAP3430_EN_PER_SHIFT, - .wkdep_srcs = per_usbhost_wkdeps, - .sleepdep_srcs = dss_per_usbhost_sleepdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRSTS_OFF_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ - }, -}; - -static struct powerdomain emu_pwrdm = { - .name = "emu_pwrdm", - .prcm_offs = OMAP3430_EMU_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -}; - -static struct powerdomain neon_pwrdm = { - .name = "neon_pwrdm", - .prcm_offs = OMAP3430_NEON_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), - .wkdep_srcs = neon_wkdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, -}; - -static struct powerdomain usbhost_pwrdm = { - .name = "usbhost_pwrdm", - .prcm_offs = OMAP3430ES2_USBHOST_MOD, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2), - .wkdep_srcs = per_usbhost_wkdeps, - .sleepdep_srcs = dss_per_usbhost_sleepdeps, - .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, - .banks = 1, - .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ - }, - .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ - }, -}; - -#endif /* CONFIG_ARCH_OMAP34XX */ - - -#endif diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c new file mode 100644 index 00000000000..328c1037cb6 --- /dev/null +++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c @@ -0,0 +1,504 @@ +/* + * OMAP3 powerdomain definitions + * + * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc. + * Copyright (C) 2007-2011 Nokia Corporation + * + * Paul Walmsley, Jouni Högander + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/bug.h> + +#include "soc.h" +#include "powerdomain.h" +#include "powerdomains2xxx_3xxx_data.h" +#include "prcm-common.h" +#include "prm2xxx_3xxx.h" +#include "prm-regbits-34xx.h" +#include "cm2xxx_3xxx.h" +#include "cm-regbits-34xx.h" + +/* + * 34XX-specific powerdomains, dependencies + */ + +/* + * Powerdomains + */ + +static struct powerdomain iva2_pwrdm = { + .name = "iva2_pwrdm", + .prcm_offs = OMAP3430_IVA2_MOD, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 4, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, + [1] = PWRSTS_OFF_RET, + [2] = PWRSTS_OFF_RET, + [3] = PWRSTS_OFF_RET, + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, + [1] = PWRSTS_ON, + [2] = PWRSTS_OFF_ON, + [3] = PWRSTS_ON, + }, + .voltdm = { .name = "mpu_iva" }, +}; + +static struct powerdomain mpu_3xxx_pwrdm = { + .name = "mpu_pwrdm", + .prcm_offs = MPU_MOD, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .flags = PWRDM_HAS_MPU_QUIRK, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_ON, + }, + .voltdm = { .name = "mpu_iva" }, +}; + +static struct powerdomain mpu_am35x_pwrdm = { + .name = "mpu_pwrdm", + .prcm_offs = MPU_MOD, + .pwrsts = PWRSTS_ON, + .pwrsts_logic_ret = PWRSTS_ON, + .flags = PWRDM_HAS_MPU_QUIRK, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_ON, + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, + }, + .voltdm = { .name = "mpu_iva" }, +}; + +/* + * The USBTLL Save-and-Restore mechanism is broken on + * 3430s up to ES3.0 and 3630ES1.0. Hence this feature + * needs to be disabled on these chips. + * Refer: 3430 errata ID i459 and 3630 errata ID i579 + * + * Note: setting the SAR flag could help for errata ID i478 + * which applies to 3430 <= ES3.1, but since the SAR feature + * is broken, do not use it. + */ +static struct powerdomain core_3xxx_pre_es3_1_pwrdm = { + .name = "core_pwrdm", + .prcm_offs = CORE_MOD, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 2, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */ + [1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */ + [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ + }, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain core_3xxx_es3_1_pwrdm = { + .name = "core_pwrdm", + .prcm_offs = CORE_MOD, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + /* + * Setting the SAR flag for errata ID i478 which applies + * to 3430 <= ES3.1 + */ + .flags = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */ + .banks = 2, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */ + [1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */ + [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */ + }, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain core_am35x_pwrdm = { + .name = "core_pwrdm", + .prcm_offs = CORE_MOD, + .pwrsts = PWRSTS_ON, + .pwrsts_logic_ret = PWRSTS_ON, + .banks = 2, + .pwrsts_mem_ret = { + [0] = PWRSTS_ON, /* MEM1RETSTATE */ + [1] = PWRSTS_ON, /* MEM2RETSTATE */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* MEM1ONSTATE */ + [1] = PWRSTS_ON, /* MEM2ONSTATE */ + }, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain dss_pwrdm = { + .name = "dss_pwrdm", + .prcm_offs = OMAP3430_DSS_MOD, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_RET, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_RET, /* MEMRETSTATE */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* MEMONSTATE */ + }, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain dss_am35x_pwrdm = { + .name = "dss_pwrdm", + .prcm_offs = OMAP3430_DSS_MOD, + .pwrsts = PWRSTS_ON, + .pwrsts_logic_ret = PWRSTS_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_ON, /* MEMRETSTATE */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* MEMONSTATE */ + }, + .voltdm = { .name = "core" }, +}; + +/* + * Although the 34XX TRM Rev K Table 4-371 notes that retention is a + * possible SGX powerstate, the SGX device itself does not support + * retention. + */ +static struct powerdomain sgx_pwrdm = { + .name = "sgx_pwrdm", + .prcm_offs = OMAP3430ES2_SGX_MOD, + /* XXX This is accurate for 3430 SGX, but what about GFX? */ + .pwrsts = PWRSTS_OFF_ON, + .pwrsts_logic_ret = PWRSTS_RET, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_RET, /* MEMRETSTATE */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* MEMONSTATE */ + }, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain sgx_am35x_pwrdm = { + .name = "sgx_pwrdm", + .prcm_offs = OMAP3430ES2_SGX_MOD, + .pwrsts = PWRSTS_ON, + .pwrsts_logic_ret = PWRSTS_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_ON, /* MEMRETSTATE */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* MEMONSTATE */ + }, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain cam_pwrdm = { + .name = "cam_pwrdm", + .prcm_offs = OMAP3430_CAM_MOD, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_RET, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_RET, /* MEMRETSTATE */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* MEMONSTATE */ + }, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain per_pwrdm = { + .name = "per_pwrdm", + .prcm_offs = OMAP3430_PER_MOD, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_RET, /* MEMRETSTATE */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* MEMONSTATE */ + }, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain per_am35x_pwrdm = { + .name = "per_pwrdm", + .prcm_offs = OMAP3430_PER_MOD, + .pwrsts = PWRSTS_ON, + .pwrsts_logic_ret = PWRSTS_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_ON, /* MEMRETSTATE */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* MEMONSTATE */ + }, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain emu_pwrdm = { + .name = "emu_pwrdm", + .prcm_offs = OMAP3430_EMU_MOD, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain neon_pwrdm = { + .name = "neon_pwrdm", + .prcm_offs = OMAP3430_NEON_MOD, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_RET, + .voltdm = { .name = "mpu_iva" }, +}; + +static struct powerdomain neon_am35x_pwrdm = { + .name = "neon_pwrdm", + .prcm_offs = OMAP3430_NEON_MOD, + .pwrsts = PWRSTS_ON, + .pwrsts_logic_ret = PWRSTS_ON, + .voltdm = { .name = "mpu_iva" }, +}; + +static struct powerdomain usbhost_pwrdm = { + .name = "usbhost_pwrdm", + .prcm_offs = OMAP3430ES2_USBHOST_MOD, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_RET, + /* + * REVISIT: Enabling usb host save and restore mechanism seems to + * leave the usb host domain permanently in ACTIVE mode after + * changing the usb host power domain state from OFF to active once. + * Disabling for now. + */ + /*.flags = PWRDM_HAS_HDWR_SAR,*/ /* for USBHOST ctrlr only */ + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_RET, /* MEMRETSTATE */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* MEMONSTATE */ + }, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain dpll1_pwrdm = { + .name = "dpll1_pwrdm", + .prcm_offs = MPU_MOD, + .voltdm = { .name = "mpu_iva" }, +}; + +static struct powerdomain dpll2_pwrdm = { + .name = "dpll2_pwrdm", + .prcm_offs = OMAP3430_IVA2_MOD, + .voltdm = { .name = "mpu_iva" }, +}; + +static struct powerdomain dpll3_pwrdm = { + .name = "dpll3_pwrdm", + .prcm_offs = PLL_MOD, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain dpll4_pwrdm = { + .name = "dpll4_pwrdm", + .prcm_offs = PLL_MOD, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain dpll5_pwrdm = { + .name = "dpll5_pwrdm", + .prcm_offs = PLL_MOD, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain alwon_81xx_pwrdm = { + .name = "alwon_pwrdm", + .prcm_offs = TI81XX_PRM_ALWON_MOD, + .pwrsts = PWRSTS_OFF_ON, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain device_81xx_pwrdm = { + .name = "device_pwrdm", + .prcm_offs = TI81XX_PRM_DEVICE_MOD, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain active_816x_pwrdm = { + .name = "active_pwrdm", + .prcm_offs = TI816X_PRM_ACTIVE_MOD, + .pwrsts = PWRSTS_OFF_ON, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain default_816x_pwrdm = { + .name = "default_pwrdm", + .prcm_offs = TI81XX_PRM_DEFAULT_MOD, + .pwrsts = PWRSTS_OFF_ON, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain ivahd0_816x_pwrdm = { + .name = "ivahd0_pwrdm", + .prcm_offs = TI816X_PRM_IVAHD0_MOD, + .pwrsts = PWRSTS_OFF_ON, + .voltdm = { .name = "mpu_iva" }, +}; + +static struct powerdomain ivahd1_816x_pwrdm = { + .name = "ivahd1_pwrdm", + .prcm_offs = TI816X_PRM_IVAHD1_MOD, + .pwrsts = PWRSTS_OFF_ON, + .voltdm = { .name = "mpu_iva" }, +}; + +static struct powerdomain ivahd2_816x_pwrdm = { + .name = "ivahd2_pwrdm", + .prcm_offs = TI816X_PRM_IVAHD2_MOD, + .pwrsts = PWRSTS_OFF_ON, + .voltdm = { .name = "mpu_iva" }, +}; + +static struct powerdomain sgx_816x_pwrdm = { + .name = "sgx_pwrdm", + .prcm_offs = TI816X_PRM_SGX_MOD, + .pwrsts = PWRSTS_OFF_ON, + .voltdm = { .name = "core" }, +}; + +/* As powerdomains are added or removed above, this list must also be changed */ +static struct powerdomain *powerdomains_omap3430_common[] __initdata = { + &wkup_omap2_pwrdm, + &iva2_pwrdm, + &mpu_3xxx_pwrdm, + &neon_pwrdm, + &cam_pwrdm, + &dss_pwrdm, + &per_pwrdm, + &emu_pwrdm, + &dpll1_pwrdm, + &dpll2_pwrdm, + &dpll3_pwrdm, + &dpll4_pwrdm, + NULL +}; + +static struct powerdomain *powerdomains_omap3430es1[] __initdata = { + &gfx_omap2_pwrdm, + &core_3xxx_pre_es3_1_pwrdm, + NULL +}; + +/* also includes 3630ES1.0 */ +static struct powerdomain *powerdomains_omap3430es2_es3_0[] __initdata = { + &core_3xxx_pre_es3_1_pwrdm, + &sgx_pwrdm, + &usbhost_pwrdm, + &dpll5_pwrdm, + NULL +}; + +/* also includes 3630ES1.1+ */ +static struct powerdomain *powerdomains_omap3430es3_1plus[] __initdata = { + &core_3xxx_es3_1_pwrdm, + &sgx_pwrdm, + &usbhost_pwrdm, + &dpll5_pwrdm, + NULL +}; + +static struct powerdomain *powerdomains_am35x[] __initdata = { + &wkup_omap2_pwrdm, + &mpu_am35x_pwrdm, + &neon_am35x_pwrdm, + &core_am35x_pwrdm, + &sgx_am35x_pwrdm, + &dss_am35x_pwrdm, + &per_am35x_pwrdm, + &emu_pwrdm, + &dpll1_pwrdm, + &dpll3_pwrdm, + &dpll4_pwrdm, + &dpll5_pwrdm, + NULL +}; + +static struct powerdomain *powerdomains_ti81xx[] __initdata = { + &alwon_81xx_pwrdm, + &device_81xx_pwrdm, + &active_816x_pwrdm, + &default_816x_pwrdm, + &ivahd0_816x_pwrdm, + &ivahd1_816x_pwrdm, + &ivahd2_816x_pwrdm, + &sgx_816x_pwrdm, + NULL +}; + +void __init omap3xxx_powerdomains_init(void) +{ + unsigned int rev; + + if (!cpu_is_omap34xx()) + return; + + pwrdm_register_platform_funcs(&omap3_pwrdm_operations); + + rev = omap_rev(); + + if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) { + pwrdm_register_pwrdms(powerdomains_am35x); + } else if (rev == TI8168_REV_ES1_0 || rev == TI8168_REV_ES1_1 + || rev == TI8168_REV_ES2_0 || rev == TI8168_REV_ES2_1) { + pwrdm_register_pwrdms(powerdomains_ti81xx); + } else { + pwrdm_register_pwrdms(powerdomains_omap3430_common); + + switch (rev) { + case OMAP3430_REV_ES1_0: + pwrdm_register_pwrdms(powerdomains_omap3430es1); + break; + case OMAP3430_REV_ES2_0: + case OMAP3430_REV_ES2_1: + case OMAP3430_REV_ES3_0: + case OMAP3630_REV_ES1_0: + pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0); + break; + case OMAP3430_REV_ES3_1: + case OMAP3430_REV_ES3_1_2: + case OMAP3630_REV_ES1_1: + case OMAP3630_REV_ES1_2: + pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus); + break; + default: + WARN(1, "OMAP3 powerdomain init: unknown chip type\n"); + } + } + + pwrdm_complete_init(); +} diff --git a/arch/arm/mach-omap2/powerdomains43xx_data.c b/arch/arm/mach-omap2/powerdomains43xx_data.c new file mode 100644 index 00000000000..95fee54c38a --- /dev/null +++ b/arch/arm/mach-omap2/powerdomains43xx_data.c @@ -0,0 +1,136 @@ +/* + * AM43xx Power domains framework + * + * Copyright (C) 2013 Texas Instruments, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include "powerdomain.h" + +#include "prcm-common.h" +#include "prcm44xx.h" +#include "prcm43xx.h" + +static struct powerdomain gfx_43xx_pwrdm = { + .name = "gfx_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = AM43XX_PRM_GFX_INST, + .prcm_partition = AM43XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .banks = 1, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* gfx_mem */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +static struct powerdomain mpu_43xx_pwrdm = { + .name = "mpu_pwrdm", + .voltdm = { .name = "mpu" }, + .prcm_offs = AM43XX_PRM_MPU_INST, + .prcm_partition = AM43XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 3, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* mpu_l1 */ + [1] = PWRSTS_OFF_RET, /* mpu_l2 */ + [2] = PWRSTS_OFF_RET, /* mpu_ram */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* mpu_l1 */ + [1] = PWRSTS_ON, /* mpu_l2 */ + [2] = PWRSTS_ON, /* mpu_ram */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +static struct powerdomain rtc_43xx_pwrdm = { + .name = "rtc_pwrdm", + .voltdm = { .name = "rtc" }, + .prcm_offs = AM43XX_PRM_RTC_INST, + .prcm_partition = AM43XX_PRM_PARTITION, + .pwrsts = PWRSTS_ON, +}; + +static struct powerdomain wkup_43xx_pwrdm = { + .name = "wkup_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = AM43XX_PRM_WKUP_INST, + .prcm_partition = AM43XX_PRM_PARTITION, + .pwrsts = PWRSTS_ON, + .banks = 1, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* debugss_mem */ + }, +}; + +static struct powerdomain tamper_43xx_pwrdm = { + .name = "tamper_pwrdm", + .voltdm = { .name = "tamper" }, + .prcm_offs = AM43XX_PRM_TAMPER_INST, + .prcm_partition = AM43XX_PRM_PARTITION, + .pwrsts = PWRSTS_ON, +}; + +static struct powerdomain cefuse_43xx_pwrdm = { + .name = "cefuse_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = AM43XX_PRM_CEFUSE_INST, + .prcm_partition = AM43XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +static struct powerdomain per_43xx_pwrdm = { + .name = "per_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = AM43XX_PRM_PER_INST, + .prcm_partition = AM43XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 4, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* icss_mem */ + [1] = PWRSTS_OFF_RET, /* per_mem */ + [2] = PWRSTS_OFF_RET, /* ram1_mem */ + [3] = PWRSTS_OFF_RET, /* ram2_mem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* icss_mem */ + [1] = PWRSTS_ON, /* per_mem */ + [2] = PWRSTS_ON, /* ram1_mem */ + [3] = PWRSTS_ON, /* ram2_mem */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +static struct powerdomain *powerdomains_am43xx[] __initdata = { + &gfx_43xx_pwrdm, + &mpu_43xx_pwrdm, + &rtc_43xx_pwrdm, + &wkup_43xx_pwrdm, + &tamper_43xx_pwrdm, + &cefuse_43xx_pwrdm, + &per_43xx_pwrdm, + NULL +}; + +static int am43xx_check_vcvp(void) +{ + return 0; +} + +void __init am43xx_powerdomains_init(void) +{ + omap4_pwrdm_operations.pwrdm_has_voltdm = am43xx_check_vcvp; + pwrdm_register_platform_funcs(&omap4_pwrdm_operations); + pwrdm_register_pwrdms(powerdomains_am43xx); + pwrdm_complete_init(); +} diff --git a/arch/arm/mach-omap2/powerdomains44xx_data.c b/arch/arm/mach-omap2/powerdomains44xx_data.c new file mode 100644 index 00000000000..704664c0e25 --- /dev/null +++ b/arch/arm/mach-omap2/powerdomains44xx_data.c @@ -0,0 +1,358 @@ +/* + * OMAP4 Power domains framework + * + * Copyright (C) 2009-2011 Texas Instruments, Inc. + * Copyright (C) 2009-2011 Nokia Corporation + * + * Abhijit Pagare (abhijitpagare@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * Paul Walmsley (paul@pwsan.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include "powerdomain.h" + +#include "prcm-common.h" +#include "prcm44xx.h" +#include "prm-regbits-44xx.h" +#include "prm44xx.h" +#include "prcm_mpu44xx.h" + +/* core_44xx_pwrdm: CORE power domain */ +static struct powerdomain core_44xx_pwrdm = { + .name = "core_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = OMAP4430_PRM_CORE_INST, + .prcm_partition = OMAP4430_PRM_PARTITION, + .pwrsts = PWRSTS_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 5, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF, /* core_nret_bank */ + [1] = PWRSTS_RET, /* core_ocmram */ + [2] = PWRSTS_RET, /* core_other_bank */ + [3] = PWRSTS_OFF_RET, /* ducati_l2ram */ + [4] = PWRSTS_OFF_RET, /* ducati_unicache */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* core_nret_bank */ + [1] = PWRSTS_ON, /* core_ocmram */ + [2] = PWRSTS_ON, /* core_other_bank */ + [3] = PWRSTS_ON, /* ducati_l2ram */ + [4] = PWRSTS_ON, /* ducati_unicache */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* gfx_44xx_pwrdm: 3D accelerator power domain */ +static struct powerdomain gfx_44xx_pwrdm = { + .name = "gfx_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = OMAP4430_PRM_GFX_INST, + .prcm_partition = OMAP4430_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF, /* gfx_mem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* gfx_mem */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* abe_44xx_pwrdm: Audio back end power domain */ +static struct powerdomain abe_44xx_pwrdm = { + .name = "abe_pwrdm", + .voltdm = { .name = "iva" }, + .prcm_offs = OMAP4430_PRM_ABE_INST, + .prcm_partition = OMAP4430_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF, + .banks = 2, + .pwrsts_mem_ret = { + [0] = PWRSTS_RET, /* aessmem */ + [1] = PWRSTS_OFF, /* periphmem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* aessmem */ + [1] = PWRSTS_ON, /* periphmem */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* dss_44xx_pwrdm: Display subsystem power domain */ +static struct powerdomain dss_44xx_pwrdm = { + .name = "dss_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = OMAP4430_PRM_DSS_INST, + .prcm_partition = OMAP4430_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF, /* dss_mem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* dss_mem */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* tesla_44xx_pwrdm: Tesla processor power domain */ +static struct powerdomain tesla_44xx_pwrdm = { + .name = "tesla_pwrdm", + .voltdm = { .name = "iva" }, + .prcm_offs = OMAP4430_PRM_TESLA_INST, + .prcm_partition = OMAP4430_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 3, + .pwrsts_mem_ret = { + [0] = PWRSTS_RET, /* tesla_edma */ + [1] = PWRSTS_OFF_RET, /* tesla_l1 */ + [2] = PWRSTS_OFF_RET, /* tesla_l2 */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* tesla_edma */ + [1] = PWRSTS_ON, /* tesla_l1 */ + [2] = PWRSTS_ON, /* tesla_l2 */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* wkup_44xx_pwrdm: Wake-up power domain */ +static struct powerdomain wkup_44xx_pwrdm = { + .name = "wkup_pwrdm", + .voltdm = { .name = "wakeup" }, + .prcm_offs = OMAP4430_PRM_WKUP_INST, + .prcm_partition = OMAP4430_PRM_PARTITION, + .pwrsts = PWRSTS_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF, /* wkup_bank */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* wkup_bank */ + }, +}; + +/* cpu0_44xx_pwrdm: MPU0 processor and Neon coprocessor power domain */ +static struct powerdomain cpu0_44xx_pwrdm = { + .name = "cpu0_pwrdm", + .voltdm = { .name = "mpu" }, + .prcm_offs = OMAP4430_PRCM_MPU_CPU0_INST, + .prcm_partition = OMAP4430_PRCM_MPU_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* cpu0_l1 */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* cpu0_l1 */ + }, +}; + +/* cpu1_44xx_pwrdm: MPU1 processor and Neon coprocessor power domain */ +static struct powerdomain cpu1_44xx_pwrdm = { + .name = "cpu1_pwrdm", + .voltdm = { .name = "mpu" }, + .prcm_offs = OMAP4430_PRCM_MPU_CPU1_INST, + .prcm_partition = OMAP4430_PRCM_MPU_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* cpu1_l1 */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* cpu1_l1 */ + }, +}; + +/* emu_44xx_pwrdm: Emulation power domain */ +static struct powerdomain emu_44xx_pwrdm = { + .name = "emu_pwrdm", + .voltdm = { .name = "wakeup" }, + .prcm_offs = OMAP4430_PRM_EMU_INST, + .prcm_partition = OMAP4430_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF, /* emu_bank */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* emu_bank */ + }, +}; + +/* mpu_44xx_pwrdm: Modena processor and the Neon coprocessor power domain */ +static struct powerdomain mpu_44xx_pwrdm = { + .name = "mpu_pwrdm", + .voltdm = { .name = "mpu" }, + .prcm_offs = OMAP4430_PRM_MPU_INST, + .prcm_partition = OMAP4430_PRM_PARTITION, + .pwrsts = PWRSTS_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 3, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* mpu_l1 */ + [1] = PWRSTS_OFF_RET, /* mpu_l2 */ + [2] = PWRSTS_RET, /* mpu_ram */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* mpu_l1 */ + [1] = PWRSTS_ON, /* mpu_l2 */ + [2] = PWRSTS_ON, /* mpu_ram */ + }, +}; + +/* ivahd_44xx_pwrdm: IVA-HD power domain */ +static struct powerdomain ivahd_44xx_pwrdm = { + .name = "ivahd_pwrdm", + .voltdm = { .name = "iva" }, + .prcm_offs = OMAP4430_PRM_IVAHD_INST, + .prcm_partition = OMAP4430_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF, + .banks = 4, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF, /* hwa_mem */ + [1] = PWRSTS_OFF_RET, /* sl2_mem */ + [2] = PWRSTS_OFF_RET, /* tcm1_mem */ + [3] = PWRSTS_OFF_RET, /* tcm2_mem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* hwa_mem */ + [1] = PWRSTS_ON, /* sl2_mem */ + [2] = PWRSTS_ON, /* tcm1_mem */ + [3] = PWRSTS_ON, /* tcm2_mem */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* cam_44xx_pwrdm: Camera subsystem power domain */ +static struct powerdomain cam_44xx_pwrdm = { + .name = "cam_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = OMAP4430_PRM_CAM_INST, + .prcm_partition = OMAP4430_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF, /* cam_mem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* cam_mem */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* l3init_44xx_pwrdm: L3 initators pheripherals power domain */ +static struct powerdomain l3init_44xx_pwrdm = { + .name = "l3init_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = OMAP4430_PRM_L3INIT_INST, + .prcm_partition = OMAP4430_PRM_PARTITION, + .pwrsts = PWRSTS_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF, /* l3init_bank1 */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* l3init_bank1 */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* l4per_44xx_pwrdm: Target peripherals power domain */ +static struct powerdomain l4per_44xx_pwrdm = { + .name = "l4per_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = OMAP4430_PRM_L4PER_INST, + .prcm_partition = OMAP4430_PRM_PARTITION, + .pwrsts = PWRSTS_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 2, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF, /* nonretained_bank */ + [1] = PWRSTS_RET, /* retained_bank */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* nonretained_bank */ + [1] = PWRSTS_ON, /* retained_bank */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* + * always_on_core_44xx_pwrdm: Always ON logic that sits in VDD_CORE voltage + * domain + */ +static struct powerdomain always_on_core_44xx_pwrdm = { + .name = "always_on_core_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = OMAP4430_PRM_ALWAYS_ON_INST, + .prcm_partition = OMAP4430_PRM_PARTITION, + .pwrsts = PWRSTS_ON, +}; + +/* cefuse_44xx_pwrdm: Customer efuse controller power domain */ +static struct powerdomain cefuse_44xx_pwrdm = { + .name = "cefuse_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = OMAP4430_PRM_CEFUSE_INST, + .prcm_partition = OMAP4430_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* + * The following power domains are not under SW control + * + * always_on_iva + * always_on_mpu + * stdefuse + */ + +/* As powerdomains are added or removed above, this list must also be changed */ +static struct powerdomain *powerdomains_omap44xx[] __initdata = { + &core_44xx_pwrdm, + &gfx_44xx_pwrdm, + &abe_44xx_pwrdm, + &dss_44xx_pwrdm, + &tesla_44xx_pwrdm, + &wkup_44xx_pwrdm, + &cpu0_44xx_pwrdm, + &cpu1_44xx_pwrdm, + &emu_44xx_pwrdm, + &mpu_44xx_pwrdm, + &ivahd_44xx_pwrdm, + &cam_44xx_pwrdm, + &l3init_44xx_pwrdm, + &l4per_44xx_pwrdm, + &always_on_core_44xx_pwrdm, + &cefuse_44xx_pwrdm, + NULL +}; + +void __init omap44xx_powerdomains_init(void) +{ + pwrdm_register_platform_funcs(&omap4_pwrdm_operations); + pwrdm_register_pwrdms(powerdomains_omap44xx); + pwrdm_complete_init(); +} diff --git a/arch/arm/mach-omap2/powerdomains54xx_data.c b/arch/arm/mach-omap2/powerdomains54xx_data.c new file mode 100644 index 00000000000..ce1d752af99 --- /dev/null +++ b/arch/arm/mach-omap2/powerdomains54xx_data.c @@ -0,0 +1,330 @@ +/* + * OMAP54XX Power domains framework + * + * Copyright (C) 2013 Texas Instruments, Inc. + * + * Abhijit Pagare (abhijitpagare@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * Paul Walmsley (paul@pwsan.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include "powerdomain.h" + +#include "prcm-common.h" +#include "prcm44xx.h" +#include "prm54xx.h" +#include "prcm_mpu54xx.h" + +/* core_54xx_pwrdm: CORE power domain */ +static struct powerdomain core_54xx_pwrdm = { + .name = "core_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = OMAP54XX_PRM_CORE_INST, + .prcm_partition = OMAP54XX_PRM_PARTITION, + .pwrsts = PWRSTS_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 5, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* core_nret_bank */ + [1] = PWRSTS_OFF_RET, /* core_ocmram */ + [2] = PWRSTS_OFF_RET, /* core_other_bank */ + [3] = PWRSTS_OFF_RET, /* ipu_l2ram */ + [4] = PWRSTS_OFF_RET, /* ipu_unicache */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* core_nret_bank */ + [1] = PWRSTS_OFF_RET, /* core_ocmram */ + [2] = PWRSTS_OFF_RET, /* core_other_bank */ + [3] = PWRSTS_OFF_RET, /* ipu_l2ram */ + [4] = PWRSTS_OFF_RET, /* ipu_unicache */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* abe_54xx_pwrdm: Audio back end power domain */ +static struct powerdomain abe_54xx_pwrdm = { + .name = "abe_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = OMAP54XX_PRM_ABE_INST, + .prcm_partition = OMAP54XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF, + .banks = 2, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* aessmem */ + [1] = PWRSTS_OFF_RET, /* periphmem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* aessmem */ + [1] = PWRSTS_OFF_RET, /* periphmem */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* coreaon_54xx_pwrdm: Always ON logic that sits in VDD_CORE voltage domain */ +static struct powerdomain coreaon_54xx_pwrdm = { + .name = "coreaon_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = OMAP54XX_PRM_COREAON_INST, + .prcm_partition = OMAP54XX_PRM_PARTITION, + .pwrsts = PWRSTS_ON, +}; + +/* dss_54xx_pwrdm: Display subsystem power domain */ +static struct powerdomain dss_54xx_pwrdm = { + .name = "dss_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = OMAP54XX_PRM_DSS_INST, + .prcm_partition = OMAP54XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* dss_mem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* dss_mem */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* cpu0_54xx_pwrdm: MPU0 processor and Neon coprocessor power domain */ +static struct powerdomain cpu0_54xx_pwrdm = { + .name = "cpu0_pwrdm", + .voltdm = { .name = "mpu" }, + .prcm_offs = OMAP54XX_PRCM_MPU_PRM_C0_INST, + .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* cpu0_l1 */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* cpu0_l1 */ + }, +}; + +/* cpu1_54xx_pwrdm: MPU1 processor and Neon coprocessor power domain */ +static struct powerdomain cpu1_54xx_pwrdm = { + .name = "cpu1_pwrdm", + .voltdm = { .name = "mpu" }, + .prcm_offs = OMAP54XX_PRCM_MPU_PRM_C1_INST, + .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* cpu1_l1 */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* cpu1_l1 */ + }, +}; + +/* emu_54xx_pwrdm: Emulation power domain */ +static struct powerdomain emu_54xx_pwrdm = { + .name = "emu_pwrdm", + .voltdm = { .name = "wkup" }, + .prcm_offs = OMAP54XX_PRM_EMU_INST, + .prcm_partition = OMAP54XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* emu_bank */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* emu_bank */ + }, +}; + +/* mpu_54xx_pwrdm: Modena processor and the Neon coprocessor power domain */ +static struct powerdomain mpu_54xx_pwrdm = { + .name = "mpu_pwrdm", + .voltdm = { .name = "mpu" }, + .prcm_offs = OMAP54XX_PRM_MPU_INST, + .prcm_partition = OMAP54XX_PRM_PARTITION, + .pwrsts = PWRSTS_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 2, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* mpu_l2 */ + [1] = PWRSTS_RET, /* mpu_ram */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* mpu_l2 */ + [1] = PWRSTS_OFF_RET, /* mpu_ram */ + }, +}; + +/* custefuse_54xx_pwrdm: Customer efuse controller power domain */ +static struct powerdomain custefuse_54xx_pwrdm = { + .name = "custefuse_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = OMAP54XX_PRM_CUSTEFUSE_INST, + .prcm_partition = OMAP54XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* dsp_54xx_pwrdm: Tesla processor power domain */ +static struct powerdomain dsp_54xx_pwrdm = { + .name = "dsp_pwrdm", + .voltdm = { .name = "mm" }, + .prcm_offs = OMAP54XX_PRM_DSP_INST, + .prcm_partition = OMAP54XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 3, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* dsp_edma */ + [1] = PWRSTS_OFF_RET, /* dsp_l1 */ + [2] = PWRSTS_OFF_RET, /* dsp_l2 */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* dsp_edma */ + [1] = PWRSTS_OFF_RET, /* dsp_l1 */ + [2] = PWRSTS_OFF_RET, /* dsp_l2 */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* cam_54xx_pwrdm: Camera subsystem power domain */ +static struct powerdomain cam_54xx_pwrdm = { + .name = "cam_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = OMAP54XX_PRM_CAM_INST, + .prcm_partition = OMAP54XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* cam_mem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* cam_mem */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* l3init_54xx_pwrdm: L3 initators pheripherals power domain */ +static struct powerdomain l3init_54xx_pwrdm = { + .name = "l3init_pwrdm", + .voltdm = { .name = "core" }, + .prcm_offs = OMAP54XX_PRM_L3INIT_INST, + .prcm_partition = OMAP54XX_PRM_PARTITION, + .pwrsts = PWRSTS_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 2, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* l3init_bank1 */ + [1] = PWRSTS_OFF_RET, /* l3init_bank2 */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* l3init_bank1 */ + [1] = PWRSTS_OFF_RET, /* l3init_bank2 */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* gpu_54xx_pwrdm: 3D accelerator power domain */ +static struct powerdomain gpu_54xx_pwrdm = { + .name = "gpu_pwrdm", + .voltdm = { .name = "mm" }, + .prcm_offs = OMAP54XX_PRM_GPU_INST, + .prcm_partition = OMAP54XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* gpu_mem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* gpu_mem */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* wkupaon_54xx_pwrdm: Wake-up power domain */ +static struct powerdomain wkupaon_54xx_pwrdm = { + .name = "wkupaon_pwrdm", + .voltdm = { .name = "wkup" }, + .prcm_offs = OMAP54XX_PRM_WKUPAON_INST, + .prcm_partition = OMAP54XX_PRM_PARTITION, + .pwrsts = PWRSTS_ON, + .banks = 1, + .pwrsts_mem_ret = { + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* wkup_bank */ + }, +}; + +/* iva_54xx_pwrdm: IVA-HD power domain */ +static struct powerdomain iva_54xx_pwrdm = { + .name = "iva_pwrdm", + .voltdm = { .name = "mm" }, + .prcm_offs = OMAP54XX_PRM_IVA_INST, + .prcm_partition = OMAP54XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF, + .banks = 4, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* hwa_mem */ + [1] = PWRSTS_OFF_RET, /* sl2_mem */ + [2] = PWRSTS_OFF_RET, /* tcm1_mem */ + [3] = PWRSTS_OFF_RET, /* tcm2_mem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* hwa_mem */ + [1] = PWRSTS_OFF_RET, /* sl2_mem */ + [2] = PWRSTS_OFF_RET, /* tcm1_mem */ + [3] = PWRSTS_OFF_RET, /* tcm2_mem */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* + * The following power domains are not under SW control + * + * mpuaon + * mmaon + */ + +/* As powerdomains are added or removed above, this list must also be changed */ +static struct powerdomain *powerdomains_omap54xx[] __initdata = { + &core_54xx_pwrdm, + &abe_54xx_pwrdm, + &coreaon_54xx_pwrdm, + &dss_54xx_pwrdm, + &cpu0_54xx_pwrdm, + &cpu1_54xx_pwrdm, + &emu_54xx_pwrdm, + &mpu_54xx_pwrdm, + &custefuse_54xx_pwrdm, + &dsp_54xx_pwrdm, + &cam_54xx_pwrdm, + &l3init_54xx_pwrdm, + &gpu_54xx_pwrdm, + &wkupaon_54xx_pwrdm, + &iva_54xx_pwrdm, + NULL +}; + +void __init omap54xx_powerdomains_init(void) +{ + pwrdm_register_platform_funcs(&omap4_pwrdm_operations); + pwrdm_register_pwrdms(powerdomains_omap54xx); + pwrdm_complete_init(); +} diff --git a/arch/arm/mach-omap2/powerdomains7xx_data.c b/arch/arm/mach-omap2/powerdomains7xx_data.c new file mode 100644 index 00000000000..48151d1cfde --- /dev/null +++ b/arch/arm/mach-omap2/powerdomains7xx_data.c @@ -0,0 +1,454 @@ +/* + * DRA7xx Power domains framework + * + * Copyright (C) 2009-2013 Texas Instruments, Inc. + * Copyright (C) 2009-2011 Nokia Corporation + * + * Generated by code originally written by: + * Abhijit Pagare (abhijitpagare@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * Paul Walmsley (paul@pwsan.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include "powerdomain.h" + +#include "prcm-common.h" +#include "prcm44xx.h" +#include "prm7xx.h" +#include "prcm_mpu7xx.h" + +/* iva_7xx_pwrdm: IVA-HD power domain */ +static struct powerdomain iva_7xx_pwrdm = { + .name = "iva_pwrdm", + .prcm_offs = DRA7XX_PRM_IVA_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF, + .banks = 4, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* hwa_mem */ + [1] = PWRSTS_OFF_RET, /* sl2_mem */ + [2] = PWRSTS_OFF_RET, /* tcm1_mem */ + [3] = PWRSTS_OFF_RET, /* tcm2_mem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* hwa_mem */ + [1] = PWRSTS_OFF_RET, /* sl2_mem */ + [2] = PWRSTS_OFF_RET, /* tcm1_mem */ + [3] = PWRSTS_OFF_RET, /* tcm2_mem */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* rtc_7xx_pwrdm: */ +static struct powerdomain rtc_7xx_pwrdm = { + .name = "rtc_pwrdm", + .prcm_offs = DRA7XX_PRM_RTC_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_ON, +}; + +/* custefuse_7xx_pwrdm: Customer efuse controller power domain */ +static struct powerdomain custefuse_7xx_pwrdm = { + .name = "custefuse_pwrdm", + .prcm_offs = DRA7XX_PRM_CUSTEFUSE_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* ipu_7xx_pwrdm: Audio back end power domain */ +static struct powerdomain ipu_7xx_pwrdm = { + .name = "ipu_pwrdm", + .prcm_offs = DRA7XX_PRM_IPU_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF, + .banks = 2, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* aessmem */ + [1] = PWRSTS_OFF_RET, /* periphmem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* aessmem */ + [1] = PWRSTS_OFF_RET, /* periphmem */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* dss_7xx_pwrdm: Display subsystem power domain */ +static struct powerdomain dss_7xx_pwrdm = { + .name = "dss_pwrdm", + .prcm_offs = DRA7XX_PRM_DSS_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* dss_mem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* dss_mem */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* l4per_7xx_pwrdm: Target peripherals power domain */ +static struct powerdomain l4per_7xx_pwrdm = { + .name = "l4per_pwrdm", + .prcm_offs = DRA7XX_PRM_L4PER_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 2, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* nonretained_bank */ + [1] = PWRSTS_OFF_RET, /* retained_bank */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* nonretained_bank */ + [1] = PWRSTS_OFF_RET, /* retained_bank */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* gpu_7xx_pwrdm: 3D accelerator power domain */ +static struct powerdomain gpu_7xx_pwrdm = { + .name = "gpu_pwrdm", + .prcm_offs = DRA7XX_PRM_GPU_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* gpu_mem */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* gpu_mem */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* wkupaon_7xx_pwrdm: Wake-up power domain */ +static struct powerdomain wkupaon_7xx_pwrdm = { + .name = "wkupaon_pwrdm", + .prcm_offs = DRA7XX_PRM_WKUPAON_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_ON, + .banks = 1, + .pwrsts_mem_ret = { + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* wkup_bank */ + }, +}; + +/* core_7xx_pwrdm: CORE power domain */ +static struct powerdomain core_7xx_pwrdm = { + .name = "core_pwrdm", + .prcm_offs = DRA7XX_PRM_CORE_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 5, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* core_nret_bank */ + [1] = PWRSTS_OFF_RET, /* core_ocmram */ + [2] = PWRSTS_OFF_RET, /* core_other_bank */ + [3] = PWRSTS_OFF_RET, /* ipu_l2ram */ + [4] = PWRSTS_OFF_RET, /* ipu_unicache */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* core_nret_bank */ + [1] = PWRSTS_OFF_RET, /* core_ocmram */ + [2] = PWRSTS_OFF_RET, /* core_other_bank */ + [3] = PWRSTS_OFF_RET, /* ipu_l2ram */ + [4] = PWRSTS_OFF_RET, /* ipu_unicache */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* coreaon_7xx_pwrdm: Always ON logic that sits in VDD_CORE voltage domain */ +static struct powerdomain coreaon_7xx_pwrdm = { + .name = "coreaon_pwrdm", + .prcm_offs = DRA7XX_PRM_COREAON_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_ON, +}; + +/* cpu0_7xx_pwrdm: MPU0 processor and Neon coprocessor power domain */ +static struct powerdomain cpu0_7xx_pwrdm = { + .name = "cpu0_pwrdm", + .prcm_offs = DRA7XX_MPU_PRCM_PRM_C0_INST, + .prcm_partition = DRA7XX_MPU_PRCM_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* cpu0_l1 */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* cpu0_l1 */ + }, +}; + +/* cpu1_7xx_pwrdm: MPU1 processor and Neon coprocessor power domain */ +static struct powerdomain cpu1_7xx_pwrdm = { + .name = "cpu1_pwrdm", + .prcm_offs = DRA7XX_MPU_PRCM_PRM_C1_INST, + .prcm_partition = DRA7XX_MPU_PRCM_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* cpu1_l1 */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_ON, /* cpu1_l1 */ + }, +}; + +/* vpe_7xx_pwrdm: */ +static struct powerdomain vpe_7xx_pwrdm = { + .name = "vpe_pwrdm", + .prcm_offs = DRA7XX_PRM_VPE_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* vpe_bank */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* vpe_bank */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* mpu_7xx_pwrdm: Modena processor and the Neon coprocessor power domain */ +static struct powerdomain mpu_7xx_pwrdm = { + .name = "mpu_pwrdm", + .prcm_offs = DRA7XX_PRM_MPU_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 2, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* mpu_l2 */ + [1] = PWRSTS_RET, /* mpu_ram */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* mpu_l2 */ + [1] = PWRSTS_OFF_RET, /* mpu_ram */ + }, +}; + +/* l3init_7xx_pwrdm: L3 initators pheripherals power domain */ +static struct powerdomain l3init_7xx_pwrdm = { + .name = "l3init_pwrdm", + .prcm_offs = DRA7XX_PRM_L3INIT_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, + .banks = 3, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* gmac_bank */ + [1] = PWRSTS_OFF_RET, /* l3init_bank1 */ + [2] = PWRSTS_OFF_RET, /* l3init_bank2 */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* gmac_bank */ + [1] = PWRSTS_OFF_RET, /* l3init_bank1 */ + [2] = PWRSTS_OFF_RET, /* l3init_bank2 */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* eve3_7xx_pwrdm: */ +static struct powerdomain eve3_7xx_pwrdm = { + .name = "eve3_pwrdm", + .prcm_offs = DRA7XX_PRM_EVE3_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* eve3_bank */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* eve3_bank */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* emu_7xx_pwrdm: Emulation power domain */ +static struct powerdomain emu_7xx_pwrdm = { + .name = "emu_pwrdm", + .prcm_offs = DRA7XX_PRM_EMU_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* emu_bank */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* emu_bank */ + }, +}; + +/* dsp2_7xx_pwrdm: */ +static struct powerdomain dsp2_7xx_pwrdm = { + .name = "dsp2_pwrdm", + .prcm_offs = DRA7XX_PRM_DSP2_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .banks = 3, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* dsp2_edma */ + [1] = PWRSTS_OFF_RET, /* dsp2_l1 */ + [2] = PWRSTS_OFF_RET, /* dsp2_l2 */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* dsp2_edma */ + [1] = PWRSTS_OFF_RET, /* dsp2_l1 */ + [2] = PWRSTS_OFF_RET, /* dsp2_l2 */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* dsp1_7xx_pwrdm: Tesla processor power domain */ +static struct powerdomain dsp1_7xx_pwrdm = { + .name = "dsp1_pwrdm", + .prcm_offs = DRA7XX_PRM_DSP1_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .banks = 3, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* dsp1_edma */ + [1] = PWRSTS_OFF_RET, /* dsp1_l1 */ + [2] = PWRSTS_OFF_RET, /* dsp1_l2 */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* dsp1_edma */ + [1] = PWRSTS_OFF_RET, /* dsp1_l1 */ + [2] = PWRSTS_OFF_RET, /* dsp1_l2 */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* cam_7xx_pwrdm: Camera subsystem power domain */ +static struct powerdomain cam_7xx_pwrdm = { + .name = "cam_pwrdm", + .prcm_offs = DRA7XX_PRM_CAM_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* vip_bank */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* vip_bank */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* eve4_7xx_pwrdm: */ +static struct powerdomain eve4_7xx_pwrdm = { + .name = "eve4_pwrdm", + .prcm_offs = DRA7XX_PRM_EVE4_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* eve4_bank */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* eve4_bank */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* eve2_7xx_pwrdm: */ +static struct powerdomain eve2_7xx_pwrdm = { + .name = "eve2_pwrdm", + .prcm_offs = DRA7XX_PRM_EVE2_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* eve2_bank */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* eve2_bank */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* eve1_7xx_pwrdm: */ +static struct powerdomain eve1_7xx_pwrdm = { + .name = "eve1_pwrdm", + .prcm_offs = DRA7XX_PRM_EVE1_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_OFF_ON, + .banks = 1, + .pwrsts_mem_ret = { + [0] = PWRSTS_OFF_RET, /* eve1_bank */ + }, + .pwrsts_mem_on = { + [0] = PWRSTS_OFF_RET, /* eve1_bank */ + }, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, +}; + +/* + * The following power domains are not under SW control + * + * mpuaon + * mmaon + */ + +/* As powerdomains are added or removed above, this list must also be changed */ +static struct powerdomain *powerdomains_dra7xx[] __initdata = { + &iva_7xx_pwrdm, + &rtc_7xx_pwrdm, + &custefuse_7xx_pwrdm, + &ipu_7xx_pwrdm, + &dss_7xx_pwrdm, + &l4per_7xx_pwrdm, + &gpu_7xx_pwrdm, + &wkupaon_7xx_pwrdm, + &core_7xx_pwrdm, + &coreaon_7xx_pwrdm, + &cpu0_7xx_pwrdm, + &cpu1_7xx_pwrdm, + &vpe_7xx_pwrdm, + &mpu_7xx_pwrdm, + &l3init_7xx_pwrdm, + &eve3_7xx_pwrdm, + &emu_7xx_pwrdm, + &dsp2_7xx_pwrdm, + &dsp1_7xx_pwrdm, + &cam_7xx_pwrdm, + &eve4_7xx_pwrdm, + &eve2_7xx_pwrdm, + &eve1_7xx_pwrdm, + NULL +}; + +void __init dra7xx_powerdomains_init(void) +{ + pwrdm_register_platform_funcs(&omap4_pwrdm_operations); + pwrdm_register_pwrdms(powerdomains_dra7xx); + pwrdm_complete_init(); +} diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index 4a32822ff3f..a8e4b582c52 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h @@ -4,8 +4,8 @@ /* * OMAP2/3 PRCM base and module definitions * - * Copyright (C) 2007-2008 Texas Instruments, Inc. - * Copyright (C) 2007-2008 Nokia Corporation + * Copyright (C) 2007-2009, 2011 Texas Instruments, Inc. + * Copyright (C) 2007-2009 Nokia Corporation * * Written by Paul Walmsley * @@ -14,7 +14,6 @@ * published by the Free Software Foundation. */ - /* Module offsets from both CM_BASE & PRM_BASE */ /* @@ -49,110 +48,157 @@ #define OMAP3430_NEON_MOD 0xb00 #define OMAP3430ES2_USBHOST_MOD 0xc00 +/* + * TI81XX PRM module offsets + */ +#define TI81XX_PRM_DEVICE_MOD 0x0000 +#define TI816X_PRM_ACTIVE_MOD 0x0a00 +#define TI81XX_PRM_DEFAULT_MOD 0x0b00 +#define TI816X_PRM_IVAHD0_MOD 0x0c00 +#define TI816X_PRM_IVAHD1_MOD 0x0d00 +#define TI816X_PRM_IVAHD2_MOD 0x0e00 +#define TI816X_PRM_SGX_MOD 0x0f00 +#define TI81XX_PRM_ALWON_MOD 0x1800 /* 24XX register bits shared between CM & PRM registers */ /* CM_FCLKEN1_CORE, CM_ICLKEN1_CORE, PM_WKEN1_CORE shared bits */ #define OMAP2420_EN_MMC_SHIFT 26 -#define OMAP2420_EN_MMC (1 << 26) +#define OMAP2420_EN_MMC_MASK (1 << 26) #define OMAP24XX_EN_UART2_SHIFT 22 -#define OMAP24XX_EN_UART2 (1 << 22) +#define OMAP24XX_EN_UART2_MASK (1 << 22) #define OMAP24XX_EN_UART1_SHIFT 21 -#define OMAP24XX_EN_UART1 (1 << 21) +#define OMAP24XX_EN_UART1_MASK (1 << 21) #define OMAP24XX_EN_MCSPI2_SHIFT 18 -#define OMAP24XX_EN_MCSPI2 (1 << 18) +#define OMAP24XX_EN_MCSPI2_MASK (1 << 18) #define OMAP24XX_EN_MCSPI1_SHIFT 17 -#define OMAP24XX_EN_MCSPI1 (1 << 17) +#define OMAP24XX_EN_MCSPI1_MASK (1 << 17) #define OMAP24XX_EN_MCBSP2_SHIFT 16 -#define OMAP24XX_EN_MCBSP2 (1 << 16) +#define OMAP24XX_EN_MCBSP2_MASK (1 << 16) #define OMAP24XX_EN_MCBSP1_SHIFT 15 -#define OMAP24XX_EN_MCBSP1 (1 << 15) +#define OMAP24XX_EN_MCBSP1_MASK (1 << 15) #define OMAP24XX_EN_GPT12_SHIFT 14 -#define OMAP24XX_EN_GPT12 (1 << 14) +#define OMAP24XX_EN_GPT12_MASK (1 << 14) #define OMAP24XX_EN_GPT11_SHIFT 13 -#define OMAP24XX_EN_GPT11 (1 << 13) +#define OMAP24XX_EN_GPT11_MASK (1 << 13) #define OMAP24XX_EN_GPT10_SHIFT 12 -#define OMAP24XX_EN_GPT10 (1 << 12) +#define OMAP24XX_EN_GPT10_MASK (1 << 12) #define OMAP24XX_EN_GPT9_SHIFT 11 -#define OMAP24XX_EN_GPT9 (1 << 11) +#define OMAP24XX_EN_GPT9_MASK (1 << 11) #define OMAP24XX_EN_GPT8_SHIFT 10 -#define OMAP24XX_EN_GPT8 (1 << 10) +#define OMAP24XX_EN_GPT8_MASK (1 << 10) #define OMAP24XX_EN_GPT7_SHIFT 9 -#define OMAP24XX_EN_GPT7 (1 << 9) +#define OMAP24XX_EN_GPT7_MASK (1 << 9) #define OMAP24XX_EN_GPT6_SHIFT 8 -#define OMAP24XX_EN_GPT6 (1 << 8) +#define OMAP24XX_EN_GPT6_MASK (1 << 8) #define OMAP24XX_EN_GPT5_SHIFT 7 -#define OMAP24XX_EN_GPT5 (1 << 7) +#define OMAP24XX_EN_GPT5_MASK (1 << 7) #define OMAP24XX_EN_GPT4_SHIFT 6 -#define OMAP24XX_EN_GPT4 (1 << 6) +#define OMAP24XX_EN_GPT4_MASK (1 << 6) #define OMAP24XX_EN_GPT3_SHIFT 5 -#define OMAP24XX_EN_GPT3 (1 << 5) +#define OMAP24XX_EN_GPT3_MASK (1 << 5) #define OMAP24XX_EN_GPT2_SHIFT 4 -#define OMAP24XX_EN_GPT2 (1 << 4) +#define OMAP24XX_EN_GPT2_MASK (1 << 4) #define OMAP2420_EN_VLYNQ_SHIFT 3 -#define OMAP2420_EN_VLYNQ (1 << 3) +#define OMAP2420_EN_VLYNQ_MASK (1 << 3) /* CM_FCLKEN2_CORE, CM_ICLKEN2_CORE, PM_WKEN2_CORE shared bits */ #define OMAP2430_EN_GPIO5_SHIFT 10 -#define OMAP2430_EN_GPIO5 (1 << 10) +#define OMAP2430_EN_GPIO5_MASK (1 << 10) #define OMAP2430_EN_MCSPI3_SHIFT 9 -#define OMAP2430_EN_MCSPI3 (1 << 9) +#define OMAP2430_EN_MCSPI3_MASK (1 << 9) #define OMAP2430_EN_MMCHS2_SHIFT 8 -#define OMAP2430_EN_MMCHS2 (1 << 8) +#define OMAP2430_EN_MMCHS2_MASK (1 << 8) #define OMAP2430_EN_MMCHS1_SHIFT 7 -#define OMAP2430_EN_MMCHS1 (1 << 7) +#define OMAP2430_EN_MMCHS1_MASK (1 << 7) #define OMAP24XX_EN_UART3_SHIFT 2 -#define OMAP24XX_EN_UART3 (1 << 2) +#define OMAP24XX_EN_UART3_MASK (1 << 2) #define OMAP24XX_EN_USB_SHIFT 0 -#define OMAP24XX_EN_USB (1 << 0) +#define OMAP24XX_EN_USB_MASK (1 << 0) /* CM_ICLKEN2_CORE, PM_WKEN2_CORE shared bits */ #define OMAP2430_EN_MDM_INTC_SHIFT 11 -#define OMAP2430_EN_MDM_INTC (1 << 11) +#define OMAP2430_EN_MDM_INTC_MASK (1 << 11) #define OMAP2430_EN_USBHS_SHIFT 6 -#define OMAP2430_EN_USBHS (1 << 6) +#define OMAP2430_EN_USBHS_MASK (1 << 6) +#define OMAP24XX_EN_GPMC_SHIFT 1 +#define OMAP24XX_EN_GPMC_MASK (1 << 1) /* CM_IDLEST1_CORE, PM_WKST1_CORE shared bits */ -#define OMAP2420_ST_MMC (1 << 26) -#define OMAP24XX_ST_UART2 (1 << 22) -#define OMAP24XX_ST_UART1 (1 << 21) -#define OMAP24XX_ST_MCSPI2 (1 << 18) -#define OMAP24XX_ST_MCSPI1 (1 << 17) -#define OMAP24XX_ST_GPT12 (1 << 14) -#define OMAP24XX_ST_GPT11 (1 << 13) -#define OMAP24XX_ST_GPT10 (1 << 12) -#define OMAP24XX_ST_GPT9 (1 << 11) -#define OMAP24XX_ST_GPT8 (1 << 10) -#define OMAP24XX_ST_GPT7 (1 << 9) -#define OMAP24XX_ST_GPT6 (1 << 8) -#define OMAP24XX_ST_GPT5 (1 << 7) -#define OMAP24XX_ST_GPT4 (1 << 6) -#define OMAP24XX_ST_GPT3 (1 << 5) -#define OMAP24XX_ST_GPT2 (1 << 4) -#define OMAP2420_ST_VLYNQ (1 << 3) +#define OMAP2420_ST_MMC_SHIFT 26 +#define OMAP2420_ST_MMC_MASK (1 << 26) +#define OMAP24XX_ST_UART2_SHIFT 22 +#define OMAP24XX_ST_UART2_MASK (1 << 22) +#define OMAP24XX_ST_UART1_SHIFT 21 +#define OMAP24XX_ST_UART1_MASK (1 << 21) +#define OMAP24XX_ST_MCSPI2_SHIFT 18 +#define OMAP24XX_ST_MCSPI2_MASK (1 << 18) +#define OMAP24XX_ST_MCSPI1_SHIFT 17 +#define OMAP24XX_ST_MCSPI1_MASK (1 << 17) +#define OMAP24XX_ST_MCBSP2_SHIFT 16 +#define OMAP24XX_ST_MCBSP2_MASK (1 << 16) +#define OMAP24XX_ST_MCBSP1_SHIFT 15 +#define OMAP24XX_ST_MCBSP1_MASK (1 << 15) +#define OMAP24XX_ST_GPT12_SHIFT 14 +#define OMAP24XX_ST_GPT12_MASK (1 << 14) +#define OMAP24XX_ST_GPT11_SHIFT 13 +#define OMAP24XX_ST_GPT11_MASK (1 << 13) +#define OMAP24XX_ST_GPT10_SHIFT 12 +#define OMAP24XX_ST_GPT10_MASK (1 << 12) +#define OMAP24XX_ST_GPT9_SHIFT 11 +#define OMAP24XX_ST_GPT9_MASK (1 << 11) +#define OMAP24XX_ST_GPT8_SHIFT 10 +#define OMAP24XX_ST_GPT8_MASK (1 << 10) +#define OMAP24XX_ST_GPT7_SHIFT 9 +#define OMAP24XX_ST_GPT7_MASK (1 << 9) +#define OMAP24XX_ST_GPT6_SHIFT 8 +#define OMAP24XX_ST_GPT6_MASK (1 << 8) +#define OMAP24XX_ST_GPT5_SHIFT 7 +#define OMAP24XX_ST_GPT5_MASK (1 << 7) +#define OMAP24XX_ST_GPT4_SHIFT 6 +#define OMAP24XX_ST_GPT4_MASK (1 << 6) +#define OMAP24XX_ST_GPT3_SHIFT 5 +#define OMAP24XX_ST_GPT3_MASK (1 << 5) +#define OMAP24XX_ST_GPT2_SHIFT 4 +#define OMAP24XX_ST_GPT2_MASK (1 << 4) +#define OMAP2420_ST_VLYNQ_SHIFT 3 +#define OMAP2420_ST_VLYNQ_MASK (1 << 3) /* CM_IDLEST2_CORE, PM_WKST2_CORE shared bits */ -#define OMAP2430_ST_MDM_INTC (1 << 11) -#define OMAP2430_ST_GPIO5 (1 << 10) -#define OMAP2430_ST_MCSPI3 (1 << 9) -#define OMAP2430_ST_MMCHS2 (1 << 8) -#define OMAP2430_ST_MMCHS1 (1 << 7) -#define OMAP2430_ST_USBHS (1 << 6) -#define OMAP24XX_ST_UART3 (1 << 2) -#define OMAP24XX_ST_USB (1 << 0) +#define OMAP2430_ST_MDM_INTC_SHIFT 11 +#define OMAP2430_ST_MDM_INTC_MASK (1 << 11) +#define OMAP2430_ST_GPIO5_SHIFT 10 +#define OMAP2430_ST_GPIO5_MASK (1 << 10) +#define OMAP2430_ST_MCSPI3_SHIFT 9 +#define OMAP2430_ST_MCSPI3_MASK (1 << 9) +#define OMAP2430_ST_MMCHS2_SHIFT 8 +#define OMAP2430_ST_MMCHS2_MASK (1 << 8) +#define OMAP2430_ST_MMCHS1_SHIFT 7 +#define OMAP2430_ST_MMCHS1_MASK (1 << 7) +#define OMAP2430_ST_USBHS_SHIFT 6 +#define OMAP2430_ST_USBHS_MASK (1 << 6) +#define OMAP24XX_ST_UART3_SHIFT 2 +#define OMAP24XX_ST_UART3_MASK (1 << 2) +#define OMAP24XX_ST_USB_SHIFT 0 +#define OMAP24XX_ST_USB_MASK (1 << 0) /* CM_FCLKEN_WKUP, CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */ #define OMAP24XX_EN_GPIOS_SHIFT 2 -#define OMAP24XX_EN_GPIOS (1 << 2) +#define OMAP24XX_EN_GPIOS_MASK (1 << 2) #define OMAP24XX_EN_GPT1_SHIFT 0 -#define OMAP24XX_EN_GPT1 (1 << 0) +#define OMAP24XX_EN_GPT1_MASK (1 << 0) /* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */ -#define OMAP24XX_ST_GPIOS (1 << 2) -#define OMAP24XX_ST_GPT1 (1 << 0) +#define OMAP24XX_ST_GPIOS_SHIFT 2 +#define OMAP24XX_ST_GPIOS_MASK (1 << 2) +#define OMAP24XX_ST_32KSYNC_SHIFT 1 +#define OMAP24XX_ST_32KSYNC_MASK (1 << 1) +#define OMAP24XX_ST_GPT1_SHIFT 0 +#define OMAP24XX_ST_GPT1_MASK (1 << 0) /* CM_IDLEST_MDM and PM_WKST_MDM shared bits */ -#define OMAP2430_ST_MDM (1 << 0) +#define OMAP2430_ST_MDM_SHIFT 0 +#define OMAP2430_ST_MDM_MASK (1 << 0) /* 3430 register bits shared between CM & PRM registers */ @@ -162,158 +208,323 @@ #define OMAP3430_REV_MASK (0xff << 0) /* CM_SYSCONFIG, PRM_SYSCONFIG shared bits */ -#define OMAP3430_AUTOIDLE (1 << 0) +#define OMAP3430_AUTOIDLE_MASK (1 << 0) /* CM_FCLKEN1_CORE, CM_ICLKEN1_CORE, PM_WKEN1_CORE shared bits */ -#define OMAP3430_EN_MMC2 (1 << 25) +#define OMAP3430_EN_MMC3_MASK (1 << 30) +#define OMAP3430_EN_MMC3_SHIFT 30 +#define OMAP3430_EN_MMC2_MASK (1 << 25) #define OMAP3430_EN_MMC2_SHIFT 25 -#define OMAP3430_EN_MMC1 (1 << 24) +#define OMAP3430_EN_MMC1_MASK (1 << 24) #define OMAP3430_EN_MMC1_SHIFT 24 -#define OMAP3430_EN_MCSPI4 (1 << 21) +#define AM35XX_EN_UART4_MASK (1 << 23) +#define AM35XX_EN_UART4_SHIFT 23 +#define OMAP3430_EN_MCSPI4_MASK (1 << 21) #define OMAP3430_EN_MCSPI4_SHIFT 21 -#define OMAP3430_EN_MCSPI3 (1 << 20) +#define OMAP3430_EN_MCSPI3_MASK (1 << 20) #define OMAP3430_EN_MCSPI3_SHIFT 20 -#define OMAP3430_EN_MCSPI2 (1 << 19) +#define OMAP3430_EN_MCSPI2_MASK (1 << 19) #define OMAP3430_EN_MCSPI2_SHIFT 19 -#define OMAP3430_EN_MCSPI1 (1 << 18) +#define OMAP3430_EN_MCSPI1_MASK (1 << 18) #define OMAP3430_EN_MCSPI1_SHIFT 18 -#define OMAP3430_EN_I2C3 (1 << 17) +#define OMAP3430_EN_I2C3_MASK (1 << 17) #define OMAP3430_EN_I2C3_SHIFT 17 -#define OMAP3430_EN_I2C2 (1 << 16) +#define OMAP3430_EN_I2C2_MASK (1 << 16) #define OMAP3430_EN_I2C2_SHIFT 16 -#define OMAP3430_EN_I2C1 (1 << 15) +#define OMAP3430_EN_I2C1_MASK (1 << 15) #define OMAP3430_EN_I2C1_SHIFT 15 -#define OMAP3430_EN_UART2 (1 << 14) +#define OMAP3430_EN_UART2_MASK (1 << 14) #define OMAP3430_EN_UART2_SHIFT 14 -#define OMAP3430_EN_UART1 (1 << 13) +#define OMAP3430_EN_UART1_MASK (1 << 13) #define OMAP3430_EN_UART1_SHIFT 13 -#define OMAP3430_EN_GPT11 (1 << 12) +#define OMAP3430_EN_GPT11_MASK (1 << 12) #define OMAP3430_EN_GPT11_SHIFT 12 -#define OMAP3430_EN_GPT10 (1 << 11) +#define OMAP3430_EN_GPT10_MASK (1 << 11) #define OMAP3430_EN_GPT10_SHIFT 11 -#define OMAP3430_EN_MCBSP5 (1 << 10) +#define OMAP3430_EN_MCBSP5_MASK (1 << 10) #define OMAP3430_EN_MCBSP5_SHIFT 10 -#define OMAP3430_EN_MCBSP1 (1 << 9) +#define OMAP3430_EN_MCBSP1_MASK (1 << 9) #define OMAP3430_EN_MCBSP1_SHIFT 9 -#define OMAP3430_EN_FSHOSTUSB (1 << 5) +#define OMAP3430_EN_FSHOSTUSB_MASK (1 << 5) #define OMAP3430_EN_FSHOSTUSB_SHIFT 5 -#define OMAP3430_EN_D2D (1 << 3) +#define OMAP3430_EN_D2D_MASK (1 << 3) #define OMAP3430_EN_D2D_SHIFT 3 /* CM_ICLKEN1_CORE, PM_WKEN1_CORE shared bits */ -#define OMAP3430_EN_HSOTGUSB (1 << 4) -#define OMAP3430_EN_HSOTGUSB_SHIFT 4 +#define OMAP3430_EN_HSOTGUSB_MASK (1 << 4) +#define OMAP3430_EN_HSOTGUSB_SHIFT 4 /* PM_WKST1_CORE, CM_IDLEST1_CORE shared bits */ -#define OMAP3430_ST_MMC2 (1 << 25) -#define OMAP3430_ST_MMC1 (1 << 24) -#define OMAP3430_ST_MCSPI4 (1 << 21) -#define OMAP3430_ST_MCSPI3 (1 << 20) -#define OMAP3430_ST_MCSPI2 (1 << 19) -#define OMAP3430_ST_MCSPI1 (1 << 18) -#define OMAP3430_ST_I2C3 (1 << 17) -#define OMAP3430_ST_I2C2 (1 << 16) -#define OMAP3430_ST_I2C1 (1 << 15) -#define OMAP3430_ST_UART2 (1 << 14) -#define OMAP3430_ST_UART1 (1 << 13) -#define OMAP3430_ST_GPT11 (1 << 12) -#define OMAP3430_ST_GPT10 (1 << 11) -#define OMAP3430_ST_MCBSP5 (1 << 10) -#define OMAP3430_ST_MCBSP1 (1 << 9) -#define OMAP3430_ST_FSHOSTUSB (1 << 5) -#define OMAP3430_ST_HSOTGUSB (1 << 4) -#define OMAP3430_ST_D2D (1 << 3) +#define OMAP3430_ST_MMC3_SHIFT 30 +#define OMAP3430_ST_MMC3_MASK (1 << 30) +#define OMAP3430_ST_MMC2_SHIFT 25 +#define OMAP3430_ST_MMC2_MASK (1 << 25) +#define OMAP3430_ST_MMC1_SHIFT 24 +#define OMAP3430_ST_MMC1_MASK (1 << 24) +#define OMAP3430_ST_MCSPI4_SHIFT 21 +#define OMAP3430_ST_MCSPI4_MASK (1 << 21) +#define OMAP3430_ST_MCSPI3_SHIFT 20 +#define OMAP3430_ST_MCSPI3_MASK (1 << 20) +#define OMAP3430_ST_MCSPI2_SHIFT 19 +#define OMAP3430_ST_MCSPI2_MASK (1 << 19) +#define OMAP3430_ST_MCSPI1_SHIFT 18 +#define OMAP3430_ST_MCSPI1_MASK (1 << 18) +#define OMAP3430_ST_I2C3_SHIFT 17 +#define OMAP3430_ST_I2C3_MASK (1 << 17) +#define OMAP3430_ST_I2C2_SHIFT 16 +#define OMAP3430_ST_I2C2_MASK (1 << 16) +#define OMAP3430_ST_I2C1_SHIFT 15 +#define OMAP3430_ST_I2C1_MASK (1 << 15) +#define OMAP3430_ST_UART2_SHIFT 14 +#define OMAP3430_ST_UART2_MASK (1 << 14) +#define OMAP3430_ST_UART1_SHIFT 13 +#define OMAP3430_ST_UART1_MASK (1 << 13) +#define OMAP3430_ST_GPT11_SHIFT 12 +#define OMAP3430_ST_GPT11_MASK (1 << 12) +#define OMAP3430_ST_GPT10_SHIFT 11 +#define OMAP3430_ST_GPT10_MASK (1 << 11) +#define OMAP3430_ST_MCBSP5_SHIFT 10 +#define OMAP3430_ST_MCBSP5_MASK (1 << 10) +#define OMAP3430_ST_MCBSP1_SHIFT 9 +#define OMAP3430_ST_MCBSP1_MASK (1 << 9) +#define OMAP3430ES1_ST_FSHOSTUSB_SHIFT 5 +#define OMAP3430ES1_ST_FSHOSTUSB_MASK (1 << 5) +#define OMAP3430ES1_ST_HSOTGUSB_SHIFT 4 +#define OMAP3430ES1_ST_HSOTGUSB_MASK (1 << 4) +#define OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT 5 +#define OMAP3430ES2_ST_HSOTGUSB_IDLE_MASK (1 << 5) +#define OMAP3430ES2_ST_HSOTGUSB_STDBY_SHIFT 4 +#define OMAP3430ES2_ST_HSOTGUSB_STDBY_MASK (1 << 4) +#define OMAP3430_ST_D2D_SHIFT 3 +#define OMAP3430_ST_D2D_MASK (1 << 3) /* CM_FCLKEN_WKUP, CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */ -#define OMAP3430_EN_GPIO1 (1 << 3) +#define OMAP3430_EN_GPIO1_MASK (1 << 3) #define OMAP3430_EN_GPIO1_SHIFT 3 -#define OMAP3430_EN_GPT1 (1 << 0) +#define OMAP3430_EN_GPT12_MASK (1 << 1) +#define OMAP3430_EN_GPT12_SHIFT 1 +#define OMAP3430_EN_GPT1_MASK (1 << 0) #define OMAP3430_EN_GPT1_SHIFT 0 /* CM_FCLKEN_WKUP, PM_WKEN_WKUP shared bits */ -#define OMAP3430_EN_SR2 (1 << 7) +#define OMAP3430_EN_SR2_MASK (1 << 7) #define OMAP3430_EN_SR2_SHIFT 7 -#define OMAP3430_EN_SR1 (1 << 6) +#define OMAP3430_EN_SR1_MASK (1 << 6) #define OMAP3430_EN_SR1_SHIFT 6 /* CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */ -#define OMAP3430_EN_GPT12 (1 << 1) +#define OMAP3430_EN_GPT12_MASK (1 << 1) #define OMAP3430_EN_GPT12_SHIFT 1 /* CM_IDLEST_WKUP, PM_WKST_WKUP shared bits */ -#define OMAP3430_ST_SR2 (1 << 7) -#define OMAP3430_ST_SR1 (1 << 6) -#define OMAP3430_ST_GPIO1 (1 << 3) -#define OMAP3430_ST_GPT12 (1 << 1) -#define OMAP3430_ST_GPT1 (1 << 0) +#define OMAP3430_ST_SR2_SHIFT 7 +#define OMAP3430_ST_SR2_MASK (1 << 7) +#define OMAP3430_ST_SR1_SHIFT 6 +#define OMAP3430_ST_SR1_MASK (1 << 6) +#define OMAP3430_ST_GPIO1_SHIFT 3 +#define OMAP3430_ST_GPIO1_MASK (1 << 3) +#define OMAP3430_ST_32KSYNC_SHIFT 2 +#define OMAP3430_ST_32KSYNC_MASK (1 << 2) +#define OMAP3430_ST_GPT12_SHIFT 1 +#define OMAP3430_ST_GPT12_MASK (1 << 1) +#define OMAP3430_ST_GPT1_SHIFT 0 +#define OMAP3430_ST_GPT1_MASK (1 << 0) /* * CM_SLEEPDEP_GFX, CM_SLEEPDEP_DSS, CM_SLEEPDEP_CAM, * CM_SLEEPDEP_PER, PM_WKDEP_IVA2, PM_WKDEP_GFX, * PM_WKDEP_DSS, PM_WKDEP_CAM, PM_WKDEP_PER, PM_WKDEP_NEON shared bits */ -#define OMAP3430_EN_MPU (1 << 1) +#define OMAP3430_EN_MPU_MASK (1 << 1) #define OMAP3430_EN_MPU_SHIFT 1 /* CM_FCLKEN_PER, CM_ICLKEN_PER, PM_WKEN_PER shared bits */ -#define OMAP3430_EN_GPIO6 (1 << 17) + +#define OMAP3630_EN_UART4_MASK (1 << 18) +#define OMAP3630_EN_UART4_SHIFT 18 +#define OMAP3430_EN_GPIO6_MASK (1 << 17) #define OMAP3430_EN_GPIO6_SHIFT 17 -#define OMAP3430_EN_GPIO5 (1 << 16) +#define OMAP3430_EN_GPIO5_MASK (1 << 16) #define OMAP3430_EN_GPIO5_SHIFT 16 -#define OMAP3430_EN_GPIO4 (1 << 15) +#define OMAP3430_EN_GPIO4_MASK (1 << 15) #define OMAP3430_EN_GPIO4_SHIFT 15 -#define OMAP3430_EN_GPIO3 (1 << 14) +#define OMAP3430_EN_GPIO3_MASK (1 << 14) #define OMAP3430_EN_GPIO3_SHIFT 14 -#define OMAP3430_EN_GPIO2 (1 << 13) +#define OMAP3430_EN_GPIO2_MASK (1 << 13) #define OMAP3430_EN_GPIO2_SHIFT 13 -#define OMAP3430_EN_UART3 (1 << 11) +#define OMAP3430_EN_UART3_MASK (1 << 11) #define OMAP3430_EN_UART3_SHIFT 11 -#define OMAP3430_EN_GPT9 (1 << 10) +#define OMAP3430_EN_GPT9_MASK (1 << 10) #define OMAP3430_EN_GPT9_SHIFT 10 -#define OMAP3430_EN_GPT8 (1 << 9) +#define OMAP3430_EN_GPT8_MASK (1 << 9) #define OMAP3430_EN_GPT8_SHIFT 9 -#define OMAP3430_EN_GPT7 (1 << 8) +#define OMAP3430_EN_GPT7_MASK (1 << 8) #define OMAP3430_EN_GPT7_SHIFT 8 -#define OMAP3430_EN_GPT6 (1 << 7) +#define OMAP3430_EN_GPT6_MASK (1 << 7) #define OMAP3430_EN_GPT6_SHIFT 7 -#define OMAP3430_EN_GPT5 (1 << 6) +#define OMAP3430_EN_GPT5_MASK (1 << 6) #define OMAP3430_EN_GPT5_SHIFT 6 -#define OMAP3430_EN_GPT4 (1 << 5) +#define OMAP3430_EN_GPT4_MASK (1 << 5) #define OMAP3430_EN_GPT4_SHIFT 5 -#define OMAP3430_EN_GPT3 (1 << 4) +#define OMAP3430_EN_GPT3_MASK (1 << 4) #define OMAP3430_EN_GPT3_SHIFT 4 -#define OMAP3430_EN_GPT2 (1 << 3) +#define OMAP3430_EN_GPT2_MASK (1 << 3) #define OMAP3430_EN_GPT2_SHIFT 3 /* CM_FCLKEN_PER, CM_ICLKEN_PER, PM_WKEN_PER, PM_WKST_PER shared bits */ /* XXX Possible TI documentation bug: should the PM_WKST_PER EN_* bits * be ST_* bits instead? */ -#define OMAP3430_EN_MCBSP4 (1 << 2) +#define OMAP3430_EN_MCBSP4_MASK (1 << 2) #define OMAP3430_EN_MCBSP4_SHIFT 2 -#define OMAP3430_EN_MCBSP3 (1 << 1) +#define OMAP3430_EN_MCBSP3_MASK (1 << 1) #define OMAP3430_EN_MCBSP3_SHIFT 1 -#define OMAP3430_EN_MCBSP2 (1 << 0) +#define OMAP3430_EN_MCBSP2_MASK (1 << 0) #define OMAP3430_EN_MCBSP2_SHIFT 0 /* CM_IDLEST_PER, PM_WKST_PER shared bits */ -#define OMAP3430_ST_GPIO6 (1 << 17) -#define OMAP3430_ST_GPIO5 (1 << 16) -#define OMAP3430_ST_GPIO4 (1 << 15) -#define OMAP3430_ST_GPIO3 (1 << 14) -#define OMAP3430_ST_GPIO2 (1 << 13) -#define OMAP3430_ST_UART3 (1 << 11) -#define OMAP3430_ST_GPT9 (1 << 10) -#define OMAP3430_ST_GPT8 (1 << 9) -#define OMAP3430_ST_GPT7 (1 << 8) -#define OMAP3430_ST_GPT6 (1 << 7) -#define OMAP3430_ST_GPT5 (1 << 6) -#define OMAP3430_ST_GPT4 (1 << 5) -#define OMAP3430_ST_GPT3 (1 << 4) -#define OMAP3430_ST_GPT2 (1 << 3) +#define OMAP3630_ST_UART4_SHIFT 18 +#define OMAP3630_ST_UART4_MASK (1 << 18) +#define OMAP3430_ST_GPIO6_SHIFT 17 +#define OMAP3430_ST_GPIO6_MASK (1 << 17) +#define OMAP3430_ST_GPIO5_SHIFT 16 +#define OMAP3430_ST_GPIO5_MASK (1 << 16) +#define OMAP3430_ST_GPIO4_SHIFT 15 +#define OMAP3430_ST_GPIO4_MASK (1 << 15) +#define OMAP3430_ST_GPIO3_SHIFT 14 +#define OMAP3430_ST_GPIO3_MASK (1 << 14) +#define OMAP3430_ST_GPIO2_SHIFT 13 +#define OMAP3430_ST_GPIO2_MASK (1 << 13) +#define OMAP3430_ST_UART3_SHIFT 11 +#define OMAP3430_ST_UART3_MASK (1 << 11) +#define OMAP3430_ST_GPT9_SHIFT 10 +#define OMAP3430_ST_GPT9_MASK (1 << 10) +#define OMAP3430_ST_GPT8_SHIFT 9 +#define OMAP3430_ST_GPT8_MASK (1 << 9) +#define OMAP3430_ST_GPT7_SHIFT 8 +#define OMAP3430_ST_GPT7_MASK (1 << 8) +#define OMAP3430_ST_GPT6_SHIFT 7 +#define OMAP3430_ST_GPT6_MASK (1 << 7) +#define OMAP3430_ST_GPT5_SHIFT 6 +#define OMAP3430_ST_GPT5_MASK (1 << 6) +#define OMAP3430_ST_GPT4_SHIFT 5 +#define OMAP3430_ST_GPT4_MASK (1 << 5) +#define OMAP3430_ST_GPT3_SHIFT 4 +#define OMAP3430_ST_GPT3_MASK (1 << 4) +#define OMAP3430_ST_GPT2_SHIFT 3 +#define OMAP3430_ST_GPT2_MASK (1 << 3) /* CM_SLEEPDEP_PER, PM_WKDEP_IVA2, PM_WKDEP_MPU, PM_WKDEP_PER shared bits */ #define OMAP3430_EN_CORE_SHIFT 0 #define OMAP3430_EN_CORE_MASK (1 << 0) + + +/* + * Maximum time(us) it takes to output the signal WUCLKOUT of the last + * pad of the I/O ring after asserting WUCLKIN high. Tero measured + * the actual time at 7 to 8 microseconds on OMAP3 and 2 to 4 + * microseconds on OMAP4, so this timeout may be too high. + */ +#define MAX_IOPAD_LATCH_TIME 100 +# ifndef __ASSEMBLER__ + +#include <linux/delay.h> + +/** + * omap_test_timeout - busy-loop, testing a condition + * @cond: condition to test until it evaluates to true + * @timeout: maximum number of microseconds in the timeout + * @index: loop index (integer) + * + * Loop waiting for @cond to become true or until at least @timeout + * microseconds have passed. To use, define some integer @index in the + * calling code. After running, if @index == @timeout, then the loop has + * timed out. + */ +#define omap_test_timeout(cond, timeout, index) \ +({ \ + for (index = 0; index < timeout; index++) { \ + if (cond) \ + break; \ + udelay(1); \ + } \ +}) + +/** + * struct omap_prcm_irq - describes a PRCM interrupt bit + * @name: a short name describing the interrupt type, e.g. "wkup" or "io" + * @offset: the bit shift of the interrupt inside the IRQ{ENABLE,STATUS} regs + * @priority: should this interrupt be handled before @priority=false IRQs? + * + * Describes interrupt bits inside the PRM_IRQ{ENABLE,STATUS}_MPU* registers. + * On systems with multiple PRM MPU IRQ registers, the bitfields read from + * the registers are concatenated, so @offset could be > 31 on these systems - + * see omap_prm_irq_handler() for more details. I/O ring interrupts should + * have @priority set to true. + */ +struct omap_prcm_irq { + const char *name; + unsigned int offset; + bool priority; +}; + +/** + * struct omap_prcm_irq_setup - PRCM interrupt controller details + * @ack: PRM register offset for the first PRM_IRQSTATUS_MPU register + * @mask: PRM register offset for the first PRM_IRQENABLE_MPU register + * @nr_regs: number of PRM_IRQ{STATUS,ENABLE}_MPU* registers + * @nr_irqs: number of entries in the @irqs array + * @irqs: ptr to an array of PRCM interrupt bits (see @nr_irqs) + * @irq: MPU IRQ asserted when a PRCM interrupt arrives + * @read_pending_irqs: fn ptr to determine if any PRCM IRQs are pending + * @ocp_barrier: fn ptr to force buffered PRM writes to complete + * @save_and_clear_irqen: fn ptr to save and clear IRQENABLE regs + * @restore_irqen: fn ptr to save and clear IRQENABLE regs + * @reconfigure_io_chain: fn ptr to reconfigure IO chain + * @saved_mask: IRQENABLE regs are saved here during suspend + * @priority_mask: 1 bit per IRQ, set to 1 if omap_prcm_irq.priority = true + * @base_irq: base dynamic IRQ number, returned from irq_alloc_descs() in init + * @suspended: set to true after Linux suspend code has called our ->prepare() + * @suspend_save_flag: set to true after IRQ masks have been saved and disabled + * + * @saved_mask, @priority_mask, @base_irq, @suspended, and + * @suspend_save_flag are populated dynamically, and are not to be + * specified in static initializers. + */ +struct omap_prcm_irq_setup { + u16 ack; + u16 mask; + u8 nr_regs; + u8 nr_irqs; + const struct omap_prcm_irq *irqs; + int irq; + void (*read_pending_irqs)(unsigned long *events); + void (*ocp_barrier)(void); + void (*save_and_clear_irqen)(u32 *saved_mask); + void (*restore_irqen)(u32 *saved_mask); + void (*reconfigure_io_chain)(void); + u32 *saved_mask; + u32 *priority_mask; + int base_irq; + bool suspended; + bool suspend_save_flag; +}; + +/* OMAP_PRCM_IRQ: convenience macro for creating struct omap_prcm_irq records */ +#define OMAP_PRCM_IRQ(_name, _offset, _priority) { \ + .name = _name, \ + .offset = _offset, \ + .priority = _priority \ + } + +extern void omap_prcm_irq_cleanup(void); +extern int omap_prcm_register_chain_handler( + struct omap_prcm_irq_setup *irq_setup); +extern int omap_prcm_event_to_irq(const char *event); +extern void omap_prcm_irq_prepare(void); +extern void omap_prcm_irq_complete(void); + +# endif + #endif diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c deleted file mode 100644 index f945156d558..00000000000 --- a/arch/arm/mach-omap2/prcm.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/prcm.c - * - * OMAP 24xx Power Reset and Clock Management (PRCM) functions - * - * Copyright (C) 2005 Nokia Corporation - * - * Written by Tony Lindgren <tony.lindgren@nokia.com> - * - * Some pieces of code Copyright (C) 2005 Texas Instruments, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/module.h> -#include <linux/init.h> -#include <linux/clk.h> -#include <linux/io.h> - -#include <mach/common.h> -#include <mach/prcm.h> - -#include "clock.h" -#include "prm.h" -#include "prm-regbits-24xx.h" - -static void __iomem *prm_base; -static void __iomem *cm_base; - -u32 omap_prcm_get_reset_sources(void) -{ - /* XXX This presumably needs modification for 34XX */ - return prm_read_mod_reg(WKUP_MOD, RM_RSTST) & 0x7f; -} -EXPORT_SYMBOL(omap_prcm_get_reset_sources); - -/* Resets clock rates and reboots the system. Only called from system.h */ -void omap_prcm_arch_reset(char mode) -{ - s16 prcm_offs; - omap2_clk_prepare_for_reboot(); - - if (cpu_is_omap24xx()) - prcm_offs = WKUP_MOD; - else if (cpu_is_omap34xx()) - prcm_offs = OMAP3430_GR_MOD; - else - WARN_ON(1); - - prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs, RM_RSTCTRL); -} - -static inline u32 __omap_prcm_read(void __iomem *base, s16 module, u16 reg) -{ - BUG_ON(!base); - return __raw_readl(base + module + reg); -} - -static inline void __omap_prcm_write(u32 value, void __iomem *base, - s16 module, u16 reg) -{ - BUG_ON(!base); - __raw_writel(value, base + module + reg); -} - -/* Read a register in a PRM module */ -u32 prm_read_mod_reg(s16 module, u16 idx) -{ - return __omap_prcm_read(prm_base, module, idx); -} -EXPORT_SYMBOL(prm_read_mod_reg); - -/* Write into a register in a PRM module */ -void prm_write_mod_reg(u32 val, s16 module, u16 idx) -{ - __omap_prcm_write(val, prm_base, module, idx); -} -EXPORT_SYMBOL(prm_write_mod_reg); - -/* Read-modify-write a register in a PRM module. Caller must lock */ -u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx) -{ - u32 v; - - v = prm_read_mod_reg(module, idx); - v &= ~mask; - v |= bits; - prm_write_mod_reg(v, module, idx); - - return v; -} -EXPORT_SYMBOL(prm_rmw_mod_reg_bits); - -/* Read a register in a CM module */ -u32 cm_read_mod_reg(s16 module, u16 idx) -{ - return __omap_prcm_read(cm_base, module, idx); -} -EXPORT_SYMBOL(cm_read_mod_reg); - -/* Write into a register in a CM module */ -void cm_write_mod_reg(u32 val, s16 module, u16 idx) -{ - __omap_prcm_write(val, cm_base, module, idx); -} -EXPORT_SYMBOL(cm_write_mod_reg); - -/* Read-modify-write a register in a CM module. Caller must lock */ -u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx) -{ - u32 v; - - v = cm_read_mod_reg(module, idx); - v &= ~mask; - v |= bits; - cm_write_mod_reg(v, module, idx); - - return v; -} -EXPORT_SYMBOL(cm_rmw_mod_reg_bits); - -void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals) -{ - prm_base = omap2_globals->prm; - cm_base = omap2_globals->cm; -} diff --git a/arch/arm/mach-omap2/prcm43xx.h b/arch/arm/mach-omap2/prcm43xx.h new file mode 100644 index 00000000000..7785be984ed --- /dev/null +++ b/arch/arm/mach-omap2/prcm43xx.h @@ -0,0 +1,146 @@ +/* + * AM43x PRCM defines + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_PRCM_43XX_H +#define __ARCH_ARM_MACH_OMAP2_PRCM_43XX_H + +#define AM43XX_PRM_PARTITION 1 +#define AM43XX_CM_PARTITION 1 + +/* PRM instances */ +#define AM43XX_PRM_OCP_SOCKET_INST 0x0000 +#define AM43XX_PRM_MPU_INST 0x0300 +#define AM43XX_PRM_GFX_INST 0x0400 +#define AM43XX_PRM_RTC_INST 0x0500 +#define AM43XX_PRM_TAMPER_INST 0x0600 +#define AM43XX_PRM_CEFUSE_INST 0x0700 +#define AM43XX_PRM_PER_INST 0x0800 +#define AM43XX_PRM_WKUP_INST 0x2000 +#define AM43XX_PRM_DEVICE_INST 0x4000 + +/* RM RSTCTRL offsets */ +#define AM43XX_RM_PER_RSTCTRL_OFFSET 0x0010 +#define AM43XX_RM_GFX_RSTCTRL_OFFSET 0x0010 +#define AM43XX_RM_WKUP_RSTCTRL_OFFSET 0x0010 + +/* RM RSTST offsets */ +#define AM43XX_RM_GFX_RSTST_OFFSET 0x0014 +#define AM43XX_RM_WKUP_RSTST_OFFSET 0x0014 + +/* CM instances */ +#define AM43XX_CM_WKUP_INST 0x2800 +#define AM43XX_CM_DEVICE_INST 0x4100 +#define AM43XX_CM_DPLL_INST 0x4200 +#define AM43XX_CM_MPU_INST 0x8300 +#define AM43XX_CM_GFX_INST 0x8400 +#define AM43XX_CM_RTC_INST 0x8500 +#define AM43XX_CM_TAMPER_INST 0x8600 +#define AM43XX_CM_CEFUSE_INST 0x8700 +#define AM43XX_CM_PER_INST 0x8800 + +/* CD offsets */ +#define AM43XX_CM_WKUP_L3_AON_CDOFFS 0x0000 +#define AM43XX_CM_WKUP_L3S_TSC_CDOFFS 0x0100 +#define AM43XX_CM_WKUP_L4_WKUP_AON_CDOFFS 0x0200 +#define AM43XX_CM_WKUP_WKUP_CDOFFS 0x0300 +#define AM43XX_CM_MPU_MPU_CDOFFS 0x0000 +#define AM43XX_CM_GFX_GFX_L3_CDOFFS 0x0000 +#define AM43XX_CM_RTC_RTC_CDOFFS 0x0000 +#define AM43XX_CM_TAMPER_TAMPER_CDOFFS 0x0000 +#define AM43XX_CM_CEFUSE_CEFUSE_CDOFFS 0x0000 +#define AM43XX_CM_PER_L3_CDOFFS 0x0000 +#define AM43XX_CM_PER_L3S_CDOFFS 0x0200 +#define AM43XX_CM_PER_ICSS_CDOFFS 0x0300 +#define AM43XX_CM_PER_L4LS_CDOFFS 0x0400 +#define AM43XX_CM_PER_EMIF_CDOFFS 0x0700 +#define AM43XX_CM_PER_DSS_CDOFFS 0x0a00 +#define AM43XX_CM_PER_CPSW_CDOFFS 0x0b00 +#define AM43XX_CM_PER_OCPWP_L3_CDOFFS 0x0c00 + +/* CLK CTRL offsets */ +#define AM43XX_CM_PER_UART1_CLKCTRL_OFFSET 0x0580 +#define AM43XX_CM_PER_UART2_CLKCTRL_OFFSET 0x0588 +#define AM43XX_CM_PER_UART3_CLKCTRL_OFFSET 0x0590 +#define AM43XX_CM_PER_UART4_CLKCTRL_OFFSET 0x0598 +#define AM43XX_CM_PER_UART5_CLKCTRL_OFFSET 0x05a0 +#define AM43XX_CM_PER_DCAN0_CLKCTRL_OFFSET 0x0428 +#define AM43XX_CM_PER_DCAN1_CLKCTRL_OFFSET 0x0430 +#define AM43XX_CM_PER_ELM_CLKCTRL_OFFSET 0x0468 +#define AM43XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET 0x0438 +#define AM43XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET 0x0440 +#define AM43XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET 0x0448 +#define AM43XX_CM_PER_GPIO1_CLKCTRL_OFFSET 0x0478 +#define AM43XX_CM_PER_GPIO2_CLKCTRL_OFFSET 0x0480 +#define AM43XX_CM_PER_GPIO3_CLKCTRL_OFFSET 0x0488 +#define AM43XX_CM_PER_I2C1_CLKCTRL_OFFSET 0x04a8 +#define AM43XX_CM_PER_I2C2_CLKCTRL_OFFSET 0x04b0 +#define AM43XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET 0x04b8 +#define AM43XX_CM_PER_MMC0_CLKCTRL_OFFSET 0x04c0 +#define AM43XX_CM_PER_MMC1_CLKCTRL_OFFSET 0x04c8 +#define AM43XX_CM_PER_SPI0_CLKCTRL_OFFSET 0x0500 +#define AM43XX_CM_PER_SPI1_CLKCTRL_OFFSET 0x0508 +#define AM43XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET 0x0528 +#define AM43XX_CM_PER_TIMER2_CLKCTRL_OFFSET 0x0530 +#define AM43XX_CM_PER_TIMER3_CLKCTRL_OFFSET 0x0538 +#define AM43XX_CM_PER_TIMER4_CLKCTRL_OFFSET 0x0540 +#define AM43XX_CM_PER_TIMER5_CLKCTRL_OFFSET 0x0548 +#define AM43XX_CM_PER_TIMER6_CLKCTRL_OFFSET 0x0550 +#define AM43XX_CM_PER_TIMER7_CLKCTRL_OFFSET 0x0558 +#define AM43XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET 0x0228 +#define AM43XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET 0x0360 +#define AM43XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET 0x0350 +#define AM43XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET 0x0358 +#define AM43XX_CM_WKUP_UART0_CLKCTRL_OFFSET 0x0348 +#define AM43XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET 0x0328 +#define AM43XX_CM_WKUP_I2C0_CLKCTRL_OFFSET 0x0340 +#define AM43XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET 0x0368 +#define AM43XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET 0x0120 +#define AM43XX_CM_WKUP_WDT1_CLKCTRL_OFFSET 0x0338 +#define AM43XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET 0x0220 +#define AM43XX_CM_RTC_RTC_CLKCTRL_OFFSET 0x0020 +#define AM43XX_CM_PER_MMC2_CLKCTRL_OFFSET 0x0248 +#define AM43XX_CM_PER_QSPI_CLKCTRL_OFFSET 0x0258 +#define AM43XX_CM_PER_GPMC_CLKCTRL_OFFSET 0x0220 +#define AM43XX_CM_PER_MCASP0_CLKCTRL_OFFSET 0x0238 +#define AM43XX_CM_PER_MCASP1_CLKCTRL_OFFSET 0x0240 +#define AM43XX_CM_PER_L4LS_CLKCTRL_OFFSET 0x0420 +#define AM43XX_CM_PER_L3_CLKCTRL_OFFSET 0x0020 +#define AM43XX_CM_PER_TPCC_CLKCTRL_OFFSET 0x0078 +#define AM43XX_CM_PER_TPTC0_CLKCTRL_OFFSET 0x0080 +#define AM43XX_CM_PER_TPTC1_CLKCTRL_OFFSET 0x0088 +#define AM43XX_CM_PER_TPTC2_CLKCTRL_OFFSET 0x0090 +#define AM43XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET 0x0b20 +#define AM43XX_CM_PER_PRUSS_CLKCTRL_OFFSET 0x0320 +#define AM43XX_CM_GFX_GFX_CLKCTRL_OFFSET 0x0020 +#define AM43XX_CM_PER_L4HS_CLKCTRL_OFFSET 0x00a0 +#define AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET 0x0020 +#define AM43XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET 0x0040 +#define AM43XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET 0x0050 +#define AM43XX_CM_PER_SHA0_CLKCTRL_OFFSET 0x0058 +#define AM43XX_CM_PER_AES0_CLKCTRL_OFFSET 0x0028 +#define AM43XX_CM_PER_TIMER8_CLKCTRL_OFFSET 0x0560 +#define AM43XX_CM_PER_TIMER9_CLKCTRL_OFFSET 0x0568 +#define AM43XX_CM_PER_TIMER10_CLKCTRL_OFFSET 0x0570 +#define AM43XX_CM_PER_TIMER11_CLKCTRL_OFFSET 0x0578 +#define AM43XX_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET 0x0230 +#define AM43XX_CM_PER_EPWMSS3_CLKCTRL_OFFSET 0x0450 +#define AM43XX_CM_PER_EPWMSS4_CLKCTRL_OFFSET 0x0458 +#define AM43XX_CM_PER_EPWMSS5_CLKCTRL_OFFSET 0x0460 +#define AM43XX_CM_PER_SPI2_CLKCTRL_OFFSET 0x0510 +#define AM43XX_CM_PER_SPI3_CLKCTRL_OFFSET 0x0518 +#define AM43XX_CM_PER_SPI4_CLKCTRL_OFFSET 0x0520 +#define AM43XX_CM_PER_GPIO4_CLKCTRL_OFFSET 0x0490 +#define AM43XX_CM_PER_GPIO5_CLKCTRL_OFFSET 0x0498 +#define AM43XX_CM_PER_USB_OTG_SS0_CLKCTRL_OFFSET 0x0260 +#define AM43XX_CM_PER_USBPHYOCP2SCP0_CLKCTRL_OFFSET 0x05B8 +#define AM43XX_CM_PER_USB_OTG_SS1_CLKCTRL_OFFSET 0x0268 +#define AM43XX_CM_PER_USBPHYOCP2SCP1_CLKCTRL_OFFSET 0x05C0 + +#endif diff --git a/arch/arm/mach-omap2/prcm44xx.h b/arch/arm/mach-omap2/prcm44xx.h new file mode 100644 index 00000000000..4fea2cfdf2c --- /dev/null +++ b/arch/arm/mach-omap2/prcm44xx.h @@ -0,0 +1,53 @@ +/* + * OMAP4 PRCM definitions + * + * Copyright (C) 2010 Texas Instruments, Inc. + * Copyright (C) 2010 Nokia Corporation + * + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This file contains macros and functions that are common to all of + * the PRM/CM/PRCM blocks on the OMAP4 devices: PRM, CM1, CM2, + * PRCM_MPU, SCRM + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_PRCM44XX_H +#define __ARCH_ARM_MACH_OMAP2_PRCM44XX_H + +/* + * OMAP4 PRCM partition IDs + * + * The numbers and order are arbitrary, but 0 is reserved for the + * 'invalid' partition in case someone forgets to add a + * .prcm_partition field. + */ +#define OMAP4430_INVALID_PRCM_PARTITION 0 +#define OMAP4430_PRM_PARTITION 1 +#define OMAP4430_CM1_PARTITION 2 +#define OMAP4430_CM2_PARTITION 3 +#define OMAP4430_SCRM_PARTITION 4 +#define OMAP4430_PRCM_MPU_PARTITION 5 + +#define OMAP54XX_PRM_PARTITION 1 +#define OMAP54XX_CM_CORE_AON_PARTITION 2 +#define OMAP54XX_CM_CORE_PARTITION 3 +#define OMAP54XX_SCRM_PARTITION 4 +#define OMAP54XX_PRCM_MPU_PARTITION 5 + +#define DRA7XX_PRM_PARTITION 1 +#define DRA7XX_CM_CORE_AON_PARTITION 2 +#define DRA7XX_CM_CORE_PARTITION 3 +#define DRA7XX_MPU_PRCM_PARTITION 5 + +/* + * OMAP4_MAX_PRCM_PARTITIONS: set to the highest value of the PRCM partition + * IDs, plus one + */ +#define OMAP4_MAX_PRCM_PARTITIONS 6 + + +#endif diff --git a/arch/arm/mach-omap2/prcm_mpu44xx.c b/arch/arm/mach-omap2/prcm_mpu44xx.c new file mode 100644 index 00000000000..cdbee6326d2 --- /dev/null +++ b/arch/arm/mach-omap2/prcm_mpu44xx.c @@ -0,0 +1,62 @@ +/* + * OMAP4 PRCM_MPU module functions + * + * Copyright (C) 2009 Nokia Corporation + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/io.h> + +#include "iomap.h" +#include "common.h" +#include "prcm_mpu44xx.h" +#include "cm-regbits-44xx.h" + +/* + * prcm_mpu_base: the virtual address of the start of the PRCM_MPU IP + * block registers + */ +void __iomem *prcm_mpu_base; + +/* PRCM_MPU low-level functions */ + +u32 omap4_prcm_mpu_read_inst_reg(s16 inst, u16 reg) +{ + return readl_relaxed(OMAP44XX_PRCM_MPU_REGADDR(inst, reg)); +} + +void omap4_prcm_mpu_write_inst_reg(u32 val, s16 inst, u16 reg) +{ + writel_relaxed(val, OMAP44XX_PRCM_MPU_REGADDR(inst, reg)); +} + +u32 omap4_prcm_mpu_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg) +{ + u32 v; + + v = omap4_prcm_mpu_read_inst_reg(inst, reg); + v &= ~mask; + v |= bits; + omap4_prcm_mpu_write_inst_reg(v, inst, reg); + + return v; +} + +/** + * omap2_set_globals_prcm_mpu - set the MPU PRCM base address (for early use) + * @prcm_mpu: PRCM_MPU base virtual address + * + * XXX Will be replaced when the PRM/CM drivers are completed. + */ +void __init omap2_set_globals_prcm_mpu(void __iomem *prcm_mpu) +{ + prcm_mpu_base = prcm_mpu; +} diff --git a/arch/arm/mach-omap2/prcm_mpu44xx.h b/arch/arm/mach-omap2/prcm_mpu44xx.h new file mode 100644 index 00000000000..ac9cb455023 --- /dev/null +++ b/arch/arm/mach-omap2/prcm_mpu44xx.h @@ -0,0 +1,97 @@ +/* + * OMAP44xx PRCM MPU instance offset macros + * + * Copyright (C) 2010, 2012 Texas Instruments, Inc. + * Copyright (C) 2010 Nokia Corporation + * + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * XXX This file needs to be updated to align on one of "OMAP4", "OMAP44XX", + * or "OMAP4430". + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_PRCM_MPU44XX_H +#define __ARCH_ARM_MACH_OMAP2_PRCM_MPU44XX_H + +#include "prcm_mpu_44xx_54xx.h" + +#define OMAP4430_PRCM_MPU_BASE 0x48243000 + +#define OMAP44XX_PRCM_MPU_REGADDR(inst, reg) \ + OMAP2_L4_IO_ADDRESS(OMAP4430_PRCM_MPU_BASE + (inst) + (reg)) + +/* PRCM_MPU instances */ +#define OMAP4430_PRCM_MPU_OCP_SOCKET_PRCM_INST 0x0000 +#define OMAP4430_PRCM_MPU_DEVICE_PRM_INST 0x0200 +#define OMAP4430_PRCM_MPU_CPU0_INST 0x0400 +#define OMAP4430_PRCM_MPU_CPU1_INST 0x0800 + +/* PRCM_MPU clockdomain register offsets (from instance start) */ +#define OMAP4430_PRCM_MPU_CPU0_CPU0_CDOFFS 0x0018 +#define OMAP4430_PRCM_MPU_CPU1_CPU1_CDOFFS 0x0018 + + +/* + * PRCM_MPU + * + * The PRCM_MPU is a local PRCM inside the MPU subsystem. For the PRCM (global) + * point of view the PRCM_MPU is a single entity. It shares the same + * programming model as the global PRCM and thus can be assimilate as two new + * MOD inside the PRCM + */ + +/* PRCM_MPU.OCP_SOCKET_PRCM register offsets */ +#define OMAP4_REVISION_PRCM_OFFSET 0x0000 +#define OMAP4430_REVISION_PRCM OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_OCP_SOCKET_PRCM_INST, 0x0000) + +/* PRCM_MPU.DEVICE_PRM register offsets */ +#define OMAP4_PRCM_MPU_PRM_RSTST_OFFSET 0x0000 +#define OMAP4430_PRCM_MPU_PRM_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_DEVICE_PRM_INST, 0x0000) +#define OMAP4_PRCM_MPU_PRM_PSCON_COUNT_OFFSET 0x0004 +#define OMAP4430_PRCM_MPU_PRM_PSCON_COUNT OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_DEVICE_PRM_INST, 0x0004) + +/* PRCM_MPU.CPU0 register offsets */ +#define OMAP4_PM_CPU0_PWRSTCTRL_OFFSET 0x0000 +#define OMAP4430_PM_CPU0_PWRSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x0000) +#define OMAP4_PM_CPU0_PWRSTST_OFFSET 0x0004 +#define OMAP4430_PM_CPU0_PWRSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x0004) +#define OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET 0x0008 +#define OMAP4430_RM_CPU0_CPU0_CONTEXT OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x0008) +#define OMAP4_RM_CPU0_CPU0_RSTCTRL_OFFSET 0x000c +#define OMAP4430_RM_CPU0_CPU0_RSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x000c) +#define OMAP4_RM_CPU0_CPU0_RSTST_OFFSET 0x0010 +#define OMAP4430_RM_CPU0_CPU0_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x0010) +#define OMAP4_CM_CPU0_CPU0_CLKCTRL_OFFSET 0x0014 +#define OMAP4430_CM_CPU0_CPU0_CLKCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x0014) +#define OMAP4_CM_CPU0_CLKSTCTRL_OFFSET 0x0018 +#define OMAP4430_CM_CPU0_CLKSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x0018) + +/* PRCM_MPU.CPU1 register offsets */ +#define OMAP4_PM_CPU1_PWRSTCTRL_OFFSET 0x0000 +#define OMAP4430_PM_CPU1_PWRSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0000) +#define OMAP4_PM_CPU1_PWRSTST_OFFSET 0x0004 +#define OMAP4430_PM_CPU1_PWRSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0004) +#define OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET 0x0008 +#define OMAP4430_RM_CPU1_CPU1_CONTEXT OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0008) +#define OMAP4_RM_CPU1_CPU1_RSTCTRL_OFFSET 0x000c +#define OMAP4430_RM_CPU1_CPU1_RSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x000c) +#define OMAP4_RM_CPU1_CPU1_RSTST_OFFSET 0x0010 +#define OMAP4430_RM_CPU1_CPU1_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0010) +#define OMAP4_CM_CPU1_CPU1_CLKCTRL_OFFSET 0x0014 +#define OMAP4430_CM_CPU1_CPU1_CLKCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0014) +#define OMAP4_CM_CPU1_CLKSTCTRL_OFFSET 0x0018 +#define OMAP4430_CM_CPU1_CLKSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0018) + +#endif diff --git a/arch/arm/mach-omap2/prcm_mpu54xx.h b/arch/arm/mach-omap2/prcm_mpu54xx.h new file mode 100644 index 00000000000..bc2ce328831 --- /dev/null +++ b/arch/arm/mach-omap2/prcm_mpu54xx.h @@ -0,0 +1,87 @@ +/* + * OMAP54xx PRCM MPU instance offset macros + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_PRCM_MPU54XX_H +#define __ARCH_ARM_MACH_OMAP2_PRCM_MPU54XX_H + +#include "prcm_mpu_44xx_54xx.h" +#include "common.h" + +#define OMAP54XX_PRCM_MPU_BASE 0x48243000 + +#define OMAP54XX_PRCM_MPU_REGADDR(inst, reg) \ + OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE + (inst) + (reg)) + +/* PRCM_MPU instances */ +#define OMAP54XX_PRCM_MPU_OCP_SOCKET_INST 0x0000 +#define OMAP54XX_PRCM_MPU_DEVICE_INST 0x0200 +#define OMAP54XX_PRCM_MPU_PRM_C0_INST 0x0400 +#define OMAP54XX_PRCM_MPU_CM_C0_INST 0x0600 +#define OMAP54XX_PRCM_MPU_PRM_C1_INST 0x0800 +#define OMAP54XX_PRCM_MPU_CM_C1_INST 0x0a00 + +/* PRCM_MPU clockdomain register offsets (from instance start) */ +#define OMAP54XX_PRCM_MPU_CM_C0_CPU0_CDOFFS 0x0000 +#define OMAP54XX_PRCM_MPU_CM_C1_CPU1_CDOFFS 0x0000 + + +/* + * PRCM_MPU + * + * The PRCM_MPU is a local PRCM inside the MPU subsystem. For the PRCM (global) + * point of view the PRCM_MPU is a single entity. It shares the same + * programming model as the global PRCM and thus can be assimilate as two new + * MOD inside the PRCM + */ + +/* PRCM_MPU.PRCM_MPU_OCP_SOCKET register offsets */ +#define OMAP54XX_REVISION_PRCM_MPU_OFFSET 0x0000 + +/* PRCM_MPU.PRCM_MPU_DEVICE register offsets */ +#define OMAP54XX_PRCM_MPU_PRM_RSTST_OFFSET 0x0000 +#define OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET 0x0004 +#define OMAP54XX_PRM_FRAC_INCREMENTER_NUMERATOR_OFFSET 0x0010 +#define OMAP54XX_PRM_FRAC_INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x0014 + +/* PRCM_MPU.PRCM_MPU_PRM_C0 register offsets */ +#define OMAP54XX_PM_CPU0_PWRSTCTRL_OFFSET 0x0000 +#define OMAP54XX_PM_CPU0_PWRSTST_OFFSET 0x0004 +#define OMAP54XX_RM_CPU0_CPU0_RSTCTRL_OFFSET 0x0010 +#define OMAP54XX_RM_CPU0_CPU0_RSTST_OFFSET 0x0014 +#define OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET 0x0024 + +/* PRCM_MPU.PRCM_MPU_CM_C0 register offsets */ +#define OMAP54XX_CM_CPU0_CLKSTCTRL_OFFSET 0x0000 +#define OMAP54XX_CM_CPU0_CPU0_CLKCTRL_OFFSET 0x0020 +#define OMAP54XX_CM_CPU0_CPU0_CLKCTRL OMAP54XX_PRCM_MPU_REGADDR(OMAP54XX_PRCM_MPU_CM_C0_INST, 0x0020) + +/* PRCM_MPU.PRCM_MPU_PRM_C1 register offsets */ +#define OMAP54XX_PM_CPU1_PWRSTCTRL_OFFSET 0x0000 +#define OMAP54XX_PM_CPU1_PWRSTST_OFFSET 0x0004 +#define OMAP54XX_RM_CPU1_CPU1_RSTCTRL_OFFSET 0x0010 +#define OMAP54XX_RM_CPU1_CPU1_RSTST_OFFSET 0x0014 +#define OMAP54XX_RM_CPU1_CPU1_CONTEXT_OFFSET 0x0024 + +/* PRCM_MPU.PRCM_MPU_CM_C1 register offsets */ +#define OMAP54XX_CM_CPU1_CLKSTCTRL_OFFSET 0x0000 +#define OMAP54XX_CM_CPU1_CPU1_CLKCTRL_OFFSET 0x0020 +#define OMAP54XX_CM_CPU1_CPU1_CLKCTRL OMAP54XX_PRCM_MPU_REGADDR(OMAP54XX_PRCM_MPU_CM_C1_INST, 0x0020) + +#endif diff --git a/arch/arm/mach-omap2/prcm_mpu7xx.h b/arch/arm/mach-omap2/prcm_mpu7xx.h new file mode 100644 index 00000000000..9ebb5ce0878 --- /dev/null +++ b/arch/arm/mach-omap2/prcm_mpu7xx.h @@ -0,0 +1,78 @@ +/* + * DRA7xx PRCM MPU instance offset macros + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * + * Generated by code originally written by: + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_PRCM_MPU7XX_H +#define __ARCH_ARM_MACH_OMAP2_PRCM_MPU7XX_H + +#include "prcm_mpu_44xx_54xx.h" + +#define DRA7XX_PRCM_MPU_BASE 0x48243000 + +#define DRA7XX_PRCM_MPU_REGADDR(inst, reg) \ + OMAP2_L4_IO_ADDRESS(DRA7XX_PRCM_MPU_BASE + (inst) + (reg)) + +/* MPU_PRCM instances */ +#define DRA7XX_MPU_PRCM_OCP_SOCKET_INST 0x0000 +#define DRA7XX_MPU_PRCM_DEVICE_INST 0x0200 +#define DRA7XX_MPU_PRCM_PRM_C0_INST 0x0400 +#define DRA7XX_MPU_PRCM_CM_C0_INST 0x0600 +#define DRA7XX_MPU_PRCM_PRM_C1_INST 0x0800 +#define DRA7XX_MPU_PRCM_CM_C1_INST 0x0a00 + +/* PRCM_MPU clockdomain register offsets (from instance start) */ +#define DRA7XX_MPU_PRCM_CM_C0_CPU0_CDOFFS 0x0000 +#define DRA7XX_MPU_PRCM_CM_C1_CPU1_CDOFFS 0x0000 + + +/* MPU_PRCM */ + +/* MPU_PRCM.PRCM_MPU_OCP_SOCKET register offsets */ +#define DRA7XX_REVISION_PRCM_MPU_OFFSET 0x0000 + +/* MPU_PRCM.PRCM_MPU_DEVICE register offsets */ +#define DRA7XX_PRM_FRAC_INCREMENTER_NUMERATOR_OFFSET 0x0010 +#define DRA7XX_PRM_FRAC_INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x0014 + +/* MPU_PRCM.PRCM_MPU_PRM_C0 register offsets */ +#define DRA7XX_PM_CPU0_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_CPU0_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_CPU0_CPU0_RSTCTRL_OFFSET 0x0010 +#define DRA7XX_RM_CPU0_CPU0_RSTST_OFFSET 0x0014 +#define DRA7XX_RM_CPU0_CPU0_CONTEXT_OFFSET 0x0024 + +/* MPU_PRCM.PRCM_MPU_CM_C0 register offsets */ +#define DRA7XX_CM_CPU0_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_CPU0_CPU0_CLKCTRL_OFFSET 0x0020 +#define DRA7XX_CM_CPU0_CPU0_CLKCTRL DRA7XX_MPU_PRCM_REGADDR(DRA7XX_MPU_PRCM_CM_C0_INST, 0x0020) + +/* MPU_PRCM.PRCM_MPU_PRM_C1 register offsets */ +#define DRA7XX_PM_CPU1_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_CPU1_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_CPU1_CPU1_RSTCTRL_OFFSET 0x0010 +#define DRA7XX_RM_CPU1_CPU1_RSTST_OFFSET 0x0014 +#define DRA7XX_RM_CPU1_CPU1_CONTEXT_OFFSET 0x0024 + +/* MPU_PRCM.PRCM_MPU_CM_C1 register offsets */ +#define DRA7XX_CM_CPU1_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_CPU1_CPU1_CLKCTRL_OFFSET 0x0020 +#define DRA7XX_CM_CPU1_CPU1_CLKCTRL DRA7XX_MPU_PRCM_REGADDR(DRA7XX_MPU_PRCM_CM_C1_INST, 0x0020) + +#endif diff --git a/arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h b/arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h new file mode 100644 index 00000000000..ca149e70bed --- /dev/null +++ b/arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h @@ -0,0 +1,36 @@ +/* + * OMAP44xx and OMAP54xx PRCM MPU function prototypes + * + * Copyright (C) 2010, 2013 Texas Instruments, Inc. + * Copyright (C) 2010 Nokia Corporation + * + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_PRCM_MPU_44XX_54XX_H +#define __ARCH_ARM_MACH_OMAP2_PRCM_MPU_44XX_54XX_H + +#ifndef __ASSEMBLER__ +extern void __iomem *prcm_mpu_base; + +extern u32 omap4_prcm_mpu_read_inst_reg(s16 inst, u16 idx); +extern void omap4_prcm_mpu_write_inst_reg(u32 val, s16 inst, u16 idx); +extern u32 omap4_prcm_mpu_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, + s16 idx); +extern void __init omap2_set_globals_prcm_mpu(void __iomem *prcm_mpu); +#endif + +#endif diff --git a/arch/arm/mach-omap2/prm-regbits-24xx.h b/arch/arm/mach-omap2/prm-regbits-24xx.h index 4002051c20b..37fc905c963 100644 --- a/arch/arm/mach-omap2/prm-regbits-24xx.h +++ b/arch/arm/mach-omap2/prm-regbits-24xx.h @@ -14,270 +14,29 @@ * published by the Free Software Foundation. */ -#include "prm.h" +#include "prm2xxx.h" -/* Bits shared between registers */ - -/* PRCM_IRQSTATUS_MPU, PM_IRQSTATUS_DSP, PRCM_IRQSTATUS_IVA shared bits */ -#define OMAP24XX_VOLTTRANS_ST (1 << 2) -#define OMAP24XX_WKUP2_ST (1 << 1) -#define OMAP24XX_WKUP1_ST (1 << 0) - -/* PRCM_IRQENABLE_MPU, PM_IRQENABLE_DSP, PRCM_IRQENABLE_IVA shared bits */ -#define OMAP24XX_VOLTTRANS_EN (1 << 2) -#define OMAP24XX_WKUP2_EN (1 << 1) -#define OMAP24XX_WKUP1_EN (1 << 0) - -/* PM_WKDEP_GFX, PM_WKDEP_MPU, PM_WKDEP_DSP, PM_WKDEP_MDM shared bits */ -#define OMAP24XX_EN_MPU_SHIFT 1 -#define OMAP24XX_EN_MPU_MASK (1 << 1) #define OMAP24XX_EN_CORE_SHIFT 0 -#define OMAP24XX_EN_CORE_MASK (1 << 0) - -/* - * PM_PWSTCTRL_MPU, PM_PWSTCTRL_GFX, PM_PWSTCTRL_DSP, PM_PWSTCTRL_MDM - * shared bits - */ -#define OMAP24XX_MEMONSTATE_SHIFT 10 -#define OMAP24XX_MEMONSTATE_MASK (0x3 << 10) -#define OMAP24XX_MEMRETSTATE (1 << 3) - -/* PM_PWSTCTRL_GFX, PM_PWSTCTRL_DSP, PM_PWSTCTRL_MDM shared bits */ -#define OMAP24XX_FORCESTATE (1 << 18) - -/* - * PM_PWSTST_CORE, PM_PWSTST_GFX, PM_PWSTST_MPU, PM_PWSTST_DSP, - * PM_PWSTST_MDM shared bits - */ -#define OMAP24XX_CLKACTIVITY (1 << 19) - -/* PM_PWSTST_MPU, PM_PWSTST_CORE, PM_PWSTST_DSP shared bits */ -#define OMAP24XX_LASTSTATEENTERED_SHIFT 4 -#define OMAP24XX_LASTSTATEENTERED_MASK (0x3 << 4) - -/* PM_PWSTST_MPU and PM_PWSTST_DSP shared bits */ -#define OMAP2430_MEMSTATEST_SHIFT 10 -#define OMAP2430_MEMSTATEST_MASK (0x3 << 10) - -/* PM_PWSTST_GFX, PM_PWSTST_DSP, PM_PWSTST_MDM shared bits */ -#define OMAP24XX_POWERSTATEST_SHIFT 0 -#define OMAP24XX_POWERSTATEST_MASK (0x3 << 0) - - -/* Bits specific to each register */ - -/* PRCM_REVISION */ -#define OMAP24XX_REV_SHIFT 0 -#define OMAP24XX_REV_MASK (0xff << 0) - -/* PRCM_SYSCONFIG */ -#define OMAP24XX_AUTOIDLE (1 << 0) - -/* PRCM_IRQSTATUS_MPU specific bits */ -#define OMAP2430_DPLL_RECAL_ST (1 << 6) -#define OMAP24XX_TRANSITION_ST (1 << 5) -#define OMAP24XX_EVGENOFF_ST (1 << 4) -#define OMAP24XX_EVGENON_ST (1 << 3) - -/* PRCM_IRQENABLE_MPU specific bits */ -#define OMAP2430_DPLL_RECAL_EN (1 << 6) -#define OMAP24XX_TRANSITION_EN (1 << 5) -#define OMAP24XX_EVGENOFF_EN (1 << 4) -#define OMAP24XX_EVGENON_EN (1 << 3) - -/* PRCM_VOLTCTRL */ -#define OMAP24XX_AUTO_EXTVOLT (1 << 15) -#define OMAP24XX_FORCE_EXTVOLT (1 << 14) +#define OMAP24XX_FORCESTATE_MASK (1 << 18) +#define OMAP24XX_AUTOIDLE_MASK (1 << 0) +#define OMAP24XX_AUTO_EXTVOLT_MASK (1 << 15) #define OMAP24XX_SETOFF_LEVEL_SHIFT 12 -#define OMAP24XX_SETOFF_LEVEL_MASK (0x3 << 12) -#define OMAP24XX_MEMRETCTRL (1 << 8) +#define OMAP24XX_MEMRETCTRL_MASK (1 << 8) #define OMAP24XX_SETRET_LEVEL_SHIFT 6 -#define OMAP24XX_SETRET_LEVEL_MASK (0x3 << 6) #define OMAP24XX_VOLT_LEVEL_SHIFT 0 -#define OMAP24XX_VOLT_LEVEL_MASK (0x3 << 0) - -/* PRCM_VOLTST */ -#define OMAP24XX_ST_VOLTLEVEL_SHIFT 0 -#define OMAP24XX_ST_VOLTLEVEL_MASK (0x3 << 0) - -/* PRCM_CLKSRC_CTRL specific bits */ - -/* PRCM_CLKOUT_CTRL */ #define OMAP2420_CLKOUT2_EN_SHIFT 15 -#define OMAP2420_CLKOUT2_EN (1 << 15) #define OMAP2420_CLKOUT2_DIV_SHIFT 11 -#define OMAP2420_CLKOUT2_DIV_MASK (0x7 << 11) -#define OMAP2420_CLKOUT2_SOURCE_SHIFT 8 +#define OMAP2420_CLKOUT2_DIV_WIDTH 3 #define OMAP2420_CLKOUT2_SOURCE_MASK (0x3 << 8) #define OMAP24XX_CLKOUT_EN_SHIFT 7 -#define OMAP24XX_CLKOUT_EN (1 << 7) #define OMAP24XX_CLKOUT_DIV_SHIFT 3 -#define OMAP24XX_CLKOUT_DIV_MASK (0x7 << 3) -#define OMAP24XX_CLKOUT_SOURCE_SHIFT 0 +#define OMAP24XX_CLKOUT_DIV_WIDTH 3 #define OMAP24XX_CLKOUT_SOURCE_MASK (0x3 << 0) - -/* PRCM_CLKEMUL_CTRL */ #define OMAP24XX_EMULATION_EN_SHIFT 0 -#define OMAP24XX_EMULATION_EN (1 << 0) - -/* PRCM_CLKCFG_CTRL */ -#define OMAP24XX_VALID_CONFIG (1 << 0) - -/* PRCM_CLKCFG_STATUS */ -#define OMAP24XX_CONFIG_STATUS (1 << 0) - -/* PRCM_VOLTSETUP specific bits */ - -/* PRCM_CLKSSETUP specific bits */ - -/* PRCM_POLCTRL */ -#define OMAP2420_CLKOUT2_POL (1 << 10) -#define OMAP24XX_CLKOUT_POL (1 << 9) -#define OMAP24XX_CLKREQ_POL (1 << 8) -#define OMAP2430_USE_POWEROK (1 << 2) -#define OMAP2430_POWEROK_POL (1 << 1) -#define OMAP24XX_EXTVOL_POL (1 << 0) - -/* RM_RSTST_MPU specific bits */ -/* 2430 calls GLOBALWMPU_RST "GLOBALWARM_RST" instead */ - -/* PM_WKDEP_MPU specific bits */ #define OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT 5 -#define OMAP2430_PM_WKDEP_MPU_EN_MDM_MASK (1 << 5) #define OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT 2 -#define OMAP24XX_PM_WKDEP_MPU_EN_DSP_MASK (1 << 2) - -/* PM_EVGENCTRL_MPU specific bits */ - -/* PM_EVEGENONTIM_MPU specific bits */ - -/* PM_EVEGENOFFTIM_MPU specific bits */ - -/* PM_PWSTCTRL_MPU specific bits */ -#define OMAP2430_FORCESTATE (1 << 18) - -/* PM_PWSTST_MPU specific bits */ -/* INTRANSITION, CLKACTIVITY, POWERSTATE, MEMSTATEST are 2430 only */ - -/* PM_WKEN1_CORE specific bits */ - -/* PM_WKEN2_CORE specific bits */ - -/* PM_WKST1_CORE specific bits*/ - -/* PM_WKST2_CORE specific bits */ - -/* PM_WKDEP_CORE specific bits*/ -#define OMAP2430_PM_WKDEP_CORE_EN_MDM (1 << 5) -#define OMAP24XX_PM_WKDEP_CORE_EN_GFX (1 << 3) -#define OMAP24XX_PM_WKDEP_CORE_EN_DSP (1 << 2) - -/* PM_PWSTCTRL_CORE specific bits */ -#define OMAP24XX_MEMORYCHANGE (1 << 20) -#define OMAP24XX_MEM3ONSTATE_SHIFT 14 -#define OMAP24XX_MEM3ONSTATE_MASK (0x3 << 14) -#define OMAP24XX_MEM2ONSTATE_SHIFT 12 -#define OMAP24XX_MEM2ONSTATE_MASK (0x3 << 12) -#define OMAP24XX_MEM1ONSTATE_SHIFT 10 -#define OMAP24XX_MEM1ONSTATE_MASK (0x3 << 10) -#define OMAP24XX_MEM3RETSTATE (1 << 5) -#define OMAP24XX_MEM2RETSTATE (1 << 4) -#define OMAP24XX_MEM1RETSTATE (1 << 3) - -/* PM_PWSTST_CORE specific bits */ -#define OMAP24XX_MEM3STATEST_SHIFT 14 -#define OMAP24XX_MEM3STATEST_MASK (0x3 << 14) -#define OMAP24XX_MEM2STATEST_SHIFT 12 -#define OMAP24XX_MEM2STATEST_MASK (0x3 << 12) -#define OMAP24XX_MEM1STATEST_SHIFT 10 -#define OMAP24XX_MEM1STATEST_MASK (0x3 << 10) - -/* RM_RSTCTRL_GFX */ -#define OMAP24XX_GFX_RST (1 << 0) - -/* RM_RSTST_GFX specific bits */ -#define OMAP24XX_GFX_SW_RST (1 << 4) - -/* PM_PWSTCTRL_GFX specific bits */ - -/* PM_WKDEP_GFX specific bits */ -/* 2430 often calls EN_WAKEUP "EN_WKUP" */ - -/* RM_RSTCTRL_WKUP specific bits */ - -/* RM_RSTTIME_WKUP specific bits */ - -/* RM_RSTST_WKUP specific bits */ -/* 2430 calls EXTWMPU_RST "EXTWARM_RST" and GLOBALWMPU_RST "GLOBALWARM_RST" */ -#define OMAP24XX_EXTWMPU_RST (1 << 6) -#define OMAP24XX_SECU_WD_RST (1 << 5) -#define OMAP24XX_MPU_WD_RST (1 << 4) -#define OMAP24XX_SECU_VIOL_RST (1 << 3) - -/* PM_WKEN_WKUP specific bits */ - -/* PM_WKST_WKUP specific bits */ - -/* RM_RSTCTRL_DSP */ -#define OMAP2420_RST_IVA (1 << 8) -#define OMAP24XX_RST2_DSP (1 << 1) -#define OMAP24XX_RST1_DSP (1 << 0) - -/* RM_RSTST_DSP specific bits */ -/* 2430 calls GLOBALWMPU_RST "GLOBALWARM_RST" */ -#define OMAP2420_IVA_SW_RST (1 << 8) -#define OMAP24XX_DSP_SW_RST2 (1 << 5) -#define OMAP24XX_DSP_SW_RST1 (1 << 4) - -/* PM_WKDEP_DSP specific bits */ - -/* PM_PWSTCTRL_DSP specific bits */ -/* 2430 only: MEMONSTATE, MEMRETSTATE */ -#define OMAP2420_MEMIONSTATE_SHIFT 12 -#define OMAP2420_MEMIONSTATE_MASK (0x3 << 12) -#define OMAP2420_MEMIRETSTATE (1 << 4) - -/* PM_PWSTST_DSP specific bits */ -/* MEMSTATEST is 2430 only */ -#define OMAP2420_MEMISTATEST_SHIFT 12 -#define OMAP2420_MEMISTATEST_MASK (0x3 << 12) - -/* PRCM_IRQSTATUS_DSP specific bits */ - -/* PRCM_IRQENABLE_DSP specific bits */ - -/* RM_RSTCTRL_MDM */ -/* 2430 only */ -#define OMAP2430_PWRON1_MDM (1 << 1) -#define OMAP2430_RST1_MDM (1 << 0) - -/* RM_RSTST_MDM specific bits */ -/* 2430 only */ -#define OMAP2430_MDM_SECU_VIOL (1 << 6) -#define OMAP2430_MDM_SW_PWRON1 (1 << 5) -#define OMAP2430_MDM_SW_RST1 (1 << 4) - -/* PM_WKEN_MDM */ -/* 2430 only */ -#define OMAP2430_PM_WKEN_MDM_EN_MDM (1 << 0) - -/* PM_WKST_MDM specific bits */ -/* 2430 only */ - -/* PM_WKDEP_MDM specific bits */ -/* 2430 only */ - -/* PM_PWSTCTRL_MDM specific bits */ -/* 2430 only */ -#define OMAP2430_KILLDOMAINWKUP (1 << 19) - -/* PM_PWSTST_MDM specific bits */ -/* 2430 only */ - -/* PRCM_IRQSTATUS_IVA */ -/* 2420 only */ - -/* PRCM_IRQENABLE_IVA */ -/* 2420 only */ - +#define OMAP24XX_EXTWMPU_RST_SHIFT 6 +#define OMAP24XX_SECU_WD_RST_SHIFT 5 +#define OMAP24XX_MPU_WD_RST_SHIFT 4 +#define OMAP24XX_SECU_VIOL_RST_SHIFT 3 #endif diff --git a/arch/arm/mach-omap2/prm-regbits-33xx.h b/arch/arm/mach-omap2/prm-regbits-33xx.h new file mode 100644 index 00000000000..84feecee4fe --- /dev/null +++ b/arch/arm/mach-omap2/prm-regbits-33xx.h @@ -0,0 +1,52 @@ +/* + * AM33XX PRM_XXX register bits + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_33XX_H +#define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_33XX_H + +#include "prm.h" + +#define AM33XX_GFX_MEM_ONSTATE_MASK (0x3 << 17) +#define AM33XX_GFX_MEM_RETSTATE_MASK (1 << 6) +#define AM33XX_GFX_MEM_STATEST_MASK (0x3 << 4) +#define AM33XX_GLOBAL_WARM_SW_RST_MASK (1 << 1) +#define AM33XX_RST_GLOBAL_WARM_SW_MASK (1 << 0) +#define AM33XX_PRUSS_MEM_ONSTATE_MASK (0x3 << 5) +#define AM33XX_PRUSS_MEM_RETSTATE_MASK (1 << 7) +#define AM33XX_PRUSS_MEM_STATEST_MASK (0x3 << 23) +#define AM33XX_LASTPOWERSTATEENTERED_SHIFT 24 +#define AM33XX_LASTPOWERSTATEENTERED_MASK (0x3 << 24) +#define AM33XX_LOGICRETSTATE_MASK (1 << 2) +#define AM33XX_LOGICRETSTATE_3_3_MASK (1 << 3) +#define AM33XX_LOGICSTATEST_SHIFT 2 +#define AM33XX_LOGICSTATEST_MASK (1 << 2) +#define AM33XX_LOWPOWERSTATECHANGE_SHIFT 4 +#define AM33XX_LOWPOWERSTATECHANGE_MASK (1 << 4) +#define AM33XX_MPU_L1_ONSTATE_MASK (0x3 << 18) +#define AM33XX_MPU_L1_RETSTATE_MASK (1 << 22) +#define AM33XX_MPU_L1_STATEST_MASK (0x3 << 6) +#define AM33XX_MPU_L2_ONSTATE_MASK (0x3 << 20) +#define AM33XX_MPU_L2_RETSTATE_MASK (1 << 23) +#define AM33XX_MPU_L2_STATEST_MASK (0x3 << 8) +#define AM33XX_MPU_RAM_ONSTATE_MASK (0x3 << 16) +#define AM33XX_MPU_RAM_RETSTATE_MASK (1 << 24) +#define AM33XX_MPU_RAM_STATEST_MASK (0x3 << 4) +#define AM33XX_PER_MEM_ONSTATE_MASK (0x3 << 25) +#define AM33XX_PER_MEM_RETSTATE_MASK (1 << 29) +#define AM33XX_PER_MEM_STATEST_MASK (0x3 << 17) +#define AM33XX_RAM_MEM_ONSTATE_MASK (0x3 << 30) +#define AM33XX_RAM_MEM_RETSTATE_MASK (1 << 27) +#define AM33XX_RAM_MEM_STATEST_MASK (0x3 << 21) +#endif diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h index 5b5ecfe6c99..cbefbd7cfdb 100644 --- a/arch/arm/mach-omap2/prm-regbits-34xx.h +++ b/arch/arm/mach-omap2/prm-regbits-34xx.h @@ -1,6 +1,3 @@ -#ifndef __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_34XX_H -#define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_34XX_H - /* * OMAP3430 Power/Reset Management register bits * @@ -13,573 +10,134 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#ifndef __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_34XX_H +#define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_34XX_H -#include "prm.h" - -/* Shared register bits */ -/* PRM_VC_CMD_VAL_0, PRM_VC_CMD_VAL_1 shared bits */ -#define OMAP3430_ON_SHIFT 24 -#define OMAP3430_ON_MASK (0xff << 24) -#define OMAP3430_ONLP_SHIFT 16 -#define OMAP3430_ONLP_MASK (0xff << 16) -#define OMAP3430_RET_SHIFT 8 -#define OMAP3430_RET_MASK (0xff << 8) -#define OMAP3430_OFF_SHIFT 0 -#define OMAP3430_OFF_MASK (0xff << 0) +#include "prm3xxx.h" -/* PRM_VP1_CONFIG, PRM_VP2_CONFIG shared bits */ -#define OMAP3430_ERROROFFSET_SHIFT 24 #define OMAP3430_ERROROFFSET_MASK (0xff << 24) -#define OMAP3430_ERRORGAIN_SHIFT 16 #define OMAP3430_ERRORGAIN_MASK (0xff << 16) -#define OMAP3430_INITVOLTAGE_SHIFT 8 #define OMAP3430_INITVOLTAGE_MASK (0xff << 8) -#define OMAP3430_TIMEOUTEN (1 << 3) -#define OMAP3430_INITVDD (1 << 2) -#define OMAP3430_FORCEUPDATE (1 << 1) -#define OMAP3430_VPENABLE (1 << 0) - -/* PRM_VP1_VSTEPMIN, PRM_VP2_VSTEPMIN shared bits */ +#define OMAP3430_TIMEOUTEN_MASK (1 << 3) +#define OMAP3430_INITVDD_MASK (1 << 2) +#define OMAP3430_FORCEUPDATE_MASK (1 << 1) +#define OMAP3430_VPENABLE_MASK (1 << 0) #define OMAP3430_SMPSWAITTIMEMIN_SHIFT 8 -#define OMAP3430_SMPSWAITTIMEMIN_MASK (0xffff << 8) #define OMAP3430_VSTEPMIN_SHIFT 0 -#define OMAP3430_VSTEPMIN_MASK (0xff << 0) - -/* PRM_VP1_VSTEPMAX, PRM_VP2_VSTEPMAX shared bits */ #define OMAP3430_SMPSWAITTIMEMAX_SHIFT 8 -#define OMAP3430_SMPSWAITTIMEMAX_MASK (0xffff << 8) #define OMAP3430_VSTEPMAX_SHIFT 0 -#define OMAP3430_VSTEPMAX_MASK (0xff << 0) - -/* PRM_VP1_VLIMITTO, PRM_VP2_VLIMITTO shared bits */ #define OMAP3430_VDDMAX_SHIFT 24 -#define OMAP3430_VDDMAX_MASK (0xff << 24) #define OMAP3430_VDDMIN_SHIFT 16 -#define OMAP3430_VDDMIN_MASK (0xff << 16) #define OMAP3430_TIMEOUT_SHIFT 0 -#define OMAP3430_TIMEOUT_MASK (0xffff << 0) - -/* PRM_VP1_VOLTAGE, PRM_VP2_VOLTAGE shared bits */ -#define OMAP3430_VPVOLTAGE_SHIFT 0 #define OMAP3430_VPVOLTAGE_MASK (0xff << 0) - -/* PRM_VP1_STATUS, PRM_VP2_STATUS shared bits */ -#define OMAP3430_VPINIDLE (1 << 0) - -/* PM_WKDEP_IVA2, PM_WKDEP_MPU shared bits */ #define OMAP3430_EN_PER_SHIFT 7 -#define OMAP3430_EN_PER_MASK (1 << 7) - -/* PM_PWSTCTRL_IVA2, PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE shared bits */ -#define OMAP3430_MEMORYCHANGE (1 << 3) - -/* PM_PWSTST_IVA2, PM_PWSTST_CORE shared bits */ -#define OMAP3430_LOGICSTATEST (1 << 2) - -/* PM_PREPWSTST_IVA2, PM_PREPWSTST_CORE shared bits */ -#define OMAP3430_LASTLOGICSTATEENTERED (1 << 2) - -/* - * PM_PREPWSTST_IVA2, PM_PREPWSTST_MPU, PM_PREPWSTST_CORE, - * PM_PREPWSTST_GFX, PM_PREPWSTST_DSS, PM_PREPWSTST_CAM, - * PM_PREPWSTST_PER, PM_PREPWSTST_NEON shared bits - */ -#define OMAP3430_LASTPOWERSTATEENTERED_SHIFT 0 -#define OMAP3430_LASTPOWERSTATEENTERED_MASK (0x3 << 0) - -/* PRM_IRQSTATUS_IVA2, PRM_IRQSTATUS_MPU shared bits */ -#define OMAP3430_WKUP_ST (1 << 0) - -/* PRM_IRQENABLE_IVA2, PRM_IRQENABLE_MPU shared bits */ -#define OMAP3430_WKUP_EN (1 << 0) - -/* PM_MPUGRPSEL1_CORE, PM_IVA2GRPSEL1_CORE shared bits */ -#define OMAP3430_GRPSEL_MMC2 (1 << 25) -#define OMAP3430_GRPSEL_MMC1 (1 << 24) -#define OMAP3430_GRPSEL_MCSPI4 (1 << 21) -#define OMAP3430_GRPSEL_MCSPI3 (1 << 20) -#define OMAP3430_GRPSEL_MCSPI2 (1 << 19) -#define OMAP3430_GRPSEL_MCSPI1 (1 << 18) -#define OMAP3430_GRPSEL_I2C3 (1 << 17) -#define OMAP3430_GRPSEL_I2C2 (1 << 16) -#define OMAP3430_GRPSEL_I2C1 (1 << 15) -#define OMAP3430_GRPSEL_UART2 (1 << 14) -#define OMAP3430_GRPSEL_UART1 (1 << 13) -#define OMAP3430_GRPSEL_GPT11 (1 << 12) -#define OMAP3430_GRPSEL_GPT10 (1 << 11) -#define OMAP3430_GRPSEL_MCBSP5 (1 << 10) -#define OMAP3430_GRPSEL_MCBSP1 (1 << 9) -#define OMAP3430_GRPSEL_HSOTGUSB (1 << 4) -#define OMAP3430_GRPSEL_D2D (1 << 3) - -/* - * PM_PWSTCTRL_GFX, PM_PWSTCTRL_DSS, PM_PWSTCTRL_CAM, - * PM_PWSTCTRL_PER shared bits - */ -#define OMAP3430_MEMONSTATE_SHIFT 16 -#define OMAP3430_MEMONSTATE_MASK (0x3 << 16) -#define OMAP3430_MEMRETSTATE (1 << 8) - -/* PM_MPUGRPSEL_PER, PM_IVA2GRPSEL_PER shared bits */ -#define OMAP3430_GRPSEL_GPIO6 (1 << 17) -#define OMAP3430_GRPSEL_GPIO5 (1 << 16) -#define OMAP3430_GRPSEL_GPIO4 (1 << 15) -#define OMAP3430_GRPSEL_GPIO3 (1 << 14) -#define OMAP3430_GRPSEL_GPIO2 (1 << 13) -#define OMAP3430_GRPSEL_UART3 (1 << 11) -#define OMAP3430_GRPSEL_GPT9 (1 << 10) -#define OMAP3430_GRPSEL_GPT8 (1 << 9) -#define OMAP3430_GRPSEL_GPT7 (1 << 8) -#define OMAP3430_GRPSEL_GPT6 (1 << 7) -#define OMAP3430_GRPSEL_GPT5 (1 << 6) -#define OMAP3430_GRPSEL_GPT4 (1 << 5) -#define OMAP3430_GRPSEL_GPT3 (1 << 4) -#define OMAP3430_GRPSEL_GPT2 (1 << 3) -#define OMAP3430_GRPSEL_MCBSP4 (1 << 2) -#define OMAP3430_GRPSEL_MCBSP3 (1 << 1) -#define OMAP3430_GRPSEL_MCBSP2 (1 << 0) - -/* PM_MPUGRPSEL_WKUP, PM_IVA2GRPSEL_WKUP shared bits */ -#define OMAP3430_GRPSEL_IO (1 << 8) -#define OMAP3430_GRPSEL_SR2 (1 << 7) -#define OMAP3430_GRPSEL_SR1 (1 << 6) -#define OMAP3430_GRPSEL_GPIO1 (1 << 3) -#define OMAP3430_GRPSEL_GPT12 (1 << 1) -#define OMAP3430_GRPSEL_GPT1 (1 << 0) - -/* Bits specific to each register */ - -/* RM_RSTCTRL_IVA2 */ -#define OMAP3430_RST3_IVA2 (1 << 2) -#define OMAP3430_RST2_IVA2 (1 << 1) -#define OMAP3430_RST1_IVA2 (1 << 0) - -/* RM_RSTST_IVA2 specific bits */ -#define OMAP3430_EMULATION_VSEQ_RST (1 << 13) -#define OMAP3430_EMULATION_VHWA_RST (1 << 12) -#define OMAP3430_EMULATION_IVA2_RST (1 << 11) -#define OMAP3430_IVA2_SW_RST3 (1 << 10) -#define OMAP3430_IVA2_SW_RST2 (1 << 9) -#define OMAP3430_IVA2_SW_RST1 (1 << 8) - -/* PM_WKDEP_IVA2 specific bits */ - -/* PM_PWSTCTRL_IVA2 specific bits */ -#define OMAP3430_L2FLATMEMONSTATE_SHIFT 22 +#define OMAP3430_LOGICSTATEST_MASK (1 << 2) +#define OMAP3430_LASTLOGICSTATEENTERED_MASK (1 << 2) +#define OMAP3430_LASTPOWERSTATEENTERED_MASK (0x3 << 0) +#define OMAP3430_GRPSEL_MCBSP5_MASK (1 << 10) +#define OMAP3430_GRPSEL_MCBSP1_MASK (1 << 9) +#define OMAP3630_GRPSEL_UART4_MASK (1 << 18) +#define OMAP3430_GRPSEL_GPIO6_MASK (1 << 17) +#define OMAP3430_GRPSEL_GPIO5_MASK (1 << 16) +#define OMAP3430_GRPSEL_GPIO4_MASK (1 << 15) +#define OMAP3430_GRPSEL_GPIO3_MASK (1 << 14) +#define OMAP3430_GRPSEL_GPIO2_MASK (1 << 13) +#define OMAP3430_GRPSEL_UART3_MASK (1 << 11) +#define OMAP3430_GRPSEL_GPT8_MASK (1 << 9) +#define OMAP3430_GRPSEL_GPT7_MASK (1 << 8) +#define OMAP3430_GRPSEL_GPT6_MASK (1 << 7) +#define OMAP3430_GRPSEL_GPT5_MASK (1 << 6) +#define OMAP3430_GRPSEL_MCBSP4_MASK (1 << 2) +#define OMAP3430_GRPSEL_MCBSP3_MASK (1 << 1) +#define OMAP3430_GRPSEL_MCBSP2_MASK (1 << 0) +#define OMAP3430_GRPSEL_GPIO1_MASK (1 << 3) +#define OMAP3430_GRPSEL_GPT12_MASK (1 << 1) +#define OMAP3430_GRPSEL_GPT1_MASK (1 << 0) +#define OMAP3430_RST3_IVA2_MASK (1 << 2) +#define OMAP3430_RST2_IVA2_MASK (1 << 1) +#define OMAP3430_RST1_IVA2_MASK (1 << 0) #define OMAP3430_L2FLATMEMONSTATE_MASK (0x3 << 22) -#define OMAP3430_SHAREDL2CACHEFLATONSTATE_SHIFT 20 #define OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK (0x3 << 20) -#define OMAP3430_L1FLATMEMONSTATE_SHIFT 18 #define OMAP3430_L1FLATMEMONSTATE_MASK (0x3 << 18) -#define OMAP3430_SHAREDL1CACHEFLATONSTATE_SHIFT 16 #define OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK (0x3 << 16) -#define OMAP3430_L2FLATMEMRETSTATE (1 << 11) -#define OMAP3430_SHAREDL2CACHEFLATRETSTATE (1 << 10) -#define OMAP3430_L1FLATMEMRETSTATE (1 << 9) -#define OMAP3430_SHAREDL1CACHEFLATRETSTATE (1 << 8) - -/* PM_PWSTST_IVA2 specific bits */ -#define OMAP3430_L2FLATMEMSTATEST_SHIFT 10 +#define OMAP3430_L2FLATMEMRETSTATE_MASK (1 << 11) +#define OMAP3430_SHAREDL2CACHEFLATRETSTATE_MASK (1 << 10) +#define OMAP3430_L1FLATMEMRETSTATE_MASK (1 << 9) +#define OMAP3430_SHAREDL1CACHEFLATRETSTATE_MASK (1 << 8) #define OMAP3430_L2FLATMEMSTATEST_MASK (0x3 << 10) -#define OMAP3430_SHAREDL2CACHEFLATSTATEST_SHIFT 8 #define OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK (0x3 << 8) -#define OMAP3430_L1FLATMEMSTATEST_SHIFT 6 #define OMAP3430_L1FLATMEMSTATEST_MASK (0x3 << 6) -#define OMAP3430_SHAREDL1CACHEFLATSTATEST_SHIFT 4 #define OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK (0x3 << 4) - -/* PM_PREPWSTST_IVA2 specific bits */ -#define OMAP3430_LASTL2FLATMEMSTATEENTERED_SHIFT 10 #define OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK (0x3 << 10) -#define OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_SHIFT 8 #define OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK (0x3 << 8) -#define OMAP3430_LASTL1FLATMEMSTATEENTERED_SHIFT 6 -#define OMAP3430_LASTL1FLATMEMSTATEENTERED_MASK (0x3 << 6) -#define OMAP3430_LASTSHAREDL1CACHEFLATSTATEENTERED_SHIFT 4 -#define OMAP3430_LASTSHAREDL1CACHEFLATSTATEENTERED_MASK (0x3 << 4) - -/* PRM_IRQSTATUS_IVA2 specific bits */ -#define OMAP3430_PRM_IRQSTATUS_IVA2_IVA2_DPLL_ST (1 << 2) -#define OMAP3430_FORCEWKUP_ST (1 << 1) - -/* PRM_IRQENABLE_IVA2 specific bits */ -#define OMAP3430_PRM_IRQENABLE_IVA2_IVA2_DPLL_RECAL_EN (1 << 2) -#define OMAP3430_FORCEWKUP_EN (1 << 1) - -/* PRM_REVISION specific bits */ - -/* PRM_SYSCONFIG specific bits */ - -/* PRM_IRQSTATUS_MPU specific bits */ #define OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT 25 -#define OMAP3430ES2_SND_PERIPH_DPLL_ST (1 << 25) -#define OMAP3430_VC_TIMEOUTERR_ST (1 << 24) -#define OMAP3430_VC_RAERR_ST (1 << 23) -#define OMAP3430_VC_SAERR_ST (1 << 22) -#define OMAP3430_VP2_TRANXDONE_ST (1 << 21) -#define OMAP3430_VP2_EQVALUE_ST (1 << 20) -#define OMAP3430_VP2_NOSMPSACK_ST (1 << 19) -#define OMAP3430_VP2_MAXVDD_ST (1 << 18) -#define OMAP3430_VP2_MINVDD_ST (1 << 17) -#define OMAP3430_VP2_OPPCHANGEDONE_ST (1 << 16) -#define OMAP3430_VP1_TRANXDONE_ST (1 << 15) -#define OMAP3430_VP1_EQVALUE_ST (1 << 14) -#define OMAP3430_VP1_NOSMPSACK_ST (1 << 13) -#define OMAP3430_VP1_MAXVDD_ST (1 << 12) -#define OMAP3430_VP1_MINVDD_ST (1 << 11) -#define OMAP3430_VP1_OPPCHANGEDONE_ST (1 << 10) -#define OMAP3430_IO_ST (1 << 9) -#define OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST (1 << 8) +#define OMAP3430_VP2_TRANXDONE_ST_MASK (1 << 21) +#define OMAP3430_VP1_TRANXDONE_ST_MASK (1 << 15) #define OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT 8 -#define OMAP3430_MPU_DPLL_ST (1 << 7) #define OMAP3430_MPU_DPLL_ST_SHIFT 7 -#define OMAP3430_PERIPH_DPLL_ST (1 << 6) #define OMAP3430_PERIPH_DPLL_ST_SHIFT 6 -#define OMAP3430_CORE_DPLL_ST (1 << 5) #define OMAP3430_CORE_DPLL_ST_SHIFT 5 -#define OMAP3430_TRANSITION_ST (1 << 4) -#define OMAP3430_EVGENOFF_ST (1 << 3) -#define OMAP3430_EVGENON_ST (1 << 2) -#define OMAP3430_FS_USB_WKUP_ST (1 << 1) - -/* PRM_IRQENABLE_MPU specific bits */ #define OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT 25 -#define OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN (1 << 25) -#define OMAP3430_VC_TIMEOUTERR_EN (1 << 24) -#define OMAP3430_VC_RAERR_EN (1 << 23) -#define OMAP3430_VC_SAERR_EN (1 << 22) -#define OMAP3430_VP2_TRANXDONE_EN (1 << 21) -#define OMAP3430_VP2_EQVALUE_EN (1 << 20) -#define OMAP3430_VP2_NOSMPSACK_EN (1 << 19) -#define OMAP3430_VP2_MAXVDD_EN (1 << 18) -#define OMAP3430_VP2_MINVDD_EN (1 << 17) -#define OMAP3430_VP2_OPPCHANGEDONE_EN (1 << 16) -#define OMAP3430_VP1_TRANXDONE_EN (1 << 15) -#define OMAP3430_VP1_EQVALUE_EN (1 << 14) -#define OMAP3430_VP1_NOSMPSACK_EN (1 << 13) -#define OMAP3430_VP1_MAXVDD_EN (1 << 12) -#define OMAP3430_VP1_MINVDD_EN (1 << 11) -#define OMAP3430_VP1_OPPCHANGEDONE_EN (1 << 10) -#define OMAP3430_IO_EN (1 << 9) -#define OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN (1 << 8) #define OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT 8 -#define OMAP3430_MPU_DPLL_RECAL_EN (1 << 7) #define OMAP3430_MPU_DPLL_RECAL_EN_SHIFT 7 -#define OMAP3430_PERIPH_DPLL_RECAL_EN (1 << 6) #define OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT 6 -#define OMAP3430_CORE_DPLL_RECAL_EN (1 << 5) #define OMAP3430_CORE_DPLL_RECAL_EN_SHIFT 5 -#define OMAP3430_TRANSITION_EN (1 << 4) -#define OMAP3430_EVGENOFF_EN (1 << 3) -#define OMAP3430_EVGENON_EN (1 << 2) -#define OMAP3430_FS_USB_WKUP_EN (1 << 1) - -/* RM_RSTST_MPU specific bits */ -#define OMAP3430_EMULATION_MPU_RST (1 << 11) - -/* PM_WKDEP_MPU specific bits */ #define OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT 5 -#define OMAP3430_PM_WKDEP_MPU_EN_DSS_MASK (1 << 5) #define OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT 2 -#define OMAP3430_PM_WKDEP_MPU_EN_IVA2_MASK (1 << 2) - -/* PM_EVGENCTRL_MPU */ -#define OMAP3430_OFFLOADMODE_SHIFT 3 -#define OMAP3430_OFFLOADMODE_MASK (0x3 << 3) -#define OMAP3430_ONLOADMODE_SHIFT 1 -#define OMAP3430_ONLOADMODE_MASK (0x3 << 1) -#define OMAP3430_ENABLE (1 << 0) - -/* PM_EVGENONTIM_MPU */ -#define OMAP3430_ONTIMEVAL_SHIFT 0 -#define OMAP3430_ONTIMEVAL_MASK (0xffffffff << 0) - -/* PM_EVGENOFFTIM_MPU */ -#define OMAP3430_OFFTIMEVAL_SHIFT 0 -#define OMAP3430_OFFTIMEVAL_MASK (0xffffffff << 0) - -/* PM_PWSTCTRL_MPU specific bits */ -#define OMAP3430_L2CACHEONSTATE_SHIFT 16 -#define OMAP3430_L2CACHEONSTATE_MASK (0x3 << 16) -#define OMAP3430_L2CACHERETSTATE (1 << 8) -#define OMAP3430_LOGICL1CACHERETSTATE (1 << 2) - -/* PM_PWSTST_MPU specific bits */ -#define OMAP3430_L2CACHESTATEST_SHIFT 6 -#define OMAP3430_L2CACHESTATEST_MASK (0x3 << 6) -#define OMAP3430_LOGICL1CACHESTATEST (1 << 2) - -/* PM_PREPWSTST_MPU specific bits */ -#define OMAP3430_LASTL2CACHESTATEENTERED_SHIFT 6 -#define OMAP3430_LASTL2CACHESTATEENTERED_MASK (0x3 << 6) -#define OMAP3430_LASTLOGICL1CACHESTATEENTERED (1 << 2) - -/* RM_RSTCTRL_CORE */ -#define OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON (1 << 1) -#define OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST (1 << 0) - -/* RM_RSTST_CORE specific bits */ -#define OMAP3430_MODEM_SECURITY_VIOL_RST (1 << 10) -#define OMAP3430_RM_RSTST_CORE_MODEM_SW_RSTPWRON (1 << 9) -#define OMAP3430_RM_RSTST_CORE_MODEM_SW_RST (1 << 8) - -/* PM_WKEN1_CORE specific bits */ - -/* PM_MPUGRPSEL1_CORE specific bits */ -#define OMAP3430_GRPSEL_FSHOSTUSB (1 << 5) - -/* PM_IVA2GRPSEL1_CORE specific bits */ - -/* PM_WKST1_CORE specific bits */ - -/* PM_PWSTCTRL_CORE specific bits */ -#define OMAP3430_MEM2ONSTATE_SHIFT 18 -#define OMAP3430_MEM2ONSTATE_MASK (0x3 << 18) -#define OMAP3430_MEM1ONSTATE_SHIFT 16 -#define OMAP3430_MEM1ONSTATE_MASK (0x3 << 16) -#define OMAP3430_MEM2RETSTATE (1 << 9) -#define OMAP3430_MEM1RETSTATE (1 << 8) - -/* PM_PWSTST_CORE specific bits */ -#define OMAP3430_MEM2STATEST_SHIFT 6 -#define OMAP3430_MEM2STATEST_MASK (0x3 << 6) -#define OMAP3430_MEM1STATEST_SHIFT 4 -#define OMAP3430_MEM1STATEST_MASK (0x3 << 4) - -/* PM_PREPWSTST_CORE specific bits */ -#define OMAP3430_LASTMEM2STATEENTERED_SHIFT 6 +#define OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON_MASK (1 << 1) +#define OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST_MASK (1 << 0) #define OMAP3430_LASTMEM2STATEENTERED_MASK (0x3 << 6) -#define OMAP3430_LASTMEM1STATEENTERED_SHIFT 4 #define OMAP3430_LASTMEM1STATEENTERED_MASK (0x3 << 4) - -/* RM_RSTST_GFX specific bits */ - -/* PM_WKDEP_GFX specific bits */ -#define OMAP3430_PM_WKDEP_GFX_EN_IVA2 (1 << 2) - -/* PM_PWSTCTRL_GFX specific bits */ - -/* PM_PWSTST_GFX specific bits */ - -/* PM_PREPWSTST_GFX specific bits */ - -/* PM_WKEN_WKUP specific bits */ -#define OMAP3430_EN_IO (1 << 8) - -/* PM_MPUGRPSEL_WKUP specific bits */ - -/* PM_IVA2GRPSEL_WKUP specific bits */ - -/* PM_WKST_WKUP specific bits */ -#define OMAP3430_ST_IO (1 << 8) - -/* PRM_CLKSEL */ +#define OMAP3430_EN_IO_CHAIN_MASK (1 << 16) +#define OMAP3430_EN_IO_MASK (1 << 8) +#define OMAP3430_EN_GPIO1_MASK (1 << 3) +#define OMAP3430_ST_IO_CHAIN_MASK (1 << 16) +#define OMAP3430_ST_IO_MASK (1 << 8) #define OMAP3430_SYS_CLKIN_SEL_SHIFT 0 -#define OMAP3430_SYS_CLKIN_SEL_MASK (0x7 << 0) - -/* PRM_CLKOUT_CTRL */ -#define OMAP3430_CLKOUT_EN (1 << 7) +#define OMAP3430_SYS_CLKIN_SEL_WIDTH 3 #define OMAP3430_CLKOUT_EN_SHIFT 7 - -/* RM_RSTST_DSS specific bits */ - -/* PM_WKEN_DSS */ -#define OMAP3430_PM_WKEN_DSS_EN_DSS (1 << 0) - -/* PM_WKDEP_DSS specific bits */ -#define OMAP3430_PM_WKDEP_DSS_EN_IVA2 (1 << 2) - -/* PM_PWSTCTRL_DSS specific bits */ - -/* PM_PWSTST_DSS specific bits */ - -/* PM_PREPWSTST_DSS specific bits */ - -/* RM_RSTST_CAM specific bits */ - -/* PM_WKDEP_CAM specific bits */ -#define OMAP3430_PM_WKDEP_CAM_EN_IVA2 (1 << 2) - -/* PM_PWSTCTRL_CAM specific bits */ - -/* PM_PWSTST_CAM specific bits */ - -/* PM_PREPWSTST_CAM specific bits */ - -/* PM_PWSTCTRL_USBHOST specific bits */ -#define OMAP3430ES2_SAVEANDRESTORE_SHIFT (1 << 4) - -/* RM_RSTST_PER specific bits */ - -/* PM_WKEN_PER specific bits */ - -/* PM_MPUGRPSEL_PER specific bits */ - -/* PM_IVA2GRPSEL_PER specific bits */ - -/* PM_WKST_PER specific bits */ - -/* PM_WKDEP_PER specific bits */ -#define OMAP3430_PM_WKDEP_PER_EN_IVA2 (1 << 2) - -/* PM_PWSTCTRL_PER specific bits */ - -/* PM_PWSTST_PER specific bits */ - -/* PM_PREPWSTST_PER specific bits */ - -/* RM_RSTST_EMU specific bits */ - -/* PM_PWSTST_EMU specific bits */ - -/* PRM_VC_SMPS_SA */ +#define OMAP3430_PM_WKEN_DSS_EN_DSS_MASK (1 << 0) +#define OMAP3430ES2_SAVEANDRESTORE_SHIFT 4 #define OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT 16 #define OMAP3430_PRM_VC_SMPS_SA_SA1_MASK (0x7f << 16) #define OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT 0 #define OMAP3430_PRM_VC_SMPS_SA_SA0_MASK (0x7f << 0) - -/* PRM_VC_SMPS_VOL_RA */ -#define OMAP3430_VOLRA1_SHIFT 16 #define OMAP3430_VOLRA1_MASK (0xff << 16) -#define OMAP3430_VOLRA0_SHIFT 0 #define OMAP3430_VOLRA0_MASK (0xff << 0) - -/* PRM_VC_SMPS_CMD_RA */ -#define OMAP3430_CMDRA1_SHIFT 16 #define OMAP3430_CMDRA1_MASK (0xff << 16) -#define OMAP3430_CMDRA0_SHIFT 0 #define OMAP3430_CMDRA0_MASK (0xff << 0) - -/* PRM_VC_CMD_VAL_0 specific bits */ - -/* PRM_VC_CMD_VAL_1 specific bits */ - -/* PRM_VC_CH_CONF */ -#define OMAP3430_CMD1 (1 << 20) -#define OMAP3430_RACEN1 (1 << 19) -#define OMAP3430_RAC1 (1 << 18) -#define OMAP3430_RAV1 (1 << 17) -#define OMAP3430_PRM_VC_CH_CONF_SA1 (1 << 16) -#define OMAP3430_CMD0 (1 << 4) -#define OMAP3430_RACEN0 (1 << 3) -#define OMAP3430_RAC0 (1 << 2) -#define OMAP3430_RAV0 (1 << 1) -#define OMAP3430_PRM_VC_CH_CONF_SA0 (1 << 0) - -/* PRM_VC_I2C_CFG */ -#define OMAP3430_HSMASTER (1 << 5) -#define OMAP3430_SREN (1 << 4) -#define OMAP3430_HSEN (1 << 3) -#define OMAP3430_MCODE_SHIFT 0 +#define OMAP3430_VC_CMD_ON_SHIFT 24 +#define OMAP3430_VC_CMD_ON_MASK (0xFF << 24) +#define OMAP3430_VC_CMD_ONLP_SHIFT 16 +#define OMAP3430_VC_CMD_RET_SHIFT 8 +#define OMAP3430_VC_CMD_OFF_SHIFT 0 +#define OMAP3430_HSEN_MASK (1 << 3) #define OMAP3430_MCODE_MASK (0x7 << 0) - -/* PRM_VC_BYPASS_VAL */ -#define OMAP3430_VALID (1 << 24) +#define OMAP3430_VALID_MASK (1 << 24) #define OMAP3430_DATA_SHIFT 16 -#define OMAP3430_DATA_MASK (0xff << 16) #define OMAP3430_REGADDR_SHIFT 8 -#define OMAP3430_REGADDR_MASK (0xff << 8) #define OMAP3430_SLAVEADDR_SHIFT 0 -#define OMAP3430_SLAVEADDR_MASK (0x7f << 0) - -/* PRM_RSTCTRL */ -#define OMAP3430_RST_DPLL3 (1 << 2) -#define OMAP3430_RST_GS (1 << 1) - -/* PRM_RSTTIME */ -#define OMAP3430_RSTTIME2_SHIFT 8 -#define OMAP3430_RSTTIME2_MASK (0x1f << 8) -#define OMAP3430_RSTTIME1_SHIFT 0 -#define OMAP3430_RSTTIME1_MASK (0xff << 0) - -/* PRM_RSTST */ -#define OMAP3430_ICECRUSHER_RST (1 << 10) -#define OMAP3430_ICEPICK_RST (1 << 9) -#define OMAP3430_VDD2_VOLTAGE_MANAGER_RST (1 << 8) -#define OMAP3430_VDD1_VOLTAGE_MANAGER_RST (1 << 7) -#define OMAP3430_EXTERNAL_WARM_RST (1 << 6) -#define OMAP3430_SECURE_WD_RST (1 << 5) -#define OMAP3430_MPU_WD_RST (1 << 4) -#define OMAP3430_SECURITY_VIOL_RST (1 << 3) -#define OMAP3430_GLOBAL_SW_RST (1 << 1) -#define OMAP3430_GLOBAL_COLD_RST (1 << 0) - -/* PRM_VOLTCTRL */ -#define OMAP3430_SEL_VMODE (1 << 4) -#define OMAP3430_SEL_OFF (1 << 3) -#define OMAP3430_AUTO_OFF (1 << 2) -#define OMAP3430_AUTO_RET (1 << 1) -#define OMAP3430_AUTO_SLEEP (1 << 0) - -/* PRM_SRAM_PCHARGE */ -#define OMAP3430_PCHARGE_TIME_SHIFT 0 -#define OMAP3430_PCHARGE_TIME_MASK (0xff << 0) - -/* PRM_CLKSRC_CTRL */ -#define OMAP3430_SYSCLKDIV_SHIFT 6 -#define OMAP3430_SYSCLKDIV_MASK (0x3 << 6) -#define OMAP3430_AUTOEXTCLKMODE_SHIFT 3 -#define OMAP3430_AUTOEXTCLKMODE_MASK (0x3 << 3) -#define OMAP3430_SYSCLKSEL_SHIFT 0 -#define OMAP3430_SYSCLKSEL_MASK (0x3 << 0) - -/* PRM_VOLTSETUP1 */ -#define OMAP3430_SETUP_TIME2_SHIFT 16 +#define OMAP3430_ICECRUSHER_RST_SHIFT 10 +#define OMAP3430_ICEPICK_RST_SHIFT 9 +#define OMAP3430_VDD2_VOLTAGE_MANAGER_RST_SHIFT 8 +#define OMAP3430_VDD1_VOLTAGE_MANAGER_RST_SHIFT 7 +#define OMAP3430_EXTERNAL_WARM_RST_SHIFT 6 +#define OMAP3430_SECURE_WD_RST_SHIFT 5 +#define OMAP3430_MPU_WD_RST_SHIFT 4 +#define OMAP3430_SECURITY_VIOL_RST_SHIFT 3 +#define OMAP3430_GLOBAL_SW_RST_SHIFT 1 +#define OMAP3430_GLOBAL_COLD_RST_SHIFT 0 +#define OMAP3430_GLOBAL_COLD_RST_MASK (1 << 0) +#define OMAP3430_PRM_VOLTCTRL_SEL_VMODE (1 << 4) +#define OMAP3430_PRM_VOLTCTRL_SEL_OFF (1 << 3) +#define OMAP3430_PRM_VOLTCTRL_AUTO_OFF (1 << 2) +#define OMAP3430_PRM_VOLTCTRL_AUTO_RET (1 << 1) +#define OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP (1 << 0) #define OMAP3430_SETUP_TIME2_MASK (0xffff << 16) -#define OMAP3430_SETUP_TIME1_SHIFT 0 #define OMAP3430_SETUP_TIME1_MASK (0xffff << 0) - -/* PRM_VOLTOFFSET */ -#define OMAP3430_OFFSET_TIME_SHIFT 0 -#define OMAP3430_OFFSET_TIME_MASK (0xffff << 0) - -/* PRM_CLKSETUP */ -#define OMAP3430_SETUP_TIME_SHIFT 0 -#define OMAP3430_SETUP_TIME_MASK (0xffff << 0) - -/* PRM_POLCTRL */ -#define OMAP3430_OFFMODE_POL (1 << 3) -#define OMAP3430_CLKOUT_POL (1 << 2) -#define OMAP3430_CLKREQ_POL (1 << 1) -#define OMAP3430_EXTVOL_POL (1 << 0) - -/* PRM_VOLTSETUP2 */ -#define OMAP3430_OFFMODESETUPTIME_SHIFT 0 -#define OMAP3430_OFFMODESETUPTIME_MASK (0xffff << 0) - -/* PRM_VP1_CONFIG specific bits */ - -/* PRM_VP1_VSTEPMIN specific bits */ - -/* PRM_VP1_VSTEPMAX specific bits */ - -/* PRM_VP1_VLIMITTO specific bits */ - -/* PRM_VP1_VOLTAGE specific bits */ - -/* PRM_VP1_STATUS specific bits */ - -/* PRM_VP2_CONFIG specific bits */ - -/* PRM_VP2_VSTEPMIN specific bits */ - -/* PRM_VP2_VSTEPMAX specific bits */ - -/* PRM_VP2_VLIMITTO specific bits */ - -/* PRM_VP2_VOLTAGE specific bits */ - -/* PRM_VP2_STATUS specific bits */ - -/* RM_RSTST_NEON specific bits */ - -/* PM_WKDEP_NEON specific bits */ - -/* PM_PWSTCTRL_NEON specific bits */ - -/* PM_PWSTST_NEON specific bits */ - -/* PM_PREPWSTST_NEON specific bits */ - +#define OMAP3430_PRM_POLCTRL_OFFMODE_POL (1 << 3) +#define OMAP3430_PRM_POLCTRL_CLKOUT_POL (1 << 2) +#define OMAP3430_PRM_POLCTRL_CLKREQ_POL (1 << 1) +#define OMAP3430_PRM_POLCTRL_EXTVOL_POL (1 << 0) #endif diff --git a/arch/arm/mach-omap2/prm-regbits-44xx.h b/arch/arm/mach-omap2/prm-regbits-44xx.h new file mode 100644 index 00000000000..b1c7a33e00e --- /dev/null +++ b/arch/arm/mach-omap2/prm-regbits-44xx.h @@ -0,0 +1,101 @@ +/* + * OMAP44xx Power Management register bits + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * Copyright (C) 2009-2010 Nokia Corporation + * + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_44XX_H +#define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_44XX_H + +#define OMAP4430_C2C_RST_SHIFT 10 +#define OMAP4430_CMDRA_VDD_CORE_L_MASK (0xff << 0) +#define OMAP4430_CMDRA_VDD_IVA_L_MASK (0xff << 8) +#define OMAP4430_CMDRA_VDD_MPU_L_MASK (0xff << 16) +#define OMAP4430_DATA_SHIFT 16 +#define OMAP4430_ERRORGAIN_MASK (0xff << 16) +#define OMAP4430_ERROROFFSET_MASK (0xff << 24) +#define OMAP4430_EXTERNAL_WARM_RST_SHIFT 5 +#define OMAP4430_FORCEUPDATE_MASK (1 << 1) +#define OMAP4430_GLOBAL_COLD_RST_SHIFT 0 +#define OMAP4430_GLOBAL_WARM_SW_RST_SHIFT 1 +#define OMAP4430_GLOBAL_WUEN_MASK (1 << 16) +#define OMAP4430_HSMCODE_MASK (0x7 << 0) +#define OMAP4430_HSMODEEN_MASK (1 << 3) +#define OMAP4430_HSSCLL_SHIFT 24 +#define OMAP4430_ICEPICK_RST_SHIFT 9 +#define OMAP4430_INITVDD_MASK (1 << 2) +#define OMAP4430_INITVOLTAGE_MASK (0xff << 8) +#define OMAP4430_LASTPOWERSTATEENTERED_SHIFT 24 +#define OMAP4430_LASTPOWERSTATEENTERED_MASK (0x3 << 24) +#define OMAP4430_LOGICRETSTATE_SHIFT 2 +#define OMAP4430_LOGICRETSTATE_MASK (1 << 2) +#define OMAP4430_LOGICSTATEST_SHIFT 2 +#define OMAP4430_LOGICSTATEST_MASK (1 << 2) +#define OMAP4430_LOSTCONTEXT_DFF_MASK (1 << 0) +#define OMAP4430_LOSTMEM_AESSMEM_MASK (1 << 8) +#define OMAP4430_LOWPOWERSTATECHANGE_SHIFT 4 +#define OMAP4430_LOWPOWERSTATECHANGE_MASK (1 << 4) +#define OMAP4430_MPU_SECURITY_VIOL_RST_SHIFT 2 +#define OMAP4430_MPU_WDT_RST_SHIFT 3 +#define OMAP4430_OCP_NRET_BANK_ONSTATE_MASK (0x3 << 24) +#define OMAP4430_OCP_NRET_BANK_RETSTATE_MASK (1 << 12) +#define OMAP4430_OCP_NRET_BANK_STATEST_MASK (0x3 << 12) +#define OMAP4430_OFF_SHIFT 0 +#define OMAP4430_ON_SHIFT 24 +#define OMAP4430_ON_MASK (0xff << 24) +#define OMAP4430_ONLP_SHIFT 16 +#define OMAP4430_RAMP_DOWN_COUNT_SHIFT 16 +#define OMAP4430_RAMP_UP_COUNT_SHIFT 0 +#define OMAP4430_RAMP_UP_PRESCAL_SHIFT 8 +#define OMAP4430_REGADDR_SHIFT 8 +#define OMAP4430_RET_SHIFT 8 +#define OMAP4430_RST_GLOBAL_WARM_SW_MASK (1 << 0) +#define OMAP4430_SA_VDD_CORE_L_SHIFT 0 +#define OMAP4430_SA_VDD_CORE_L_0_6_MASK (0x7f << 0) +#define OMAP4430_SA_VDD_IVA_L_SHIFT 8 +#define OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK (0x7f << 8) +#define OMAP4430_SA_VDD_MPU_L_SHIFT 16 +#define OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK (0x7f << 16) +#define OMAP4430_SCLH_SHIFT 0 +#define OMAP4430_SCLL_SHIFT 8 +#define OMAP4430_SECURE_WDT_RST_SHIFT 4 +#define OMAP4430_SLAVEADDR_SHIFT 0 +#define OMAP4430_SMPSWAITTIMEMAX_SHIFT 8 +#define OMAP4430_SMPSWAITTIMEMIN_SHIFT 8 +#define OMAP4430_TIMEOUT_SHIFT 0 +#define OMAP4430_TIMEOUTEN_MASK (1 << 3) +#define OMAP4430_VALID_MASK (1 << 24) +#define OMAP4430_VDDMAX_SHIFT 24 +#define OMAP4430_VDDMIN_SHIFT 16 +#define OMAP4430_VDD_CORE_VOLT_MGR_RST_SHIFT 8 +#define OMAP4430_VDD_IVA_VOLT_MGR_RST_SHIFT 7 +#define OMAP4430_VDD_MPU_VOLT_MGR_RST_SHIFT 6 +#define OMAP4430_VOLRA_VDD_CORE_L_MASK (0xff << 0) +#define OMAP4430_VOLRA_VDD_IVA_L_MASK (0xff << 8) +#define OMAP4430_VOLRA_VDD_MPU_L_MASK (0xff << 16) +#define OMAP4430_VPENABLE_MASK (1 << 0) +#define OMAP4430_VPVOLTAGE_MASK (0xff << 0) +#define OMAP4430_VP_CORE_TRANXDONE_ST_MASK (1 << 21) +#define OMAP4430_VP_IVA_TRANXDONE_ST_MASK (1 << 29) +#define OMAP4430_VP_MPU_TRANXDONE_ST_MASK (1 << 5) +#define OMAP4430_VSTEPMAX_SHIFT 0 +#define OMAP4430_VSTEPMIN_SHIFT 0 +#define OMAP4430_WUCLK_CTRL_MASK (1 << 8) +#define OMAP4430_WUCLK_STATUS_SHIFT 9 +#define OMAP4430_WUCLK_STATUS_MASK (1 << 9) +#endif diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h index e4dc4b17881..48480d557b6 100644 --- a/arch/arm/mach-omap2/prm.h +++ b/arch/arm/mach-omap2/prm.h @@ -1,246 +1,49 @@ -#ifndef __ARCH_ARM_MACH_OMAP2_PRM_H -#define __ARCH_ARM_MACH_OMAP2_PRM_H - /* - * OMAP2/3 Power/Reset Management (PRM) register definitions + * OMAP2/3/4 Power/Reset Management (PRM) bitfield definitions * - * Copyright (C) 2007 Texas Instruments, Inc. - * Copyright (C) 2007 Nokia Corporation + * Copyright (C) 2007-2009, 2012 Texas Instruments, Inc. + * Copyright (C) 2010 Nokia Corporation * - * Written by Paul Walmsley + * Paul Walmsley * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#ifndef __ARCH_ARM_MACH_OMAP2_PRM_H +#define __ARCH_ARM_MACH_OMAP2_PRM_H #include "prcm-common.h" -#ifndef __ASSEMBLER__ -#define OMAP_PRM_REGADDR(module, reg) \ - IO_ADDRESS(OMAP2_PRM_BASE + (module) + (reg)) -#else -#define OMAP2420_PRM_REGADDR(module, reg) \ - IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg)) -#define OMAP2430_PRM_REGADDR(module, reg) \ - IO_ADDRESS(OMAP2430_PRM_BASE + (module) + (reg)) -#define OMAP34XX_PRM_REGADDR(module, reg) \ - IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg)) -#endif +# ifndef __ASSEMBLER__ +extern void __iomem *prm_base; +extern u16 prm_features; +extern void omap2_set_globals_prm(void __iomem *prm); +int of_prcm_init(void); +# endif /* - * Architecture-specific global PRM registers - * Use __raw_{read,write}l() with these registers. - * - * With a few exceptions, these are the register names beginning with - * PRCM_* on 24xx, and PRM_* on 34xx. (The exceptions are the - * IRQSTATUS and IRQENABLE bits.) + * prm_features flag values * + * PRM_HAS_IO_WAKEUP: has IO wakeup capability + * PRM_HAS_VOLTAGE: has voltage domains */ - -/* Global 24xx registers in GR_MOD (Same as OCP_MOD for 24xx) */ -#define OMAP24XX_PRCM_VOLTCTRL_OFFSET 0x0050 -#define OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET 0x0080 - -/* 242x GR_MOD registers, use these only for assembly code */ -#define OMAP242X_PRCM_VOLTCTRL OMAP2420_PRM_REGADDR(OMAP24XX_GR_MOD, \ - OMAP24XX_PRCM_VOLTCTRL_OFFSET) -#define OMAP242X_PRCM_CLKCFG_CTRL OMAP2420_PRM_REGADDR(OMAP24XX_GR_MOD, \ - OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET) - -/* 243x GR_MOD registers, use these only for assembly code */ -#define OMAP243X_PRCM_VOLTCTRL OMAP2430_PRM_REGADDR(OMAP24XX_GR_MOD, \ - OMAP24XX_PRCM_VOLTCTRL_OFFSET) -#define OMAP243X_PRCM_CLKCFG_CTRL OMAP2430_PRM_REGADDR(OMAP24XX_GR_MOD, \ - OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET) - -/* These will disappear */ -#define OMAP24XX_PRCM_REVISION OMAP_PRM_REGADDR(OCP_MOD, 0x0000) -#define OMAP24XX_PRCM_SYSCONFIG OMAP_PRM_REGADDR(OCP_MOD, 0x0010) - -#define OMAP24XX_PRCM_IRQSTATUS_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x0018) -#define OMAP24XX_PRCM_IRQENABLE_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x001c) - -#define OMAP24XX_PRCM_VOLTST OMAP_PRM_REGADDR(OCP_MOD, 0x0054) -#define OMAP24XX_PRCM_CLKSRC_CTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0060) -#define OMAP24XX_PRCM_CLKOUT_CTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0070) -#define OMAP24XX_PRCM_CLKEMUL_CTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0078) -#define OMAP24XX_PRCM_CLKCFG_CTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0080) -#define OMAP24XX_PRCM_CLKCFG_STATUS OMAP_PRM_REGADDR(OCP_MOD, 0x0084) -#define OMAP24XX_PRCM_VOLTSETUP OMAP_PRM_REGADDR(OCP_MOD, 0x0090) -#define OMAP24XX_PRCM_CLKSSETUP OMAP_PRM_REGADDR(OCP_MOD, 0x0094) -#define OMAP24XX_PRCM_POLCTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0098) - -#define OMAP3430_PRM_REVISION OMAP_PRM_REGADDR(OCP_MOD, 0x0004) -#define OMAP3430_PRM_SYSCONFIG OMAP_PRM_REGADDR(OCP_MOD, 0x0014) - -#define OMAP3430_PRM_IRQSTATUS_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x0018) -#define OMAP3430_PRM_IRQENABLE_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x001c) - - -#define OMAP3430_PRM_VC_SMPS_SA OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0020) -#define OMAP3430_PRM_VC_SMPS_VOL_RA OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0024) -#define OMAP3430_PRM_VC_SMPS_CMD_RA OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0028) -#define OMAP3430_PRM_VC_CMD_VAL_0 OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x002c) -#define OMAP3430_PRM_VC_CMD_VAL_1 OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0030) -#define OMAP3430_PRM_VC_CH_CONF OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0034) -#define OMAP3430_PRM_VC_I2C_CFG OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0038) -#define OMAP3430_PRM_VC_BYPASS_VAL OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x003c) -#define OMAP3430_PRM_RSTCTRL OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0050) -#define OMAP3430_PRM_RSTTIME OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0054) -#define OMAP3430_PRM_RSTST OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0058) -#define OMAP3430_PRM_VOLTCTRL OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0060) -#define OMAP3430_PRM_SRAM_PCHARGE OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0064) -#define OMAP3430_PRM_CLKSRC_CTRL OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0070) -#define OMAP3430_PRM_VOLTSETUP1 OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0090) -#define OMAP3430_PRM_VOLTOFFSET OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0094) -#define OMAP3430_PRM_CLKSETUP OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0098) -#define OMAP3430_PRM_POLCTRL OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x009c) -#define OMAP3430_PRM_VOLTSETUP2 OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00a0) -#define OMAP3430_PRM_VP1_CONFIG OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b0) -#define OMAP3430_PRM_VP1_VSTEPMIN OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b4) -#define OMAP3430_PRM_VP1_VSTEPMAX OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b8) -#define OMAP3430_PRM_VP1_VLIMITTO OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00bc) -#define OMAP3430_PRM_VP1_VOLTAGE OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c0) -#define OMAP3430_PRM_VP1_STATUS OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c4) -#define OMAP3430_PRM_VP2_CONFIG OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d0) -#define OMAP3430_PRM_VP2_VSTEPMIN OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d4) -#define OMAP3430_PRM_VP2_VSTEPMAX OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d8) -#define OMAP3430_PRM_VP2_VLIMITTO OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00dc) -#define OMAP3430_PRM_VP2_VOLTAGE OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e0) -#define OMAP3430_PRM_VP2_STATUS OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e4) - -#define OMAP3430_PRM_CLKSEL OMAP_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0040) -#define OMAP3430_PRM_CLKOUT_CTRL OMAP_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0070) +#define PRM_HAS_IO_WAKEUP (1 << 0) /* - * Module specific PRM registers from PRM_BASE + domain offset - * - * Use prm_{read,write}_mod_reg() with these registers. - * - * With a few exceptions, these are the register names beginning with - * {PM,RM}_* on both architectures. (The exceptions are the IRQSTATUS - * and IRQENABLE bits.) - * + * MAX_MODULE_SOFTRESET_WAIT: Maximum microseconds to wait for OMAP + * module to softreset */ - -/* Registers appearing on both 24xx and 34xx */ - -#define RM_RSTCTRL 0x0050 -#define RM_RSTTIME 0x0054 -#define RM_RSTST 0x0058 - -#define PM_WKEN 0x00a0 -#define PM_WKEN1 PM_WKEN -#define PM_WKST 0x00b0 -#define PM_WKST1 PM_WKST -#define PM_WKDEP 0x00c8 -#define PM_EVGENCTRL 0x00d4 -#define PM_EVGENONTIM 0x00d8 -#define PM_EVGENOFFTIM 0x00dc -#define PM_PWSTCTRL 0x00e0 -#define PM_PWSTST 0x00e4 - -#define OMAP3430_PM_MPUGRPSEL 0x00a4 -#define OMAP3430_PM_MPUGRPSEL1 OMAP3430_PM_MPUGRPSEL - -#define OMAP3430_PM_IVAGRPSEL 0x00a8 -#define OMAP3430_PM_IVAGRPSEL1 OMAP3430_PM_IVAGRPSEL - -#define OMAP3430_PM_PREPWSTST 0x00e8 - -#define OMAP3430_PRM_IRQSTATUS_IVA2 0x00f8 -#define OMAP3430_PRM_IRQENABLE_IVA2 0x00fc - - -/* Architecture-specific registers */ - -#define OMAP24XX_PM_WKEN2 0x00a4 -#define OMAP24XX_PM_WKST2 0x00b4 - -#define OMAP24XX_PRCM_IRQSTATUS_DSP 0x00f0 /* IVA mod */ -#define OMAP24XX_PRCM_IRQENABLE_DSP 0x00f4 /* IVA mod */ -#define OMAP24XX_PRCM_IRQSTATUS_IVA 0x00f8 -#define OMAP24XX_PRCM_IRQENABLE_IVA 0x00fc - -#ifndef __ASSEMBLER__ - -/* Power/reset management domain register get/set */ -extern u32 prm_read_mod_reg(s16 module, u16 idx); -extern void prm_write_mod_reg(u32 val, s16 module, u16 idx); -extern u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); - -/* Read-modify-write bits in a PRM register (by domain) */ -static inline u32 prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) -{ - return prm_rmw_mod_reg_bits(bits, bits, module, idx); -} - -static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) -{ - return prm_rmw_mod_reg_bits(bits, 0x0, module, idx); -} - -#endif +#define MAX_MODULE_SOFTRESET_WAIT 10000 /* - * Bits common to specific registers - * - * The 3430 register and bit names are generally used, - * since they tend to make more sense + * MAX_MODULE_HARDRESET_WAIT: Maximum microseconds to wait for an OMAP + * submodule to exit hardreset */ - -/* PM_EVGENONTIM_MPU */ -/* Named PM_EVEGENONTIM_MPU on the 24XX */ -#define OMAP_ONTIMEVAL_SHIFT 0 -#define OMAP_ONTIMEVAL_MASK (0xffffffff << 0) - -/* PM_EVGENOFFTIM_MPU */ -/* Named PM_EVEGENOFFTIM_MPU on the 24XX */ -#define OMAP_OFFTIMEVAL_SHIFT 0 -#define OMAP_OFFTIMEVAL_MASK (0xffffffff << 0) - -/* PRM_CLKSETUP and PRCM_VOLTSETUP */ -/* Named PRCM_CLKSSETUP on the 24XX */ -#define OMAP_SETUP_TIME_SHIFT 0 -#define OMAP_SETUP_TIME_MASK (0xffff << 0) - -/* PRM_CLKSRC_CTRL */ -/* Named PRCM_CLKSRC_CTRL on the 24XX */ -#define OMAP_SYSCLKDIV_SHIFT 6 -#define OMAP_SYSCLKDIV_MASK (0x3 << 6) -#define OMAP_AUTOEXTCLKMODE_SHIFT 3 -#define OMAP_AUTOEXTCLKMODE_MASK (0x3 << 3) -#define OMAP_SYSCLKSEL_SHIFT 0 -#define OMAP_SYSCLKSEL_MASK (0x3 << 0) - -/* PM_EVGENCTRL_MPU */ -#define OMAP_OFFLOADMODE_SHIFT 3 -#define OMAP_OFFLOADMODE_MASK (0x3 << 3) -#define OMAP_ONLOADMODE_SHIFT 1 -#define OMAP_ONLOADMODE_MASK (0x3 << 1) -#define OMAP_ENABLE (1 << 0) - -/* PRM_RSTTIME */ -/* Named RM_RSTTIME_WKUP on the 24xx */ -#define OMAP_RSTTIME2_SHIFT 8 -#define OMAP_RSTTIME2_MASK (0x1f << 8) -#define OMAP_RSTTIME1_SHIFT 0 -#define OMAP_RSTTIME1_MASK (0xff << 0) - - -/* PRM_RSTCTRL */ -/* Named RM_RSTCTRL_WKUP on the 24xx */ -/* 2420 calls RST_DPLL3 'RST_DPLL' */ -#define OMAP_RST_DPLL3 (1 << 2) -#define OMAP_RST_GS (1 << 1) - +#define MAX_MODULE_HARDRESET_WAIT 10000 /* - * Bits common to module-shared registers - * - * Not all registers of a particular type support all of these bits - - * check TRM if you are unsure + * Register bitfields */ /* @@ -252,7 +55,7 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) * PM_PWSTST_DSS, PM_PWSTST_CAM, PM_PWSTST_PER, PM_PWSTST_EMU, * PM_PWSTST_NEON */ -#define OMAP_INTRANSITION (1 << 20) +#define OMAP_INTRANSITION_MASK (1 << 20) /* @@ -268,59 +71,6 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) #define OMAP_POWERSTATEST_MASK (0x3 << 0) /* - * 24XX: RM_RSTST_MPU and RM_RSTST_DSP - on 24XX, 'COREDOMAINWKUP_RST' is - * called 'COREWKUP_RST' - * - * 3430: RM_RSTST_IVA2, RM_RSTST_MPU, RM_RSTST_GFX, RM_RSTST_DSS, - * RM_RSTST_CAM, RM_RSTST_PER, RM_RSTST_NEON - */ -#define OMAP_COREDOMAINWKUP_RST (1 << 3) - -/* - * 24XX: RM_RSTST_MPU, RM_RSTST_GFX, RM_RSTST_DSP - * - * 2430: RM_RSTST_MDM - * - * 3430: RM_RSTST_CORE, RM_RSTST_EMU - */ -#define OMAP_DOMAINWKUP_RST (1 << 2) - -/* - * 24XX: RM_RSTST_MPU, RM_RSTST_WKUP, RM_RSTST_DSP - * On 24XX, 'GLOBALWARM_RST' is called 'GLOBALWMPU_RST'. - * - * 2430: RM_RSTST_MDM - * - * 3430: RM_RSTST_CORE, RM_RSTST_EMU - */ -#define OMAP_GLOBALWARM_RST (1 << 1) -#define OMAP_GLOBALCOLD_RST (1 << 0) - -/* - * 24XX: PM_WKDEP_GFX, PM_WKDEP_MPU, PM_WKDEP_CORE, PM_WKDEP_DSP - * 2420 TRM sometimes uses "EN_WAKEUP" instead of "EN_WKUP" - * - * 2430: PM_WKDEP_MDM - * - * 3430: PM_WKDEP_IVA2, PM_WKDEP_GFX, PM_WKDEP_DSS, PM_WKDEP_CAM, - * PM_WKDEP_PER - */ -#define OMAP_EN_WKUP_SHIFT 4 -#define OMAP_EN_WKUP_MASK (1 << 4) - -/* - * 24XX: PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE, PM_PWSTCTRL_GFX, - * PM_PWSTCTRL_DSP - * - * 2430: PM_PWSTCTRL_MDM - * - * 3430: PM_PWSTCTRL_IVA2, PM_PWSTCTRL_CORE, PM_PWSTCTRL_GFX, - * PM_PWSTCTRL_DSS, PM_PWSTCTRL_CAM, PM_PWSTCTRL_PER, - * PM_PWSTCTRL_NEON - */ -#define OMAP_LOGICRETSTATE (1 << 2) - -/* * 24XX: PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE, PM_PWSTCTRL_GFX, * PM_PWSTCTRL_DSP, PM_PWSTST_MPU * @@ -333,5 +83,69 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) #define OMAP_POWERSTATE_SHIFT 0 #define OMAP_POWERSTATE_MASK (0x3 << 0) +/* + * Standardized OMAP reset source bits + * + * To the extent these happen to match the hardware register bit + * shifts, it's purely coincidental. Used by omap-wdt.c. + * OMAP_UNKNOWN_RST_SRC_ID_SHIFT is a special value, used whenever + * there are any bits remaining in the global PRM_RSTST register that + * haven't been identified, or when the PRM code for the current SoC + * doesn't know how to interpret the register. + */ +#define OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT 0 +#define OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT 1 +#define OMAP_SECU_VIOL_RST_SRC_ID_SHIFT 2 +#define OMAP_MPU_WD_RST_SRC_ID_SHIFT 3 +#define OMAP_SECU_WD_RST_SRC_ID_SHIFT 4 +#define OMAP_EXTWARM_RST_SRC_ID_SHIFT 5 +#define OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT 6 +#define OMAP_VDD_IVA_VM_RST_SRC_ID_SHIFT 7 +#define OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT 8 +#define OMAP_ICEPICK_RST_SRC_ID_SHIFT 9 +#define OMAP_ICECRUSHER_RST_SRC_ID_SHIFT 10 +#define OMAP_C2C_RST_SRC_ID_SHIFT 11 +#define OMAP_UNKNOWN_RST_SRC_ID_SHIFT 12 + +#ifndef __ASSEMBLER__ + +/** + * struct prm_reset_src_map - map register bitshifts to standard bitshifts + * @reg_shift: bitshift in the PRM reset source register + * @std_shift: bitshift equivalent in the standard reset source list + * + * The fields are signed because -1 is used as a terminator. + */ +struct prm_reset_src_map { + s8 reg_shift; + s8 std_shift; +}; + +/** + * struct prm_ll_data - fn ptrs to per-SoC PRM function implementations + * @read_reset_sources: ptr to the SoC PRM-specific get_reset_source impl + * @was_any_context_lost_old: ptr to the SoC PRM context loss test fn + * @clear_context_loss_flags_old: ptr to the SoC PRM context loss flag clear fn + * @late_init: ptr to the late init function + * + * XXX @was_any_context_lost_old and @clear_context_loss_flags_old are + * deprecated. + */ +struct prm_ll_data { + u32 (*read_reset_sources)(void); + bool (*was_any_context_lost_old)(u8 part, s16 inst, u16 idx); + void (*clear_context_loss_flags_old)(u8 part, s16 inst, u16 idx); + int (*late_init)(void); +}; + +extern int prm_register(struct prm_ll_data *pld); +extern int prm_unregister(struct prm_ll_data *pld); + +extern u32 prm_read_reset_sources(void); +extern bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx); +extern void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx); + +#endif + #endif diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c new file mode 100644 index 00000000000..a3a3cca2bcc --- /dev/null +++ b/arch/arm/mach-omap2/prm2xxx.c @@ -0,0 +1,208 @@ +/* + * OMAP2xxx PRM module functions + * + * Copyright (C) 2010-2012 Texas Instruments, Inc. + * Copyright (C) 2010 Nokia Corporation + * Benoît Cousson + * Paul Walmsley + * Rajendra Nayak <rnayak@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/irq.h> + +#include "powerdomain.h" +#include "clockdomain.h" +#include "prm2xxx.h" +#include "cm2xxx_3xxx.h" +#include "prm-regbits-24xx.h" + +/* + * OMAP24xx PM_PWSTCTRL_*.POWERSTATE and PM_PWSTST_*.LASTSTATEENTERED bits - + * these are reversed from the bits used on OMAP3+ + */ +#define OMAP24XX_PWRDM_POWER_ON 0x0 +#define OMAP24XX_PWRDM_POWER_RET 0x1 +#define OMAP24XX_PWRDM_POWER_OFF 0x3 + +/* + * omap2xxx_prm_reset_src_map - map from bits in the PRM_RSTST_WKUP + * hardware register (which are specific to the OMAP2xxx SoCs) to + * reset source ID bit shifts (which is an OMAP SoC-independent + * enumeration) + */ +static struct prm_reset_src_map omap2xxx_prm_reset_src_map[] = { + { OMAP_GLOBALCOLD_RST_SHIFT, OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT }, + { OMAP_GLOBALWARM_RST_SHIFT, OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT }, + { OMAP24XX_SECU_VIOL_RST_SHIFT, OMAP_SECU_VIOL_RST_SRC_ID_SHIFT }, + { OMAP24XX_MPU_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT }, + { OMAP24XX_SECU_WD_RST_SHIFT, OMAP_SECU_WD_RST_SRC_ID_SHIFT }, + { OMAP24XX_EXTWMPU_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT }, + { -1, -1 }, +}; + +/** + * omap2xxx_prm_read_reset_sources - return the last SoC reset source + * + * Return a u32 representing the last reset sources of the SoC. The + * returned reset source bits are standardized across OMAP SoCs. + */ +static u32 omap2xxx_prm_read_reset_sources(void) +{ + struct prm_reset_src_map *p; + u32 r = 0; + u32 v; + + v = omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST); + + p = omap2xxx_prm_reset_src_map; + while (p->reg_shift >= 0 && p->std_shift >= 0) { + if (v & (1 << p->reg_shift)) + r |= 1 << p->std_shift; + p++; + } + + return r; +} + +/** + * omap2xxx_pwrst_to_common_pwrst - convert OMAP2xxx pwrst to common pwrst + * @omap2xxx_pwrst: OMAP2xxx hardware power state to convert + * + * Return the common power state bits corresponding to the OMAP2xxx + * hardware power state bits @omap2xxx_pwrst, or -EINVAL upon error. + */ +static int omap2xxx_pwrst_to_common_pwrst(u8 omap2xxx_pwrst) +{ + u8 pwrst; + + switch (omap2xxx_pwrst) { + case OMAP24XX_PWRDM_POWER_OFF: + pwrst = PWRDM_POWER_OFF; + break; + case OMAP24XX_PWRDM_POWER_RET: + pwrst = PWRDM_POWER_RET; + break; + case OMAP24XX_PWRDM_POWER_ON: + pwrst = PWRDM_POWER_ON; + break; + default: + return -EINVAL; + } + + return pwrst; +} + +/** + * omap2xxx_prm_dpll_reset - use DPLL reset to reboot the OMAP SoC + * + * Set the DPLL reset bit, which should reboot the SoC. This is the + * recommended way to restart the SoC. No return value. + */ +void omap2xxx_prm_dpll_reset(void) +{ + omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, WKUP_MOD, + OMAP2_RM_RSTCTRL); + /* OCP barrier */ + omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTCTRL); +} + +int omap2xxx_clkdm_sleep(struct clockdomain *clkdm) +{ + omap2_prm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, + clkdm->pwrdm.ptr->prcm_offs, + OMAP2_PM_PWSTCTRL); + return 0; +} + +int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm) +{ + omap2_prm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, + clkdm->pwrdm.ptr->prcm_offs, + OMAP2_PM_PWSTCTRL); + return 0; +} + +static int omap2xxx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) +{ + u8 omap24xx_pwrst; + + switch (pwrst) { + case PWRDM_POWER_OFF: + omap24xx_pwrst = OMAP24XX_PWRDM_POWER_OFF; + break; + case PWRDM_POWER_RET: + omap24xx_pwrst = OMAP24XX_PWRDM_POWER_RET; + break; + case PWRDM_POWER_ON: + omap24xx_pwrst = OMAP24XX_PWRDM_POWER_ON; + break; + default: + return -EINVAL; + } + + omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK, + (omap24xx_pwrst << OMAP_POWERSTATE_SHIFT), + pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL); + return 0; +} + +static int omap2xxx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm) +{ + u8 omap2xxx_pwrst; + + omap2xxx_pwrst = omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, + OMAP2_PM_PWSTCTRL, + OMAP_POWERSTATE_MASK); + + return omap2xxx_pwrst_to_common_pwrst(omap2xxx_pwrst); +} + +static int omap2xxx_pwrdm_read_pwrst(struct powerdomain *pwrdm) +{ + u8 omap2xxx_pwrst; + + omap2xxx_pwrst = omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, + OMAP2_PM_PWSTST, + OMAP_POWERSTATEST_MASK); + + return omap2xxx_pwrst_to_common_pwrst(omap2xxx_pwrst); +} + +struct pwrdm_ops omap2_pwrdm_operations = { + .pwrdm_set_next_pwrst = omap2xxx_pwrdm_set_next_pwrst, + .pwrdm_read_next_pwrst = omap2xxx_pwrdm_read_next_pwrst, + .pwrdm_read_pwrst = omap2xxx_pwrdm_read_pwrst, + .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst, + .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst, + .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst, + .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst, + .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst, + .pwrdm_wait_transition = omap2_pwrdm_wait_transition, +}; + +/* + * + */ + +static struct prm_ll_data omap2xxx_prm_ll_data = { + .read_reset_sources = &omap2xxx_prm_read_reset_sources, +}; + +int __init omap2xxx_prm_init(void) +{ + return prm_register(&omap2xxx_prm_ll_data); +} + +static void __exit omap2xxx_prm_exit(void) +{ + prm_unregister(&omap2xxx_prm_ll_data); +} +__exitcall(omap2xxx_prm_exit); diff --git a/arch/arm/mach-omap2/prm2xxx.h b/arch/arm/mach-omap2/prm2xxx.h new file mode 100644 index 00000000000..d2cb6365716 --- /dev/null +++ b/arch/arm/mach-omap2/prm2xxx.h @@ -0,0 +1,133 @@ +/* + * OMAP2xxx Power/Reset Management (PRM) register definitions + * + * Copyright (C) 2007-2009, 2011-2012 Texas Instruments, Inc. + * Copyright (C) 2008-2010 Nokia Corporation + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * The PRM hardware modules on the OMAP2/3 are quite similar to each + * other. The PRM on OMAP4 has a new register layout, and is handled + * in a separate file. + */ +#ifndef __ARCH_ARM_MACH_OMAP2_PRM2XXX_H +#define __ARCH_ARM_MACH_OMAP2_PRM2XXX_H + +#include "prcm-common.h" +#include "prm.h" +#include "prm2xxx_3xxx.h" + +#define OMAP2420_PRM_REGADDR(module, reg) \ + OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg)) +#define OMAP2430_PRM_REGADDR(module, reg) \ + OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE + (module) + (reg)) + +/* + * OMAP2-specific global PRM registers + * Use {read,write}l_relaxed() with these registers. + * + * With a few exceptions, these are the register names beginning with + * PRCM_* on 24xx. (The exceptions are the IRQSTATUS and IRQENABLE + * bits.) + * + */ + +#define OMAP2_PRCM_REVISION_OFFSET 0x0000 +#define OMAP2420_PRCM_REVISION OMAP2420_PRM_REGADDR(OCP_MOD, 0x0000) +#define OMAP2_PRCM_SYSCONFIG_OFFSET 0x0010 +#define OMAP2420_PRCM_SYSCONFIG OMAP2420_PRM_REGADDR(OCP_MOD, 0x0010) + +#define OMAP2_PRCM_IRQSTATUS_MPU_OFFSET 0x0018 +#define OMAP2420_PRCM_IRQSTATUS_MPU OMAP2420_PRM_REGADDR(OCP_MOD, 0x0018) +#define OMAP2_PRCM_IRQENABLE_MPU_OFFSET 0x001c +#define OMAP2420_PRCM_IRQENABLE_MPU OMAP2420_PRM_REGADDR(OCP_MOD, 0x001c) + +#define OMAP2_PRCM_VOLTCTRL_OFFSET 0x0050 +#define OMAP2420_PRCM_VOLTCTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0050) +#define OMAP2_PRCM_VOLTST_OFFSET 0x0054 +#define OMAP2420_PRCM_VOLTST OMAP2420_PRM_REGADDR(OCP_MOD, 0x0054) +#define OMAP2_PRCM_CLKSRC_CTRL_OFFSET 0x0060 +#define OMAP2420_PRCM_CLKSRC_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0060) +#define OMAP2_PRCM_CLKOUT_CTRL_OFFSET 0x0070 +#define OMAP2420_PRCM_CLKOUT_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0070) +#define OMAP2_PRCM_CLKEMUL_CTRL_OFFSET 0x0078 +#define OMAP2420_PRCM_CLKEMUL_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0078) +#define OMAP2_PRCM_CLKCFG_CTRL_OFFSET 0x0080 +#define OMAP2420_PRCM_CLKCFG_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0080) +#define OMAP2_PRCM_CLKCFG_STATUS_OFFSET 0x0084 +#define OMAP2420_PRCM_CLKCFG_STATUS OMAP2420_PRM_REGADDR(OCP_MOD, 0x0084) +#define OMAP2_PRCM_VOLTSETUP_OFFSET 0x0090 +#define OMAP2420_PRCM_VOLTSETUP OMAP2420_PRM_REGADDR(OCP_MOD, 0x0090) +#define OMAP2_PRCM_CLKSSETUP_OFFSET 0x0094 +#define OMAP2420_PRCM_CLKSSETUP OMAP2420_PRM_REGADDR(OCP_MOD, 0x0094) +#define OMAP2_PRCM_POLCTRL_OFFSET 0x0098 +#define OMAP2420_PRCM_POLCTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0098) + +#define OMAP2430_PRCM_REVISION OMAP2430_PRM_REGADDR(OCP_MOD, 0x0000) +#define OMAP2430_PRCM_SYSCONFIG OMAP2430_PRM_REGADDR(OCP_MOD, 0x0010) + +#define OMAP2430_PRCM_IRQSTATUS_MPU OMAP2430_PRM_REGADDR(OCP_MOD, 0x0018) +#define OMAP2430_PRCM_IRQENABLE_MPU OMAP2430_PRM_REGADDR(OCP_MOD, 0x001c) + +#define OMAP2430_PRCM_VOLTCTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0050) +#define OMAP2430_PRCM_VOLTST OMAP2430_PRM_REGADDR(OCP_MOD, 0x0054) +#define OMAP2430_PRCM_CLKSRC_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0060) +#define OMAP2430_PRCM_CLKOUT_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0070) +#define OMAP2430_PRCM_CLKEMUL_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0078) +#define OMAP2430_PRCM_CLKCFG_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0080) +#define OMAP2430_PRCM_CLKCFG_STATUS OMAP2430_PRM_REGADDR(OCP_MOD, 0x0084) +#define OMAP2430_PRCM_VOLTSETUP OMAP2430_PRM_REGADDR(OCP_MOD, 0x0090) +#define OMAP2430_PRCM_CLKSSETUP OMAP2430_PRM_REGADDR(OCP_MOD, 0x0094) +#define OMAP2430_PRCM_POLCTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0098) + +/* + * Module specific PRM register offsets from PRM_BASE + domain offset + * + * Use prm_{read,write}_mod_reg() with these registers. + * + * With a few exceptions, these are the register names beginning with + * {PM,RM}_* on both OMAP2/3 SoC families.. (The exceptions are the + * IRQSTATUS and IRQENABLE bits.) + */ + +/* Register offsets appearing on both OMAP2 and OMAP3 */ + +#define OMAP2_RM_RSTCTRL 0x0050 +#define OMAP2_RM_RSTTIME 0x0054 +#define OMAP2_RM_RSTST 0x0058 +#define OMAP2_PM_PWSTCTRL 0x00e0 +#define OMAP2_PM_PWSTST 0x00e4 + +#define PM_WKEN 0x00a0 +#define PM_WKEN1 PM_WKEN +#define PM_WKST 0x00b0 +#define PM_WKST1 PM_WKST +#define PM_WKDEP 0x00c8 +#define PM_EVGENCTRL 0x00d4 +#define PM_EVGENONTIM 0x00d8 +#define PM_EVGENOFFTIM 0x00dc + +/* OMAP2xxx specific register offsets */ +#define OMAP24XX_PM_WKEN2 0x00a4 +#define OMAP24XX_PM_WKST2 0x00b4 + +#define OMAP24XX_PRCM_IRQSTATUS_DSP 0x00f0 /* IVA mod */ +#define OMAP24XX_PRCM_IRQENABLE_DSP 0x00f4 /* IVA mod */ +#define OMAP24XX_PRCM_IRQSTATUS_IVA 0x00f8 +#define OMAP24XX_PRCM_IRQENABLE_IVA 0x00fc + +#ifndef __ASSEMBLER__ +/* Function prototypes */ +extern int omap2xxx_clkdm_sleep(struct clockdomain *clkdm); +extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm); + +extern void omap2xxx_prm_dpll_reset(void); + +extern int __init omap2xxx_prm_init(void); + +#endif + +#endif diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c new file mode 100644 index 00000000000..c13b4e293ff --- /dev/null +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c @@ -0,0 +1,231 @@ +/* + * OMAP2/3 PRM module functions + * + * Copyright (C) 2010-2011 Texas Instruments, Inc. + * Copyright (C) 2010 Nokia Corporation + * Benoît Cousson + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/io.h> + +#include "powerdomain.h" +#include "prm2xxx_3xxx.h" +#include "prm-regbits-24xx.h" +#include "clockdomain.h" + +/** + * omap2_prm_is_hardreset_asserted - read the HW reset line state of + * submodules contained in the hwmod module + * @prm_mod: PRM submodule base (e.g. CORE_MOD) + * @shift: register bit shift corresponding to the reset line to check + * + * Returns 1 if the (sub)module hardreset line is currently asserted, + * 0 if the (sub)module hardreset line is not currently asserted, or + * -EINVAL if called while running on a non-OMAP2/3 chip. + */ +int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift) +{ + return omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, + (1 << shift)); +} + +/** + * omap2_prm_assert_hardreset - assert the HW reset line of a submodule + * @prm_mod: PRM submodule base (e.g. CORE_MOD) + * @shift: register bit shift corresponding to the reset line to assert + * + * Some IPs like dsp or iva contain processors that require an HW + * reset line to be asserted / deasserted in order to fully enable the + * IP. These modules may have multiple hard-reset lines that reset + * different 'submodules' inside the IP block. This function will + * place the submodule into reset. Returns 0 upon success or -EINVAL + * upon an argument error. + */ +int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift) +{ + u32 mask; + + mask = 1 << shift; + omap2_prm_rmw_mod_reg_bits(mask, mask, prm_mod, OMAP2_RM_RSTCTRL); + + return 0; +} + +/** + * omap2_prm_deassert_hardreset - deassert a submodule hardreset line and wait + * @prm_mod: PRM submodule base (e.g. CORE_MOD) + * @rst_shift: register bit shift corresponding to the reset line to deassert + * @st_shift: register bit shift for the status of the deasserted submodule + * + * Some IPs like dsp or iva contain processors that require an HW + * reset line to be asserted / deasserted in order to fully enable the + * IP. These modules may have multiple hard-reset lines that reset + * different 'submodules' inside the IP block. This function will + * take the submodule out of reset and wait until the PRCM indicates + * that the reset has completed before returning. Returns 0 upon success or + * -EINVAL upon an argument error, -EEXIST if the submodule was already out + * of reset, or -EBUSY if the submodule did not exit reset promptly. + */ +int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift) +{ + u32 rst, st; + int c; + + rst = 1 << rst_shift; + st = 1 << st_shift; + + /* Check the current status to avoid de-asserting the line twice */ + if (omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, rst) == 0) + return -EEXIST; + + /* Clear the reset status by writing 1 to the status bit */ + omap2_prm_rmw_mod_reg_bits(0xffffffff, st, prm_mod, OMAP2_RM_RSTST); + /* de-assert the reset control line */ + omap2_prm_rmw_mod_reg_bits(rst, 0, prm_mod, OMAP2_RM_RSTCTRL); + /* wait the status to be set */ + omap_test_timeout(omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTST, + st), + MAX_MODULE_HARDRESET_WAIT, c); + + return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0; +} + + +/* Powerdomain low-level functions */ + +/* Common functions across OMAP2 and OMAP3 */ +int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, + u8 pwrst) +{ + u32 m; + + m = omap2_pwrdm_get_mem_bank_onstate_mask(bank); + + omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs, + OMAP2_PM_PWSTCTRL); + + return 0; +} + +int omap2_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, + u8 pwrst) +{ + u32 m; + + m = omap2_pwrdm_get_mem_bank_retst_mask(bank); + + omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs, + OMAP2_PM_PWSTCTRL); + + return 0; +} + +int omap2_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) +{ + u32 m; + + m = omap2_pwrdm_get_mem_bank_stst_mask(bank); + + return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP2_PM_PWSTST, + m); +} + +int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) +{ + u32 m; + + m = omap2_pwrdm_get_mem_bank_retst_mask(bank); + + return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, + OMAP2_PM_PWSTCTRL, m); +} + +int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) +{ + u32 v; + + v = pwrst << __ffs(OMAP_LOGICRETSTATE_MASK); + omap2_prm_rmw_mod_reg_bits(OMAP_LOGICRETSTATE_MASK, v, pwrdm->prcm_offs, + OMAP2_PM_PWSTCTRL); + + return 0; +} + +int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm) +{ + u32 c = 0; + + /* + * REVISIT: pwrdm_wait_transition() may be better implemented + * via a callback and a periodic timer check -- how long do we expect + * powerdomain transitions to take? + */ + + /* XXX Is this udelay() value meaningful? */ + while ((omap2_prm_read_mod_reg(pwrdm->prcm_offs, OMAP2_PM_PWSTST) & + OMAP_INTRANSITION_MASK) && + (c++ < PWRDM_TRANSITION_BAILOUT)) + udelay(1); + + if (c > PWRDM_TRANSITION_BAILOUT) { + pr_err("powerdomain: %s: waited too long to complete transition\n", + pwrdm->name); + return -EAGAIN; + } + + pr_debug("powerdomain: completed transition in %d loops\n", c); + + return 0; +} + +int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) +{ + omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit), + clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP); + return 0; +} + +int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) +{ + omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit), + clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP); + return 0; +} + +int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) +{ + return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, + PM_WKDEP, (1 << clkdm2->dep_bit)); +} + +/* XXX Caller must hold the clkdm's powerdomain lock */ +int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm) +{ + struct clkdm_dep *cd; + u32 mask = 0; + + for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) { + if (!cd->clkdm) + continue; /* only happens if data is erroneous */ + + /* PRM accesses are slow, so minimize them */ + mask |= 1 << cd->clkdm->dep_bit; + cd->wkdep_usecount = 0; + } + + omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, + PM_WKDEP); + return 0; +} + diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h new file mode 100644 index 00000000000..1a3a96392b9 --- /dev/null +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h @@ -0,0 +1,245 @@ +/* + * OMAP2xxx/3xxx-common Power/Reset Management (PRM) register definitions + * + * Copyright (C) 2007-2009, 2011-2012 Texas Instruments, Inc. + * Copyright (C) 2008-2010 Nokia Corporation + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * The PRM hardware modules on the OMAP2/3 are quite similar to each + * other. The PRM on OMAP4 has a new register layout, and is handled + * in a separate file. + */ +#ifndef __ARCH_ARM_MACH_OMAP2_PRM2XXX_3XXX_H +#define __ARCH_ARM_MACH_OMAP2_PRM2XXX_3XXX_H + +#include "prcm-common.h" +#include "prm.h" + +/* + * Module specific PRM register offsets from PRM_BASE + domain offset + * + * Use prm_{read,write}_mod_reg() with these registers. + * + * With a few exceptions, these are the register names beginning with + * {PM,RM}_* on both OMAP2/3 SoC families.. (The exceptions are the + * IRQSTATUS and IRQENABLE bits.) + */ + +/* Register offsets appearing on both OMAP2 and OMAP3 */ + +#define OMAP2_RM_RSTCTRL 0x0050 +#define OMAP2_RM_RSTTIME 0x0054 +#define OMAP2_RM_RSTST 0x0058 +#define OMAP2_PM_PWSTCTRL 0x00e0 +#define OMAP2_PM_PWSTST 0x00e4 + +#define PM_WKEN 0x00a0 +#define PM_WKEN1 PM_WKEN +#define PM_WKST 0x00b0 +#define PM_WKST1 PM_WKST +#define PM_WKDEP 0x00c8 +#define PM_EVGENCTRL 0x00d4 +#define PM_EVGENONTIM 0x00d8 +#define PM_EVGENOFFTIM 0x00dc + + +#ifndef __ASSEMBLER__ + +#include <linux/io.h> +#include "powerdomain.h" + +/* Power/reset management domain register get/set */ +static inline u32 omap2_prm_read_mod_reg(s16 module, u16 idx) +{ + return readl_relaxed(prm_base + module + idx); +} + +static inline void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx) +{ + writel_relaxed(val, prm_base + module + idx); +} + +/* Read-modify-write a register in a PRM module. Caller must lock */ +static inline u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, + s16 idx) +{ + u32 v; + + v = omap2_prm_read_mod_reg(module, idx); + v &= ~mask; + v |= bits; + omap2_prm_write_mod_reg(v, module, idx); + + return v; +} + +/* Read a PRM register, AND it, and shift the result down to bit 0 */ +static inline u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask) +{ + u32 v; + + v = omap2_prm_read_mod_reg(domain, idx); + v &= mask; + v >>= __ffs(mask); + + return v; +} + +static inline u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) +{ + return omap2_prm_rmw_mod_reg_bits(bits, bits, module, idx); +} + +static inline u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) +{ + return omap2_prm_rmw_mod_reg_bits(bits, 0x0, module, idx); +} + +/* These omap2_ PRM functions apply to both OMAP2 and 3 */ +extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift); +extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift); +extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift); + +extern int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst); +extern int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm); +extern int omap2_pwrdm_read_pwrst(struct powerdomain *pwrdm); +extern int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, + u8 pwrst); +extern int omap2_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, + u8 pwrst); +extern int omap2_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank); +extern int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank); +extern int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst); +extern int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm); + +extern int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2); +extern int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2); +extern int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2); +extern int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm); + +#endif /* __ASSEMBLER */ + +/* + * Bits common to specific registers + * + * The 3430 register and bit names are generally used, + * since they tend to make more sense + */ + +/* PM_EVGENONTIM_MPU */ +/* Named PM_EVEGENONTIM_MPU on the 24XX */ +#define OMAP_ONTIMEVAL_SHIFT 0 +#define OMAP_ONTIMEVAL_MASK (0xffffffff << 0) + +/* PM_EVGENOFFTIM_MPU */ +/* Named PM_EVEGENOFFTIM_MPU on the 24XX */ +#define OMAP_OFFTIMEVAL_SHIFT 0 +#define OMAP_OFFTIMEVAL_MASK (0xffffffff << 0) + +/* PRM_CLKSETUP and PRCM_VOLTSETUP */ +/* Named PRCM_CLKSSETUP on the 24XX */ +#define OMAP_SETUP_TIME_SHIFT 0 +#define OMAP_SETUP_TIME_MASK (0xffff << 0) + +/* PRM_CLKSRC_CTRL */ +/* Named PRCM_CLKSRC_CTRL on the 24XX */ +#define OMAP_SYSCLKDIV_SHIFT 6 +#define OMAP_SYSCLKDIV_MASK (0x3 << 6) +#define OMAP_SYSCLKDIV_WIDTH 2 +#define OMAP_AUTOEXTCLKMODE_SHIFT 3 +#define OMAP_AUTOEXTCLKMODE_MASK (0x3 << 3) +#define OMAP_SYSCLKSEL_SHIFT 0 +#define OMAP_SYSCLKSEL_MASK (0x3 << 0) + +/* PM_EVGENCTRL_MPU */ +#define OMAP_OFFLOADMODE_SHIFT 3 +#define OMAP_OFFLOADMODE_MASK (0x3 << 3) +#define OMAP_ONLOADMODE_SHIFT 1 +#define OMAP_ONLOADMODE_MASK (0x3 << 1) +#define OMAP_ENABLE_MASK (1 << 0) + +/* PRM_RSTTIME */ +/* Named RM_RSTTIME_WKUP on the 24xx */ +#define OMAP_RSTTIME2_SHIFT 8 +#define OMAP_RSTTIME2_MASK (0x1f << 8) +#define OMAP_RSTTIME1_SHIFT 0 +#define OMAP_RSTTIME1_MASK (0xff << 0) + +/* PRM_RSTCTRL */ +/* Named RM_RSTCTRL_WKUP on the 24xx */ +/* 2420 calls RST_DPLL3 'RST_DPLL' */ +#define OMAP_RST_DPLL3_MASK (1 << 2) +#define OMAP_RST_GS_MASK (1 << 1) + + +/* + * Bits common to module-shared registers + * + * Not all registers of a particular type support all of these bits - + * check TRM if you are unsure + */ + +/* + * 24XX: RM_RSTST_MPU and RM_RSTST_DSP - on 24XX, 'COREDOMAINWKUP_RST' is + * called 'COREWKUP_RST' + * + * 3430: RM_RSTST_IVA2, RM_RSTST_MPU, RM_RSTST_GFX, RM_RSTST_DSS, + * RM_RSTST_CAM, RM_RSTST_PER, RM_RSTST_NEON + */ +#define OMAP_COREDOMAINWKUP_RST_MASK (1 << 3) + +/* + * 24XX: RM_RSTST_MPU, RM_RSTST_GFX, RM_RSTST_DSP + * + * 2430: RM_RSTST_MDM + * + * 3430: RM_RSTST_CORE, RM_RSTST_EMU + */ +#define OMAP_DOMAINWKUP_RST_MASK (1 << 2) + +/* + * 24XX: RM_RSTST_MPU, RM_RSTST_WKUP, RM_RSTST_DSP + * On 24XX, 'GLOBALWARM_RST' is called 'GLOBALWMPU_RST'. + * + * 2430: RM_RSTST_MDM + * + * 3430: RM_RSTST_CORE, RM_RSTST_EMU + */ +#define OMAP_GLOBALWARM_RST_SHIFT 1 +#define OMAP_GLOBALWARM_RST_MASK (1 << 1) +#define OMAP_GLOBALCOLD_RST_SHIFT 0 +#define OMAP_GLOBALCOLD_RST_MASK (1 << 0) + +/* + * 24XX: PM_WKDEP_GFX, PM_WKDEP_MPU, PM_WKDEP_CORE, PM_WKDEP_DSP + * 2420 TRM sometimes uses "EN_WAKEUP" instead of "EN_WKUP" + * + * 2430: PM_WKDEP_MDM + * + * 3430: PM_WKDEP_IVA2, PM_WKDEP_GFX, PM_WKDEP_DSS, PM_WKDEP_CAM, + * PM_WKDEP_PER + */ +#define OMAP_EN_WKUP_SHIFT 4 +#define OMAP_EN_WKUP_MASK (1 << 4) + +/* + * 24XX: PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE, PM_PWSTCTRL_GFX, + * PM_PWSTCTRL_DSP + * + * 2430: PM_PWSTCTRL_MDM + * + * 3430: PM_PWSTCTRL_IVA2, PM_PWSTCTRL_CORE, PM_PWSTCTRL_GFX, + * PM_PWSTCTRL_DSS, PM_PWSTCTRL_CAM, PM_PWSTCTRL_PER, + * PM_PWSTCTRL_NEON + */ +#define OMAP_LOGICRETSTATE_MASK (1 << 2) + + +#endif diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c new file mode 100644 index 00000000000..62709cd2f9c --- /dev/null +++ b/arch/arm/mach-omap2/prm33xx.c @@ -0,0 +1,344 @@ +/* + * AM33XX PRM functions + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/io.h> + +#include "powerdomain.h" +#include "prm33xx.h" +#include "prm-regbits-33xx.h" + +/* Read a register in a PRM instance */ +u32 am33xx_prm_read_reg(s16 inst, u16 idx) +{ + return readl_relaxed(prm_base + inst + idx); +} + +/* Write into a register in a PRM instance */ +void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx) +{ + writel_relaxed(val, prm_base + inst + idx); +} + +/* Read-modify-write a register in PRM. Caller must lock */ +u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx) +{ + u32 v; + + v = am33xx_prm_read_reg(inst, idx); + v &= ~mask; + v |= bits; + am33xx_prm_write_reg(v, inst, idx); + + return v; +} + +/** + * am33xx_prm_is_hardreset_asserted - read the HW reset line state of + * submodules contained in the hwmod module + * @shift: register bit shift corresponding to the reset line to check + * @inst: CM instance register offset (*_INST macro) + * @rstctrl_offs: RM_RSTCTRL register address offset for this module + * + * Returns 1 if the (sub)module hardreset line is currently asserted, + * 0 if the (sub)module hardreset line is not currently asserted, or + * -EINVAL upon parameter error. + */ +int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst, u16 rstctrl_offs) +{ + u32 v; + + v = am33xx_prm_read_reg(inst, rstctrl_offs); + v &= 1 << shift; + v >>= shift; + + return v; +} + +/** + * am33xx_prm_assert_hardreset - assert the HW reset line of a submodule + * @shift: register bit shift corresponding to the reset line to assert + * @inst: CM instance register offset (*_INST macro) + * @rstctrl_reg: RM_RSTCTRL register address for this module + * + * Some IPs like dsp, ipu or iva contain processors that require an HW + * reset line to be asserted / deasserted in order to fully enable the + * IP. These modules may have multiple hard-reset lines that reset + * different 'submodules' inside the IP block. This function will + * place the submodule into reset. Returns 0 upon success or -EINVAL + * upon an argument error. + */ +int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs) +{ + u32 mask = 1 << shift; + + am33xx_prm_rmw_reg_bits(mask, mask, inst, rstctrl_offs); + + return 0; +} + +/** + * am33xx_prm_deassert_hardreset - deassert a submodule hardreset line and + * wait + * @shift: register bit shift corresponding to the reset line to deassert + * @inst: CM instance register offset (*_INST macro) + * @rstctrl_reg: RM_RSTCTRL register address for this module + * @rstst_reg: RM_RSTST register address for this module + * + * Some IPs like dsp, ipu or iva contain processors that require an HW + * reset line to be asserted / deasserted in order to fully enable the + * IP. These modules may have multiple hard-reset lines that reset + * different 'submodules' inside the IP block. This function will + * take the submodule out of reset and wait until the PRCM indicates + * that the reset has completed before returning. Returns 0 upon success or + * -EINVAL upon an argument error, -EEXIST if the submodule was already out + * of reset, or -EBUSY if the submodule did not exit reset promptly. + */ +int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, s16 inst, + u16 rstctrl_offs, u16 rstst_offs) +{ + int c; + u32 mask = 1 << st_shift; + + /* Check the current status to avoid de-asserting the line twice */ + if (am33xx_prm_is_hardreset_asserted(shift, inst, rstctrl_offs) == 0) + return -EEXIST; + + /* Clear the reset status by writing 1 to the status bit */ + am33xx_prm_rmw_reg_bits(0xffffffff, mask, inst, rstst_offs); + + /* de-assert the reset control line */ + mask = 1 << shift; + + am33xx_prm_rmw_reg_bits(mask, 0, inst, rstctrl_offs); + + /* wait the status to be set */ + omap_test_timeout(am33xx_prm_is_hardreset_asserted(st_shift, inst, + rstst_offs), + MAX_MODULE_HARDRESET_WAIT, c); + + return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0; +} + +static int am33xx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) +{ + am33xx_prm_rmw_reg_bits(OMAP_POWERSTATE_MASK, + (pwrst << OMAP_POWERSTATE_SHIFT), + pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); + return 0; +} + +static int am33xx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm) +{ + u32 v; + + v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); + v &= OMAP_POWERSTATE_MASK; + v >>= OMAP_POWERSTATE_SHIFT; + + return v; +} + +static int am33xx_pwrdm_read_pwrst(struct powerdomain *pwrdm) +{ + u32 v; + + v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs); + v &= OMAP_POWERSTATEST_MASK; + v >>= OMAP_POWERSTATEST_SHIFT; + + return v; +} + +static int am33xx_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) +{ + u32 v; + + v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs); + v &= AM33XX_LASTPOWERSTATEENTERED_MASK; + v >>= AM33XX_LASTPOWERSTATEENTERED_SHIFT; + + return v; +} + +static int am33xx_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm) +{ + am33xx_prm_rmw_reg_bits(AM33XX_LOWPOWERSTATECHANGE_MASK, + (1 << AM33XX_LOWPOWERSTATECHANGE_SHIFT), + pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); + return 0; +} + +static int am33xx_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) +{ + am33xx_prm_rmw_reg_bits(AM33XX_LASTPOWERSTATEENTERED_MASK, + AM33XX_LASTPOWERSTATEENTERED_MASK, + pwrdm->prcm_offs, pwrdm->pwrstst_offs); + return 0; +} + +static int am33xx_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) +{ + u32 m; + + m = pwrdm->logicretstate_mask; + if (!m) + return -EINVAL; + + am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)), + pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); + + return 0; +} + +static int am33xx_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) +{ + u32 v; + + v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs); + v &= AM33XX_LOGICSTATEST_MASK; + v >>= AM33XX_LOGICSTATEST_SHIFT; + + return v; +} + +static int am33xx_pwrdm_read_logic_retst(struct powerdomain *pwrdm) +{ + u32 v, m; + + m = pwrdm->logicretstate_mask; + if (!m) + return -EINVAL; + + v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); + v &= m; + v >>= __ffs(m); + + return v; +} + +static int am33xx_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, + u8 pwrst) +{ + u32 m; + + m = pwrdm->mem_on_mask[bank]; + if (!m) + return -EINVAL; + + am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)), + pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); + + return 0; +} + +static int am33xx_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, + u8 pwrst) +{ + u32 m; + + m = pwrdm->mem_ret_mask[bank]; + if (!m) + return -EINVAL; + + am33xx_prm_rmw_reg_bits(m, (pwrst << __ffs(m)), + pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); + + return 0; +} + +static int am33xx_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) +{ + u32 m, v; + + m = pwrdm->mem_pwrst_mask[bank]; + if (!m) + return -EINVAL; + + v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs); + v &= m; + v >>= __ffs(m); + + return v; +} + +static int am33xx_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) +{ + u32 m, v; + + m = pwrdm->mem_retst_mask[bank]; + if (!m) + return -EINVAL; + + v = am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstctrl_offs); + v &= m; + v >>= __ffs(m); + + return v; +} + +static int am33xx_pwrdm_wait_transition(struct powerdomain *pwrdm) +{ + u32 c = 0; + + /* + * REVISIT: pwrdm_wait_transition() may be better implemented + * via a callback and a periodic timer check -- how long do we expect + * powerdomain transitions to take? + */ + + /* XXX Is this udelay() value meaningful? */ + while ((am33xx_prm_read_reg(pwrdm->prcm_offs, pwrdm->pwrstst_offs) + & OMAP_INTRANSITION_MASK) && + (c++ < PWRDM_TRANSITION_BAILOUT)) + udelay(1); + + if (c > PWRDM_TRANSITION_BAILOUT) { + pr_err("powerdomain: %s: waited too long to complete transition\n", + pwrdm->name); + return -EAGAIN; + } + + pr_debug("powerdomain: completed transition in %d loops\n", c); + + return 0; +} + +static int am33xx_check_vcvp(void) +{ + /* No VC/VP on am33xx devices */ + return 0; +} + +struct pwrdm_ops am33xx_pwrdm_operations = { + .pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst, + .pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst, + .pwrdm_read_pwrst = am33xx_pwrdm_read_pwrst, + .pwrdm_read_prev_pwrst = am33xx_pwrdm_read_prev_pwrst, + .pwrdm_set_logic_retst = am33xx_pwrdm_set_logic_retst, + .pwrdm_read_logic_pwrst = am33xx_pwrdm_read_logic_pwrst, + .pwrdm_read_logic_retst = am33xx_pwrdm_read_logic_retst, + .pwrdm_clear_all_prev_pwrst = am33xx_pwrdm_clear_all_prev_pwrst, + .pwrdm_set_lowpwrstchange = am33xx_pwrdm_set_lowpwrstchange, + .pwrdm_read_mem_pwrst = am33xx_pwrdm_read_mem_pwrst, + .pwrdm_read_mem_retst = am33xx_pwrdm_read_mem_retst, + .pwrdm_set_mem_onst = am33xx_pwrdm_set_mem_onst, + .pwrdm_set_mem_retst = am33xx_pwrdm_set_mem_retst, + .pwrdm_wait_transition = am33xx_pwrdm_wait_transition, + .pwrdm_has_voltdm = am33xx_check_vcvp, +}; diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h new file mode 100644 index 00000000000..9b9918dfb11 --- /dev/null +++ b/arch/arm/mach-omap2/prm33xx.h @@ -0,0 +1,131 @@ +/* + * AM33XX PRM instance offset macros + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_PRM33XX_H +#define __ARCH_ARM_MACH_OMAP2_PRM33XX_H + +#include "prcm-common.h" +#include "prm.h" + +#define AM33XX_PRM_BASE 0x44E00000 + +#define AM33XX_PRM_REGADDR(inst, reg) \ + AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRM_BASE + (inst) + (reg)) + + +/* PRM instances */ +#define AM33XX_PRM_OCP_SOCKET_MOD 0x0B00 +#define AM33XX_PRM_PER_MOD 0x0C00 +#define AM33XX_PRM_WKUP_MOD 0x0D00 +#define AM33XX_PRM_MPU_MOD 0x0E00 +#define AM33XX_PRM_DEVICE_MOD 0x0F00 +#define AM33XX_PRM_RTC_MOD 0x1000 +#define AM33XX_PRM_GFX_MOD 0x1100 +#define AM33XX_PRM_CEFUSE_MOD 0x1200 + +/* PRM */ + +/* PRM.OCP_SOCKET_PRM register offsets */ +#define AM33XX_REVISION_PRM_OFFSET 0x0000 +#define AM33XX_REVISION_PRM AM33XX_PRM_REGADDR(AM33XX_PRM_OCP_SOCKET_MOD, 0x0000) +#define AM33XX_PRM_IRQSTATUS_MPU_OFFSET 0x0004 +#define AM33XX_PRM_IRQSTATUS_MPU AM33XX_PRM_REGADDR(AM33XX_PRM_OCP_SOCKET_MOD, 0x0004) +#define AM33XX_PRM_IRQENABLE_MPU_OFFSET 0x0008 +#define AM33XX_PRM_IRQENABLE_MPU AM33XX_PRM_REGADDR(AM33XX_PRM_OCP_SOCKET_MOD, 0x0008) +#define AM33XX_PRM_IRQSTATUS_M3_OFFSET 0x000c +#define AM33XX_PRM_IRQSTATUS_M3 AM33XX_PRM_REGADDR(AM33XX_PRM_OCP_SOCKET_MOD, 0x000c) +#define AM33XX_PRM_IRQENABLE_M3_OFFSET 0x0010 +#define AM33XX_PRM_IRQENABLE_M3 AM33XX_PRM_REGADDR(AM33XX_PRM_OCP_SOCKET_MOD, 0x0010) + +/* PRM.PER_PRM register offsets */ +#define AM33XX_RM_PER_RSTCTRL_OFFSET 0x0000 +#define AM33XX_RM_PER_RSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_PER_MOD, 0x0000) +#define AM33XX_RM_PER_RSTST_OFFSET 0x0004 +#define AM33XX_RM_PER_RSTST AM33XX_PRM_REGADDR(AM33XX_PRM_PER_MOD, 0x0004) +#define AM33XX_PM_PER_PWRSTST_OFFSET 0x0008 +#define AM33XX_PM_PER_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_PER_MOD, 0x0008) +#define AM33XX_PM_PER_PWRSTCTRL_OFFSET 0x000c +#define AM33XX_PM_PER_PWRSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_PER_MOD, 0x000c) + +/* PRM.WKUP_PRM register offsets */ +#define AM33XX_RM_WKUP_RSTCTRL_OFFSET 0x0000 +#define AM33XX_RM_WKUP_RSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_WKUP_MOD, 0x0000) +#define AM33XX_PM_WKUP_PWRSTCTRL_OFFSET 0x0004 +#define AM33XX_PM_WKUP_PWRSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_WKUP_MOD, 0x0004) +#define AM33XX_PM_WKUP_PWRSTST_OFFSET 0x0008 +#define AM33XX_PM_WKUP_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_WKUP_MOD, 0x0008) +#define AM33XX_RM_WKUP_RSTST_OFFSET 0x000c +#define AM33XX_RM_WKUP_RSTST AM33XX_PRM_REGADDR(AM33XX_PRM_WKUP_MOD, 0x000c) + +/* PRM.MPU_PRM register offsets */ +#define AM33XX_PM_MPU_PWRSTCTRL_OFFSET 0x0000 +#define AM33XX_PM_MPU_PWRSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_MPU_MOD, 0x0000) +#define AM33XX_PM_MPU_PWRSTST_OFFSET 0x0004 +#define AM33XX_PM_MPU_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_MPU_MOD, 0x0004) +#define AM33XX_RM_MPU_RSTST_OFFSET 0x0008 +#define AM33XX_RM_MPU_RSTST AM33XX_PRM_REGADDR(AM33XX_PRM_MPU_MOD, 0x0008) + +/* PRM.DEVICE_PRM register offsets */ +#define AM33XX_PRM_RSTCTRL_OFFSET 0x0000 +#define AM33XX_PRM_RSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x0000) +#define AM33XX_PRM_RSTTIME_OFFSET 0x0004 +#define AM33XX_PRM_RSTTIME AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x0004) +#define AM33XX_PRM_RSTST_OFFSET 0x0008 +#define AM33XX_PRM_RSTST AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x0008) +#define AM33XX_PRM_SRAM_COUNT_OFFSET 0x000c +#define AM33XX_PRM_SRAM_COUNT AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x000c) +#define AM33XX_PRM_LDO_SRAM_CORE_SETUP_OFFSET 0x0010 +#define AM33XX_PRM_LDO_SRAM_CORE_SETUP AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x0010) +#define AM33XX_PRM_LDO_SRAM_CORE_CTRL_OFFSET 0x0014 +#define AM33XX_PRM_LDO_SRAM_CORE_CTRL AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x0014) +#define AM33XX_PRM_LDO_SRAM_MPU_SETUP_OFFSET 0x0018 +#define AM33XX_PRM_LDO_SRAM_MPU_SETUP AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x0018) +#define AM33XX_PRM_LDO_SRAM_MPU_CTRL_OFFSET 0x001c +#define AM33XX_PRM_LDO_SRAM_MPU_CTRL AM33XX_PRM_REGADDR(AM33XX_PRM_DEVICE_MOD, 0x001c) + +/* PRM.RTC_PRM register offsets */ +#define AM33XX_PM_RTC_PWRSTCTRL_OFFSET 0x0000 +#define AM33XX_PM_RTC_PWRSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_RTC_MOD, 0x0000) +#define AM33XX_PM_RTC_PWRSTST_OFFSET 0x0004 +#define AM33XX_PM_RTC_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_RTC_MOD, 0x0004) + +/* PRM.GFX_PRM register offsets */ +#define AM33XX_PM_GFX_PWRSTCTRL_OFFSET 0x0000 +#define AM33XX_PM_GFX_PWRSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_GFX_MOD, 0x0000) +#define AM33XX_RM_GFX_RSTCTRL_OFFSET 0x0004 +#define AM33XX_RM_GFX_RSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_GFX_MOD, 0x0004) +#define AM33XX_PM_GFX_PWRSTST_OFFSET 0x0010 +#define AM33XX_PM_GFX_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_GFX_MOD, 0x0010) +#define AM33XX_RM_GFX_RSTST_OFFSET 0x0014 +#define AM33XX_RM_GFX_RSTST AM33XX_PRM_REGADDR(AM33XX_PRM_GFX_MOD, 0x0014) + +/* PRM.CEFUSE_PRM register offsets */ +#define AM33XX_PM_CEFUSE_PWRSTCTRL_OFFSET 0x0000 +#define AM33XX_PM_CEFUSE_PWRSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0000) +#define AM33XX_PM_CEFUSE_PWRSTST_OFFSET 0x0004 +#define AM33XX_PM_CEFUSE_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0004) + +#ifndef __ASSEMBLER__ +extern u32 am33xx_prm_read_reg(s16 inst, u16 idx); +extern void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx); +extern u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx); +extern void am33xx_prm_global_warm_sw_reset(void); +extern int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst, + u16 rstctrl_offs); +extern int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs); +extern int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, s16 inst, + u16 rstctrl_offs, u16 rstst_offs); +#endif /* ASSEMBLER */ +#endif diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c new file mode 100644 index 00000000000..4bd7a2dca8a --- /dev/null +++ b/arch/arm/mach-omap2/prm3xxx.c @@ -0,0 +1,439 @@ +/* + * OMAP3xxx PRM module functions + * + * Copyright (C) 2010-2012 Texas Instruments, Inc. + * Copyright (C) 2010 Nokia Corporation + * Benoît Cousson + * Paul Walmsley + * Rajendra Nayak <rnayak@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/irq.h> + +#include "soc.h" +#include "common.h" +#include "vp.h" +#include "powerdomain.h" +#include "prm3xxx.h" +#include "prm2xxx_3xxx.h" +#include "cm2xxx_3xxx.h" +#include "prm-regbits-34xx.h" + +static const struct omap_prcm_irq omap3_prcm_irqs[] = { + OMAP_PRCM_IRQ("wkup", 0, 0), + OMAP_PRCM_IRQ("io", 9, 1), +}; + +static struct omap_prcm_irq_setup omap3_prcm_irq_setup = { + .ack = OMAP3_PRM_IRQSTATUS_MPU_OFFSET, + .mask = OMAP3_PRM_IRQENABLE_MPU_OFFSET, + .nr_regs = 1, + .irqs = omap3_prcm_irqs, + .nr_irqs = ARRAY_SIZE(omap3_prcm_irqs), + .irq = 11 + OMAP_INTC_START, + .read_pending_irqs = &omap3xxx_prm_read_pending_irqs, + .ocp_barrier = &omap3xxx_prm_ocp_barrier, + .save_and_clear_irqen = &omap3xxx_prm_save_and_clear_irqen, + .restore_irqen = &omap3xxx_prm_restore_irqen, + .reconfigure_io_chain = &omap3xxx_prm_reconfigure_io_chain, +}; + +/* + * omap3_prm_reset_src_map - map from bits in the PRM_RSTST hardware + * register (which are specific to OMAP3xxx SoCs) to reset source ID + * bit shifts (which is an OMAP SoC-independent enumeration) + */ +static struct prm_reset_src_map omap3xxx_prm_reset_src_map[] = { + { OMAP3430_GLOBAL_COLD_RST_SHIFT, OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT }, + { OMAP3430_GLOBAL_SW_RST_SHIFT, OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT }, + { OMAP3430_SECURITY_VIOL_RST_SHIFT, OMAP_SECU_VIOL_RST_SRC_ID_SHIFT }, + { OMAP3430_MPU_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT }, + { OMAP3430_SECURE_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT }, + { OMAP3430_EXTERNAL_WARM_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT }, + { OMAP3430_VDD1_VOLTAGE_MANAGER_RST_SHIFT, + OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT }, + { OMAP3430_VDD2_VOLTAGE_MANAGER_RST_SHIFT, + OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT }, + { OMAP3430_ICEPICK_RST_SHIFT, OMAP_ICEPICK_RST_SRC_ID_SHIFT }, + { OMAP3430_ICECRUSHER_RST_SHIFT, OMAP_ICECRUSHER_RST_SRC_ID_SHIFT }, + { -1, -1 }, +}; + +/* PRM VP */ + +/* + * struct omap3_vp - OMAP3 VP register access description. + * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg + */ +struct omap3_vp { + u32 tranxdone_status; +}; + +static struct omap3_vp omap3_vp[] = { + [OMAP3_VP_VDD_MPU_ID] = { + .tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK, + }, + [OMAP3_VP_VDD_CORE_ID] = { + .tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK, + }, +}; + +#define MAX_VP_ID ARRAY_SIZE(omap3_vp); + +u32 omap3_prm_vp_check_txdone(u8 vp_id) +{ + struct omap3_vp *vp = &omap3_vp[vp_id]; + u32 irqstatus; + + irqstatus = omap2_prm_read_mod_reg(OCP_MOD, + OMAP3_PRM_IRQSTATUS_MPU_OFFSET); + return irqstatus & vp->tranxdone_status; +} + +void omap3_prm_vp_clear_txdone(u8 vp_id) +{ + struct omap3_vp *vp = &omap3_vp[vp_id]; + + omap2_prm_write_mod_reg(vp->tranxdone_status, + OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); +} + +u32 omap3_prm_vcvp_read(u8 offset) +{ + return omap2_prm_read_mod_reg(OMAP3430_GR_MOD, offset); +} + +void omap3_prm_vcvp_write(u32 val, u8 offset) +{ + omap2_prm_write_mod_reg(val, OMAP3430_GR_MOD, offset); +} + +u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset) +{ + return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset); +} + +/** + * omap3xxx_prm_dpll3_reset - use DPLL3 reset to reboot the OMAP SoC + * + * Set the DPLL3 reset bit, which should reboot the SoC. This is the + * recommended way to restart the SoC, considering Errata i520. No + * return value. + */ +void omap3xxx_prm_dpll3_reset(void) +{ + omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, OMAP3430_GR_MOD, + OMAP2_RM_RSTCTRL); + /* OCP barrier */ + omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP2_RM_RSTCTRL); +} + +/** + * omap3xxx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events + * @events: ptr to a u32, preallocated by caller + * + * Read PRM_IRQSTATUS_MPU bits, AND'ed with the currently-enabled PRM + * MPU IRQs, and store the result into the u32 pointed to by @events. + * No return value. + */ +void omap3xxx_prm_read_pending_irqs(unsigned long *events) +{ + u32 mask, st; + + /* XXX Can the mask read be avoided (e.g., can it come from RAM?) */ + mask = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET); + st = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); + + events[0] = mask & st; +} + +/** + * omap3xxx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete + * + * Force any buffered writes to the PRM IP block to complete. Needed + * by the PRM IRQ handler, which reads and writes directly to the IP + * block, to avoid race conditions after acknowledging or clearing IRQ + * bits. No return value. + */ +void omap3xxx_prm_ocp_barrier(void) +{ + omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET); +} + +/** + * omap3xxx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU reg + * @saved_mask: ptr to a u32 array to save IRQENABLE bits + * + * Save the PRM_IRQENABLE_MPU register to @saved_mask. @saved_mask + * must be allocated by the caller. Intended to be used in the PRM + * interrupt handler suspend callback. The OCP barrier is needed to + * ensure the write to disable PRM interrupts reaches the PRM before + * returning; otherwise, spurious interrupts might occur. No return + * value. + */ +void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask) +{ + saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD, + OMAP3_PRM_IRQENABLE_MPU_OFFSET); + omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET); + + /* OCP barrier */ + omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET); +} + +/** + * omap3xxx_prm_restore_irqen - set PRM_IRQENABLE_MPU register from args + * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously + * + * Restore the PRM_IRQENABLE_MPU register from @saved_mask. Intended + * to be used in the PRM interrupt handler resume callback to restore + * values saved by omap3xxx_prm_save_and_clear_irqen(). No OCP + * barrier should be needed here; any pending PRM interrupts will fire + * once the writes reach the PRM. No return value. + */ +void omap3xxx_prm_restore_irqen(u32 *saved_mask) +{ + omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD, + OMAP3_PRM_IRQENABLE_MPU_OFFSET); +} + +/** + * omap3xxx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain + * + * Clear any previously-latched I/O wakeup events and ensure that the + * I/O wakeup gates are aligned with the current mux settings. Works + * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then + * deasserting WUCLKIN and clearing the ST_IO_CHAIN WKST bit. No + * return value. + */ +void omap3xxx_prm_reconfigure_io_chain(void) +{ + int i = 0; + + omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); + + omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) & + OMAP3430_ST_IO_CHAIN_MASK, + MAX_IOPAD_LATCH_TIME, i); + if (i == MAX_IOPAD_LATCH_TIME) + pr_warn("PRM: I/O chain clock line assertion timed out\n"); + + omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); + + omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD, + PM_WKST); + + omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST); +} + +/** + * omap3xxx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches + * + * Activates the I/O wakeup event latches and allows events logged by + * those latches to signal a wakeup event to the PRCM. For I/O + * wakeups to occur, WAKEUPENABLE bits must be set in the pad mux + * registers, and omap3xxx_prm_reconfigure_io_chain() must be called. + * No return value. + */ +static void __init omap3xxx_prm_enable_io_wakeup(void) +{ + if (prm_features & PRM_HAS_IO_WAKEUP) + omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, + PM_WKEN); +} + +/** + * omap3xxx_prm_read_reset_sources - return the last SoC reset source + * + * Return a u32 representing the last reset sources of the SoC. The + * returned reset source bits are standardized across OMAP SoCs. + */ +static u32 omap3xxx_prm_read_reset_sources(void) +{ + struct prm_reset_src_map *p; + u32 r = 0; + u32 v; + + v = omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST); + + p = omap3xxx_prm_reset_src_map; + while (p->reg_shift >= 0 && p->std_shift >= 0) { + if (v & (1 << p->reg_shift)) + r |= 1 << p->std_shift; + p++; + } + + return r; +} + +/* Powerdomain low-level functions */ + +static int omap3_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) +{ + omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK, + (pwrst << OMAP_POWERSTATE_SHIFT), + pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL); + return 0; +} + +static int omap3_pwrdm_read_next_pwrst(struct powerdomain *pwrdm) +{ + return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, + OMAP2_PM_PWSTCTRL, + OMAP_POWERSTATE_MASK); +} + +static int omap3_pwrdm_read_pwrst(struct powerdomain *pwrdm) +{ + return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, + OMAP2_PM_PWSTST, + OMAP_POWERSTATEST_MASK); +} + +/* Applicable only for OMAP3. Not supported on OMAP2 */ +static int omap3_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) +{ + return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, + OMAP3430_PM_PREPWSTST, + OMAP3430_LASTPOWERSTATEENTERED_MASK); +} + +static int omap3_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) +{ + return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, + OMAP2_PM_PWSTST, + OMAP3430_LOGICSTATEST_MASK); +} + +static int omap3_pwrdm_read_logic_retst(struct powerdomain *pwrdm) +{ + return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, + OMAP2_PM_PWSTCTRL, + OMAP3430_LOGICSTATEST_MASK); +} + +static int omap3_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) +{ + return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, + OMAP3430_PM_PREPWSTST, + OMAP3430_LASTLOGICSTATEENTERED_MASK); +} + +static int omap3_get_mem_bank_lastmemst_mask(u8 bank) +{ + switch (bank) { + case 0: + return OMAP3430_LASTMEM1STATEENTERED_MASK; + case 1: + return OMAP3430_LASTMEM2STATEENTERED_MASK; + case 2: + return OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK; + case 3: + return OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK; + default: + WARN_ON(1); /* should never happen */ + return -EEXIST; + } + return 0; +} + +static int omap3_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) +{ + u32 m; + + m = omap3_get_mem_bank_lastmemst_mask(bank); + + return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, + OMAP3430_PM_PREPWSTST, m); +} + +static int omap3_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) +{ + omap2_prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST); + return 0; +} + +static int omap3_pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm) +{ + return omap2_prm_rmw_mod_reg_bits(0, + 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, + pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL); +} + +static int omap3_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm) +{ + return omap2_prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, + 0, pwrdm->prcm_offs, + OMAP2_PM_PWSTCTRL); +} + +struct pwrdm_ops omap3_pwrdm_operations = { + .pwrdm_set_next_pwrst = omap3_pwrdm_set_next_pwrst, + .pwrdm_read_next_pwrst = omap3_pwrdm_read_next_pwrst, + .pwrdm_read_pwrst = omap3_pwrdm_read_pwrst, + .pwrdm_read_prev_pwrst = omap3_pwrdm_read_prev_pwrst, + .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst, + .pwrdm_read_logic_pwrst = omap3_pwrdm_read_logic_pwrst, + .pwrdm_read_logic_retst = omap3_pwrdm_read_logic_retst, + .pwrdm_read_prev_logic_pwrst = omap3_pwrdm_read_prev_logic_pwrst, + .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst, + .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst, + .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst, + .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst, + .pwrdm_read_prev_mem_pwrst = omap3_pwrdm_read_prev_mem_pwrst, + .pwrdm_clear_all_prev_pwrst = omap3_pwrdm_clear_all_prev_pwrst, + .pwrdm_enable_hdwr_sar = omap3_pwrdm_enable_hdwr_sar, + .pwrdm_disable_hdwr_sar = omap3_pwrdm_disable_hdwr_sar, + .pwrdm_wait_transition = omap2_pwrdm_wait_transition, +}; + +/* + * + */ + +static int omap3xxx_prm_late_init(void); + +static struct prm_ll_data omap3xxx_prm_ll_data = { + .read_reset_sources = &omap3xxx_prm_read_reset_sources, + .late_init = &omap3xxx_prm_late_init, +}; + +int __init omap3xxx_prm_init(void) +{ + if (omap3_has_io_wakeup()) + prm_features |= PRM_HAS_IO_WAKEUP; + + return prm_register(&omap3xxx_prm_ll_data); +} + +static int omap3xxx_prm_late_init(void) +{ + int ret; + + if (!(prm_features & PRM_HAS_IO_WAKEUP)) + return 0; + + omap3xxx_prm_enable_io_wakeup(); + ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); + if (!ret) + irq_set_status_flags(omap_prcm_event_to_irq("io"), + IRQ_NOAUTOEN); + + return ret; +} + +static void __exit omap3xxx_prm_exit(void) +{ + prm_unregister(&omap3xxx_prm_ll_data); +} +__exitcall(omap3xxx_prm_exit); diff --git a/arch/arm/mach-omap2/prm3xxx.h b/arch/arm/mach-omap2/prm3xxx.h new file mode 100644 index 00000000000..1dacfc5b195 --- /dev/null +++ b/arch/arm/mach-omap2/prm3xxx.h @@ -0,0 +1,169 @@ +/* + * OMAP3xxx Power/Reset Management (PRM) register definitions + * + * Copyright (C) 2007-2009, 2011-2012 Texas Instruments, Inc. + * Copyright (C) 2008-2010 Nokia Corporation + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * The PRM hardware modules on the OMAP2/3 are quite similar to each + * other. The PRM on OMAP4 has a new register layout, and is handled + * in a separate file. + */ +#ifndef __ARCH_ARM_MACH_OMAP2_PRM3XXX_H +#define __ARCH_ARM_MACH_OMAP2_PRM3XXX_H + +#include "prcm-common.h" +#include "prm.h" +#include "prm2xxx_3xxx.h" + +#define OMAP34XX_PRM_REGADDR(module, reg) \ + OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg)) + + +/* + * OMAP3-specific global PRM registers + * Use {read,write}l_relaxed() with these registers. + * + * With a few exceptions, these are the register names beginning with + * PRM_* on 34xx. (The exceptions are the IRQSTATUS and IRQENABLE + * bits.) + */ + +#define OMAP3_PRM_REVISION_OFFSET 0x0004 +#define OMAP3430_PRM_REVISION OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0004) +#define OMAP3_PRM_SYSCONFIG_OFFSET 0x0014 +#define OMAP3430_PRM_SYSCONFIG OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0014) + +#define OMAP3_PRM_IRQSTATUS_MPU_OFFSET 0x0018 +#define OMAP3430_PRM_IRQSTATUS_MPU OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0018) +#define OMAP3_PRM_IRQENABLE_MPU_OFFSET 0x001c +#define OMAP3430_PRM_IRQENABLE_MPU OMAP34XX_PRM_REGADDR(OCP_MOD, 0x001c) + + +#define OMAP3_PRM_VC_SMPS_SA_OFFSET 0x0020 +#define OMAP3430_PRM_VC_SMPS_SA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0020) +#define OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET 0x0024 +#define OMAP3430_PRM_VC_SMPS_VOL_RA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0024) +#define OMAP3_PRM_VC_SMPS_CMD_RA_OFFSET 0x0028 +#define OMAP3430_PRM_VC_SMPS_CMD_RA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0028) +#define OMAP3_PRM_VC_CMD_VAL_0_OFFSET 0x002c +#define OMAP3430_PRM_VC_CMD_VAL_0 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x002c) +#define OMAP3_PRM_VC_CMD_VAL_1_OFFSET 0x0030 +#define OMAP3430_PRM_VC_CMD_VAL_1 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0030) +#define OMAP3_PRM_VC_CH_CONF_OFFSET 0x0034 +#define OMAP3430_PRM_VC_CH_CONF OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0034) +#define OMAP3_PRM_VC_I2C_CFG_OFFSET 0x0038 +#define OMAP3430_PRM_VC_I2C_CFG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0038) +#define OMAP3_PRM_VC_BYPASS_VAL_OFFSET 0x003c +#define OMAP3430_PRM_VC_BYPASS_VAL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x003c) +#define OMAP3_PRM_RSTCTRL_OFFSET 0x0050 +#define OMAP3430_PRM_RSTCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0050) +#define OMAP3_PRM_RSTTIME_OFFSET 0x0054 +#define OMAP3430_PRM_RSTTIME OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0054) +#define OMAP3_PRM_RSTST_OFFSET 0x0058 +#define OMAP3430_PRM_RSTST OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0058) +#define OMAP3_PRM_VOLTCTRL_OFFSET 0x0060 +#define OMAP3430_PRM_VOLTCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0060) +#define OMAP3_PRM_SRAM_PCHARGE_OFFSET 0x0064 +#define OMAP3430_PRM_SRAM_PCHARGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0064) +#define OMAP3_PRM_CLKSRC_CTRL_OFFSET 0x0070 +#define OMAP3430_PRM_CLKSRC_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0070) +#define OMAP3_PRM_VOLTSETUP1_OFFSET 0x0090 +#define OMAP3430_PRM_VOLTSETUP1 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0090) +#define OMAP3_PRM_VOLTOFFSET_OFFSET 0x0094 +#define OMAP3430_PRM_VOLTOFFSET OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0094) +#define OMAP3_PRM_CLKSETUP_OFFSET 0x0098 +#define OMAP3430_PRM_CLKSETUP OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0098) +#define OMAP3_PRM_POLCTRL_OFFSET 0x009c +#define OMAP3430_PRM_POLCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x009c) +#define OMAP3_PRM_VOLTSETUP2_OFFSET 0x00a0 +#define OMAP3430_PRM_VOLTSETUP2 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00a0) +#define OMAP3_PRM_VP1_CONFIG_OFFSET 0x00b0 +#define OMAP3430_PRM_VP1_CONFIG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b0) +#define OMAP3_PRM_VP1_VSTEPMIN_OFFSET 0x00b4 +#define OMAP3430_PRM_VP1_VSTEPMIN OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b4) +#define OMAP3_PRM_VP1_VSTEPMAX_OFFSET 0x00b8 +#define OMAP3430_PRM_VP1_VSTEPMAX OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b8) +#define OMAP3_PRM_VP1_VLIMITTO_OFFSET 0x00bc +#define OMAP3430_PRM_VP1_VLIMITTO OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00bc) +#define OMAP3_PRM_VP1_VOLTAGE_OFFSET 0x00c0 +#define OMAP3430_PRM_VP1_VOLTAGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c0) +#define OMAP3_PRM_VP1_STATUS_OFFSET 0x00c4 +#define OMAP3430_PRM_VP1_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c4) +#define OMAP3_PRM_VP2_CONFIG_OFFSET 0x00d0 +#define OMAP3430_PRM_VP2_CONFIG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d0) +#define OMAP3_PRM_VP2_VSTEPMIN_OFFSET 0x00d4 +#define OMAP3430_PRM_VP2_VSTEPMIN OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d4) +#define OMAP3_PRM_VP2_VSTEPMAX_OFFSET 0x00d8 +#define OMAP3430_PRM_VP2_VSTEPMAX OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d8) +#define OMAP3_PRM_VP2_VLIMITTO_OFFSET 0x00dc +#define OMAP3430_PRM_VP2_VLIMITTO OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00dc) +#define OMAP3_PRM_VP2_VOLTAGE_OFFSET 0x00e0 +#define OMAP3430_PRM_VP2_VOLTAGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e0) +#define OMAP3_PRM_VP2_STATUS_OFFSET 0x00e4 +#define OMAP3430_PRM_VP2_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e4) + +#define OMAP3_PRM_CLKSEL_OFFSET 0x0040 +#define OMAP3430_PRM_CLKSEL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0040) +#define OMAP3_PRM_CLKOUT_CTRL_OFFSET 0x0070 +#define OMAP3430_PRM_CLKOUT_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0070) + +/* OMAP3 specific register offsets */ +#define OMAP3430ES2_PM_WKEN3 0x00f0 +#define OMAP3430ES2_PM_WKST3 0x00b8 + +#define OMAP3430_PM_MPUGRPSEL 0x00a4 +#define OMAP3430_PM_MPUGRPSEL1 OMAP3430_PM_MPUGRPSEL +#define OMAP3430ES2_PM_MPUGRPSEL3 0x00f8 + +#define OMAP3430_PM_IVAGRPSEL 0x00a8 +#define OMAP3430_PM_IVAGRPSEL1 OMAP3430_PM_IVAGRPSEL +#define OMAP3430ES2_PM_IVAGRPSEL3 0x00f4 + +#define OMAP3430_PM_PREPWSTST 0x00e8 + +#define OMAP3430_PRM_IRQSTATUS_IVA2 0x00f8 +#define OMAP3430_PRM_IRQENABLE_IVA2 0x00fc + + +#ifndef __ASSEMBLER__ + +/* OMAP3-specific VP functions */ +u32 omap3_prm_vp_check_txdone(u8 vp_id); +void omap3_prm_vp_clear_txdone(u8 vp_id); + +/* + * OMAP3 access functions for voltage controller (VC) and + * voltage proccessor (VP) in the PRM. + */ +extern u32 omap3_prm_vcvp_read(u8 offset); +extern void omap3_prm_vcvp_write(u32 val, u8 offset); +extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); + +#ifdef CONFIG_ARCH_OMAP3 +void omap3xxx_prm_reconfigure_io_chain(void); +#else +static inline void omap3xxx_prm_reconfigure_io_chain(void) +{ +} +#endif + +/* PRM interrupt-related functions */ +extern void omap3xxx_prm_read_pending_irqs(unsigned long *events); +extern void omap3xxx_prm_ocp_barrier(void); +extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask); +extern void omap3xxx_prm_restore_irqen(u32 *saved_mask); + +extern void omap3xxx_prm_dpll3_reset(void); + +extern int __init omap3xxx_prm_init(void); +extern u32 omap3xxx_prm_get_reset_sources(void); + +#endif /* __ASSEMBLER */ + + +#endif diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c new file mode 100644 index 00000000000..a7f6ea27180 --- /dev/null +++ b/arch/arm/mach-omap2/prm44xx.c @@ -0,0 +1,687 @@ +/* + * OMAP4 PRM module functions + * + * Copyright (C) 2011-2012 Texas Instruments, Inc. + * Copyright (C) 2010 Nokia Corporation + * Benoît Cousson + * Paul Walmsley + * Rajendra Nayak <rnayak@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/io.h> + + +#include "soc.h" +#include "iomap.h" +#include "common.h" +#include "vp.h" +#include "prm44xx.h" +#include "prm-regbits-44xx.h" +#include "prcm44xx.h" +#include "prminst44xx.h" +#include "powerdomain.h" + +/* Static data */ + +static const struct omap_prcm_irq omap4_prcm_irqs[] = { + OMAP_PRCM_IRQ("wkup", 0, 0), + OMAP_PRCM_IRQ("io", 9, 1), +}; + +static struct omap_prcm_irq_setup omap4_prcm_irq_setup = { + .ack = OMAP4_PRM_IRQSTATUS_MPU_OFFSET, + .mask = OMAP4_PRM_IRQENABLE_MPU_OFFSET, + .nr_regs = 2, + .irqs = omap4_prcm_irqs, + .nr_irqs = ARRAY_SIZE(omap4_prcm_irqs), + .irq = 11 + OMAP44XX_IRQ_GIC_START, + .read_pending_irqs = &omap44xx_prm_read_pending_irqs, + .ocp_barrier = &omap44xx_prm_ocp_barrier, + .save_and_clear_irqen = &omap44xx_prm_save_and_clear_irqen, + .restore_irqen = &omap44xx_prm_restore_irqen, + .reconfigure_io_chain = &omap44xx_prm_reconfigure_io_chain, +}; + +/* + * omap44xx_prm_reset_src_map - map from bits in the PRM_RSTST + * hardware register (which are specific to OMAP44xx SoCs) to reset + * source ID bit shifts (which is an OMAP SoC-independent + * enumeration) + */ +static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = { + { OMAP4430_GLOBAL_WARM_SW_RST_SHIFT, + OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT }, + { OMAP4430_GLOBAL_COLD_RST_SHIFT, + OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT }, + { OMAP4430_MPU_SECURITY_VIOL_RST_SHIFT, + OMAP_SECU_VIOL_RST_SRC_ID_SHIFT }, + { OMAP4430_MPU_WDT_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT }, + { OMAP4430_SECURE_WDT_RST_SHIFT, OMAP_SECU_WD_RST_SRC_ID_SHIFT }, + { OMAP4430_EXTERNAL_WARM_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT }, + { OMAP4430_VDD_MPU_VOLT_MGR_RST_SHIFT, + OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT }, + { OMAP4430_VDD_IVA_VOLT_MGR_RST_SHIFT, + OMAP_VDD_IVA_VM_RST_SRC_ID_SHIFT }, + { OMAP4430_VDD_CORE_VOLT_MGR_RST_SHIFT, + OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT }, + { OMAP4430_ICEPICK_RST_SHIFT, OMAP_ICEPICK_RST_SRC_ID_SHIFT }, + { OMAP4430_C2C_RST_SHIFT, OMAP_C2C_RST_SRC_ID_SHIFT }, + { -1, -1 }, +}; + +/* PRM low-level functions */ + +/* Read a register in a CM/PRM instance in the PRM module */ +u32 omap4_prm_read_inst_reg(s16 inst, u16 reg) +{ + return readl_relaxed(prm_base + inst + reg); +} + +/* Write into a register in a CM/PRM instance in the PRM module */ +void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg) +{ + writel_relaxed(val, prm_base + inst + reg); +} + +/* Read-modify-write a register in a PRM module. Caller must lock */ +u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg) +{ + u32 v; + + v = omap4_prm_read_inst_reg(inst, reg); + v &= ~mask; + v |= bits; + omap4_prm_write_inst_reg(v, inst, reg); + + return v; +} + +/* PRM VP */ + +/* + * struct omap4_vp - OMAP4 VP register access description. + * @irqstatus_mpu: offset to IRQSTATUS_MPU register for VP + * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg + */ +struct omap4_vp { + u32 irqstatus_mpu; + u32 tranxdone_status; +}; + +static struct omap4_vp omap4_vp[] = { + [OMAP4_VP_VDD_MPU_ID] = { + .irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET, + .tranxdone_status = OMAP4430_VP_MPU_TRANXDONE_ST_MASK, + }, + [OMAP4_VP_VDD_IVA_ID] = { + .irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_OFFSET, + .tranxdone_status = OMAP4430_VP_IVA_TRANXDONE_ST_MASK, + }, + [OMAP4_VP_VDD_CORE_ID] = { + .irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_OFFSET, + .tranxdone_status = OMAP4430_VP_CORE_TRANXDONE_ST_MASK, + }, +}; + +u32 omap4_prm_vp_check_txdone(u8 vp_id) +{ + struct omap4_vp *vp = &omap4_vp[vp_id]; + u32 irqstatus; + + irqstatus = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, + OMAP4430_PRM_OCP_SOCKET_INST, + vp->irqstatus_mpu); + return irqstatus & vp->tranxdone_status; +} + +void omap4_prm_vp_clear_txdone(u8 vp_id) +{ + struct omap4_vp *vp = &omap4_vp[vp_id]; + + omap4_prminst_write_inst_reg(vp->tranxdone_status, + OMAP4430_PRM_PARTITION, + OMAP4430_PRM_OCP_SOCKET_INST, + vp->irqstatus_mpu); +}; + +u32 omap4_prm_vcvp_read(u8 offset) +{ + return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, + OMAP4430_PRM_DEVICE_INST, offset); +} + +void omap4_prm_vcvp_write(u32 val, u8 offset) +{ + omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION, + OMAP4430_PRM_DEVICE_INST, offset); +} + +u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset) +{ + return omap4_prminst_rmw_inst_reg_bits(mask, bits, + OMAP4430_PRM_PARTITION, + OMAP4430_PRM_DEVICE_INST, + offset); +} + +static inline u32 _read_pending_irq_reg(u16 irqen_offs, u16 irqst_offs) +{ + u32 mask, st; + + /* XXX read mask from RAM? */ + mask = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, + irqen_offs); + st = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, irqst_offs); + + return mask & st; +} + +/** + * omap44xx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events + * @events: ptr to two consecutive u32s, preallocated by caller + * + * Read PRM_IRQSTATUS_MPU* bits, AND'ed with the currently-enabled PRM + * MPU IRQs, and store the result into the two u32s pointed to by @events. + * No return value. + */ +void omap44xx_prm_read_pending_irqs(unsigned long *events) +{ + events[0] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_OFFSET, + OMAP4_PRM_IRQSTATUS_MPU_OFFSET); + + events[1] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_2_OFFSET, + OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET); +} + +/** + * omap44xx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete + * + * Force any buffered writes to the PRM IP block to complete. Needed + * by the PRM IRQ handler, which reads and writes directly to the IP + * block, to avoid race conditions after acknowledging or clearing IRQ + * bits. No return value. + */ +void omap44xx_prm_ocp_barrier(void) +{ + omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, + OMAP4_REVISION_PRM_OFFSET); +} + +/** + * omap44xx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU* regs + * @saved_mask: ptr to a u32 array to save IRQENABLE bits + * + * Save the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers to + * @saved_mask. @saved_mask must be allocated by the caller. + * Intended to be used in the PRM interrupt handler suspend callback. + * The OCP barrier is needed to ensure the write to disable PRM + * interrupts reaches the PRM before returning; otherwise, spurious + * interrupts might occur. No return value. + */ +void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) +{ + saved_mask[0] = + omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, + OMAP4_PRM_IRQSTATUS_MPU_OFFSET); + saved_mask[1] = + omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, + OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET); + + omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST, + OMAP4_PRM_IRQENABLE_MPU_OFFSET); + omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST, + OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); + + /* OCP barrier */ + omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, + OMAP4_REVISION_PRM_OFFSET); +} + +/** + * omap44xx_prm_restore_irqen - set PRM_IRQENABLE_MPU* registers from args + * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously + * + * Restore the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers from + * @saved_mask. Intended to be used in the PRM interrupt handler resume + * callback to restore values saved by omap44xx_prm_save_and_clear_irqen(). + * No OCP barrier should be needed here; any pending PRM interrupts will fire + * once the writes reach the PRM. No return value. + */ +void omap44xx_prm_restore_irqen(u32 *saved_mask) +{ + omap4_prm_write_inst_reg(saved_mask[0], OMAP4430_PRM_OCP_SOCKET_INST, + OMAP4_PRM_IRQENABLE_MPU_OFFSET); + omap4_prm_write_inst_reg(saved_mask[1], OMAP4430_PRM_OCP_SOCKET_INST, + OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); +} + +/** + * omap44xx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain + * + * Clear any previously-latched I/O wakeup events and ensure that the + * I/O wakeup gates are aligned with the current mux settings. Works + * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then + * deasserting WUCLKIN and waiting for WUCLKOUT to be deasserted. + * No return value. XXX Are the final two steps necessary? + */ +void omap44xx_prm_reconfigure_io_chain(void) +{ + int i = 0; + + /* Trigger WUCLKIN enable */ + omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, + OMAP4430_WUCLK_CTRL_MASK, + OMAP4430_PRM_DEVICE_INST, + OMAP4_PRM_IO_PMCTRL_OFFSET); + omap_test_timeout( + (((omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, + OMAP4_PRM_IO_PMCTRL_OFFSET) & + OMAP4430_WUCLK_STATUS_MASK) >> + OMAP4430_WUCLK_STATUS_SHIFT) == 1), + MAX_IOPAD_LATCH_TIME, i); + if (i == MAX_IOPAD_LATCH_TIME) + pr_warn("PRM: I/O chain clock line assertion timed out\n"); + + /* Trigger WUCLKIN disable */ + omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, 0x0, + OMAP4430_PRM_DEVICE_INST, + OMAP4_PRM_IO_PMCTRL_OFFSET); + omap_test_timeout( + (((omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, + OMAP4_PRM_IO_PMCTRL_OFFSET) & + OMAP4430_WUCLK_STATUS_MASK) >> + OMAP4430_WUCLK_STATUS_SHIFT) == 0), + MAX_IOPAD_LATCH_TIME, i); + if (i == MAX_IOPAD_LATCH_TIME) + pr_warn("PRM: I/O chain clock line deassertion timed out\n"); + + return; +} + +/** + * omap44xx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches + * + * Activates the I/O wakeup event latches and allows events logged by + * those latches to signal a wakeup event to the PRCM. For I/O wakeups + * to occur, WAKEUPENABLE bits must be set in the pad mux registers, and + * omap44xx_prm_reconfigure_io_chain() must be called. No return value. + */ +static void __init omap44xx_prm_enable_io_wakeup(void) +{ + omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK, + OMAP4430_GLOBAL_WUEN_MASK, + OMAP4430_PRM_DEVICE_INST, + OMAP4_PRM_IO_PMCTRL_OFFSET); +} + +/** + * omap44xx_prm_read_reset_sources - return the last SoC reset source + * + * Return a u32 representing the last reset sources of the SoC. The + * returned reset source bits are standardized across OMAP SoCs. + */ +static u32 omap44xx_prm_read_reset_sources(void) +{ + struct prm_reset_src_map *p; + u32 r = 0; + u32 v; + + v = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, + OMAP4_RM_RSTST); + + p = omap44xx_prm_reset_src_map; + while (p->reg_shift >= 0 && p->std_shift >= 0) { + if (v & (1 << p->reg_shift)) + r |= 1 << p->std_shift; + p++; + } + + return r; +} + +/** + * omap44xx_prm_was_any_context_lost_old - was module hardware context lost? + * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION) + * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST) + * @idx: CONTEXT register offset + * + * Return 1 if any bits were set in the *_CONTEXT_* register + * identified by (@part, @inst, @idx), which means that some context + * was lost for that module; otherwise, return 0. + */ +static bool omap44xx_prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx) +{ + return (omap4_prminst_read_inst_reg(part, inst, idx)) ? 1 : 0; +} + +/** + * omap44xx_prm_clear_context_lost_flags_old - clear context loss flags + * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION) + * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST) + * @idx: CONTEXT register offset + * + * Clear hardware context loss bits for the module identified by + * (@part, @inst, @idx). No return value. XXX Writes to reserved bits; + * is there a way to avoid this? + */ +static void omap44xx_prm_clear_context_loss_flags_old(u8 part, s16 inst, + u16 idx) +{ + omap4_prminst_write_inst_reg(0xffffffff, part, inst, idx); +} + +/* Powerdomain low-level functions */ + +static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) +{ + omap4_prminst_rmw_inst_reg_bits(OMAP_POWERSTATE_MASK, + (pwrst << OMAP_POWERSTATE_SHIFT), + pwrdm->prcm_partition, + pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL); + return 0; +} + +static int omap4_pwrdm_read_next_pwrst(struct powerdomain *pwrdm) +{ + u32 v; + + v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, + OMAP4_PM_PWSTCTRL); + v &= OMAP_POWERSTATE_MASK; + v >>= OMAP_POWERSTATE_SHIFT; + + return v; +} + +static int omap4_pwrdm_read_pwrst(struct powerdomain *pwrdm) +{ + u32 v; + + v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, + OMAP4_PM_PWSTST); + v &= OMAP_POWERSTATEST_MASK; + v >>= OMAP_POWERSTATEST_SHIFT; + + return v; +} + +static int omap4_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) +{ + u32 v; + + v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, + OMAP4_PM_PWSTST); + v &= OMAP4430_LASTPOWERSTATEENTERED_MASK; + v >>= OMAP4430_LASTPOWERSTATEENTERED_SHIFT; + + return v; +} + +static int omap4_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm) +{ + omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK, + (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT), + pwrdm->prcm_partition, + pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL); + return 0; +} + +static int omap4_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) +{ + omap4_prminst_rmw_inst_reg_bits(OMAP4430_LASTPOWERSTATEENTERED_MASK, + OMAP4430_LASTPOWERSTATEENTERED_MASK, + pwrdm->prcm_partition, + pwrdm->prcm_offs, OMAP4_PM_PWSTST); + return 0; +} + +static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst) +{ + u32 v; + + v = pwrst << __ffs(OMAP4430_LOGICRETSTATE_MASK); + omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOGICRETSTATE_MASK, v, + pwrdm->prcm_partition, pwrdm->prcm_offs, + OMAP4_PM_PWSTCTRL); + + return 0; +} + +static int omap4_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, + u8 pwrst) +{ + u32 m; + + m = omap2_pwrdm_get_mem_bank_onstate_mask(bank); + + omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)), + pwrdm->prcm_partition, pwrdm->prcm_offs, + OMAP4_PM_PWSTCTRL); + + return 0; +} + +static int omap4_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, + u8 pwrst) +{ + u32 m; + + m = omap2_pwrdm_get_mem_bank_retst_mask(bank); + + omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)), + pwrdm->prcm_partition, pwrdm->prcm_offs, + OMAP4_PM_PWSTCTRL); + + return 0; +} + +static int omap4_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) +{ + u32 v; + + v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, + OMAP4_PM_PWSTST); + v &= OMAP4430_LOGICSTATEST_MASK; + v >>= OMAP4430_LOGICSTATEST_SHIFT; + + return v; +} + +static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm) +{ + u32 v; + + v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, + OMAP4_PM_PWSTCTRL); + v &= OMAP4430_LOGICRETSTATE_MASK; + v >>= OMAP4430_LOGICRETSTATE_SHIFT; + + return v; +} + +/** + * omap4_pwrdm_read_prev_logic_pwrst - read the previous logic powerstate + * @pwrdm: struct powerdomain * to read the state for + * + * Reads the previous logic powerstate for a powerdomain. This + * function must determine the previous logic powerstate by first + * checking the previous powerstate for the domain. If that was OFF, + * then logic has been lost. If previous state was RETENTION, the + * function reads the setting for the next retention logic state to + * see the actual value. In every other case, the logic is + * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET + * depending whether the logic was retained or not. + */ +static int omap4_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm) +{ + int state; + + state = omap4_pwrdm_read_prev_pwrst(pwrdm); + + if (state == PWRDM_POWER_OFF) + return PWRDM_POWER_OFF; + + if (state != PWRDM_POWER_RET) + return PWRDM_POWER_RET; + + return omap4_pwrdm_read_logic_retst(pwrdm); +} + +static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank) +{ + u32 m, v; + + m = omap2_pwrdm_get_mem_bank_stst_mask(bank); + + v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, + OMAP4_PM_PWSTST); + v &= m; + v >>= __ffs(m); + + return v; +} + +static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) +{ + u32 m, v; + + m = omap2_pwrdm_get_mem_bank_retst_mask(bank); + + v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, + OMAP4_PM_PWSTCTRL); + v &= m; + v >>= __ffs(m); + + return v; +} + +/** + * omap4_pwrdm_read_prev_mem_pwrst - reads the previous memory powerstate + * @pwrdm: struct powerdomain * to read mem powerstate for + * @bank: memory bank index + * + * Reads the previous memory powerstate for a powerdomain. This + * function must determine the previous memory powerstate by first + * checking the previous powerstate for the domain. If that was OFF, + * then logic has been lost. If previous state was RETENTION, the + * function reads the setting for the next memory retention state to + * see the actual value. In every other case, the logic is + * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET + * depending whether logic was retained or not. + */ +static int omap4_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank) +{ + int state; + + state = omap4_pwrdm_read_prev_pwrst(pwrdm); + + if (state == PWRDM_POWER_OFF) + return PWRDM_POWER_OFF; + + if (state != PWRDM_POWER_RET) + return PWRDM_POWER_RET; + + return omap4_pwrdm_read_mem_retst(pwrdm, bank); +} + +static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm) +{ + u32 c = 0; + + /* + * REVISIT: pwrdm_wait_transition() may be better implemented + * via a callback and a periodic timer check -- how long do we expect + * powerdomain transitions to take? + */ + + /* XXX Is this udelay() value meaningful? */ + while ((omap4_prminst_read_inst_reg(pwrdm->prcm_partition, + pwrdm->prcm_offs, + OMAP4_PM_PWSTST) & + OMAP_INTRANSITION_MASK) && + (c++ < PWRDM_TRANSITION_BAILOUT)) + udelay(1); + + if (c > PWRDM_TRANSITION_BAILOUT) { + pr_err("powerdomain: %s: waited too long to complete transition\n", + pwrdm->name); + return -EAGAIN; + } + + pr_debug("powerdomain: completed transition in %d loops\n", c); + + return 0; +} + +static int omap4_check_vcvp(void) +{ + /* No VC/VP on dra7xx devices */ + if (soc_is_dra7xx()) + return 0; + + return 1; +} + +struct pwrdm_ops omap4_pwrdm_operations = { + .pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst, + .pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst, + .pwrdm_read_pwrst = omap4_pwrdm_read_pwrst, + .pwrdm_read_prev_pwrst = omap4_pwrdm_read_prev_pwrst, + .pwrdm_set_lowpwrstchange = omap4_pwrdm_set_lowpwrstchange, + .pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst, + .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst, + .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst, + .pwrdm_read_prev_logic_pwrst = omap4_pwrdm_read_prev_logic_pwrst, + .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst, + .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst, + .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst, + .pwrdm_read_prev_mem_pwrst = omap4_pwrdm_read_prev_mem_pwrst, + .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst, + .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst, + .pwrdm_wait_transition = omap4_pwrdm_wait_transition, + .pwrdm_has_voltdm = omap4_check_vcvp, +}; + +static int omap44xx_prm_late_init(void); + +/* + * XXX document + */ +static struct prm_ll_data omap44xx_prm_ll_data = { + .read_reset_sources = &omap44xx_prm_read_reset_sources, + .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old, + .clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old, + .late_init = &omap44xx_prm_late_init, +}; + +int __init omap44xx_prm_init(void) +{ + if (cpu_is_omap44xx()) + prm_features |= PRM_HAS_IO_WAKEUP; + + return prm_register(&omap44xx_prm_ll_data); +} + +static int omap44xx_prm_late_init(void) +{ + if (!(prm_features & PRM_HAS_IO_WAKEUP)) + return 0; + + omap44xx_prm_enable_io_wakeup(); + + return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup); +} + +static void __exit omap44xx_prm_exit(void) +{ + prm_unregister(&omap44xx_prm_ll_data); +} +__exitcall(omap44xx_prm_exit); diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h new file mode 100644 index 00000000000..7db2422faa1 --- /dev/null +++ b/arch/arm/mach-omap2/prm44xx.h @@ -0,0 +1,748 @@ +/* + * OMAP44xx PRM instance offset macros + * + * Copyright (C) 2009-2011 Texas Instruments, Inc. + * Copyright (C) 2009-2010 Nokia Corporation + * + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * XXX This file needs to be updated to align on one of "OMAP4", "OMAP44XX", + * or "OMAP4430". + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_PRM44XX_H +#define __ARCH_ARM_MACH_OMAP2_PRM44XX_H + +#include "prm44xx_54xx.h" +#include "prcm-common.h" +#include "prm.h" + +#define OMAP4430_PRM_BASE 0x4a306000 + +#define OMAP44XX_PRM_REGADDR(inst, reg) \ + OMAP2_L4_IO_ADDRESS(OMAP4430_PRM_BASE + (inst) + (reg)) + + +/* PRM instances */ +#define OMAP4430_PRM_OCP_SOCKET_INST 0x0000 +#define OMAP4430_PRM_CKGEN_INST 0x0100 +#define OMAP4430_PRM_MPU_INST 0x0300 +#define OMAP4430_PRM_TESLA_INST 0x0400 +#define OMAP4430_PRM_ABE_INST 0x0500 +#define OMAP4430_PRM_ALWAYS_ON_INST 0x0600 +#define OMAP4430_PRM_CORE_INST 0x0700 +#define OMAP4430_PRM_IVAHD_INST 0x0f00 +#define OMAP4430_PRM_CAM_INST 0x1000 +#define OMAP4430_PRM_DSS_INST 0x1100 +#define OMAP4430_PRM_GFX_INST 0x1200 +#define OMAP4430_PRM_L3INIT_INST 0x1300 +#define OMAP4430_PRM_L4PER_INST 0x1400 +#define OMAP4430_PRM_CEFUSE_INST 0x1600 +#define OMAP4430_PRM_WKUP_INST 0x1700 +#define OMAP4430_PRM_WKUP_CM_INST 0x1800 +#define OMAP4430_PRM_EMU_INST 0x1900 +#define OMAP4430_PRM_EMU_CM_INST 0x1a00 +#define OMAP4430_PRM_DEVICE_INST 0x1b00 +#define OMAP4430_PRM_INSTR_INST 0x1f00 + +/* PRM clockdomain register offsets (from instance start) */ +#define OMAP4430_PRM_WKUP_CM_WKUP_CDOFFS 0x0000 +#define OMAP4430_PRM_EMU_CM_EMU_CDOFFS 0x0000 + +/* OMAP4 specific register offsets */ +#define OMAP4_RM_RSTCTRL 0x0000 +#define OMAP4_RM_RSTST 0x0004 +#define OMAP4_RM_RSTTIME 0x0008 +#define OMAP4_PM_PWSTCTRL 0x0000 +#define OMAP4_PM_PWSTST 0x0004 + + +/* PRM */ + +/* PRM.OCP_SOCKET_PRM register offsets */ +#define OMAP4_REVISION_PRM_OFFSET 0x0000 +#define OMAP4430_REVISION_PRM OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0000) +#define OMAP4_PRM_IRQSTATUS_MPU_OFFSET 0x0010 +#define OMAP4430_PRM_IRQSTATUS_MPU OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0010) +#define OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET 0x0014 +#define OMAP4430_PRM_IRQSTATUS_MPU_2 OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0014) +#define OMAP4_PRM_IRQENABLE_MPU_OFFSET 0x0018 +#define OMAP4430_PRM_IRQENABLE_MPU OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0018) +#define OMAP4_PRM_IRQENABLE_MPU_2_OFFSET 0x001c +#define OMAP4430_PRM_IRQENABLE_MPU_2 OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x001c) +#define OMAP4_PRM_IRQSTATUS_DUCATI_OFFSET 0x0020 +#define OMAP4430_PRM_IRQSTATUS_DUCATI OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0020) +#define OMAP4_PRM_IRQENABLE_DUCATI_OFFSET 0x0028 +#define OMAP4430_PRM_IRQENABLE_DUCATI OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0028) +#define OMAP4_PRM_IRQSTATUS_TESLA_OFFSET 0x0030 +#define OMAP4430_PRM_IRQSTATUS_TESLA OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0030) +#define OMAP4_PRM_IRQENABLE_TESLA_OFFSET 0x0038 +#define OMAP4430_PRM_IRQENABLE_TESLA OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0038) +#define OMAP4_CM_PRM_PROFILING_CLKCTRL_OFFSET 0x0040 +#define OMAP4430_CM_PRM_PROFILING_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0040) + +/* PRM.CKGEN_PRM register offsets */ +#define OMAP4_CM_ABE_DSS_SYS_CLKSEL_OFFSET 0x0000 +#define OMAP4430_CM_ABE_DSS_SYS_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_INST, 0x0000) +#define OMAP4_CM_L4_WKUP_CLKSEL_OFFSET 0x0008 +#define OMAP4430_CM_L4_WKUP_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_INST, 0x0008) +#define OMAP4_CM_ABE_PLL_REF_CLKSEL_OFFSET 0x000c +#define OMAP4430_CM_ABE_PLL_REF_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_INST, 0x000c) +#define OMAP4_CM_SYS_CLKSEL_OFFSET 0x0010 +#define OMAP4430_CM_SYS_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_INST, 0x0010) + +/* PRM.MPU_PRM register offsets */ +#define OMAP4_PM_MPU_PWRSTCTRL_OFFSET 0x0000 +#define OMAP4430_PM_MPU_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_INST, 0x0000) +#define OMAP4_PM_MPU_PWRSTST_OFFSET 0x0004 +#define OMAP4430_PM_MPU_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_INST, 0x0004) +#define OMAP4_RM_MPU_RSTST_OFFSET 0x0014 +#define OMAP4430_RM_MPU_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_INST, 0x0014) +#define OMAP4_RM_MPU_MPU_CONTEXT_OFFSET 0x0024 +#define OMAP4430_RM_MPU_MPU_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_INST, 0x0024) + +/* PRM.TESLA_PRM register offsets */ +#define OMAP4_PM_TESLA_PWRSTCTRL_OFFSET 0x0000 +#define OMAP4430_PM_TESLA_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_INST, 0x0000) +#define OMAP4_PM_TESLA_PWRSTST_OFFSET 0x0004 +#define OMAP4430_PM_TESLA_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_INST, 0x0004) +#define OMAP4_RM_TESLA_RSTCTRL_OFFSET 0x0010 +#define OMAP4430_RM_TESLA_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_INST, 0x0010) +#define OMAP4_RM_TESLA_RSTST_OFFSET 0x0014 +#define OMAP4430_RM_TESLA_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_INST, 0x0014) +#define OMAP4_RM_TESLA_TESLA_CONTEXT_OFFSET 0x0024 +#define OMAP4430_RM_TESLA_TESLA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_INST, 0x0024) + +/* PRM.ABE_PRM register offsets */ +#define OMAP4_PM_ABE_PWRSTCTRL_OFFSET 0x0000 +#define OMAP4430_PM_ABE_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0000) +#define OMAP4_PM_ABE_PWRSTST_OFFSET 0x0004 +#define OMAP4430_PM_ABE_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0004) +#define OMAP4_RM_ABE_AESS_CONTEXT_OFFSET 0x002c +#define OMAP4430_RM_ABE_AESS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x002c) +#define OMAP4_PM_ABE_PDM_WKDEP_OFFSET 0x0030 +#define OMAP4430_PM_ABE_PDM_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0030) +#define OMAP4_RM_ABE_PDM_CONTEXT_OFFSET 0x0034 +#define OMAP4430_RM_ABE_PDM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0034) +#define OMAP4_PM_ABE_DMIC_WKDEP_OFFSET 0x0038 +#define OMAP4430_PM_ABE_DMIC_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0038) +#define OMAP4_RM_ABE_DMIC_CONTEXT_OFFSET 0x003c +#define OMAP4430_RM_ABE_DMIC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x003c) +#define OMAP4_PM_ABE_MCASP_WKDEP_OFFSET 0x0040 +#define OMAP4430_PM_ABE_MCASP_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0040) +#define OMAP4_RM_ABE_MCASP_CONTEXT_OFFSET 0x0044 +#define OMAP4430_RM_ABE_MCASP_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0044) +#define OMAP4_PM_ABE_MCBSP1_WKDEP_OFFSET 0x0048 +#define OMAP4430_PM_ABE_MCBSP1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0048) +#define OMAP4_RM_ABE_MCBSP1_CONTEXT_OFFSET 0x004c +#define OMAP4430_RM_ABE_MCBSP1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x004c) +#define OMAP4_PM_ABE_MCBSP2_WKDEP_OFFSET 0x0050 +#define OMAP4430_PM_ABE_MCBSP2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0050) +#define OMAP4_RM_ABE_MCBSP2_CONTEXT_OFFSET 0x0054 +#define OMAP4430_RM_ABE_MCBSP2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0054) +#define OMAP4_PM_ABE_MCBSP3_WKDEP_OFFSET 0x0058 +#define OMAP4430_PM_ABE_MCBSP3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0058) +#define OMAP4_RM_ABE_MCBSP3_CONTEXT_OFFSET 0x005c +#define OMAP4430_RM_ABE_MCBSP3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x005c) +#define OMAP4_PM_ABE_SLIMBUS_WKDEP_OFFSET 0x0060 +#define OMAP4430_PM_ABE_SLIMBUS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0060) +#define OMAP4_RM_ABE_SLIMBUS_CONTEXT_OFFSET 0x0064 +#define OMAP4430_RM_ABE_SLIMBUS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0064) +#define OMAP4_PM_ABE_TIMER5_WKDEP_OFFSET 0x0068 +#define OMAP4430_PM_ABE_TIMER5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0068) +#define OMAP4_RM_ABE_TIMER5_CONTEXT_OFFSET 0x006c +#define OMAP4430_RM_ABE_TIMER5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x006c) +#define OMAP4_PM_ABE_TIMER6_WKDEP_OFFSET 0x0070 +#define OMAP4430_PM_ABE_TIMER6_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0070) +#define OMAP4_RM_ABE_TIMER6_CONTEXT_OFFSET 0x0074 +#define OMAP4430_RM_ABE_TIMER6_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0074) +#define OMAP4_PM_ABE_TIMER7_WKDEP_OFFSET 0x0078 +#define OMAP4430_PM_ABE_TIMER7_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0078) +#define OMAP4_RM_ABE_TIMER7_CONTEXT_OFFSET 0x007c +#define OMAP4430_RM_ABE_TIMER7_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x007c) +#define OMAP4_PM_ABE_TIMER8_WKDEP_OFFSET 0x0080 +#define OMAP4430_PM_ABE_TIMER8_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0080) +#define OMAP4_RM_ABE_TIMER8_CONTEXT_OFFSET 0x0084 +#define OMAP4430_RM_ABE_TIMER8_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0084) +#define OMAP4_PM_ABE_WDT3_WKDEP_OFFSET 0x0088 +#define OMAP4430_PM_ABE_WDT3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0088) +#define OMAP4_RM_ABE_WDT3_CONTEXT_OFFSET 0x008c +#define OMAP4430_RM_ABE_WDT3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x008c) + +/* PRM.ALWAYS_ON_PRM register offsets */ +#define OMAP4_RM_ALWON_MDMINTC_CONTEXT_OFFSET 0x0024 +#define OMAP4430_RM_ALWON_MDMINTC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x0024) +#define OMAP4_PM_ALWON_SR_MPU_WKDEP_OFFSET 0x0028 +#define OMAP4430_PM_ALWON_SR_MPU_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x0028) +#define OMAP4_RM_ALWON_SR_MPU_CONTEXT_OFFSET 0x002c +#define OMAP4430_RM_ALWON_SR_MPU_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x002c) +#define OMAP4_PM_ALWON_SR_IVA_WKDEP_OFFSET 0x0030 +#define OMAP4430_PM_ALWON_SR_IVA_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x0030) +#define OMAP4_RM_ALWON_SR_IVA_CONTEXT_OFFSET 0x0034 +#define OMAP4430_RM_ALWON_SR_IVA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x0034) +#define OMAP4_PM_ALWON_SR_CORE_WKDEP_OFFSET 0x0038 +#define OMAP4430_PM_ALWON_SR_CORE_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x0038) +#define OMAP4_RM_ALWON_SR_CORE_CONTEXT_OFFSET 0x003c +#define OMAP4430_RM_ALWON_SR_CORE_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x003c) + +/* PRM.CORE_PRM register offsets */ +#define OMAP4_PM_CORE_PWRSTCTRL_OFFSET 0x0000 +#define OMAP4430_PM_CORE_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0000) +#define OMAP4_PM_CORE_PWRSTST_OFFSET 0x0004 +#define OMAP4430_PM_CORE_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0004) +#define OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET 0x0024 +#define OMAP4430_RM_L3_1_L3_1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0024) +#define OMAP4_RM_L3_2_L3_2_CONTEXT_OFFSET 0x0124 +#define OMAP4430_RM_L3_2_L3_2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0124) +#define OMAP4_RM_L3_2_GPMC_CONTEXT_OFFSET 0x012c +#define OMAP4430_RM_L3_2_GPMC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x012c) +#define OMAP4_RM_L3_2_OCMC_RAM_CONTEXT_OFFSET 0x0134 +#define OMAP4430_RM_L3_2_OCMC_RAM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0134) +#define OMAP4_RM_DUCATI_RSTCTRL_OFFSET 0x0210 +#define OMAP4430_RM_DUCATI_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0210) +#define OMAP4_RM_DUCATI_RSTST_OFFSET 0x0214 +#define OMAP4430_RM_DUCATI_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0214) +#define OMAP4_RM_DUCATI_DUCATI_CONTEXT_OFFSET 0x0224 +#define OMAP4430_RM_DUCATI_DUCATI_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0224) +#define OMAP4_RM_SDMA_SDMA_CONTEXT_OFFSET 0x0324 +#define OMAP4430_RM_SDMA_SDMA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0324) +#define OMAP4_RM_MEMIF_DMM_CONTEXT_OFFSET 0x0424 +#define OMAP4430_RM_MEMIF_DMM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0424) +#define OMAP4_RM_MEMIF_EMIF_FW_CONTEXT_OFFSET 0x042c +#define OMAP4430_RM_MEMIF_EMIF_FW_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x042c) +#define OMAP4_RM_MEMIF_EMIF_1_CONTEXT_OFFSET 0x0434 +#define OMAP4430_RM_MEMIF_EMIF_1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0434) +#define OMAP4_RM_MEMIF_EMIF_2_CONTEXT_OFFSET 0x043c +#define OMAP4430_RM_MEMIF_EMIF_2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x043c) +#define OMAP4_RM_MEMIF_DLL_CONTEXT_OFFSET 0x0444 +#define OMAP4430_RM_MEMIF_DLL_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0444) +#define OMAP4_RM_MEMIF_EMIF_H1_CONTEXT_OFFSET 0x0454 +#define OMAP4430_RM_MEMIF_EMIF_H1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0454) +#define OMAP4_RM_MEMIF_EMIF_H2_CONTEXT_OFFSET 0x045c +#define OMAP4430_RM_MEMIF_EMIF_H2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x045c) +#define OMAP4_RM_MEMIF_DLL_H_CONTEXT_OFFSET 0x0464 +#define OMAP4430_RM_MEMIF_DLL_H_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0464) +#define OMAP4_RM_D2D_SAD2D_CONTEXT_OFFSET 0x0524 +#define OMAP4430_RM_D2D_SAD2D_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0524) +#define OMAP4_RM_D2D_MODEM_ICR_CONTEXT_OFFSET 0x052c +#define OMAP4430_RM_D2D_MODEM_ICR_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x052c) +#define OMAP4_RM_D2D_SAD2D_FW_CONTEXT_OFFSET 0x0534 +#define OMAP4430_RM_D2D_SAD2D_FW_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0534) +#define OMAP4_RM_L4CFG_L4_CFG_CONTEXT_OFFSET 0x0624 +#define OMAP4430_RM_L4CFG_L4_CFG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0624) +#define OMAP4_RM_L4CFG_HW_SEM_CONTEXT_OFFSET 0x062c +#define OMAP4430_RM_L4CFG_HW_SEM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x062c) +#define OMAP4_RM_L4CFG_MAILBOX_CONTEXT_OFFSET 0x0634 +#define OMAP4430_RM_L4CFG_MAILBOX_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0634) +#define OMAP4_RM_L4CFG_SAR_ROM_CONTEXT_OFFSET 0x063c +#define OMAP4430_RM_L4CFG_SAR_ROM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x063c) +#define OMAP4_RM_L3INSTR_L3_3_CONTEXT_OFFSET 0x0724 +#define OMAP4430_RM_L3INSTR_L3_3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0724) +#define OMAP4_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET 0x072c +#define OMAP4430_RM_L3INSTR_L3_INSTR_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x072c) +#define OMAP4_RM_L3INSTR_OCP_WP1_CONTEXT_OFFSET 0x0744 +#define OMAP4430_RM_L3INSTR_OCP_WP1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0744) + +/* PRM.IVAHD_PRM register offsets */ +#define OMAP4_PM_IVAHD_PWRSTCTRL_OFFSET 0x0000 +#define OMAP4430_PM_IVAHD_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_INST, 0x0000) +#define OMAP4_PM_IVAHD_PWRSTST_OFFSET 0x0004 +#define OMAP4430_PM_IVAHD_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_INST, 0x0004) +#define OMAP4_RM_IVAHD_RSTCTRL_OFFSET 0x0010 +#define OMAP4430_RM_IVAHD_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_INST, 0x0010) +#define OMAP4_RM_IVAHD_RSTST_OFFSET 0x0014 +#define OMAP4430_RM_IVAHD_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_INST, 0x0014) +#define OMAP4_RM_IVAHD_IVAHD_CONTEXT_OFFSET 0x0024 +#define OMAP4430_RM_IVAHD_IVAHD_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_INST, 0x0024) +#define OMAP4_RM_IVAHD_SL2_CONTEXT_OFFSET 0x002c +#define OMAP4430_RM_IVAHD_SL2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_INST, 0x002c) + +/* PRM.CAM_PRM register offsets */ +#define OMAP4_PM_CAM_PWRSTCTRL_OFFSET 0x0000 +#define OMAP4430_PM_CAM_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_INST, 0x0000) +#define OMAP4_PM_CAM_PWRSTST_OFFSET 0x0004 +#define OMAP4430_PM_CAM_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_INST, 0x0004) +#define OMAP4_RM_CAM_ISS_CONTEXT_OFFSET 0x0024 +#define OMAP4430_RM_CAM_ISS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_INST, 0x0024) +#define OMAP4_RM_CAM_FDIF_CONTEXT_OFFSET 0x002c +#define OMAP4430_RM_CAM_FDIF_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_INST, 0x002c) + +/* PRM.DSS_PRM register offsets */ +#define OMAP4_PM_DSS_PWRSTCTRL_OFFSET 0x0000 +#define OMAP4430_PM_DSS_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_INST, 0x0000) +#define OMAP4_PM_DSS_PWRSTST_OFFSET 0x0004 +#define OMAP4430_PM_DSS_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_INST, 0x0004) +#define OMAP4_PM_DSS_DSS_WKDEP_OFFSET 0x0020 +#define OMAP4430_PM_DSS_DSS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_INST, 0x0020) +#define OMAP4_RM_DSS_DSS_CONTEXT_OFFSET 0x0024 +#define OMAP4430_RM_DSS_DSS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_INST, 0x0024) +#define OMAP4_RM_DSS_DEISS_CONTEXT_OFFSET 0x002c +#define OMAP4430_RM_DSS_DEISS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_INST, 0x002c) + +/* PRM.GFX_PRM register offsets */ +#define OMAP4_PM_GFX_PWRSTCTRL_OFFSET 0x0000 +#define OMAP4430_PM_GFX_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_GFX_INST, 0x0000) +#define OMAP4_PM_GFX_PWRSTST_OFFSET 0x0004 +#define OMAP4430_PM_GFX_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_GFX_INST, 0x0004) +#define OMAP4_RM_GFX_GFX_CONTEXT_OFFSET 0x0024 +#define OMAP4430_RM_GFX_GFX_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_GFX_INST, 0x0024) + +/* PRM.L3INIT_PRM register offsets */ +#define OMAP4_PM_L3INIT_PWRSTCTRL_OFFSET 0x0000 +#define OMAP4430_PM_L3INIT_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0000) +#define OMAP4_PM_L3INIT_PWRSTST_OFFSET 0x0004 +#define OMAP4430_PM_L3INIT_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0004) +#define OMAP4_PM_L3INIT_MMC1_WKDEP_OFFSET 0x0028 +#define OMAP4430_PM_L3INIT_MMC1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0028) +#define OMAP4_RM_L3INIT_MMC1_CONTEXT_OFFSET 0x002c +#define OMAP4430_RM_L3INIT_MMC1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x002c) +#define OMAP4_PM_L3INIT_MMC2_WKDEP_OFFSET 0x0030 +#define OMAP4430_PM_L3INIT_MMC2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0030) +#define OMAP4_RM_L3INIT_MMC2_CONTEXT_OFFSET 0x0034 +#define OMAP4430_RM_L3INIT_MMC2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0034) +#define OMAP4_PM_L3INIT_HSI_WKDEP_OFFSET 0x0038 +#define OMAP4430_PM_L3INIT_HSI_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0038) +#define OMAP4_RM_L3INIT_HSI_CONTEXT_OFFSET 0x003c +#define OMAP4430_RM_L3INIT_HSI_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x003c) +#define OMAP4_PM_L3INIT_UNIPRO1_WKDEP_OFFSET 0x0040 +#define OMAP4430_PM_L3INIT_UNIPRO1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0040) +#define OMAP4_RM_L3INIT_UNIPRO1_CONTEXT_OFFSET 0x0044 +#define OMAP4430_RM_L3INIT_UNIPRO1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0044) +#define OMAP4_PM_L3INIT_USB_HOST_WKDEP_OFFSET 0x0058 +#define OMAP4430_PM_L3INIT_USB_HOST_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0058) +#define OMAP4_RM_L3INIT_USB_HOST_CONTEXT_OFFSET 0x005c +#define OMAP4430_RM_L3INIT_USB_HOST_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x005c) +#define OMAP4_PM_L3INIT_USB_OTG_WKDEP_OFFSET 0x0060 +#define OMAP4430_PM_L3INIT_USB_OTG_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0060) +#define OMAP4_RM_L3INIT_USB_OTG_CONTEXT_OFFSET 0x0064 +#define OMAP4430_RM_L3INIT_USB_OTG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0064) +#define OMAP4_PM_L3INIT_USB_TLL_WKDEP_OFFSET 0x0068 +#define OMAP4430_PM_L3INIT_USB_TLL_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0068) +#define OMAP4_RM_L3INIT_USB_TLL_CONTEXT_OFFSET 0x006c +#define OMAP4430_RM_L3INIT_USB_TLL_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x006c) +#define OMAP4_RM_L3INIT_P1500_CONTEXT_OFFSET 0x007c +#define OMAP4430_RM_L3INIT_P1500_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x007c) +#define OMAP4_RM_L3INIT_EMAC_CONTEXT_OFFSET 0x0084 +#define OMAP4430_RM_L3INIT_EMAC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0084) +#define OMAP4_PM_L3INIT_SATA_WKDEP_OFFSET 0x0088 +#define OMAP4430_PM_L3INIT_SATA_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0088) +#define OMAP4_RM_L3INIT_SATA_CONTEXT_OFFSET 0x008c +#define OMAP4430_RM_L3INIT_SATA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x008c) +#define OMAP4_RM_L3INIT_TPPSS_CONTEXT_OFFSET 0x0094 +#define OMAP4430_RM_L3INIT_TPPSS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0094) +#define OMAP4_PM_L3INIT_PCIESS_WKDEP_OFFSET 0x0098 +#define OMAP4430_PM_L3INIT_PCIESS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0098) +#define OMAP4_RM_L3INIT_PCIESS_CONTEXT_OFFSET 0x009c +#define OMAP4430_RM_L3INIT_PCIESS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x009c) +#define OMAP4_RM_L3INIT_CCPTX_CONTEXT_OFFSET 0x00ac +#define OMAP4430_RM_L3INIT_CCPTX_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00ac) +#define OMAP4_PM_L3INIT_XHPI_WKDEP_OFFSET 0x00c0 +#define OMAP4430_PM_L3INIT_XHPI_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00c0) +#define OMAP4_RM_L3INIT_XHPI_CONTEXT_OFFSET 0x00c4 +#define OMAP4430_RM_L3INIT_XHPI_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00c4) +#define OMAP4_PM_L3INIT_MMC6_WKDEP_OFFSET 0x00c8 +#define OMAP4430_PM_L3INIT_MMC6_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00c8) +#define OMAP4_RM_L3INIT_MMC6_CONTEXT_OFFSET 0x00cc +#define OMAP4430_RM_L3INIT_MMC6_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00cc) +#define OMAP4_PM_L3INIT_USB_HOST_FS_WKDEP_OFFSET 0x00d0 +#define OMAP4430_PM_L3INIT_USB_HOST_FS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00d0) +#define OMAP4_RM_L3INIT_USB_HOST_FS_CONTEXT_OFFSET 0x00d4 +#define OMAP4430_RM_L3INIT_USB_HOST_FS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00d4) +#define OMAP4_RM_L3INIT_USBPHYOCP2SCP_CONTEXT_OFFSET 0x00e4 +#define OMAP4430_RM_L3INIT_USBPHYOCP2SCP_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00e4) + +/* PRM.L4PER_PRM register offsets */ +#define OMAP4_PM_L4PER_PWRSTCTRL_OFFSET 0x0000 +#define OMAP4430_PM_L4PER_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0000) +#define OMAP4_PM_L4PER_PWRSTST_OFFSET 0x0004 +#define OMAP4430_PM_L4PER_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0004) +#define OMAP4_RM_L4PER_ADC_CONTEXT_OFFSET 0x0024 +#define OMAP4430_RM_L4PER_ADC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0024) +#define OMAP4_PM_L4PER_DMTIMER10_WKDEP_OFFSET 0x0028 +#define OMAP4430_PM_L4PER_DMTIMER10_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0028) +#define OMAP4_RM_L4PER_DMTIMER10_CONTEXT_OFFSET 0x002c +#define OMAP4430_RM_L4PER_DMTIMER10_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x002c) +#define OMAP4_PM_L4PER_DMTIMER11_WKDEP_OFFSET 0x0030 +#define OMAP4430_PM_L4PER_DMTIMER11_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0030) +#define OMAP4_RM_L4PER_DMTIMER11_CONTEXT_OFFSET 0x0034 +#define OMAP4430_RM_L4PER_DMTIMER11_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0034) +#define OMAP4_PM_L4PER_DMTIMER2_WKDEP_OFFSET 0x0038 +#define OMAP4430_PM_L4PER_DMTIMER2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0038) +#define OMAP4_RM_L4PER_DMTIMER2_CONTEXT_OFFSET 0x003c +#define OMAP4430_RM_L4PER_DMTIMER2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x003c) +#define OMAP4_PM_L4PER_DMTIMER3_WKDEP_OFFSET 0x0040 +#define OMAP4430_PM_L4PER_DMTIMER3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0040) +#define OMAP4_RM_L4PER_DMTIMER3_CONTEXT_OFFSET 0x0044 +#define OMAP4430_RM_L4PER_DMTIMER3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0044) +#define OMAP4_PM_L4PER_DMTIMER4_WKDEP_OFFSET 0x0048 +#define OMAP4430_PM_L4PER_DMTIMER4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0048) +#define OMAP4_RM_L4PER_DMTIMER4_CONTEXT_OFFSET 0x004c +#define OMAP4430_RM_L4PER_DMTIMER4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x004c) +#define OMAP4_PM_L4PER_DMTIMER9_WKDEP_OFFSET 0x0050 +#define OMAP4430_PM_L4PER_DMTIMER9_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0050) +#define OMAP4_RM_L4PER_DMTIMER9_CONTEXT_OFFSET 0x0054 +#define OMAP4430_RM_L4PER_DMTIMER9_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0054) +#define OMAP4_RM_L4PER_ELM_CONTEXT_OFFSET 0x005c +#define OMAP4430_RM_L4PER_ELM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x005c) +#define OMAP4_PM_L4PER_GPIO2_WKDEP_OFFSET 0x0060 +#define OMAP4430_PM_L4PER_GPIO2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0060) +#define OMAP4_RM_L4PER_GPIO2_CONTEXT_OFFSET 0x0064 +#define OMAP4430_RM_L4PER_GPIO2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0064) +#define OMAP4_PM_L4PER_GPIO3_WKDEP_OFFSET 0x0068 +#define OMAP4430_PM_L4PER_GPIO3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0068) +#define OMAP4_RM_L4PER_GPIO3_CONTEXT_OFFSET 0x006c +#define OMAP4430_RM_L4PER_GPIO3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x006c) +#define OMAP4_PM_L4PER_GPIO4_WKDEP_OFFSET 0x0070 +#define OMAP4430_PM_L4PER_GPIO4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0070) +#define OMAP4_RM_L4PER_GPIO4_CONTEXT_OFFSET 0x0074 +#define OMAP4430_RM_L4PER_GPIO4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0074) +#define OMAP4_PM_L4PER_GPIO5_WKDEP_OFFSET 0x0078 +#define OMAP4430_PM_L4PER_GPIO5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0078) +#define OMAP4_RM_L4PER_GPIO5_CONTEXT_OFFSET 0x007c +#define OMAP4430_RM_L4PER_GPIO5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x007c) +#define OMAP4_PM_L4PER_GPIO6_WKDEP_OFFSET 0x0080 +#define OMAP4430_PM_L4PER_GPIO6_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0080) +#define OMAP4_RM_L4PER_GPIO6_CONTEXT_OFFSET 0x0084 +#define OMAP4430_RM_L4PER_GPIO6_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0084) +#define OMAP4_RM_L4PER_HDQ1W_CONTEXT_OFFSET 0x008c +#define OMAP4430_RM_L4PER_HDQ1W_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x008c) +#define OMAP4_PM_L4PER_HECC1_WKDEP_OFFSET 0x0090 +#define OMAP4430_PM_L4PER_HECC1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0090) +#define OMAP4_RM_L4PER_HECC1_CONTEXT_OFFSET 0x0094 +#define OMAP4430_RM_L4PER_HECC1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0094) +#define OMAP4_PM_L4PER_HECC2_WKDEP_OFFSET 0x0098 +#define OMAP4430_PM_L4PER_HECC2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0098) +#define OMAP4_RM_L4PER_HECC2_CONTEXT_OFFSET 0x009c +#define OMAP4430_RM_L4PER_HECC2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x009c) +#define OMAP4_PM_L4PER_I2C1_WKDEP_OFFSET 0x00a0 +#define OMAP4430_PM_L4PER_I2C1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00a0) +#define OMAP4_RM_L4PER_I2C1_CONTEXT_OFFSET 0x00a4 +#define OMAP4430_RM_L4PER_I2C1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00a4) +#define OMAP4_PM_L4PER_I2C2_WKDEP_OFFSET 0x00a8 +#define OMAP4430_PM_L4PER_I2C2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00a8) +#define OMAP4_RM_L4PER_I2C2_CONTEXT_OFFSET 0x00ac +#define OMAP4430_RM_L4PER_I2C2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00ac) +#define OMAP4_PM_L4PER_I2C3_WKDEP_OFFSET 0x00b0 +#define OMAP4430_PM_L4PER_I2C3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00b0) +#define OMAP4_RM_L4PER_I2C3_CONTEXT_OFFSET 0x00b4 +#define OMAP4430_RM_L4PER_I2C3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00b4) +#define OMAP4_PM_L4PER_I2C4_WKDEP_OFFSET 0x00b8 +#define OMAP4430_PM_L4PER_I2C4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00b8) +#define OMAP4_RM_L4PER_I2C4_CONTEXT_OFFSET 0x00bc +#define OMAP4430_RM_L4PER_I2C4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00bc) +#define OMAP4_RM_L4PER_L4_PER_CONTEXT_OFFSET 0x00c0 +#define OMAP4430_RM_L4PER_L4_PER_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00c0) +#define OMAP4_PM_L4PER_MCASP2_WKDEP_OFFSET 0x00d0 +#define OMAP4430_PM_L4PER_MCASP2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00d0) +#define OMAP4_RM_L4PER_MCASP2_CONTEXT_OFFSET 0x00d4 +#define OMAP4430_RM_L4PER_MCASP2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00d4) +#define OMAP4_PM_L4PER_MCASP3_WKDEP_OFFSET 0x00d8 +#define OMAP4430_PM_L4PER_MCASP3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00d8) +#define OMAP4_RM_L4PER_MCASP3_CONTEXT_OFFSET 0x00dc +#define OMAP4430_RM_L4PER_MCASP3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00dc) +#define OMAP4_PM_L4PER_MCBSP4_WKDEP_OFFSET 0x00e0 +#define OMAP4430_PM_L4PER_MCBSP4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00e0) +#define OMAP4_RM_L4PER_MCBSP4_CONTEXT_OFFSET 0x00e4 +#define OMAP4430_RM_L4PER_MCBSP4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00e4) +#define OMAP4_RM_L4PER_MGATE_CONTEXT_OFFSET 0x00ec +#define OMAP4430_RM_L4PER_MGATE_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00ec) +#define OMAP4_PM_L4PER_MCSPI1_WKDEP_OFFSET 0x00f0 +#define OMAP4430_PM_L4PER_MCSPI1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00f0) +#define OMAP4_RM_L4PER_MCSPI1_CONTEXT_OFFSET 0x00f4 +#define OMAP4430_RM_L4PER_MCSPI1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00f4) +#define OMAP4_PM_L4PER_MCSPI2_WKDEP_OFFSET 0x00f8 +#define OMAP4430_PM_L4PER_MCSPI2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00f8) +#define OMAP4_RM_L4PER_MCSPI2_CONTEXT_OFFSET 0x00fc +#define OMAP4430_RM_L4PER_MCSPI2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00fc) +#define OMAP4_PM_L4PER_MCSPI3_WKDEP_OFFSET 0x0100 +#define OMAP4430_PM_L4PER_MCSPI3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0100) +#define OMAP4_RM_L4PER_MCSPI3_CONTEXT_OFFSET 0x0104 +#define OMAP4430_RM_L4PER_MCSPI3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0104) +#define OMAP4_PM_L4PER_MCSPI4_WKDEP_OFFSET 0x0108 +#define OMAP4430_PM_L4PER_MCSPI4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0108) +#define OMAP4_RM_L4PER_MCSPI4_CONTEXT_OFFSET 0x010c +#define OMAP4430_RM_L4PER_MCSPI4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x010c) +#define OMAP4_PM_L4PER_MMCSD3_WKDEP_OFFSET 0x0120 +#define OMAP4430_PM_L4PER_MMCSD3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0120) +#define OMAP4_RM_L4PER_MMCSD3_CONTEXT_OFFSET 0x0124 +#define OMAP4430_RM_L4PER_MMCSD3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0124) +#define OMAP4_PM_L4PER_MMCSD4_WKDEP_OFFSET 0x0128 +#define OMAP4430_PM_L4PER_MMCSD4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0128) +#define OMAP4_RM_L4PER_MMCSD4_CONTEXT_OFFSET 0x012c +#define OMAP4430_RM_L4PER_MMCSD4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x012c) +#define OMAP4_RM_L4PER_MSPROHG_CONTEXT_OFFSET 0x0134 +#define OMAP4430_RM_L4PER_MSPROHG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0134) +#define OMAP4_PM_L4PER_SLIMBUS2_WKDEP_OFFSET 0x0138 +#define OMAP4430_PM_L4PER_SLIMBUS2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0138) +#define OMAP4_RM_L4PER_SLIMBUS2_CONTEXT_OFFSET 0x013c +#define OMAP4430_RM_L4PER_SLIMBUS2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x013c) +#define OMAP4_PM_L4PER_UART1_WKDEP_OFFSET 0x0140 +#define OMAP4430_PM_L4PER_UART1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0140) +#define OMAP4_RM_L4PER_UART1_CONTEXT_OFFSET 0x0144 +#define OMAP4430_RM_L4PER_UART1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0144) +#define OMAP4_PM_L4PER_UART2_WKDEP_OFFSET 0x0148 +#define OMAP4430_PM_L4PER_UART2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0148) +#define OMAP4_RM_L4PER_UART2_CONTEXT_OFFSET 0x014c +#define OMAP4430_RM_L4PER_UART2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x014c) +#define OMAP4_PM_L4PER_UART3_WKDEP_OFFSET 0x0150 +#define OMAP4430_PM_L4PER_UART3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0150) +#define OMAP4_RM_L4PER_UART3_CONTEXT_OFFSET 0x0154 +#define OMAP4430_RM_L4PER_UART3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0154) +#define OMAP4_PM_L4PER_UART4_WKDEP_OFFSET 0x0158 +#define OMAP4430_PM_L4PER_UART4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0158) +#define OMAP4_RM_L4PER_UART4_CONTEXT_OFFSET 0x015c +#define OMAP4430_RM_L4PER_UART4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x015c) +#define OMAP4_PM_L4PER_MMCSD5_WKDEP_OFFSET 0x0160 +#define OMAP4430_PM_L4PER_MMCSD5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0160) +#define OMAP4_RM_L4PER_MMCSD5_CONTEXT_OFFSET 0x0164 +#define OMAP4430_RM_L4PER_MMCSD5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0164) +#define OMAP4_PM_L4PER_I2C5_WKDEP_OFFSET 0x0168 +#define OMAP4430_PM_L4PER_I2C5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0168) +#define OMAP4_RM_L4PER_I2C5_CONTEXT_OFFSET 0x016c +#define OMAP4430_RM_L4PER_I2C5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x016c) +#define OMAP4_RM_L4SEC_AES1_CONTEXT_OFFSET 0x01a4 +#define OMAP4430_RM_L4SEC_AES1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01a4) +#define OMAP4_RM_L4SEC_AES2_CONTEXT_OFFSET 0x01ac +#define OMAP4430_RM_L4SEC_AES2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01ac) +#define OMAP4_RM_L4SEC_DES3DES_CONTEXT_OFFSET 0x01b4 +#define OMAP4430_RM_L4SEC_DES3DES_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01b4) +#define OMAP4_RM_L4SEC_PKAEIP29_CONTEXT_OFFSET 0x01bc +#define OMAP4430_RM_L4SEC_PKAEIP29_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01bc) +#define OMAP4_RM_L4SEC_RNG_CONTEXT_OFFSET 0x01c4 +#define OMAP4430_RM_L4SEC_RNG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01c4) +#define OMAP4_RM_L4SEC_SHA2MD51_CONTEXT_OFFSET 0x01cc +#define OMAP4430_RM_L4SEC_SHA2MD51_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01cc) +#define OMAP4_RM_L4SEC_CRYPTODMA_CONTEXT_OFFSET 0x01dc +#define OMAP4430_RM_L4SEC_CRYPTODMA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01dc) + +/* PRM.CEFUSE_PRM register offsets */ +#define OMAP4_PM_CEFUSE_PWRSTCTRL_OFFSET 0x0000 +#define OMAP4430_PM_CEFUSE_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CEFUSE_INST, 0x0000) +#define OMAP4_PM_CEFUSE_PWRSTST_OFFSET 0x0004 +#define OMAP4430_PM_CEFUSE_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CEFUSE_INST, 0x0004) +#define OMAP4_RM_CEFUSE_CEFUSE_CONTEXT_OFFSET 0x0024 +#define OMAP4430_RM_CEFUSE_CEFUSE_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CEFUSE_INST, 0x0024) + +/* PRM.WKUP_PRM register offsets */ +#define OMAP4_RM_WKUP_L4WKUP_CONTEXT_OFFSET 0x0024 +#define OMAP4430_RM_WKUP_L4WKUP_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0024) +#define OMAP4_RM_WKUP_WDT1_CONTEXT_OFFSET 0x002c +#define OMAP4430_RM_WKUP_WDT1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x002c) +#define OMAP4_PM_WKUP_WDT2_WKDEP_OFFSET 0x0030 +#define OMAP4430_PM_WKUP_WDT2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0030) +#define OMAP4_RM_WKUP_WDT2_CONTEXT_OFFSET 0x0034 +#define OMAP4430_RM_WKUP_WDT2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0034) +#define OMAP4_PM_WKUP_GPIO1_WKDEP_OFFSET 0x0038 +#define OMAP4430_PM_WKUP_GPIO1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0038) +#define OMAP4_RM_WKUP_GPIO1_CONTEXT_OFFSET 0x003c +#define OMAP4430_RM_WKUP_GPIO1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x003c) +#define OMAP4_PM_WKUP_TIMER1_WKDEP_OFFSET 0x0040 +#define OMAP4430_PM_WKUP_TIMER1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0040) +#define OMAP4_RM_WKUP_TIMER1_CONTEXT_OFFSET 0x0044 +#define OMAP4430_RM_WKUP_TIMER1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0044) +#define OMAP4_PM_WKUP_TIMER12_WKDEP_OFFSET 0x0048 +#define OMAP4430_PM_WKUP_TIMER12_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0048) +#define OMAP4_RM_WKUP_TIMER12_CONTEXT_OFFSET 0x004c +#define OMAP4430_RM_WKUP_TIMER12_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x004c) +#define OMAP4_RM_WKUP_SYNCTIMER_CONTEXT_OFFSET 0x0054 +#define OMAP4430_RM_WKUP_SYNCTIMER_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0054) +#define OMAP4_PM_WKUP_USIM_WKDEP_OFFSET 0x0058 +#define OMAP4430_PM_WKUP_USIM_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0058) +#define OMAP4_RM_WKUP_USIM_CONTEXT_OFFSET 0x005c +#define OMAP4430_RM_WKUP_USIM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x005c) +#define OMAP4_RM_WKUP_SARRAM_CONTEXT_OFFSET 0x0064 +#define OMAP4430_RM_WKUP_SARRAM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0064) +#define OMAP4_PM_WKUP_KEYBOARD_WKDEP_OFFSET 0x0078 +#define OMAP4430_PM_WKUP_KEYBOARD_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0078) +#define OMAP4_RM_WKUP_KEYBOARD_CONTEXT_OFFSET 0x007c +#define OMAP4430_RM_WKUP_KEYBOARD_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x007c) +#define OMAP4_PM_WKUP_RTC_WKDEP_OFFSET 0x0080 +#define OMAP4430_PM_WKUP_RTC_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0080) +#define OMAP4_RM_WKUP_RTC_CONTEXT_OFFSET 0x0084 +#define OMAP4430_RM_WKUP_RTC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0084) + +/* PRM.WKUP_CM register offsets */ +#define OMAP4_CM_WKUP_CLKSTCTRL_OFFSET 0x0000 +#define OMAP4430_CM_WKUP_CLKSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0000) +#define OMAP4_CM_WKUP_L4WKUP_CLKCTRL_OFFSET 0x0020 +#define OMAP4430_CM_WKUP_L4WKUP_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0020) +#define OMAP4_CM_WKUP_WDT1_CLKCTRL_OFFSET 0x0028 +#define OMAP4430_CM_WKUP_WDT1_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0028) +#define OMAP4_CM_WKUP_WDT2_CLKCTRL_OFFSET 0x0030 +#define OMAP4430_CM_WKUP_WDT2_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0030) +#define OMAP4_CM_WKUP_GPIO1_CLKCTRL_OFFSET 0x0038 +#define OMAP4430_CM_WKUP_GPIO1_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0038) +#define OMAP4_CM_WKUP_TIMER1_CLKCTRL_OFFSET 0x0040 +#define OMAP4430_CM_WKUP_TIMER1_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0040) +#define OMAP4_CM_WKUP_TIMER12_CLKCTRL_OFFSET 0x0048 +#define OMAP4430_CM_WKUP_TIMER12_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0048) +#define OMAP4_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET 0x0050 +#define OMAP4430_CM_WKUP_SYNCTIMER_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0050) +#define OMAP4_CM_WKUP_USIM_CLKCTRL_OFFSET 0x0058 +#define OMAP4430_CM_WKUP_USIM_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0058) +#define OMAP4_CM_WKUP_SARRAM_CLKCTRL_OFFSET 0x0060 +#define OMAP4430_CM_WKUP_SARRAM_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0060) +#define OMAP4_CM_WKUP_KEYBOARD_CLKCTRL_OFFSET 0x0078 +#define OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0078) +#define OMAP4_CM_WKUP_RTC_CLKCTRL_OFFSET 0x0080 +#define OMAP4430_CM_WKUP_RTC_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0080) +#define OMAP4_CM_WKUP_BANDGAP_CLKCTRL_OFFSET 0x0088 +#define OMAP4430_CM_WKUP_BANDGAP_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0088) + +/* PRM.EMU_PRM register offsets */ +#define OMAP4_PM_EMU_PWRSTCTRL_OFFSET 0x0000 +#define OMAP4430_PM_EMU_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_INST, 0x0000) +#define OMAP4_PM_EMU_PWRSTST_OFFSET 0x0004 +#define OMAP4430_PM_EMU_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_INST, 0x0004) +#define OMAP4_RM_EMU_DEBUGSS_CONTEXT_OFFSET 0x0024 +#define OMAP4430_RM_EMU_DEBUGSS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_INST, 0x0024) + +/* PRM.EMU_CM register offsets */ +#define OMAP4_CM_EMU_CLKSTCTRL_OFFSET 0x0000 +#define OMAP4430_CM_EMU_CLKSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_CM_INST, 0x0000) +#define OMAP4_CM_EMU_DYNAMICDEP_OFFSET 0x0008 +#define OMAP4430_CM_EMU_DYNAMICDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_CM_INST, 0x0008) +#define OMAP4_CM_EMU_DEBUGSS_CLKCTRL_OFFSET 0x0020 +#define OMAP4430_CM_EMU_DEBUGSS_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_CM_INST, 0x0020) + +/* PRM.DEVICE_PRM register offsets */ +#define OMAP4_PRM_RSTCTRL_OFFSET 0x0000 +#define OMAP4430_PRM_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0000) +#define OMAP4_PRM_RSTST_OFFSET 0x0004 +#define OMAP4430_PRM_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0004) +#define OMAP4_PRM_RSTTIME_OFFSET 0x0008 +#define OMAP4430_PRM_RSTTIME OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0008) +#define OMAP4_PRM_CLKREQCTRL_OFFSET 0x000c +#define OMAP4430_PRM_CLKREQCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x000c) +#define OMAP4_PRM_VOLTCTRL_OFFSET 0x0010 +#define OMAP4430_PRM_VOLTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0010) +#define OMAP4_PRM_PWRREQCTRL_OFFSET 0x0014 +#define OMAP4430_PRM_PWRREQCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0014) +#define OMAP4_PRM_PSCON_COUNT_OFFSET 0x0018 +#define OMAP4430_PRM_PSCON_COUNT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0018) +#define OMAP4_PRM_IO_COUNT_OFFSET 0x001c +#define OMAP4430_PRM_IO_COUNT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x001c) +#define OMAP4_PRM_IO_PMCTRL_OFFSET 0x0020 +#define OMAP4430_PRM_IO_PMCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0020) +#define OMAP4_PRM_VOLTSETUP_WARMRESET_OFFSET 0x0024 +#define OMAP4430_PRM_VOLTSETUP_WARMRESET OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0024) +#define OMAP4_PRM_VOLTSETUP_CORE_OFF_OFFSET 0x0028 +#define OMAP4430_PRM_VOLTSETUP_CORE_OFF OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0028) +#define OMAP4_PRM_VOLTSETUP_MPU_OFF_OFFSET 0x002c +#define OMAP4430_PRM_VOLTSETUP_MPU_OFF OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x002c) +#define OMAP4_PRM_VOLTSETUP_IVA_OFF_OFFSET 0x0030 +#define OMAP4430_PRM_VOLTSETUP_IVA_OFF OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0030) +#define OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET 0x0034 +#define OMAP4430_PRM_VOLTSETUP_CORE_RET_SLEEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0034) +#define OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET 0x0038 +#define OMAP4430_PRM_VOLTSETUP_MPU_RET_SLEEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0038) +#define OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET 0x003c +#define OMAP4430_PRM_VOLTSETUP_IVA_RET_SLEEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x003c) +#define OMAP4_PRM_VP_CORE_CONFIG_OFFSET 0x0040 +#define OMAP4430_PRM_VP_CORE_CONFIG OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0040) +#define OMAP4_PRM_VP_CORE_STATUS_OFFSET 0x0044 +#define OMAP4430_PRM_VP_CORE_STATUS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0044) +#define OMAP4_PRM_VP_CORE_VLIMITTO_OFFSET 0x0048 +#define OMAP4430_PRM_VP_CORE_VLIMITTO OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0048) +#define OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET 0x004c +#define OMAP4430_PRM_VP_CORE_VOLTAGE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x004c) +#define OMAP4_PRM_VP_CORE_VSTEPMAX_OFFSET 0x0050 +#define OMAP4430_PRM_VP_CORE_VSTEPMAX OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0050) +#define OMAP4_PRM_VP_CORE_VSTEPMIN_OFFSET 0x0054 +#define OMAP4430_PRM_VP_CORE_VSTEPMIN OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0054) +#define OMAP4_PRM_VP_MPU_CONFIG_OFFSET 0x0058 +#define OMAP4430_PRM_VP_MPU_CONFIG OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0058) +#define OMAP4_PRM_VP_MPU_STATUS_OFFSET 0x005c +#define OMAP4430_PRM_VP_MPU_STATUS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x005c) +#define OMAP4_PRM_VP_MPU_VLIMITTO_OFFSET 0x0060 +#define OMAP4430_PRM_VP_MPU_VLIMITTO OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0060) +#define OMAP4_PRM_VP_MPU_VOLTAGE_OFFSET 0x0064 +#define OMAP4430_PRM_VP_MPU_VOLTAGE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0064) +#define OMAP4_PRM_VP_MPU_VSTEPMAX_OFFSET 0x0068 +#define OMAP4430_PRM_VP_MPU_VSTEPMAX OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0068) +#define OMAP4_PRM_VP_MPU_VSTEPMIN_OFFSET 0x006c +#define OMAP4430_PRM_VP_MPU_VSTEPMIN OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x006c) +#define OMAP4_PRM_VP_IVA_CONFIG_OFFSET 0x0070 +#define OMAP4430_PRM_VP_IVA_CONFIG OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0070) +#define OMAP4_PRM_VP_IVA_STATUS_OFFSET 0x0074 +#define OMAP4430_PRM_VP_IVA_STATUS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0074) +#define OMAP4_PRM_VP_IVA_VLIMITTO_OFFSET 0x0078 +#define OMAP4430_PRM_VP_IVA_VLIMITTO OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0078) +#define OMAP4_PRM_VP_IVA_VOLTAGE_OFFSET 0x007c +#define OMAP4430_PRM_VP_IVA_VOLTAGE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x007c) +#define OMAP4_PRM_VP_IVA_VSTEPMAX_OFFSET 0x0080 +#define OMAP4430_PRM_VP_IVA_VSTEPMAX OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0080) +#define OMAP4_PRM_VP_IVA_VSTEPMIN_OFFSET 0x0084 +#define OMAP4430_PRM_VP_IVA_VSTEPMIN OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0084) +#define OMAP4_PRM_VC_SMPS_SA_OFFSET 0x0088 +#define OMAP4430_PRM_VC_SMPS_SA OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0088) +#define OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET 0x008c +#define OMAP4430_PRM_VC_VAL_SMPS_RA_VOL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x008c) +#define OMAP4_PRM_VC_VAL_SMPS_RA_CMD_OFFSET 0x0090 +#define OMAP4430_PRM_VC_VAL_SMPS_RA_CMD OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0090) +#define OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET 0x0094 +#define OMAP4430_PRM_VC_VAL_CMD_VDD_CORE_L OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0094) +#define OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET 0x0098 +#define OMAP4430_PRM_VC_VAL_CMD_VDD_MPU_L OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0098) +#define OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET 0x009c +#define OMAP4430_PRM_VC_VAL_CMD_VDD_IVA_L OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x009c) +#define OMAP4_PRM_VC_VAL_BYPASS_OFFSET 0x00a0 +#define OMAP4430_PRM_VC_VAL_BYPASS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00a0) +#define OMAP4_PRM_VC_CFG_CHANNEL_OFFSET 0x00a4 +#define OMAP4430_PRM_VC_CFG_CHANNEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00a4) +#define OMAP4_PRM_VC_CFG_I2C_MODE_OFFSET 0x00a8 +#define OMAP4430_PRM_VC_CFG_I2C_MODE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00a8) +#define OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET 0x00ac +#define OMAP4430_PRM_VC_CFG_I2C_CLK OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00ac) +#define OMAP4_PRM_SRAM_COUNT_OFFSET 0x00b0 +#define OMAP4430_PRM_SRAM_COUNT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00b0) +#define OMAP4_PRM_SRAM_WKUP_SETUP_OFFSET 0x00b4 +#define OMAP4430_PRM_SRAM_WKUP_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00b4) +#define OMAP4_PRM_LDO_SRAM_CORE_SETUP_OFFSET 0x00b8 +#define OMAP4430_PRM_LDO_SRAM_CORE_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00b8) +#define OMAP4_PRM_LDO_SRAM_CORE_CTRL_OFFSET 0x00bc +#define OMAP4430_PRM_LDO_SRAM_CORE_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00bc) +#define OMAP4_PRM_LDO_SRAM_MPU_SETUP_OFFSET 0x00c0 +#define OMAP4430_PRM_LDO_SRAM_MPU_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00c0) +#define OMAP4_PRM_LDO_SRAM_MPU_CTRL_OFFSET 0x00c4 +#define OMAP4430_PRM_LDO_SRAM_MPU_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00c4) +#define OMAP4_PRM_LDO_SRAM_IVA_SETUP_OFFSET 0x00c8 +#define OMAP4430_PRM_LDO_SRAM_IVA_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00c8) +#define OMAP4_PRM_LDO_SRAM_IVA_CTRL_OFFSET 0x00cc +#define OMAP4430_PRM_LDO_SRAM_IVA_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00cc) +#define OMAP4_PRM_LDO_ABB_MPU_SETUP_OFFSET 0x00d0 +#define OMAP4430_PRM_LDO_ABB_MPU_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00d0) +#define OMAP4_PRM_LDO_ABB_MPU_CTRL_OFFSET 0x00d4 +#define OMAP4430_PRM_LDO_ABB_MPU_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00d4) +#define OMAP4_PRM_LDO_ABB_IVA_SETUP_OFFSET 0x00d8 +#define OMAP4430_PRM_LDO_ABB_IVA_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00d8) +#define OMAP4_PRM_LDO_ABB_IVA_CTRL_OFFSET 0x00dc +#define OMAP4430_PRM_LDO_ABB_IVA_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00dc) +#define OMAP4_PRM_LDO_BANDGAP_SETUP_OFFSET 0x00e0 +#define OMAP4430_PRM_LDO_BANDGAP_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00e0) +#define OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET 0x00e4 +#define OMAP4430_PRM_DEVICE_OFF_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00e4) +#define OMAP4_PRM_PHASE1_CNDP_OFFSET 0x00e8 +#define OMAP4430_PRM_PHASE1_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00e8) +#define OMAP4_PRM_PHASE2A_CNDP_OFFSET 0x00ec +#define OMAP4430_PRM_PHASE2A_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00ec) +#define OMAP4_PRM_PHASE2B_CNDP_OFFSET 0x00f0 +#define OMAP4430_PRM_PHASE2B_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00f0) +#define OMAP4_PRM_MODEM_IF_CTRL_OFFSET 0x00f4 +#define OMAP4430_PRM_MODEM_IF_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00f4) +#define OMAP4_PRM_VC_ERRST_OFFSET 0x00f8 +#define OMAP4430_PRM_VC_ERRST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00f8) + +#endif diff --git a/arch/arm/mach-omap2/prm44xx_54xx.h b/arch/arm/mach-omap2/prm44xx_54xx.h new file mode 100644 index 00000000000..8d95aa543ef --- /dev/null +++ b/arch/arm/mach-omap2/prm44xx_54xx.h @@ -0,0 +1,65 @@ +/* + * OMAP44xx and 54xx PRM common functions + * + * Copyright (C) 2009-2013 Texas Instruments, Inc. + * Copyright (C) 2009-2010 Nokia Corporation + * + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_PRM44XX_54XX_H +#define __ARCH_ARM_MACH_OMAP2_PRM44XX_54XX_H + +/* Function prototypes */ +#ifndef __ASSEMBLER__ + +extern u32 omap4_prm_read_inst_reg(s16 inst, u16 idx); +extern void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 idx); +extern u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx); + +/* OMAP4/OMAP5-specific VP functions */ +u32 omap4_prm_vp_check_txdone(u8 vp_id); +void omap4_prm_vp_clear_txdone(u8 vp_id); + +/* + * OMAP4/OMAP5 access functions for voltage controller (VC) and + * voltage proccessor (VP) in the PRM. + */ +extern u32 omap4_prm_vcvp_read(u8 offset); +extern void omap4_prm_vcvp_write(u32 val, u8 offset); +extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); + +#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ + defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM43XX) +void omap44xx_prm_reconfigure_io_chain(void); +#else +static inline void omap44xx_prm_reconfigure_io_chain(void) +{ +} +#endif + +/* PRM interrupt-related functions */ +extern void omap44xx_prm_read_pending_irqs(unsigned long *events); +extern void omap44xx_prm_ocp_barrier(void); +extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask); +extern void omap44xx_prm_restore_irqen(u32 *saved_mask); + +extern int __init omap44xx_prm_init(void); +extern u32 omap44xx_prm_get_reset_sources(void); + +#endif + +#endif diff --git a/arch/arm/mach-omap2/prm54xx.h b/arch/arm/mach-omap2/prm54xx.h new file mode 100644 index 00000000000..e4411010309 --- /dev/null +++ b/arch/arm/mach-omap2/prm54xx.h @@ -0,0 +1,421 @@ +/* + * OMAP54xx PRM instance offset macros + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_PRM54XX_H +#define __ARCH_ARM_MACH_OMAP2_PRM54XX_H + +#include "prm44xx_54xx.h" +#include "prcm-common.h" +#include "prm.h" + +#define OMAP54XX_PRM_BASE 0x4ae06000 + +#define OMAP54XX_PRM_REGADDR(inst, reg) \ + OMAP2_L4_IO_ADDRESS(OMAP54XX_PRM_BASE + (inst) + (reg)) + + +/* PRM instances */ +#define OMAP54XX_PRM_OCP_SOCKET_INST 0x0000 +#define OMAP54XX_PRM_CKGEN_INST 0x0100 +#define OMAP54XX_PRM_MPU_INST 0x0300 +#define OMAP54XX_PRM_DSP_INST 0x0400 +#define OMAP54XX_PRM_ABE_INST 0x0500 +#define OMAP54XX_PRM_COREAON_INST 0x0600 +#define OMAP54XX_PRM_CORE_INST 0x0700 +#define OMAP54XX_PRM_IVA_INST 0x1200 +#define OMAP54XX_PRM_CAM_INST 0x1300 +#define OMAP54XX_PRM_DSS_INST 0x1400 +#define OMAP54XX_PRM_GPU_INST 0x1500 +#define OMAP54XX_PRM_L3INIT_INST 0x1600 +#define OMAP54XX_PRM_CUSTEFUSE_INST 0x1700 +#define OMAP54XX_PRM_WKUPAON_INST 0x1800 +#define OMAP54XX_PRM_WKUPAON_CM_INST 0x1900 +#define OMAP54XX_PRM_EMU_INST 0x1a00 +#define OMAP54XX_PRM_EMU_CM_INST 0x1b00 +#define OMAP54XX_PRM_DEVICE_INST 0x1c00 +#define OMAP54XX_PRM_INSTR_INST 0x1f00 + +/* PRM clockdomain register offsets (from instance start) */ +#define OMAP54XX_PRM_WKUPAON_CM_WKUPAON_CDOFFS 0x0000 +#define OMAP54XX_PRM_EMU_CM_EMU_CDOFFS 0x0000 + +/* PRM */ + +/* PRM.OCP_SOCKET_PRM register offsets */ +#define OMAP54XX_REVISION_PRM_OFFSET 0x0000 +#define OMAP54XX_PRM_IRQSTATUS_MPU_OFFSET 0x0010 +#define OMAP54XX_PRM_IRQSTATUS_MPU_2_OFFSET 0x0014 +#define OMAP54XX_PRM_IRQENABLE_MPU_OFFSET 0x0018 +#define OMAP54XX_PRM_IRQENABLE_MPU_2_OFFSET 0x001c +#define OMAP54XX_PRM_IRQSTATUS_IPU_OFFSET 0x0020 +#define OMAP54XX_PRM_IRQENABLE_IPU_OFFSET 0x0028 +#define OMAP54XX_PRM_IRQSTATUS_DSP_OFFSET 0x0030 +#define OMAP54XX_PRM_IRQENABLE_DSP_OFFSET 0x0038 +#define OMAP54XX_CM_PRM_PROFILING_CLKCTRL_OFFSET 0x0040 +#define OMAP54XX_CM_PRM_PROFILING_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_OCP_SOCKET_INST, 0x0040) +#define OMAP54XX_PRM_DEBUG_OUT_OFFSET 0x0084 +#define OMAP54XX_PRM_DEBUG_TRANS_CFG_OFFSET 0x0090 +#define OMAP54XX_PRM_DEBUG_OFF_TRANS_OFFSET 0x0094 +#define OMAP54XX_PRM_DEBUG_CORE_RET_TRANS_OFFSET 0x0098 +#define OMAP54XX_PRM_DEBUG_MPU_RET_TRANS_OFFSET 0x009c +#define OMAP54XX_PRM_DEBUG_MM_RET_TRANS_OFFSET 0x00a0 +#define OMAP54XX_PRM_DEBUG_WKUPAON_FD_TRANS_OFFSET 0x00a4 + +/* PRM.CKGEN_PRM register offsets */ +#define OMAP54XX_CM_CLKSEL_ABE_DSS_SYS_OFFSET 0x0000 +#define OMAP54XX_CM_CLKSEL_ABE_DSS_SYS OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_CKGEN_INST, 0x0000) +#define OMAP54XX_CM_CLKSEL_WKUPAON_OFFSET 0x0008 +#define OMAP54XX_CM_CLKSEL_WKUPAON OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_CKGEN_INST, 0x0008) +#define OMAP54XX_CM_CLKSEL_ABE_PLL_REF_OFFSET 0x000c +#define OMAP54XX_CM_CLKSEL_ABE_PLL_REF OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_CKGEN_INST, 0x000c) +#define OMAP54XX_CM_CLKSEL_SYS_OFFSET 0x0010 +#define OMAP54XX_CM_CLKSEL_SYS OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_CKGEN_INST, 0x0010) + +/* PRM.MPU_PRM register offsets */ +#define OMAP54XX_PM_MPU_PWRSTCTRL_OFFSET 0x0000 +#define OMAP54XX_PM_MPU_PWRSTST_OFFSET 0x0004 +#define OMAP54XX_RM_MPU_MPU_CONTEXT_OFFSET 0x0024 + +/* PRM.DSP_PRM register offsets */ +#define OMAP54XX_PM_DSP_PWRSTCTRL_OFFSET 0x0000 +#define OMAP54XX_PM_DSP_PWRSTST_OFFSET 0x0004 +#define OMAP54XX_RM_DSP_RSTCTRL_OFFSET 0x0010 +#define OMAP54XX_RM_DSP_RSTST_OFFSET 0x0014 +#define OMAP54XX_RM_DSP_DSP_CONTEXT_OFFSET 0x0024 + +/* PRM.ABE_PRM register offsets */ +#define OMAP54XX_PM_ABE_PWRSTCTRL_OFFSET 0x0000 +#define OMAP54XX_PM_ABE_PWRSTST_OFFSET 0x0004 +#define OMAP54XX_RM_ABE_AESS_CONTEXT_OFFSET 0x002c +#define OMAP54XX_PM_ABE_MCPDM_WKDEP_OFFSET 0x0030 +#define OMAP54XX_RM_ABE_MCPDM_CONTEXT_OFFSET 0x0034 +#define OMAP54XX_PM_ABE_DMIC_WKDEP_OFFSET 0x0038 +#define OMAP54XX_RM_ABE_DMIC_CONTEXT_OFFSET 0x003c +#define OMAP54XX_PM_ABE_MCASP_WKDEP_OFFSET 0x0040 +#define OMAP54XX_RM_ABE_MCASP_CONTEXT_OFFSET 0x0044 +#define OMAP54XX_PM_ABE_MCBSP1_WKDEP_OFFSET 0x0048 +#define OMAP54XX_RM_ABE_MCBSP1_CONTEXT_OFFSET 0x004c +#define OMAP54XX_PM_ABE_MCBSP2_WKDEP_OFFSET 0x0050 +#define OMAP54XX_RM_ABE_MCBSP2_CONTEXT_OFFSET 0x0054 +#define OMAP54XX_PM_ABE_MCBSP3_WKDEP_OFFSET 0x0058 +#define OMAP54XX_RM_ABE_MCBSP3_CONTEXT_OFFSET 0x005c +#define OMAP54XX_PM_ABE_SLIMBUS1_WKDEP_OFFSET 0x0060 +#define OMAP54XX_RM_ABE_SLIMBUS1_CONTEXT_OFFSET 0x0064 +#define OMAP54XX_PM_ABE_TIMER5_WKDEP_OFFSET 0x0068 +#define OMAP54XX_RM_ABE_TIMER5_CONTEXT_OFFSET 0x006c +#define OMAP54XX_PM_ABE_TIMER6_WKDEP_OFFSET 0x0070 +#define OMAP54XX_RM_ABE_TIMER6_CONTEXT_OFFSET 0x0074 +#define OMAP54XX_PM_ABE_TIMER7_WKDEP_OFFSET 0x0078 +#define OMAP54XX_RM_ABE_TIMER7_CONTEXT_OFFSET 0x007c +#define OMAP54XX_PM_ABE_TIMER8_WKDEP_OFFSET 0x0080 +#define OMAP54XX_RM_ABE_TIMER8_CONTEXT_OFFSET 0x0084 +#define OMAP54XX_PM_ABE_WD_TIMER3_WKDEP_OFFSET 0x0088 +#define OMAP54XX_RM_ABE_WD_TIMER3_CONTEXT_OFFSET 0x008c + +/* PRM.COREAON_PRM register offsets */ +#define OMAP54XX_PM_COREAON_SMARTREFLEX_MPU_WKDEP_OFFSET 0x0028 +#define OMAP54XX_RM_COREAON_SMARTREFLEX_MPU_CONTEXT_OFFSET 0x002c +#define OMAP54XX_PM_COREAON_SMARTREFLEX_MM_WKDEP_OFFSET 0x0030 +#define OMAP54XX_RM_COREAON_SMARTREFLEX_MM_CONTEXT_OFFSET 0x0034 +#define OMAP54XX_PM_COREAON_SMARTREFLEX_CORE_WKDEP_OFFSET 0x0038 +#define OMAP54XX_RM_COREAON_SMARTREFLEX_CORE_CONTEXT_OFFSET 0x003c + +/* PRM.CORE_PRM register offsets */ +#define OMAP54XX_PM_CORE_PWRSTCTRL_OFFSET 0x0000 +#define OMAP54XX_PM_CORE_PWRSTST_OFFSET 0x0004 +#define OMAP54XX_RM_L3MAIN1_L3_MAIN_1_CONTEXT_OFFSET 0x0024 +#define OMAP54XX_RM_L3MAIN2_L3_MAIN_2_CONTEXT_OFFSET 0x0124 +#define OMAP54XX_RM_L3MAIN2_GPMC_CONTEXT_OFFSET 0x012c +#define OMAP54XX_RM_L3MAIN2_OCMC_RAM_CONTEXT_OFFSET 0x0134 +#define OMAP54XX_RM_IPU_RSTCTRL_OFFSET 0x0210 +#define OMAP54XX_RM_IPU_RSTST_OFFSET 0x0214 +#define OMAP54XX_RM_IPU_IPU_CONTEXT_OFFSET 0x0224 +#define OMAP54XX_RM_DMA_DMA_SYSTEM_CONTEXT_OFFSET 0x0324 +#define OMAP54XX_RM_EMIF_DMM_CONTEXT_OFFSET 0x0424 +#define OMAP54XX_RM_EMIF_EMIF_OCP_FW_CONTEXT_OFFSET 0x042c +#define OMAP54XX_RM_EMIF_EMIF1_CONTEXT_OFFSET 0x0434 +#define OMAP54XX_RM_EMIF_EMIF2_CONTEXT_OFFSET 0x043c +#define OMAP54XX_RM_EMIF_EMIF_DLL_CONTEXT_OFFSET 0x0444 +#define OMAP54XX_RM_C2C_C2C_CONTEXT_OFFSET 0x0524 +#define OMAP54XX_RM_C2C_MODEM_ICR_CONTEXT_OFFSET 0x052c +#define OMAP54XX_RM_C2C_C2C_OCP_FW_CONTEXT_OFFSET 0x0534 +#define OMAP54XX_RM_L4CFG_L4_CFG_CONTEXT_OFFSET 0x0624 +#define OMAP54XX_RM_L4CFG_SPINLOCK_CONTEXT_OFFSET 0x062c +#define OMAP54XX_RM_L4CFG_MAILBOX_CONTEXT_OFFSET 0x0634 +#define OMAP54XX_RM_L4CFG_SAR_ROM_CONTEXT_OFFSET 0x063c +#define OMAP54XX_RM_L4CFG_OCP2SCP2_CONTEXT_OFFSET 0x0644 +#define OMAP54XX_RM_L3INSTR_L3_MAIN_3_CONTEXT_OFFSET 0x0724 +#define OMAP54XX_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET 0x072c +#define OMAP54XX_RM_L3INSTR_OCP_WP_NOC_CONTEXT_OFFSET 0x0744 +#define OMAP54XX_RM_MIPIEXT_LLI_CONTEXT_OFFSET 0x0824 +#define OMAP54XX_RM_MIPIEXT_LLI_OCP_FW_CONTEXT_OFFSET 0x082c +#define OMAP54XX_RM_MIPIEXT_MPHY_CONTEXT_OFFSET 0x0834 +#define OMAP54XX_PM_L4PER_TIMER10_WKDEP_OFFSET 0x0928 +#define OMAP54XX_RM_L4PER_TIMER10_CONTEXT_OFFSET 0x092c +#define OMAP54XX_PM_L4PER_TIMER11_WKDEP_OFFSET 0x0930 +#define OMAP54XX_RM_L4PER_TIMER11_CONTEXT_OFFSET 0x0934 +#define OMAP54XX_PM_L4PER_TIMER2_WKDEP_OFFSET 0x0938 +#define OMAP54XX_RM_L4PER_TIMER2_CONTEXT_OFFSET 0x093c +#define OMAP54XX_PM_L4PER_TIMER3_WKDEP_OFFSET 0x0940 +#define OMAP54XX_RM_L4PER_TIMER3_CONTEXT_OFFSET 0x0944 +#define OMAP54XX_PM_L4PER_TIMER4_WKDEP_OFFSET 0x0948 +#define OMAP54XX_RM_L4PER_TIMER4_CONTEXT_OFFSET 0x094c +#define OMAP54XX_PM_L4PER_TIMER9_WKDEP_OFFSET 0x0950 +#define OMAP54XX_RM_L4PER_TIMER9_CONTEXT_OFFSET 0x0954 +#define OMAP54XX_RM_L4PER_ELM_CONTEXT_OFFSET 0x095c +#define OMAP54XX_PM_L4PER_GPIO2_WKDEP_OFFSET 0x0960 +#define OMAP54XX_RM_L4PER_GPIO2_CONTEXT_OFFSET 0x0964 +#define OMAP54XX_PM_L4PER_GPIO3_WKDEP_OFFSET 0x0968 +#define OMAP54XX_RM_L4PER_GPIO3_CONTEXT_OFFSET 0x096c +#define OMAP54XX_PM_L4PER_GPIO4_WKDEP_OFFSET 0x0970 +#define OMAP54XX_RM_L4PER_GPIO4_CONTEXT_OFFSET 0x0974 +#define OMAP54XX_PM_L4PER_GPIO5_WKDEP_OFFSET 0x0978 +#define OMAP54XX_RM_L4PER_GPIO5_CONTEXT_OFFSET 0x097c +#define OMAP54XX_PM_L4PER_GPIO6_WKDEP_OFFSET 0x0980 +#define OMAP54XX_RM_L4PER_GPIO6_CONTEXT_OFFSET 0x0984 +#define OMAP54XX_RM_L4PER_HDQ1W_CONTEXT_OFFSET 0x098c +#define OMAP54XX_PM_L4PER_I2C1_WKDEP_OFFSET 0x09a0 +#define OMAP54XX_RM_L4PER_I2C1_CONTEXT_OFFSET 0x09a4 +#define OMAP54XX_PM_L4PER_I2C2_WKDEP_OFFSET 0x09a8 +#define OMAP54XX_RM_L4PER_I2C2_CONTEXT_OFFSET 0x09ac +#define OMAP54XX_PM_L4PER_I2C3_WKDEP_OFFSET 0x09b0 +#define OMAP54XX_RM_L4PER_I2C3_CONTEXT_OFFSET 0x09b4 +#define OMAP54XX_PM_L4PER_I2C4_WKDEP_OFFSET 0x09b8 +#define OMAP54XX_RM_L4PER_I2C4_CONTEXT_OFFSET 0x09bc +#define OMAP54XX_RM_L4PER_L4_PER_CONTEXT_OFFSET 0x09c0 +#define OMAP54XX_PM_L4PER_MCSPI1_WKDEP_OFFSET 0x09f0 +#define OMAP54XX_RM_L4PER_MCSPI1_CONTEXT_OFFSET 0x09f4 +#define OMAP54XX_PM_L4PER_MCSPI2_WKDEP_OFFSET 0x09f8 +#define OMAP54XX_RM_L4PER_MCSPI2_CONTEXT_OFFSET 0x09fc +#define OMAP54XX_PM_L4PER_MCSPI3_WKDEP_OFFSET 0x0a00 +#define OMAP54XX_RM_L4PER_MCSPI3_CONTEXT_OFFSET 0x0a04 +#define OMAP54XX_PM_L4PER_MCSPI4_WKDEP_OFFSET 0x0a08 +#define OMAP54XX_RM_L4PER_MCSPI4_CONTEXT_OFFSET 0x0a0c +#define OMAP54XX_PM_L4PER_GPIO7_WKDEP_OFFSET 0x0a10 +#define OMAP54XX_RM_L4PER_GPIO7_CONTEXT_OFFSET 0x0a14 +#define OMAP54XX_PM_L4PER_GPIO8_WKDEP_OFFSET 0x0a18 +#define OMAP54XX_RM_L4PER_GPIO8_CONTEXT_OFFSET 0x0a1c +#define OMAP54XX_PM_L4PER_MMC3_WKDEP_OFFSET 0x0a20 +#define OMAP54XX_RM_L4PER_MMC3_CONTEXT_OFFSET 0x0a24 +#define OMAP54XX_PM_L4PER_MMC4_WKDEP_OFFSET 0x0a28 +#define OMAP54XX_RM_L4PER_MMC4_CONTEXT_OFFSET 0x0a2c +#define OMAP54XX_PM_L4PER_UART1_WKDEP_OFFSET 0x0a40 +#define OMAP54XX_RM_L4PER_UART1_CONTEXT_OFFSET 0x0a44 +#define OMAP54XX_PM_L4PER_UART2_WKDEP_OFFSET 0x0a48 +#define OMAP54XX_RM_L4PER_UART2_CONTEXT_OFFSET 0x0a4c +#define OMAP54XX_PM_L4PER_UART3_WKDEP_OFFSET 0x0a50 +#define OMAP54XX_RM_L4PER_UART3_CONTEXT_OFFSET 0x0a54 +#define OMAP54XX_RM_L4PER_UART4_CONTEXT_OFFSET 0x0a58 +#define OMAP54XX_PM_L4PER_UART4_WKDEP_OFFSET 0x0a5c +#define OMAP54XX_PM_L4PER_MMC5_WKDEP_OFFSET 0x0a60 +#define OMAP54XX_RM_L4PER_MMC5_CONTEXT_OFFSET 0x0a64 +#define OMAP54XX_PM_L4PER_I2C5_WKDEP_OFFSET 0x0a68 +#define OMAP54XX_RM_L4PER_I2C5_CONTEXT_OFFSET 0x0a6c +#define OMAP54XX_PM_L4PER_UART5_WKDEP_OFFSET 0x0a70 +#define OMAP54XX_RM_L4PER_UART5_CONTEXT_OFFSET 0x0a74 +#define OMAP54XX_PM_L4PER_UART6_WKDEP_OFFSET 0x0a78 +#define OMAP54XX_RM_L4PER_UART6_CONTEXT_OFFSET 0x0a7c +#define OMAP54XX_RM_L4SEC_AES1_CONTEXT_OFFSET 0x0aa4 +#define OMAP54XX_RM_L4SEC_AES2_CONTEXT_OFFSET 0x0aac +#define OMAP54XX_RM_L4SEC_DES3DES_CONTEXT_OFFSET 0x0ab4 +#define OMAP54XX_RM_L4SEC_FPKA_CONTEXT_OFFSET 0x0abc +#define OMAP54XX_RM_L4SEC_RNG_CONTEXT_OFFSET 0x0ac4 +#define OMAP54XX_RM_L4SEC_SHA2MD5_CONTEXT_OFFSET 0x0acc +#define OMAP54XX_RM_L4SEC_DMA_CRYPTO_CONTEXT_OFFSET 0x0adc + +/* PRM.IVA_PRM register offsets */ +#define OMAP54XX_PM_IVA_PWRSTCTRL_OFFSET 0x0000 +#define OMAP54XX_PM_IVA_PWRSTST_OFFSET 0x0004 +#define OMAP54XX_RM_IVA_RSTCTRL_OFFSET 0x0010 +#define OMAP54XX_RM_IVA_RSTST_OFFSET 0x0014 +#define OMAP54XX_RM_IVA_IVA_CONTEXT_OFFSET 0x0024 +#define OMAP54XX_RM_IVA_SL2_CONTEXT_OFFSET 0x002c + +/* PRM.CAM_PRM register offsets */ +#define OMAP54XX_PM_CAM_PWRSTCTRL_OFFSET 0x0000 +#define OMAP54XX_PM_CAM_PWRSTST_OFFSET 0x0004 +#define OMAP54XX_RM_CAM_ISS_CONTEXT_OFFSET 0x0024 +#define OMAP54XX_RM_CAM_FDIF_CONTEXT_OFFSET 0x002c +#define OMAP54XX_RM_CAM_CAL_CONTEXT_OFFSET 0x0034 + +/* PRM.DSS_PRM register offsets */ +#define OMAP54XX_PM_DSS_PWRSTCTRL_OFFSET 0x0000 +#define OMAP54XX_PM_DSS_PWRSTST_OFFSET 0x0004 +#define OMAP54XX_PM_DSS_DSS_WKDEP_OFFSET 0x0020 +#define OMAP54XX_RM_DSS_DSS_CONTEXT_OFFSET 0x0024 +#define OMAP54XX_RM_DSS_BB2D_CONTEXT_OFFSET 0x0034 + +/* PRM.GPU_PRM register offsets */ +#define OMAP54XX_PM_GPU_PWRSTCTRL_OFFSET 0x0000 +#define OMAP54XX_PM_GPU_PWRSTST_OFFSET 0x0004 +#define OMAP54XX_RM_GPU_GPU_CONTEXT_OFFSET 0x0024 + +/* PRM.L3INIT_PRM register offsets */ +#define OMAP54XX_PM_L3INIT_PWRSTCTRL_OFFSET 0x0000 +#define OMAP54XX_PM_L3INIT_PWRSTST_OFFSET 0x0004 +#define OMAP54XX_PM_L3INIT_MMC1_WKDEP_OFFSET 0x0028 +#define OMAP54XX_RM_L3INIT_MMC1_CONTEXT_OFFSET 0x002c +#define OMAP54XX_PM_L3INIT_MMC2_WKDEP_OFFSET 0x0030 +#define OMAP54XX_RM_L3INIT_MMC2_CONTEXT_OFFSET 0x0034 +#define OMAP54XX_PM_L3INIT_HSI_WKDEP_OFFSET 0x0038 +#define OMAP54XX_RM_L3INIT_HSI_CONTEXT_OFFSET 0x003c +#define OMAP54XX_PM_L3INIT_UNIPRO2_WKDEP_OFFSET 0x0040 +#define OMAP54XX_RM_L3INIT_UNIPRO2_CONTEXT_OFFSET 0x0044 +#define OMAP54XX_PM_L3INIT_USB_HOST_HS_WKDEP_OFFSET 0x0058 +#define OMAP54XX_RM_L3INIT_USB_HOST_HS_CONTEXT_OFFSET 0x005c +#define OMAP54XX_PM_L3INIT_USB_TLL_HS_WKDEP_OFFSET 0x0068 +#define OMAP54XX_RM_L3INIT_USB_TLL_HS_CONTEXT_OFFSET 0x006c +#define OMAP54XX_RM_L3INIT_IEEE1500_2_OCP_CONTEXT_OFFSET 0x007c +#define OMAP54XX_PM_L3INIT_SATA_WKDEP_OFFSET 0x0088 +#define OMAP54XX_RM_L3INIT_SATA_CONTEXT_OFFSET 0x008c +#define OMAP54XX_RM_L3INIT_OCP2SCP1_CONTEXT_OFFSET 0x00e4 +#define OMAP54XX_RM_L3INIT_OCP2SCP3_CONTEXT_OFFSET 0x00ec +#define OMAP54XX_PM_L3INIT_USB_OTG_SS_WKDEP_OFFSET 0x00f0 +#define OMAP54XX_RM_L3INIT_USB_OTG_SS_CONTEXT_OFFSET 0x00f4 + +/* PRM.CUSTEFUSE_PRM register offsets */ +#define OMAP54XX_PM_CUSTEFUSE_PWRSTCTRL_OFFSET 0x0000 +#define OMAP54XX_PM_CUSTEFUSE_PWRSTST_OFFSET 0x0004 +#define OMAP54XX_RM_CUSTEFUSE_EFUSE_CTRL_CUST_CONTEXT_OFFSET 0x0024 + +/* PRM.WKUPAON_PRM register offsets */ +#define OMAP54XX_RM_WKUPAON_L4_WKUP_CONTEXT_OFFSET 0x0024 +#define OMAP54XX_RM_WKUPAON_WD_TIMER1_CONTEXT_OFFSET 0x002c +#define OMAP54XX_PM_WKUPAON_WD_TIMER2_WKDEP_OFFSET 0x0030 +#define OMAP54XX_RM_WKUPAON_WD_TIMER2_CONTEXT_OFFSET 0x0034 +#define OMAP54XX_PM_WKUPAON_GPIO1_WKDEP_OFFSET 0x0038 +#define OMAP54XX_RM_WKUPAON_GPIO1_CONTEXT_OFFSET 0x003c +#define OMAP54XX_PM_WKUPAON_TIMER1_WKDEP_OFFSET 0x0040 +#define OMAP54XX_RM_WKUPAON_TIMER1_CONTEXT_OFFSET 0x0044 +#define OMAP54XX_PM_WKUPAON_TIMER12_WKDEP_OFFSET 0x0048 +#define OMAP54XX_RM_WKUPAON_TIMER12_CONTEXT_OFFSET 0x004c +#define OMAP54XX_RM_WKUPAON_COUNTER_32K_CONTEXT_OFFSET 0x0054 +#define OMAP54XX_RM_WKUPAON_SAR_RAM_CONTEXT_OFFSET 0x0064 +#define OMAP54XX_PM_WKUPAON_KBD_WKDEP_OFFSET 0x0078 +#define OMAP54XX_RM_WKUPAON_KBD_CONTEXT_OFFSET 0x007c + +/* PRM.WKUPAON_CM register offsets */ +#define OMAP54XX_CM_WKUPAON_CLKSTCTRL_OFFSET 0x0000 +#define OMAP54XX_CM_WKUPAON_L4_WKUP_CLKCTRL_OFFSET 0x0020 +#define OMAP54XX_CM_WKUPAON_L4_WKUP_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0020) +#define OMAP54XX_CM_WKUPAON_WD_TIMER1_CLKCTRL_OFFSET 0x0028 +#define OMAP54XX_CM_WKUPAON_WD_TIMER1_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0028) +#define OMAP54XX_CM_WKUPAON_WD_TIMER2_CLKCTRL_OFFSET 0x0030 +#define OMAP54XX_CM_WKUPAON_WD_TIMER2_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0030) +#define OMAP54XX_CM_WKUPAON_GPIO1_CLKCTRL_OFFSET 0x0038 +#define OMAP54XX_CM_WKUPAON_GPIO1_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0038) +#define OMAP54XX_CM_WKUPAON_TIMER1_CLKCTRL_OFFSET 0x0040 +#define OMAP54XX_CM_WKUPAON_TIMER1_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0040) +#define OMAP54XX_CM_WKUPAON_TIMER12_CLKCTRL_OFFSET 0x0048 +#define OMAP54XX_CM_WKUPAON_TIMER12_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0048) +#define OMAP54XX_CM_WKUPAON_COUNTER_32K_CLKCTRL_OFFSET 0x0050 +#define OMAP54XX_CM_WKUPAON_COUNTER_32K_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0050) +#define OMAP54XX_CM_WKUPAON_SAR_RAM_CLKCTRL_OFFSET 0x0060 +#define OMAP54XX_CM_WKUPAON_SAR_RAM_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0060) +#define OMAP54XX_CM_WKUPAON_KBD_CLKCTRL_OFFSET 0x0078 +#define OMAP54XX_CM_WKUPAON_KBD_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0078) +#define OMAP54XX_CM_WKUPAON_SCRM_CLKCTRL_OFFSET 0x0090 +#define OMAP54XX_CM_WKUPAON_SCRM_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0090) +#define OMAP54XX_CM_WKUPAON_IO_SRCOMP_CLKCTRL_OFFSET 0x0098 +#define OMAP54XX_CM_WKUPAON_IO_SRCOMP_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0098) + +/* PRM.EMU_PRM register offsets */ +#define OMAP54XX_PM_EMU_PWRSTCTRL_OFFSET 0x0000 +#define OMAP54XX_PM_EMU_PWRSTST_OFFSET 0x0004 +#define OMAP54XX_RM_EMU_DEBUGSS_CONTEXT_OFFSET 0x0024 + +/* PRM.EMU_CM register offsets */ +#define OMAP54XX_CM_EMU_CLKSTCTRL_OFFSET 0x0000 +#define OMAP54XX_CM_EMU_DYNAMICDEP_OFFSET 0x0008 +#define OMAP54XX_CM_EMU_DEBUGSS_CLKCTRL_OFFSET 0x0020 +#define OMAP54XX_CM_EMU_DEBUGSS_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_EMU_CM_INST, 0x0020) +#define OMAP54XX_CM_EMU_MPU_EMU_DBG_CLKCTRL_OFFSET 0x0028 +#define OMAP54XX_CM_EMU_MPU_EMU_DBG_CLKCTRL OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_EMU_CM_INST, 0x0028) + +/* PRM.DEVICE_PRM register offsets */ +#define OMAP54XX_PRM_RSTCTRL_OFFSET 0x0000 +#define OMAP54XX_PRM_RSTST_OFFSET 0x0004 +#define OMAP54XX_PRM_RSTTIME_OFFSET 0x0008 +#define OMAP54XX_PRM_CLKREQCTRL_OFFSET 0x000c +#define OMAP54XX_PRM_VOLTCTRL_OFFSET 0x0010 +#define OMAP54XX_PRM_PWRREQCTRL_OFFSET 0x0014 +#define OMAP54XX_PRM_PSCON_COUNT_OFFSET 0x0018 +#define OMAP54XX_PRM_IO_COUNT_OFFSET 0x001c +#define OMAP54XX_PRM_IO_PMCTRL_OFFSET 0x0020 +#define OMAP54XX_PRM_VOLTSETUP_WARMRESET_OFFSET 0x0024 +#define OMAP54XX_PRM_VOLTSETUP_CORE_OFF_OFFSET 0x0028 +#define OMAP54XX_PRM_VOLTSETUP_MPU_OFF_OFFSET 0x002c +#define OMAP54XX_PRM_VOLTSETUP_MM_OFF_OFFSET 0x0030 +#define OMAP54XX_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET 0x0034 +#define OMAP54XX_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET 0x0038 +#define OMAP54XX_PRM_VOLTSETUP_MM_RET_SLEEP_OFFSET 0x003c +#define OMAP54XX_PRM_VP_CORE_CONFIG_OFFSET 0x0040 +#define OMAP54XX_PRM_VP_CORE_STATUS_OFFSET 0x0044 +#define OMAP54XX_PRM_VP_CORE_VLIMITTO_OFFSET 0x0048 +#define OMAP54XX_PRM_VP_CORE_VOLTAGE_OFFSET 0x004c +#define OMAP54XX_PRM_VP_CORE_VSTEPMAX_OFFSET 0x0050 +#define OMAP54XX_PRM_VP_CORE_VSTEPMIN_OFFSET 0x0054 +#define OMAP54XX_PRM_VP_MPU_CONFIG_OFFSET 0x0058 +#define OMAP54XX_PRM_VP_MPU_STATUS_OFFSET 0x005c +#define OMAP54XX_PRM_VP_MPU_VLIMITTO_OFFSET 0x0060 +#define OMAP54XX_PRM_VP_MPU_VOLTAGE_OFFSET 0x0064 +#define OMAP54XX_PRM_VP_MPU_VSTEPMAX_OFFSET 0x0068 +#define OMAP54XX_PRM_VP_MPU_VSTEPMIN_OFFSET 0x006c +#define OMAP54XX_PRM_VP_MM_CONFIG_OFFSET 0x0070 +#define OMAP54XX_PRM_VP_MM_STATUS_OFFSET 0x0074 +#define OMAP54XX_PRM_VP_MM_VLIMITTO_OFFSET 0x0078 +#define OMAP54XX_PRM_VP_MM_VOLTAGE_OFFSET 0x007c +#define OMAP54XX_PRM_VP_MM_VSTEPMAX_OFFSET 0x0080 +#define OMAP54XX_PRM_VP_MM_VSTEPMIN_OFFSET 0x0084 +#define OMAP54XX_PRM_VC_SMPS_CORE_CONFIG_OFFSET 0x0088 +#define OMAP54XX_PRM_VC_SMPS_MM_CONFIG_OFFSET 0x008c +#define OMAP54XX_PRM_VC_SMPS_MPU_CONFIG_OFFSET 0x0090 +#define OMAP54XX_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET 0x0094 +#define OMAP54XX_PRM_VC_VAL_CMD_VDD_MM_L_OFFSET 0x0098 +#define OMAP54XX_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET 0x009c +#define OMAP54XX_PRM_VC_VAL_BYPASS_OFFSET 0x00a0 +#define OMAP54XX_PRM_VC_CORE_ERRST_OFFSET 0x00a4 +#define OMAP54XX_PRM_VC_MM_ERRST_OFFSET 0x00a8 +#define OMAP54XX_PRM_VC_MPU_ERRST_OFFSET 0x00ac +#define OMAP54XX_PRM_VC_BYPASS_ERRST_OFFSET 0x00b0 +#define OMAP54XX_PRM_VC_CFG_I2C_MODE_OFFSET 0x00b4 +#define OMAP54XX_PRM_VC_CFG_I2C_CLK_OFFSET 0x00b8 +#define OMAP54XX_PRM_SRAM_COUNT_OFFSET 0x00bc +#define OMAP54XX_PRM_SRAM_WKUP_SETUP_OFFSET 0x00c0 +#define OMAP54XX_PRM_SLDO_CORE_SETUP_OFFSET 0x00c4 +#define OMAP54XX_PRM_SLDO_CORE_CTRL_OFFSET 0x00c8 +#define OMAP54XX_PRM_SLDO_MPU_SETUP_OFFSET 0x00cc +#define OMAP54XX_PRM_SLDO_MPU_CTRL_OFFSET 0x00d0 +#define OMAP54XX_PRM_SLDO_MM_SETUP_OFFSET 0x00d4 +#define OMAP54XX_PRM_SLDO_MM_CTRL_OFFSET 0x00d8 +#define OMAP54XX_PRM_ABBLDO_MPU_SETUP_OFFSET 0x00dc +#define OMAP54XX_PRM_ABBLDO_MPU_CTRL_OFFSET 0x00e0 +#define OMAP54XX_PRM_ABBLDO_MM_SETUP_OFFSET 0x00e4 +#define OMAP54XX_PRM_ABBLDO_MM_CTRL_OFFSET 0x00e8 +#define OMAP54XX_PRM_BANDGAP_SETUP_OFFSET 0x00ec +#define OMAP54XX_PRM_DEVICE_OFF_CTRL_OFFSET 0x00f0 +#define OMAP54XX_PRM_PHASE1_CNDP_OFFSET 0x00f4 +#define OMAP54XX_PRM_PHASE2A_CNDP_OFFSET 0x00f8 +#define OMAP54XX_PRM_PHASE2B_CNDP_OFFSET 0x00fc +#define OMAP54XX_PRM_MODEM_IF_CTRL_OFFSET 0x0100 +#define OMAP54XX_PRM_VOLTST_MPU_OFFSET 0x0110 +#define OMAP54XX_PRM_VOLTST_MM_OFFSET 0x0114 + +#endif diff --git a/arch/arm/mach-omap2/prm7xx.h b/arch/arm/mach-omap2/prm7xx.h new file mode 100644 index 00000000000..d92a8404edc --- /dev/null +++ b/arch/arm/mach-omap2/prm7xx.h @@ -0,0 +1,678 @@ +/* + * DRA7xx PRM instance offset macros + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * + * Generated by code originally written by: + * Paul Walmsley (paul@pwsan.com) + * Rajendra Nayak (rnayak@ti.com) + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_PRM7XX_H +#define __ARCH_ARM_MACH_OMAP2_PRM7XX_H + +#include "prm44xx_54xx.h" +#include "prcm-common.h" +#include "prm.h" + +#define DRA7XX_PRM_BASE 0x4ae06000 + +#define DRA7XX_PRM_REGADDR(inst, reg) \ + OMAP2_L4_IO_ADDRESS(DRA7XX_PRM_BASE + (inst) + (reg)) + + +/* PRM instances */ +#define DRA7XX_PRM_OCP_SOCKET_INST 0x0000 +#define DRA7XX_PRM_CKGEN_INST 0x0100 +#define DRA7XX_PRM_MPU_INST 0x0300 +#define DRA7XX_PRM_DSP1_INST 0x0400 +#define DRA7XX_PRM_IPU_INST 0x0500 +#define DRA7XX_PRM_COREAON_INST 0x0628 +#define DRA7XX_PRM_CORE_INST 0x0700 +#define DRA7XX_PRM_IVA_INST 0x0f00 +#define DRA7XX_PRM_CAM_INST 0x1000 +#define DRA7XX_PRM_DSS_INST 0x1100 +#define DRA7XX_PRM_GPU_INST 0x1200 +#define DRA7XX_PRM_L3INIT_INST 0x1300 +#define DRA7XX_PRM_L4PER_INST 0x1400 +#define DRA7XX_PRM_CUSTEFUSE_INST 0x1600 +#define DRA7XX_PRM_WKUPAON_INST 0x1724 +#define DRA7XX_PRM_WKUPAON_CM_INST 0x1800 +#define DRA7XX_PRM_EMU_INST 0x1900 +#define DRA7XX_PRM_EMU_CM_INST 0x1a00 +#define DRA7XX_PRM_DSP2_INST 0x1b00 +#define DRA7XX_PRM_EVE1_INST 0x1b40 +#define DRA7XX_PRM_EVE2_INST 0x1b80 +#define DRA7XX_PRM_EVE3_INST 0x1bc0 +#define DRA7XX_PRM_EVE4_INST 0x1c00 +#define DRA7XX_PRM_RTC_INST 0x1c60 +#define DRA7XX_PRM_VPE_INST 0x1c80 +#define DRA7XX_PRM_DEVICE_INST 0x1d00 +#define DRA7XX_PRM_INSTR_INST 0x1f00 + +/* PRM clockdomain register offsets (from instance start) */ +#define DRA7XX_PRM_WKUPAON_CM_WKUPAON_CDOFFS 0x0000 +#define DRA7XX_PRM_EMU_CM_EMU_CDOFFS 0x0000 + +/* PRM */ + +/* PRM.OCP_SOCKET_PRM register offsets */ +#define DRA7XX_REVISION_PRM_OFFSET 0x0000 +#define DRA7XX_PRM_IRQSTATUS_MPU_OFFSET 0x0010 +#define DRA7XX_PRM_IRQSTATUS_MPU_2_OFFSET 0x0014 +#define DRA7XX_PRM_IRQENABLE_MPU_OFFSET 0x0018 +#define DRA7XX_PRM_IRQENABLE_MPU_2_OFFSET 0x001c +#define DRA7XX_PRM_IRQSTATUS_IPU2_OFFSET 0x0020 +#define DRA7XX_PRM_IRQENABLE_IPU2_OFFSET 0x0028 +#define DRA7XX_PRM_IRQSTATUS_DSP1_OFFSET 0x0030 +#define DRA7XX_PRM_IRQENABLE_DSP1_OFFSET 0x0038 +#define DRA7XX_CM_PRM_PROFILING_CLKCTRL_OFFSET 0x0040 +#define DRA7XX_CM_PRM_PROFILING_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_OCP_SOCKET_INST, 0x0040) +#define DRA7XX_PRM_IRQENABLE_DSP2_OFFSET 0x0044 +#define DRA7XX_PRM_IRQENABLE_EVE1_OFFSET 0x0048 +#define DRA7XX_PRM_IRQENABLE_EVE2_OFFSET 0x004c +#define DRA7XX_PRM_IRQENABLE_EVE3_OFFSET 0x0050 +#define DRA7XX_PRM_IRQENABLE_EVE4_OFFSET 0x0054 +#define DRA7XX_PRM_IRQENABLE_IPU1_OFFSET 0x0058 +#define DRA7XX_PRM_IRQSTATUS_DSP2_OFFSET 0x005c +#define DRA7XX_PRM_IRQSTATUS_EVE1_OFFSET 0x0060 +#define DRA7XX_PRM_IRQSTATUS_EVE2_OFFSET 0x0064 +#define DRA7XX_PRM_IRQSTATUS_EVE3_OFFSET 0x0068 +#define DRA7XX_PRM_IRQSTATUS_EVE4_OFFSET 0x006c +#define DRA7XX_PRM_IRQSTATUS_IPU1_OFFSET 0x0070 +#define DRA7XX_PRM_DEBUG_CFG1_OFFSET 0x00e4 +#define DRA7XX_PRM_DEBUG_CFG2_OFFSET 0x00e8 +#define DRA7XX_PRM_DEBUG_CFG3_OFFSET 0x00ec +#define DRA7XX_PRM_DEBUG_OUT_OFFSET 0x00f4 + +/* PRM.CKGEN_PRM register offsets */ +#define DRA7XX_CM_CLKSEL_SYSCLK1_OFFSET 0x0000 +#define DRA7XX_CM_CLKSEL_SYSCLK1 DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0000) +#define DRA7XX_CM_CLKSEL_WKUPAON_OFFSET 0x0008 +#define DRA7XX_CM_CLKSEL_WKUPAON DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0008) +#define DRA7XX_CM_CLKSEL_ABE_PLL_REF_OFFSET 0x000c +#define DRA7XX_CM_CLKSEL_ABE_PLL_REF DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x000c) +#define DRA7XX_CM_CLKSEL_SYS_OFFSET 0x0010 +#define DRA7XX_CM_CLKSEL_SYS DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0010) +#define DRA7XX_CM_CLKSEL_ABE_PLL_BYPAS_OFFSET 0x0014 +#define DRA7XX_CM_CLKSEL_ABE_PLL_BYPAS DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0014) +#define DRA7XX_CM_CLKSEL_ABE_PLL_SYS_OFFSET 0x0018 +#define DRA7XX_CM_CLKSEL_ABE_PLL_SYS DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0018) +#define DRA7XX_CM_CLKSEL_ABE_24M_OFFSET 0x001c +#define DRA7XX_CM_CLKSEL_ABE_24M DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x001c) +#define DRA7XX_CM_CLKSEL_ABE_SYS_OFFSET 0x0020 +#define DRA7XX_CM_CLKSEL_ABE_SYS DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0020) +#define DRA7XX_CM_CLKSEL_HDMI_MCASP_AUX_OFFSET 0x0024 +#define DRA7XX_CM_CLKSEL_HDMI_MCASP_AUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0024) +#define DRA7XX_CM_CLKSEL_HDMI_TIMER_OFFSET 0x0028 +#define DRA7XX_CM_CLKSEL_HDMI_TIMER DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0028) +#define DRA7XX_CM_CLKSEL_MCASP_SYS_OFFSET 0x002c +#define DRA7XX_CM_CLKSEL_MCASP_SYS DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x002c) +#define DRA7XX_CM_CLKSEL_MLBP_MCASP_OFFSET 0x0030 +#define DRA7XX_CM_CLKSEL_MLBP_MCASP DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0030) +#define DRA7XX_CM_CLKSEL_MLB_MCASP_OFFSET 0x0034 +#define DRA7XX_CM_CLKSEL_MLB_MCASP DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0034) +#define DRA7XX_CM_CLKSEL_PER_ABE_X1_GFCLK_MCASP_AUX_OFFSET 0x0038 +#define DRA7XX_CM_CLKSEL_PER_ABE_X1_GFCLK_MCASP_AUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0038) +#define DRA7XX_CM_CLKSEL_SYS_CLK1_32K_OFFSET 0x0040 +#define DRA7XX_CM_CLKSEL_SYS_CLK1_32K DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0040) +#define DRA7XX_CM_CLKSEL_TIMER_SYS_OFFSET 0x0044 +#define DRA7XX_CM_CLKSEL_TIMER_SYS DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0044) +#define DRA7XX_CM_CLKSEL_VIDEO1_MCASP_AUX_OFFSET 0x0048 +#define DRA7XX_CM_CLKSEL_VIDEO1_MCASP_AUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0048) +#define DRA7XX_CM_CLKSEL_VIDEO1_TIMER_OFFSET 0x004c +#define DRA7XX_CM_CLKSEL_VIDEO1_TIMER DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x004c) +#define DRA7XX_CM_CLKSEL_VIDEO2_MCASP_AUX_OFFSET 0x0050 +#define DRA7XX_CM_CLKSEL_VIDEO2_MCASP_AUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0050) +#define DRA7XX_CM_CLKSEL_VIDEO2_TIMER_OFFSET 0x0054 +#define DRA7XX_CM_CLKSEL_VIDEO2_TIMER DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0054) +#define DRA7XX_CM_CLKSEL_CLKOUTMUX0_OFFSET 0x0058 +#define DRA7XX_CM_CLKSEL_CLKOUTMUX0 DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0058) +#define DRA7XX_CM_CLKSEL_CLKOUTMUX1_OFFSET 0x005c +#define DRA7XX_CM_CLKSEL_CLKOUTMUX1 DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x005c) +#define DRA7XX_CM_CLKSEL_CLKOUTMUX2_OFFSET 0x0060 +#define DRA7XX_CM_CLKSEL_CLKOUTMUX2 DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0060) +#define DRA7XX_CM_CLKSEL_HDMI_PLL_SYS_OFFSET 0x0064 +#define DRA7XX_CM_CLKSEL_HDMI_PLL_SYS DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0064) +#define DRA7XX_CM_CLKSEL_VIDEO1_PLL_SYS_OFFSET 0x0068 +#define DRA7XX_CM_CLKSEL_VIDEO1_PLL_SYS DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0068) +#define DRA7XX_CM_CLKSEL_VIDEO2_PLL_SYS_OFFSET 0x006c +#define DRA7XX_CM_CLKSEL_VIDEO2_PLL_SYS DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x006c) +#define DRA7XX_CM_CLKSEL_ABE_CLK_DIV_OFFSET 0x0070 +#define DRA7XX_CM_CLKSEL_ABE_CLK_DIV DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0070) +#define DRA7XX_CM_CLKSEL_ABE_GICLK_DIV_OFFSET 0x0074 +#define DRA7XX_CM_CLKSEL_ABE_GICLK_DIV DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0074) +#define DRA7XX_CM_CLKSEL_AESS_FCLK_DIV_OFFSET 0x0078 +#define DRA7XX_CM_CLKSEL_AESS_FCLK_DIV DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0078) +#define DRA7XX_CM_CLKSEL_EVE_CLK_OFFSET 0x0080 +#define DRA7XX_CM_CLKSEL_EVE_CLK DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0080) +#define DRA7XX_CM_CLKSEL_USB_OTG_CLK_CLKOUTMUX_OFFSET 0x0084 +#define DRA7XX_CM_CLKSEL_USB_OTG_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0084) +#define DRA7XX_CM_CLKSEL_CORE_DPLL_OUT_CLK_CLKOUTMUX_OFFSET 0x0088 +#define DRA7XX_CM_CLKSEL_CORE_DPLL_OUT_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0088) +#define DRA7XX_CM_CLKSEL_DSP_GFCLK_CLKOUTMUX_OFFSET 0x008c +#define DRA7XX_CM_CLKSEL_DSP_GFCLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x008c) +#define DRA7XX_CM_CLKSEL_EMIF_PHY_GCLK_CLKOUTMUX_OFFSET 0x0090 +#define DRA7XX_CM_CLKSEL_EMIF_PHY_GCLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0090) +#define DRA7XX_CM_CLKSEL_EMU_CLK_CLKOUTMUX_OFFSET 0x0094 +#define DRA7XX_CM_CLKSEL_EMU_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0094) +#define DRA7XX_CM_CLKSEL_FUNC_96M_AON_CLK_CLKOUTMUX_OFFSET 0x0098 +#define DRA7XX_CM_CLKSEL_FUNC_96M_AON_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x0098) +#define DRA7XX_CM_CLKSEL_GMAC_250M_CLK_CLKOUTMUX_OFFSET 0x009c +#define DRA7XX_CM_CLKSEL_GMAC_250M_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x009c) +#define DRA7XX_CM_CLKSEL_GPU_GCLK_CLKOUTMUX_OFFSET 0x00a0 +#define DRA7XX_CM_CLKSEL_GPU_GCLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00a0) +#define DRA7XX_CM_CLKSEL_HDMI_CLK_CLKOUTMUX_OFFSET 0x00a4 +#define DRA7XX_CM_CLKSEL_HDMI_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00a4) +#define DRA7XX_CM_CLKSEL_IVA_GCLK_CLKOUTMUX_OFFSET 0x00a8 +#define DRA7XX_CM_CLKSEL_IVA_GCLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00a8) +#define DRA7XX_CM_CLKSEL_L3INIT_480M_GFCLK_CLKOUTMUX_OFFSET 0x00ac +#define DRA7XX_CM_CLKSEL_L3INIT_480M_GFCLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00ac) +#define DRA7XX_CM_CLKSEL_MPU_GCLK_CLKOUTMUX_OFFSET 0x00b0 +#define DRA7XX_CM_CLKSEL_MPU_GCLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00b0) +#define DRA7XX_CM_CLKSEL_PCIE1_CLK_CLKOUTMUX_OFFSET 0x00b4 +#define DRA7XX_CM_CLKSEL_PCIE1_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00b4) +#define DRA7XX_CM_CLKSEL_PCIE2_CLK_CLKOUTMUX_OFFSET 0x00b8 +#define DRA7XX_CM_CLKSEL_PCIE2_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00b8) +#define DRA7XX_CM_CLKSEL_PER_ABE_X1_CLK_CLKOUTMUX_OFFSET 0x00bc +#define DRA7XX_CM_CLKSEL_PER_ABE_X1_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00bc) +#define DRA7XX_CM_CLKSEL_SATA_CLK_CLKOUTMUX_OFFSET 0x00c0 +#define DRA7XX_CM_CLKSEL_SATA_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00c0) +#define DRA7XX_CM_CLKSEL_SECURE_32K_CLK_CLKOUTMUX_OFFSET 0x00c4 +#define DRA7XX_CM_CLKSEL_SECURE_32K_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00c4) +#define DRA7XX_CM_CLKSEL_SYS_CLK1_CLKOUTMUX_OFFSET 0x00c8 +#define DRA7XX_CM_CLKSEL_SYS_CLK1_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00c8) +#define DRA7XX_CM_CLKSEL_SYS_CLK2_CLKOUTMUX_OFFSET 0x00cc +#define DRA7XX_CM_CLKSEL_SYS_CLK2_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00cc) +#define DRA7XX_CM_CLKSEL_VIDEO1_CLK_CLKOUTMUX_OFFSET 0x00d0 +#define DRA7XX_CM_CLKSEL_VIDEO1_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00d0) +#define DRA7XX_CM_CLKSEL_VIDEO2_CLK_CLKOUTMUX_OFFSET 0x00d4 +#define DRA7XX_CM_CLKSEL_VIDEO2_CLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00d4) +#define DRA7XX_CM_CLKSEL_ABE_LP_CLK_OFFSET 0x00d8 +#define DRA7XX_CM_CLKSEL_ABE_LP_CLK DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00d8) +#define DRA7XX_CM_CLKSEL_ADC_GFCLK_OFFSET 0x00dc +#define DRA7XX_CM_CLKSEL_ADC_GFCLK DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00dc) +#define DRA7XX_CM_CLKSEL_EVE_GFCLK_CLKOUTMUX_OFFSET 0x00e0 +#define DRA7XX_CM_CLKSEL_EVE_GFCLK_CLKOUTMUX DRA7XX_PRM_REGADDR(DRA7XX_PRM_CKGEN_INST, 0x00e0) + +/* PRM.MPU_PRM register offsets */ +#define DRA7XX_PM_MPU_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_MPU_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_MPU_MPU_CONTEXT_OFFSET 0x0024 + +/* PRM.DSP1_PRM register offsets */ +#define DRA7XX_PM_DSP1_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_DSP1_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_DSP1_RSTCTRL_OFFSET 0x0010 +#define DRA7XX_RM_DSP1_RSTST_OFFSET 0x0014 +#define DRA7XX_RM_DSP1_DSP1_CONTEXT_OFFSET 0x0024 + +/* PRM.IPU_PRM register offsets */ +#define DRA7XX_PM_IPU_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_IPU_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_IPU1_RSTCTRL_OFFSET 0x0010 +#define DRA7XX_RM_IPU1_RSTST_OFFSET 0x0014 +#define DRA7XX_RM_IPU1_IPU1_CONTEXT_OFFSET 0x0024 +#define DRA7XX_PM_IPU_MCASP1_WKDEP_OFFSET 0x0050 +#define DRA7XX_RM_IPU_MCASP1_CONTEXT_OFFSET 0x0054 +#define DRA7XX_PM_IPU_TIMER5_WKDEP_OFFSET 0x0058 +#define DRA7XX_RM_IPU_TIMER5_CONTEXT_OFFSET 0x005c +#define DRA7XX_PM_IPU_TIMER6_WKDEP_OFFSET 0x0060 +#define DRA7XX_RM_IPU_TIMER6_CONTEXT_OFFSET 0x0064 +#define DRA7XX_PM_IPU_TIMER7_WKDEP_OFFSET 0x0068 +#define DRA7XX_RM_IPU_TIMER7_CONTEXT_OFFSET 0x006c +#define DRA7XX_PM_IPU_TIMER8_WKDEP_OFFSET 0x0070 +#define DRA7XX_RM_IPU_TIMER8_CONTEXT_OFFSET 0x0074 +#define DRA7XX_PM_IPU_I2C5_WKDEP_OFFSET 0x0078 +#define DRA7XX_RM_IPU_I2C5_CONTEXT_OFFSET 0x007c +#define DRA7XX_PM_IPU_UART6_WKDEP_OFFSET 0x0080 +#define DRA7XX_RM_IPU_UART6_CONTEXT_OFFSET 0x0084 + +/* PRM.COREAON_PRM register offsets */ +#define DRA7XX_PM_COREAON_SMARTREFLEX_MPU_WKDEP_OFFSET 0x0000 +#define DRA7XX_RM_COREAON_SMARTREFLEX_MPU_CONTEXT_OFFSET 0x0004 +#define DRA7XX_PM_COREAON_SMARTREFLEX_CORE_WKDEP_OFFSET 0x0010 +#define DRA7XX_RM_COREAON_SMARTREFLEX_CORE_CONTEXT_OFFSET 0x0014 +#define DRA7XX_PM_COREAON_SMARTREFLEX_GPU_WKDEP_OFFSET 0x0030 +#define DRA7XX_RM_COREAON_SMARTREFLEX_GPU_CONTEXT_OFFSET 0x0034 +#define DRA7XX_PM_COREAON_SMARTREFLEX_DSPEVE_WKDEP_OFFSET 0x0040 +#define DRA7XX_RM_COREAON_SMARTREFLEX_DSPEVE_CONTEXT_OFFSET 0x0044 +#define DRA7XX_PM_COREAON_SMARTREFLEX_IVAHD_WKDEP_OFFSET 0x0050 +#define DRA7XX_RM_COREAON_SMARTREFLEX_IVAHD_CONTEXT_OFFSET 0x0054 +#define DRA7XX_RM_COREAON_DUMMY_MODULE1_CONTEXT_OFFSET 0x0084 +#define DRA7XX_RM_COREAON_DUMMY_MODULE2_CONTEXT_OFFSET 0x0094 +#define DRA7XX_RM_COREAON_DUMMY_MODULE3_CONTEXT_OFFSET 0x00a4 +#define DRA7XX_RM_COREAON_DUMMY_MODULE4_CONTEXT_OFFSET 0x00b4 + +/* PRM.CORE_PRM register offsets */ +#define DRA7XX_PM_CORE_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_CORE_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_L3MAIN1_L3_MAIN_1_CONTEXT_OFFSET 0x0024 +#define DRA7XX_RM_L3MAIN1_GPMC_CONTEXT_OFFSET 0x002c +#define DRA7XX_RM_L3MAIN1_MMU_EDMA_CONTEXT_OFFSET 0x0034 +#define DRA7XX_PM_L3MAIN1_OCMC_RAM1_WKDEP_OFFSET 0x0050 +#define DRA7XX_RM_L3MAIN1_OCMC_RAM1_CONTEXT_OFFSET 0x0054 +#define DRA7XX_PM_L3MAIN1_OCMC_RAM2_WKDEP_OFFSET 0x0058 +#define DRA7XX_RM_L3MAIN1_OCMC_RAM2_CONTEXT_OFFSET 0x005c +#define DRA7XX_PM_L3MAIN1_OCMC_RAM3_WKDEP_OFFSET 0x0060 +#define DRA7XX_RM_L3MAIN1_OCMC_RAM3_CONTEXT_OFFSET 0x0064 +#define DRA7XX_RM_L3MAIN1_OCMC_ROM_CONTEXT_OFFSET 0x006c +#define DRA7XX_PM_L3MAIN1_TPCC_WKDEP_OFFSET 0x0070 +#define DRA7XX_RM_L3MAIN1_TPCC_CONTEXT_OFFSET 0x0074 +#define DRA7XX_PM_L3MAIN1_TPTC1_WKDEP_OFFSET 0x0078 +#define DRA7XX_RM_L3MAIN1_TPTC1_CONTEXT_OFFSET 0x007c +#define DRA7XX_PM_L3MAIN1_TPTC2_WKDEP_OFFSET 0x0080 +#define DRA7XX_RM_L3MAIN1_TPTC2_CONTEXT_OFFSET 0x0084 +#define DRA7XX_RM_L3MAIN1_VCP1_CONTEXT_OFFSET 0x008c +#define DRA7XX_RM_L3MAIN1_VCP2_CONTEXT_OFFSET 0x0094 +#define DRA7XX_RM_L3MAIN1_SPARE_CME_CONTEXT_OFFSET 0x009c +#define DRA7XX_RM_L3MAIN1_SPARE_HDMI_CONTEXT_OFFSET 0x00a4 +#define DRA7XX_RM_L3MAIN1_SPARE_ICM_CONTEXT_OFFSET 0x00ac +#define DRA7XX_RM_L3MAIN1_SPARE_IVA2_CONTEXT_OFFSET 0x00b4 +#define DRA7XX_RM_L3MAIN1_SPARE_SATA2_CONTEXT_OFFSET 0x00bc +#define DRA7XX_RM_L3MAIN1_SPARE_UNKNOWN4_CONTEXT_OFFSET 0x00c4 +#define DRA7XX_RM_L3MAIN1_SPARE_UNKNOWN5_CONTEXT_OFFSET 0x00cc +#define DRA7XX_RM_L3MAIN1_SPARE_UNKNOWN6_CONTEXT_OFFSET 0x00d4 +#define DRA7XX_RM_L3MAIN1_SPARE_VIDEOPLL1_CONTEXT_OFFSET 0x00dc +#define DRA7XX_RM_L3MAIN1_SPARE_VIDEOPLL2_CONTEXT_OFFSET 0x00f4 +#define DRA7XX_RM_L3MAIN1_SPARE_VIDEOPLL3_CONTEXT_OFFSET 0x00fc +#define DRA7XX_RM_IPU2_RSTCTRL_OFFSET 0x0210 +#define DRA7XX_RM_IPU2_RSTST_OFFSET 0x0214 +#define DRA7XX_RM_IPU2_IPU2_CONTEXT_OFFSET 0x0224 +#define DRA7XX_RM_DMA_DMA_SYSTEM_CONTEXT_OFFSET 0x0324 +#define DRA7XX_RM_EMIF_DMM_CONTEXT_OFFSET 0x0424 +#define DRA7XX_RM_EMIF_EMIF_OCP_FW_CONTEXT_OFFSET 0x042c +#define DRA7XX_RM_EMIF_EMIF1_CONTEXT_OFFSET 0x0434 +#define DRA7XX_RM_EMIF_EMIF2_CONTEXT_OFFSET 0x043c +#define DRA7XX_RM_EMIF_EMIF_DLL_CONTEXT_OFFSET 0x0444 +#define DRA7XX_RM_ATL_ATL_CONTEXT_OFFSET 0x0524 +#define DRA7XX_RM_L4CFG_L4_CFG_CONTEXT_OFFSET 0x0624 +#define DRA7XX_RM_L4CFG_SPINLOCK_CONTEXT_OFFSET 0x062c +#define DRA7XX_RM_L4CFG_MAILBOX1_CONTEXT_OFFSET 0x0634 +#define DRA7XX_RM_L4CFG_SAR_ROM_CONTEXT_OFFSET 0x063c +#define DRA7XX_RM_L4CFG_OCP2SCP2_CONTEXT_OFFSET 0x0644 +#define DRA7XX_RM_L4CFG_MAILBOX2_CONTEXT_OFFSET 0x064c +#define DRA7XX_RM_L4CFG_MAILBOX3_CONTEXT_OFFSET 0x0654 +#define DRA7XX_RM_L4CFG_MAILBOX4_CONTEXT_OFFSET 0x065c +#define DRA7XX_RM_L4CFG_MAILBOX5_CONTEXT_OFFSET 0x0664 +#define DRA7XX_RM_L4CFG_MAILBOX6_CONTEXT_OFFSET 0x066c +#define DRA7XX_RM_L4CFG_MAILBOX7_CONTEXT_OFFSET 0x0674 +#define DRA7XX_RM_L4CFG_MAILBOX8_CONTEXT_OFFSET 0x067c +#define DRA7XX_RM_L4CFG_MAILBOX9_CONTEXT_OFFSET 0x0684 +#define DRA7XX_RM_L4CFG_MAILBOX10_CONTEXT_OFFSET 0x068c +#define DRA7XX_RM_L4CFG_MAILBOX11_CONTEXT_OFFSET 0x0694 +#define DRA7XX_RM_L4CFG_MAILBOX12_CONTEXT_OFFSET 0x069c +#define DRA7XX_RM_L4CFG_MAILBOX13_CONTEXT_OFFSET 0x06a4 +#define DRA7XX_RM_L4CFG_SPARE_SMARTREFLEX_RTC_CONTEXT_OFFSET 0x06ac +#define DRA7XX_RM_L4CFG_SPARE_SMARTREFLEX_SDRAM_CONTEXT_OFFSET 0x06b4 +#define DRA7XX_RM_L4CFG_SPARE_SMARTREFLEX_WKUP_CONTEXT_OFFSET 0x06bc +#define DRA7XX_RM_L4CFG_IO_DELAY_BLOCK_CONTEXT_OFFSET 0x06c4 +#define DRA7XX_RM_L3INSTR_L3_MAIN_2_CONTEXT_OFFSET 0x0724 +#define DRA7XX_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET 0x072c +#define DRA7XX_RM_L3INSTR_OCP_WP_NOC_CONTEXT_OFFSET 0x0744 + +/* PRM.IVA_PRM register offsets */ +#define DRA7XX_PM_IVA_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_IVA_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_IVA_RSTCTRL_OFFSET 0x0010 +#define DRA7XX_RM_IVA_RSTST_OFFSET 0x0014 +#define DRA7XX_RM_IVA_IVA_CONTEXT_OFFSET 0x0024 +#define DRA7XX_RM_IVA_SL2_CONTEXT_OFFSET 0x002c + +/* PRM.CAM_PRM register offsets */ +#define DRA7XX_PM_CAM_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_CAM_PWRSTST_OFFSET 0x0004 +#define DRA7XX_PM_CAM_VIP1_WKDEP_OFFSET 0x0020 +#define DRA7XX_RM_CAM_VIP1_CONTEXT_OFFSET 0x0024 +#define DRA7XX_PM_CAM_VIP2_WKDEP_OFFSET 0x0028 +#define DRA7XX_RM_CAM_VIP2_CONTEXT_OFFSET 0x002c +#define DRA7XX_PM_CAM_VIP3_WKDEP_OFFSET 0x0030 +#define DRA7XX_RM_CAM_VIP3_CONTEXT_OFFSET 0x0034 +#define DRA7XX_RM_CAM_LVDSRX_CONTEXT_OFFSET 0x003c +#define DRA7XX_RM_CAM_CSI1_CONTEXT_OFFSET 0x0044 +#define DRA7XX_RM_CAM_CSI2_CONTEXT_OFFSET 0x004c + +/* PRM.DSS_PRM register offsets */ +#define DRA7XX_PM_DSS_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_DSS_PWRSTST_OFFSET 0x0004 +#define DRA7XX_PM_DSS_DSS_WKDEP_OFFSET 0x0020 +#define DRA7XX_RM_DSS_DSS_CONTEXT_OFFSET 0x0024 +#define DRA7XX_PM_DSS_DSS2_WKDEP_OFFSET 0x0028 +#define DRA7XX_RM_DSS_BB2D_CONTEXT_OFFSET 0x0034 +#define DRA7XX_RM_DSS_SDVENC_CONTEXT_OFFSET 0x003c + +/* PRM.GPU_PRM register offsets */ +#define DRA7XX_PM_GPU_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_GPU_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_GPU_GPU_CONTEXT_OFFSET 0x0024 + +/* PRM.L3INIT_PRM register offsets */ +#define DRA7XX_PM_L3INIT_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_L3INIT_PWRSTST_OFFSET 0x0004 +#define DRA7XX_PM_L3INIT_MMC1_WKDEP_OFFSET 0x0028 +#define DRA7XX_RM_L3INIT_MMC1_CONTEXT_OFFSET 0x002c +#define DRA7XX_PM_L3INIT_MMC2_WKDEP_OFFSET 0x0030 +#define DRA7XX_RM_L3INIT_MMC2_CONTEXT_OFFSET 0x0034 +#define DRA7XX_PM_L3INIT_USB_OTG_SS2_WKDEP_OFFSET 0x0040 +#define DRA7XX_RM_L3INIT_USB_OTG_SS2_CONTEXT_OFFSET 0x0044 +#define DRA7XX_PM_L3INIT_USB_OTG_SS3_WKDEP_OFFSET 0x0048 +#define DRA7XX_RM_L3INIT_USB_OTG_SS3_CONTEXT_OFFSET 0x004c +#define DRA7XX_PM_L3INIT_USB_OTG_SS4_WKDEP_OFFSET 0x0050 +#define DRA7XX_RM_L3INIT_USB_OTG_SS4_CONTEXT_OFFSET 0x0054 +#define DRA7XX_RM_L3INIT_MLB_SS_CONTEXT_OFFSET 0x005c +#define DRA7XX_RM_L3INIT_IEEE1500_2_OCP_CONTEXT_OFFSET 0x007c +#define DRA7XX_PM_L3INIT_SATA_WKDEP_OFFSET 0x0088 +#define DRA7XX_RM_L3INIT_SATA_CONTEXT_OFFSET 0x008c +#define DRA7XX_RM_GMAC_GMAC_CONTEXT_OFFSET 0x00d4 +#define DRA7XX_RM_L3INIT_OCP2SCP1_CONTEXT_OFFSET 0x00e4 +#define DRA7XX_RM_L3INIT_OCP2SCP3_CONTEXT_OFFSET 0x00ec +#define DRA7XX_PM_L3INIT_USB_OTG_SS1_WKDEP_OFFSET 0x00f0 +#define DRA7XX_RM_L3INIT_USB_OTG_SS1_CONTEXT_OFFSET 0x00f4 + +/* PRM.L4PER_PRM register offsets */ +#define DRA7XX_PM_L4PER_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_L4PER_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_L4PER2_L4PER2_CONTEXT_OFFSET 0x000c +#define DRA7XX_RM_L4PER3_L4PER3_CONTEXT_OFFSET 0x0014 +#define DRA7XX_RM_L4PER2_PRUSS1_CONTEXT_OFFSET 0x001c +#define DRA7XX_RM_L4PER2_PRUSS2_CONTEXT_OFFSET 0x0024 +#define DRA7XX_PM_L4PER_TIMER10_WKDEP_OFFSET 0x0028 +#define DRA7XX_RM_L4PER_TIMER10_CONTEXT_OFFSET 0x002c +#define DRA7XX_PM_L4PER_TIMER11_WKDEP_OFFSET 0x0030 +#define DRA7XX_RM_L4PER_TIMER11_CONTEXT_OFFSET 0x0034 +#define DRA7XX_PM_L4PER_TIMER2_WKDEP_OFFSET 0x0038 +#define DRA7XX_RM_L4PER_TIMER2_CONTEXT_OFFSET 0x003c +#define DRA7XX_PM_L4PER_TIMER3_WKDEP_OFFSET 0x0040 +#define DRA7XX_RM_L4PER_TIMER3_CONTEXT_OFFSET 0x0044 +#define DRA7XX_PM_L4PER_TIMER4_WKDEP_OFFSET 0x0048 +#define DRA7XX_RM_L4PER_TIMER4_CONTEXT_OFFSET 0x004c +#define DRA7XX_PM_L4PER_TIMER9_WKDEP_OFFSET 0x0050 +#define DRA7XX_RM_L4PER_TIMER9_CONTEXT_OFFSET 0x0054 +#define DRA7XX_RM_L4PER_ELM_CONTEXT_OFFSET 0x005c +#define DRA7XX_PM_L4PER_GPIO2_WKDEP_OFFSET 0x0060 +#define DRA7XX_RM_L4PER_GPIO2_CONTEXT_OFFSET 0x0064 +#define DRA7XX_PM_L4PER_GPIO3_WKDEP_OFFSET 0x0068 +#define DRA7XX_RM_L4PER_GPIO3_CONTEXT_OFFSET 0x006c +#define DRA7XX_PM_L4PER_GPIO4_WKDEP_OFFSET 0x0070 +#define DRA7XX_RM_L4PER_GPIO4_CONTEXT_OFFSET 0x0074 +#define DRA7XX_PM_L4PER_GPIO5_WKDEP_OFFSET 0x0078 +#define DRA7XX_RM_L4PER_GPIO5_CONTEXT_OFFSET 0x007c +#define DRA7XX_PM_L4PER_GPIO6_WKDEP_OFFSET 0x0080 +#define DRA7XX_RM_L4PER_GPIO6_CONTEXT_OFFSET 0x0084 +#define DRA7XX_RM_L4PER_HDQ1W_CONTEXT_OFFSET 0x008c +#define DRA7XX_RM_L4PER2_PWMSS2_CONTEXT_OFFSET 0x0094 +#define DRA7XX_RM_L4PER2_PWMSS3_CONTEXT_OFFSET 0x009c +#define DRA7XX_PM_L4PER_I2C1_WKDEP_OFFSET 0x00a0 +#define DRA7XX_RM_L4PER_I2C1_CONTEXT_OFFSET 0x00a4 +#define DRA7XX_PM_L4PER_I2C2_WKDEP_OFFSET 0x00a8 +#define DRA7XX_RM_L4PER_I2C2_CONTEXT_OFFSET 0x00ac +#define DRA7XX_PM_L4PER_I2C3_WKDEP_OFFSET 0x00b0 +#define DRA7XX_RM_L4PER_I2C3_CONTEXT_OFFSET 0x00b4 +#define DRA7XX_PM_L4PER_I2C4_WKDEP_OFFSET 0x00b8 +#define DRA7XX_RM_L4PER_I2C4_CONTEXT_OFFSET 0x00bc +#define DRA7XX_RM_L4PER_L4PER1_CONTEXT_OFFSET 0x00c0 +#define DRA7XX_RM_L4PER2_PWMSS1_CONTEXT_OFFSET 0x00c4 +#define DRA7XX_PM_L4PER_TIMER13_WKDEP_OFFSET 0x00c8 +#define DRA7XX_RM_L4PER3_TIMER13_CONTEXT_OFFSET 0x00cc +#define DRA7XX_PM_L4PER_TIMER14_WKDEP_OFFSET 0x00d0 +#define DRA7XX_RM_L4PER3_TIMER14_CONTEXT_OFFSET 0x00d4 +#define DRA7XX_PM_L4PER_TIMER15_WKDEP_OFFSET 0x00d8 +#define DRA7XX_RM_L4PER3_TIMER15_CONTEXT_OFFSET 0x00dc +#define DRA7XX_PM_L4PER_MCSPI1_WKDEP_OFFSET 0x00f0 +#define DRA7XX_RM_L4PER_MCSPI1_CONTEXT_OFFSET 0x00f4 +#define DRA7XX_PM_L4PER_MCSPI2_WKDEP_OFFSET 0x00f8 +#define DRA7XX_RM_L4PER_MCSPI2_CONTEXT_OFFSET 0x00fc +#define DRA7XX_PM_L4PER_MCSPI3_WKDEP_OFFSET 0x0100 +#define DRA7XX_RM_L4PER_MCSPI3_CONTEXT_OFFSET 0x0104 +#define DRA7XX_PM_L4PER_MCSPI4_WKDEP_OFFSET 0x0108 +#define DRA7XX_RM_L4PER_MCSPI4_CONTEXT_OFFSET 0x010c +#define DRA7XX_PM_L4PER_GPIO7_WKDEP_OFFSET 0x0110 +#define DRA7XX_RM_L4PER_GPIO7_CONTEXT_OFFSET 0x0114 +#define DRA7XX_PM_L4PER_GPIO8_WKDEP_OFFSET 0x0118 +#define DRA7XX_RM_L4PER_GPIO8_CONTEXT_OFFSET 0x011c +#define DRA7XX_PM_L4PER_MMC3_WKDEP_OFFSET 0x0120 +#define DRA7XX_RM_L4PER_MMC3_CONTEXT_OFFSET 0x0124 +#define DRA7XX_PM_L4PER_MMC4_WKDEP_OFFSET 0x0128 +#define DRA7XX_RM_L4PER_MMC4_CONTEXT_OFFSET 0x012c +#define DRA7XX_PM_L4PER_TIMER16_WKDEP_OFFSET 0x0130 +#define DRA7XX_RM_L4PER3_TIMER16_CONTEXT_OFFSET 0x0134 +#define DRA7XX_PM_L4PER2_QSPI_WKDEP_OFFSET 0x0138 +#define DRA7XX_RM_L4PER2_QSPI_CONTEXT_OFFSET 0x013c +#define DRA7XX_PM_L4PER_UART1_WKDEP_OFFSET 0x0140 +#define DRA7XX_RM_L4PER_UART1_CONTEXT_OFFSET 0x0144 +#define DRA7XX_PM_L4PER_UART2_WKDEP_OFFSET 0x0148 +#define DRA7XX_RM_L4PER_UART2_CONTEXT_OFFSET 0x014c +#define DRA7XX_PM_L4PER_UART3_WKDEP_OFFSET 0x0150 +#define DRA7XX_RM_L4PER_UART3_CONTEXT_OFFSET 0x0154 +#define DRA7XX_PM_L4PER_UART4_WKDEP_OFFSET 0x0158 +#define DRA7XX_RM_L4PER_UART4_CONTEXT_OFFSET 0x015c +#define DRA7XX_PM_L4PER2_MCASP2_WKDEP_OFFSET 0x0160 +#define DRA7XX_RM_L4PER2_MCASP2_CONTEXT_OFFSET 0x0164 +#define DRA7XX_PM_L4PER2_MCASP3_WKDEP_OFFSET 0x0168 +#define DRA7XX_RM_L4PER2_MCASP3_CONTEXT_OFFSET 0x016c +#define DRA7XX_PM_L4PER_UART5_WKDEP_OFFSET 0x0170 +#define DRA7XX_RM_L4PER_UART5_CONTEXT_OFFSET 0x0174 +#define DRA7XX_PM_L4PER2_MCASP5_WKDEP_OFFSET 0x0178 +#define DRA7XX_RM_L4PER2_MCASP5_CONTEXT_OFFSET 0x017c +#define DRA7XX_PM_L4PER2_MCASP6_WKDEP_OFFSET 0x0180 +#define DRA7XX_RM_L4PER2_MCASP6_CONTEXT_OFFSET 0x0184 +#define DRA7XX_PM_L4PER2_MCASP7_WKDEP_OFFSET 0x0188 +#define DRA7XX_RM_L4PER2_MCASP7_CONTEXT_OFFSET 0x018c +#define DRA7XX_PM_L4PER2_MCASP8_WKDEP_OFFSET 0x0190 +#define DRA7XX_RM_L4PER2_MCASP8_CONTEXT_OFFSET 0x0194 +#define DRA7XX_PM_L4PER2_MCASP4_WKDEP_OFFSET 0x0198 +#define DRA7XX_RM_L4PER2_MCASP4_CONTEXT_OFFSET 0x019c +#define DRA7XX_RM_L4SEC_AES1_CONTEXT_OFFSET 0x01a4 +#define DRA7XX_RM_L4SEC_AES2_CONTEXT_OFFSET 0x01ac +#define DRA7XX_RM_L4SEC_DES3DES_CONTEXT_OFFSET 0x01b4 +#define DRA7XX_RM_L4SEC_FPKA_CONTEXT_OFFSET 0x01bc +#define DRA7XX_RM_L4SEC_RNG_CONTEXT_OFFSET 0x01c4 +#define DRA7XX_RM_L4SEC_SHA2MD51_CONTEXT_OFFSET 0x01cc +#define DRA7XX_PM_L4PER2_UART7_WKDEP_OFFSET 0x01d0 +#define DRA7XX_RM_L4PER2_UART7_CONTEXT_OFFSET 0x01d4 +#define DRA7XX_RM_L4SEC_DMA_CRYPTO_CONTEXT_OFFSET 0x01dc +#define DRA7XX_PM_L4PER2_UART8_WKDEP_OFFSET 0x01e0 +#define DRA7XX_RM_L4PER2_UART8_CONTEXT_OFFSET 0x01e4 +#define DRA7XX_PM_L4PER2_UART9_WKDEP_OFFSET 0x01e8 +#define DRA7XX_RM_L4PER2_UART9_CONTEXT_OFFSET 0x01ec +#define DRA7XX_PM_L4PER2_DCAN2_WKDEP_OFFSET 0x01f0 +#define DRA7XX_RM_L4PER2_DCAN2_CONTEXT_OFFSET 0x01f4 +#define DRA7XX_RM_L4SEC_SHA2MD52_CONTEXT_OFFSET 0x01fc + +/* PRM.CUSTEFUSE_PRM register offsets */ +#define DRA7XX_PM_CUSTEFUSE_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_CUSTEFUSE_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_CUSTEFUSE_EFUSE_CTRL_CUST_CONTEXT_OFFSET 0x0024 + +/* PRM.WKUPAON_PRM register offsets */ +#define DRA7XX_RM_WKUPAON_L4_WKUP_CONTEXT_OFFSET 0x0000 +#define DRA7XX_PM_WKUPAON_WD_TIMER1_WKDEP_OFFSET 0x0004 +#define DRA7XX_RM_WKUPAON_WD_TIMER1_CONTEXT_OFFSET 0x0008 +#define DRA7XX_PM_WKUPAON_WD_TIMER2_WKDEP_OFFSET 0x000c +#define DRA7XX_RM_WKUPAON_WD_TIMER2_CONTEXT_OFFSET 0x0010 +#define DRA7XX_PM_WKUPAON_GPIO1_WKDEP_OFFSET 0x0014 +#define DRA7XX_RM_WKUPAON_GPIO1_CONTEXT_OFFSET 0x0018 +#define DRA7XX_PM_WKUPAON_TIMER1_WKDEP_OFFSET 0x001c +#define DRA7XX_RM_WKUPAON_TIMER1_CONTEXT_OFFSET 0x0020 +#define DRA7XX_PM_WKUPAON_TIMER12_WKDEP_OFFSET 0x0024 +#define DRA7XX_RM_WKUPAON_TIMER12_CONTEXT_OFFSET 0x0028 +#define DRA7XX_RM_WKUPAON_COUNTER_32K_CONTEXT_OFFSET 0x0030 +#define DRA7XX_RM_WKUPAON_SAR_RAM_CONTEXT_OFFSET 0x0040 +#define DRA7XX_PM_WKUPAON_KBD_WKDEP_OFFSET 0x0054 +#define DRA7XX_RM_WKUPAON_KBD_CONTEXT_OFFSET 0x0058 +#define DRA7XX_PM_WKUPAON_UART10_WKDEP_OFFSET 0x005c +#define DRA7XX_RM_WKUPAON_UART10_CONTEXT_OFFSET 0x0060 +#define DRA7XX_PM_WKUPAON_DCAN1_WKDEP_OFFSET 0x0064 +#define DRA7XX_RM_WKUPAON_DCAN1_CONTEXT_OFFSET 0x0068 +#define DRA7XX_PM_WKUPAON_ADC_WKDEP_OFFSET 0x007c +#define DRA7XX_RM_WKUPAON_ADC_CONTEXT_OFFSET 0x0080 +#define DRA7XX_RM_WKUPAON_SPARE_SAFETY1_CONTEXT_OFFSET 0x0090 +#define DRA7XX_RM_WKUPAON_SPARE_SAFETY2_CONTEXT_OFFSET 0x0098 +#define DRA7XX_RM_WKUPAON_SPARE_SAFETY3_CONTEXT_OFFSET 0x00a0 +#define DRA7XX_RM_WKUPAON_SPARE_SAFETY4_CONTEXT_OFFSET 0x00a8 +#define DRA7XX_RM_WKUPAON_SPARE_UNKNOWN2_CONTEXT_OFFSET 0x00b0 +#define DRA7XX_RM_WKUPAON_SPARE_UNKNOWN3_CONTEXT_OFFSET 0x00b8 + +/* PRM.WKUPAON_CM register offsets */ +#define DRA7XX_CM_WKUPAON_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_WKUPAON_L4_WKUP_CLKCTRL_OFFSET 0x0020 +#define DRA7XX_CM_WKUPAON_L4_WKUP_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0020) +#define DRA7XX_CM_WKUPAON_WD_TIMER1_CLKCTRL_OFFSET 0x0028 +#define DRA7XX_CM_WKUPAON_WD_TIMER1_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0028) +#define DRA7XX_CM_WKUPAON_WD_TIMER2_CLKCTRL_OFFSET 0x0030 +#define DRA7XX_CM_WKUPAON_WD_TIMER2_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0030) +#define DRA7XX_CM_WKUPAON_GPIO1_CLKCTRL_OFFSET 0x0038 +#define DRA7XX_CM_WKUPAON_GPIO1_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0038) +#define DRA7XX_CM_WKUPAON_TIMER1_CLKCTRL_OFFSET 0x0040 +#define DRA7XX_CM_WKUPAON_TIMER1_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0040) +#define DRA7XX_CM_WKUPAON_TIMER12_CLKCTRL_OFFSET 0x0048 +#define DRA7XX_CM_WKUPAON_TIMER12_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0048) +#define DRA7XX_CM_WKUPAON_COUNTER_32K_CLKCTRL_OFFSET 0x0050 +#define DRA7XX_CM_WKUPAON_COUNTER_32K_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0050) +#define DRA7XX_CM_WKUPAON_SAR_RAM_CLKCTRL_OFFSET 0x0060 +#define DRA7XX_CM_WKUPAON_SAR_RAM_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0060) +#define DRA7XX_CM_WKUPAON_KBD_CLKCTRL_OFFSET 0x0078 +#define DRA7XX_CM_WKUPAON_KBD_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0078) +#define DRA7XX_CM_WKUPAON_UART10_CLKCTRL_OFFSET 0x0080 +#define DRA7XX_CM_WKUPAON_UART10_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0080) +#define DRA7XX_CM_WKUPAON_DCAN1_CLKCTRL_OFFSET 0x0088 +#define DRA7XX_CM_WKUPAON_DCAN1_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0088) +#define DRA7XX_CM_WKUPAON_SCRM_CLKCTRL_OFFSET 0x0090 +#define DRA7XX_CM_WKUPAON_SCRM_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0090) +#define DRA7XX_CM_WKUPAON_IO_SRCOMP_CLKCTRL_OFFSET 0x0098 +#define DRA7XX_CM_WKUPAON_IO_SRCOMP_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x0098) +#define DRA7XX_CM_WKUPAON_ADC_CLKCTRL_OFFSET 0x00a0 +#define DRA7XX_CM_WKUPAON_ADC_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x00a0) +#define DRA7XX_CM_WKUPAON_SPARE_SAFETY1_CLKCTRL_OFFSET 0x00b0 +#define DRA7XX_CM_WKUPAON_SPARE_SAFETY1_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x00b0) +#define DRA7XX_CM_WKUPAON_SPARE_SAFETY2_CLKCTRL_OFFSET 0x00b8 +#define DRA7XX_CM_WKUPAON_SPARE_SAFETY2_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x00b8) +#define DRA7XX_CM_WKUPAON_SPARE_SAFETY3_CLKCTRL_OFFSET 0x00c0 +#define DRA7XX_CM_WKUPAON_SPARE_SAFETY3_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x00c0) +#define DRA7XX_CM_WKUPAON_SPARE_SAFETY4_CLKCTRL_OFFSET 0x00c8 +#define DRA7XX_CM_WKUPAON_SPARE_SAFETY4_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x00c8) +#define DRA7XX_CM_WKUPAON_SPARE_UNKNOWN2_CLKCTRL_OFFSET 0x00d0 +#define DRA7XX_CM_WKUPAON_SPARE_UNKNOWN2_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x00d0) +#define DRA7XX_CM_WKUPAON_SPARE_UNKNOWN3_CLKCTRL_OFFSET 0x00d8 +#define DRA7XX_CM_WKUPAON_SPARE_UNKNOWN3_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_WKUPAON_CM_INST, 0x00d8) + +/* PRM.EMU_PRM register offsets */ +#define DRA7XX_PM_EMU_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_EMU_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_EMU_DEBUGSS_CONTEXT_OFFSET 0x0024 + +/* PRM.EMU_CM register offsets */ +#define DRA7XX_CM_EMU_CLKSTCTRL_OFFSET 0x0000 +#define DRA7XX_CM_EMU_DEBUGSS_CLKCTRL_OFFSET 0x0004 +#define DRA7XX_CM_EMU_DEBUGSS_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_EMU_CM_INST, 0x0004) +#define DRA7XX_CM_EMU_DYNAMICDEP_OFFSET 0x0008 +#define DRA7XX_CM_EMU_MPU_EMU_DBG_CLKCTRL_OFFSET 0x000c +#define DRA7XX_CM_EMU_MPU_EMU_DBG_CLKCTRL DRA7XX_PRM_REGADDR(DRA7XX_PRM_EMU_CM_INST, 0x000c) + +/* PRM.DSP2_PRM register offsets */ +#define DRA7XX_PM_DSP2_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_DSP2_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_DSP2_RSTCTRL_OFFSET 0x0010 +#define DRA7XX_RM_DSP2_RSTST_OFFSET 0x0014 +#define DRA7XX_RM_DSP2_DSP2_CONTEXT_OFFSET 0x0024 + +/* PRM.EVE1_PRM register offsets */ +#define DRA7XX_PM_EVE1_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_EVE1_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_EVE1_RSTCTRL_OFFSET 0x0010 +#define DRA7XX_RM_EVE1_RSTST_OFFSET 0x0014 +#define DRA7XX_PM_EVE1_EVE1_WKDEP_OFFSET 0x0020 +#define DRA7XX_RM_EVE1_EVE1_CONTEXT_OFFSET 0x0024 + +/* PRM.EVE2_PRM register offsets */ +#define DRA7XX_PM_EVE2_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_EVE2_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_EVE2_RSTCTRL_OFFSET 0x0010 +#define DRA7XX_RM_EVE2_RSTST_OFFSET 0x0014 +#define DRA7XX_PM_EVE2_EVE2_WKDEP_OFFSET 0x0020 +#define DRA7XX_RM_EVE2_EVE2_CONTEXT_OFFSET 0x0024 + +/* PRM.EVE3_PRM register offsets */ +#define DRA7XX_PM_EVE3_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_EVE3_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_EVE3_RSTCTRL_OFFSET 0x0010 +#define DRA7XX_RM_EVE3_RSTST_OFFSET 0x0014 +#define DRA7XX_PM_EVE3_EVE3_WKDEP_OFFSET 0x0020 +#define DRA7XX_RM_EVE3_EVE3_CONTEXT_OFFSET 0x0024 + +/* PRM.EVE4_PRM register offsets */ +#define DRA7XX_PM_EVE4_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_EVE4_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_EVE4_RSTCTRL_OFFSET 0x0010 +#define DRA7XX_RM_EVE4_RSTST_OFFSET 0x0014 +#define DRA7XX_PM_EVE4_EVE4_WKDEP_OFFSET 0x0020 +#define DRA7XX_RM_EVE4_EVE4_CONTEXT_OFFSET 0x0024 + +/* PRM.RTC_PRM register offsets */ +#define DRA7XX_PM_RTC_RTCSS_WKDEP_OFFSET 0x0000 +#define DRA7XX_RM_RTC_RTCSS_CONTEXT_OFFSET 0x0004 + +/* PRM.VPE_PRM register offsets */ +#define DRA7XX_PM_VPE_PWRSTCTRL_OFFSET 0x0000 +#define DRA7XX_PM_VPE_PWRSTST_OFFSET 0x0004 +#define DRA7XX_PM_VPE_VPE_WKDEP_OFFSET 0x0020 +#define DRA7XX_RM_VPE_VPE_CONTEXT_OFFSET 0x0024 + +/* PRM.DEVICE_PRM register offsets */ +#define DRA7XX_PRM_RSTCTRL_OFFSET 0x0000 +#define DRA7XX_PRM_RSTST_OFFSET 0x0004 +#define DRA7XX_PRM_RSTTIME_OFFSET 0x0008 +#define DRA7XX_PRM_CLKREQCTRL_OFFSET 0x000c +#define DRA7XX_PRM_VOLTCTRL_OFFSET 0x0010 +#define DRA7XX_PRM_PWRREQCTRL_OFFSET 0x0014 +#define DRA7XX_PRM_PSCON_COUNT_OFFSET 0x0018 +#define DRA7XX_PRM_IO_COUNT_OFFSET 0x001c +#define DRA7XX_PRM_IO_PMCTRL_OFFSET 0x0020 +#define DRA7XX_PRM_VOLTSETUP_WARMRESET_OFFSET 0x0024 +#define DRA7XX_PRM_VOLTSETUP_CORE_OFF_OFFSET 0x0028 +#define DRA7XX_PRM_VOLTSETUP_MPU_OFF_OFFSET 0x002c +#define DRA7XX_PRM_VOLTSETUP_MM_OFF_OFFSET 0x0030 +#define DRA7XX_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET 0x0034 +#define DRA7XX_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET 0x0038 +#define DRA7XX_PRM_VOLTSETUP_MM_RET_SLEEP_OFFSET 0x003c +#define DRA7XX_PRM_SRAM_COUNT_OFFSET 0x00bc +#define DRA7XX_PRM_SRAM_WKUP_SETUP_OFFSET 0x00c0 +#define DRA7XX_PRM_SLDO_CORE_SETUP_OFFSET 0x00c4 +#define DRA7XX_PRM_SLDO_CORE_CTRL_OFFSET 0x00c8 +#define DRA7XX_PRM_SLDO_MPU_SETUP_OFFSET 0x00cc +#define DRA7XX_PRM_SLDO_MPU_CTRL_OFFSET 0x00d0 +#define DRA7XX_PRM_SLDO_GPU_SETUP_OFFSET 0x00d4 +#define DRA7XX_PRM_SLDO_GPU_CTRL_OFFSET 0x00d8 +#define DRA7XX_PRM_ABBLDO_MPU_SETUP_OFFSET 0x00dc +#define DRA7XX_PRM_ABBLDO_MPU_CTRL_OFFSET 0x00e0 +#define DRA7XX_PRM_ABBLDO_GPU_SETUP_OFFSET 0x00e4 +#define DRA7XX_PRM_ABBLDO_GPU_CTRL_OFFSET 0x00e8 +#define DRA7XX_PRM_BANDGAP_SETUP_OFFSET 0x00ec +#define DRA7XX_PRM_DEVICE_OFF_CTRL_OFFSET 0x00f0 +#define DRA7XX_PRM_PHASE1_CNDP_OFFSET 0x00f4 +#define DRA7XX_PRM_PHASE2A_CNDP_OFFSET 0x00f8 +#define DRA7XX_PRM_PHASE2B_CNDP_OFFSET 0x00fc +#define DRA7XX_PRM_MODEM_IF_CTRL_OFFSET 0x0100 +#define DRA7XX_PRM_VOLTST_MPU_OFFSET 0x0110 +#define DRA7XX_PRM_VOLTST_MM_OFFSET 0x0114 +#define DRA7XX_PRM_SLDO_DSPEVE_SETUP_OFFSET 0x0118 +#define DRA7XX_PRM_SLDO_IVA_SETUP_OFFSET 0x011c +#define DRA7XX_PRM_ABBLDO_DSPEVE_CTRL_OFFSET 0x0120 +#define DRA7XX_PRM_ABBLDO_IVA_CTRL_OFFSET 0x0124 +#define DRA7XX_PRM_SLDO_DSPEVE_CTRL_OFFSET 0x0128 +#define DRA7XX_PRM_SLDO_IVA_CTRL_OFFSET 0x012c +#define DRA7XX_PRM_ABBLDO_DSPEVE_SETUP_OFFSET 0x0130 +#define DRA7XX_PRM_ABBLDO_IVA_SETUP_OFFSET 0x0134 + +#endif diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c new file mode 100644 index 00000000000..25e8b823211 --- /dev/null +++ b/arch/arm/mach-omap2/prm_common.c @@ -0,0 +1,537 @@ +/* + * OMAP2+ common Power & Reset Management (PRM) IP block functions + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Tero Kristo <t-kristo@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * + * For historical purposes, the API used to configure the PRM + * interrupt handler refers to it as the "PRCM interrupt." The + * underlying registers are located in the PRM on OMAP3/4. + * + * XXX This code should eventually be moved to a PRM driver. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <linux/slab.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/clk-provider.h> +#include <linux/clk/ti.h> + +#include "soc.h" +#include "prm2xxx_3xxx.h" +#include "prm2xxx.h" +#include "prm3xxx.h" +#include "prm44xx.h" +#include "common.h" +#include "clock.h" + +/* + * OMAP_PRCM_MAX_NR_PENDING_REG: maximum number of PRM_IRQ*_MPU regs + * XXX this is technically not needed, since + * omap_prcm_register_chain_handler() could allocate this based on the + * actual amount of memory needed for the SoC + */ +#define OMAP_PRCM_MAX_NR_PENDING_REG 2 + +/* + * prcm_irq_chips: an array of all of the "generic IRQ chips" in use + * by the PRCM interrupt handler code. There will be one 'chip' per + * PRM_{IRQSTATUS,IRQENABLE}_MPU register pair. (So OMAP3 will have + * one "chip" and OMAP4 will have two.) + */ +static struct irq_chip_generic **prcm_irq_chips; + +/* + * prcm_irq_setup: the PRCM IRQ parameters for the hardware the code + * is currently running on. Defined and passed by initialization code + * that calls omap_prcm_register_chain_handler(). + */ +static struct omap_prcm_irq_setup *prcm_irq_setup; + +/* prm_base: base virtual address of the PRM IP block */ +void __iomem *prm_base; + +u16 prm_features; + +/* + * prm_ll_data: function pointers to SoC-specific implementations of + * common PRM functions + */ +static struct prm_ll_data null_prm_ll_data; +static struct prm_ll_data *prm_ll_data = &null_prm_ll_data; + +/* Private functions */ + +/* + * Move priority events from events to priority_events array + */ +static void omap_prcm_events_filter_priority(unsigned long *events, + unsigned long *priority_events) +{ + int i; + + for (i = 0; i < prcm_irq_setup->nr_regs; i++) { + priority_events[i] = + events[i] & prcm_irq_setup->priority_mask[i]; + events[i] ^= priority_events[i]; + } +} + +/* + * PRCM Interrupt Handler + * + * This is a common handler for the OMAP PRCM interrupts. Pending + * interrupts are detected by a call to prcm_pending_events and + * dispatched accordingly. Clearing of the wakeup events should be + * done by the SoC specific individual handlers. + */ +static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + unsigned long pending[OMAP_PRCM_MAX_NR_PENDING_REG]; + unsigned long priority_pending[OMAP_PRCM_MAX_NR_PENDING_REG]; + struct irq_chip *chip = irq_desc_get_chip(desc); + unsigned int virtirq; + int nr_irq = prcm_irq_setup->nr_regs * 32; + + /* + * If we are suspended, mask all interrupts from PRCM level, + * this does not ack them, and they will be pending until we + * re-enable the interrupts, at which point the + * omap_prcm_irq_handler will be executed again. The + * _save_and_clear_irqen() function must ensure that the PRM + * write to disable all IRQs has reached the PRM before + * returning, or spurious PRCM interrupts may occur during + * suspend. + */ + if (prcm_irq_setup->suspended) { + prcm_irq_setup->save_and_clear_irqen(prcm_irq_setup->saved_mask); + prcm_irq_setup->suspend_save_flag = true; + } + + /* + * Loop until all pending irqs are handled, since + * generic_handle_irq() can cause new irqs to come + */ + while (!prcm_irq_setup->suspended) { + prcm_irq_setup->read_pending_irqs(pending); + + /* No bit set, then all IRQs are handled */ + if (find_first_bit(pending, nr_irq) >= nr_irq) + break; + + omap_prcm_events_filter_priority(pending, priority_pending); + + /* + * Loop on all currently pending irqs so that new irqs + * cannot starve previously pending irqs + */ + + /* Serve priority events first */ + for_each_set_bit(virtirq, priority_pending, nr_irq) + generic_handle_irq(prcm_irq_setup->base_irq + virtirq); + + /* Serve normal events next */ + for_each_set_bit(virtirq, pending, nr_irq) + generic_handle_irq(prcm_irq_setup->base_irq + virtirq); + } + if (chip->irq_ack) + chip->irq_ack(&desc->irq_data); + if (chip->irq_eoi) + chip->irq_eoi(&desc->irq_data); + chip->irq_unmask(&desc->irq_data); + + prcm_irq_setup->ocp_barrier(); /* avoid spurious IRQs */ +} + +/* Public functions */ + +/** + * omap_prcm_event_to_irq - given a PRCM event name, returns the + * corresponding IRQ on which the handler should be registered + * @name: name of the PRCM interrupt bit to look up - see struct omap_prcm_irq + * + * Returns the Linux internal IRQ ID corresponding to @name upon success, + * or -ENOENT upon failure. + */ +int omap_prcm_event_to_irq(const char *name) +{ + int i; + + if (!prcm_irq_setup || !name) + return -ENOENT; + + for (i = 0; i < prcm_irq_setup->nr_irqs; i++) + if (!strcmp(prcm_irq_setup->irqs[i].name, name)) + return prcm_irq_setup->base_irq + + prcm_irq_setup->irqs[i].offset; + + return -ENOENT; +} + +/** + * omap_prcm_irq_cleanup - reverses memory allocated and other steps + * done by omap_prcm_register_chain_handler() + * + * No return value. + */ +void omap_prcm_irq_cleanup(void) +{ + int i; + + if (!prcm_irq_setup) { + pr_err("PRCM: IRQ handler not initialized; cannot cleanup\n"); + return; + } + + if (prcm_irq_chips) { + for (i = 0; i < prcm_irq_setup->nr_regs; i++) { + if (prcm_irq_chips[i]) + irq_remove_generic_chip(prcm_irq_chips[i], + 0xffffffff, 0, 0); + prcm_irq_chips[i] = NULL; + } + kfree(prcm_irq_chips); + prcm_irq_chips = NULL; + } + + kfree(prcm_irq_setup->saved_mask); + prcm_irq_setup->saved_mask = NULL; + + kfree(prcm_irq_setup->priority_mask); + prcm_irq_setup->priority_mask = NULL; + + irq_set_chained_handler(prcm_irq_setup->irq, NULL); + + if (prcm_irq_setup->base_irq > 0) + irq_free_descs(prcm_irq_setup->base_irq, + prcm_irq_setup->nr_regs * 32); + prcm_irq_setup->base_irq = 0; +} + +void omap_prcm_irq_prepare(void) +{ + prcm_irq_setup->suspended = true; +} + +void omap_prcm_irq_complete(void) +{ + prcm_irq_setup->suspended = false; + + /* If we have not saved the masks, do not attempt to restore */ + if (!prcm_irq_setup->suspend_save_flag) + return; + + prcm_irq_setup->suspend_save_flag = false; + + /* + * Re-enable all masked PRCM irq sources, this causes the PRCM + * interrupt to fire immediately if the events were masked + * previously in the chain handler + */ + prcm_irq_setup->restore_irqen(prcm_irq_setup->saved_mask); +} + +/** + * omap_prcm_register_chain_handler - initializes the prcm chained interrupt + * handler based on provided parameters + * @irq_setup: hardware data about the underlying PRM/PRCM + * + * Set up the PRCM chained interrupt handler on the PRCM IRQ. Sets up + * one generic IRQ chip per PRM interrupt status/enable register pair. + * Returns 0 upon success, -EINVAL if called twice or if invalid + * arguments are passed, or -ENOMEM on any other error. + */ +int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) +{ + int nr_regs; + u32 mask[OMAP_PRCM_MAX_NR_PENDING_REG]; + int offset, i; + struct irq_chip_generic *gc; + struct irq_chip_type *ct; + + if (!irq_setup) + return -EINVAL; + + nr_regs = irq_setup->nr_regs; + + if (prcm_irq_setup) { + pr_err("PRCM: already initialized; won't reinitialize\n"); + return -EINVAL; + } + + if (nr_regs > OMAP_PRCM_MAX_NR_PENDING_REG) { + pr_err("PRCM: nr_regs too large\n"); + return -EINVAL; + } + + prcm_irq_setup = irq_setup; + + prcm_irq_chips = kzalloc(sizeof(void *) * nr_regs, GFP_KERNEL); + prcm_irq_setup->saved_mask = kzalloc(sizeof(u32) * nr_regs, GFP_KERNEL); + prcm_irq_setup->priority_mask = kzalloc(sizeof(u32) * nr_regs, + GFP_KERNEL); + + if (!prcm_irq_chips || !prcm_irq_setup->saved_mask || + !prcm_irq_setup->priority_mask) { + pr_err("PRCM: kzalloc failed\n"); + goto err; + } + + memset(mask, 0, sizeof(mask)); + + for (i = 0; i < irq_setup->nr_irqs; i++) { + offset = irq_setup->irqs[i].offset; + mask[offset >> 5] |= 1 << (offset & 0x1f); + if (irq_setup->irqs[i].priority) + irq_setup->priority_mask[offset >> 5] |= + 1 << (offset & 0x1f); + } + + irq_set_chained_handler(irq_setup->irq, omap_prcm_irq_handler); + + irq_setup->base_irq = irq_alloc_descs(-1, 0, irq_setup->nr_regs * 32, + 0); + + if (irq_setup->base_irq < 0) { + pr_err("PRCM: failed to allocate irq descs: %d\n", + irq_setup->base_irq); + goto err; + } + + for (i = 0; i < irq_setup->nr_regs; i++) { + gc = irq_alloc_generic_chip("PRCM", 1, + irq_setup->base_irq + i * 32, prm_base, + handle_level_irq); + + if (!gc) { + pr_err("PRCM: failed to allocate generic chip\n"); + goto err; + } + ct = gc->chip_types; + ct->chip.irq_ack = irq_gc_ack_set_bit; + ct->chip.irq_mask = irq_gc_mask_clr_bit; + ct->chip.irq_unmask = irq_gc_mask_set_bit; + + ct->regs.ack = irq_setup->ack + i * 4; + ct->regs.mask = irq_setup->mask + i * 4; + + irq_setup_generic_chip(gc, mask[i], 0, IRQ_NOREQUEST, 0); + prcm_irq_chips[i] = gc; + } + + if (of_have_populated_dt()) { + int irq = omap_prcm_event_to_irq("io"); + omap_pcs_legacy_init(irq, irq_setup->reconfigure_io_chain); + } + + return 0; + +err: + omap_prcm_irq_cleanup(); + return -ENOMEM; +} + +/** + * omap2_set_globals_prm - set the PRM base address (for early use) + * @prm: PRM base virtual address + * + * XXX Will be replaced when the PRM/CM drivers are completed. + */ +void __init omap2_set_globals_prm(void __iomem *prm) +{ + prm_base = prm; +} + +/** + * prm_read_reset_sources - return the sources of the SoC's last reset + * + * Return a u32 bitmask representing the reset sources that caused the + * SoC to reset. The low-level per-SoC functions called by this + * function remap the SoC-specific reset source bits into an + * OMAP-common set of reset source bits, defined in + * arch/arm/mach-omap2/prm.h. Returns the standardized reset source + * u32 bitmask from the hardware upon success, or returns (1 << + * OMAP_UNKNOWN_RST_SRC_ID_SHIFT) if no low-level read_reset_sources() + * function was registered. + */ +u32 prm_read_reset_sources(void) +{ + u32 ret = 1 << OMAP_UNKNOWN_RST_SRC_ID_SHIFT; + + if (prm_ll_data->read_reset_sources) + ret = prm_ll_data->read_reset_sources(); + else + WARN_ONCE(1, "prm: %s: no mapping function defined for reset sources\n", __func__); + + return ret; +} + +/** + * prm_was_any_context_lost_old - was device context lost? (old API) + * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION) + * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST) + * @idx: CONTEXT register offset + * + * Return 1 if any bits were set in the *_CONTEXT_* register + * identified by (@part, @inst, @idx), which means that some context + * was lost for that module; otherwise, return 0. XXX Deprecated; + * callers need to use a less-SoC-dependent way to identify hardware + * IP blocks. + */ +bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx) +{ + bool ret = true; + + if (prm_ll_data->was_any_context_lost_old) + ret = prm_ll_data->was_any_context_lost_old(part, inst, idx); + else + WARN_ONCE(1, "prm: %s: no mapping function defined\n", + __func__); + + return ret; +} + +/** + * prm_clear_context_lost_flags_old - clear context loss flags (old API) + * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION) + * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST) + * @idx: CONTEXT register offset + * + * Clear hardware context loss bits for the module identified by + * (@part, @inst, @idx). No return value. XXX Deprecated; callers + * need to use a less-SoC-dependent way to identify hardware IP + * blocks. + */ +void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx) +{ + if (prm_ll_data->clear_context_loss_flags_old) + prm_ll_data->clear_context_loss_flags_old(part, inst, idx); + else + WARN_ONCE(1, "prm: %s: no mapping function defined\n", + __func__); +} + +/** + * prm_register - register per-SoC low-level data with the PRM + * @pld: low-level per-SoC OMAP PRM data & function pointers to register + * + * Register per-SoC low-level OMAP PRM data and function pointers with + * the OMAP PRM common interface. The caller must keep the data + * pointed to by @pld valid until it calls prm_unregister() and + * it returns successfully. Returns 0 upon success, -EINVAL if @pld + * is NULL, or -EEXIST if prm_register() has already been called + * without an intervening prm_unregister(). + */ +int prm_register(struct prm_ll_data *pld) +{ + if (!pld) + return -EINVAL; + + if (prm_ll_data != &null_prm_ll_data) + return -EEXIST; + + prm_ll_data = pld; + + return 0; +} + +/** + * prm_unregister - unregister per-SoC low-level data & function pointers + * @pld: low-level per-SoC OMAP PRM data & function pointers to unregister + * + * Unregister per-SoC low-level OMAP PRM data and function pointers + * that were previously registered with prm_register(). The + * caller may not destroy any of the data pointed to by @pld until + * this function returns successfully. Returns 0 upon success, or + * -EINVAL if @pld is NULL or if @pld does not match the struct + * prm_ll_data * previously registered by prm_register(). + */ +int prm_unregister(struct prm_ll_data *pld) +{ + if (!pld || prm_ll_data != pld) + return -EINVAL; + + prm_ll_data = &null_prm_ll_data; + + return 0; +} + +static struct of_device_id omap_prcm_dt_match_table[] = { + { .compatible = "ti,am3-prcm" }, + { .compatible = "ti,am3-scrm" }, + { .compatible = "ti,am4-prcm" }, + { .compatible = "ti,am4-scrm" }, + { .compatible = "ti,omap3-prm" }, + { .compatible = "ti,omap3-cm" }, + { .compatible = "ti,omap3-scrm" }, + { .compatible = "ti,omap4-cm1" }, + { .compatible = "ti,omap4-prm" }, + { .compatible = "ti,omap4-cm2" }, + { .compatible = "ti,omap4-scrm" }, + { .compatible = "ti,omap5-prm" }, + { .compatible = "ti,omap5-cm-core-aon" }, + { .compatible = "ti,omap5-scrm" }, + { .compatible = "ti,omap5-cm-core" }, + { .compatible = "ti,dra7-prm" }, + { .compatible = "ti,dra7-cm-core-aon" }, + { .compatible = "ti,dra7-cm-core" }, + { } +}; + +static struct clk_hw_omap memmap_dummy_ck = { + .flags = MEMMAP_ADDRESSING, +}; + +static u32 prm_clk_readl(void __iomem *reg) +{ + return omap2_clk_readl(&memmap_dummy_ck, reg); +} + +static void prm_clk_writel(u32 val, void __iomem *reg) +{ + omap2_clk_writel(val, &memmap_dummy_ck, reg); +} + +static struct ti_clk_ll_ops omap_clk_ll_ops = { + .clk_readl = prm_clk_readl, + .clk_writel = prm_clk_writel, +}; + +int __init of_prcm_init(void) +{ + struct device_node *np; + void __iomem *mem; + int memmap_index = 0; + + ti_clk_ll_ops = &omap_clk_ll_ops; + + for_each_matching_node(np, omap_prcm_dt_match_table) { + mem = of_iomap(np, 0); + clk_memmaps[memmap_index] = mem; + ti_dt_clk_init_provider(np, memmap_index); + memmap_index++; + } + + ti_dt_clockdomains_setup(); + + return 0; +} + +static int __init prm_late_init(void) +{ + if (prm_ll_data->late_init) + return prm_ll_data->late_init(); + return 0; +} +subsys_initcall(prm_late_init); diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c new file mode 100644 index 00000000000..69f0dd08629 --- /dev/null +++ b/arch/arm/mach-omap2/prminst44xx.c @@ -0,0 +1,196 @@ +/* + * OMAP4 PRM instance functions + * + * Copyright (C) 2009 Nokia Corporation + * Copyright (C) 2011 Texas Instruments, Inc. + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/io.h> + +#include "iomap.h" +#include "common.h" +#include "prcm-common.h" +#include "prm44xx.h" +#include "prm54xx.h" +#include "prm7xx.h" +#include "prminst44xx.h" +#include "prm-regbits-44xx.h" +#include "prcm44xx.h" +#include "prcm43xx.h" +#include "prcm_mpu44xx.h" +#include "soc.h" + +static void __iomem *_prm_bases[OMAP4_MAX_PRCM_PARTITIONS]; + +/** + * omap_prm_base_init - Populates the prm partitions + * + * Populates the base addresses of the _prm_bases + * array used for read/write of prm module registers. + */ +void omap_prm_base_init(void) +{ + _prm_bases[OMAP4430_PRM_PARTITION] = prm_base; + _prm_bases[OMAP4430_PRCM_MPU_PARTITION] = prcm_mpu_base; +} + +/* Read a register in a PRM instance */ +u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx) +{ + BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || + part == OMAP4430_INVALID_PRCM_PARTITION || + !_prm_bases[part]); + return readl_relaxed(_prm_bases[part] + inst + idx); +} + +/* Write into a register in a PRM instance */ +void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx) +{ + BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || + part == OMAP4430_INVALID_PRCM_PARTITION || + !_prm_bases[part]); + writel_relaxed(val, _prm_bases[part] + inst + idx); +} + +/* Read-modify-write a register in PRM. Caller must lock */ +u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst, + u16 idx) +{ + u32 v; + + v = omap4_prminst_read_inst_reg(part, inst, idx); + v &= ~mask; + v |= bits; + omap4_prminst_write_inst_reg(v, part, inst, idx); + + return v; +} + +/* + * Address offset (in bytes) between the reset control and the reset + * status registers: 4 bytes on OMAP4 + */ +#define OMAP4_RST_CTRL_ST_OFFSET 4 + +/** + * omap4_prminst_is_hardreset_asserted - read the HW reset line state of + * submodules contained in the hwmod module + * @rstctrl_reg: RM_RSTCTRL register address for this module + * @shift: register bit shift corresponding to the reset line to check + * + * Returns 1 if the (sub)module hardreset line is currently asserted, + * 0 if the (sub)module hardreset line is not currently asserted, or + * -EINVAL upon parameter error. + */ +int omap4_prminst_is_hardreset_asserted(u8 shift, u8 part, s16 inst, + u16 rstctrl_offs) +{ + u32 v; + + v = omap4_prminst_read_inst_reg(part, inst, rstctrl_offs); + v &= 1 << shift; + v >>= shift; + + return v; +} + +/** + * omap4_prminst_assert_hardreset - assert the HW reset line of a submodule + * @rstctrl_reg: RM_RSTCTRL register address for this module + * @shift: register bit shift corresponding to the reset line to assert + * + * Some IPs like dsp, ipu or iva contain processors that require an HW + * reset line to be asserted / deasserted in order to fully enable the + * IP. These modules may have multiple hard-reset lines that reset + * different 'submodules' inside the IP block. This function will + * place the submodule into reset. Returns 0 upon success or -EINVAL + * upon an argument error. + */ +int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst, + u16 rstctrl_offs) +{ + u32 mask = 1 << shift; + + omap4_prminst_rmw_inst_reg_bits(mask, mask, part, inst, rstctrl_offs); + + return 0; +} + +/** + * omap4_prminst_deassert_hardreset - deassert a submodule hardreset line and + * wait + * @rstctrl_reg: RM_RSTCTRL register address for this module + * @shift: register bit shift corresponding to the reset line to deassert + * + * Some IPs like dsp, ipu or iva contain processors that require an HW + * reset line to be asserted / deasserted in order to fully enable the + * IP. These modules may have multiple hard-reset lines that reset + * different 'submodules' inside the IP block. This function will + * take the submodule out of reset and wait until the PRCM indicates + * that the reset has completed before returning. Returns 0 upon success or + * -EINVAL upon an argument error, -EEXIST if the submodule was already out + * of reset, or -EBUSY if the submodule did not exit reset promptly. + */ +int omap4_prminst_deassert_hardreset(u8 shift, u8 part, s16 inst, + u16 rstctrl_offs) +{ + int c; + u32 mask = 1 << shift; + u16 rstst_offs = rstctrl_offs + OMAP4_RST_CTRL_ST_OFFSET; + + /* Check the current status to avoid de-asserting the line twice */ + if (omap4_prminst_is_hardreset_asserted(shift, part, inst, + rstctrl_offs) == 0) + return -EEXIST; + + /* Clear the reset status by writing 1 to the status bit */ + omap4_prminst_rmw_inst_reg_bits(0xffffffff, mask, part, inst, + rstst_offs); + /* de-assert the reset control line */ + omap4_prminst_rmw_inst_reg_bits(mask, 0, part, inst, rstctrl_offs); + /* wait the status to be set */ + omap_test_timeout(omap4_prminst_is_hardreset_asserted(shift, part, inst, + rstst_offs), + MAX_MODULE_HARDRESET_WAIT, c); + + return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0; +} + + +void omap4_prminst_global_warm_sw_reset(void) +{ + u32 v; + s16 dev_inst; + + if (cpu_is_omap44xx()) + dev_inst = OMAP4430_PRM_DEVICE_INST; + else if (soc_is_omap54xx()) + dev_inst = OMAP54XX_PRM_DEVICE_INST; + else if (soc_is_dra7xx()) + dev_inst = DRA7XX_PRM_DEVICE_INST; + else if (soc_is_am43xx()) + dev_inst = AM43XX_PRM_DEVICE_INST; + else + return; + + v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, dev_inst, + OMAP4_PRM_RSTCTRL_OFFSET); + v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK; + omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION, + dev_inst, + OMAP4_PRM_RSTCTRL_OFFSET); + + /* OCP barrier */ + v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, + dev_inst, + OMAP4_PRM_RSTCTRL_OFFSET); +} diff --git a/arch/arm/mach-omap2/prminst44xx.h b/arch/arm/mach-omap2/prminst44xx.h new file mode 100644 index 00000000000..a2ede2d6548 --- /dev/null +++ b/arch/arm/mach-omap2/prminst44xx.h @@ -0,0 +1,35 @@ +/* + * OMAP4 Power/Reset Management (PRM) function prototypes + * + * Copyright (C) 2010 Nokia Corporation + * Copyright (C) 2011 Texas Instruments, Inc. + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ARCH_ASM_MACH_OMAP2_PRMINST44XX_H +#define __ARCH_ASM_MACH_OMAP2_PRMINST44XX_H + +/* + * In an ideal world, we would not export these low-level functions, + * but this will probably take some time to fix properly + */ +extern u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx); +extern void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx); +extern u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, + s16 inst, u16 idx); + +extern void omap4_prminst_global_warm_sw_reset(void); + +extern int omap4_prminst_is_hardreset_asserted(u8 shift, u8 part, s16 inst, + u16 rstctrl_offs); +extern int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst, + u16 rstctrl_offs); +extern int omap4_prminst_deassert_hardreset(u8 shift, u8 part, s16 inst, + u16 rstctrl_offs); + +extern void omap_prm_base_init(void); + +#endif diff --git a/arch/arm/mach-omap2/scrm44xx.h b/arch/arm/mach-omap2/scrm44xx.h new file mode 100644 index 00000000000..e897ac89a3f --- /dev/null +++ b/arch/arm/mach-omap2/scrm44xx.h @@ -0,0 +1,177 @@ +/* + * OMAP44xx SCRM registers and bitfields + * + * Copyright (C) 2010 Texas Instruments, Inc. + * + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_SCRM_44XX_H +#define __ARCH_ARM_MACH_OMAP2_SCRM_44XX_H + +#define OMAP4_SCRM_BASE 0x4a30a000 + +#define OMAP44XX_SCRM_REGADDR(reg) \ + OMAP2_L4_IO_ADDRESS(OMAP4_SCRM_BASE + (reg)) + +/* Registers offset */ +#define OMAP4_SCRM_REVISION_SCRM_OFFSET 0x0000 +#define OMAP4_SCRM_REVISION_SCRM OMAP44XX_SCRM_REGADDR(0x0000) +#define OMAP4_SCRM_CLKSETUPTIME_OFFSET 0x0100 +#define OMAP4_SCRM_CLKSETUPTIME OMAP44XX_SCRM_REGADDR(0x0100) +#define OMAP4_SCRM_PMICSETUPTIME_OFFSET 0x0104 +#define OMAP4_SCRM_PMICSETUPTIME OMAP44XX_SCRM_REGADDR(0x0104) +#define OMAP4_SCRM_ALTCLKSRC_OFFSET 0x0110 +#define OMAP4_SCRM_ALTCLKSRC OMAP44XX_SCRM_REGADDR(0x0110) +#define OMAP4_SCRM_MODEMCLKM_OFFSET 0x0118 +#define OMAP4_SCRM_MODEMCLKM OMAP44XX_SCRM_REGADDR(0x0118) +#define OMAP4_SCRM_D2DCLKM_OFFSET 0x011c +#define OMAP4_SCRM_D2DCLKM OMAP44XX_SCRM_REGADDR(0x011c) +#define OMAP4_SCRM_EXTCLKREQ_OFFSET 0x0200 +#define OMAP4_SCRM_EXTCLKREQ OMAP44XX_SCRM_REGADDR(0x0200) +#define OMAP4_SCRM_ACCCLKREQ_OFFSET 0x0204 +#define OMAP4_SCRM_ACCCLKREQ OMAP44XX_SCRM_REGADDR(0x0204) +#define OMAP4_SCRM_PWRREQ_OFFSET 0x0208 +#define OMAP4_SCRM_PWRREQ OMAP44XX_SCRM_REGADDR(0x0208) +#define OMAP4_SCRM_AUXCLKREQ0_OFFSET 0x0210 +#define OMAP4_SCRM_AUXCLKREQ0 OMAP44XX_SCRM_REGADDR(0x0210) +#define OMAP4_SCRM_AUXCLKREQ1_OFFSET 0x0214 +#define OMAP4_SCRM_AUXCLKREQ1 OMAP44XX_SCRM_REGADDR(0x0214) +#define OMAP4_SCRM_AUXCLKREQ2_OFFSET 0x0218 +#define OMAP4_SCRM_AUXCLKREQ2 OMAP44XX_SCRM_REGADDR(0x0218) +#define OMAP4_SCRM_AUXCLKREQ3_OFFSET 0x021c +#define OMAP4_SCRM_AUXCLKREQ3 OMAP44XX_SCRM_REGADDR(0x021c) +#define OMAP4_SCRM_AUXCLKREQ4_OFFSET 0x0220 +#define OMAP4_SCRM_AUXCLKREQ4 OMAP44XX_SCRM_REGADDR(0x0220) +#define OMAP4_SCRM_AUXCLKREQ5_OFFSET 0x0224 +#define OMAP4_SCRM_AUXCLKREQ5 OMAP44XX_SCRM_REGADDR(0x0224) +#define OMAP4_SCRM_D2DCLKREQ_OFFSET 0x0234 +#define OMAP4_SCRM_D2DCLKREQ OMAP44XX_SCRM_REGADDR(0x0234) +#define OMAP4_SCRM_AUXCLK0_OFFSET 0x0310 +#define OMAP4_SCRM_AUXCLK0 OMAP44XX_SCRM_REGADDR(0x0310) +#define OMAP4_SCRM_AUXCLK1_OFFSET 0x0314 +#define OMAP4_SCRM_AUXCLK1 OMAP44XX_SCRM_REGADDR(0x0314) +#define OMAP4_SCRM_AUXCLK2_OFFSET 0x0318 +#define OMAP4_SCRM_AUXCLK2 OMAP44XX_SCRM_REGADDR(0x0318) +#define OMAP4_SCRM_AUXCLK3_OFFSET 0x031c +#define OMAP4_SCRM_AUXCLK3 OMAP44XX_SCRM_REGADDR(0x031c) +#define OMAP4_SCRM_AUXCLK4_OFFSET 0x0320 +#define OMAP4_SCRM_AUXCLK4 OMAP44XX_SCRM_REGADDR(0x0320) +#define OMAP4_SCRM_AUXCLK5_OFFSET 0x0324 +#define OMAP4_SCRM_AUXCLK5 OMAP44XX_SCRM_REGADDR(0x0324) +#define OMAP4_SCRM_RSTTIME_OFFSET 0x0400 +#define OMAP4_SCRM_RSTTIME OMAP44XX_SCRM_REGADDR(0x0400) +#define OMAP4_SCRM_MODEMRSTCTRL_OFFSET 0x0418 +#define OMAP4_SCRM_MODEMRSTCTRL OMAP44XX_SCRM_REGADDR(0x0418) +#define OMAP4_SCRM_D2DRSTCTRL_OFFSET 0x041c +#define OMAP4_SCRM_D2DRSTCTRL OMAP44XX_SCRM_REGADDR(0x041c) +#define OMAP4_SCRM_EXTPWRONRSTCTRL_OFFSET 0x0420 +#define OMAP4_SCRM_EXTPWRONRSTCTRL OMAP44XX_SCRM_REGADDR(0x0420) +#define OMAP4_SCRM_EXTWARMRSTST_OFFSET 0x0510 +#define OMAP4_SCRM_EXTWARMRSTST OMAP44XX_SCRM_REGADDR(0x0510) +#define OMAP4_SCRM_APEWARMRSTST_OFFSET 0x0514 +#define OMAP4_SCRM_APEWARMRSTST OMAP44XX_SCRM_REGADDR(0x0514) +#define OMAP4_SCRM_MODEMWARMRSTST_OFFSET 0x0518 +#define OMAP4_SCRM_MODEMWARMRSTST OMAP44XX_SCRM_REGADDR(0x0518) +#define OMAP4_SCRM_D2DWARMRSTST_OFFSET 0x051c +#define OMAP4_SCRM_D2DWARMRSTST OMAP44XX_SCRM_REGADDR(0x051c) + +/* Registers shifts and masks */ + +/* REVISION_SCRM */ +#define OMAP4_REV_SHIFT 0 +#define OMAP4_REV_MASK (0xff << 0) + +/* CLKSETUPTIME */ +#define OMAP4_DOWNTIME_SHIFT 16 +#define OMAP4_DOWNTIME_MASK (0x3f << 16) +#define OMAP4_SETUPTIME_SHIFT 0 +#define OMAP4_SETUPTIME_MASK (0xfff << 0) + +/* PMICSETUPTIME */ +#define OMAP4_WAKEUPTIME_SHIFT 16 +#define OMAP4_WAKEUPTIME_MASK (0x3f << 16) +#define OMAP4_SLEEPTIME_SHIFT 0 +#define OMAP4_SLEEPTIME_MASK (0x3f << 0) + +/* ALTCLKSRC */ +#define OMAP4_ENABLE_EXT_SHIFT 3 +#define OMAP4_ENABLE_EXT_MASK (1 << 3) +#define OMAP4_ENABLE_INT_SHIFT 2 +#define OMAP4_ENABLE_INT_MASK (1 << 2) +#define OMAP4_ALTCLKSRC_MODE_SHIFT 0 +#define OMAP4_ALTCLKSRC_MODE_MASK (0x3 << 0) + +/* MODEMCLKM */ +#define OMAP4_CLK_32KHZ_SHIFT 0 +#define OMAP4_CLK_32KHZ_MASK (1 << 0) + +/* D2DCLKM */ +#define OMAP4_SYSCLK_SHIFT 1 +#define OMAP4_SYSCLK_MASK (1 << 1) + +/* EXTCLKREQ */ +#define OMAP4_POLARITY_SHIFT 0 +#define OMAP4_POLARITY_MASK (1 << 0) + +/* AUXCLKREQ0 */ +#define OMAP4_MAPPING_SHIFT 2 +#define OMAP4_MAPPING_MASK (0x7 << 2) +#define OMAP4_MAPPING_WIDTH 3 +#define OMAP4_ACCURACY_SHIFT 1 +#define OMAP4_ACCURACY_MASK (1 << 1) + +/* AUXCLK0 */ +#define OMAP4_CLKDIV_SHIFT 16 +#define OMAP4_CLKDIV_MASK (0xf << 16) +#define OMAP4_CLKDIV_WIDTH 4 +#define OMAP4_DISABLECLK_SHIFT 9 +#define OMAP4_DISABLECLK_MASK (1 << 9) +#define OMAP4_ENABLE_SHIFT 8 +#define OMAP4_ENABLE_MASK (1 << 8) +#define OMAP4_SRCSELECT_SHIFT 1 +#define OMAP4_SRCSELECT_MASK (0x3 << 1) + +/* RSTTIME */ +#define OMAP4_RSTTIME_SHIFT 0 +#define OMAP4_RSTTIME_MASK (0xf << 0) + +/* MODEMRSTCTRL */ +#define OMAP4_WARMRST_SHIFT 1 +#define OMAP4_WARMRST_MASK (1 << 1) +#define OMAP4_COLDRST_SHIFT 0 +#define OMAP4_COLDRST_MASK (1 << 0) + +/* EXTPWRONRSTCTRL */ +#define OMAP4_PWRONRST_SHIFT 1 +#define OMAP4_PWRONRST_MASK (1 << 1) +#define OMAP4_ENABLE_EXTPWRONRSTCTRL_SHIFT 0 +#define OMAP4_ENABLE_EXTPWRONRSTCTRL_MASK (1 << 0) + +/* EXTWARMRSTST */ +#define OMAP4_EXTWARMRSTST_SHIFT 0 +#define OMAP4_EXTWARMRSTST_MASK (1 << 0) + +/* APEWARMRSTST */ +#define OMAP4_APEWARMRSTST_SHIFT 1 +#define OMAP4_APEWARMRSTST_MASK (1 << 1) + +/* MODEMWARMRSTST */ +#define OMAP4_MODEMWARMRSTST_SHIFT 2 +#define OMAP4_MODEMWARMRSTST_MASK (1 << 2) + +/* D2DWARMRSTST */ +#define OMAP4_D2DWARMRSTST_SHIFT 3 +#define OMAP4_D2DWARMRSTST_MASK (1 << 3) + +#endif diff --git a/arch/arm/mach-omap2/scrm54xx.h b/arch/arm/mach-omap2/scrm54xx.h new file mode 100644 index 00000000000..57e86c8f823 --- /dev/null +++ b/arch/arm/mach-omap2/scrm54xx.h @@ -0,0 +1,231 @@ +/* + * OMAP54XX SCRM registers and bitfields + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * + * Benoit Cousson (b-cousson@ti.com) + * + * This file is automatically generated from the OMAP hardware databases. + * We respectfully ask that any modifications to this file be coordinated + * with the public linux-omap@vger.kernel.org mailing list and the + * authors above to ensure that the autogeneration scripts are kept + * up-to-date with the file contents. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_SCRM_54XX_H +#define __ARCH_ARM_MACH_OMAP2_SCRM_54XX_H + +#define OMAP5_SCRM_BASE 0x4ae0a000 + +#define OMAP54XX_SCRM_REGADDR(reg) \ + OMAP2_L4_IO_ADDRESS(OMAP5_SCRM_BASE + (reg)) + +/* SCRM */ + +/* SCRM.SCRM register offsets */ +#define OMAP5_SCRM_REVISION_SCRM_OFFSET 0x0000 +#define OMAP5_SCRM_REVISION_SCRM OMAP54XX_SCRM_REGADDR(0x0000) +#define OMAP5_SCRM_CLKSETUPTIME_OFFSET 0x0100 +#define OMAP5_SCRM_CLKSETUPTIME OMAP54XX_SCRM_REGADDR(0x0100) +#define OMAP5_SCRM_PMICSETUPTIME_OFFSET 0x0104 +#define OMAP5_SCRM_PMICSETUPTIME OMAP54XX_SCRM_REGADDR(0x0104) +#define OMAP5_SCRM_ALTCLKSRC_OFFSET 0x0110 +#define OMAP5_SCRM_ALTCLKSRC OMAP54XX_SCRM_REGADDR(0x0110) +#define OMAP5_SCRM_MODEMCLKM_OFFSET 0x0118 +#define OMAP5_SCRM_MODEMCLKM OMAP54XX_SCRM_REGADDR(0x0118) +#define OMAP5_SCRM_D2DCLKM_OFFSET 0x011c +#define OMAP5_SCRM_D2DCLKM OMAP54XX_SCRM_REGADDR(0x011c) +#define OMAP5_SCRM_EXTCLKREQ_OFFSET 0x0200 +#define OMAP5_SCRM_EXTCLKREQ OMAP54XX_SCRM_REGADDR(0x0200) +#define OMAP5_SCRM_ACCCLKREQ_OFFSET 0x0204 +#define OMAP5_SCRM_ACCCLKREQ OMAP54XX_SCRM_REGADDR(0x0204) +#define OMAP5_SCRM_PWRREQ_OFFSET 0x0208 +#define OMAP5_SCRM_PWRREQ OMAP54XX_SCRM_REGADDR(0x0208) +#define OMAP5_SCRM_AUXCLKREQ0_OFFSET 0x0210 +#define OMAP5_SCRM_AUXCLKREQ0 OMAP54XX_SCRM_REGADDR(0x0210) +#define OMAP5_SCRM_AUXCLKREQ1_OFFSET 0x0214 +#define OMAP5_SCRM_AUXCLKREQ1 OMAP54XX_SCRM_REGADDR(0x0214) +#define OMAP5_SCRM_AUXCLKREQ2_OFFSET 0x0218 +#define OMAP5_SCRM_AUXCLKREQ2 OMAP54XX_SCRM_REGADDR(0x0218) +#define OMAP5_SCRM_AUXCLKREQ3_OFFSET 0x021c +#define OMAP5_SCRM_AUXCLKREQ3 OMAP54XX_SCRM_REGADDR(0x021c) +#define OMAP5_SCRM_AUXCLKREQ4_OFFSET 0x0220 +#define OMAP5_SCRM_AUXCLKREQ4 OMAP54XX_SCRM_REGADDR(0x0220) +#define OMAP5_SCRM_AUXCLKREQ5_OFFSET 0x0224 +#define OMAP5_SCRM_AUXCLKREQ5 OMAP54XX_SCRM_REGADDR(0x0224) +#define OMAP5_SCRM_D2DCLKREQ_OFFSET 0x0234 +#define OMAP5_SCRM_D2DCLKREQ OMAP54XX_SCRM_REGADDR(0x0234) +#define OMAP5_SCRM_AUXCLK0_OFFSET 0x0310 +#define OMAP5_SCRM_AUXCLK0 OMAP54XX_SCRM_REGADDR(0x0310) +#define OMAP5_SCRM_AUXCLK1_OFFSET 0x0314 +#define OMAP5_SCRM_AUXCLK1 OMAP54XX_SCRM_REGADDR(0x0314) +#define OMAP5_SCRM_AUXCLK2_OFFSET 0x0318 +#define OMAP5_SCRM_AUXCLK2 OMAP54XX_SCRM_REGADDR(0x0318) +#define OMAP5_SCRM_AUXCLK3_OFFSET 0x031c +#define OMAP5_SCRM_AUXCLK3 OMAP54XX_SCRM_REGADDR(0x031c) +#define OMAP5_SCRM_AUXCLK4_OFFSET 0x0320 +#define OMAP5_SCRM_AUXCLK4 OMAP54XX_SCRM_REGADDR(0x0320) +#define OMAP5_SCRM_AUXCLK5_OFFSET 0x0324 +#define OMAP5_SCRM_AUXCLK5 OMAP54XX_SCRM_REGADDR(0x0324) +#define OMAP5_SCRM_RSTTIME_OFFSET 0x0400 +#define OMAP5_SCRM_RSTTIME OMAP54XX_SCRM_REGADDR(0x0400) +#define OMAP5_SCRM_MODEMRSTCTRL_OFFSET 0x0418 +#define OMAP5_SCRM_MODEMRSTCTRL OMAP54XX_SCRM_REGADDR(0x0418) +#define OMAP5_SCRM_D2DRSTCTRL_OFFSET 0x041c +#define OMAP5_SCRM_D2DRSTCTRL OMAP54XX_SCRM_REGADDR(0x041c) +#define OMAP5_SCRM_EXTPWRONRSTCTRL_OFFSET 0x0420 +#define OMAP5_SCRM_EXTPWRONRSTCTRL OMAP54XX_SCRM_REGADDR(0x0420) +#define OMAP5_SCRM_EXTWARMRSTST_OFFSET 0x0510 +#define OMAP5_SCRM_EXTWARMRSTST OMAP54XX_SCRM_REGADDR(0x0510) +#define OMAP5_SCRM_APEWARMRSTST_OFFSET 0x0514 +#define OMAP5_SCRM_APEWARMRSTST OMAP54XX_SCRM_REGADDR(0x0514) +#define OMAP5_SCRM_MODEMWARMRSTST_OFFSET 0x0518 +#define OMAP5_SCRM_MODEMWARMRSTST OMAP54XX_SCRM_REGADDR(0x0518) +#define OMAP5_SCRM_D2DWARMRSTST_OFFSET 0x051c +#define OMAP5_SCRM_D2DWARMRSTST OMAP54XX_SCRM_REGADDR(0x051c) + +/* + * Used by AUXCLKREQ0, AUXCLKREQ1, AUXCLKREQ2, AUXCLKREQ3, AUXCLKREQ4, + * AUXCLKREQ5, D2DCLKREQ + */ +#define OMAP5_ACCURACY_SHIFT 1 +#define OMAP5_ACCURACY_WIDTH 0x1 +#define OMAP5_ACCURACY_MASK (1 << 1) + +/* Used by APEWARMRSTST */ +#define OMAP5_APEWARMRSTST_SHIFT 1 +#define OMAP5_APEWARMRSTST_WIDTH 0x1 +#define OMAP5_APEWARMRSTST_MASK (1 << 1) + +/* Used by AUXCLK0, AUXCLK1, AUXCLK2, AUXCLK3, AUXCLK4, AUXCLK5 */ +#define OMAP5_CLKDIV_SHIFT 16 +#define OMAP5_CLKDIV_WIDTH 0x4 +#define OMAP5_CLKDIV_MASK (0xf << 16) + +/* Used by D2DCLKM, MODEMCLKM */ +#define OMAP5_CLK_32KHZ_SHIFT 0 +#define OMAP5_CLK_32KHZ_WIDTH 0x1 +#define OMAP5_CLK_32KHZ_MASK (1 << 0) + +/* Used by D2DRSTCTRL, MODEMRSTCTRL */ +#define OMAP5_COLDRST_SHIFT 0 +#define OMAP5_COLDRST_WIDTH 0x1 +#define OMAP5_COLDRST_MASK (1 << 0) + +/* Used by D2DWARMRSTST */ +#define OMAP5_D2DWARMRSTST_SHIFT 3 +#define OMAP5_D2DWARMRSTST_WIDTH 0x1 +#define OMAP5_D2DWARMRSTST_MASK (1 << 3) + +/* Used by AUXCLK0 */ +#define OMAP5_DISABLECLK_SHIFT 9 +#define OMAP5_DISABLECLK_WIDTH 0x1 +#define OMAP5_DISABLECLK_MASK (1 << 9) + +/* Used by CLKSETUPTIME */ +#define OMAP5_DOWNTIME_SHIFT 16 +#define OMAP5_DOWNTIME_WIDTH 0x6 +#define OMAP5_DOWNTIME_MASK (0x3f << 16) + +/* Used by AUXCLK0, AUXCLK1, AUXCLK2, AUXCLK3, AUXCLK4, AUXCLK5 */ +#define OMAP5_ENABLE_SHIFT 8 +#define OMAP5_ENABLE_WIDTH 0x1 +#define OMAP5_ENABLE_MASK (1 << 8) + +/* Renamed from ENABLE Used by EXTPWRONRSTCTRL */ +#define OMAP5_ENABLE_0_0_SHIFT 0 +#define OMAP5_ENABLE_0_0_WIDTH 0x1 +#define OMAP5_ENABLE_0_0_MASK (1 << 0) + +/* Used by ALTCLKSRC */ +#define OMAP5_ENABLE_EXT_SHIFT 3 +#define OMAP5_ENABLE_EXT_WIDTH 0x1 +#define OMAP5_ENABLE_EXT_MASK (1 << 3) + +/* Used by ALTCLKSRC */ +#define OMAP5_ENABLE_INT_SHIFT 2 +#define OMAP5_ENABLE_INT_WIDTH 0x1 +#define OMAP5_ENABLE_INT_MASK (1 << 2) + +/* Used by EXTWARMRSTST */ +#define OMAP5_EXTWARMRSTST_SHIFT 0 +#define OMAP5_EXTWARMRSTST_WIDTH 0x1 +#define OMAP5_EXTWARMRSTST_MASK (1 << 0) + +/* + * Used by AUXCLKREQ0, AUXCLKREQ1, AUXCLKREQ2, AUXCLKREQ3, AUXCLKREQ4, + * AUXCLKREQ5 + */ +#define OMAP5_MAPPING_SHIFT 2 +#define OMAP5_MAPPING_WIDTH 0x3 +#define OMAP5_MAPPING_MASK (0x7 << 2) + +/* Used by ALTCLKSRC */ +#define OMAP5_MODE_SHIFT 0 +#define OMAP5_MODE_WIDTH 0x2 +#define OMAP5_MODE_MASK (0x3 << 0) + +/* Used by MODEMWARMRSTST */ +#define OMAP5_MODEMWARMRSTST_SHIFT 2 +#define OMAP5_MODEMWARMRSTST_WIDTH 0x1 +#define OMAP5_MODEMWARMRSTST_MASK (1 << 2) + +/* + * Used by ACCCLKREQ, AUXCLK0, AUXCLK1, AUXCLK2, AUXCLK3, AUXCLK4, AUXCLK5, + * AUXCLKREQ0, AUXCLKREQ1, AUXCLKREQ2, AUXCLKREQ3, AUXCLKREQ4, AUXCLKREQ5, + * D2DCLKREQ, EXTCLKREQ, PWRREQ + */ +#define OMAP5_POLARITY_SHIFT 0 +#define OMAP5_POLARITY_WIDTH 0x1 +#define OMAP5_POLARITY_MASK (1 << 0) + +/* Used by EXTPWRONRSTCTRL */ +#define OMAP5_PWRONRST_SHIFT 1 +#define OMAP5_PWRONRST_WIDTH 0x1 +#define OMAP5_PWRONRST_MASK (1 << 1) + +/* Used by REVISION_SCRM */ +#define OMAP5_REV_SHIFT 0 +#define OMAP5_REV_WIDTH 0x8 +#define OMAP5_REV_MASK (0xff << 0) + +/* Used by RSTTIME */ +#define OMAP5_RSTTIME_SHIFT 0 +#define OMAP5_RSTTIME_WIDTH 0x4 +#define OMAP5_RSTTIME_MASK (0xf << 0) + +/* Used by CLKSETUPTIME */ +#define OMAP5_SETUPTIME_SHIFT 0 +#define OMAP5_SETUPTIME_WIDTH 0xc +#define OMAP5_SETUPTIME_MASK (0xfff << 0) + +/* Used by PMICSETUPTIME */ +#define OMAP5_SLEEPTIME_SHIFT 0 +#define OMAP5_SLEEPTIME_WIDTH 0x6 +#define OMAP5_SLEEPTIME_MASK (0x3f << 0) + +/* Used by AUXCLK0, AUXCLK1, AUXCLK2, AUXCLK3, AUXCLK4, AUXCLK5 */ +#define OMAP5_SRCSELECT_SHIFT 1 +#define OMAP5_SRCSELECT_WIDTH 0x2 +#define OMAP5_SRCSELECT_MASK (0x3 << 1) + +/* Used by D2DCLKM */ +#define OMAP5_SYSCLK_SHIFT 1 +#define OMAP5_SYSCLK_WIDTH 0x1 +#define OMAP5_SYSCLK_MASK (1 << 1) + +/* Used by PMICSETUPTIME */ +#define OMAP5_WAKEUPTIME_SHIFT 16 +#define OMAP5_WAKEUPTIME_WIDTH 0x6 +#define OMAP5_WAKEUPTIME_MASK (0x3f << 16) + +/* Used by D2DRSTCTRL, MODEMRSTCTRL */ +#define OMAP5_WARMRST_SHIFT 1 +#define OMAP5_WARMRST_WIDTH 0x1 +#define OMAP5_WARMRST_MASK (1 << 1) + +#endif diff --git a/arch/arm/mach-omap2/sdram-hynix-h8mbx00u0mer-0em.h b/arch/arm/mach-omap2/sdram-hynix-h8mbx00u0mer-0em.h new file mode 100644 index 00000000000..1ee58c281a3 --- /dev/null +++ b/arch/arm/mach-omap2/sdram-hynix-h8mbx00u0mer-0em.h @@ -0,0 +1,51 @@ +/* + * SDRC register values for the Hynix H8MBX00U0MER-0EM + * + * Copyright (C) 2009 Texas Instruments, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_SDRAM_HYNIX_H8MBX00U0MER0EM +#define __ARCH_ARM_MACH_OMAP2_SDRAM_HYNIX_H8MBX00U0MER0EM + +#include "sdrc.h" + +/* Hynix H8MBX00U0MER-0EM */ +static struct omap_sdrc_params h8mbx00u0mer0em_sdrc_params[] = { + [0] = { + .rate = 200000000, + .actim_ctrla = 0xa2e1b4c6, + .actim_ctrlb = 0x0002131c, + .rfr_ctrl = 0x0005e601, + .mr = 0x00000032, + }, + [1] = { + .rate = 166000000, + .actim_ctrla = 0x629db4c6, + .actim_ctrlb = 0x00012214, + .rfr_ctrl = 0x0004dc01, + .mr = 0x00000032, + }, + [2] = { + .rate = 100000000, + .actim_ctrla = 0x51912284, + .actim_ctrlb = 0x0002120e, + .rfr_ctrl = 0x0002d101, + .mr = 0x00000022, + }, + [3] = { + .rate = 83000000, + .actim_ctrla = 0x31512283, + .actim_ctrlb = 0x0001220a, + .rfr_ctrl = 0x00025501, + .mr = 0x00000022, + }, + [4] = { + .rate = 0 + }, +}; + +#endif diff --git a/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h b/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h new file mode 100644 index 00000000000..85cccc004c0 --- /dev/null +++ b/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h @@ -0,0 +1,55 @@ +/* + * SDRC register values for the Micron MT46H32M32LF-6 + * + * Copyright (C) 2008 Texas Instruments, Inc. + * Copyright (C) 2008-2009 Nokia Corporation + * + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef ARCH_ARM_MACH_OMAP2_SDRAM_MICRON_MT46H32M32LF +#define ARCH_ARM_MACH_OMAP2_SDRAM_MICRON_MT46H32M32LF + +#include "sdrc.h" + +/* Micron MT46H32M32LF-6 */ +/* XXX Using ARE = 0x1 (no autorefresh burst) -- can this be changed? */ +static struct omap_sdrc_params mt46h32m32lf6_sdrc_params[] = { + [0] = { + .rate = 166000000, + .actim_ctrla = 0x9a9db4c6, + .actim_ctrlb = 0x00011217, + .rfr_ctrl = 0x0004dc01, + .mr = 0x00000032, + }, + [1] = { + .rate = 165941176, + .actim_ctrla = 0x9a9db4c6, + .actim_ctrlb = 0x00011217, + .rfr_ctrl = 0x0004dc01, + .mr = 0x00000032, + }, + [2] = { + .rate = 83000000, + .actim_ctrla = 0x51512283, + .actim_ctrlb = 0x0001120c, + .rfr_ctrl = 0x00025501, + .mr = 0x00000032, + }, + [3] = { + .rate = 82970588, + .actim_ctrla = 0x51512283, + .actim_ctrlb = 0x0001120c, + .rfr_ctrl = 0x00025501, + .mr = 0x00000032, + }, + [4] = { + .rate = 0 + }, +}; + +#endif diff --git a/arch/arm/mach-omap2/sdram-nokia.c b/arch/arm/mach-omap2/sdram-nokia.c new file mode 100644 index 00000000000..0fa7ffa9b5e --- /dev/null +++ b/arch/arm/mach-omap2/sdram-nokia.c @@ -0,0 +1,299 @@ +/* + * SDRC register values for Nokia boards + * + * Copyright (C) 2008, 2010-2011 Nokia Corporation + * + * Lauri Leukkunen <lauri.leukkunen@nokia.com> + * + * Original code by Juha Yrjola <juha.yrjola@solidboot.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/io.h> + +#include "common.h" +#include "sdram-nokia.h" +#include "sdrc.h" + +/* In picoseconds, except for tREF (ns), tXP, tCKE, tWTR (clks) */ +struct sdram_timings { + u32 casl; + u32 tDAL; + u32 tDPL; + u32 tRRD; + u32 tRCD; + u32 tRP; + u32 tRAS; + u32 tRC; + u32 tRFC; + u32 tXSR; + + u32 tREF; /* in ns */ + + u32 tXP; + u32 tCKE; + u32 tWTR; +}; + +static const struct sdram_timings nokia_97dot6mhz_timings[] = { + { + .casl = 3, + .tDAL = 30725, + .tDPL = 15362, + .tRRD = 10241, + .tRCD = 20483, + .tRP = 15362, + .tRAS = 40967, + .tRC = 56330, + .tRFC = 138266, + .tXSR = 204839, + + .tREF = 7798, + + .tXP = 2, + .tCKE = 4, + .tWTR = 2, + }, +}; + +static const struct sdram_timings nokia_166mhz_timings[] = { + { + .casl = 3, + .tDAL = 33000, + .tDPL = 15000, + .tRRD = 12000, + .tRCD = 22500, + .tRP = 18000, + .tRAS = 42000, + .tRC = 66000, + .tRFC = 138000, + .tXSR = 200000, + + .tREF = 7800, + + .tXP = 2, + .tCKE = 2, + .tWTR = 2 + }, +}; + +static const struct sdram_timings nokia_195dot2mhz_timings[] = { + { + .casl = 3, + .tDAL = 30725, + .tDPL = 15362, + .tRRD = 10241, + .tRCD = 20483, + .tRP = 15362, + .tRAS = 40967, + .tRC = 56330, + .tRFC = 138266, + .tXSR = 204839, + + .tREF = 7752, + + .tXP = 2, + .tCKE = 4, + .tWTR = 2, + }, +}; + +static const struct sdram_timings nokia_200mhz_timings[] = { + { + .casl = 3, + .tDAL = 30000, + .tDPL = 15000, + .tRRD = 10000, + .tRCD = 20000, + .tRP = 15000, + .tRAS = 40000, + .tRC = 55000, + .tRFC = 140000, + .tXSR = 200000, + + .tREF = 7800, + + .tXP = 2, + .tCKE = 4, + .tWTR = 2 + }, +}; + +static const struct { + long rate; + struct sdram_timings const *data; +} nokia_timings[] = { + { 83000000, nokia_166mhz_timings }, + { 97600000, nokia_97dot6mhz_timings }, + { 100000000, nokia_200mhz_timings }, + { 166000000, nokia_166mhz_timings }, + { 195200000, nokia_195dot2mhz_timings }, + { 200000000, nokia_200mhz_timings }, +}; +static struct omap_sdrc_params nokia_sdrc_params[ARRAY_SIZE(nokia_timings) + 1]; + +static unsigned long sdrc_get_fclk_period(long rate) +{ + /* In picoseconds */ + return 1000000000 / rate; +} + +static unsigned int sdrc_ps_to_ticks(unsigned int time_ps, long rate) +{ + unsigned long tick_ps; + + /* Calculate in picosecs to yield more exact results */ + tick_ps = sdrc_get_fclk_period(rate); + + return (time_ps + tick_ps - 1) / tick_ps; +} +#undef DEBUG +#ifdef DEBUG +static int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit, + int ticks, long rate, const char *name) +#else +static int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit, + int ticks) +#endif +{ + int mask, nr_bits; + + nr_bits = end_bit - st_bit + 1; + if (ticks >= 1 << nr_bits) + return -1; + mask = (1 << nr_bits) - 1; + *regval &= ~(mask << st_bit); + *regval |= ticks << st_bit; +#ifdef DEBUG + printk(KERN_INFO "SDRC %s: %i ticks %i ns\n", name, ticks, + (unsigned int)sdrc_get_fclk_period(rate) * ticks / + 1000); +#endif + + return 0; +} + +#ifdef DEBUG +#define SDRC_SET_ONE(reg, st, end, field, rate) \ + if (set_sdrc_timing_regval((reg), (st), (end), \ + memory_timings->field, (rate), #field) < 0) \ + err = -1; +#else +#define SDRC_SET_ONE(reg, st, end, field, rate) \ + if (set_sdrc_timing_regval((reg), (st), (end), \ + memory_timings->field) < 0) \ + err = -1; +#endif + +#ifdef DEBUG +static int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit, + int time, long rate, const char *name) +#else +static int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit, + int time, long rate) +#endif +{ + int ticks, ret; + ret = 0; + + if (time == 0) + ticks = 0; + else + ticks = sdrc_ps_to_ticks(time, rate); + +#ifdef DEBUG + ret = set_sdrc_timing_regval(regval, st_bit, end_bit, ticks, + rate, name); +#else + ret = set_sdrc_timing_regval(regval, st_bit, end_bit, ticks); +#endif + + return ret; +} + +#ifdef DEBUG +#define SDRC_SET_ONE_PS(reg, st, end, field, rate) \ + if (set_sdrc_timing_regval_ps((reg), (st), (end), \ + memory_timings->field, \ + (rate), #field) < 0) \ + err = -1; + +#else +#define SDRC_SET_ONE_PS(reg, st, end, field, rate) \ + if (set_sdrc_timing_regval_ps((reg), (st), (end), \ + memory_timings->field, (rate)) < 0) \ + err = -1; +#endif + +static int sdrc_timings(int id, long rate, + const struct sdram_timings *memory_timings) +{ + u32 ticks_per_ms; + u32 rfr, l; + u32 actim_ctrla = 0, actim_ctrlb = 0; + u32 rfr_ctrl; + int err = 0; + long l3_rate = rate / 1000; + + SDRC_SET_ONE_PS(&actim_ctrla, 0, 4, tDAL, l3_rate); + SDRC_SET_ONE_PS(&actim_ctrla, 6, 8, tDPL, l3_rate); + SDRC_SET_ONE_PS(&actim_ctrla, 9, 11, tRRD, l3_rate); + SDRC_SET_ONE_PS(&actim_ctrla, 12, 14, tRCD, l3_rate); + SDRC_SET_ONE_PS(&actim_ctrla, 15, 17, tRP, l3_rate); + SDRC_SET_ONE_PS(&actim_ctrla, 18, 21, tRAS, l3_rate); + SDRC_SET_ONE_PS(&actim_ctrla, 22, 26, tRC, l3_rate); + SDRC_SET_ONE_PS(&actim_ctrla, 27, 31, tRFC, l3_rate); + + SDRC_SET_ONE_PS(&actim_ctrlb, 0, 7, tXSR, l3_rate); + + SDRC_SET_ONE(&actim_ctrlb, 8, 10, tXP, l3_rate); + SDRC_SET_ONE(&actim_ctrlb, 12, 14, tCKE, l3_rate); + SDRC_SET_ONE(&actim_ctrlb, 16, 17, tWTR, l3_rate); + + ticks_per_ms = l3_rate; + rfr = memory_timings[0].tREF * ticks_per_ms / 1000000; + if (rfr > 65535 + 50) + rfr = 65535; + else + rfr -= 50; + +#ifdef DEBUG + printk(KERN_INFO "SDRC tREF: %i ticks\n", rfr); +#endif + + l = rfr << 8; + rfr_ctrl = l | 0x1; /* autorefresh, reload counter with 1xARCV */ + + nokia_sdrc_params[id].rate = rate; + nokia_sdrc_params[id].actim_ctrla = actim_ctrla; + nokia_sdrc_params[id].actim_ctrlb = actim_ctrlb; + nokia_sdrc_params[id].rfr_ctrl = rfr_ctrl; + nokia_sdrc_params[id].mr = 0x32; + + nokia_sdrc_params[id + 1].rate = 0; + + return err; +} + +struct omap_sdrc_params *nokia_get_sdram_timings(void) +{ + int err = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(nokia_timings); i++) { + err |= sdrc_timings(i, nokia_timings[i].rate, + nokia_timings[i].data); + if (err) + pr_err("%s: error with rate %ld: %d\n", __func__, + nokia_timings[i].rate, err); + } + + return err ? NULL : nokia_sdrc_params; +} + diff --git a/arch/arm/mach-omap2/sdram-nokia.h b/arch/arm/mach-omap2/sdram-nokia.h new file mode 100644 index 00000000000..ee63da5f8df --- /dev/null +++ b/arch/arm/mach-omap2/sdram-nokia.h @@ -0,0 +1,12 @@ +/* + * SDRC register values for Nokia boards + * + * Copyright (C) 2010 Nokia + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +struct omap_sdrc_params *nokia_get_sdram_timings(void); + diff --git a/arch/arm/mach-omap2/sdram-numonyx-m65kxxxxam.h b/arch/arm/mach-omap2/sdram-numonyx-m65kxxxxam.h new file mode 100644 index 00000000000..003f7bf4e2e --- /dev/null +++ b/arch/arm/mach-omap2/sdram-numonyx-m65kxxxxam.h @@ -0,0 +1,51 @@ +/* + * SDRC register values for the Numonyx M65KXXXXAM + * + * Copyright (C) 2009 Integration Software and Electronic Engineering. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_SDRAM_NUMONYX_M65KXXXXAM +#define __ARCH_ARM_MACH_OMAP2_SDRAM_NUMONYX_M65KXXXXAM + +#include "sdrc.h" + +/* Numonyx M65KXXXXAM */ +static struct omap_sdrc_params m65kxxxxam_sdrc_params[] = { + [0] = { + .rate = 200000000, + .actim_ctrla = 0xe321d4c6, + .actim_ctrlb = 0x00022328, + .rfr_ctrl = 0x0005e601, + .mr = 0x00000032, + }, + [1] = { + .rate = 166000000, + .actim_ctrla = 0xba9dc485, + .actim_ctrlb = 0x00022321, + .rfr_ctrl = 0x0004dc01, + .mr = 0x00000032, + }, + [2] = { + .rate = 133000000, + .actim_ctrla = 0x9a19b485, + .actim_ctrlb = 0x0002231b, + .rfr_ctrl = 0x0003de01, + .mr = 0x00000032, + }, + [3] = { + .rate = 83000000, + .actim_ctrla = 0x594ca242, + .actim_ctrlb = 0x00022310, + .rfr_ctrl = 0x00025501, + .mr = 0x00000032, + }, + [4] = { + .rate = 0 + }, +}; + +#endif diff --git a/arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h b/arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h new file mode 100644 index 00000000000..8dc3de5ebb5 --- /dev/null +++ b/arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h @@ -0,0 +1,54 @@ +/* + * SDRC register values for the Qimonda HYB18M512160AF-6 + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * Copyright (C) 2008-2009 Nokia Corporation + * + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef ARCH_ARM_MACH_OMAP2_SDRAM_QIMONDA_HYB18M512160AF6 +#define ARCH_ARM_MACH_OMAP2_SDRAM_QIMONDA_HYB18M512160AF6 + +#include "sdrc.h" + +/* Qimonda HYB18M512160AF-6 */ +static struct omap_sdrc_params hyb18m512160af6_sdrc_params[] = { + [0] = { + .rate = 166000000, + .actim_ctrla = 0x629db4c6, + .actim_ctrlb = 0x00012214, + .rfr_ctrl = 0x0004dc01, + .mr = 0x00000032, + }, + [1] = { + .rate = 165941176, + .actim_ctrla = 0x629db4c6, + .actim_ctrlb = 0x00012214, + .rfr_ctrl = 0x0004dc01, + .mr = 0x00000032, + }, + [2] = { + .rate = 83000000, + .actim_ctrla = 0x31512283, + .actim_ctrlb = 0x0001220a, + .rfr_ctrl = 0x00025501, + .mr = 0x00000022, + }, + [3] = { + .rate = 82970588, + .actim_ctrla = 0x31512283, + .actim_ctrlb = 0x0001220a, + .rfr_ctrl = 0x00025501, + .mr = 0x00000022, + }, + [4] = { + .rate = 0 + }, +}; + +#endif diff --git a/arch/arm/mach-omap2/sdrc.c b/arch/arm/mach-omap2/sdrc.c new file mode 100644 index 00000000000..dae7e4804a4 --- /dev/null +++ b/arch/arm/mach-omap2/sdrc.c @@ -0,0 +1,157 @@ +/* + * SMS/SDRC (SDRAM controller) common code for OMAP2/3 + * + * Copyright (C) 2005, 2008 Texas Instruments Inc. + * Copyright (C) 2005, 2008 Nokia Corporation + * + * Tony Lindgren <tony@atomide.com> + * Paul Walmsley + * Richard Woodruff <r-woodruff2@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#undef DEBUG + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/device.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/delay.h> +#include <linux/clk.h> +#include <linux/io.h> + +#include "common.h" +#include "clock.h" +#include "sdrc.h" + +static struct omap_sdrc_params *sdrc_init_params_cs0, *sdrc_init_params_cs1; + +void __iomem *omap2_sdrc_base; +void __iomem *omap2_sms_base; + +struct omap2_sms_regs { + u32 sms_sysconfig; +}; + +static struct omap2_sms_regs sms_context; + +/* SDRC_POWER register bits */ +#define SDRC_POWER_EXTCLKDIS_SHIFT 3 +#define SDRC_POWER_PWDENA_SHIFT 2 +#define SDRC_POWER_PAGEPOLICY_SHIFT 0 + +/** + * omap2_sms_save_context - Save SMS registers + * + * Save SMS registers that need to be restored after off mode. + */ +void omap2_sms_save_context(void) +{ + sms_context.sms_sysconfig = sms_read_reg(SMS_SYSCONFIG); +} + +/** + * omap2_sms_restore_context - Restore SMS registers + * + * Restore SMS registers that need to be Restored after off mode. + */ +void omap2_sms_restore_context(void) +{ + sms_write_reg(sms_context.sms_sysconfig, SMS_SYSCONFIG); +} + +/** + * omap2_sdrc_get_params - return SDRC register values for a given clock rate + * @r: SDRC clock rate (in Hz) + * @sdrc_cs0: chip select 0 ram timings ** + * @sdrc_cs1: chip select 1 ram timings ** + * + * Return pre-calculated values for the SDRC_ACTIM_CTRLA, + * SDRC_ACTIM_CTRLB, SDRC_RFR_CTRL and SDRC_MR registers in sdrc_cs[01] + * structs,for a given SDRC clock rate 'r'. + * These parameters control various timing delays in the SDRAM controller + * that are expressed in terms of the number of SDRC clock cycles to + * wait; hence the clock rate dependency. + * + * Supports 2 different timing parameters for both chip selects. + * + * Note 1: the sdrc_init_params_cs[01] must be sorted rate descending. + * Note 2: If sdrc_init_params_cs_1 is not NULL it must be of same size + * as sdrc_init_params_cs_0. + * + * Fills in the struct omap_sdrc_params * for each chip select. + * Returns 0 upon success or -1 upon failure. + */ +int omap2_sdrc_get_params(unsigned long r, + struct omap_sdrc_params **sdrc_cs0, + struct omap_sdrc_params **sdrc_cs1) +{ + struct omap_sdrc_params *sp0, *sp1; + + if (!sdrc_init_params_cs0) + return -1; + + sp0 = sdrc_init_params_cs0; + sp1 = sdrc_init_params_cs1; + + while (sp0->rate && sp0->rate != r) { + sp0++; + if (sdrc_init_params_cs1) + sp1++; + } + + if (!sp0->rate) + return -1; + + *sdrc_cs0 = sp0; + *sdrc_cs1 = sp1; + return 0; +} + + +void __init omap2_set_globals_sdrc(void __iomem *sdrc, void __iomem *sms) +{ + omap2_sdrc_base = sdrc; + omap2_sms_base = sms; +} + +/** + * omap2_sdrc_init - initialize SMS, SDRC devices on boot + * @sdrc_cs[01]: pointers to a null-terminated list of struct omap_sdrc_params + * Support for 2 chip selects timings + * + * Turn on smart idle modes for SDRAM scheduler and controller. + * Program a known-good configuration for the SDRC to deal with buggy + * bootloaders. + */ +void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0, + struct omap_sdrc_params *sdrc_cs1) +{ + u32 l; + + l = sms_read_reg(SMS_SYSCONFIG); + l &= ~(0x3 << 3); + l |= (0x2 << 3); + sms_write_reg(l, SMS_SYSCONFIG); + + l = sdrc_read_reg(SDRC_SYSCONFIG); + l &= ~(0x3 << 3); + l |= (0x2 << 3); + sdrc_write_reg(l, SDRC_SYSCONFIG); + + sdrc_init_params_cs0 = sdrc_cs0; + sdrc_init_params_cs1 = sdrc_cs1; + + /* XXX Enable SRFRONIDLEREQ here also? */ + /* + * PWDENA should not be set due to 34xx erratum 1.150 - PWDENA + * can cause random memory corruption + */ + l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) | + (1 << SDRC_POWER_PAGEPOLICY_SHIFT); + sdrc_write_reg(l, SDRC_POWER); + omap2_sms_save_context(); +} diff --git a/arch/arm/mach-omap2/sdrc.h b/arch/arm/mach-omap2/sdrc.h index 1a8bbd09406..645a2a46b21 100644 --- a/arch/arm/mach-omap2/sdrc.h +++ b/arch/arm/mach-omap2/sdrc.h @@ -2,12 +2,14 @@ #define __ARCH_ARM_MACH_OMAP2_SDRC_H /* - * OMAP2 SDRC register definitions + * OMAP2/3 SDRC/SMS macros and prototypes * - * Copyright (C) 2007 Texas Instruments, Inc. - * Copyright (C) 2007 Nokia Corporation + * Copyright (C) 2007-2008, 2012 Texas Instruments, Inc. + * Copyright (C) 2007-2008 Nokia Corporation * - * Written by Paul Walmsley + * Paul Walmsley + * Tony Lindgren + * Richard Woodruff * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -15,9 +17,10 @@ */ #undef DEBUG -#include <mach/sdrc.h> - #ifndef __ASSEMBLER__ + +#include <linux/io.h> + extern void __iomem *omap2_sdrc_base; extern void __iomem *omap2_sms_base; @@ -28,29 +31,183 @@ extern void __iomem *omap2_sms_base; static inline void sdrc_write_reg(u32 val, u16 reg) { - __raw_writel(val, OMAP_SDRC_REGADDR(reg)); + writel_relaxed(val, OMAP_SDRC_REGADDR(reg)); } static inline u32 sdrc_read_reg(u16 reg) { - return __raw_readl(OMAP_SDRC_REGADDR(reg)); + return readl_relaxed(OMAP_SDRC_REGADDR(reg)); } /* SMS global register get/set */ static inline void sms_write_reg(u32 val, u16 reg) { - __raw_writel(val, OMAP_SMS_REGADDR(reg)); + writel_relaxed(val, OMAP_SMS_REGADDR(reg)); } static inline u32 sms_read_reg(u16 reg) { - return __raw_readl(OMAP_SMS_REGADDR(reg)); + return readl_relaxed(OMAP_SMS_REGADDR(reg)); } + +extern void omap2_set_globals_sdrc(void __iomem *sdrc, void __iomem *sms); + + +/** + * struct omap_sdrc_params - SDRC parameters for a given SDRC clock rate + * @rate: SDRC clock rate (in Hz) + * @actim_ctrla: Value to program to SDRC_ACTIM_CTRLA for this rate + * @actim_ctrlb: Value to program to SDRC_ACTIM_CTRLB for this rate + * @rfr_ctrl: Value to program to SDRC_RFR_CTRL for this rate + * @mr: Value to program to SDRC_MR for this rate + * + * This structure holds a pre-computed set of register values for the + * SDRC for a given SDRC clock rate and SDRAM chip. These are + * intended to be pre-computed and specified in an array in the board-*.c + * files. The structure is keyed off the 'rate' field. + */ +struct omap_sdrc_params { + unsigned long rate; + u32 actim_ctrla; + u32 actim_ctrlb; + u32 rfr_ctrl; + u32 mr; +}; + +#ifdef CONFIG_SOC_HAS_OMAP2_SDRC +void omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0, + struct omap_sdrc_params *sdrc_cs1); #else -#define OMAP242X_SDRC_REGADDR(reg) IO_ADDRESS(OMAP2420_SDRC_BASE + (reg)) -#define OMAP243X_SDRC_REGADDR(reg) IO_ADDRESS(OMAP243X_SDRC_BASE + (reg)) -#define OMAP34XX_SDRC_REGADDR(reg) IO_ADDRESS(OMAP343X_SDRC_BASE + (reg)) +static inline void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0, + struct omap_sdrc_params *sdrc_cs1) {}; +#endif + +int omap2_sdrc_get_params(unsigned long r, + struct omap_sdrc_params **sdrc_cs0, + struct omap_sdrc_params **sdrc_cs1); +void omap2_sms_save_context(void); +void omap2_sms_restore_context(void); + +struct memory_timings { + u32 m_type; /* ddr = 1, sdr = 0 */ + u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */ + u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */ + u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */ + u32 base_cs; /* base chip select to use for calculations */ +}; + +extern void omap2xxx_sdrc_init_params(u32 force_lock_to_unlock_mode); +struct omap_sdrc_params *rx51_get_sdram_timings(void); + +u32 omap2xxx_sdrc_dll_is_unlocked(void); +u32 omap2xxx_sdrc_reprogram(u32 level, u32 force); + + +#else +#define OMAP242X_SDRC_REGADDR(reg) \ + OMAP2_L3_IO_ADDRESS(OMAP2420_SDRC_BASE + (reg)) +#define OMAP243X_SDRC_REGADDR(reg) \ + OMAP2_L3_IO_ADDRESS(OMAP243X_SDRC_BASE + (reg)) +#define OMAP34XX_SDRC_REGADDR(reg) \ + OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE + (reg)) + #endif /* __ASSEMBLER__ */ +/* Minimum frequency that the SDRC DLL can lock at */ +#define MIN_SDRC_DLL_LOCK_FREQ 83000000 + +/* Scale factor for fixed-point arith in omap3_core_dpll_m2_set_rate() */ +#define SDRC_MPURATE_SCALE 8 + +/* 2^SDRC_MPURATE_BASE_SHIFT: MPU MHz that SDRC_MPURATE_LOOPS is defined for */ +#define SDRC_MPURATE_BASE_SHIFT 9 + +/* + * SDRC_MPURATE_LOOPS: Number of MPU loops to execute at + * 2^MPURATE_BASE_SHIFT MHz for SDRC to stabilize + */ +#define SDRC_MPURATE_LOOPS 96 + +/* SDRC register offsets - read/write with sdrc_{read,write}_reg() */ + +#define SDRC_SYSCONFIG 0x010 +#define SDRC_CS_CFG 0x040 +#define SDRC_SHARING 0x044 +#define SDRC_ERR_TYPE 0x04C +#define SDRC_DLLA_CTRL 0x060 +#define SDRC_DLLA_STATUS 0x064 +#define SDRC_DLLB_CTRL 0x068 +#define SDRC_DLLB_STATUS 0x06C +#define SDRC_POWER 0x070 +#define SDRC_MCFG_0 0x080 +#define SDRC_MR_0 0x084 +#define SDRC_EMR2_0 0x08c +#define SDRC_ACTIM_CTRL_A_0 0x09c +#define SDRC_ACTIM_CTRL_B_0 0x0a0 +#define SDRC_RFR_CTRL_0 0x0a4 +#define SDRC_MANUAL_0 0x0a8 +#define SDRC_MCFG_1 0x0B0 +#define SDRC_MR_1 0x0B4 +#define SDRC_EMR2_1 0x0BC +#define SDRC_ACTIM_CTRL_A_1 0x0C4 +#define SDRC_ACTIM_CTRL_B_1 0x0C8 +#define SDRC_RFR_CTRL_1 0x0D4 +#define SDRC_MANUAL_1 0x0D8 + +#define SDRC_POWER_AUTOCOUNT_SHIFT 8 +#define SDRC_POWER_AUTOCOUNT_MASK (0xffff << SDRC_POWER_AUTOCOUNT_SHIFT) +#define SDRC_POWER_CLKCTRL_SHIFT 4 +#define SDRC_POWER_CLKCTRL_MASK (0x3 << SDRC_POWER_CLKCTRL_SHIFT) +#define SDRC_SELF_REFRESH_ON_AUTOCOUNT (0x2 << SDRC_POWER_CLKCTRL_SHIFT) + +/* + * These values represent the number of memory clock cycles between + * autorefresh initiation. They assume 1 refresh per 64 ms (JEDEC), 8192 + * rows per device, and include a subtraction of a 50 cycle window in the + * event that the autorefresh command is delayed due to other SDRC activity. + * The '| 1' sets the ARE field to send one autorefresh when the autorefresh + * counter reaches 0. + * + * These represent optimal values for common parts, it won't work for all. + * As long as you scale down, most parameters are still work, they just + * become sub-optimal. The RFR value goes in the opposite direction. If you + * don't adjust it down as your clock period increases the refresh interval + * will not be met. Setting all parameters for complete worst case may work, + * but may cut memory performance by 2x. Due to errata the DLLs need to be + * unlocked and their value needs run time calibration. A dynamic call is + * need for that as no single right value exists acorss production samples. + * + * Only the FULL speed values are given. Current code is such that rate + * changes must be made at DPLLoutx2. The actual value adjustment for low + * frequency operation will be handled by omap_set_performance() + * + * By having the boot loader boot up in the fastest L4 speed available likely + * will result in something which you can switch between. + */ +#define SDRC_RFR_CTRL_165MHz (0x00044c00 | 1) +#define SDRC_RFR_CTRL_133MHz (0x0003de00 | 1) +#define SDRC_RFR_CTRL_100MHz (0x0002da01 | 1) +#define SDRC_RFR_CTRL_110MHz (0x0002da01 | 1) /* Need to calc */ +#define SDRC_RFR_CTRL_BYPASS (0x00005000 | 1) /* Need to calc */ + + +/* + * SMS register access + */ + +#define OMAP242X_SMS_REGADDR(reg) \ + (void __iomem *)OMAP2_L3_IO_ADDRESS(OMAP2420_SMS_BASE + reg) +#define OMAP243X_SMS_REGADDR(reg) \ + (void __iomem *)OMAP2_L3_IO_ADDRESS(OMAP243X_SMS_BASE + reg) +#define OMAP343X_SMS_REGADDR(reg) \ + (void __iomem *)OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE + reg) + +/* SMS register offsets - read/write with sms_{read,write}_reg() */ + +#define SMS_SYSCONFIG 0x010 +/* REVISIT: fill in other SMS registers here */ + + + #endif diff --git a/arch/arm/mach-omap2/memory.c b/arch/arm/mach-omap2/sdrc2xxx.c index 882c7022429..ae3f1553158 100644 --- a/arch/arm/mach-omap2/memory.c +++ b/arch/arm/mach-omap2/sdrc2xxx.c @@ -1,13 +1,14 @@ /* - * linux/arch/arm/mach-omap2/memory.c + * linux/arch/arm/mach-omap2/sdrc2xxx.c * - * Memory timing related functions for OMAP24XX + * SDRAM timing related functions for OMAP2xxx * - * Copyright (C) 2005 Texas Instruments Inc. - * Richard Woodruff <r-woodruff2@ti.com> + * Copyright (C) 2005, 2008 Texas Instruments Inc. + * Copyright (C) 2005, 2008 Nokia Corporation * - * Copyright (C) 2005 Nokia Corporation * Tony Lindgren <tony@atomide.com> + * Paul Walmsley + * Richard Woodruff <r-woodruff2@ti.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -23,32 +24,35 @@ #include <linux/clk.h> #include <linux/io.h> -#include <mach/common.h> -#include <mach/clock.h> -#include <mach/sram.h> - -#include "prm.h" - -#include "memory.h" +#include "soc.h" +#include "iomap.h" +#include "common.h" +#include "prm2xxx.h" +#include "clock.h" #include "sdrc.h" +#include "sram.h" + +/* Memory timing, DLL mode flags */ +#define M_DDR 1 +#define M_LOCK_CTRL (1 << 2) +#define M_UNLOCK 0 +#define M_LOCK 1 -void __iomem *omap2_sdrc_base; -void __iomem *omap2_sms_base; static struct memory_timings mem_timings; static u32 curr_perf_level = CORE_CLK_SRC_DPLL_X2; -u32 omap2_memory_get_slow_dll_ctrl(void) +static u32 omap2xxx_sdrc_get_slow_dll_ctrl(void) { return mem_timings.slow_dll_ctrl; } -u32 omap2_memory_get_fast_dll_ctrl(void) +static u32 omap2xxx_sdrc_get_fast_dll_ctrl(void) { return mem_timings.fast_dll_ctrl; } -u32 omap2_memory_get_type(void) +static u32 omap2xxx_sdrc_get_type(void) { return mem_timings.m_type; } @@ -57,7 +61,7 @@ u32 omap2_memory_get_type(void) * Check the DLL lock state, and return tue if running in unlock mode. * This is needed to compensate for the shifted DLL value in unlock mode. */ -u32 omap2_dll_force_needed(void) +u32 omap2xxx_sdrc_dll_is_unlocked(void) { /* dlla and dllb are a set */ u32 dll_state = sdrc_read_reg(SDRC_DLLA_CTRL); @@ -72,8 +76,10 @@ u32 omap2_dll_force_needed(void) * 'level' is the value to store to CM_CLKSEL2_PLL.CORE_CLK_SRC. * Practical values are CORE_CLK_SRC_DPLL (for CORE_CLK = DPLL_CLK) or * CORE_CLK_SRC_DPLL_X2 (for CORE_CLK = * DPLL_CLK * 2) + * + * Used by the clock framework during CORE DPLL changes */ -u32 omap2_reprogram_sdrc(u32 level, u32 force) +u32 omap2xxx_sdrc_reprogram(u32 level, u32 force) { u32 dll_ctrl, m_type; u32 prev = curr_perf_level; @@ -82,18 +88,24 @@ u32 omap2_reprogram_sdrc(u32 level, u32 force) if ((curr_perf_level == level) && !force) return prev; - if (level == CORE_CLK_SRC_DPLL) { - dll_ctrl = omap2_memory_get_slow_dll_ctrl(); - } else if (level == CORE_CLK_SRC_DPLL_X2) { - dll_ctrl = omap2_memory_get_fast_dll_ctrl(); - } else { + if (level == CORE_CLK_SRC_DPLL) + dll_ctrl = omap2xxx_sdrc_get_slow_dll_ctrl(); + else if (level == CORE_CLK_SRC_DPLL_X2) + dll_ctrl = omap2xxx_sdrc_get_fast_dll_ctrl(); + else return prev; - } - m_type = omap2_memory_get_type(); + m_type = omap2xxx_sdrc_get_type(); local_irq_save(flags); - __raw_writel(0xffff, OMAP24XX_PRCM_VOLTSETUP); + /* + * XXX These calls should be abstracted out through a + * prm2xxx.c function + */ + if (cpu_is_omap2420()) + writel_relaxed(0xffff, OMAP2420_PRCM_VOLTSETUP); + else + writel_relaxed(0xffff, OMAP2430_PRCM_VOLTSETUP); omap2_sram_reprogram_sdrc(level, dll_ctrl, m_type); curr_perf_level = level; local_irq_restore(flags); @@ -101,23 +113,14 @@ u32 omap2_reprogram_sdrc(u32 level, u32 force) return prev; } -#if !defined(CONFIG_ARCH_OMAP2) -void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, - u32 base_cs, u32 force_unlock) -{ -} -void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, - u32 mem_type) -{ -} -#endif - -void omap2_init_memory_params(u32 force_lock_to_unlock_mode) +/* Used by the clock framework during CORE DPLL changes */ +void omap2xxx_sdrc_init_params(u32 force_lock_to_unlock_mode) { unsigned long dll_cnt; u32 fast_dll = 0; - mem_timings.m_type = !((sdrc_read_reg(SDRC_MR_0) & 0x3) == 0x1); /* DDR = 1, SDR = 0 */ + /* DDR = 1, SDR = 0 */ + mem_timings.m_type = !((sdrc_read_reg(SDRC_MR_0) & 0x3) == 0x1); /* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others. * In the case of 2422, its ok to use CS1 instead of CS0. @@ -164,28 +167,3 @@ void omap2_init_memory_params(u32 force_lock_to_unlock_mode) /* 90 degree phase for anything below 133Mhz + disable DLL filter */ mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8)); } - -void __init omap2_set_globals_memory(struct omap_globals *omap2_globals) -{ - omap2_sdrc_base = omap2_globals->sdrc; - omap2_sms_base = omap2_globals->sms; -} - -/* turn on smart idle modes for SDRAM scheduler and controller */ -void __init omap2_init_memory(void) -{ - u32 l; - - if (!cpu_is_omap2420()) - return; - - l = sms_read_reg(SMS_SYSCONFIG); - l &= ~(0x3 << 3); - l |= (0x2 << 3); - sms_write_reg(l, SMS_SYSCONFIG); - - l = sdrc_read_reg(SDRC_SYSCONFIG); - l &= ~(0x3 << 3); - l |= (0x2 << 3); - sdrc_write_reg(l, SDRC_SYSCONFIG); -} diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 4dcf39c285b..a388f8c1bcb 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -6,154 +6,330 @@ * Copyright (C) 2005-2008 Nokia Corporation * Author: Paul Mundt <paul.mundt@nokia.com> * + * Major rework for PM support by Kevin Hilman + * * Based off of arch/arm/mach-omap/omap1/serial.c * + * Copyright (C) 2009 Texas Instruments + * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com + * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. */ #include <linux/kernel.h> #include <linux/init.h> -#include <linux/serial_8250.h> -#include <linux/serial_reg.h> #include <linux/clk.h> #include <linux/io.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/pm_runtime.h> +#include <linux/console.h> +#include <linux/omap-dma.h> +#include <linux/platform_data/serial-omap.h> + +#include "common.h" +#include "omap_hwmod.h" +#include "omap_device.h" +#include "omap-pm.h" +#include "soc.h" +#include "prm2xxx_3xxx.h" +#include "pm.h" +#include "cm2xxx_3xxx.h" +#include "prm-regbits-34xx.h" +#include "control.h" +#include "mux.h" +#include "serial.h" + +/* + * NOTE: By default the serial auto_suspend timeout is disabled as it causes + * lost characters over the serial ports. This means that the UART clocks will + * stay on until power/autosuspend_delay is set for the uart from sysfs. + * This also causes that any deeper omap sleep states are blocked. + */ +#define DEFAULT_AUTOSUSPEND_DELAY -1 + +#define MAX_UART_HWMOD_NAME_LEN 16 + +struct omap_uart_state { + int num; + + struct list_head node; + struct omap_hwmod *oh; + struct omap_device_pad default_omap_uart_pads[2]; +}; -#include <mach/common.h> -#include <mach/board.h> +static LIST_HEAD(uart_list); +static u8 num_uarts; +static u8 console_uart_id = -1; +static u8 uart_debug; -static struct clk *uart_ick[OMAP_MAX_NR_PORTS]; -static struct clk *uart_fck[OMAP_MAX_NR_PORTS]; +#define DEFAULT_RXDMA_POLLRATE 1 /* RX DMA polling rate (us) */ +#define DEFAULT_RXDMA_BUFSIZE 4096 /* RX DMA buffer size */ +#define DEFAULT_RXDMA_TIMEOUT (3 * HZ)/* RX DMA timeout (jiffies) */ -static struct plat_serial8250_port serial_platform_data[] = { +static struct omap_uart_port_info omap_serial_default_info[] __initdata = { { - .membase = IO_ADDRESS(OMAP_UART1_BASE), - .mapbase = OMAP_UART1_BASE, - .irq = 72, - .flags = UPF_BOOT_AUTOCONF, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = OMAP24XX_BASE_BAUD * 16, - }, { - .membase = IO_ADDRESS(OMAP_UART2_BASE), - .mapbase = OMAP_UART2_BASE, - .irq = 73, - .flags = UPF_BOOT_AUTOCONF, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = OMAP24XX_BASE_BAUD * 16, - }, { - .membase = IO_ADDRESS(OMAP_UART3_BASE), - .mapbase = OMAP_UART3_BASE, - .irq = 74, - .flags = UPF_BOOT_AUTOCONF, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = OMAP24XX_BASE_BAUD * 16, - }, { - .flags = 0 - } + .dma_enabled = false, + .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE, + .dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE, + .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT, + .autosuspend_timeout = DEFAULT_AUTOSUSPEND_DELAY, + }, }; -static inline unsigned int serial_read_reg(struct plat_serial8250_port *up, - int offset) +#ifdef CONFIG_PM +static void omap_uart_enable_wakeup(struct device *dev, bool enable) { - offset <<= up->regshift; - return (unsigned int)__raw_readb(up->membase + offset); + struct platform_device *pdev = to_platform_device(dev); + struct omap_device *od = to_omap_device(pdev); + + if (!od) + return; + + if (enable) + omap_hwmod_enable_wakeup(od->hwmods[0]); + else + omap_hwmod_disable_wakeup(od->hwmods[0]); } -static inline void serial_write_reg(struct plat_serial8250_port *p, int offset, - int value) +#else +static void omap_uart_enable_wakeup(struct device *dev, bool enable) +{} +#endif /* CONFIG_PM */ + +#ifdef CONFIG_OMAP_MUX + +#define OMAP_UART_DEFAULT_PAD_NAME_LEN 28 +static char rx_pad_name[OMAP_UART_DEFAULT_PAD_NAME_LEN], + tx_pad_name[OMAP_UART_DEFAULT_PAD_NAME_LEN] __initdata; + +static void __init +omap_serial_fill_uart_tx_rx_pads(struct omap_board_data *bdata, + struct omap_uart_state *uart) { - offset <<= p->regshift; - __raw_writeb(value, p->membase + offset); + uart->default_omap_uart_pads[0].name = rx_pad_name; + uart->default_omap_uart_pads[0].flags = OMAP_DEVICE_PAD_REMUX | + OMAP_DEVICE_PAD_WAKEUP; + uart->default_omap_uart_pads[0].enable = OMAP_PIN_INPUT | + OMAP_MUX_MODE0; + uart->default_omap_uart_pads[0].idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0; + uart->default_omap_uart_pads[1].name = tx_pad_name; + uart->default_omap_uart_pads[1].enable = OMAP_PIN_OUTPUT | + OMAP_MUX_MODE0; + bdata->pads = uart->default_omap_uart_pads; + bdata->pads_cnt = ARRAY_SIZE(uart->default_omap_uart_pads); } -/* - * Internal UARTs need to be initialized for the 8250 autoconfig to work - * properly. Note that the TX watermark initialization may not be needed - * once the 8250.c watermark handling code is merged. - */ -static inline void __init omap_serial_reset(struct plat_serial8250_port *p) +static void __init omap_serial_check_wakeup(struct omap_board_data *bdata, + struct omap_uart_state *uart) { - serial_write_reg(p, UART_OMAP_MDR1, 0x07); - serial_write_reg(p, UART_OMAP_SCR, 0x08); - serial_write_reg(p, UART_OMAP_MDR1, 0x00); - serial_write_reg(p, UART_OMAP_SYSC, (0x02 << 3) | (1 << 2) | (1 << 0)); + struct omap_mux_partition *tx_partition = NULL, *rx_partition = NULL; + struct omap_mux *rx_mux = NULL, *tx_mux = NULL; + char *rx_fmt, *tx_fmt; + int uart_nr = bdata->id + 1; + + if (bdata->id != 2) { + rx_fmt = "uart%d_rx.uart%d_rx"; + tx_fmt = "uart%d_tx.uart%d_tx"; + } else { + rx_fmt = "uart%d_rx_irrx.uart%d_rx_irrx"; + tx_fmt = "uart%d_tx_irtx.uart%d_tx_irtx"; + } + + snprintf(rx_pad_name, OMAP_UART_DEFAULT_PAD_NAME_LEN, rx_fmt, + uart_nr, uart_nr); + snprintf(tx_pad_name, OMAP_UART_DEFAULT_PAD_NAME_LEN, tx_fmt, + uart_nr, uart_nr); + + if (omap_mux_get_by_name(rx_pad_name, &rx_partition, &rx_mux) >= 0 && + omap_mux_get_by_name + (tx_pad_name, &tx_partition, &tx_mux) >= 0) { + u16 tx_mode, rx_mode; + + tx_mode = omap_mux_read(tx_partition, tx_mux->reg_offset); + rx_mode = omap_mux_read(rx_partition, rx_mux->reg_offset); + + /* + * Check if uart is used in default tx/rx mode i.e. in mux mode0 + * if yes then configure rx pin for wake up capability + */ + if (OMAP_MODE_UART(rx_mode) && OMAP_MODE_UART(tx_mode)) + omap_serial_fill_uart_tx_rx_pads(bdata, uart); + } } +#else +static void __init omap_serial_check_wakeup(struct omap_board_data *bdata, + struct omap_uart_state *uart) +{ +} +#endif + +static char *cmdline_find_option(char *str) +{ + extern char *saved_command_line; -void omap_serial_enable_clocks(int enable) + return strstr(saved_command_line, str); +} + +static int __init omap_serial_early_init(void) { - int i; - for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { - if (uart_ick[i] && uart_fck[i]) { - if (enable) { - clk_enable(uart_ick[i]); - clk_enable(uart_fck[i]); - } else { - clk_disable(uart_ick[i]); - clk_disable(uart_fck[i]); + if (of_have_populated_dt()) + return -ENODEV; + + do { + char oh_name[MAX_UART_HWMOD_NAME_LEN]; + struct omap_hwmod *oh; + struct omap_uart_state *uart; + char uart_name[MAX_UART_HWMOD_NAME_LEN]; + + snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN, + "uart%d", num_uarts + 1); + oh = omap_hwmod_lookup(oh_name); + if (!oh) + break; + + uart = kzalloc(sizeof(struct omap_uart_state), GFP_KERNEL); + if (WARN_ON(!uart)) + return -ENODEV; + + uart->oh = oh; + uart->num = num_uarts++; + list_add_tail(&uart->node, &uart_list); + snprintf(uart_name, MAX_UART_HWMOD_NAME_LEN, + "%s%d", OMAP_SERIAL_NAME, uart->num); + + if (cmdline_find_option(uart_name)) { + console_uart_id = uart->num; + + if (console_loglevel >= 10) { + uart_debug = true; + pr_info("%s used as console in debug mode: uart%d clocks will not be gated", + uart_name, uart->num); } } - } + } while (1); + + return 0; } +omap_core_initcall(omap_serial_early_init); -void __init omap_serial_init(void) +/** + * omap_serial_init_port() - initialize single serial port + * @bdata: port specific board data pointer + * @info: platform specific data pointer + * + * This function initialies serial driver for given port only. + * Platforms can call this function instead of omap_serial_init() + * if they don't plan to use all available UARTs as serial ports. + * + * Don't mix calls to omap_serial_init_port() and omap_serial_init(), + * use only one of the two. + */ +void __init omap_serial_init_port(struct omap_board_data *bdata, + struct omap_uart_port_info *info) { - int i; - const struct omap_uart_config *info; - char name[16]; + struct omap_uart_state *uart; + struct omap_hwmod *oh; + struct platform_device *pdev; + void *pdata = NULL; + u32 pdata_size = 0; + char *name; + struct omap_uart_port_info omap_up; + + if (WARN_ON(!bdata)) + return; + if (WARN_ON(bdata->id < 0)) + return; + if (WARN_ON(bdata->id >= num_uarts)) + return; + + list_for_each_entry(uart, &uart_list, node) + if (bdata->id == uart->num) + break; + if (!info) + info = omap_serial_default_info; - /* - * Make sure the serial ports are muxed on at this point. - * You have to mux them off in device drivers later on - * if not needed. - */ + oh = uart->oh; + name = DRIVER_NAME; - info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config); + omap_up.dma_enabled = info->dma_enabled; + omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; + omap_up.flags = UPF_BOOT_AUTOCONF; + omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count; + omap_up.enable_wakeup = omap_uart_enable_wakeup; + omap_up.dma_rx_buf_size = info->dma_rx_buf_size; + omap_up.dma_rx_timeout = info->dma_rx_timeout; + omap_up.dma_rx_poll_rate = info->dma_rx_poll_rate; + omap_up.autosuspend_timeout = info->autosuspend_timeout; + omap_up.DTR_gpio = info->DTR_gpio; + omap_up.DTR_inverted = info->DTR_inverted; + omap_up.DTR_present = info->DTR_present; - if (info == NULL) + pdata = &omap_up; + pdata_size = sizeof(struct omap_uart_port_info); + + if (WARN_ON(!oh)) return; - for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { - struct plat_serial8250_port *p = serial_platform_data + i; + pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size); + if (IS_ERR(pdev)) { + WARN(1, "Could not build omap_device for %s: %s.\n", name, + oh->name); + return; + } - if (!(info->enabled_uarts & (1 << i))) { - p->membase = NULL; - p->mapbase = 0; - continue; - } + oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); - sprintf(name, "uart%d_ick", i+1); - uart_ick[i] = clk_get(NULL, name); - if (IS_ERR(uart_ick[i])) { - printk(KERN_ERR "Could not get uart%d_ick\n", i+1); - uart_ick[i] = NULL; - } else - clk_enable(uart_ick[i]); - - sprintf(name, "uart%d_fck", i+1); - uart_fck[i] = clk_get(NULL, name); - if (IS_ERR(uart_fck[i])) { - printk(KERN_ERR "Could not get uart%d_fck\n", i+1); - uart_fck[i] = NULL; - } else - clk_enable(uart_fck[i]); - - omap_serial_reset(p); + if (console_uart_id == bdata->id) { + omap_device_enable(pdev); + pm_runtime_set_active(&pdev->dev); } + + oh->dev_attr = uart; + + if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) + && !uart_debug) + device_init_wakeup(&pdev->dev, true); } -static struct platform_device serial_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = serial_platform_data, - }, -}; +/** + * omap_serial_board_init() - initialize all supported serial ports + * @info: platform specific data pointer + * + * Initializes all available UARTs as serial ports. Platforms + * can call this function when they want to have default behaviour + * for serial ports (e.g initialize them all as serial ports). + */ +void __init omap_serial_board_init(struct omap_uart_port_info *info) +{ + struct omap_uart_state *uart; + struct omap_board_data bdata; -static int __init omap_init(void) + list_for_each_entry(uart, &uart_list, node) { + bdata.id = uart->num; + bdata.flags = 0; + bdata.pads = NULL; + bdata.pads_cnt = 0; + + omap_serial_check_wakeup(&bdata, uart); + + if (!info) + omap_serial_init_port(&bdata, NULL); + else + omap_serial_init_port(&bdata, &info[uart->num]); + } +} + +/** + * omap_serial_init() - initialize all supported serial ports + * + * Initializes all available UARTs. + * Platforms can call this function when they want to have default behaviour + * for serial ports (e.g initialize them all as serial ports). + */ +void __init omap_serial_init(void) { - return platform_device_register(&serial_device); + omap_serial_board_init(NULL); } -arch_initcall(omap_init); diff --git a/arch/arm/mach-omap2/serial.h b/arch/arm/mach-omap2/serial.h new file mode 100644 index 00000000000..c4014f013df --- /dev/null +++ b/arch/arm/mach-omap2/serial.h @@ -0,0 +1 @@ +#include <mach/serial.h> diff --git a/arch/arm/mach-omap2/sleep24xx.S b/arch/arm/mach-omap2/sleep24xx.S index bf9e96105e1..1d3cb25c962 100644 --- a/arch/arm/mach-omap2/sleep24xx.S +++ b/arch/arm/mach-omap2/sleep24xx.S @@ -27,11 +27,8 @@ #include <linux/linkage.h> #include <asm/assembler.h> -#include <mach/io.h> -#include <mach/pm.h> - -#include <mach/omap24xx.h> +#include "omap24xx.h" #include "sdrc.h" /* First address of reserved address space? apparently valid for OMAP2 & 3 */ @@ -40,24 +37,6 @@ .text /* - * Forces OMAP into idle state - * - * omap24xx_idle_loop_suspend() - This bit of code just executes the WFI - * for normal idles. - * - * Note: This code get's copied to internal SRAM at boot. When the OMAP - * wakes up it continues execution at the point it went to sleep. - */ -ENTRY(omap24xx_idle_loop_suspend) - stmfd sp!, {r0, lr} @ save registers on stack - mov r0, #0 @ clear for mcr setup - mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt - ldmfd sp!, {r0, pc} @ restore regs and return - -ENTRY(omap24xx_idle_loop_suspend_sz) - .word . - omap24xx_idle_loop_suspend - -/* * omap24xx_cpu_suspend() - Forces OMAP into deep sleep state by completing * SDRC shutdown then ARM shutdown. Upon wake MPU is back on so just restore * SDRC. @@ -83,6 +62,7 @@ ENTRY(omap24xx_idle_loop_suspend_sz) * The DLL load value is not kept in RETENTION or OFF. It needs to be restored * at wake */ + .align 3 ENTRY(omap24xx_cpu_suspend) stmfd sp!, {r0 - r12, lr} @ save registers on stack mov r3, #0x0 @ clear for mcr call diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S new file mode 100644 index 00000000000..d1dedc8195e --- /dev/null +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -0,0 +1,616 @@ +/* + * (C) Copyright 2007 + * Texas Instruments + * Karthik Dasu <karthik-dp@ti.com> + * + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <linux/linkage.h> + +#include <asm/assembler.h> + +#include "omap34xx.h" +#include "iomap.h" +#include "cm3xxx.h" +#include "prm3xxx.h" +#include "sdrc.h" +#include "sram.h" +#include "control.h" + +/* + * Registers access definitions + */ +#define SDRC_SCRATCHPAD_SEM_OFFS 0xc +#define SDRC_SCRATCHPAD_SEM_V OMAP343X_SCRATCHPAD_REGADDR\ + (SDRC_SCRATCHPAD_SEM_OFFS) +#define PM_PREPWSTST_CORE_P OMAP3430_PRM_BASE + CORE_MOD +\ + OMAP3430_PM_PREPWSTST +#define PM_PWSTCTRL_MPU_P OMAP3430_PRM_BASE + MPU_MOD + OMAP2_PM_PWSTCTRL +#define CM_IDLEST1_CORE_V OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST1) +#define CM_IDLEST_CKGEN_V OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST) +#define SRAM_BASE_P OMAP3_SRAM_PA +#define CONTROL_STAT OMAP343X_CTRL_BASE + OMAP343X_CONTROL_STATUS +#define CONTROL_MEM_RTA_CTRL (OMAP343X_CTRL_BASE +\ + OMAP36XX_CONTROL_MEM_RTA_CTRL) + +/* Move this as correct place is available */ +#define SCRATCHPAD_MEM_OFFS 0x310 +#define SCRATCHPAD_BASE_P (OMAP343X_CTRL_BASE +\ + OMAP343X_CONTROL_MEM_WKUP +\ + SCRATCHPAD_MEM_OFFS) +#define SDRC_POWER_V OMAP34XX_SDRC_REGADDR(SDRC_POWER) +#define SDRC_SYSCONFIG_P (OMAP343X_SDRC_BASE + SDRC_SYSCONFIG) +#define SDRC_MR_0_P (OMAP343X_SDRC_BASE + SDRC_MR_0) +#define SDRC_EMR2_0_P (OMAP343X_SDRC_BASE + SDRC_EMR2_0) +#define SDRC_MANUAL_0_P (OMAP343X_SDRC_BASE + SDRC_MANUAL_0) +#define SDRC_MR_1_P (OMAP343X_SDRC_BASE + SDRC_MR_1) +#define SDRC_EMR2_1_P (OMAP343X_SDRC_BASE + SDRC_EMR2_1) +#define SDRC_MANUAL_1_P (OMAP343X_SDRC_BASE + SDRC_MANUAL_1) +#define SDRC_DLLA_STATUS_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS) +#define SDRC_DLLA_CTRL_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL) + +/* + * This file needs be built unconditionally as ARM to interoperate correctly + * with non-Thumb-2-capable firmware. + */ + .arm + +/* + * API functions + */ + + .text +/* + * L2 cache needs to be toggled for stable OFF mode functionality on 3630. + * This function sets up a flag that will allow for this toggling to take + * place on 3630. Hopefully some version in the future may not need this. + */ +ENTRY(enable_omap3630_toggle_l2_on_restore) + stmfd sp!, {lr} @ save registers on stack + /* Setup so that we will disable and enable l2 */ + mov r1, #0x1 + adrl r2, l2dis_3630 @ may be too distant for plain adr + str r1, [r2] + ldmfd sp!, {pc} @ restore regs and return +ENDPROC(enable_omap3630_toggle_l2_on_restore) + + .text +/* Function to call rom code to save secure ram context */ + .align 3 +ENTRY(save_secure_ram_context) + stmfd sp!, {r4 - r11, lr} @ save registers on stack + adr r3, api_params @ r3 points to parameters + str r0, [r3,#0x4] @ r0 has sdram address + ldr r12, high_mask + and r3, r3, r12 + ldr r12, sram_phy_addr_mask + orr r3, r3, r12 + mov r0, #25 @ set service ID for PPA + mov r12, r0 @ copy secure service ID in r12 + mov r1, #0 @ set task id for ROM code in r1 + mov r2, #4 @ set some flags in r2, r6 + mov r6, #0xff + dsb @ data write barrier + dmb @ data memory barrier + smc #1 @ call SMI monitor (smi #1) + nop + nop + nop + nop + ldmfd sp!, {r4 - r11, pc} + .align +sram_phy_addr_mask: + .word SRAM_BASE_P +high_mask: + .word 0xffff +api_params: + .word 0x4, 0x0, 0x0, 0x1, 0x1 +ENDPROC(save_secure_ram_context) +ENTRY(save_secure_ram_context_sz) + .word . - save_secure_ram_context + +/* + * ====================== + * == Idle entry point == + * ====================== + */ + +/* + * Forces OMAP into idle state + * + * omap34xx_cpu_suspend() - This bit of code saves the CPU context if needed + * and executes the WFI instruction. Calling WFI effectively changes the + * power domains states to the desired target power states. + * + * + * Notes: + * - only the minimum set of functions gets copied to internal SRAM at boot + * and after wake-up from OFF mode, cf. omap_push_sram_idle. The function + * pointers in SDRAM or SRAM are called depending on the desired low power + * target state. + * - when the OMAP wakes up it continues at different execution points + * depending on the low power mode (non-OFF vs OFF modes), + * cf. 'Resume path for xxx mode' comments. + */ + .align 3 +ENTRY(omap34xx_cpu_suspend) + stmfd sp!, {r4 - r11, lr} @ save registers on stack + + /* + * r0 contains information about saving context: + * 0 - No context lost + * 1 - Only L1 and logic lost + * 2 - Only L2 lost (Even L1 is retained we clean it along with L2) + * 3 - Both L1 and L2 lost and logic lost + */ + + /* + * For OFF mode: save context and jump to WFI in SDRAM (omap3_do_wfi) + * For non-OFF modes: jump to the WFI code in SRAM (omap3_do_wfi_sram) + */ + ldr r4, omap3_do_wfi_sram_addr + ldr r5, [r4] + cmp r0, #0x0 @ If no context save required, + bxeq r5 @ jump to the WFI code in SRAM + + + /* Otherwise fall through to the save context code */ +save_context_wfi: + /* + * jump out to kernel flush routine + * - reuse that code is better + * - it executes in a cached space so is faster than refetch per-block + * - should be faster and will change with kernel + * - 'might' have to copy address, load and jump to it + * Flush all data from the L1 data cache before disabling + * SCTLR.C bit. + */ + ldr r1, kernel_flush + mov lr, pc + bx r1 + + /* + * Clear the SCTLR.C bit to prevent further data cache + * allocation. Clearing SCTLR.C would make all the data accesses + * strongly ordered and would not hit the cache. + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #(1 << 2) @ Disable the C bit + mcr p15, 0, r0, c1, c0, 0 + isb + + /* + * Invalidate L1 data cache. Even though only invalidate is + * necessary exported flush API is used here. Doing clean + * on already clean cache would be almost NOP. + */ + ldr r1, kernel_flush + blx r1 + /* + * The kernel doesn't interwork: v7_flush_dcache_all in particluar will + * always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled. + * This sequence switches back to ARM. Note that .align may insert a + * nop: bx pc needs to be word-aligned in order to work. + */ + THUMB( .thumb ) + THUMB( .align ) + THUMB( bx pc ) + THUMB( nop ) + .arm + + b omap3_do_wfi + +/* + * Local variables + */ +omap3_do_wfi_sram_addr: + .word omap3_do_wfi_sram +kernel_flush: + .word v7_flush_dcache_all + +/* =================================== + * == WFI instruction => Enter idle == + * =================================== + */ + +/* + * Do WFI instruction + * Includes the resume path for non-OFF modes + * + * This code gets copied to internal SRAM and is accessible + * from both SDRAM and SRAM: + * - executed from SRAM for non-off modes (omap3_do_wfi_sram), + * - executed from SDRAM for OFF mode (omap3_do_wfi). + */ + .align 3 +ENTRY(omap3_do_wfi) + ldr r4, sdrc_power @ read the SDRC_POWER register + ldr r5, [r4] @ read the contents of SDRC_POWER + orr r5, r5, #0x40 @ enable self refresh on idle req + str r5, [r4] @ write back to SDRC_POWER register + + /* Data memory barrier and Data sync barrier */ + dsb + dmb + +/* + * =================================== + * == WFI instruction => Enter idle == + * =================================== + */ + wfi @ wait for interrupt + +/* + * =================================== + * == Resume path for non-OFF modes == + * =================================== + */ + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + +/* + * This function implements the erratum ID i581 WA: + * SDRC state restore before accessing the SDRAM + * + * Only used at return from non-OFF mode. For OFF + * mode the ROM code configures the SDRC and + * the DPLL before calling the restore code directly + * from DDR. + */ + +/* Make sure SDRC accesses are ok */ +wait_sdrc_ok: + +/* DPLL3 must be locked before accessing the SDRC. Maybe the HW ensures this */ + ldr r4, cm_idlest_ckgen +wait_dpll3_lock: + ldr r5, [r4] + tst r5, #1 + beq wait_dpll3_lock + + ldr r4, cm_idlest1_core +wait_sdrc_ready: + ldr r5, [r4] + tst r5, #0x2 + bne wait_sdrc_ready + /* allow DLL powerdown upon hw idle req */ + ldr r4, sdrc_power + ldr r5, [r4] + bic r5, r5, #0x40 + str r5, [r4] + +/* + * PC-relative stores lead to undefined behaviour in Thumb-2: use a r7 as a + * base instead. + * Be careful not to clobber r7 when maintaing this code. + */ + +is_dll_in_lock_mode: + /* Is dll in lock mode? */ + ldr r4, sdrc_dlla_ctrl + ldr r5, [r4] + tst r5, #0x4 + bne exit_nonoff_modes @ Return if locked + /* wait till dll locks */ + adr r7, kick_counter +wait_dll_lock_timed: + ldr r4, wait_dll_lock_counter + add r4, r4, #1 + str r4, [r7, #wait_dll_lock_counter - kick_counter] + ldr r4, sdrc_dlla_status + /* Wait 20uS for lock */ + mov r6, #8 +wait_dll_lock: + subs r6, r6, #0x1 + beq kick_dll + ldr r5, [r4] + and r5, r5, #0x4 + cmp r5, #0x4 + bne wait_dll_lock + b exit_nonoff_modes @ Return when locked + + /* disable/reenable DLL if not locked */ +kick_dll: + ldr r4, sdrc_dlla_ctrl + ldr r5, [r4] + mov r6, r5 + bic r6, #(1<<3) @ disable dll + str r6, [r4] + dsb + orr r6, r6, #(1<<3) @ enable dll + str r6, [r4] + dsb + ldr r4, kick_counter + add r4, r4, #1 + str r4, [r7] @ kick_counter + b wait_dll_lock_timed + +exit_nonoff_modes: + /* Re-enable C-bit if needed */ + mrc p15, 0, r0, c1, c0, 0 + tst r0, #(1 << 2) @ Check C bit enabled? + orreq r0, r0, #(1 << 2) @ Enable the C bit if cleared + mcreq p15, 0, r0, c1, c0, 0 + isb + +/* + * =================================== + * == Exit point from non-OFF modes == + * =================================== + */ + ldmfd sp!, {r4 - r11, pc} @ restore regs and return + +/* + * Local variables + */ +sdrc_power: + .word SDRC_POWER_V +cm_idlest1_core: + .word CM_IDLEST1_CORE_V +cm_idlest_ckgen: + .word CM_IDLEST_CKGEN_V +sdrc_dlla_status: + .word SDRC_DLLA_STATUS_V +sdrc_dlla_ctrl: + .word SDRC_DLLA_CTRL_V + /* + * When exporting to userspace while the counters are in SRAM, + * these 2 words need to be at the end to facilitate retrival! + */ +kick_counter: + .word 0 +wait_dll_lock_counter: + .word 0 + +ENTRY(omap3_do_wfi_sz) + .word . - omap3_do_wfi + + +/* + * ============================== + * == Resume path for OFF mode == + * ============================== + */ + +/* + * The restore_* functions are called by the ROM code + * when back from WFI in OFF mode. + * Cf. the get_*restore_pointer functions. + * + * restore_es3: applies to 34xx >= ES3.0 + * restore_3630: applies to 36xx + * restore: common code for 3xxx + * + * Note: when back from CORE and MPU OFF mode we are running + * from SDRAM, without MMU, without the caches and prediction. + * Also the SRAM content has been cleared. + */ +ENTRY(omap3_restore_es3) + ldr r5, pm_prepwstst_core_p + ldr r4, [r5] + and r4, r4, #0x3 + cmp r4, #0x0 @ Check if previous power state of CORE is OFF + bne omap3_restore @ Fall through to OMAP3 common code + adr r0, es3_sdrc_fix + ldr r1, sram_base + ldr r2, es3_sdrc_fix_sz + mov r2, r2, ror #2 +copy_to_sram: + ldmia r0!, {r3} @ val = *src + stmia r1!, {r3} @ *dst = val + subs r2, r2, #0x1 @ num_words-- + bne copy_to_sram + ldr r1, sram_base + blx r1 + b omap3_restore @ Fall through to OMAP3 common code +ENDPROC(omap3_restore_es3) + +ENTRY(omap3_restore_3630) + ldr r1, pm_prepwstst_core_p + ldr r2, [r1] + and r2, r2, #0x3 + cmp r2, #0x0 @ Check if previous power state of CORE is OFF + bne omap3_restore @ Fall through to OMAP3 common code + /* Disable RTA before giving control */ + ldr r1, control_mem_rta + mov r2, #OMAP36XX_RTA_DISABLE + str r2, [r1] +ENDPROC(omap3_restore_3630) + + /* Fall through to common code for the remaining logic */ + +ENTRY(omap3_restore) + /* + * Read the pwstctrl register to check the reason for mpu reset. + * This tells us what was lost. + */ + ldr r1, pm_pwstctrl_mpu + ldr r2, [r1] + and r2, r2, #0x3 + cmp r2, #0x0 @ Check if target power state was OFF or RET + bne logic_l1_restore + + ldr r0, l2dis_3630 + cmp r0, #0x1 @ should we disable L2 on 3630? + bne skipl2dis + mrc p15, 0, r0, c1, c0, 1 + bic r0, r0, #2 @ disable L2 cache + mcr p15, 0, r0, c1, c0, 1 +skipl2dis: + ldr r0, control_stat + ldr r1, [r0] + and r1, #0x700 + cmp r1, #0x300 + beq l2_inv_gp + mov r0, #40 @ set service ID for PPA + mov r12, r0 @ copy secure Service ID in r12 + mov r1, #0 @ set task id for ROM code in r1 + mov r2, #4 @ set some flags in r2, r6 + mov r6, #0xff + adr r3, l2_inv_api_params @ r3 points to dummy parameters + dsb @ data write barrier + dmb @ data memory barrier + smc #1 @ call SMI monitor (smi #1) + /* Write to Aux control register to set some bits */ + mov r0, #42 @ set service ID for PPA + mov r12, r0 @ copy secure Service ID in r12 + mov r1, #0 @ set task id for ROM code in r1 + mov r2, #4 @ set some flags in r2, r6 + mov r6, #0xff + ldr r4, scratchpad_base + ldr r3, [r4, #0xBC] @ r3 points to parameters + dsb @ data write barrier + dmb @ data memory barrier + smc #1 @ call SMI monitor (smi #1) + +#ifdef CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE + /* Restore L2 aux control register */ + @ set service ID for PPA + mov r0, #CONFIG_OMAP3_L2_AUX_SECURE_SERVICE_SET_ID + mov r12, r0 @ copy service ID in r12 + mov r1, #0 @ set task ID for ROM code in r1 + mov r2, #4 @ set some flags in r2, r6 + mov r6, #0xff + ldr r4, scratchpad_base + ldr r3, [r4, #0xBC] + adds r3, r3, #8 @ r3 points to parameters + dsb @ data write barrier + dmb @ data memory barrier + smc #1 @ call SMI monitor (smi #1) +#endif + b logic_l1_restore + + .align +l2_inv_api_params: + .word 0x1, 0x00 +l2_inv_gp: + /* Execute smi to invalidate L2 cache */ + mov r12, #0x1 @ set up to invalidate L2 + smc #0 @ Call SMI monitor (smieq) + /* Write to Aux control register to set some bits */ + ldr r4, scratchpad_base + ldr r3, [r4,#0xBC] + ldr r0, [r3,#4] + mov r12, #0x3 + smc #0 @ Call SMI monitor (smieq) + ldr r4, scratchpad_base + ldr r3, [r4,#0xBC] + ldr r0, [r3,#12] + mov r12, #0x2 + smc #0 @ Call SMI monitor (smieq) +logic_l1_restore: + ldr r1, l2dis_3630 + cmp r1, #0x1 @ Test if L2 re-enable needed on 3630 + bne skipl2reen + mrc p15, 0, r1, c1, c0, 1 + orr r1, r1, #2 @ re-enable L2 cache + mcr p15, 0, r1, c1, c0, 1 +skipl2reen: + + /* Now branch to the common CPU resume function */ + b cpu_resume +ENDPROC(omap3_restore) + + .ltorg + +/* + * Local variables + */ +pm_prepwstst_core_p: + .word PM_PREPWSTST_CORE_P +pm_pwstctrl_mpu: + .word PM_PWSTCTRL_MPU_P +scratchpad_base: + .word SCRATCHPAD_BASE_P +sram_base: + .word SRAM_BASE_P + 0x8000 +control_stat: + .word CONTROL_STAT +control_mem_rta: + .word CONTROL_MEM_RTA_CTRL +l2dis_3630: + .word 0 + +/* + * Internal functions + */ + +/* + * This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0 + * Copied to and run from SRAM in order to reconfigure the SDRC parameters. + */ + .text + .align 3 +ENTRY(es3_sdrc_fix) + ldr r4, sdrc_syscfg @ get config addr + ldr r5, [r4] @ get value + tst r5, #0x100 @ is part access blocked + it eq + biceq r5, r5, #0x100 @ clear bit if set + str r5, [r4] @ write back change + ldr r4, sdrc_mr_0 @ get config addr + ldr r5, [r4] @ get value + str r5, [r4] @ write back change + ldr r4, sdrc_emr2_0 @ get config addr + ldr r5, [r4] @ get value + str r5, [r4] @ write back change + ldr r4, sdrc_manual_0 @ get config addr + mov r5, #0x2 @ autorefresh command + str r5, [r4] @ kick off refreshes + ldr r4, sdrc_mr_1 @ get config addr + ldr r5, [r4] @ get value + str r5, [r4] @ write back change + ldr r4, sdrc_emr2_1 @ get config addr + ldr r5, [r4] @ get value + str r5, [r4] @ write back change + ldr r4, sdrc_manual_1 @ get config addr + mov r5, #0x2 @ autorefresh command + str r5, [r4] @ kick off refreshes + bx lr + +/* + * Local variables + */ + .align +sdrc_syscfg: + .word SDRC_SYSCONFIG_P +sdrc_mr_0: + .word SDRC_MR_0_P +sdrc_emr2_0: + .word SDRC_EMR2_0_P +sdrc_manual_0: + .word SDRC_MANUAL_0_P +sdrc_mr_1: + .word SDRC_MR_1_P +sdrc_emr2_1: + .word SDRC_EMR2_1_P +sdrc_manual_1: + .word SDRC_MANUAL_1_P +ENDPROC(es3_sdrc_fix) +ENTRY(es3_sdrc_fix_sz) + .word . - es3_sdrc_fix diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S new file mode 100644 index 00000000000..9086ce03ae1 --- /dev/null +++ b/arch/arm/mach-omap2/sleep44xx.S @@ -0,0 +1,386 @@ +/* + * OMAP44xx sleep code. + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * This program is free software,you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/linkage.h> +#include <asm/smp_scu.h> +#include <asm/memory.h> +#include <asm/hardware/cache-l2x0.h> + +#include "omap-secure.h" + +#include "common.h" +#include "omap44xx.h" +#include "omap4-sar-layout.h" + +#if defined(CONFIG_SMP) && defined(CONFIG_PM) + +.macro DO_SMC + dsb + smc #0 + dsb +.endm + +ppa_zero_params: + .word 0x0 + +ppa_por_params: + .word 1, 0 + +#ifdef CONFIG_ARCH_OMAP4 + +/* + * ============================= + * == CPU suspend finisher == + * ============================= + * + * void omap4_finish_suspend(unsigned long cpu_state) + * + * This function code saves the CPU context and performs the CPU + * power down sequence. Calling WFI effectively changes the CPU + * power domains states to the desired target power state. + * + * @cpu_state : contains context save state (r0) + * 0 - No context lost + * 1 - CPUx L1 and logic lost: MPUSS CSWR + * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR + * 3 - CPUx L1 and logic lost + GIC + L2 lost: MPUSS OFF + * @return: This function never returns for CPU OFF and DORMANT power states. + * Post WFI, CPU transitions to DORMANT or OFF power state and on wake-up + * from this follows a full CPU reset path via ROM code to CPU restore code. + * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET. + * It returns to the caller for CPU INACTIVE and ON power states or in case + * CPU failed to transition to targeted OFF/DORMANT state. + * + * omap4_finish_suspend() calls v7_flush_dcache_all() which doesn't save + * stack frame and it expects the caller to take care of it. Hence the entire + * stack frame is saved to avoid possible stack corruption. + */ +ENTRY(omap4_finish_suspend) + stmfd sp!, {r4-r12, lr} + cmp r0, #0x0 + beq do_WFI @ No lowpower state, jump to WFI + + /* + * Flush all data from the L1 data cache before disabling + * SCTLR.C bit. + */ + bl omap4_get_sar_ram_base + ldr r9, [r0, #OMAP_TYPE_OFFSET] + cmp r9, #0x1 @ Check for HS device + bne skip_secure_l1_clean + mov r0, #SCU_PM_NORMAL + mov r1, #0xFF @ clean seucre L1 + stmfd r13!, {r4-r12, r14} + ldr r12, =OMAP4_MON_SCU_PWR_INDEX + DO_SMC + ldmfd r13!, {r4-r12, r14} +skip_secure_l1_clean: + bl v7_flush_dcache_all + + /* + * Clear the SCTLR.C bit to prevent further data cache + * allocation. Clearing SCTLR.C would make all the data accesses + * strongly ordered and would not hit the cache. + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #(1 << 2) @ Disable the C bit + mcr p15, 0, r0, c1, c0, 0 + isb + + /* + * Invalidate L1 data cache. Even though only invalidate is + * necessary exported flush API is used here. Doing clean + * on already clean cache would be almost NOP. + */ + bl v7_flush_dcache_all + + /* + * Switch the CPU from Symmetric Multiprocessing (SMP) mode + * to AsymmetricMultiprocessing (AMP) mode by programming + * the SCU power status to DORMANT or OFF mode. + * This enables the CPU to be taken out of coherency by + * preventing the CPU from receiving cache, TLB, or BTB + * maintenance operations broadcast by other CPUs in the cluster. + */ + bl omap4_get_sar_ram_base + mov r8, r0 + ldr r9, [r8, #OMAP_TYPE_OFFSET] + cmp r9, #0x1 @ Check for HS device + bne scu_gp_set + mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR + ands r0, r0, #0x0f + ldreq r0, [r8, #SCU_OFFSET0] + ldrne r0, [r8, #SCU_OFFSET1] + mov r1, #0x00 + stmfd r13!, {r4-r12, r14} + ldr r12, =OMAP4_MON_SCU_PWR_INDEX + DO_SMC + ldmfd r13!, {r4-r12, r14} + b skip_scu_gp_set +scu_gp_set: + mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR + ands r0, r0, #0x0f + ldreq r1, [r8, #SCU_OFFSET0] + ldrne r1, [r8, #SCU_OFFSET1] + bl omap4_get_scu_base + bl scu_power_mode +skip_scu_gp_set: + mrc p15, 0, r0, c1, c1, 2 @ Read NSACR data + tst r0, #(1 << 18) + mrcne p15, 0, r0, c1, c0, 1 + bicne r0, r0, #(1 << 6) @ Disable SMP bit + mcrne p15, 0, r0, c1, c0, 1 + isb + dsb +#ifdef CONFIG_CACHE_L2X0 + /* + * Clean and invalidate the L2 cache. + * Common cache-l2x0.c functions can't be used here since it + * uses spinlocks. We are out of coherency here with data cache + * disabled. The spinlock implementation uses exclusive load/store + * instruction which can fail without data cache being enabled. + * OMAP4 hardware doesn't support exclusive monitor which can + * overcome exclusive access issue. Because of this, CPU can + * lead to deadlock. + */ + bl omap4_get_sar_ram_base + mov r8, r0 + mrc p15, 0, r5, c0, c0, 5 @ Read MPIDR + ands r5, r5, #0x0f + ldreq r0, [r8, #L2X0_SAVE_OFFSET0] @ Retrieve L2 state from SAR + ldrne r0, [r8, #L2X0_SAVE_OFFSET1] @ memory. + cmp r0, #3 + bne do_WFI +#ifdef CONFIG_PL310_ERRATA_727915 + mov r0, #0x03 + mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX + DO_SMC +#endif + bl omap4_get_l2cache_base + mov r2, r0 + ldr r0, =0xffff + str r0, [r2, #L2X0_CLEAN_INV_WAY] +wait: + ldr r0, [r2, #L2X0_CLEAN_INV_WAY] + ldr r1, =0xffff + ands r0, r0, r1 + bne wait +#ifdef CONFIG_PL310_ERRATA_727915 + mov r0, #0x00 + mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX + DO_SMC +#endif +l2x_sync: + bl omap4_get_l2cache_base + mov r2, r0 + mov r0, #0x0 + str r0, [r2, #L2X0_CACHE_SYNC] +sync: + ldr r0, [r2, #L2X0_CACHE_SYNC] + ands r0, r0, #0x1 + bne sync +#endif + +do_WFI: + bl omap_do_wfi + + /* + * CPU is here when it failed to enter OFF/DORMANT or + * no low power state was attempted. + */ + mrc p15, 0, r0, c1, c0, 0 + tst r0, #(1 << 2) @ Check C bit enabled? + orreq r0, r0, #(1 << 2) @ Enable the C bit + mcreq p15, 0, r0, c1, c0, 0 + isb + + /* + * Ensure the CPU power state is set to NORMAL in + * SCU power state so that CPU is back in coherency. + * In non-coherent mode CPU can lock-up and lead to + * system deadlock. + */ + mrc p15, 0, r0, c1, c0, 1 + tst r0, #(1 << 6) @ Check SMP bit enabled? + orreq r0, r0, #(1 << 6) + mcreq p15, 0, r0, c1, c0, 1 + isb + bl omap4_get_sar_ram_base + mov r8, r0 + ldr r9, [r8, #OMAP_TYPE_OFFSET] + cmp r9, #0x1 @ Check for HS device + bne scu_gp_clear + mov r0, #SCU_PM_NORMAL + mov r1, #0x00 + stmfd r13!, {r4-r12, r14} + ldr r12, =OMAP4_MON_SCU_PWR_INDEX + DO_SMC + ldmfd r13!, {r4-r12, r14} + b skip_scu_gp_clear +scu_gp_clear: + bl omap4_get_scu_base + mov r1, #SCU_PM_NORMAL + bl scu_power_mode +skip_scu_gp_clear: + isb + dsb + ldmfd sp!, {r4-r12, pc} +ENDPROC(omap4_finish_suspend) + +/* + * ============================ + * == CPU resume entry point == + * ============================ + * + * void omap4_cpu_resume(void) + * + * ROM code jumps to this function while waking up from CPU + * OFF or DORMANT state. Physical address of the function is + * stored in the SAR RAM while entering to OFF or DORMANT mode. + * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET. + */ +ENTRY(omap4_cpu_resume) + /* + * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device. + * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA + * init and for CPU1, a secure PPA API provided. CPU0 must be ON + * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+. + * OMAP443X GP devices- SMP bit isn't accessible. + * OMAP446X GP devices - SMP bit access is enabled on both CPUs. + */ + ldr r8, =OMAP44XX_SAR_RAM_BASE + ldr r9, [r8, #OMAP_TYPE_OFFSET] + cmp r9, #0x1 @ Skip if GP device + bne skip_ns_smp_enable + mrc p15, 0, r0, c0, c0, 5 + ands r0, r0, #0x0f + beq skip_ns_smp_enable +ppa_actrl_retry: + mov r0, #OMAP4_PPA_CPU_ACTRL_SMP_INDEX + adr r3, ppa_zero_params @ Pointer to parameters + mov r1, #0x0 @ Process ID + mov r2, #0x4 @ Flag + mov r6, #0xff + mov r12, #0x00 @ Secure Service ID + DO_SMC + cmp r0, #0x0 @ API returns 0 on success. + beq enable_smp_bit + b ppa_actrl_retry +enable_smp_bit: + mrc p15, 0, r0, c1, c0, 1 + tst r0, #(1 << 6) @ Check SMP bit enabled? + orreq r0, r0, #(1 << 6) + mcreq p15, 0, r0, c1, c0, 1 + isb +skip_ns_smp_enable: +#ifdef CONFIG_CACHE_L2X0 + /* + * Restore the L2 AUXCTRL and enable the L2 cache. + * OMAP4_MON_L2X0_AUXCTRL_INDEX = Program the L2X0 AUXCTRL + * OMAP4_MON_L2X0_CTRL_INDEX = Enable the L2 using L2X0 CTRL + * register r0 contains value to be programmed. + * L2 cache is already invalidate by ROM code as part + * of MPUSS OFF wakeup path. + */ + ldr r2, =OMAP44XX_L2CACHE_BASE + ldr r0, [r2, #L2X0_CTRL] + and r0, #0x0f + cmp r0, #1 + beq skip_l2en @ Skip if already enabled + ldr r3, =OMAP44XX_SAR_RAM_BASE + ldr r1, [r3, #OMAP_TYPE_OFFSET] + cmp r1, #0x1 @ Check for HS device + bne set_gp_por + ldr r0, =OMAP4_PPA_L2_POR_INDEX + ldr r1, =OMAP44XX_SAR_RAM_BASE + ldr r4, [r1, #L2X0_PREFETCH_CTRL_OFFSET] + adr r3, ppa_por_params + str r4, [r3, #0x04] + mov r1, #0x0 @ Process ID + mov r2, #0x4 @ Flag + mov r6, #0xff + mov r12, #0x00 @ Secure Service ID + DO_SMC + b set_aux_ctrl +set_gp_por: + ldr r1, =OMAP44XX_SAR_RAM_BASE + ldr r0, [r1, #L2X0_PREFETCH_CTRL_OFFSET] + ldr r12, =OMAP4_MON_L2X0_PREFETCH_INDEX @ Setup L2 PREFETCH + DO_SMC +set_aux_ctrl: + ldr r1, =OMAP44XX_SAR_RAM_BASE + ldr r0, [r1, #L2X0_AUXCTRL_OFFSET] + ldr r12, =OMAP4_MON_L2X0_AUXCTRL_INDEX @ Setup L2 AUXCTRL + DO_SMC + mov r0, #0x1 + ldr r12, =OMAP4_MON_L2X0_CTRL_INDEX @ Enable L2 cache + DO_SMC +skip_l2en: +#endif + + b cpu_resume @ Jump to generic resume +ENDPROC(omap4_cpu_resume) +#endif /* CONFIG_ARCH_OMAP4 */ + +#endif /* defined(CONFIG_SMP) && defined(CONFIG_PM) */ + +#ifndef CONFIG_OMAP4_ERRATA_I688 +ENTRY(omap_bus_sync) + mov pc, lr +ENDPROC(omap_bus_sync) +#endif + +ENTRY(omap_do_wfi) + stmfd sp!, {lr} + /* Drain interconnect write buffers. */ + bl omap_bus_sync + + /* + * Execute an ISB instruction to ensure that all of the + * CP15 register changes have been committed. + */ + isb + + /* + * Execute a barrier instruction to ensure that all cache, + * TLB and branch predictor maintenance operations issued + * by any CPU in the cluster have completed. + */ + dsb + dmb + + /* + * Execute a WFI instruction and wait until the + * STANDBYWFI output is asserted to indicate that the + * CPU is in idle and low power state. CPU can specualatively + * prefetch the instructions so add NOPs after WFI. Sixteen + * NOPs as per Cortex-A9 pipeline. + */ + wfi @ Wait For Interrupt + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + ldmfd sp!, {pc} +ENDPROC(omap_do_wfi) diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c new file mode 100644 index 00000000000..7a42e1960c3 --- /dev/null +++ b/arch/arm/mach-omap2/smartreflex-class3.c @@ -0,0 +1,62 @@ +/* + * Smart reflex Class 3 specific implementations + * + * Author: Thara Gopinath <thara@ti.com> + * + * Copyright (C) 2010 Texas Instruments, Inc. + * Thara Gopinath <thara@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/power/smartreflex.h> +#include "soc.h" +#include "voltage.h" + +static int sr_class3_enable(struct omap_sr *sr) +{ + unsigned long volt = voltdm_get_voltage(sr->voltdm); + + if (!volt) { + pr_warning("%s: Curr voltage unknown. Cannot enable %s\n", + __func__, sr->name); + return -ENODATA; + } + + omap_vp_enable(sr->voltdm); + return sr_enable(sr, volt); +} + +static int sr_class3_disable(struct omap_sr *sr, int is_volt_reset) +{ + sr_disable_errgen(sr); + omap_vp_disable(sr->voltdm); + sr_disable(sr); + if (is_volt_reset) + voltdm_reset(sr->voltdm); + + return 0; +} + +static int sr_class3_configure(struct omap_sr *sr) +{ + return sr_configure_errgen(sr); +} + +/* SR class3 structure */ +static struct omap_sr_class_data class3_data = { + .enable = sr_class3_enable, + .disable = sr_class3_disable, + .configure = sr_class3_configure, + .class_type = SR_CLASS3, +}; + +/* Smartreflex Class3 init API to be called from board file */ +static int __init sr_class3_init(void) +{ + pr_info("SmartReflex Class3 initialized\n"); + return sr_register_class(&class3_data); +} +omap_late_initcall(sr_class3_init); diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h new file mode 100644 index 00000000000..01ca8086fb6 --- /dev/null +++ b/arch/arm/mach-omap2/soc.h @@ -0,0 +1,551 @@ +/* + * OMAP cpu type detection + * + * Copyright (C) 2004, 2008 Nokia Corporation + * + * Copyright (C) 2009-11 Texas Instruments. + * + * Written by Tony Lindgren <tony.lindgren@nokia.com> + * + * Added OMAP4/5 specific defines - Santosh Shilimkar<santosh.shilimkar@ti.com> + * Added DRA7xxx specific defines - Sricharan R<r.sricharan@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "omap24xx.h" +#include "omap34xx.h" +#include "omap44xx.h" +#include "ti81xx.h" +#include "am33xx.h" +#include "omap54xx.h" + +#ifndef __ASSEMBLY__ + +#include <linux/bitops.h> +#include <linux/of.h> + +/* + * Test if multicore OMAP support is needed + */ +#undef MULTI_OMAP2 +#undef OMAP_NAME + +#ifdef CONFIG_ARCH_MULTIPLATFORM +#define MULTI_OMAP2 +#endif +#ifdef CONFIG_SOC_OMAP2420 +# ifdef OMAP_NAME +# undef MULTI_OMAP2 +# define MULTI_OMAP2 +# else +# define OMAP_NAME omap2420 +# endif +#endif +#ifdef CONFIG_SOC_OMAP2430 +# ifdef OMAP_NAME +# undef MULTI_OMAP2 +# define MULTI_OMAP2 +# else +# define OMAP_NAME omap2430 +# endif +#endif +#ifdef CONFIG_ARCH_OMAP3 +# ifdef OMAP_NAME +# undef MULTI_OMAP2 +# define MULTI_OMAP2 +# else +# define OMAP_NAME omap3 +# endif +#endif +#ifdef CONFIG_ARCH_OMAP4 +# ifdef OMAP_NAME +# undef MULTI_OMAP2 +# define MULTI_OMAP2 +# else +# define OMAP_NAME omap4 +# endif +#endif + +#ifdef CONFIG_SOC_OMAP5 +# ifdef OMAP_NAME +# undef MULTI_OMAP2 +# define MULTI_OMAP2 +# else +# define OMAP_NAME omap5 +# endif +#endif + +#ifdef CONFIG_SOC_AM33XX +# ifdef OMAP_NAME +# undef MULTI_OMAP2 +# define MULTI_OMAP2 +# else +# define OMAP_NAME am33xx +# endif +#endif + +#ifdef CONFIG_SOC_AM43XX +# ifdef OMAP_NAME +# undef MULTI_OMAP2 +# define MULTI_OMAP2 +# else +# define OMAP_NAME am43xx +# endif +#endif + +#ifdef CONFIG_SOC_DRA7XX +# ifdef OMAP_NAME +# undef MULTI_OMAP2 +# define MULTI_OMAP2 +# else +# define OMAP_NAME DRA7XX +# endif +#endif + +/* + * Omap device type i.e. EMU/HS/TST/GP/BAD + */ +#define OMAP2_DEVICE_TYPE_TEST 0 +#define OMAP2_DEVICE_TYPE_EMU 1 +#define OMAP2_DEVICE_TYPE_SEC 2 +#define OMAP2_DEVICE_TYPE_GP 3 +#define OMAP2_DEVICE_TYPE_BAD 4 + +int omap_type(void); + +/* + * omap_rev bits: + * CPU id bits (0730, 1510, 1710, 2422...) [31:16] + * CPU revision (See _REV_ defined in cpu.h) [15:08] + * CPU class bits (15xx, 16xx, 24xx, 34xx...) [07:00] + */ +unsigned int omap_rev(void); + +static inline int soc_is_omap(void) +{ + return omap_rev() != 0; +} + +/* + * Get the CPU revision for OMAP devices + */ +#define GET_OMAP_REVISION() ((omap_rev() >> 8) & 0xff) + +/* + * Macros to group OMAP into cpu classes. + * These can be used in most places. + * cpu_is_omap24xx(): True for OMAP2420, OMAP2422, OMAP2423, OMAP2430 + * cpu_is_omap242x(): True for OMAP2420, OMAP2422, OMAP2423 + * cpu_is_omap243x(): True for OMAP2430 + * cpu_is_omap343x(): True for OMAP3430 + * cpu_is_omap443x(): True for OMAP4430 + * cpu_is_omap446x(): True for OMAP4460 + * cpu_is_omap447x(): True for OMAP4470 + * soc_is_omap543x(): True for OMAP5430, OMAP5432 + */ +#define GET_OMAP_CLASS (omap_rev() & 0xff) + +#define IS_OMAP_CLASS(class, id) \ +static inline int is_omap ##class (void) \ +{ \ + return (GET_OMAP_CLASS == (id)) ? 1 : 0; \ +} + +#define GET_AM_CLASS ((omap_rev() >> 24) & 0xff) + +#define IS_AM_CLASS(class, id) \ +static inline int is_am ##class (void) \ +{ \ + return (GET_AM_CLASS == (id)) ? 1 : 0; \ +} + +#define GET_TI_CLASS ((omap_rev() >> 24) & 0xff) + +#define IS_TI_CLASS(class, id) \ +static inline int is_ti ##class (void) \ +{ \ + return (GET_TI_CLASS == (id)) ? 1 : 0; \ +} + +#define GET_OMAP_SUBCLASS ((omap_rev() >> 20) & 0x0fff) + +#define IS_OMAP_SUBCLASS(subclass, id) \ +static inline int is_omap ##subclass (void) \ +{ \ + return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \ +} + +#define IS_TI_SUBCLASS(subclass, id) \ +static inline int is_ti ##subclass (void) \ +{ \ + return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \ +} + +#define IS_AM_SUBCLASS(subclass, id) \ +static inline int is_am ##subclass (void) \ +{ \ + return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \ +} + +IS_OMAP_CLASS(24xx, 0x24) +IS_OMAP_CLASS(34xx, 0x34) +IS_OMAP_CLASS(44xx, 0x44) +IS_AM_CLASS(35xx, 0x35) +IS_OMAP_CLASS(54xx, 0x54) +IS_AM_CLASS(33xx, 0x33) +IS_AM_CLASS(43xx, 0x43) + +IS_TI_CLASS(81xx, 0x81) + +IS_OMAP_SUBCLASS(242x, 0x242) +IS_OMAP_SUBCLASS(243x, 0x243) +IS_OMAP_SUBCLASS(343x, 0x343) +IS_OMAP_SUBCLASS(363x, 0x363) +IS_OMAP_SUBCLASS(443x, 0x443) +IS_OMAP_SUBCLASS(446x, 0x446) +IS_OMAP_SUBCLASS(447x, 0x447) +IS_OMAP_SUBCLASS(543x, 0x543) + +IS_TI_SUBCLASS(816x, 0x816) +IS_TI_SUBCLASS(814x, 0x814) +IS_AM_SUBCLASS(335x, 0x335) +IS_AM_SUBCLASS(437x, 0x437) + +#define cpu_is_omap24xx() 0 +#define cpu_is_omap242x() 0 +#define cpu_is_omap243x() 0 +#define cpu_is_omap34xx() 0 +#define cpu_is_omap343x() 0 +#define cpu_is_ti81xx() 0 +#define cpu_is_ti816x() 0 +#define cpu_is_ti814x() 0 +#define soc_is_am35xx() 0 +#define soc_is_am33xx() 0 +#define soc_is_am335x() 0 +#define soc_is_am43xx() 0 +#define soc_is_am437x() 0 +#define cpu_is_omap44xx() 0 +#define cpu_is_omap443x() 0 +#define cpu_is_omap446x() 0 +#define cpu_is_omap447x() 0 +#define soc_is_omap54xx() 0 +#define soc_is_omap543x() 0 +#define soc_is_dra7xx() 0 + +#if defined(MULTI_OMAP2) +# if defined(CONFIG_ARCH_OMAP2) +# undef cpu_is_omap24xx +# define cpu_is_omap24xx() is_omap24xx() +# endif +# if defined (CONFIG_SOC_OMAP2420) +# undef cpu_is_omap242x +# define cpu_is_omap242x() is_omap242x() +# endif +# if defined (CONFIG_SOC_OMAP2430) +# undef cpu_is_omap243x +# define cpu_is_omap243x() is_omap243x() +# endif +# if defined(CONFIG_ARCH_OMAP3) +# undef cpu_is_omap34xx +# undef cpu_is_omap343x +# define cpu_is_omap34xx() is_omap34xx() +# define cpu_is_omap343x() is_omap343x() +# endif +#else +# if defined(CONFIG_ARCH_OMAP2) +# undef cpu_is_omap24xx +# define cpu_is_omap24xx() 1 +# endif +# if defined(CONFIG_SOC_OMAP2420) +# undef cpu_is_omap242x +# define cpu_is_omap242x() 1 +# endif +# if defined(CONFIG_SOC_OMAP2430) +# undef cpu_is_omap243x +# define cpu_is_omap243x() 1 +# endif +# if defined(CONFIG_ARCH_OMAP3) +# undef cpu_is_omap34xx +# define cpu_is_omap34xx() 1 +# endif +# if defined(CONFIG_SOC_OMAP3430) +# undef cpu_is_omap343x +# define cpu_is_omap343x() 1 +# endif +#endif + +/* + * Macros to detect individual cpu types. + * These are only rarely needed. + * cpu_is_omap2420(): True for OMAP2420 + * cpu_is_omap2422(): True for OMAP2422 + * cpu_is_omap2423(): True for OMAP2423 + * cpu_is_omap2430(): True for OMAP2430 + * cpu_is_omap3430(): True for OMAP3430 + */ +#define GET_OMAP_TYPE ((omap_rev() >> 16) & 0xffff) + +#define IS_OMAP_TYPE(type, id) \ +static inline int is_omap ##type (void) \ +{ \ + return (GET_OMAP_TYPE == (id)) ? 1 : 0; \ +} + +IS_OMAP_TYPE(2420, 0x2420) +IS_OMAP_TYPE(2422, 0x2422) +IS_OMAP_TYPE(2423, 0x2423) +IS_OMAP_TYPE(2430, 0x2430) +IS_OMAP_TYPE(3430, 0x3430) + +#define cpu_is_omap2420() 0 +#define cpu_is_omap2422() 0 +#define cpu_is_omap2423() 0 +#define cpu_is_omap2430() 0 +#define cpu_is_omap3430() 0 +#define cpu_is_omap3630() 0 +#define soc_is_omap5430() 0 + +/* These are needed for the common code */ +#ifdef CONFIG_ARCH_OMAP2PLUS +#define cpu_is_omap7xx() 0 +#define cpu_is_omap15xx() 0 +#define cpu_is_omap16xx() 0 +#define cpu_is_omap1510() 0 +#define cpu_is_omap1610() 0 +#define cpu_is_omap1611() 0 +#define cpu_is_omap1621() 0 +#define cpu_is_omap1710() 0 +#define cpu_class_is_omap1() 0 +#define cpu_class_is_omap2() 1 +#endif + +#if defined(CONFIG_ARCH_OMAP2) +# undef cpu_is_omap2420 +# undef cpu_is_omap2422 +# undef cpu_is_omap2423 +# undef cpu_is_omap2430 +# define cpu_is_omap2420() is_omap2420() +# define cpu_is_omap2422() is_omap2422() +# define cpu_is_omap2423() is_omap2423() +# define cpu_is_omap2430() is_omap2430() +#endif + +#if defined(CONFIG_ARCH_OMAP3) +# undef cpu_is_omap3430 +# undef cpu_is_ti81xx +# undef cpu_is_ti816x +# undef cpu_is_ti814x +# undef soc_is_am35xx +# define cpu_is_omap3430() is_omap3430() +# undef cpu_is_omap3630 +# define cpu_is_omap3630() is_omap363x() +# define cpu_is_ti81xx() is_ti81xx() +# define cpu_is_ti816x() is_ti816x() +# define cpu_is_ti814x() is_ti814x() +# define soc_is_am35xx() is_am35xx() +#endif + +# if defined(CONFIG_SOC_AM33XX) +# undef soc_is_am33xx +# undef soc_is_am335x +# define soc_is_am33xx() is_am33xx() +# define soc_is_am335x() is_am335x() +#endif + +#ifdef CONFIG_SOC_AM43XX +# undef soc_is_am43xx +# undef soc_is_am437x +# define soc_is_am43xx() is_am43xx() +# define soc_is_am437x() is_am437x() +#endif + +# if defined(CONFIG_ARCH_OMAP4) +# undef cpu_is_omap44xx +# undef cpu_is_omap443x +# undef cpu_is_omap446x +# undef cpu_is_omap447x +# define cpu_is_omap44xx() is_omap44xx() +# define cpu_is_omap443x() is_omap443x() +# define cpu_is_omap446x() is_omap446x() +# define cpu_is_omap447x() is_omap447x() +# endif + +# if defined(CONFIG_SOC_OMAP5) +# undef soc_is_omap54xx +# undef soc_is_omap543x +# define soc_is_omap54xx() is_omap54xx() +# define soc_is_omap543x() is_omap543x() +#endif + +#if defined(CONFIG_SOC_DRA7XX) +#undef soc_is_dra7xx +#define soc_is_dra7xx() (of_machine_is_compatible("ti,dra7")) +#endif + +/* Various silicon revisions for omap2 */ +#define OMAP242X_CLASS 0x24200024 +#define OMAP2420_REV_ES1_0 OMAP242X_CLASS +#define OMAP2420_REV_ES2_0 (OMAP242X_CLASS | (0x1 << 8)) + +#define OMAP243X_CLASS 0x24300024 +#define OMAP2430_REV_ES1_0 OMAP243X_CLASS + +#define OMAP343X_CLASS 0x34300034 +#define OMAP3430_REV_ES1_0 OMAP343X_CLASS +#define OMAP3430_REV_ES2_0 (OMAP343X_CLASS | (0x1 << 8)) +#define OMAP3430_REV_ES2_1 (OMAP343X_CLASS | (0x2 << 8)) +#define OMAP3430_REV_ES3_0 (OMAP343X_CLASS | (0x3 << 8)) +#define OMAP3430_REV_ES3_1 (OMAP343X_CLASS | (0x4 << 8)) +#define OMAP3430_REV_ES3_1_2 (OMAP343X_CLASS | (0x5 << 8)) + +#define OMAP363X_CLASS 0x36300034 +#define OMAP3630_REV_ES1_0 OMAP363X_CLASS +#define OMAP3630_REV_ES1_1 (OMAP363X_CLASS | (0x1 << 8)) +#define OMAP3630_REV_ES1_2 (OMAP363X_CLASS | (0x2 << 8)) + +#define TI816X_CLASS 0x81600034 +#define TI8168_REV_ES1_0 TI816X_CLASS +#define TI8168_REV_ES1_1 (TI816X_CLASS | (0x1 << 8)) +#define TI8168_REV_ES2_0 (TI816X_CLASS | (0x2 << 8)) +#define TI8168_REV_ES2_1 (TI816X_CLASS | (0x3 << 8)) + +#define TI814X_CLASS 0x81400034 +#define TI8148_REV_ES1_0 TI814X_CLASS +#define TI8148_REV_ES2_0 (TI814X_CLASS | (0x1 << 8)) +#define TI8148_REV_ES2_1 (TI814X_CLASS | (0x2 << 8)) + +#define AM35XX_CLASS 0x35170034 +#define AM35XX_REV_ES1_0 AM35XX_CLASS +#define AM35XX_REV_ES1_1 (AM35XX_CLASS | (0x1 << 8)) + +#define AM335X_CLASS 0x33500033 +#define AM335X_REV_ES1_0 AM335X_CLASS +#define AM335X_REV_ES2_0 (AM335X_CLASS | (0x1 << 8)) +#define AM335X_REV_ES2_1 (AM335X_CLASS | (0x2 << 8)) + +#define AM437X_CLASS 0x43700000 +#define AM437X_REV_ES1_0 (AM437X_CLASS | (0x10 << 8)) +#define AM437X_REV_ES1_1 (AM437X_CLASS | (0x11 << 8)) + +#define OMAP443X_CLASS 0x44300044 +#define OMAP4430_REV_ES1_0 (OMAP443X_CLASS | (0x10 << 8)) +#define OMAP4430_REV_ES2_0 (OMAP443X_CLASS | (0x20 << 8)) +#define OMAP4430_REV_ES2_1 (OMAP443X_CLASS | (0x21 << 8)) +#define OMAP4430_REV_ES2_2 (OMAP443X_CLASS | (0x22 << 8)) +#define OMAP4430_REV_ES2_3 (OMAP443X_CLASS | (0x23 << 8)) + +#define OMAP446X_CLASS 0x44600044 +#define OMAP4460_REV_ES1_0 (OMAP446X_CLASS | (0x10 << 8)) +#define OMAP4460_REV_ES1_1 (OMAP446X_CLASS | (0x11 << 8)) + +#define OMAP447X_CLASS 0x44700044 +#define OMAP4470_REV_ES1_0 (OMAP447X_CLASS | (0x10 << 8)) + +#define OMAP54XX_CLASS 0x54000054 +#define OMAP5430_REV_ES2_0 (OMAP54XX_CLASS | (0x30 << 16) | (0x20 << 8)) +#define OMAP5432_REV_ES2_0 (OMAP54XX_CLASS | (0x32 << 16) | (0x20 << 8)) + +#define DRA7XX_CLASS 0x07000000 +#define DRA752_REV_ES1_0 (DRA7XX_CLASS | (0x52 << 16) | (0x10 << 8)) +#define DRA752_REV_ES1_1 (DRA7XX_CLASS | (0x52 << 16) | (0x11 << 8)) +#define DRA722_REV_ES1_0 (DRA7XX_CLASS | (0x22 << 16) | (0x10 << 8)) + +void omap2xxx_check_revision(void); +void omap3xxx_check_revision(void); +void omap4xxx_check_revision(void); +void omap5xxx_check_revision(void); +void dra7xxx_check_revision(void); +void omap3xxx_check_features(void); +void ti81xx_check_features(void); +void am33xx_check_features(void); +void omap4xxx_check_features(void); + +/* + * Runtime detection of OMAP3 features + * + * OMAP3_HAS_IO_CHAIN_CTRL: Some later members of the OMAP3 chip + * family have OS-level control over the I/O chain clock. This is + * to avoid a window during which wakeups could potentially be lost + * during powerdomain transitions. If this bit is set, it + * indicates that the chip does support OS-level control of this + * feature. + */ +extern u32 omap_features; + +#define OMAP3_HAS_L2CACHE BIT(0) +#define OMAP3_HAS_IVA BIT(1) +#define OMAP3_HAS_SGX BIT(2) +#define OMAP3_HAS_NEON BIT(3) +#define OMAP3_HAS_ISP BIT(4) +#define OMAP3_HAS_192MHZ_CLK BIT(5) +#define OMAP3_HAS_IO_WAKEUP BIT(6) +#define OMAP3_HAS_SDRC BIT(7) +#define OMAP3_HAS_IO_CHAIN_CTRL BIT(8) +#define OMAP4_HAS_PERF_SILICON BIT(9) + + +#define OMAP3_HAS_FEATURE(feat,flag) \ +static inline unsigned int omap3_has_ ##feat(void) \ +{ \ + return omap_features & OMAP3_HAS_ ##flag; \ +} \ + +OMAP3_HAS_FEATURE(l2cache, L2CACHE) +OMAP3_HAS_FEATURE(sgx, SGX) +OMAP3_HAS_FEATURE(iva, IVA) +OMAP3_HAS_FEATURE(neon, NEON) +OMAP3_HAS_FEATURE(isp, ISP) +OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK) +OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP) +OMAP3_HAS_FEATURE(sdrc, SDRC) +OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL) + +/* + * Runtime detection of OMAP4 features + */ +#define OMAP4_HAS_FEATURE(feat, flag) \ +static inline unsigned int omap4_has_ ##feat(void) \ +{ \ + return omap_features & OMAP4_HAS_ ##flag; \ +} \ + +OMAP4_HAS_FEATURE(perf_silicon, PERF_SILICON) + +/* + * We need to make sure omap initcalls don't run when + * multiplatform kernels are booted on other SoCs. + */ +#define omap_initcall(level, fn) \ +static int __init __used __##fn(void) \ +{ \ + if (!soc_is_omap()) \ + return 0; \ + return fn(); \ +} \ +level(__##fn); + +#define omap_early_initcall(fn) omap_initcall(early_initcall, fn) +#define omap_core_initcall(fn) omap_initcall(core_initcall, fn) +#define omap_postcore_initcall(fn) omap_initcall(postcore_initcall, fn) +#define omap_arch_initcall(fn) omap_initcall(arch_initcall, fn) +#define omap_subsys_initcall(fn) omap_initcall(subsys_initcall, fn) +#define omap_device_initcall(fn) omap_initcall(device_initcall, fn) +#define omap_late_initcall(fn) omap_initcall(late_initcall, fn) +#define omap_late_initcall_sync(fn) omap_initcall(late_initcall_sync, fn) + +#endif /* __ASSEMBLY__ */ + diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c new file mode 100644 index 00000000000..1b91ef0c182 --- /dev/null +++ b/arch/arm/mach-omap2/sr_device.c @@ -0,0 +1,177 @@ +/* + * OMAP3/OMAP4 smartreflex device file + * + * Author: Thara Gopinath <thara@ti.com> + * + * Based originally on code from smartreflex.c + * Copyright (C) 2010 Texas Instruments, Inc. + * Thara Gopinath <thara@ti.com> + * + * Copyright (C) 2008 Nokia Corporation + * Kalle Jokiniemi + * + * Copyright (C) 2007 Texas Instruments, Inc. + * Lesly A M <x0080970@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/power/smartreflex.h> + +#include <linux/err.h> +#include <linux/slab.h> +#include <linux/io.h> + +#include "soc.h" +#include "omap_device.h" +#include "voltage.h" +#include "control.h" +#include "pm.h" + +static bool sr_enable_on_init; + +/* Read EFUSE values from control registers for OMAP3430 */ +static void __init sr_set_nvalues(struct omap_volt_data *volt_data, + struct omap_sr_data *sr_data) +{ + struct omap_sr_nvalue_table *nvalue_table; + int i, j, count = 0; + + sr_data->nvalue_count = 0; + sr_data->nvalue_table = NULL; + + while (volt_data[count].volt_nominal) + count++; + + nvalue_table = kzalloc(sizeof(struct omap_sr_nvalue_table)*count, + GFP_KERNEL); + + if (!nvalue_table) { + pr_err("OMAP: SmartReflex: cannot allocate memory for n-value table\n"); + return; + } + + for (i = 0, j = 0; i < count; i++) { + u32 v; + + /* + * In OMAP4 the efuse registers are 24 bit aligned. + * A readl_relaxed will fail for non-32 bit aligned address + * and hence the 8-bit read and shift. + */ + if (cpu_is_omap44xx()) { + u16 offset = volt_data[i].sr_efuse_offs; + + v = omap_ctrl_readb(offset) | + omap_ctrl_readb(offset + 1) << 8 | + omap_ctrl_readb(offset + 2) << 16; + } else { + v = omap_ctrl_readl(volt_data[i].sr_efuse_offs); + } + + /* + * Many OMAP SoCs don't have the eFuse values set. + * For example, pretty much all OMAP3xxx before + * ES3.something. + * + * XXX There needs to be some way for board files or + * userspace to add these in. + */ + if (v == 0) + continue; + + nvalue_table[j].nvalue = v; + nvalue_table[j].efuse_offs = volt_data[i].sr_efuse_offs; + nvalue_table[j].errminlimit = volt_data[i].sr_errminlimit; + nvalue_table[j].volt_nominal = volt_data[i].volt_nominal; + + j++; + } + + sr_data->nvalue_table = nvalue_table; + sr_data->nvalue_count = j; +} + +static int __init sr_dev_init(struct omap_hwmod *oh, void *user) +{ + struct omap_sr_data *sr_data; + struct platform_device *pdev; + struct omap_volt_data *volt_data; + struct omap_smartreflex_dev_attr *sr_dev_attr; + char *name = "smartreflex"; + static int i; + + sr_data = kzalloc(sizeof(struct omap_sr_data), GFP_KERNEL); + if (!sr_data) { + pr_err("%s: Unable to allocate memory for %s sr_data\n", + __func__, oh->name); + return -ENOMEM; + } + + sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr; + if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) { + pr_err("%s: No voltage domain specified for %s. Cannot initialize\n", + __func__, oh->name); + goto exit; + } + + sr_data->name = oh->name; + sr_data->ip_type = oh->class->rev; + sr_data->senn_mod = 0x1; + sr_data->senp_mod = 0x1; + + if (cpu_is_omap34xx() || cpu_is_omap44xx()) { + sr_data->err_weight = OMAP3430_SR_ERRWEIGHT; + sr_data->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT; + sr_data->accum_data = OMAP3430_SR_ACCUMDATA; + if (!(strcmp(sr_data->name, "smartreflex_mpu"))) { + sr_data->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT; + sr_data->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT; + } else { + sr_data->senn_avgweight = OMAP3430_SR2_SENNAVGWEIGHT; + sr_data->senp_avgweight = OMAP3430_SR2_SENPAVGWEIGHT; + } + } + + sr_data->voltdm = voltdm_lookup(sr_dev_attr->sensor_voltdm_name); + if (!sr_data->voltdm) { + pr_err("%s: Unable to get voltage domain pointer for VDD %s\n", + __func__, sr_dev_attr->sensor_voltdm_name); + goto exit; + } + + omap_voltage_get_volttable(sr_data->voltdm, &volt_data); + if (!volt_data) { + pr_err("%s: No Voltage table registered for VDD%d\n", + __func__, i + 1); + goto exit; + } + + sr_set_nvalues(volt_data, sr_data); + + sr_data->enable_on_init = sr_enable_on_init; + + pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data)); + if (IS_ERR(pdev)) + pr_warning("%s: Could not build omap_device for %s: %s.\n\n", + __func__, name, oh->name); +exit: + i++; + kfree(sr_data); + return 0; +} + +/* + * API to be called from board files to enable smartreflex + * autocompensation at init. + */ +void __init omap_enable_smartreflex_on_init(void) +{ + sr_enable_on_init = true; +} + +int __init omap_devinit_smartreflex(void) +{ + return omap_hwmod_for_each_by_class("smartreflex", sr_dev_init, NULL); +} diff --git a/arch/arm/mach-omap2/sram.c b/arch/arm/mach-omap2/sram.c new file mode 100644 index 00000000000..ddf1818af22 --- /dev/null +++ b/arch/arm/mach-omap2/sram.c @@ -0,0 +1,308 @@ +/* + * + * OMAP SRAM detection and management + * + * Copyright (C) 2005 Nokia Corporation + * Written by Tony Lindgren <tony@atomide.com> + * + * Copyright (C) 2009-2012 Texas Instruments + * Added OMAP4/5 support - Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/io.h> + +#include <asm/fncpy.h> +#include <asm/tlb.h> +#include <asm/cacheflush.h> + +#include <asm/mach/map.h> + +#include "soc.h" +#include "iomap.h" +#include "prm2xxx_3xxx.h" +#include "sdrc.h" +#include "sram.h" + +#define OMAP2_SRAM_PUB_PA (OMAP2_SRAM_PA + 0xf800) +#define OMAP3_SRAM_PUB_PA (OMAP3_SRAM_PA + 0x8000) +#ifdef CONFIG_OMAP4_ERRATA_I688 +#define OMAP4_SRAM_PUB_PA OMAP4_SRAM_PA +#else +#define OMAP4_SRAM_PUB_PA (OMAP4_SRAM_PA + 0x4000) +#endif +#define OMAP5_SRAM_PA 0x40300000 + +#define SRAM_BOOTLOADER_SZ 0x00 + +#define OMAP24XX_VA_REQINFOPERM0 OMAP2_L3_IO_ADDRESS(0x68005048) +#define OMAP24XX_VA_READPERM0 OMAP2_L3_IO_ADDRESS(0x68005050) +#define OMAP24XX_VA_WRITEPERM0 OMAP2_L3_IO_ADDRESS(0x68005058) + +#define OMAP34XX_VA_REQINFOPERM0 OMAP2_L3_IO_ADDRESS(0x68012848) +#define OMAP34XX_VA_READPERM0 OMAP2_L3_IO_ADDRESS(0x68012850) +#define OMAP34XX_VA_WRITEPERM0 OMAP2_L3_IO_ADDRESS(0x68012858) +#define OMAP34XX_VA_ADDR_MATCH2 OMAP2_L3_IO_ADDRESS(0x68012880) +#define OMAP34XX_VA_SMS_RG_ATT0 OMAP2_L3_IO_ADDRESS(0x6C000048) + +#define GP_DEVICE 0x300 + +#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) + +static unsigned long omap_sram_start; +static unsigned long omap_sram_skip; +static unsigned long omap_sram_size; + +/* + * Depending on the target RAMFS firewall setup, the public usable amount of + * SRAM varies. The default accessible size for all device types is 2k. A GP + * device allows ARM11 but not other initiators for full size. This + * functionality seems ok until some nice security API happens. + */ +static int is_sram_locked(void) +{ + if (OMAP2_DEVICE_TYPE_GP == omap_type()) { + /* RAMFW: R/W access to all initiators for all qualifier sets */ + if (cpu_is_omap242x()) { + writel_relaxed(0xFF, OMAP24XX_VA_REQINFOPERM0); /* all q-vects */ + writel_relaxed(0xCFDE, OMAP24XX_VA_READPERM0); /* all i-read */ + writel_relaxed(0xCFDE, OMAP24XX_VA_WRITEPERM0); /* all i-write */ + } + if (cpu_is_omap34xx()) { + writel_relaxed(0xFFFF, OMAP34XX_VA_REQINFOPERM0); /* all q-vects */ + writel_relaxed(0xFFFF, OMAP34XX_VA_READPERM0); /* all i-read */ + writel_relaxed(0xFFFF, OMAP34XX_VA_WRITEPERM0); /* all i-write */ + writel_relaxed(0x0, OMAP34XX_VA_ADDR_MATCH2); + writel_relaxed(0xFFFFFFFF, OMAP34XX_VA_SMS_RG_ATT0); + } + return 0; + } else + return 1; /* assume locked with no PPA or security driver */ +} + +/* + * The amount of SRAM depends on the core type. + * Note that we cannot try to test for SRAM here because writes + * to secure SRAM will hang the system. Also the SRAM is not + * yet mapped at this point. + */ +static void __init omap_detect_sram(void) +{ + omap_sram_skip = SRAM_BOOTLOADER_SZ; + if (is_sram_locked()) { + if (cpu_is_omap34xx()) { + omap_sram_start = OMAP3_SRAM_PUB_PA; + if ((omap_type() == OMAP2_DEVICE_TYPE_EMU) || + (omap_type() == OMAP2_DEVICE_TYPE_SEC)) { + omap_sram_size = 0x7000; /* 28K */ + omap_sram_skip += SZ_16K; + } else { + omap_sram_size = 0x8000; /* 32K */ + } + } else if (cpu_is_omap44xx()) { + omap_sram_start = OMAP4_SRAM_PUB_PA; + omap_sram_size = 0xa000; /* 40K */ + } else if (soc_is_omap54xx()) { + omap_sram_start = OMAP5_SRAM_PA; + omap_sram_size = SZ_128K; /* 128KB */ + } else { + omap_sram_start = OMAP2_SRAM_PUB_PA; + omap_sram_size = 0x800; /* 2K */ + } + } else { + if (soc_is_am33xx()) { + omap_sram_start = AM33XX_SRAM_PA; + omap_sram_size = 0x10000; /* 64K */ + } else if (soc_is_am43xx()) { + omap_sram_start = AM33XX_SRAM_PA; + omap_sram_size = SZ_256K; + } else if (cpu_is_omap34xx()) { + omap_sram_start = OMAP3_SRAM_PA; + omap_sram_size = 0x10000; /* 64K */ + } else if (cpu_is_omap44xx()) { + omap_sram_start = OMAP4_SRAM_PA; + omap_sram_size = 0xe000; /* 56K */ + } else if (soc_is_omap54xx()) { + omap_sram_start = OMAP5_SRAM_PA; + omap_sram_size = SZ_128K; /* 128KB */ + } else { + omap_sram_start = OMAP2_SRAM_PA; + if (cpu_is_omap242x()) + omap_sram_size = 0xa0000; /* 640K */ + else if (cpu_is_omap243x()) + omap_sram_size = 0x10000; /* 64K */ + } + } +} + +/* + * Note that we cannot use ioremap for SRAM, as clock init needs SRAM early. + */ +static void __init omap2_map_sram(void) +{ + int cached = 1; + +#ifdef CONFIG_OMAP4_ERRATA_I688 + if (cpu_is_omap44xx()) { + omap_sram_start += PAGE_SIZE; + omap_sram_size -= SZ_16K; + } +#endif + if (cpu_is_omap34xx()) { + /* + * SRAM must be marked as non-cached on OMAP3 since the + * CORE DPLL M2 divider change code (in SRAM) runs with the + * SDRAM controller disabled, and if it is marked cached, + * the ARM may attempt to write cache lines back to SDRAM + * which will cause the system to hang. + */ + cached = 0; + } + + omap_map_sram(omap_sram_start, omap_sram_size, + omap_sram_skip, cached); +} + +static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, + u32 base_cs, u32 force_unlock); + +void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, + u32 base_cs, u32 force_unlock) +{ + BUG_ON(!_omap2_sram_ddr_init); + _omap2_sram_ddr_init(slow_dll_ctrl, fast_dll_ctrl, + base_cs, force_unlock); +} + +static void (*_omap2_sram_reprogram_sdrc)(u32 perf_level, u32 dll_val, + u32 mem_type); + +void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type) +{ + BUG_ON(!_omap2_sram_reprogram_sdrc); + _omap2_sram_reprogram_sdrc(perf_level, dll_val, mem_type); +} + +static u32 (*_omap2_set_prcm)(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass); + +u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass) +{ + BUG_ON(!_omap2_set_prcm); + return _omap2_set_prcm(dpll_ctrl_val, sdrc_rfr_val, bypass); +} + +#ifdef CONFIG_SOC_OMAP2420 +static int __init omap242x_sram_init(void) +{ + _omap2_sram_ddr_init = omap_sram_push(omap242x_sram_ddr_init, + omap242x_sram_ddr_init_sz); + + _omap2_sram_reprogram_sdrc = omap_sram_push(omap242x_sram_reprogram_sdrc, + omap242x_sram_reprogram_sdrc_sz); + + _omap2_set_prcm = omap_sram_push(omap242x_sram_set_prcm, + omap242x_sram_set_prcm_sz); + + return 0; +} +#else +static inline int omap242x_sram_init(void) +{ + return 0; +} +#endif + +#ifdef CONFIG_SOC_OMAP2430 +static int __init omap243x_sram_init(void) +{ + _omap2_sram_ddr_init = omap_sram_push(omap243x_sram_ddr_init, + omap243x_sram_ddr_init_sz); + + _omap2_sram_reprogram_sdrc = omap_sram_push(omap243x_sram_reprogram_sdrc, + omap243x_sram_reprogram_sdrc_sz); + + _omap2_set_prcm = omap_sram_push(omap243x_sram_set_prcm, + omap243x_sram_set_prcm_sz); + + return 0; +} +#else +static inline int omap243x_sram_init(void) +{ + return 0; +} +#endif + +#ifdef CONFIG_ARCH_OMAP3 + +static u32 (*_omap3_sram_configure_core_dpll)( + u32 m2, u32 unlock_dll, u32 f, u32 inc, + u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0, + u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0, + u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1, + u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1); + +u32 omap3_configure_core_dpll(u32 m2, u32 unlock_dll, u32 f, u32 inc, + u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0, + u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0, + u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1, + u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1) +{ + BUG_ON(!_omap3_sram_configure_core_dpll); + return _omap3_sram_configure_core_dpll( + m2, unlock_dll, f, inc, + sdrc_rfr_ctrl_0, sdrc_actim_ctrl_a_0, + sdrc_actim_ctrl_b_0, sdrc_mr_0, + sdrc_rfr_ctrl_1, sdrc_actim_ctrl_a_1, + sdrc_actim_ctrl_b_1, sdrc_mr_1); +} + +void omap3_sram_restore_context(void) +{ + omap_sram_reset(); + + _omap3_sram_configure_core_dpll = + omap_sram_push(omap3_sram_configure_core_dpll, + omap3_sram_configure_core_dpll_sz); + omap_push_sram_idle(); +} + +static inline int omap34xx_sram_init(void) +{ + omap3_sram_restore_context(); + return 0; +} +#else +static inline int omap34xx_sram_init(void) +{ + return 0; +} +#endif /* CONFIG_ARCH_OMAP3 */ + +static inline int am33xx_sram_init(void) +{ + return 0; +} + +int __init omap_sram_init(void) +{ + omap_detect_sram(); + omap2_map_sram(); + + if (cpu_is_omap242x()) + omap242x_sram_init(); + else if (cpu_is_omap2430()) + omap243x_sram_init(); + else if (soc_is_am33xx()) + am33xx_sram_init(); + else if (cpu_is_omap34xx()) + omap34xx_sram_init(); + + return 0; +} diff --git a/arch/arm/mach-omap2/sram.h b/arch/arm/mach-omap2/sram.h new file mode 100644 index 00000000000..ca7277c2a9e --- /dev/null +++ b/arch/arm/mach-omap2/sram.h @@ -0,0 +1,83 @@ +/* + * Interface for functions that need to be run in internal SRAM + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASSEMBLY__ +#include <plat/sram.h> + +extern void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, + u32 base_cs, u32 force_unlock); +extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, + u32 mem_type); +extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass); + +extern u32 omap3_configure_core_dpll( + u32 m2, u32 unlock_dll, u32 f, u32 inc, + u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0, + u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0, + u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1, + u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1); +extern void omap3_sram_restore_context(void); + +/* Do not use these */ +extern void omap24xx_sram_reprogram_clock(u32 ckctl, u32 dpllctl); +extern unsigned long omap24xx_sram_reprogram_clock_sz; + +extern void omap242x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, + u32 base_cs, u32 force_unlock); +extern unsigned long omap242x_sram_ddr_init_sz; + +extern u32 omap242x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, + int bypass); +extern unsigned long omap242x_sram_set_prcm_sz; + +extern void omap242x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, + u32 mem_type); +extern unsigned long omap242x_sram_reprogram_sdrc_sz; + + +extern void omap243x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, + u32 base_cs, u32 force_unlock); +extern unsigned long omap243x_sram_ddr_init_sz; + +extern u32 omap243x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, + int bypass); +extern unsigned long omap243x_sram_set_prcm_sz; + +extern void omap243x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, + u32 mem_type); +extern unsigned long omap243x_sram_reprogram_sdrc_sz; + +extern u32 omap3_sram_configure_core_dpll( + u32 m2, u32 unlock_dll, u32 f, u32 inc, + u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0, + u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0, + u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1, + u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1); +extern unsigned long omap3_sram_configure_core_dpll_sz; + +#ifdef CONFIG_PM +extern void omap_push_sram_idle(void); +#else +static inline void omap_push_sram_idle(void) {} +#endif /* CONFIG_PM */ + +#endif /* __ASSEMBLY__ */ + +/* + * OMAP2+: define the SRAM PA addresses. + * Used by the SRAM management code and the idle sleep code. + */ +#define OMAP2_SRAM_PA 0x40200000 +#define OMAP3_SRAM_PA 0x40200000 +#ifdef CONFIG_OMAP4_ERRATA_I688 +#define OMAP4_SRAM_PA 0x40304000 +#define OMAP4_SRAM_VA 0xfe404000 +#else +#define OMAP4_SRAM_PA 0x40300000 +#endif +#define AM33XX_SRAM_PA 0x40300000 diff --git a/arch/arm/mach-omap2/sram242x.S b/arch/arm/mach-omap2/sram242x.S index af4bd349022..680a7c56cc3 100644 --- a/arch/arm/mach-omap2/sram242x.S +++ b/arch/arm/mach-omap2/sram242x.S @@ -21,18 +21,26 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA + * + * Richard Woodruff notes that any changes to this code must be carefully + * audited and tested to ensure that they don't cause a TLB miss while + * the SDRAM is inaccessible. Such a situation will crash the system + * since it will cause the ARM MMU to attempt to walk the page tables. + * These crashes may be intermittent. */ #include <linux/linkage.h> + #include <asm/assembler.h> -#include <mach/io.h> -#include <mach/hardware.h> -#include "prm.h" -#include "cm.h" +#include "soc.h" +#include "iomap.h" +#include "prm2xxx.h" +#include "cm2xxx.h" #include "sdrc.h" .text + .align 3 ENTRY(omap242x_sram_ddr_init) stmfd sp!, {r0 - r12, lr} @ save registers on stack @@ -124,11 +132,11 @@ omap242x_sdi_cm_clksel2_pll: omap242x_sdi_sdrc_dlla_ctrl: .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) omap242x_sdi_prcm_voltctrl: - .word OMAP242X_PRCM_VOLTCTRL + .word OMAP2420_PRCM_VOLTCTRL prcm_mask_val: .word 0xFFFF3FFC omap242x_sdi_timer_32ksynct_cr: - .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) + .word OMAP2_L4_IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010) ENTRY(omap242x_sram_ddr_init_sz) .word . - omap242x_sram_ddr_init @@ -137,6 +145,7 @@ ENTRY(omap242x_sram_ddr_init_sz) * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0 */ + .align 3 ENTRY(omap242x_sram_reprogram_sdrc) stmfd sp!, {r0 - r10, lr} @ save registers on stack mov r3, #0x0 @ clear for mrc call @@ -220,11 +229,11 @@ omap242x_srs_sdrc_dlla_ctrl: omap242x_srs_sdrc_rfr_ctrl: .word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0) omap242x_srs_prcm_voltctrl: - .word OMAP242X_PRCM_VOLTCTRL + .word OMAP2420_PRCM_VOLTCTRL ddr_prcm_mask_val: .word 0xFFFF3FFC omap242x_srs_timer_32ksynct: - .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) + .word OMAP2_L4_IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010) ENTRY(omap242x_sram_reprogram_sdrc_sz) .word . - omap242x_sram_reprogram_sdrc @@ -232,6 +241,7 @@ ENTRY(omap242x_sram_reprogram_sdrc_sz) /* * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. */ + .align 3 ENTRY(omap242x_sram_set_prcm) stmfd sp!, {r0-r12, lr} @ regs to stack adr r4, pbegin @ addr of preload start @@ -305,7 +315,7 @@ wait_dll_lock: ldmfd sp!, {r0-r12, pc} @ restore regs and return omap242x_ssp_set_config: - .word OMAP242X_PRCM_CLKCFG_CTRL + .word OMAP2420_PRCM_CLKCFG_CTRL omap242x_ssp_pll_ctl: .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKEN) omap242x_ssp_pll_stat: diff --git a/arch/arm/mach-omap2/sram243x.S b/arch/arm/mach-omap2/sram243x.S index 84363e269e8..a1e9edd673f 100644 --- a/arch/arm/mach-omap2/sram243x.S +++ b/arch/arm/mach-omap2/sram243x.S @@ -21,18 +21,26 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA + * + * Richard Woodruff notes that any changes to this code must be carefully + * audited and tested to ensure that they don't cause a TLB miss while + * the SDRAM is inaccessible. Such a situation will crash the system + * since it will cause the ARM MMU to attempt to walk the page tables. + * These crashes may be intermittent. */ #include <linux/linkage.h> + #include <asm/assembler.h> -#include <mach/io.h> -#include <mach/hardware.h> -#include "prm.h" -#include "cm.h" +#include "soc.h" +#include "iomap.h" +#include "prm2xxx.h" +#include "cm2xxx.h" #include "sdrc.h" .text + .align 3 ENTRY(omap243x_sram_ddr_init) stmfd sp!, {r0 - r12, lr} @ save registers on stack @@ -124,11 +132,11 @@ omap243x_sdi_cm_clksel2_pll: omap243x_sdi_sdrc_dlla_ctrl: .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL) omap243x_sdi_prcm_voltctrl: - .word OMAP243X_PRCM_VOLTCTRL + .word OMAP2430_PRCM_VOLTCTRL prcm_mask_val: .word 0xFFFF3FFC omap243x_sdi_timer_32ksynct_cr: - .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) + .word OMAP2_L4_IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010) ENTRY(omap243x_sram_ddr_init_sz) .word . - omap243x_sram_ddr_init @@ -137,6 +145,7 @@ ENTRY(omap243x_sram_ddr_init_sz) * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0 */ + .align 3 ENTRY(omap243x_sram_reprogram_sdrc) stmfd sp!, {r0 - r10, lr} @ save registers on stack mov r3, #0x0 @ clear for mrc call @@ -220,11 +229,11 @@ omap243x_srs_sdrc_dlla_ctrl: omap243x_srs_sdrc_rfr_ctrl: .word OMAP243X_SDRC_REGADDR(SDRC_RFR_CTRL_0) omap243x_srs_prcm_voltctrl: - .word OMAP243X_PRCM_VOLTCTRL + .word OMAP2430_PRCM_VOLTCTRL ddr_prcm_mask_val: .word 0xFFFF3FFC omap243x_srs_timer_32ksynct: - .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) + .word OMAP2_L4_IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010) ENTRY(omap243x_sram_reprogram_sdrc_sz) .word . - omap243x_sram_reprogram_sdrc @@ -232,6 +241,7 @@ ENTRY(omap243x_sram_reprogram_sdrc_sz) /* * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. */ + .align 3 ENTRY(omap243x_sram_set_prcm) stmfd sp!, {r0-r12, lr} @ regs to stack adr r4, pbegin @ addr of preload start @@ -305,7 +315,7 @@ wait_dll_lock: ldmfd sp!, {r0-r12, pc} @ restore regs and return omap243x_ssp_set_config: - .word OMAP243X_PRCM_CLKCFG_CTRL + .word OMAP2430_PRCM_CLKCFG_CTRL omap243x_ssp_pll_ctl: .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKEN) omap243x_ssp_pll_stat: diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S index 2c714613634..1446331b576 100644 --- a/arch/arm/mach-omap2/sram34xx.S +++ b/arch/arm/mach-omap2/sram34xx.S @@ -3,13 +3,12 @@ * * Omap3 specific functions that need to be run in internal SRAM * - * (C) Copyright 2007 - * Texas Instruments Inc. - * Rajendra Nayak <rnayak@ti.com> + * Copyright (C) 2004, 2007, 2008 Texas Instruments, Inc. + * Copyright (C) 2008 Nokia Corporation * - * (C) Copyright 2004 - * Texas Instruments, <www.ti.com> + * Rajendra Nayak <rnayak@ti.com> * Richard Woodruff <r-woodruff2@ti.com> + * Paul Walmsley * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -27,133 +26,271 @@ * MA 02111-1307 USA */ #include <linux/linkage.h> -#include <asm/assembler.h> -#include <mach/hardware.h> -#include <mach/io.h> +#include <asm/assembler.h> +#include "soc.h" +#include "iomap.h" #include "sdrc.h" -#include "cm.h" +#include "cm3xxx.h" + +/* + * This file needs be built unconditionally as ARM to interoperate correctly + * with non-Thumb-2-capable firmware. + */ + .arm .text +/* r1 parameters */ +#define SDRC_NO_UNLOCK_DLL 0x0 +#define SDRC_UNLOCK_DLL 0x1 + +/* SDRC_DLLA_CTRL bit settings */ +#define FIXEDDELAY_SHIFT 24 +#define FIXEDDELAY_MASK (0xff << FIXEDDELAY_SHIFT) +#define DLLIDLE_MASK 0x4 + /* - * Change frequency of core dpll - * r0 = sdrc_rfr_ctrl r1 = sdrc_actim_ctrla r2 = sdrc_actim_ctrlb r3 = M2 + * SDRC_DLLA_CTRL default values: TI hardware team indicates that + * FIXEDDELAY should be initialized to 0xf. This apparently was + * empirically determined during process testing, so no derivation + * was provided. */ +#define FIXEDDELAY_DEFAULT (0x0f << FIXEDDELAY_SHIFT) + +/* SDRC_DLLA_STATUS bit settings */ +#define LOCKSTATUS_MASK 0x4 + +/* SDRC_POWER bit settings */ +#define SRFRONIDLEREQ_MASK 0x40 + +/* CM_IDLEST1_CORE bit settings */ +#define ST_SDRC_MASK 0x2 + +/* CM_ICLKEN1_CORE bit settings */ +#define EN_SDRC_MASK 0x2 + +/* CM_CLKSEL1_PLL bit settings */ +#define CORE_DPLL_CLKOUT_DIV_SHIFT 0x1b + +/* + * omap3_sram_configure_core_dpll - change DPLL3 M2 divider + * + * Params passed in registers: + * r0 = new M2 divider setting (only 1 and 2 supported right now) + * r1 = unlock SDRC DLL? (1 = yes, 0 = no). Only unlock DLL for + * SDRC rates < 83MHz + * r2 = number of MPU cycles to wait for SDRC to stabilize after + * reprogramming the SDRC when switching to a slower MPU speed + * r3 = increasing SDRC rate? (1 = yes, 0 = no) + * + * Params passed via the stack. The needed params will be copied in SRAM + * before use by the code in SRAM (SDRAM is not accessible during SDRC + * reconfiguration): + * new SDRC_RFR_CTRL_0 register contents + * new SDRC_ACTIM_CTRL_A_0 register contents + * new SDRC_ACTIM_CTRL_B_0 register contents + * new SDRC_MR_0 register value + * new SDRC_RFR_CTRL_1 register contents + * new SDRC_ACTIM_CTRL_A_1 register contents + * new SDRC_ACTIM_CTRL_B_1 register contents + * new SDRC_MR_1 register value + * + * If the param SDRC_RFR_CTRL_1 is 0, the parameters are not programmed into + * the SDRC CS1 registers + * + * NOTE: This code no longer attempts to program the SDRC AC timing and MR + * registers. This is because the code currently cannot ensure that all + * L3 initiators (e.g., sDMA, IVA, DSS DISPC, etc.) are not accessing the + * SDRAM when the registers are written. If the registers are changed while + * an initiator is accessing SDRAM, memory can be corrupted and/or the SDRC + * may enter an unpredictable state. In the future, the intent is to + * re-enable this code in cases where we can ensure that no initiators are + * touching the SDRAM. Until that time, users who know that their use case + * can satisfy the above requirement can enable the CONFIG_OMAP3_SDRC_AC_TIMING + * option. + * + * Richard Woodruff notes that any changes to this code must be carefully + * audited and tested to ensure that they don't cause a TLB miss while + * the SDRAM is inaccessible. Such a situation will crash the system + * since it will cause the ARM MMU to attempt to walk the page tables. + * These crashes may be intermittent. + */ + .align 3 ENTRY(omap3_sram_configure_core_dpll) stmfd sp!, {r1-r12, lr} @ store regs to stack - cmp r3, #0x2 - blne configure_sdrc - cmp r3, #0x2 + + @ pull the extra args off the stack + @ and store them in SRAM + +/* + * PC-relative stores are deprecated in ARMv7 and lead to undefined behaviour + * in Thumb-2: use a r7 as a base instead. + * Be careful not to clobber r7 when maintaing this file. + */ + THUMB( adr r7, omap3_sram_configure_core_dpll ) + .macro strtext Rt:req, label:req + ARM( str \Rt, \label ) + THUMB( str \Rt, [r7, \label - omap3_sram_configure_core_dpll] ) + .endm + + ldr r4, [sp, #52] + strtext r4, omap_sdrc_rfr_ctrl_0_val + ldr r4, [sp, #56] + strtext r4, omap_sdrc_actim_ctrl_a_0_val + ldr r4, [sp, #60] + strtext r4, omap_sdrc_actim_ctrl_b_0_val + ldr r4, [sp, #64] + strtext r4, omap_sdrc_mr_0_val + ldr r4, [sp, #68] + strtext r4, omap_sdrc_rfr_ctrl_1_val + cmp r4, #0 @ if SDRC_RFR_CTRL_1 is 0, + beq skip_cs1_params @ do not use cs1 params + ldr r4, [sp, #72] + strtext r4, omap_sdrc_actim_ctrl_a_1_val + ldr r4, [sp, #76] + strtext r4, omap_sdrc_actim_ctrl_b_1_val + ldr r4, [sp, #80] + strtext r4, omap_sdrc_mr_1_val +skip_cs1_params: + mrc p15, 0, r8, c1, c0, 0 @ read ctrl register + bic r10, r8, #0x800 @ clear Z-bit, disable branch prediction + mcr p15, 0, r10, c1, c0, 0 @ write ctrl register + dsb @ flush buffered writes to interconnect + isb @ prevent speculative exec past here + cmp r3, #1 @ if increasing SDRC clk rate, + bleq configure_sdrc @ program the SDRC regs early (for RFR) + cmp r1, #SDRC_UNLOCK_DLL @ set the intended DLL state + bleq unlock_dll blne lock_dll - cmp r3, #0x1 - blne unlock_dll - bl sdram_in_selfrefresh @ put the SDRAM in self refresh - bl configure_core_dpll - bl enable_sdrc - cmp r3, #0x1 - blne wait_dll_unlock - cmp r3, #0x2 + bl sdram_in_selfrefresh @ put SDRAM in self refresh, idle SDRC + bl configure_core_dpll @ change the DPLL3 M2 divider + mov r12, r2 + bl wait_clk_stable @ wait for SDRC to stabilize + bl enable_sdrc @ take SDRC out of idle + cmp r1, #SDRC_UNLOCK_DLL @ wait for DLL status to change + bleq wait_dll_unlock blne wait_dll_lock - cmp r3, #0x1 - blne configure_sdrc + cmp r3, #1 @ if increasing SDRC clk rate, + beq return_to_sdram @ return to SDRAM code, otherwise, + bl configure_sdrc @ reprogram SDRC regs now +return_to_sdram: + mcr p15, 0, r8, c1, c0, 0 @ restore ctrl register + isb @ prevent speculative exec past here mov r0, #0 @ return value ldmfd sp!, {r1-r12, pc} @ restore regs and return unlock_dll: - ldr r4, omap3_sdrc_dlla_ctrl - ldr r5, [r4] - orr r5, r5, #0x4 - str r5, [r4] + ldr r11, omap3_sdrc_dlla_ctrl + ldr r12, [r11] + bic r12, r12, #FIXEDDELAY_MASK + orr r12, r12, #FIXEDDELAY_DEFAULT + orr r12, r12, #DLLIDLE_MASK + str r12, [r11] @ (no OCP barrier needed) bx lr lock_dll: - ldr r4, omap3_sdrc_dlla_ctrl - ldr r5, [r4] - bic r5, r5, #0x4 - str r5, [r4] + ldr r11, omap3_sdrc_dlla_ctrl + ldr r12, [r11] + bic r12, r12, #DLLIDLE_MASK + str r12, [r11] @ (no OCP barrier needed) bx lr sdram_in_selfrefresh: - mov r5, #0x0 @ Move 0 to R5 - mcr p15, 0, r5, c7, c10, 5 @ memory barrier - ldr r4, omap3_sdrc_power @ read the SDRC_POWER register - ldr r5, [r4] @ read the contents of SDRC_POWER - orr r5, r5, #0x40 @ enable self refresh on idle req - str r5, [r4] @ write back to SDRC_POWER register - ldr r4, omap3_cm_iclken1_core @ read the CM_ICLKEN1_CORE reg - ldr r5, [r4] - bic r5, r5, #0x2 @ disable iclk bit for SRDC - str r5, [r4] + ldr r11, omap3_sdrc_power @ read the SDRC_POWER register + ldr r12, [r11] @ read the contents of SDRC_POWER + mov r9, r12 @ keep a copy of SDRC_POWER bits + orr r12, r12, #SRFRONIDLEREQ_MASK @ enable self refresh on idle + str r12, [r11] @ write back to SDRC_POWER register + ldr r12, [r11] @ posted-write barrier for SDRC +idle_sdrc: + ldr r11, omap3_cm_iclken1_core @ read the CM_ICLKEN1_CORE reg + ldr r12, [r11] + bic r12, r12, #EN_SDRC_MASK @ disable iclk bit for SDRC + str r12, [r11] wait_sdrc_idle: - ldr r4, omap3_cm_idlest1_core - ldr r5, [r4] - and r5, r5, #0x2 @ check for SDRC idle - cmp r5, #2 + ldr r11, omap3_cm_idlest1_core + ldr r12, [r11] + and r12, r12, #ST_SDRC_MASK @ check for SDRC idle + cmp r12, #ST_SDRC_MASK bne wait_sdrc_idle bx lr configure_core_dpll: - ldr r4, omap3_cm_clksel1_pll - ldr r5, [r4] - ldr r6, core_m2_mask_val @ modify m2 for core dpll - and r5, r5, r6 - orr r5, r5, r3, lsl #0x1B @ r3 contains the M2 val - str r5, [r4] - mov r5, #0x800 @ wait for the clock to stabilise - cmp r3, #2 - bne wait_clk_stable + ldr r11, omap3_cm_clksel1_pll + ldr r12, [r11] + ldr r10, core_m2_mask_val @ modify m2 for core dpll + and r12, r12, r10 + orr r12, r12, r0, lsl #CORE_DPLL_CLKOUT_DIV_SHIFT + str r12, [r11] + ldr r12, [r11] @ posted-write barrier for CM bx lr wait_clk_stable: - subs r5, r5, #1 + subs r12, r12, #1 bne wait_clk_stable - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop bx lr enable_sdrc: - ldr r4, omap3_cm_iclken1_core - ldr r5, [r4] - orr r5, r5, #0x2 @ enable iclk bit for SDRC - str r5, [r4] + ldr r11, omap3_cm_iclken1_core + ldr r12, [r11] + orr r12, r12, #EN_SDRC_MASK @ enable iclk bit for SDRC + str r12, [r11] wait_sdrc_idle1: - ldr r4, omap3_cm_idlest1_core - ldr r5, [r4] - and r5, r5, #0x2 - cmp r5, #0 + ldr r11, omap3_cm_idlest1_core + ldr r12, [r11] + and r12, r12, #ST_SDRC_MASK + cmp r12, #0 bne wait_sdrc_idle1 - ldr r4, omap3_sdrc_power - ldr r5, [r4] - bic r5, r5, #0x40 - str r5, [r4] +restore_sdrc_power_val: + ldr r11, omap3_sdrc_power + str r9, [r11] @ restore SDRC_POWER, no barrier needed bx lr wait_dll_lock: - ldr r4, omap3_sdrc_dlla_status - ldr r5, [r4] - and r5, r5, #0x4 - cmp r5, #0x4 + ldr r11, omap3_sdrc_dlla_status + ldr r12, [r11] + and r12, r12, #LOCKSTATUS_MASK + cmp r12, #LOCKSTATUS_MASK bne wait_dll_lock bx lr wait_dll_unlock: - ldr r4, omap3_sdrc_dlla_status - ldr r5, [r4] - and r5, r5, #0x4 - cmp r5, #0x0 + ldr r11, omap3_sdrc_dlla_status + ldr r12, [r11] + and r12, r12, #LOCKSTATUS_MASK + cmp r12, #0x0 bne wait_dll_unlock bx lr configure_sdrc: - ldr r4, omap3_sdrc_rfr_ctrl - str r0, [r4] - ldr r4, omap3_sdrc_actim_ctrla - str r1, [r4] - ldr r4, omap3_sdrc_actim_ctrlb - str r2, [r4] + ldr r12, omap_sdrc_rfr_ctrl_0_val @ fetch value from SRAM + ldr r11, omap3_sdrc_rfr_ctrl_0 @ fetch addr from SRAM + str r12, [r11] @ store +#ifdef CONFIG_OMAP3_SDRC_AC_TIMING + ldr r12, omap_sdrc_actim_ctrl_a_0_val + ldr r11, omap3_sdrc_actim_ctrl_a_0 + str r12, [r11] + ldr r12, omap_sdrc_actim_ctrl_b_0_val + ldr r11, omap3_sdrc_actim_ctrl_b_0 + str r12, [r11] + ldr r12, omap_sdrc_mr_0_val + ldr r11, omap3_sdrc_mr_0 + str r12, [r11] +#endif + ldr r12, omap_sdrc_rfr_ctrl_1_val + cmp r12, #0 @ if SDRC_RFR_CTRL_1 is 0, + beq skip_cs1_prog @ do not program cs1 params + ldr r11, omap3_sdrc_rfr_ctrl_1 + str r12, [r11] +#ifdef CONFIG_OMAP3_SDRC_AC_TIMING + ldr r12, omap_sdrc_actim_ctrl_a_1_val + ldr r11, omap3_sdrc_actim_ctrl_a_1 + str r12, [r11] + ldr r12, omap_sdrc_actim_ctrl_b_1_val + ldr r11, omap3_sdrc_actim_ctrl_b_1 + str r12, [r11] + ldr r12, omap_sdrc_mr_1_val + ldr r11, omap3_sdrc_mr_1 + str r12, [r11] +#endif +skip_cs1_prog: + ldr r12, [r11] @ posted-write barrier for SDRC bx lr + .align omap3_sdrc_power: .word OMAP34XX_SDRC_REGADDR(SDRC_POWER) omap3_cm_clksel1_pll: @@ -162,18 +299,48 @@ omap3_cm_idlest1_core: .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST) omap3_cm_iclken1_core: .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_ICLKEN1) -omap3_sdrc_rfr_ctrl: + +omap3_sdrc_rfr_ctrl_0: .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_0) -omap3_sdrc_actim_ctrla: +omap3_sdrc_rfr_ctrl_1: + .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_1) +omap3_sdrc_actim_ctrl_a_0: .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_0) -omap3_sdrc_actim_ctrlb: +omap3_sdrc_actim_ctrl_a_1: + .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_1) +omap3_sdrc_actim_ctrl_b_0: .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_0) +omap3_sdrc_actim_ctrl_b_1: + .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_1) +omap3_sdrc_mr_0: + .word OMAP34XX_SDRC_REGADDR(SDRC_MR_0) +omap3_sdrc_mr_1: + .word OMAP34XX_SDRC_REGADDR(SDRC_MR_1) +omap_sdrc_rfr_ctrl_0_val: + .word 0xDEADBEEF +omap_sdrc_rfr_ctrl_1_val: + .word 0xDEADBEEF +omap_sdrc_actim_ctrl_a_0_val: + .word 0xDEADBEEF +omap_sdrc_actim_ctrl_a_1_val: + .word 0xDEADBEEF +omap_sdrc_actim_ctrl_b_0_val: + .word 0xDEADBEEF +omap_sdrc_actim_ctrl_b_1_val: + .word 0xDEADBEEF +omap_sdrc_mr_0_val: + .word 0xDEADBEEF +omap_sdrc_mr_1_val: + .word 0xDEADBEEF + omap3_sdrc_dlla_status: .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS) omap3_sdrc_dlla_ctrl: .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL) core_m2_mask_val: .word 0x07FFFFFF +ENDPROC(omap3_sram_configure_core_dpll) ENTRY(omap3_sram_configure_core_dpll_sz) .word . - omap3_sram_configure_core_dpll + diff --git a/arch/arm/mach-omap2/ti81xx.h b/arch/arm/mach-omap2/ti81xx.h new file mode 100644 index 00000000000..a1e6caf0dba --- /dev/null +++ b/arch/arm/mach-omap2/ti81xx.h @@ -0,0 +1,36 @@ +/* + * This file contains the address data for various TI81XX modules. + * + * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARCH_TI81XX_H +#define __ASM_ARCH_TI81XX_H + +#define L4_SLOW_TI81XX_BASE 0x48000000 + +#define TI81XX_SCM_BASE 0x48140000 +#define TI81XX_CTRL_BASE TI81XX_SCM_BASE +#define TI81XX_PRCM_BASE 0x48180000 + +/* + * Adjust TAP register base such that omap3_check_revision accesses the correct + * TI81XX register for checking device ID (it adds 0x204 to tap base while + * TI81XX DEVICE ID register is at offset 0x600 from control base). + */ +#define TI81XX_TAP_BASE (TI81XX_CTRL_BASE + \ + TI81XX_CONTROL_DEVICE_ID - 0x204) + + +#define TI81XX_ARM_INTC_BASE 0x48200000 + +#endif /* __ASM_ARCH_TI81XX_H */ diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c deleted file mode 100644 index 9fc13a2cc3f..00000000000 --- a/arch/arm/mach-omap2/timer-gp.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/timer-gp.c - * - * OMAP2 GP timer support. - * - * Update to use new clocksource/clockevent layers - * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> - * Copyright (C) 2007 MontaVista Software, Inc. - * - * Original driver: - * Copyright (C) 2005 Nokia Corporation - * Author: Paul Mundt <paul.mundt@nokia.com> - * Juha Yrjölä <juha.yrjola@nokia.com> - * OMAP Dual-mode timer framework support by Timo Teras - * - * Some parts based off of TI's 24xx code: - * - * Copyright (C) 2004 Texas Instruments, Inc. - * - * Roughly modelled after the OMAP1 MPU timer code. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include <linux/init.h> -#include <linux/time.h> -#include <linux/interrupt.h> -#include <linux/err.h> -#include <linux/clk.h> -#include <linux/delay.h> -#include <linux/irq.h> -#include <linux/clocksource.h> -#include <linux/clockchips.h> - -#include <asm/mach/time.h> -#include <mach/dmtimer.h> - -static struct omap_dm_timer *gptimer; -static struct clock_event_device clockevent_gpt; - -static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) -{ - struct omap_dm_timer *gpt = (struct omap_dm_timer *)dev_id; - struct clock_event_device *evt = &clockevent_gpt; - - omap_dm_timer_write_status(gpt, OMAP_TIMER_INT_OVERFLOW); - - evt->event_handler(evt); - return IRQ_HANDLED; -} - -static struct irqaction omap2_gp_timer_irq = { - .name = "gp timer", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = omap2_gp_timer_interrupt, -}; - -static int omap2_gp_timer_set_next_event(unsigned long cycles, - struct clock_event_device *evt) -{ - omap_dm_timer_set_load_start(gptimer, 0, 0xffffffff - cycles); - - return 0; -} - -static void omap2_gp_timer_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - u32 period; - - omap_dm_timer_stop(gptimer); - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ; - period -= 1; - - omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - period); - break; - case CLOCK_EVT_MODE_ONESHOT: - break; - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - case CLOCK_EVT_MODE_RESUME: - break; - } -} - -static struct clock_event_device clockevent_gpt = { - .name = "gp timer", - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .shift = 32, - .set_next_event = omap2_gp_timer_set_next_event, - .set_mode = omap2_gp_timer_set_mode, -}; - -static void __init omap2_gp_clockevent_init(void) -{ - u32 tick_rate; - - gptimer = omap_dm_timer_request_specific(1); - BUG_ON(gptimer == NULL); - -#if defined(CONFIG_OMAP_32K_TIMER) - omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_32_KHZ); -#else - omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_SYS_CLK); -#endif - tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer)); - - omap2_gp_timer_irq.dev_id = (void *)gptimer; - setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq); - omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW); - - clockevent_gpt.mult = div_sc(tick_rate, NSEC_PER_SEC, - clockevent_gpt.shift); - clockevent_gpt.max_delta_ns = - clockevent_delta2ns(0xffffffff, &clockevent_gpt); - clockevent_gpt.min_delta_ns = - clockevent_delta2ns(3, &clockevent_gpt); - /* Timer internal resynch latency. */ - - clockevent_gpt.cpumask = cpumask_of(0); - clockevents_register_device(&clockevent_gpt); -} - -#ifdef CONFIG_OMAP_32K_TIMER -/* - * When 32k-timer is enabled, don't use GPTimer for clocksource - * instead, just leave default clocksource which uses the 32k - * sync counter. See clocksource setup in see plat-omap/common.c. - */ - -static inline void __init omap2_gp_clocksource_init(void) {} -#else -/* - * clocksource - */ -static struct omap_dm_timer *gpt_clocksource; -static cycle_t clocksource_read_cycles(void) -{ - return (cycle_t)omap_dm_timer_read_counter(gpt_clocksource); -} - -static struct clocksource clocksource_gpt = { - .name = "gp timer", - .rating = 300, - .read = clocksource_read_cycles, - .mask = CLOCKSOURCE_MASK(32), - .shift = 24, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -/* Setup free-running counter for clocksource */ -static void __init omap2_gp_clocksource_init(void) -{ - static struct omap_dm_timer *gpt; - u32 tick_rate, tick_period; - static char err1[] __initdata = KERN_ERR - "%s: failed to request dm-timer\n"; - static char err2[] __initdata = KERN_ERR - "%s: can't register clocksource!\n"; - - gpt = omap_dm_timer_request(); - if (!gpt) - printk(err1, clocksource_gpt.name); - gpt_clocksource = gpt; - - omap_dm_timer_set_source(gpt, OMAP_TIMER_SRC_SYS_CLK); - tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gpt)); - tick_period = (tick_rate / HZ) - 1; - - omap_dm_timer_set_load_start(gpt, 1, 0); - - clocksource_gpt.mult = - clocksource_khz2mult(tick_rate/1000, clocksource_gpt.shift); - if (clocksource_register(&clocksource_gpt)) - printk(err2, clocksource_gpt.name); -} -#endif - -static void __init omap2_gp_timer_init(void) -{ - omap_dm_timer_init(); - - omap2_gp_clockevent_init(); - omap2_gp_clocksource_init(); -} - -struct sys_timer omap_timer = { - .init = omap2_gp_timer_init, -}; diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c new file mode 100644 index 00000000000..43d03fbf4c0 --- /dev/null +++ b/arch/arm/mach-omap2/timer.c @@ -0,0 +1,770 @@ +/* + * linux/arch/arm/mach-omap2/timer.c + * + * OMAP2 GP timer support. + * + * Copyright (C) 2009 Nokia Corporation + * + * Update to use new clocksource/clockevent layers + * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> + * Copyright (C) 2007 MontaVista Software, Inc. + * + * Original driver: + * Copyright (C) 2005 Nokia Corporation + * Author: Paul Mundt <paul.mundt@nokia.com> + * Juha Yrjölä <juha.yrjola@nokia.com> + * OMAP Dual-mode timer framework support by Timo Teras + * + * Some parts based off of TI's 24xx code: + * + * Copyright (C) 2004-2009 Texas Instruments, Inc. + * + * Roughly modelled after the OMAP1 MPU timer code. + * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/time.h> +#include <linux/interrupt.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/clocksource.h> +#include <linux/clockchips.h> +#include <linux/slab.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/platform_device.h> +#include <linux/platform_data/dmtimer-omap.h> +#include <linux/sched_clock.h> + +#include <asm/mach/time.h> +#include <asm/smp_twd.h> + +#include "omap_hwmod.h" +#include "omap_device.h" +#include <plat/counter-32k.h> +#include <plat/dmtimer.h> +#include "omap-pm.h" + +#include "soc.h" +#include "common.h" +#include "powerdomain.h" +#include "omap-secure.h" + +#define REALTIME_COUNTER_BASE 0x48243200 +#define INCREMENTER_NUMERATOR_OFFSET 0x10 +#define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14 +#define NUMERATOR_DENUMERATOR_MASK 0xfffff000 + +/* Clockevent code */ + +static struct omap_dm_timer clkev; +static struct clock_event_device clockevent_gpt; + +#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER +static unsigned long arch_timer_freq; + +void set_cntfreq(void) +{ + omap_smc1(OMAP5_DRA7_MON_SET_CNTFRQ_INDEX, arch_timer_freq); +} +#endif + +static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = &clockevent_gpt; + + __omap_dm_timer_write_status(&clkev, OMAP_TIMER_INT_OVERFLOW); + + evt->event_handler(evt); + return IRQ_HANDLED; +} + +static struct irqaction omap2_gp_timer_irq = { + .name = "gp_timer", + .flags = IRQF_TIMER | IRQF_IRQPOLL, + .handler = omap2_gp_timer_interrupt, +}; + +static int omap2_gp_timer_set_next_event(unsigned long cycles, + struct clock_event_device *evt) +{ + __omap_dm_timer_load_start(&clkev, OMAP_TIMER_CTRL_ST, + 0xffffffff - cycles, OMAP_TIMER_POSTED); + + return 0; +} + +static void omap2_gp_timer_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + u32 period; + + __omap_dm_timer_stop(&clkev, OMAP_TIMER_POSTED, clkev.rate); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + period = clkev.rate / HZ; + period -= 1; + /* Looks like we need to first set the load value separately */ + __omap_dm_timer_write(&clkev, OMAP_TIMER_LOAD_REG, + 0xffffffff - period, OMAP_TIMER_POSTED); + __omap_dm_timer_load_start(&clkev, + OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST, + 0xffffffff - period, OMAP_TIMER_POSTED); + break; + case CLOCK_EVT_MODE_ONESHOT: + break; + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_RESUME: + break; + } +} + +static struct clock_event_device clockevent_gpt = { + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .rating = 300, + .set_next_event = omap2_gp_timer_set_next_event, + .set_mode = omap2_gp_timer_set_mode, +}; + +static struct property device_disabled = { + .name = "status", + .length = sizeof("disabled"), + .value = "disabled", +}; + +static struct of_device_id omap_timer_match[] __initdata = { + { .compatible = "ti,omap2420-timer", }, + { .compatible = "ti,omap3430-timer", }, + { .compatible = "ti,omap4430-timer", }, + { .compatible = "ti,omap5430-timer", }, + { .compatible = "ti,am335x-timer", }, + { .compatible = "ti,am335x-timer-1ms", }, + { } +}; + +/** + * omap_get_timer_dt - get a timer using device-tree + * @match - device-tree match structure for matching a device type + * @property - optional timer property to match + * + * Helper function to get a timer during early boot using device-tree for use + * as kernel system timer. Optionally, the property argument can be used to + * select a timer with a specific property. Once a timer is found then mark + * the timer node in device-tree as disabled, to prevent the kernel from + * registering this timer as a platform device and so no one else can use it. + */ +static struct device_node * __init omap_get_timer_dt(struct of_device_id *match, + const char *property) +{ + struct device_node *np; + + for_each_matching_node(np, match) { + if (!of_device_is_available(np)) + continue; + + if (property && !of_get_property(np, property, NULL)) + continue; + + if (!property && (of_get_property(np, "ti,timer-alwon", NULL) || + of_get_property(np, "ti,timer-dsp", NULL) || + of_get_property(np, "ti,timer-pwm", NULL) || + of_get_property(np, "ti,timer-secure", NULL))) + continue; + + of_add_property(np, &device_disabled); + return np; + } + + return NULL; +} + +/** + * omap_dmtimer_init - initialisation function when device tree is used + * + * For secure OMAP3 devices, timers with device type "timer-secure" cannot + * be used by the kernel as they are reserved. Therefore, to prevent the + * kernel registering these devices remove them dynamically from the device + * tree on boot. + */ +static void __init omap_dmtimer_init(void) +{ + struct device_node *np; + + if (!cpu_is_omap34xx()) + return; + + /* If we are a secure device, remove any secure timer nodes */ + if ((omap_type() != OMAP2_DEVICE_TYPE_GP)) { + np = omap_get_timer_dt(omap_timer_match, "ti,timer-secure"); + if (np) + of_node_put(np); + } +} + +/** + * omap_dm_timer_get_errata - get errata flags for a timer + * + * Get the timer errata flags that are specific to the OMAP device being used. + */ +static u32 __init omap_dm_timer_get_errata(void) +{ + if (cpu_is_omap24xx()) + return 0; + + return OMAP_TIMER_ERRATA_I103_I767; +} + +static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, + const char *fck_source, + const char *property, + const char **timer_name, + int posted) +{ + char name[10]; /* 10 = sizeof("gptXX_Xck0") */ + const char *oh_name = NULL; + struct device_node *np; + struct omap_hwmod *oh; + struct resource irq, mem; + struct clk *src; + int r = 0; + + if (of_have_populated_dt()) { + np = omap_get_timer_dt(omap_timer_match, property); + if (!np) + return -ENODEV; + + of_property_read_string_index(np, "ti,hwmods", 0, &oh_name); + if (!oh_name) + return -ENODEV; + + timer->irq = irq_of_parse_and_map(np, 0); + if (!timer->irq) + return -ENXIO; + + timer->io_base = of_iomap(np, 0); + + of_node_put(np); + } else { + if (omap_dm_timer_reserve_systimer(timer->id)) + return -ENODEV; + + sprintf(name, "timer%d", timer->id); + oh_name = name; + } + + oh = omap_hwmod_lookup(oh_name); + if (!oh) + return -ENODEV; + + *timer_name = oh->name; + + if (!of_have_populated_dt()) { + r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL, + &irq); + if (r) + return -ENXIO; + timer->irq = irq.start; + + r = omap_hwmod_get_resource_byname(oh, IORESOURCE_MEM, NULL, + &mem); + if (r) + return -ENXIO; + + /* Static mapping, never released */ + timer->io_base = ioremap(mem.start, mem.end - mem.start); + } + + if (!timer->io_base) + return -ENXIO; + + /* After the dmtimer is using hwmod these clocks won't be needed */ + timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); + if (IS_ERR(timer->fclk)) + return PTR_ERR(timer->fclk); + + src = clk_get(NULL, fck_source); + if (IS_ERR(src)) + return PTR_ERR(src); + + if (clk_get_parent(timer->fclk) != src) { + r = clk_set_parent(timer->fclk, src); + if (r < 0) { + pr_warn("%s: %s cannot set source\n", __func__, + oh->name); + clk_put(src); + return r; + } + } + + clk_put(src); + + omap_hwmod_setup_one(oh_name); + omap_hwmod_enable(oh); + __omap_dm_timer_init_regs(timer); + + if (posted) + __omap_dm_timer_enable_posted(timer); + + /* Check that the intended posted configuration matches the actual */ + if (posted != timer->posted) + return -EINVAL; + + timer->rate = clk_get_rate(timer->fclk); + timer->reserved = 1; + + return r; +} + +static void __init omap2_gp_clockevent_init(int gptimer_id, + const char *fck_source, + const char *property) +{ + int res; + + clkev.id = gptimer_id; + clkev.errata = omap_dm_timer_get_errata(); + + /* + * For clock-event timers we never read the timer counter and + * so we are not impacted by errata i103 and i767. Therefore, + * we can safely ignore this errata for clock-event timers. + */ + __omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767); + + res = omap_dm_timer_init_one(&clkev, fck_source, property, + &clockevent_gpt.name, OMAP_TIMER_POSTED); + BUG_ON(res); + + omap2_gp_timer_irq.dev_id = &clkev; + setup_irq(clkev.irq, &omap2_gp_timer_irq); + + __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW); + + clockevent_gpt.cpumask = cpu_possible_mask; + clockevent_gpt.irq = omap_dm_timer_get_irq(&clkev); + clockevents_config_and_register(&clockevent_gpt, clkev.rate, + 3, /* Timer internal resynch latency */ + 0xffffffff); + + pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name, + clkev.rate); +} + +/* Clocksource code */ +static struct omap_dm_timer clksrc; +static bool use_gptimer_clksrc __initdata; + +/* + * clocksource + */ +static cycle_t clocksource_read_cycles(struct clocksource *cs) +{ + return (cycle_t)__omap_dm_timer_read_counter(&clksrc, + OMAP_TIMER_NONPOSTED); +} + +static struct clocksource clocksource_gpt = { + .rating = 300, + .read = clocksource_read_cycles, + .mask = CLOCKSOURCE_MASK(32), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static u64 notrace dmtimer_read_sched_clock(void) +{ + if (clksrc.reserved) + return __omap_dm_timer_read_counter(&clksrc, + OMAP_TIMER_NONPOSTED); + + return 0; +} + +static struct of_device_id omap_counter_match[] __initdata = { + { .compatible = "ti,omap-counter32k", }, + { } +}; + +/* Setup free-running counter for clocksource */ +static int __init __maybe_unused omap2_sync32k_clocksource_init(void) +{ + int ret; + struct device_node *np = NULL; + struct omap_hwmod *oh; + void __iomem *vbase; + const char *oh_name = "counter_32k"; + + /* + * If device-tree is present, then search the DT blob + * to see if the 32kHz counter is supported. + */ + if (of_have_populated_dt()) { + np = omap_get_timer_dt(omap_counter_match, NULL); + if (!np) + return -ENODEV; + + of_property_read_string_index(np, "ti,hwmods", 0, &oh_name); + if (!oh_name) + return -ENODEV; + } + + /* + * First check hwmod data is available for sync32k counter + */ + oh = omap_hwmod_lookup(oh_name); + if (!oh || oh->slaves_cnt == 0) + return -ENODEV; + + omap_hwmod_setup_one(oh_name); + + if (np) { + vbase = of_iomap(np, 0); + of_node_put(np); + } else { + vbase = omap_hwmod_get_mpu_rt_va(oh); + } + + if (!vbase) { + pr_warn("%s: failed to get counter_32k resource\n", __func__); + return -ENXIO; + } + + ret = omap_hwmod_enable(oh); + if (ret) { + pr_warn("%s: failed to enable counter_32k module (%d)\n", + __func__, ret); + return ret; + } + + ret = omap_init_clocksource_32k(vbase); + if (ret) { + pr_warn("%s: failed to initialize counter_32k as a clocksource (%d)\n", + __func__, ret); + omap_hwmod_idle(oh); + } + + return ret; +} + +static void __init omap2_gptimer_clocksource_init(int gptimer_id, + const char *fck_source, + const char *property) +{ + int res; + + clksrc.id = gptimer_id; + clksrc.errata = omap_dm_timer_get_errata(); + + res = omap_dm_timer_init_one(&clksrc, fck_source, property, + &clocksource_gpt.name, + OMAP_TIMER_NONPOSTED); + BUG_ON(res); + + __omap_dm_timer_load_start(&clksrc, + OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, + OMAP_TIMER_NONPOSTED); + sched_clock_register(dmtimer_read_sched_clock, 32, clksrc.rate); + + if (clocksource_register_hz(&clocksource_gpt, clksrc.rate)) + pr_err("Could not register clocksource %s\n", + clocksource_gpt.name); + else + pr_info("OMAP clocksource: %s at %lu Hz\n", + clocksource_gpt.name, clksrc.rate); +} + +#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER +/* + * The realtime counter also called master counter, is a free-running + * counter, which is related to real time. It produces the count used + * by the CPU local timer peripherals in the MPU cluster. The timer counts + * at a rate of 6.144 MHz. Because the device operates on different clocks + * in different power modes, the master counter shifts operation between + * clocks, adjusting the increment per clock in hardware accordingly to + * maintain a constant count rate. + */ +static void __init realtime_counter_init(void) +{ + void __iomem *base; + static struct clk *sys_clk; + unsigned long rate; + unsigned int reg, num, den; + + base = ioremap(REALTIME_COUNTER_BASE, SZ_32); + if (!base) { + pr_err("%s: ioremap failed\n", __func__); + return; + } + sys_clk = clk_get(NULL, "sys_clkin"); + if (IS_ERR(sys_clk)) { + pr_err("%s: failed to get system clock handle\n", __func__); + iounmap(base); + return; + } + + rate = clk_get_rate(sys_clk); + /* Numerator/denumerator values refer TRM Realtime Counter section */ + switch (rate) { + case 1200000: + num = 64; + den = 125; + break; + case 1300000: + num = 768; + den = 1625; + break; + case 19200000: + num = 8; + den = 25; + break; + case 20000000: + num = 192; + den = 625; + break; + case 2600000: + num = 384; + den = 1625; + break; + case 2700000: + num = 256; + den = 1125; + break; + case 38400000: + default: + /* Program it for 38.4 MHz */ + num = 4; + den = 25; + break; + } + + /* Program numerator and denumerator registers */ + reg = readl_relaxed(base + INCREMENTER_NUMERATOR_OFFSET) & + NUMERATOR_DENUMERATOR_MASK; + reg |= num; + writel_relaxed(reg, base + INCREMENTER_NUMERATOR_OFFSET); + + reg = readl_relaxed(base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET) & + NUMERATOR_DENUMERATOR_MASK; + reg |= den; + writel_relaxed(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET); + + arch_timer_freq = (rate / den) * num; + set_cntfreq(); + + iounmap(base); +} +#else +static inline void __init realtime_counter_init(void) +{} +#endif + +#define OMAP_SYS_GP_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ + clksrc_nr, clksrc_src, clksrc_prop) \ +void __init omap##name##_gptimer_timer_init(void) \ +{ \ + omap_clk_init(); \ + omap_dmtimer_init(); \ + omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ + omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src, \ + clksrc_prop); \ +} + +#define OMAP_SYS_32K_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ + clksrc_nr, clksrc_src, clksrc_prop) \ +void __init omap##name##_sync32k_timer_init(void) \ +{ \ + omap_clk_init(); \ + omap_dmtimer_init(); \ + omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ + /* Enable the use of clocksource="gp_timer" kernel parameter */ \ + if (use_gptimer_clksrc) \ + omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src, \ + clksrc_prop); \ + else \ + omap2_sync32k_clocksource_init(); \ +} + +#ifdef CONFIG_ARCH_OMAP2 +OMAP_SYS_32K_TIMER_INIT(2, 1, "timer_32k_ck", "ti,timer-alwon", + 2, "timer_sys_ck", NULL); +#endif /* CONFIG_ARCH_OMAP2 */ + +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM43XX) +OMAP_SYS_32K_TIMER_INIT(3, 1, "timer_32k_ck", "ti,timer-alwon", + 2, "timer_sys_ck", NULL); +OMAP_SYS_32K_TIMER_INIT(3_secure, 12, "secure_32k_fck", "ti,timer-secure", + 2, "timer_sys_ck", NULL); +#endif /* CONFIG_ARCH_OMAP3 */ + +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) || \ + defined(CONFIG_SOC_AM43XX) +OMAP_SYS_GP_TIMER_INIT(3, 2, "timer_sys_ck", NULL, + 1, "timer_sys_ck", "ti,timer-alwon"); +#endif + +#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ + defined(CONFIG_SOC_DRA7XX) +static OMAP_SYS_32K_TIMER_INIT(4, 1, "timer_32k_ck", "ti,timer-alwon", + 2, "sys_clkin_ck", NULL); +#endif + +#ifdef CONFIG_ARCH_OMAP4 +#ifdef CONFIG_HAVE_ARM_TWD +static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, OMAP44XX_LOCAL_TWD_BASE, 29); +void __init omap4_local_timer_init(void) +{ + omap4_sync32k_timer_init(); + /* Local timers are not supprted on OMAP4430 ES1.0 */ + if (omap_rev() != OMAP4430_REV_ES1_0) { + int err; + + if (of_have_populated_dt()) { + clocksource_of_init(); + return; + } + + err = twd_local_timer_register(&twd_local_timer); + if (err) + pr_err("twd_local_timer_register failed %d\n", err); + } +} +#else +void __init omap4_local_timer_init(void) +{ + omap4_sync32k_timer_init(); +} +#endif /* CONFIG_HAVE_ARM_TWD */ +#endif /* CONFIG_ARCH_OMAP4 */ + +#if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) +void __init omap5_realtime_timer_init(void) +{ + omap4_sync32k_timer_init(); + realtime_counter_init(); + + clocksource_of_init(); +} +#endif /* CONFIG_SOC_OMAP5 || CONFIG_SOC_DRA7XX */ + +/** + * omap_timer_init - build and register timer device with an + * associated timer hwmod + * @oh: timer hwmod pointer to be used to build timer device + * @user: parameter that can be passed from calling hwmod API + * + * Called by omap_hwmod_for_each_by_class to register each of the timer + * devices present in the system. The number of timer devices is known + * by parsing through the hwmod database for a given class name. At the + * end of function call memory is allocated for timer device and it is + * registered to the framework ready to be proved by the driver. + */ +static int __init omap_timer_init(struct omap_hwmod *oh, void *unused) +{ + int id; + int ret = 0; + char *name = "omap_timer"; + struct dmtimer_platform_data *pdata; + struct platform_device *pdev; + struct omap_timer_capability_dev_attr *timer_dev_attr; + + pr_debug("%s: %s\n", __func__, oh->name); + + /* on secure device, do not register secure timer */ + timer_dev_attr = oh->dev_attr; + if (omap_type() != OMAP2_DEVICE_TYPE_GP && timer_dev_attr) + if (timer_dev_attr->timer_capability == OMAP_TIMER_SECURE) + return ret; + + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + pr_err("%s: No memory for [%s]\n", __func__, oh->name); + return -ENOMEM; + } + + /* + * Extract the IDs from name field in hwmod database + * and use the same for constructing ids' for the + * timer devices. In a way, we are avoiding usage of + * static variable witin the function to do the same. + * CAUTION: We have to be careful and make sure the + * name in hwmod database does not change in which case + * we might either make corresponding change here or + * switch back static variable mechanism. + */ + sscanf(oh->name, "timer%2d", &id); + + if (timer_dev_attr) + pdata->timer_capability = timer_dev_attr->timer_capability; + + pdata->timer_errata = omap_dm_timer_get_errata(); + pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count; + + pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata)); + + if (IS_ERR(pdev)) { + pr_err("%s: Can't build omap_device for %s: %s.\n", + __func__, name, oh->name); + ret = -EINVAL; + } + + kfree(pdata); + + return ret; +} + +/** + * omap2_dm_timer_init - top level regular device initialization + * + * Uses dedicated hwmod api to parse through hwmod database for + * given class name and then build and register the timer device. + */ +static int __init omap2_dm_timer_init(void) +{ + int ret; + + /* If dtb is there, the devices will be created dynamically */ + if (of_have_populated_dt()) + return -ENODEV; + + ret = omap_hwmod_for_each_by_class("timer", omap_timer_init, NULL); + if (unlikely(ret)) { + pr_err("%s: device registration failed.\n", __func__); + return -EINVAL; + } + + return 0; +} +omap_arch_initcall(omap2_dm_timer_init); + +/** + * omap2_override_clocksource - clocksource override with user configuration + * + * Allows user to override default clocksource, using kernel parameter + * clocksource="gp_timer" (For all OMAP2PLUS architectures) + * + * Note that, here we are using same standard kernel parameter "clocksource=", + * and not introducing any OMAP specific interface. + */ +static int __init omap2_override_clocksource(char *str) +{ + if (!str) + return 0; + /* + * For OMAP architecture, we only have two options + * - sync_32k (default) + * - gp_timer (sys_clk based) + */ + if (!strcmp(str, "gp_timer")) + use_gptimer_clksrc = true; + + return 0; +} +early_param("clocksource", omap2_override_clocksource); diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c new file mode 100644 index 00000000000..b0d54dae1bc --- /dev/null +++ b/arch/arm/mach-omap2/twl-common.c @@ -0,0 +1,570 @@ +/* + * twl-common.c + * + * Copyright (C) 2011 Texas Instruments, Inc.. + * Author: Peter Ujfalusi <peter.ujfalusi@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include <linux/i2c.h> +#include <linux/i2c/twl.h> +#include <linux/gpio.h> +#include <linux/string.h> +#include <linux/phy/phy.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/fixed.h> + +#include "soc.h" +#include "twl-common.h" +#include "pm.h" +#include "voltage.h" +#include "mux.h" + +static struct i2c_board_info __initdata pmic_i2c_board_info = { + .addr = 0x48, + .flags = I2C_CLIENT_WAKE, +}; + +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) +static int twl_set_voltage(void *data, int target_uV) +{ + struct voltagedomain *voltdm = (struct voltagedomain *)data; + return voltdm_scale(voltdm, target_uV); +} + +static int twl_get_voltage(void *data) +{ + struct voltagedomain *voltdm = (struct voltagedomain *)data; + return voltdm_get_voltage(voltdm); +} +#endif + +void __init omap_pmic_init(int bus, u32 clkrate, + const char *pmic_type, int pmic_irq, + struct twl4030_platform_data *pmic_data) +{ + omap_mux_init_signal("sys_nirq", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE); + strlcpy(pmic_i2c_board_info.type, pmic_type, + sizeof(pmic_i2c_board_info.type)); + pmic_i2c_board_info.irq = pmic_irq; + pmic_i2c_board_info.platform_data = pmic_data; + + omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1); +} + +void __init omap4_pmic_init(const char *pmic_type, + struct twl4030_platform_data *pmic_data, + struct i2c_board_info *devices, int nr_devices) +{ + /* PMIC part*/ + omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE); + omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT); + omap_pmic_init(1, 400, pmic_type, 7 + OMAP44XX_IRQ_GIC_START, pmic_data); + + /* Register additional devices on i2c1 bus if needed */ + if (devices) + i2c_register_board_info(1, devices, nr_devices); +} + +void __init omap_pmic_late_init(void) +{ + /* Init the OMAP TWL parameters (if PMIC has been registerd) */ + if (!pmic_i2c_board_info.irq) + return; + + omap3_twl_init(); + omap4_twl_init(); +} + +#if defined(CONFIG_ARCH_OMAP3) +struct phy_consumer consumers[] = { + PHY_CONSUMER("musb-hdrc.0", "usb"), +}; + +struct phy_init_data init_data = { + .consumers = consumers, + .num_consumers = ARRAY_SIZE(consumers), +}; + +static struct twl4030_usb_data omap3_usb_pdata = { + .usb_mode = T2_USB_MODE_ULPI, + .init_data = &init_data, +}; + +static int omap3_batt_table[] = { +/* 0 C */ +30800, 29500, 28300, 27100, +26000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, 17900, +17200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, 12600, 12100, +11600, 11200, 10800, 10400, 10000, 9630, 9280, 8950, 8620, 8310, +8020, 7730, 7460, 7200, 6950, 6710, 6470, 6250, 6040, 5830, +5640, 5450, 5260, 5090, 4920, 4760, 4600, 4450, 4310, 4170, +4040, 3910, 3790, 3670, 3550 +}; + +static struct twl4030_bci_platform_data omap3_bci_pdata = { + .battery_tmp_tbl = omap3_batt_table, + .tblsize = ARRAY_SIZE(omap3_batt_table), +}; + +static struct twl4030_madc_platform_data omap3_madc_pdata = { + .irq_line = 1, +}; + +static struct twl4030_codec_data omap3_codec; + +static struct twl4030_audio_data omap3_audio_pdata = { + .audio_mclk = 26000000, + .codec = &omap3_codec, +}; + +static struct regulator_consumer_supply omap3_vdda_dac_supplies[] = { + REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"), +}; + +static struct regulator_init_data omap3_vdac_idata = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(omap3_vdda_dac_supplies), + .consumer_supplies = omap3_vdda_dac_supplies, +}; + +static struct regulator_consumer_supply omap3_vpll2_supplies[] = { + REGULATOR_SUPPLY("vdds_dsi", "omapdss"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dpi.0"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"), +}; + +static struct regulator_init_data omap3_vpll2_idata = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(omap3_vpll2_supplies), + .consumer_supplies = omap3_vpll2_supplies, +}; + +static struct regulator_consumer_supply omap3_vdd1_supply[] = { + REGULATOR_SUPPLY("vcc", "cpu0"), +}; + +static struct regulator_consumer_supply omap3_vdd2_supply[] = { + REGULATOR_SUPPLY("vcc", "l3_main.0"), +}; + +static struct regulator_init_data omap3_vdd1 = { + .constraints = { + .name = "vdd_mpu_iva", + .min_uV = 600000, + .max_uV = 1450000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = ARRAY_SIZE(omap3_vdd1_supply), + .consumer_supplies = omap3_vdd1_supply, +}; + +static struct regulator_init_data omap3_vdd2 = { + .constraints = { + .name = "vdd_core", + .min_uV = 600000, + .max_uV = 1450000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = ARRAY_SIZE(omap3_vdd2_supply), + .consumer_supplies = omap3_vdd2_supply, +}; + +static struct twl_regulator_driver_data omap3_vdd1_drvdata = { + .get_voltage = twl_get_voltage, + .set_voltage = twl_set_voltage, +}; + +static struct twl_regulator_driver_data omap3_vdd2_drvdata = { + .get_voltage = twl_get_voltage, + .set_voltage = twl_set_voltage, +}; + +void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data, + u32 pdata_flags, u32 regulators_flags) +{ + if (!pmic_data->vdd1) { + omap3_vdd1.driver_data = &omap3_vdd1_drvdata; + omap3_vdd1_drvdata.data = voltdm_lookup("mpu_iva"); + pmic_data->vdd1 = &omap3_vdd1; + } + if (!pmic_data->vdd2) { + omap3_vdd2.driver_data = &omap3_vdd2_drvdata; + omap3_vdd2_drvdata.data = voltdm_lookup("core"); + pmic_data->vdd2 = &omap3_vdd2; + } + + /* Common platform data configurations */ + if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb) + pmic_data->usb = &omap3_usb_pdata; + + if (pdata_flags & TWL_COMMON_PDATA_BCI && !pmic_data->bci) + pmic_data->bci = &omap3_bci_pdata; + + if (pdata_flags & TWL_COMMON_PDATA_MADC && !pmic_data->madc) + pmic_data->madc = &omap3_madc_pdata; + + if (pdata_flags & TWL_COMMON_PDATA_AUDIO && !pmic_data->audio) + pmic_data->audio = &omap3_audio_pdata; + + /* Common regulator configurations */ + if (regulators_flags & TWL_COMMON_REGULATOR_VDAC && !pmic_data->vdac) + pmic_data->vdac = &omap3_vdac_idata; + + if (regulators_flags & TWL_COMMON_REGULATOR_VPLL2 && !pmic_data->vpll2) + pmic_data->vpll2 = &omap3_vpll2_idata; +} +#endif /* CONFIG_ARCH_OMAP3 */ + +#if defined(CONFIG_ARCH_OMAP4) +static struct twl4030_usb_data omap4_usb_pdata = { +}; + +static struct regulator_consumer_supply omap4_vdda_hdmi_dac_supplies[] = { + REGULATOR_SUPPLY("vdda_hdmi_dac", "omapdss_hdmi"), +}; + +static struct regulator_init_data omap4_vdac_idata = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(omap4_vdda_hdmi_dac_supplies), + .consumer_supplies = omap4_vdda_hdmi_dac_supplies, + .supply_regulator = "V2V1", +}; + +static struct regulator_init_data omap4_vaux2_idata = { + .constraints = { + .min_uV = 1200000, + .max_uV = 2800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data omap4_vaux3_idata = { + .constraints = { + .min_uV = 1000000, + .max_uV = 3000000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_consumer_supply omap4_vmmc_supply[] = { + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), +}; + +/* VMMC1 for MMC1 card */ +static struct regulator_init_data omap4_vmmc_idata = { + .constraints = { + .min_uV = 1200000, + .max_uV = 3000000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(omap4_vmmc_supply), + .consumer_supplies = omap4_vmmc_supply, +}; + +static struct regulator_init_data omap4_vpp_idata = { + .constraints = { + .min_uV = 1800000, + .max_uV = 2500000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data omap4_vana_idata = { + .constraints = { + .min_uV = 2100000, + .max_uV = 2100000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_consumer_supply omap4_vcxio_supply[] = { + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"), + REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.1"), +}; + +static struct regulator_init_data omap4_vcxio_idata = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + .always_on = true, + }, + .num_consumer_supplies = ARRAY_SIZE(omap4_vcxio_supply), + .consumer_supplies = omap4_vcxio_supply, + .supply_regulator = "V2V1", +}; + +static struct regulator_init_data omap4_vusb_idata = { + .constraints = { + .min_uV = 3300000, + .max_uV = 3300000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data omap4_clk32kg_idata = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_consumer_supply omap4_vdd1_supply[] = { + REGULATOR_SUPPLY("vcc", "cpu0"), +}; + +static struct regulator_consumer_supply omap4_vdd2_supply[] = { + REGULATOR_SUPPLY("vcc", "iva.0"), +}; + +static struct regulator_consumer_supply omap4_vdd3_supply[] = { + REGULATOR_SUPPLY("vcc", "l3_main.0"), +}; + +static struct regulator_init_data omap4_vdd1 = { + .constraints = { + .name = "vdd_mpu", + .min_uV = 500000, + .max_uV = 1500000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = ARRAY_SIZE(omap4_vdd1_supply), + .consumer_supplies = omap4_vdd1_supply, +}; + +static struct regulator_init_data omap4_vdd2 = { + .constraints = { + .name = "vdd_iva", + .min_uV = 500000, + .max_uV = 1500000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = ARRAY_SIZE(omap4_vdd2_supply), + .consumer_supplies = omap4_vdd2_supply, +}; + +static struct regulator_init_data omap4_vdd3 = { + .constraints = { + .name = "vdd_core", + .min_uV = 500000, + .max_uV = 1500000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = ARRAY_SIZE(omap4_vdd3_supply), + .consumer_supplies = omap4_vdd3_supply, +}; + + +static struct twl_regulator_driver_data omap4_vdd1_drvdata = { + .get_voltage = twl_get_voltage, + .set_voltage = twl_set_voltage, +}; + +static struct twl_regulator_driver_data omap4_vdd2_drvdata = { + .get_voltage = twl_get_voltage, + .set_voltage = twl_set_voltage, +}; + +static struct twl_regulator_driver_data omap4_vdd3_drvdata = { + .get_voltage = twl_get_voltage, + .set_voltage = twl_set_voltage, +}; + +static struct regulator_consumer_supply omap4_v1v8_supply[] = { + REGULATOR_SUPPLY("vio", "1-004b"), +}; + +static struct regulator_init_data omap4_v1v8_idata = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + .always_on = true, + }, + .num_consumer_supplies = ARRAY_SIZE(omap4_v1v8_supply), + .consumer_supplies = omap4_v1v8_supply, +}; + +static struct regulator_consumer_supply omap4_v2v1_supply[] = { + REGULATOR_SUPPLY("v2v1", "1-004b"), +}; + +static struct regulator_init_data omap4_v2v1_idata = { + .constraints = { + .min_uV = 2100000, + .max_uV = 2100000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(omap4_v2v1_supply), + .consumer_supplies = omap4_v2v1_supply, +}; + +void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data, + u32 pdata_flags, u32 regulators_flags) +{ + if (!pmic_data->vdd1) { + omap4_vdd1.driver_data = &omap4_vdd1_drvdata; + omap4_vdd1_drvdata.data = voltdm_lookup("mpu"); + pmic_data->vdd1 = &omap4_vdd1; + } + + if (!pmic_data->vdd2) { + omap4_vdd2.driver_data = &omap4_vdd2_drvdata; + omap4_vdd2_drvdata.data = voltdm_lookup("iva"); + pmic_data->vdd2 = &omap4_vdd2; + } + + if (!pmic_data->vdd3) { + omap4_vdd3.driver_data = &omap4_vdd3_drvdata; + omap4_vdd3_drvdata.data = voltdm_lookup("core"); + pmic_data->vdd3 = &omap4_vdd3; + } + + /* Common platform data configurations */ + if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb) + pmic_data->usb = &omap4_usb_pdata; + + /* Common regulator configurations */ + if (regulators_flags & TWL_COMMON_REGULATOR_VDAC && !pmic_data->vdac) + pmic_data->vdac = &omap4_vdac_idata; + + if (regulators_flags & TWL_COMMON_REGULATOR_VAUX2 && !pmic_data->vaux2) + pmic_data->vaux2 = &omap4_vaux2_idata; + + if (regulators_flags & TWL_COMMON_REGULATOR_VAUX3 && !pmic_data->vaux3) + pmic_data->vaux3 = &omap4_vaux3_idata; + + if (regulators_flags & TWL_COMMON_REGULATOR_VMMC && !pmic_data->vmmc) + pmic_data->vmmc = &omap4_vmmc_idata; + + if (regulators_flags & TWL_COMMON_REGULATOR_VPP && !pmic_data->vpp) + pmic_data->vpp = &omap4_vpp_idata; + + if (regulators_flags & TWL_COMMON_REGULATOR_VANA && !pmic_data->vana) + pmic_data->vana = &omap4_vana_idata; + + if (regulators_flags & TWL_COMMON_REGULATOR_VCXIO && !pmic_data->vcxio) + pmic_data->vcxio = &omap4_vcxio_idata; + + if (regulators_flags & TWL_COMMON_REGULATOR_VUSB && !pmic_data->vusb) + pmic_data->vusb = &omap4_vusb_idata; + + if (regulators_flags & TWL_COMMON_REGULATOR_CLK32KG && + !pmic_data->clk32kg) + pmic_data->clk32kg = &omap4_clk32kg_idata; + + if (regulators_flags & TWL_COMMON_REGULATOR_V1V8 && !pmic_data->v1v8) + pmic_data->v1v8 = &omap4_v1v8_idata; + + if (regulators_flags & TWL_COMMON_REGULATOR_V2V1 && !pmic_data->v2v1) + pmic_data->v2v1 = &omap4_v2v1_idata; +} +#endif /* CONFIG_ARCH_OMAP4 */ + +#if defined(CONFIG_SND_OMAP_SOC_OMAP_TWL4030) || \ + defined(CONFIG_SND_OMAP_SOC_OMAP_TWL4030_MODULE) +#include <linux/platform_data/omap-twl4030.h> + +/* Commonly used configuration */ +static struct omap_tw4030_pdata omap_twl4030_audio_data; + +static struct platform_device audio_device = { + .name = "omap-twl4030", + .id = -1, +}; + +void omap_twl4030_audio_init(char *card_name, + struct omap_tw4030_pdata *pdata) +{ + if (!pdata) + pdata = &omap_twl4030_audio_data; + + pdata->card_name = card_name; + + audio_device.dev.platform_data = pdata; + platform_device_register(&audio_device); +} + +#else /* SOC_OMAP_TWL4030 */ +void omap_twl4030_audio_init(char *card_name, + struct omap_tw4030_pdata *pdata) +{ + return; +} +#endif /* SOC_OMAP_TWL4030 */ diff --git a/arch/arm/mach-omap2/twl-common.h b/arch/arm/mach-omap2/twl-common.h new file mode 100644 index 00000000000..24b65d081b6 --- /dev/null +++ b/arch/arm/mach-omap2/twl-common.h @@ -0,0 +1,66 @@ +#ifndef __OMAP_PMIC_COMMON__ +#define __OMAP_PMIC_COMMON__ + +#include "common.h" + +#define TWL_COMMON_PDATA_USB (1 << 0) +#define TWL_COMMON_PDATA_BCI (1 << 1) +#define TWL_COMMON_PDATA_MADC (1 << 2) +#define TWL_COMMON_PDATA_AUDIO (1 << 3) + +/* Common LDO regulators for TWL4030/TWL6030 */ +#define TWL_COMMON_REGULATOR_VDAC (1 << 0) +#define TWL_COMMON_REGULATOR_VAUX1 (1 << 1) +#define TWL_COMMON_REGULATOR_VAUX2 (1 << 2) +#define TWL_COMMON_REGULATOR_VAUX3 (1 << 3) + +/* TWL6030 LDO regulators */ +#define TWL_COMMON_REGULATOR_VMMC (1 << 4) +#define TWL_COMMON_REGULATOR_VPP (1 << 5) +#define TWL_COMMON_REGULATOR_VUSIM (1 << 6) +#define TWL_COMMON_REGULATOR_VANA (1 << 7) +#define TWL_COMMON_REGULATOR_VCXIO (1 << 8) +#define TWL_COMMON_REGULATOR_VUSB (1 << 9) +#define TWL_COMMON_REGULATOR_CLK32KG (1 << 10) +#define TWL_COMMON_REGULATOR_V1V8 (1 << 11) +#define TWL_COMMON_REGULATOR_V2V1 (1 << 12) + +/* TWL4030 LDO regulators */ +#define TWL_COMMON_REGULATOR_VPLL1 (1 << 4) +#define TWL_COMMON_REGULATOR_VPLL2 (1 << 5) + + +struct twl4030_platform_data; +struct twl6040_platform_data; +struct omap_tw4030_pdata; +struct i2c_board_info; + +void omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq, + struct twl4030_platform_data *pmic_data); +void omap_pmic_late_init(void); + +static inline void omap2_pmic_init(const char *pmic_type, + struct twl4030_platform_data *pmic_data) +{ + omap_pmic_init(2, 2600, pmic_type, 7 + OMAP_INTC_START, pmic_data); +} + +static inline void omap3_pmic_init(const char *pmic_type, + struct twl4030_platform_data *pmic_data) +{ + omap_pmic_init(1, 2600, pmic_type, 7 + OMAP_INTC_START, pmic_data); +} + +void omap4_pmic_init(const char *pmic_type, + struct twl4030_platform_data *pmic_data, + struct i2c_board_info *devices, int nr_devices); + +void omap3_pmic_get_config(struct twl4030_platform_data *pmic_data, + u32 pdata_flags, u32 regulators_flags); + +void omap4_pmic_get_config(struct twl4030_platform_data *pmic_data, + u32 pdata_flags, u32 regulators_flags); + +void omap_twl4030_audio_init(char *card_name, struct omap_tw4030_pdata *pdata); + +#endif /* __OMAP_PMIC_COMMON__ */ diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c new file mode 100644 index 00000000000..745367c0c2b --- /dev/null +++ b/arch/arm/mach-omap2/usb-host.c @@ -0,0 +1,496 @@ +/* + * usb-host.c - OMAP USB Host + * + * This file will contain the board specific details for the + * Synopsys EHCI/OHCI host controller on OMAP3430 and onwards + * + * Copyright (C) 2007-2011 Texas Instruments + * Author: Vikram Pandita <vikram.pandita@ti.com> + * Author: Keshava Munegowda <keshava_mgowda@ti.com> + * + * Generalization by: + * Felipe Balbi <balbi@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/dma-mapping.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/fixed.h> +#include <linux/string.h> +#include <linux/io.h> +#include <linux/gpio.h> +#include <linux/usb/phy.h> +#include <linux/usb/usb_phy_generic.h> + +#include "soc.h" +#include "omap_device.h" +#include "mux.h" +#include "usb.h" + +#ifdef CONFIG_MFD_OMAP_USB_HOST + +#define OMAP_USBHS_DEVICE "usbhs_omap" +#define OMAP_USBTLL_DEVICE "usbhs_tll" +#define USBHS_UHH_HWMODNAME "usb_host_hs" +#define USBHS_TLL_HWMODNAME "usb_tll_hs" + +/* MUX settings for EHCI pins */ +/* + * setup_ehci_io_mux - initialize IO pad mux for USBHOST + */ +static void __init setup_ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) +{ + switch (port_mode[0]) { + case OMAP_EHCI_PORT_MODE_PHY: + omap_mux_init_signal("hsusb1_stp", OMAP_PIN_OUTPUT); + omap_mux_init_signal("hsusb1_clk", OMAP_PIN_OUTPUT); + omap_mux_init_signal("hsusb1_dir", OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_nxt", OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_data0", OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_data1", OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_data2", OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_data3", OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_data4", OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_data5", OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_data6", OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_data7", OMAP_PIN_INPUT_PULLDOWN); + break; + case OMAP_EHCI_PORT_MODE_TLL: + omap_mux_init_signal("hsusb1_tll_stp", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("hsusb1_tll_clk", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_tll_dir", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_tll_nxt", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_tll_data0", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_tll_data1", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_tll_data2", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_tll_data3", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_tll_data4", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_tll_data5", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_tll_data6", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb1_tll_data7", + OMAP_PIN_INPUT_PULLDOWN); + break; + case OMAP_USBHS_PORT_MODE_UNUSED: + /* FALLTHROUGH */ + default: + break; + } + + switch (port_mode[1]) { + case OMAP_EHCI_PORT_MODE_PHY: + omap_mux_init_signal("hsusb2_stp", OMAP_PIN_OUTPUT); + omap_mux_init_signal("hsusb2_clk", OMAP_PIN_OUTPUT); + omap_mux_init_signal("hsusb2_dir", OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_nxt", OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_data0", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_data1", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_data2", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_data3", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_data4", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_data5", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_data6", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_data7", + OMAP_PIN_INPUT_PULLDOWN); + break; + case OMAP_EHCI_PORT_MODE_TLL: + omap_mux_init_signal("hsusb2_tll_stp", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("hsusb2_tll_clk", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_tll_dir", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_tll_nxt", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_tll_data0", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_tll_data1", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_tll_data2", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_tll_data3", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_tll_data4", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_tll_data5", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_tll_data6", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb2_tll_data7", + OMAP_PIN_INPUT_PULLDOWN); + break; + case OMAP_USBHS_PORT_MODE_UNUSED: + /* FALLTHROUGH */ + default: + break; + } + + switch (port_mode[2]) { + case OMAP_EHCI_PORT_MODE_PHY: + printk(KERN_WARNING "Port3 can't be used in PHY mode\n"); + break; + case OMAP_EHCI_PORT_MODE_TLL: + omap_mux_init_signal("hsusb3_tll_stp", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("hsusb3_tll_clk", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb3_tll_dir", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb3_tll_nxt", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb3_tll_data0", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb3_tll_data1", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb3_tll_data2", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb3_tll_data3", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb3_tll_data4", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb3_tll_data5", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb3_tll_data6", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("hsusb3_tll_data7", + OMAP_PIN_INPUT_PULLDOWN); + break; + case OMAP_USBHS_PORT_MODE_UNUSED: + /* FALLTHROUGH */ + default: + break; + } + + return; +} + +static void __init setup_ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) +{ + switch (port_mode[0]) { + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: + omap_mux_init_signal("mm1_rxdp", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("mm1_rxdm", + OMAP_PIN_INPUT_PULLDOWN); + /* FALLTHROUGH */ + case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: + case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: + omap_mux_init_signal("mm1_rxrcv", + OMAP_PIN_INPUT_PULLDOWN); + /* FALLTHROUGH */ + case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: + omap_mux_init_signal("mm1_txen_n", OMAP_PIN_OUTPUT); + /* FALLTHROUGH */ + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: + omap_mux_init_signal("mm1_txse0", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("mm1_txdat", + OMAP_PIN_INPUT_PULLDOWN); + break; + case OMAP_USBHS_PORT_MODE_UNUSED: + /* FALLTHROUGH */ + default: + break; + } + switch (port_mode[1]) { + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: + omap_mux_init_signal("mm2_rxdp", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("mm2_rxdm", + OMAP_PIN_INPUT_PULLDOWN); + /* FALLTHROUGH */ + case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: + case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: + omap_mux_init_signal("mm2_rxrcv", + OMAP_PIN_INPUT_PULLDOWN); + /* FALLTHROUGH */ + case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: + omap_mux_init_signal("mm2_txen_n", OMAP_PIN_OUTPUT); + /* FALLTHROUGH */ + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: + omap_mux_init_signal("mm2_txse0", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("mm2_txdat", + OMAP_PIN_INPUT_PULLDOWN); + break; + case OMAP_USBHS_PORT_MODE_UNUSED: + /* FALLTHROUGH */ + default: + break; + } + switch (port_mode[2]) { + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: + omap_mux_init_signal("mm3_rxdp", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("mm3_rxdm", + OMAP_PIN_INPUT_PULLDOWN); + /* FALLTHROUGH */ + case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: + case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: + omap_mux_init_signal("mm3_rxrcv", + OMAP_PIN_INPUT_PULLDOWN); + /* FALLTHROUGH */ + case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: + omap_mux_init_signal("mm3_txen_n", OMAP_PIN_OUTPUT); + /* FALLTHROUGH */ + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: + omap_mux_init_signal("mm3_txse0", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("mm3_txdat", + OMAP_PIN_INPUT_PULLDOWN); + break; + case OMAP_USBHS_PORT_MODE_UNUSED: + /* FALLTHROUGH */ + default: + break; + } +} + +void __init usbhs_init(struct usbhs_omap_platform_data *pdata) +{ + struct omap_hwmod *uhh_hwm, *tll_hwm; + struct platform_device *pdev; + int bus_id = -1; + + if (cpu_is_omap34xx()) { + setup_ehci_io_mux(pdata->port_mode); + setup_ohci_io_mux(pdata->port_mode); + + if (omap_rev() <= OMAP3430_REV_ES2_1) + pdata->single_ulpi_bypass = true; + + } + + uhh_hwm = omap_hwmod_lookup(USBHS_UHH_HWMODNAME); + if (!uhh_hwm) { + pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME); + return; + } + + tll_hwm = omap_hwmod_lookup(USBHS_TLL_HWMODNAME); + if (!tll_hwm) { + pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME); + return; + } + + pdev = omap_device_build(OMAP_USBTLL_DEVICE, bus_id, tll_hwm, + pdata, sizeof(*pdata)); + if (IS_ERR(pdev)) { + pr_err("Could not build hwmod device %s\n", + USBHS_TLL_HWMODNAME); + return; + } + + pdev = omap_device_build(OMAP_USBHS_DEVICE, bus_id, uhh_hwm, + pdata, sizeof(*pdata)); + if (IS_ERR(pdev)) { + pr_err("Could not build hwmod devices %s\n", + USBHS_UHH_HWMODNAME); + return; + } +} + +#else + +void __init usbhs_init(struct usbhs_omap_platform_data *pdata) +{ +} + +#endif + +/* Template for PHY regulators */ +static struct fixed_voltage_config hsusb_reg_config = { + /* .supply_name filled later */ + .microvolts = 3300000, + .gpio = -1, /* updated later */ + .startup_delay = 70000, /* 70msec */ + .enable_high = 1, /* updated later */ + .enabled_at_boot = 0, /* keep in RESET */ + /* .init_data filled later */ +}; + +static const char *nop_name = "usb_phy_generic"; /* NOP PHY driver */ +static const char *reg_name = "reg-fixed-voltage"; /* Regulator driver */ + +/** + * usbhs_add_regulator - Add a gpio based fixed voltage regulator device + * @name: name for the regulator + * @dev_id: device id of the device this regulator supplies power to + * @dev_supply: supply name that the device expects + * @gpio: GPIO number + * @polarity: 1 - Active high, 0 - Active low + */ +static int usbhs_add_regulator(char *name, char *dev_id, char *dev_supply, + int gpio, int polarity) +{ + struct regulator_consumer_supply *supplies; + struct regulator_init_data *reg_data; + struct fixed_voltage_config *config; + struct platform_device *pdev; + struct platform_device_info pdevinfo; + int ret = -ENOMEM; + + supplies = kzalloc(sizeof(*supplies), GFP_KERNEL); + if (!supplies) + return -ENOMEM; + + supplies->supply = dev_supply; + supplies->dev_name = dev_id; + + reg_data = kzalloc(sizeof(*reg_data), GFP_KERNEL); + if (!reg_data) + goto err_data; + + reg_data->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS; + reg_data->consumer_supplies = supplies; + reg_data->num_consumer_supplies = 1; + + config = kmemdup(&hsusb_reg_config, sizeof(hsusb_reg_config), + GFP_KERNEL); + if (!config) + goto err_config; + + config->supply_name = kstrdup(name, GFP_KERNEL); + if (!config->supply_name) + goto err_supplyname; + + config->gpio = gpio; + config->enable_high = polarity; + config->init_data = reg_data; + + /* create a regulator device */ + memset(&pdevinfo, 0, sizeof(pdevinfo)); + pdevinfo.name = reg_name; + pdevinfo.id = PLATFORM_DEVID_AUTO; + pdevinfo.data = config; + pdevinfo.size_data = sizeof(*config); + + pdev = platform_device_register_full(&pdevinfo); + if (IS_ERR(pdev)) { + ret = PTR_ERR(pdev); + pr_err("%s: Failed registering regulator %s for %s : %d\n", + __func__, name, dev_id, ret); + goto err_register; + } + + return 0; + +err_register: + kfree(config->supply_name); +err_supplyname: + kfree(config); +err_config: + kfree(reg_data); +err_data: + kfree(supplies); + return ret; +} + +#define MAX_STR 20 + +int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys) +{ + char rail_name[MAX_STR]; + int i; + struct platform_device *pdev; + char *phy_id; + struct platform_device_info pdevinfo; + struct usb_phy_generic_platform_data nop_pdata; + + for (i = 0; i < num_phys; i++) { + + if (!phy->port) { + pr_err("%s: Invalid port 0. Must start from 1\n", + __func__); + continue; + } + + /* do we need a NOP PHY device ? */ + if (!gpio_is_valid(phy->reset_gpio) && + !gpio_is_valid(phy->vcc_gpio)) + continue; + + phy_id = kmalloc(MAX_STR, GFP_KERNEL); + if (!phy_id) { + pr_err("%s: kmalloc() failed\n", __func__); + return -ENOMEM; + } + + /* set platform data */ + memset(&nop_pdata, 0, sizeof(nop_pdata)); + if (gpio_is_valid(phy->vcc_gpio)) + nop_pdata.needs_vcc = true; + nop_pdata.gpio_reset = phy->reset_gpio; + nop_pdata.type = USB_PHY_TYPE_USB2; + + /* create a NOP PHY device */ + memset(&pdevinfo, 0, sizeof(pdevinfo)); + pdevinfo.name = nop_name; + pdevinfo.id = phy->port; + pdevinfo.data = &nop_pdata; + pdevinfo.size_data = + sizeof(struct usb_phy_generic_platform_data); + scnprintf(phy_id, MAX_STR, "usb_phy_generic.%d", + phy->port); + pdev = platform_device_register_full(&pdevinfo); + if (IS_ERR(pdev)) { + pr_err("%s: Failed to register device %s : %ld\n", + __func__, phy_id, PTR_ERR(pdev)); + kfree(phy_id); + continue; + } + + usb_bind_phy("ehci-omap.0", phy->port - 1, phy_id); + + /* Do we need VCC regulator ? */ + if (gpio_is_valid(phy->vcc_gpio)) { + scnprintf(rail_name, MAX_STR, "hsusb%d_vcc", phy->port); + usbhs_add_regulator(rail_name, phy_id, "vcc", + phy->vcc_gpio, phy->vcc_polarity); + } + + phy++; + } + + return 0; +} diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c new file mode 100644 index 00000000000..bc897231bd1 --- /dev/null +++ b/arch/arm/mach-omap2/usb-musb.c @@ -0,0 +1,114 @@ +/* + * linux/arch/arm/mach-omap2/usb-musb.c + * + * This file will contain the board specific details for the + * MENTOR USB OTG controller on OMAP3430 + * + * Copyright (C) 2007-2008 Texas Instruments + * Copyright (C) 2008 Nokia Corporation + * Author: Vikram Pandita + * + * Generalization by: + * Felipe Balbi <felipe.balbi@nokia.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/clk.h> +#include <linux/dma-mapping.h> +#include <linux/io.h> +#include <linux/usb/musb.h> + +#include "omap_device.h" +#include "soc.h" +#include "mux.h" +#include "usb.h" + +static struct musb_hdrc_config musb_config = { + .multipoint = 1, + .dyn_fifo = 1, + .num_eps = 16, + .ram_bits = 12, +}; + +static struct musb_hdrc_platform_data musb_plat = { + .mode = MUSB_OTG, + + /* .clock is set dynamically */ + .config = &musb_config, + + /* REVISIT charge pump on TWL4030 can supply up to + * 100 mA ... but this value is board-specific, like + * "mode", and should be passed to usb_musb_init(). + */ + .power = 50, /* up to 100 mA */ +}; + +static u64 musb_dmamask = DMA_BIT_MASK(32); + +static struct omap_musb_board_data musb_default_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 100, +}; + +void __init usb_musb_init(struct omap_musb_board_data *musb_board_data) +{ + struct omap_hwmod *oh; + struct platform_device *pdev; + struct device *dev; + int bus_id = -1; + const char *oh_name, *name; + struct omap_musb_board_data *board_data; + + if (musb_board_data) + board_data = musb_board_data; + else + board_data = &musb_default_board_data; + + /* + * REVISIT: This line can be removed once all the platforms using + * musb_core.c have been converted to use use clkdev. + */ + musb_plat.clock = "ick"; + musb_plat.board_data = board_data; + musb_plat.power = board_data->power >> 1; + musb_plat.mode = board_data->mode; + musb_plat.extvbus = board_data->extvbus; + + if (soc_is_am35xx()) { + oh_name = "am35x_otg_hs"; + name = "musb-am35x"; + } else if (cpu_is_ti81xx()) { + oh_name = "usb_otg_hs"; + name = "musb-ti81xx"; + } else { + oh_name = "usb_otg_hs"; + name = "musb-omap2430"; + } + + oh = omap_hwmod_lookup(oh_name); + if (WARN(!oh, "%s: could not find omap_hwmod for %s\n", + __func__, oh_name)) + return; + + pdev = omap_device_build(name, bus_id, oh, &musb_plat, + sizeof(musb_plat)); + if (IS_ERR(pdev)) { + pr_err("Could not build omap_device for %s %s\n", + name, oh_name); + return; + } + + dev = &pdev->dev; + get_device(dev); + dev->dma_mask = &musb_dmamask; + dev->coherent_dma_mask = musb_dmamask; + put_device(dev); +} diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c index 15e509013de..e832bc7b8e2 100644 --- a/arch/arm/mach-omap2/usb-tusb6010.c +++ b/arch/arm/mach-omap2/usb-tusb6010.c @@ -8,182 +8,106 @@ * published by the Free Software Foundation. */ +#include <linux/err.h> +#include <linux/string.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/gpio.h> +#include <linux/export.h> +#include <linux/platform_data/usb-omap.h> #include <linux/usb/musb.h> -#include <mach/gpmc.h> -#include <mach/mux.h> +#include "gpmc.h" +#include "mux.h" static u8 async_cs, sync_cs; static unsigned refclk_psec; +static struct gpmc_settings tusb_async = { + .wait_on_read = true, + .wait_on_write = true, + .device_width = GPMC_DEVWIDTH_16BIT, + .mux_add_data = GPMC_MUX_AD, +}; -/* t2_ps, when quantized to fclk units, must happen no earlier than - * the clock after after t1_NS. - * - * Return a possibly updated value of t2_ps, converted to nsec. - */ -static unsigned -next_clk(unsigned t1_NS, unsigned t2_ps, unsigned fclk_ps) -{ - unsigned t1_ps = t1_NS * 1000; - unsigned t1_f, t2_f; - - if ((t1_ps + fclk_ps) < t2_ps) - return t2_ps / 1000; - - t1_f = (t1_ps + fclk_ps - 1) / fclk_ps; - t2_f = (t2_ps + fclk_ps - 1) / fclk_ps; - - if (t1_f >= t2_f) - t2_f = t1_f + 1; - - return (t2_f * fclk_ps) / 1000; -} +static struct gpmc_settings tusb_sync = { + .burst_read = true, + .burst_write = true, + .sync_read = true, + .sync_write = true, + .wait_on_read = true, + .wait_on_write = true, + .burst_len = GPMC_BURST_16, + .device_width = GPMC_DEVWIDTH_16BIT, + .mux_add_data = GPMC_MUX_AD, +}; /* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */ -static int tusb_set_async_mode(unsigned sysclk_ps, unsigned fclk_ps) +static int tusb_set_async_mode(unsigned sysclk_ps) { + struct gpmc_device_timings dev_t; struct gpmc_timings t; unsigned t_acsnh_advnh = sysclk_ps + 3000; - unsigned tmp; - - memset(&t, 0, sizeof(t)); - - /* CS_ON = t_acsnh_acsnl */ - t.cs_on = 8; - /* ADV_ON = t_acsnh_advnh - t_advn */ - t.adv_on = next_clk(t.cs_on, t_acsnh_advnh - 7000, fclk_ps); - - /* - * READ ... from omap2420 TRM fig 12-13 - */ - - /* ADV_RD_OFF = t_acsnh_advnh */ - t.adv_rd_off = next_clk(t.adv_on, t_acsnh_advnh, fclk_ps); - - /* OE_ON = t_acsnh_advnh + t_advn_oen (then wait for nRDY) */ - t.oe_on = next_clk(t.adv_on, t_acsnh_advnh + 1000, fclk_ps); - - /* ACCESS = counters continue only after nRDY */ - tmp = t.oe_on * 1000 + 300; - t.access = next_clk(t.oe_on, tmp, fclk_ps); - - /* OE_OFF = after data gets sampled */ - tmp = t.access * 1000; - t.oe_off = next_clk(t.access, tmp, fclk_ps); - - t.cs_rd_off = t.oe_off; - - tmp = t.cs_rd_off * 1000 + 7000 /* t_acsn_rdy_z */; - t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps); - - /* - * WRITE ... from omap2420 TRM fig 12-15 - */ - - /* ADV_WR_OFF = t_acsnh_advnh */ - t.adv_wr_off = t.adv_rd_off; - - /* WE_ON = t_acsnh_advnh + t_advn_wen (then wait for nRDY) */ - t.we_on = next_clk(t.adv_wr_off, t_acsnh_advnh + 1000, fclk_ps); - /* WE_OFF = after data gets sampled */ - tmp = t.we_on * 1000 + 300; - t.we_off = next_clk(t.we_on, tmp, fclk_ps); + memset(&dev_t, 0, sizeof(dev_t)); - t.cs_wr_off = t.we_off; + dev_t.t_ceasu = 8 * 1000; + dev_t.t_avdasu = t_acsnh_advnh - 7000; + dev_t.t_ce_avd = 1000; + dev_t.t_avdp_r = t_acsnh_advnh; + dev_t.t_oeasu = t_acsnh_advnh + 1000; + dev_t.t_oe = 300; + dev_t.t_cez_r = 7000; + dev_t.t_cez_w = dev_t.t_cez_r; + dev_t.t_avdp_w = t_acsnh_advnh; + dev_t.t_weasu = t_acsnh_advnh + 1000; + dev_t.t_wpl = 300; + dev_t.cyc_aavdh_we = 1; - tmp = t.cs_wr_off * 1000 + 7000 /* t_acsn_rdy_z */; - t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps); + gpmc_calc_timings(&t, &tusb_async, &dev_t); return gpmc_cs_set_timings(async_cs, &t); } -static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps) +static int tusb_set_sync_mode(unsigned sysclk_ps) { + struct gpmc_device_timings dev_t; struct gpmc_timings t; unsigned t_scsnh_advnh = sysclk_ps + 3000; - unsigned tmp; - memset(&t, 0, sizeof(t)); - t.cs_on = 8; - - /* ADV_ON = t_acsnh_advnh - t_advn */ - t.adv_on = next_clk(t.cs_on, t_scsnh_advnh - 7000, fclk_ps); - - /* GPMC_CLK rate = fclk rate / div */ - t.sync_clk = 12 /* 11.1 nsec */; - tmp = (t.sync_clk * 1000 + fclk_ps - 1) / fclk_ps; - if (tmp > 4) - return -ERANGE; - if (tmp <= 0) - tmp = 1; - t.page_burst_access = (fclk_ps * tmp) / 1000; - - /* - * READ ... based on omap2420 TRM fig 12-19, 12-20 - */ - - /* ADV_RD_OFF = t_scsnh_advnh */ - t.adv_rd_off = next_clk(t.adv_on, t_scsnh_advnh, fclk_ps); - - /* OE_ON = t_scsnh_advnh + t_advn_oen * fclk_ps (then wait for nRDY) */ - tmp = (t.adv_rd_off * 1000) + (3 * fclk_ps); - t.oe_on = next_clk(t.adv_on, tmp, fclk_ps); - - /* ACCESS = number of clock cycles after t_adv_eon */ - tmp = (t.oe_on * 1000) + (5 * fclk_ps); - t.access = next_clk(t.oe_on, tmp, fclk_ps); - - /* OE_OFF = after data gets sampled */ - tmp = (t.access * 1000) + (1 * fclk_ps); - t.oe_off = next_clk(t.access, tmp, fclk_ps); - - t.cs_rd_off = t.oe_off; - - tmp = t.cs_rd_off * 1000 + 7000 /* t_scsn_rdy_z */; - t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps); - - /* - * WRITE ... based on omap2420 TRM fig 12-21 - */ - - /* ADV_WR_OFF = t_scsnh_advnh */ - t.adv_wr_off = t.adv_rd_off; - - /* WE_ON = t_scsnh_advnh + t_advn_wen * fclk_ps (then wait for nRDY) */ - tmp = (t.adv_wr_off * 1000) + (3 * fclk_ps); - t.we_on = next_clk(t.adv_wr_off, tmp, fclk_ps); - - /* WE_OFF = number of clock cycles after t_adv_wen */ - tmp = (t.we_on * 1000) + (6 * fclk_ps); - t.we_off = next_clk(t.we_on, tmp, fclk_ps); - - t.cs_wr_off = t.we_off; - - tmp = t.cs_wr_off * 1000 + 7000 /* t_scsn_rdy_z */; - t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps); + memset(&dev_t, 0, sizeof(dev_t)); + + dev_t.clk = 11100; + dev_t.t_bacc = 1000; + dev_t.t_ces = 1000; + dev_t.t_ceasu = 8 * 1000; + dev_t.t_avdasu = t_scsnh_advnh - 7000; + dev_t.t_ce_avd = 1000; + dev_t.t_avdp_r = t_scsnh_advnh; + dev_t.cyc_aavdh_oe = 3; + dev_t.cyc_oe = 5; + dev_t.t_ce_rdyz = 7000; + dev_t.t_avdp_w = t_scsnh_advnh; + dev_t.cyc_aavdh_we = 3; + dev_t.cyc_wpl = 6; + dev_t.t_ce_rdyz = 7000; + + gpmc_calc_timings(&t, &tusb_sync, &dev_t); return gpmc_cs_set_timings(sync_cs, &t); } -extern unsigned long gpmc_get_fclk_period(void); - /* tusb driver calls this when it changes the chip's clocking */ int tusb6010_platform_retime(unsigned is_refclk) { static const char error[] = KERN_ERR "tusb6010 %s retime error %d\n"; - unsigned fclk_ps = gpmc_get_fclk_period(); unsigned sysclk_ps; int status; @@ -192,12 +116,12 @@ int tusb6010_platform_retime(unsigned is_refclk) sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60; - status = tusb_set_async_mode(sysclk_ps, fclk_ps); + status = tusb_set_async_mode(sysclk_ps); if (status < 0) { printk(error, "async", status); goto done; } - status = tusb_set_sync_mode(sysclk_ps, fclk_ps); + status = tusb_set_sync_mode(sysclk_ps); if (status < 0) printk(error, "sync", status); done: @@ -216,6 +140,7 @@ static struct resource tusb_resources[] = { .flags = IORESOURCE_MEM, }, { /* IRQ */ + .name = "mc", .flags = IORESOURCE_IRQ, }, }; @@ -223,7 +148,7 @@ static struct resource tusb_resources[] = { static u64 tusb_dmamask = ~(u32)0; static struct platform_device tusb_device = { - .name = "musb_hdrc", + .name = "musb-tusb", .id = -1, .dev = { .dma_mask = &tusb_dmamask, @@ -253,18 +178,12 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data, return status; } tusb_resources[0].end = tusb_resources[0].start + 0x9ff; + tusb_async.wait_pin = waitpin; async_cs = async; - gpmc_cs_write_reg(async, GPMC_CS_CONFIG1, - GPMC_CONFIG1_PAGE_LEN(2) - | GPMC_CONFIG1_WAIT_READ_MON - | GPMC_CONFIG1_WAIT_WRITE_MON - | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin) - | GPMC_CONFIG1_READTYPE_ASYNC - | GPMC_CONFIG1_WRITETYPE_ASYNC - | GPMC_CONFIG1_DEVICESIZE_16 - | GPMC_CONFIG1_DEVICETYPE_NOR - | GPMC_CONFIG1_MUXADDDATA); + status = gpmc_cs_program_settings(async_cs, &tusb_async); + if (status < 0) + return status; /* SYNC region, primarily for DMA */ status = gpmc_cs_request(sync, SZ_16M, (unsigned long *) @@ -274,31 +193,20 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data, return status; } tusb_resources[1].end = tusb_resources[1].start + 0x9ff; + tusb_sync.wait_pin = waitpin; sync_cs = sync; - gpmc_cs_write_reg(sync, GPMC_CS_CONFIG1, - GPMC_CONFIG1_READMULTIPLE_SUPP - | GPMC_CONFIG1_READTYPE_SYNC - | GPMC_CONFIG1_WRITEMULTIPLE_SUPP - | GPMC_CONFIG1_WRITETYPE_SYNC - | GPMC_CONFIG1_CLKACTIVATIONTIME(1) - | GPMC_CONFIG1_PAGE_LEN(2) - | GPMC_CONFIG1_WAIT_READ_MON - | GPMC_CONFIG1_WAIT_WRITE_MON - | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin) - | GPMC_CONFIG1_DEVICESIZE_16 - | GPMC_CONFIG1_DEVICETYPE_NOR - | GPMC_CONFIG1_MUXADDDATA - /* fclk divider gets set later */ - ); + + status = gpmc_cs_program_settings(sync_cs, &tusb_sync); + if (status < 0) + return status; /* IRQ */ - status = gpio_request(irq, "TUSB6010 irq"); + status = gpio_request_one(irq, GPIOF_IN, "TUSB6010 irq"); if (status < 0) { printk(error, 3, status); return status; } - gpio_direction_input(irq); - tusb_resources[2].start = irq + IH_GPIO_BASE; + tusb_resources[2].start = gpio_to_irq(irq); /* set up memory timings ... can speed them up later */ if (!ps_refclk) { @@ -325,17 +233,17 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data, else { /* assume OMAP 2420 ES2.0 and later */ if (dmachan & (1 << 0)) - omap_cfg_reg(AA10_242X_DMAREQ0); + omap_mux_init_signal("sys_ndmareq0", 0); if (dmachan & (1 << 1)) - omap_cfg_reg(AA6_242X_DMAREQ1); + omap_mux_init_signal("sys_ndmareq1", 0); if (dmachan & (1 << 2)) - omap_cfg_reg(E4_242X_DMAREQ2); + omap_mux_init_signal("sys_ndmareq2", 0); if (dmachan & (1 << 3)) - omap_cfg_reg(G4_242X_DMAREQ3); + omap_mux_init_signal("sys_ndmareq3", 0); if (dmachan & (1 << 4)) - omap_cfg_reg(D3_242X_DMAREQ4); + omap_mux_init_signal("sys_ndmareq4", 0); if (dmachan & (1 << 5)) - omap_cfg_reg(E3_242X_DMAREQ5); + omap_mux_init_signal("sys_ndmareq5", 0); } /* so far so good ... register the device */ diff --git a/arch/arm/mach-omap2/usb.h b/arch/arm/mach-omap2/usb.h new file mode 100644 index 00000000000..4ba2ae75989 --- /dev/null +++ b/arch/arm/mach-omap2/usb.h @@ -0,0 +1,72 @@ +#include <linux/platform_data/usb-omap.h> + +/* AM35x */ +/* USB 2.0 PHY Control */ +#define CONF2_PHY_GPIOMODE (1 << 23) +#define CONF2_OTGMODE (3 << 14) +#define CONF2_NO_OVERRIDE (0 << 14) +#define CONF2_FORCE_HOST (1 << 14) +#define CONF2_FORCE_DEVICE (2 << 14) +#define CONF2_FORCE_HOST_VBUS_LOW (3 << 14) +#define CONF2_SESENDEN (1 << 13) +#define CONF2_VBDTCTEN (1 << 12) +#define CONF2_REFFREQ_24MHZ (2 << 8) +#define CONF2_REFFREQ_26MHZ (7 << 8) +#define CONF2_REFFREQ_13MHZ (6 << 8) +#define CONF2_REFFREQ (0xf << 8) +#define CONF2_PHYCLKGD (1 << 7) +#define CONF2_VBUSSENSE (1 << 6) +#define CONF2_PHY_PLLON (1 << 5) +#define CONF2_RESET (1 << 4) +#define CONF2_PHYPWRDN (1 << 3) +#define CONF2_OTGPWRDN (1 << 2) +#define CONF2_DATPOL (1 << 1) + +/* TI81XX specific definitions */ +#define USBCTRL0 0x620 +#define USBSTAT0 0x624 + +/* TI816X PHY controls bits */ +#define TI816X_USBPHY0_NORMAL_MODE (1 << 0) +#define TI816X_USBPHY_REFCLK_OSC (1 << 8) + +/* TI814X PHY controls bits */ +#define USBPHY_CM_PWRDN (1 << 0) +#define USBPHY_OTG_PWRDN (1 << 1) +#define USBPHY_CHGDET_DIS (1 << 2) +#define USBPHY_CHGDET_RSTRT (1 << 3) +#define USBPHY_SRCONDM (1 << 4) +#define USBPHY_SINKONDP (1 << 5) +#define USBPHY_CHGISINK_EN (1 << 6) +#define USBPHY_CHGVSRC_EN (1 << 7) +#define USBPHY_DMPULLUP (1 << 8) +#define USBPHY_DPPULLUP (1 << 9) +#define USBPHY_CDET_EXTCTL (1 << 10) +#define USBPHY_GPIO_MODE (1 << 12) +#define USBPHY_DPOPBUFCTL (1 << 13) +#define USBPHY_DMOPBUFCTL (1 << 14) +#define USBPHY_DPINPUT (1 << 15) +#define USBPHY_DMINPUT (1 << 16) +#define USBPHY_DPGPIO_PD (1 << 17) +#define USBPHY_DMGPIO_PD (1 << 18) +#define USBPHY_OTGVDET_EN (1 << 19) +#define USBPHY_OTGSESSEND_EN (1 << 20) +#define USBPHY_DATA_POLARITY (1 << 23) + +struct usbhs_phy_data { + int port; /* 1 indexed port number */ + int reset_gpio; + int vcc_gpio; + bool vcc_polarity; /* 1 active high, 0 active low */ +}; + +extern void usb_musb_init(struct omap_musb_board_data *board_data); +extern void usbhs_init(struct usbhs_omap_platform_data *pdata); +extern int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys); + +extern void am35x_musb_reset(void); +extern void am35x_musb_phy_power(u8 on); +extern void am35x_musb_clear_irq(void); +extern void am35x_set_mode(u8 musb_mode); +extern void ti81xx_musb_phy_power(u8 on); + diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c new file mode 100644 index 00000000000..a4628a9e760 --- /dev/null +++ b/arch/arm/mach-omap2/vc.c @@ -0,0 +1,839 @@ +/* + * OMAP Voltage Controller (VC) interface + * + * Copyright (C) 2011 Texas Instruments, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/bug.h> +#include <linux/io.h> + +#include <asm/div64.h> + +#include "iomap.h" +#include "soc.h" +#include "voltage.h" +#include "vc.h" +#include "prm-regbits-34xx.h" +#include "prm-regbits-44xx.h" +#include "prm44xx.h" +#include "pm.h" +#include "scrm44xx.h" +#include "control.h" + +/** + * struct omap_vc_channel_cfg - describe the cfg_channel bitfield + * @sa: bit for slave address + * @rav: bit for voltage configuration register + * @rac: bit for command configuration register + * @racen: enable bit for RAC + * @cmd: bit for command value set selection + * + * Channel configuration bits, common for OMAP3+ + * OMAP3 register: PRM_VC_CH_CONF + * OMAP4 register: PRM_VC_CFG_CHANNEL + * OMAP5 register: PRM_VC_SMPS_<voltdm>_CONFIG + */ +struct omap_vc_channel_cfg { + u8 sa; + u8 rav; + u8 rac; + u8 racen; + u8 cmd; +}; + +static struct omap_vc_channel_cfg vc_default_channel_cfg = { + .sa = BIT(0), + .rav = BIT(1), + .rac = BIT(2), + .racen = BIT(3), + .cmd = BIT(4), +}; + +/* + * On OMAP3+, all VC channels have the above default bitfield + * configuration, except the OMAP4 MPU channel. This appears + * to be a freak accident as every other VC channel has the + * default configuration, thus creating a mutant channel config. + */ +static struct omap_vc_channel_cfg vc_mutant_channel_cfg = { + .sa = BIT(0), + .rav = BIT(2), + .rac = BIT(3), + .racen = BIT(4), + .cmd = BIT(1), +}; + +static struct omap_vc_channel_cfg *vc_cfg_bits; + +/* Default I2C trace length on pcb, 6.3cm. Used for capacitance calculations. */ +static u32 sr_i2c_pcb_length = 63; +#define CFG_CHANNEL_MASK 0x1f + +/** + * omap_vc_config_channel - configure VC channel to PMIC mappings + * @voltdm: pointer to voltagdomain defining the desired VC channel + * + * Configures the VC channel to PMIC mappings for the following + * PMIC settings + * - i2c slave address (SA) + * - voltage configuration address (RAV) + * - command configuration address (RAC) and enable bit (RACEN) + * - command values for ON, ONLP, RET and OFF (CMD) + * + * This function currently only allows flexible configuration of the + * non-default channel. Starting with OMAP4, there are more than 2 + * channels, with one defined as the default (on OMAP4, it's MPU.) + * Only the non-default channel can be configured. + */ +static int omap_vc_config_channel(struct voltagedomain *voltdm) +{ + struct omap_vc_channel *vc = voltdm->vc; + + /* + * For default channel, the only configurable bit is RACEN. + * All others must stay at zero (see function comment above.) + */ + if (vc->flags & OMAP_VC_CHANNEL_DEFAULT) + vc->cfg_channel &= vc_cfg_bits->racen; + + voltdm->rmw(CFG_CHANNEL_MASK << vc->cfg_channel_sa_shift, + vc->cfg_channel << vc->cfg_channel_sa_shift, + vc->cfg_channel_reg); + + return 0; +} + +/* Voltage scale and accessory APIs */ +int omap_vc_pre_scale(struct voltagedomain *voltdm, + unsigned long target_volt, + u8 *target_vsel, u8 *current_vsel) +{ + struct omap_vc_channel *vc = voltdm->vc; + u32 vc_cmdval; + + /* Check if sufficient pmic info is available for this vdd */ + if (!voltdm->pmic) { + pr_err("%s: Insufficient pmic info to scale the vdd_%s\n", + __func__, voltdm->name); + return -EINVAL; + } + + if (!voltdm->pmic->uv_to_vsel) { + pr_err("%s: PMIC function to convert voltage in uV to vsel not registered. Hence unable to scale voltage for vdd_%s\n", + __func__, voltdm->name); + return -ENODATA; + } + + if (!voltdm->read || !voltdm->write) { + pr_err("%s: No read/write API for accessing vdd_%s regs\n", + __func__, voltdm->name); + return -EINVAL; + } + + *target_vsel = voltdm->pmic->uv_to_vsel(target_volt); + *current_vsel = voltdm->pmic->uv_to_vsel(voltdm->nominal_volt); + + /* Setting the ON voltage to the new target voltage */ + vc_cmdval = voltdm->read(vc->cmdval_reg); + vc_cmdval &= ~vc->common->cmd_on_mask; + vc_cmdval |= (*target_vsel << vc->common->cmd_on_shift); + voltdm->write(vc_cmdval, vc->cmdval_reg); + + voltdm->vc_param->on = target_volt; + + omap_vp_update_errorgain(voltdm, target_volt); + + return 0; +} + +void omap_vc_post_scale(struct voltagedomain *voltdm, + unsigned long target_volt, + u8 target_vsel, u8 current_vsel) +{ + u32 smps_steps = 0, smps_delay = 0; + + smps_steps = abs(target_vsel - current_vsel); + /* SMPS slew rate / step size. 2us added as buffer. */ + smps_delay = ((smps_steps * voltdm->pmic->step_size) / + voltdm->pmic->slew_rate) + 2; + udelay(smps_delay); +} + +/* vc_bypass_scale - VC bypass method of voltage scaling */ +int omap_vc_bypass_scale(struct voltagedomain *voltdm, + unsigned long target_volt) +{ + struct omap_vc_channel *vc = voltdm->vc; + u32 loop_cnt = 0, retries_cnt = 0; + u32 vc_valid, vc_bypass_val_reg, vc_bypass_value; + u8 target_vsel, current_vsel; + int ret; + + ret = omap_vc_pre_scale(voltdm, target_volt, &target_vsel, ¤t_vsel); + if (ret) + return ret; + + vc_valid = vc->common->valid; + vc_bypass_val_reg = vc->common->bypass_val_reg; + vc_bypass_value = (target_vsel << vc->common->data_shift) | + (vc->volt_reg_addr << vc->common->regaddr_shift) | + (vc->i2c_slave_addr << vc->common->slaveaddr_shift); + + voltdm->write(vc_bypass_value, vc_bypass_val_reg); + voltdm->write(vc_bypass_value | vc_valid, vc_bypass_val_reg); + + vc_bypass_value = voltdm->read(vc_bypass_val_reg); + /* + * Loop till the bypass command is acknowledged from the SMPS. + * NOTE: This is legacy code. The loop count and retry count needs + * to be revisited. + */ + while (!(vc_bypass_value & vc_valid)) { + loop_cnt++; + + if (retries_cnt > 10) { + pr_warning("%s: Retry count exceeded\n", __func__); + return -ETIMEDOUT; + } + + if (loop_cnt > 50) { + retries_cnt++; + loop_cnt = 0; + udelay(10); + } + vc_bypass_value = voltdm->read(vc_bypass_val_reg); + } + + omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel); + return 0; +} + +/* Convert microsecond value to number of 32kHz clock cycles */ +static inline u32 omap_usec_to_32k(u32 usec) +{ + return DIV_ROUND_UP_ULL(32768ULL * (u64)usec, 1000000ULL); +} + +struct omap3_vc_timings { + u32 voltsetup1; + u32 voltsetup2; +}; + +struct omap3_vc { + struct voltagedomain *vd; + u32 voltctrl; + u32 voltsetup1; + u32 voltsetup2; + struct omap3_vc_timings timings[2]; +}; +static struct omap3_vc vc; + +void omap3_vc_set_pmic_signaling(int core_next_state) +{ + struct voltagedomain *vd = vc.vd; + struct omap3_vc_timings *c = vc.timings; + u32 voltctrl, voltsetup1, voltsetup2; + + voltctrl = vc.voltctrl; + voltsetup1 = vc.voltsetup1; + voltsetup2 = vc.voltsetup2; + + switch (core_next_state) { + case PWRDM_POWER_OFF: + voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_RET | + OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP); + voltctrl |= OMAP3430_PRM_VOLTCTRL_AUTO_OFF; + if (voltctrl & OMAP3430_PRM_VOLTCTRL_SEL_OFF) + voltsetup2 = c->voltsetup2; + else + voltsetup1 = c->voltsetup1; + break; + case PWRDM_POWER_RET: + default: + c++; + voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_OFF | + OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP); + voltctrl |= OMAP3430_PRM_VOLTCTRL_AUTO_RET; + voltsetup1 = c->voltsetup1; + break; + } + + if (voltctrl != vc.voltctrl) { + vd->write(voltctrl, OMAP3_PRM_VOLTCTRL_OFFSET); + vc.voltctrl = voltctrl; + } + if (voltsetup1 != vc.voltsetup1) { + vd->write(c->voltsetup1, + OMAP3_PRM_VOLTSETUP1_OFFSET); + vc.voltsetup1 = voltsetup1; + } + if (voltsetup2 != vc.voltsetup2) { + vd->write(c->voltsetup2, + OMAP3_PRM_VOLTSETUP2_OFFSET); + vc.voltsetup2 = voltsetup2; + } +} + +#define PRM_POLCTRL_TWL_MASK (OMAP3430_PRM_POLCTRL_CLKREQ_POL | \ + OMAP3430_PRM_POLCTRL_CLKREQ_POL) +#define PRM_POLCTRL_TWL_VAL OMAP3430_PRM_POLCTRL_CLKREQ_POL + +/* + * Configure signal polarity for sys_clkreq and sys_off_mode pins + * as the default values are wrong and can cause the system to hang + * if any twl4030 scripts are loaded. + */ +static void __init omap3_vc_init_pmic_signaling(struct voltagedomain *voltdm) +{ + u32 val; + + if (vc.vd) + return; + + vc.vd = voltdm; + + val = voltdm->read(OMAP3_PRM_POLCTRL_OFFSET); + if (!(val & OMAP3430_PRM_POLCTRL_CLKREQ_POL) || + (val & OMAP3430_PRM_POLCTRL_CLKREQ_POL)) { + val |= OMAP3430_PRM_POLCTRL_CLKREQ_POL; + val &= ~OMAP3430_PRM_POLCTRL_OFFMODE_POL; + pr_debug("PM: fixing sys_clkreq and sys_off_mode polarity to 0x%x\n", + val); + voltdm->write(val, OMAP3_PRM_POLCTRL_OFFSET); + } + + /* + * By default let's use I2C4 signaling for retention idle + * and sys_off_mode pin signaling for off idle. This way we + * have sys_clk_req pin go down for retention and both + * sys_clk_req and sys_off_mode pins will go down for off + * idle. And we can also scale voltages to zero for off-idle. + * Note that no actual voltage scaling during off-idle will + * happen unless the board specific twl4030 PMIC scripts are + * loaded. + */ + val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET); + if (!(val & OMAP3430_PRM_VOLTCTRL_SEL_OFF)) { + val |= OMAP3430_PRM_VOLTCTRL_SEL_OFF; + pr_debug("PM: setting voltctrl sys_off_mode signaling to 0x%x\n", + val); + voltdm->write(val, OMAP3_PRM_VOLTCTRL_OFFSET); + } + vc.voltctrl = val; + + omap3_vc_set_pmic_signaling(PWRDM_POWER_ON); +} + +static void omap3_init_voltsetup1(struct voltagedomain *voltdm, + struct omap3_vc_timings *c, u32 idle) +{ + unsigned long val; + + val = (voltdm->vc_param->on - idle) / voltdm->pmic->slew_rate; + val *= voltdm->sys_clk.rate / 8 / 1000000 + 1; + val <<= __ffs(voltdm->vfsm->voltsetup_mask); + c->voltsetup1 &= ~voltdm->vfsm->voltsetup_mask; + c->voltsetup1 |= val; +} + +/** + * omap3_set_i2c_timings - sets i2c sleep timings for a channel + * @voltdm: channel to configure + * @off_mode: select whether retention or off mode values used + * + * Calculates and sets up voltage controller to use I2C based + * voltage scaling for sleep modes. This can be used for either off mode + * or retention. Off mode has additionally an option to use sys_off_mode + * pad, which uses a global signal to program the whole power IC to + * off-mode. + * + * Note that pmic is not controlling the voltage scaling during + * retention signaled over I2C4, so we can keep voltsetup2 as 0. + * And the oscillator is not shut off over I2C4, so no need to + * set clksetup. + */ +static void omap3_set_i2c_timings(struct voltagedomain *voltdm) +{ + struct omap3_vc_timings *c = vc.timings; + + /* Configure PRWDM_POWER_OFF over I2C4 */ + omap3_init_voltsetup1(voltdm, c, voltdm->vc_param->off); + c++; + /* Configure PRWDM_POWER_RET over I2C4 */ + omap3_init_voltsetup1(voltdm, c, voltdm->vc_param->ret); +} + +/** + * omap3_set_off_timings - sets off-mode timings for a channel + * @voltdm: channel to configure + * + * Calculates and sets up off-mode timings for a channel. Off-mode + * can use either I2C based voltage scaling, or alternatively + * sys_off_mode pad can be used to send a global command to power IC.n, + * sys_off_mode has the additional benefit that voltages can be + * scaled to zero volt level with TWL4030 / TWL5030, I2C can only + * scale to 600mV. + * + * Note that omap is not controlling the voltage scaling during + * off idle signaled by sys_off_mode, so we can keep voltsetup1 + * as 0. + */ +static void omap3_set_off_timings(struct voltagedomain *voltdm) +{ + struct omap3_vc_timings *c = vc.timings; + u32 tstart, tshut, clksetup, voltoffset; + + if (c->voltsetup2) + return; + + omap_pm_get_oscillator(&tstart, &tshut); + if (tstart == ULONG_MAX) { + pr_debug("PM: oscillator start-up time not initialized, using 10ms\n"); + clksetup = omap_usec_to_32k(10000); + } else { + clksetup = omap_usec_to_32k(tstart); + } + + /* + * For twl4030 errata 27, we need to allow minimum ~488.32 us wait to + * switch from HFCLKIN to internal oscillator. That means timings + * have voltoffset fixed to 0xa in rounded up 32 KiHz cycles. And + * that means we can calculate the value based on the oscillator + * start-up time since voltoffset2 = clksetup - voltoffset. + */ + voltoffset = omap_usec_to_32k(488); + c->voltsetup2 = clksetup - voltoffset; + voltdm->write(clksetup, OMAP3_PRM_CLKSETUP_OFFSET); + voltdm->write(voltoffset, OMAP3_PRM_VOLTOFFSET_OFFSET); +} + +static void __init omap3_vc_init_channel(struct voltagedomain *voltdm) +{ + omap3_vc_init_pmic_signaling(voltdm); + omap3_set_off_timings(voltdm); + omap3_set_i2c_timings(voltdm); +} + +/** + * omap4_calc_volt_ramp - calculates voltage ramping delays on omap4 + * @voltdm: channel to calculate values for + * @voltage_diff: voltage difference in microvolts + * + * Calculates voltage ramp prescaler + counter values for a voltage + * difference on omap4. Returns a field value suitable for writing to + * VOLTSETUP register for a channel in following format: + * bits[8:9] prescaler ... bits[0:5] counter. See OMAP4 TRM for reference. + */ +static u32 omap4_calc_volt_ramp(struct voltagedomain *voltdm, u32 voltage_diff) +{ + u32 prescaler; + u32 cycles; + u32 time; + + time = voltage_diff / voltdm->pmic->slew_rate; + + cycles = voltdm->sys_clk.rate / 1000 * time / 1000; + + cycles /= 64; + prescaler = 0; + + /* shift to next prescaler until no overflow */ + + /* scale for div 256 = 64 * 4 */ + if (cycles > 63) { + cycles /= 4; + prescaler++; + } + + /* scale for div 512 = 256 * 2 */ + if (cycles > 63) { + cycles /= 2; + prescaler++; + } + + /* scale for div 2048 = 512 * 4 */ + if (cycles > 63) { + cycles /= 4; + prescaler++; + } + + /* check for overflow => invalid ramp time */ + if (cycles > 63) { + pr_warn("%s: invalid setuptime for vdd_%s\n", __func__, + voltdm->name); + return 0; + } + + cycles++; + + return (prescaler << OMAP4430_RAMP_UP_PRESCAL_SHIFT) | + (cycles << OMAP4430_RAMP_UP_COUNT_SHIFT); +} + +/** + * omap4_usec_to_val_scrm - convert microsecond value to SCRM module bitfield + * @usec: microseconds + * @shift: number of bits to shift left + * @mask: bitfield mask + * + * Converts microsecond value to OMAP4 SCRM bitfield. Bitfield is + * shifted to requested position, and checked agains the mask value. + * If larger, forced to the max value of the field (i.e. the mask itself.) + * Returns the SCRM bitfield value. + */ +static u32 omap4_usec_to_val_scrm(u32 usec, int shift, u32 mask) +{ + u32 val; + + val = omap_usec_to_32k(usec) << shift; + + /* Check for overflow, if yes, force to max value */ + if (val > mask) + val = mask; + + return val; +} + +/** + * omap4_set_timings - set voltage ramp timings for a channel + * @voltdm: channel to configure + * @off_mode: whether off-mode values are used + * + * Calculates and sets the voltage ramp up / down values for a channel. + */ +static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode) +{ + u32 val; + u32 ramp; + int offset; + u32 tstart, tshut; + + if (off_mode) { + ramp = omap4_calc_volt_ramp(voltdm, + voltdm->vc_param->on - voltdm->vc_param->off); + offset = voltdm->vfsm->voltsetup_off_reg; + } else { + ramp = omap4_calc_volt_ramp(voltdm, + voltdm->vc_param->on - voltdm->vc_param->ret); + offset = voltdm->vfsm->voltsetup_reg; + } + + if (!ramp) + return; + + val = voltdm->read(offset); + + val |= ramp << OMAP4430_RAMP_DOWN_COUNT_SHIFT; + + val |= ramp << OMAP4430_RAMP_UP_COUNT_SHIFT; + + voltdm->write(val, offset); + + omap_pm_get_oscillator(&tstart, &tshut); + + val = omap4_usec_to_val_scrm(tstart, OMAP4_SETUPTIME_SHIFT, + OMAP4_SETUPTIME_MASK); + val |= omap4_usec_to_val_scrm(tshut, OMAP4_DOWNTIME_SHIFT, + OMAP4_DOWNTIME_MASK); + + writel_relaxed(val, OMAP4_SCRM_CLKSETUPTIME); +} + +/* OMAP4 specific voltage init functions */ +static void __init omap4_vc_init_channel(struct voltagedomain *voltdm) +{ + omap4_set_timings(voltdm, true); + omap4_set_timings(voltdm, false); +} + +struct i2c_init_data { + u8 loadbits; + u8 load; + u8 hsscll_38_4; + u8 hsscll_26; + u8 hsscll_19_2; + u8 hsscll_16_8; + u8 hsscll_12; +}; + +static const __initdata struct i2c_init_data omap4_i2c_timing_data[] = { + { + .load = 50, + .loadbits = 0x3, + .hsscll_38_4 = 13, + .hsscll_26 = 11, + .hsscll_19_2 = 9, + .hsscll_16_8 = 9, + .hsscll_12 = 8, + }, + { + .load = 25, + .loadbits = 0x2, + .hsscll_38_4 = 13, + .hsscll_26 = 11, + .hsscll_19_2 = 9, + .hsscll_16_8 = 9, + .hsscll_12 = 8, + }, + { + .load = 12, + .loadbits = 0x1, + .hsscll_38_4 = 11, + .hsscll_26 = 10, + .hsscll_19_2 = 9, + .hsscll_16_8 = 9, + .hsscll_12 = 8, + }, + { + .load = 0, + .loadbits = 0x0, + .hsscll_38_4 = 12, + .hsscll_26 = 10, + .hsscll_19_2 = 9, + .hsscll_16_8 = 8, + .hsscll_12 = 8, + }, +}; + +/** + * omap4_vc_i2c_timing_init - sets up board I2C timing parameters + * @voltdm: voltagedomain pointer to get data from + * + * Use PMIC + board supplied settings for calculating the total I2C + * channel capacitance and set the timing parameters based on this. + * Pre-calculated values are provided in data tables, as it is not + * too straightforward to calculate these runtime. + */ +static void __init omap4_vc_i2c_timing_init(struct voltagedomain *voltdm) +{ + u32 capacitance; + u32 val; + u16 hsscll; + const struct i2c_init_data *i2c_data; + + if (!voltdm->pmic->i2c_high_speed) { + pr_warn("%s: only high speed supported!\n", __func__); + return; + } + + /* PCB trace capacitance, 0.125pF / mm => mm / 8 */ + capacitance = DIV_ROUND_UP(sr_i2c_pcb_length, 8); + + /* OMAP pad capacitance */ + capacitance += 4; + + /* PMIC pad capacitance */ + capacitance += voltdm->pmic->i2c_pad_load; + + /* Search for capacitance match in the table */ + i2c_data = omap4_i2c_timing_data; + + while (i2c_data->load > capacitance) + i2c_data++; + + /* Select proper values based on sysclk frequency */ + switch (voltdm->sys_clk.rate) { + case 38400000: + hsscll = i2c_data->hsscll_38_4; + break; + case 26000000: + hsscll = i2c_data->hsscll_26; + break; + case 19200000: + hsscll = i2c_data->hsscll_19_2; + break; + case 16800000: + hsscll = i2c_data->hsscll_16_8; + break; + case 12000000: + hsscll = i2c_data->hsscll_12; + break; + default: + pr_warn("%s: unsupported sysclk rate: %d!\n", __func__, + voltdm->sys_clk.rate); + return; + } + + /* Loadbits define pull setup for the I2C channels */ + val = i2c_data->loadbits << 25 | i2c_data->loadbits << 29; + + /* Write to SYSCTRL_PADCONF_WKUP_CTRL_I2C_2 to setup I2C pull */ + writel_relaxed(val, OMAP2_L4_IO_ADDRESS(OMAP4_CTRL_MODULE_PAD_WKUP + + OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_I2C_2)); + + /* HSSCLH can always be zero */ + val = hsscll << OMAP4430_HSSCLL_SHIFT; + val |= (0x28 << OMAP4430_SCLL_SHIFT | 0x2c << OMAP4430_SCLH_SHIFT); + + /* Write setup times to I2C config register */ + voltdm->write(val, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET); +} + + + +/** + * omap_vc_i2c_init - initialize I2C interface to PMIC + * @voltdm: voltage domain containing VC data + * + * Use PMIC supplied settings for I2C high-speed mode and + * master code (if set) and program the VC I2C configuration + * register. + * + * The VC I2C configuration is common to all VC channels, + * so this function only configures I2C for the first VC + * channel registers. All other VC channels will use the + * same configuration. + */ +static void __init omap_vc_i2c_init(struct voltagedomain *voltdm) +{ + struct omap_vc_channel *vc = voltdm->vc; + static bool initialized; + static bool i2c_high_speed; + u8 mcode; + + if (initialized) { + if (voltdm->pmic->i2c_high_speed != i2c_high_speed) + pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).\n", + __func__, voltdm->name, i2c_high_speed); + return; + } + + i2c_high_speed = voltdm->pmic->i2c_high_speed; + if (i2c_high_speed) + voltdm->rmw(vc->common->i2c_cfg_hsen_mask, + vc->common->i2c_cfg_hsen_mask, + vc->common->i2c_cfg_reg); + + mcode = voltdm->pmic->i2c_mcode; + if (mcode) + voltdm->rmw(vc->common->i2c_mcode_mask, + mcode << __ffs(vc->common->i2c_mcode_mask), + vc->common->i2c_cfg_reg); + + if (cpu_is_omap44xx()) + omap4_vc_i2c_timing_init(voltdm); + + initialized = true; +} + +/** + * omap_vc_calc_vsel - calculate vsel value for a channel + * @voltdm: channel to calculate value for + * @uvolt: microvolt value to convert to vsel + * + * Converts a microvolt value to vsel value for the used PMIC. + * This checks whether the microvolt value is out of bounds, and + * adjusts the value accordingly. If unsupported value detected, + * warning is thrown. + */ +static u8 omap_vc_calc_vsel(struct voltagedomain *voltdm, u32 uvolt) +{ + if (voltdm->pmic->vddmin > uvolt) + uvolt = voltdm->pmic->vddmin; + if (voltdm->pmic->vddmax < uvolt) { + WARN(1, "%s: voltage not supported by pmic: %u vs max %u\n", + __func__, uvolt, voltdm->pmic->vddmax); + /* Lets try maximum value anyway */ + uvolt = voltdm->pmic->vddmax; + } + + return voltdm->pmic->uv_to_vsel(uvolt); +} + +#ifdef CONFIG_PM +/** + * omap_pm_setup_sr_i2c_pcb_length - set length of SR I2C traces on PCB + * @mm: length of the PCB trace in millimetres + * + * Sets the PCB trace length for the I2C channel. By default uses 63mm. + * This is needed for properly calculating the capacitance value for + * the PCB trace, and for setting the SR I2C channel timing parameters. + */ +void __init omap_pm_setup_sr_i2c_pcb_length(u32 mm) +{ + sr_i2c_pcb_length = mm; +} +#endif + +void __init omap_vc_init_channel(struct voltagedomain *voltdm) +{ + struct omap_vc_channel *vc = voltdm->vc; + u8 on_vsel, onlp_vsel, ret_vsel, off_vsel; + u32 val; + + if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) { + pr_err("%s: No PMIC info for vdd_%s\n", __func__, voltdm->name); + return; + } + + if (!voltdm->read || !voltdm->write) { + pr_err("%s: No read/write API for accessing vdd_%s regs\n", + __func__, voltdm->name); + return; + } + + vc->cfg_channel = 0; + if (vc->flags & OMAP_VC_CHANNEL_CFG_MUTANT) + vc_cfg_bits = &vc_mutant_channel_cfg; + else + vc_cfg_bits = &vc_default_channel_cfg; + + /* get PMIC/board specific settings */ + vc->i2c_slave_addr = voltdm->pmic->i2c_slave_addr; + vc->volt_reg_addr = voltdm->pmic->volt_reg_addr; + vc->cmd_reg_addr = voltdm->pmic->cmd_reg_addr; + + /* Configure the i2c slave address for this VC */ + voltdm->rmw(vc->smps_sa_mask, + vc->i2c_slave_addr << __ffs(vc->smps_sa_mask), + vc->smps_sa_reg); + vc->cfg_channel |= vc_cfg_bits->sa; + + /* + * Configure the PMIC register addresses. + */ + voltdm->rmw(vc->smps_volra_mask, + vc->volt_reg_addr << __ffs(vc->smps_volra_mask), + vc->smps_volra_reg); + vc->cfg_channel |= vc_cfg_bits->rav; + + if (vc->cmd_reg_addr) { + voltdm->rmw(vc->smps_cmdra_mask, + vc->cmd_reg_addr << __ffs(vc->smps_cmdra_mask), + vc->smps_cmdra_reg); + vc->cfg_channel |= vc_cfg_bits->rac; + } + + if (vc->cmd_reg_addr == vc->volt_reg_addr) + vc->cfg_channel |= vc_cfg_bits->racen; + + /* Set up the on, inactive, retention and off voltage */ + on_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->on); + onlp_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->onlp); + ret_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->ret); + off_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->off); + + val = ((on_vsel << vc->common->cmd_on_shift) | + (onlp_vsel << vc->common->cmd_onlp_shift) | + (ret_vsel << vc->common->cmd_ret_shift) | + (off_vsel << vc->common->cmd_off_shift)); + voltdm->write(val, vc->cmdval_reg); + vc->cfg_channel |= vc_cfg_bits->cmd; + + /* Channel configuration */ + omap_vc_config_channel(voltdm); + + omap_vc_i2c_init(voltdm); + + if (cpu_is_omap34xx()) + omap3_vc_init_channel(voltdm); + else if (cpu_is_omap44xx()) + omap4_vc_init_channel(voltdm); +} + diff --git a/arch/arm/mach-omap2/vc.h b/arch/arm/mach-omap2/vc.h new file mode 100644 index 00000000000..cdbdd78e755 --- /dev/null +++ b/arch/arm/mach-omap2/vc.h @@ -0,0 +1,134 @@ +/* + * OMAP3/4 Voltage Controller (VC) structure and macro definitions + * + * Copyright (C) 2007, 2010 Texas Instruments, Inc. + * Rajendra Nayak <rnayak@ti.com> + * Lesly A M <x0080970@ti.com> + * Thara Gopinath <thara@ti.com> + * + * Copyright (C) 2008, 2011 Nokia Corporation + * Kalle Jokiniemi + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + */ +#ifndef __ARCH_ARM_MACH_OMAP2_VC_H +#define __ARCH_ARM_MACH_OMAP2_VC_H + +#include <linux/kernel.h> + +struct voltagedomain; + +/** + * struct omap_vc_common - per-VC register/bitfield data + * @cmd_on_mask: ON bitmask in PRM_VC_CMD_VAL* register + * @valid: VALID bitmask in PRM_VC_BYPASS_VAL register + * @bypass_val_reg: Offset of PRM_VC_BYPASS_VAL reg from PRM start + * @data_shift: DATA field shift in PRM_VC_BYPASS_VAL register + * @slaveaddr_shift: SLAVEADDR field shift in PRM_VC_BYPASS_VAL register + * @regaddr_shift: REGADDR field shift in PRM_VC_BYPASS_VAL register + * @cmd_on_shift: ON field shift in PRM_VC_CMD_VAL_* register + * @cmd_onlp_shift: ONLP field shift in PRM_VC_CMD_VAL_* register + * @cmd_ret_shift: RET field shift in PRM_VC_CMD_VAL_* register + * @cmd_off_shift: OFF field shift in PRM_VC_CMD_VAL_* register + * @i2c_cfg_reg: I2C configuration register offset + * @i2c_cfg_hsen_mask: high-speed mode bit field mask in I2C config register + * @i2c_mcode_mask: MCODE field mask for I2C config register + * + * XXX One of cmd_on_mask and cmd_on_shift are not needed + * XXX VALID should probably be a shift, not a mask + */ +struct omap_vc_common { + u32 cmd_on_mask; + u32 valid; + u8 bypass_val_reg; + u8 data_shift; + u8 slaveaddr_shift; + u8 regaddr_shift; + u8 cmd_on_shift; + u8 cmd_onlp_shift; + u8 cmd_ret_shift; + u8 cmd_off_shift; + u8 i2c_cfg_reg; + u8 i2c_cfg_hsen_mask; + u8 i2c_mcode_mask; +}; + +/* omap_vc_channel.flags values */ +#define OMAP_VC_CHANNEL_DEFAULT BIT(0) +#define OMAP_VC_CHANNEL_CFG_MUTANT BIT(1) + +/** + * struct omap_vc_channel - VC per-instance data + * @i2c_slave_addr: I2C slave address of PMIC for this VC channel + * @volt_reg_addr: voltage configuration register address + * @cmd_reg_addr: command configuration register address + * @setup_time: setup time (in sys_clk cycles) of regulator for this channel + * @cfg_channel: current value of VC channel configuration register + * @i2c_high_speed: whether or not to use I2C high-speed mode + * + * @common: pointer to VC common data for this platform + * @smps_sa_mask: i2c slave address bitmask in the PRM_VC_SMPS_SA register + * @smps_volra_mask: VOLRA* bitmask in the PRM_VC_VOL_RA register + * @smps_cmdra_mask: CMDRA* bitmask in the PRM_VC_CMD_RA register + * @cmdval_reg: register for on/ret/off voltage level values for this channel + * @smps_sa_reg: Offset of PRM_VC_SMPS_SA reg from PRM start + * @smps_volra_reg: Offset of PRM_VC_SMPS_VOL_RA reg from PRM start + * @smps_cmdra_reg: Offset of PRM_VC_SMPS_CMD_RA reg from PRM start + * @cfg_channel_reg: VC channel configuration register + * @cfg_channel_sa_shift: bit shift for slave address cfg_channel register + * @flags: VC channel-specific flags (optional) + */ +struct omap_vc_channel { + /* channel state */ + u16 i2c_slave_addr; + u16 volt_reg_addr; + u16 cmd_reg_addr; + u8 cfg_channel; + bool i2c_high_speed; + + /* register access data */ + const struct omap_vc_common *common; + u32 smps_sa_mask; + u32 smps_volra_mask; + u32 smps_cmdra_mask; + u8 cmdval_reg; + u8 smps_sa_reg; + u8 smps_volra_reg; + u8 smps_cmdra_reg; + u8 cfg_channel_reg; + u8 cfg_channel_sa_shift; + u8 flags; +}; + +extern struct omap_vc_channel omap3_vc_mpu; +extern struct omap_vc_channel omap3_vc_core; + +extern struct omap_vc_channel omap4_vc_mpu; +extern struct omap_vc_channel omap4_vc_iva; +extern struct omap_vc_channel omap4_vc_core; + +extern struct omap_vc_param omap3_mpu_vc_data; +extern struct omap_vc_param omap3_core_vc_data; + +extern struct omap_vc_param omap4_mpu_vc_data; +extern struct omap_vc_param omap4_iva_vc_data; +extern struct omap_vc_param omap4_core_vc_data; + +void omap3_vc_set_pmic_signaling(int core_next_state); + + +void omap_vc_init_channel(struct voltagedomain *voltdm); +int omap_vc_pre_scale(struct voltagedomain *voltdm, + unsigned long target_volt, + u8 *target_vsel, u8 *current_vsel); +void omap_vc_post_scale(struct voltagedomain *voltdm, + unsigned long target_volt, + u8 target_vsel, u8 current_vsel); +int omap_vc_bypass_scale(struct voltagedomain *voltdm, + unsigned long target_volt); + +#endif + diff --git a/arch/arm/mach-omap2/vc3xxx_data.c b/arch/arm/mach-omap2/vc3xxx_data.c new file mode 100644 index 00000000000..75bc4aa22b3 --- /dev/null +++ b/arch/arm/mach-omap2/vc3xxx_data.c @@ -0,0 +1,95 @@ +/* + * OMAP3 Voltage Controller (VC) data + * + * Copyright (C) 2007, 2010 Texas Instruments, Inc. + * Rajendra Nayak <rnayak@ti.com> + * Lesly A M <x0080970@ti.com> + * Thara Gopinath <thara@ti.com> + * + * Copyright (C) 2008, 2011 Nokia Corporation + * Kalle Jokiniemi + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/io.h> +#include <linux/err.h> +#include <linux/init.h> + +#include "common.h" + +#include "prm-regbits-34xx.h" +#include "voltage.h" + +#include "vc.h" + +/* + * VC data common to 34xx/36xx chips + * XXX This stuff presumably belongs in the vc3xxx.c or vc.c file. + */ +static struct omap_vc_common omap3_vc_common = { + .bypass_val_reg = OMAP3_PRM_VC_BYPASS_VAL_OFFSET, + .data_shift = OMAP3430_DATA_SHIFT, + .slaveaddr_shift = OMAP3430_SLAVEADDR_SHIFT, + .regaddr_shift = OMAP3430_REGADDR_SHIFT, + .valid = OMAP3430_VALID_MASK, + .cmd_on_shift = OMAP3430_VC_CMD_ON_SHIFT, + .cmd_on_mask = OMAP3430_VC_CMD_ON_MASK, + .cmd_onlp_shift = OMAP3430_VC_CMD_ONLP_SHIFT, + .cmd_ret_shift = OMAP3430_VC_CMD_RET_SHIFT, + .cmd_off_shift = OMAP3430_VC_CMD_OFF_SHIFT, + .i2c_cfg_hsen_mask = OMAP3430_HSEN_MASK, + .i2c_cfg_reg = OMAP3_PRM_VC_I2C_CFG_OFFSET, + .i2c_mcode_mask = OMAP3430_MCODE_MASK, +}; + +struct omap_vc_channel omap3_vc_mpu = { + .flags = OMAP_VC_CHANNEL_DEFAULT, + .common = &omap3_vc_common, + .smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET, + .smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET, + .smps_cmdra_reg = OMAP3_PRM_VC_SMPS_CMD_RA_OFFSET, + .cfg_channel_reg = OMAP3_PRM_VC_CH_CONF_OFFSET, + .cmdval_reg = OMAP3_PRM_VC_CMD_VAL_0_OFFSET, + .smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA0_MASK, + .smps_volra_mask = OMAP3430_VOLRA0_MASK, + .smps_cmdra_mask = OMAP3430_CMDRA0_MASK, + .cfg_channel_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT, +}; + +struct omap_vc_channel omap3_vc_core = { + .common = &omap3_vc_common, + .smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET, + .smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET, + .smps_cmdra_reg = OMAP3_PRM_VC_SMPS_CMD_RA_OFFSET, + .cfg_channel_reg = OMAP3_PRM_VC_CH_CONF_OFFSET, + .cmdval_reg = OMAP3_PRM_VC_CMD_VAL_1_OFFSET, + .smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA1_MASK, + .smps_volra_mask = OMAP3430_VOLRA1_MASK, + .smps_cmdra_mask = OMAP3430_CMDRA1_MASK, + .cfg_channel_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT, +}; + +/* + * Voltage levels for different operating modes: on, sleep, retention and off + */ +#define OMAP3_ON_VOLTAGE_UV 1200000 +#define OMAP3_ONLP_VOLTAGE_UV 1000000 +#define OMAP3_RET_VOLTAGE_UV 975000 +#define OMAP3_OFF_VOLTAGE_UV 600000 + +struct omap_vc_param omap3_mpu_vc_data = { + .on = OMAP3_ON_VOLTAGE_UV, + .onlp = OMAP3_ONLP_VOLTAGE_UV, + .ret = OMAP3_RET_VOLTAGE_UV, + .off = OMAP3_OFF_VOLTAGE_UV, +}; + +struct omap_vc_param omap3_core_vc_data = { + .on = OMAP3_ON_VOLTAGE_UV, + .onlp = OMAP3_ONLP_VOLTAGE_UV, + .ret = OMAP3_RET_VOLTAGE_UV, + .off = OMAP3_OFF_VOLTAGE_UV, +}; diff --git a/arch/arm/mach-omap2/vc44xx_data.c b/arch/arm/mach-omap2/vc44xx_data.c new file mode 100644 index 00000000000..085e5d6a04f --- /dev/null +++ b/arch/arm/mach-omap2/vc44xx_data.c @@ -0,0 +1,117 @@ +/* + * OMAP4 Voltage Controller (VC) data + * + * Copyright (C) 2007, 2010 Texas Instruments, Inc. + * Rajendra Nayak <rnayak@ti.com> + * Lesly A M <x0080970@ti.com> + * Thara Gopinath <thara@ti.com> + * + * Copyright (C) 2008, 2011 Nokia Corporation + * Kalle Jokiniemi + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/io.h> +#include <linux/err.h> +#include <linux/init.h> + +#include "common.h" + +#include "prm44xx.h" +#include "prm-regbits-44xx.h" +#include "voltage.h" + +#include "vc.h" + +/* + * VC data common to 44xx chips + * XXX This stuff presumably belongs in the vc3xxx.c or vc.c file. + */ +static const struct omap_vc_common omap4_vc_common = { + .bypass_val_reg = OMAP4_PRM_VC_VAL_BYPASS_OFFSET, + .data_shift = OMAP4430_DATA_SHIFT, + .slaveaddr_shift = OMAP4430_SLAVEADDR_SHIFT, + .regaddr_shift = OMAP4430_REGADDR_SHIFT, + .valid = OMAP4430_VALID_MASK, + .cmd_on_shift = OMAP4430_ON_SHIFT, + .cmd_on_mask = OMAP4430_ON_MASK, + .cmd_onlp_shift = OMAP4430_ONLP_SHIFT, + .cmd_ret_shift = OMAP4430_RET_SHIFT, + .cmd_off_shift = OMAP4430_OFF_SHIFT, + .i2c_cfg_reg = OMAP4_PRM_VC_CFG_I2C_MODE_OFFSET, + .i2c_cfg_hsen_mask = OMAP4430_HSMODEEN_MASK, + .i2c_mcode_mask = OMAP4430_HSMCODE_MASK, +}; + +/* VC instance data for each controllable voltage line */ +struct omap_vc_channel omap4_vc_mpu = { + .flags = OMAP_VC_CHANNEL_DEFAULT | OMAP_VC_CHANNEL_CFG_MUTANT, + .common = &omap4_vc_common, + .smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET, + .smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET, + .smps_cmdra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_CMD_OFFSET, + .cfg_channel_reg = OMAP4_PRM_VC_CFG_CHANNEL_OFFSET, + .cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET, + .smps_sa_mask = OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK, + .smps_volra_mask = OMAP4430_VOLRA_VDD_MPU_L_MASK, + .smps_cmdra_mask = OMAP4430_CMDRA_VDD_MPU_L_MASK, + .cfg_channel_sa_shift = OMAP4430_SA_VDD_MPU_L_SHIFT, +}; + +struct omap_vc_channel omap4_vc_iva = { + .common = &omap4_vc_common, + .smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET, + .smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET, + .smps_cmdra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_CMD_OFFSET, + .cfg_channel_reg = OMAP4_PRM_VC_CFG_CHANNEL_OFFSET, + .cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET, + .smps_sa_mask = OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK, + .smps_volra_mask = OMAP4430_VOLRA_VDD_IVA_L_MASK, + .smps_cmdra_mask = OMAP4430_CMDRA_VDD_IVA_L_MASK, + .cfg_channel_sa_shift = OMAP4430_SA_VDD_IVA_L_SHIFT, +}; + +struct omap_vc_channel omap4_vc_core = { + .common = &omap4_vc_common, + .smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET, + .smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET, + .smps_cmdra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_CMD_OFFSET, + .cfg_channel_reg = OMAP4_PRM_VC_CFG_CHANNEL_OFFSET, + .cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET, + .smps_sa_mask = OMAP4430_SA_VDD_CORE_L_0_6_MASK, + .smps_volra_mask = OMAP4430_VOLRA_VDD_CORE_L_MASK, + .smps_cmdra_mask = OMAP4430_CMDRA_VDD_CORE_L_MASK, + .cfg_channel_sa_shift = OMAP4430_SA_VDD_CORE_L_SHIFT, +}; + +/* + * Voltage levels for different operating modes: on, sleep, retention and off + */ +#define OMAP4_ON_VOLTAGE_UV 1375000 +#define OMAP4_ONLP_VOLTAGE_UV 1375000 +#define OMAP4_RET_VOLTAGE_UV 837500 +#define OMAP4_OFF_VOLTAGE_UV 0 + +struct omap_vc_param omap4_mpu_vc_data = { + .on = OMAP4_ON_VOLTAGE_UV, + .onlp = OMAP4_ONLP_VOLTAGE_UV, + .ret = OMAP4_RET_VOLTAGE_UV, + .off = OMAP4_OFF_VOLTAGE_UV, +}; + +struct omap_vc_param omap4_iva_vc_data = { + .on = OMAP4_ON_VOLTAGE_UV, + .onlp = OMAP4_ONLP_VOLTAGE_UV, + .ret = OMAP4_RET_VOLTAGE_UV, + .off = OMAP4_OFF_VOLTAGE_UV, +}; + +struct omap_vc_param omap4_core_vc_data = { + .on = OMAP4_ON_VOLTAGE_UV, + .onlp = OMAP4_ONLP_VOLTAGE_UV, + .ret = OMAP4_RET_VOLTAGE_UV, + .off = OMAP4_OFF_VOLTAGE_UV, +}; diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c new file mode 100644 index 00000000000..3ac8fe1d821 --- /dev/null +++ b/arch/arm/mach-omap2/voltage.c @@ -0,0 +1,446 @@ +/* + * OMAP3/OMAP4 Voltage Management Routines + * + * Author: Thara Gopinath <thara@ti.com> + * + * Copyright (C) 2007 Texas Instruments, Inc. + * Rajendra Nayak <rnayak@ti.com> + * Lesly A M <x0080970@ti.com> + * + * Copyright (C) 2008, 2011 Nokia Corporation + * Kalle Jokiniemi + * Paul Walmsley + * + * Copyright (C) 2010 Texas Instruments, Inc. + * Thara Gopinath <thara@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/export.h> +#include <linux/debugfs.h> +#include <linux/slab.h> +#include <linux/clk.h> + +#include "common.h" + +#include "prm-regbits-34xx.h" +#include "prm-regbits-44xx.h" +#include "prm44xx.h" +#include "prcm44xx.h" +#include "prminst44xx.h" +#include "control.h" + +#include "voltage.h" +#include "powerdomain.h" + +#include "vc.h" +#include "vp.h" + +static LIST_HEAD(voltdm_list); + +/* Public functions */ +/** + * voltdm_get_voltage() - Gets the current non-auto-compensated voltage + * @voltdm: pointer to the voltdm for which current voltage info is needed + * + * API to get the current non-auto-compensated voltage for a voltage domain. + * Returns 0 in case of error else returns the current voltage. + */ +unsigned long voltdm_get_voltage(struct voltagedomain *voltdm) +{ + if (!voltdm || IS_ERR(voltdm)) { + pr_warning("%s: VDD specified does not exist!\n", __func__); + return 0; + } + + return voltdm->nominal_volt; +} + +/** + * voltdm_scale() - API to scale voltage of a particular voltage domain. + * @voltdm: pointer to the voltage domain which is to be scaled. + * @target_volt: The target voltage of the voltage domain + * + * This API should be called by the kernel to do the voltage scaling + * for a particular voltage domain during DVFS. + */ +int voltdm_scale(struct voltagedomain *voltdm, + unsigned long target_volt) +{ + int ret, i; + unsigned long volt = 0; + + if (!voltdm || IS_ERR(voltdm)) { + pr_warning("%s: VDD specified does not exist!\n", __func__); + return -EINVAL; + } + + if (!voltdm->scale) { + pr_err("%s: No voltage scale API registered for vdd_%s\n", + __func__, voltdm->name); + return -ENODATA; + } + + /* Adjust voltage to the exact voltage from the OPP table */ + for (i = 0; voltdm->volt_data[i].volt_nominal != 0; i++) { + if (voltdm->volt_data[i].volt_nominal >= target_volt) { + volt = voltdm->volt_data[i].volt_nominal; + break; + } + } + + if (!volt) { + pr_warning("%s: not scaling. OPP voltage for %lu, not found.\n", + __func__, target_volt); + return -EINVAL; + } + + ret = voltdm->scale(voltdm, volt); + if (!ret) + voltdm->nominal_volt = volt; + + return ret; +} + +/** + * voltdm_reset() - Resets the voltage of a particular voltage domain + * to that of the current OPP. + * @voltdm: pointer to the voltage domain whose voltage is to be reset. + * + * This API finds out the correct voltage the voltage domain is supposed + * to be at and resets the voltage to that level. Should be used especially + * while disabling any voltage compensation modules. + */ +void voltdm_reset(struct voltagedomain *voltdm) +{ + unsigned long target_volt; + + if (!voltdm || IS_ERR(voltdm)) { + pr_warning("%s: VDD specified does not exist!\n", __func__); + return; + } + + target_volt = voltdm_get_voltage(voltdm); + if (!target_volt) { + pr_err("%s: unable to find current voltage for vdd_%s\n", + __func__, voltdm->name); + return; + } + + voltdm_scale(voltdm, target_volt); +} + +/** + * omap_voltage_get_volttable() - API to get the voltage table associated with a + * particular voltage domain. + * @voltdm: pointer to the VDD for which the voltage table is required + * @volt_data: the voltage table for the particular vdd which is to be + * populated by this API + * + * This API populates the voltage table associated with a VDD into the + * passed parameter pointer. Returns the count of distinct voltages + * supported by this vdd. + * + */ +void omap_voltage_get_volttable(struct voltagedomain *voltdm, + struct omap_volt_data **volt_data) +{ + if (!voltdm || IS_ERR(voltdm)) { + pr_warning("%s: VDD specified does not exist!\n", __func__); + return; + } + + *volt_data = voltdm->volt_data; +} + +/** + * omap_voltage_get_voltdata() - API to get the voltage table entry for a + * particular voltage + * @voltdm: pointer to the VDD whose voltage table has to be searched + * @volt: the voltage to be searched in the voltage table + * + * This API searches through the voltage table for the required voltage + * domain and tries to find a matching entry for the passed voltage volt. + * If a matching entry is found volt_data is populated with that entry. + * This API searches only through the non-compensated voltages int the + * voltage table. + * Returns pointer to the voltage table entry corresponding to volt on + * success. Returns -ENODATA if no voltage table exisits for the passed voltage + * domain or if there is no matching entry. + */ +struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm, + unsigned long volt) +{ + int i; + + if (!voltdm || IS_ERR(voltdm)) { + pr_warning("%s: VDD specified does not exist!\n", __func__); + return ERR_PTR(-EINVAL); + } + + if (!voltdm->volt_data) { + pr_warning("%s: voltage table does not exist for vdd_%s\n", + __func__, voltdm->name); + return ERR_PTR(-ENODATA); + } + + for (i = 0; voltdm->volt_data[i].volt_nominal != 0; i++) { + if (voltdm->volt_data[i].volt_nominal == volt) + return &voltdm->volt_data[i]; + } + + pr_notice("%s: Unable to match the current voltage with the voltage table for vdd_%s\n", + __func__, voltdm->name); + + return ERR_PTR(-ENODATA); +} + +/** + * omap_voltage_register_pmic() - API to register PMIC specific data + * @voltdm: pointer to the VDD for which the PMIC specific data is + * to be registered + * @pmic: the structure containing pmic info + * + * This API is to be called by the SOC/PMIC file to specify the + * pmic specific info as present in omap_voltdm_pmic structure. + */ +int omap_voltage_register_pmic(struct voltagedomain *voltdm, + struct omap_voltdm_pmic *pmic) +{ + if (!voltdm || IS_ERR(voltdm)) { + pr_warning("%s: VDD specified does not exist!\n", __func__); + return -EINVAL; + } + + voltdm->pmic = pmic; + + return 0; +} + +/** + * omap_change_voltscale_method() - API to change the voltage scaling method. + * @voltdm: pointer to the VDD whose voltage scaling method + * has to be changed. + * @voltscale_method: the method to be used for voltage scaling. + * + * This API can be used by the board files to change the method of voltage + * scaling between vpforceupdate and vcbypass. The parameter values are + * defined in voltage.h + */ +void omap_change_voltscale_method(struct voltagedomain *voltdm, + int voltscale_method) +{ + if (!voltdm || IS_ERR(voltdm)) { + pr_warning("%s: VDD specified does not exist!\n", __func__); + return; + } + + switch (voltscale_method) { + case VOLTSCALE_VPFORCEUPDATE: + voltdm->scale = omap_vp_forceupdate_scale; + return; + case VOLTSCALE_VCBYPASS: + voltdm->scale = omap_vc_bypass_scale; + return; + default: + pr_warn("%s: Trying to change the method of voltage scaling to an unsupported one!\n", + __func__); + } +} + +/** + * omap_voltage_late_init() - Init the various voltage parameters + * + * This API is to be called in the later stages of the + * system boot to init the voltage controller and + * voltage processors. + */ +int __init omap_voltage_late_init(void) +{ + struct voltagedomain *voltdm; + + if (list_empty(&voltdm_list)) { + pr_err("%s: Voltage driver support not added\n", + __func__); + return -EINVAL; + } + + list_for_each_entry(voltdm, &voltdm_list, node) { + struct clk *sys_ck; + + if (!voltdm->scalable) + continue; + + sys_ck = clk_get(NULL, voltdm->sys_clk.name); + if (IS_ERR(sys_ck)) { + pr_warning("%s: Could not get sys clk.\n", __func__); + return -EINVAL; + } + voltdm->sys_clk.rate = clk_get_rate(sys_ck); + WARN_ON(!voltdm->sys_clk.rate); + clk_put(sys_ck); + + if (voltdm->vc) { + voltdm->scale = omap_vc_bypass_scale; + omap_vc_init_channel(voltdm); + } + + if (voltdm->vp) { + voltdm->scale = omap_vp_forceupdate_scale; + omap_vp_init(voltdm); + } + } + + return 0; +} + +static struct voltagedomain *_voltdm_lookup(const char *name) +{ + struct voltagedomain *voltdm, *temp_voltdm; + + voltdm = NULL; + + list_for_each_entry(temp_voltdm, &voltdm_list, node) { + if (!strcmp(name, temp_voltdm->name)) { + voltdm = temp_voltdm; + break; + } + } + + return voltdm; +} + +/** + * voltdm_add_pwrdm - add a powerdomain to a voltagedomain + * @voltdm: struct voltagedomain * to add the powerdomain to + * @pwrdm: struct powerdomain * to associate with a voltagedomain + * + * Associate the powerdomain @pwrdm with a voltagedomain @voltdm. This + * enables the use of voltdm_for_each_pwrdm(). Returns -EINVAL if + * presented with invalid pointers; -ENOMEM if memory could not be allocated; + * or 0 upon success. + */ +int voltdm_add_pwrdm(struct voltagedomain *voltdm, struct powerdomain *pwrdm) +{ + if (!voltdm || !pwrdm) + return -EINVAL; + + pr_debug("voltagedomain: %s: associating powerdomain %s\n", + voltdm->name, pwrdm->name); + + list_add(&pwrdm->voltdm_node, &voltdm->pwrdm_list); + + return 0; +} + +/** + * voltdm_for_each_pwrdm - call function for each pwrdm in a voltdm + * @voltdm: struct voltagedomain * to iterate over + * @fn: callback function * + * + * Call the supplied function @fn for each powerdomain in the + * voltagedomain @voltdm. Returns -EINVAL if presented with invalid + * pointers; or passes along the last return value of the callback + * function, which should be 0 for success or anything else to + * indicate failure. + */ +int voltdm_for_each_pwrdm(struct voltagedomain *voltdm, + int (*fn)(struct voltagedomain *voltdm, + struct powerdomain *pwrdm)) +{ + struct powerdomain *pwrdm; + int ret = 0; + + if (!fn) + return -EINVAL; + + list_for_each_entry(pwrdm, &voltdm->pwrdm_list, voltdm_node) + ret = (*fn)(voltdm, pwrdm); + + return ret; +} + +/** + * voltdm_for_each - call function on each registered voltagedomain + * @fn: callback function * + * + * Call the supplied function @fn for each registered voltagedomain. + * The callback function @fn can return anything but 0 to bail out + * early from the iterator. Returns the last return value of the + * callback function, which should be 0 for success or anything else + * to indicate failure; or -EINVAL if the function pointer is null. + */ +int voltdm_for_each(int (*fn)(struct voltagedomain *voltdm, void *user), + void *user) +{ + struct voltagedomain *temp_voltdm; + int ret = 0; + + if (!fn) + return -EINVAL; + + list_for_each_entry(temp_voltdm, &voltdm_list, node) { + ret = (*fn)(temp_voltdm, user); + if (ret) + break; + } + + return ret; +} + +static int _voltdm_register(struct voltagedomain *voltdm) +{ + if (!voltdm || !voltdm->name) + return -EINVAL; + + INIT_LIST_HEAD(&voltdm->pwrdm_list); + list_add(&voltdm->node, &voltdm_list); + + pr_debug("voltagedomain: registered %s\n", voltdm->name); + + return 0; +} + +/** + * voltdm_lookup - look up a voltagedomain by name, return a pointer + * @name: name of voltagedomain + * + * Find a registered voltagedomain by its name @name. Returns a pointer + * to the struct voltagedomain if found, or NULL otherwise. + */ +struct voltagedomain *voltdm_lookup(const char *name) +{ + struct voltagedomain *voltdm ; + + if (!name) + return NULL; + + voltdm = _voltdm_lookup(name); + + return voltdm; +} + +/** + * voltdm_init - set up the voltagedomain layer + * @voltdm_list: array of struct voltagedomain pointers to register + * + * Loop through the array of voltagedomains @voltdm_list, registering all + * that are available on the current CPU. If voltdm_list is supplied + * and not null, all of the referenced voltagedomains will be + * registered. No return value. + */ +void voltdm_init(struct voltagedomain **voltdms) +{ + struct voltagedomain **v; + + if (voltdms) { + for (v = voltdms; *v; v++) + _voltdm_register(*v); + } +} diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h new file mode 100644 index 00000000000..f7f2879b31b --- /dev/null +++ b/arch/arm/mach-omap2/voltage.h @@ -0,0 +1,186 @@ +/* + * OMAP Voltage Management Routines + * + * Author: Thara Gopinath <thara@ti.com> + * + * Copyright (C) 2009 Texas Instruments, Inc. + * Thara Gopinath <thara@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_VOLTAGE_H +#define __ARCH_ARM_MACH_OMAP2_VOLTAGE_H + +#include <linux/err.h> + +#include <linux/platform_data/voltage-omap.h> + +#include "vc.h" +#include "vp.h" + +struct powerdomain; + +/* XXX document */ +#define VOLTSCALE_VPFORCEUPDATE 1 +#define VOLTSCALE_VCBYPASS 2 + +/* + * OMAP3 GENERIC setup times. Revisit to see if these needs to be + * passed from board or PMIC file + */ +#define OMAP3_CLKSETUP 0xff +#define OMAP3_VOLTOFFSET 0xff +#define OMAP3_VOLTSETUP2 0xff + +/** + * struct omap_vfsm_instance - per-voltage manager FSM register/bitfield + * data + * @voltsetup_mask: SETUP_TIME* bitmask in the PRM_VOLTSETUP* register + * @voltsetup_reg: register offset of PRM_VOLTSETUP from PRM base + * @voltsetup_off_reg: register offset of PRM_VOLTSETUP_OFF from PRM base + * + * XXX What about VOLTOFFSET/VOLTCTRL? + */ +struct omap_vfsm_instance { + u32 voltsetup_mask; + u8 voltsetup_reg; + u8 voltsetup_off_reg; +}; + +/** + * struct voltagedomain - omap voltage domain global structure. + * @name: Name of the voltage domain which can be used as a unique identifier. + * @scalable: Whether or not this voltage domain is scalable + * @node: list_head linking all voltage domains + * @pwrdm_list: list_head linking all powerdomains in this voltagedomain + * @vc: pointer to VC channel associated with this voltagedomain + * @vp: pointer to VP associated with this voltagedomain + * @read: read a VC/VP register + * @write: write a VC/VP register + * @read: read-modify-write a VC/VP register + * @sys_clk: system clock name/frequency, used for various timing calculations + * @scale: function used to scale the voltage of the voltagedomain + * @nominal_volt: current nominal voltage for this voltage domain + * @volt_data: voltage table having the distinct voltages supported + * by the domain and other associated per voltage data. + */ +struct voltagedomain { + char *name; + bool scalable; + struct list_head node; + struct list_head pwrdm_list; + struct omap_vc_channel *vc; + const struct omap_vfsm_instance *vfsm; + struct omap_vp_instance *vp; + struct omap_voltdm_pmic *pmic; + struct omap_vp_param *vp_param; + struct omap_vc_param *vc_param; + + /* VC/VP register access functions: SoC specific */ + u32 (*read) (u8 offset); + void (*write) (u32 val, u8 offset); + u32 (*rmw)(u32 mask, u32 bits, u8 offset); + + union { + const char *name; + u32 rate; + } sys_clk; + + int (*scale) (struct voltagedomain *voltdm, + unsigned long target_volt); + + u32 nominal_volt; + struct omap_volt_data *volt_data; +}; + +/* Min and max voltages from OMAP perspective */ +#define OMAP3430_VP1_VLIMITTO_VDDMIN 850000 +#define OMAP3430_VP1_VLIMITTO_VDDMAX 1425000 +#define OMAP3430_VP2_VLIMITTO_VDDMIN 900000 +#define OMAP3430_VP2_VLIMITTO_VDDMAX 1150000 + +#define OMAP3630_VP1_VLIMITTO_VDDMIN 900000 +#define OMAP3630_VP1_VLIMITTO_VDDMAX 1350000 +#define OMAP3630_VP2_VLIMITTO_VDDMIN 900000 +#define OMAP3630_VP2_VLIMITTO_VDDMAX 1200000 + +#define OMAP4_VP_MPU_VLIMITTO_VDDMIN 830000 +#define OMAP4_VP_MPU_VLIMITTO_VDDMAX 1410000 +#define OMAP4_VP_IVA_VLIMITTO_VDDMIN 830000 +#define OMAP4_VP_IVA_VLIMITTO_VDDMAX 1260000 +#define OMAP4_VP_CORE_VLIMITTO_VDDMIN 830000 +#define OMAP4_VP_CORE_VLIMITTO_VDDMAX 1200000 + +/** + * struct omap_voltdm_pmic - PMIC specific data required by voltage driver. + * @slew_rate: PMIC slew rate (in uv/us) + * @step_size: PMIC voltage step size (in uv) + * @i2c_slave_addr: I2C slave address of PMIC + * @volt_reg_addr: voltage configuration register address + * @cmd_reg_addr: command (on, on-LP, ret, off) configuration register address + * @i2c_high_speed: whether VC uses I2C high-speed mode to PMIC + * @i2c_mcode: master code value for I2C high-speed preamble transmission + * @vsel_to_uv: PMIC API to convert vsel value to actual voltage in uV. + * @uv_to_vsel: PMIC API to convert voltage in uV to vsel value. + */ +struct omap_voltdm_pmic { + int slew_rate; + int step_size; + u16 i2c_slave_addr; + u16 volt_reg_addr; + u16 cmd_reg_addr; + u8 vp_erroroffset; + u8 vp_vstepmin; + u8 vp_vstepmax; + u32 vddmin; + u32 vddmax; + u8 vp_timeout_us; + bool i2c_high_speed; + u32 i2c_pad_load; + u8 i2c_mcode; + unsigned long (*vsel_to_uv) (const u8 vsel); + u8 (*uv_to_vsel) (unsigned long uV); +}; + +struct omap_vp_param { + u32 vddmax; + u32 vddmin; +}; + +struct omap_vc_param { + u32 on; + u32 onlp; + u32 ret; + u32 off; +}; + +void omap_voltage_get_volttable(struct voltagedomain *voltdm, + struct omap_volt_data **volt_data); +struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm, + unsigned long volt); +int omap_voltage_register_pmic(struct voltagedomain *voltdm, + struct omap_voltdm_pmic *pmic); +void omap_change_voltscale_method(struct voltagedomain *voltdm, + int voltscale_method); +int omap_voltage_late_init(void); + +extern void omap2xxx_voltagedomains_init(void); +extern void omap3xxx_voltagedomains_init(void); +extern void omap44xx_voltagedomains_init(void); +extern void omap54xx_voltagedomains_init(void); + +struct voltagedomain *voltdm_lookup(const char *name); +void voltdm_init(struct voltagedomain **voltdm_list); +int voltdm_add_pwrdm(struct voltagedomain *voltdm, struct powerdomain *pwrdm); +int voltdm_for_each(int (*fn)(struct voltagedomain *voltdm, void *user), + void *user); +int voltdm_for_each_pwrdm(struct voltagedomain *voltdm, + int (*fn)(struct voltagedomain *voltdm, + struct powerdomain *pwrdm)); +int voltdm_scale(struct voltagedomain *voltdm, unsigned long target_volt); +void voltdm_reset(struct voltagedomain *voltdm); +unsigned long voltdm_get_voltage(struct voltagedomain *voltdm); +#endif diff --git a/arch/arm/mach-omap2/voltagedomains2xxx_data.c b/arch/arm/mach-omap2/voltagedomains2xxx_data.c new file mode 100644 index 00000000000..7a41349981e --- /dev/null +++ b/arch/arm/mach-omap2/voltagedomains2xxx_data.c @@ -0,0 +1,32 @@ +/* + * OMAP3 voltage domain data + * + * Copyright (C) 2011 Texas Instruments, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/kernel.h> +#include <linux/init.h> + +#include "voltage.h" + +static struct voltagedomain omap2_voltdm_core = { + .name = "core", +}; + +static struct voltagedomain omap2_voltdm_wkup = { + .name = "wakeup", +}; + +static struct voltagedomain *voltagedomains_omap2[] __initdata = { + &omap2_voltdm_core, + &omap2_voltdm_wkup, + NULL, +}; + +void __init omap2xxx_voltagedomains_init(void) +{ + voltdm_init(voltagedomains_omap2); +} diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c new file mode 100644 index 00000000000..261bb7cb4e6 --- /dev/null +++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c @@ -0,0 +1,134 @@ +/* + * OMAP3 voltage domain data + * + * Copyright (C) 2007, 2010 Texas Instruments, Inc. + * Rajendra Nayak <rnayak@ti.com> + * Lesly A M <x0080970@ti.com> + * Thara Gopinath <thara@ti.com> + * + * Copyright (C) 2008, 2011 Nokia Corporation + * Kalle Jokiniemi + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/kernel.h> +#include <linux/err.h> +#include <linux/init.h> + +#include "soc.h" +#include "common.h" +#include "prm-regbits-34xx.h" +#include "omap_opp_data.h" +#include "voltage.h" +#include "vc.h" +#include "vp.h" + +/* + * VDD data + */ + +/* OMAP3-common voltagedomain data */ + +static struct voltagedomain omap3_voltdm_wkup = { + .name = "wakeup", +}; + +/* 34xx/36xx voltagedomain data */ + +static const struct omap_vfsm_instance omap3_vdd1_vfsm = { + .voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET, + .voltsetup_mask = OMAP3430_SETUP_TIME1_MASK, +}; + +static const struct omap_vfsm_instance omap3_vdd2_vfsm = { + .voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET, + .voltsetup_mask = OMAP3430_SETUP_TIME2_MASK, +}; + +static struct voltagedomain omap3_voltdm_mpu = { + .name = "mpu_iva", + .scalable = true, + .read = omap3_prm_vcvp_read, + .write = omap3_prm_vcvp_write, + .rmw = omap3_prm_vcvp_rmw, + .vc = &omap3_vc_mpu, + .vfsm = &omap3_vdd1_vfsm, + .vp = &omap3_vp_mpu, +}; + +static struct voltagedomain omap3_voltdm_core = { + .name = "core", + .scalable = true, + .read = omap3_prm_vcvp_read, + .write = omap3_prm_vcvp_write, + .rmw = omap3_prm_vcvp_rmw, + .vc = &omap3_vc_core, + .vfsm = &omap3_vdd2_vfsm, + .vp = &omap3_vp_core, +}; + +static struct voltagedomain *voltagedomains_omap3[] __initdata = { + &omap3_voltdm_mpu, + &omap3_voltdm_core, + &omap3_voltdm_wkup, + NULL, +}; + +/* AM35xx voltagedomain data */ + +static struct voltagedomain am35xx_voltdm_mpu = { + .name = "mpu_iva", +}; + +static struct voltagedomain am35xx_voltdm_core = { + .name = "core", +}; + +static struct voltagedomain *voltagedomains_am35xx[] __initdata = { + &am35xx_voltdm_mpu, + &am35xx_voltdm_core, + &omap3_voltdm_wkup, + NULL, +}; + + +static const char *sys_clk_name __initdata = "sys_ck"; + +void __init omap3xxx_voltagedomains_init(void) +{ + struct voltagedomain *voltdm; + struct voltagedomain **voltdms; + int i; + + /* + * XXX Will depend on the process, validation, and binning + * for the currently-running IC + */ +#ifdef CONFIG_PM_OPP + if (cpu_is_omap3630()) { + omap3_voltdm_mpu.volt_data = omap36xx_vddmpu_volt_data; + omap3_voltdm_core.volt_data = omap36xx_vddcore_volt_data; + } else { + omap3_voltdm_mpu.volt_data = omap34xx_vddmpu_volt_data; + omap3_voltdm_core.volt_data = omap34xx_vddcore_volt_data; + } +#endif + + omap3_voltdm_mpu.vp_param = &omap3_mpu_vp_data; + omap3_voltdm_core.vp_param = &omap3_core_vp_data; + omap3_voltdm_mpu.vc_param = &omap3_mpu_vc_data; + omap3_voltdm_core.vc_param = &omap3_core_vc_data; + + if (soc_is_am35xx()) + voltdms = voltagedomains_am35xx; + else + voltdms = voltagedomains_omap3; + + for (i = 0; voltdm = voltdms[i], voltdm; i++) + voltdm->sys_clk.name = sys_clk_name; + + voltdm_init(voltdms); +}; diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c new file mode 100644 index 00000000000..48b22a0a0c8 --- /dev/null +++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c @@ -0,0 +1,130 @@ +/* + * OMAP3/OMAP4 Voltage Management Routines + * + * Author: Thara Gopinath <thara@ti.com> + * + * Copyright (C) 2007 Texas Instruments, Inc. + * Rajendra Nayak <rnayak@ti.com> + * Lesly A M <x0080970@ti.com> + * + * Copyright (C) 2008 Nokia Corporation + * Kalle Jokiniemi + * + * Copyright (C) 2010 Texas Instruments, Inc. + * Thara Gopinath <thara@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/kernel.h> +#include <linux/err.h> +#include <linux/init.h> + +#include "common.h" +#include "soc.h" +#include "prm-regbits-44xx.h" +#include "prm44xx.h" +#include "prcm44xx.h" +#include "prminst44xx.h" +#include "voltage.h" +#include "omap_opp_data.h" +#include "vc.h" +#include "vp.h" + +static const struct omap_vfsm_instance omap4_vdd_mpu_vfsm = { + .voltsetup_reg = OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET, + .voltsetup_off_reg = OMAP4_PRM_VOLTSETUP_MPU_OFF_OFFSET, +}; + +static const struct omap_vfsm_instance omap4_vdd_iva_vfsm = { + .voltsetup_reg = OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET, + .voltsetup_off_reg = OMAP4_PRM_VOLTSETUP_IVA_OFF_OFFSET, +}; + +static const struct omap_vfsm_instance omap4_vdd_core_vfsm = { + .voltsetup_reg = OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET, + .voltsetup_off_reg = OMAP4_PRM_VOLTSETUP_CORE_OFF_OFFSET, +}; + +static struct voltagedomain omap4_voltdm_mpu = { + .name = "mpu", + .scalable = true, + .read = omap4_prm_vcvp_read, + .write = omap4_prm_vcvp_write, + .rmw = omap4_prm_vcvp_rmw, + .vc = &omap4_vc_mpu, + .vfsm = &omap4_vdd_mpu_vfsm, + .vp = &omap4_vp_mpu, +}; + +static struct voltagedomain omap4_voltdm_iva = { + .name = "iva", + .scalable = true, + .read = omap4_prm_vcvp_read, + .write = omap4_prm_vcvp_write, + .rmw = omap4_prm_vcvp_rmw, + .vc = &omap4_vc_iva, + .vfsm = &omap4_vdd_iva_vfsm, + .vp = &omap4_vp_iva, +}; + +static struct voltagedomain omap4_voltdm_core = { + .name = "core", + .scalable = true, + .read = omap4_prm_vcvp_read, + .write = omap4_prm_vcvp_write, + .rmw = omap4_prm_vcvp_rmw, + .vc = &omap4_vc_core, + .vfsm = &omap4_vdd_core_vfsm, + .vp = &omap4_vp_core, +}; + +static struct voltagedomain omap4_voltdm_wkup = { + .name = "wakeup", +}; + +static struct voltagedomain *voltagedomains_omap4[] __initdata = { + &omap4_voltdm_mpu, + &omap4_voltdm_iva, + &omap4_voltdm_core, + &omap4_voltdm_wkup, + NULL, +}; + +static const char *sys_clk_name __initdata = "sys_clkin_ck"; + +void __init omap44xx_voltagedomains_init(void) +{ + struct voltagedomain *voltdm; + int i; + + /* + * XXX Will depend on the process, validation, and binning + * for the currently-running IC + */ +#ifdef CONFIG_PM_OPP + if (cpu_is_omap443x()) { + omap4_voltdm_mpu.volt_data = omap443x_vdd_mpu_volt_data; + omap4_voltdm_iva.volt_data = omap443x_vdd_iva_volt_data; + omap4_voltdm_core.volt_data = omap443x_vdd_core_volt_data; + } else if (cpu_is_omap446x()) { + omap4_voltdm_mpu.volt_data = omap446x_vdd_mpu_volt_data; + omap4_voltdm_iva.volt_data = omap446x_vdd_iva_volt_data; + omap4_voltdm_core.volt_data = omap446x_vdd_core_volt_data; + } +#endif + + omap4_voltdm_mpu.vp_param = &omap4_mpu_vp_data; + omap4_voltdm_iva.vp_param = &omap4_iva_vp_data; + omap4_voltdm_core.vp_param = &omap4_core_vp_data; + + omap4_voltdm_mpu.vc_param = &omap4_mpu_vc_data; + omap4_voltdm_iva.vc_param = &omap4_iva_vc_data; + omap4_voltdm_core.vc_param = &omap4_core_vc_data; + + for (i = 0; voltdm = voltagedomains_omap4[i], voltdm; i++) + voltdm->sys_clk.name = sys_clk_name; + + voltdm_init(voltagedomains_omap4); +}; diff --git a/arch/arm/mach-omap2/voltagedomains54xx_data.c b/arch/arm/mach-omap2/voltagedomains54xx_data.c new file mode 100644 index 00000000000..33d22b87252 --- /dev/null +++ b/arch/arm/mach-omap2/voltagedomains54xx_data.c @@ -0,0 +1,92 @@ +/* + * OMAP5 Voltage Management Routines + * + * Based on voltagedomains44xx_data.c + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/kernel.h> +#include <linux/err.h> +#include <linux/init.h> + +#include "common.h" + +#include "prm54xx.h" +#include "voltage.h" +#include "omap_opp_data.h" +#include "vc.h" +#include "vp.h" + +static const struct omap_vfsm_instance omap5_vdd_mpu_vfsm = { + .voltsetup_reg = OMAP54XX_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET, +}; + +static const struct omap_vfsm_instance omap5_vdd_mm_vfsm = { + .voltsetup_reg = OMAP54XX_PRM_VOLTSETUP_MM_RET_SLEEP_OFFSET, +}; + +static const struct omap_vfsm_instance omap5_vdd_core_vfsm = { + .voltsetup_reg = OMAP54XX_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET, +}; + +static struct voltagedomain omap5_voltdm_mpu = { + .name = "mpu", + .scalable = true, + .read = omap4_prm_vcvp_read, + .write = omap4_prm_vcvp_write, + .rmw = omap4_prm_vcvp_rmw, + .vc = &omap4_vc_mpu, + .vfsm = &omap5_vdd_mpu_vfsm, + .vp = &omap4_vp_mpu, +}; + +static struct voltagedomain omap5_voltdm_mm = { + .name = "mm", + .scalable = true, + .read = omap4_prm_vcvp_read, + .write = omap4_prm_vcvp_write, + .rmw = omap4_prm_vcvp_rmw, + .vc = &omap4_vc_iva, + .vfsm = &omap5_vdd_mm_vfsm, + .vp = &omap4_vp_iva, +}; + +static struct voltagedomain omap5_voltdm_core = { + .name = "core", + .scalable = true, + .read = omap4_prm_vcvp_read, + .write = omap4_prm_vcvp_write, + .rmw = omap4_prm_vcvp_rmw, + .vc = &omap4_vc_core, + .vfsm = &omap5_vdd_core_vfsm, + .vp = &omap4_vp_core, +}; + +static struct voltagedomain omap5_voltdm_wkup = { + .name = "wkup", +}; + +static struct voltagedomain *voltagedomains_omap5[] __initdata = { + &omap5_voltdm_mpu, + &omap5_voltdm_mm, + &omap5_voltdm_core, + &omap5_voltdm_wkup, + NULL, +}; + +static const char *sys_clk_name __initdata = "sys_clkin"; + +void __init omap54xx_voltagedomains_init(void) +{ + struct voltagedomain *voltdm; + int i; + + for (i = 0; voltdm = voltagedomains_omap5[i], voltdm; i++) + voltdm->sys_clk.name = sys_clk_name; + + voltdm_init(voltagedomains_omap5); +}; diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c new file mode 100644 index 00000000000..a3c30655aa3 --- /dev/null +++ b/arch/arm/mach-omap2/vp.c @@ -0,0 +1,282 @@ +#include <linux/kernel.h> +#include <linux/init.h> + +#include "common.h" + +#include "voltage.h" +#include "vp.h" +#include "prm-regbits-34xx.h" +#include "prm-regbits-44xx.h" +#include "prm44xx.h" + +static u32 _vp_set_init_voltage(struct voltagedomain *voltdm, u32 volt) +{ + struct omap_vp_instance *vp = voltdm->vp; + u32 vpconfig; + char vsel; + + vsel = voltdm->pmic->uv_to_vsel(volt); + + vpconfig = voltdm->read(vp->vpconfig); + vpconfig &= ~(vp->common->vpconfig_initvoltage_mask | + vp->common->vpconfig_forceupdate | + vp->common->vpconfig_initvdd); + vpconfig |= vsel << __ffs(vp->common->vpconfig_initvoltage_mask); + voltdm->write(vpconfig, vp->vpconfig); + + /* Trigger initVDD value copy to voltage processor */ + voltdm->write((vpconfig | vp->common->vpconfig_initvdd), + vp->vpconfig); + + /* Clear initVDD copy trigger bit */ + voltdm->write(vpconfig, vp->vpconfig); + + return vpconfig; +} + +/* Generic voltage init functions */ +void __init omap_vp_init(struct voltagedomain *voltdm) +{ + struct omap_vp_instance *vp = voltdm->vp; + u32 val, sys_clk_rate, timeout, waittime; + u32 vddmin, vddmax, vstepmin, vstepmax; + + if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) { + pr_err("%s: No PMIC info for vdd_%s\n", __func__, voltdm->name); + return; + } + + if (!voltdm->read || !voltdm->write) { + pr_err("%s: No read/write API for accessing vdd_%s regs\n", + __func__, voltdm->name); + return; + } + + vp->enabled = false; + + /* Divide to avoid overflow */ + sys_clk_rate = voltdm->sys_clk.rate / 1000; + + timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000; + vddmin = max(voltdm->vp_param->vddmin, voltdm->pmic->vddmin); + vddmax = min(voltdm->vp_param->vddmax, voltdm->pmic->vddmax); + vddmin = voltdm->pmic->uv_to_vsel(vddmin); + vddmax = voltdm->pmic->uv_to_vsel(vddmax); + + waittime = DIV_ROUND_UP(voltdm->pmic->step_size * sys_clk_rate, + 1000 * voltdm->pmic->slew_rate); + vstepmin = voltdm->pmic->vp_vstepmin; + vstepmax = voltdm->pmic->vp_vstepmax; + + /* + * VP_CONFIG: error gain is not set here, it will be updated + * on each scale, based on OPP. + */ + val = (voltdm->pmic->vp_erroroffset << + __ffs(voltdm->vp->common->vpconfig_erroroffset_mask)) | + vp->common->vpconfig_timeouten; + voltdm->write(val, vp->vpconfig); + + /* VSTEPMIN */ + val = (waittime << vp->common->vstepmin_smpswaittimemin_shift) | + (vstepmin << vp->common->vstepmin_stepmin_shift); + voltdm->write(val, vp->vstepmin); + + /* VSTEPMAX */ + val = (vstepmax << vp->common->vstepmax_stepmax_shift) | + (waittime << vp->common->vstepmax_smpswaittimemax_shift); + voltdm->write(val, vp->vstepmax); + + /* VLIMITTO */ + val = (vddmax << vp->common->vlimitto_vddmax_shift) | + (vddmin << vp->common->vlimitto_vddmin_shift) | + (timeout << vp->common->vlimitto_timeout_shift); + voltdm->write(val, vp->vlimitto); +} + +int omap_vp_update_errorgain(struct voltagedomain *voltdm, + unsigned long target_volt) +{ + struct omap_volt_data *volt_data; + + if (!voltdm->vp) + return -EINVAL; + + /* Get volt_data corresponding to target_volt */ + volt_data = omap_voltage_get_voltdata(voltdm, target_volt); + if (IS_ERR(volt_data)) + return -EINVAL; + + /* Setting vp errorgain based on the voltage */ + voltdm->rmw(voltdm->vp->common->vpconfig_errorgain_mask, + volt_data->vp_errgain << + __ffs(voltdm->vp->common->vpconfig_errorgain_mask), + voltdm->vp->vpconfig); + + return 0; +} + +/* VP force update method of voltage scaling */ +int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, + unsigned long target_volt) +{ + struct omap_vp_instance *vp = voltdm->vp; + u32 vpconfig; + u8 target_vsel, current_vsel; + int ret, timeout = 0; + + ret = omap_vc_pre_scale(voltdm, target_volt, &target_vsel, ¤t_vsel); + if (ret) + return ret; + + /* + * Clear all pending TransactionDone interrupt/status. Typical latency + * is <3us + */ + while (timeout++ < VP_TRANXDONE_TIMEOUT) { + vp->common->ops->clear_txdone(vp->id); + if (!vp->common->ops->check_txdone(vp->id)) + break; + udelay(1); + } + if (timeout >= VP_TRANXDONE_TIMEOUT) { + pr_warn("%s: vdd_%s TRANXDONE timeout exceeded. Voltage change aborted\n", + __func__, voltdm->name); + return -ETIMEDOUT; + } + + vpconfig = _vp_set_init_voltage(voltdm, target_volt); + + /* Force update of voltage */ + voltdm->write(vpconfig | vp->common->vpconfig_forceupdate, + voltdm->vp->vpconfig); + + /* + * Wait for TransactionDone. Typical latency is <200us. + * Depends on SMPSWAITTIMEMIN/MAX and voltage change + */ + timeout = 0; + omap_test_timeout(vp->common->ops->check_txdone(vp->id), + VP_TRANXDONE_TIMEOUT, timeout); + if (timeout >= VP_TRANXDONE_TIMEOUT) + pr_err("%s: vdd_%s TRANXDONE timeout exceeded. TRANXDONE never got set after the voltage update\n", + __func__, voltdm->name); + + omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel); + + /* + * Disable TransactionDone interrupt , clear all status, clear + * control registers + */ + timeout = 0; + while (timeout++ < VP_TRANXDONE_TIMEOUT) { + vp->common->ops->clear_txdone(vp->id); + if (!vp->common->ops->check_txdone(vp->id)) + break; + udelay(1); + } + + if (timeout >= VP_TRANXDONE_TIMEOUT) + pr_warn("%s: vdd_%s TRANXDONE timeout exceeded while trying to clear the TRANXDONE status\n", + __func__, voltdm->name); + + /* Clear force bit */ + voltdm->write(vpconfig, vp->vpconfig); + + return 0; +} + +/** + * omap_vp_enable() - API to enable a particular VP + * @voltdm: pointer to the VDD whose VP is to be enabled. + * + * This API enables a particular voltage processor. Needed by the smartreflex + * class drivers. + */ +void omap_vp_enable(struct voltagedomain *voltdm) +{ + struct omap_vp_instance *vp; + u32 vpconfig, volt; + + if (!voltdm || IS_ERR(voltdm)) { + pr_warn("%s: VDD specified does not exist!\n", __func__); + return; + } + + vp = voltdm->vp; + if (!voltdm->read || !voltdm->write) { + pr_err("%s: No read/write API for accessing vdd_%s regs\n", + __func__, voltdm->name); + return; + } + + /* If VP is already enabled, do nothing. Return */ + if (vp->enabled) + return; + + volt = voltdm_get_voltage(voltdm); + if (!volt) { + pr_warn("%s: unable to find current voltage for %s\n", + __func__, voltdm->name); + return; + } + + vpconfig = _vp_set_init_voltage(voltdm, volt); + + /* Enable VP */ + vpconfig |= vp->common->vpconfig_vpenable; + voltdm->write(vpconfig, vp->vpconfig); + + vp->enabled = true; +} + +/** + * omap_vp_disable() - API to disable a particular VP + * @voltdm: pointer to the VDD whose VP is to be disabled. + * + * This API disables a particular voltage processor. Needed by the smartreflex + * class drivers. + */ +void omap_vp_disable(struct voltagedomain *voltdm) +{ + struct omap_vp_instance *vp; + u32 vpconfig; + int timeout; + + if (!voltdm || IS_ERR(voltdm)) { + pr_warn("%s: VDD specified does not exist!\n", __func__); + return; + } + + vp = voltdm->vp; + if (!voltdm->read || !voltdm->write) { + pr_err("%s: No read/write API for accessing vdd_%s regs\n", + __func__, voltdm->name); + return; + } + + /* If VP is already disabled, do nothing. Return */ + if (!vp->enabled) { + pr_warn("%s: Trying to disable VP for vdd_%s when it is already disabled\n", + __func__, voltdm->name); + return; + } + + /* Disable VP */ + vpconfig = voltdm->read(vp->vpconfig); + vpconfig &= ~vp->common->vpconfig_vpenable; + voltdm->write(vpconfig, vp->vpconfig); + + /* + * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us + */ + omap_test_timeout((voltdm->read(vp->vstatus)), + VP_IDLE_TIMEOUT, timeout); + + if (timeout >= VP_IDLE_TIMEOUT) + pr_warn("%s: vdd_%s idle timedout\n", __func__, voltdm->name); + + vp->enabled = false; + + return; +} diff --git a/arch/arm/mach-omap2/vp.h b/arch/arm/mach-omap2/vp.h new file mode 100644 index 00000000000..0fdf7080e4a --- /dev/null +++ b/arch/arm/mach-omap2/vp.h @@ -0,0 +1,135 @@ +/* + * OMAP3/4 Voltage Processor (VP) structure and macro definitions + * + * Copyright (C) 2007, 2010 Texas Instruments, Inc. + * Rajendra Nayak <rnayak@ti.com> + * Lesly A M <x0080970@ti.com> + * Thara Gopinath <thara@ti.com> + * + * Copyright (C) 2008, 2011 Nokia Corporation + * Kalle Jokiniemi + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + */ +#ifndef __ARCH_ARM_MACH_OMAP2_VP_H +#define __ARCH_ARM_MACH_OMAP2_VP_H + +#include <linux/kernel.h> + +struct voltagedomain; + +/* + * Voltage Processor (VP) identifiers + */ +#define OMAP3_VP_VDD_MPU_ID 0 +#define OMAP3_VP_VDD_CORE_ID 1 +#define OMAP4_VP_VDD_CORE_ID 0 +#define OMAP4_VP_VDD_IVA_ID 1 +#define OMAP4_VP_VDD_MPU_ID 2 + +/* XXX document */ +#define VP_IDLE_TIMEOUT 200 +#define VP_TRANXDONE_TIMEOUT 300 + +/** + * struct omap_vp_ops - per-VP operations + * @check_txdone: check for VP transaction done + * @clear_txdone: clear VP transaction done status + */ +struct omap_vp_ops { + u32 (*check_txdone)(u8 vp_id); + void (*clear_txdone)(u8 vp_id); +}; + +/** + * struct omap_vp_common - register data common to all VDDs + * @vpconfig_erroroffset_mask: ERROROFFSET bitmask in the PRM_VP*_CONFIG reg + * @vpconfig_errorgain_mask: ERRORGAIN bitmask in the PRM_VP*_CONFIG reg + * @vpconfig_initvoltage_mask: INITVOLTAGE bitmask in the PRM_VP*_CONFIG reg + * @vpconfig_timeouten: TIMEOUT bitmask in the PRM_VP*_CONFIG reg + * @vpconfig_initvdd: INITVDD bitmask in the PRM_VP*_CONFIG reg + * @vpconfig_forceupdate: FORCEUPDATE bitmask in the PRM_VP*_CONFIG reg + * @vpconfig_vpenable: VPENABLE bitmask in the PRM_VP*_CONFIG reg + * @vpconfig_erroroffset_shift: ERROROFFSET field shift in PRM_VP*_CONFIG reg + * @vpconfig_errorgain_shift: ERRORGAIN field shift in PRM_VP*_CONFIG reg + * @vpconfig_initvoltage_shift: INITVOLTAGE field shift in PRM_VP*_CONFIG reg + * @vstepmin_stepmin_shift: VSTEPMIN field shift in the PRM_VP*_VSTEPMIN reg + * @vstepmin_smpswaittimemin_shift: SMPSWAITTIMEMIN field shift in PRM_VP*_VSTEPMIN reg + * @vstepmax_stepmax_shift: VSTEPMAX field shift in the PRM_VP*_VSTEPMAX reg + * @vstepmax_smpswaittimemax_shift: SMPSWAITTIMEMAX field shift in PRM_VP*_VSTEPMAX reg + * @vlimitto_vddmin_shift: VDDMIN field shift in PRM_VP*_VLIMITTO reg + * @vlimitto_vddmax_shift: VDDMAX field shift in PRM_VP*_VLIMITTO reg + * @vlimitto_timeout_shift: TIMEOUT field shift in PRM_VP*_VLIMITTO reg + * @vpvoltage_mask: VPVOLTAGE field mask in PRM_VP*_VOLTAGE reg + */ +struct omap_vp_common { + u32 vpconfig_erroroffset_mask; + u32 vpconfig_errorgain_mask; + u32 vpconfig_initvoltage_mask; + u8 vpconfig_timeouten; + u8 vpconfig_initvdd; + u8 vpconfig_forceupdate; + u8 vpconfig_vpenable; + u8 vstepmin_stepmin_shift; + u8 vstepmin_smpswaittimemin_shift; + u8 vstepmax_stepmax_shift; + u8 vstepmax_smpswaittimemax_shift; + u8 vlimitto_vddmin_shift; + u8 vlimitto_vddmax_shift; + u8 vlimitto_timeout_shift; + u8 vpvoltage_mask; + + const struct omap_vp_ops *ops; +}; + +/** + * struct omap_vp_instance - VP register offsets (per-VDD) + * @common: pointer to struct omap_vp_common * for this SoC + * @vpconfig: PRM_VP*_CONFIG reg offset from PRM start + * @vstepmin: PRM_VP*_VSTEPMIN reg offset from PRM start + * @vlimitto: PRM_VP*_VLIMITTO reg offset from PRM start + * @vstatus: PRM_VP*_VSTATUS reg offset from PRM start + * @voltage: PRM_VP*_VOLTAGE reg offset from PRM start + * @id: Unique identifier for VP instance. + * @enabled: flag to keep track of whether vp is enabled or not + * + * XXX vp_common is probably not needed since it is per-SoC + */ +struct omap_vp_instance { + const struct omap_vp_common *common; + u8 vpconfig; + u8 vstepmin; + u8 vstepmax; + u8 vlimitto; + u8 vstatus; + u8 voltage; + u8 id; + bool enabled; +}; + +extern struct omap_vp_instance omap3_vp_mpu; +extern struct omap_vp_instance omap3_vp_core; + +extern struct omap_vp_instance omap4_vp_mpu; +extern struct omap_vp_instance omap4_vp_iva; +extern struct omap_vp_instance omap4_vp_core; + +extern struct omap_vp_param omap3_mpu_vp_data; +extern struct omap_vp_param omap3_core_vp_data; + +extern struct omap_vp_param omap4_mpu_vp_data; +extern struct omap_vp_param omap4_iva_vp_data; +extern struct omap_vp_param omap4_core_vp_data; + +void omap_vp_init(struct voltagedomain *voltdm); +void omap_vp_enable(struct voltagedomain *voltdm); +void omap_vp_disable(struct voltagedomain *voltdm); +int omap_vp_forceupdate_scale(struct voltagedomain *voltdm, + unsigned long target_volt); +int omap_vp_update_errorgain(struct voltagedomain *voltdm, + unsigned long target_volt); + +#endif diff --git a/arch/arm/mach-omap2/vp3xxx_data.c b/arch/arm/mach-omap2/vp3xxx_data.c new file mode 100644 index 00000000000..1914e026245 --- /dev/null +++ b/arch/arm/mach-omap2/vp3xxx_data.c @@ -0,0 +1,89 @@ +/* + * OMAP3 Voltage Processor (VP) data + * + * Copyright (C) 2007, 2010 Texas Instruments, Inc. + * Rajendra Nayak <rnayak@ti.com> + * Lesly A M <x0080970@ti.com> + * Thara Gopinath <thara@ti.com> + * + * Copyright (C) 2008, 2011 Nokia Corporation + * Kalle Jokiniemi + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/io.h> +#include <linux/err.h> +#include <linux/init.h> + +#include "common.h" + +#include "prm-regbits-34xx.h" +#include "voltage.h" + +#include "vp.h" +#include "prm2xxx_3xxx.h" + +static const struct omap_vp_ops omap3_vp_ops = { + .check_txdone = omap3_prm_vp_check_txdone, + .clear_txdone = omap3_prm_vp_clear_txdone, +}; + +/* + * VP data common to 34xx/36xx chips + * XXX This stuff presumably belongs in the vp3xxx.c or vp.c file. + */ +static const struct omap_vp_common omap3_vp_common = { + .vpconfig_erroroffset_mask = OMAP3430_ERROROFFSET_MASK, + .vpconfig_errorgain_mask = OMAP3430_ERRORGAIN_MASK, + .vpconfig_initvoltage_mask = OMAP3430_INITVOLTAGE_MASK, + .vpconfig_timeouten = OMAP3430_TIMEOUTEN_MASK, + .vpconfig_initvdd = OMAP3430_INITVDD_MASK, + .vpconfig_forceupdate = OMAP3430_FORCEUPDATE_MASK, + .vpconfig_vpenable = OMAP3430_VPENABLE_MASK, + .vstepmin_smpswaittimemin_shift = OMAP3430_SMPSWAITTIMEMIN_SHIFT, + .vstepmax_smpswaittimemax_shift = OMAP3430_SMPSWAITTIMEMAX_SHIFT, + .vstepmin_stepmin_shift = OMAP3430_VSTEPMIN_SHIFT, + .vstepmax_stepmax_shift = OMAP3430_VSTEPMAX_SHIFT, + .vlimitto_vddmin_shift = OMAP3430_VDDMIN_SHIFT, + .vlimitto_vddmax_shift = OMAP3430_VDDMAX_SHIFT, + .vlimitto_timeout_shift = OMAP3430_TIMEOUT_SHIFT, + .vpvoltage_mask = OMAP3430_VPVOLTAGE_MASK, + + .ops = &omap3_vp_ops, +}; + +struct omap_vp_instance omap3_vp_mpu = { + .id = OMAP3_VP_VDD_MPU_ID, + .common = &omap3_vp_common, + .vpconfig = OMAP3_PRM_VP1_CONFIG_OFFSET, + .vstepmin = OMAP3_PRM_VP1_VSTEPMIN_OFFSET, + .vstepmax = OMAP3_PRM_VP1_VSTEPMAX_OFFSET, + .vlimitto = OMAP3_PRM_VP1_VLIMITTO_OFFSET, + .vstatus = OMAP3_PRM_VP1_STATUS_OFFSET, + .voltage = OMAP3_PRM_VP1_VOLTAGE_OFFSET, +}; + +struct omap_vp_instance omap3_vp_core = { + .id = OMAP3_VP_VDD_CORE_ID, + .common = &omap3_vp_common, + .vpconfig = OMAP3_PRM_VP2_CONFIG_OFFSET, + .vstepmin = OMAP3_PRM_VP2_VSTEPMIN_OFFSET, + .vstepmax = OMAP3_PRM_VP2_VSTEPMAX_OFFSET, + .vlimitto = OMAP3_PRM_VP2_VLIMITTO_OFFSET, + .vstatus = OMAP3_PRM_VP2_STATUS_OFFSET, + .voltage = OMAP3_PRM_VP2_VOLTAGE_OFFSET, +}; + +struct omap_vp_param omap3_mpu_vp_data = { + .vddmin = OMAP3430_VP1_VLIMITTO_VDDMIN, + .vddmax = OMAP3430_VP1_VLIMITTO_VDDMAX, +}; + +struct omap_vp_param omap3_core_vp_data = { + .vddmin = OMAP3430_VP2_VLIMITTO_VDDMIN, + .vddmax = OMAP3430_VP2_VLIMITTO_VDDMAX, +}; diff --git a/arch/arm/mach-omap2/vp44xx_data.c b/arch/arm/mach-omap2/vp44xx_data.c new file mode 100644 index 00000000000..e62f6b018be --- /dev/null +++ b/arch/arm/mach-omap2/vp44xx_data.c @@ -0,0 +1,104 @@ +/* + * OMAP3 Voltage Processor (VP) data + * + * Copyright (C) 2007, 2010 Texas Instruments, Inc. + * Rajendra Nayak <rnayak@ti.com> + * Lesly A M <x0080970@ti.com> + * Thara Gopinath <thara@ti.com> + * + * Copyright (C) 2008, 2011 Nokia Corporation + * Kalle Jokiniemi + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/io.h> +#include <linux/err.h> +#include <linux/init.h> + +#include "common.h" + +#include "prm44xx.h" +#include "prm-regbits-44xx.h" +#include "voltage.h" + +#include "vp.h" + +static const struct omap_vp_ops omap4_vp_ops = { + .check_txdone = omap4_prm_vp_check_txdone, + .clear_txdone = omap4_prm_vp_clear_txdone, +}; + +/* + * VP data common to 44xx chips + * XXX This stuff presumably belongs in the vp44xx.c or vp.c file. + */ +static const struct omap_vp_common omap4_vp_common = { + .vpconfig_erroroffset_mask = OMAP4430_ERROROFFSET_MASK, + .vpconfig_errorgain_mask = OMAP4430_ERRORGAIN_MASK, + .vpconfig_initvoltage_mask = OMAP4430_INITVOLTAGE_MASK, + .vpconfig_timeouten = OMAP4430_TIMEOUTEN_MASK, + .vpconfig_initvdd = OMAP4430_INITVDD_MASK, + .vpconfig_forceupdate = OMAP4430_FORCEUPDATE_MASK, + .vpconfig_vpenable = OMAP4430_VPENABLE_MASK, + .vstepmin_smpswaittimemin_shift = OMAP4430_SMPSWAITTIMEMIN_SHIFT, + .vstepmax_smpswaittimemax_shift = OMAP4430_SMPSWAITTIMEMAX_SHIFT, + .vstepmin_stepmin_shift = OMAP4430_VSTEPMIN_SHIFT, + .vstepmax_stepmax_shift = OMAP4430_VSTEPMAX_SHIFT, + .vlimitto_vddmin_shift = OMAP4430_VDDMIN_SHIFT, + .vlimitto_vddmax_shift = OMAP4430_VDDMAX_SHIFT, + .vlimitto_timeout_shift = OMAP4430_TIMEOUT_SHIFT, + .vpvoltage_mask = OMAP4430_VPVOLTAGE_MASK, + .ops = &omap4_vp_ops, +}; + +struct omap_vp_instance omap4_vp_mpu = { + .id = OMAP4_VP_VDD_MPU_ID, + .common = &omap4_vp_common, + .vpconfig = OMAP4_PRM_VP_MPU_CONFIG_OFFSET, + .vstepmin = OMAP4_PRM_VP_MPU_VSTEPMIN_OFFSET, + .vstepmax = OMAP4_PRM_VP_MPU_VSTEPMAX_OFFSET, + .vlimitto = OMAP4_PRM_VP_MPU_VLIMITTO_OFFSET, + .vstatus = OMAP4_PRM_VP_MPU_STATUS_OFFSET, + .voltage = OMAP4_PRM_VP_MPU_VOLTAGE_OFFSET, +}; + +struct omap_vp_instance omap4_vp_iva = { + .id = OMAP4_VP_VDD_IVA_ID, + .common = &omap4_vp_common, + .vpconfig = OMAP4_PRM_VP_IVA_CONFIG_OFFSET, + .vstepmin = OMAP4_PRM_VP_IVA_VSTEPMIN_OFFSET, + .vstepmax = OMAP4_PRM_VP_IVA_VSTEPMAX_OFFSET, + .vlimitto = OMAP4_PRM_VP_IVA_VLIMITTO_OFFSET, + .vstatus = OMAP4_PRM_VP_IVA_STATUS_OFFSET, + .voltage = OMAP4_PRM_VP_IVA_VOLTAGE_OFFSET, +}; + +struct omap_vp_instance omap4_vp_core = { + .id = OMAP4_VP_VDD_CORE_ID, + .common = &omap4_vp_common, + .vpconfig = OMAP4_PRM_VP_CORE_CONFIG_OFFSET, + .vstepmin = OMAP4_PRM_VP_CORE_VSTEPMIN_OFFSET, + .vstepmax = OMAP4_PRM_VP_CORE_VSTEPMAX_OFFSET, + .vlimitto = OMAP4_PRM_VP_CORE_VLIMITTO_OFFSET, + .vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET, + .voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET, +}; + +struct omap_vp_param omap4_mpu_vp_data = { + .vddmin = OMAP4_VP_MPU_VLIMITTO_VDDMIN, + .vddmax = OMAP4_VP_MPU_VLIMITTO_VDDMAX, +}; + +struct omap_vp_param omap4_iva_vp_data = { + .vddmin = OMAP4_VP_IVA_VLIMITTO_VDDMIN, + .vddmax = OMAP4_VP_IVA_VLIMITTO_VDDMAX, +}; + +struct omap_vp_param omap4_core_vp_data = { + .vddmin = OMAP4_VP_CORE_VLIMITTO_VDDMIN, + .vddmax = OMAP4_VP_CORE_VLIMITTO_VDDMAX, +}; diff --git a/arch/arm/mach-omap2/wd_timer.c b/arch/arm/mach-omap2/wd_timer.c new file mode 100644 index 00000000000..97d6607d447 --- /dev/null +++ b/arch/arm/mach-omap2/wd_timer.c @@ -0,0 +1,132 @@ +/* + * OMAP2+ MPU WD_TIMER-specific code + * + * Copyright (C) 2012 Texas Instruments, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/err.h> + +#include <linux/platform_data/omap-wd-timer.h> + +#include "omap_hwmod.h" +#include "omap_device.h" +#include "wd_timer.h" +#include "common.h" +#include "prm.h" +#include "soc.h" + +/* + * In order to avoid any assumptions from bootloader regarding WDT + * settings, WDT module is reset during init. This enables the watchdog + * timer. Hence it is required to disable the watchdog after the WDT reset + * during init. Otherwise the system would reboot as per the default + * watchdog timer registers settings. + */ +#define OMAP_WDT_WPS 0x34 +#define OMAP_WDT_SPR 0x48 + +int omap2_wd_timer_disable(struct omap_hwmod *oh) +{ + void __iomem *base; + + if (!oh) { + pr_err("%s: Could not look up wdtimer_hwmod\n", __func__); + return -EINVAL; + } + + base = omap_hwmod_get_mpu_rt_va(oh); + if (!base) { + pr_err("%s: Could not get the base address for %s\n", + oh->name, __func__); + return -EINVAL; + } + + /* sequence required to disable watchdog */ + writel_relaxed(0xAAAA, base + OMAP_WDT_SPR); + while (readl_relaxed(base + OMAP_WDT_WPS) & 0x10) + cpu_relax(); + + writel_relaxed(0x5555, base + OMAP_WDT_SPR); + while (readl_relaxed(base + OMAP_WDT_WPS) & 0x10) + cpu_relax(); + + return 0; +} + +/** + * omap2_wdtimer_reset - reset and disable the WDTIMER IP block + * @oh: struct omap_hwmod * + * + * After the WDTIMER IP blocks are reset on OMAP2/3, we must also take + * care to execute the special watchdog disable sequence. This is + * because the watchdog is re-armed upon OCP softreset. (On OMAP4, + * this behavior was apparently changed and the watchdog is no longer + * re-armed after an OCP soft-reset.) Returns -ETIMEDOUT if the reset + * did not complete, or 0 upon success. + * + * XXX Most of this code should be moved to the omap_hwmod.c layer + * during a normal merge window. omap_hwmod_softreset() should be + * renamed to omap_hwmod_set_ocp_softreset(), and omap_hwmod_softreset() + * should call the hwmod _ocp_softreset() code. + */ +int omap2_wd_timer_reset(struct omap_hwmod *oh) +{ + int c = 0; + + /* Write to the SOFTRESET bit */ + omap_hwmod_softreset(oh); + + /* Poll on RESETDONE bit */ + omap_test_timeout((omap_hwmod_read(oh, + oh->class->sysc->syss_offs) + & SYSS_RESETDONE_MASK), + MAX_MODULE_SOFTRESET_WAIT, c); + + if (oh->class->sysc->srst_udelay) + udelay(oh->class->sysc->srst_udelay); + + if (c == MAX_MODULE_SOFTRESET_WAIT) + pr_warning("%s: %s: softreset failed (waited %d usec)\n", + __func__, oh->name, MAX_MODULE_SOFTRESET_WAIT); + else + pr_debug("%s: %s: softreset in %d usec\n", __func__, + oh->name, c); + + return (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : + omap2_wd_timer_disable(oh); +} + +static int __init omap_init_wdt(void) +{ + int id = -1; + struct platform_device *pdev; + struct omap_hwmod *oh; + char *oh_name = "wd_timer2"; + char *dev_name = "omap_wdt"; + struct omap_wd_timer_platform_data pdata; + + if (!cpu_class_is_omap2() || of_have_populated_dt()) + return 0; + + oh = omap_hwmod_lookup(oh_name); + if (!oh) { + pr_err("Could not look up wd_timer%d hwmod\n", id); + return -EINVAL; + } + + pdata.read_reset_sources = prm_read_reset_sources; + + pdev = omap_device_build(dev_name, id, oh, &pdata, + sizeof(struct omap_wd_timer_platform_data)); + WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", + dev_name, oh->name); + return 0; +} +omap_subsys_initcall(omap_init_wdt); diff --git a/arch/arm/mach-omap2/wd_timer.h b/arch/arm/mach-omap2/wd_timer.h new file mode 100644 index 00000000000..a78f81034a9 --- /dev/null +++ b/arch/arm/mach-omap2/wd_timer.h @@ -0,0 +1,18 @@ +/* + * OMAP2+ MPU WD_TIMER-specific function prototypes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_WD_TIMER_H +#define __ARCH_ARM_MACH_OMAP2_WD_TIMER_H + +#include "omap_hwmod.h" + +extern int omap2_wd_timer_disable(struct omap_hwmod *oh); +extern int omap2_wd_timer_reset(struct omap_hwmod *oh); + +#endif |
