diff options
Diffstat (limited to 'arch/arm/mach-omap2')
106 files changed, 6389 insertions, 3024 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index cc83f5e13d5..dd2db025f77 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -9,7 +9,7 @@ config ARCH_OMAP2PLUS_TYPICAL  	select REGULATOR  	select PM_RUNTIME  	select VFP -	select NEON if ARCH_OMAP3 || ARCH_OMAP4 +	select NEON if ARCH_OMAP3 || ARCH_OMAP4 || SOC_OMAP5  	select SERIAL_OMAP  	select SERIAL_OMAP_CONSOLE  	select I2C @@ -21,12 +21,16 @@ config ARCH_OMAP2PLUS_TYPICAL  	help  	  Compile a kernel suitable for booting most boards +config SOC_HAS_OMAP2_SDRC +	bool "OMAP2 SDRAM Controller support" +  config ARCH_OMAP2  	bool "TI OMAP2"  	depends on ARCH_OMAP2PLUS  	default y  	select CPU_V6  	select MULTI_IRQ_HANDLER +	select SOC_HAS_OMAP2_SDRC  config ARCH_OMAP3  	bool "TI OMAP3" @@ -35,9 +39,11 @@ config ARCH_OMAP3  	select CPU_V7  	select USB_ARCH_HAS_EHCI if USB_SUPPORT  	select ARCH_HAS_OPP +	select PM_RUNTIME if CPU_IDLE  	select PM_OPP if PM  	select ARM_CPU_SUSPEND if PM  	select MULTI_IRQ_HANDLER +	select SOC_HAS_OMAP2_SDRC  config ARCH_OMAP4  	bool "TI OMAP4" @@ -52,11 +58,18 @@ config ARCH_OMAP4  	select PL310_ERRATA_727915  	select ARM_ERRATA_720789  	select ARCH_HAS_OPP +	select PM_RUNTIME if CPU_IDLE  	select PM_OPP if PM  	select USB_ARCH_HAS_EHCI if USB_SUPPORT  	select ARM_CPU_SUSPEND if PM  	select ARCH_NEEDS_CPU_IDLE_COUPLED +config SOC_OMAP5 +	bool "TI OMAP5" +	select CPU_V7 +	select ARM_GIC +	select HAVE_SMP +  comment "OMAP Core Type"  	depends on ARCH_OMAP2 @@ -65,19 +78,19 @@ config SOC_OMAP2420  	depends on ARCH_OMAP2  	default y  	select OMAP_DM_TIMER -	select ARCH_OMAP_OTG +	select SOC_HAS_OMAP2_SDRC  config SOC_OMAP2430  	bool "OMAP2430 support"  	depends on ARCH_OMAP2  	default y -	select ARCH_OMAP_OTG +	select SOC_HAS_OMAP2_SDRC  config SOC_OMAP3430  	bool "OMAP3430 support"  	depends on ARCH_OMAP3  	default y -	select ARCH_OMAP_OTG +	select SOC_HAS_OMAP2_SDRC  config SOC_TI81XX  	bool "TI81XX support" @@ -86,8 +99,10 @@ config SOC_TI81XX  config SOC_AM33XX  	bool "AM33XX support" -	depends on ARCH_OMAP3  	default y +	select CPU_V7 +	select ARM_CPU_SUSPEND if PM +	select MULTI_IRQ_HANDLER  config OMAP_PACKAGE_ZAF         bool diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index fa742f3c262..f6a24b3f9c4 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -6,7 +6,7 @@  obj-y := id.o io.o control.o mux.o devices.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-2-3-common				= irq.o sdrc.o +omap-2-3-common				= irq.o  hwmod-common				= omap_hwmod.o \  					  omap_hwmod_common_data.o  clock-common				= clock.o clock_common_data.o \ @@ -16,19 +16,24 @@ 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) += prm44xx.o $(hwmod-common) $(secure-common) +obj-$(CONFIG_SOC_AM33XX) += irq.o $(hwmod-common) +obj-$(CONFIG_SOC_OMAP5)	 += prm44xx.o $(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  # SMP support ONLY available for OMAP4  obj-$(CONFIG_SMP)			+= omap-smp.o omap-headsmp.o  obj-$(CONFIG_HOTPLUG_CPU)		+= omap-hotplug.o -obj-$(CONFIG_ARCH_OMAP4)		+= omap4-common.o omap-wakeupgen.o -obj-$(CONFIG_ARCH_OMAP4)		+= sleep44xx.o +omap-4-5-common				=  omap4-common.o omap-wakeupgen.o \ +					   sleep44xx.o +obj-$(CONFIG_ARCH_OMAP4)		+= $(omap-4-5-common) +obj-$(CONFIG_SOC_OMAP5)			+= $(omap-4-5-common)  plus_sec := $(call as-instr,.arch_extension sec,+sec)  AFLAGS_omap-headsmp.o			:=-Wa,-march=armv7-a$(plus_sec) @@ -66,12 +71,12 @@ ifeq ($(CONFIG_PM),y)  obj-$(CONFIG_ARCH_OMAP2)		+= pm24xx.o  obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o  obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o -obj-$(CONFIG_ARCH_OMAP3)		+= cpuidle34xx.o  obj-$(CONFIG_ARCH_OMAP4)		+= pm44xx.o omap-mpuss-lowpower.o -obj-$(CONFIG_ARCH_OMAP4)		+= cpuidle44xx.o +obj-$(CONFIG_SOC_OMAP5)			+= omap-mpuss-lowpower.o  obj-$(CONFIG_PM_DEBUG)			+= pm-debug.o -obj-$(CONFIG_OMAP_SMARTREFLEX)          += sr_device.o smartreflex.o -obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3)	+= smartreflex-class3.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) @@ -82,14 +87,22 @@ endif  endif +ifeq ($(CONFIG_CPU_IDLE),y) +obj-$(CONFIG_ARCH_OMAP3)                += cpuidle34xx.o +obj-$(CONFIG_ARCH_OMAP4)                += cpuidle44xx.o +endif +  # PRCM +omap-prcm-4-5-common			=  prcm.o cminst44xx.o cm44xx.o \ +					   prcm_mpu44xx.o prminst44xx.o \ +					   vc44xx_data.o vp44xx_data.o  obj-y					+= prm_common.o  obj-$(CONFIG_ARCH_OMAP2)		+= prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o  obj-$(CONFIG_ARCH_OMAP3)		+= prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o  obj-$(CONFIG_ARCH_OMAP3)		+= vc3xxx_data.o vp3xxx_data.o -obj-$(CONFIG_ARCH_OMAP4)		+= prcm.o cminst44xx.o cm44xx.o -obj-$(CONFIG_ARCH_OMAP4)		+= prcm_mpu44xx.o prminst44xx.o -obj-$(CONFIG_ARCH_OMAP4)		+= vc44xx_data.o vp44xx_data.o prm44xx.o +obj-$(CONFIG_SOC_AM33XX)		+= prcm.o prm33xx.o cm33xx.o +obj-$(CONFIG_ARCH_OMAP4)		+= $(omap-prcm-4-5-common) prm44xx.o +obj-$(CONFIG_SOC_OMAP5)			+= $(omap-prcm-4-5-common)  # OMAP voltage domains  voltagedomain-common			:= voltage.o vc.o vp.o @@ -99,6 +112,9 @@ 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_AM33XX)                += voltagedomains33xx_data.o +obj-$(CONFIG_SOC_OMAP5)			+= $(voltagedomain-common)  # OMAP powerdomain framework  powerdomain-common			+= powerdomain.o powerdomain-common.o @@ -113,10 +129,14 @@ obj-$(CONFIG_ARCH_OMAP3)		+= powerdomains2xxx_3xxx_data.o  obj-$(CONFIG_ARCH_OMAP4)		+= $(powerdomain-common)  obj-$(CONFIG_ARCH_OMAP4)		+= powerdomain44xx.o  obj-$(CONFIG_ARCH_OMAP4)		+= powerdomains44xx_data.o +obj-$(CONFIG_SOC_AM33XX)		+= $(powerdomain-common) +obj-$(CONFIG_SOC_AM33XX)		+= powerdomain33xx.o +obj-$(CONFIG_SOC_AM33XX)		+= powerdomains33xx_data.o +obj-$(CONFIG_SOC_OMAP5)			+= $(powerdomain-common) +obj-$(CONFIG_SOC_OMAP5)			+= powerdomain44xx.o  # PRCM clockdomain control  clockdomain-common			+= clockdomain.o -clockdomain-common			+= clockdomains_common_data.o  obj-$(CONFIG_ARCH_OMAP2)		+= $(clockdomain-common)  obj-$(CONFIG_ARCH_OMAP2)		+= clockdomain2xxx_3xxx.o  obj-$(CONFIG_ARCH_OMAP2)		+= clockdomains2xxx_3xxx_data.o @@ -129,6 +149,11 @@ obj-$(CONFIG_ARCH_OMAP3)		+= clockdomains3xxx_data.o  obj-$(CONFIG_ARCH_OMAP4)		+= $(clockdomain-common)  obj-$(CONFIG_ARCH_OMAP4)		+= clockdomain44xx.o  obj-$(CONFIG_ARCH_OMAP4)		+= clockdomains44xx_data.o +obj-$(CONFIG_SOC_AM33XX)		+= $(clockdomain-common) +obj-$(CONFIG_SOC_AM33XX)		+= clockdomain33xx.o +obj-$(CONFIG_SOC_AM33XX)		+= clockdomains33xx_data.o +obj-$(CONFIG_SOC_OMAP5)			+= $(clockdomain-common) +obj-$(CONFIG_SOC_OMAP5)			+= clockdomain44xx.o  # Clock framework  obj-$(CONFIG_ARCH_OMAP2)		+= $(clock-common) clock2xxx.o @@ -146,6 +171,10 @@ obj-$(CONFIG_ARCH_OMAP3)		+= dpll3xxx.o clock3xxx_data.o  obj-$(CONFIG_ARCH_OMAP3)		+= clkt_iclk.o  obj-$(CONFIG_ARCH_OMAP4)		+= $(clock-common) clock44xx_data.o  obj-$(CONFIG_ARCH_OMAP4)		+= dpll3xxx.o dpll44xx.o +obj-$(CONFIG_SOC_AM33XX)		+= $(clock-common) dpll3xxx.o +obj-$(CONFIG_SOC_AM33XX)		+= clock33xx_data.o +obj-$(CONFIG_SOC_OMAP5)			+= $(clock-common) +obj-$(CONFIG_SOC_OMAP5)			+= dpll3xxx.o dpll44xx.o  # OMAP2 clock rate set data (old "OPP" data)  obj-$(CONFIG_SOC_OMAP2420)		+= opp2420_data.o @@ -173,6 +202,7 @@ obj-$(CONFIG_OMAP3_EMU)			+= emu.o  # L3 interconnect  obj-$(CONFIG_ARCH_OMAP3)		+= omap_l3_smx.o  obj-$(CONFIG_ARCH_OMAP4)		+= omap_l3_noc.o +obj-$(CONFIG_SOC_OMAP5)			+= omap_l3_noc.o  obj-$(CONFIG_OMAP_MBOX_FWK)		+= mailbox_mach.o  mailbox_mach-objs			:= mailbox.o @@ -189,6 +219,10 @@ endif  # OMAP2420 MSDI controller integration support ("MMC")  obj-$(CONFIG_SOC_OMAP2420)		+= msdi.o +ifneq ($(CONFIG_DRM_OMAP),) +obj-y					+= drm.o +endif +  # Specific board support  obj-$(CONFIG_MACH_OMAP_GENERIC)		+= board-generic.o  obj-$(CONFIG_MACH_OMAP_H4)		+= board-h4.o @@ -244,9 +278,6 @@ obj-y					+= $(omap-flash-y) $(omap-flash-m)  omap-hsmmc-$(CONFIG_MMC_OMAP_HS)	:= hsmmc.o  obj-y					+= $(omap-hsmmc-m) $(omap-hsmmc-y) - -usbfs-$(CONFIG_ARCH_OMAP_OTG)		:= usb-fs.o -obj-y					+= $(usbfs-m) $(usbfs-y)  obj-y					+= usb-musb.o  obj-y					+= omap_phy_internal.o diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c index 447682c4e11..2c90ac68668 100644 --- a/arch/arm/mach-omap2/am35xx-emac.c +++ b/arch/arm/mach-omap2/am35xx-emac.c @@ -15,27 +15,13 @@   * General Public License for more details.   */ -#include <linux/clk.h> +#include <linux/err.h>  #include <linux/davinci_emac.h> -#include <linux/platform_device.h> -#include <plat/irqs.h> +#include <asm/system.h> +#include <plat/omap_device.h>  #include <mach/am35xx.h> -  #include "control.h" - -static struct mdio_platform_data am35xx_emac_mdio_pdata; - -static struct resource am35xx_emac_mdio_resources[] = { -	DEFINE_RES_MEM(AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET, SZ_4K), -}; - -static struct platform_device am35xx_emac_mdio_device = { -	.name		= "davinci_mdio", -	.id		= 0, -	.num_resources	= ARRAY_SIZE(am35xx_emac_mdio_resources), -	.resource	= am35xx_emac_mdio_resources, -	.dev.platform_data = &am35xx_emac_mdio_pdata, -}; +#include "am35xx-emac.h"  static void am35xx_enable_emac_int(void)  { @@ -69,41 +55,57 @@ static struct emac_platform_data am35xx_emac_pdata = {  	.interrupt_disable	= am35xx_disable_emac_int,  }; -static struct resource am35xx_emac_resources[] = { -	DEFINE_RES_MEM(AM35XX_IPSS_EMAC_BASE, 0x30000), -	DEFINE_RES_IRQ(INT_35XX_EMAC_C0_RXTHRESH_IRQ), -	DEFINE_RES_IRQ(INT_35XX_EMAC_C0_RX_PULSE_IRQ), -	DEFINE_RES_IRQ(INT_35XX_EMAC_C0_TX_PULSE_IRQ), -	DEFINE_RES_IRQ(INT_35XX_EMAC_C0_MISC_PULSE_IRQ), -}; +static struct mdio_platform_data am35xx_mdio_pdata; -static struct platform_device am35xx_emac_device = { -	.name		= "davinci_emac", -	.id		= -1, -	.num_resources	= ARRAY_SIZE(am35xx_emac_resources), -	.resource	= am35xx_emac_resources, -	.dev		= { -		.platform_data	= &am35xx_emac_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, +				 NULL, 0, false); +	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 err; +	int ret; -	am35xx_emac_pdata.rmii_en = rmii_en; -	am35xx_emac_mdio_pdata.bus_freq = mdio_bus_freq; -	err = platform_device_register(&am35xx_emac_device); -	if (err) { -		pr_err("AM35x: failed registering EMAC device: %d\n", err); +	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;  	} -	err = platform_device_register(&am35xx_emac_mdio_device); -	if (err) { -		pr_err("AM35x: failed registering EMAC MDIO device: %d\n", err); -		platform_device_unregister(&am35xx_emac_device); +	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;  	} diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 99ca6bad5c3..9511584fdc4 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -218,9 +218,6 @@ static struct twl4030_gpio_platform_data sdp2430_gpio_data = {  };  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,  	.vmmc1		= &sdp2430_vmmc1, @@ -254,16 +251,6 @@ static struct omap2_hsmmc_info mmc[] __initdata = {  	{}	/* Terminator */  }; -static struct omap_usb_config sdp2430_usb_config __initdata = { -	.otg		= 1, -#ifdef  CONFIG_USB_GADGET_OMAP -	.hmc_mode	= 0x0, -#elif   defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) -	.hmc_mode	= 0x1, -#endif -	.pins[0]	= 3, -}; -  #ifdef CONFIG_OMAP_MUX  static struct omap_board_mux board_mux[] __initdata = {  	{ .reg_offset = OMAP_MUX_TERMINATOR }, @@ -280,7 +267,6 @@ static void __init omap_2430sdp_init(void)  	omap_serial_init();  	omap_sdrc_init(NULL, NULL);  	omap_hsmmc_init(mmc); -	omap2_usbfs_init(&sdp2430_usb_config);  	omap_mux_init_signal("usb0hs_stp", OMAP_PULL_ENA | OMAP_PULL_UP);  	usb_musb_init(NULL); diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 8e17284a803..ad8a7d94afc 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -821,6 +821,9 @@ static void __init omap_4430sdp_display_init(void)  #ifdef CONFIG_OMAP_MUX  static struct omap_board_mux board_mux[] __initdata = {  	OMAP4_MUX(USBB2_ULPITLL_CLK, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), +	/* NIRQ2 for twl6040 */ +	OMAP4_MUX(SYS_NIRQ2, OMAP_MUX_MODE0 | +		  OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE),  	{ .reg_offset = OMAP_MUX_TERMINATOR },  }; diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index 502c31e123b..e5fa46bfde2 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c @@ -35,7 +35,6 @@  #include <asm/mach/flash.h>  #include <plat/led.h> -#include <plat/usb.h>  #include <plat/board.h>  #include "common.h"  #include <plat/gpmc.h> @@ -253,13 +252,6 @@ out:  	clk_put(gpmc_fck);  } -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 panel_generic_dpi_data apollon_panel_data = {  	.name			= "apollon",  }; @@ -297,15 +289,6 @@ static void __init apollon_led_init(void)  	gpio_request_array(apollon_gpio_leds, ARRAY_SIZE(apollon_gpio_leds));  } -static void __init apollon_usb_init(void) -{ -	/* USB device */ -	/* DEVICE_SUSPEND */ -	omap_mux_init_signal("mcbsp2_clkx.gpio_12", 0); -	gpio_request_one(12, GPIOF_OUT_INIT_LOW, "USB suspend"); -	omap2_usbfs_init(&apollon_usb_config); -} -  #ifdef CONFIG_OMAP_MUX  static struct omap_board_mux board_mux[] __initdata = {  	{ .reg_offset = OMAP_MUX_TERMINATOR }, @@ -321,7 +304,6 @@ static void __init omap_apollon_init(void)  	apollon_init_smc91x();  	apollon_led_init();  	apollon_flash_init(); -	apollon_usb_init();  	/* REVISIT: where's the correct place */  	omap_mux_init_signal("sys_nirq", OMAP_PULL_ENA | OMAP_PULL_UP); @@ -329,7 +311,7 @@ static void __init omap_apollon_init(void)  	/* LCD PWR_EN */  	omap_mux_init_signal("mcbsp2_dr.gpio_11", OMAP_PULL_ENA | OMAP_PULL_UP); -	/* Use Interal loop-back in MMC/SDIO Module Input Clock selection */ +	/* Use Internal 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); diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index ded100c80a9..97d719047af 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -490,6 +490,71 @@ static struct twl4030_platform_data cm_t35_twldata = {  	.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 void __init cm_t35_init_camera(void) +{ +	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, @@ -497,6 +562,8 @@ static void __init cm_t35_init_i2c(void)  			      TWL_COMMON_PDATA_AUDIO);  	omap3_pmic_init("tps65930", &cm_t35_twldata); + +	omap_register_i2c_bus(3, 400, NULL, 0);  }  #ifdef CONFIG_OMAP_MUX @@ -574,6 +641,27 @@ static struct omap_board_mux board_mux[] __initdata = {  	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), @@ -646,6 +734,7 @@ static void __init cm_t3x_common_init(void)  	usb_musb_init(NULL);  	cm_t35_init_usbh(); +	cm_t35_init_camera();  }  static void __init cm_t35_init(void) diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 20293465786..6f93a20536e 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -25,23 +25,12 @@  #include "common-board-devices.h"  #if !(defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)) -#define omap_intc_of_init	NULL +#define intc_of_init	NULL  #endif  #ifndef CONFIG_ARCH_OMAP4  #define gic_of_init		NULL  #endif -static struct of_device_id irq_match[] __initdata = { -	{ .compatible = "ti,omap2-intc", .data = omap_intc_of_init, }, -	{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, -	{ } -}; - -static void __init omap_init_irq(void) -{ -	of_irq_init(irq_match); -} -  static struct of_device_id omap_dt_match_table[] __initdata = {  	{ .compatible = "simple-bus", },  	{ .compatible = "ti,omap-infra", }, @@ -65,7 +54,7 @@ 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_init_irq, +	.init_irq	= omap_intc_of_init,  	.handle_irq	= omap2_intc_handle_irq,  	.init_machine	= omap_generic_init,  	.timer		= &omap2_timer, @@ -84,7 +73,7 @@ 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_init_irq, +	.init_irq	= omap_intc_of_init,  	.handle_irq	= omap2_intc_handle_irq,  	.init_machine	= omap_generic_init,  	.timer		= &omap2_timer, @@ -103,7 +92,7 @@ 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_init_irq, +	.init_irq	= omap_intc_of_init,  	.handle_irq	= omap3_intc_handle_irq,  	.init_machine	= omap_generic_init,  	.timer		= &omap3_timer, @@ -112,6 +101,24 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")  MACHINE_END  #endif +#ifdef CONFIG_SOC_AM33XX +static const char *am33xx_boards_compat[] __initdata = { +	"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, +	.timer		= &omap3_am33xx_timer, +	.dt_compat	= am33xx_boards_compat, +MACHINE_END +#endif +  #ifdef CONFIG_ARCH_OMAP4  static const char *omap4_boards_compat[] __initdata = {  	"ti,omap4", @@ -122,7 +129,7 @@ DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)")  	.reserve	= omap_reserve,  	.map_io		= omap4_map_io,  	.init_early	= omap4430_init_early, -	.init_irq	= omap_init_irq, +	.init_irq	= omap_gic_of_init,  	.handle_irq	= gic_handle_irq,  	.init_machine	= omap_generic_init,  	.init_late	= omap4430_init_late, @@ -131,3 +138,22 @@ DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)")  	.restart	= omap_prcm_restart,  MACHINE_END  #endif + +#ifdef CONFIG_SOC_OMAP5 +static const char *omap5_boards_compat[] __initdata = { +	"ti,omap5", +	NULL, +}; + +DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)") +	.reserve	= omap_reserve, +	.map_io		= omap5_map_io, +	.init_early	= omap5_init_early, +	.init_irq	= omap_gic_of_init, +	.handle_irq	= gic_handle_irq, +	.init_machine	= omap_generic_init, +	.timer		= &omap5_timer, +	.dt_compat	= omap5_boards_compat, +	.restart	= omap_prcm_restart, +MACHINE_END +#endif diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index 876becf8205..ace20482e3e 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -32,7 +32,6 @@  #include <asm/mach/arch.h>  #include <asm/mach/map.h> -#include <plat/usb.h>  #include <plat/board.h>  #include "common.h"  #include <plat/menelaus.h> @@ -329,17 +328,6 @@ static void __init h4_init_flash(void)  	h4_flash_resource.end	= base + SZ_64M - 1;  } -static struct omap_usb_config h4_usb_config __initdata = { -	/* S1.10 OFF -- usb "download port" -	 * usb0 switched to Mini-B port and isp1105 transceiver; -	 * S2.POS3 = ON, S2.POS4 = OFF ... to enable battery charging -	 */ -	.register_dev	= 1, -	.pins[0]	= 3, -/*	.hmc_mode	= 0x14,*/	/* 0:dev 1:host 2:disable */ -	.hmc_mode	= 0x00,		/* 0:dev|otg 1:disable 2:disable */ -}; -  static struct at24_platform_data m24c01 = {  	.byte_len	= SZ_1K / 8,  	.page_size	= 16, @@ -381,7 +369,6 @@ static void __init omap_h4_init(void)  			ARRAY_SIZE(h4_i2c_board_info));  	platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices)); -	omap2_usbfs_init(&h4_usb_config);  	omap_serial_init();  	omap_sdrc_init(NULL, NULL);  	h4_init_flash(); diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index 2c5d0ed7528..677357ff61a 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -468,7 +468,6 @@ static struct omap_mmc_platform_data mmc1_data = {  	.cleanup			= n8x0_mmc_cleanup,  	.shutdown			= n8x0_mmc_shutdown,  	.max_freq			= 24000000, -	.dma_mask			= 0xffffffff,  	.slots[0] = {  		.wires			= 4,  		.set_power		= n8x0_mmc_set_power, diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 580fd17208d..6202fc76e49 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -433,7 +433,7 @@ static struct platform_device *omap3_beagle_devices[] __initdata = {  static const struct usbhs_omap_board_data usbhs_bdata __initconst = { -	.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, +	.port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,  	.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,  	.port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index 639bd07ea38..ef230a0eb5e 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -24,6 +24,10 @@  #include <linux/leds.h>  #include <linux/interrupt.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/nand.h> +  #include <linux/spi/spi.h>  #include <linux/spi/ads7846.h>  #include <linux/i2c/twl.h> @@ -43,6 +47,7 @@  #include <plat/board.h>  #include <plat/usb.h> +#include <plat/nand.h>  #include "common.h"  #include <plat/mcspi.h>  #include <video/omapdss.h> @@ -53,7 +58,6 @@  #include "hsmmc.h"  #include "common-board-devices.h" -#define OMAP3_EVM_TS_GPIO	175  #define OMAP3_EVM_EHCI_VBUS	22  #define OMAP3_EVM_EHCI_SELECT	61 @@ -355,6 +359,19 @@ static int omap3evm_twl_gpio_setup(struct device *dev,  	platform_device_register(&leds_gpio); +	/* Enable VBUS switch by setting TWL4030.GPIO2DIR as output +	 * for starting USB tranceiver +	 */ +#ifdef CONFIG_TWL4030_CORE +	if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) { +		u8 val; + +		twl_i2c_read_u8(TWL4030_MODULE_GPIO, &val, REG_GPIODATADIR1); +		val |= 0x04; /* TWL4030.GPIO2DIR BIT at GPIODATADIR1(0x9B) */ +		twl_i2c_write_u8(TWL4030_MODULE_GPIO, val, REG_GPIODATADIR1); +	} +#endif +  	return 0;  } @@ -461,6 +478,28 @@ struct wl12xx_platform_data omap3evm_wlan_data __initdata = {  };  #endif +/* VAUX2 for USB */ +static struct regulator_consumer_supply omap3evm_vaux2_supplies[] = { +	REGULATOR_SUPPLY("VDD_CSIPHY1", "omap3isp"),	/* OMAP ISP */ +	REGULATOR_SUPPLY("VDD_CSIPHY2", "omap3isp"),	/* OMAP ISP */ +	REGULATOR_SUPPLY("hsusb1", "ehci-omap.0"), +	REGULATOR_SUPPLY("vaux2", NULL), +}; + +static struct regulator_init_data omap3evm_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, +	}, +	.num_consumer_supplies		= ARRAY_SIZE(omap3evm_vaux2_supplies), +	.consumer_supplies		= omap3evm_vaux2_supplies, +}; +  static struct twl4030_platform_data omap3evm_twldata = {  	/* platform_data for children goes here */  	.keypad		= &omap3evm_kp_data, @@ -607,6 +646,37 @@ static struct regulator_consumer_supply dummy_supplies[] = {  	REGULATOR_SUPPLY("vdd33a", "smsc911x.0"),  }; +static struct mtd_partition omap3evm_nand_partitions[] = { +	/* All the partition sizes are listed in terms of NAND block size */ +	{ +		.name           = "X-Loader", +		.offset         = 0, +		.size           = 4*(SZ_128K), +		.mask_flags     = MTD_WRITEABLE +	}, +	{ +		.name           = "U-Boot", +		.offset         = MTDPART_OFS_APPEND, +		.size           = 14*(SZ_128K), +		.mask_flags     = MTD_WRITEABLE +	}, +	{ +		.name           = "U-Boot Env", +		.offset         = MTDPART_OFS_APPEND, +		.size           = 2*(SZ_128K) +	}, +	{ +		.name           = "Kernel", +		.offset         = MTDPART_OFS_APPEND, +		.size           = 40*(SZ_128K) +	}, +	{ +		.name           = "File system", +		.size           = MTDPART_SIZ_FULL, +		.offset         = MTDPART_OFS_APPEND, +	}, +}; +  static void __init omap3_evm_init(void)  {  	struct omap_board_mux *obm; @@ -623,6 +693,9 @@ static void __init omap3_evm_init(void)  	omap_mux_init_gpio(63, OMAP_PIN_INPUT);  	omap_hsmmc_init(mmc); +	if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) +		omap3evm_twldata.vaux2 = &omap3evm_vaux2; +  	omap3_evm_i2c_init();  	omap_display_init(&omap3_evm_dss_data); @@ -656,6 +729,9 @@ static void __init omap3_evm_init(void)  	}  	usb_musb_init(&musb_board_data);  	usbhs_init(&usbhs_bdata); +	omap_nand_flash_init(NAND_BUSWIDTH_16, omap3evm_nand_partitions, +			     ARRAY_SIZE(omap3evm_nand_partitions)); +  	omap_ads7846_init(1, OMAP3_EVM_TS_GPIO, 310, NULL);  	omap3evm_init_smsc911x();  	omap3_evm_display_init(); diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c index 932e1778aff..fca93d1afd4 100644 --- a/arch/arm/mach-omap2/board-omap3logic.c +++ b/arch/arm/mach-omap2/board-omap3logic.c @@ -93,9 +93,6 @@ static struct twl4030_usb_data omap3logic_usb_data = {  static struct twl4030_platform_data omap3logic_twldata = { -	.irq_base	= TWL4030_IRQ_BASE, -	.irq_end	= TWL4030_IRQ_END, -  	/* platform_data for children goes here */  	.gpio		= &omap3logic_gpio_data,  	.vmmc1		= &omap3logic_vmmc1, diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 982fb2622ab..70f6d1d2546 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -106,7 +106,7 @@ static struct platform_device leds_gpio = {  static struct omap_abe_twl6040_data panda_abe_audio_data = {  	/* Audio out */  	.has_hs		= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT, -	/* HandsFree through expasion connector */ +	/* HandsFree through expansion connector */  	.has_hf		= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,  	/* PandaBoard: FM TX, PandaBoardES: can be connected to audio out */  	.has_aux	= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT, @@ -379,6 +379,9 @@ static struct omap_board_mux board_mux[] __initdata = {  	OMAP4_MUX(DPM_EMU18, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),  	/* dispc2_data0 */  	OMAP4_MUX(DPM_EMU19, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), +	/* NIRQ2 for twl6040 */ +	OMAP4_MUX(SYS_NIRQ2, OMAP_MUX_MODE0 | +		  OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE),  	{ .reg_offset = OMAP_MUX_TERMINATOR },  }; diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 5c4e6654216..ea3f565ba1a 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -398,24 +398,6 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)  	return omap2_clksel_set_parent(clk, new_parent);  } -/* OMAP3/4 non-CORE DPLL clkops */ - -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) - -const struct clkops clkops_omap3_noncore_dpll_ops = { -	.enable		= omap3_noncore_dpll_enable, -	.disable	= omap3_noncore_dpll_disable, -	.allow_idle	= omap3_dpll_allow_idle, -	.deny_idle	= omap3_dpll_deny_idle, -}; - -const struct clkops clkops_omap3_core_dpll_ops = { -	.allow_idle	= omap3_dpll_allow_idle, -	.deny_idle	= omap3_dpll_deny_idle, -}; - -#endif -  /*   * OMAP2+ clock reset and init functions   */ diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index a1bb23a2335..35ec5f3d9a7 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -155,4 +155,18 @@ extern const struct clkops clkops_omap3_noncore_dpll_ops;  extern const struct clkops clkops_omap3_core_dpll_ops;  extern const struct clkops clkops_omap4_dpllmx_ops; +/* clksel_rate blocks shared between OMAP44xx and AM33xx */ +extern const struct clksel_rate div_1_0_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[]; + +/* clocks shared between various OMAP SoCs */ +extern struct clk virt_19200000_ck; +extern struct clk virt_26000000_ck; + +extern int am33xx_clk_init(void); +  #endif diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c index bace9308a4d..002745181ad 100644 --- a/arch/arm/mach-omap2/clock2420_data.c +++ b/arch/arm/mach-omap2/clock2420_data.c @@ -1774,8 +1774,6 @@ static struct omap_clk omap2420_clks[] = {  	CLK(NULL,	"osc_ck",	&osc_ck,	CK_242X),  	CLK(NULL,	"sys_ck",	&sys_ck,	CK_242X),  	CLK(NULL,	"alt_ck",	&alt_ck,	CK_242X), -	CLK("omap-mcbsp.1",	"pad_fck",	&mcbsp_clks,	CK_242X), -	CLK("omap-mcbsp.2",	"pad_fck",	&mcbsp_clks,	CK_242X),  	CLK(NULL,	"mcbsp_clks",	&mcbsp_clks,	CK_242X),  	/* internal analog sources */  	CLK(NULL,	"dpll_ck",	&dpll_ck,	CK_242X), @@ -1784,8 +1782,6 @@ static struct omap_clk omap2420_clks[] = {  	/* internal prcm root sources */  	CLK(NULL,	"func_54m_ck",	&func_54m_ck,	CK_242X),  	CLK(NULL,	"core_ck",	&core_ck,	CK_242X), -	CLK("omap-mcbsp.1",	"prcm_fck",	&func_96m_ck,	CK_242X), -	CLK("omap-mcbsp.2",	"prcm_fck",	&func_96m_ck,	CK_242X),  	CLK(NULL,	"func_96m_ck",	&func_96m_ck,	CK_242X),  	CLK(NULL,	"func_48m_ck",	&func_48m_ck,	CK_242X),  	CLK(NULL,	"func_12m_ck",	&func_12m_ck,	CK_242X), @@ -1901,42 +1897,9 @@ static struct omap_clk omap2420_clks[] = {  	CLK(NULL,	"pka_ick",	&pka_ick,	CK_242X),  	CLK(NULL,	"usb_fck",	&usb_fck,	CK_242X),  	CLK("musb-hdrc",	"fck",	&osc_ck,	CK_242X), -	CLK("omap_timer.1",	"32k_ck",	&func_32k_ck,	CK_243X), -	CLK("omap_timer.2",	"32k_ck",	&func_32k_ck,	CK_243X), -	CLK("omap_timer.3",	"32k_ck",	&func_32k_ck,	CK_243X), -	CLK("omap_timer.4",	"32k_ck",	&func_32k_ck,	CK_243X), -	CLK("omap_timer.5",	"32k_ck",	&func_32k_ck,	CK_243X), -	CLK("omap_timer.6",	"32k_ck",	&func_32k_ck,	CK_243X), -	CLK("omap_timer.7",	"32k_ck",	&func_32k_ck,	CK_243X), -	CLK("omap_timer.8",	"32k_ck",	&func_32k_ck,	CK_243X), -	CLK("omap_timer.9",	"32k_ck",	&func_32k_ck,	CK_243X), -	CLK("omap_timer.10",	"32k_ck",	&func_32k_ck,	CK_243X), -	CLK("omap_timer.11",	"32k_ck",	&func_32k_ck,	CK_243X), -	CLK("omap_timer.12",	"32k_ck",	&func_32k_ck,	CK_243X), -	CLK("omap_timer.1",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.2",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.3",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.4",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.5",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.6",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.7",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.8",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.9",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.10",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.11",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.12",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.1",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.2",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.3",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.4",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.5",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.6",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.7",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.8",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.9",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.10",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.11",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.12",	"alt_ck",	&alt_ck,	CK_243X), +	CLK(NULL,	"timer_32k_ck",	&func_32k_ck,	CK_243X), +	CLK(NULL,	"timer_sys_ck",	&sys_ck,	CK_243X), +	CLK(NULL,	"timer_ext_ck",	&alt_ck,	CK_243X),  };  /* diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c index 3b4d09a5039..cacabb070e2 100644 --- a/arch/arm/mach-omap2/clock2430_data.c +++ b/arch/arm/mach-omap2/clock2430_data.c @@ -1858,11 +1858,6 @@ static struct omap_clk omap2430_clks[] = {  	CLK(NULL,	"osc_ck",	&osc_ck,	CK_243X),  	CLK(NULL,	"sys_ck",	&sys_ck,	CK_243X),  	CLK(NULL,	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap-mcbsp.1",	"pad_fck",	&mcbsp_clks,	CK_243X), -	CLK("omap-mcbsp.2",	"pad_fck",	&mcbsp_clks,	CK_243X), -	CLK("omap-mcbsp.3",	"pad_fck",	&mcbsp_clks,	CK_243X), -	CLK("omap-mcbsp.4",	"pad_fck",	&mcbsp_clks,	CK_243X), -	CLK("omap-mcbsp.5",	"pad_fck",	&mcbsp_clks,	CK_243X),  	CLK(NULL,	"mcbsp_clks",	&mcbsp_clks,	CK_243X),  	/* internal analog sources */  	CLK(NULL,	"dpll_ck",	&dpll_ck,	CK_243X), @@ -1871,11 +1866,6 @@ static struct omap_clk omap2430_clks[] = {  	/* internal prcm root sources */  	CLK(NULL,	"func_54m_ck",	&func_54m_ck,	CK_243X),  	CLK(NULL,	"core_ck",	&core_ck,	CK_243X), -	CLK("omap-mcbsp.1",	"prcm_fck",	&func_96m_ck,	CK_243X), -	CLK("omap-mcbsp.2",	"prcm_fck",	&func_96m_ck,	CK_243X), -	CLK("omap-mcbsp.3",	"prcm_fck",	&func_96m_ck,	CK_243X), -	CLK("omap-mcbsp.4",	"prcm_fck",	&func_96m_ck,	CK_243X), -	CLK("omap-mcbsp.5",	"prcm_fck",	&func_96m_ck,	CK_243X),  	CLK(NULL,	"func_96m_ck",	&func_96m_ck,	CK_243X),  	CLK(NULL,	"func_48m_ck",	&func_48m_ck,	CK_243X),  	CLK(NULL,	"func_12m_ck",	&func_12m_ck,	CK_243X), @@ -2000,42 +1990,9 @@ static struct omap_clk omap2430_clks[] = {  	CLK(NULL,	"mdm_intc_ick",	&mdm_intc_ick,	CK_243X),  	CLK("omap_hsmmc.0", "mmchsdb_fck",	&mmchsdb1_fck,	CK_243X),  	CLK("omap_hsmmc.1", "mmchsdb_fck",	&mmchsdb2_fck,	CK_243X), -	CLK("omap_timer.1",	"32k_ck",  &func_32k_ck,   CK_243X), -	CLK("omap_timer.2",	"32k_ck",  &func_32k_ck,   CK_243X), -	CLK("omap_timer.3",	"32k_ck",  &func_32k_ck,   CK_243X), -	CLK("omap_timer.4",	"32k_ck",  &func_32k_ck,   CK_243X), -	CLK("omap_timer.5",	"32k_ck",  &func_32k_ck,   CK_243X), -	CLK("omap_timer.6",	"32k_ck",  &func_32k_ck,   CK_243X), -	CLK("omap_timer.7",	"32k_ck",  &func_32k_ck,   CK_243X), -	CLK("omap_timer.8",	"32k_ck",  &func_32k_ck,   CK_243X), -	CLK("omap_timer.9",	"32k_ck",  &func_32k_ck,   CK_243X), -	CLK("omap_timer.10",	"32k_ck",  &func_32k_ck,   CK_243X), -	CLK("omap_timer.11",	"32k_ck",  &func_32k_ck,   CK_243X), -	CLK("omap_timer.12",	"32k_ck",  &func_32k_ck,   CK_243X), -	CLK("omap_timer.1",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.2",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.3",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.4",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.5",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.6",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.7",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.8",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.9",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.10",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.11",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.12",	"sys_ck",	&sys_ck,	CK_243X), -	CLK("omap_timer.1",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.2",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.3",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.4",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.5",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.6",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.7",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.8",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.9",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.10",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.11",	"alt_ck",	&alt_ck,	CK_243X), -	CLK("omap_timer.12",	"alt_ck",	&alt_ck,	CK_243X), +	CLK(NULL,	"timer_32k_ck",  &func_32k_ck,   CK_243X), +	CLK(NULL,	"timer_sys_ck",	&sys_ck,	CK_243X), +	CLK(NULL,	"timer_ext_ck",	&alt_ck,	CK_243X),  };  /* diff --git a/arch/arm/mach-omap2/clock33xx_data.c b/arch/arm/mach-omap2/clock33xx_data.c new file mode 100644 index 00000000000..25bbcc7ca4d --- /dev/null +++ b/arch/arm/mach-omap2/clock33xx_data.c @@ -0,0 +1,1105 @@ +/* + * AM33XX Clock data + * + * Copyright (C) 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/list.h> +#include <linux/clk.h> +#include <plat/clkdev_omap.h> +#include <plat/am33xx.h> + +#include "iomap.h" +#include "control.h" +#include "clock.h" +#include "cm.h" +#include "cm33xx.h" +#include "cm-regbits-33xx.h" +#include "prm.h" + +/* Maximum DPLL multiplier, divider values for AM33XX */ +#define AM33XX_MAX_DPLL_MULT		2047 +#define AM33XX_MAX_DPLL_DIV		128 + +/* Modulemode control */ +#define AM33XX_MODULEMODE_HWCTRL	0 +#define AM33XX_MODULEMODE_SWCTRL	1 + +/* TRM ERRATA: Timer 3 & 6 default parent (TCLKIN) may not be always + *    physically present, in such a case HWMOD enabling of + *    clock would be failure with default parent. And timer + *    probe thinks clock is already enabled, this leads to + *    crash upon accessing timer 3 & 6 registers in probe. + *    Fix by setting parent of both these timers to master + *    oscillator clock. + */ +static inline void am33xx_init_timer_parent(struct clk *clk) +{ +	omap2_clksel_set_parent(clk, clk->parent); +} + +/* Root clocks */ + +/* RTC 32k */ +static struct clk clk_32768_ck = { +	.name		= "clk_32768_ck", +	.clkdm_name	= "l4_rtc_clkdm", +	.rate		= 32768, +	.ops		= &clkops_null, +}; + +/* On-Chip 32KHz RC OSC */ +static struct clk clk_rc32k_ck = { +	.name		= "clk_rc32k_ck", +	.rate		= 32000, +	.ops		= &clkops_null, +}; + +/* Crystal input clks */ +static struct clk virt_24000000_ck = { +	.name		= "virt_24000000_ck", +	.rate		= 24000000, +	.ops		= &clkops_null, +}; + +static struct clk virt_25000000_ck = { +	.name		= "virt_25000000_ck", +	.rate		= 25000000, +	.ops		= &clkops_null, +}; + +/* Oscillator clock */ +/* 19.2, 24, 25 or 26 MHz */ +static const struct clksel sys_clkin_sel[] = { +	{ .parent = &virt_19200000_ck, .rates = div_1_0_rates }, +	{ .parent = &virt_24000000_ck, .rates = div_1_1_rates }, +	{ .parent = &virt_25000000_ck, .rates = div_1_2_rates }, +	{ .parent = &virt_26000000_ck, .rates = div_1_3_rates }, +	{ .parent = NULL }, +}; + +/* External clock - 12 MHz */ +static struct clk tclkin_ck = { +	.name		= "tclkin_ck", +	.rate		= 12000000, +	.ops		= &clkops_null, +}; + +/* + * sys_clk in: input to the dpll and also used as funtional clock for, + *   adc_tsc, smartreflex0-1, timer1-7, mcasp0-1, dcan0-1, cefuse + * + */ +static struct clk sys_clkin_ck = { +	.name		= "sys_clkin_ck", +	.parent		= &virt_24000000_ck, +	.init		= &omap2_init_clksel_parent, +	.clksel_reg	= AM33XX_CTRL_REGADDR(AM33XX_CONTROL_STATUS), +	.clksel_mask	= AM33XX_CONTROL_STATUS_SYSBOOT1_MASK, +	.clksel		= sys_clkin_sel, +	.ops		= &clkops_null, +	.recalc		= &omap2_clksel_recalc, +}; + +/* DPLL_CORE */ +static struct dpll_data dpll_core_dd = { +	.mult_div1_reg	= AM33XX_CM_CLKSEL_DPLL_CORE, +	.clk_bypass	= &sys_clkin_ck, +	.clk_ref	= &sys_clkin_ck, +	.control_reg	= AM33XX_CM_CLKMODE_DPLL_CORE, +	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), +	.idlest_reg	= AM33XX_CM_IDLEST_DPLL_CORE, +	.mult_mask	= AM33XX_DPLL_MULT_MASK, +	.div1_mask	= AM33XX_DPLL_DIV_MASK, +	.enable_mask	= AM33XX_DPLL_EN_MASK, +	.idlest_mask	= AM33XX_ST_DPLL_CLK_MASK, +	.max_multiplier	= AM33XX_MAX_DPLL_MULT, +	.max_divider	= AM33XX_MAX_DPLL_DIV, +	.min_divider	= 1, +}; + +/* CLKDCOLDO output */ +static struct clk dpll_core_ck = { +	.name		= "dpll_core_ck", +	.parent		= &sys_clkin_ck, +	.dpll_data	= &dpll_core_dd, +	.init		= &omap2_init_dpll_parent, +	.ops		= &clkops_omap3_core_dpll_ops, +	.recalc		= &omap3_dpll_recalc, +}; + +static struct clk dpll_core_x2_ck = { +	.name		= "dpll_core_x2_ck", +	.parent		= &dpll_core_ck, +	.flags		= CLOCK_CLKOUTX2, +	.ops		= &clkops_null, +	.recalc		= &omap3_clkoutx2_recalc, +}; + + +static const struct clksel dpll_core_m4_div[] = { +	{ .parent = &dpll_core_x2_ck, .rates = div31_1to31_rates }, +	{ .parent = NULL }, +}; + +static struct clk dpll_core_m4_ck = { +	.name		= "dpll_core_m4_ck", +	.parent		= &dpll_core_x2_ck, +	.init		= &omap2_init_clksel_parent, +	.clksel		= dpll_core_m4_div, +	.clksel_reg	= AM33XX_CM_DIV_M4_DPLL_CORE, +	.clksel_mask	= AM33XX_HSDIVIDER_CLKOUT1_DIV_MASK, +	.ops		= &clkops_null, +	.recalc		= &omap2_clksel_recalc, +	.round_rate	= &omap2_clksel_round_rate, +	.set_rate	= &omap2_clksel_set_rate, +}; + +static const struct clksel dpll_core_m5_div[] = { +	{ .parent = &dpll_core_x2_ck, .rates = div31_1to31_rates }, +	{ .parent = NULL }, +}; + +static struct clk dpll_core_m5_ck = { +	.name		= "dpll_core_m5_ck", +	.parent		= &dpll_core_x2_ck, +	.init		= &omap2_init_clksel_parent, +	.clksel		= dpll_core_m5_div, +	.clksel_reg	= AM33XX_CM_DIV_M5_DPLL_CORE, +	.clksel_mask	= AM33XX_HSDIVIDER_CLKOUT2_DIV_MASK, +	.ops		= &clkops_null, +	.recalc		= &omap2_clksel_recalc, +	.round_rate	= &omap2_clksel_round_rate, +	.set_rate	= &omap2_clksel_set_rate, +}; + +static const struct clksel dpll_core_m6_div[] = { +	{ .parent = &dpll_core_x2_ck, .rates = div31_1to31_rates }, +	{ .parent = NULL }, +}; + +static struct clk dpll_core_m6_ck = { +	.name		= "dpll_core_m6_ck", +	.parent		= &dpll_core_x2_ck, +	.init		= &omap2_init_clksel_parent, +	.clksel		= dpll_core_m6_div, +	.clksel_reg	= AM33XX_CM_DIV_M6_DPLL_CORE, +	.clksel_mask	= AM33XX_HSDIVIDER_CLKOUT3_DIV_MASK, +	.ops		= &clkops_null, +	.recalc		= &omap2_clksel_recalc, +	.round_rate	= &omap2_clksel_round_rate, +	.set_rate	= &omap2_clksel_set_rate, +}; + +/* DPLL_MPU */ +static struct dpll_data dpll_mpu_dd = { +	.mult_div1_reg	= AM33XX_CM_CLKSEL_DPLL_MPU, +	.clk_bypass	= &sys_clkin_ck, +	.clk_ref	= &sys_clkin_ck, +	.control_reg	= AM33XX_CM_CLKMODE_DPLL_MPU, +	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), +	.idlest_reg	= AM33XX_CM_IDLEST_DPLL_MPU, +	.mult_mask	= AM33XX_DPLL_MULT_MASK, +	.div1_mask	= AM33XX_DPLL_DIV_MASK, +	.enable_mask	= AM33XX_DPLL_EN_MASK, +	.idlest_mask	= AM33XX_ST_DPLL_CLK_MASK, +	.max_multiplier	= AM33XX_MAX_DPLL_MULT, +	.max_divider	= AM33XX_MAX_DPLL_DIV, +	.min_divider	= 1, +}; + +/* CLKOUT: fdpll/M2 */ +static struct clk dpll_mpu_ck = { +	.name		= "dpll_mpu_ck", +	.parent		= &sys_clkin_ck, +	.dpll_data	= &dpll_mpu_dd, +	.init		= &omap2_init_dpll_parent, +	.ops		= &clkops_omap3_noncore_dpll_ops, +	.recalc		= &omap3_dpll_recalc, +	.round_rate	= &omap2_dpll_round_rate, +	.set_rate	= &omap3_noncore_dpll_set_rate, +}; + +/* + * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2 + * and ALT_CLK1/2) + */ +static const struct clksel dpll_mpu_m2_div[] = { +	{ .parent = &dpll_mpu_ck, .rates = div31_1to31_rates }, +	{ .parent = NULL }, +}; + +static struct clk dpll_mpu_m2_ck = { +	.name		= "dpll_mpu_m2_ck", +	.clkdm_name	= "mpu_clkdm", +	.parent		= &dpll_mpu_ck, +	.clksel		= dpll_mpu_m2_div, +	.clksel_reg	= AM33XX_CM_DIV_M2_DPLL_MPU, +	.clksel_mask	= AM33XX_DPLL_CLKOUT_DIV_MASK, +	.ops		= &clkops_null, +	.recalc		= &omap2_clksel_recalc, +	.round_rate	= &omap2_clksel_round_rate, +	.set_rate	= &omap2_clksel_set_rate, +}; + +/* DPLL_DDR */ +static struct dpll_data dpll_ddr_dd = { +	.mult_div1_reg	= AM33XX_CM_CLKSEL_DPLL_DDR, +	.clk_bypass	= &sys_clkin_ck, +	.clk_ref	= &sys_clkin_ck, +	.control_reg	= AM33XX_CM_CLKMODE_DPLL_DDR, +	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), +	.idlest_reg	= AM33XX_CM_IDLEST_DPLL_DDR, +	.mult_mask	= AM33XX_DPLL_MULT_MASK, +	.div1_mask	= AM33XX_DPLL_DIV_MASK, +	.enable_mask	= AM33XX_DPLL_EN_MASK, +	.idlest_mask	= AM33XX_ST_DPLL_CLK_MASK, +	.max_multiplier	= AM33XX_MAX_DPLL_MULT, +	.max_divider	= AM33XX_MAX_DPLL_DIV, +	.min_divider	= 1, +}; + +/* CLKOUT: fdpll/M2 */ +static struct clk dpll_ddr_ck = { +	.name		= "dpll_ddr_ck", +	.parent		= &sys_clkin_ck, +	.dpll_data	= &dpll_ddr_dd, +	.init		= &omap2_init_dpll_parent, +	.ops		= &clkops_null, +	.recalc		= &omap3_dpll_recalc, +}; + +/* + * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2 + * and ALT_CLK1/2) + */ +static const struct clksel dpll_ddr_m2_div[] = { +	{ .parent = &dpll_ddr_ck, .rates = div31_1to31_rates }, +	{ .parent = NULL }, +}; + +static struct clk dpll_ddr_m2_ck = { +	.name		= "dpll_ddr_m2_ck", +	.parent		= &dpll_ddr_ck, +	.clksel		= dpll_ddr_m2_div, +	.clksel_reg	= AM33XX_CM_DIV_M2_DPLL_DDR, +	.clksel_mask	= AM33XX_DPLL_CLKOUT_DIV_MASK, +	.ops		= &clkops_null, +	.recalc		= &omap2_clksel_recalc, +	.round_rate	= &omap2_clksel_round_rate, +	.set_rate	= &omap2_clksel_set_rate, +}; + +/* emif_fck functional clock */ +static struct clk dpll_ddr_m2_div2_ck = { +	.name		= "dpll_ddr_m2_div2_ck", +	.clkdm_name	= "l3_clkdm", +	.parent		= &dpll_ddr_m2_ck, +	.ops		= &clkops_null, +	.fixed_div	= 2, +	.recalc		= &omap_fixed_divisor_recalc, +}; + +/* DPLL_DISP */ +static struct dpll_data dpll_disp_dd = { +	.mult_div1_reg	= AM33XX_CM_CLKSEL_DPLL_DISP, +	.clk_bypass	= &sys_clkin_ck, +	.clk_ref	= &sys_clkin_ck, +	.control_reg	= AM33XX_CM_CLKMODE_DPLL_DISP, +	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), +	.idlest_reg	= AM33XX_CM_IDLEST_DPLL_DISP, +	.mult_mask	= AM33XX_DPLL_MULT_MASK, +	.div1_mask	= AM33XX_DPLL_DIV_MASK, +	.enable_mask	= AM33XX_DPLL_EN_MASK, +	.idlest_mask	= AM33XX_ST_DPLL_CLK_MASK, +	.max_multiplier	= AM33XX_MAX_DPLL_MULT, +	.max_divider	= AM33XX_MAX_DPLL_DIV, +	.min_divider	= 1, +}; + +/* CLKOUT: fdpll/M2 */ +static struct clk dpll_disp_ck = { +	.name		= "dpll_disp_ck", +	.parent		= &sys_clkin_ck, +	.dpll_data	= &dpll_disp_dd, +	.init		= &omap2_init_dpll_parent, +	.ops		= &clkops_null, +	.recalc		= &omap3_dpll_recalc, +	.round_rate	= &omap2_dpll_round_rate, +	.set_rate	= &omap3_noncore_dpll_set_rate, +}; + +/* + * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2 + * and ALT_CLK1/2) + */ +static const struct clksel dpll_disp_m2_div[] = { +	{ .parent = &dpll_disp_ck, .rates = div31_1to31_rates }, +	{ .parent = NULL }, +}; + +static struct clk dpll_disp_m2_ck = { +	.name		= "dpll_disp_m2_ck", +	.parent		= &dpll_disp_ck, +	.clksel		= dpll_disp_m2_div, +	.clksel_reg	= AM33XX_CM_DIV_M2_DPLL_DISP, +	.clksel_mask	= AM33XX_DPLL_CLKOUT_DIV_MASK, +	.ops		= &clkops_null, +	.recalc		= &omap2_clksel_recalc, +	.round_rate	= &omap2_clksel_round_rate, +	.set_rate	= &omap2_clksel_set_rate, +}; + +/* DPLL_PER */ +static struct dpll_data dpll_per_dd = { +	.mult_div1_reg	= AM33XX_CM_CLKSEL_DPLL_PERIPH, +	.clk_bypass	= &sys_clkin_ck, +	.clk_ref	= &sys_clkin_ck, +	.control_reg	= AM33XX_CM_CLKMODE_DPLL_PER, +	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), +	.idlest_reg	= AM33XX_CM_IDLEST_DPLL_PER, +	.mult_mask	= AM33XX_DPLL_MULT_PERIPH_MASK, +	.div1_mask	= AM33XX_DPLL_PER_DIV_MASK, +	.enable_mask	= AM33XX_DPLL_EN_MASK, +	.idlest_mask	= AM33XX_ST_DPLL_CLK_MASK, +	.max_multiplier	= AM33XX_MAX_DPLL_MULT, +	.max_divider	= AM33XX_MAX_DPLL_DIV, +	.min_divider	= 1, +	.flags		= DPLL_J_TYPE, +}; + +/* CLKDCOLDO */ +static struct clk dpll_per_ck = { +	.name		= "dpll_per_ck", +	.parent		= &sys_clkin_ck, +	.dpll_data	= &dpll_per_dd, +	.init		= &omap2_init_dpll_parent, +	.ops		= &clkops_null, +	.recalc		= &omap3_dpll_recalc, +	.round_rate	= &omap2_dpll_round_rate, +	.set_rate	= &omap3_noncore_dpll_set_rate, +}; + +/* CLKOUT: fdpll/M2 */ +static const struct clksel dpll_per_m2_div[] = { +	{ .parent = &dpll_per_ck, .rates = div31_1to31_rates }, +	{ .parent = NULL }, +}; + +static struct clk dpll_per_m2_ck = { +	.name		= "dpll_per_m2_ck", +	.parent		= &dpll_per_ck, +	.clksel		= dpll_per_m2_div, +	.clksel_reg	= AM33XX_CM_DIV_M2_DPLL_PER, +	.clksel_mask	= AM33XX_DPLL_CLKOUT_DIV_MASK, +	.ops		= &clkops_null, +	.recalc		= &omap2_clksel_recalc, +	.round_rate	= &omap2_clksel_round_rate, +	.set_rate	= &omap2_clksel_set_rate, +}; + +static struct clk dpll_per_m2_div4_wkupdm_ck = { +	.name		= "dpll_per_m2_div4_wkupdm_ck", +	.clkdm_name	= "l4_wkup_clkdm", +	.parent		= &dpll_per_m2_ck, +	.fixed_div	= 4, +	.ops		= &clkops_null, +	.recalc		= &omap_fixed_divisor_recalc, +}; + +static struct clk dpll_per_m2_div4_ck = { +	.name		= "dpll_per_m2_div4_ck", +	.clkdm_name	= "l4ls_clkdm", +	.parent		= &dpll_per_m2_ck, +	.fixed_div	= 4, +	.ops		= &clkops_null, +	.recalc		= &omap_fixed_divisor_recalc, +}; + +static struct clk l3_gclk = { +	.name		= "l3_gclk", +	.clkdm_name	= "l3_clkdm", +	.parent		= &dpll_core_m4_ck, +	.ops		= &clkops_null, +	.recalc		= &followparent_recalc, +}; + +static struct clk dpll_core_m4_div2_ck = { +	.name		= "dpll_core_m4_div2_ck", +	.clkdm_name	= "l4_wkup_clkdm", +	.parent		= &dpll_core_m4_ck, +	.ops		= &clkops_null, +	.fixed_div	= 2, +	.recalc		= &omap_fixed_divisor_recalc, +}; + +static struct clk l4_rtc_gclk = { +	.name		= "l4_rtc_gclk", +	.parent		= &dpll_core_m4_ck, +	.ops		= &clkops_null, +	.fixed_div	= 2, +	.recalc		= &omap_fixed_divisor_recalc, +}; + +static struct clk clk_24mhz = { +	.name		= "clk_24mhz", +	.parent		= &dpll_per_m2_ck, +	.fixed_div	= 8, +	.ops		= &clkops_null, +	.recalc		= &omap_fixed_divisor_recalc, +}; + +/* + * Below clock nodes describes clockdomains derived out + * of core clock. + */ +static struct clk l4hs_gclk = { +	.name		= "l4hs_gclk", +	.clkdm_name	= "l4hs_clkdm", +	.parent		= &dpll_core_m4_ck, +	.ops		= &clkops_null, +	.recalc		= &followparent_recalc, +}; + +static struct clk l3s_gclk = { +	.name		= "l3s_gclk", +	.clkdm_name	= "l3s_clkdm", +	.parent		= &dpll_core_m4_div2_ck, +	.ops		= &clkops_null, +	.recalc		= &followparent_recalc, +}; + +static struct clk l4fw_gclk = { +	.name		= "l4fw_gclk", +	.clkdm_name	= "l4fw_clkdm", +	.parent		= &dpll_core_m4_div2_ck, +	.ops		= &clkops_null, +	.recalc		= &followparent_recalc, +}; + +static struct clk l4ls_gclk = { +	.name		= "l4ls_gclk", +	.clkdm_name	= "l4ls_clkdm", +	.parent		= &dpll_core_m4_div2_ck, +	.ops		= &clkops_null, +	.recalc		= &followparent_recalc, +}; + +static struct clk sysclk_div_ck = { +	.name		= "sysclk_div_ck", +	.parent		= &dpll_core_m4_ck, +	.ops		= &clkops_null, +	.recalc		= &followparent_recalc, +}; + +/* + * In order to match the clock domain with hwmod clockdomain entry, + * separate clock nodes is required for the modules which are + * directly getting their funtioncal clock from sys_clkin. + */ +static struct clk adc_tsc_fck = { +	.name		= "adc_tsc_fck", +	.clkdm_name	= "l4_wkup_clkdm", +	.parent		= &sys_clkin_ck, +	.ops		= &clkops_null, +	.recalc		= &followparent_recalc, +}; + +static struct clk dcan0_fck = { +	.name		= "dcan0_fck", +	.clkdm_name	= "l4ls_clkdm", +	.parent		= &sys_clkin_ck, +	.ops		= &clkops_null, +	.recalc		= &followparent_recalc, +}; + +static struct clk dcan1_fck = { +	.name		= "dcan1_fck", +	.clkdm_name	= "l4ls_clkdm", +	.parent		= &sys_clkin_ck, +	.ops		= &clkops_null, +	.recalc		= &followparent_recalc, +}; + +static struct clk mcasp0_fck = { +	.name		= "mcasp0_fck", +	.clkdm_name	= "l3s_clkdm", +	.parent		= &sys_clkin_ck, +	.ops		= &clkops_null, +	.recalc		= &followparent_recalc, +}; + +static struct clk mcasp1_fck = { +	.name		= "mcasp1_fck", +	.clkdm_name	= "l3s_clkdm", +	.parent		= &sys_clkin_ck, +	.ops		= &clkops_null, +	.recalc		= &followparent_recalc, +}; + +static struct clk smartreflex0_fck = { +	.name		= "smartreflex0_fck", +	.clkdm_name	= "l4_wkup_clkdm", +	.parent		= &sys_clkin_ck, +	.ops		= &clkops_null, +	.recalc		= &followparent_recalc, +}; + +static struct clk smartreflex1_fck = { +	.name		= "smartreflex1_fck", +	.clkdm_name	= "l4_wkup_clkdm", +	.parent		= &sys_clkin_ck, +	.ops		= &clkops_null, +	.recalc		= &followparent_recalc, +}; + +/* + * Modules clock nodes + * + * The following clock leaf nodes are added for the moment because: + * + *  - hwmod data is not present for these modules, either hwmod + *    control is not required or its not populated. + *  - Driver code is not yet migrated to use hwmod/runtime pm + *  - Modules outside kernel access (to disable them by default) + * + *     - debugss + *     - mmu (gfx domain) + *     - cefuse + *     - usbotg_fck (its additional clock and not really a modulemode) + *     - ieee5000 + */ +static struct clk debugss_ick = { +	.name		= "debugss_ick", +	.clkdm_name	= "l3_aon_clkdm", +	.parent		= &dpll_core_m4_ck, +	.ops		= &clkops_omap2_dflt, +	.enable_reg	= AM33XX_CM_WKUP_DEBUGSS_CLKCTRL, +	.enable_bit	= AM33XX_MODULEMODE_SWCTRL, +	.recalc		= &followparent_recalc, +}; + +static struct clk mmu_fck = { +	.name		= "mmu_fck", +	.clkdm_name	= "gfx_l3_clkdm", +	.parent		= &dpll_core_m4_ck, +	.ops		= &clkops_omap2_dflt, +	.enable_reg	= AM33XX_CM_GFX_MMUDATA_CLKCTRL, +	.enable_bit	= AM33XX_MODULEMODE_SWCTRL, +	.recalc		= &followparent_recalc, +}; + +static struct clk cefuse_fck = { +	.name		= "cefuse_fck", +	.clkdm_name	= "l4_cefuse_clkdm", +	.parent		= &sys_clkin_ck, +	.enable_reg	= AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL, +	.enable_bit	= AM33XX_MODULEMODE_SWCTRL, +	.ops		= &clkops_omap2_dflt, +	.recalc		= &followparent_recalc, +}; + +/* + * clkdiv32 is generated from fixed division of 732.4219 + */ +static struct clk clkdiv32k_ick = { +	.name		= "clkdiv32k_ick", +	.clkdm_name	= "clk_24mhz_clkdm", +	.rate		= 32768, +	.parent		= &clk_24mhz, +	.enable_reg	= AM33XX_CM_PER_CLKDIV32K_CLKCTRL, +	.enable_bit	= AM33XX_MODULEMODE_SWCTRL, +	.ops		= &clkops_omap2_dflt, +}; + +static struct clk usbotg_fck = { +	.name		= "usbotg_fck", +	.clkdm_name	= "l3s_clkdm", +	.parent		= &dpll_per_ck, +	.enable_reg	= AM33XX_CM_CLKDCOLDO_DPLL_PER, +	.enable_bit	= AM33XX_ST_DPLL_CLKDCOLDO_SHIFT, +	.ops		= &clkops_omap2_dflt, +	.recalc		= &followparent_recalc, +}; + +static struct clk ieee5000_fck = { +	.name		= "ieee5000_fck", +	.clkdm_name	= "l3s_clkdm", +	.parent		= &dpll_core_m4_div2_ck, +	.enable_reg	= AM33XX_CM_PER_IEEE5000_CLKCTRL, +	.enable_bit	= AM33XX_MODULEMODE_SWCTRL, +	.ops		= &clkops_omap2_dflt, +	.recalc		= &followparent_recalc, +}; + +/* Timers */ +static const struct clksel timer1_clkmux_sel[] = { +	{ .parent = &sys_clkin_ck, .rates = div_1_0_rates }, +	{ .parent = &clkdiv32k_ick, .rates = div_1_1_rates }, +	{ .parent = &tclkin_ck, .rates = div_1_2_rates }, +	{ .parent = &clk_rc32k_ck, .rates = div_1_3_rates }, +	{ .parent = &clk_32768_ck, .rates = div_1_4_rates }, +	{ .parent = NULL }, +}; + +static struct clk timer1_fck = { +	.name		= "timer1_fck", +	.clkdm_name	= "l4ls_clkdm", +	.parent		= &sys_clkin_ck, +	.init		= &omap2_init_clksel_parent, +	.clksel		= timer1_clkmux_sel, +	.clksel_reg	= AM33XX_CLKSEL_TIMER1MS_CLK, +	.clksel_mask	= AM33XX_CLKSEL_0_2_MASK, +	.ops		= &clkops_null, +	.recalc		= &omap2_clksel_recalc, +}; + +static const struct clksel timer2_to_7_clk_sel[] = { +	{ .parent = &tclkin_ck, .rates = div_1_0_rates }, +	{ .parent = &sys_clkin_ck, .rates = div_1_1_rates }, +	{ .parent = &clkdiv32k_ick, .rates = div_1_2_rates }, +	{ .parent = NULL }, +}; + +static struct clk timer2_fck = { +	.name		= "timer2_fck", +	.clkdm_name	= "l4ls_clkdm", +	.parent		= &sys_clkin_ck, +	.init		= &omap2_init_clksel_parent, +	.clksel		= timer2_to_7_clk_sel, +	.clksel_reg	= AM33XX_CLKSEL_TIMER2_CLK, +	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK, +	.ops		= &clkops_null, +	.recalc		= &omap2_clksel_recalc, +}; + +static struct clk timer3_fck = { +	.name		= "timer3_fck", +	.clkdm_name	= "l4ls_clkdm", +	.parent		= &sys_clkin_ck, +	.init		= &am33xx_init_timer_parent, +	.clksel		= timer2_to_7_clk_sel, +	.clksel_reg	= AM33XX_CLKSEL_TIMER3_CLK, +	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK, +	.ops		= &clkops_null, +	.recalc		= &omap2_clksel_recalc, +}; + +static struct clk timer4_fck = { +	.name		= "timer4_fck", +	.clkdm_name	= "l4ls_clkdm", +	.parent		= &sys_clkin_ck, +	.init		= &omap2_init_clksel_parent, +	.clksel		= timer2_to_7_clk_sel, +	.clksel_reg	= AM33XX_CLKSEL_TIMER4_CLK, +	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK, +	.ops		= &clkops_null, +	.recalc		= &omap2_clksel_recalc, +}; + +static struct clk timer5_fck = { +	.name		= "timer5_fck", +	.clkdm_name	= "l4ls_clkdm", +	.parent		= &sys_clkin_ck, +	.init		= &omap2_init_clksel_parent, +	.clksel		= timer2_to_7_clk_sel, +	.clksel_reg	= AM33XX_CLKSEL_TIMER5_CLK, +	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK, +	.ops		= &clkops_null, +	.recalc		= &omap2_clksel_recalc, +}; + +static struct clk timer6_fck = { +	.name		= "timer6_fck", +	.clkdm_name	= "l4ls_clkdm", +	.parent		= &sys_clkin_ck, +	.init		= &am33xx_init_timer_parent, +	.clksel		= timer2_to_7_clk_sel, +	.clksel_reg	= AM33XX_CLKSEL_TIMER6_CLK, +	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK, +	.ops		= &clkops_null, +	.recalc		= &omap2_clksel_recalc, +}; + +static struct clk timer7_fck = { +	.name		= "timer7_fck", +	.clkdm_name	= "l4ls_clkdm", +	.parent		= &sys_clkin_ck, +	.init		= &omap2_init_clksel_parent, +	.clksel		= timer2_to_7_clk_sel, +	.clksel_reg	= AM33XX_CLKSEL_TIMER7_CLK, +	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK, +	.ops		= &clkops_null, +	.recalc		= &omap2_clksel_recalc, +}; + +static struct clk cpsw_125mhz_gclk = { +	.name		= "cpsw_125mhz_gclk", +	.clkdm_name	= "cpsw_125mhz_clkdm", +	.parent		= &dpll_core_m5_ck, +	.ops		= &clkops_null, +	.fixed_div	= 2, +	.recalc		= &omap_fixed_divisor_recalc, +}; + +static const struct clksel cpsw_cpts_rft_clkmux_sel[] = { +	{ .parent = &dpll_core_m5_ck, .rates = div_1_0_rates }, +	{ .parent = &dpll_core_m4_ck, .rates = div_1_1_rates }, +	{ .parent = NULL }, +}; + +static struct clk cpsw_cpts_rft_clk = { +	.name		= "cpsw_cpts_rft_clk", +	.clkdm_name	= "cpsw_125mhz_clkdm", +	.parent		= &dpll_core_m5_ck, +	.clksel		= cpsw_cpts_rft_clkmux_sel, +	.clksel_reg	= AM33XX_CM_CPTS_RFT_CLKSEL, +	.clksel_mask	= AM33XX_CLKSEL_0_0_MASK, +	.ops		= &clkops_null, +	.recalc		= &followparent_recalc, +}; + +/* gpio */ +static const struct clksel gpio0_dbclk_mux_sel[] = { +	{ .parent = &clk_rc32k_ck, .rates = div_1_0_rates }, +	{ .parent = &clk_32768_ck, .rates = div_1_1_rates }, +	{ .parent = &clkdiv32k_ick, .rates = div_1_2_rates }, +	{ .parent = NULL }, +}; + +static struct clk gpio0_dbclk_mux_ck = { +	.name		= "gpio0_dbclk_mux_ck", +	.clkdm_name	= "l4_wkup_clkdm", +	.parent		= &clk_rc32k_ck, +	.init		= &omap2_init_clksel_parent, +	.clksel		= gpio0_dbclk_mux_sel, +	.clksel_reg	= AM33XX_CLKSEL_GPIO0_DBCLK, +	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK, +	.ops		= &clkops_null, +	.recalc		= &omap2_clksel_recalc, +}; + +static struct clk gpio0_dbclk = { +	.name		= "gpio0_dbclk", +	.clkdm_name	= "l4_wkup_clkdm", +	.parent		= &gpio0_dbclk_mux_ck, +	.enable_reg	= AM33XX_CM_WKUP_GPIO0_CLKCTRL, +	.enable_bit	= AM33XX_OPTFCLKEN_GPIO0_GDBCLK_SHIFT, +	.ops		= &clkops_omap2_dflt, +	.recalc		= &followparent_recalc, +}; + +static struct clk gpio1_dbclk = { +	.name		= "gpio1_dbclk", +	.clkdm_name	= "l4ls_clkdm", +	.parent		= &clkdiv32k_ick, +	.enable_reg	= AM33XX_CM_PER_GPIO1_CLKCTRL, +	.enable_bit	= AM33XX_OPTFCLKEN_GPIO_1_GDBCLK_SHIFT, +	.ops		= &clkops_omap2_dflt, +	.recalc		= &followparent_recalc, +}; + +static struct clk gpio2_dbclk = { +	.name		= "gpio2_dbclk", +	.clkdm_name	= "l4ls_clkdm", +	.parent		= &clkdiv32k_ick, +	.enable_reg	= AM33XX_CM_PER_GPIO2_CLKCTRL, +	.enable_bit	= AM33XX_OPTFCLKEN_GPIO_2_GDBCLK_SHIFT, +	.ops		= &clkops_omap2_dflt, +	.recalc		= &followparent_recalc, +}; + +static struct clk gpio3_dbclk = { +	.name		= "gpio3_dbclk", +	.clkdm_name	= "l4ls_clkdm", +	.parent		= &clkdiv32k_ick, +	.enable_reg	= AM33XX_CM_PER_GPIO3_CLKCTRL, +	.enable_bit	= AM33XX_OPTFCLKEN_GPIO_3_GDBCLK_SHIFT, +	.ops		= &clkops_omap2_dflt, +	.recalc		= &followparent_recalc, +}; + +static const struct clksel pruss_ocp_clk_mux_sel[] = { +	{ .parent = &l3_gclk, .rates = div_1_0_rates }, +	{ .parent = &dpll_disp_m2_ck, .rates = div_1_1_rates }, +	{ .parent = NULL }, +}; + +static struct clk pruss_ocp_gclk = { +	.name		= "pruss_ocp_gclk", +	.clkdm_name	= "pruss_ocp_clkdm", +	.parent		= &l3_gclk, +	.init		= &omap2_init_clksel_parent, +	.clksel		= pruss_ocp_clk_mux_sel, +	.clksel_reg	= AM33XX_CLKSEL_PRUSS_OCP_CLK, +	.clksel_mask	= AM33XX_CLKSEL_0_0_MASK, +	.ops		= &clkops_null, +	.recalc		= &followparent_recalc, +}; + +static const struct clksel lcd_clk_mux_sel[] = { +	{ .parent = &dpll_disp_m2_ck, .rates = div_1_0_rates }, +	{ .parent = &dpll_core_m5_ck, .rates = div_1_1_rates }, +	{ .parent = &dpll_per_m2_ck, .rates = div_1_2_rates }, +	{ .parent = NULL }, +}; + +static struct clk lcd_gclk = { +	.name		= "lcd_gclk", +	.clkdm_name	= "lcdc_clkdm", +	.parent		= &dpll_disp_m2_ck, +	.init		= &omap2_init_clksel_parent, +	.clksel		= lcd_clk_mux_sel, +	.clksel_reg	= AM33XX_CLKSEL_LCDC_PIXEL_CLK, +	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK, +	.ops		= &clkops_null, +	.recalc		= &followparent_recalc, +}; + +static struct clk mmc_clk = { +	.name		= "mmc_clk", +	.clkdm_name	= "l4ls_clkdm", +	.parent		= &dpll_per_m2_ck, +	.ops		= &clkops_null, +	.fixed_div	= 2, +	.recalc		= &omap_fixed_divisor_recalc, +}; + +static struct clk mmc2_fck = { +	.name		= "mmc2_fck", +	.clkdm_name	= "l3s_clkdm", +	.parent		= &mmc_clk, +	.ops		= &clkops_null, +	.recalc		= &followparent_recalc, +}; + +static const struct clksel gfx_clksel_sel[] = { +	{ .parent = &dpll_core_m4_ck, .rates = div_1_0_rates }, +	{ .parent = &dpll_per_m2_ck, .rates = div_1_1_rates }, +	{ .parent = NULL }, +}; + +static struct clk gfx_fclk_clksel_ck = { +	.name		= "gfx_fclk_clksel_ck", +	.parent		= &dpll_core_m4_ck, +	.clksel		= gfx_clksel_sel, +	.ops		= &clkops_null, +	.clksel_reg	= AM33XX_CLKSEL_GFX_FCLK, +	.clksel_mask	= AM33XX_CLKSEL_GFX_FCLK_MASK, +	.recalc		= &omap2_clksel_recalc, +}; + +static const struct clksel_rate div_1_0_2_1_rates[] = { +	{ .div = 1, .val = 0, .flags = RATE_IN_AM33XX }, +	{ .div = 2, .val = 1, .flags = RATE_IN_AM33XX }, +	{ .div = 0 }, +}; + +static const struct clksel gfx_div_sel[] = { +	{ .parent = &gfx_fclk_clksel_ck, .rates = div_1_0_2_1_rates }, +	{ .parent = NULL }, +}; + +static struct clk gfx_fck_div_ck = { +	.name		= "gfx_fck_div_ck", +	.clkdm_name	= "gfx_l3_clkdm", +	.parent		= &gfx_fclk_clksel_ck, +	.init		= &omap2_init_clksel_parent, +	.clksel		= gfx_div_sel, +	.clksel_reg	= AM33XX_CLKSEL_GFX_FCLK, +	.clksel_mask	= AM33XX_CLKSEL_0_0_MASK, +	.recalc		= &omap2_clksel_recalc, +	.round_rate	= &omap2_clksel_round_rate, +	.set_rate	= &omap2_clksel_set_rate, +	.ops		= &clkops_null, +}; + +static const struct clksel sysclkout_pre_sel[] = { +	{ .parent = &clk_32768_ck, .rates = div_1_0_rates }, +	{ .parent = &l3_gclk, .rates = div_1_1_rates }, +	{ .parent = &dpll_ddr_m2_ck, .rates = div_1_2_rates }, +	{ .parent = &dpll_per_m2_ck, .rates = div_1_3_rates }, +	{ .parent = &lcd_gclk, .rates = div_1_4_rates }, +	{ .parent = NULL }, +}; + +static struct clk sysclkout_pre_ck = { +	.name		= "sysclkout_pre_ck", +	.parent		= &clk_32768_ck, +	.init		= &omap2_init_clksel_parent, +	.clksel		= sysclkout_pre_sel, +	.clksel_reg	= AM33XX_CM_CLKOUT_CTRL, +	.clksel_mask	= AM33XX_CLKOUT2SOURCE_MASK, +	.ops		= &clkops_null, +	.recalc		= &omap2_clksel_recalc, +}; + +/* Divide by 8 clock rates with default clock is 1/1*/ +static const struct clksel_rate div8_rates[] = { +	{ .div = 1, .val = 0, .flags = RATE_IN_AM33XX }, +	{ .div = 2, .val = 1, .flags = RATE_IN_AM33XX }, +	{ .div = 3, .val = 2, .flags = RATE_IN_AM33XX }, +	{ .div = 4, .val = 3, .flags = RATE_IN_AM33XX }, +	{ .div = 5, .val = 4, .flags = RATE_IN_AM33XX }, +	{ .div = 6, .val = 5, .flags = RATE_IN_AM33XX }, +	{ .div = 7, .val = 6, .flags = RATE_IN_AM33XX }, +	{ .div = 8, .val = 7, .flags = RATE_IN_AM33XX }, +	{ .div = 0 }, +}; + +static const struct clksel clkout2_div[] = { +	{ .parent = &sysclkout_pre_ck, .rates = div8_rates }, +	{ .parent = NULL }, +}; + +static struct clk clkout2_ck = { +	.name		= "clkout2_ck", +	.parent		= &sysclkout_pre_ck, +	.ops		= &clkops_omap2_dflt, +	.clksel		= clkout2_div, +	.clksel_reg	= AM33XX_CM_CLKOUT_CTRL, +	.clksel_mask	= AM33XX_CLKOUT2DIV_MASK, +	.enable_reg	= AM33XX_CM_CLKOUT_CTRL, +	.enable_bit	= AM33XX_CLKOUT2EN_SHIFT, +	.recalc		= &omap2_clksel_recalc, +	.round_rate	= &omap2_clksel_round_rate, +	.set_rate	= &omap2_clksel_set_rate, +}; + +static const struct clksel wdt_clkmux_sel[] = { +	{ .parent = &clk_rc32k_ck, .rates = div_1_0_rates }, +	{ .parent = &clkdiv32k_ick, .rates = div_1_1_rates }, +	{ .parent = NULL }, +}; + +static struct clk wdt1_fck = { +	.name		= "wdt1_fck", +	.clkdm_name	= "l4_wkup_clkdm", +	.parent		= &clk_rc32k_ck, +	.init		= &omap2_init_clksel_parent, +	.clksel		= wdt_clkmux_sel, +	.clksel_reg	= AM33XX_CLKSEL_WDT1_CLK, +	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK, +	.ops		= &clkops_null, +	.recalc		= &omap2_clksel_recalc, +}; + +/* + * clkdev + */ +static struct omap_clk am33xx_clks[] = { +	CLK(NULL,	"clk_32768_ck",		&clk_32768_ck,	CK_AM33XX), +	CLK(NULL,	"clk_rc32k_ck",		&clk_rc32k_ck,	CK_AM33XX), +	CLK(NULL,	"virt_19200000_ck",	&virt_19200000_ck,	CK_AM33XX), +	CLK(NULL,	"virt_24000000_ck",	&virt_24000000_ck,	CK_AM33XX), +	CLK(NULL,	"virt_25000000_ck",	&virt_25000000_ck,	CK_AM33XX), +	CLK(NULL,	"virt_26000000_ck",	&virt_26000000_ck,	CK_AM33XX), +	CLK(NULL,	"sys_clkin_ck",		&sys_clkin_ck,	CK_AM33XX), +	CLK(NULL,	"tclkin_ck",		&tclkin_ck,	CK_AM33XX), +	CLK(NULL,	"dpll_core_ck",		&dpll_core_ck,	CK_AM33XX), +	CLK(NULL,	"dpll_core_x2_ck",	&dpll_core_x2_ck,	CK_AM33XX), +	CLK(NULL,	"dpll_core_m4_ck",	&dpll_core_m4_ck,	CK_AM33XX), +	CLK(NULL,	"dpll_core_m5_ck",	&dpll_core_m5_ck,	CK_AM33XX), +	CLK(NULL,	"dpll_core_m6_ck",	&dpll_core_m6_ck,	CK_AM33XX), +	CLK(NULL,	"dpll_mpu_ck",		&dpll_mpu_ck,	CK_AM33XX), +	CLK(NULL,	"dpll_mpu_m2_ck",	&dpll_mpu_m2_ck,	CK_AM33XX), +	CLK(NULL,	"dpll_ddr_ck",		&dpll_ddr_ck,	CK_AM33XX), +	CLK(NULL,	"dpll_ddr_m2_ck",	&dpll_ddr_m2_ck,	CK_AM33XX), +	CLK(NULL,	"dpll_ddr_m2_div2_ck",	&dpll_ddr_m2_div2_ck,	CK_AM33XX), +	CLK(NULL,	"dpll_disp_ck",		&dpll_disp_ck,	CK_AM33XX), +	CLK(NULL,	"dpll_disp_m2_ck",	&dpll_disp_m2_ck,	CK_AM33XX), +	CLK(NULL,	"dpll_per_ck",		&dpll_per_ck,	CK_AM33XX), +	CLK(NULL,	"dpll_per_m2_ck",	&dpll_per_m2_ck,	CK_AM33XX), +	CLK(NULL,	"dpll_per_m2_div4_wkupdm_ck",	&dpll_per_m2_div4_wkupdm_ck,	CK_AM33XX), +	CLK(NULL,	"dpll_per_m2_div4_ck",	&dpll_per_m2_div4_ck,	CK_AM33XX), +	CLK(NULL,	"adc_tsc_fck",		&adc_tsc_fck,	CK_AM33XX), +	CLK(NULL,	"cefuse_fck",		&cefuse_fck,	CK_AM33XX), +	CLK(NULL,	"clkdiv32k_ick",	&clkdiv32k_ick,	CK_AM33XX), +	CLK(NULL,	"dcan0_fck",		&dcan0_fck,	CK_AM33XX), +	CLK(NULL,	"dcan1_fck",		&dcan1_fck,	CK_AM33XX), +	CLK(NULL,	"debugss_ick",		&debugss_ick,	CK_AM33XX), +	CLK(NULL,	"pruss_ocp_gclk",	&pruss_ocp_gclk,	CK_AM33XX), +	CLK("davinci-mcasp.0",  NULL,           &mcasp0_fck,    CK_AM33XX), +	CLK("davinci-mcasp.1",  NULL,           &mcasp1_fck,    CK_AM33XX), +	CLK("NULL",	"mmc2_fck",		&mmc2_fck,	CK_AM33XX), +	CLK(NULL,	"mmu_fck",		&mmu_fck,	CK_AM33XX), +	CLK(NULL,	"smartreflex0_fck",	&smartreflex0_fck,	CK_AM33XX), +	CLK(NULL,	"smartreflex1_fck",	&smartreflex1_fck,	CK_AM33XX), +	CLK(NULL,	"gpt1_fck",		&timer1_fck,	CK_AM33XX), +	CLK(NULL,	"gpt2_fck",		&timer2_fck,	CK_AM33XX), +	CLK(NULL,	"gpt3_fck",		&timer3_fck,	CK_AM33XX), +	CLK(NULL,	"gpt4_fck",		&timer4_fck,	CK_AM33XX), +	CLK(NULL,	"gpt5_fck",		&timer5_fck,	CK_AM33XX), +	CLK(NULL,	"gpt6_fck",		&timer6_fck,	CK_AM33XX), +	CLK(NULL,	"gpt7_fck",		&timer7_fck,	CK_AM33XX), +	CLK(NULL,	"usbotg_fck",		&usbotg_fck,	CK_AM33XX), +	CLK(NULL,	"ieee5000_fck",		&ieee5000_fck,	CK_AM33XX), +	CLK(NULL,	"wdt1_fck",		&wdt1_fck,	CK_AM33XX), +	CLK(NULL,	"l4_rtc_gclk",		&l4_rtc_gclk,	CK_AM33XX), +	CLK(NULL,	"l3_gclk",		&l3_gclk,	CK_AM33XX), +	CLK(NULL,	"dpll_core_m4_div2_ck",	&dpll_core_m4_div2_ck,	CK_AM33XX), +	CLK(NULL,	"l4hs_gclk",		&l4hs_gclk,	CK_AM33XX), +	CLK(NULL,	"l3s_gclk",		&l3s_gclk,	CK_AM33XX), +	CLK(NULL,	"l4fw_gclk",		&l4fw_gclk,	CK_AM33XX), +	CLK(NULL,	"l4ls_gclk",		&l4ls_gclk,	CK_AM33XX), +	CLK(NULL,	"clk_24mhz",		&clk_24mhz,	CK_AM33XX), +	CLK(NULL,	"sysclk_div_ck",	&sysclk_div_ck,	CK_AM33XX), +	CLK(NULL,	"cpsw_125mhz_gclk",	&cpsw_125mhz_gclk,	CK_AM33XX), +	CLK(NULL,	"cpsw_cpts_rft_clk",	&cpsw_cpts_rft_clk,	CK_AM33XX), +	CLK(NULL,	"gpio0_dbclk_mux_ck",	&gpio0_dbclk_mux_ck,	CK_AM33XX), +	CLK(NULL,	"gpio0_dbclk",		&gpio0_dbclk,	CK_AM33XX), +	CLK(NULL,	"gpio1_dbclk",		&gpio1_dbclk,	CK_AM33XX), +	CLK(NULL,	"gpio2_dbclk",		&gpio2_dbclk,	CK_AM33XX), +	CLK(NULL,	"gpio3_dbclk",		&gpio3_dbclk,	CK_AM33XX), +	CLK(NULL,	"lcd_gclk",		&lcd_gclk,	CK_AM33XX), +	CLK(NULL,	"mmc_clk",		&mmc_clk,	CK_AM33XX), +	CLK(NULL,	"gfx_fclk_clksel_ck",	&gfx_fclk_clksel_ck,	CK_AM33XX), +	CLK(NULL,	"gfx_fck_div_ck",	&gfx_fck_div_ck,	CK_AM33XX), +	CLK(NULL,	"sysclkout_pre_ck",	&sysclkout_pre_ck,	CK_AM33XX), +	CLK(NULL,	"clkout2_ck",		&clkout2_ck,	CK_AM33XX), +}; + +int __init am33xx_clk_init(void) +{ +	struct omap_clk *c; +	u32 cpu_clkflg; + +	if (soc_is_am33xx()) { +		cpu_mask = RATE_IN_AM33XX; +		cpu_clkflg = CK_AM33XX; +	} + +	clk_init(&omap2_clk_functions); + +	for (c = am33xx_clks; c < am33xx_clks + ARRAY_SIZE(am33xx_clks); c++) +		clk_preinit(c->lk.clk); + +	for (c = am33xx_clks; c < am33xx_clks + ARRAY_SIZE(am33xx_clks); c++) { +		if (c->cpu & cpu_clkflg) { +			clkdev_add(&c->lk); +			clk_register(c->lk.clk); +			omap2_init_clk_clkdm(c->lk.clk); +		} +	} + +	recalculate_root_clocks(); + +	/* +	 * Only enable those clocks we will need, let the drivers +	 * enable other clocks as necessary +	 */ +	clk_enable_init_clocks(); + +	return 0; +} diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 1efdec236ae..83bed9ad301 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -93,18 +93,6 @@ static struct clk virt_16_8m_ck = {  	.rate		= 16800000,  }; -static struct clk virt_19_2m_ck = { -	.name		= "virt_19_2m_ck", -	.ops		= &clkops_null, -	.rate		= 19200000, -}; - -static struct clk virt_26m_ck = { -	.name		= "virt_26m_ck", -	.ops		= &clkops_null, -	.rate		= 26000000, -}; -  static struct clk virt_38_4m_ck = {  	.name		= "virt_38_4m_ck",  	.ops		= &clkops_null, @@ -145,8 +133,8 @@ 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_19200000_ck, .rates = osc_sys_19_2m_rates }, +	{ .parent = &virt_26000000_ck,   .rates = osc_sys_26m_rates },  	{ .parent = &virt_38_4m_ck, .rates = osc_sys_38_4m_rates },  	{ .parent = NULL },  }; @@ -2490,13 +2478,13 @@ static struct clk uart4_fck = {  };  static struct clk uart4_fck_am35xx = { -	.name           = "uart4_fck", -	.ops            = &clkops_omap2_dflt_wait, -	.parent         = &per_48m_fck, -	.enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), -	.enable_bit     = OMAP3430_EN_UART4_SHIFT, -	.clkdm_name     = "core_l4_clkdm", -	.recalc         = &followparent_recalc, +	.name		= "uart4_fck", +	.ops		= &clkops_omap2_dflt_wait, +	.parent		= &core_48m_fck, +	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), +	.enable_bit	= AM35XX_EN_UART4_SHIFT, +	.clkdm_name	= "core_l4_clkdm", +	.recalc		= &followparent_recalc,  };  static struct clk gpt2_fck = { @@ -3201,8 +3189,12 @@ static struct clk vpfe_fck = {  };  /* - * The UART1/2 functional clock acts as the functional - * clock for UART4. No separate fclk control available. + * The UART1/2 functional clock acts as the functional clock for + * UART4. No separate fclk control available.  XXX Well now we have a + * uart4_fck that is apparently used as the UART4 functional clock, + * but it also seems that uart1_fck or uart2_fck are still needed, at + * least for UART4 softresets to complete.  This really needs + * clarification.   */  static struct clk uart4_ick_am35xx = {  	.name		= "uart4_ick", @@ -3230,17 +3222,12 @@ static struct omap_clk omap3xxx_clks[] = {  	CLK(NULL,	"virt_12m_ck",	&virt_12m_ck,	CK_3XXX),  	CLK(NULL,	"virt_13m_ck",	&virt_13m_ck,	CK_3XXX),  	CLK(NULL,	"virt_16_8m_ck", &virt_16_8m_ck, CK_3430ES2PLUS | CK_AM35XX  | CK_36XX), -	CLK(NULL,	"virt_19_2m_ck", &virt_19_2m_ck, CK_3XXX), -	CLK(NULL,	"virt_26m_ck",	&virt_26m_ck,	CK_3XXX), +	CLK(NULL,	"virt_19200000_ck", &virt_19200000_ck, CK_3XXX), +	CLK(NULL,	"virt_26000000_ck",	&virt_26000000_ck,	CK_3XXX),  	CLK(NULL,	"virt_38_4m_ck", &virt_38_4m_ck, CK_3XXX),  	CLK(NULL,	"osc_sys_ck",	&osc_sys_ck,	CK_3XXX),  	CLK(NULL,	"sys_ck",	&sys_ck,	CK_3XXX),  	CLK(NULL,	"sys_altclk",	&sys_altclk,	CK_3XXX), -	CLK("omap-mcbsp.1",	"pad_fck",	&mcbsp_clks,	CK_3XXX), -	CLK("omap-mcbsp.2",	"pad_fck",	&mcbsp_clks,	CK_3XXX), -	CLK("omap-mcbsp.3",	"pad_fck",	&mcbsp_clks,	CK_3XXX), -	CLK("omap-mcbsp.4",	"pad_fck",	&mcbsp_clks,	CK_3XXX), -	CLK("omap-mcbsp.5",	"pad_fck",	&mcbsp_clks,	CK_3XXX),  	CLK(NULL,	"mcbsp_clks",	&mcbsp_clks,	CK_3XXX),  	CLK(NULL,	"sys_clkout1",	&sys_clkout1,	CK_3XXX),  	CLK(NULL,	"dpll1_ck",	&dpll1_ck,	CK_3XXX), @@ -3307,8 +3294,6 @@ static struct omap_clk omap3xxx_clks[] = {  	CLK(NULL,	"ts_fck",	&ts_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),  	CLK(NULL,	"usbtll_fck",	&usbtll_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),  	CLK("usbhs_omap",	"usbtll_fck",	&usbtll_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -	CLK("omap-mcbsp.1",	"prcm_fck",	&core_96m_fck,	CK_3XXX), -	CLK("omap-mcbsp.5",	"prcm_fck",	&core_96m_fck,	CK_3XXX),  	CLK(NULL,	"core_96m_fck",	&core_96m_fck,	CK_3XXX),  	CLK(NULL,	"mmchs3_fck",	&mmchs3_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),  	CLK(NULL,	"mmchs2_fck",	&mmchs2_fck,	CK_3XXX), @@ -3391,15 +3376,15 @@ static struct omap_clk omap3xxx_clks[] = {  	CLK(NULL,	"usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),  	CLK(NULL,	"usbhost_ick",	&usbhost_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),  	CLK("usbhs_omap",	"usbhost_ick",	&usbhost_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -	CLK("usbhs_omap",	"utmi_p1_gfclk",	&dummy_ck,	CK_3XXX), -	CLK("usbhs_omap",	"utmi_p2_gfclk",	&dummy_ck,	CK_3XXX), -	CLK("usbhs_omap",	"xclk60mhsp1_ck",	&dummy_ck,	CK_3XXX), -	CLK("usbhs_omap",	"xclk60mhsp2_ck",	&dummy_ck,	CK_3XXX), -	CLK("usbhs_omap",	"usb_host_hs_utmi_p1_clk",	&dummy_ck,	CK_3XXX), -	CLK("usbhs_omap",	"usb_host_hs_utmi_p2_clk",	&dummy_ck,	CK_3XXX), +	CLK(NULL,	"utmi_p1_gfclk",	&dummy_ck,	CK_3XXX), +	CLK(NULL,	"utmi_p2_gfclk",	&dummy_ck,	CK_3XXX), +	CLK(NULL,	"xclk60mhsp1_ck",	&dummy_ck,	CK_3XXX), +	CLK(NULL,	"xclk60mhsp2_ck",	&dummy_ck,	CK_3XXX), +	CLK(NULL,	"usb_host_hs_utmi_p1_clk",	&dummy_ck,	CK_3XXX), +	CLK(NULL,	"usb_host_hs_utmi_p2_clk",	&dummy_ck,	CK_3XXX),  	CLK("usbhs_omap",	"usb_tll_hs_usb_ch0_clk",	&dummy_ck,	CK_3XXX),  	CLK("usbhs_omap",	"usb_tll_hs_usb_ch1_clk",	&dummy_ck,	CK_3XXX), -	CLK("usbhs_omap",	"init_60m_fclk",	&dummy_ck,	CK_3XXX), +	CLK(NULL,	"init_60m_fclk",	&dummy_ck,	CK_3XXX),  	CLK(NULL,	"usim_fck",	&usim_fck,	CK_3430ES2PLUS | CK_36XX),  	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_3XXX),  	CLK(NULL,	"wkup_32k_fck",	&wkup_32k_fck,	CK_3XXX), @@ -3413,9 +3398,6 @@ static struct omap_clk omap3xxx_clks[] = {  	CLK(NULL,	"omap_32ksync_ick", &omap_32ksync_ick, CK_3XXX),  	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_3XXX),  	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_3XXX), -	CLK("omap-mcbsp.2",	"prcm_fck",	&per_96m_fck,	CK_3XXX), -	CLK("omap-mcbsp.3",	"prcm_fck",	&per_96m_fck,	CK_3XXX), -	CLK("omap-mcbsp.4",	"prcm_fck",	&per_96m_fck,	CK_3XXX),  	CLK(NULL,	"per_96m_fck",	&per_96m_fck,	CK_3XXX),  	CLK(NULL,	"per_48m_fck",	&per_48m_fck,	CK_3XXX),  	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_3XXX), @@ -3474,38 +3456,16 @@ static struct omap_clk omap3xxx_clks[] = {  	CLK(NULL,	"ipss_ick",	&ipss_ick,	CK_AM35XX),  	CLK(NULL,	"rmii_ck",	&rmii_ck,	CK_AM35XX),  	CLK(NULL,	"pclk_ck",	&pclk_ck,	CK_AM35XX), -	CLK("davinci_emac",	NULL,	&emac_ick,	CK_AM35XX), +	CLK("davinci_emac.0",	NULL,	&emac_ick,	CK_AM35XX),  	CLK("davinci_mdio.0",	NULL,	&emac_fck,	CK_AM35XX),  	CLK("vpfe-capture",	"master",	&vpfe_ick,	CK_AM35XX),  	CLK("vpfe-capture",	"slave",	&vpfe_fck,	CK_AM35XX), -	CLK("musb-am35x",	"ick",		&hsotgusb_ick_am35xx,	CK_AM35XX), -	CLK("musb-am35x",	"fck",		&hsotgusb_fck_am35xx,	CK_AM35XX), +	CLK(NULL,	"hsotgusb_ick",		&hsotgusb_ick_am35xx,	CK_AM35XX), +	CLK(NULL,	"hsotgusb_fck",		&hsotgusb_fck_am35xx,	CK_AM35XX),  	CLK(NULL,	"hecc_ck",	&hecc_ck,	CK_AM35XX),  	CLK(NULL,	"uart4_ick",	&uart4_ick_am35xx,	CK_AM35XX), -	CLK("omap_timer.1",	"32k_ck",	&omap_32k_fck,  CK_3XXX), -	CLK("omap_timer.2",	"32k_ck",	&omap_32k_fck,  CK_3XXX), -	CLK("omap_timer.3",	"32k_ck",	&omap_32k_fck,  CK_3XXX), -	CLK("omap_timer.4",	"32k_ck",	&omap_32k_fck,  CK_3XXX), -	CLK("omap_timer.5",	"32k_ck",	&omap_32k_fck,  CK_3XXX), -	CLK("omap_timer.6",	"32k_ck",	&omap_32k_fck,  CK_3XXX), -	CLK("omap_timer.7",	"32k_ck",	&omap_32k_fck,  CK_3XXX), -	CLK("omap_timer.8",	"32k_ck",	&omap_32k_fck,  CK_3XXX), -	CLK("omap_timer.9",	"32k_ck",	&omap_32k_fck,  CK_3XXX), -	CLK("omap_timer.10",	"32k_ck",	&omap_32k_fck,  CK_3XXX), -	CLK("omap_timer.11",	"32k_ck",	&omap_32k_fck,  CK_3XXX), -	CLK("omap_timer.12",	"32k_ck",	&omap_32k_fck,  CK_3XXX), -	CLK("omap_timer.1",	"sys_ck",	&sys_ck,	CK_3XXX), -	CLK("omap_timer.2",	"sys_ck",	&sys_ck,	CK_3XXX), -	CLK("omap_timer.3",	"sys_ck",	&sys_ck,	CK_3XXX), -	CLK("omap_timer.4",	"sys_ck",	&sys_ck,	CK_3XXX), -	CLK("omap_timer.5",	"sys_ck",	&sys_ck,	CK_3XXX), -	CLK("omap_timer.6",	"sys_ck",	&sys_ck,	CK_3XXX), -	CLK("omap_timer.7",	"sys_ck",	&sys_ck,	CK_3XXX), -	CLK("omap_timer.8",	"sys_ck",	&sys_ck,	CK_3XXX), -	CLK("omap_timer.9",	"sys_ck",	&sys_ck,	CK_3XXX), -	CLK("omap_timer.10",	"sys_ck",	&sys_ck,	CK_3XXX), -	CLK("omap_timer.11",	"sys_ck",	&sys_ck,	CK_3XXX), -	CLK("omap_timer.12",	"sys_ck",	&sys_ck,	CK_3XXX), +	CLK(NULL,	"timer_32k_ck",	&omap_32k_fck,  CK_3XXX), +	CLK(NULL,	"timer_sys_ck",	&sys_ck,	CK_3XXX),  }; @@ -3523,7 +3483,7 @@ int __init omap3xxx_clk_init(void)  	} else if (cpu_is_ti816x()) {  		cpu_mask = RATE_IN_TI816X;  		cpu_clkflg = CK_TI816X; -	} else if (cpu_is_am33xx()) { +	} else if (soc_is_am33xx()) {  		cpu_mask = RATE_IN_AM33XX;  	} else if (cpu_is_ti814x()) {  		cpu_mask = RATE_IN_TI814X; diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index ba6f9a0a43e..d7f55e43b76 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -107,18 +107,6 @@ static struct clk virt_16800000_ck = {  	.rate		= 16800000,  }; -static struct clk virt_19200000_ck = { -	.name		= "virt_19200000_ck", -	.ops		= &clkops_null, -	.rate		= 19200000, -}; - -static struct clk virt_26000000_ck = { -	.name		= "virt_26000000_ck", -	.ops		= &clkops_null, -	.rate		= 26000000, -}; -  static struct clk virt_27000000_ck = {  	.name		= "virt_27000000_ck",  	.ops		= &clkops_null, @@ -131,31 +119,6 @@ static struct clk virt_38400000_ck = {  	.rate		= 38400000,  }; -static const struct clksel_rate div_1_0_rates[] = { -	{ .div = 1, .val = 0, .flags = RATE_IN_4430 }, -	{ .div = 0 }, -}; - -static const struct clksel_rate div_1_1_rates[] = { -	{ .div = 1, .val = 1, .flags = RATE_IN_4430 }, -	{ .div = 0 }, -}; - -static const struct clksel_rate div_1_2_rates[] = { -	{ .div = 1, .val = 2, .flags = RATE_IN_4430 }, -	{ .div = 0 }, -}; - -static const struct clksel_rate div_1_3_rates[] = { -	{ .div = 1, .val = 3, .flags = RATE_IN_4430 }, -	{ .div = 0 }, -}; - -static const struct clksel_rate div_1_4_rates[] = { -	{ .div = 1, .val = 4, .flags = RATE_IN_4430 }, -	{ .div = 0 }, -}; -  static const struct clksel_rate div_1_5_rates[] = {  	{ .div = 1, .val = 5, .flags = RATE_IN_4430 },  	{ .div = 0 }, @@ -289,41 +252,6 @@ static struct clk dpll_abe_x2_ck = {  	.recalc		= &omap3_clkoutx2_recalc,  }; -static const struct clksel_rate div31_1to31_rates[] = { -	{ .div = 1, .val = 1, .flags = RATE_IN_4430 }, -	{ .div = 2, .val = 2, .flags = RATE_IN_4430 }, -	{ .div = 3, .val = 3, .flags = RATE_IN_4430 }, -	{ .div = 4, .val = 4, .flags = RATE_IN_4430 }, -	{ .div = 5, .val = 5, .flags = RATE_IN_4430 }, -	{ .div = 6, .val = 6, .flags = RATE_IN_4430 }, -	{ .div = 7, .val = 7, .flags = RATE_IN_4430 }, -	{ .div = 8, .val = 8, .flags = RATE_IN_4430 }, -	{ .div = 9, .val = 9, .flags = RATE_IN_4430 }, -	{ .div = 10, .val = 10, .flags = RATE_IN_4430 }, -	{ .div = 11, .val = 11, .flags = RATE_IN_4430 }, -	{ .div = 12, .val = 12, .flags = RATE_IN_4430 }, -	{ .div = 13, .val = 13, .flags = RATE_IN_4430 }, -	{ .div = 14, .val = 14, .flags = RATE_IN_4430 }, -	{ .div = 15, .val = 15, .flags = RATE_IN_4430 }, -	{ .div = 16, .val = 16, .flags = RATE_IN_4430 }, -	{ .div = 17, .val = 17, .flags = RATE_IN_4430 }, -	{ .div = 18, .val = 18, .flags = RATE_IN_4430 }, -	{ .div = 19, .val = 19, .flags = RATE_IN_4430 }, -	{ .div = 20, .val = 20, .flags = RATE_IN_4430 }, -	{ .div = 21, .val = 21, .flags = RATE_IN_4430 }, -	{ .div = 22, .val = 22, .flags = RATE_IN_4430 }, -	{ .div = 23, .val = 23, .flags = RATE_IN_4430 }, -	{ .div = 24, .val = 24, .flags = RATE_IN_4430 }, -	{ .div = 25, .val = 25, .flags = RATE_IN_4430 }, -	{ .div = 26, .val = 26, .flags = RATE_IN_4430 }, -	{ .div = 27, .val = 27, .flags = RATE_IN_4430 }, -	{ .div = 28, .val = 28, .flags = RATE_IN_4430 }, -	{ .div = 29, .val = 29, .flags = RATE_IN_4430 }, -	{ .div = 30, .val = 30, .flags = RATE_IN_4430 }, -	{ .div = 31, .val = 31, .flags = RATE_IN_4430 }, -	{ .div = 0 }, -}; -  static const struct clksel dpll_abe_m2x2_div[] = {  	{ .parent = &dpll_abe_x2_ck, .rates = div31_1to31_rates },  	{ .parent = NULL }, @@ -3299,17 +3227,17 @@ static struct omap_clk omap44xx_clks[] = {  	CLK(NULL,	"smartreflex_core_fck",		&smartreflex_core_fck,	CK_443X),  	CLK(NULL,	"smartreflex_iva_fck",		&smartreflex_iva_fck,	CK_443X),  	CLK(NULL,	"smartreflex_mpu_fck",		&smartreflex_mpu_fck,	CK_443X), -	CLK(NULL,	"gpt1_fck",			&timer1_fck,	CK_443X), -	CLK(NULL,	"gpt10_fck",			&timer10_fck,	CK_443X), -	CLK(NULL,	"gpt11_fck",			&timer11_fck,	CK_443X), -	CLK(NULL,	"gpt2_fck",			&timer2_fck,	CK_443X), -	CLK(NULL,	"gpt3_fck",			&timer3_fck,	CK_443X), -	CLK(NULL,	"gpt4_fck",			&timer4_fck,	CK_443X), -	CLK(NULL,	"gpt5_fck",			&timer5_fck,	CK_443X), -	CLK(NULL,	"gpt6_fck",			&timer6_fck,	CK_443X), -	CLK(NULL,	"gpt7_fck",			&timer7_fck,	CK_443X), -	CLK(NULL,	"gpt8_fck",			&timer8_fck,	CK_443X), -	CLK(NULL,	"gpt9_fck",			&timer9_fck,	CK_443X), +	CLK(NULL,	"timer1_fck",			&timer1_fck,	CK_443X), +	CLK(NULL,	"timer10_fck",			&timer10_fck,	CK_443X), +	CLK(NULL,	"timer11_fck",			&timer11_fck,	CK_443X), +	CLK(NULL,	"timer2_fck",			&timer2_fck,	CK_443X), +	CLK(NULL,	"timer3_fck",			&timer3_fck,	CK_443X), +	CLK(NULL,	"timer4_fck",			&timer4_fck,	CK_443X), +	CLK(NULL,	"timer5_fck",			&timer5_fck,	CK_443X), +	CLK(NULL,	"timer6_fck",			&timer6_fck,	CK_443X), +	CLK(NULL,	"timer7_fck",			&timer7_fck,	CK_443X), +	CLK(NULL,	"timer8_fck",			&timer8_fck,	CK_443X), +	CLK(NULL,	"timer9_fck",			&timer9_fck,	CK_443X),  	CLK(NULL,	"uart1_fck",			&uart1_fck,	CK_443X),  	CLK(NULL,	"uart2_fck",			&uart2_fck,	CK_443X),  	CLK(NULL,	"uart3_fck",			&uart3_fck,	CK_443X), @@ -3385,28 +3313,18 @@ static struct omap_clk omap44xx_clks[] = {  	CLK("usbhs_omap",	"usbhost_ick",		&dummy_ck,		CK_443X),  	CLK("usbhs_omap",	"usbtll_fck",		&dummy_ck,	CK_443X),  	CLK("omap_wdt",	"ick",				&dummy_ck,	CK_443X), -	CLK("omap_timer.1",	"32k_ck",	&sys_32k_ck,	CK_443X), -	CLK("omap_timer.2",	"32k_ck",	&sys_32k_ck,	CK_443X), -	CLK("omap_timer.3",	"32k_ck",	&sys_32k_ck,	CK_443X), -	CLK("omap_timer.4",	"32k_ck",	&sys_32k_ck,	CK_443X), -	CLK("omap_timer.5",	"32k_ck",	&sys_32k_ck,	CK_443X), -	CLK("omap_timer.6",	"32k_ck",	&sys_32k_ck,	CK_443X), -	CLK("omap_timer.7",	"32k_ck",	&sys_32k_ck,	CK_443X), -	CLK("omap_timer.8",	"32k_ck",	&sys_32k_ck,	CK_443X), -	CLK("omap_timer.9",	"32k_ck",	&sys_32k_ck,	CK_443X), -	CLK("omap_timer.10",	"32k_ck",	&sys_32k_ck,	CK_443X), -	CLK("omap_timer.11",	"32k_ck",	&sys_32k_ck,	CK_443X), -	CLK("omap_timer.1",	"sys_ck",	&sys_clkin_ck,	CK_443X), -	CLK("omap_timer.2",	"sys_ck",	&sys_clkin_ck,	CK_443X), -	CLK("omap_timer.3",	"sys_ck",	&sys_clkin_ck,	CK_443X), -	CLK("omap_timer.4",	"sys_ck",	&sys_clkin_ck,	CK_443X), -	CLK("omap_timer.9",	"sys_ck",	&sys_clkin_ck,	CK_443X), -	CLK("omap_timer.10",	"sys_ck",	&sys_clkin_ck,	CK_443X), -	CLK("omap_timer.11",	"sys_ck",	&sys_clkin_ck,	CK_443X), -	CLK("omap_timer.5",	"sys_ck",	&syc_clk_div_ck,	CK_443X), -	CLK("omap_timer.6",	"sys_ck",	&syc_clk_div_ck,	CK_443X), -	CLK("omap_timer.7",	"sys_ck",	&syc_clk_div_ck,	CK_443X), -	CLK("omap_timer.8",	"sys_ck",	&syc_clk_div_ck,	CK_443X), +	CLK(NULL,	"timer_32k_ck",	&sys_32k_ck,	CK_443X), +	CLK("omap_timer.1",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X), +	CLK("omap_timer.2",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X), +	CLK("omap_timer.3",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X), +	CLK("omap_timer.4",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X), +	CLK("omap_timer.9",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X), +	CLK("omap_timer.10",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X), +	CLK("omap_timer.11",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X), +	CLK("omap_timer.5",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X), +	CLK("omap_timer.6",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X), +	CLK("omap_timer.7",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X), +	CLK("omap_timer.8",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X),  };  int __init omap4xxx_clk_init(void) diff --git a/arch/arm/mach-omap2/clock_common_data.c b/arch/arm/mach-omap2/clock_common_data.c index 6424d46be14..b9f3ba68148 100644 --- a/arch/arm/mach-omap2/clock_common_data.c +++ b/arch/arm/mach-omap2/clock_common_data.c @@ -43,3 +43,80 @@ const struct clksel_rate dsp_ick_rates[] = {  	{ .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 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 */ + +struct clk virt_19200000_ck = { +	.name		= "virt_19200000_ck", +	.ops		= &clkops_null, +	.rate		= 19200000, +}; + +struct clk virt_26000000_ck = { +	.name		= "virt_26000000_ck", +	.ops		= &clkops_null, +	.rate		= 26000000, +}; diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index 6227e9505c2..5601dc13785 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h @@ -199,6 +199,7 @@ 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 _clkdm_add_autodeps(struct clockdomain *clkdm);  extern void _clkdm_del_autodeps(struct clockdomain *clkdm); @@ -206,11 +207,10 @@ 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_dep gfx_24xx_wkdeps[];  extern struct clkdm_dep dsp_24xx_wkdeps[];  extern struct clockdomain wkup_common_clkdm; -extern struct clockdomain prm_common_clkdm; -extern struct clockdomain cm_common_clkdm;  #endif diff --git a/arch/arm/mach-omap2/clockdomain33xx.c b/arch/arm/mach-omap2/clockdomain33xx.c new file mode 100644 index 00000000000..aca6388fad7 --- /dev/null +++ b/arch/arm/mach-omap2/clockdomain33xx.c @@ -0,0 +1,74 @@ +/* + * AM33XX clockdomain control + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * Vaibhav Hiremath <hvaibhav@ti.com> + * + * Derived from mach-omap2/clockdomain44xx.c written by Rajendra Nayak + * + * 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 "clockdomain.h" +#include "cm33xx.h" + + +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/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c index 4f04dd11d65..762f2cc542c 100644 --- a/arch/arm/mach-omap2/clockdomain44xx.c +++ b/arch/arm/mach-omap2/clockdomain44xx.c @@ -70,7 +70,7 @@ static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)  static int omap4_clkdm_sleep(struct clockdomain *clkdm)  { -	omap4_cminst_clkdm_force_sleep(clkdm->prcm_partition, +	omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,  					clkdm->cm_inst, clkdm->clkdm_offs);  	return 0;  } @@ -90,8 +90,12 @@ static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)  static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)  { -	omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition, -					clkdm->cm_inst, clkdm->clkdm_offs); +	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) diff --git a/arch/arm/mach-omap2/clockdomains2420_data.c b/arch/arm/mach-omap2/clockdomains2420_data.c index 0ab8e46d5b2..5c741852fac 100644 --- a/arch/arm/mach-omap2/clockdomains2420_data.c +++ b/arch/arm/mach-omap2/clockdomains2420_data.c @@ -131,8 +131,6 @@ static struct clockdomain dss_2420_clkdm = {  static struct clockdomain *clockdomains_omap242x[] __initdata = {  	&wkup_common_clkdm, -	&cm_common_clkdm, -	&prm_common_clkdm,  	&mpu_2420_clkdm,  	&iva1_2420_clkdm,  	&dsp_2420_clkdm, diff --git a/arch/arm/mach-omap2/clockdomains2430_data.c b/arch/arm/mach-omap2/clockdomains2430_data.c index 3645ed04489..f09617555e1 100644 --- a/arch/arm/mach-omap2/clockdomains2430_data.c +++ b/arch/arm/mach-omap2/clockdomains2430_data.c @@ -157,8 +157,6 @@ static struct clockdomain dss_2430_clkdm = {  static struct clockdomain *clockdomains_omap243x[] __initdata = {  	&wkup_common_clkdm, -	&cm_common_clkdm, -	&prm_common_clkdm,  	&mpu_2430_clkdm,  	&mdm_clkdm,  	&dsp_2430_clkdm, 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 index 6038adb9771..56089c49142 100644 --- a/arch/arm/mach-omap2/clockdomains3xxx_data.c +++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c @@ -59,6 +59,12 @@ static struct clkdm_dep gfx_sgx_3xxx_wkdeps[] = {  	{ 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" }, @@ -69,6 +75,14 @@ static struct clkdm_dep per_wkdeps[] = {  	{ 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" }, @@ -79,6 +93,14 @@ static struct clkdm_dep usbhost_wkdeps[] = {  	{ 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" }, @@ -89,6 +111,14 @@ static struct clkdm_dep mpu_3xxx_wkdeps[] = {  	{ 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" }, @@ -116,6 +146,12 @@ static struct clkdm_dep dss_wkdeps[] = {  	{ 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" }, @@ -131,6 +167,11 @@ static struct clkdm_dep dss_sleepdeps[] = {  	{ 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" }, @@ -138,6 +179,11 @@ static struct clkdm_dep per_sleepdeps[] = {  	{ 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" }, @@ -145,6 +191,11 @@ static struct clkdm_dep usbhost_sleepdeps[] = {  	{ 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" }, @@ -175,6 +226,15 @@ static struct clockdomain mpu_3xxx_clkdm = {  	.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" }, @@ -210,6 +270,15 @@ static struct clockdomain sgx_clkdm = {  	.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 @@ -261,6 +330,16 @@ static struct clockdomain dss_3xxx_clkdm = {  	.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" }, @@ -279,6 +358,15 @@ static struct clockdomain usbhost_clkdm = {  	.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" }, @@ -289,6 +377,16 @@ static struct clockdomain per_clkdm = {  	.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, +}; +  /*   * Disable hw supervised mode for emu_clkdm, because emu_pwrdm is   * switched of even if sdti is in use @@ -341,31 +439,42 @@ static struct clkdm_autodep clkdm_autodeps[] = {  	}  }; +static struct clkdm_autodep clkdm_am35x_autodeps[] = { +	{ +		.clkdm = { .name = "mpu_clkdm" }, +	}, +	{ +		.clkdm = { .name = NULL }, +	} +}; +  /*   *   */ -static struct clockdomain *clockdomains_omap3430_common[] __initdata = { +static struct clockdomain *clockdomains_common[] __initdata = {  	&wkup_common_clkdm, -	&cm_common_clkdm, -	&prm_common_clkdm, -	&mpu_3xxx_clkdm,  	&neon_clkdm, -	&iva2_clkdm, -	&d2d_clkdm,  	&core_l3_3xxx_clkdm,  	&core_l4_3xxx_clkdm, -	&dss_3xxx_clkdm, -	&cam_clkdm, -	&per_clkdm,  	&emu_clkdm,  	&dpll1_clkdm, -	&dpll2_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, @@ -378,21 +487,41 @@ static struct clockdomain *clockdomains_omap3430es2plus[] __initdata = {  	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_omap3430_common); +	clkdm_register_clkdms(clockdomains_common); -	sc = (omap_rev() == OMAP3430_REV_ES1_0) ? clockdomains_omap3430es1 : -		clockdomains_omap3430es2plus; +	rev = omap_rev(); -	clkdm_register_clkdms(sc); +	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_register_autodeps(clkdm_autodeps);  	clkdm_complete_init();  } diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c index 7f2133abe7d..63d60a773d3 100644 --- a/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -430,8 +430,6 @@ static struct clockdomain *clockdomains_omap44xx[] __initdata = {  	&l4_wkup_44xx_clkdm,  	&emu_sys_44xx_clkdm,  	&l3_dma_44xx_clkdm, -	&prm_common_clkdm, -	&cm_common_clkdm,  	NULL  }; diff --git a/arch/arm/mach-omap2/clockdomains_common_data.c b/arch/arm/mach-omap2/clockdomains_common_data.c deleted file mode 100644 index 615b1f04967..00000000000 --- a/arch/arm/mach-omap2/clockdomains_common_data.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * OMAP2+-common clockdomain data - * - * Copyright (C) 2008-2012 Texas Instruments, Inc. - * Copyright (C) 2008-2010 Nokia Corporation - * - * Paul Walmsley, Jouni Högander - */ - -#include <linux/kernel.h> -#include <linux/io.h> - -#include "clockdomain.h" - -/* These are implicit clockdomains - they are never defined as such in TRM */ -struct clockdomain prm_common_clkdm = { -	.name		= "prm_clkdm", -	.pwrdm		= { .name = "wkup_pwrdm" }, -}; - -struct clockdomain cm_common_clkdm = { -	.name		= "cm_clkdm", -	.pwrdm		= { .name = "core_pwrdm" }, -}; 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..532027ee3d8 --- /dev/null +++ b/arch/arm/mach-omap2/cm-regbits-33xx.h @@ -0,0 +1,687 @@ +/* + * 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 + +/* + * Used by CM_AUTOIDLE_DPLL_CORE, CM_AUTOIDLE_DPLL_DDR, CM_AUTOIDLE_DPLL_DISP, + * CM_AUTOIDLE_DPLL_MPU, CM_AUTOIDLE_DPLL_PER + */ +#define AM33XX_AUTO_DPLL_MODE_SHIFT			0 +#define AM33XX_AUTO_DPLL_MODE_MASK			(0x7 << 0) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_ADC_FCLK_SHIFT		14 +#define AM33XX_CLKACTIVITY_ADC_FCLK_MASK		(1 << 16) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_CAN_CLK_SHIFT		11 +#define AM33XX_CLKACTIVITY_CAN_CLK_MASK			(1 << 11) + +/* Used by CM_PER_CLK_24MHZ_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_CLK_24MHZ_GCLK_SHIFT		4 +#define AM33XX_CLKACTIVITY_CLK_24MHZ_GCLK_MASK		(1 << 4) + +/* Used by CM_PER_CPSW_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_CPSW_125MHZ_GCLK_SHIFT	4 +#define AM33XX_CLKACTIVITY_CPSW_125MHZ_GCLK_MASK	(1 << 4) + +/* Used by CM_PER_L4HS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_CPSW_250MHZ_GCLK_SHIFT	4 +#define AM33XX_CLKACTIVITY_CPSW_250MHZ_GCLK_MASK	(1 << 4) + +/* Used by CM_PER_L4HS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_CPSW_50MHZ_GCLK_SHIFT	5 +#define AM33XX_CLKACTIVITY_CPSW_50MHZ_GCLK_MASK		(1 << 5) + +/* Used by CM_PER_L4HS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_CPSW_5MHZ_GCLK_SHIFT		6 +#define AM33XX_CLKACTIVITY_CPSW_5MHZ_GCLK_MASK		(1 << 6) + +/* Used by CM_PER_L3_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_CPTS_RFT_GCLK_SHIFT		6 +#define AM33XX_CLKACTIVITY_CPTS_RFT_GCLK_MASK		(1 << 6) + +/* Used by CM_CEFUSE_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_CUST_EFUSE_SYS_CLK_SHIFT	9 +#define AM33XX_CLKACTIVITY_CUST_EFUSE_SYS_CLK_MASK	(1 << 9) + +/* Used by CM_L3_AON_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_DBGSYSCLK_SHIFT		2 +#define AM33XX_CLKACTIVITY_DBGSYSCLK_MASK		(1 << 2) + +/* Used by CM_L3_AON_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_DEBUG_CLKA_SHIFT		4 +#define AM33XX_CLKACTIVITY_DEBUG_CLKA_MASK		(1 << 4) + +/* Used by CM_PER_L3_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_EMIF_GCLK_SHIFT		2 +#define AM33XX_CLKACTIVITY_EMIF_GCLK_MASK		(1 << 2) + +/* Used by CM_GFX_L3_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_GFX_FCLK_SHIFT		9 +#define AM33XX_CLKACTIVITY_GFX_FCLK_MASK		(1 << 9) + +/* Used by CM_GFX_L3_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_GFX_L3_GCLK_SHIFT		8 +#define AM33XX_CLKACTIVITY_GFX_L3_GCLK_MASK		(1 << 8) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_GPIO0_GDBCLK_SHIFT		8 +#define AM33XX_CLKACTIVITY_GPIO0_GDBCLK_MASK		(1 << 8) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_GPIO_1_GDBCLK_SHIFT		19 +#define AM33XX_CLKACTIVITY_GPIO_1_GDBCLK_MASK		(1 << 19) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_GPIO_2_GDBCLK_SHIFT		20 +#define AM33XX_CLKACTIVITY_GPIO_2_GDBCLK_MASK		(1 << 20) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_GPIO_3_GDBCLK_SHIFT		21 +#define AM33XX_CLKACTIVITY_GPIO_3_GDBCLK_MASK		(1 << 21) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_GPIO_4_GDBCLK_SHIFT		22 +#define AM33XX_CLKACTIVITY_GPIO_4_GDBCLK_MASK		(1 << 22) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_GPIO_5_GDBCLK_SHIFT		26 +#define AM33XX_CLKACTIVITY_GPIO_5_GDBCLK_MASK		(1 << 26) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_GPIO_6_GDBCLK_SHIFT		18 +#define AM33XX_CLKACTIVITY_GPIO_6_GDBCLK_MASK		(1 << 18) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_I2C0_GFCLK_SHIFT		11 +#define AM33XX_CLKACTIVITY_I2C0_GFCLK_MASK		(1 << 11) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_I2C_FCLK_SHIFT		24 +#define AM33XX_CLKACTIVITY_I2C_FCLK_MASK		(1 << 24) + +/* Used by CM_PER_PRUSS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_PRUSS_IEP_GCLK_SHIFT		5 +#define AM33XX_CLKACTIVITY_PRUSS_IEP_GCLK_MASK		(1 << 5) + +/* Used by CM_PER_PRUSS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_PRUSS_OCP_GCLK_SHIFT		4 +#define AM33XX_CLKACTIVITY_PRUSS_OCP_GCLK_MASK		(1 << 4) + +/* Used by CM_PER_PRUSS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_PRUSS_UART_GCLK_SHIFT	6 +#define AM33XX_CLKACTIVITY_PRUSS_UART_GCLK_MASK		(1 << 6) + +/* Used by CM_PER_L3S_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L3S_GCLK_SHIFT		3 +#define AM33XX_CLKACTIVITY_L3S_GCLK_MASK		(1 << 3) + +/* Used by CM_L3_AON_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L3_AON_GCLK_SHIFT		3 +#define AM33XX_CLKACTIVITY_L3_AON_GCLK_MASK		(1 << 3) + +/* Used by CM_PER_L3_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L3_GCLK_SHIFT		4 +#define AM33XX_CLKACTIVITY_L3_GCLK_MASK			(1 << 4) + +/* Used by CM_PER_L4FW_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L4FW_GCLK_SHIFT		8 +#define AM33XX_CLKACTIVITY_L4FW_GCLK_MASK		(1 << 8) + +/* Used by CM_PER_L4HS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L4HS_GCLK_SHIFT		3 +#define AM33XX_CLKACTIVITY_L4HS_GCLK_MASK		(1 << 3) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L4LS_GCLK_SHIFT		8 +#define AM33XX_CLKACTIVITY_L4LS_GCLK_MASK		(1 << 8) + +/* Used by CM_GFX_L4LS_GFX_CLKSTCTRL__1 */ +#define AM33XX_CLKACTIVITY_L4LS_GFX_GCLK_SHIFT		8 +#define AM33XX_CLKACTIVITY_L4LS_GFX_GCLK_MASK		(1 << 8) + +/* Used by CM_CEFUSE_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L4_CEFUSE_GICLK_SHIFT	8 +#define AM33XX_CLKACTIVITY_L4_CEFUSE_GICLK_MASK		(1 << 8) + +/* Used by CM_RTC_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L4_RTC_GCLK_SHIFT		8 +#define AM33XX_CLKACTIVITY_L4_RTC_GCLK_MASK		(1 << 8) + +/* Used by CM_L4_WKUP_AON_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L4_WKUP_AON_GCLK_SHIFT	2 +#define AM33XX_CLKACTIVITY_L4_WKUP_AON_GCLK_MASK	(1 << 2) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_L4_WKUP_GCLK_SHIFT		2 +#define AM33XX_CLKACTIVITY_L4_WKUP_GCLK_MASK		(1 << 2) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_LCDC_GCLK_SHIFT		17 +#define AM33XX_CLKACTIVITY_LCDC_GCLK_MASK		(1 << 17) + +/* Used by CM_PER_LCDC_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_LCDC_L3_OCP_GCLK_SHIFT	4 +#define AM33XX_CLKACTIVITY_LCDC_L3_OCP_GCLK_MASK	(1 << 4) + +/* Used by CM_PER_LCDC_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_LCDC_L4_OCP_GCLK_SHIFT	5 +#define AM33XX_CLKACTIVITY_LCDC_L4_OCP_GCLK_MASK	(1 << 5) + +/* Used by CM_PER_L3_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_MCASP_GCLK_SHIFT		7 +#define AM33XX_CLKACTIVITY_MCASP_GCLK_MASK		(1 << 7) + +/* Used by CM_PER_L3_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_MMC_FCLK_SHIFT		3 +#define AM33XX_CLKACTIVITY_MMC_FCLK_MASK		(1 << 3) + +/* Used by CM_MPU_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_MPU_CLK_SHIFT		2 +#define AM33XX_CLKACTIVITY_MPU_CLK_MASK			(1 << 2) + +/* Used by CM_PER_OCPWP_L3_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_OCPWP_L3_GCLK_SHIFT		4 +#define AM33XX_CLKACTIVITY_OCPWP_L3_GCLK_MASK		(1 << 4) + +/* Used by CM_PER_OCPWP_L3_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_OCPWP_L4_GCLK_SHIFT		5 +#define AM33XX_CLKACTIVITY_OCPWP_L4_GCLK_MASK		(1 << 5) + +/* Used by CM_RTC_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_RTC_32KCLK_SHIFT		9 +#define AM33XX_CLKACTIVITY_RTC_32KCLK_MASK		(1 << 9) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_SPI_GCLK_SHIFT		25 +#define AM33XX_CLKACTIVITY_SPI_GCLK_MASK		(1 << 25) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_SR_SYSCLK_SHIFT		3 +#define AM33XX_CLKACTIVITY_SR_SYSCLK_MASK		(1 << 3) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_TIMER0_GCLK_SHIFT		10 +#define AM33XX_CLKACTIVITY_TIMER0_GCLK_MASK		(1 << 10) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_TIMER1_GCLK_SHIFT		13 +#define AM33XX_CLKACTIVITY_TIMER1_GCLK_MASK		(1 << 13) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_TIMER2_GCLK_SHIFT		14 +#define AM33XX_CLKACTIVITY_TIMER2_GCLK_MASK		(1 << 14) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_TIMER3_GCLK_SHIFT		15 +#define AM33XX_CLKACTIVITY_TIMER3_GCLK_MASK		(1 << 15) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_TIMER4_GCLK_SHIFT		16 +#define AM33XX_CLKACTIVITY_TIMER4_GCLK_MASK		(1 << 16) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_TIMER5_GCLK_SHIFT		27 +#define AM33XX_CLKACTIVITY_TIMER5_GCLK_MASK		(1 << 27) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_TIMER6_GCLK_SHIFT		28 +#define AM33XX_CLKACTIVITY_TIMER6_GCLK_MASK		(1 << 28) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_TIMER7_GCLK_SHIFT		13 +#define AM33XX_CLKACTIVITY_TIMER7_GCLK_MASK		(1 << 13) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_UART0_GFCLK_SHIFT		12 +#define AM33XX_CLKACTIVITY_UART0_GFCLK_MASK		(1 << 12) + +/* Used by CM_PER_L4LS_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_UART_GFCLK_SHIFT		10 +#define AM33XX_CLKACTIVITY_UART_GFCLK_MASK		(1 << 10) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_WDT0_GCLK_SHIFT		9 +#define AM33XX_CLKACTIVITY_WDT0_GCLK_MASK		(1 << 9) + +/* Used by CM_WKUP_CLKSTCTRL */ +#define AM33XX_CLKACTIVITY_WDT1_GCLK_SHIFT		4 +#define AM33XX_CLKACTIVITY_WDT1_GCLK_MASK		(1 << 4) + +/* Used by CLKSEL_GFX_FCLK */ +#define AM33XX_CLKDIV_SEL_GFX_FCLK_SHIFT		0 +#define AM33XX_CLKDIV_SEL_GFX_FCLK_MASK			(1 << 0) + +/* Used by CM_CLKOUT_CTRL */ +#define AM33XX_CLKOUT2DIV_SHIFT				3 +#define AM33XX_CLKOUT2DIV_MASK				(0x05 << 3) + +/* Used by CM_CLKOUT_CTRL */ +#define AM33XX_CLKOUT2EN_SHIFT				7 +#define AM33XX_CLKOUT2EN_MASK				(1 << 7) + +/* Used by CM_CLKOUT_CTRL */ +#define AM33XX_CLKOUT2SOURCE_SHIFT			0 +#define AM33XX_CLKOUT2SOURCE_MASK			(0x02 << 0) + +/* + * Used by CLKSEL_GPIO0_DBCLK, CLKSEL_LCDC_PIXEL_CLK, CLKSEL_TIMER2_CLK, + * CLKSEL_TIMER3_CLK, CLKSEL_TIMER4_CLK, CLKSEL_TIMER5_CLK, CLKSEL_TIMER6_CLK, + * CLKSEL_TIMER7_CLK + */ +#define AM33XX_CLKSEL_SHIFT				0 +#define AM33XX_CLKSEL_MASK				(0x01 << 0) + +/* + * Renamed from CLKSEL Used by CLKSEL_PRUSS_OCP_CLK, CLKSEL_WDT1_CLK, + * CM_CPTS_RFT_CLKSEL + */ +#define AM33XX_CLKSEL_0_0_SHIFT				0 +#define AM33XX_CLKSEL_0_0_MASK				(1 << 0) + +#define AM33XX_CLKSEL_0_1_SHIFT				0 +#define AM33XX_CLKSEL_0_1_MASK				(3 << 0) + +/* Renamed from CLKSEL Used by CLKSEL_TIMER1MS_CLK */ +#define AM33XX_CLKSEL_0_2_SHIFT				0 +#define AM33XX_CLKSEL_0_2_MASK				(7 << 0) + +/* Used by CLKSEL_GFX_FCLK */ +#define AM33XX_CLKSEL_GFX_FCLK_SHIFT			1 +#define AM33XX_CLKSEL_GFX_FCLK_MASK			(1 << 1) + +/* + * Used by CM_MPU_CLKSTCTRL, CM_RTC_CLKSTCTRL, CM_PER_CLK_24MHZ_CLKSTCTRL, + * CM_PER_CPSW_CLKSTCTRL, CM_PER_PRUSS_CLKSTCTRL, CM_PER_L3S_CLKSTCTRL, + * CM_PER_L3_CLKSTCTRL, CM_PER_L4FW_CLKSTCTRL, CM_PER_L4HS_CLKSTCTRL, + * CM_PER_L4LS_CLKSTCTRL, CM_PER_LCDC_CLKSTCTRL, CM_PER_OCPWP_L3_CLKSTCTRL, + * CM_L3_AON_CLKSTCTRL, CM_L4_WKUP_AON_CLKSTCTRL, CM_WKUP_CLKSTCTRL, + * CM_GFX_L3_CLKSTCTRL, CM_GFX_L4LS_GFX_CLKSTCTRL__1, CM_CEFUSE_CLKSTCTRL + */ +#define AM33XX_CLKTRCTRL_SHIFT				0 +#define AM33XX_CLKTRCTRL_MASK				(0x3 << 0) + +/* + * Used by CM_SSC_DELTAMSTEP_DPLL_CORE, CM_SSC_DELTAMSTEP_DPLL_DDR, + * CM_SSC_DELTAMSTEP_DPLL_DISP, CM_SSC_DELTAMSTEP_DPLL_MPU, + * CM_SSC_DELTAMSTEP_DPLL_PER + */ +#define AM33XX_DELTAMSTEP_SHIFT				0 +#define AM33XX_DELTAMSTEP_MASK				(0x19 << 0) + +/* Used by CM_CLKSEL_DPLL_DDR, CM_CLKSEL_DPLL_DISP, CM_CLKSEL_DPLL_MPU */ +#define AM33XX_DPLL_BYP_CLKSEL_SHIFT			23 +#define AM33XX_DPLL_BYP_CLKSEL_MASK			(1 << 23) + +/* Used by CM_CLKDCOLDO_DPLL_PER */ +#define AM33XX_DPLL_CLKDCOLDO_GATE_CTRL_SHIFT		8 +#define AM33XX_DPLL_CLKDCOLDO_GATE_CTRL_MASK		(1 << 8) + +/* Used by CM_CLKDCOLDO_DPLL_PER */ +#define AM33XX_DPLL_CLKDCOLDO_PWDN_SHIFT		12 +#define AM33XX_DPLL_CLKDCOLDO_PWDN_MASK			(1 << 12) + +/* Used by CM_DIV_M2_DPLL_DDR, CM_DIV_M2_DPLL_DISP, CM_DIV_M2_DPLL_MPU */ +#define AM33XX_DPLL_CLKOUT_DIV_SHIFT			0 +#define AM33XX_DPLL_CLKOUT_DIV_MASK			(0x1f << 0) + +/* Renamed from DPLL_CLKOUT_DIV Used by CM_DIV_M2_DPLL_PER */ +#define AM33XX_DPLL_CLKOUT_DIV_0_6_SHIFT		0 +#define AM33XX_DPLL_CLKOUT_DIV_0_6_MASK			(0x06 << 0) + +/* Used by CM_DIV_M2_DPLL_DDR, CM_DIV_M2_DPLL_DISP, CM_DIV_M2_DPLL_MPU */ +#define AM33XX_DPLL_CLKOUT_DIVCHACK_SHIFT		5 +#define AM33XX_DPLL_CLKOUT_DIVCHACK_MASK		(1 << 5) + +/* Renamed from DPLL_CLKOUT_DIVCHACK Used by CM_DIV_M2_DPLL_PER */ +#define AM33XX_DPLL_CLKOUT_DIVCHACK_M2_PER_SHIFT	7 +#define AM33XX_DPLL_CLKOUT_DIVCHACK_M2_PER_MASK		(1 << 7) + +/* + * Used by CM_DIV_M2_DPLL_DDR, CM_DIV_M2_DPLL_DISP, CM_DIV_M2_DPLL_MPU, + * CM_DIV_M2_DPLL_PER + */ +#define AM33XX_DPLL_CLKOUT_GATE_CTRL_SHIFT		8 +#define AM33XX_DPLL_CLKOUT_GATE_CTRL_MASK		(1 << 8) + +/* + * Used by CM_CLKSEL_DPLL_CORE, CM_CLKSEL_DPLL_DDR, CM_CLKSEL_DPLL_DISP, + * CM_CLKSEL_DPLL_MPU + */ +#define AM33XX_DPLL_DIV_SHIFT				0 +#define AM33XX_DPLL_DIV_MASK				(0x7f << 0) + +#define AM33XX_DPLL_PER_DIV_MASK			(0xff << 0) + +/* Renamed from DPLL_DIV Used by CM_CLKSEL_DPLL_PERIPH */ +#define AM33XX_DPLL_DIV_0_7_SHIFT			0 +#define AM33XX_DPLL_DIV_0_7_MASK			(0x07 << 0) + +/* + * Used by CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_DDR, CM_CLKMODE_DPLL_DISP, + * CM_CLKMODE_DPLL_MPU + */ +#define AM33XX_DPLL_DRIFTGUARD_EN_SHIFT			8 +#define AM33XX_DPLL_DRIFTGUARD_EN_MASK			(1 << 8) + +/* + * Used by CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_DDR, CM_CLKMODE_DPLL_DISP, + * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER + */ +#define AM33XX_DPLL_EN_SHIFT				0 +#define AM33XX_DPLL_EN_MASK				(0x7 << 0) + +/* + * Used by CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_DDR, CM_CLKMODE_DPLL_DISP, + * CM_CLKMODE_DPLL_MPU + */ +#define AM33XX_DPLL_LPMODE_EN_SHIFT			10 +#define AM33XX_DPLL_LPMODE_EN_MASK			(1 << 10) + +/* + * Used by CM_CLKSEL_DPLL_CORE, CM_CLKSEL_DPLL_DDR, CM_CLKSEL_DPLL_DISP, + * CM_CLKSEL_DPLL_MPU + */ +#define AM33XX_DPLL_MULT_SHIFT				8 +#define AM33XX_DPLL_MULT_MASK				(0x7ff << 8) + +/* Renamed from DPLL_MULT Used by CM_CLKSEL_DPLL_PERIPH */ +#define AM33XX_DPLL_MULT_PERIPH_SHIFT			8 +#define AM33XX_DPLL_MULT_PERIPH_MASK			(0xfff << 8) + +/* + * Used by CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_DDR, CM_CLKMODE_DPLL_DISP, + * CM_CLKMODE_DPLL_MPU + */ +#define AM33XX_DPLL_REGM4XEN_SHIFT			11 +#define AM33XX_DPLL_REGM4XEN_MASK			(1 << 11) + +/* Used by CM_CLKSEL_DPLL_PERIPH */ +#define AM33XX_DPLL_SD_DIV_SHIFT			24 +#define AM33XX_DPLL_SD_DIV_MASK				(24, 31) + +/* + * Used by CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_DDR, CM_CLKMODE_DPLL_DISP, + * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER + */ +#define AM33XX_DPLL_SSC_ACK_SHIFT			13 +#define AM33XX_DPLL_SSC_ACK_MASK			(1 << 13) + +/* + * Used by CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_DDR, CM_CLKMODE_DPLL_DISP, + * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER + */ +#define AM33XX_DPLL_SSC_DOWNSPREAD_SHIFT		14 +#define AM33XX_DPLL_SSC_DOWNSPREAD_MASK			(1 << 14) + +/* + * Used by CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_DDR, CM_CLKMODE_DPLL_DISP, + * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER + */ +#define AM33XX_DPLL_SSC_EN_SHIFT			12 +#define AM33XX_DPLL_SSC_EN_MASK				(1 << 12) + +/* Used by CM_DIV_M4_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT1_DIV_SHIFT		0 +#define AM33XX_HSDIVIDER_CLKOUT1_DIV_MASK		(0x1f << 0) + +/* Used by CM_DIV_M4_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT1_DIVCHACK_SHIFT		5 +#define AM33XX_HSDIVIDER_CLKOUT1_DIVCHACK_MASK		(1 << 5) + +/* Used by CM_DIV_M4_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT1_GATE_CTRL_SHIFT	8 +#define AM33XX_HSDIVIDER_CLKOUT1_GATE_CTRL_MASK		(1 << 8) + +/* Used by CM_DIV_M4_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT1_PWDN_SHIFT		12 +#define AM33XX_HSDIVIDER_CLKOUT1_PWDN_MASK		(1 << 12) + +/* Used by CM_DIV_M5_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT2_DIV_SHIFT		0 +#define AM33XX_HSDIVIDER_CLKOUT2_DIV_MASK		(0x1f << 0) + +/* Used by CM_DIV_M5_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT2_DIVCHACK_SHIFT		5 +#define AM33XX_HSDIVIDER_CLKOUT2_DIVCHACK_MASK		(1 << 5) + +/* Used by CM_DIV_M5_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT2_GATE_CTRL_SHIFT	8 +#define AM33XX_HSDIVIDER_CLKOUT2_GATE_CTRL_MASK		(1 << 8) + +/* Used by CM_DIV_M5_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT2_PWDN_SHIFT		12 +#define AM33XX_HSDIVIDER_CLKOUT2_PWDN_MASK		(1 << 12) + +/* Used by CM_DIV_M6_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT3_DIV_SHIFT		0 +#define AM33XX_HSDIVIDER_CLKOUT3_DIV_MASK		(0x04 << 0) + +/* Used by CM_DIV_M6_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT3_DIVCHACK_SHIFT		5 +#define AM33XX_HSDIVIDER_CLKOUT3_DIVCHACK_MASK		(1 << 5) + +/* Used by CM_DIV_M6_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT3_GATE_CTRL_SHIFT	8 +#define AM33XX_HSDIVIDER_CLKOUT3_GATE_CTRL_MASK		(1 << 8) + +/* Used by CM_DIV_M6_DPLL_CORE */ +#define AM33XX_HSDIVIDER_CLKOUT3_PWDN_SHIFT		12 +#define AM33XX_HSDIVIDER_CLKOUT3_PWDN_MASK		(1 << 12) + +/* + * Used by CM_MPU_MPU_CLKCTRL, CM_RTC_RTC_CLKCTRL, CM_PER_AES0_CLKCTRL, + * CM_PER_AES1_CLKCTRL, CM_PER_CLKDIV32K_CLKCTRL, CM_PER_CPGMAC0_CLKCTRL, + * CM_PER_DCAN0_CLKCTRL, CM_PER_DCAN1_CLKCTRL, CM_PER_DES_CLKCTRL, + * CM_PER_ELM_CLKCTRL, CM_PER_EMIF_CLKCTRL, CM_PER_EMIF_FW_CLKCTRL, + * CM_PER_EPWMSS0_CLKCTRL, CM_PER_EPWMSS1_CLKCTRL, CM_PER_EPWMSS2_CLKCTRL, + * CM_PER_GPIO1_CLKCTRL, CM_PER_GPIO2_CLKCTRL, CM_PER_GPIO3_CLKCTRL, + * CM_PER_GPIO4_CLKCTRL, CM_PER_GPIO5_CLKCTRL, CM_PER_GPIO6_CLKCTRL, + * CM_PER_GPMC_CLKCTRL, CM_PER_I2C1_CLKCTRL, CM_PER_I2C2_CLKCTRL, + * CM_PER_PRUSS_CLKCTRL, CM_PER_IEEE5000_CLKCTRL, CM_PER_L3_CLKCTRL, + * CM_PER_L3_INSTR_CLKCTRL, CM_PER_L4FW_CLKCTRL, CM_PER_L4HS_CLKCTRL, + * CM_PER_L4LS_CLKCTRL, CM_PER_LCDC_CLKCTRL, CM_PER_MAILBOX0_CLKCTRL, + * CM_PER_MAILBOX1_CLKCTRL, CM_PER_MCASP0_CLKCTRL, CM_PER_MCASP1_CLKCTRL, + * CM_PER_MCASP2_CLKCTRL, CM_PER_MLB_CLKCTRL, CM_PER_MMC0_CLKCTRL, + * CM_PER_MMC1_CLKCTRL, CM_PER_MMC2_CLKCTRL, CM_PER_MSTR_EXPS_CLKCTRL, + * CM_PER_OCMCRAM_CLKCTRL, CM_PER_OCPWP_CLKCTRL, CM_PER_PCIE_CLKCTRL, + * CM_PER_PKA_CLKCTRL, CM_PER_RNG_CLKCTRL, CM_PER_SHA0_CLKCTRL, + * CM_PER_SLV_EXPS_CLKCTRL, CM_PER_SPARE0_CLKCTRL, CM_PER_SPARE1_CLKCTRL, + * CM_PER_SPARE_CLKCTRL, CM_PER_SPI0_CLKCTRL, CM_PER_SPI1_CLKCTRL, + * CM_PER_SPI2_CLKCTRL, CM_PER_SPI3_CLKCTRL, CM_PER_SPINLOCK_CLKCTRL, + * CM_PER_TIMER2_CLKCTRL, CM_PER_TIMER3_CLKCTRL, CM_PER_TIMER4_CLKCTRL, + * CM_PER_TIMER5_CLKCTRL, CM_PER_TIMER6_CLKCTRL, CM_PER_TIMER7_CLKCTRL, + * CM_PER_TPCC_CLKCTRL, CM_PER_TPTC0_CLKCTRL, CM_PER_TPTC1_CLKCTRL, + * CM_PER_TPTC2_CLKCTRL, CM_PER_UART1_CLKCTRL, CM_PER_UART2_CLKCTRL, + * CM_PER_UART3_CLKCTRL, CM_PER_UART4_CLKCTRL, CM_PER_UART5_CLKCTRL, + * CM_PER_USB0_CLKCTRL, CM_WKUP_ADC_TSC_CLKCTRL, CM_WKUP_CONTROL_CLKCTRL, + * CM_WKUP_DEBUGSS_CLKCTRL, CM_WKUP_GPIO0_CLKCTRL, CM_WKUP_I2C0_CLKCTRL, + * CM_WKUP_L4WKUP_CLKCTRL, CM_WKUP_SMARTREFLEX0_CLKCTRL, + * CM_WKUP_SMARTREFLEX1_CLKCTRL, CM_WKUP_TIMER0_CLKCTRL, + * CM_WKUP_TIMER1_CLKCTRL, CM_WKUP_UART0_CLKCTRL, CM_WKUP_WDT0_CLKCTRL, + * CM_WKUP_WDT1_CLKCTRL, CM_GFX_BITBLT_CLKCTRL, CM_GFX_GFX_CLKCTRL, + * CM_GFX_MMUCFG_CLKCTRL, CM_GFX_MMUDATA_CLKCTRL, CM_CEFUSE_CEFUSE_CLKCTRL + */ +#define AM33XX_IDLEST_SHIFT				16 +#define AM33XX_IDLEST_MASK				(0x3 << 16) +#define AM33XX_IDLEST_VAL				0x3 + +/* Used by CM_MAC_CLKSEL */ +#define AM33XX_MII_CLK_SEL_SHIFT			2 +#define AM33XX_MII_CLK_SEL_MASK				(1 << 2) + +/* + * Used by CM_SSC_MODFREQDIV_DPLL_CORE, CM_SSC_MODFREQDIV_DPLL_DDR, + * CM_SSC_MODFREQDIV_DPLL_DISP, CM_SSC_MODFREQDIV_DPLL_MPU, + * CM_SSC_MODFREQDIV_DPLL_PER + */ +#define AM33XX_MODFREQDIV_EXPONENT_SHIFT		8 +#define AM33XX_MODFREQDIV_EXPONENT_MASK			(0x10 << 8) + +/* + * Used by CM_SSC_MODFREQDIV_DPLL_CORE, CM_SSC_MODFREQDIV_DPLL_DDR, + * CM_SSC_MODFREQDIV_DPLL_DISP, CM_SSC_MODFREQDIV_DPLL_MPU, + * CM_SSC_MODFREQDIV_DPLL_PER + */ +#define AM33XX_MODFREQDIV_MANTISSA_SHIFT		0 +#define AM33XX_MODFREQDIV_MANTISSA_MASK			(0x06 << 0) + +/* + * Used by CM_MPU_MPU_CLKCTRL, CM_RTC_RTC_CLKCTRL, CM_PER_AES0_CLKCTRL, + * CM_PER_AES1_CLKCTRL, CM_PER_CLKDIV32K_CLKCTRL, CM_PER_CPGMAC0_CLKCTRL, + * CM_PER_DCAN0_CLKCTRL, CM_PER_DCAN1_CLKCTRL, CM_PER_DES_CLKCTRL, + * CM_PER_ELM_CLKCTRL, CM_PER_EMIF_CLKCTRL, CM_PER_EMIF_FW_CLKCTRL, + * CM_PER_EPWMSS0_CLKCTRL, CM_PER_EPWMSS1_CLKCTRL, CM_PER_EPWMSS2_CLKCTRL, + * CM_PER_GPIO1_CLKCTRL, CM_PER_GPIO2_CLKCTRL, CM_PER_GPIO3_CLKCTRL, + * CM_PER_GPIO4_CLKCTRL, CM_PER_GPIO5_CLKCTRL, CM_PER_GPIO6_CLKCTRL, + * CM_PER_GPMC_CLKCTRL, CM_PER_I2C1_CLKCTRL, CM_PER_I2C2_CLKCTRL, + * CM_PER_PRUSS_CLKCTRL, CM_PER_IEEE5000_CLKCTRL, CM_PER_L3_CLKCTRL, + * CM_PER_L3_INSTR_CLKCTRL, CM_PER_L4FW_CLKCTRL, CM_PER_L4HS_CLKCTRL, + * CM_PER_L4LS_CLKCTRL, CM_PER_LCDC_CLKCTRL, CM_PER_MAILBOX0_CLKCTRL, + * CM_PER_MAILBOX1_CLKCTRL, CM_PER_MCASP0_CLKCTRL, CM_PER_MCASP1_CLKCTRL, + * CM_PER_MCASP2_CLKCTRL, CM_PER_MLB_CLKCTRL, CM_PER_MMC0_CLKCTRL, + * CM_PER_MMC1_CLKCTRL, CM_PER_MMC2_CLKCTRL, CM_PER_MSTR_EXPS_CLKCTRL, + * CM_PER_OCMCRAM_CLKCTRL, CM_PER_OCPWP_CLKCTRL, CM_PER_PCIE_CLKCTRL, + * CM_PER_PKA_CLKCTRL, CM_PER_RNG_CLKCTRL, CM_PER_SHA0_CLKCTRL, + * CM_PER_SLV_EXPS_CLKCTRL, CM_PER_SPARE0_CLKCTRL, CM_PER_SPARE1_CLKCTRL, + * CM_PER_SPARE_CLKCTRL, CM_PER_SPI0_CLKCTRL, CM_PER_SPI1_CLKCTRL, + * CM_PER_SPI2_CLKCTRL, CM_PER_SPI3_CLKCTRL, CM_PER_SPINLOCK_CLKCTRL, + * CM_PER_TIMER2_CLKCTRL, CM_PER_TIMER3_CLKCTRL, CM_PER_TIMER4_CLKCTRL, + * CM_PER_TIMER5_CLKCTRL, CM_PER_TIMER6_CLKCTRL, CM_PER_TIMER7_CLKCTRL, + * CM_PER_TPCC_CLKCTRL, CM_PER_TPTC0_CLKCTRL, CM_PER_TPTC1_CLKCTRL, + * CM_PER_TPTC2_CLKCTRL, CM_PER_UART1_CLKCTRL, CM_PER_UART2_CLKCTRL, + * CM_PER_UART3_CLKCTRL, CM_PER_UART4_CLKCTRL, CM_PER_UART5_CLKCTRL, + * CM_PER_USB0_CLKCTRL, CM_WKUP_ADC_TSC_CLKCTRL, CM_WKUP_CONTROL_CLKCTRL, + * CM_WKUP_DEBUGSS_CLKCTRL, CM_WKUP_GPIO0_CLKCTRL, CM_WKUP_I2C0_CLKCTRL, + * CM_WKUP_L4WKUP_CLKCTRL, CM_WKUP_SMARTREFLEX0_CLKCTRL, + * CM_WKUP_SMARTREFLEX1_CLKCTRL, CM_WKUP_TIMER0_CLKCTRL, + * CM_WKUP_TIMER1_CLKCTRL, CM_WKUP_UART0_CLKCTRL, CM_WKUP_WDT0_CLKCTRL, + * CM_WKUP_WDT1_CLKCTRL, CM_WKUP_WKUP_M3_CLKCTRL, CM_GFX_BITBLT_CLKCTRL, + * CM_GFX_GFX_CLKCTRL, CM_GFX_MMUCFG_CLKCTRL, CM_GFX_MMUDATA_CLKCTRL, + * CM_CEFUSE_CEFUSE_CLKCTRL + */ +#define AM33XX_MODULEMODE_SHIFT				0 +#define AM33XX_MODULEMODE_MASK				(0x3 << 0) + +/* Used by CM_WKUP_DEBUGSS_CLKCTRL */ +#define AM33XX_OPTCLK_DEBUG_CLKA_SHIFT			30 +#define AM33XX_OPTCLK_DEBUG_CLKA_MASK			(1 << 30) + +/* Used by CM_WKUP_DEBUGSS_CLKCTRL */ +#define AM33XX_OPTFCLKEN_DBGSYSCLK_SHIFT		19 +#define AM33XX_OPTFCLKEN_DBGSYSCLK_MASK			(1 << 19) + +/* Used by CM_WKUP_GPIO0_CLKCTRL */ +#define AM33XX_OPTFCLKEN_GPIO0_GDBCLK_SHIFT		18 +#define AM33XX_OPTFCLKEN_GPIO0_GDBCLK_MASK		(1 << 18) + +/* Used by CM_PER_GPIO1_CLKCTRL */ +#define AM33XX_OPTFCLKEN_GPIO_1_GDBCLK_SHIFT		18 +#define AM33XX_OPTFCLKEN_GPIO_1_GDBCLK_MASK		(1 << 18) + +/* Used by CM_PER_GPIO2_CLKCTRL */ +#define AM33XX_OPTFCLKEN_GPIO_2_GDBCLK_SHIFT		18 +#define AM33XX_OPTFCLKEN_GPIO_2_GDBCLK_MASK		(1 << 18) + +/* Used by CM_PER_GPIO3_CLKCTRL */ +#define AM33XX_OPTFCLKEN_GPIO_3_GDBCLK_SHIFT		18 +#define AM33XX_OPTFCLKEN_GPIO_3_GDBCLK_MASK		(1 << 18) + +/* Used by CM_PER_GPIO4_CLKCTRL */ +#define AM33XX_OPTFCLKEN_GPIO_4_GDBCLK_SHIFT		18 +#define AM33XX_OPTFCLKEN_GPIO_4_GDBCLK_MASK		(1 << 18) + +/* Used by CM_PER_GPIO5_CLKCTRL */ +#define AM33XX_OPTFCLKEN_GPIO_5_GDBCLK_SHIFT		18 +#define AM33XX_OPTFCLKEN_GPIO_5_GDBCLK_MASK		(1 << 18) + +/* Used by CM_PER_GPIO6_CLKCTRL */ +#define AM33XX_OPTFCLKEN_GPIO_6_GDBCLK_SHIFT		18 +#define AM33XX_OPTFCLKEN_GPIO_6_GDBCLK_MASK		(1 << 18) + +/* + * Used by CM_MPU_MPU_CLKCTRL, CM_PER_CPGMAC0_CLKCTRL, CM_PER_PRUSS_CLKCTRL, + * CM_PER_IEEE5000_CLKCTRL, CM_PER_LCDC_CLKCTRL, CM_PER_MLB_CLKCTRL, + * CM_PER_MSTR_EXPS_CLKCTRL, CM_PER_OCPWP_CLKCTRL, CM_PER_PCIE_CLKCTRL, + * CM_PER_SPARE_CLKCTRL, CM_PER_TPTC0_CLKCTRL, CM_PER_TPTC1_CLKCTRL, + * CM_PER_TPTC2_CLKCTRL, CM_PER_USB0_CLKCTRL, CM_WKUP_DEBUGSS_CLKCTRL, + * CM_WKUP_WKUP_M3_CLKCTRL, CM_GFX_BITBLT_CLKCTRL, CM_GFX_GFX_CLKCTRL + */ +#define AM33XX_STBYST_SHIFT				18 +#define AM33XX_STBYST_MASK				(1 << 18) + +/* Used by CM_WKUP_DEBUGSS_CLKCTRL */ +#define AM33XX_STM_PMD_CLKDIVSEL_SHIFT			27 +#define AM33XX_STM_PMD_CLKDIVSEL_MASK			(0x29 << 27) + +/* Used by CM_WKUP_DEBUGSS_CLKCTRL */ +#define AM33XX_STM_PMD_CLKSEL_SHIFT			22 +#define AM33XX_STM_PMD_CLKSEL_MASK			(0x23 << 22) + +/* + * Used by CM_IDLEST_DPLL_CORE, CM_IDLEST_DPLL_DDR, CM_IDLEST_DPLL_DISP, + * CM_IDLEST_DPLL_MPU, CM_IDLEST_DPLL_PER + */ +#define AM33XX_ST_DPLL_CLK_SHIFT			0 +#define AM33XX_ST_DPLL_CLK_MASK				(1 << 0) + +/* Used by CM_CLKDCOLDO_DPLL_PER */ +#define AM33XX_ST_DPLL_CLKDCOLDO_SHIFT			8 +#define AM33XX_ST_DPLL_CLKDCOLDO_MASK			(1 << 8) + +/* + * Used by CM_DIV_M2_DPLL_DDR, CM_DIV_M2_DPLL_DISP, CM_DIV_M2_DPLL_MPU, + * CM_DIV_M2_DPLL_PER + */ +#define AM33XX_ST_DPLL_CLKOUT_SHIFT			9 +#define AM33XX_ST_DPLL_CLKOUT_MASK			(1 << 9) + +/* Used by CM_DIV_M4_DPLL_CORE */ +#define AM33XX_ST_HSDIVIDER_CLKOUT1_SHIFT		9 +#define AM33XX_ST_HSDIVIDER_CLKOUT1_MASK		(1 << 9) + +/* Used by CM_DIV_M5_DPLL_CORE */ +#define AM33XX_ST_HSDIVIDER_CLKOUT2_SHIFT		9 +#define AM33XX_ST_HSDIVIDER_CLKOUT2_MASK		(1 << 9) + +/* Used by CM_DIV_M6_DPLL_CORE */ +#define AM33XX_ST_HSDIVIDER_CLKOUT3_SHIFT		9 +#define AM33XX_ST_HSDIVIDER_CLKOUT3_MASK		(1 << 9) + +/* + * Used by CM_IDLEST_DPLL_CORE, CM_IDLEST_DPLL_DDR, CM_IDLEST_DPLL_DISP, + * CM_IDLEST_DPLL_MPU, CM_IDLEST_DPLL_PER + */ +#define AM33XX_ST_MN_BYPASS_SHIFT			8 +#define AM33XX_ST_MN_BYPASS_MASK			(1 << 8) + +/* Used by CM_WKUP_DEBUGSS_CLKCTRL */ +#define AM33XX_TRC_PMD_CLKDIVSEL_SHIFT			24 +#define AM33XX_TRC_PMD_CLKDIVSEL_MASK			(0x26 << 24) + +/* Used by CM_WKUP_DEBUGSS_CLKCTRL */ +#define AM33XX_TRC_PMD_CLKSEL_SHIFT			20 +#define AM33XX_TRC_PMD_CLKSEL_MASK			(0x21 << 20) + +/* Used by CONTROL_SEC_CLK_CTRL */ +#define AM33XX_TIMER0_CLKSEL_MASK			(0x3 << 4) +#endif diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h index 8083a8cdc55..766338fe4d3 100644 --- a/arch/arm/mach-omap2/cm-regbits-34xx.h +++ b/arch/arm/mach-omap2/cm-regbits-34xx.h @@ -169,8 +169,6 @@  /* AM35XX specific CM_ICLKEN1_CORE bits */  #define AM35XX_EN_IPSS_MASK				(1 << 4)  #define AM35XX_EN_IPSS_SHIFT				4 -#define AM35XX_EN_UART4_MASK				(1 << 23) -#define AM35XX_EN_UART4_SHIFT				23  /* CM_ICLKEN2_CORE */  #define OMAP3430_EN_PKA_MASK				(1 << 4) @@ -207,6 +205,8 @@  #define OMAP3430_ST_DES2_MASK				(1 << 26)  #define OMAP3430_ST_MSPRO_SHIFT				23  #define OMAP3430_ST_MSPRO_MASK				(1 << 23) +#define AM35XX_ST_UART4_SHIFT				23 +#define AM35XX_ST_UART4_MASK				(1 << 23)  #define OMAP3430_ST_HDQ_SHIFT				22  #define OMAP3430_ST_HDQ_MASK				(1 << 22)  #define OMAP3430ES1_ST_FAC_SHIFT			8 diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c new file mode 100644 index 00000000000..13f56eafef0 --- /dev/null +++ b/arch/arm/mach-omap2/cm33xx.c @@ -0,0 +1,313 @@ +/* + * 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 <plat/common.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(s16 inst, u16 idx) +{ +	return __raw_readl(cm_base + inst + idx); +} + +/* Write into a register in a CM */ +static inline void am33xx_cm_write_reg(u32 val, s16 inst, u16 idx) +{ +	__raw_writel(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, s16 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(s16 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(s16 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(s16 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(s16 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(s16 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; + +	if (!clkctrl_offs) +		return 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); +} diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h new file mode 100644 index 00000000000..5fa0b62e1a7 --- /dev/null +++ b/arch/arm/mach-omap2/cm33xx.h @@ -0,0 +1,420 @@ +/* + * 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 <linux/delay.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/io.h> + +#include "common.h" + +#include "cm.h" +#include "cm-regbits-33xx.h" +#include "cm33xx.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) + + +extern bool am33xx_cm_is_clkdm_in_hwsup(s16 inst, u16 cdoffs); +extern void am33xx_cm_clkdm_enable_hwsup(s16 inst, u16 cdoffs); +extern void am33xx_cm_clkdm_disable_hwsup(s16 inst, u16 cdoffs); +extern void am33xx_cm_clkdm_force_sleep(s16 inst, u16 cdoffs); +extern void am33xx_cm_clkdm_force_wakeup(s16 inst, u16 cdoffs); + +#ifdef CONFIG_SOC_AM33XX +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 diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index 1a39945d9ff..1894015ff04 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c @@ -235,20 +235,6 @@ void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs)  }  /** - * omap4_cminst_clkdm_force_sleep - try to put a clockdomain into idle - * @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 idle - * No return value. - */ -void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs) -{ -	_clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, 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) diff --git a/arch/arm/mach-omap2/cminst44xx.h b/arch/arm/mach-omap2/cminst44xx.h index a018a732787..d69fdefef98 100644 --- a/arch/arm/mach-omap2/cminst44xx.h +++ b/arch/arm/mach-omap2/cminst44xx.h @@ -16,38 +16,13 @@ extern void omap4_cminst_clkdm_enable_hwsup(u8 part, s16 inst, u16 cdoffs);  extern void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs);  extern void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs);  extern void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs); -  extern int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs); - -# ifdef CONFIG_ARCH_OMAP4  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); - -# else - -static inline int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, -					u16 clkctrl_offs) -{ -	return 0; -} - -static inline void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, -				s16 cdoffs, u16 clkctrl_offs) -{ -} - -static inline void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, -				 u16 clkctrl_offs) -{ -} - -# endif -  /*   * In an ideal world, we would not export these low-level functions,   * but this will probably take some time to fix properly diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c index 1706ebcec08..14734746457 100644 --- a/arch/arm/mach-omap2/common-board-devices.c +++ b/arch/arm/mach-omap2/common-board-devices.c @@ -35,6 +35,16 @@ static struct omap2_mcspi_device_config ads7846_mcspi_config = {  	.turbo_mode	= 0,  }; +/* + * ADS7846 driver maybe request a gpio according to the value + * of pdata->get_pendown_state, but we have done this. So set + * get_pendown_state to avoid twice gpio requesting. + */ +static int omap3_get_pendown_state(void) +{ +	return !gpio_get_value(OMAP3_EVM_TS_GPIO); +} +  static struct ads7846_platform_data ads7846_config = {  	.x_max			= 0x0fff,  	.y_max			= 0x0fff, @@ -45,6 +55,7 @@ static struct ads7846_platform_data ads7846_config = {  	.debounce_rep		= 1,  	.gpio_pendown		= -EINVAL,  	.keep_vref_on		= 1, +	.get_pendown_state	= &omap3_get_pendown_state,  };  static struct spi_board_info ads7846_spi_board_info __initdata = { @@ -63,28 +74,30 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,  	struct spi_board_info *spi_bi = &ads7846_spi_board_info;  	int err; -	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; -		} -		gpio_export(gpio_pendown, 0); - -		if (gpio_debounce) -			gpio_set_debounce(gpio_pendown, gpio_debounce); +	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); +  	spi_bi->bus_num	= bus_num;  	spi_bi->irq	= gpio_to_irq(gpio_pendown);  	if (board_pdata) {  		board_pdata->gpio_pendown = gpio_pendown;  		spi_bi->platform_data = board_pdata; +		if (board_pdata->get_pendown_state) +			gpio_export(gpio_pendown, 0);  	} else {  		ads7846_config.gpio_pendown = gpio_pendown;  	} +	if (!board_pdata || (board_pdata && !board_pdata->get_pendown_state)) +		gpio_free(gpio_pendown); +  	spi_register_board_info(&ads7846_spi_board_info, 1);  }  #else diff --git a/arch/arm/mach-omap2/common-board-devices.h b/arch/arm/mach-omap2/common-board-devices.h index a0b4a42836a..4c4ef6a6166 100644 --- a/arch/arm/mach-omap2/common-board-devices.h +++ b/arch/arm/mach-omap2/common-board-devices.h @@ -4,6 +4,7 @@  #include "twl-common.h"  #define NAND_BLOCK_SIZE	SZ_128K +#define OMAP3_EVM_TS_GPIO	175  struct mtd_partition;  struct ads7846_platform_data; diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c index 8a6953a34fe..069f9725b1c 100644 --- a/arch/arm/mach-omap2/common.c +++ b/arch/arm/mach-omap2/common.c @@ -29,8 +29,6 @@  /* Global address base setup code */ -#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) -  static void __init __omap2_set_globals(struct omap_globals *omap2_globals)  {  	omap2_set_globals_tap(omap2_globals); @@ -39,8 +37,6 @@ static void __init __omap2_set_globals(struct omap_globals *omap2_globals)  	omap2_set_globals_prcm(omap2_globals);  } -#endif -  #if defined(CONFIG_SOC_OMAP2420)  static struct omap_globals omap242x_globals = { @@ -134,7 +130,9 @@ void __init ti81xx_map_io(void)  {  	omapti81xx_map_common_io();  } +#endif +#if defined(CONFIG_SOC_AM33XX)  #define AM33XX_TAP_BASE		(AM33XX_CTRL_BASE + \  				TI81XX_CONTROL_DEVICE_ID - 0x204) @@ -171,9 +169,7 @@ static struct omap_globals omap4_globals = {  void __init omap2_set_globals_443x(void)  { -	omap2_set_globals_tap(&omap4_globals); -	omap2_set_globals_control(&omap4_globals); -	omap2_set_globals_prcm(&omap4_globals); +	__omap2_set_globals(&omap4_globals);  }  void __init omap4_map_io(void) @@ -182,3 +178,27 @@ void __init omap4_map_io(void)  }  #endif +#if defined(CONFIG_SOC_OMAP5) +static struct omap_globals omap5_globals = { +	.class	= OMAP54XX_CLASS, +	.tap	= OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE), +	.ctrl	= OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE), +	.ctrl_pad	= OMAP2_L4_IO_ADDRESS(OMAP54XX_CTRL_BASE), +	.prm	= OMAP2_L4_IO_ADDRESS(OMAP54XX_PRM_BASE), +	.cm	= OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_AON_BASE), +	.cm2	= OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_BASE), +	.prcm_mpu = OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE), +}; + +void __init omap2_set_globals_5xxx(void) +{ +	omap2_set_globals_tap(&omap5_globals); +	omap2_set_globals_control(&omap5_globals); +	omap2_set_globals_prcm(&omap5_globals); +} + +void __init omap5_map_io(void) +{ +	omap5_map_common_io(); +} +#endif diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index be9dfd1abe6..1f65b1871c2 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -115,12 +115,22 @@ static inline int omap_mux_late_init(void)  }  #endif +#ifdef CONFIG_SOC_OMAP5 +extern void omap5_map_common_io(void); +#else +static inline void omap5_map_common_io(void) +{ +} +#endif +  extern void omap2_init_common_infrastructure(void);  extern struct sys_timer omap2_timer;  extern struct sys_timer omap3_timer;  extern struct sys_timer omap3_secure_timer; +extern struct sys_timer omap3_am33xx_timer;  extern struct sys_timer omap4_timer; +extern struct sys_timer omap5_timer;  void omap2420_init_early(void);  void omap2430_init_early(void); @@ -128,9 +138,12 @@ 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 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); @@ -166,12 +179,18 @@ void omap2_set_globals_242x(void);  void omap2_set_globals_243x(void);  void omap2_set_globals_3xxx(void);  void omap2_set_globals_443x(void); +void omap2_set_globals_5xxx(void);  void omap2_set_globals_ti81xx(void);  void omap2_set_globals_am33xx(void);  /* These get called from omap2_set_globals_xxxx(), do not call these */  void omap2_set_globals_tap(struct omap_globals *); +#if defined(CONFIG_SOC_HAS_OMAP2_SDRC)  void omap2_set_globals_sdrc(struct omap_globals *); +#else +static inline void omap2_set_globals_sdrc(struct omap_globals *omap2_globals) +{ } +#endif  void omap2_set_globals_control(struct omap_globals *);  void omap2_set_globals_prcm(struct omap_globals *); @@ -180,6 +199,7 @@ void omap243x_map_io(void);  void omap3_map_io(void);  void am33xx_map_io(void);  void omap4_map_io(void); +void omap5_map_io(void);  void ti81xx_map_io(void);  void omap_barriers_init(void); @@ -219,6 +239,8 @@ 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); @@ -226,10 +248,10 @@ extern void __iomem *omap4_get_l2cache_base(void);  struct device_node;  #ifdef CONFIG_OF -int __init omap_intc_of_init(struct device_node *node, +int __init intc_of_init(struct device_node *node,  			     struct device_node *parent);  #else -int __init omap_intc_of_init(struct device_node *node, +int __init intc_of_init(struct device_node *node,  			     struct device_node *parent)  {  	return 0; @@ -256,6 +278,7 @@ extern void omap_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 omap5_secondary_startup(void);  #endif  #if defined(CONFIG_SMP) && defined(CONFIG_PM) diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index 08e674bb041..3223b81e753 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c @@ -241,6 +241,49 @@ void omap3_ctrl_write_boot_mode(u8 bootmode)  #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 : +		     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- diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index a406fd045ce..b8cdc8531b6 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h @@ -21,6 +21,8 @@  #include <mach/ctrl_module_pad_core_44xx.h>  #include <mach/ctrl_module_pad_wkup_44xx.h> +#include <plat/am33xx.h> +  #ifndef __ASSEMBLY__  #define OMAP242X_CTRL_REGADDR(reg)					\  		OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE + (reg)) @@ -28,6 +30,8 @@  		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)) @@ -35,6 +39,8 @@  		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__ */  /* @@ -182,6 +188,7 @@  #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 @@ -246,6 +253,10 @@  /* 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. @@ -312,15 +323,15 @@  						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 +#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*/ +/* 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) @@ -330,21 +341,22 @@  #define AM35XX_VPFE_CCDC_VD1_INT_CLR	BIT(6)  #define AM35XX_VPFE_CCDC_VD2_INT_CLR	BIT(7) -/*AM35XX CONTROL_IP_SW_RESET bits*/ +/* 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) -/* - * CONTROL AM33XX STATUS register - */ +/* AM33XX CONTROL_STATUS register */  #define AM33XX_CONTROL_STATUS		0x040 +#define AM33XX_CONTROL_SEC_CLK_CTRL	0x1bc -/* - * CONTROL OMAP STATUS register to identify OMAP3 features - */ +/* AM33XX CONTROL_STATUS bitfields (partial) */ +#define AM33XX_CONTROL_STATUS_SYSBOOT1_SHIFT		22 +#define AM33XX_CONTROL_STATUS_SYSBOOT1_MASK		(0x3 << 22) + +/* CONTROL OMAP STATUS register to identify OMAP3 features */  #define OMAP3_CONTROL_OMAP_STATUS	0x044c  #define OMAP3_SGX_SHIFT			13 @@ -397,6 +409,8 @@ 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);  #else diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index 207bc1c7759..f2a49a48ef5 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -36,8 +36,6 @@  #include "control.h"  #include "common.h" -#ifdef CONFIG_CPU_IDLE -  /* Mach specific information to be recorded in the C-state driver_data */  struct omap3_idle_statedata {  	u32 mpu_state; @@ -77,20 +75,6 @@ static struct omap3_idle_statedata omap3_idle_data[] = {  static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd; -static int _cpuidle_allow_idle(struct powerdomain *pwrdm, -				struct clockdomain *clkdm) -{ -	clkdm_allow_idle(clkdm); -	return 0; -} - -static int _cpuidle_deny_idle(struct powerdomain *pwrdm, -				struct clockdomain *clkdm) -{ -	clkdm_deny_idle(clkdm); -	return 0; -} -  static int __omap3_enter_idle(struct cpuidle_device *dev,  				struct cpuidle_driver *drv,  				int index) @@ -108,8 +92,8 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,  	/* Deny idle for C1 */  	if (index == 0) { -		pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle); -		pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle); +		clkdm_deny_idle(mpu_pd->pwrdm_clkdms[0]); +		clkdm_deny_idle(core_pd->pwrdm_clkdms[0]);  	}  	/* @@ -131,8 +115,8 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,  	/* Re-allow idle for C1 */  	if (index == 0) { -		pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle); -		pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle); +		clkdm_allow_idle(mpu_pd->pwrdm_clkdms[0]); +		clkdm_allow_idle(core_pd->pwrdm_clkdms[0]);  	}  return_sleep_time: @@ -178,7 +162,7 @@ static int next_valid_state(struct cpuidle_device *dev,  	u32 mpu_deepest_state = PWRDM_POWER_RET;  	u32 core_deepest_state = PWRDM_POWER_RET;  	int idx; -	int next_index = -1; +	int next_index = 0; /* C1 is the default value */  	if (enable_off_mode) {  		mpu_deepest_state = PWRDM_POWER_OFF; @@ -209,12 +193,6 @@ static int next_valid_state(struct cpuidle_device *dev,  		}  	} -	/* -	 * C1 is always valid. -	 * So, no need to check for 'next_index == -1' outside -	 * this loop. -	 */ -  	return next_index;  } @@ -228,23 +206,22 @@ static int next_valid_state(struct cpuidle_device *dev,   * the device to the specified or a safer state.   */  static int omap3_enter_idle_bm(struct cpuidle_device *dev, -				struct cpuidle_driver *drv, +			       struct cpuidle_driver *drv,  			       int index)  {  	int new_state_idx; -	u32 core_next_state, per_next_state = 0, per_saved_state = 0, cam_state; +	u32 core_next_state, per_next_state = 0, per_saved_state = 0;  	struct omap3_idle_statedata *cx;  	int ret;  	/* -	 * Prevent idle completely if CAM is active. +	 * Use only C1 if CAM is active.  	 * CAM does not have wakeup capability in OMAP3.  	 */ -	cam_state = pwrdm_read_pwrst(cam_pd); -	if (cam_state == PWRDM_POWER_ON) { +	if (pwrdm_read_pwrst(cam_pd) == PWRDM_POWER_ON)  		new_state_idx = drv->safe_state_index; -		goto select_state; -	} +	else +		new_state_idx = next_valid_state(dev, drv, index);  	/*  	 * FIXME: we currently manage device-specific idle states @@ -254,24 +231,28 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,  	 *        its own code.  	 */ -	/* -	 * Prevent PER off if CORE is not in retention or off as this -	 * would disable PER wakeups completely. -	 */ -	cx = &omap3_idle_data[index]; +	/* Program PER state */ +	cx = &omap3_idle_data[new_state_idx];  	core_next_state = cx->core_state;  	per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd); -	if ((per_next_state == PWRDM_POWER_OFF) && -	    (core_next_state > PWRDM_POWER_RET)) -		per_next_state = PWRDM_POWER_RET; +	if (new_state_idx == 0) { +		/* In C1 do not allow PER state lower than CORE state */ +		if (per_next_state < core_next_state) +			per_next_state = core_next_state; +	} else { +		/* +		 * Prevent PER OFF if CORE is not in RETention or OFF as this +		 * would disable PER wakeups completely. +		 */ +		if ((per_next_state == PWRDM_POWER_OFF) && +		    (core_next_state > PWRDM_POWER_RET)) +			per_next_state = PWRDM_POWER_RET; +	}  	/* Are we changing PER target state? */  	if (per_next_state != per_saved_state)  		pwrdm_set_next_pwrst(per_pd, per_next_state); -	new_state_idx = next_valid_state(dev, drv, index); - -select_state:  	ret = omap3_enter_idle(dev, drv, new_state_idx);  	/* Restore original PER state if it was modified */ @@ -288,7 +269,7 @@ struct cpuidle_driver omap3_idle_driver = {  	.owner = 	THIS_MODULE,  	.states = {  		{ -			.enter		  = omap3_enter_idle, +			.enter		  = omap3_enter_idle_bm,  			.exit_latency	  = 2 + 2,  			.target_residency = 5,  			.flags		  = CPUIDLE_FLAG_TIME_VALID, @@ -379,9 +360,3 @@ int __init omap3_idle_init(void)  	return 0;  } -#else -int __init omap3_idle_init(void) -{ -	return 0; -} -#endif /* CONFIG_CPU_IDLE */ diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index 45e6a54d581..ee05e193fc6 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -23,8 +23,6 @@  #include "prm.h"  #include "clockdomain.h" -#ifdef CONFIG_CPU_IDLE -  /* Machine specific information */  struct omap4_idle_statedata {  	u32 cpu_state; @@ -252,9 +250,3 @@ int __init omap4_idle_init(void)  	return 0;  } -#else -int __init omap4_idle_init(void) -{ -	return 0; -} -#endif /* CONFIG_CPU_IDLE */ diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 7b4b9327e54..c00c68961bb 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -27,7 +27,6 @@  #include "iomap.h"  #include <plat/board.h> -#include <plat/mmc.h>  #include <plat/dma.h>  #include <plat/omap_hwmod.h>  #include <plat/omap_device.h> @@ -84,7 +83,7 @@ static int __init omap4_l3_init(void)  	 * To avoid code running on other OMAPs in  	 * multi-omap builds  	 */ -	if (!(cpu_is_omap44xx())) +	if (!cpu_is_omap44xx() && !soc_is_omap54xx())  		return -ENODEV;  	for (i = 0; i < L3_MODULES; i++) { @@ -603,112 +602,6 @@ static inline void omap_init_aes(void) { }  /*-------------------------------------------------------------------------*/ -#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) - -static inline void omap242x_mmc_mux(struct omap_mmc_platform_data -							*mmc_controller) -{ -	if ((mmc_controller->slots[0].switch_pin > 0) && \ -		(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 ((mmc_controller->slots[0].gpio_wp > 0) && \ -		(mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES)) -		omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp, -					OMAP_PIN_INPUT_PULLUP); - -	omap_mux_init_signal("sdmmc_cmd", 0); -	omap_mux_init_signal("sdmmc_clki", 0); -	omap_mux_init_signal("sdmmc_clko", 0); -	omap_mux_init_signal("sdmmc_dat0", 0); -	omap_mux_init_signal("sdmmc_dat_dir0", 0); -	omap_mux_init_signal("sdmmc_cmd_dir", 0); -	if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) { -		omap_mux_init_signal("sdmmc_dat1", 0); -		omap_mux_init_signal("sdmmc_dat2", 0); -		omap_mux_init_signal("sdmmc_dat3", 0); -		omap_mux_init_signal("sdmmc_dat_dir1", 0); -		omap_mux_init_signal("sdmmc_dat_dir2", 0); -		omap_mux_init_signal("sdmmc_dat_dir3", 0); -	} - -	/* -	 * 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); -	} -} - -void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data) -{ -	struct platform_device *pdev; -	struct omap_hwmod *oh; -	int id = 0; -	char *oh_name = "msdi1"; -	char *dev_name = "mmci-omap"; - -	if (!mmc_data[0]) { -		pr_err("%s fails: Incomplete platform data\n", __func__); -		return; -	} - -	omap242x_mmc_mux(mmc_data[0]); - -	oh = omap_hwmod_lookup(oh_name); -	if (!oh) { -		pr_err("Could not look up %s\n", oh_name); -		return; -	} -	pdev = omap_device_build(dev_name, id, oh, mmc_data[0], -				 sizeof(struct omap_mmc_platform_data), NULL, 0, 0); -	if (IS_ERR(pdev)) -		WARN(1, "Can'd build omap_device for %s:%s.\n", -					dev_name, oh->name); -} - -#endif - -/*-------------------------------------------------------------------------*/ - -#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE) -#define OMAP_HDQ_BASE	0x480B2000 -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, -	}, -}; -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, -}; -static inline void omap_hdq_init(void) -{ -	if (cpu_is_omap2420()) -		return; - -	platform_device_register(&omap_hdq_dev); -} -#else -static inline void omap_hdq_init(void) {} -#endif - -/*---------------------------------------------------------------------------*/ -  #if defined(CONFIG_VIDEO_OMAP2_VOUT) || \  	defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE)  #if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) @@ -753,7 +646,6 @@ static int __init omap2_init_devices(void)  		omap_init_mcspi();  	}  	omap_init_pmu(); -	omap_hdq_init();  	omap_init_sti();  	omap_init_sham();  	omap_init_aes(); @@ -772,7 +664,7 @@ static int __init omap_init_wdt(void)  	char *oh_name = "wd_timer2";  	char *dev_name = "omap_wdt"; -	if (!cpu_class_is_omap2()) +	if (!cpu_class_is_omap2() || of_have_populated_dt())  		return 0;  	oh = omap_hwmod_lookup(oh_name); diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 5fb47a14f4b..af1ed7d24a1 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -37,6 +37,7 @@  #define DISPC_CONTROL		0x0040  #define DISPC_CONTROL2		0x0238 +#define DISPC_CONTROL3		0x0848  #define DISPC_IRQSTATUS		0x0018  #define DSS_SYSCONFIG		0x10 @@ -52,6 +53,7 @@  #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  /* @@ -376,7 +378,7 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)  static void dispc_disable_outputs(void)  {  	u32 v, irq_mask = 0; -	bool lcd_en, digit_en, lcd2_en = false; +	bool lcd_en, digit_en, lcd2_en = false, lcd3_en = false;  	int i;  	struct omap_dss_dispc_dev_attr *da;  	struct omap_hwmod *oh; @@ -405,7 +407,13 @@ static void dispc_disable_outputs(void)  		lcd2_en = v & LCD_EN_MASK;  	} -	if (!(lcd_en | digit_en | lcd2_en)) +	/* 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 */  	/* @@ -426,10 +434,12 @@ static void dispc_disable_outputs(void)  	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 or FRAMEDONE2 interrupts +	 * EVSYNC_EVEN/ODD, FRAMEDONE2 or FRAMEDONE3 interrupts  	 */  	omap_hwmod_write(irq_mask, oh, DISPC_IRQSTATUS); @@ -445,12 +455,19 @@ static void dispc_disable_outputs(void)  		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 or TV interrupt\n"); +			pr_err("didn't get FRAMEDONE1/2/3 or TV interrupt\n");  			break;  		}  		mdelay(1); diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index f0f10beeffe..b9c8d2f6a81 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c @@ -135,11 +135,20 @@ static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)   */  static int _omap3_noncore_dpll_lock(struct clk *clk)  { +	const struct dpll_data *dd;  	u8 ai; -	int r; +	u8 state = 1; +	int r = 0;  	pr_debug("clock: locking DPLL %s\n", clk->name); +	dd = clk->dpll_data; +	state <<= __ffs(dd->idlest_mask); + +	/* Check if already locked */ +	if ((__raw_readl(dd->idlest_reg) & dd->idlest_mask) == state) +		goto done; +  	ai = omap3_dpll_autoidle_read(clk);  	if (ai) @@ -152,6 +161,7 @@ static int _omap3_noncore_dpll_lock(struct clk *clk)  	if (ai)  		omap3_dpll_allow_idle(clk); +done:  	return r;  } @@ -628,3 +638,17 @@ unsigned long omap3_clkoutx2_recalc(struct clk *clk)  		rate = clk->parent->rate * 2;  	return rate;  } + +/* OMAP3/4 non-CORE DPLL clkops */ + +const struct clkops clkops_omap3_noncore_dpll_ops = { +	.enable		= omap3_noncore_dpll_enable, +	.disable	= omap3_noncore_dpll_disable, +	.allow_idle	= omap3_dpll_allow_idle, +	.deny_idle	= omap3_dpll_deny_idle, +}; + +const struct clkops clkops_omap3_core_dpll_ops = { +	.allow_idle	= omap3_dpll_allow_idle, +	.deny_idle	= omap3_dpll_deny_idle, +}; diff --git a/arch/arm/mach-omap2/drm.c b/arch/arm/mach-omap2/drm.c new file mode 100644 index 00000000000..72e0f01b715 --- /dev/null +++ b/arch/arm/mach-omap2/drm.c @@ -0,0 +1,61 @@ +/* + * 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 <plat/omap_device.h> +#include <plat/omap_hwmod.h> + +#if defined(CONFIG_DRM_OMAP) || (CONFIG_DRM_OMAP_MODULE) + +static struct platform_device omap_drm_device = { +	.dev = { +		.coherent_dma_mask = DMA_BIT_MASK(32), +	}, +	.name = "omapdrm", +	.id = 0, +}; + +static int __init omap_init_drm(void) +{ +	struct omap_hwmod *oh = NULL; +	struct platform_device *pdev; + +	/* lookup and populate the DMM information, if present - OMAP4+ */ +	oh = omap_hwmod_lookup("dmm"); + +	if (oh) { +		pdev = omap_device_build(oh->name, -1, oh, NULL, 0, NULL, 0, +					false); +		WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", +			oh->name); +	} + +	return platform_device_register(&omap_drm_device); + +} + +arch_initcall(omap_init_drm); + +#endif diff --git a/arch/arm/mach-omap2/dsp.c b/arch/arm/mach-omap2/dsp.c index 88ffa1e645c..a636ebc16b3 100644 --- a/arch/arm/mach-omap2/dsp.c +++ b/arch/arm/mach-omap2/dsp.c @@ -23,6 +23,7 @@  #include <asm/memblock.h> +#include "control.h"  #include "cm2xxx_3xxx.h"  #include "prm2xxx_3xxx.h"  #ifdef CONFIG_BRIDGE_DVFS @@ -46,6 +47,9 @@ static struct omap_dsp_platform_data omap_dsp_pdata __initdata = {  	.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; diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 2286410671e..b2b5759ab0f 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -727,7 +727,8 @@ static int __init gpmc_init(void)  		ck = "gpmc_fck";  		l = OMAP34XX_GPMC_BASE;  		gpmc_irq = INT_34XX_GPMC_IRQ; -	} else if (cpu_is_omap44xx()) { +	} else if (cpu_is_omap44xx() || soc_is_omap54xx()) { +		/* Base address and irq number are same for OMAP4/5 */  		ck = "gpmc_ck";  		l = OMAP44XX_GPMC_BASE;  		gpmc_irq = OMAP44XX_IRQ_GPMC; diff --git a/arch/arm/mach-omap2/hdq1w.c b/arch/arm/mach-omap2/hdq1w.c index 297ebe03f09..cdd6dda0382 100644 --- a/arch/arm/mach-omap2/hdq1w.c +++ b/arch/arm/mach-omap2/hdq1w.c @@ -22,7 +22,13 @@   * 02110-1301 USA   */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/err.h> +#include <linux/platform_device.h> +  #include <plat/omap_hwmod.h> +#include <plat/omap_device.h>  #include <plat/hdq1w.h>  #include "common.h" @@ -70,3 +76,23 @@ int omap_hdq1w_reset(struct omap_hwmod *oh)  	return 0;  } + +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, NULL, 0, 0); +	WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", +	     devname, oh->name); + +	return 0; +} +arch_initcall(omap_init_hdq); diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index be697d4e084..a9675d8d182 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -315,7 +315,6 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,  	mmc->slots[0].caps = c->caps;  	mmc->slots[0].pm_caps = c->pm_caps;  	mmc->slots[0].internal_clock = !c->ext_clock; -	mmc->dma_mask = 0xffffffff;  	mmc->max_freq = c->max_freq;  	if (cpu_is_omap44xx())  		mmc->reg_offset = OMAP4_MMC_REG_OFFSET; diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 00486a8564f..40373db649a 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -44,12 +44,17 @@ int omap_type(void)  	if (cpu_is_omap24xx()) {  		val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS); -	} else if (cpu_is_am33xx()) { +	} else if (soc_is_am33xx()) {  		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()) { +		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; @@ -100,7 +105,7 @@ static u16 tap_prod_id;  void omap_get_die_id(struct omap_die_id *odi)  { -	if (cpu_is_omap44xx()) { +	if (cpu_is_omap44xx() || soc_is_omap54xx()) {  		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); @@ -189,7 +194,7 @@ static void __init omap3_cpuinfo(void)  		cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505";  	} else if (cpu_is_ti816x()) {  		cpu_name = "TI816X"; -	} else if (cpu_is_am335x()) { +	} else if (soc_is_am335x()) {  		cpu_name =  "AM335X";  	} else if (cpu_is_ti814x()) {  		cpu_name = "TI814X"; @@ -513,6 +518,41 @@ void __init omap4xxx_check_revision(void)  		((omap_rev() >> 12) & 0xf), ((omap_rev() >> 8) & 0xf));  } +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: +		default: +			omap_revision = OMAP5430_REV_ES1_0; +		} +		break; + +	case 0xb998: +		switch (rev) { +		case 0: +		default: +			omap_revision = OMAP5432_REV_ES1_0; +		} +		break; + +	default: +		/* Unknown default to latest silicon rev as default*/ +		omap_revision = OMAP5430_REV_ES1_0; +	} + +	pr_info("OMAP%04x ES%d.0\n", +			omap_rev() >> 16, ((omap_rev() >> 12) & 0xf)); +} +  /*   * Set up things for map_io and processor detection later on. Gets called   * pretty much first thing from board init. For multi-omap, this gets diff --git a/arch/arm/mach-omap2/include/mach/am35xx.h b/arch/arm/mach-omap2/include/mach/am35xx.h index f1e13d1ca5e..95594495fcf 100644 --- a/arch/arm/mach-omap2/include/mach/am35xx.h +++ b/arch/arm/mach-omap2/include/mach/am35xx.h @@ -36,6 +36,8 @@  #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) diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h index 2f7ac70a20d..01970824e0e 100644 --- a/arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h +++ b/arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h @@ -42,6 +42,7 @@  #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 diff --git a/arch/arm/mach-omap2/include/mach/debug-macro.S b/arch/arm/mach-omap2/include/mach/debug-macro.S index cdfc2a1f0e7..93d10de7129 100644 --- a/arch/arm/mach-omap2/include/mach/debug-macro.S +++ b/arch/arm/mach-omap2/include/mach/debug-macro.S @@ -60,18 +60,20 @@ omap_uart_lsr:	.word	0  		beq	23f			@ configure OMAP2UART3  		cmp	\rp, #OMAP3UART3	@ only on 34xx  		beq	33f			@ configure OMAP3UART3 -		cmp	\rp, #OMAP4UART3	@ only on 44xx -		beq	43f			@ configure OMAP4UART3 +		cmp	\rp, #OMAP4UART3	@ only on 44xx/54xx +		beq	43f			@ configure OMAP4/5UART3  		cmp	\rp, #OMAP3UART4	@ only on 36xx  		beq	34f			@ configure OMAP3UART4 -		cmp	\rp, #OMAP4UART4	@ only on 44xx -		beq	44f			@ configure OMAP4UART4 +		cmp	\rp, #OMAP4UART4	@ only on 44xx/54xx +		beq	44f			@ configure OMAP4/5UART4  		cmp	\rp, #TI81XXUART1	@ ti81Xx UART offsets different  		beq	81f			@ configure UART1  		cmp	\rp, #TI81XXUART2	@ ti81Xx UART offsets different  		beq	82f			@ configure UART2  		cmp	\rp, #TI81XXUART3	@ ti81Xx UART offsets different  		beq	83f			@ configure UART3 +		cmp	\rp, #AM33XXUART1	@ AM33XX UART offsets different +		beq	84f			@ configure UART1  		cmp	\rp, #ZOOM_UART		@ only on zoom2/3  		beq	95f			@ configure ZOOM_UART @@ -100,7 +102,9 @@ omap_uart_lsr:	.word	0  		b	98f  83:		mov	\rp, #UART_OFFSET(TI81XX_UART3_BASE)  		b	98f - +84:		ldr	\rp, =AM33XX_UART1_BASE +		and	\rp, \rp, #0x00ffffff +		b	97f  95:		ldr	\rp, =ZOOM_UART_BASE  		str	\rp, [\tmp, #0]		@ omap_uart_phys  		ldr	\rp, =ZOOM_UART_VIRT @@ -109,6 +113,17 @@ omap_uart_lsr:	.word	0  		str	\rp, [\tmp, #8]		@ omap_uart_lsr  		b	10b +		/* AM33XX: Store both phys and virt address for the uart */ +97:		add	\rp, \rp, #0x44000000	@ phys base +		str	\rp, [\tmp, #0]		@ omap_uart_phys +		sub	\rp, \rp, #0x44000000	@ phys base +		add	\rp, \rp, #0xf9000000	@ virt base +		str	\rp, [\tmp, #4]		@ omap_uart_virt +		mov	\rp, #(UART_LSR << OMAP_PORT_SHIFT) +		str	\rp, [\tmp, #8]		@ omap_uart_lsr + +		b	10b +  		/* Store both phys and virt address for the uart */  98:		add	\rp, \rp, #0x48000000	@ phys base  		str	\rp, [\tmp, #0]		@ omap_uart_phys diff --git a/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h b/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h index 548de90b58c..b0fd16f5c39 100644 --- a/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h +++ b/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h @@ -11,15 +11,20 @@  #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 @@ -28,4 +33,6 @@  #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/io.c b/arch/arm/mach-omap2/io.c index 8d014ba04ab..4d2d981ff5c 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -38,6 +38,7 @@  #include "powerdomain.h"  #include "clockdomain.h"  #include "common.h" +#include "clock.h"  #include "clock2xxx.h"  #include "clock3xxx.h"  #include "clock44xx.h" @@ -233,6 +234,35 @@ static struct map_desc omap44xx_io_desc[] __initdata = {  };  #endif +#ifdef	CONFIG_SOC_OMAP5 +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, +	}, +}; +#endif +  #ifdef CONFIG_SOC_OMAP2420  void __init omap242x_map_common_io(void)  { @@ -278,6 +308,12 @@ void __init omap44xx_map_common_io(void)  }  #endif +#ifdef CONFIG_SOC_OMAP5 +void __init omap5_map_common_io(void) +{ +	iotable_init(omap54xx_io_desc, ARRAY_SIZE(omap54xx_io_desc)); +} +#endif  /*   * omap2_init_reprogram_sdrc - reprogram SDRC timing parameters   * @@ -477,6 +513,20 @@ void __init ti81xx_init_late(void)  }  #endif +#ifdef CONFIG_SOC_AM33XX +void __init am33xx_init_early(void) +{ +	omap2_set_globals_am33xx(); +	omap3xxx_check_revision(); +	ti81xx_check_features(); +	omap_common_init_early(); +	am33xx_voltagedomains_init(); +	am33xx_powerdomains_init(); +	am33xx_clockdomains_init(); +	am33xx_clk_init(); +} +#endif +  #ifdef CONFIG_ARCH_OMAP4  void __init omap4430_init_early(void)  { @@ -500,6 +550,15 @@ void __init omap4430_init_late(void)  }  #endif +#ifdef CONFIG_SOC_OMAP5 +void __init omap5_init_early(void) +{ +	omap2_set_globals_5xxx(); +	omap5xxx_check_revision(); +	omap_common_init_early(); +} +#endif +  void __init omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,  				      struct omap_sdrc_params *sdrc_cs1)  { diff --git a/arch/arm/mach-omap2/iomap.h b/arch/arm/mach-omap2/iomap.h index 80b88921fab..cce2b65039f 100644 --- a/arch/arm/mach-omap2/iomap.h +++ b/arch/arm/mach-omap2/iomap.h @@ -1,6 +1,14 @@  /*   * 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 @@ -166,4 +174,23 @@  						/* 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 6038a8c84b7..bcd83db41bb 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -21,6 +21,7 @@  #include <linux/irqdomain.h>  #include <linux/of.h>  #include <linux/of_address.h> +#include <linux/of_irq.h>  #include <mach/hardware.h> @@ -258,11 +259,11 @@ asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs *regs  	omap_intc_handle_irq(base_addr, regs);  } -int __init omap_intc_of_init(struct device_node *node, +int __init intc_of_init(struct device_node *node,  			     struct device_node *parent)  {  	struct resource res; -	u32 nr_irqs = 96; +	u32 nr_irq = 96;  	if (WARN_ON(!node))  		return -ENODEV; @@ -272,15 +273,25 @@ int __init omap_intc_of_init(struct device_node *node,  		return -EINVAL;  	} -	if (of_property_read_u32(node, "ti,intc-size", &nr_irqs)) -		pr_warn("unable to get intc-size, default to %d\n", nr_irqs); +	if (of_property_read_u32(node, "ti,intc-size", &nr_irq)) +		pr_warn("unable to get intc-size, default to %d\n", nr_irq); -	omap_init_irq(res.start, nr_irqs, of_node_get(node)); +	omap_init_irq(res.start, nr_irq, of_node_get(node));  	return 0;  } -#ifdef CONFIG_ARCH_OMAP3 +static struct of_device_id irq_match[] __initdata = { +	{ .compatible = "ti,omap2-intc", .data = intc_of_init, }, +	{ } +}; + +void __init omap_intc_of_init(void) +{ +	of_irq_init(irq_match); +} + +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX)  static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)];  void omap_intc_save_context(void) diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index 19b8b677486..6875be837d9 100644 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c @@ -83,8 +83,6 @@ static int omap2_mbox_startup(struct omap_mbox *mbox)  	l = mbox_read_reg(MAILBOX_REVISION);  	pr_debug("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f)); -	omap2_mbox_enable_irq(mbox, IRQ_RX); -  	return 0;  } diff --git a/arch/arm/mach-omap2/msdi.c b/arch/arm/mach-omap2/msdi.c index ef2a6924731..fb5bc6cf377 100644 --- a/arch/arm/mach-omap2/msdi.c +++ b/arch/arm/mach-omap2/msdi.c @@ -22,11 +22,15 @@   */  #include <linux/kernel.h> +#include <linux/err.h>  #include <plat/omap_hwmod.h> +#include <plat/omap_device.h>  #include <plat/mmc.h>  #include "common.h" +#include "control.h" +#include "mux.h"  /*   * MSDI_CON_OFFSET: offset in bytes of the MSDI IP block's CON register @@ -86,3 +90,72 @@ int omap_msdi_reset(struct omap_hwmod *oh)  	return 0;  } + +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) + +static inline void omap242x_mmc_mux(struct omap_mmc_platform_data +				    *mmc_controller) +{ +	if ((mmc_controller->slots[0].switch_pin > 0) && \ +		(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 ((mmc_controller->slots[0].gpio_wp > 0) && \ +		(mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES)) +		omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp, +					OMAP_PIN_INPUT_PULLUP); + +	omap_mux_init_signal("sdmmc_cmd", 0); +	omap_mux_init_signal("sdmmc_clki", 0); +	omap_mux_init_signal("sdmmc_clko", 0); +	omap_mux_init_signal("sdmmc_dat0", 0); +	omap_mux_init_signal("sdmmc_dat_dir0", 0); +	omap_mux_init_signal("sdmmc_cmd_dir", 0); +	if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) { +		omap_mux_init_signal("sdmmc_dat1", 0); +		omap_mux_init_signal("sdmmc_dat2", 0); +		omap_mux_init_signal("sdmmc_dat3", 0); +		omap_mux_init_signal("sdmmc_dat_dir1", 0); +		omap_mux_init_signal("sdmmc_dat_dir2", 0); +		omap_mux_init_signal("sdmmc_dat_dir3", 0); +	} + +	/* +	 * 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); +	} +} + +void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data) +{ +	struct platform_device *pdev; +	struct omap_hwmod *oh; +	int id = 0; +	char *oh_name = "msdi1"; +	char *dev_name = "mmci-omap"; + +	if (!mmc_data[0]) { +		pr_err("%s fails: Incomplete platform data\n", __func__); +		return; +	} + +	omap242x_mmc_mux(mmc_data[0]); + +	oh = omap_hwmod_lookup(oh_name); +	if (!oh) { +		pr_err("Could not look up %s\n", oh_name); +		return; +	} +	pdev = omap_device_build(dev_name, id, oh, mmc_data[0], +				 sizeof(struct omap_mmc_platform_data), NULL, 0, 0); +	if (IS_ERR(pdev)) +		WARN(1, "Can'd build omap_device for %s:%s.\n", +					dev_name, oh->name); +} + +#endif diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S index 503ac777a2b..502e3135aad 100644 --- a/arch/arm/mach-omap2/omap-headsmp.S +++ b/arch/arm/mach-omap2/omap-headsmp.S @@ -19,6 +19,27 @@  #include <linux/init.h>  	__CPUINIT + +/* 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 +END(omap5_secondary_startup)  /*   * OMAP4 specific entry point for secondary CPU to jump from ROM   * code.  This routine also provides a holding flag into which diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c index 56c345b8b93..414083b427d 100644 --- a/arch/arm/mach-omap2/omap-hotplug.c +++ b/arch/arm/mach-omap2/omap-hotplug.c @@ -17,8 +17,10 @@  #include <linux/kernel.h>  #include <linux/errno.h>  #include <linux/smp.h> +#include <linux/io.h>  #include <asm/cacheflush.h> +#include <mach/omap-wakeupgen.h>  #include "common.h" @@ -35,7 +37,8 @@ int platform_cpu_kill(unsigned int cpu)   */  void __ref platform_cpu_die(unsigned int cpu)  { -	unsigned int this_cpu; +	unsigned int boot_cpu = 0; +	void __iomem *base = omap_get_wakeupgen_base();  	flush_cache_all();  	dsb(); @@ -43,16 +46,27 @@ void __ref platform_cpu_die(unsigned int cpu)  	/*  	 * we're ready for shutdown now, so do it  	 */ -	if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0) -		pr_err("Secure clear status failed\n"); +	if (omap_secure_apis_support()) { +		if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0) +			pr_err("Secure clear status failed\n"); +	} else { +		__raw_writel(0, base + OMAP_AUX_CORE_BOOT_0); +	} +  	for (;;) {  		/*  		 * Enter into low power state  		 */  		omap4_hotplug_cpu(cpu, PWRDM_POWER_OFF); -		this_cpu = smp_processor_id(); -		if (omap_read_auxcoreboot0() == this_cpu) { + +		if (omap_secure_apis_support()) +			boot_cpu = omap_read_auxcoreboot0(); +		else +			boot_cpu = +				__raw_readl(base + OMAP_AUX_CORE_BOOT_0) >> 5; + +		if (boot_cpu == smp_processor_id()) {  			/*  			 * OK, proper wakeup, we're done  			 */ diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c index ac49384d028..1be8bcb52e9 100644 --- a/arch/arm/mach-omap2/omap-iommu.c +++ b/arch/arm/mach-omap2/omap-iommu.c @@ -73,19 +73,17 @@ static struct iommu_device omap4_devices[] = {  			.da_end = 0xFFFFF000,  		},  	}, -#if defined(CONFIG_MPU_TESLA_IOMMU)  	{  		.base = OMAP4_MMU2_BASE, -		.irq = INT_44XX_DSP_MMU, +		.irq = OMAP44XX_IRQ_TESLA_MMU,  		.pdata = {  			.name = "tesla",  			.nr_tlb_entries = 32, -			.clk_name = "tesla_ick", +			.clk_name = "dsp_fck",  			.da_start = 0x0,  			.da_end = 0xFFFFF000,  		},  	}, -#endif  };  #define NR_OMAP4_IOMMU_DEVICES ARRAY_SIZE(omap4_devices)  static struct platform_device *omap4_iommu_pdev[NR_OMAP4_IOMMU_DEVICES]; diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 13670aa84e5..637a1bdf2ac 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -255,7 +255,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)  		return -ENXIO;  	} -	pwrdm_pre_transition(); +	pwrdm_pre_transition(NULL);  	/*  	 * Check MPUSS next state and save interrupt controller if needed. @@ -287,7 +287,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)  	wakeup_cpu = smp_processor_id();  	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON); -	pwrdm_post_transition(); +	pwrdm_post_transition(NULL);  	return 0;  } @@ -313,7 +313,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)  	scu_pwrst_prepare(cpu, power_state);  	/* -	 * CPU never retuns back if targetted power state is OFF mode. +	 * CPU never retuns back if targeted power state is OFF mode.  	 * CPU ONLINE follows normal CPU ONLINE ptah via  	 * omap_secondary_startup().  	 */ diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index deffbf1c962..9a35adf9123 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -26,11 +26,19 @@  #include <mach/hardware.h>  #include <mach/omap-secure.h> +#include <mach/omap-wakeupgen.h> +#include <asm/cputype.h>  #include "iomap.h"  #include "common.h"  #include "clockdomain.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; @@ -73,6 +81,8 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)  {  	static struct clockdomain *cpu1_clkdm;  	static bool booted; +	void __iomem *base = omap_get_wakeupgen_base(); +  	/*  	 * Set synchronisation state between this boot processor  	 * and the secondary one @@ -85,7 +95,11 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)  	 * the AuxCoreBoot1 register is updated with cpu state  	 * A barrier is added to ensure that write buffer is drained  	 */ -	omap_modify_auxcoreboot0(0x200, 0xfffffdff); +	if (omap_secure_apis_support()) +		omap_modify_auxcoreboot0(0x200, 0xfffffdff); +	else +		__raw_writel(0x20, base + OMAP_AUX_CORE_BOOT_0); +  	flush_cache_all();  	smp_wmb(); @@ -111,7 +125,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)  		booted = true;  	} -	gic_raise_softirq(cpumask_of(cpu), 1); +	gic_raise_softirq(cpumask_of(cpu), 0);  	/*  	 * Now the secondary core is starting up let it run its @@ -124,13 +138,19 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)  static void __init wakeup_secondary(void)  { +	void __iomem *base = omap_get_wakeupgen_base();  	/*  	 * 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  	 */ -	omap_auxcoreboot_addr(virt_to_phys(omap_secondary_startup)); +	if (omap_secure_apis_support()) +		omap_auxcoreboot_addr(virt_to_phys(omap_secondary_startup)); +	else +		__raw_writel(virt_to_phys(omap5_secondary_startup), +						base + OMAP_AUX_CORE_BOOT_1); +  	smp_wmb();  	/* @@ -147,16 +167,21 @@ static void __init wakeup_secondary(void)   */  void __init smp_init_cpus(void)  { -	unsigned int i, ncores; +	unsigned int i = 0, ncores = 1, cpu_id; -	/* -	 * Currently we can't call ioremap here because -	 * SoC detection won't work until after init_early. -	 */ -	scu_base =  OMAP2_L4_IO_ADDRESS(OMAP44XX_SCU_BASE); -	BUG_ON(!scu_base); - -	ncores = scu_get_core_count(scu_base); +	/* Use ARM cpuid check here, as SoC detection will not work so early */ +	cpu_id = read_cpuid(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(OMAP44XX_SCU_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) { @@ -178,6 +203,7 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)  	 * Initialise the SCU and wake up the secondary core using  	 * wakeup_secondary().  	 */ -	scu_enable(scu_base); +	if (scu_base) +		scu_enable(scu_base);  	wakeup_secondary();  } diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index d811c779035..05fdebfaa19 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -33,18 +33,23 @@  #include "omap4-sar-layout.h"  #include "common.h" -#define NR_REG_BANKS		4 -#define MAX_IRQS		128 +#define MAX_NR_REG_BANKS	5 +#define MAX_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_SPINLOCK(wakeupgen_lock);  static unsigned int irq_target_cpu[NR_IRQS]; +static unsigned int irq_banks = MAX_NR_REG_BANKS; +static unsigned int max_irqs = MAX_IRQS; +static unsigned int omap_secure_apis;  /*   * Static helper functions. @@ -146,13 +151,13 @@ static void wakeupgen_unmask(struct irq_data *d)  }  #ifdef CONFIG_HOTPLUG_CPU -static DEFINE_PER_CPU(u32 [NR_REG_BANKS], irqmasks); +static DEFINE_PER_CPU(u32 [MAX_NR_REG_BANKS], irqmasks);  static void _wakeupgen_save_masks(unsigned int cpu)  {  	u8 i; -	for (i = 0; i < NR_REG_BANKS; i++) +	for (i = 0; i < irq_banks; i++)  		per_cpu(irqmasks, cpu)[i] = wakeupgen_readl(i, cpu);  } @@ -160,7 +165,7 @@ static void _wakeupgen_restore_masks(unsigned int cpu)  {  	u8 i; -	for (i = 0; i < NR_REG_BANKS; i++) +	for (i = 0; i < irq_banks; i++)  		wakeupgen_writel(per_cpu(irqmasks, cpu)[i], i, cpu);  } @@ -168,7 +173,7 @@ static void _wakeupgen_set_all(unsigned int cpu, unsigned int reg)  {  	u8 i; -	for (i = 0; i < NR_REG_BANKS; i++) +	for (i = 0; i < irq_banks; i++)  		wakeupgen_writel(reg, i, cpu);  } @@ -196,25 +201,14 @@ static void wakeupgen_irqmask_all(unsigned int cpu, unsigned int set)  #endif  #ifdef CONFIG_CPU_PM -/* - * 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) +static inline void omap4_irq_save_context(void)  {  	u32 i, val;  	if (omap_rev() == OMAP4430_REV_ES1_0)  		return; -	if (!sar_base) -		sar_base = omap4_get_sar_ram_base(); - -	for (i = 0; i < NR_REG_BANKS; i++) { +	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); @@ -254,6 +248,53 @@ static void irq_save_context(void)  	val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET);  	val |= SAR_BACKUP_STATUS_WAKEUPGEN;  	__raw_writel(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 = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); +	__raw_writel(val, sar_base + OMAP5_AUXCOREBOOT0_OFFSET); +	val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); +	__raw_writel(val, sar_base + OMAP5_AUXCOREBOOT1_OFFSET); + +	/* Set the Backup Bit Mask status */ +	val = __raw_readl(sar_base + OMAP5_SAR_BACKUP_STATUS_OFFSET); +	val |= SAR_BACKUP_STATUS_WAKEUPGEN; +	__raw_writel(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();  }  /* @@ -262,9 +303,14 @@ static void irq_save_context(void)  static void irq_sar_clear(void)  {  	u32 val; -	val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET); +	u32 offset = SAR_BACKUP_STATUS_OFFSET; + +	if (soc_is_omap54xx()) +		offset = OMAP5_SAR_BACKUP_STATUS_OFFSET; + +	val = __raw_readl(sar_base + offset);  	val &= ~SAR_BACKUP_STATUS_WAKEUPGEN; -	__raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET); +	__raw_writel(val, sar_base + offset);  }  /* @@ -336,13 +382,25 @@ static struct notifier_block irq_notifier_block = {  static void __init irq_pm_init(void)  { -	cpu_pm_register_notifier(&irq_notifier_block); +	/* 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.   */ @@ -358,12 +416,18 @@ int __init omap_wakeupgen_init(void)  	}  	/* Static mapping, never released */ -	wakeupgen_base = ioremap(OMAP44XX_WKUPGEN_BASE, SZ_4K); +	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; +	} +  	/* Clear all IRQ bitmasks at wakeupGen level */ -	for (i = 0; i < NR_REG_BANKS; i++) { +	for (i = 0; i < irq_banks; i++) {  		wakeupgen_writel(0, i, CPU0_ID);  		wakeupgen_writel(0, i, CPU1_ID);  	} @@ -382,7 +446,7 @@ int __init omap_wakeupgen_init(void)  	 */  	/* Associate all the IRQs to boot CPU like GIC init does. */ -	for (i = 0; i < NR_IRQS; i++) +	for (i = 0; i < max_irqs; i++)  		irq_target_cpu[i] = boot_cpu;  	irq_hotplug_init(); diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index a8161e5f320..c29dee998a7 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -21,6 +21,8 @@  #include <asm/hardware/cache-l2x0.h>  #include <asm/mach/map.h>  #include <asm/memblock.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h>  #include <plat/irqs.h>  #include <plat/sram.h> @@ -210,6 +212,18 @@ static int __init omap4_sar_ram_init(void)  }  early_initcall(omap4_sar_ram_init); +static struct of_device_id irq_match[] __initdata = { +	{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, +	{ .compatible = "arm,cortex-a15-gic", .data = gic_of_init, }, +	{ } +}; + +void __init omap_gic_of_init(void) +{ +	omap_wakeupgen_init(); +	of_irq_init(irq_match); +} +  #if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)  static int omap4_twl6030_hsmmc_late_init(struct device *dev)  { diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h index fe5b545ad44..e170fe803b0 100644 --- a/arch/arm/mach-omap2/omap4-sar-layout.h +++ b/arch/arm/mach-omap2/omap4-sar-layout.h @@ -12,7 +12,7 @@  #define OMAP_ARCH_OMAP4_SAR_LAYOUT_H  /* - * SAR BANK offsets from base address OMAP44XX_SAR_RAM_BASE + * SAR BANK offsets from base address OMAP44XX/54XX_SAR_RAM_BASE   */  #define SAR_BANK1_OFFSET		0x0000  #define SAR_BANK2_OFFSET		0x1000 @@ -47,4 +47,14 @@  #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 + 0x8d4) +#define OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU0	(SAR_BANK3_OFFSET + 0x8e8) +#define OMAP5_WAKEUPGENENB_OFFSET_CPU1		(SAR_BANK3_OFFSET + 0x8fc) +#define OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU1	(SAR_BANK3_OFFSET + 0x910) +#define OMAP5_AUXCOREBOOT0_OFFSET		(SAR_BANK3_OFFSET + 0x924) +#define OMAP5_AUXCOREBOOT1_OFFSET		(SAR_BANK3_OFFSET + 0x928) +#define OMAP5_AMBA_IF_MODE_OFFSET		(SAR_BANK3_OFFSET + 0x92c) +#define OMAP5_SAR_BACKUP_STATUS_OFFSET		(SAR_BANK3_OFFSET + 0x800) +  #endif diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 2d710f50fca..6ca8e519968 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -153,6 +153,7 @@  #include "prm44xx.h"  #include "prminst44xx.h"  #include "mux.h" +#include "pm.h"  /* Maximum microseconds to wait for OMAP module to softreset */  #define MAX_MODULE_SOFTRESET_WAIT	10000 @@ -166,12 +167,40 @@   */  #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); +}; + +/* 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 @@ -186,6 +215,9 @@ static struct omap_hwmod_link *linkspace;   */  static unsigned short free_ls, max_ls, ls_supp; +/* inited: set to true once the hwmod code is initialized */ +static bool inited; +  /* Private functions */  /** @@ -388,6 +420,49 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v)  }  /** + * _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) @@ -771,23 +846,19 @@ static void _disable_optional_clocks(struct omap_hwmod *oh)  }  /** - * _enable_module - enable CLKCTRL modulemode on OMAP4 + * _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 _enable_module(struct omap_hwmod *oh) +static void _omap4_enable_module(struct omap_hwmod *oh)  { -	/* The module mode does not exist prior OMAP4 */ -	if (cpu_is_omap24xx() || cpu_is_omap34xx()) -		return; -  	if (!oh->clkdm || !oh->prcm.omap4.modulemode)  		return; -	pr_debug("omap_hwmod: %s: _enable_module: %d\n", -		 oh->name, oh->prcm.omap4.modulemode); +	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, @@ -807,10 +878,7 @@ static void _enable_module(struct omap_hwmod *oh)   */  static int _omap4_wait_target_disable(struct omap_hwmod *oh)  { -	if (!cpu_is_omap44xx()) -		return 0; - -	if (!oh) +	if (!oh || !oh->clkdm)  		return -EINVAL;  	if (oh->_int_flags & _HWMOD_NO_MPU_PORT) @@ -1301,24 +1369,20 @@ static struct omap_hwmod *_lookup(const char *name)  	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 clkdm_name does not exist or if the lookup failed. + * Return -EINVAL if the clkdm_name lookup failed.   */  static int _init_clkdm(struct omap_hwmod *oh)  { -	if (cpu_is_omap24xx() || cpu_is_omap34xx()) +	if (!oh->clkdm_name)  		return 0; -	if (!oh->clkdm_name) { -		pr_warning("omap_hwmod: %s: no clkdm_name\n", oh->name); -		return -EINVAL; -	} -  	oh->clkdm = clkdm_lookup(oh->clkdm_name);  	if (!oh->clkdm) {  		pr_warning("omap_hwmod: %s: could not associate to clkdm %s\n", @@ -1354,7 +1418,8 @@ static int _init_clocks(struct omap_hwmod *oh, void *data)  	ret |= _init_main_clk(oh);  	ret |= _init_interface_clks(oh);  	ret |= _init_opt_clks(oh); -	ret |= _init_clkdm(oh); +	if (soc_ops.init_clkdm) +		ret |= soc_ops.init_clkdm(oh);  	if (!ret)  		oh->_state = _HWMOD_STATE_CLKS_INITED; @@ -1365,53 +1430,6 @@ static int _init_clocks(struct omap_hwmod *oh, void *data)  }  /** - * _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 _wait_target_ready(struct omap_hwmod *oh) -{ -	struct omap_hwmod_ocp_if *os; -	int ret; - -	if (!oh) -		return -EINVAL; - -	if (oh->flags & HWMOD_NO_IDLEST) -		return 0; - -	os = _find_mpu_rt_port(oh); -	if (!os) -		return 0; - -	/* XXX check module SIDLEMODE */ - -	/* XXX check clock enable states */ - -	if (cpu_is_omap24xx() || cpu_is_omap34xx()) { -		ret = omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs, -						 oh->prcm.omap2.idlest_reg_id, -						 oh->prcm.omap2.idlest_idle_bit); -	} else if (cpu_is_omap44xx()) { -		if (!oh->clkdm) -			return -EINVAL; - -		ret = omap4_cminst_wait_module_ready(oh->clkdm->prcm_partition, -						     oh->clkdm->cm_inst, -						     oh->clkdm->clkdm_offs, -						     oh->prcm.omap4.clkctrl_offs); -	} else { -		BUG(); -	}; - -	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 @@ -1447,32 +1465,31 @@ static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name,   * @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. + * 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; -	u8 ret; +	u8 ret = -EINVAL;  	if (!oh)  		return -EINVAL; +	if (!soc_ops.assert_hardreset) +		return -ENOSYS; +  	ret = _lookup_hardreset(oh, name, &ohri);  	if (IS_ERR_VALUE(ret))  		return ret; -	if (cpu_is_omap24xx() || cpu_is_omap34xx()) -		return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs, -						  ohri.rst_shift); -	else if (cpu_is_omap44xx()) -		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); -	else -		return -EINVAL; +	ret = soc_ops.assert_hardreset(oh, &ohri); + +	return ret;  }  /** @@ -1481,38 +1498,29 @@ static int _assert_hardreset(struct omap_hwmod *oh, const char *name)   * @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. + * 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; +	int ret = -EINVAL;  	if (!oh)  		return -EINVAL; +	if (!soc_ops.deassert_hardreset) +		return -ENOSYS; +  	ret = _lookup_hardreset(oh, name, &ohri);  	if (IS_ERR_VALUE(ret))  		return ret; -	if (cpu_is_omap24xx() || cpu_is_omap34xx()) { -		ret = omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs, -						   ohri.rst_shift, -						   ohri.st_shift); -	} else if (cpu_is_omap44xx()) { -		if (ohri.st_shift) -			pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n", -			       oh->name, name); -		ret = omap4_prminst_deassert_hardreset(ohri.rst_shift, -				  oh->clkdm->pwrdm.ptr->prcm_partition, -				  oh->clkdm->pwrdm.ptr->prcm_offs, -				  oh->prcm.omap4.rstctrl_offs); -	} else { -		return -EINVAL; -	} - +	ret = soc_ops.deassert_hardreset(oh, &ohri);  	if (ret == -EBUSY)  		pr_warning("omap_hwmod: %s: failed to hardreset\n", oh->name); @@ -1525,31 +1533,28 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)   * @oh: struct omap_hwmod *   * @name: name of the reset line to look up and read   * - * Return the state of the reset line. + * 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; -	u8 ret; +	u8 ret = -EINVAL;  	if (!oh)  		return -EINVAL; +	if (!soc_ops.is_hardreset_asserted) +		return -ENOSYS; +  	ret = _lookup_hardreset(oh, name, &ohri);  	if (IS_ERR_VALUE(ret))  		return ret; -	if (cpu_is_omap24xx() || cpu_is_omap34xx()) { -		return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs, -						       ohri.st_shift); -	} else if (cpu_is_omap44xx()) { -		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); -	} else { -		return -EINVAL; -	} +	return soc_ops.is_hardreset_asserted(oh, &ohri);  }  /** @@ -1587,10 +1592,6 @@ static int _omap4_disable_module(struct omap_hwmod *oh)  {  	int v; -	/* The module mode does not exist prior OMAP4 */ -	if (!cpu_is_omap44xx()) -		return -EINVAL; -  	if (!oh->clkdm || !oh->prcm.omap4.modulemode)  		return -EINVAL; @@ -1714,11 +1715,17 @@ dis_opt_clks:   * 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.  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. + * 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)  { @@ -1740,6 +1747,8 @@ static int _reset(struct omap_hwmod *oh)  		}  	} +	_set_dmadisable(oh); +  	/*  	 * OCP_SYSCONFIG bits need to be reprogrammed after a  	 * softreset.  The _enable() function should be split to avoid @@ -1754,6 +1763,32 @@ static int _reset(struct omap_hwmod *oh)  }  /** + * _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); +} + +/**   * _enable - enable an omap_hwmod   * @oh: struct omap_hwmod *   * @@ -1809,8 +1844,10 @@ static int _enable(struct omap_hwmod *oh)  	/* Mux pins for device runtime if populated */  	if (oh->mux && (!oh->mux->enabled ||  			((oh->_state == _HWMOD_STATE_IDLE) && -			 oh->mux->pads_dynamic))) +			 oh->mux->pads_dynamic))) {  		omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED); +		_reconfigure_io_chain(); +	}  	_add_initiator_dep(oh, mpu_oh); @@ -1830,9 +1867,11 @@ static int _enable(struct omap_hwmod *oh)  	}  	_enable_clocks(oh); -	_enable_module(oh); +	if (soc_ops.enable_module) +		soc_ops.enable_module(oh); -	r = _wait_target_ready(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, @@ -1886,7 +1925,8 @@ static int _idle(struct omap_hwmod *oh)  		_idle_sysc(oh);  	_del_initiator_dep(oh, mpu_oh); -	_omap4_disable_module(oh); +	if (soc_ops.disable_module) +		soc_ops.disable_module(oh);  	/*  	 * The module must be in idle mode before disabling any parents @@ -1899,8 +1939,10 @@ static int _idle(struct omap_hwmod *oh)  		clkdm_hwmod_disable(oh->clkdm, oh);  	/* Mux pins for device idle if populated */ -	if (oh->mux && oh->mux->pads_dynamic) +	if (oh->mux && oh->mux->pads_dynamic) {  		omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE); +		_reconfigure_io_chain(); +	}  	oh->_state = _HWMOD_STATE_IDLE; @@ -1991,7 +2033,8 @@ static int _shutdown(struct omap_hwmod *oh)  	if (oh->_state == _HWMOD_STATE_ENABLED) {  		_del_initiator_dep(oh, mpu_oh);  		/* XXX what about the other system initiators here? dma, dsp */ -		_omap4_disable_module(oh); +		if (soc_ops.disable_module) +			soc_ops.disable_module(oh);  		_disable_clocks(oh);  		if (oh->clkdm)  			clkdm_hwmod_disable(oh->clkdm, oh); @@ -2447,6 +2490,194 @@ static int __init _alloc_linkspace(struct omap_hwmod_ocp_if **ois)  	return 0;  } +/* Static functions intended only for use in soc_ops field function pointers */ + +/** + * _omap2_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 _omap2_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 omap2_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 || !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 omap4_cminst_wait_module_ready(oh->clkdm->prcm_partition, +					      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); +} +  /* Public functions */  u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs) @@ -2579,12 +2810,18 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),   *   * 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 0. + * 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; @@ -3417,3 +3654,47 @@ int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int 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() || cpu_is_omap34xx()) { +		soc_ops.wait_target_ready = _omap2_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_omap44xx() || soc_is_omap54xx()) { +		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; +	} 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_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index a7640d1b215..50cfab61b0e 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -192,6 +192,11 @@ 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_irq_info omap2420_mcbsp1_irqs[] = {  	{ .name = "tx", .irq = 59 }, @@ -214,6 +219,8 @@ static struct omap_hwmod omap2420_mcbsp1_hwmod = {  			.idlest_idle_bit = OMAP24XX_ST_MCBSP1_SHIFT,  		},  	}, +	.opt_clks	= mcbsp_opt_clks, +	.opt_clks_cnt	= ARRAY_SIZE(mcbsp_opt_clks),  };  /* mcbsp2 */ @@ -238,6 +245,8 @@ static struct omap_hwmod omap2420_mcbsp2_hwmod = {  			.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 = { @@ -585,5 +594,6 @@ static struct omap_hwmod_ocp_if *omap2420_hwmod_ocp_ifs[] __initdata = {  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 index 4d726498123..58b5bc196d3 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -296,6 +296,11 @@ static struct omap_hwmod_class omap2430_mcbsp_hwmod_class = {  	.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_irq_info omap2430_mcbsp1_irqs[] = {  	{ .name = "tx",		.irq = 59 }, @@ -320,6 +325,8 @@ static struct omap_hwmod omap2430_mcbsp1_hwmod = {  			.idlest_idle_bit = OMAP24XX_ST_MCBSP1_SHIFT,  		},  	}, +	.opt_clks	= mcbsp_opt_clks, +	.opt_clks_cnt	= ARRAY_SIZE(mcbsp_opt_clks),  };  /* mcbsp2 */ @@ -345,6 +352,8 @@ static struct omap_hwmod omap2430_mcbsp2_hwmod = {  			.idlest_idle_bit = OMAP24XX_ST_MCBSP2_SHIFT,  		},  	}, +	.opt_clks	= mcbsp_opt_clks, +	.opt_clks_cnt	= ARRAY_SIZE(mcbsp_opt_clks),  };  /* mcbsp3 */ @@ -370,6 +379,8 @@ static struct omap_hwmod omap2430_mcbsp3_hwmod = {  			.idlest_idle_bit = OMAP2430_ST_MCBSP3_SHIFT,  		},  	}, +	.opt_clks	= mcbsp_opt_clks, +	.opt_clks_cnt	= ARRAY_SIZE(mcbsp_opt_clks),  };  /* mcbsp4 */ @@ -401,6 +412,8 @@ static struct omap_hwmod omap2430_mcbsp4_hwmod = {  			.idlest_idle_bit = OMAP2430_ST_MCBSP4_SHIFT,  		},  	}, +	.opt_clks	= mcbsp_opt_clks, +	.opt_clks_cnt	= ARRAY_SIZE(mcbsp_opt_clks),  };  /* mcbsp5 */ @@ -432,6 +445,8 @@ static struct omap_hwmod omap2430_mcbsp5_hwmod = {  			.idlest_idle_bit = OMAP2430_ST_MCBSP5_SHIFT,  		},  	}, +	.opt_clks	= mcbsp_opt_clks, +	.opt_clks_cnt	= ARRAY_SIZE(mcbsp_opt_clks),  };  /* MMC/SD/SDIO common */ @@ -938,5 +953,6 @@ static struct omap_hwmod_ocp_if *omap2430_hwmod_ocp_ifs[] __initdata = {  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_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c index 83eafd96eca..afad69c6ba6 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c @@ -68,7 +68,6 @@ static struct omap_hwmod_class_sysconfig omap2xxx_timer_sysc = {  struct omap_hwmod_class omap2xxx_timer_hwmod_class = {  	.name	= "timer",  	.sysc	= &omap2xxx_timer_sysc, -	.rev	= OMAP_TIMER_IP_VERSION_1,  };  /* @@ -257,7 +256,6 @@ struct omap_hwmod omap2xxx_timer2_hwmod = {  			.idlest_idle_bit = OMAP24XX_ST_GPT2_SHIFT,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  	.class		= &omap2xxx_timer_hwmod_class,  }; @@ -276,7 +274,6 @@ struct omap_hwmod omap2xxx_timer3_hwmod = {  			.idlest_idle_bit = OMAP24XX_ST_GPT3_SHIFT,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  	.class		= &omap2xxx_timer_hwmod_class,  }; @@ -295,7 +292,6 @@ struct omap_hwmod omap2xxx_timer4_hwmod = {  			.idlest_idle_bit = OMAP24XX_ST_GPT4_SHIFT,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  	.class		= &omap2xxx_timer_hwmod_class,  }; @@ -314,7 +310,6 @@ struct omap_hwmod omap2xxx_timer5_hwmod = {  			.idlest_idle_bit = OMAP24XX_ST_GPT5_SHIFT,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  	.class		= &omap2xxx_timer_hwmod_class,  }; @@ -333,7 +328,6 @@ struct omap_hwmod omap2xxx_timer6_hwmod = {  			.idlest_idle_bit = OMAP24XX_ST_GPT6_SHIFT,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  	.class		= &omap2xxx_timer_hwmod_class,  }; @@ -352,7 +346,6 @@ struct omap_hwmod omap2xxx_timer7_hwmod = {  			.idlest_idle_bit = OMAP24XX_ST_GPT7_SHIFT,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  	.class		= &omap2xxx_timer_hwmod_class,  }; @@ -371,7 +364,6 @@ struct omap_hwmod omap2xxx_timer8_hwmod = {  			.idlest_idle_bit = OMAP24XX_ST_GPT8_SHIFT,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  	.class		= &omap2xxx_timer_hwmod_class,  }; diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index b26d3c9bca1..c9e38200216 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -14,6 +14,8 @@   *   * XXX these should be marked initdata for multi-OMAP kernels   */ +#include <linux/power/smartreflex.h> +  #include <plat/omap_hwmod.h>  #include <mach/irqs.h>  #include <plat/cpu.h> @@ -29,8 +31,6 @@  #include <plat/dmtimer.h>  #include "omap_hwmod_common_data.h" - -#include "smartreflex.h"  #include "prm-regbits-34xx.h"  #include "cm-regbits-34xx.h"  #include "wd_timer.h" @@ -129,7 +129,6 @@ static struct omap_hwmod_class_sysconfig omap3xxx_timer_1ms_sysc = {  static struct omap_hwmod_class omap3xxx_timer_1ms_hwmod_class = {  	.name = "timer",  	.sysc = &omap3xxx_timer_1ms_sysc, -	.rev = OMAP_TIMER_IP_VERSION_1,  };  static struct omap_hwmod_class_sysconfig omap3xxx_timer_sysc = { @@ -145,12 +144,11 @@ static struct omap_hwmod_class_sysconfig omap3xxx_timer_sysc = {  static struct omap_hwmod_class omap3xxx_timer_hwmod_class = {  	.name = "timer",  	.sysc = &omap3xxx_timer_sysc, -	.rev =  OMAP_TIMER_IP_VERSION_1,  };  /* secure timers dev attribute */  static struct omap_timer_capability_dev_attr capability_secure_dev_attr = { -	.timer_capability	= OMAP_TIMER_SECURE, +	.timer_capability	= OMAP_TIMER_ALWON | OMAP_TIMER_SECURE,  };  /* always-on timers dev attribute */ @@ -195,7 +193,6 @@ static struct omap_hwmod omap3xxx_timer2_hwmod = {  			.idlest_idle_bit = OMAP3430_ST_GPT2_SHIFT,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  	.class		= &omap3xxx_timer_1ms_hwmod_class,  }; @@ -213,7 +210,6 @@ static struct omap_hwmod omap3xxx_timer3_hwmod = {  			.idlest_idle_bit = OMAP3430_ST_GPT3_SHIFT,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  	.class		= &omap3xxx_timer_hwmod_class,  }; @@ -231,7 +227,6 @@ static struct omap_hwmod omap3xxx_timer4_hwmod = {  			.idlest_idle_bit = OMAP3430_ST_GPT4_SHIFT,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  	.class		= &omap3xxx_timer_hwmod_class,  }; @@ -249,7 +244,6 @@ static struct omap_hwmod omap3xxx_timer5_hwmod = {  			.idlest_idle_bit = OMAP3430_ST_GPT5_SHIFT,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  	.class		= &omap3xxx_timer_hwmod_class,  }; @@ -267,7 +261,6 @@ static struct omap_hwmod omap3xxx_timer6_hwmod = {  			.idlest_idle_bit = OMAP3430_ST_GPT6_SHIFT,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  	.class		= &omap3xxx_timer_hwmod_class,  }; @@ -285,7 +278,6 @@ static struct omap_hwmod omap3xxx_timer7_hwmod = {  			.idlest_idle_bit = OMAP3430_ST_GPT7_SHIFT,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  	.class		= &omap3xxx_timer_hwmod_class,  }; @@ -527,11 +519,27 @@ static struct omap_hwmod omap36xx_uart4_hwmod = {  static struct omap_hwmod_irq_info am35xx_uart4_mpu_irqs[] = {  	{ .irq = INT_35XX_UART4_IRQ, }, +	{ .irq = -1 }  };  static struct omap_hwmod_dma_info am35xx_uart4_sdma_reqs[] = {  	{ .name = "rx", .dma_req = AM35XX_DMA_UART4_RX, },  	{ .name = "tx", .dma_req = AM35XX_DMA_UART4_TX, }, +	{ .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 = { @@ -543,11 +551,14 @@ static struct omap_hwmod am35xx_uart4_hwmod = {  		.omap2 = {  			.module_offs = CORE_MOD,  			.prcm_reg_id = 1, -			.module_bit = OMAP3430_EN_UART4_SHIFT, +			.module_bit = AM35XX_EN_UART4_SHIFT,  			.idlest_reg_id = 1, -			.idlest_idle_bit = OMAP3430_EN_UART4_SHIFT, +			.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,  }; @@ -1074,6 +1085,17 @@ static struct omap_hwmod_class omap3xxx_mcbsp_hwmod_class = {  	.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 }, @@ -1097,6 +1119,8 @@ static struct omap_hwmod omap3xxx_mcbsp1_hwmod = {  			.idlest_idle_bit = OMAP3430_ST_MCBSP1_SHIFT,  		},  	}, +	.opt_clks	= mcbsp15_opt_clks, +	.opt_clks_cnt	= ARRAY_SIZE(mcbsp15_opt_clks),  };  /* mcbsp2 */ @@ -1126,6 +1150,8 @@ static struct omap_hwmod omap3xxx_mcbsp2_hwmod = {  			.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,  }; @@ -1156,6 +1182,8 @@ static struct omap_hwmod omap3xxx_mcbsp3_hwmod = {  			.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,  }; @@ -1188,6 +1216,8 @@ static struct omap_hwmod omap3xxx_mcbsp4_hwmod = {  			.idlest_idle_bit = OMAP3430_ST_MCBSP4_SHIFT,  		},  	}, +	.opt_clks	= mcbsp234_opt_clks, +	.opt_clks_cnt	= ARRAY_SIZE(mcbsp234_opt_clks),  };  /* mcbsp5 */ @@ -1219,6 +1249,8 @@ static struct omap_hwmod omap3xxx_mcbsp5_hwmod = {  			.idlest_idle_bit = OMAP3430_ST_MCBSP5_SHIFT,  		},  	}, +	.opt_clks	= mcbsp15_opt_clks, +	.opt_clks_cnt	= ARRAY_SIZE(mcbsp15_opt_clks),  };  /* 'mcbsp sidetone' class */ @@ -1325,7 +1357,7 @@ static struct omap_hwmod_irq_info omap3_smartreflex_mpu_irqs[] = {  };  static struct omap_hwmod omap34xx_sr1_hwmod = { -	.name		= "sr1", +	.name		= "smartreflex_mpu_iva",  	.class		= &omap34xx_smartreflex_hwmod_class,  	.main_clk	= "sr1_fck",  	.prcm		= { @@ -1343,7 +1375,7 @@ static struct omap_hwmod omap34xx_sr1_hwmod = {  };  static struct omap_hwmod omap36xx_sr1_hwmod = { -	.name		= "sr1", +	.name		= "smartreflex_mpu_iva",  	.class		= &omap36xx_smartreflex_hwmod_class,  	.main_clk	= "sr1_fck",  	.prcm		= { @@ -1370,7 +1402,7 @@ static struct omap_hwmod_irq_info omap3_smartreflex_core_irqs[] = {  };  static struct omap_hwmod omap34xx_sr2_hwmod = { -	.name		= "sr2", +	.name		= "smartreflex_core",  	.class		= &omap34xx_smartreflex_hwmod_class,  	.main_clk	= "sr2_fck",  	.prcm		= { @@ -1388,7 +1420,7 @@ static struct omap_hwmod omap34xx_sr2_hwmod = {  };  static struct omap_hwmod omap36xx_sr2_hwmod = { -	.name		= "sr2", +	.name		= "smartreflex_core",  	.class		= &omap36xx_smartreflex_hwmod_class,  	.main_clk	= "sr2_fck",  	.prcm		= { @@ -1638,25 +1670,20 @@ static struct omap_hwmod omap3xxx_usbhsotg_hwmod = {  /* usb_otg_hs */  static struct omap_hwmod_irq_info am35xx_usbhsotg_mpu_irqs[] = { -  	{ .name = "mc", .irq = 71 },  	{ .irq = -1 }  };  static struct omap_hwmod_class am35xx_usbotg_class = {  	.name = "am35xx_usbotg", -	.sysc = NULL,  };  static struct omap_hwmod am35xx_usbhsotg_hwmod = {  	.name		= "am35x_otg_hs",  	.mpu_irqs	= am35xx_usbhsotg_mpu_irqs, -	.main_clk	= NULL, -	.prcm = { -		.omap2 = { -		}, -	}, +	.main_clk	= "hsotgusb_fck",  	.class		= &am35xx_usbotg_class, +	.flags		= HWMOD_NO_IDLEST,  };  /* MMC/SD/SDIO common */ @@ -2097,9 +2124,10 @@ static struct omap_hwmod_ocp_if omap3xxx_usbhsotg__l3 = {  static struct omap_hwmod_ocp_if am35xx_usbhsotg__l3 = {  	.master		= &am35xx_usbhsotg_hwmod,  	.slave		= &omap3xxx_l3_main_hwmod, -	.clk		= "core_l3_ick", +	.clk		= "hsotgusb_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, @@ -2243,6 +2271,7 @@ static struct omap_hwmod_addr_space am35xx_uart4_addr_space[] = {  		.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 = { @@ -2393,7 +2422,7 @@ static struct omap_hwmod_addr_space am35xx_usbhsotg_addrs[] = {  static struct omap_hwmod_ocp_if am35xx_l4_core__usbhsotg = {  	.master		= &omap3xxx_l4_core_hwmod,  	.slave		= &am35xx_usbhsotg_hwmod, -	.clk		= "l4_ick", +	.clk		= "hsotgusb_ick",  	.addr		= am35xx_usbhsotg_addrs,  	.user		= OCP_USER_MPU,  }; @@ -3138,6 +3167,107 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__counter_32k = {  	.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 = INT_35XX_EMAC_C0_RXTHRESH_IRQ }, +	{ .name = "rx_pulse",	.irq = INT_35XX_EMAC_C0_RX_PULSE_IRQ }, +	{ .name = "tx_pulse",	.irq = INT_35XX_EMAC_C0_TX_PULSE_IRQ }, +	{ .name = "misc_pulse",	.irq = INT_35XX_EMAC_C0_MISC_PULSE_IRQ }, +	{ .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, +	.flags		= HWMOD_NO_IDLEST, +}; + +/* 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_hwmod_ocp_ifs[] __initdata = {  	&omap3xxx_l3_main__l4_core,  	&omap3xxx_l3_main__l4_per, @@ -3266,6 +3396,10 @@ static struct omap_hwmod_ocp_if *am35xx_hwmod_ocp_ifs[] __initdata = {  	&omap3xxx_l4_core__usb_tll_hs,  	&omap3xxx_l4_core__es3plus_mmc1,  	&omap3xxx_l4_core__es3plus_mmc2, +	&am35xx_mdio__l3, +	&am35xx_l4_core__mdio, +	&am35xx_emac__l3, +	&am35xx_l4_core__emac,  	NULL  }; @@ -3283,6 +3417,8 @@ int __init omap3xxx_hwmod_init(void)  	struct omap_hwmod_ocp_if **h = 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) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index b7bcba5221b..242aee498ce 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -19,6 +19,7 @@   */  #include <linux/io.h> +#include <linux/power/smartreflex.h>  #include <plat/omap_hwmod.h>  #include <plat/cpu.h> @@ -32,8 +33,6 @@  #include <plat/common.h>  #include "omap_hwmod_common_data.h" - -#include "smartreflex.h"  #include "cm1_44xx.h"  #include "cm2_44xx.h"  #include "prm44xx.h" @@ -2544,14 +2543,12 @@ static struct omap_hwmod omap44xx_prcm_mpu_hwmod = {  static struct omap_hwmod omap44xx_cm_core_aon_hwmod = {  	.name		= "cm_core_aon",  	.class		= &omap44xx_prcm_hwmod_class, -	.clkdm_name	= "cm_clkdm",  };  /* cm_core */  static struct omap_hwmod omap44xx_cm_core_hwmod = {  	.name		= "cm_core",  	.class		= &omap44xx_prcm_hwmod_class, -	.clkdm_name	= "cm_clkdm",  };  /* prm */ @@ -2568,7 +2565,6 @@ static struct omap_hwmod_rst_info omap44xx_prm_resets[] = {  static struct omap_hwmod omap44xx_prm_hwmod = {  	.name		= "prm",  	.class		= &omap44xx_prcm_hwmod_class, -	.clkdm_name	= "prm_clkdm",  	.mpu_irqs	= omap44xx_prm_irqs,  	.rst_lines	= omap44xx_prm_resets,  	.rst_lines_cnt	= ARRAY_SIZE(omap44xx_prm_resets), @@ -2947,7 +2943,6 @@ static struct omap_hwmod omap44xx_timer2_hwmod = {  			.modulemode   = MODULEMODE_SWCTRL,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  };  /* timer3 */ @@ -2969,7 +2964,6 @@ static struct omap_hwmod omap44xx_timer3_hwmod = {  			.modulemode   = MODULEMODE_SWCTRL,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  };  /* timer4 */ @@ -2991,7 +2985,6 @@ static struct omap_hwmod omap44xx_timer4_hwmod = {  			.modulemode   = MODULEMODE_SWCTRL,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  };  /* timer5 */ @@ -3013,7 +3006,6 @@ static struct omap_hwmod omap44xx_timer5_hwmod = {  			.modulemode   = MODULEMODE_SWCTRL,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  };  /* timer6 */ @@ -3036,7 +3028,6 @@ static struct omap_hwmod omap44xx_timer6_hwmod = {  			.modulemode   = MODULEMODE_SWCTRL,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  };  /* timer7 */ @@ -3058,7 +3049,6 @@ static struct omap_hwmod omap44xx_timer7_hwmod = {  			.modulemode   = MODULEMODE_SWCTRL,  		},  	}, -	.dev_attr	= &capability_alwon_dev_attr,  };  /* timer8 */ @@ -6148,6 +6138,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {  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_common_data.c b/arch/arm/mach-omap2/omap_hwmod_common_data.c index 51e5418899f..9f1ccdc8cc8 100644 --- a/arch/arm/mach-omap2/omap_hwmod_common_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_common_data.c @@ -47,6 +47,16 @@ 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 = { diff --git a/arch/arm/mach-omap2/omap_l3_noc.h b/arch/arm/mach-omap2/omap_l3_noc.h index 90b50984cd2..a6ce34dc481 100644 --- a/arch/arm/mach-omap2/omap_l3_noc.h +++ b/arch/arm/mach-omap2/omap_l3_noc.h @@ -51,7 +51,9 @@ static u32 l3_targ_inst_clk1[] = {  	0x200, /* DMM2 */  	0x300, /* ABE */  	0x400, /* L4CFG */ -	0x600  /* CLK2 PWR DISC */ +	0x600,  /* CLK2 PWR DISC */ +	0x0,	/* Host CLK1 */ +	0x900	/* L4 Wakeup */  };  static u32 l3_targ_inst_clk2[] = { @@ -72,11 +74,16 @@ static u32 l3_targ_inst_clk2[] = {  	0xE00, /* missing in TRM corresponds to AES2*/  	0xC00, /* L4 PER3 */  	0xA00, /* L4 PER1*/ -	0xB00 /* L4 PER2*/ +	0xB00, /* L4 PER2*/ +	0x0, /* HOST CLK2 */ +	0x1800, /* CAL */ +	0x1700 /* LLI */  };  static u32 l3_targ_inst_clk3[] = { -	0x0100	/* EMUSS */ +	0x0100	/* EMUSS */, +	0x0300, /* DEBUGSS_CT_TBR */ +	0x0 /* HOST CLK3 */  };  static struct l3_masters_data { @@ -110,13 +117,15 @@ static struct l3_masters_data {  	{ 0xC8, "USBHOSTFS"}  }; -static char *l3_targ_inst_name[L3_MODULES][18] = { +static char *l3_targ_inst_name[L3_MODULES][21] = {  	{  		"DMM1",  		"DMM2",  		"ABE",  		"L4CFG",  		"CLK2 PWR DISC", +		"HOST CLK1", +		"L4 WAKEUP"  	},  	{  		"CORTEX M3" , @@ -137,9 +146,14 @@ static char *l3_targ_inst_name[L3_MODULES][18] = {  		"L4 PER3",  		"L4 PER1",  		"L4 PER2", +		"HOST CLK2", +		"CAL", +		"LLI"  	},  	{  		"EMUSS", +		"DEBUG SOURCE", +		"HOST CLK3"  	},  }; diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c index de6d4645174..d8f6dbf45d1 100644 --- a/arch/arm/mach-omap2/opp.c +++ b/arch/arm/mach-omap2/opp.c @@ -53,7 +53,7 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def,  	omap_table_init = 1;  	/* Lets now register with OPP library */ -	for (i = 0; i < opp_def_size; i++) { +	for (i = 0; i < opp_def_size; i++, opp_def++) {  		struct omap_hwmod *oh;  		struct device *dev; @@ -86,7 +86,6 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def,  					__func__, opp_def->freq,  					opp_def->hwmod_name, i, r);  		} -		opp_def++;  	}  	return 0; diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 78564895e91..686137d164d 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -15,12 +15,25 @@  #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_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); -extern int omap3_idle_init(void); -extern int omap4_idle_init(void);  extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused);  extern int (*omap_pm_suspend)(void); @@ -88,7 +101,7 @@ extern void enable_omap3630_toggle_l2_on_restore(void);  static inline void enable_omap3630_toggle_l2_on_restore(void) { }  #endif		/* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ -#ifdef CONFIG_OMAP_SMARTREFLEX +#ifdef CONFIG_POWER_AVS_OMAP  extern int omap_devinit_smartreflex(void);  extern void omap_enable_smartreflex_on_init(void);  #else diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 3a595e89972..e4fc88c65db 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -70,34 +70,6 @@ void (*omap3_do_wfi_sram)(void);  static struct powerdomain *mpu_pwrdm, *neon_pwrdm;  static struct powerdomain *core_pwrdm, *per_pwrdm; -static struct powerdomain *cam_pwrdm; - -static void omap3_enable_io_chain(void) -{ -	int timeout = 0; - -	omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, -				   PM_WKEN); -	/* Do a readback to assure write has been done */ -	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); - -	while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & -		 OMAP3430_ST_IO_CHAIN_MASK)) { -		timeout++; -		if (timeout > 1000) { -			pr_err("Wake up daisy chain activation failed.\n"); -			return; -		} -		omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, -					   WKUP_MOD, PM_WKEN); -	} -} - -static void omap3_disable_io_chain(void) -{ -	omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, -				     PM_WKEN); -}  static void omap3_core_save_context(void)  { @@ -299,24 +271,22 @@ void omap_sram_idle(void)  	/* 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); -	if (omap3_has_io_wakeup() && -	    (per_next_state < PWRDM_POWER_ON || -	     core_next_state < PWRDM_POWER_ON)) { -		omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); -		if (omap3_has_io_chain_ctrl()) -			omap3_enable_io_chain(); -	} -	pwrdm_pre_transition(); +	if (mpu_next_state < PWRDM_POWER_ON) { +		pwrdm_pre_transition(mpu_pwrdm); +		pwrdm_pre_transition(neon_pwrdm); +	}  	/* PER */  	if (per_next_state < PWRDM_POWER_ON) { +		pwrdm_pre_transition(per_pwrdm);  		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) { +		pwrdm_pre_transition(core_pwrdm);  		if (core_next_state == PWRDM_POWER_OFF) {  			omap3_core_save_context();  			omap3_cm_save_context(); @@ -369,26 +339,20 @@ void omap_sram_idle(void)  			omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,  					       OMAP3430_GR_MOD,  					       OMAP3_PRM_VOLTCTRL_OFFSET); +		pwrdm_post_transition(core_pwrdm);  	}  	omap3_intc_resume_idle(); -	pwrdm_post_transition(); -  	/* PER */ -	if (per_next_state < PWRDM_POWER_ON) +	if (per_next_state < PWRDM_POWER_ON) {  		omap2_gpio_resume_after_idle(); - -	/* Disable IO-PAD and IO-CHAIN wakeup */ -	if (omap3_has_io_wakeup() && -	    (per_next_state < PWRDM_POWER_ON || -	     core_next_state < PWRDM_POWER_ON)) { -		omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, -					     PM_WKEN); -		if (omap3_has_io_chain_ctrl()) -			omap3_disable_io_chain(); +		pwrdm_post_transition(per_pwrdm);  	} -	clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); +	if (mpu_next_state < PWRDM_POWER_ON) { +		pwrdm_post_transition(mpu_pwrdm); +		pwrdm_post_transition(neon_pwrdm); +	}  }  static void omap3_pm_idle(void) @@ -581,10 +545,13 @@ static void __init prcm_setup_regs(void)  			  OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);  	/* Don't attach IVA interrupts */ -	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); +	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); @@ -598,7 +565,9 @@ static void __init prcm_setup_regs(void)  	/* Clear any pending PRCM interrupts */  	omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); -	omap3_iva_idle(); +	if (omap3_has_iva()) +		omap3_iva_idle(); +  	omap3_d2d_idle();  } @@ -749,7 +718,6 @@ int __init omap3_pm_init(void)  	neon_pwrdm = pwrdm_lookup("neon_pwrdm");  	per_pwrdm = pwrdm_lookup("per_pwrdm");  	core_pwrdm = pwrdm_lookup("core_pwrdm"); -	cam_pwrdm = pwrdm_lookup("cam_pwrdm");  	neon_clkdm = clkdm_lookup("neon_clkdm");  	mpu_clkdm = clkdm_lookup("mpu_clkdm"); diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 96114901b93..69b36e185e9 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -526,7 +526,8 @@ int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)   *   * 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)  { @@ -535,6 +536,9 @@ int pwrdm_read_pwrst(struct powerdomain *pwrdm)  	if (!pwrdm)  		return -EINVAL; +	if (pwrdm->pwrsts == PWRSTS_ON) +		return PWRDM_POWER_ON; +  	if (arch_pwrdm && arch_pwrdm->pwrdm_read_pwrst)  		ret = arch_pwrdm->pwrdm_read_pwrst(pwrdm); @@ -981,15 +985,23 @@ int pwrdm_state_switch(struct powerdomain *pwrdm)  	return ret;  } -int pwrdm_pre_transition(void) +int pwrdm_pre_transition(struct powerdomain *pwrdm)  { -	pwrdm_for_each(_pwrdm_pre_transition_cb, NULL); +	if (pwrdm) +		_pwrdm_pre_transition_cb(pwrdm, NULL); +	else +		pwrdm_for_each(_pwrdm_pre_transition_cb, NULL); +  	return 0;  } -int pwrdm_post_transition(void) +int pwrdm_post_transition(struct powerdomain *pwrdm)  { -	pwrdm_for_each(_pwrdm_post_transition_cb, NULL); +	if (pwrdm) +		_pwrdm_post_transition_cb(pwrdm, NULL); +	else +		pwrdm_for_each(_pwrdm_post_transition_cb, NULL); +  	return 0;  } diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h index 8f88d65c46e..baee90608d1 100644 --- a/arch/arm/mach-omap2/powerdomain.h +++ b/arch/arm/mach-omap2/powerdomain.h @@ -67,9 +67,9 @@  /*   * Maximum number of clockdomains that can be associated with a powerdomain. - * CORE powerdomain on OMAP4 is the worst case + * PER powerdomain on AM33XX is the worst case   */ -#define PWRDM_MAX_CLKDMS	9 +#define PWRDM_MAX_CLKDMS	11  /* XXX A completely arbitrary number. What is reasonable here? */  #define PWRDM_TRANSITION_BAILOUT 100000 @@ -92,6 +92,15 @@ struct powerdomain;   * @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: @@ -121,6 +130,14 @@ struct powerdomain {  	unsigned ret_logic_off_counter;  	unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS]; +	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]; @@ -213,8 +230,8 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);  int pwrdm_wait_transition(struct powerdomain *pwrdm);  int pwrdm_state_switch(struct powerdomain *pwrdm); -int pwrdm_pre_transition(void); -int pwrdm_post_transition(void); +int pwrdm_pre_transition(struct powerdomain *pwrdm); +int pwrdm_post_transition(struct powerdomain *pwrdm);  int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);  int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);  bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm); @@ -222,10 +239,12 @@ bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);  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 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 */ diff --git a/arch/arm/mach-omap2/powerdomain33xx.c b/arch/arm/mach-omap2/powerdomain33xx.c new file mode 100644 index 00000000000..67c5663899b --- /dev/null +++ b/arch/arm/mach-omap2/powerdomain33xx.c @@ -0,0 +1,229 @@ +/* + * AM33XX Powerdomain control + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * Derived from mach-omap2/powerdomain44xx.c written 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 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/io.h> +#include <linux/errno.h> +#include <linux/delay.h> + +#include <plat/prcm.h> + +#include "powerdomain.h" +#include "prm33xx.h" +#include "prm-regbits-33xx.h" + + +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; +} + +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, +}; 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/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c index fb0a0a6869d..bb883e46307 100644 --- a/arch/arm/mach-omap2/powerdomains3xxx_data.c +++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c @@ -71,6 +71,22 @@ static struct powerdomain mpu_3xxx_pwrdm = {  	.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 @@ -120,6 +136,23 @@ static struct powerdomain core_3xxx_es3_1_pwrdm = {  	.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, @@ -135,6 +168,21 @@ static struct powerdomain dss_pwrdm = {  	.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 @@ -156,6 +204,21 @@ static struct powerdomain sgx_pwrdm = {  	.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, @@ -186,6 +249,21 @@ static struct powerdomain per_pwrdm = {  	.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, @@ -200,6 +278,14 @@ static struct powerdomain neon_pwrdm = {  	.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, @@ -293,6 +379,22 @@ static struct powerdomain *powerdomains_omap3430es3_1plus[] __initdata = {  	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 +}; +  void __init omap3xxx_powerdomains_init(void)  {  	unsigned int rev; @@ -301,21 +403,34 @@ void __init omap3xxx_powerdomains_init(void)  		return;  	pwrdm_register_platform_funcs(&omap3_pwrdm_operations); -	pwrdm_register_pwrdms(powerdomains_omap3430_common);  	rev = omap_rev(); -	if (rev == OMAP3430_REV_ES1_0) -		pwrdm_register_pwrdms(powerdomains_omap3430es1); -	else if (rev == OMAP3430_REV_ES2_0 || rev == OMAP3430_REV_ES2_1 || -		 rev == OMAP3430_REV_ES3_0 || rev == OMAP3630_REV_ES1_0) -		pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0); -	else if (rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2 || -		 rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1 || -		 rev == OMAP3630_REV_ES1_1 || rev == OMAP3630_REV_ES1_2) -		pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus); -	else -		WARN(1, "OMAP3 powerdomain init: unknown chip type\n"); +	if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) { +		pwrdm_register_pwrdms(powerdomains_am35x); +	} 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/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index 6da3ba483ad..e5f0503a68b 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h @@ -203,8 +203,8 @@  #define OMAP3430_EN_MMC2_SHIFT				25  #define OMAP3430_EN_MMC1_MASK				(1 << 24)  #define OMAP3430_EN_MMC1_SHIFT				24 -#define OMAP3430_EN_UART4_MASK				(1 << 23) -#define OMAP3430_EN_UART4_SHIFT				23 +#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_MASK				(1 << 20) @@ -410,13 +410,21 @@   */  #define MAX_MODULE_HARDRESET_WAIT		10000 +/* + * 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__  extern void __iomem *prm_base;  extern void __iomem *cm_base;  extern void __iomem *cm2_base;  extern void __iomem *prcm_mpu_base; -#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_OMAP5) +#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)  extern void omap_prm_base_init(void);  extern void omap_cm_base_init(void);  #else diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c index 480f40a5ee4..053e24ed3c4 100644 --- a/arch/arm/mach-omap2/prcm.c +++ b/arch/arm/mach-omap2/prcm.c @@ -35,6 +35,7 @@  #include "prm2xxx_3xxx.h"  #include "prm44xx.h"  #include "prminst44xx.h" +#include "cminst44xx.h"  #include "prm-regbits-24xx.h"  #include "prm-regbits-44xx.h"  #include "control.h" @@ -159,8 +160,30 @@ void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals)  	if (omap2_globals->prcm_mpu)  		prcm_mpu_base = omap2_globals->prcm_mpu; -	if (cpu_is_omap44xx()) { +	if (cpu_is_omap44xx() || soc_is_omap54xx()) {  		omap_prm_base_init();  		omap_cm_base_init();  	}  } + +/* + * Stubbed functions so that common files continue to build when + * custom builds are used + * XXX These are temporary and should be removed at the earliest possible + * opportunity + */ +int __weak omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, +					u16 clkctrl_offs) +{ +	return 0; +} + +void __weak omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, +				s16 cdoffs, u16 clkctrl_offs) +{ +} + +void __weak omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, +				 u16 clkctrl_offs) +{ +} 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..0221b5c20e8 --- /dev/null +++ b/arch/arm/mach-omap2/prm-regbits-33xx.h @@ -0,0 +1,357 @@ +/* + * 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" + +/* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_MPU_SETUP */ +#define AM33XX_ABBOFF_ACT_EXPORT_SHIFT			1 +#define AM33XX_ABBOFF_ACT_EXPORT_MASK			(1 << 1) + +/* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_MPU_SETUP */ +#define AM33XX_ABBOFF_SLEEP_EXPORT_SHIFT		2 +#define AM33XX_ABBOFF_SLEEP_EXPORT_MASK			(1 << 2) + +/* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_MPU_SETUP */ +#define AM33XX_AIPOFF_SHIFT				8 +#define AM33XX_AIPOFF_MASK				(1 << 8) + +/* Used by PM_WKUP_PWRSTST */ +#define AM33XX_DEBUGSS_MEM_STATEST_SHIFT		17 +#define AM33XX_DEBUGSS_MEM_STATEST_MASK			(0x3 << 17) + +/* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_MPU_SETUP */ +#define AM33XX_DISABLE_RTA_EXPORT_SHIFT			0 +#define AM33XX_DISABLE_RTA_EXPORT_MASK			(1 << 0) + +/* Used by PRM_IRQENABLE_M3, PRM_IRQENABLE_MPU */ +#define AM33XX_DPLL_CORE_RECAL_EN_SHIFT			12 +#define AM33XX_DPLL_CORE_RECAL_EN_MASK			(1 << 12) + +/* Used by PRM_IRQSTATUS_M3, PRM_IRQSTATUS_MPU */ +#define AM33XX_DPLL_CORE_RECAL_ST_SHIFT			12 +#define AM33XX_DPLL_CORE_RECAL_ST_MASK			(1 << 12) + +/* Used by PRM_IRQENABLE_M3, PRM_IRQENABLE_MPU */ +#define AM33XX_DPLL_DDR_RECAL_EN_SHIFT			14 +#define AM33XX_DPLL_DDR_RECAL_EN_MASK			(1 << 14) + +/* Used by PRM_IRQSTATUS_M3, PRM_IRQSTATUS_MPU */ +#define AM33XX_DPLL_DDR_RECAL_ST_SHIFT			14 +#define AM33XX_DPLL_DDR_RECAL_ST_MASK			(1 << 14) + +/* Used by PRM_IRQENABLE_M3, PRM_IRQENABLE_MPU */ +#define AM33XX_DPLL_DISP_RECAL_EN_SHIFT			15 +#define AM33XX_DPLL_DISP_RECAL_EN_MASK			(1 << 15) + +/* Used by PRM_IRQSTATUS_M3, PRM_IRQSTATUS_MPU */ +#define AM33XX_DPLL_DISP_RECAL_ST_SHIFT			13 +#define AM33XX_DPLL_DISP_RECAL_ST_MASK			(1 << 13) + +/* Used by PRM_IRQENABLE_M3, PRM_IRQENABLE_MPU */ +#define AM33XX_DPLL_MPU_RECAL_EN_SHIFT			11 +#define AM33XX_DPLL_MPU_RECAL_EN_MASK			(1 << 11) + +/* Used by PRM_IRQSTATUS_M3, PRM_IRQSTATUS_MPU */ +#define AM33XX_DPLL_MPU_RECAL_ST_SHIFT			11 +#define AM33XX_DPLL_MPU_RECAL_ST_MASK			(1 << 11) + +/* Used by PRM_IRQENABLE_M3, PRM_IRQENABLE_MPU */ +#define AM33XX_DPLL_PER_RECAL_EN_SHIFT			13 +#define AM33XX_DPLL_PER_RECAL_EN_MASK			(1 << 13) + +/* Used by PRM_IRQSTATUS_M3, PRM_IRQSTATUS_MPU */ +#define AM33XX_DPLL_PER_RECAL_ST_SHIFT			15 +#define AM33XX_DPLL_PER_RECAL_ST_MASK			(1 << 15) + +/* Used by RM_WKUP_RSTST */ +#define AM33XX_EMULATION_M3_RST_SHIFT			6 +#define AM33XX_EMULATION_M3_RST_MASK			(1 << 6) + +/* Used by RM_MPU_RSTST */ +#define AM33XX_EMULATION_MPU_RST_SHIFT			5 +#define AM33XX_EMULATION_MPU_RST_MASK			(1 << 5) + +/* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_MPU_SETUP */ +#define AM33XX_ENFUNC1_EXPORT_SHIFT			3 +#define AM33XX_ENFUNC1_EXPORT_MASK			(1 << 3) + +/* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_MPU_SETUP */ +#define AM33XX_ENFUNC3_EXPORT_SHIFT			5 +#define AM33XX_ENFUNC3_EXPORT_MASK			(1 << 5) + +/* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_MPU_SETUP */ +#define AM33XX_ENFUNC4_SHIFT				6 +#define AM33XX_ENFUNC4_MASK				(1 << 6) + +/* Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_MPU_SETUP */ +#define AM33XX_ENFUNC5_SHIFT				7 +#define AM33XX_ENFUNC5_MASK				(1 << 7) + +/* Used by PRM_RSTST */ +#define AM33XX_EXTERNAL_WARM_RST_SHIFT			5 +#define AM33XX_EXTERNAL_WARM_RST_MASK			(1 << 5) + +/* Used by PRM_IRQENABLE_M3, PRM_IRQENABLE_MPU */ +#define AM33XX_FORCEWKUP_EN_SHIFT			10 +#define AM33XX_FORCEWKUP_EN_MASK			(1 << 10) + +/* Used by PRM_IRQSTATUS_M3, PRM_IRQSTATUS_MPU */ +#define AM33XX_FORCEWKUP_ST_SHIFT			10 +#define AM33XX_FORCEWKUP_ST_MASK			(1 << 10) + +/* Used by PM_GFX_PWRSTCTRL */ +#define AM33XX_GFX_MEM_ONSTATE_SHIFT			17 +#define AM33XX_GFX_MEM_ONSTATE_MASK			(0x3 << 17) + +/* Used by PM_GFX_PWRSTCTRL */ +#define AM33XX_GFX_MEM_RETSTATE_SHIFT			6 +#define AM33XX_GFX_MEM_RETSTATE_MASK			(1 << 6) + +/* Used by PM_GFX_PWRSTST */ +#define AM33XX_GFX_MEM_STATEST_SHIFT			4 +#define AM33XX_GFX_MEM_STATEST_MASK			(0x3 << 4) + +/* Used by RM_GFX_RSTCTRL, RM_GFX_RSTST */ +#define AM33XX_GFX_RST_SHIFT				0 +#define AM33XX_GFX_RST_MASK				(1 << 0) + +/* Used by PRM_RSTST */ +#define AM33XX_GLOBAL_COLD_RST_SHIFT			0 +#define AM33XX_GLOBAL_COLD_RST_MASK			(1 << 0) + +/* Used by PRM_RSTST */ +#define AM33XX_GLOBAL_WARM_SW_RST_SHIFT			1 +#define AM33XX_GLOBAL_WARM_SW_RST_MASK			(1 << 1) + +/* Used by RM_WKUP_RSTST */ +#define AM33XX_ICECRUSHER_M3_RST_SHIFT			7 +#define AM33XX_ICECRUSHER_M3_RST_MASK			(1 << 7) + +/* Used by RM_MPU_RSTST */ +#define AM33XX_ICECRUSHER_MPU_RST_SHIFT			6 +#define AM33XX_ICECRUSHER_MPU_RST_MASK			(1 << 6) + +/* Used by PRM_RSTST */ +#define AM33XX_ICEPICK_RST_SHIFT			9 +#define AM33XX_ICEPICK_RST_MASK				(1 << 9) + +/* Used by RM_PER_RSTCTRL */ +#define AM33XX_PRUSS_LRST_SHIFT				1 +#define AM33XX_PRUSS_LRST_MASK				(1 << 1) + +/* Used by PM_PER_PWRSTCTRL */ +#define AM33XX_PRUSS_MEM_ONSTATE_SHIFT			5 +#define AM33XX_PRUSS_MEM_ONSTATE_MASK			(0x3 << 5) + +/* Used by PM_PER_PWRSTCTRL */ +#define AM33XX_PRUSS_MEM_RETSTATE_SHIFT			7 +#define AM33XX_PRUSS_MEM_RETSTATE_MASK			(1 << 7) + +/* Used by PM_PER_PWRSTST */ +#define AM33XX_PRUSS_MEM_STATEST_SHIFT			23 +#define AM33XX_PRUSS_MEM_STATEST_MASK			(0x3 << 23) + +/* + * Used by PM_GFX_PWRSTST, PM_CEFUSE_PWRSTST, PM_PER_PWRSTST, PM_MPU_PWRSTST, + * PM_WKUP_PWRSTST, PM_RTC_PWRSTST + */ +#define AM33XX_INTRANSITION_SHIFT			20 +#define AM33XX_INTRANSITION_MASK			(1 << 20) + +/* Used by PM_CEFUSE_PWRSTST */ +#define AM33XX_LASTPOWERSTATEENTERED_SHIFT		24 +#define AM33XX_LASTPOWERSTATEENTERED_MASK		(0x3 << 24) + +/* Used by PM_GFX_PWRSTCTRL, PM_MPU_PWRSTCTRL, PM_RTC_PWRSTCTRL */ +#define AM33XX_LOGICRETSTATE_SHIFT			2 +#define AM33XX_LOGICRETSTATE_MASK			(1 << 2) + +/* Renamed from LOGICRETSTATE Used by PM_PER_PWRSTCTRL, PM_WKUP_PWRSTCTRL */ +#define AM33XX_LOGICRETSTATE_3_3_SHIFT			3 +#define AM33XX_LOGICRETSTATE_3_3_MASK			(1 << 3) + +/* + * Used by PM_GFX_PWRSTST, PM_CEFUSE_PWRSTST, PM_PER_PWRSTST, PM_MPU_PWRSTST, + * PM_WKUP_PWRSTST, PM_RTC_PWRSTST + */ +#define AM33XX_LOGICSTATEST_SHIFT			2 +#define AM33XX_LOGICSTATEST_MASK			(1 << 2) + +/* + * Used by PM_GFX_PWRSTCTRL, PM_CEFUSE_PWRSTCTRL, PM_PER_PWRSTCTRL, + * PM_MPU_PWRSTCTRL, PM_WKUP_PWRSTCTRL, PM_RTC_PWRSTCTRL + */ +#define AM33XX_LOWPOWERSTATECHANGE_SHIFT		4 +#define AM33XX_LOWPOWERSTATECHANGE_MASK			(1 << 4) + +/* Used by PM_MPU_PWRSTCTRL */ +#define AM33XX_MPU_L1_ONSTATE_SHIFT			18 +#define AM33XX_MPU_L1_ONSTATE_MASK			(0x3 << 18) + +/* Used by PM_MPU_PWRSTCTRL */ +#define AM33XX_MPU_L1_RETSTATE_SHIFT			22 +#define AM33XX_MPU_L1_RETSTATE_MASK			(1 << 22) + +/* Used by PM_MPU_PWRSTST */ +#define AM33XX_MPU_L1_STATEST_SHIFT			6 +#define AM33XX_MPU_L1_STATEST_MASK			(0x3 << 6) + +/* Used by PM_MPU_PWRSTCTRL */ +#define AM33XX_MPU_L2_ONSTATE_SHIFT			20 +#define AM33XX_MPU_L2_ONSTATE_MASK			(0x3 << 20) + +/* Used by PM_MPU_PWRSTCTRL */ +#define AM33XX_MPU_L2_RETSTATE_SHIFT			23 +#define AM33XX_MPU_L2_RETSTATE_MASK			(1 << 23) + +/* Used by PM_MPU_PWRSTST */ +#define AM33XX_MPU_L2_STATEST_SHIFT			8 +#define AM33XX_MPU_L2_STATEST_MASK			(0x3 << 8) + +/* Used by PM_MPU_PWRSTCTRL */ +#define AM33XX_MPU_RAM_ONSTATE_SHIFT			16 +#define AM33XX_MPU_RAM_ONSTATE_MASK			(0x3 << 16) + +/* Used by PM_MPU_PWRSTCTRL */ +#define AM33XX_MPU_RAM_RETSTATE_SHIFT			24 +#define AM33XX_MPU_RAM_RETSTATE_MASK			(1 << 24) + +/* Used by PM_MPU_PWRSTST */ +#define AM33XX_MPU_RAM_STATEST_SHIFT			4 +#define AM33XX_MPU_RAM_STATEST_MASK			(0x3 << 4) + +/* Used by PRM_RSTST */ +#define AM33XX_MPU_SECURITY_VIOL_RST_SHIFT		2 +#define AM33XX_MPU_SECURITY_VIOL_RST_MASK		(1 << 2) + +/* Used by PRM_SRAM_COUNT */ +#define AM33XX_PCHARGECNT_VALUE_SHIFT			0 +#define AM33XX_PCHARGECNT_VALUE_MASK			(0x3f << 0) + +/* Used by RM_PER_RSTCTRL */ +#define AM33XX_PCI_LRST_SHIFT				0 +#define AM33XX_PCI_LRST_MASK				(1 << 0) + +/* Renamed from PCI_LRST Used by RM_PER_RSTST */ +#define AM33XX_PCI_LRST_5_5_SHIFT			5 +#define AM33XX_PCI_LRST_5_5_MASK			(1 << 5) + +/* Used by PM_PER_PWRSTCTRL */ +#define AM33XX_PER_MEM_ONSTATE_SHIFT			25 +#define AM33XX_PER_MEM_ONSTATE_MASK			(0x3 << 25) + +/* Used by PM_PER_PWRSTCTRL */ +#define AM33XX_PER_MEM_RETSTATE_SHIFT			29 +#define AM33XX_PER_MEM_RETSTATE_MASK			(1 << 29) + +/* Used by PM_PER_PWRSTST */ +#define AM33XX_PER_MEM_STATEST_SHIFT			17 +#define AM33XX_PER_MEM_STATEST_MASK			(0x3 << 17) + +/* + * Used by PM_GFX_PWRSTCTRL, PM_CEFUSE_PWRSTCTRL, PM_PER_PWRSTCTRL, + * PM_MPU_PWRSTCTRL + */ +#define AM33XX_POWERSTATE_SHIFT				0 +#define AM33XX_POWERSTATE_MASK				(0x3 << 0) + +/* Used by PM_GFX_PWRSTST, PM_CEFUSE_PWRSTST, PM_PER_PWRSTST, PM_MPU_PWRSTST */ +#define AM33XX_POWERSTATEST_SHIFT			0 +#define AM33XX_POWERSTATEST_MASK			(0x3 << 0) + +/* Used by PM_PER_PWRSTCTRL */ +#define AM33XX_RAM_MEM_ONSTATE_SHIFT			30 +#define AM33XX_RAM_MEM_ONSTATE_MASK			(0x3 << 30) + +/* Used by PM_PER_PWRSTCTRL */ +#define AM33XX_RAM_MEM_RETSTATE_SHIFT			27 +#define AM33XX_RAM_MEM_RETSTATE_MASK			(1 << 27) + +/* Used by PM_PER_PWRSTST */ +#define AM33XX_RAM_MEM_STATEST_SHIFT			21 +#define AM33XX_RAM_MEM_STATEST_MASK			(0x3 << 21) + +/* Used by PRM_LDO_SRAM_CORE_CTRL, PRM_LDO_SRAM_MPU_CTRL */ +#define AM33XX_RETMODE_ENABLE_SHIFT			0 +#define AM33XX_RETMODE_ENABLE_MASK			(1 << 0) + +/* Used by REVISION_PRM */ +#define AM33XX_REV_SHIFT				0 +#define AM33XX_REV_MASK					(0xff << 0) + +/* Used by PRM_RSTTIME */ +#define AM33XX_RSTTIME1_SHIFT				0 +#define AM33XX_RSTTIME1_MASK				(0xff << 0) + +/* Used by PRM_RSTTIME */ +#define AM33XX_RSTTIME2_SHIFT				8 +#define AM33XX_RSTTIME2_MASK				(0x1f << 8) + +/* Used by PRM_RSTCTRL */ +#define AM33XX_RST_GLOBAL_COLD_SW_SHIFT			1 +#define AM33XX_RST_GLOBAL_COLD_SW_MASK			(1 << 1) + +/* Used by PRM_RSTCTRL */ +#define AM33XX_RST_GLOBAL_WARM_SW_SHIFT			0 +#define AM33XX_RST_GLOBAL_WARM_SW_MASK			(1 << 0) + +/* Used by PRM_SRAM_COUNT */ +#define AM33XX_SLPCNT_VALUE_SHIFT			16 +#define AM33XX_SLPCNT_VALUE_MASK			(0xff << 16) + +/* Used by PRM_LDO_SRAM_CORE_CTRL, PRM_LDO_SRAM_MPU_CTRL */ +#define AM33XX_SRAMLDO_STATUS_SHIFT			8 +#define AM33XX_SRAMLDO_STATUS_MASK			(1 << 8) + +/* Used by PRM_LDO_SRAM_CORE_CTRL, PRM_LDO_SRAM_MPU_CTRL */ +#define AM33XX_SRAM_IN_TRANSITION_SHIFT			9 +#define AM33XX_SRAM_IN_TRANSITION_MASK			(1 << 9) + +/* Used by PRM_SRAM_COUNT */ +#define AM33XX_STARTUP_COUNT_SHIFT			24 +#define AM33XX_STARTUP_COUNT_MASK			(0xff << 24) + +/* Used by PRM_IRQENABLE_M3, PRM_IRQENABLE_MPU */ +#define AM33XX_TRANSITION_EN_SHIFT			8 +#define AM33XX_TRANSITION_EN_MASK			(1 << 8) + +/* Used by PRM_IRQSTATUS_M3, PRM_IRQSTATUS_MPU */ +#define AM33XX_TRANSITION_ST_SHIFT			8 +#define AM33XX_TRANSITION_ST_MASK			(1 << 8) + +/* Used by PRM_SRAM_COUNT */ +#define AM33XX_VSETUPCNT_VALUE_SHIFT			8 +#define AM33XX_VSETUPCNT_VALUE_MASK			(0xff << 8) + +/* Used by PRM_RSTST */ +#define AM33XX_WDT0_RST_SHIFT				3 +#define AM33XX_WDT0_RST_MASK				(1 << 3) + +/* Used by PRM_RSTST */ +#define AM33XX_WDT1_RST_SHIFT				4 +#define AM33XX_WDT1_RST_MASK				(1 << 4) + +/* Used by RM_WKUP_RSTCTRL */ +#define AM33XX_WKUP_M3_LRST_SHIFT			3 +#define AM33XX_WKUP_M3_LRST_MASK			(1 << 3) + +/* Renamed from WKUP_M3_LRST Used by RM_WKUP_RSTST */ +#define AM33XX_WKUP_M3_LRST_5_5_SHIFT			5 +#define AM33XX_WKUP_M3_LRST_5_5_MASK			(1 << 5) + +#endif diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c index 21cb74003a5..a0309dea679 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c @@ -302,11 +302,59 @@ void omap3xxx_prm_restore_irqen(u32 *saved_mask)  				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 (omap3_has_io_wakeup()) +		omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, +					   PM_WKEN); +} +  static int __init omap3xxx_prcm_init(void)  {  	int ret = 0;  	if (cpu_is_omap34xx()) { +		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"), diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h index 70ac2a19dc5..c19d249b481 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.h +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h @@ -228,68 +228,6 @@  #ifndef __ASSEMBLER__ -/* - * Stub omap2xxx/omap3xxx functions so that common files - * continue to build when custom builds are used - */ -#if defined(CONFIG_ARCH_OMAP4) && !(defined(CONFIG_ARCH_OMAP2) ||	\ -					defined(CONFIG_ARCH_OMAP3)) -static inline u32 omap2_prm_read_mod_reg(s16 module, u16 idx) -{ -	WARN(1, "prm: omap2xxx/omap3xxx specific function and " -		"not suppose to be used on omap4\n"); -	return 0; -} -static inline void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx) -{ -	WARN(1, "prm: omap2xxx/omap3xxx specific function and " -		"not suppose to be used on omap4\n"); -} -static inline u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, -		s16 module, s16 idx) -{ -	WARN(1, "prm: omap2xxx/omap3xxx specific function and " -		"not suppose to be used on omap4\n"); -	return 0; -} -static inline u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) -{ -	WARN(1, "prm: omap2xxx/omap3xxx specific function and " -		"not suppose to be used on omap4\n"); -	return 0; -} -static inline u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) -{ -	WARN(1, "prm: omap2xxx/omap3xxx specific function and " -		"not suppose to be used on omap4\n"); -	return 0; -} -static inline u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask) -{ -	WARN(1, "prm: omap2xxx/omap3xxx specific function and " -		"not suppose to be used on omap4\n"); -	return 0; -} -static inline int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift) -{ -	WARN(1, "prm: omap2xxx/omap3xxx specific function and " -		"not suppose to be used on omap4\n"); -	return 0; -} -static inline int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift) -{ -	WARN(1, "prm: omap2xxx/omap3xxx specific function and " -		"not suppose to be used on omap4\n"); -	return 0; -} -static inline int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, -						u8 st_shift) -{ -	WARN(1, "prm: omap2xxx/omap3xxx specific function and " -		"not suppose to be used on omap4\n"); -	return 0; -} -#else  /* Power/reset management domain register get/set */  extern u32 omap2_prm_read_mod_reg(s16 module, u16 idx);  extern void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx); @@ -315,15 +253,15 @@ 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); +extern void omap3xxx_prm_reconfigure_io_chain(void); +  /* 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); -#endif	/* CONFIG_ARCH_OMAP4 */ - -#endif +#endif /* __ASSEMBLER */  /*   * Bits common to specific registers diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c new file mode 100644 index 00000000000..e7dbb6cf125 --- /dev/null +++ b/arch/arm/mach-omap2/prm33xx.c @@ -0,0 +1,135 @@ +/* + * 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 <plat/common.h> + +#include "common.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 __raw_readl(prm_base + inst + idx); +} + +/* Write into a register in a PRM instance */ +void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx) +{ +	__raw_writel(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, s16 inst, +		u16 rstctrl_offs, u16 rstst_offs) +{ +	int c; +	u32 mask = 1 << 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 */ +	am33xx_prm_rmw_reg_bits(mask, 0, inst, rstctrl_offs); +	/* wait the status to be set */ + +	omap_test_timeout(am33xx_prm_is_hardreset_asserted(shift, inst, +							   rstst_offs), +			  MAX_MODULE_HARDRESET_WAIT, c); + +	return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0; +} diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h new file mode 100644 index 00000000000..3f25c563a82 --- /dev/null +++ b/arch/arm/mach-omap2/prm33xx.h @@ -0,0 +1,129 @@ +/* + * 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) + +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, s16 inst, +		u16 rstctrl_offs, u16 rstst_offs); +#endif diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index f106d21ff58..bb727c2d933 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -233,10 +233,71 @@ void omap44xx_prm_restore_irqen(u32 *saved_mask)  				 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); +} +  static int __init omap4xxx_prcm_init(void)  { -	if (cpu_is_omap44xx()) +	if (cpu_is_omap44xx()) { +		omap44xx_prm_enable_io_wakeup();  		return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup); +	}  	return 0;  }  subsys_initcall(omap4xxx_prcm_init); diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h index 7978092946d..ee72ae6bd8c 100644 --- a/arch/arm/mach-omap2/prm44xx.h +++ b/arch/arm/mach-omap2/prm44xx.h @@ -763,6 +763,8 @@ 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); +extern void omap44xx_prm_reconfigure_io_chain(void); +  /* PRM interrupt-related functions */  extern void omap44xx_prm_read_pending_irqs(unsigned long *events);  extern void omap44xx_prm_ocp_barrier(void); diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index dfe00ddb5c6..03b126d9ad9 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -85,7 +85,7 @@ static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc)  	unsigned long priority_pending[OMAP_PRCM_MAX_NR_PENDING_REG];  	struct irq_chip *chip = irq_desc_get_chip(desc);  	unsigned int virtirq; -	int nr_irqs = prcm_irq_setup->nr_regs * 32; +	int nr_irq = prcm_irq_setup->nr_regs * 32;  	/*  	 * If we are suspended, mask all interrupts from PRCM level, @@ -110,7 +110,7 @@ static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc)  		prcm_irq_setup->read_pending_irqs(pending);  		/* No bit set, then all IRQs are handled */ -		if (find_first_bit(pending, nr_irqs) >= nr_irqs) +		if (find_first_bit(pending, nr_irq) >= nr_irq)  			break;  		omap_prcm_events_filter_priority(pending, priority_pending); @@ -121,11 +121,11 @@ static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc)  		 */  		/* Serve priority events first */ -		for_each_set_bit(virtirq, priority_pending, nr_irqs) +		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_irqs) +		for_each_set_bit(virtirq, pending, nr_irq)  			generic_handle_irq(prcm_irq_setup->base_irq + virtirq);  	}  	if (chip->irq_ack) @@ -319,3 +319,65 @@ err:  	omap_prcm_irq_cleanup();  	return -ENOMEM;  } + +/* + * Stubbed functions so that common files continue to build when + * custom builds are used + * XXX These are temporary and should be removed at the earliest possible + * opportunity + */ +u32 __weak omap2_prm_read_mod_reg(s16 module, u16 idx) +{ +	WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n"); +	return 0; +} + +void __weak omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx) +{ +	WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n"); +} + +u32 __weak omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, +		s16 module, s16 idx) +{ +	WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n"); +	return 0; +} + +u32 __weak omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) +{ +	WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n"); +	return 0; +} + +u32 __weak omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) +{ +	WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n"); +	return 0; +} + +u32 __weak omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask) +{ +	WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n"); +	return 0; +} + +int __weak omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift) +{ +	WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n"); +	return 0; +} + +int __weak omap2_prm_assert_hardreset(s16 prm_mod, u8 shift) +{ +	WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n"); +	return 0; +} + +int __weak omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, +						u8 st_shift) +{ +	WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n"); +	return 0; +} + diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c index 955566eefac..1da8f03c479 100644 --- a/arch/arm/mach-omap2/smartreflex-class3.c +++ b/arch/arm/mach-omap2/smartreflex-class3.c @@ -11,36 +11,37 @@   * published by the Free Software Foundation.   */ -#include "smartreflex.h" +#include <linux/power/smartreflex.h> +#include "voltage.h" -static int sr_class3_enable(struct voltagedomain *voltdm) +static int sr_class3_enable(struct omap_sr *sr)  { -	unsigned long volt = voltdm_get_voltage(voltdm); +	unsigned long volt = voltdm_get_voltage(sr->voltdm);  	if (!volt) { -		pr_warning("%s: Curr voltage unknown. Cannot enable sr_%s\n", -				__func__, voltdm->name); +		pr_warning("%s: Curr voltage unknown. Cannot enable %s\n", +				__func__, sr->name);  		return -ENODATA;  	} -	omap_vp_enable(voltdm); -	return sr_enable(voltdm, volt); +	omap_vp_enable(sr->voltdm); +	return sr_enable(sr->voltdm, volt);  } -static int sr_class3_disable(struct voltagedomain *voltdm, int is_volt_reset) +static int sr_class3_disable(struct omap_sr *sr, int is_volt_reset)  { -	sr_disable_errgen(voltdm); -	omap_vp_disable(voltdm); -	sr_disable(voltdm); +	sr_disable_errgen(sr->voltdm); +	omap_vp_disable(sr->voltdm); +	sr_disable(sr->voltdm);  	if (is_volt_reset) -		voltdm_reset(voltdm); +		voltdm_reset(sr->voltdm);  	return 0;  } -static int sr_class3_configure(struct voltagedomain *voltdm) +static int sr_class3_configure(struct omap_sr *sr)  { -	return sr_configure_errgen(voltdm); +	return sr_configure_errgen(sr->voltdm);  }  /* SR class3 structure */ diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c deleted file mode 100644 index 008fbd7b935..00000000000 --- a/arch/arm/mach-omap2/smartreflex.c +++ /dev/null @@ -1,1165 +0,0 @@ -/* - * OMAP SmartReflex Voltage Control - * - * Author: Thara Gopinath	<thara@ti.com> - * - * 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/module.h> -#include <linux/interrupt.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/debugfs.h> -#include <linux/delay.h> -#include <linux/slab.h> -#include <linux/pm_runtime.h> - -#include "common.h" - -#include "pm.h" -#include "smartreflex.h" - -#define SMARTREFLEX_NAME_LEN	16 -#define NVALUE_NAME_LEN		40 -#define SR_DISABLE_TIMEOUT	200 - -struct omap_sr { -	struct list_head		node; -	struct platform_device		*pdev; -	struct omap_sr_nvalue_table	*nvalue_table; -	struct voltagedomain		*voltdm; -	struct dentry			*dbg_dir; -	unsigned int			irq; -	int				srid; -	int				ip_type; -	int				nvalue_count; -	bool				autocomp_active; -	u32				clk_length; -	u32				err_weight; -	u32				err_minlimit; -	u32				err_maxlimit; -	u32				accum_data; -	u32				senn_avgweight; -	u32				senp_avgweight; -	u32				senp_mod; -	u32				senn_mod; -	void __iomem			*base; -}; - -/* sr_list contains all the instances of smartreflex module */ -static LIST_HEAD(sr_list); - -static struct omap_sr_class_data *sr_class; -static struct omap_sr_pmic_data *sr_pmic_data; -static struct dentry		*sr_dbg_dir; - -static inline void sr_write_reg(struct omap_sr *sr, unsigned offset, u32 value) -{ -	__raw_writel(value, (sr->base + offset)); -} - -static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask, -					u32 value) -{ -	u32 reg_val; - -	/* -	 * Smartreflex error config register is special as it contains -	 * certain status bits which if written a 1 into means a clear -	 * of those bits. So in order to make sure no accidental write of -	 * 1 happens to those status bits, do a clear of them in the read -	 * value. This mean this API doesn't rewrite values in these bits -	 * if they are currently set, but does allow the caller to write -	 * those bits. -	 */ -	if (sr->ip_type == SR_TYPE_V1 && offset == ERRCONFIG_V1) -		mask |= ERRCONFIG_STATUS_V1_MASK; -	else if (sr->ip_type == SR_TYPE_V2 && offset == ERRCONFIG_V2) -		mask |= ERRCONFIG_VPBOUNDINTST_V2; - -	reg_val = __raw_readl(sr->base + offset); -	reg_val &= ~mask; - -	value &= mask; - -	reg_val |= value; - -	__raw_writel(reg_val, (sr->base + offset)); -} - -static inline u32 sr_read_reg(struct omap_sr *sr, unsigned offset) -{ -	return __raw_readl(sr->base + offset); -} - -static struct omap_sr *_sr_lookup(struct voltagedomain *voltdm) -{ -	struct omap_sr *sr_info; - -	if (!voltdm) { -		pr_err("%s: Null voltage domain passed!\n", __func__); -		return ERR_PTR(-EINVAL); -	} - -	list_for_each_entry(sr_info, &sr_list, node) { -		if (voltdm == sr_info->voltdm) -			return sr_info; -	} - -	return ERR_PTR(-ENODATA); -} - -static irqreturn_t sr_interrupt(int irq, void *data) -{ -	struct omap_sr *sr_info = data; -	u32 status = 0; - -	switch (sr_info->ip_type) { -	case SR_TYPE_V1: -		/* Read the status bits */ -		status = sr_read_reg(sr_info, ERRCONFIG_V1); - -		/* Clear them by writing back */ -		sr_write_reg(sr_info, ERRCONFIG_V1, status); -		break; -	case SR_TYPE_V2: -		/* Read the status bits */ -		status = sr_read_reg(sr_info, IRQSTATUS); - -		/* Clear them by writing back */ -		sr_write_reg(sr_info, IRQSTATUS, status); -		break; -	default: -		dev_err(&sr_info->pdev->dev, "UNKNOWN IP type %d\n", -			sr_info->ip_type); -		return IRQ_NONE; -	} - -	if (sr_class->notify) -		sr_class->notify(sr_info->voltdm, status); - -	return IRQ_HANDLED; -} - -static void sr_set_clk_length(struct omap_sr *sr) -{ -	struct clk *sys_ck; -	u32 sys_clk_speed; - -	if (cpu_is_omap34xx()) -		sys_ck = clk_get(NULL, "sys_ck"); -	else -		sys_ck = clk_get(NULL, "sys_clkin_ck"); - -	if (IS_ERR(sys_ck)) { -		dev_err(&sr->pdev->dev, "%s: unable to get sys clk\n", -			__func__); -		return; -	} - -	sys_clk_speed = clk_get_rate(sys_ck); -	clk_put(sys_ck); - -	switch (sys_clk_speed) { -	case 12000000: -		sr->clk_length = SRCLKLENGTH_12MHZ_SYSCLK; -		break; -	case 13000000: -		sr->clk_length = SRCLKLENGTH_13MHZ_SYSCLK; -		break; -	case 19200000: -		sr->clk_length = SRCLKLENGTH_19MHZ_SYSCLK; -		break; -	case 26000000: -		sr->clk_length = SRCLKLENGTH_26MHZ_SYSCLK; -		break; -	case 38400000: -		sr->clk_length = SRCLKLENGTH_38MHZ_SYSCLK; -		break; -	default: -		dev_err(&sr->pdev->dev, "%s: Invalid sysclk value: %d\n", -			__func__, sys_clk_speed); -		break; -	} -} - -static void sr_set_regfields(struct omap_sr *sr) -{ -	/* -	 * For time being these values are defined in smartreflex.h -	 * and populated during init. May be they can be moved to board -	 * file or pmic specific data structure. In that case these structure -	 * fields will have to be populated using the pdata or pmic structure. -	 */ -	if (cpu_is_omap34xx() || cpu_is_omap44xx()) { -		sr->err_weight = OMAP3430_SR_ERRWEIGHT; -		sr->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT; -		sr->accum_data = OMAP3430_SR_ACCUMDATA; -		if (!(strcmp(sr->voltdm->name, "mpu"))) { -			sr->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT; -			sr->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT; -		} else { -			sr->senn_avgweight = OMAP3430_SR2_SENNAVGWEIGHT; -			sr->senp_avgweight = OMAP3430_SR2_SENPAVGWEIGHT; -		} -	} -} - -static void sr_start_vddautocomp(struct omap_sr *sr) -{ -	if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) { -		dev_warn(&sr->pdev->dev, -			"%s: smartreflex class driver not registered\n", -			__func__); -		return; -	} - -	if (!sr_class->enable(sr->voltdm)) -		sr->autocomp_active = true; -} - -static void sr_stop_vddautocomp(struct omap_sr *sr) -{ -	if (!sr_class || !(sr_class->disable)) { -		dev_warn(&sr->pdev->dev, -			"%s: smartreflex class driver not registered\n", -			__func__); -		return; -	} - -	if (sr->autocomp_active) { -		sr_class->disable(sr->voltdm, 1); -		sr->autocomp_active = false; -	} -} - -/* - * This function handles the intializations which have to be done - * only when both sr device and class driver regiter has - * completed. This will be attempted to be called from both sr class - * driver register and sr device intializtion API's. Only one call - * will ultimately succeed. - * - * Currently this function registers interrupt handler for a particular SR - * if smartreflex class driver is already registered and has - * requested for interrupts and the SR interrupt line in present. - */ -static int sr_late_init(struct omap_sr *sr_info) -{ -	char *name; -	struct omap_sr_data *pdata = sr_info->pdev->dev.platform_data; -	struct resource *mem; -	int ret = 0; - -	if (sr_class->notify && sr_class->notify_flags && sr_info->irq) { -		name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name); -		if (name == NULL) { -			ret = -ENOMEM; -			goto error; -		} -		ret = request_irq(sr_info->irq, sr_interrupt, -				0, name, sr_info); -		if (ret) -			goto error; -		disable_irq(sr_info->irq); -	} - -	if (pdata && pdata->enable_on_init) -		sr_start_vddautocomp(sr_info); - -	return ret; - -error: -	iounmap(sr_info->base); -	mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0); -	release_mem_region(mem->start, resource_size(mem)); -	list_del(&sr_info->node); -	dev_err(&sr_info->pdev->dev, "%s: ERROR in registering" -		"interrupt handler. Smartreflex will" -		"not function as desired\n", __func__); -	kfree(name); -	kfree(sr_info); - -	return ret; -} - -static void sr_v1_disable(struct omap_sr *sr) -{ -	int timeout = 0; -	int errconf_val = ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST | -			ERRCONFIG_MCUBOUNDINTST; - -	/* Enable MCUDisableAcknowledge interrupt */ -	sr_modify_reg(sr, ERRCONFIG_V1, -			ERRCONFIG_MCUDISACKINTEN, ERRCONFIG_MCUDISACKINTEN); - -	/* SRCONFIG - disable SR */ -	sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0); - -	/* Disable all other SR interrupts and clear the status as needed */ -	if (sr_read_reg(sr, ERRCONFIG_V1) & ERRCONFIG_VPBOUNDINTST_V1) -		errconf_val |= ERRCONFIG_VPBOUNDINTST_V1; -	sr_modify_reg(sr, ERRCONFIG_V1, -			(ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN | -			ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN_V1), -			errconf_val); - -	/* -	 * Wait for SR to be disabled. -	 * wait until ERRCONFIG.MCUDISACKINTST = 1. Typical latency is 1us. -	 */ -	omap_test_timeout((sr_read_reg(sr, ERRCONFIG_V1) & -			ERRCONFIG_MCUDISACKINTST), SR_DISABLE_TIMEOUT, -			timeout); - -	if (timeout >= SR_DISABLE_TIMEOUT) -		dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n", -			__func__); - -	/* Disable MCUDisableAcknowledge interrupt & clear pending interrupt */ -	sr_modify_reg(sr, ERRCONFIG_V1, ERRCONFIG_MCUDISACKINTEN, -			ERRCONFIG_MCUDISACKINTST); -} - -static void sr_v2_disable(struct omap_sr *sr) -{ -	int timeout = 0; - -	/* Enable MCUDisableAcknowledge interrupt */ -	sr_write_reg(sr, IRQENABLE_SET, IRQENABLE_MCUDISABLEACKINT); - -	/* SRCONFIG - disable SR */ -	sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0); - -	/* -	 * Disable all other SR interrupts and clear the status -	 * write to status register ONLY on need basis - only if status -	 * is set. -	 */ -	if (sr_read_reg(sr, ERRCONFIG_V2) & ERRCONFIG_VPBOUNDINTST_V2) -		sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2, -			ERRCONFIG_VPBOUNDINTST_V2); -	else -		sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2, -				0x0); -	sr_write_reg(sr, IRQENABLE_CLR, (IRQENABLE_MCUACCUMINT | -			IRQENABLE_MCUVALIDINT | -			IRQENABLE_MCUBOUNDSINT)); -	sr_write_reg(sr, IRQSTATUS, (IRQSTATUS_MCUACCUMINT | -			IRQSTATUS_MCVALIDINT | -			IRQSTATUS_MCBOUNDSINT)); - -	/* -	 * Wait for SR to be disabled. -	 * wait until IRQSTATUS.MCUDISACKINTST = 1. Typical latency is 1us. -	 */ -	omap_test_timeout((sr_read_reg(sr, IRQSTATUS) & -			IRQSTATUS_MCUDISABLEACKINT), SR_DISABLE_TIMEOUT, -			timeout); - -	if (timeout >= SR_DISABLE_TIMEOUT) -		dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n", -			__func__); - -	/* Disable MCUDisableAcknowledge interrupt & clear pending interrupt */ -	sr_write_reg(sr, IRQENABLE_CLR, IRQENABLE_MCUDISABLEACKINT); -	sr_write_reg(sr, IRQSTATUS, IRQSTATUS_MCUDISABLEACKINT); -} - -static u32 sr_retrieve_nvalue(struct omap_sr *sr, u32 efuse_offs) -{ -	int i; - -	if (!sr->nvalue_table) { -		dev_warn(&sr->pdev->dev, "%s: Missing ntarget value table\n", -			__func__); -		return 0; -	} - -	for (i = 0; i < sr->nvalue_count; i++) { -		if (sr->nvalue_table[i].efuse_offs == efuse_offs) -			return sr->nvalue_table[i].nvalue; -	} - -	return 0; -} - -/* Public Functions */ - -/** - * sr_configure_errgen() - Configures the smrtreflex to perform AVS using the - *			 error generator module. - * @voltdm:	VDD pointer to which the SR module to be configured belongs to. - * - * This API is to be called from the smartreflex class driver to - * configure the error generator module inside the smartreflex module. - * SR settings if using the ERROR module inside Smartreflex. - * SR CLASS 3 by default uses only the ERROR module where as - * SR CLASS 2 can choose between ERROR module and MINMAXAVG - * module. Returns 0 on success and error value in case of failure. - */ -int sr_configure_errgen(struct voltagedomain *voltdm) -{ -	u32 sr_config, sr_errconfig, errconfig_offs; -	u32 vpboundint_en, vpboundint_st; -	u32 senp_en = 0, senn_en = 0; -	u8 senp_shift, senn_shift; -	struct omap_sr *sr = _sr_lookup(voltdm); - -	if (IS_ERR(sr)) { -		pr_warning("%s: omap_sr struct for sr_%s not found\n", -			__func__, voltdm->name); -		return PTR_ERR(sr); -	} - -	if (!sr->clk_length) -		sr_set_clk_length(sr); - -	senp_en = sr->senp_mod; -	senn_en = sr->senn_mod; - -	sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) | -		SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN; - -	switch (sr->ip_type) { -	case SR_TYPE_V1: -		sr_config |= SRCONFIG_DELAYCTRL; -		senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT; -		senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT; -		errconfig_offs = ERRCONFIG_V1; -		vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1; -		vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1; -		break; -	case SR_TYPE_V2: -		senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT; -		senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT; -		errconfig_offs = ERRCONFIG_V2; -		vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2; -		vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2; -		break; -	default: -		dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" -			"module without specifying the ip\n", __func__); -		return -EINVAL; -	} - -	sr_config |= ((senn_en << senn_shift) | (senp_en << senp_shift)); -	sr_write_reg(sr, SRCONFIG, sr_config); -	sr_errconfig = (sr->err_weight << ERRCONFIG_ERRWEIGHT_SHIFT) | -		(sr->err_maxlimit << ERRCONFIG_ERRMAXLIMIT_SHIFT) | -		(sr->err_minlimit <<  ERRCONFIG_ERRMINLIMIT_SHIFT); -	sr_modify_reg(sr, errconfig_offs, (SR_ERRWEIGHT_MASK | -		SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK), -		sr_errconfig); - -	/* Enabling the interrupts if the ERROR module is used */ -	sr_modify_reg(sr, errconfig_offs, (vpboundint_en | vpboundint_st), -		      vpboundint_en); - -	return 0; -} - -/** - * sr_disable_errgen() - Disables SmartReflex AVS module's errgen component - * @voltdm:	VDD pointer to which the SR module to be configured belongs to. - * - * This API is to be called from the smartreflex class driver to - * disable the error generator module inside the smartreflex module. - * - * Returns 0 on success and error value in case of failure. - */ -int sr_disable_errgen(struct voltagedomain *voltdm) -{ -	u32 errconfig_offs; -	u32 vpboundint_en, vpboundint_st; -	struct omap_sr *sr = _sr_lookup(voltdm); - -	if (IS_ERR(sr)) { -		pr_warning("%s: omap_sr struct for sr_%s not found\n", -			__func__, voltdm->name); -		return PTR_ERR(sr); -	} - -	switch (sr->ip_type) { -	case SR_TYPE_V1: -		errconfig_offs = ERRCONFIG_V1; -		vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1; -		vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1; -		break; -	case SR_TYPE_V2: -		errconfig_offs = ERRCONFIG_V2; -		vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2; -		vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2; -		break; -	default: -		dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" -			"module without specifying the ip\n", __func__); -		return -EINVAL; -	} - -	/* Disable the interrupts of ERROR module */ -	sr_modify_reg(sr, errconfig_offs, vpboundint_en | vpboundint_st, 0); - -	/* Disable the Sensor and errorgen */ -	sr_modify_reg(sr, SRCONFIG, SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN, 0); - -	return 0; -} - -/** - * sr_configure_minmax() - Configures the smrtreflex to perform AVS using the - *			 minmaxavg module. - * @voltdm:	VDD pointer to which the SR module to be configured belongs to. - * - * This API is to be called from the smartreflex class driver to - * configure the minmaxavg module inside the smartreflex module. - * SR settings if using the ERROR module inside Smartreflex. - * SR CLASS 3 by default uses only the ERROR module where as - * SR CLASS 2 can choose between ERROR module and MINMAXAVG - * module. Returns 0 on success and error value in case of failure. - */ -int sr_configure_minmax(struct voltagedomain *voltdm) -{ -	u32 sr_config, sr_avgwt; -	u32 senp_en = 0, senn_en = 0; -	u8 senp_shift, senn_shift; -	struct omap_sr *sr = _sr_lookup(voltdm); - -	if (IS_ERR(sr)) { -		pr_warning("%s: omap_sr struct for sr_%s not found\n", -			__func__, voltdm->name); -		return PTR_ERR(sr); -	} - -	if (!sr->clk_length) -		sr_set_clk_length(sr); - -	senp_en = sr->senp_mod; -	senn_en = sr->senn_mod; - -	sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) | -		SRCONFIG_SENENABLE | -		(sr->accum_data << SRCONFIG_ACCUMDATA_SHIFT); - -	switch (sr->ip_type) { -	case SR_TYPE_V1: -		sr_config |= SRCONFIG_DELAYCTRL; -		senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT; -		senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT; -		break; -	case SR_TYPE_V2: -		senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT; -		senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT; -		break; -	default: -		dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" -			"module without specifying the ip\n", __func__); -		return -EINVAL; -	} - -	sr_config |= ((senn_en << senn_shift) | (senp_en << senp_shift)); -	sr_write_reg(sr, SRCONFIG, sr_config); -	sr_avgwt = (sr->senp_avgweight << AVGWEIGHT_SENPAVGWEIGHT_SHIFT) | -		(sr->senn_avgweight << AVGWEIGHT_SENNAVGWEIGHT_SHIFT); -	sr_write_reg(sr, AVGWEIGHT, sr_avgwt); - -	/* -	 * Enabling the interrupts if MINMAXAVG module is used. -	 * TODO: check if all the interrupts are mandatory -	 */ -	switch (sr->ip_type) { -	case SR_TYPE_V1: -		sr_modify_reg(sr, ERRCONFIG_V1, -			(ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN | -			ERRCONFIG_MCUBOUNDINTEN), -			(ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUACCUMINTST | -			 ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUVALIDINTST | -			 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_MCUBOUNDINTST)); -		break; -	case SR_TYPE_V2: -		sr_write_reg(sr, IRQSTATUS, -			IRQSTATUS_MCUACCUMINT | IRQSTATUS_MCVALIDINT | -			IRQSTATUS_MCBOUNDSINT | IRQSTATUS_MCUDISABLEACKINT); -		sr_write_reg(sr, IRQENABLE_SET, -			IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT | -			IRQENABLE_MCUBOUNDSINT | IRQENABLE_MCUDISABLEACKINT); -		break; -	default: -		dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" -			"module without specifying the ip\n", __func__); -		return -EINVAL; -	} - -	return 0; -} - -/** - * sr_enable() - Enables the smartreflex module. - * @voltdm:	VDD pointer to which the SR module to be configured belongs to. - * @volt:	The voltage at which the Voltage domain associated with - *		the smartreflex module is operating at. - *		This is required only to program the correct Ntarget value. - * - * This API is to be called from the smartreflex class driver to - * enable a smartreflex module. Returns 0 on success. Returns error - * value if the voltage passed is wrong or if ntarget value is wrong. - */ -int sr_enable(struct voltagedomain *voltdm, unsigned long volt) -{ -	struct omap_volt_data *volt_data; -	struct omap_sr *sr = _sr_lookup(voltdm); -	u32 nvalue_reciprocal; -	int ret; - -	if (IS_ERR(sr)) { -		pr_warning("%s: omap_sr struct for sr_%s not found\n", -			__func__, voltdm->name); -		return PTR_ERR(sr); -	} - -	volt_data = omap_voltage_get_voltdata(sr->voltdm, volt); - -	if (IS_ERR(volt_data)) { -		dev_warn(&sr->pdev->dev, "%s: Unable to get voltage table" -			"for nominal voltage %ld\n", __func__, volt); -		return PTR_ERR(volt_data); -	} - -	nvalue_reciprocal = sr_retrieve_nvalue(sr, volt_data->sr_efuse_offs); - -	if (!nvalue_reciprocal) { -		dev_warn(&sr->pdev->dev, "%s: NVALUE = 0 at voltage %ld\n", -			__func__, volt); -		return -ENODATA; -	} - -	/* errminlimit is opp dependent and hence linked to voltage */ -	sr->err_minlimit = volt_data->sr_errminlimit; - -	pm_runtime_get_sync(&sr->pdev->dev); - -	/* Check if SR is already enabled. If yes do nothing */ -	if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE) -		return 0; - -	/* Configure SR */ -	ret = sr_class->configure(voltdm); -	if (ret) -		return ret; - -	sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal); - -	/* SRCONFIG - enable SR */ -	sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE); -	return 0; -} - -/** - * sr_disable() - Disables the smartreflex module. - * @voltdm:	VDD pointer to which the SR module to be configured belongs to. - * - * This API is to be called from the smartreflex class driver to - * disable a smartreflex module. - */ -void sr_disable(struct voltagedomain *voltdm) -{ -	struct omap_sr *sr = _sr_lookup(voltdm); - -	if (IS_ERR(sr)) { -		pr_warning("%s: omap_sr struct for sr_%s not found\n", -			__func__, voltdm->name); -		return; -	} - -	/* Check if SR clocks are already disabled. If yes do nothing */ -	if (pm_runtime_suspended(&sr->pdev->dev)) -		return; - -	/* -	 * Disable SR if only it is indeed enabled. Else just -	 * disable the clocks. -	 */ -	if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE) { -		switch (sr->ip_type) { -		case SR_TYPE_V1: -			sr_v1_disable(sr); -			break; -		case SR_TYPE_V2: -			sr_v2_disable(sr); -			break; -		default: -			dev_err(&sr->pdev->dev, "UNKNOWN IP type %d\n", -				sr->ip_type); -		} -	} - -	pm_runtime_put_sync_suspend(&sr->pdev->dev); -} - -/** - * sr_register_class() - API to register a smartreflex class parameters. - * @class_data:	The structure containing various sr class specific data. - * - * This API is to be called by the smartreflex class driver to register itself - * with the smartreflex driver during init. Returns 0 on success else the - * error value. - */ -int sr_register_class(struct omap_sr_class_data *class_data) -{ -	struct omap_sr *sr_info; - -	if (!class_data) { -		pr_warning("%s:, Smartreflex class data passed is NULL\n", -			__func__); -		return -EINVAL; -	} - -	if (sr_class) { -		pr_warning("%s: Smartreflex class driver already registered\n", -			__func__); -		return -EBUSY; -	} - -	sr_class = class_data; - -	/* -	 * Call into late init to do intializations that require -	 * both sr driver and sr class driver to be initiallized. -	 */ -	list_for_each_entry(sr_info, &sr_list, node) -		sr_late_init(sr_info); - -	return 0; -} - -/** - * omap_sr_enable() -  API to enable SR clocks and to call into the - *			registered smartreflex class enable API. - * @voltdm:	VDD pointer to which the SR module to be configured belongs to. - * - * This API is to be called from the kernel in order to enable - * a particular smartreflex module. This API will do the initial - * configurations to turn on the smartreflex module and in turn call - * into the registered smartreflex class enable API. - */ -void omap_sr_enable(struct voltagedomain *voltdm) -{ -	struct omap_sr *sr = _sr_lookup(voltdm); - -	if (IS_ERR(sr)) { -		pr_warning("%s: omap_sr struct for sr_%s not found\n", -			__func__, voltdm->name); -		return; -	} - -	if (!sr->autocomp_active) -		return; - -	if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) { -		dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not" -			"registered\n", __func__); -		return; -	} - -	sr_class->enable(voltdm); -} - -/** - * omap_sr_disable() - API to disable SR without resetting the voltage - *			processor voltage - * @voltdm:	VDD pointer to which the SR module to be configured belongs to. - * - * This API is to be called from the kernel in order to disable - * a particular smartreflex module. This API will in turn call - * into the registered smartreflex class disable API. This API will tell - * the smartreflex class disable not to reset the VP voltage after - * disabling smartreflex. - */ -void omap_sr_disable(struct voltagedomain *voltdm) -{ -	struct omap_sr *sr = _sr_lookup(voltdm); - -	if (IS_ERR(sr)) { -		pr_warning("%s: omap_sr struct for sr_%s not found\n", -			__func__, voltdm->name); -		return; -	} - -	if (!sr->autocomp_active) -		return; - -	if (!sr_class || !(sr_class->disable)) { -		dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not" -			"registered\n", __func__); -		return; -	} - -	sr_class->disable(voltdm, 0); -} - -/** - * omap_sr_disable_reset_volt() - API to disable SR and reset the - *				voltage processor voltage - * @voltdm:	VDD pointer to which the SR module to be configured belongs to. - * - * This API is to be called from the kernel in order to disable - * a particular smartreflex module. This API will in turn call - * into the registered smartreflex class disable API. This API will tell - * the smartreflex class disable to reset the VP voltage after - * disabling smartreflex. - */ -void omap_sr_disable_reset_volt(struct voltagedomain *voltdm) -{ -	struct omap_sr *sr = _sr_lookup(voltdm); - -	if (IS_ERR(sr)) { -		pr_warning("%s: omap_sr struct for sr_%s not found\n", -			__func__, voltdm->name); -		return; -	} - -	if (!sr->autocomp_active) -		return; - -	if (!sr_class || !(sr_class->disable)) { -		dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not" -			"registered\n", __func__); -		return; -	} - -	sr_class->disable(voltdm, 1); -} - -/** - * omap_sr_register_pmic() - API to register pmic specific info. - * @pmic_data:	The structure containing pmic specific data. - * - * This API is to be called from the PMIC specific code to register with - * smartreflex driver pmic specific info. Currently the only info required - * is the smartreflex init on the PMIC side. - */ -void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data) -{ -	if (!pmic_data) { -		pr_warning("%s: Trying to register NULL PMIC data structure" -			"with smartreflex\n", __func__); -		return; -	} - -	sr_pmic_data = pmic_data; -} - -/* PM Debug FS entries to enable and disable smartreflex. */ -static int omap_sr_autocomp_show(void *data, u64 *val) -{ -	struct omap_sr *sr_info = data; - -	if (!sr_info) { -		pr_warning("%s: omap_sr struct not found\n", __func__); -		return -EINVAL; -	} - -	*val = sr_info->autocomp_active; - -	return 0; -} - -static int omap_sr_autocomp_store(void *data, u64 val) -{ -	struct omap_sr *sr_info = data; - -	if (!sr_info) { -		pr_warning("%s: omap_sr struct not found\n", __func__); -		return -EINVAL; -	} - -	/* Sanity check */ -	if (val > 1) { -		pr_warning("%s: Invalid argument %lld\n", __func__, val); -		return -EINVAL; -	} - -	/* control enable/disable only if there is a delta in value */ -	if (sr_info->autocomp_active != val) { -		if (!val) -			sr_stop_vddautocomp(sr_info); -		else -			sr_start_vddautocomp(sr_info); -	} - -	return 0; -} - -DEFINE_SIMPLE_ATTRIBUTE(pm_sr_fops, omap_sr_autocomp_show, -			omap_sr_autocomp_store, "%llu\n"); - -static int __init omap_sr_probe(struct platform_device *pdev) -{ -	struct omap_sr *sr_info; -	struct omap_sr_data *pdata = pdev->dev.platform_data; -	struct resource *mem, *irq; -	struct dentry *nvalue_dir; -	struct omap_volt_data *volt_data; -	int i, ret = 0; -	char *name; - -	sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); -	if (!sr_info) { -		dev_err(&pdev->dev, "%s: unable to allocate sr_info\n", -			__func__); -		return -ENOMEM; -	} - -	platform_set_drvdata(pdev, sr_info); - -	if (!pdata) { -		dev_err(&pdev->dev, "%s: platform data missing\n", __func__); -		ret = -EINVAL; -		goto err_free_devinfo; -	} - -	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!mem) { -		dev_err(&pdev->dev, "%s: no mem resource\n", __func__); -		ret = -ENODEV; -		goto err_free_devinfo; -	} - -	mem = request_mem_region(mem->start, resource_size(mem), -					dev_name(&pdev->dev)); -	if (!mem) { -		dev_err(&pdev->dev, "%s: no mem region\n", __func__); -		ret = -EBUSY; -		goto err_free_devinfo; -	} - -	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - -	pm_runtime_enable(&pdev->dev); -	pm_runtime_irq_safe(&pdev->dev); - -	sr_info->pdev = pdev; -	sr_info->srid = pdev->id; -	sr_info->voltdm = pdata->voltdm; -	sr_info->nvalue_table = pdata->nvalue_table; -	sr_info->nvalue_count = pdata->nvalue_count; -	sr_info->senn_mod = pdata->senn_mod; -	sr_info->senp_mod = pdata->senp_mod; -	sr_info->autocomp_active = false; -	sr_info->ip_type = pdata->ip_type; -	sr_info->base = ioremap(mem->start, resource_size(mem)); -	if (!sr_info->base) { -		dev_err(&pdev->dev, "%s: ioremap fail\n", __func__); -		ret = -ENOMEM; -		goto err_release_region; -	} - -	if (irq) -		sr_info->irq = irq->start; - -	sr_set_clk_length(sr_info); -	sr_set_regfields(sr_info); - -	list_add(&sr_info->node, &sr_list); - -	/* -	 * Call into late init to do intializations that require -	 * both sr driver and sr class driver to be initiallized. -	 */ -	if (sr_class) { -		ret = sr_late_init(sr_info); -		if (ret) { -			pr_warning("%s: Error in SR late init\n", __func__); -			goto err_iounmap; -		} -	} - -	dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__); -	if (!sr_dbg_dir) { -		sr_dbg_dir = debugfs_create_dir("smartreflex", NULL); -		if (IS_ERR_OR_NULL(sr_dbg_dir)) { -			ret = PTR_ERR(sr_dbg_dir); -			pr_err("%s:sr debugfs dir creation failed(%d)\n", -				__func__, ret); -			goto err_iounmap; -		} -	} - -	name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name); -	if (!name) { -		dev_err(&pdev->dev, "%s: Unable to alloc debugfs name\n", -			__func__); -		ret = -ENOMEM; -		goto err_iounmap; -	} -	sr_info->dbg_dir = debugfs_create_dir(name, sr_dbg_dir); -	kfree(name); -	if (IS_ERR_OR_NULL(sr_info->dbg_dir)) { -		dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n", -			__func__); -		ret = PTR_ERR(sr_info->dbg_dir); -		goto err_iounmap; -	} - -	(void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, -			sr_info->dbg_dir, (void *)sr_info, &pm_sr_fops); -	(void) debugfs_create_x32("errweight", S_IRUGO, sr_info->dbg_dir, -			&sr_info->err_weight); -	(void) debugfs_create_x32("errmaxlimit", S_IRUGO, sr_info->dbg_dir, -			&sr_info->err_maxlimit); -	(void) debugfs_create_x32("errminlimit", S_IRUGO, sr_info->dbg_dir, -			&sr_info->err_minlimit); - -	nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir); -	if (IS_ERR_OR_NULL(nvalue_dir)) { -		dev_err(&pdev->dev, "%s: Unable to create debugfs directory" -			"for n-values\n", __func__); -		ret = PTR_ERR(nvalue_dir); -		goto err_debugfs; -	} - -	omap_voltage_get_volttable(sr_info->voltdm, &volt_data); -	if (!volt_data) { -		dev_warn(&pdev->dev, "%s: No Voltage table for the" -			" corresponding vdd vdd_%s. Cannot create debugfs" -			"entries for n-values\n", -			__func__, sr_info->voltdm->name); -		ret = -ENODATA; -		goto err_debugfs; -	} - -	for (i = 0; i < sr_info->nvalue_count; i++) { -		char name[NVALUE_NAME_LEN + 1]; - -		snprintf(name, sizeof(name), "volt_%d", -			 volt_data[i].volt_nominal); -		(void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir, -				&(sr_info->nvalue_table[i].nvalue)); -	} - -	return ret; - -err_debugfs: -	debugfs_remove_recursive(sr_info->dbg_dir); -err_iounmap: -	list_del(&sr_info->node); -	iounmap(sr_info->base); -err_release_region: -	release_mem_region(mem->start, resource_size(mem)); -err_free_devinfo: -	kfree(sr_info); - -	return ret; -} - -static int __devexit omap_sr_remove(struct platform_device *pdev) -{ -	struct omap_sr_data *pdata = pdev->dev.platform_data; -	struct omap_sr *sr_info; -	struct resource *mem; - -	if (!pdata) { -		dev_err(&pdev->dev, "%s: platform data missing\n", __func__); -		return -EINVAL; -	} - -	sr_info = _sr_lookup(pdata->voltdm); -	if (IS_ERR(sr_info)) { -		dev_warn(&pdev->dev, "%s: omap_sr struct not found\n", -			__func__); -		return PTR_ERR(sr_info); -	} - -	if (sr_info->autocomp_active) -		sr_stop_vddautocomp(sr_info); -	if (sr_info->dbg_dir) -		debugfs_remove_recursive(sr_info->dbg_dir); - -	list_del(&sr_info->node); -	iounmap(sr_info->base); -	kfree(sr_info); -	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	release_mem_region(mem->start, resource_size(mem)); - -	return 0; -} - -static void __devexit omap_sr_shutdown(struct platform_device *pdev) -{ -	struct omap_sr_data *pdata = pdev->dev.platform_data; -	struct omap_sr *sr_info; - -	if (!pdata) { -		dev_err(&pdev->dev, "%s: platform data missing\n", __func__); -		return; -	} - -	sr_info = _sr_lookup(pdata->voltdm); -	if (IS_ERR(sr_info)) { -		dev_warn(&pdev->dev, "%s: omap_sr struct not found\n", -			__func__); -		return; -	} - -	if (sr_info->autocomp_active) -		sr_stop_vddautocomp(sr_info); - -	return; -} - -static struct platform_driver smartreflex_driver = { -	.remove         = __devexit_p(omap_sr_remove), -	.shutdown	= __devexit_p(omap_sr_shutdown), -	.driver		= { -		.name	= "smartreflex", -	}, -}; - -static int __init sr_init(void) -{ -	int ret = 0; - -	/* -	 * sr_init is a late init. If by then a pmic specific API is not -	 * registered either there is no need for anything to be done on -	 * the PMIC side or somebody has forgotten to register a PMIC -	 * handler. Warn for the second condition. -	 */ -	if (sr_pmic_data && sr_pmic_data->sr_pmic_init) -		sr_pmic_data->sr_pmic_init(); -	else -		pr_warning("%s: No PMIC hook to init smartreflex\n", __func__); - -	ret = platform_driver_probe(&smartreflex_driver, omap_sr_probe); -	if (ret) { -		pr_err("%s: platform driver register failed for SR\n", -			__func__); -		return ret; -	} - -	return 0; -} -late_initcall(sr_init); - -static void __exit sr_exit(void) -{ -	platform_driver_unregister(&smartreflex_driver); -} -module_exit(sr_exit); - -MODULE_DESCRIPTION("OMAP Smartreflex Driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:" DRIVER_NAME); -MODULE_AUTHOR("Texas Instruments Inc"); diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h deleted file mode 100644 index 5809141171f..00000000000 --- a/arch/arm/mach-omap2/smartreflex.h +++ /dev/null @@ -1,256 +0,0 @@ -/* - * OMAP Smartreflex Defines and Routines - * - * Author: Thara Gopinath	<thara@ti.com> - * - * 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. - */ - -#ifndef __ASM_ARM_OMAP_SMARTREFLEX_H -#define __ASM_ARM_OMAP_SMARTREFLEX_H - -#include <linux/platform_device.h> - -#include "voltage.h" - -/* - * Different Smartreflex IPs version. The v1 is the 65nm version used in - * OMAP3430. The v2 is the update for the 45nm version of the IP - * used in OMAP3630 and OMAP4430 - */ -#define SR_TYPE_V1	1 -#define SR_TYPE_V2	2 - -/* SMART REFLEX REG ADDRESS OFFSET */ -#define SRCONFIG		0x00 -#define SRSTATUS		0x04 -#define SENVAL			0x08 -#define SENMIN			0x0C -#define SENMAX			0x10 -#define SENAVG			0x14 -#define AVGWEIGHT		0x18 -#define NVALUERECIPROCAL	0x1c -#define SENERROR_V1		0x20 -#define ERRCONFIG_V1		0x24 -#define IRQ_EOI			0x20 -#define IRQSTATUS_RAW		0x24 -#define IRQSTATUS		0x28 -#define IRQENABLE_SET		0x2C -#define IRQENABLE_CLR		0x30 -#define SENERROR_V2		0x34 -#define ERRCONFIG_V2		0x38 - -/* Bit/Shift Positions */ - -/* SRCONFIG */ -#define SRCONFIG_ACCUMDATA_SHIFT	22 -#define SRCONFIG_SRCLKLENGTH_SHIFT	12 -#define SRCONFIG_SENNENABLE_V1_SHIFT	5 -#define SRCONFIG_SENPENABLE_V1_SHIFT	3 -#define SRCONFIG_SENNENABLE_V2_SHIFT	1 -#define SRCONFIG_SENPENABLE_V2_SHIFT	0 -#define SRCONFIG_CLKCTRL_SHIFT		0 - -#define SRCONFIG_ACCUMDATA_MASK		(0x3ff << 22) - -#define SRCONFIG_SRENABLE		BIT(11) -#define SRCONFIG_SENENABLE		BIT(10) -#define SRCONFIG_ERRGEN_EN		BIT(9) -#define SRCONFIG_MINMAXAVG_EN		BIT(8) -#define SRCONFIG_DELAYCTRL		BIT(2) - -/* AVGWEIGHT */ -#define AVGWEIGHT_SENPAVGWEIGHT_SHIFT	2 -#define AVGWEIGHT_SENNAVGWEIGHT_SHIFT	0 - -/* NVALUERECIPROCAL */ -#define NVALUERECIPROCAL_SENPGAIN_SHIFT	20 -#define NVALUERECIPROCAL_SENNGAIN_SHIFT	16 -#define NVALUERECIPROCAL_RNSENP_SHIFT	8 -#define NVALUERECIPROCAL_RNSENN_SHIFT	0 - -/* ERRCONFIG */ -#define ERRCONFIG_ERRWEIGHT_SHIFT	16 -#define ERRCONFIG_ERRMAXLIMIT_SHIFT	8 -#define ERRCONFIG_ERRMINLIMIT_SHIFT	0 - -#define SR_ERRWEIGHT_MASK		(0x07 << 16) -#define SR_ERRMAXLIMIT_MASK		(0xff << 8) -#define SR_ERRMINLIMIT_MASK		(0xff << 0) - -#define ERRCONFIG_VPBOUNDINTEN_V1	BIT(31) -#define ERRCONFIG_VPBOUNDINTST_V1	BIT(30) -#define	ERRCONFIG_MCUACCUMINTEN		BIT(29) -#define ERRCONFIG_MCUACCUMINTST		BIT(28) -#define	ERRCONFIG_MCUVALIDINTEN		BIT(27) -#define ERRCONFIG_MCUVALIDINTST		BIT(26) -#define ERRCONFIG_MCUBOUNDINTEN		BIT(25) -#define	ERRCONFIG_MCUBOUNDINTST		BIT(24) -#define	ERRCONFIG_MCUDISACKINTEN	BIT(23) -#define ERRCONFIG_VPBOUNDINTST_V2	BIT(23) -#define ERRCONFIG_MCUDISACKINTST	BIT(22) -#define ERRCONFIG_VPBOUNDINTEN_V2	BIT(22) - -#define ERRCONFIG_STATUS_V1_MASK	(ERRCONFIG_VPBOUNDINTST_V1 | \ -					ERRCONFIG_MCUACCUMINTST | \ -					ERRCONFIG_MCUVALIDINTST | \ -					ERRCONFIG_MCUBOUNDINTST | \ -					ERRCONFIG_MCUDISACKINTST) -/* IRQSTATUS */ -#define IRQSTATUS_MCUACCUMINT		BIT(3) -#define IRQSTATUS_MCVALIDINT		BIT(2) -#define IRQSTATUS_MCBOUNDSINT		BIT(1) -#define IRQSTATUS_MCUDISABLEACKINT	BIT(0) - -/* IRQENABLE_SET and IRQENABLE_CLEAR */ -#define IRQENABLE_MCUACCUMINT		BIT(3) -#define IRQENABLE_MCUVALIDINT		BIT(2) -#define IRQENABLE_MCUBOUNDSINT		BIT(1) -#define IRQENABLE_MCUDISABLEACKINT	BIT(0) - -/* Common Bit values */ - -#define SRCLKLENGTH_12MHZ_SYSCLK	0x3c -#define SRCLKLENGTH_13MHZ_SYSCLK	0x41 -#define SRCLKLENGTH_19MHZ_SYSCLK	0x60 -#define SRCLKLENGTH_26MHZ_SYSCLK	0x82 -#define SRCLKLENGTH_38MHZ_SYSCLK	0xC0 - -/* - * 3430 specific values. Maybe these should be passed from board file or - * pmic structures. - */ -#define OMAP3430_SR_ACCUMDATA		0x1f4 - -#define OMAP3430_SR1_SENPAVGWEIGHT	0x03 -#define OMAP3430_SR1_SENNAVGWEIGHT	0x03 - -#define OMAP3430_SR2_SENPAVGWEIGHT	0x01 -#define OMAP3430_SR2_SENNAVGWEIGHT	0x01 - -#define OMAP3430_SR_ERRWEIGHT		0x04 -#define OMAP3430_SR_ERRMAXLIMIT		0x02 - -/** - * struct omap_sr_pmic_data - Strucutre to be populated by pmic code to pass - *				pmic specific info to smartreflex driver - * - * @sr_pmic_init:	API to initialize smartreflex on the PMIC side. - */ -struct omap_sr_pmic_data { -	void (*sr_pmic_init) (void); -}; - -/** - * struct omap_smartreflex_dev_attr - Smartreflex Device attribute. - * - * @sensor_voltdm_name:       Name of voltdomain of SR instance - */ -struct omap_smartreflex_dev_attr { -	const char      *sensor_voltdm_name; -}; - -#ifdef CONFIG_OMAP_SMARTREFLEX -/* - * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR. - * The smartreflex class driver should pass the class type. - * Should be used to populate the class_type field of the - * omap_smartreflex_class_data structure. - */ -#define SR_CLASS1	0x1 -#define SR_CLASS2	0x2 -#define SR_CLASS3	0x3 - -/** - * struct omap_sr_class_data - Smartreflex class driver info - * - * @enable:		API to enable a particular class smaartreflex. - * @disable:		API to disable a particular class smartreflex. - * @configure:		API to configure a particular class smartreflex. - * @notify:		API to notify the class driver about an event in SR. - *			Not needed for class3. - * @notify_flags:	specify the events to be notified to the class driver - * @class_type:		specify which smartreflex class. - *			Can be used by the SR driver to take any class - *			based decisions. - */ -struct omap_sr_class_data { -	int (*enable)(struct voltagedomain *voltdm); -	int (*disable)(struct voltagedomain *voltdm, int is_volt_reset); -	int (*configure)(struct voltagedomain *voltdm); -	int (*notify)(struct voltagedomain *voltdm, u32 status); -	u8 notify_flags; -	u8 class_type; -}; - -/** - * struct omap_sr_nvalue_table	- Smartreflex n-target value info - * - * @efuse_offs:	The offset of the efuse where n-target values are stored. - * @nvalue:	The n-target value. - */ -struct omap_sr_nvalue_table { -	u32 efuse_offs; -	u32 nvalue; -}; - -/** - * struct omap_sr_data - Smartreflex platform data. - * - * @ip_type:		Smartreflex IP type. - * @senp_mod:		SENPENABLE value for the sr - * @senn_mod:		SENNENABLE value for sr - * @nvalue_count:	Number of distinct nvalues in the nvalue table - * @enable_on_init:	whether this sr module needs to enabled at - *			boot up or not. - * @nvalue_table:	table containing the  efuse offsets and nvalues - *			corresponding to them. - * @voltdm:		Pointer to the voltage domain associated with the SR - */ -struct omap_sr_data { -	int				ip_type; -	u32				senp_mod; -	u32				senn_mod; -	int				nvalue_count; -	bool				enable_on_init; -	struct omap_sr_nvalue_table	*nvalue_table; -	struct voltagedomain		*voltdm; -}; - -/* Smartreflex module enable/disable interface */ -void omap_sr_enable(struct voltagedomain *voltdm); -void omap_sr_disable(struct voltagedomain *voltdm); -void omap_sr_disable_reset_volt(struct voltagedomain *voltdm); - -/* API to register the pmic specific data with the smartreflex driver. */ -void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data); - -/* Smartreflex driver hooks to be called from Smartreflex class driver */ -int sr_enable(struct voltagedomain *voltdm, unsigned long volt); -void sr_disable(struct voltagedomain *voltdm); -int sr_configure_errgen(struct voltagedomain *voltdm); -int sr_disable_errgen(struct voltagedomain *voltdm); -int sr_configure_minmax(struct voltagedomain *voltdm); - -/* API to register the smartreflex class driver with the smartreflex driver */ -int sr_register_class(struct omap_sr_class_data *class_data); -#else -static inline void omap_sr_enable(struct voltagedomain *voltdm) {} -static inline void omap_sr_disable(struct voltagedomain *voltdm) {} -static inline void omap_sr_disable_reset_volt( -		struct voltagedomain *voltdm) {} -static inline void omap_sr_register_pmic( -		struct omap_sr_pmic_data *pmic_data) {} -#endif -#endif diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index a503e1e8358..d033a65f4e4 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c @@ -17,6 +17,7 @@   * 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> @@ -24,7 +25,6 @@  #include <plat/omap_device.h> -#include "smartreflex.h"  #include "voltage.h"  #include "control.h"  #include "pm.h" @@ -36,7 +36,10 @@ 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, count = 0; +	int i, j, count = 0; + +	sr_data->nvalue_count = 0; +	sr_data->nvalue_table = NULL;  	while (volt_data[count].volt_nominal)  		count++; @@ -44,8 +47,14 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data,  	nvalue_table = kzalloc(sizeof(struct omap_sr_nvalue_table)*count,  			GFP_KERNEL); -	for (i = 0; i < count; i++) { +	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 __raw_readl will fail for non-32 bit aligned address @@ -58,15 +67,30 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data,  				omap_ctrl_readb(offset + 1) << 8 |  				omap_ctrl_readb(offset + 2) << 16;  		} else { -			 v = omap_ctrl_readl(volt_data[i].sr_efuse_offs); +			v = omap_ctrl_readl(volt_data[i].sr_efuse_offs);  		} -		nvalue_table[i].efuse_offs = volt_data[i].sr_efuse_offs; -		nvalue_table[i].nvalue = v; +		/* +		 * 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 = count; +	sr_data->nvalue_count = j;  }  static int __init sr_dev_init(struct omap_hwmod *oh, void *user) @@ -93,6 +117,7 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user)  		goto exit;  	} +	sr_data->name = oh->name;  	sr_data->ip_type = oh->class->rev;  	sr_data->senn_mod = 0x1;  	sr_data->senp_mod = 0x1; @@ -106,7 +131,7 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user)  	omap_voltage_get_volttable(sr_data->voltdm, &volt_data);  	if (!volt_data) { -		pr_warning("%s: No Voltage table registerd fo VDD%d." +		pr_warning("%s: No Voltage table registered fo VDD%d."  			"Something really wrong\n\n", __func__, i + 1);  		goto exit;  	} diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 9b7a0736061..2ff6d41ec6c 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -69,11 +69,6 @@  #define OMAP3_SECURE_TIMER	1  #endif -/* MAX_GPTIMER_ID: number of GPTIMERs on the chip */ -#define MAX_GPTIMER_ID		12 - -static u32 sys_timer_reserved; -  /* Clockevent code */  static struct omap_dm_timer clkev; @@ -174,14 +169,14 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,  		return -ENXIO;  	/* After the dmtimer is using hwmod these clocks won't be needed */ -	sprintf(name, "gpt%d_fck", gptimer_id); -	timer->fclk = clk_get(NULL, name); +	timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh));  	if (IS_ERR(timer->fclk))  		return -ENODEV;  	omap_hwmod_enable(oh); -	sys_timer_reserved |= (1 << (gptimer_id - 1)); +	if (omap_dm_timer_reserve_systimer(gptimer_id)) +		return -ENODEV;  	if (gptimer_id != 12) {  		struct clk *src; @@ -370,6 +365,11 @@ OMAP_SYS_TIMER_INIT(3_secure, OMAP3_SECURE_TIMER, OMAP3_CLKEV_SOURCE,  OMAP_SYS_TIMER(3_secure)  #endif +#ifdef CONFIG_SOC_AM33XX +OMAP_SYS_TIMER_INIT(3_am33xx, 1, OMAP4_MPU_SOURCE, 2, OMAP4_MPU_SOURCE) +OMAP_SYS_TIMER(3_am33xx) +#endif +  #ifdef CONFIG_ARCH_OMAP4  #ifdef CONFIG_LOCAL_TIMERS  static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, @@ -395,65 +395,10 @@ static void __init omap4_timer_init(void)  OMAP_SYS_TIMER(4)  #endif -/** - * omap2_dm_timer_set_src - change the timer input clock source - * @pdev:	timer platform device pointer - * @source:	array index of parent clock source - */ -static int omap2_dm_timer_set_src(struct platform_device *pdev, int source) -{ -	int ret; -	struct dmtimer_platform_data *pdata = pdev->dev.platform_data; -	struct clk *fclk, *parent; -	char *parent_name = NULL; - -	fclk = clk_get(&pdev->dev, "fck"); -	if (IS_ERR_OR_NULL(fclk)) { -		dev_err(&pdev->dev, "%s: %d: clk_get() FAILED\n", -				__func__, __LINE__); -		return -EINVAL; -	} - -	switch (source) { -	case OMAP_TIMER_SRC_SYS_CLK: -		parent_name = "sys_ck"; -		break; - -	case OMAP_TIMER_SRC_32_KHZ: -		parent_name = "32k_ck"; -		break; - -	case OMAP_TIMER_SRC_EXT_CLK: -		if (pdata->timer_ip_version == OMAP_TIMER_IP_VERSION_1) { -			parent_name = "alt_ck"; -			break; -		} -		dev_err(&pdev->dev, "%s: %d: invalid clk src.\n", -			__func__, __LINE__); -		clk_put(fclk); -		return -EINVAL; -	} - -	parent = clk_get(&pdev->dev, parent_name); -	if (IS_ERR_OR_NULL(parent)) { -		dev_err(&pdev->dev, "%s: %d: clk_get() %s FAILED\n", -			__func__, __LINE__, parent_name); -		clk_put(fclk); -		return -EINVAL; -	} - -	ret = clk_set_parent(fclk, parent); -	if (IS_ERR_VALUE(ret)) { -		dev_err(&pdev->dev, "%s: clk_set_parent() to %s FAILED\n", -			__func__, parent_name); -		ret = -EINVAL; -	} - -	clk_put(parent); -	clk_put(fclk); - -	return ret; -} +#ifdef CONFIG_SOC_OMAP5 +OMAP_SYS_TIMER_INIT(5, 1, OMAP4_CLKEV_SOURCE, 2, OMAP4_MPU_SOURCE) +OMAP_SYS_TIMER(5) +#endif  /**   * omap_timer_init - build and register timer device with an @@ -475,7 +420,6 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)  	struct dmtimer_platform_data *pdata;  	struct platform_device *pdev;  	struct omap_timer_capability_dev_attr *timer_dev_attr; -	struct powerdomain *pwrdm;  	pr_debug("%s: %s\n", __func__, oh->name); @@ -503,18 +447,9 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)  	 */  	sscanf(oh->name, "timer%2d", &id); -	pdata->set_timer_src = omap2_dm_timer_set_src; -	pdata->timer_ip_version = oh->class->rev; +	if (timer_dev_attr) +		pdata->timer_capability = timer_dev_attr->timer_capability; -	/* Mark clocksource and clockevent timers as reserved */ -	if ((sys_timer_reserved >> (id - 1)) & 0x1) -		pdata->reserved = 1; - -	pwrdm = omap_hwmod_get_pwrdm(oh); -	pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm); -#ifdef CONFIG_PM -	pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count; -#endif  	pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata),  				 NULL, 0, 0); diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 43a97907533..de47f170ba5 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -49,6 +49,7 @@ static struct i2c_board_info __initdata omap4_i2c1_board_info[] = {  	},  }; +#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; @@ -60,6 +61,7 @@ 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, @@ -94,7 +96,7 @@ void __init omap4_pmic_init(const char *pmic_type,  void __init omap_pmic_late_init(void)  { -	/* Init the OMAP TWL parameters (if PMIC has been registerd) */ +	/* Init the OMAP TWL parameters (if PMIC has been registered) */  	if (pmic_i2c_board_info.irq)  		omap3_twl_init();  	if (omap4_i2c1_board_info[0].irq) @@ -213,10 +215,6 @@ static struct twl_regulator_driver_data omap3_vdd2_drvdata = {  void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,  				  u32 pdata_flags, u32 regulators_flags)  { -	if (!pmic_data->irq_base) -		pmic_data->irq_base = TWL4030_IRQ_BASE; -	if (!pmic_data->irq_end) -		pmic_data->irq_end = TWL4030_IRQ_END;  	if (!pmic_data->vdd1) {  		omap3_vdd1.driver_data = &omap3_vdd1_drvdata;  		omap3_vdd1_drvdata.data = voltdm_lookup("mpu_iva"); @@ -481,11 +479,6 @@ static struct regulator_init_data omap4_v2v1_idata = {  void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,  				  u32 pdata_flags, u32 regulators_flags)  { -	if (!pmic_data->irq_base) -		pmic_data->irq_base = TWL6030_IRQ_BASE; -	if (!pmic_data->irq_end) -		pmic_data->irq_end = TWL6030_IRQ_END; -  	if (!pmic_data->vdd1) {  		omap4_vdd1.driver_data = &omap4_vdd1_drvdata;  		omap4_vdd1_drvdata.data = voltdm_lookup("mpu"); diff --git a/arch/arm/mach-omap2/usb-fs.c b/arch/arm/mach-omap2/usb-fs.c deleted file mode 100644 index 1481078763b..00000000000 --- a/arch/arm/mach-omap2/usb-fs.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Platform level USB initialization for FS USB OTG controller on omap1 and 24xx - * - * Copyright (C) 2004 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. - * - * 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/types.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/clk.h> -#include <linux/err.h> - -#include <asm/irq.h> - -#include <plat/usb.h> -#include <plat/board.h> - -#include "control.h" -#include "mux.h" - -#define INT_USB_IRQ_GEN		INT_24XX_USB_IRQ_GEN -#define INT_USB_IRQ_NISO	INT_24XX_USB_IRQ_NISO -#define INT_USB_IRQ_ISO		INT_24XX_USB_IRQ_ISO -#define INT_USB_IRQ_HGEN	INT_24XX_USB_IRQ_HGEN -#define INT_USB_IRQ_OTG		INT_24XX_USB_IRQ_OTG - -#if defined(CONFIG_ARCH_OMAP2) - -#ifdef	CONFIG_USB_GADGET_OMAP - -static struct resource udc_resources[] = { -	/* order is significant! */ -	{		/* registers */ -		.start		= UDC_BASE, -		.end		= UDC_BASE + 0xff, -		.flags		= IORESOURCE_MEM, -	}, {		/* general IRQ */ -		.start		= INT_USB_IRQ_GEN, -		.flags		= IORESOURCE_IRQ, -	}, {		/* PIO IRQ */ -		.start		= INT_USB_IRQ_NISO, -		.flags		= IORESOURCE_IRQ, -	}, {		/* SOF IRQ */ -		.start		= INT_USB_IRQ_ISO, -		.flags		= IORESOURCE_IRQ, -	}, -}; - -static u64 udc_dmamask = ~(u32)0; - -static struct platform_device udc_device = { -	.name		= "omap_udc", -	.id		= -1, -	.dev = { -		.dma_mask		= &udc_dmamask, -		.coherent_dma_mask	= 0xffffffff, -	}, -	.num_resources	= ARRAY_SIZE(udc_resources), -	.resource	= udc_resources, -}; - -static inline void udc_device_init(struct omap_usb_config *pdata) -{ -	pdata->udc_device = &udc_device; -} - -#else - -static inline void udc_device_init(struct omap_usb_config *pdata) -{ -} - -#endif - -#if	defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) - -/* The dmamask must be set for OHCI to work */ -static u64 ohci_dmamask = ~(u32)0; - -static struct resource ohci_resources[] = { -	{ -		.start	= OMAP_OHCI_BASE, -		.end	= OMAP_OHCI_BASE + 0xff, -		.flags	= IORESOURCE_MEM, -	}, -	{ -		.start	= INT_USB_IRQ_HGEN, -		.flags	= IORESOURCE_IRQ, -	}, -}; - -static struct platform_device ohci_device = { -	.name			= "ohci", -	.id			= -1, -	.dev = { -		.dma_mask		= &ohci_dmamask, -		.coherent_dma_mask	= 0xffffffff, -	}, -	.num_resources	= ARRAY_SIZE(ohci_resources), -	.resource		= ohci_resources, -}; - -static inline void ohci_device_init(struct omap_usb_config *pdata) -{ -	pdata->ohci_device = &ohci_device; -} - -#else - -static inline void ohci_device_init(struct omap_usb_config *pdata) -{ -} - -#endif - -#if	defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG) - -static struct resource otg_resources[] = { -	/* order is significant! */ -	{ -		.start		= OTG_BASE, -		.end		= OTG_BASE + 0xff, -		.flags		= IORESOURCE_MEM, -	}, { -		.start		= INT_USB_IRQ_OTG, -		.flags		= IORESOURCE_IRQ, -	}, -}; - -static struct platform_device otg_device = { -	.name		= "omap_otg", -	.id		= -1, -	.num_resources	= ARRAY_SIZE(otg_resources), -	.resource	= otg_resources, -}; - -static inline void otg_device_init(struct omap_usb_config *pdata) -{ -	pdata->otg_device = &otg_device; -} - -#else - -static inline void otg_device_init(struct omap_usb_config *pdata) -{ -} - -#endif - -static void omap2_usb_devconf_clear(u8 port, u32 mask) -{ -	u32 r; - -	r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); -	r &= ~USBTXWRMODEI(port, mask); -	omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); -} - -static void omap2_usb_devconf_set(u8 port, u32 mask) -{ -	u32 r; - -	r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); -	r |= USBTXWRMODEI(port, mask); -	omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); -} - -static void omap2_usb2_disable_5pinbitll(void) -{ -	u32 r; - -	r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); -	r &= ~(USBTXWRMODEI(2, USB_BIDIR_TLL) | USBT2TLL5PI); -	omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); -} - -static void omap2_usb2_enable_5pinunitll(void) -{ -	u32 r; - -	r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); -	r |= USBTXWRMODEI(2, USB_UNIDIR_TLL) | USBT2TLL5PI; -	omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); -} - -static u32 __init omap2_usb0_init(unsigned nwires, unsigned is_device) -{ -	u32	syscon1 = 0; - -	omap2_usb_devconf_clear(0, USB_BIDIR_TLL); - -	if (nwires == 0) -		return 0; - -	if (is_device) -		omap_mux_init_signal("usb0_puen", 0); - -	omap_mux_init_signal("usb0_dat", 0); -	omap_mux_init_signal("usb0_txen", 0); -	omap_mux_init_signal("usb0_se0", 0); -	if (nwires != 3) -		omap_mux_init_signal("usb0_rcv", 0); - -	switch (nwires) { -	case 3: -		syscon1 = 2; -		omap2_usb_devconf_set(0, USB_BIDIR); -		break; -	case 4: -		syscon1 = 1; -		omap2_usb_devconf_set(0, USB_BIDIR); -		break; -	case 6: -		syscon1 = 3; -		omap_mux_init_signal("usb0_vp", 0); -		omap_mux_init_signal("usb0_vm", 0); -		omap2_usb_devconf_set(0, USB_UNIDIR); -		break; -	default: -		printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", -			0, nwires); -	} - -	return syscon1 << 16; -} - -static u32 __init omap2_usb1_init(unsigned nwires) -{ -	u32	syscon1 = 0; - -	omap2_usb_devconf_clear(1, USB_BIDIR_TLL); - -	if (nwires == 0) -		return 0; - -	/* NOTE:  board-specific code must set up pin muxing for usb1, -	 * since each signal could come out on either of two balls. -	 */ - -	switch (nwires) { -	case 2: -		/* NOTE: board-specific code must override this setting if -		 * this TLL link is not using DP/DM -		 */ -		syscon1 = 1; -		omap2_usb_devconf_set(1, USB_BIDIR_TLL); -		break; -	case 3: -		syscon1 = 2; -		omap2_usb_devconf_set(1, USB_BIDIR); -		break; -	case 4: -		syscon1 = 1; -		omap2_usb_devconf_set(1, USB_BIDIR); -		break; -	case 6: -	default: -		printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", -			1, nwires); -	} - -	return syscon1 << 20; -} - -static u32 __init omap2_usb2_init(unsigned nwires, unsigned alt_pingroup) -{ -	u32	syscon1 = 0; - -	omap2_usb2_disable_5pinbitll(); -	alt_pingroup = 0; - -	/* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */ -	if (alt_pingroup || nwires == 0) -		return 0; - -	omap_mux_init_signal("usb2_dat", 0); -	omap_mux_init_signal("usb2_se0", 0); -	if (nwires > 2) -		omap_mux_init_signal("usb2_txen", 0); -	if (nwires > 3) -		omap_mux_init_signal("usb2_rcv", 0); - -	switch (nwires) { -	case 2: -		/* NOTE: board-specific code must override this setting if -		 * this TLL link is not using DP/DM -		 */ -		syscon1 = 1; -		omap2_usb_devconf_set(2, USB_BIDIR_TLL); -		break; -	case 3: -		syscon1 = 2; -		omap2_usb_devconf_set(2, USB_BIDIR); -		break; -	case 4: -		syscon1 = 1; -		omap2_usb_devconf_set(2, USB_BIDIR); -		break; -	case 5: -		/* NOTE: board-specific code must mux this setting depending -		 * on TLL link using DP/DM.  Something must also -		 * set up OTG_SYSCON2.HMC_TLL{ATTACH,SPEED} -		 * 2420: hdq_sio.usb2_tllse0 or vlynq_rx0.usb2_tllse0 -		 * 2430: hdq_sio.usb2_tllse0 or sdmmc2_dat0.usb2_tllse0 -		 */ - -		syscon1 = 3; -		omap2_usb2_enable_5pinunitll(); -		break; -	case 6: -	default: -		printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", -			2, nwires); -	} - -	return syscon1 << 24; -} - -void __init omap2_usbfs_init(struct omap_usb_config *pdata) -{ -	struct clk *ick; - -	if (!cpu_is_omap24xx()) -		return; - -	ick = clk_get(NULL, "usb_l4_ick"); -	if (IS_ERR(ick)) -		return; - -	clk_enable(ick); -	pdata->usb0_init = omap2_usb0_init; -	pdata->usb1_init = omap2_usb1_init; -	pdata->usb2_init = omap2_usb2_init; -	udc_device_init(pdata); -	ohci_device_init(pdata); -	otg_device_init(pdata); -	omap_otg_init(pdata); -	clk_disable(ick); -	clk_put(ick); -} - -#endif diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h index 16a1b092cf3..0ac2caf1594 100644 --- a/arch/arm/mach-omap2/voltage.h +++ b/arch/arm/mach-omap2/voltage.h @@ -16,6 +16,8 @@  #include <linux/err.h> +#include <plat/voltage.h> +  #include "vc.h"  #include "vp.h" @@ -91,25 +93,6 @@ struct voltagedomain {  };  /** - * struct omap_volt_data - Omap voltage specific data. - * @voltage_nominal:	The possible voltage value in uV - * @sr_efuse_offs:	The offset of the efuse register(from system - *			control module base address) from where to read - *			the n-target value for the smartreflex module. - * @sr_errminlimit:	Error min limit value for smartreflex. This value - *			differs at differnet opp and thus is linked - *			with voltage. - * @vp_errorgain:	Error gain value for the voltage processor. This - *			field also differs according to the voltage/opp. - */ -struct omap_volt_data { -	u32	volt_nominal; -	u32	sr_efuse_offs; -	u8	sr_errminlimit; -	u8	vp_errgain; -}; - -/**   * 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) @@ -156,6 +139,7 @@ int omap_voltage_late_init(void);  extern void omap2xxx_voltagedomains_init(void);  extern void omap3xxx_voltagedomains_init(void); +extern void am33xx_voltagedomains_init(void);  extern void omap44xx_voltagedomains_init(void);  struct voltagedomain *voltdm_lookup(const char *name); diff --git a/arch/arm/mach-omap2/voltagedomains33xx_data.c b/arch/arm/mach-omap2/voltagedomains33xx_data.c new file mode 100644 index 00000000000..965458dc0cb --- /dev/null +++ b/arch/arm/mach-omap2/voltagedomains33xx_data.c @@ -0,0 +1,43 @@ +/* + * AM33XX voltage domain data + * + * Copyright (C) 2011 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 "voltage.h" + +static struct voltagedomain am33xx_voltdm_mpu = { +	.name		= "mpu", +}; + +static struct voltagedomain am33xx_voltdm_core = { +	.name		= "core", +}; + +static struct voltagedomain am33xx_voltdm_rtc = { +	.name		= "rtc", +}; + +static struct voltagedomain *voltagedomains_am33xx[] __initdata = { +	&am33xx_voltdm_mpu, +	&am33xx_voltdm_core, +	&am33xx_voltdm_rtc, +	NULL, +}; + +void __init am33xx_voltagedomains_init(void) +{ +	voltdm_init(voltagedomains_am33xx); +}  |