diff options
Diffstat (limited to 'arch/arm/mach-omap2')
25 files changed, 560 insertions, 273 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 2a1a898..2265e58 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -11,7 +11,6 @@ config ARCH_OMAP2PLUS_TYPICAL select I2C_OMAP select MENELAUS if ARCH_OMAP2 select NEON if ARCH_OMAP3 || ARCH_OMAP4 || SOC_OMAP5 - select PINCTRL select PM_RUNTIME select REGULATOR select SERIAL_OMAP @@ -271,14 +270,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 fe40d9e..fb38a9b 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -279,4 +279,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 3669c12..8ce98ae 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -37,9 +37,6 @@ #include <plat/usb.h> #include <plat/mmc.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 601ecdf..8f5f21c 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-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 388c431..d41ab98 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -24,6 +24,7 @@ #include <linux/input.h> #include <linux/gpio_keys.h> #include <linux/opp.h> +#include <linux/cpu.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> @@ -444,27 +445,31 @@ static struct omap_board_mux board_mux[] __initdata = { }; #endif -static void __init beagle_opp_init(void) +static int __init beagle_opp_init(void) { int r = 0; - /* Initialize the omap3 opp table */ - if (omap3_opp_init()) { + if (!machine_is_omap3_beagle()) + return 0; + + /* Initialize the omap3 opp table if not already created. */ + r = omap3_opp_init(); + if (IS_ERR_VALUE(r) && (r != -EEXIST)) { pr_err("%s: opp default init failed\n", __func__); - return; + return r; } /* Custom OPP enabled for all xM versions */ if (cpu_is_omap3630()) { struct device *mpu_dev, *iva_dev; - mpu_dev = omap_device_get_by_hwmod_name("mpu"); + mpu_dev = get_cpu_device(0); iva_dev = omap_device_get_by_hwmod_name("iva"); if (IS_ERR(mpu_dev) || IS_ERR(iva_dev)) { pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n", __func__, mpu_dev, iva_dev); - return; + return -ENODEV; } /* Enable MPU 1GHz and lower opps */ r = opp_enable(mpu_dev, 800000000); @@ -484,8 +489,9 @@ static void __init beagle_opp_init(void) opp_disable(iva_dev, 660000000); } } - return; + return 0; } +device_initcall(beagle_opp_init); static void __init omap3_beagle_init(void) { @@ -522,8 +528,6 @@ static void __init omap3_beagle_init(void) /* Ensure SDRC pins are mux'd for self-refresh */ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); - - beagle_opp_init(); } MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board") diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index bfcd397..ab505a2 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -36,26 +36,22 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <video/omapdss.h> #include "common.h" #include <plat/usb.h> #include <plat/mmc.h> -#include <video/omap-panel-tfp410.h> #include "soc.h" #include "hsmmc.h" #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 +405,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 45997bf..42ac9d3 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 7bbb05d..e5af119 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/clock33xx_data.c b/arch/arm/mach-omap2/clock33xx_data.c index 114ab4b..1a45d6b 100644 --- a/arch/arm/mach-omap2/clock33xx_data.c +++ b/arch/arm/mach-omap2/clock33xx_data.c @@ -1073,6 +1073,8 @@ static struct omap_clk am33xx_clks[] = { 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), + CLK(NULL, "timer_32k_ck", &clkdiv32k_ick, CK_AM33XX), + CLK(NULL, "timer_sys_ck", &sys_clkin_ck, CK_AM33XX), }; int __init am33xx_clk_init(void) diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index d661d13..6efc30c 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -3294,7 +3294,7 @@ static struct omap_clk omap44xx_clks[] = { CLK(NULL, "auxclk5_src_ck", &auxclk5_src_ck, CK_443X), CLK(NULL, "auxclk5_ck", &auxclk5_ck, CK_443X), CLK(NULL, "auxclkreq5_ck", &auxclkreq5_ck, CK_443X), - CLK(NULL, "gpmc_ck", &dummy_ck, CK_443X), + CLK("omap-gpmc", "fck", &dummy_ck, CK_443X), CLK("omap_i2c.1", "ick", &dummy_ck, CK_443X), CLK("omap_i2c.2", "ick", &dummy_ck, CK_443X), CLK("omap_i2c.3", "ick", &dummy_ck, CK_443X), diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index cbb8791..512e79a 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -925,15 +925,18 @@ static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm) if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable) return -EINVAL; + spin_lock_irqsave(&clkdm->lock, flags); + /* * For arch's with no autodeps, clkcm_clk_enable * should be called for every clock instance or hwmod that is * enabled, so the clkdm can be force woken up. */ - if ((atomic_inc_return(&clkdm->usecount) > 1) && autodeps) + if ((atomic_inc_return(&clkdm->usecount) > 1) && autodeps) { + spin_unlock_irqrestore(&clkdm->lock, flags); return 0; + } - spin_lock_irqsave(&clkdm->lock, flags); arch_clkdm->clkdm_clk_enable(clkdm); pwrdm_state_switch(clkdm->pwrdm.ptr); spin_unlock_irqrestore(&clkdm->lock, flags); @@ -950,15 +953,19 @@ static int _clkdm_clk_hwmod_disable(struct clockdomain *clkdm) if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_disable) return -EINVAL; + spin_lock_irqsave(&clkdm->lock, flags); + if (atomic_read(&clkdm->usecount) == 0) { + spin_unlock_irqrestore(&clkdm->lock, flags); WARN_ON(1); /* underflow */ return -ERANGE; } - if (atomic_dec_return(&clkdm->usecount) > 0) + if (atomic_dec_return(&clkdm->usecount) > 0) { + spin_unlock_irqrestore(&clkdm->lock, flags); return 0; + } - spin_lock_irqsave(&clkdm->lock, flags); arch_clkdm->clkdm_clk_disable(clkdm); pwrdm_state_switch(clkdm->pwrdm.ptr); spin_unlock_irqrestore(&clkdm->lock, flags); diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c index b56d06b..95192a06 100644 --- a/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -359,7 +359,7 @@ static struct clockdomain iss_44xx_clkdm = { .clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS, .wkdep_srcs = iss_wkup_sleep_deps, .sleepdep_srcs = iss_wkup_sleep_deps, - .flags = CLKDM_CAN_HWSUP_SWSUP, + .flags = CLKDM_CAN_SWSUP, }; static struct clockdomain l3_dss_44xx_clkdm = { diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index c8c2117..c72b5a7 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -19,6 +19,7 @@ #include <linux/of.h> #include <linux/pinctrl/machine.h> #include <linux/platform_data/omap4-keypad.h> +#include <linux/platform_data/omap_ocp2scp.h> #include <asm/mach-types.h> #include <asm/mach/map.h> @@ -341,7 +342,7 @@ static void __init omap_init_dmic(void) oh = omap_hwmod_lookup("dmic"); if (!oh) { - printk(KERN_ERR "Could not look up mcpdm hw_mod\n"); + pr_err("Could not look up dmic hw_mod\n"); return; } @@ -613,6 +614,83 @@ static void omap_init_vout(void) static inline void omap_init_vout(void) {} #endif +#if defined(CONFIG_OMAP_OCP2SCP) || defined(CONFIG_OMAP_OCP2SCP_MODULE) +static int count_ocp2scp_devices(struct omap_ocp2scp_dev *ocp2scp_dev) +{ + int cnt = 0; + + while (ocp2scp_dev->drv_name != NULL) { + cnt++; + ocp2scp_dev++; + } + + return cnt; +} + +static void omap_init_ocp2scp(void) +{ + struct omap_hwmod *oh; + struct platform_device *pdev; + int bus_id = -1, dev_cnt = 0, i; + struct omap_ocp2scp_dev *ocp2scp_dev; + const char *oh_name, *name; + struct omap_ocp2scp_platform_data *pdata; + + if (!cpu_is_omap44xx()) + return; + + oh_name = "ocp2scp_usb_phy"; + name = "omap-ocp2scp"; + + oh = omap_hwmod_lookup(oh_name); + if (!oh) { + pr_err("%s: could not find omap_hwmod for %s\n", __func__, + oh_name); + return; + } + + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + pr_err("%s: No memory for ocp2scp pdata\n", __func__); + return; + } + + ocp2scp_dev = oh->dev_attr; + dev_cnt = count_ocp2scp_devices(ocp2scp_dev); + + if (!dev_cnt) { + pr_err("%s: No devices connected to ocp2scp\n", __func__); + kfree(pdata); + return; + } + + pdata->devices = kzalloc(sizeof(struct omap_ocp2scp_dev *) + * dev_cnt, GFP_KERNEL); + if (!pdata->devices) { + pr_err("%s: No memory for ocp2scp pdata devices\n", __func__); + kfree(pdata); + return; + } + + for (i = 0; i < dev_cnt; i++, ocp2scp_dev++) + pdata->devices[i] = ocp2scp_dev; + + pdata->dev_cnt = dev_cnt; + + pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata), NULL, + 0, false); + if (IS_ERR(pdev)) { + pr_err("Could not build omap_device for %s %s\n", + name, oh_name); + kfree(pdata->devices); + kfree(pdata); + return; + } +} +#else +static inline void omap_init_ocp2scp(void) { } +#endif + /*-------------------------------------------------------------------------*/ static int __init omap2_init_devices(void) @@ -640,6 +718,7 @@ static int __init omap2_init_devices(void) omap_init_sham(); omap_init_aes(); omap_init_vout(); + omap_init_ocp2scp(); return 0; } diff --git a/arch/arm/mach-omap2/dss-common.c b/arch/arm/mach-omap2/dss-common.c new file mode 100644 index 0000000..679a047 --- /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 0000000..915f6ff --- /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/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 5ac5cf3..92b5718 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -868,9 +868,9 @@ static void __devexit gpmc_mem_exit(void) } -static void __devinit gpmc_mem_init(void) +static int __devinit gpmc_mem_init(void) { - int cs; + int cs, rc; unsigned long boot_rom_space = 0; /* never allocate the first page, to facilitate bug detection; @@ -890,13 +890,21 @@ static void __devinit gpmc_mem_init(void) if (!gpmc_cs_mem_enabled(cs)) continue; gpmc_cs_get_memconf(cs, &base, &size); - if (gpmc_cs_insert_mem(cs, base, size) < 0) - BUG(); + rc = gpmc_cs_insert_mem(cs, base, size); + if (IS_ERR_VALUE(rc)) { + while (--cs >= 0) + if (gpmc_cs_mem_enabled(cs)) + gpmc_cs_delete_mem(cs); + return rc; + } } + + return 0; } static __devinit int gpmc_probe(struct platform_device *pdev) { + int rc; u32 l; struct resource *res; @@ -936,7 +944,13 @@ static __devinit int gpmc_probe(struct platform_device *pdev) dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l), GPMC_REVISION_MINOR(l)); - gpmc_mem_init(); + rc = gpmc_mem_init(); + if (IS_ERR_VALUE(rc)) { + clk_disable_unprepare(gpmc_l3_clk); + clk_put(gpmc_l3_clk); + dev_err(gpmc_dev, "failed to reserve memory\n"); + return rc; + } if (IS_ERR_VALUE(gpmc_setup_irq())) dev_warn(gpmc_dev, "gpmc_setup_irq failed\n"); diff --git a/arch/arm/mach-omap2/mux34xx.c b/arch/arm/mach-omap2/mux34xx.c index 17f80e4..c47140b 100644 --- a/arch/arm/mach-omap2/mux34xx.c +++ b/arch/arm/mach-omap2/mux34xx.c @@ -614,16 +614,16 @@ static struct omap_mux __initdata omap3_muxmodes[] = { "sys_off_mode", NULL, NULL, NULL, "gpio_9", NULL, NULL, "safe_mode"), _OMAP3_MUXENTRY(UART1_CTS, 150, - "uart1_cts", NULL, NULL, NULL, + "uart1_cts", "ssi1_rdy_tx", NULL, NULL, "gpio_150", "hsusb3_tll_clk", NULL, "safe_mode"), _OMAP3_MUXENTRY(UART1_RTS, 149, - "uart1_rts", NULL, NULL, NULL, + "uart1_rts", "ssi1_flag_tx", NULL, NULL, "gpio_149", NULL, NULL, "safe_mode"), _OMAP3_MUXENTRY(UART1_RX, 151, - "uart1_rx", NULL, "mcbsp1_clkr", "mcspi4_clk", + "uart1_rx", "ss1_wake_tx", "mcbsp1_clkr", "mcspi4_clk", "gpio_151", NULL, NULL, "safe_mode"), _OMAP3_MUXENTRY(UART1_TX, 148, - "uart1_tx", NULL, NULL, NULL, + "uart1_tx", "ssi1_dat_tx", NULL, NULL, "gpio_148", NULL, NULL, "safe_mode"), _OMAP3_MUXENTRY(UART2_CTS, 144, "uart2_cts", "mcbsp3_dx", "gpt9_pwm_evt", NULL, diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index b969ab1..87cc6d0 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -422,6 +422,38 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v) } /** + * _wait_softreset_complete - wait for an OCP softreset to complete + * @oh: struct omap_hwmod * to wait on + * + * Wait until the IP block represented by @oh reports that its OCP + * softreset is complete. This can be triggered by software (see + * _ocp_softreset()) or by hardware upon returning from off-mode (one + * example is HSMMC). Waits for up to MAX_MODULE_SOFTRESET_WAIT + * microseconds. Returns the number of microseconds waited. + */ +static int _wait_softreset_complete(struct omap_hwmod *oh) +{ + struct omap_hwmod_class_sysconfig *sysc; + u32 softrst_mask; + int c = 0; + + sysc = oh->class->sysc; + + if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS) + omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs) + & SYSS_RESETDONE_MASK), + MAX_MODULE_SOFTRESET_WAIT, c); + else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { + softrst_mask = (0x1 << sysc->sysc_fields->srst_shift); + omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs) + & softrst_mask), + MAX_MODULE_SOFTRESET_WAIT, c); + } + + return c; +} + +/** * _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v * @oh: struct omap_hwmod * * @@ -1282,6 +1314,18 @@ static void _enable_sysc(struct omap_hwmod *oh) if (!oh->class->sysc) return; + /* + * Wait until reset has completed, this is needed as the IP + * block is reset automatically by hardware in some cases + * (off-mode for example), and the drivers require the + * IP to be ready when they access it + */ + if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) + _enable_optional_clocks(oh); + _wait_softreset_complete(oh); + if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) + _disable_optional_clocks(oh); + v = oh->_sysc_cache; sf = oh->class->sysc->sysc_flags; @@ -1804,7 +1848,7 @@ static int _am33xx_disable_module(struct omap_hwmod *oh) */ static int _ocp_softreset(struct omap_hwmod *oh) { - u32 v, softrst_mask; + u32 v; int c = 0; int ret = 0; @@ -1834,19 +1878,7 @@ static int _ocp_softreset(struct omap_hwmod *oh) if (oh->class->sysc->srst_udelay) udelay(oh->class->sysc->srst_udelay); - if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS) - omap_test_timeout((omap_hwmod_read(oh, - oh->class->sysc->syss_offs) - & SYSS_RESETDONE_MASK), - MAX_MODULE_SOFTRESET_WAIT, c); - else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { - softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift); - omap_test_timeout(!(omap_hwmod_read(oh, - oh->class->sysc->sysc_offs) - & softrst_mask), - MAX_MODULE_SOFTRESET_WAIT, c); - } - + c = _wait_softreset_complete(oh); if (c == MAX_MODULE_SOFTRESET_WAIT) pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", oh->name, MAX_MODULE_SOFTRESET_WAIT); @@ -2352,6 +2384,9 @@ static int __init _setup_reset(struct omap_hwmod *oh) if (oh->_state != _HWMOD_STATE_INITIALIZED) return -EINVAL; + if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK) + return -EPERM; + if (oh->rst_lines_cnt == 0) { r = _enable(oh); if (r) { diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 652d028..0b1249e 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -21,6 +21,7 @@ #include <linux/io.h> #include <linux/platform_data/gpio-omap.h> #include <linux/power/smartreflex.h> +#include <linux/platform_data/omap_ocp2scp.h> #include <plat/omap_hwmod.h> #include <plat/i2c.h> @@ -2125,6 +2126,14 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = { .name = "mcpdm", .class = &omap44xx_mcpdm_hwmod_class, .clkdm_name = "abe_clkdm", + /* + * It's suspected that the McPDM requires an off-chip main + * functional clock, controlled via I2C. This IP block is + * currently reset very early during boot, before I2C is + * available, so it doesn't seem that we have any choice in + * the kernel other than to avoid resetting it. + */ + .flags = HWMOD_EXT_OPT_MAIN_CLK, .mpu_irqs = omap44xx_mcpdm_irqs, .sdma_reqs = omap44xx_mcpdm_sdma_reqs, .main_clk = "mcpdm_fck", @@ -2681,6 +2690,32 @@ static struct omap_hwmod_class omap44xx_ocp2scp_hwmod_class = { .sysc = &omap44xx_ocp2scp_sysc, }; +/* ocp2scp dev_attr */ +static struct resource omap44xx_usb_phy_and_pll_addrs[] = { + { + .name = "usb_phy", + .start = 0x4a0ad080, + .end = 0x4a0ae000, + .flags = IORESOURCE_MEM, + }, + { + /* XXX: Remove this once control module driver is in place */ + .name = "ctrl_dev", + .start = 0x4a002300, + .end = 0x4a002303, + .flags = IORESOURCE_MEM, + }, + { } +}; + +static struct omap_ocp2scp_dev ocp2scp_dev_attr[] = { + { + .drv_name = "omap-usb2", + .res = omap44xx_usb_phy_and_pll_addrs, + }, + { } +}; + /* ocp2scp_usb_phy */ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { .name = "ocp2scp_usb_phy", @@ -2694,6 +2729,7 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { .modulemode = MODULEMODE_HWCTRL, }, }, + .dev_attr = ocp2scp_dev_attr, }; /* diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 686137d..67d6613 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -91,6 +91,7 @@ extern void omap3_save_scratchpad_contents(void); #define PM_RTA_ERRATUM_i608 (1 << 0) #define PM_SDRC_WAKEUP_ERRATUM_i583 (1 << 1) +#define PM_PER_MEMORIES_ERRATUM_i582 (1 << 2) #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) extern u16 pm34xx_errata; diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index ba670db..3a904de 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -652,14 +652,17 @@ static void __init pm_errata_configure(void) /* Enable the l2 cache toggling in sleep logic */ enable_omap3630_toggle_l2_on_restore(); if (omap_rev() < OMAP3630_REV_ES1_2) - pm34xx_errata |= PM_SDRC_WAKEUP_ERRATUM_i583; + pm34xx_errata |= (PM_SDRC_WAKEUP_ERRATUM_i583 | + PM_PER_MEMORIES_ERRATUM_i582); + } else if (cpu_is_omap34xx()) { + pm34xx_errata |= PM_PER_MEMORIES_ERRATUM_i582; } } int __init omap3_pm_init(void) { struct power_state *pwrst, *tmp; - struct clockdomain *neon_clkdm, *mpu_clkdm; + struct clockdomain *neon_clkdm, *mpu_clkdm, *per_clkdm, *wkup_clkdm; int ret; if (!omap3_has_io_chain_ctrl()) @@ -711,6 +714,8 @@ int __init omap3_pm_init(void) neon_clkdm = clkdm_lookup("neon_clkdm"); mpu_clkdm = clkdm_lookup("mpu_clkdm"); + per_clkdm = clkdm_lookup("per_clkdm"); + wkup_clkdm = clkdm_lookup("wkup_clkdm"); #ifdef CONFIG_SUSPEND omap_pm_suspend = omap3_pm_suspend; @@ -727,6 +732,27 @@ int __init omap3_pm_init(void) if (IS_PM34XX_ERRATUM(PM_RTA_ERRATUM_i608)) omap3630_ctrl_disable_rta(); + /* + * The UART3/4 FIFO and the sidetone memory in McBSP2/3 are + * not correctly reset when the PER powerdomain comes back + * from OFF or OSWR when the CORE powerdomain is kept active. + * See OMAP36xx Erratum i582 "PER Domain reset issue after + * Domain-OFF/OSWR Wakeup". This wakeup dependency is not a + * complete workaround. The kernel must also prevent the PER + * powerdomain from going to OSWR/OFF while the CORE + * powerdomain is not going to OSWR/OFF. And if PER last + * power state was off while CORE last power state was ON, the + * UART3/4 and McBSP2/3 SIDETONE devices need to run a + * self-test using their loopback tests; if that fails, those + * devices are unusable until the PER/CORE can complete a transition + * from ON to OSWR/OFF and then back to ON. + * + * XXX Technically this workaround is only needed if off-mode + * or OSWR is enabled. + */ + if (IS_PM34XX_ERRATUM(PM_PER_MEMORIES_ERRATUM_i582)) + clkdm_add_wkdep(per_clkdm, wkup_clkdm); + clkdm_add_wkdep(neon_clkdm, mpu_clkdm); if (omap_type() != OMAP2_DEVICE_TYPE_GP) { omap3_secure_ram_storage = diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 0405c81..a507cd6 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -329,6 +329,11 @@ void __init omap_serial_init_port(struct omap_board_data *bdata, oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); + if (console_uart_id == bdata->id) { + omap_device_enable(pdev); + pm_runtime_set_active(&pdev->dev); + } + oh->dev_attr = uart; if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 44f9aa7..69e4663 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -467,7 +467,7 @@ OMAP_SYS_TIMER(3_am33xx) #ifdef CONFIG_ARCH_OMAP4 #ifdef CONFIG_LOCAL_TIMERS static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, - OMAP44XX_LOCAL_TWD_BASE, 29 + OMAP_INTC_START); + OMAP44XX_LOCAL_TWD_BASE, 29); #endif static void __init omap4_timer_init(void) diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 635e109..44c4205 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -366,7 +366,7 @@ static struct regulator_init_data omap4_clk32kg_idata = { }; static struct regulator_consumer_supply omap4_vdd1_supply[] = { - REGULATOR_SUPPLY("vcc", "mpu.0"), + REGULATOR_SUPPLY("vcc", "cpu0"), }; static struct regulator_consumer_supply omap4_vdd2_supply[] = { diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c index 880249b..75878c3 100644 --- a/arch/arm/mach-omap2/vc.c +++ b/arch/arm/mach-omap2/vc.c @@ -264,7 +264,7 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm) if (initialized) { if (voltdm->pmic->i2c_high_speed != i2c_high_speed) - pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).", + pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).\n", __func__, voltdm->name, i2c_high_speed); return; } |