diff options
Diffstat (limited to 'arch/arm/mach-omap2')
49 files changed, 1115 insertions, 593 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 49ac3dfebef9..b9c0ed3f648c 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -311,9 +311,6 @@ config MACH_OMAP_ZOOM2 default y select OMAP_PACKAGE_CBB select REGULATOR_FIXED_VOLTAGE if REGULATOR - select SERIAL_8250 - select SERIAL_8250_CONSOLE - select SERIAL_CORE_CONSOLE config MACH_OMAP_ZOOM3 bool "OMAP3630 Zoom3 board" @@ -321,9 +318,6 @@ config MACH_OMAP_ZOOM3 default y select OMAP_PACKAGE_CBP select REGULATOR_FIXED_VOLTAGE if REGULATOR - select SERIAL_8250 - select SERIAL_8250_CONSOLE - select SERIAL_CORE_CONSOLE config MACH_CM_T35 bool "CompuLab CM-T35/CM-T3730 modules" @@ -414,7 +408,7 @@ config OMAP3_SDRC_AC_TIMING config OMAP4_ERRATA_I688 bool "OMAP4 errata: Async Bridge Corruption" - depends on ARCH_OMAP4 && !ARCH_MULTIPLATFORM + depends on (ARCH_OMAP4 || SOC_OMAP5) && !ARCH_MULTIPLATFORM select ARCH_HAS_BARRIERS help If a data is stalled inside asynchronous bridge because of back diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index a3e0aaa4886b..cb0596b631cf 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -166,7 +166,7 @@ static void __init sdp2430_display_init(void) omap_display_init(&sdp2430_dss_data); } -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91x_MODULE) +#if IS_ENABLED(CONFIG_SMC91X) static struct omap_smc91x_platform_data board_smc91x_data = { .cs = 5, diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index ce812decfaca..7eb9651dd0f7 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -445,16 +445,23 @@ static void enable_board_wakeup_source(void) OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); } +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 1, + .reset_gpio = 57, + .vcc_gpio = -EINVAL, + }, + { + .port = 2, + .reset_gpio = 61, + .vcc_gpio = -EINVAL, + }, +}; + static struct usbhs_omap_platform_data usbhs_bdata __initdata = { .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, - - .phy_reset = true, - .reset_gpio_port[0] = 57, - .reset_gpio_port[1] = 61, - .reset_gpio_port[2] = -EINVAL }; #ifdef CONFIG_OMAP_MUX @@ -606,6 +613,8 @@ static void __init omap_3430sdp_init(void) board_flash_init(sdp_flash_partitions, chip_sel_3430, 0); sdp3430_display_init(); enable_board_wakeup_source(); + + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); usbhs_init(&usbhs_bdata); } diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index 67447bd4564f..20d6d8189240 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -53,16 +53,23 @@ static void enable_board_wakeup_source(void) OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); } +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 1, + .reset_gpio = 126, + .vcc_gpio = -EINVAL, + }, + { + .port = 2, + .reset_gpio = 61, + .vcc_gpio = -EINVAL, + }, +}; + static struct usbhs_omap_platform_data usbhs_bdata __initdata = { .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, - - .phy_reset = true, - .reset_gpio_port[0] = 126, - .reset_gpio_port[1] = 61, - .reset_gpio_port[2] = -EINVAL }; #ifdef CONFIG_OMAP_MUX @@ -199,6 +206,8 @@ static void __init omap_sdp_init(void) board_smc91x_init(); board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_BUSWIDTH_16); enable_board_wakeup_source(); + + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); usbhs_init(&usbhs_bdata); } diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c index 7d3358b2e593..fc53911d0d13 100644 --- a/arch/arm/mach-omap2/board-am3517crane.c +++ b/arch/arm/mach-omap2/board-am3517crane.c @@ -47,15 +47,17 @@ static struct omap_board_mux board_mux[] __initdata = { }; #endif +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 1, + .reset_gpio = GPIO_USB_NRESET, + .vcc_gpio = GPIO_USB_POWER, + .vcc_polarity = 1, + }, +}; + static struct usbhs_omap_platform_data usbhs_bdata __initdata = { .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, - .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, - - .phy_reset = true, - .reset_gpio_port[0] = GPIO_USB_NRESET, - .reset_gpio_port[1] = -EINVAL, - .reset_gpio_port[2] = -EINVAL }; static struct mtd_partition crane_nand_partitions[] = { @@ -131,13 +133,7 @@ static void __init am3517_crane_init(void) return; } - ret = gpio_request_one(GPIO_USB_POWER, GPIOF_OUT_INIT_HIGH, - "usb_ehci_enable"); - if (ret < 0) { - pr_err("Can not request GPIO %d\n", GPIO_USB_POWER); - return; - } - + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); usbhs_init(&usbhs_bdata); am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1); } diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 9fb85908a61e..191f9762ba63 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -274,6 +274,14 @@ static __init void am3517_evm_mcbsp1_init(void) omap_ctrl_writel(devconf0, OMAP2_CONTROL_DEVCONF0); } +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 1, + .reset_gpio = 57, + .vcc_gpio = -EINVAL, + }, +}; + static struct usbhs_omap_platform_data usbhs_bdata __initdata = { .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, #if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \ @@ -282,12 +290,6 @@ static struct usbhs_omap_platform_data usbhs_bdata __initdata = { #else .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, #endif - .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, - - .phy_reset = true, - .reset_gpio_port[0] = 57, - .reset_gpio_port[1] = -EINVAL, - .reset_gpio_port[2] = -EINVAL }; #ifdef CONFIG_OMAP_MUX @@ -349,7 +351,6 @@ static struct omap2_hsmmc_info mmc[] = { {} /* Terminator */ }; - static void __init am3517_evm_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); @@ -361,6 +362,8 @@ static void __init am3517_evm_init(void) /* Configure GPIO for EHCI port */ omap_mux_init_gpio(57, OMAP_PIN_OUTPUT); + + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); usbhs_init(&usbhs_bdata); am3517_evm_hecc_init(&am3517_evm_hecc_pdata); /* DSS */ diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index af2bb219e214..7fda3f5f8a7f 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -419,15 +419,22 @@ static struct omap2_hsmmc_info mmc[] = { {} /* Terminator */ }; +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 1, + .reset_gpio = OMAP_MAX_GPIO_LINES + 6, + .vcc_gpio = -EINVAL, + }, + { + .port = 2, + .reset_gpio = OMAP_MAX_GPIO_LINES + 7, + .vcc_gpio = -EINVAL, + }, +}; + static struct usbhs_omap_platform_data usbhs_bdata __initdata = { .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, - - .phy_reset = true, - .reset_gpio_port[0] = OMAP_MAX_GPIO_LINES + 6, - .reset_gpio_port[1] = OMAP_MAX_GPIO_LINES + 7, - .reset_gpio_port[2] = -EINVAL }; static void __init cm_t35_init_usbh(void) @@ -444,6 +451,7 @@ static void __init cm_t35_init_usbh(void) msleep(1); } + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); usbhs_init(&usbhs_bdata); } diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c index a66da808cc4a..4eb5e6f2f7f5 100644 --- a/arch/arm/mach-omap2/board-cm-t3517.c +++ b/arch/arm/mach-omap2/board-cm-t3517.c @@ -188,15 +188,22 @@ static inline void cm_t3517_init_rtc(void) {} #define HSUSB2_RESET_GPIO (147) #define USB_HUB_RESET_GPIO (152) +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 1, + .reset_gpio = HSUSB1_RESET_GPIO, + .vcc_gpio = -EINVAL, + }, + { + .port = 2, + .reset_gpio = HSUSB2_RESET_GPIO, + .vcc_gpio = -EINVAL, + }, +}; + static struct usbhs_omap_platform_data cm_t3517_ehci_pdata __initdata = { .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, - - .phy_reset = true, - .reset_gpio_port[0] = HSUSB1_RESET_GPIO, - .reset_gpio_port[1] = HSUSB2_RESET_GPIO, - .reset_gpio_port[2] = -EINVAL, }; static int __init cm_t3517_init_usbh(void) @@ -213,6 +220,7 @@ static int __init cm_t3517_init_usbh(void) msleep(1); } + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); usbhs_init(&cm_t3517_ehci_pdata); return 0; @@ -324,6 +332,6 @@ MACHINE_START(CM_T3517, "Compulab CM-T3517") .handle_irq = omap3_intc_handle_irq, .init_machine = cm_t3517_init, .init_late = am35xx_init_late, - .init_time = omap3_gp_gptimer_timer_init, + .init_time = omap3_gptimer_timer_init, .restart = omap3xxx_restart, MACHINE_END diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index 53056c3b0836..42fbf1ef12a9 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c @@ -437,15 +437,7 @@ static struct platform_device *devkit8000_devices[] __initdata = { }; static struct usbhs_omap_platform_data usbhs_bdata __initdata = { - .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, - .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, - - .phy_reset = true, - .reset_gpio_port[0] = -EINVAL, - .reset_gpio_port[1] = -EINVAL, - .reset_gpio_port[2] = -EINVAL }; #ifdef CONFIG_OMAP_MUX diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 0274ff7a2a2b..78813b397209 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -102,6 +102,7 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)") .init_irq = omap_intc_of_init, .handle_irq = omap3_intc_handle_irq, .init_machine = omap_generic_init, + .init_late = omap3_init_late, .init_time = omap3_sync32k_timer_init, .dt_compat = omap3_boards_compat, .restart = omap3xxx_restart, @@ -119,6 +120,7 @@ DT_MACHINE_START(OMAP3_GP_DT, "Generic OMAP3-GP (Flattened Device Tree)") .init_irq = omap_intc_of_init, .handle_irq = omap3_intc_handle_irq, .init_machine = omap_generic_init, + .init_late = omap3_init_late, .init_time = omap3_secure_sync32k_timer_init, .dt_compat = omap3_gp_boards_compat, .restart = omap3xxx_restart, @@ -138,7 +140,7 @@ DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)") .init_irq = omap_intc_of_init, .handle_irq = omap3_intc_handle_irq, .init_machine = omap_generic_init, - .init_time = omap3_am33xx_gptimer_timer_init, + .init_time = omap3_gptimer_timer_init, .dt_compat = am33xx_boards_compat, .restart = am33xx_restart, MACHINE_END diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index 812c829fa46f..5b4ec51c385f 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -246,7 +246,7 @@ static u32 is_gpmc_muxed(void) return 0; } -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91x_MODULE) +#if IS_ENABLED(CONFIG_SMC91X) static struct omap_smc91x_platform_data board_smc91x_data = { .cs = 1, diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index bf92678a01d0..95ccec0eeab9 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -527,26 +527,28 @@ static void __init igep_i2c_init(void) omap3_pmic_init("twl4030", &igep_twldata); } +static struct usbhs_phy_data igep2_phy_data[] __initdata = { + { + .port = 1, + .reset_gpio = IGEP2_GPIO_USBH_NRESET, + .vcc_gpio = -EINVAL, + }, +}; + +static struct usbhs_phy_data igep3_phy_data[] __initdata = { + { + .port = 2, + .reset_gpio = IGEP3_GPIO_USBH_NRESET, + .vcc_gpio = -EINVAL, + }, +}; + static struct usbhs_omap_platform_data igep2_usbhs_bdata __initdata = { .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, - .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, - - .phy_reset = true, - .reset_gpio_port[0] = IGEP2_GPIO_USBH_NRESET, - .reset_gpio_port[1] = -EINVAL, - .reset_gpio_port[2] = -EINVAL, }; static struct usbhs_omap_platform_data igep3_usbhs_bdata __initdata = { - .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, - - .phy_reset = true, - .reset_gpio_port[0] = -EINVAL, - .reset_gpio_port[1] = IGEP3_GPIO_USBH_NRESET, - .reset_gpio_port[2] = -EINVAL, }; #ifdef CONFIG_OMAP_MUX @@ -642,8 +644,10 @@ static void __init igep_init(void) if (machine_is_igep0020()) { omap_display_init(&igep2_dss_data); igep2_init_smsc911x(); + usbhs_init_phys(igep2_phy_data, ARRAY_SIZE(igep2_phy_data)); usbhs_init(&igep2_usbhs_bdata); } else { + usbhs_init_phys(igep3_phy_data, ARRAY_SIZE(igep3_phy_data)); usbhs_init(&igep3_usbhs_bdata); } } diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index c3558f93d42c..6955a428f534 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -33,6 +33,7 @@ #include <linux/mtd/nand.h> #include <linux/mmc/host.h> #include <linux/usb/phy.h> +#include <linux/usb/nop-usb-xceiv.h> #include <linux/regulator/machine.h> #include <linux/i2c/twl.h> @@ -277,6 +278,21 @@ static struct regulator_consumer_supply beagle_vsim_supply[] = { static struct gpio_led gpio_leds[]; +/* PHY's VCC regulator might be added later, so flag that we need it */ +static struct nop_usb_xceiv_platform_data hsusb2_phy_data = { + .needs_vcc = true, +}; + +static struct usbhs_phy_data phy_data[] = { + { + .port = 2, + .reset_gpio = 147, + .vcc_gpio = -1, /* updated in beagle_twl_gpio_setup */ + .vcc_polarity = 1, /* updated in beagle_twl_gpio_setup */ + .platform_data = &hsusb2_phy_data, + }, +}; + static int beagle_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio) { @@ -318,9 +334,11 @@ static int beagle_twl_gpio_setup(struct device *dev, } dvi_panel.power_down_gpio = beagle_config.dvi_pd_gpio; - gpio_request_one(gpio + TWL4030_GPIO_MAX, beagle_config.usb_pwr_level, - "nEN_USB_PWR"); + /* TWL4030_GPIO_MAX i.e. LED_GPO controls HS USB Port 2 power */ + phy_data[0].vcc_gpio = gpio + TWL4030_GPIO_MAX; + phy_data[0].vcc_polarity = beagle_config.usb_pwr_level; + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); return 0; } @@ -453,15 +471,7 @@ static struct platform_device *omap3_beagle_devices[] __initdata = { }; static struct usbhs_omap_platform_data usbhs_bdata __initdata = { - - .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, - - .phy_reset = true, - .reset_gpio_port[0] = -EINVAL, - .reset_gpio_port[1] = 147, - .reset_gpio_port[2] = -EINVAL }; #ifdef CONFIG_OMAP_MUX @@ -479,7 +489,7 @@ static int __init beagle_opp_init(void) /* Initialize the omap3 opp table if not already created. */ r = omap3_opp_init(); - if (IS_ERR_VALUE(r) && (r != -EEXIST)) { + if (r < 0 && (r != -EEXIST)) { pr_err("%s: opp default init failed\n", __func__); return r; } @@ -543,7 +553,9 @@ static void __init omap3_beagle_init(void) usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); usb_musb_init(NULL); + usbhs_init(&usbhs_bdata); + board_nand_init(omap3beagle_nand_partitions, ARRAY_SIZE(omap3beagle_nand_partitions), NAND_CS, NAND_BUSWIDTH_16, NULL); diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index 48789e0bb915..2de92facc8a3 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -496,7 +496,7 @@ struct wl12xx_platform_data omap3evm_wlan_data __initdata = { 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("vcc", "nop_usb_xceiv.2"), /* hsusb port 2 */ REGULATOR_SUPPLY("vaux2", NULL), }; @@ -539,17 +539,16 @@ static int __init omap3_evm_i2c_init(void) return 0; } -static struct usbhs_omap_platform_data usbhs_bdata __initdata = { +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 2, + .reset_gpio = -1, /* set at runtime */ + .vcc_gpio = -EINVAL, + }, +}; - .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, +static struct usbhs_omap_platform_data usbhs_bdata __initdata = { .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, - - .phy_reset = true, - /* PHY reset GPIO will be runtime programmed based on EVM version */ - .reset_gpio_port[0] = -EINVAL, - .reset_gpio_port[1] = -EINVAL, - .reset_gpio_port[2] = -EINVAL }; #ifdef CONFIG_OMAP_MUX @@ -725,7 +724,7 @@ static void __init omap3_evm_init(void) /* setup EHCI phy reset config */ omap_mux_init_gpio(21, OMAP_PIN_INPUT_PULLUP); - usbhs_bdata.reset_gpio_port[1] = 21; + phy_data[0].reset_gpio = 21; /* EVM REV >= E can supply 500mA with EXTVBUS programming */ musb_board_data.power = 500; @@ -733,10 +732,12 @@ static void __init omap3_evm_init(void) } else { /* setup EHCI phy reset on MDC */ omap_mux_init_gpio(135, OMAP_PIN_OUTPUT); - usbhs_bdata.reset_gpio_port[1] = 135; + phy_data[0].reset_gpio = 135; } usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); usb_musb_init(&musb_board_data); + + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); usbhs_init(&usbhs_bdata); board_nand_init(omap3evm_nand_partitions, ARRAY_SIZE(omap3evm_nand_partitions), NAND_CS, diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 2bba362148a0..1004d2aaa68f 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -346,7 +346,7 @@ static struct regulator_consumer_supply pandora_vcc_lcd_supply[] = { }; static struct regulator_consumer_supply pandora_usb_phy_supply[] = { - REGULATOR_SUPPLY("hsusb1", "ehci-omap.0"), + REGULATOR_SUPPLY("vcc", "nop_usb_xceiv.2"), /* hsusb port 2 */ }; /* ads7846 on SPI and 2 nub controllers on I2C */ @@ -561,6 +561,14 @@ fail: printk(KERN_ERR "wl1251 board initialisation failed\n"); } +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 2, + .reset_gpio = 16, + .vcc_gpio = -EINVAL, + }, +}; + static struct platform_device *omap3pandora_devices[] __initdata = { &pandora_leds_gpio, &pandora_keys_gpio, @@ -569,15 +577,7 @@ static struct platform_device *omap3pandora_devices[] __initdata = { }; static struct usbhs_omap_platform_data usbhs_bdata __initdata = { - - .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, - - .phy_reset = true, - .reset_gpio_port[0] = -EINVAL, - .reset_gpio_port[1] = 16, - .reset_gpio_port[2] = -EINVAL }; #ifdef CONFIG_OMAP_MUX @@ -601,7 +601,10 @@ static void __init omap3pandora_init(void) spi_register_board_info(omap3pandora_spi_board_info, ARRAY_SIZE(omap3pandora_spi_board_info)); omap_ads7846_init(1, OMAP3_PANDORA_TS_GPIO, 0, NULL); + + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); usbhs_init(&usbhs_bdata); + usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); usb_musb_init(NULL); gpmc_nand_init(&pandora_nand_data, NULL); diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c index 95c10b3aa678..bf0956489899 100644 --- a/arch/arm/mach-omap2/board-omap3stalker.c +++ b/arch/arm/mach-omap2/board-omap3stalker.c @@ -358,19 +358,20 @@ static int __init omap3_stalker_i2c_init(void) #define OMAP3_STALKER_TS_GPIO 175 +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 2, + .reset_gpio = 21, + .vcc_gpio = -EINVAL, + }, +}; + static struct platform_device *omap3_stalker_devices[] __initdata = { &keys_gpio, }; static struct usbhs_omap_platform_data usbhs_bdata __initdata = { - .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, - - .phy_reset = true, - .reset_gpio_port[0] = -EINVAL, - .reset_gpio_port[1] = 21, - .reset_gpio_port[2] = -EINVAL, }; #ifdef CONFIG_OMAP_MUX @@ -407,6 +408,8 @@ static void __init omap3_stalker_init(void) omap_sdrc_init(mt46h32m32lf6_sdrc_params, NULL); usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); usb_musb_init(NULL); + + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); usbhs_init(&usbhs_bdata); omap_ads7846_init(1, OMAP3_STALKER_TS_GPIO, 310, NULL); diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c index bcd44fbcd877..7da48bc42bbf 100644 --- a/arch/arm/mach-omap2/board-omap3touchbook.c +++ b/arch/arm/mach-omap2/board-omap3touchbook.c @@ -305,21 +305,22 @@ static struct omap_board_mux board_mux[] __initdata = { }; #endif +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 2, + .reset_gpio = 147, + .vcc_gpio = -EINVAL, + }, +}; + static struct platform_device *omap3_touchbook_devices[] __initdata = { &leds_gpio, &keys_gpio, }; static struct usbhs_omap_platform_data usbhs_bdata __initdata = { - .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, - - .phy_reset = true, - .reset_gpio_port[0] = -EINVAL, - .reset_gpio_port[1] = 147, - .reset_gpio_port[2] = -EINVAL }; static void omap3_touchbook_poweroff(void) @@ -368,6 +369,8 @@ static void __init omap3_touchbook_init(void) omap_ads7846_init(4, OMAP3_TS_GPIO, 310, &ads7846_pdata); usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); usb_musb_init(NULL); + + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); usbhs_init(&usbhs_bdata); board_nand_init(omap3touchbook_nand_partitions, ARRAY_SIZE(omap3touchbook_nand_partitions), NAND_CS, diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index b02c2f00609b..a71ad345f20d 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -31,6 +31,7 @@ #include <linux/ti_wilink_st.h> #include <linux/usb/musb.h> #include <linux/usb/phy.h> +#include <linux/usb/nop-usb-xceiv.h> #include <linux/wl12xx.h> #include <linux/irqchip/arm-gic.h> #include <linux/platform_data/omap-abe-twl6040.h> @@ -132,6 +133,22 @@ static struct platform_device btwilink_device = { .id = -1, }; +/* PHY device on HS USB Port 1 i.e. nop_usb_xceiv.1 */ +static struct nop_usb_xceiv_platform_data hsusb1_phy_data = { + /* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */ + .clk_rate = 19200000, +}; + +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 1, + .reset_gpio = GPIO_HUB_NRESET, + .vcc_gpio = GPIO_HUB_POWER, + .vcc_polarity = 1, + .platform_data = &hsusb1_phy_data, + }, +}; + static struct platform_device *panda_devices[] __initdata = { &leds_gpio, &wl1271_device, @@ -142,49 +159,19 @@ static struct platform_device *panda_devices[] __initdata = { static struct usbhs_omap_platform_data usbhs_bdata __initdata = { .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, - .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, - .phy_reset = false, - .reset_gpio_port[0] = -EINVAL, - .reset_gpio_port[1] = -EINVAL, - .reset_gpio_port[2] = -EINVAL -}; - -static struct gpio panda_ehci_gpios[] __initdata = { - { GPIO_HUB_POWER, GPIOF_OUT_INIT_LOW, "hub_power" }, - { GPIO_HUB_NRESET, GPIOF_OUT_INIT_LOW, "hub_nreset" }, }; static void __init omap4_ehci_init(void) { int ret; - struct clk *phy_ref_clk; /* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */ - phy_ref_clk = clk_get(NULL, "auxclk3_ck"); - if (IS_ERR(phy_ref_clk)) { - pr_err("Cannot request auxclk3\n"); - return; - } - clk_set_rate(phy_ref_clk, 19200000); - clk_prepare_enable(phy_ref_clk); - - /* disable the power to the usb hub prior to init and reset phy+hub */ - ret = gpio_request_array(panda_ehci_gpios, - ARRAY_SIZE(panda_ehci_gpios)); - if (ret) { - pr_err("Unable to initialize EHCI power/reset\n"); - return; - } - - gpio_export(GPIO_HUB_POWER, 0); - gpio_export(GPIO_HUB_NRESET, 0); - gpio_set_value(GPIO_HUB_NRESET, 1); + ret = clk_add_alias("main_clk", "nop_usb_xceiv.1", "auxclk3_ck", NULL); + if (ret) + pr_err("Failed to add main_clk alias to auxclk3_ck\n"); + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); usbhs_init(&usbhs_bdata); - - /* enable power to hub */ - gpio_set_value(GPIO_HUB_POWER, 1); } static struct omap_musb_board_data musb_board_data = { diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index 86bab51154ee..ab79a4422bcc 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c @@ -458,14 +458,16 @@ static int __init overo_spi_init(void) return 0; } +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 2, + .reset_gpio = OVERO_GPIO_USBH_NRESET, + .vcc_gpio = -EINVAL, + }, +}; + static struct usbhs_omap_platform_data usbhs_bdata __initdata = { - .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, - .phy_reset = true, - .reset_gpio_port[0] = -EINVAL, - .reset_gpio_port[1] = OVERO_GPIO_USBH_NRESET, - .reset_gpio_port[2] = -EINVAL }; #ifdef CONFIG_OMAP_MUX @@ -502,6 +504,8 @@ static void __init overo_init(void) ARRAY_SIZE(overo_nand_partitions), NAND_CS, 0, NULL); usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); usb_musb_init(NULL); + + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); usbhs_init(&usbhs_bdata); overo_spi_init(); overo_init_smsc911x(); diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c index f7c4616cbb60..d2ea68ea678a 100644 --- a/arch/arm/mach-omap2/board-rx51.c +++ b/arch/arm/mach-omap2/board-rx51.c @@ -17,6 +17,7 @@ #include <linux/io.h> #include <linux/gpio.h> #include <linux/leds.h> +#include <linux/usb/phy.h> #include <linux/usb/musb.h> #include <linux/platform_data/spi-omap2-mcspi.h> @@ -98,6 +99,7 @@ static void __init rx51_init(void) sdrc_params = nokia_get_sdram_timings(); omap_sdrc_init(sdrc_params, sdrc_params); + usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); usb_musb_init(&musb_board_data); rx51_peripherals_init(); diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c index 5e4d4c9fe61a..1a3dd865d8eb 100644 --- a/arch/arm/mach-omap2/board-zoom.c +++ b/arch/arm/mach-omap2/board-zoom.c @@ -92,14 +92,16 @@ static struct mtd_partition zoom_nand_partitions[] = { }, }; +static struct usbhs_phy_data phy_data[] __initdata = { + { + .port = 2, + .reset_gpio = ZOOM3_EHCI_RESET_GPIO, + .vcc_gpio = -EINVAL, + }, +}; + static struct usbhs_omap_platform_data usbhs_bdata __initdata = { - .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, - .phy_reset = true, - .reset_gpio_port[0] = -EINVAL, - .reset_gpio_port[1] = ZOOM3_EHCI_RESET_GPIO, - .reset_gpio_port[2] = -EINVAL, }; static void __init omap_zoom_init(void) @@ -109,6 +111,8 @@ static void __init omap_zoom_init(void) } else if (machine_is_omap_zoom3()) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBP); omap_mux_init_gpio(ZOOM3_EHCI_RESET_GPIO, OMAP_PIN_OUTPUT); + + usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); usbhs_init(&usbhs_bdata); } diff --git a/arch/arm/mach-omap2/cclock33xx_data.c b/arch/arm/mach-omap2/cclock33xx_data.c index 476b82066cb6..7f091c85384e 100644 --- a/arch/arm/mach-omap2/cclock33xx_data.c +++ b/arch/arm/mach-omap2/cclock33xx_data.c @@ -958,6 +958,14 @@ int __init am33xx_clk_init(void) clk_set_parent(&timer3_fck, &sys_clkin_ck); clk_set_parent(&timer6_fck, &sys_clkin_ck); + /* + * The On-Chip 32K RC Osc clock is not an accurate clock-source as per + * the design/spec, so as a result, for example, timer which supposed + * to get expired @60Sec, but will expire somewhere ~@40Sec, which is + * not expected by any use-case, so change WDT1 clock source to PRCM + * 32KHz clock. + */ + clk_set_parent(&wdt1_fck, &clkdiv32k_ick); return 0; } diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index e4ec3a69ee2e..2191f25ad21b 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -596,7 +596,7 @@ int __init omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name) return -ENOENT; r = clk_set_rate(mpurate_ck, mpurate); - if (IS_ERR_VALUE(r)) { + if (r < 0) { WARN(1, "clock: %s: unable to set MPU rate to %d: %d\n", mpurate_ck_name, mpurate, r); clk_put(mpurate_ck); diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 0a6b9c7a63da..bf70e2b57ff8 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -82,8 +82,7 @@ extern void omap2_init_common_infrastructure(void); extern void omap2_sync32k_timer_init(void); extern void omap3_sync32k_timer_init(void); extern void omap3_secure_sync32k_timer_init(void); -extern void omap3_gp_gptimer_timer_init(void); -extern void omap3_am33xx_gptimer_timer_init(void); +extern void omap3_gptimer_timer_init(void); extern void omap4_local_timer_init(void); extern void omap5_realtime_timer_init(void); @@ -108,7 +107,6 @@ void omap35xx_init_late(void); void omap3630_init_late(void); void am35xx_init_late(void); void ti81xx_init_late(void); -void omap4430_init_late(void); int omap2_common_pm_late_init(void); #if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430) diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index 3aed4b0b9563..3a0296cfcace 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c @@ -307,10 +307,10 @@ static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 freqsel) _omap3_noncore_dpll_bypass(clk); /* - * Set jitter correction. No jitter correction for OMAP4 and 3630 - * since freqsel field is no longer present + * Set jitter correction. Jitter correction applicable for OMAP343X + * only since freqsel field is no longer present on other devices. */ - if (!soc_is_am33xx() && !cpu_is_omap44xx() && !cpu_is_omap3630()) { + if (cpu_is_omap343x()) { v = __raw_readl(dd->control_reg); v &= ~dd->freqsel_mask; v |= freqsel << __ffs(dd->freqsel_mask); @@ -480,29 +480,30 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, if (!dd) return -EINVAL; - __clk_prepare(dd->clk_bypass); - clk_enable(dd->clk_bypass); - __clk_prepare(dd->clk_ref); - clk_enable(dd->clk_ref); - if (__clk_get_rate(dd->clk_bypass) == rate && (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { pr_debug("%s: %s: set rate: entering bypass.\n", __func__, __clk_get_name(hw->clk)); + __clk_prepare(dd->clk_bypass); + clk_enable(dd->clk_bypass); ret = _omap3_noncore_dpll_bypass(clk); if (!ret) new_parent = dd->clk_bypass; + clk_disable(dd->clk_bypass); + __clk_unprepare(dd->clk_bypass); } else { + __clk_prepare(dd->clk_ref); + clk_enable(dd->clk_ref); + if (dd->last_rounded_rate != rate) rate = __clk_round_rate(hw->clk, rate); if (dd->last_rounded_rate == 0) return -EINVAL; - /* No freqsel on AM335x, OMAP4 and OMAP3630 */ - if (!soc_is_am33xx() && !cpu_is_omap44xx() && - !cpu_is_omap3630()) { + /* Freqsel is available only on OMAP343X devices */ + if (cpu_is_omap343x()) { freqsel = _omap3_dpll_compute_freqsel(clk, dd->last_rounded_n); WARN_ON(!freqsel); @@ -514,6 +515,8 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, ret = omap3_noncore_dpll_program(clk, freqsel); if (!ret) new_parent = dd->clk_ref; + clk_disable(dd->clk_ref); + __clk_unprepare(dd->clk_ref); } /* * FIXME - this is all wrong. common code handles reparenting and @@ -525,11 +528,6 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, if (!ret) __clk_reparent(hw->clk, new_parent); - clk_disable(dd->clk_ref); - __clk_unprepare(dd->clk_ref); - clk_disable(dd->clk_bypass); - __clk_unprepare(dd->clk_bypass); - return 0; } diff --git a/arch/arm/mach-omap2/dsp.c b/arch/arm/mach-omap2/dsp.c index b155500e84a8..b8208b4b1bd9 100644 --- a/arch/arm/mach-omap2/dsp.c +++ b/arch/arm/mach-omap2/dsp.c @@ -26,7 +26,7 @@ #include "control.h" #include "cm2xxx_3xxx.h" #include "prm2xxx_3xxx.h" -#ifdef CONFIG_BRIDGE_DVFS +#ifdef CONFIG_TIDSPBRIDGE_DVFS #include "omap-pm.h" #endif @@ -35,7 +35,7 @@ static struct platform_device *omap_dsp_pdev; static struct omap_dsp_platform_data omap_dsp_pdata __initdata = { -#ifdef CONFIG_BRIDGE_DVFS +#ifdef CONFIG_TIDSPBRIDGE_DVFS .dsp_set_min_opp = omap_pm_dsp_set_min_opp, .dsp_get_opp = omap_pm_dsp_get_opp, .cpu_set_freq = omap_pm_cpu_set_freq, diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c index afc1e8c32d6c..d9c27195caf0 100644 --- a/arch/arm/mach-omap2/gpmc-nand.c +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -74,14 +74,6 @@ static int omap2_nand_gpmc_retime( t.cs_wr_off = gpmc_t->cs_wr_off; t.wr_cycle = gpmc_t->wr_cycle; - /* Configure GPMC */ - if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16) - gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_DEV_SIZE, 1); - else - gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_DEV_SIZE, 0); - gpmc_cs_configure(gpmc_nand_data->cs, - GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND); - gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_WP, 0); err = gpmc_cs_set_timings(gpmc_nand_data->cs, &t); if (err) return err; @@ -115,14 +107,18 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, struct gpmc_timings *gpmc_t) { int err = 0; + struct gpmc_settings s; struct device *dev = &gpmc_nand_device.dev; + memset(&s, 0, sizeof(struct gpmc_settings)); + gpmc_nand_device.dev.platform_data = gpmc_nand_data; err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE, (unsigned long *)&gpmc_nand_resource[0].start); if (err < 0) { - dev_err(dev, "Cannot request GPMC CS\n"); + dev_err(dev, "Cannot request GPMC CS %d, error %d\n", + gpmc_nand_data->cs, err); return err; } @@ -140,11 +136,31 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, dev_err(dev, "Unable to set gpmc timings: %d\n", err); return err; } - } - /* Enable RD PIN Monitoring Reg */ - if (gpmc_nand_data->dev_ready) { - gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_RDY_BSY, 1); + if (gpmc_nand_data->of_node) { + gpmc_read_settings_dt(gpmc_nand_data->of_node, &s); + } else { + s.device_nand = true; + + /* Enable RD PIN Monitoring Reg */ + if (gpmc_nand_data->dev_ready) { + s.wait_on_read = true; + s.wait_on_write = true; + } + } + + if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16) + s.device_width = GPMC_DEVWIDTH_16BIT; + else + s.device_width = GPMC_DEVWIDTH_8BIT; + + err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s); + if (err < 0) + goto out_free_cs; + + err = gpmc_configure(GPMC_CONFIG_WP, 0); + if (err < 0) + goto out_free_cs; } gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs); diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c index fadd87435cd0..64b5a8346982 100644 --- a/arch/arm/mach-omap2/gpmc-onenand.c +++ b/arch/arm/mach-omap2/gpmc-onenand.c @@ -47,11 +47,23 @@ static struct platform_device gpmc_onenand_device = { .resource = &gpmc_onenand_resource, }; -static struct gpmc_timings omap2_onenand_calc_async_timings(void) +static struct gpmc_settings onenand_async = { + .device_width = GPMC_DEVWIDTH_16BIT, + .mux_add_data = GPMC_MUX_AD, +}; + +static struct gpmc_settings onenand_sync = { + .burst_read = true, + .burst_wrap = true, + .burst_len = GPMC_BURST_16, + .device_width = GPMC_DEVWIDTH_16BIT, + .mux_add_data = GPMC_MUX_AD, + .wait_pin = 0, +}; + +static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) { struct gpmc_device_timings dev_t; - struct gpmc_timings t; - const int t_cer = 15; const int t_avdp = 12; const int t_aavdh = 7; @@ -64,7 +76,6 @@ static struct gpmc_timings omap2_onenand_calc_async_timings(void) memset(&dev_t, 0, sizeof(dev_t)); - dev_t.mux = true; dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000; dev_t.t_avdp_w = dev_t.t_avdp_r; dev_t.t_aavdh = t_aavdh * 1000; @@ -76,19 +87,7 @@ static struct gpmc_timings omap2_onenand_calc_async_timings(void) dev_t.t_wpl = t_wpl * 1000; dev_t.t_wph = t_wph * 1000; - gpmc_calc_timings(&t, &dev_t); - - return t; -} - -static int gpmc_set_async_mode(int cs, struct gpmc_timings *t) -{ - /* Configure GPMC for asynchronous read */ - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, - GPMC_CONFIG1_DEVICESIZE_16 | - GPMC_CONFIG1_MUXADDDATA); - - return gpmc_cs_set_timings(cs, t); + gpmc_calc_timings(t, &onenand_async, &dev_t); } static void omap2_onenand_set_async_mode(void __iomem *onenand_base) @@ -158,12 +157,11 @@ static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg, return freq; } -static struct gpmc_timings -omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg, - int freq) +static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t, + unsigned int flags, + int freq) { struct gpmc_device_timings dev_t; - struct gpmc_timings t; const int t_cer = 15; const int t_avdp = 12; const int t_cez = 20; /* max of t_cez, t_oez */ @@ -172,9 +170,9 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg, int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo; int div, gpmc_clk_ns; - if (cfg->flags & ONENAND_SYNC_READ) + if (flags & ONENAND_SYNC_READ) onenand_flags = ONENAND_FLAG_SYNCREAD; - else if (cfg->flags & ONENAND_SYNC_READWRITE) + else if (flags & ONENAND_SYNC_READWRITE) onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE; switch (freq) { @@ -239,10 +237,11 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg, /* Set synchronous read timings */ memset(&dev_t, 0, sizeof(dev_t)); - dev_t.mux = true; - dev_t.sync_read = true; + if (onenand_flags & ONENAND_FLAG_SYNCREAD) + onenand_sync.sync_read = true; if (onenand_flags & ONENAND_FLAG_SYNCWRITE) { - dev_t.sync_write = true; + onenand_sync.sync_write = true; + onenand_sync.burst_write = true; } else { dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000; dev_t.t_wpl = t_wpl * 1000; @@ -265,32 +264,7 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg, dev_t.cyc_aavdh_oe = 1; dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period; - gpmc_calc_timings(&t, &dev_t); - - return t; -} - -static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t) -{ - unsigned sync_read = onenand_flags & ONENAND_FLAG_SYNCREAD; - unsigned sync_write = onenand_flags & ONENAND_FLAG_SYNCWRITE; - - /* Configure GPMC for synchronous read */ - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, - GPMC_CONFIG1_WRAPBURST_SUPP | - GPMC_CONFIG1_READMULTIPLE_SUPP | - (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) | - (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) | - (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) | - GPMC_CONFIG1_PAGE_LEN(2) | - (cpu_is_omap34xx() ? 0 : - (GPMC_CONFIG1_WAIT_READ_MON | - GPMC_CONFIG1_WAIT_PIN_SEL(0))) | - GPMC_CONFIG1_DEVICESIZE_16 | - GPMC_CONFIG1_DEVICETYPE_NOR | - GPMC_CONFIG1_MUXADDDATA); - - return gpmc_cs_set_timings(cs, t); + gpmc_calc_timings(t, &onenand_sync, &dev_t); } static int omap2_onenand_setup_async(void __iomem *onenand_base) @@ -298,12 +272,20 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base) struct gpmc_timings t; int ret; + if (gpmc_onenand_data->of_node) + gpmc_read_settings_dt(gpmc_onenand_data->of_node, + &onenand_async); + omap2_onenand_set_async_mode(onenand_base); - t = omap2_onenand_calc_async_timings(); + omap2_onenand_calc_async_timings(&t); + + ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_async); + if (ret < 0) + return ret; - ret = gpmc_set_async_mode(gpmc_onenand_data->cs, &t); - if (IS_ERR_VALUE(ret)) + ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t); + if (ret < 0) return ret; omap2_onenand_set_async_mode(onenand_base); @@ -322,10 +304,26 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr) set_onenand_cfg(onenand_base); } - t = omap2_onenand_calc_sync_timings(gpmc_onenand_data, freq); + if (gpmc_onenand_data->of_node) { + gpmc_read_settings_dt(gpmc_onenand_data->of_node, + &onenand_sync); + } else { + /* + * FIXME: Appears to be legacy code from initial ONENAND commit. + * Unclear what boards this is for and if this can be removed. + */ + if (!cpu_is_omap34xx()) + onenand_sync.wait_on_read = true; + } + + omap2_onenand_calc_sync_timings(&t, gpmc_onenand_data->flags, freq); - ret = gpmc_set_sync_mode(gpmc_onenand_data->cs, &t); - if (IS_ERR_VALUE(ret)) + ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_sync); + if (ret < 0) + return ret; + + ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t); + if (ret < 0) return ret; set_onenand_cfg(onenand_base); @@ -359,6 +357,7 @@ static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr) void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data) { int err; + struct device *dev = &gpmc_onenand_device.dev; gpmc_onenand_data = _onenand_data; gpmc_onenand_data->onenand_setup = gpmc_onenand_setup; @@ -366,7 +365,7 @@ void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data) if (cpu_is_omap24xx() && (gpmc_onenand_data->flags & ONENAND_SYNC_READWRITE)) { - printk(KERN_ERR "Onenand using only SYNC_READ on 24xx\n"); + dev_warn(dev, "OneNAND using only SYNC_READ on 24xx\n"); gpmc_onenand_data->flags &= ~ONENAND_SYNC_READWRITE; gpmc_onenand_data->flags |= ONENAND_SYNC_READ; } @@ -379,7 +378,8 @@ void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data) err = gpmc_cs_request(gpmc_onenand_data->cs, ONENAND_IO_SIZE, (unsigned long *)&gpmc_onenand_resource.start); if (err < 0) { - pr_err("%s: Cannot request GPMC CS\n", __func__); + dev_err(dev, "Cannot request GPMC CS %d, error %d\n", + gpmc_onenand_data->cs, err); return; } @@ -387,7 +387,7 @@ void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data) ONENAND_IO_SIZE - 1; if (platform_device_register(&gpmc_onenand_device) < 0) { - pr_err("%s: Unable to register OneNAND device\n", __func__); + dev_err(dev, "Unable to register OneNAND device\n"); gpmc_cs_free(gpmc_onenand_data->cs); return; } diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c index 11d0b756f098..61a063595e66 100644 --- a/arch/arm/mach-omap2/gpmc-smc91x.c +++ b/arch/arm/mach-omap2/gpmc-smc91x.c @@ -49,6 +49,10 @@ static struct platform_device gpmc_smc91x_device = { .resource = gpmc_smc91x_resources, }; +static struct gpmc_settings smc91x_settings = { + .device_width = GPMC_DEVWIDTH_16BIT, +}; + /* * Set the gpmc timings for smc91c96. The timings are taken * from the data sheet available at: @@ -67,18 +71,6 @@ static int smc91c96_gpmc_retime(void) const int t7 = 5; /* Figure 12.4 write */ const int t8 = 5; /* Figure 12.4 write */ const int t20 = 185; /* Figure 12.2 read and 12.4 write */ - u32 l; - - l = GPMC_CONFIG1_DEVICESIZE_16; - if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA) - l |= GPMC_CONFIG1_MUXADDDATA; - if (gpmc_cfg->flags & GPMC_READ_MON) - l |= GPMC_CONFIG1_WAIT_READ_MON; - if (gpmc_cfg->flags & GPMC_WRITE_MON) - l |= GPMC_CONFIG1_WAIT_WRITE_MON; - if (gpmc_cfg->wait_pin) - l |= GPMC_CONFIG1_WAIT_PIN_SEL(gpmc_cfg->wait_pin); - gpmc_cs_write_reg(gpmc_cfg->cs, GPMC_CS_CONFIG1, l); /* * FIXME: Calculate the address and data bus muxed timings. @@ -104,7 +96,7 @@ static int smc91c96_gpmc_retime(void) dev_t.t_cez_w = t4_w * 1000; dev_t.t_wr_cycle = (t20 - t3) * 1000; - gpmc_calc_timings(&t, &dev_t); + gpmc_calc_timings(&t, &smc91x_settings, &dev_t); return gpmc_cs_set_timings(gpmc_cfg->cs, &t); } @@ -133,6 +125,18 @@ void __init gpmc_smc91x_init(struct omap_smc91x_platform_data *board_data) gpmc_smc91x_resources[0].end = cs_mem_base + 0x30f; gpmc_smc91x_resources[1].flags |= (gpmc_cfg->flags & IRQF_TRIGGER_MASK); + if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA) + smc91x_settings.mux_add_data = GPMC_MUX_AD; + if (gpmc_cfg->flags & GPMC_READ_MON) + smc91x_settings.wait_on_read = true; + if (gpmc_cfg->flags & GPMC_WRITE_MON) + smc91x_settings.wait_on_write = true; + if (gpmc_cfg->wait_pin) + smc91x_settings.wait_pin = gpmc_cfg->wait_pin; + ret = gpmc_cs_program_settings(gpmc_cfg->cs, &smc91x_settings); + if (ret < 0) + goto free1; + if (gpmc_cfg->retime) { ret = gpmc_cfg->retime(); if (ret != 0) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index e4b16c8efe8b..ed946df5ad8a 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -26,6 +26,7 @@ #include <linux/interrupt.h> #include <linux/platform_device.h> #include <linux/of.h> +#include <linux/of_address.h> #include <linux/of_mtd.h> #include <linux/of_device.h> #include <linux/mtd/nand.h> @@ -91,9 +92,7 @@ #define GPMC_CS_SIZE 0x30 #define GPMC_BCH_SIZE 0x10 -#define GPMC_MEM_START 0x00000000 #define GPMC_MEM_END 0x3FFFFFFF -#define BOOT_ROM_SPACE 0x100000 /* 1MB */ #define GPMC_CHUNK_SHIFT 24 /* 16 MB */ #define GPMC_SECTION_SHIFT 28 /* 128 MB */ @@ -107,6 +106,9 @@ #define GPMC_HAS_WR_ACCESS 0x1 #define GPMC_HAS_WR_DATA_MUX_BUS 0x2 +#define GPMC_HAS_MUX_AAD 0x4 + +#define GPMC_NR_WAITPINS 4 /* XXX: Only NAND irq has been considered,currently these are the only ones used */ @@ -153,6 +155,7 @@ static struct resource gpmc_cs_mem[GPMC_CS_NUM]; static DEFINE_SPINLOCK(gpmc_mem_lock); /* Define chip-selects as reserved by default until probe completes */ static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1); +static unsigned int gpmc_nr_waitpins; static struct device *gpmc_dev; static int gpmc_irq; static resource_size_t phys_base, mem_size; @@ -181,7 +184,7 @@ void gpmc_cs_write_reg(int cs, int idx, u32 val) __raw_writel(val, reg_addr); } -u32 gpmc_cs_read_reg(int cs, int idx) +static u32 gpmc_cs_read_reg(int cs, int idx) { void __iomem *reg_addr; @@ -190,7 +193,7 @@ u32 gpmc_cs_read_reg(int cs, int idx) } /* TODO: Add support for gpmc_fck to clock framework and use it */ -unsigned long gpmc_get_fclk_period(void) +static unsigned long gpmc_get_fclk_period(void) { unsigned long rate = clk_get_rate(gpmc_l3_clk); @@ -205,7 +208,7 @@ unsigned long gpmc_get_fclk_period(void) return rate; } -unsigned int gpmc_ns_to_ticks(unsigned int time_ns) +static unsigned int gpmc_ns_to_ticks(unsigned int time_ns) { unsigned long tick_ps; @@ -215,7 +218,7 @@ unsigned int gpmc_ns_to_ticks(unsigned int time_ns) return (time_ns * 1000 + tick_ps - 1) / tick_ps; } -unsigned int gpmc_ps_to_ticks(unsigned int time_ps) +static unsigned int gpmc_ps_to_ticks(unsigned int time_ps) { unsigned long tick_ps; @@ -230,13 +233,6 @@ unsigned int gpmc_ticks_to_ns(unsigned int ticks) return ticks * gpmc_get_fclk_period() / 1000; } -unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns) -{ - unsigned long ticks = gpmc_ns_to_ticks(time_ns); - - return ticks * gpmc_get_fclk_period() / 1000; -} - static unsigned int gpmc_ticks_to_ps(unsigned int ticks) { return ticks * gpmc_get_fclk_period(); @@ -405,11 +401,18 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) return 0; } -static void gpmc_cs_enable_mem(int cs, u32 base, u32 size) +static int gpmc_cs_enable_mem(int cs, u32 base, u32 size) { u32 l; u32 mask; + /* + * Ensure that base address is aligned on a + * boundary equal to or greater than size. + */ + if (base & (size - 1)) + return -EINVAL; + mask = (1 << GPMC_SECTION_SHIFT) - size; l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); l &= ~0x3f; @@ -418,6 +421,8 @@ static void gpmc_cs_enable_mem(int cs, u32 base, u32 size) l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8; l |= GPMC_CONFIG7_CSVALID; gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); + + return 0; } static void gpmc_cs_disable_mem(int cs) @@ -448,22 +453,14 @@ static int gpmc_cs_mem_enabled(int cs) return l & GPMC_CONFIG7_CSVALID; } -int gpmc_cs_set_reserved(int cs, int reserved) +static void gpmc_cs_set_reserved(int cs, int reserved) { - if (cs > GPMC_CS_NUM) - return -ENODEV; - gpmc_cs_map &= ~(1 << cs); gpmc_cs_map |= (reserved ? 1 : 0) << cs; - - return 0; } -int gpmc_cs_reserved(int cs) +static bool gpmc_cs_reserved(int cs) { - if (cs > GPMC_CS_NUM) - return -ENODEV; - return gpmc_cs_map & (1 << cs); } @@ -510,6 +507,39 @@ static int gpmc_cs_delete_mem(int cs) return r; } +/** + * gpmc_cs_remap - remaps a chip-select physical base address + * @cs: chip-select to remap + * @base: physical base address to re-map chip-select to + * + * Re-maps a chip-select to a new physical base address specified by + * "base". Returns 0 on success and appropriate negative error code + * on failure. + */ +static int gpmc_cs_remap(int cs, u32 base) +{ + int ret; + u32 old_base, size; + + if (cs > GPMC_CS_NUM) + return -ENODEV; + gpmc_cs_get_memconf(cs, &old_base, &size); + if (base == old_base) + return 0; + gpmc_cs_disable_mem(cs); + ret = gpmc_cs_delete_mem(cs); + if (ret < 0) + return ret; + ret = gpmc_cs_insert_mem(cs, base, size); + if (ret < 0) + return ret; + ret = gpmc_cs_enable_mem(cs, base, size); + if (ret < 0) + return ret; + + return 0; +} + int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) { struct resource *res = &gpmc_cs_mem[cs]; @@ -535,7 +565,12 @@ int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) if (r < 0) goto out; - gpmc_cs_enable_mem(cs, res->start, resource_size(res)); + r = gpmc_cs_enable_mem(cs, res->start, resource_size(res)); + if (r < 0) { + release_resource(res); + goto out; + } + *base = res->start; gpmc_cs_set_reserved(cs, 1); out: @@ -561,16 +596,14 @@ void gpmc_cs_free(int cs) EXPORT_SYMBOL(gpmc_cs_free); /** - * gpmc_cs_configure - write request to configure gpmc - * @cs: chip select number + * gpmc_configure - write request to configure gpmc * @cmd: command type * @wval: value to write * @return status of the operation */ -int gpmc_cs_configure(int cs, int cmd, int wval) +int gpmc_configure(int cmd, int wval) { - int err = 0; - u32 regval = 0; + u32 regval; switch (cmd) { case GPMC_ENABLE_IRQ: @@ -590,43 +623,14 @@ int gpmc_cs_configure(int cs, int cmd, int wval) gpmc_write_reg(GPMC_CONFIG, regval); break; - case GPMC_CONFIG_RDY_BSY: - regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); - if (wval) - regval |= WR_RD_PIN_MONITORING; - else - regval &= ~WR_RD_PIN_MONITORING; - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); - break; - - case GPMC_CONFIG_DEV_SIZE: - regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); - - /* clear 2 target bits */ - regval &= ~GPMC_CONFIG1_DEVICESIZE(3); - - /* set the proper value */ - regval |= GPMC_CONFIG1_DEVICESIZE(wval); - - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); - break; - - case GPMC_CONFIG_DEV_TYPE: - regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); - regval |= GPMC_CONFIG1_DEVICETYPE(wval); - if (wval == GPMC_DEVICETYPE_NOR) - regval |= GPMC_CONFIG1_MUXADDDATA; - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); - break; - default: - printk(KERN_ERR "gpmc_configure_cs: Not supported\n"); - err = -EINVAL; + pr_err("%s: command not supported\n", __func__); + return -EINVAL; } - return err; + return 0; } -EXPORT_SYMBOL(gpmc_cs_configure); +EXPORT_SYMBOL(gpmc_configure); void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs) { @@ -716,7 +720,7 @@ static int gpmc_setup_irq(void) return -EINVAL; gpmc_irq_start = irq_alloc_descs(-1, 0, GPMC_NR_IRQ, 0); - if (IS_ERR_VALUE(gpmc_irq_start)) { + if (gpmc_irq_start < 0) { pr_err("irq_alloc_descs failed\n"); return gpmc_irq_start; } @@ -781,16 +785,16 @@ static void gpmc_mem_exit(void) } -static int gpmc_mem_init(void) +static void gpmc_mem_init(void) { - int cs, rc; - unsigned long boot_rom_space = 0; + int cs; - /* never allocate the first page, to facilitate bug detection; - * even if we didn't boot from ROM. + /* + * The first 1MB of GPMC address space is typically mapped to + * the internal ROM. Never allocate the first page, to + * facilitate bug detection; even if we didn't boot from ROM. */ - boot_rom_space = BOOT_ROM_SPACE; - gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space; + gpmc_mem_root.start = SZ_1M; gpmc_mem_root.end = GPMC_MEM_END; /* Reserve all regions that has been set up by bootloader */ @@ -800,16 +804,12 @@ static int gpmc_mem_init(void) if (!gpmc_cs_mem_enabled(cs)) continue; gpmc_cs_get_memconf(cs, &base, &size); - 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; + if (gpmc_cs_insert_mem(cs, base, size)) { + pr_warn("%s: disabling cs %d mapped at 0x%x-0x%x\n", + __func__, cs, base, base + size); + gpmc_cs_disable_mem(cs); } } - - return 0; } static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk) @@ -825,9 +825,9 @@ static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk) /* XXX: can the cycles be avoided ? */ static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t) + struct gpmc_device_timings *dev_t, + bool mux) { - bool mux = dev_t->mux; u32 temp; /* adv_rd_off */ @@ -880,9 +880,9 @@ static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t, } static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t) + struct gpmc_device_timings *dev_t, + bool mux) { - bool mux = dev_t->mux; u32 temp; /* adv_wr_off */ @@ -942,9 +942,9 @@ static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t, } static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t) + struct gpmc_device_timings *dev_t, + bool mux) { - bool mux = dev_t->mux; u32 temp; /* adv_rd_off */ @@ -982,9 +982,9 @@ static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t, } static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t) + struct gpmc_device_timings *dev_t, + bool mux) { - bool mux = dev_t->mux; u32 temp; /* adv_wr_off */ @@ -1054,7 +1054,8 @@ static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t, } static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t) + struct gpmc_device_timings *dev_t, + bool sync) { u32 temp; @@ -1068,7 +1069,7 @@ static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t, gpmc_t->cs_on + dev_t->t_ce_avd); gpmc_t->adv_on = gpmc_round_ps_to_ticks(temp); - if (dev_t->sync_write || dev_t->sync_read) + if (sync) gpmc_calc_sync_common_timings(gpmc_t, dev_t); return 0; @@ -1103,27 +1104,116 @@ static void gpmc_convert_ps_to_ns(struct gpmc_timings *t) } int gpmc_calc_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t) + struct gpmc_settings *gpmc_s, + struct gpmc_device_timings *dev_t) { + bool mux = false, sync = false; + + if (gpmc_s) { + mux = gpmc_s->mux_add_data ? true : false; + sync = (gpmc_s->sync_read || gpmc_s->sync_write); + } + memset(gpmc_t, 0, sizeof(*gpmc_t)); - gpmc_calc_common_timings(gpmc_t, dev_t); + gpmc_calc_common_timings(gpmc_t, dev_t, sync); - if (dev_t->sync_read) - gpmc_calc_sync_read_timings(gpmc_t, dev_t); + if (gpmc_s && gpmc_s->sync_read) + gpmc_calc_sync_read_timings(gpmc_t, dev_t, mux); else - gpmc_calc_async_read_timings(gpmc_t, dev_t); + gpmc_calc_async_read_timings(gpmc_t, dev_t, mux); - if (dev_t->sync_write) - gpmc_calc_sync_write_timings(gpmc_t, dev_t); + if (gpmc_s && gpmc_s->sync_write) + gpmc_calc_sync_write_timings(gpmc_t, dev_t, mux); else - gpmc_calc_async_write_timings(gpmc_t, dev_t); + gpmc_calc_async_write_timings(gpmc_t, dev_t, mux); /* TODO: remove, see function definition */ gpmc_convert_ps_to_ns(gpmc_t); - /* Now the GPMC is initialised, unreserve the chip-selects */ - gpmc_cs_map = 0; + return 0; +} + +/** + * gpmc_cs_program_settings - programs non-timing related settings + * @cs: GPMC chip-select to program + * @p: pointer to GPMC settings structure + * + * Programs non-timing related settings for a GPMC chip-select, such as + * bus-width, burst configuration, etc. Function should be called once + * for each chip-select that is being used and must be called before + * calling gpmc_cs_set_timings() as timing parameters in the CONFIG1 + * register will be initialised to zero by this function. Returns 0 on + * success and appropriate negative error code on failure. + */ +int gpmc_cs_program_settings(int cs, struct gpmc_settings *p) +{ + u32 config1; + + if ((!p->device_width) || (p->device_width > GPMC_DEVWIDTH_16BIT)) { + pr_err("%s: invalid width %d!", __func__, p->device_width); + return -EINVAL; + } + + /* Address-data multiplexing not supported for NAND devices */ + if (p->device_nand && p->mux_add_data) { + pr_err("%s: invalid configuration!\n", __func__); + return -EINVAL; + } + + if ((p->mux_add_data > GPMC_MUX_AD) || + ((p->mux_add_data == GPMC_MUX_AAD) && + !(gpmc_capability & GPMC_HAS_MUX_AAD))) { + pr_err("%s: invalid multiplex configuration!\n", __func__); + return -EINVAL; + } + + /* Page/burst mode supports lengths of 4, 8 and 16 bytes */ + if (p->burst_read || p->burst_write) { + switch (p->burst_len) { + case GPMC_BURST_4: + case GPMC_BURST_8: + case GPMC_BURST_16: + break; + default: + pr_err("%s: invalid page/burst-length (%d)\n", + __func__, p->burst_len); + return -EINVAL; + } + } + + if ((p->wait_on_read || p->wait_on_write) && + (p->wait_pin > gpmc_nr_waitpins)) { + pr_err("%s: invalid wait-pin (%d)\n", __func__, p->wait_pin); + return -EINVAL; + } + + config1 = GPMC_CONFIG1_DEVICESIZE((p->device_width - 1)); + + if (p->sync_read) + config1 |= GPMC_CONFIG1_READTYPE_SYNC; + if (p->sync_write) + config1 |= GPMC_CONFIG1_WRITETYPE_SYNC; + if (p->wait_on_read) + config1 |= GPMC_CONFIG1_WAIT_READ_MON; + if (p->wait_on_write) + config1 |= GPMC_CONFIG1_WAIT_WRITE_MON; + if (p->wait_on_read || p->wait_on_write) + config1 |= GPMC_CONFIG1_WAIT_PIN_SEL(p->wait_pin); + if (p->device_nand) + config1 |= GPMC_CONFIG1_DEVICETYPE(GPMC_DEVICETYPE_NAND); + if (p->mux_add_data) + config1 |= GPMC_CONFIG1_MUXTYPE(p->mux_add_data); + if (p->burst_read) + config1 |= GPMC_CONFIG1_READMULTIPLE_SUPP; + if (p->burst_write) + config1 |= GPMC_CONFIG1_WRITEMULTIPLE_SUPP; + if (p->burst_read || p->burst_write) { + config1 |= GPMC_CONFIG1_PAGE_LEN(p->burst_len >> 3); + config1 |= p->burst_wrap ? GPMC_CONFIG1_WRAPBURST_SUPP : 0; + } + + gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, config1); return 0; } @@ -1139,70 +1229,110 @@ static struct of_device_id gpmc_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, gpmc_dt_ids); +/** + * gpmc_read_settings_dt - read gpmc settings from device-tree + * @np: pointer to device-tree node for a gpmc child device + * @p: pointer to gpmc settings structure + * + * Reads the GPMC settings for a GPMC child device from device-tree and + * stores them in the GPMC settings structure passed. The GPMC settings + * structure is initialised to zero by this function and so any + * previously stored settings will be cleared. + */ +void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p) +{ + memset(p, 0, sizeof(struct gpmc_settings)); + + p->sync_read = of_property_read_bool(np, "gpmc,sync-read"); + p->sync_write = of_property_read_bool(np, "gpmc,sync-write"); + p->device_nand = of_property_read_bool(np, "gpmc,device-nand"); + of_property_read_u32(np, "gpmc,device-width", &p->device_width); + of_property_read_u32(np, "gpmc,mux-add-data", &p->mux_add_data); + + if (!of_property_read_u32(np, "gpmc,burst-length", &p->burst_len)) { + p->burst_wrap = of_property_read_bool(np, "gpmc,burst-wrap"); + p->burst_read = of_property_read_bool(np, "gpmc,burst-read"); + p->burst_write = of_property_read_bool(np, "gpmc,burst-write"); + if (!p->burst_read && !p->burst_write) + pr_warn("%s: page/burst-length set but not used!\n", + __func__); + } + + if (!of_property_read_u32(np, "gpmc,wait-pin", &p->wait_pin)) { + p->wait_on_read = of_property_read_bool(np, + "gpmc,wait-on-read"); + p->wait_on_write = of_property_read_bool(np, + "gpmc,wait-on-write"); + if (!p->wait_on_read && !p->wait_on_write) + pr_warn("%s: read/write wait monitoring not enabled!\n", + __func__); + } +} + static void __maybe_unused gpmc_read_timings_dt(struct device_node *np, struct gpmc_timings *gpmc_t) { - u32 val; + struct gpmc_bool_timings *p; + + if (!np || !gpmc_t) + return; memset(gpmc_t, 0, sizeof(*gpmc_t)); /* minimum clock period for syncronous mode */ - if (!of_property_read_u32(np, "gpmc,sync-clk", &val)) - gpmc_t->sync_clk = val; + of_property_read_u32(np, "gpmc,sync-clk-ps", &gpmc_t->sync_clk); /* chip select timtings */ - if (!of_property_read_u32(np, "gpmc,cs-on", &val)) - gpmc_t->cs_on = val; - - if (!of_property_read_u32(np, "gpmc,cs-rd-off", &val)) - gpmc_t->cs_rd_off = val; - - if (!of_property_read_u32(np, "gpmc,cs-wr-off", &val)) - gpmc_t->cs_wr_off = val; + of_property_read_u32(np, "gpmc,cs-on-ns", &gpmc_t->cs_on); + of_property_read_u32(np, "gpmc,cs-rd-off-ns", &gpmc_t->cs_rd_off); + of_property_read_u32(np, "gpmc,cs-wr-off-ns", &gpmc_t->cs_wr_off); /* ADV signal timings */ - if (!of_property_read_u32(np, "gpmc,adv-on", &val)) - gpmc_t->adv_on = val; - - if (!of_property_read_u32(np, "gpmc,adv-rd-off", &val)) - gpmc_t->adv_rd_off = val; - - if (!of_property_read_u32(np, "gpmc,adv-wr-off", &val)) - gpmc_t->adv_wr_off = val; + of_property_read_u32(np, "gpmc,adv-on-ns", &gpmc_t->adv_on); + of_property_read_u32(np, "gpmc,adv-rd-off-ns", &gpmc_t->adv_rd_off); + of_property_read_u32(np, "gpmc,adv-wr-off-ns", &gpmc_t->adv_wr_off); /* WE signal timings */ - if (!of_property_read_u32(np, "gpmc,we-on", &val)) - gpmc_t->we_on = val; - - if (!of_property_read_u32(np, "gpmc,we-off", &val)) - gpmc_t->we_off = val; + of_property_read_u32(np, "gpmc,we-on-ns", &gpmc_t->we_on); + of_property_read_u32(np, "gpmc,we-off-ns", &gpmc_t->we_off); /* OE signal timings */ - if (!of_property_read_u32(np, "gpmc,oe-on", &val)) - gpmc_t->oe_on = val; - - if (!of_property_read_u32(np, "gpmc,oe-off", &val)) - gpmc_t->oe_off = val; + of_property_read_u32(np, "gpmc,oe-on-ns", &gpmc_t->oe_on); + of_property_read_u32(np, "gpmc,oe-off-ns", &gpmc_t->oe_off); /* access and cycle timings */ - if (!of_property_read_u32(np, "gpmc,page-burst-access", &val)) - gpmc_t->page_burst_access = val; - - if (!of_property_read_u32(np, "gpmc,access", &val)) - gpmc_t->access = val; - - if (!of_property_read_u32(np, "gpmc,rd-cycle", &val)) - gpmc_t->rd_cycle = val; - - if (!of_property_read_u32(np, "gpmc,wr-cycle", &val)) - gpmc_t->wr_cycle = val; - - /* only for OMAP3430 */ - if (!of_property_read_u32(np, "gpmc,wr-access", &val)) - gpmc_t->wr_access = val; - - if (!of_property_read_u32(np, "gpmc,wr-data-mux-bus", &val)) - gpmc_t->wr_data_mux_bus = val; + of_property_read_u32(np, "gpmc,page-burst-access-ns", + &gpmc_t->page_burst_access); + of_property_read_u32(np, "gpmc,access-ns", &gpmc_t->access); + of_property_read_u32(np, "gpmc,rd-cycle-ns", &gpmc_t->rd_cycle); + of_property_read_u32(np, "gpmc,wr-cycle-ns", &gpmc_t->wr_cycle); + of_property_read_u32(np, "gpmc,bus-turnaround-ns", + &gpmc_t->bus_turnaround); + of_property_read_u32(np, "gpmc,cycle2cycle-delay-ns", + &gpmc_t->cycle2cycle_delay); + of_property_read_u32(np, "gpmc,wait-monitoring-ns", + &gpmc_t->wait_monitoring); + of_property_read_u32(np, "gpmc,clk-activation-ns", + &gpmc_t->clk_activation); + + /* only applicable to OMAP3+ */ + of_property_read_u32(np, "gpmc,wr-access-ns", &gpmc_t->wr_access); + of_property_read_u32(np, "gpmc,wr-data-mux-bus-ns", + &gpmc_t->wr_data_mux_bus); + + /* bool timing parameters */ + p = &gpmc_t->bool_timings; + + p->cycle2cyclediffcsen = + of_property_read_bool(np, "gpmc,cycle2cycle-diffcsen"); + p->cycle2cyclesamecsen = + of_property_read_bool(np, "gpmc,cycle2cycle-samecsen"); + p->we_extra_delay = of_property_read_bool(np, "gpmc,we-extra-delay"); + p->oe_extra_delay = of_property_read_bool(np, "gpmc,oe-extra-delay"); + p->adv_extra_delay = of_property_read_bool(np, "gpmc,adv-extra-delay"); + p->cs_extra_delay = of_property_read_bool(np, "gpmc,cs-extra-delay"); + p->time_para_granularity = + of_property_read_bool(np, "gpmc,time-para-granularity"); } #ifdef CONFIG_MTD_NAND @@ -1298,6 +1428,81 @@ static int gpmc_probe_onenand_child(struct platform_device *pdev, } #endif +/** + * gpmc_probe_generic_child - configures the gpmc for a child device + * @pdev: pointer to gpmc platform device + * @child: pointer to device-tree node for child device + * + * Allocates and configures a GPMC chip-select for a child device. + * Returns 0 on success and appropriate negative error code on failure. + */ +static int gpmc_probe_generic_child(struct platform_device *pdev, + struct device_node *child) +{ + struct gpmc_settings gpmc_s; + struct gpmc_timings gpmc_t; + struct resource res; + unsigned long base; + int ret, cs; + + if (of_property_read_u32(child, "reg", &cs) < 0) { + dev_err(&pdev->dev, "%s has no 'reg' property\n", + child->full_name); + return -ENODEV; + } + + if (of_address_to_resource(child, 0, &res) < 0) { + dev_err(&pdev->dev, "%s has malformed 'reg' property\n", + child->full_name); + return -ENODEV; + } + + ret = gpmc_cs_request(cs, resource_size(&res), &base); + if (ret < 0) { + dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs); + return ret; + } + + /* + * FIXME: gpmc_cs_request() will map the CS to an arbitary + * location in the gpmc address space. When booting with + * device-tree we want the NOR flash to be mapped to the + * location specified in the device-tree blob. So remap the + * CS to this location. Once DT migration is complete should + * just make gpmc_cs_request() map a specific address. + */ + ret = gpmc_cs_remap(cs, res.start); + if (ret < 0) { + dev_err(&pdev->dev, "cannot remap GPMC CS %d to 0x%x\n", + cs, res.start); + goto err; + } + + gpmc_read_settings_dt(child, &gpmc_s); + + ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width); + if (ret < 0) + goto err; + + ret = gpmc_cs_program_settings(cs, &gpmc_s); + if (ret < 0) + goto err; + + gpmc_read_timings_dt(child, &gpmc_t); + gpmc_cs_set_timings(cs, &gpmc_t); + + if (of_platform_device_create(child, NULL, &pdev->dev)) + return 0; + + dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name); + ret = -ENODEV; + +err: + gpmc_cs_free(cs); + + return ret; +} + static int gpmc_probe_dt(struct platform_device *pdev) { int ret; @@ -1308,6 +1513,13 @@ static int gpmc_probe_dt(struct platform_device *pdev) if (!of_id) return 0; + ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-waitpins", + &gpmc_nr_waitpins); + if (ret < 0) { + pr_err("%s: number of wait pins not found!\n", __func__); + return ret; + } + for_each_node_by_name(child, "nand") { ret = gpmc_probe_nand_child(pdev, child); if (ret < 0) { @@ -1323,6 +1535,23 @@ static int gpmc_probe_dt(struct platform_device *pdev) return ret; } } + + for_each_node_by_name(child, "nor") { + ret = gpmc_probe_generic_child(pdev, child); + if (ret < 0) { + of_node_put(child); + return ret; + } + } + + for_each_node_by_name(child, "ethernet") { + ret = gpmc_probe_generic_child(pdev, child); + if (ret < 0) { + of_node_put(child); + return ret; + } + } + return 0; } #else @@ -1367,22 +1596,37 @@ static int gpmc_probe(struct platform_device *pdev) gpmc_dev = &pdev->dev; l = gpmc_read_reg(GPMC_REVISION); + + /* + * FIXME: Once device-tree migration is complete the below flags + * should be populated based upon the device-tree compatible + * string. For now just use the IP revision. OMAP3+ devices have + * the wr_access and wr_data_mux_bus register fields. OMAP4+ + * devices support the addr-addr-data multiplex protocol. + * + * GPMC IP revisions: + * - OMAP24xx = 2.0 + * - OMAP3xxx = 5.0 + * - OMAP44xx/54xx/AM335x = 6.0 + */ if (GPMC_REVISION_MAJOR(l) > 0x4) gpmc_capability = GPMC_HAS_WR_ACCESS | GPMC_HAS_WR_DATA_MUX_BUS; + if (GPMC_REVISION_MAJOR(l) > 0x5) + gpmc_capability |= GPMC_HAS_MUX_AAD; dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l), GPMC_REVISION_MINOR(l)); - 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; - } + gpmc_mem_init(); - if (IS_ERR_VALUE(gpmc_setup_irq())) + if (gpmc_setup_irq() < 0) dev_warn(gpmc_dev, "gpmc_setup_irq failed\n"); + /* Now the GPMC is initialised, unreserve the chip-selects */ + gpmc_cs_map = 0; + + if (!pdev->dev.of_node) + gpmc_nr_waitpins = GPMC_NR_WAITPINS; + rc = gpmc_probe_dt(pdev); if (rc < 0) { clk_disable_unprepare(gpmc_l3_clk); diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h index fe0a844d5007..707f6d58edd5 100644 --- a/arch/arm/mach-omap2/gpmc.h +++ b/arch/arm/mach-omap2/gpmc.h @@ -58,7 +58,7 @@ #define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1) #define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10) #define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0) -#define GPMC_CONFIG1_MUXADDDATA (1 << 9) +#define GPMC_CONFIG1_MUXTYPE(val) ((val & 3) << 8) #define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4) #define GPMC_CONFIG1_FCLK_DIV(val) (val & 3) #define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1)) @@ -73,6 +73,13 @@ #define GPMC_IRQ_FIFOEVENTENABLE 0x01 #define GPMC_IRQ_COUNT_EVENT 0x02 +#define GPMC_BURST_4 4 /* 4 word burst */ +#define GPMC_BURST_8 8 /* 8 word burst */ +#define GPMC_BURST_16 16 /* 16 word burst */ +#define GPMC_DEVWIDTH_8BIT 1 /* 8-bit device width */ +#define GPMC_DEVWIDTH_16BIT 2 /* 16-bit device width */ +#define GPMC_MUX_AAD 1 /* Addr-Addr-Data multiplex */ +#define GPMC_MUX_AD 2 /* Addr-Data multiplex */ /* bool type time settings */ struct gpmc_bool_timings { @@ -178,10 +185,6 @@ struct gpmc_device_timings { u8 cyc_wpl; /* write deassertion time in cycles */ u32 cyc_iaa; /* initial access time in cycles */ - bool mux; /* address & data muxed */ - bool sync_write;/* synchronous write */ - bool sync_read; /* synchronous read */ - /* extra delays */ bool ce_xdelay; bool avd_xdelay; @@ -189,28 +192,40 @@ struct gpmc_device_timings { bool we_xdelay; }; +struct gpmc_settings { + bool burst_wrap; /* enables wrap bursting */ + bool burst_read; /* enables read page/burst mode */ + bool burst_write; /* enables write page/burst mode */ + bool device_nand; /* device is NAND */ + bool sync_read; /* enables synchronous reads */ + bool sync_write; /* enables synchronous writes */ + bool wait_on_read; /* monitor wait on reads */ + bool wait_on_write; /* monitor wait on writes */ + u32 burst_len; /* page/burst length */ + u32 device_width; /* device bus width (8 or 16 bit) */ + u32 mux_add_data; /* multiplex address & data */ + u32 wait_pin; /* wait-pin to be used */ +}; + extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t); + struct gpmc_settings *gpmc_s, + struct gpmc_device_timings *dev_t); extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs); extern int gpmc_get_client_irq(unsigned irq_config); -extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns); -extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps); extern unsigned int gpmc_ticks_to_ns(unsigned int ticks); -extern unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns); -extern unsigned long gpmc_get_fclk_period(void); extern void gpmc_cs_write_reg(int cs, int idx, u32 val); -extern u32 gpmc_cs_read_reg(int cs, int idx); extern int gpmc_calc_divider(unsigned int sync_clk); extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t); +extern int gpmc_cs_program_settings(int cs, struct gpmc_settings *p); extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base); extern void gpmc_cs_free(int cs); -extern int gpmc_cs_set_reserved(int cs, int reserved); -extern int gpmc_cs_reserved(int cs); extern void omap3_gpmc_save_context(void); extern void omap3_gpmc_restore_context(void); -extern int gpmc_cs_configure(int cs, int cmd, int wval); +extern int gpmc_configure(int cmd, int wval); +extern void gpmc_read_settings_dt(struct device_node *np, + struct gpmc_settings *p); #endif diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 8a68f1ec66b9..ff0bc9e51aa7 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -529,22 +529,28 @@ void __init omap5xxx_check_revision(void) case 0xb942: switch (rev) { case 0: - default: omap_revision = OMAP5430_REV_ES1_0; + break; + case 1: + default: + omap_revision = OMAP5430_REV_ES2_0; } break; case 0xb998: switch (rev) { case 0: - default: omap_revision = OMAP5432_REV_ES1_0; + break; + case 1: + default: + omap_revision = OMAP5432_REV_ES2_0; } break; default: /* Unknown default to latest silicon rev as default*/ - omap_revision = OMAP5430_REV_ES1_0; + omap_revision = OMAP5430_REV_ES2_0; } pr_info("OMAP%04x ES%d.0\n", diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 2c3fdd65387b..2bef5a7e6af8 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -271,6 +271,14 @@ static struct map_desc omap54xx_io_desc[] __initdata = { .length = L4_PER_54XX_SIZE, .type = MT_DEVICE, }, +#ifdef CONFIG_OMAP4_ERRATA_I688 + { + .virtual = OMAP4_SRAM_VA, + .pfn = __phys_to_pfn(OMAP4_SRAM_PA), + .length = PAGE_SIZE, + .type = MT_MEMORY_SO, + }, +#endif }; #endif @@ -323,6 +331,7 @@ void __init omap4_map_io(void) void __init omap5_map_io(void) { iotable_init(omap54xx_io_desc, ARRAY_SIZE(omap54xx_io_desc)); + omap_barriers_init(); } #endif /* diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 6a217c98db54..f82cf878d6af 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -211,8 +211,6 @@ static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition, return -EINVAL; } - pr_err("%s: Could not find signal %s\n", __func__, muxname); - return -ENODEV; } @@ -234,6 +232,8 @@ int __init omap_mux_get_by_name(const char *muxname, return mux_mode; } + pr_err("%s: Could not find signal %s\n", __func__, muxname); + return -ENODEV; } @@ -739,8 +739,9 @@ static void __init omap_mux_dbg_create_entry( list_for_each_entry(e, &partition->muxmodes, node) { struct omap_mux *m = &e->mux; - (void)debugfs_create_file(m->muxnames[0], S_IWUSR, mux_dbg_dir, - m, &omap_mux_dbg_signal_fops); + (void)debugfs_create_file(m->muxnames[0], S_IWUSR | S_IRUGO, + mux_dbg_dir, m, + &omap_mux_dbg_signal_fops); } } diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 708bb115a27f..2aeb928efdfd 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -240,15 +240,21 @@ void __iomem *omap4_get_sar_ram_base(void) */ static int __init omap4_sar_ram_init(void) { + unsigned long sar_base; + /* * To avoid code running on other OMAPs in * multi-omap builds */ - if (!cpu_is_omap44xx()) + if (cpu_is_omap44xx()) + sar_base = OMAP44XX_SAR_RAM_BASE; + else if (soc_is_omap54xx()) + sar_base = OMAP54XX_SAR_RAM_BASE; + else return -ENOMEM; /* Static mapping, never released */ - sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K); + sar_ram_base = ioremap(sar_base, SZ_16K); if (WARN_ON(!sar_ram_base)) return -ENOMEM; diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h index e170fe803b04..937417523b8e 100644 --- a/arch/arm/mach-omap2/omap4-sar-layout.h +++ b/arch/arm/mach-omap2/omap4-sar-layout.h @@ -48,13 +48,13 @@ #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_WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x9dc) +#define OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x9f0) +#define OMAP5_WAKEUPGENENB_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0xa04) +#define OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0xa18) +#define OMAP5_AUXCOREBOOT0_OFFSET (SAR_BANK3_OFFSET + 0xa2c) +#define OMAP5_AUXCOREBOOT1_OFFSET (SAR_BANK3_OFFSET + 0x930) +#define OMAP5_AMBA_IF_MODE_OFFSET (SAR_BANK3_OFFSET + 0xa34) #define OMAP5_SAR_BACKUP_STATUS_OFFSET (SAR_BANK3_OFFSET + 0x800) #endif diff --git a/arch/arm/mach-omap2/omap54xx.h b/arch/arm/mach-omap2/omap54xx.h index a2582bb3cab3..a086ba15868b 100644 --- a/arch/arm/mach-omap2/omap54xx.h +++ b/arch/arm/mach-omap2/omap54xx.h @@ -28,5 +28,6 @@ #define OMAP54XX_PRCM_MPU_BASE 0x48243000 #define OMAP54XX_SCM_BASE 0x4a002000 #define OMAP54XX_CTRL_BASE 0x4a002800 +#define OMAP54XX_SAR_RAM_BASE 0x4ae26000 #endif /* __ASM_SOC_OMAP555554XX_H */ diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index 381be7ac0c17..eeea4fa28fbc 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -131,7 +131,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev) int oh_cnt, i, ret = 0; oh_cnt = of_property_count_strings(node, "ti,hwmods"); - if (!oh_cnt || IS_ERR_VALUE(oh_cnt)) { + if (oh_cnt <= 0) { dev_dbg(&pdev->dev, "No 'hwmods' to build omap_device\n"); return -ENODEV; } @@ -815,20 +815,17 @@ struct device *omap_device_get_by_hwmod_name(const char *oh_name) } oh = omap_hwmod_lookup(oh_name); - if (IS_ERR_OR_NULL(oh)) { + if (!oh) { WARN(1, "%s: no hwmod for %s\n", __func__, oh_name); - return ERR_PTR(oh ? PTR_ERR(oh) : -ENODEV); + return ERR_PTR(-ENODEV); } - if (IS_ERR_OR_NULL(oh->od)) { + if (!oh->od) { WARN(1, "%s: no omap_device for %s\n", __func__, oh_name); - return ERR_PTR(oh->od ? PTR_ERR(oh->od) : -ENODEV); + return ERR_PTR(-ENODEV); } - if (IS_ERR_OR_NULL(oh->od->pdev)) - return ERR_PTR(oh->od->pdev ? PTR_ERR(oh->od->pdev) : -ENODEV); - return &oh->od->pdev->dev; } diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index c2c798c08c2b..2520d46c8508 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -610,8 +610,6 @@ static int _enable_wakeup(struct omap_hwmod *oh, u32 *v) /* XXX test pwrdm_get_wken for this hwmod's subsystem */ - oh->_int_flags |= _HWMOD_WAKEUP_ENABLED; - return 0; } @@ -645,8 +643,6 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v) /* XXX test pwrdm_get_wken for this hwmod's subsystem */ - oh->_int_flags &= ~_HWMOD_WAKEUP_ENABLED; - return 0; } @@ -1663,7 +1659,7 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name) return -ENOSYS; ret = _lookup_hardreset(oh, name, &ohri); - if (IS_ERR_VALUE(ret)) + if (ret < 0) return ret; if (oh->clkdm) { @@ -2413,7 +2409,7 @@ static int __init _init(struct omap_hwmod *oh, void *data) _init_mpu_rt_base(oh, NULL); r = _init_clocks(oh, NULL); - if (IS_ERR_VALUE(r)) { + if (r < 0) { WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name); return -EINVAL; } diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index d43d9b608eda..28f4dea0512e 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -477,15 +477,13 @@ struct omap_hwmod_omap4_prcm { * These are for internal use only and are managed by the omap_hwmod code. * * _HWMOD_NO_MPU_PORT: no path exists for the MPU to write to this module - * _HWMOD_WAKEUP_ENABLED: set when the omap_hwmod code has enabled ENAWAKEUP * _HWMOD_SYSCONFIG_LOADED: set when the OCP_SYSCONFIG value has been cached * _HWMOD_SKIP_ENABLE: set if hwmod enabled during init (HWMOD_INIT_NO_IDLE) - * causes the first call to _enable() to only update the pinmux */ #define _HWMOD_NO_MPU_PORT (1 << 0) -#define _HWMOD_WAKEUP_ENABLED (1 << 1) -#define _HWMOD_SYSCONFIG_LOADED (1 << 2) -#define _HWMOD_SKIP_ENABLE (1 << 3) +#define _HWMOD_SYSCONFIG_LOADED (1 << 1) +#define _HWMOD_SKIP_ENABLE (1 << 2) /* * omap_hwmod._state definitions diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 26eee4a556ad..31bea1ce3de1 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -28,6 +28,7 @@ #include "prm-regbits-33xx.h" #include "i2c.h" #include "mmc.h" +#include "wd_timer.h" /* * IP blocks @@ -2087,8 +2088,21 @@ static struct omap_hwmod am33xx_uart6_hwmod = { }; /* 'wd_timer' class */ +static struct omap_hwmod_class_sysconfig wdt_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x10, + .syss_offs = 0x14, + .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + static struct omap_hwmod_class am33xx_wd_timer_hwmod_class = { .name = "wd_timer", + .sysc = &wdt_sysc, + .pre_shutdown = &omap2_wd_timer_disable, }; /* @@ -2099,6 +2113,7 @@ static struct omap_hwmod am33xx_wd_timer1_hwmod = { .name = "wd_timer2", .class = &am33xx_wd_timer_hwmod_class, .clkdm_name = "l4_wkup_clkdm", + .flags = HWMOD_SWSUP_SIDLE, .main_clk = "wdt1_fck", .prcm = { .omap4 = { diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 1edd000a8143..0b339861d751 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -217,7 +217,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *dir) return 0; d = debugfs_create_dir(pwrdm->name, (struct dentry *)dir); - if (!(IS_ERR_OR_NULL(d))) + if (d) (void) debugfs_create_file("suspend", S_IRUGO|S_IWUSR, d, (void *)pwrdm, &pwrdm_suspend_fops); @@ -261,8 +261,8 @@ static int __init pm_dbg_init(void) return 0; d = debugfs_create_dir("pm_debug", NULL); - if (IS_ERR_OR_NULL(d)) - return PTR_ERR(d); + if (!d) + return -EINVAL; (void) debugfs_create_file("count", S_IRUGO, d, (void *)DEBUG_FILE_COUNTERS, &debug_fops); diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 8e61d80bf6b3..86babd740d41 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -52,7 +52,6 @@ enum { #define ALREADYACTIVE_SWITCH 0 #define FORCEWAKEUP_SWITCH 1 #define LOWPOWERSTATE_SWITCH 2 -#define ERROR_SWITCH 3 /* pwrdm_list contains all registered struct powerdomains */ static LIST_HEAD(pwrdm_list); @@ -233,10 +232,7 @@ static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm, { u8 sleep_switch; - if (curr_pwrst < 0) { - WARN_ON(1); - sleep_switch = ERROR_SWITCH; - } else if (curr_pwrst < PWRDM_POWER_ON) { + if (curr_pwrst < PWRDM_POWER_ON) { if (curr_pwrst > pwrst && pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE && arch_pwrdm->pwrdm_set_lowpwrstchange) { @@ -1091,7 +1087,8 @@ int pwrdm_post_transition(struct powerdomain *pwrdm) */ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst) { - u8 curr_pwrst, next_pwrst, sleep_switch; + u8 next_pwrst, sleep_switch; + int curr_pwrst; int ret = 0; bool hwsup = false; @@ -1107,16 +1104,17 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst) pwrdm_lock(pwrdm); curr_pwrst = pwrdm_read_pwrst(pwrdm); + if (curr_pwrst < 0) { + ret = -EINVAL; + goto osps_out; + } + next_pwrst = pwrdm_read_next_pwrst(pwrdm); if (curr_pwrst == pwrst && next_pwrst == pwrst) goto osps_out; sleep_switch = _pwrdm_save_clkdm_state_and_activate(pwrdm, curr_pwrst, pwrst, &hwsup); - if (sleep_switch == ERROR_SWITCH) { - ret = -EINVAL; - goto osps_out; - } ret = pwrdm_set_next_pwrst(pwrdm, pwrst); if (ret) @@ -1182,7 +1180,7 @@ bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm) { int i; - if (IS_ERR_OR_NULL(pwrdm)) { + if (!pwrdm) { pr_debug("powerdomain: %s: invalid powerdomain pointer\n", __func__); return 1; diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index d35f98aabf7a..415c7e0c9393 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -81,13 +81,13 @@ static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = { /* Read a register in a CM/PRM instance in the PRM module */ u32 omap4_prm_read_inst_reg(s16 inst, u16 reg) { - return __raw_readl(OMAP44XX_PRM_REGADDR(inst, reg)); + return __raw_readl(prm_base + inst + reg); } /* Write into a register in a CM/PRM instance in the PRM module */ void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg) { - __raw_writel(val, OMAP44XX_PRM_REGADDR(inst, reg)); + __raw_writel(val, prm_base + inst + reg); } /* Read-modify-write a register in a PRM module. Caller must lock */ @@ -650,7 +650,7 @@ static struct prm_ll_data omap44xx_prm_ll_data = { int __init omap44xx_prm_init(void) { - if (!cpu_is_omap44xx()) + if (!cpu_is_omap44xx() && !soc_is_omap54xx()) return 0; return prm_register(&omap44xx_prm_ll_data); diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h index c62116bbc760..18fdeeb3a44a 100644 --- a/arch/arm/mach-omap2/soc.h +++ b/arch/arm/mach-omap2/soc.h @@ -413,7 +413,9 @@ IS_OMAP_TYPE(3430, 0x3430) #define OMAP54XX_CLASS 0x54000054 #define OMAP5430_REV_ES1_0 (OMAP54XX_CLASS | (0x30 << 16) | (0x10 << 8)) +#define OMAP5430_REV_ES2_0 (OMAP54XX_CLASS | (0x30 << 16) | (0x20 << 8)) #define OMAP5432_REV_ES1_0 (OMAP54XX_CLASS | (0x32 << 16) | (0x10 << 8)) +#define OMAP5432_REV_ES2_0 (OMAP54XX_CLASS | (0x32 << 16) | (0x20 << 8)) void omap2xxx_check_revision(void); void omap3xxx_check_revision(void); diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 2bdd4cf17a8f..f12aa6c15da4 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -57,15 +57,6 @@ #include "common.h" #include "powerdomain.h" -/* Parent clocks, eventually these will come from the clock framework */ - -#define OMAP2_MPU_SOURCE "sys_ck" -#define OMAP3_MPU_SOURCE OMAP2_MPU_SOURCE -#define OMAP4_MPU_SOURCE "sys_clkin_ck" -#define OMAP2_32K_SOURCE "func_32k_ck" -#define OMAP3_32K_SOURCE "omap_32k_fck" -#define OMAP4_32K_SOURCE "sys_32k_ck" - #define REALTIME_COUNTER_BASE 0x48243200 #define INCREMENTER_NUMERATOR_OFFSET 0x10 #define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14 @@ -129,7 +120,6 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode, } static struct clock_event_device clockevent_gpt = { - .name = "gp_timer", .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, .rating = 300, .set_next_event = omap2_gp_timer_set_next_event, @@ -170,6 +160,12 @@ static struct device_node * __init omap_get_timer_dt(struct of_device_id *match, if (property && !of_get_property(np, property, NULL)) continue; + if (!property && (of_get_property(np, "ti,timer-alwon", NULL) || + of_get_property(np, "ti,timer-dsp", NULL) || + of_get_property(np, "ti,timer-pwm", NULL) || + of_get_property(np, "ti,timer-secure", NULL))) + continue; + of_add_property(np, &device_disabled); return np; } @@ -214,16 +210,17 @@ static u32 __init omap_dm_timer_get_errata(void) } static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, - int gptimer_id, - const char *fck_source, - const char *property, - int posted) + const char *fck_source, + const char *property, + const char **timer_name, + int posted) { char name[10]; /* 10 = sizeof("gptXX_Xck0") */ const char *oh_name; struct device_node *np; struct omap_hwmod *oh; struct resource irq, mem; + struct clk *src; int r = 0; if (of_have_populated_dt()) { @@ -243,10 +240,10 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, of_node_put(np); } else { - if (omap_dm_timer_reserve_systimer(gptimer_id)) + if (omap_dm_timer_reserve_systimer(timer->id)) return -ENODEV; - sprintf(name, "timer%d", gptimer_id); + sprintf(name, "timer%d", timer->id); oh_name = name; } @@ -254,6 +251,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, if (!oh) return -ENODEV; + *timer_name = oh->name; + if (!of_have_populated_dt()) { r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL, &irq); @@ -276,24 +275,24 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, /* After the dmtimer is using hwmod these clocks won't be needed */ timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); if (IS_ERR(timer->fclk)) - return -ENODEV; + return PTR_ERR(timer->fclk); - /* FIXME: Need to remove hard-coded test on timer ID */ - if (gptimer_id != 12) { - struct clk *src; - - src = clk_get(NULL, fck_source); - if (IS_ERR(src)) { - r = -EINVAL; - } else { - r = clk_set_parent(timer->fclk, src); - if (IS_ERR_VALUE(r)) - pr_warn("%s: %s cannot set source\n", - __func__, oh->name); + src = clk_get(NULL, fck_source); + if (IS_ERR(src)) + return PTR_ERR(src); + + if (clk_get_parent(timer->fclk) != src) { + r = clk_set_parent(timer->fclk, src); + if (r < 0) { + pr_warn("%s: %s cannot set source\n", __func__, + oh->name); clk_put(src); + return r; } } + clk_put(src); + omap_hwmod_setup_one(oh_name); omap_hwmod_enable(oh); __omap_dm_timer_init_regs(timer); @@ -317,6 +316,7 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, { int res; + clkev.id = gptimer_id; clkev.errata = omap_dm_timer_get_errata(); /* @@ -326,8 +326,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, */ __omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767); - res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property, - OMAP_TIMER_POSTED); + res = omap_dm_timer_init_one(&clkev, fck_source, property, + &clockevent_gpt.name, OMAP_TIMER_POSTED); BUG_ON(res); omap2_gp_timer_irq.dev_id = &clkev; @@ -341,8 +341,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, 3, /* Timer internal resynch latency */ 0xffffffff); - pr_info("OMAP clockevent source: GPTIMER%d at %lu Hz\n", - gptimer_id, clkev.rate); + pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name, + clkev.rate); } /* Clocksource code */ @@ -359,7 +359,6 @@ static cycle_t clocksource_read_cycles(struct clocksource *cs) } static struct clocksource clocksource_gpt = { - .name = "gp_timer", .rating = 300, .read = clocksource_read_cycles, .mask = CLOCKSOURCE_MASK(32), @@ -442,13 +441,16 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void) } static void __init omap2_gptimer_clocksource_init(int gptimer_id, - const char *fck_source) + const char *fck_source, + const char *property) { int res; + clksrc.id = gptimer_id; clksrc.errata = omap_dm_timer_get_errata(); - res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL, + res = omap_dm_timer_init_one(&clksrc, fck_source, property, + &clocksource_gpt.name, OMAP_TIMER_NONPOSTED); BUG_ON(res); @@ -461,8 +463,8 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id, pr_err("Could not register clocksource %s\n", clocksource_gpt.name); else - pr_info("OMAP clocksource: GPTIMER%d at %lu Hz\n", - gptimer_id, clksrc.rate); + pr_info("OMAP clocksource: %s at %lu Hz\n", + clocksource_gpt.name, clksrc.rate); } #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER @@ -487,7 +489,7 @@ static void __init realtime_counter_init(void) pr_err("%s: ioremap failed\n", __func__); return; } - sys_clk = clk_get(NULL, "sys_clkin_ck"); + sys_clk = clk_get(NULL, "sys_clkin"); if (IS_ERR(sys_clk)) { pr_err("%s: failed to get system clock handle\n", __func__); iounmap(base); @@ -544,49 +546,52 @@ static inline void __init realtime_counter_init(void) #endif #define OMAP_SYS_GP_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ - clksrc_nr, clksrc_src) \ + clksrc_nr, clksrc_src, clksrc_prop) \ void __init omap##name##_gptimer_timer_init(void) \ { \ omap_dmtimer_init(); \ omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ - omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src); \ + omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src, \ + clksrc_prop); \ } #define OMAP_SYS_32K_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ - clksrc_nr, clksrc_src) \ + clksrc_nr, clksrc_src, clksrc_prop) \ void __init omap##name##_sync32k_timer_init(void) \ { \ omap_dmtimer_init(); \ omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ /* Enable the use of clocksource="gp_timer" kernel parameter */ \ if (use_gptimer_clksrc) \ - omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src);\ + omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src, \ + clksrc_prop); \ else \ omap2_sync32k_clocksource_init(); \ } #ifdef CONFIG_ARCH_OMAP2 -OMAP_SYS_32K_TIMER_INIT(2, 1, OMAP2_32K_SOURCE, "ti,timer-alwon", - 2, OMAP2_MPU_SOURCE); +OMAP_SYS_32K_TIMER_INIT(2, 1, "timer_32k_ck", "ti,timer-alwon", + 2, "timer_sys_ck", NULL); #endif /* CONFIG_ARCH_OMAP2 */ #ifdef CONFIG_ARCH_OMAP3 -OMAP_SYS_32K_TIMER_INIT(3, 1, OMAP3_32K_SOURCE, "ti,timer-alwon", - 2, OMAP3_MPU_SOURCE); -OMAP_SYS_32K_TIMER_INIT(3_secure, 12, OMAP3_32K_SOURCE, "ti,timer-secure", - 2, OMAP3_MPU_SOURCE); -OMAP_SYS_GP_TIMER_INIT(3_gp, 1, OMAP3_MPU_SOURCE, "ti,timer-alwon", - 2, OMAP3_MPU_SOURCE); +OMAP_SYS_32K_TIMER_INIT(3, 1, "timer_32k_ck", "ti,timer-alwon", + 2, "timer_sys_ck", NULL); +OMAP_SYS_32K_TIMER_INIT(3_secure, 12, "secure_32k_fck", "ti,timer-secure", + 2, "timer_sys_ck", NULL); #endif /* CONFIG_ARCH_OMAP3 */ -#ifdef CONFIG_SOC_AM33XX -OMAP_SYS_GP_TIMER_INIT(3_am33xx, 1, OMAP4_MPU_SOURCE, "ti,timer-alwon", - 2, OMAP4_MPU_SOURCE); -#endif /* CONFIG_SOC_AM33XX */ +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) +OMAP_SYS_GP_TIMER_INIT(3, 2, "timer_sys_ck", NULL, + 1, "timer_sys_ck", "ti,timer-alwon"); +#endif + +#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) +static OMAP_SYS_32K_TIMER_INIT(4, 1, "timer_32k_ck", "ti,timer-alwon", + 2, "sys_clkin_ck", NULL); +#endif #ifdef CONFIG_ARCH_OMAP4 -OMAP_SYS_32K_TIMER_INIT(4, 1, OMAP4_32K_SOURCE, "ti,timer-alwon", - 2, OMAP4_MPU_SOURCE); #ifdef CONFIG_LOCAL_TIMERS static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, OMAP44XX_LOCAL_TWD_BASE, 29); void __init omap4_local_timer_init(void) @@ -597,7 +602,7 @@ void __init omap4_local_timer_init(void) int err; if (of_have_populated_dt()) { - twd_local_timer_of_register(); + clocksource_of_init(); return; } @@ -615,13 +620,11 @@ void __init omap4_local_timer_init(void) #endif /* CONFIG_ARCH_OMAP4 */ #ifdef CONFIG_SOC_OMAP5 -OMAP_SYS_32K_TIMER_INIT(5, 1, OMAP4_32K_SOURCE, "ti,timer-alwon", - 2, OMAP4_MPU_SOURCE); void __init omap5_realtime_timer_init(void) { int err; - omap5_sync32k_timer_init(); + omap4_sync32k_timer_init(); realtime_counter_init(); err = arch_timer_of_register(); diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c index 5706bdccf45e..aa27d7f5cbb7 100644 --- a/arch/arm/mach-omap2/usb-host.c +++ b/arch/arm/mach-omap2/usb-host.c @@ -22,8 +22,12 @@ #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/dma-mapping.h> - -#include <asm/io.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/fixed.h> +#include <linux/string.h> +#include <linux/io.h> +#include <linux/gpio.h> +#include <linux/usb/phy.h> #include "soc.h" #include "omap_device.h" @@ -526,3 +530,155 @@ void __init usbhs_init(struct usbhs_omap_platform_data *pdata) } #endif + +/* Template for PHY regulators */ +static struct fixed_voltage_config hsusb_reg_config = { + /* .supply_name filled later */ + .microvolts = 3300000, + .gpio = -1, /* updated later */ + .startup_delay = 70000, /* 70msec */ + .enable_high = 1, /* updated later */ + .enabled_at_boot = 0, /* keep in RESET */ + /* .init_data filled later */ +}; + +static const char *nop_name = "nop_usb_xceiv"; /* NOP PHY driver */ +static const char *reg_name = "reg-fixed-voltage"; /* Regulator driver */ + +/** + * usbhs_add_regulator - Add a gpio based fixed voltage regulator device + * @name: name for the regulator + * @dev_id: device id of the device this regulator supplies power to + * @dev_supply: supply name that the device expects + * @gpio: GPIO number + * @polarity: 1 - Active high, 0 - Active low + */ +static int usbhs_add_regulator(char *name, char *dev_id, char *dev_supply, + int gpio, int polarity) +{ + struct regulator_consumer_supply *supplies; + struct regulator_init_data *reg_data; + struct fixed_voltage_config *config; + struct platform_device *pdev; + int ret; + + supplies = kzalloc(sizeof(*supplies), GFP_KERNEL); + if (!supplies) + return -ENOMEM; + + supplies->supply = dev_supply; + supplies->dev_name = dev_id; + + reg_data = kzalloc(sizeof(*reg_data), GFP_KERNEL); + if (!reg_data) + return -ENOMEM; + + reg_data->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS; + reg_data->consumer_supplies = supplies; + reg_data->num_consumer_supplies = 1; + + config = kmemdup(&hsusb_reg_config, sizeof(hsusb_reg_config), + GFP_KERNEL); + if (!config) + return -ENOMEM; + + config->supply_name = name; + config->gpio = gpio; + config->enable_high = polarity; + config->init_data = reg_data; + + /* create a regulator device */ + pdev = kzalloc(sizeof(*pdev), GFP_KERNEL); + if (!pdev) + return -ENOMEM; + + pdev->id = PLATFORM_DEVID_AUTO; + pdev->name = reg_name; + pdev->dev.platform_data = config; + + ret = platform_device_register(pdev); + if (ret) + pr_err("%s: Failed registering regulator %s for %s\n", + __func__, name, dev_id); + + return ret; +} + +int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys) +{ + char *rail_name; + int i, len; + struct platform_device *pdev; + char *phy_id; + + /* the phy_id will be something like "nop_usb_xceiv.1" */ + len = strlen(nop_name) + 3; /* 3 -> ".1" and NULL terminator */ + + for (i = 0; i < num_phys; i++) { + + if (!phy->port) { + pr_err("%s: Invalid port 0. Must start from 1\n", + __func__); + continue; + } + + /* do we need a NOP PHY device ? */ + if (!gpio_is_valid(phy->reset_gpio) && + !gpio_is_valid(phy->vcc_gpio)) + continue; + + /* create a NOP PHY device */ + pdev = kzalloc(sizeof(*pdev), GFP_KERNEL); + if (!pdev) + return -ENOMEM; + + pdev->id = phy->port; + pdev->name = nop_name; + pdev->dev.platform_data = phy->platform_data; + + phy_id = kmalloc(len, GFP_KERNEL); + if (!phy_id) + return -ENOMEM; + + scnprintf(phy_id, len, "nop_usb_xceiv.%d\n", + pdev->id); + + if (platform_device_register(pdev)) { + pr_err("%s: Failed to register device %s\n", + __func__, phy_id); + continue; + } + + usb_bind_phy("ehci-omap.0", phy->port - 1, phy_id); + + /* Do we need RESET regulator ? */ + if (gpio_is_valid(phy->reset_gpio)) { + + rail_name = kmalloc(13, GFP_KERNEL); + if (!rail_name) + return -ENOMEM; + + scnprintf(rail_name, 13, "hsusb%d_reset", phy->port); + + usbhs_add_regulator(rail_name, phy_id, "reset", + phy->reset_gpio, 1); + } + + /* Do we need VCC regulator ? */ + if (gpio_is_valid(phy->vcc_gpio)) { + + rail_name = kmalloc(13, GFP_KERNEL); + if (!rail_name) + return -ENOMEM; + + scnprintf(rail_name, 13, "hsusb%d_vcc", phy->port); + + usbhs_add_regulator(rail_name, phy_id, "vcc", + phy->vcc_gpio, phy->vcc_polarity); + } + + phy++; + } + + return 0; +} diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c index c5a3c6f9504e..e832bc7b8e2d 100644 --- a/arch/arm/mach-omap2/usb-tusb6010.c +++ b/arch/arm/mach-omap2/usb-tusb6010.c @@ -8,6 +8,7 @@ * published by the Free Software Foundation. */ +#include <linux/err.h> #include <linux/string.h> #include <linux/types.h> #include <linux/errno.h> @@ -26,6 +27,24 @@ static u8 async_cs, sync_cs; static unsigned refclk_psec; +static struct gpmc_settings tusb_async = { + .wait_on_read = true, + .wait_on_write = true, + .device_width = GPMC_DEVWIDTH_16BIT, + .mux_add_data = GPMC_MUX_AD, +}; + +static struct gpmc_settings tusb_sync = { + .burst_read = true, + .burst_write = true, + .sync_read = true, + .sync_write = true, + .wait_on_read = true, + .wait_on_write = true, + .burst_len = GPMC_BURST_16, + .device_width = GPMC_DEVWIDTH_16BIT, + .mux_add_data = GPMC_MUX_AD, +}; /* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */ @@ -37,8 +56,6 @@ static int tusb_set_async_mode(unsigned sysclk_ps) memset(&dev_t, 0, sizeof(dev_t)); - dev_t.mux = true; - dev_t.t_ceasu = 8 * 1000; dev_t.t_avdasu = t_acsnh_advnh - 7000; dev_t.t_ce_avd = 1000; @@ -52,7 +69,7 @@ static int tusb_set_async_mode(unsigned sysclk_ps) dev_t.t_wpl = 300; dev_t.cyc_aavdh_we = 1; - gpmc_calc_timings(&t, &dev_t); + gpmc_calc_timings(&t, &tusb_async, &dev_t); return gpmc_cs_set_timings(async_cs, &t); } @@ -65,10 +82,6 @@ static int tusb_set_sync_mode(unsigned sysclk_ps) memset(&dev_t, 0, sizeof(dev_t)); - dev_t.mux = true; - dev_t.sync_read = true; - dev_t.sync_write = true; - dev_t.clk = 11100; dev_t.t_bacc = 1000; dev_t.t_ces = 1000; @@ -84,7 +97,7 @@ static int tusb_set_sync_mode(unsigned sysclk_ps) dev_t.cyc_wpl = 6; dev_t.t_ce_rdyz = 7000; - gpmc_calc_timings(&t, &dev_t); + gpmc_calc_timings(&t, &tusb_sync, &dev_t); return gpmc_cs_set_timings(sync_cs, &t); } @@ -165,18 +178,12 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data, return status; } tusb_resources[0].end = tusb_resources[0].start + 0x9ff; + tusb_async.wait_pin = waitpin; async_cs = async; - gpmc_cs_write_reg(async, GPMC_CS_CONFIG1, - GPMC_CONFIG1_PAGE_LEN(2) - | GPMC_CONFIG1_WAIT_READ_MON - | GPMC_CONFIG1_WAIT_WRITE_MON - | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin) - | GPMC_CONFIG1_READTYPE_ASYNC - | GPMC_CONFIG1_WRITETYPE_ASYNC - | GPMC_CONFIG1_DEVICESIZE_16 - | GPMC_CONFIG1_DEVICETYPE_NOR - | GPMC_CONFIG1_MUXADDDATA); + status = gpmc_cs_program_settings(async_cs, &tusb_async); + if (status < 0) + return status; /* SYNC region, primarily for DMA */ status = gpmc_cs_request(sync, SZ_16M, (unsigned long *) @@ -186,21 +193,12 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data, return status; } tusb_resources[1].end = tusb_resources[1].start + 0x9ff; + tusb_sync.wait_pin = waitpin; sync_cs = sync; - gpmc_cs_write_reg(sync, GPMC_CS_CONFIG1, - GPMC_CONFIG1_READMULTIPLE_SUPP - | GPMC_CONFIG1_READTYPE_SYNC - | GPMC_CONFIG1_WRITEMULTIPLE_SUPP - | GPMC_CONFIG1_WRITETYPE_SYNC - | GPMC_CONFIG1_PAGE_LEN(2) - | GPMC_CONFIG1_WAIT_READ_MON - | GPMC_CONFIG1_WAIT_WRITE_MON - | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin) - | GPMC_CONFIG1_DEVICESIZE_16 - | GPMC_CONFIG1_DEVICETYPE_NOR - | GPMC_CONFIG1_MUXADDDATA - /* fclk divider gets set later */ - ); + + status = gpmc_cs_program_settings(sync_cs, &tusb_sync); + if (status < 0) + return status; /* IRQ */ status = gpio_request_one(irq, GPIOF_IN, "TUSB6010 irq"); diff --git a/arch/arm/mach-omap2/usb.h b/arch/arm/mach-omap2/usb.h index 3319f5cf47a3..e7261ebcf7b0 100644 --- a/arch/arm/mach-omap2/usb.h +++ b/arch/arm/mach-omap2/usb.h @@ -53,8 +53,17 @@ #define USBPHY_OTGSESSEND_EN (1 << 20) #define USBPHY_DATA_POLARITY (1 << 23) +struct usbhs_phy_data { + int port; /* 1 indexed port number */ + int reset_gpio; + int vcc_gpio; + bool vcc_polarity; /* 1 active high, 0 active low */ + void *platform_data; +}; + extern void usb_musb_init(struct omap_musb_board_data *board_data); extern void usbhs_init(struct usbhs_omap_platform_data *pdata); +extern int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys); extern void am35x_musb_reset(void); extern void am35x_musb_phy_power(u8 on); |