diff options
Diffstat (limited to 'arch/arm/mach-omap2')
24 files changed, 491 insertions, 603 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index c81bc508e7a..be0f62bf903 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -275,14 +275,14 @@ config MACH_NOKIA_N8X0  	select OMAP_PACKAGE_ZAC  config MACH_NOKIA_RM680 -	bool "Nokia RM-680/696 board" +	bool "Nokia N950 (RM-680) / N9 (RM-696) phones"  	depends on ARCH_OMAP3  	default y  	select MACH_NOKIA_RM696  	select OMAP_PACKAGE_CBB  config MACH_NOKIA_RX51 -	bool "Nokia RX-51 board" +	bool "Nokia N900 (RX-51) phone"  	depends on ARCH_OMAP3  	default y  	select OMAP_PACKAGE_CBB diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 745401020c2..a8004f33b7e 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -202,8 +202,6 @@ obj-$(CONFIG_HW_PERF_EVENTS)		+= pmu.o  obj-$(CONFIG_OMAP_MBOX_FWK)		+= mailbox_mach.o  mailbox_mach-objs			:= mailbox.o -obj-$(CONFIG_OMAP_IOMMU)		+= iommu2.o -  iommu-$(CONFIG_OMAP_IOMMU)		:= omap-iommu.o  obj-y					+= $(iommu-m) $(iommu-y) @@ -297,4 +295,4 @@ endif  emac-$(CONFIG_TI_DAVINCI_EMAC)		:= am35xx-emac.o  obj-y					+= $(emac-m) $(emac-y) -obj-y					+= common-board-devices.o twl-common.o +obj-y					+= common-board-devices.o twl-common.o dss-common.o diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 85dfa71e0dc..1cc6696594f 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -36,9 +36,6 @@  #include "common.h"  #include "omap4-keypad.h" -#include <video/omapdss.h> -#include <video/omap-panel-nokia-dsi.h> -#include <video/omap-panel-picodlp.h>  #include <linux/wl12xx.h>  #include <linux/platform_data/omap-abe-twl6040.h> @@ -48,17 +45,13 @@  #include "hsmmc.h"  #include "control.h"  #include "common-board-devices.h" +#include "dss-common.h"  #define ETH_KS8851_IRQ			34  #define ETH_KS8851_POWER_ON		48  #define ETH_KS8851_QUART		138  #define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO	184  #define OMAP4_SFH7741_ENABLE_GPIO		188 -#define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */ -#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */ -#define HDMI_GPIO_HPD  63 /* Hotplug detect */ -#define DISPLAY_SEL_GPIO	59	/* LCD2/PicoDLP switch */ -#define DLP_POWER_ON_GPIO	40  #define GPIO_WIFI_PMENA		54  #define GPIO_WIFI_IRQ		53 @@ -607,154 +600,6 @@ static void __init omap_sfh7741prox_init(void)  			__func__, OMAP4_SFH7741_ENABLE_GPIO, error);  } -static struct nokia_dsi_panel_data dsi1_panel = { -		.name		= "taal", -		.reset_gpio	= 102, -		.use_ext_te	= false, -		.ext_te_gpio	= 101, -		.esd_interval	= 0, -		.pin_config = { -			.num_pins	= 6, -			.pins		= { 0, 1, 2, 3, 4, 5 }, -		}, -}; - -static struct omap_dss_device sdp4430_lcd_device = { -	.name			= "lcd", -	.driver_name		= "taal", -	.type			= OMAP_DISPLAY_TYPE_DSI, -	.data			= &dsi1_panel, -	.phy.dsi		= { -		.module		= 0, -	}, -	.channel		= OMAP_DSS_CHANNEL_LCD, -}; - -static struct nokia_dsi_panel_data dsi2_panel = { -		.name		= "taal", -		.reset_gpio	= 104, -		.use_ext_te	= false, -		.ext_te_gpio	= 103, -		.esd_interval	= 0, -		.pin_config = { -			.num_pins	= 6, -			.pins		= { 0, 1, 2, 3, 4, 5 }, -		}, -}; - -static struct omap_dss_device sdp4430_lcd2_device = { -	.name			= "lcd2", -	.driver_name		= "taal", -	.type			= OMAP_DISPLAY_TYPE_DSI, -	.data			= &dsi2_panel, -	.phy.dsi		= { - -		.module		= 1, -	}, -	.channel		= OMAP_DSS_CHANNEL_LCD2, -}; - -static struct omap_dss_hdmi_data sdp4430_hdmi_data = { -	.ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD, -	.ls_oe_gpio = HDMI_GPIO_LS_OE, -	.hpd_gpio = HDMI_GPIO_HPD, -}; - -static struct omap_dss_device sdp4430_hdmi_device = { -	.name = "hdmi", -	.driver_name = "hdmi_panel", -	.type = OMAP_DISPLAY_TYPE_HDMI, -	.channel = OMAP_DSS_CHANNEL_DIGIT, -	.data = &sdp4430_hdmi_data, -}; - -static struct picodlp_panel_data sdp4430_picodlp_pdata = { -	.picodlp_adapter_id	= 2, -	.emu_done_gpio		= 44, -	.pwrgood_gpio		= 45, -}; - -static void sdp4430_picodlp_init(void) -{ -	int r; -	const struct gpio picodlp_gpios[] = { -		{DLP_POWER_ON_GPIO, GPIOF_OUT_INIT_LOW, -			"DLP POWER ON"}, -		{sdp4430_picodlp_pdata.emu_done_gpio, GPIOF_IN, -			"DLP EMU DONE"}, -		{sdp4430_picodlp_pdata.pwrgood_gpio, GPIOF_OUT_INIT_LOW, -			"DLP PWRGOOD"}, -	}; - -	r = gpio_request_array(picodlp_gpios, ARRAY_SIZE(picodlp_gpios)); -	if (r) -		pr_err("Cannot request PicoDLP GPIOs, error %d\n", r); -} - -static int sdp4430_panel_enable_picodlp(struct omap_dss_device *dssdev) -{ -	gpio_set_value(DISPLAY_SEL_GPIO, 0); -	gpio_set_value(DLP_POWER_ON_GPIO, 1); - -	return 0; -} - -static void sdp4430_panel_disable_picodlp(struct omap_dss_device *dssdev) -{ -	gpio_set_value(DLP_POWER_ON_GPIO, 0); -	gpio_set_value(DISPLAY_SEL_GPIO, 1); -} - -static struct omap_dss_device sdp4430_picodlp_device = { -	.name			= "picodlp", -	.driver_name		= "picodlp_panel", -	.type			= OMAP_DISPLAY_TYPE_DPI, -	.phy.dpi.data_lines	= 24, -	.channel		= OMAP_DSS_CHANNEL_LCD2, -	.platform_enable	= sdp4430_panel_enable_picodlp, -	.platform_disable	= sdp4430_panel_disable_picodlp, -	.data			= &sdp4430_picodlp_pdata, -}; - -static struct omap_dss_device *sdp4430_dss_devices[] = { -	&sdp4430_lcd_device, -	&sdp4430_lcd2_device, -	&sdp4430_hdmi_device, -	&sdp4430_picodlp_device, -}; - -static struct omap_dss_board_info sdp4430_dss_data = { -	.num_devices	= ARRAY_SIZE(sdp4430_dss_devices), -	.devices	= sdp4430_dss_devices, -	.default_device	= &sdp4430_lcd_device, -}; - -static void __init omap_4430sdp_display_init(void) -{ -	int r; - -	/* Enable LCD2 by default (instead of Pico DLP) */ -	r = gpio_request_one(DISPLAY_SEL_GPIO, GPIOF_OUT_INIT_HIGH, -			"display_sel"); -	if (r) -		pr_err("%s: Could not get display_sel GPIO\n", __func__); - -	sdp4430_picodlp_init(); -	omap_display_init(&sdp4430_dss_data); -	/* -	 * OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and -	 * later have external pull up on the HDMI I2C lines -	 */ -	if (cpu_is_omap446x() || omap_rev() > OMAP4430_REV_ES2_2) -		omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP); -	else -		omap_hdmi_init(0); - -	omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT); -	omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT); -	omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN); -} -  #ifdef CONFIG_OMAP_MUX  static struct omap_board_mux board_mux[] __initdata = {  	OMAP4_MUX(USBB2_ULPITLL_CLK, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index f0715a369c4..53cb380b787 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -21,6 +21,7 @@  #include "common.h"  #include "common-board-devices.h" +#include "dss-common.h"  #if !(defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3))  #define intc_of_init	NULL @@ -40,6 +41,15 @@ static void __init omap_generic_init(void)  	omap_sdrc_init(NULL, NULL);  	of_platform_populate(NULL, omap_dt_match_table, NULL, NULL); + +	/* +	 * HACK: call display setup code for selected boards to enable omapdss. +	 * This will be removed when omapdss supports DT. +	 */ +	if (of_machine_is_compatible("ti,omap4-panda")) +		omap4_panda_display_init_of(); +	else if (of_machine_is_compatible("ti,omap4-sdp")) +		omap_4430sdp_display_init_of();  }  #ifdef CONFIG_SOC_OMAP2420 diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 12a3a24d5bb..5c8e9cee2c2 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -37,9 +37,6 @@  #include <asm/mach-types.h>  #include <asm/mach/arch.h>  #include <asm/mach/map.h> -#include <video/omapdss.h> - -#include <video/omap-panel-tfp410.h>  #include "common.h"  #include "soc.h" @@ -48,14 +45,12 @@  #include "control.h"  #include "mux.h"  #include "common-board-devices.h" +#include "dss-common.h"  #define GPIO_HUB_POWER		1  #define GPIO_HUB_NRESET		62  #define GPIO_WIFI_PMENA		43  #define GPIO_WIFI_IRQ		53 -#define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */ -#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */ -#define HDMI_GPIO_HPD  63 /* Hotplug detect */  /* wl127x BT, FM, GPS connectivity chip */  static struct ti_st_plat_data wilink_platform_data = { @@ -409,68 +404,6 @@ static struct omap_board_mux board_mux[] __initdata = {  #define board_mux	NULL  #endif -/* Display DVI */ -#define PANDA_DVI_TFP410_POWER_DOWN_GPIO	0 - -/* Using generic display panel */ -static struct tfp410_platform_data omap4_dvi_panel = { -	.i2c_bus_num		= 3, -	.power_down_gpio	= PANDA_DVI_TFP410_POWER_DOWN_GPIO, -}; - -static struct omap_dss_device omap4_panda_dvi_device = { -	.type			= OMAP_DISPLAY_TYPE_DPI, -	.name			= "dvi", -	.driver_name		= "tfp410", -	.data			= &omap4_dvi_panel, -	.phy.dpi.data_lines	= 24, -	.reset_gpio		= PANDA_DVI_TFP410_POWER_DOWN_GPIO, -	.channel		= OMAP_DSS_CHANNEL_LCD2, -}; - -static struct omap_dss_hdmi_data omap4_panda_hdmi_data = { -	.ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD, -	.ls_oe_gpio = HDMI_GPIO_LS_OE, -	.hpd_gpio = HDMI_GPIO_HPD, -}; - -static struct omap_dss_device  omap4_panda_hdmi_device = { -	.name = "hdmi", -	.driver_name = "hdmi_panel", -	.type = OMAP_DISPLAY_TYPE_HDMI, -	.channel = OMAP_DSS_CHANNEL_DIGIT, -	.data = &omap4_panda_hdmi_data, -}; - -static struct omap_dss_device *omap4_panda_dss_devices[] = { -	&omap4_panda_dvi_device, -	&omap4_panda_hdmi_device, -}; - -static struct omap_dss_board_info omap4_panda_dss_data = { -	.num_devices	= ARRAY_SIZE(omap4_panda_dss_devices), -	.devices	= omap4_panda_dss_devices, -	.default_device	= &omap4_panda_dvi_device, -}; - -static void __init omap4_panda_display_init(void) -{ - -	omap_display_init(&omap4_panda_dss_data); - -	/* -	 * OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and -	 * later have external pull up on the HDMI I2C lines -	 */ -	if (cpu_is_omap446x() || omap_rev() > OMAP4430_REV_ES2_2) -		omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP); -	else -		omap_hdmi_init(0); - -	omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT); -	omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT); -	omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN); -}  static void omap4_panda_init_rev(void)  { diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c index cbcb1b2dc31..0c777b75e48 100644 --- a/arch/arm/mach-omap2/board-rm680.c +++ b/arch/arm/mach-omap2/board-rm680.c @@ -1,5 +1,5 @@  /* - * Board support file for Nokia RM-680/696. + * Board support file for Nokia N950 (RM-680) / N9 (RM-696).   *   * Copyright (C) 2010 Nokia   * diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c index ee1045c0ad6..f1d6efe079c 100644 --- a/arch/arm/mach-omap2/board-rx51.c +++ b/arch/arm/mach-omap2/board-rx51.c @@ -1,5 +1,5 @@  /* - * linux/arch/arm/mach-omap2/board-rx51.c + * Board support file for Nokia N900 (aka RX-51).   *   * Copyright (C) 2007, 2008 Nokia   * diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 3bbcde87dea..948bcaa82eb 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -214,6 +214,9 @@ static inline void __iomem *omap4_get_scu_base(void)  #endif  extern void __init gic_init_irq(void); +extern void gic_dist_disable(void); +extern bool gic_dist_disabled(void); +extern void gic_timer_retrigger(void);  extern void omap_smc1(u32 fn, u32 arg);  extern void __iomem *omap4_get_sar_ram_base(void);  extern void omap_do_wfi(void); @@ -221,6 +224,7 @@ extern void omap_do_wfi(void);  #ifdef CONFIG_SMP  /* Needed for secondary core boot */  extern void omap_secondary_startup(void); +extern void omap_secondary_startup_4460(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); diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index cafe04660a4..c67a731cfbb 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -129,7 +129,7 @@ static struct platform_device omap2cam_device = {  #if defined(CONFIG_IOMMU_API) -#include <plat/iommu.h> +#include <linux/platform_data/iommu-omap.h>  static struct resource omap3isp_resources[] = {  	{ diff --git a/arch/arm/mach-omap2/drm.c b/arch/arm/mach-omap2/drm.c index 6282cc82661..fce5aa3fff4 100644 --- a/arch/arm/mach-omap2/drm.c +++ b/arch/arm/mach-omap2/drm.c @@ -23,15 +23,20 @@  #include <linux/init.h>  #include <linux/platform_device.h>  #include <linux/dma-mapping.h> +#include <linux/platform_data/omap_drm.h>  #include "omap_device.h"  #include "omap_hwmod.h" +#include <plat/cpu.h>  #if defined(CONFIG_DRM_OMAP) || (CONFIG_DRM_OMAP_MODULE) +static struct omap_drm_platform_data platform_data; +  static struct platform_device omap_drm_device = {  	.dev = {  		.coherent_dma_mask = DMA_BIT_MASK(32), +		.platform_data = &platform_data,  	},  	.name = "omapdrm",  	.id = 0, @@ -52,6 +57,8 @@ static int __init omap_init_drm(void)  			oh->name);  	} +	platform_data.omaprev = GET_OMAP_REVISION(); +  	return platform_device_register(&omap_drm_device);  } diff --git a/arch/arm/mach-omap2/dss-common.c b/arch/arm/mach-omap2/dss-common.c new file mode 100644 index 00000000000..679a0478644 --- /dev/null +++ b/arch/arm/mach-omap2/dss-common.c @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2012 Texas Instruments, Inc.. + * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +/* + * NOTE: this is a transitional file to help with DT adaptation. + * This file will be removed when DSS supports DT. + */ + +#include <linux/kernel.h> +#include <linux/gpio.h> + +#include <video/omapdss.h> +#include <video/omap-panel-tfp410.h> +#include <video/omap-panel-nokia-dsi.h> +#include <video/omap-panel-picodlp.h> + +#include <plat/cpu.h> + +#include "dss-common.h" +#include "mux.h" + +#define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */ +#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */ +#define HDMI_GPIO_HPD  63 /* Hotplug detect */ + +/* Display DVI */ +#define PANDA_DVI_TFP410_POWER_DOWN_GPIO	0 + +/* Using generic display panel */ +static struct tfp410_platform_data omap4_dvi_panel = { +	.i2c_bus_num		= 3, +	.power_down_gpio	= PANDA_DVI_TFP410_POWER_DOWN_GPIO, +}; + +static struct omap_dss_device omap4_panda_dvi_device = { +	.type			= OMAP_DISPLAY_TYPE_DPI, +	.name			= "dvi", +	.driver_name		= "tfp410", +	.data			= &omap4_dvi_panel, +	.phy.dpi.data_lines	= 24, +	.reset_gpio		= PANDA_DVI_TFP410_POWER_DOWN_GPIO, +	.channel		= OMAP_DSS_CHANNEL_LCD2, +}; + +static struct omap_dss_hdmi_data omap4_panda_hdmi_data = { +	.ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD, +	.ls_oe_gpio = HDMI_GPIO_LS_OE, +	.hpd_gpio = HDMI_GPIO_HPD, +}; + +static struct omap_dss_device  omap4_panda_hdmi_device = { +	.name = "hdmi", +	.driver_name = "hdmi_panel", +	.type = OMAP_DISPLAY_TYPE_HDMI, +	.channel = OMAP_DSS_CHANNEL_DIGIT, +	.data = &omap4_panda_hdmi_data, +}; + +static struct omap_dss_device *omap4_panda_dss_devices[] = { +	&omap4_panda_dvi_device, +	&omap4_panda_hdmi_device, +}; + +static struct omap_dss_board_info omap4_panda_dss_data = { +	.num_devices	= ARRAY_SIZE(omap4_panda_dss_devices), +	.devices	= omap4_panda_dss_devices, +	.default_device	= &omap4_panda_dvi_device, +}; + +void __init omap4_panda_display_init(void) +{ +	omap_display_init(&omap4_panda_dss_data); + +	/* +	 * OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and +	 * later have external pull up on the HDMI I2C lines +	 */ +	if (cpu_is_omap446x() || omap_rev() > OMAP4430_REV_ES2_2) +		omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP); +	else +		omap_hdmi_init(0); + +	omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT); +	omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT); +	omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN); +} + +void __init omap4_panda_display_init_of(void) +{ +	omap_display_init(&omap4_panda_dss_data); +} + + +/* OMAP4 Blaze display data */ + +#define DISPLAY_SEL_GPIO	59	/* LCD2/PicoDLP switch */ +#define DLP_POWER_ON_GPIO	40 + +static struct nokia_dsi_panel_data dsi1_panel = { +		.name		= "taal", +		.reset_gpio	= 102, +		.use_ext_te	= false, +		.ext_te_gpio	= 101, +		.esd_interval	= 0, +		.pin_config = { +			.num_pins	= 6, +			.pins		= { 0, 1, 2, 3, 4, 5 }, +		}, +}; + +static struct omap_dss_device sdp4430_lcd_device = { +	.name			= "lcd", +	.driver_name		= "taal", +	.type			= OMAP_DISPLAY_TYPE_DSI, +	.data			= &dsi1_panel, +	.phy.dsi		= { +		.module		= 0, +	}, +	.channel		= OMAP_DSS_CHANNEL_LCD, +}; + +static struct nokia_dsi_panel_data dsi2_panel = { +		.name		= "taal", +		.reset_gpio	= 104, +		.use_ext_te	= false, +		.ext_te_gpio	= 103, +		.esd_interval	= 0, +		.pin_config = { +			.num_pins	= 6, +			.pins		= { 0, 1, 2, 3, 4, 5 }, +		}, +}; + +static struct omap_dss_device sdp4430_lcd2_device = { +	.name			= "lcd2", +	.driver_name		= "taal", +	.type			= OMAP_DISPLAY_TYPE_DSI, +	.data			= &dsi2_panel, +	.phy.dsi		= { + +		.module		= 1, +	}, +	.channel		= OMAP_DSS_CHANNEL_LCD2, +}; + +static struct omap_dss_hdmi_data sdp4430_hdmi_data = { +	.ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD, +	.ls_oe_gpio = HDMI_GPIO_LS_OE, +	.hpd_gpio = HDMI_GPIO_HPD, +}; + +static struct omap_dss_device sdp4430_hdmi_device = { +	.name = "hdmi", +	.driver_name = "hdmi_panel", +	.type = OMAP_DISPLAY_TYPE_HDMI, +	.channel = OMAP_DSS_CHANNEL_DIGIT, +	.data = &sdp4430_hdmi_data, +}; + +static struct picodlp_panel_data sdp4430_picodlp_pdata = { +	.picodlp_adapter_id	= 2, +	.emu_done_gpio		= 44, +	.pwrgood_gpio		= 45, +}; + +static void sdp4430_picodlp_init(void) +{ +	int r; +	const struct gpio picodlp_gpios[] = { +		{DLP_POWER_ON_GPIO, GPIOF_OUT_INIT_LOW, +			"DLP POWER ON"}, +		{sdp4430_picodlp_pdata.emu_done_gpio, GPIOF_IN, +			"DLP EMU DONE"}, +		{sdp4430_picodlp_pdata.pwrgood_gpio, GPIOF_OUT_INIT_LOW, +			"DLP PWRGOOD"}, +	}; + +	r = gpio_request_array(picodlp_gpios, ARRAY_SIZE(picodlp_gpios)); +	if (r) +		pr_err("Cannot request PicoDLP GPIOs, error %d\n", r); +} + +static int sdp4430_panel_enable_picodlp(struct omap_dss_device *dssdev) +{ +	gpio_set_value(DISPLAY_SEL_GPIO, 0); +	gpio_set_value(DLP_POWER_ON_GPIO, 1); + +	return 0; +} + +static void sdp4430_panel_disable_picodlp(struct omap_dss_device *dssdev) +{ +	gpio_set_value(DLP_POWER_ON_GPIO, 0); +	gpio_set_value(DISPLAY_SEL_GPIO, 1); +} + +static struct omap_dss_device sdp4430_picodlp_device = { +	.name			= "picodlp", +	.driver_name		= "picodlp_panel", +	.type			= OMAP_DISPLAY_TYPE_DPI, +	.phy.dpi.data_lines	= 24, +	.channel		= OMAP_DSS_CHANNEL_LCD2, +	.platform_enable	= sdp4430_panel_enable_picodlp, +	.platform_disable	= sdp4430_panel_disable_picodlp, +	.data			= &sdp4430_picodlp_pdata, +}; + +static struct omap_dss_device *sdp4430_dss_devices[] = { +	&sdp4430_lcd_device, +	&sdp4430_lcd2_device, +	&sdp4430_hdmi_device, +	&sdp4430_picodlp_device, +}; + +static struct omap_dss_board_info sdp4430_dss_data = { +	.num_devices	= ARRAY_SIZE(sdp4430_dss_devices), +	.devices	= sdp4430_dss_devices, +	.default_device	= &sdp4430_lcd_device, +}; + +void __init omap_4430sdp_display_init(void) +{ +	int r; + +	/* Enable LCD2 by default (instead of Pico DLP) */ +	r = gpio_request_one(DISPLAY_SEL_GPIO, GPIOF_OUT_INIT_HIGH, +			"display_sel"); +	if (r) +		pr_err("%s: Could not get display_sel GPIO\n", __func__); + +	sdp4430_picodlp_init(); +	omap_display_init(&sdp4430_dss_data); +	/* +	 * OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and +	 * later have external pull up on the HDMI I2C lines +	 */ +	if (cpu_is_omap446x() || omap_rev() > OMAP4430_REV_ES2_2) +		omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP); +	else +		omap_hdmi_init(0); + +	omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT); +	omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT); +	omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN); +} + +void __init omap_4430sdp_display_init_of(void) +{ +	int r; + +	/* Enable LCD2 by default (instead of Pico DLP) */ +	r = gpio_request_one(DISPLAY_SEL_GPIO, GPIOF_OUT_INIT_HIGH, +			"display_sel"); +	if (r) +		pr_err("%s: Could not get display_sel GPIO\n", __func__); + +	sdp4430_picodlp_init(); +	omap_display_init(&sdp4430_dss_data); +} diff --git a/arch/arm/mach-omap2/dss-common.h b/arch/arm/mach-omap2/dss-common.h new file mode 100644 index 00000000000..915f6fff510 --- /dev/null +++ b/arch/arm/mach-omap2/dss-common.h @@ -0,0 +1,14 @@ +#ifndef __OMAP_DSS_COMMON__ +#define __OMAP_DSS_COMMON__ + +/* + * NOTE: this is a transitional file to help with DT adaptation. + * This file will be removed when DSS supports DT. + */ + +void __init omap4_panda_display_init(void); +void __init omap4_panda_display_init_of(void); +void __init omap_4430sdp_display_init(void); +void __init omap_4430sdp_display_init_of(void); + +#endif diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c deleted file mode 100644 index eefc37912ef..00000000000 --- a/arch/arm/mach-omap2/iommu2.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * omap iommu: omap2/3 architecture specific functions - * - * Copyright (C) 2008-2009 Nokia Corporation - * - * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>, - *		Paul Mundt and Toshihiro Kobayashi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/err.h> -#include <linux/device.h> -#include <linux/jiffies.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/stringify.h> - -#include <plat/iommu.h> - -/* - * omap2 architecture specific register bit definitions - */ -#define IOMMU_ARCH_VERSION	0x00000011 - -/* SYSCONF */ -#define MMU_SYS_IDLE_SHIFT	3 -#define MMU_SYS_IDLE_FORCE	(0 << MMU_SYS_IDLE_SHIFT) -#define MMU_SYS_IDLE_NONE	(1 << MMU_SYS_IDLE_SHIFT) -#define MMU_SYS_IDLE_SMART	(2 << MMU_SYS_IDLE_SHIFT) -#define MMU_SYS_IDLE_MASK	(3 << MMU_SYS_IDLE_SHIFT) - -#define MMU_SYS_SOFTRESET	(1 << 1) -#define MMU_SYS_AUTOIDLE	1 - -/* SYSSTATUS */ -#define MMU_SYS_RESETDONE	1 - -/* IRQSTATUS & IRQENABLE */ -#define MMU_IRQ_MULTIHITFAULT	(1 << 4) -#define MMU_IRQ_TABLEWALKFAULT	(1 << 3) -#define MMU_IRQ_EMUMISS		(1 << 2) -#define MMU_IRQ_TRANSLATIONFAULT	(1 << 1) -#define MMU_IRQ_TLBMISS		(1 << 0) - -#define __MMU_IRQ_FAULT		\ -	(MMU_IRQ_MULTIHITFAULT | MMU_IRQ_EMUMISS | MMU_IRQ_TRANSLATIONFAULT) -#define MMU_IRQ_MASK		\ -	(__MMU_IRQ_FAULT | MMU_IRQ_TABLEWALKFAULT | MMU_IRQ_TLBMISS) -#define MMU_IRQ_TWL_MASK	(__MMU_IRQ_FAULT | MMU_IRQ_TABLEWALKFAULT) -#define MMU_IRQ_TLB_MISS_MASK	(__MMU_IRQ_FAULT | MMU_IRQ_TLBMISS) - -/* MMU_CNTL */ -#define MMU_CNTL_SHIFT		1 -#define MMU_CNTL_MASK		(7 << MMU_CNTL_SHIFT) -#define MMU_CNTL_EML_TLB	(1 << 3) -#define MMU_CNTL_TWL_EN		(1 << 2) -#define MMU_CNTL_MMU_EN		(1 << 1) - -#define get_cam_va_mask(pgsz)				\ -	(((pgsz) == MMU_CAM_PGSZ_16M) ? 0xff000000 :	\ -	 ((pgsz) == MMU_CAM_PGSZ_1M)  ? 0xfff00000 :	\ -	 ((pgsz) == MMU_CAM_PGSZ_64K) ? 0xffff0000 :	\ -	 ((pgsz) == MMU_CAM_PGSZ_4K)  ? 0xfffff000 : 0) - - -static void __iommu_set_twl(struct omap_iommu *obj, bool on) -{ -	u32 l = iommu_read_reg(obj, MMU_CNTL); - -	if (on) -		iommu_write_reg(obj, MMU_IRQ_TWL_MASK, MMU_IRQENABLE); -	else -		iommu_write_reg(obj, MMU_IRQ_TLB_MISS_MASK, MMU_IRQENABLE); - -	l &= ~MMU_CNTL_MASK; -	if (on) -		l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN); -	else -		l |= (MMU_CNTL_MMU_EN); - -	iommu_write_reg(obj, l, MMU_CNTL); -} - - -static int omap2_iommu_enable(struct omap_iommu *obj) -{ -	u32 l, pa; -	unsigned long timeout; - -	if (!obj->iopgd || !IS_ALIGNED((u32)obj->iopgd,  SZ_16K)) -		return -EINVAL; - -	pa = virt_to_phys(obj->iopgd); -	if (!IS_ALIGNED(pa, SZ_16K)) -		return -EINVAL; - -	iommu_write_reg(obj, MMU_SYS_SOFTRESET, MMU_SYSCONFIG); - -	timeout = jiffies + msecs_to_jiffies(20); -	do { -		l = iommu_read_reg(obj, MMU_SYSSTATUS); -		if (l & MMU_SYS_RESETDONE) -			break; -	} while (!time_after(jiffies, timeout)); - -	if (!(l & MMU_SYS_RESETDONE)) { -		dev_err(obj->dev, "can't take mmu out of reset\n"); -		return -ENODEV; -	} - -	l = iommu_read_reg(obj, MMU_REVISION); -	dev_info(obj->dev, "%s: version %d.%d\n", obj->name, -		 (l >> 4) & 0xf, l & 0xf); - -	l = iommu_read_reg(obj, MMU_SYSCONFIG); -	l &= ~MMU_SYS_IDLE_MASK; -	l |= (MMU_SYS_IDLE_SMART | MMU_SYS_AUTOIDLE); -	iommu_write_reg(obj, l, MMU_SYSCONFIG); - -	iommu_write_reg(obj, pa, MMU_TTB); - -	__iommu_set_twl(obj, true); - -	return 0; -} - -static void omap2_iommu_disable(struct omap_iommu *obj) -{ -	u32 l = iommu_read_reg(obj, MMU_CNTL); - -	l &= ~MMU_CNTL_MASK; -	iommu_write_reg(obj, l, MMU_CNTL); -	iommu_write_reg(obj, MMU_SYS_IDLE_FORCE, MMU_SYSCONFIG); - -	dev_dbg(obj->dev, "%s is shutting down\n", obj->name); -} - -static void omap2_iommu_set_twl(struct omap_iommu *obj, bool on) -{ -	__iommu_set_twl(obj, false); -} - -static u32 omap2_iommu_fault_isr(struct omap_iommu *obj, u32 *ra) -{ -	u32 stat, da; -	u32 errs = 0; - -	stat = iommu_read_reg(obj, MMU_IRQSTATUS); -	stat &= MMU_IRQ_MASK; -	if (!stat) { -		*ra = 0; -		return 0; -	} - -	da = iommu_read_reg(obj, MMU_FAULT_AD); -	*ra = da; - -	if (stat & MMU_IRQ_TLBMISS) -		errs |= OMAP_IOMMU_ERR_TLB_MISS; -	if (stat & MMU_IRQ_TRANSLATIONFAULT) -		errs |= OMAP_IOMMU_ERR_TRANS_FAULT; -	if (stat & MMU_IRQ_EMUMISS) -		errs |= OMAP_IOMMU_ERR_EMU_MISS; -	if (stat & MMU_IRQ_TABLEWALKFAULT) -		errs |= OMAP_IOMMU_ERR_TBLWALK_FAULT; -	if (stat & MMU_IRQ_MULTIHITFAULT) -		errs |= OMAP_IOMMU_ERR_MULTIHIT_FAULT; -	iommu_write_reg(obj, stat, MMU_IRQSTATUS); - -	return errs; -} - -static void omap2_tlb_read_cr(struct omap_iommu *obj, struct cr_regs *cr) -{ -	cr->cam = iommu_read_reg(obj, MMU_READ_CAM); -	cr->ram = iommu_read_reg(obj, MMU_READ_RAM); -} - -static void omap2_tlb_load_cr(struct omap_iommu *obj, struct cr_regs *cr) -{ -	iommu_write_reg(obj, cr->cam | MMU_CAM_V, MMU_CAM); -	iommu_write_reg(obj, cr->ram, MMU_RAM); -} - -static u32 omap2_cr_to_virt(struct cr_regs *cr) -{ -	u32 page_size = cr->cam & MMU_CAM_PGSZ_MASK; -	u32 mask = get_cam_va_mask(cr->cam & page_size); - -	return cr->cam & mask; -} - -static struct cr_regs *omap2_alloc_cr(struct omap_iommu *obj, -						struct iotlb_entry *e) -{ -	struct cr_regs *cr; - -	if (e->da & ~(get_cam_va_mask(e->pgsz))) { -		dev_err(obj->dev, "%s:\twrong alignment: %08x\n", __func__, -			e->da); -		return ERR_PTR(-EINVAL); -	} - -	cr = kmalloc(sizeof(*cr), GFP_KERNEL); -	if (!cr) -		return ERR_PTR(-ENOMEM); - -	cr->cam = (e->da & MMU_CAM_VATAG_MASK) | e->prsvd | e->pgsz | e->valid; -	cr->ram = e->pa | e->endian | e->elsz | e->mixed; - -	return cr; -} - -static inline int omap2_cr_valid(struct cr_regs *cr) -{ -	return cr->cam & MMU_CAM_V; -} - -static u32 omap2_get_pte_attr(struct iotlb_entry *e) -{ -	u32 attr; - -	attr = e->mixed << 5; -	attr |= e->endian; -	attr |= e->elsz >> 3; -	attr <<= (((e->pgsz == MMU_CAM_PGSZ_4K) || -			(e->pgsz == MMU_CAM_PGSZ_64K)) ? 0 : 6); -	return attr; -} - -static ssize_t -omap2_dump_cr(struct omap_iommu *obj, struct cr_regs *cr, char *buf) -{ -	char *p = buf; - -	/* FIXME: Need more detail analysis of cam/ram */ -	p += sprintf(p, "%08x %08x %01x\n", cr->cam, cr->ram, -					(cr->cam & MMU_CAM_P) ? 1 : 0); - -	return p - buf; -} - -#define pr_reg(name)							\ -	do {								\ -		ssize_t bytes;						\ -		const char *str = "%20s: %08x\n";			\ -		const int maxcol = 32;					\ -		bytes = snprintf(p, maxcol, str, __stringify(name),	\ -				 iommu_read_reg(obj, MMU_##name));	\ -		p += bytes;						\ -		len -= bytes;						\ -		if (len < maxcol)					\ -			goto out;					\ -	} while (0) - -static ssize_t -omap2_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len) -{ -	char *p = buf; - -	pr_reg(REVISION); -	pr_reg(SYSCONFIG); -	pr_reg(SYSSTATUS); -	pr_reg(IRQSTATUS); -	pr_reg(IRQENABLE); -	pr_reg(WALKING_ST); -	pr_reg(CNTL); -	pr_reg(FAULT_AD); -	pr_reg(TTB); -	pr_reg(LOCK); -	pr_reg(LD_TLB); -	pr_reg(CAM); -	pr_reg(RAM); -	pr_reg(GFLUSH); -	pr_reg(FLUSH_ENTRY); -	pr_reg(READ_CAM); -	pr_reg(READ_RAM); -	pr_reg(EMU_FAULT_AD); -out: -	return p - buf; -} - -static void omap2_iommu_save_ctx(struct omap_iommu *obj) -{ -	int i; -	u32 *p = obj->ctx; - -	for (i = 0; i < (MMU_REG_SIZE / sizeof(u32)); i++) { -		p[i] = iommu_read_reg(obj, i * sizeof(u32)); -		dev_dbg(obj->dev, "%s\t[%02d] %08x\n", __func__, i, p[i]); -	} - -	BUG_ON(p[0] != IOMMU_ARCH_VERSION); -} - -static void omap2_iommu_restore_ctx(struct omap_iommu *obj) -{ -	int i; -	u32 *p = obj->ctx; - -	for (i = 0; i < (MMU_REG_SIZE / sizeof(u32)); i++) { -		iommu_write_reg(obj, p[i], i * sizeof(u32)); -		dev_dbg(obj->dev, "%s\t[%02d] %08x\n", __func__, i, p[i]); -	} - -	BUG_ON(p[0] != IOMMU_ARCH_VERSION); -} - -static void omap2_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e) -{ -	e->da		= cr->cam & MMU_CAM_VATAG_MASK; -	e->pa		= cr->ram & MMU_RAM_PADDR_MASK; -	e->valid	= cr->cam & MMU_CAM_V; -	e->pgsz		= cr->cam & MMU_CAM_PGSZ_MASK; -	e->endian	= cr->ram & MMU_RAM_ENDIAN_MASK; -	e->elsz		= cr->ram & MMU_RAM_ELSZ_MASK; -	e->mixed	= cr->ram & MMU_RAM_MIXED; -} - -static const struct iommu_functions omap2_iommu_ops = { -	.version	= IOMMU_ARCH_VERSION, - -	.enable		= omap2_iommu_enable, -	.disable	= omap2_iommu_disable, -	.set_twl	= omap2_iommu_set_twl, -	.fault_isr	= omap2_iommu_fault_isr, - -	.tlb_read_cr	= omap2_tlb_read_cr, -	.tlb_load_cr	= omap2_tlb_load_cr, - -	.cr_to_e	= omap2_cr_to_e, -	.cr_to_virt	= omap2_cr_to_virt, -	.alloc_cr	= omap2_alloc_cr, -	.cr_valid	= omap2_cr_valid, -	.dump_cr	= omap2_dump_cr, - -	.get_pte_attr	= omap2_get_pte_attr, - -	.save_ctx	= omap2_iommu_save_ctx, -	.restore_ctx	= omap2_iommu_restore_ctx, -	.dump_ctx	= omap2_iommu_dump_ctx, -}; - -static int __init omap2_iommu_init(void) -{ -	return omap_install_iommu_arch(&omap2_iommu_ops); -} -module_init(omap2_iommu_init); - -static void __exit omap2_iommu_exit(void) -{ -	omap_uninstall_iommu_arch(&omap2_iommu_ops); -} -module_exit(omap2_iommu_exit); - -MODULE_AUTHOR("Hiroshi DOYU, Paul Mundt and Toshihiro Kobayashi"); -MODULE_DESCRIPTION("omap iommu: omap2/3 architecture specific functions"); -MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S index 502e3135aad..0ea09faf327 100644 --- a/arch/arm/mach-omap2/omap-headsmp.S +++ b/arch/arm/mach-omap2/omap-headsmp.S @@ -18,6 +18,8 @@  #include <linux/linkage.h>  #include <linux/init.h> +#include "omap44xx.h" +  	__CPUINIT  /* Physical address needed since MMU not enabled yet on secondary core */ @@ -64,3 +66,39 @@ hold:	ldr	r12,=0x103  	b	secondary_startup  ENDPROC(omap_secondary_startup) +ENTRY(omap_secondary_startup_4460) +hold_2:	ldr	r12,=0x103 +	dsb +	smc	#0			@ read from AuxCoreBoot0 +	mov	r0, r0, lsr #9 +	mrc	p15, 0, r4, c0, c0, 5 +	and	r4, r4, #0x0f +	cmp	r0, r4 +	bne	hold_2 + +	/* +	 * GIC distributor control register has changed between +	 * CortexA9 r1pX and r2pX. The Control Register secure +	 * banked version is now composed of 2 bits: +	 * bit 0 == Secure Enable +	 * bit 1 == Non-Secure Enable +	 * The Non-Secure banked register has not changed +	 * Because the ROM Code is based on the r1pX GIC, the CPU1 +	 * GIC restoration will cause a problem to CPU0 Non-Secure SW. +	 * The workaround must be: +	 * 1) Before doing the CPU1 wakeup, CPU0 must disable +	 * the GIC distributor +	 * 2) CPU1 must re-enable the GIC distributor on +	 * it's wakeup path. +	 */ +	ldr	r1, =OMAP44XX_GIC_DIST_BASE +	ldr	r0, [r1] +	orr	r0, #1 +	str	r0, [r1] + +	/* +	 * we've been released from the wait loop,secondary_stack +	 * should now contain the SVC stack for this core +	 */ +	b	secondary_startup +ENDPROC(omap_secondary_startup_4460) diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c index df298d46707..a6a4ff8744b 100644 --- a/arch/arm/mach-omap2/omap-iommu.c +++ b/arch/arm/mach-omap2/omap-iommu.c @@ -13,7 +13,7 @@  #include <linux/module.h>  #include <linux/platform_device.h> -#include <plat/iommu.h> +#include <linux/platform_data/iommu-omap.h>  #include "soc.h"  #include "common.h" diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 3f5fd7e3549..aac46bfdbeb 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -68,6 +68,7 @@ struct omap4_cpu_pm_info {  	void __iomem *scu_sar_addr;  	void __iomem *wkup_sar_addr;  	void __iomem *l2x0_sar_addr; +	void (*secondary_startup)(void);  };  static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); @@ -300,6 +301,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)  int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)  {  	unsigned int cpu_state = 0; +	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);  	if (omap_rev() == OMAP4430_REV_ES1_0)  		return -ENXIO; @@ -309,7 +311,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)  	clear_cpu_prev_pwrst(cpu);  	set_cpu_next_pwrst(cpu, power_state); -	set_cpu_wakeup_addr(cpu, virt_to_phys(omap_secondary_startup)); +	set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup));  	scu_pwrst_prepare(cpu, power_state);  	/* @@ -360,6 +362,11 @@ int __init omap4_mpuss_init(void)  	pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;  	pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET;  	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; +	if (cpu_is_omap446x()) +		pm_info->secondary_startup = omap_secondary_startup_4460; +	else +		pm_info->secondary_startup = omap_secondary_startup; +  	pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");  	if (!pm_info->pwrdm) {  		pr_err("Lookup failed for CPU1 pwrdm\n"); diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 4d05fa8a4e4..cd42d921940 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -32,6 +32,7 @@  #include "iomap.h"  #include "common.h"  #include "clockdomain.h" +#include "pm.h"  #define CPU_MASK		0xff0ffff0  #define CPU_CORTEX_A9		0x410FC090 @@ -39,6 +40,8 @@  #define OMAP5_CORE_COUNT	0x2 +u16 pm44xx_errata; +  /* SCU base address */  static void __iomem *scu_base; @@ -118,8 +121,37 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *  	 *	4.3.4.2 Power States of CPU0 and CPU1  	 */  	if (booted) { +		/* +		 * GIC distributor control register has changed between +		 * CortexA9 r1pX and r2pX. The Control Register secure +		 * banked version is now composed of 2 bits: +		 * bit 0 == Secure Enable +		 * bit 1 == Non-Secure Enable +		 * The Non-Secure banked register has not changed +		 * Because the ROM Code is based on the r1pX GIC, the CPU1 +		 * GIC restoration will cause a problem to CPU0 Non-Secure SW. +		 * The workaround must be: +		 * 1) Before doing the CPU1 wakeup, CPU0 must disable +		 * the GIC distributor +		 * 2) CPU1 must re-enable the GIC distributor on +		 * it's wakeup path. +		 */ +		if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) { +			local_irq_disable(); +			gic_dist_disable(); +		} +  		clkdm_wakeup(cpu1_clkdm);  		clkdm_allow_idle(cpu1_clkdm); + +		if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) { +			while (gic_dist_disabled()) { +				udelay(1); +				cpu_relax(); +			} +			gic_timer_retrigger(); +			local_irq_enable(); +		}  	} else {  		dsb_sev();  		booted = true; @@ -138,7 +170,14 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *  static void __init wakeup_secondary(void)  { +	void *startup_addr = omap_secondary_startup;  	void __iomem *base = omap_get_wakeupgen_base(); + +	if (cpu_is_omap446x()) { +		startup_addr = omap_secondary_startup_4460; +		pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD; +	} +  	/*  	 * Write the address of secondary startup routine into the  	 * AuxCoreBoot1 where ROM code will jump and start executing @@ -146,7 +185,7 @@ static void __init wakeup_secondary(void)  	 * A barrier is added to ensure that write buffer is drained  	 */  	if (omap_secure_apis_support()) -		omap_auxcoreboot_addr(virt_to_phys(omap_secondary_startup)); +		omap_auxcoreboot_addr(virt_to_phys(startup_addr));  	else  		__raw_writel(virt_to_phys(omap5_secondary_startup),  						base + OMAP_AUX_CORE_BOOT_1); diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 5695885ea34..6897ae21bb8 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -14,6 +14,7 @@  #include <linux/kernel.h>  #include <linux/init.h>  #include <linux/io.h> +#include <linux/irq.h>  #include <linux/platform_device.h>  #include <linux/memblock.h>  #include <linux/of_irq.h> @@ -24,6 +25,7 @@  #include <asm/hardware/cache-l2x0.h>  #include <asm/mach/map.h>  #include <asm/memblock.h> +#include <asm/smp_twd.h>  #include "omap-wakeupgen.h"  #include "soc.h" @@ -42,6 +44,10 @@ static void __iomem *l2cache_base;  #endif  static void __iomem *sar_ram_base; +static void __iomem *gic_dist_base_addr; +static void __iomem *twd_base; + +#define IRQ_LOCALTIMER		29  #ifdef CONFIG_OMAP4_ERRATA_I688  /* Used to implement memory barrier on DRAM path */ @@ -96,12 +102,14 @@ void __init omap_barriers_init(void)  void __init gic_init_irq(void)  {  	void __iomem *omap_irq_base; -	void __iomem *gic_dist_base_addr;  	/* Static mapping, never released */  	gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K);  	BUG_ON(!gic_dist_base_addr); +	twd_base = ioremap(OMAP44XX_LOCAL_TWD_BASE, SZ_4K); +	BUG_ON(!twd_base); +  	/* Static mapping, never released */  	omap_irq_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512);  	BUG_ON(!omap_irq_base); @@ -111,6 +119,38 @@ void __init gic_init_irq(void)  	gic_init(0, 29, gic_dist_base_addr, omap_irq_base);  } +void gic_dist_disable(void) +{ +	if (gic_dist_base_addr) +		__raw_writel(0x0, gic_dist_base_addr + GIC_DIST_CTRL); +} + +bool gic_dist_disabled(void) +{ +	return !(__raw_readl(gic_dist_base_addr + GIC_DIST_CTRL) & 0x1); +} + +void gic_timer_retrigger(void) +{ +	u32 twd_int = __raw_readl(twd_base + TWD_TIMER_INTSTAT); +	u32 gic_int = __raw_readl(gic_dist_base_addr + GIC_DIST_PENDING_SET); +	u32 twd_ctrl = __raw_readl(twd_base + TWD_TIMER_CONTROL); + +	if (twd_int && !(gic_int & BIT(IRQ_LOCALTIMER))) { +		/* +		 * The local timer interrupt got lost while the distributor was +		 * disabled.  Ack the pending interrupt, and retrigger it. +		 */ +		pr_warn("%s: lost localtimer interrupt\n", __func__); +		__raw_writel(1, twd_base + TWD_TIMER_INTSTAT); +		if (!(twd_ctrl & TWD_TIMER_CONTROL_PERIODIC)) { +			__raw_writel(1, twd_base + TWD_TIMER_COUNTER); +			twd_ctrl |= TWD_TIMER_CONTROL_ENABLE; +			__raw_writel(twd_ctrl, twd_base + TWD_TIMER_CONTROL); +		} +	} +} +  #ifdef CONFIG_CACHE_L2X0  void __iomem *omap4_get_l2cache_base(void) diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index ad8d43b3327..32820d89f5b 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -674,6 +674,7 @@ static struct omap_hwmod am33xx_cpgmac0_hwmod = {  	.name		= "cpgmac0",  	.class		= &am33xx_cpgmac0_hwmod_class,  	.clkdm_name	= "cpsw_125mhz_clkdm", +	.flags		= (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),  	.mpu_irqs	= am33xx_cpgmac0_irqs,  	.main_clk	= "cpsw_125mhz_gclk",  	.prcm		= { @@ -685,6 +686,20 @@ static struct omap_hwmod am33xx_cpgmac0_hwmod = {  };  /* + * mdio class + */ +static struct omap_hwmod_class am33xx_mdio_hwmod_class = { +	.name		= "davinci_mdio", +}; + +static struct omap_hwmod am33xx_mdio_hwmod = { +	.name		= "davinci_mdio", +	.class		= &am33xx_mdio_hwmod_class, +	.clkdm_name	= "cpsw_125mhz_clkdm", +	.main_clk	= "cpsw_125mhz_gclk", +}; + +/*   * dcan class   */  static struct omap_hwmod_class am33xx_dcan_hwmod_class = { @@ -2501,6 +2516,21 @@ static struct omap_hwmod_ocp_if am33xx_l4_hs__cpgmac0 = {  	.user		= OCP_USER_MPU,  }; +struct omap_hwmod_addr_space am33xx_mdio_addr_space[] = { +	{ +		.pa_start	= 0x4A101000, +		.pa_end		= 0x4A101000 + SZ_256 - 1, +	}, +	{ } +}; + +struct omap_hwmod_ocp_if am33xx_cpgmac0__mdio = { +	.master		= &am33xx_cpgmac0_hwmod, +	.slave		= &am33xx_mdio_hwmod, +	.addr		= am33xx_mdio_addr_space, +	.user		= OCP_USER_MPU, +}; +  static struct omap_hwmod_addr_space am33xx_elm_addr_space[] = {  	{  		.pa_start	= 0x48080000, @@ -3371,6 +3401,7 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = {  	&am33xx_l3_main__tptc2,  	&am33xx_l3_s__usbss,  	&am33xx_l4_hs__cpgmac0, +	&am33xx_cpgmac0__mdio,  	NULL,  }; diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 0f10919f227..ec4499e5a4c 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -24,8 +24,8 @@  #include "l4_3xxx.h"  #include <linux/platform_data/asoc-ti-mcbsp.h>  #include <linux/platform_data/spi-omap2-mcspi.h> +#include <linux/platform_data/iommu-omap.h>  #include <plat/dmtimer.h> -#include <plat/iommu.h>  #include "am35xx.h" diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index ce1661d18e5..eb61cfd9452 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -29,8 +29,8 @@  #include <linux/platform_data/omap_ocp2scp.h>  #include <linux/platform_data/spi-omap2-mcspi.h>  #include <linux/platform_data/asoc-ti-mcbsp.h> +#include <linux/platform_data/iommu-omap.h>  #include <plat/dmtimer.h> -#include <plat/iommu.h>  #include "omap_hwmod.h"  #include "omap_hwmod_common_data.h" diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 02c291c8e47..c22503b17ab 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -102,6 +102,15 @@ 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) */ +#define PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD	(1 << 0) + +#if defined(CONFIG_ARCH_OMAP4) +extern u16 pm44xx_errata; +#define IS_PM44XX_ERRATUM(id)		(pm44xx_errata & (id)) +#else +#define IS_PM44XX_ERRATUM(id)		0 +#endif +  #ifdef CONFIG_POWER_AVS_OMAP  extern int omap_devinit_smartreflex(void);  extern void omap_enable_smartreflex_on_init(void); diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c index 3cf79b54ce6..250d909e38b 100644 --- a/arch/arm/mach-omap2/pmu.c +++ b/arch/arm/mach-omap2/pmu.c @@ -58,8 +58,6 @@ static int __init omap2_init_pmu(unsigned oh_num, char *oh_names[])  	if (IS_ERR(omap_pmu_dev))  		return PTR_ERR(omap_pmu_dev); -	pm_runtime_enable(&omap_pmu_dev->dev); -  	return 0;  } diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index b9cff72ceae..7016637b531 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -628,9 +628,9 @@ static void __init omap4_local_timer_init(void)  	}  }  #else /* CONFIG_LOCAL_TIMERS */ -static inline void omap4_local_timer_init(void) +static void __init omap4_local_timer_init(void)  { -	omap4_sync32_timer_init(); +	omap4_sync32k_timer_init();  }  #endif /* CONFIG_LOCAL_TIMERS */  OMAP_SYS_TIMER(4, local);  |