diff options
Diffstat (limited to 'arch')
34 files changed, 1776 insertions, 430 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 9b4e78fe3d1c..b9d8a7b2a862 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -310,6 +310,7 @@ config MACH_OMAP_4430SDP depends on ARCH_OMAP4 select OMAP_PACKAGE_CBL select OMAP_PACKAGE_CBS + select REGULATOR_FIXED_VOLTAGE config MACH_OMAP4_PANDA bool "OMAP4 Panda Board" @@ -317,6 +318,7 @@ config MACH_OMAP4_PANDA depends on ARCH_OMAP4 select OMAP_PACKAGE_CBL select OMAP_PACKAGE_CBS + select REGULATOR_FIXED_VOLTAGE config OMAP3_EMU bool "OMAP3 debugging peripherals" diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index a9e3974d015f..ee72a9787bf1 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -218,7 +218,8 @@ obj-$(CONFIG_MACH_OMAP4_PANDA) += board-omap4panda.o \ hsmmc.o \ omap_phy_internal.o -obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o +obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o \ + omap_phy_internal.o \ obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o @@ -243,3 +244,4 @@ obj-y += $(smc91x-m) $(smc91x-y) smsc911x-$(CONFIG_SMSC911X) := gpmc-smsc911x.o obj-y += $(smsc911x-m) $(smsc911x-y) +obj-$(CONFIG_ARCH_OMAP4) += hwspinlock.o diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index ec74c0f2051c..cc42d474c443 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -22,6 +22,7 @@ #include <linux/mmc/host.h> #include <linux/delay.h> #include <linux/i2c/twl.h> +#include <linux/regulator/machine.h> #include <linux/err.h> #include <linux/clk.h> #include <linux/io.h> @@ -147,6 +148,25 @@ static void __init omap_2430sdp_init_early(void) omap2_init_common_devices(NULL, NULL); } +static struct regulator_consumer_supply sdp2430_vmmc1_supplies[] = { + REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.0"), +}; + +/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */ +static struct regulator_init_data sdp2430_vmmc1 = { + .constraints = { + .min_uV = 1850000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(sdp2430_vmmc1_supplies), + .consumer_supplies = &sdp2430_vmmc1_supplies[0], +}; + static struct twl4030_gpio_platform_data sdp2430_gpio_data = { .gpio_base = OMAP_MAX_GPIO_LINES, .irq_base = TWL4030_GPIO_IRQ_BASE, @@ -159,6 +179,7 @@ static struct twl4030_platform_data sdp2430_twldata = { /* platform_data for children goes here */ .gpio = &sdp2430_gpio_data, + .vmmc1 = &sdp2430_vmmc1, }; static struct i2c_board_info __initdata sdp2430_i2c_boardinfo[] = { diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 31085883199e..76a260f7c00e 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -315,11 +315,6 @@ static struct platform_device sdp3430_dss_device = { }, }; -static struct regulator_consumer_supply sdp3430_vdda_dac_supply = { - .supply = "vdda_dac", - .dev = &sdp3430_dss_device.dev, -}; - static struct platform_device *sdp3430_devices[] __initdata = { &sdp3430_dss_device, }; @@ -369,18 +364,6 @@ static struct omap2_hsmmc_info mmc[] = { {} /* Terminator */ }; -static struct regulator_consumer_supply sdp3430_vmmc1_supply = { - .supply = "vmmc", -}; - -static struct regulator_consumer_supply sdp3430_vsim_supply = { - .supply = "vmmc_aux", -}; - -static struct regulator_consumer_supply sdp3430_vmmc2_supply = { - .supply = "vmmc", -}; - static int sdp3430_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio) { @@ -391,13 +374,6 @@ static int sdp3430_twl_gpio_setup(struct device *dev, mmc[1].gpio_cd = gpio + 1; omap2_hsmmc_init(mmc); - /* link regulators to MMC adapters ... we "know" the - * regulators will be set up only *after* we return. - */ - sdp3430_vmmc1_supply.dev = mmc[0].dev; - sdp3430_vsim_supply.dev = mmc[0].dev; - sdp3430_vmmc2_supply.dev = mmc[1].dev; - /* gpio + 7 is "sub_lcd_en_bkl" (output/PWM1) */ gpio_request(gpio + 7, "sub_lcd_en_bkl"); gpio_direction_output(gpio + 7, 0); @@ -426,6 +402,34 @@ static struct twl4030_madc_platform_data sdp3430_madc_data = { .irq_line = 1, }; +/* regulator consumer mappings */ + +/* ads7846 on SPI */ +static struct regulator_consumer_supply sdp3430_vaux3_supplies[] = { + REGULATOR_SUPPLY("vcc", "spi1.0"), +}; + +static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = { + REGULATOR_SUPPLY("vdda_dac", "omapdss"), +}; + +/* VPLL2 for digital video outputs */ +static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = { + REGULATOR_SUPPLY("vdds_dsi", "omapdss"), +}; + +static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = { + REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.0"), +}; + +static struct regulator_consumer_supply sdp3430_vsim_supplies[] = { + REGULATOR_SUPPLY("vmmc_aux", "mmci-omap-hs.0"), +}; + +static struct regulator_consumer_supply sdp3430_vmmc2_supplies[] = { + REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1"), +}; + /* * Apply all the fixed voltages since most versions of U-Boot * don't bother with that initialization. @@ -468,6 +472,8 @@ static struct regulator_init_data sdp3430_vaux3 = { .valid_ops_mask = REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, + .num_consumer_supplies = ARRAY_SIZE(sdp3430_vaux3_supplies), + .consumer_supplies = sdp3430_vaux3_supplies, }; /* VAUX4 for OMAP VDD_CSI2 (camera) */ @@ -494,8 +500,8 @@ static struct regulator_init_data sdp3430_vmmc1 = { | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, - .num_consumer_supplies = 1, - .consumer_supplies = &sdp3430_vmmc1_supply, + .num_consumer_supplies = ARRAY_SIZE(sdp3430_vmmc1_supplies), + .consumer_supplies = sdp3430_vmmc1_supplies, }; /* VMMC2 for MMC2 card */ @@ -509,8 +515,8 @@ static struct regulator_init_data sdp3430_vmmc2 = { .valid_ops_mask = REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, - .num_consumer_supplies = 1, - .consumer_supplies = &sdp3430_vmmc2_supply, + .num_consumer_supplies = ARRAY_SIZE(sdp3430_vmmc2_supplies), + .consumer_supplies = sdp3430_vmmc2_supplies, }; /* VSIM for OMAP VDD_MMC1A (i/o for DAT4..DAT7) */ @@ -524,8 +530,8 @@ static struct regulator_init_data sdp3430_vsim = { | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, - .num_consumer_supplies = 1, - .consumer_supplies = &sdp3430_vsim_supply, + .num_consumer_supplies = ARRAY_SIZE(sdp3430_vsim_supplies), + .consumer_supplies = sdp3430_vsim_supplies, }; /* VDAC for DSS driving S-Video */ @@ -539,16 +545,8 @@ static struct regulator_init_data sdp3430_vdac = { .valid_ops_mask = REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, - .num_consumer_supplies = 1, - .consumer_supplies = &sdp3430_vdda_dac_supply, -}; - -/* VPLL2 for digital video outputs */ -static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = { - { - .supply = "vdds_dsi", - .dev = &sdp3430_dss_device.dev, - } + .num_consumer_supplies = ARRAY_SIZE(sdp3430_vdda_dac_supplies), + .consumer_supplies = sdp3430_vdda_dac_supplies, }; static struct regulator_init_data sdp3430_vpll2 = { @@ -812,7 +810,7 @@ static void __init omap_3430sdp_init(void) omap_serial_init(); usb_musb_init(&musb_board_data); board_smc91x_init(); - board_flash_init(sdp_flash_partitions, chip_sel_3430); + board_flash_init(sdp_flash_partitions, chip_sel_3430, 0); sdp3430_display_init(); enable_board_wakeup_source(); usb_ehci_init(&ehci_pdata); diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index 16538757291a..8d1c4358ecf9 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -11,6 +11,7 @@ #include <linux/platform_device.h> #include <linux/input.h> #include <linux/gpio.h> +#include <linux/mtd/nand.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -208,7 +209,7 @@ static void __init omap_sdp_init(void) zoom_peripherals_init(); zoom_display_init(); board_smc91x_init(); - board_flash_init(sdp_flash_partitions, chip_sel_sdp); + board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_BUSWIDTH_16); enable_board_wakeup_source(); usb_ehci_init(&ehci_pdata); } diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index dcc8b27e3033..1a943be822c3 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -45,7 +45,6 @@ #define ETH_KS8851_IRQ 34 #define ETH_KS8851_POWER_ON 48 #define ETH_KS8851_QUART 138 -#define OMAP4SDP_MDM_PWR_EN_GPIO 157 #define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184 #define OMAP4_SFH7741_ENABLE_GPIO 188 @@ -335,16 +334,6 @@ static void __init omap_4430sdp_init_early(void) #endif } -static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN, - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, - .phy_reset = false, - .reset_gpio_port[0] = -EINVAL, - .reset_gpio_port[1] = -EINVAL, - .reset_gpio_port[2] = -EINVAL, -}; - static struct omap_musb_board_data musb_board_data = { .interface_type = MUSB_INTERFACE_UTMI, .mode = MUSB_OTG, @@ -518,7 +507,6 @@ static struct regulator_init_data sdp4430_vana = { .constraints = { .min_uV = 2100000, .max_uV = 2100000, - .apply_uV = true, .valid_modes_mask = REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY, .valid_ops_mask = REGULATOR_CHANGE_MODE @@ -530,7 +518,6 @@ static struct regulator_init_data sdp4430_vcxio = { .constraints = { .min_uV = 1800000, .max_uV = 1800000, - .apply_uV = true, .valid_modes_mask = REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY, .valid_ops_mask = REGULATOR_CHANGE_MODE @@ -542,7 +529,6 @@ static struct regulator_init_data sdp4430_vdac = { .constraints = { .min_uV = 1800000, .max_uV = 1800000, - .apply_uV = true, .valid_modes_mask = REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY, .valid_ops_mask = REGULATOR_CHANGE_MODE @@ -660,14 +646,6 @@ static void __init omap_4430sdp_init(void) omap_serial_init(); omap4_twl6030_hsmmc_init(mmc); - /* Power on the ULPI PHY */ - status = gpio_request(OMAP4SDP_MDM_PWR_EN_GPIO, "USBB1 PHY VMDM_3V3"); - if (status) - pr_err("%s: Could not get USBB1 PHY GPIO\n", __func__); - else - gpio_direction_output(OMAP4SDP_MDM_PWR_EN_GPIO, 1); - - usb_ehci_init(&ehci_pdata); usb_musb_init(&musb_board_data); status = omap_ethernet_init(); diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index d0d0f5528132..8532d6e0d53a 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -408,6 +408,10 @@ static struct omap_musb_board_data musb_board_data = { .interface_type = MUSB_INTERFACE_ULPI, .mode = MUSB_OTG, .power = 500, + .set_phy_power = am35x_musb_phy_power, + .clear_irq = am35x_musb_clear_irq, + .set_mode = am35x_musb_set_mode, + .reset = am35x_musb_reset, }; static __init void am3517_evm_musb_init(void) diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index fd38c05bb47f..c32c06828f08 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -1,5 +1,5 @@ /* - * board-sdp-flash.c + * board-flash.c * Modified from mach-omap2/board-3430sdp-flash.c * * Copyright (C) 2009 Nokia Corporation @@ -16,6 +16,7 @@ #include <linux/platform_device.h> #include <linux/mtd/physmap.h> #include <linux/io.h> +#include <plat/irqs.h> #include <plat/gpmc.h> #include <plat/nand.h> @@ -73,11 +74,11 @@ __init board_nor_init(struct mtd_partition *nor_parts, u8 nr_parts, u8 cs) + FLASH_SIZE_SDPV1 - 1; } if (err < 0) { - printk(KERN_ERR "NOR: Can't request GPMC CS\n"); + pr_err("NOR: Can't request GPMC CS\n"); return; } if (platform_device_register(&board_nor_device) < 0) - printk(KERN_ERR "Unable to register NOR device\n"); + pr_err("Unable to register NOR device\n"); } #if defined(CONFIG_MTD_ONENAND_OMAP2) || \ @@ -139,12 +140,16 @@ static struct omap_nand_platform_data board_nand_data = { }; void -__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) +__init board_nand_init(struct mtd_partition *nand_parts, + u8 nr_parts, u8 cs, int nand_type) { board_nand_data.cs = cs; board_nand_data.parts = nand_parts; - board_nand_data.nr_parts = nr_parts; + board_nand_data.nr_parts = nr_parts; + board_nand_data.devsize = nand_type; + board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT; + board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs; gpmc_nand_init(&board_nand_data); } #else @@ -189,12 +194,12 @@ unmap: } /** - * sdp3430_flash_init - Identify devices connected to GPMC and register. + * board_flash_init - Identify devices connected to GPMC and register. * * @return - void. */ void board_flash_init(struct flash_partitions partition_info[], - char chip_sel_board[][GPMC_CS_NUM]) + char chip_sel_board[][GPMC_CS_NUM], int nand_type) { u8 cs = 0; u8 norcs = GPMC_CS_NUM + 1; @@ -208,7 +213,7 @@ void board_flash_init(struct flash_partitions partition_info[], */ idx = get_gpmc0_type(); if (idx >= MAX_SUPPORTED_GPMC_CONFIG) { - printk(KERN_ERR "%s: Invalid chip select: %d\n", __func__, cs); + pr_err("%s: Invalid chip select: %d\n", __func__, cs); return; } config_sel = (unsigned char *)(chip_sel_board[idx]); @@ -232,23 +237,20 @@ void board_flash_init(struct flash_partitions partition_info[], } if (norcs > GPMC_CS_NUM) - printk(KERN_INFO "NOR: Unable to find configuration " - "in GPMC\n"); + pr_err("NOR: Unable to find configuration in GPMC\n"); else board_nor_init(partition_info[0].parts, partition_info[0].nr_parts, norcs); if (onenandcs > GPMC_CS_NUM) - printk(KERN_INFO "OneNAND: Unable to find configuration " - "in GPMC\n"); + pr_err("OneNAND: Unable to find configuration in GPMC\n"); else board_onenand_init(partition_info[1].parts, partition_info[1].nr_parts, onenandcs); if (nandcs > GPMC_CS_NUM) - printk(KERN_INFO "NAND: Unable to find configuration " - "in GPMC\n"); + pr_err("NAND: Unable to find configuration in GPMC\n"); else board_nand_init(partition_info[2].parts, - partition_info[2].nr_parts, nandcs); + partition_info[2].nr_parts, nandcs, nand_type); } diff --git a/arch/arm/mach-omap2/board-flash.h b/arch/arm/mach-omap2/board-flash.h index 69befe00dd2f..c240a3f8d163 100644 --- a/arch/arm/mach-omap2/board-flash.h +++ b/arch/arm/mach-omap2/board-flash.h @@ -25,6 +25,6 @@ struct flash_partitions { }; extern void board_flash_init(struct flash_partitions [], - char chip_sel[][GPMC_CS_NUM]); + char chip_sel[][GPMC_CS_NUM], int nand_type); extern void board_nand_init(struct mtd_partition *nand_parts, - u8 nr_parts, u8 cs); + u8 nr_parts, u8 cs, int nand_type); diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index d8eb2cb7cbc7..a3fae5697a72 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c @@ -433,7 +433,7 @@ static void __init omap_ldp_init(void) omap_serial_init(); usb_musb_init(&musb_board_data); board_nand_init(ldp_nand_partitions, - ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS); + ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0); omap2_hsmmc_init(mmc); /* link regulators to MMC adapters */ diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index c2a0fca4aa53..d4a115712290 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -30,6 +30,8 @@ #include <linux/usb/otg.h> #include <linux/smsc911x.h> +#include <linux/wl12xx.h> +#include <linux/regulator/fixed.h> #include <linux/regulator/machine.h> #include <linux/mmc/host.h> @@ -58,6 +60,13 @@ #define OMAP3EVM_ETHR_ID_REV 0x50 #define OMAP3EVM_ETHR_GPIO_IRQ 176 #define OMAP3EVM_SMSC911X_CS 5 +/* + * Eth Reset signal + * 64 = Generation 1 (<=RevD) + * 7 = Generation 2 (>=RevE) + */ +#define OMAP3EVM_GEN1_ETHR_GPIO_RST 64 +#define OMAP3EVM_GEN2_ETHR_GPIO_RST 7 static u8 omap3_evm_version; @@ -124,10 +133,15 @@ static struct platform_device omap3evm_smsc911x_device = { static inline void __init omap3evm_init_smsc911x(void) { - int eth_cs; + int eth_cs, eth_rst; struct clk *l3ck; unsigned int rate; + if (get_omap3_evm_rev() == OMAP3EVM_BOARD_GEN_1) + eth_rst = OMAP3EVM_GEN1_ETHR_GPIO_RST; + else + eth_rst = OMAP3EVM_GEN2_ETHR_GPIO_RST; + eth_cs = OMAP3EVM_SMSC911X_CS; l3ck = clk_get(NULL, "l3_ck"); @@ -136,6 +150,27 @@ static inline void __init omap3evm_init_smsc911x(void) else rate = clk_get_rate(l3ck); + /* Configure ethernet controller reset gpio */ + if (cpu_is_omap3430()) { + if (gpio_request(eth_rst, "SMSC911x gpio") < 0) { + pr_err(KERN_ERR "Failed to request %d for smsc911x\n", + eth_rst); + return; + } + + if (gpio_direction_output(eth_rst, 1) < 0) { + pr_err(KERN_ERR "Failed to set direction of %d for" \ + " smsc911x\n", eth_rst); + return; + } + /* reset pulse to ethernet controller*/ + usleep_range(150, 220); + gpio_set_value(eth_rst, 0); + usleep_range(150, 220); + gpio_set_value(eth_rst, 1); + usleep_range(1, 2); + } + if (gpio_request(OMAP3EVM_ETHR_GPIO_IRQ, "SMSC911x irq") < 0) { printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n", OMAP3EVM_ETHR_GPIO_IRQ); @@ -235,9 +270,9 @@ static int omap3_evm_enable_lcd(struct omap_dss_device *dssdev) gpio_set_value(OMAP3EVM_LCD_PANEL_ENVDD, 0); if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) - gpio_set_value(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0); + gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0); else - gpio_set_value(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1); + gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1); lcd_enabled = 1; return 0; @@ -248,9 +283,9 @@ static void omap3_evm_disable_lcd(struct omap_dss_device *dssdev) gpio_set_value(OMAP3EVM_LCD_PANEL_ENVDD, 1); if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) - gpio_set_value(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1); + gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1); else - gpio_set_value(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0); + gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0); lcd_enabled = 0; } @@ -289,7 +324,7 @@ static int omap3_evm_enable_dvi(struct omap_dss_device *dssdev) return -EINVAL; } - gpio_set_value(OMAP3EVM_DVI_PANEL_EN_GPIO, 1); + gpio_set_value_cansleep(OMAP3EVM_DVI_PANEL_EN_GPIO, 1); dvi_enabled = 1; return 0; @@ -297,7 +332,7 @@ static int omap3_evm_enable_dvi(struct omap_dss_device *dssdev) static void omap3_evm_disable_dvi(struct omap_dss_device *dssdev) { - gpio_set_value(OMAP3EVM_DVI_PANEL_EN_GPIO, 0); + gpio_set_value_cansleep(OMAP3EVM_DVI_PANEL_EN_GPIO, 0); dvi_enabled = 0; } @@ -381,6 +416,16 @@ static struct omap2_hsmmc_info mmc[] = { .gpio_cd = -EINVAL, .gpio_wp = 63, }, +#ifdef CONFIG_WL12XX_PLATFORM_DATA + { + .name = "wl1271", + .mmc = 2, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, + .gpio_wp = -EINVAL, + .gpio_cd = -EINVAL, + .nonremovable = true, + }, +#endif {} /* Terminator */ }; @@ -411,6 +456,8 @@ static struct platform_device leds_gpio = { static int omap3evm_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio) { + int r; + /* gpio + 0 is "mmc0_cd" (input/IRQ) */ omap_mux_init_gpio(63, OMAP_PIN_INPUT); mmc[0].gpio_cd = gpio + 0; @@ -426,8 +473,12 @@ static int omap3evm_twl_gpio_setup(struct device *dev, */ /* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */ - gpio_request(gpio + TWL4030_GPIO_MAX, "EN_LCD_BKL"); - gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0); + r = gpio_request(gpio + TWL4030_GPIO_MAX, "EN_LCD_BKL"); + if (!r) + r = gpio_direction_output(gpio + TWL4030_GPIO_MAX, + (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) ? 1 : 0); + if (r) + printk(KERN_ERR "failed to get/set lcd_bkl gpio\n"); /* gpio + 7 == DVI Enable */ gpio_request(gpio + 7, "EN_DVI"); @@ -538,6 +589,69 @@ static struct regulator_init_data omap3_evm_vpll2 = { .consumer_supplies = &omap3_evm_vpll2_supply, }; +/* ads7846 on SPI */ +static struct regulator_consumer_supply omap3evm_vio_supply = + REGULATOR_SUPPLY("vcc", "spi1.0"); + +/* VIO for ads7846 */ +static struct regulator_init_data omap3evm_vio = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &omap3evm_vio_supply, +}; + +#ifdef CONFIG_WL12XX_PLATFORM_DATA + +#define OMAP3EVM_WLAN_PMENA_GPIO (150) +#define OMAP3EVM_WLAN_IRQ_GPIO (149) + +static struct regulator_consumer_supply omap3evm_vmmc2_supply = { + .supply = "vmmc", + .dev_name = "mmci-omap-hs.1", +}; + +/* VMMC2 for driving the WL12xx module */ +static struct regulator_init_data omap3evm_vmmc2 = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &omap3evm_vmmc2_supply, +}; + +static struct fixed_voltage_config omap3evm_vwlan = { + .supply_name = "vwl1271", + .microvolts = 1800000, /* 1.80V */ + .gpio = OMAP3EVM_WLAN_PMENA_GPIO, + .startup_delay = 70000, /* 70ms */ + .enable_high = 1, + .enabled_at_boot = 0, + .init_data = &omap3evm_vmmc2, +}; + +static struct platform_device omap3evm_vwlan_device = { + .name = "reg-fixed-voltage", + .id = 1, + .dev = { + .platform_data = &omap3evm_vwlan, + }, +}; + +struct wl12xx_platform_data omap3evm_wlan_data __initdata = { + .irq = OMAP_GPIO_IRQ(OMAP3EVM_WLAN_IRQ_GPIO), + /* ref clock is 38.4 MHz */ + .board_ref_clock = 2, +}; +#endif + static struct twl4030_platform_data omap3evm_twldata = { .irq_base = TWL4030_IRQ_BASE, .irq_end = TWL4030_IRQ_END, @@ -550,6 +664,7 @@ static struct twl4030_platform_data omap3evm_twldata = { .codec = &omap3evm_codec_data, .vdac = &omap3_evm_vdac, .vpll2 = &omap3_evm_vpll2, + .vio = &omap3evm_vio, }; static struct i2c_board_info __initdata omap3evm_i2c_boardinfo[] = { @@ -651,14 +766,61 @@ static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = { }; #ifdef CONFIG_OMAP_MUX -static struct omap_board_mux board_mux[] __initdata = { +static struct omap_board_mux omap35x_board_mux[] __initdata = { + OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP | + OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW | + OMAP_PIN_OFF_WAKEUPENABLE), + OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | + OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW | + OMAP_PIN_OFF_WAKEUPENABLE), + OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | + OMAP_PIN_OFF_NONE), + OMAP3_MUX(GPMC_WAIT2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | + OMAP_PIN_OFF_NONE), +#ifdef CONFIG_WL12XX_PLATFORM_DATA + /* WLAN IRQ - GPIO 149 */ + OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP), + + /* WLAN POWER ENABLE - GPIO 150 */ + OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + + /* MMC2 SDIO pin muxes for WL12xx */ + OMAP3_MUX(SDMMC2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), + OMAP3_MUX(SDMMC2_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), + OMAP3_MUX(SDMMC2_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), + OMAP3_MUX(SDMMC2_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), + OMAP3_MUX(SDMMC2_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), + OMAP3_MUX(SDMMC2_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), +#endif + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; + +static struct omap_board_mux omap36x_board_mux[] __initdata = { OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW | OMAP_PIN_OFF_WAKEUPENABLE), OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | - OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW), + OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW | + OMAP_PIN_OFF_WAKEUPENABLE), + /* AM/DM37x EVM: DSS data bus muxed with sys_boot */ + OMAP3_MUX(DSS_DATA18, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), + OMAP3_MUX(DSS_DATA19, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), + OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), + OMAP3_MUX(DSS_DATA21, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), + OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), + OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), + OMAP3_MUX(SYS_BOOT0, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), + OMAP3_MUX(SYS_BOOT1, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), + OMAP3_MUX(SYS_BOOT3, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), + OMAP3_MUX(SYS_BOOT4, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), + OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), + OMAP3_MUX(SYS_BOOT6, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), + { .reg_offset = OMAP_MUX_TERMINATOR }, }; +#else +#define omap35x_board_mux NULL +#define omap36x_board_mux NULL #endif static struct omap_musb_board_data musb_board_data = { @@ -670,7 +832,11 @@ static struct omap_musb_board_data musb_board_data = { static void __init omap3_evm_init(void) { omap3_evm_get_revision(); - omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); + + if (cpu_is_omap3630()) + omap3_mux_init(omap36x_board_mux, OMAP_PACKAGE_CBB); + else + omap3_mux_init(omap35x_board_mux, OMAP_PACKAGE_CBB); omap3_evm_i2c_init(); @@ -714,6 +880,13 @@ static void __init omap3_evm_init(void) ads7846_dev_init(); omap3evm_init_smsc911x(); omap3_evm_display_init(); + +#ifdef CONFIG_WL12XX_PLATFORM_DATA + /* WL12xx WLAN Init */ + if (wl12xx_set_platform_data(&omap3evm_wlan_data)) + pr_err("error setting wl12xx data\n"); + platform_device_register(&omap3evm_vwlan_device); +#endif } MACHINE_START(OMAP3EVM, "OMAP3 EVM") diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index fca5b9e80c18..3dd241b95159 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -26,6 +26,8 @@ #include <linux/usb/otg.h> #include <linux/i2c/twl.h> #include <linux/regulator/machine.h> +#include <linux/regulator/fixed.h> +#include <linux/wl12xx.h> #include <mach/hardware.h> #include <mach/omap4-common.h> @@ -45,6 +47,8 @@ #define GPIO_HUB_POWER 1 #define GPIO_HUB_NRESET 62 +#define GPIO_WIFI_PMENA 43 +#define GPIO_WIFI_IRQ 53 static struct gpio_led gpio_leds[] = { { @@ -161,6 +165,15 @@ static struct omap2_hsmmc_info mmc[] = { .gpio_wp = -EINVAL, .gpio_cd = -EINVAL, }, + { + .name = "wl1271", + .mmc = 5, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, + .gpio_wp = -EINVAL, + .gpio_cd = -EINVAL, + .ocr_mask = MMC_VDD_165_195, + .nonremovable = true, + }, {} /* Terminator */ }; @@ -171,6 +184,43 @@ static struct regulator_consumer_supply omap4_panda_vmmc_supply[] = { }, }; +static struct regulator_consumer_supply omap4_panda_vmmc5_supply = { + .supply = "vmmc", + .dev_name = "mmci-omap-hs.4", +}; + +static struct regulator_init_data panda_vmmc5 = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &omap4_panda_vmmc5_supply, +}; + +static struct fixed_voltage_config panda_vwlan = { + .supply_name = "vwl1271", + .microvolts = 1800000, /* 1.8V */ + .gpio = GPIO_WIFI_PMENA, + .startup_delay = 70000, /* 70msec */ + .enable_high = 1, + .enabled_at_boot = 0, + .init_data = &panda_vmmc5, +}; + +static struct platform_device omap_vwlan_device = { + .name = "reg-fixed-voltage", + .id = 1, + .dev = { + .platform_data = &panda_vwlan, + }, +}; + +struct wl12xx_platform_data omap_panda_wlan_data __initdata = { + .irq = OMAP_GPIO_IRQ(GPIO_WIFI_IRQ), + /* PANDA ref clock is 38.4 MHz */ + .board_ref_clock = 2, +}; + static int omap4_twl6030_hsmmc_late_init(struct device *dev) { int ret = 0; @@ -304,7 +354,6 @@ static struct regulator_init_data omap4_panda_vana = { .constraints = { .min_uV = 2100000, .max_uV = 2100000, - .apply_uV = true, .valid_modes_mask = REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY, .valid_ops_mask = REGULATOR_CHANGE_MODE @@ -316,7 +365,6 @@ static struct regulator_init_data omap4_panda_vcxio = { .constraints = { .min_uV = 1800000, .max_uV = 1800000, - .apply_uV = true, .valid_modes_mask = REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY, .valid_ops_mask = REGULATOR_CHANGE_MODE @@ -328,7 +376,6 @@ static struct regulator_init_data omap4_panda_vdac = { .constraints = { .min_uV = 1800000, .max_uV = 1800000, - .apply_uV = true, .valid_modes_mask = REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY, .valid_ops_mask = REGULATOR_CHANGE_MODE @@ -390,6 +437,19 @@ static int __init omap4_panda_i2c_init(void) #ifdef CONFIG_OMAP_MUX static struct omap_board_mux board_mux[] __initdata = { + /* WLAN IRQ - GPIO 53 */ + OMAP4_MUX(GPMC_NCS3, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), + /* WLAN POWER ENABLE - GPIO 43 */ + OMAP4_MUX(GPMC_A19, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), + /* WLAN SDIO: MMC5 CMD */ + OMAP4_MUX(SDMMC5_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), + /* WLAN SDIO: MMC5 CLK */ + OMAP4_MUX(SDMMC5_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), + /* WLAN SDIO: MMC5 DAT[0-3] */ + OMAP4_MUX(SDMMC5_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), + OMAP4_MUX(SDMMC5_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), + OMAP4_MUX(SDMMC5_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), + OMAP4_MUX(SDMMC5_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), { .reg_offset = OMAP_MUX_TERMINATOR }, }; #else @@ -404,8 +464,12 @@ static void __init omap4_panda_init(void) package = OMAP_PACKAGE_CBL; omap4_mux_init(board_mux, package); + if (wl12xx_set_platform_data(&omap_panda_wlan_data)) + pr_err("error setting wl12xx data\n"); + omap4_panda_i2c_init(); platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices)); + platform_device_register(&omap_vwlan_device); omap_serial_init(); omap4_twl6030_hsmmc_init(mmc); omap4_ehci_init(); diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c index 85d4170f30ab..7e3f1595d77b 100644 --- a/arch/arm/mach-omap2/board-zoom.c +++ b/arch/arm/mach-omap2/board-zoom.c @@ -16,6 +16,7 @@ #include <linux/input.h> #include <linux/gpio.h> #include <linux/i2c/twl.h> +#include <linux/mtd/nand.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -124,8 +125,8 @@ static void __init omap_zoom_init(void) usb_ehci_init(&ehci_pdata); } - board_nand_init(zoom_nand_partitions, - ARRAY_SIZE(zoom_nand_partitions), ZOOM_NAND_CS); + board_nand_init(zoom_nand_partitions, ARRAY_SIZE(zoom_nand_partitions), + ZOOM_NAND_CS, NAND_BUSWIDTH_16); zoom_debugboard_init(); zoom_peripherals_init(); zoom_display_init(); diff --git a/arch/arm/mach-omap2/clkt_clksel.c b/arch/arm/mach-omap2/clkt_clksel.c index a781cd6795a4..e25364de028a 100644 --- a/arch/arm/mach-omap2/clkt_clksel.c +++ b/arch/arm/mach-omap2/clkt_clksel.c @@ -97,7 +97,7 @@ static u8 _get_div_and_fieldval(struct clk *src_clk, struct clk *clk, u32 *field_val) { const struct clksel *clks; - const struct clksel_rate *clkr, *max_clkr; + const struct clksel_rate *clkr, *max_clkr = NULL; u8 max_div = 0; clks = _get_clksel_by_parent(clk, src_clk); diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 8800486f9467..9ee876fd367a 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -15,6 +15,7 @@ #include <linux/io.h> #include <linux/clk.h> #include <linux/err.h> +#include <linux/slab.h> #include <mach/hardware.h> #include <mach/irqs.h> @@ -320,163 +321,55 @@ static inline void omap_init_audio(void) {} #include <plat/mcspi.h> -#define OMAP2_MCSPI1_BASE 0x48098000 -#define OMAP2_MCSPI2_BASE 0x4809a000 -#define OMAP2_MCSPI3_BASE 0x480b8000 -#define OMAP2_MCSPI4_BASE 0x480ba000 - -#define OMAP4_MCSPI1_BASE 0x48098100 -#define OMAP4_MCSPI2_BASE 0x4809a100 -#define OMAP4_MCSPI3_BASE 0x480b8100 -#define OMAP4_MCSPI4_BASE 0x480ba100 - -static struct omap2_mcspi_platform_config omap2_mcspi1_config = { - .num_cs = 4, -}; - -static struct resource omap2_mcspi1_resources[] = { - { - .start = OMAP2_MCSPI1_BASE, - .end = OMAP2_MCSPI1_BASE + 0xff, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device omap2_mcspi1 = { - .name = "omap2_mcspi", - .id = 1, - .num_resources = ARRAY_SIZE(omap2_mcspi1_resources), - .resource = omap2_mcspi1_resources, - .dev = { - .platform_data = &omap2_mcspi1_config, - }, -}; - -static struct omap2_mcspi_platform_config omap2_mcspi2_config = { - .num_cs = 2, -}; - -static struct resource omap2_mcspi2_resources[] = { - { - .start = OMAP2_MCSPI2_BASE, - .end = OMAP2_MCSPI2_BASE + 0xff, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device omap2_mcspi2 = { - .name = "omap2_mcspi", - .id = 2, - .num_resources = ARRAY_SIZE(omap2_mcspi2_resources), - .resource = omap2_mcspi2_resources, - .dev = { - .platform_data = &omap2_mcspi2_config, - }, -}; - -#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ - defined(CONFIG_ARCH_OMAP4) -static struct omap2_mcspi_platform_config omap2_mcspi3_config = { - .num_cs = 2, -}; - -static struct resource omap2_mcspi3_resources[] = { - { - .start = OMAP2_MCSPI3_BASE, - .end = OMAP2_MCSPI3_BASE + 0xff, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device omap2_mcspi3 = { - .name = "omap2_mcspi", - .id = 3, - .num_resources = ARRAY_SIZE(omap2_mcspi3_resources), - .resource = omap2_mcspi3_resources, - .dev = { - .platform_data = &omap2_mcspi3_config, - }, -}; -#endif - -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) -static struct omap2_mcspi_platform_config omap2_mcspi4_config = { - .num_cs = 1, -}; - -static struct resource omap2_mcspi4_resources[] = { - { - .start = OMAP2_MCSPI4_BASE, - .end = OMAP2_MCSPI4_BASE + 0xff, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device omap2_mcspi4 = { - .name = "omap2_mcspi", - .id = 4, - .num_resources = ARRAY_SIZE(omap2_mcspi4_resources), - .resource = omap2_mcspi4_resources, - .dev = { - .platform_data = &omap2_mcspi4_config, +struct omap_device_pm_latency omap_mcspi_latency[] = { + [0] = { + .deactivate_func = omap_device_idle_hwmods, + .activate_func = omap_device_enable_hwmods, + .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, }, }; -#endif -#ifdef CONFIG_ARCH_OMAP4 -static inline void omap4_mcspi_fixup(void) +static int omap_mcspi_init(struct omap_hwmod *oh, void *unused) { - omap2_mcspi1_resources[0].start = OMAP4_MCSPI1_BASE; - omap2_mcspi1_resources[0].end = OMAP4_MCSPI1_BASE + 0xff; - omap2_mcspi2_resources[0].start = OMAP4_MCSPI2_BASE; - omap2_mcspi2_resources[0].end = OMAP4_MCSPI2_BASE + 0xff; - omap2_mcspi3_resources[0].start = OMAP4_MCSPI3_BASE; - omap2_mcspi3_resources[0].end = OMAP4_MCSPI3_BASE + 0xff; - omap2_mcspi4_resources[0].start = OMAP4_MCSPI4_BASE; - omap2_mcspi4_resources[0].end = OMAP4_MCSPI4_BASE + 0xff; -} -#else -static inline void omap4_mcspi_fixup(void) -{ -} -#endif + struct omap_device *od; + char *name = "omap2_mcspi"; + struct omap2_mcspi_platform_config *pdata; + static int spi_num; + struct omap2_mcspi_dev_attr *mcspi_attrib = oh->dev_attr; + + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + pr_err("Memory allocation for McSPI device failed\n"); + return -ENOMEM; + } -#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ - defined(CONFIG_ARCH_OMAP4) -static inline void omap2_mcspi3_init(void) -{ - platform_device_register(&omap2_mcspi3); -} -#else -static inline void omap2_mcspi3_init(void) -{ -} -#endif + pdata->num_cs = mcspi_attrib->num_chipselect; + switch (oh->class->rev) { + case OMAP2_MCSPI_REV: + case OMAP3_MCSPI_REV: + pdata->regs_offset = 0; + break; + case OMAP4_MCSPI_REV: + pdata->regs_offset = OMAP4_MCSPI_REG_OFFSET; + break; + default: + pr_err("Invalid McSPI Revision value\n"); + return -EINVAL; + } -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) -static inline void omap2_mcspi4_init(void) -{ - platform_device_register(&omap2_mcspi4); -} -#else -static inline void omap2_mcspi4_init(void) -{ + spi_num++; + od = omap_device_build(name, spi_num, oh, pdata, + sizeof(*pdata), omap_mcspi_latency, + ARRAY_SIZE(omap_mcspi_latency), 0); + WARN(IS_ERR(od), "Cant build omap_device for %s:%s\n", + name, oh->name); + kfree(pdata); + return 0; } -#endif static void omap_init_mcspi(void) { - if (cpu_is_omap44xx()) - omap4_mcspi_fixup(); - - platform_device_register(&omap2_mcspi1); - platform_device_register(&omap2_mcspi2); - - if (cpu_is_omap2430() || cpu_is_omap343x() || cpu_is_omap44xx()) - omap2_mcspi3_init(); - - if (cpu_is_omap343x() || cpu_is_omap44xx()) - omap2_mcspi4_init(); + omap_hwmod_for_each_by_class("mcspi", omap_mcspi_init, NULL); } #else diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c index 2bb29c160702..c1791d08ae56 100644 --- a/arch/arm/mach-omap2/gpmc-nand.c +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -12,6 +12,7 @@ #include <linux/kernel.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/mtd/nand.h> #include <asm/mach/flash.h> @@ -69,8 +70,10 @@ static int omap2_nand_gpmc_retime(void) t.wr_cycle = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->wr_cycle); /* Configure GPMC */ - gpmc_cs_configure(gpmc_nand_data->cs, - GPMC_CONFIG_DEV_SIZE, gpmc_nand_data->devsize); + 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); err = gpmc_cs_set_timings(gpmc_nand_data->cs, &t); diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c index 3a7d25fb00ef..d776ded9830d 100644 --- a/arch/arm/mach-omap2/gpmc-onenand.c +++ b/arch/arm/mach-omap2/gpmc-onenand.c @@ -94,7 +94,7 @@ static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base) } static void set_onenand_cfg(void __iomem *onenand_base, int latency, - int sync_read, int sync_write, int hf) + int sync_read, int sync_write, int hf, int vhf) { u32 reg; @@ -114,12 +114,57 @@ static void set_onenand_cfg(void __iomem *onenand_base, int latency, reg |= ONENAND_SYS_CFG1_HF; else reg &= ~ONENAND_SYS_CFG1_HF; + if (vhf) + reg |= ONENAND_SYS_CFG1_VHF; + else + reg &= ~ONENAND_SYS_CFG1_VHF; writew(reg, onenand_base + ONENAND_REG_SYS_CFG1); } +static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg, + void __iomem *onenand_base, bool *clk_dep) +{ + u16 ver = readw(onenand_base + ONENAND_REG_VERSION_ID); + int freq = 0; + + if (cfg->get_freq) { + struct onenand_freq_info fi; + + fi.maf_id = readw(onenand_base + ONENAND_REG_MANUFACTURER_ID); + fi.dev_id = readw(onenand_base + ONENAND_REG_DEVICE_ID); + fi.ver_id = ver; + freq = cfg->get_freq(&fi, clk_dep); + if (freq) + return freq; + } + + switch ((ver >> 4) & 0xf) { + case 0: + freq = 40; + break; + case 1: + freq = 54; + break; + case 2: + freq = 66; + break; + case 3: + freq = 83; + break; + case 4: + freq = 104; + break; + default: + freq = 54; + break; + } + + return freq; +} + static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg, void __iomem *onenand_base, - int freq) + int *freq_ptr) { struct gpmc_timings t; const int t_cer = 15; @@ -130,10 +175,11 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg, const int t_wph = 30; int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo; int tick_ns, div, fclk_offset_ns, fclk_offset, gpmc_clk_ns, latency; - int first_time = 0, hf = 0, sync_read = 0, sync_write = 0; + int first_time = 0, hf = 0, vhf = 0, sync_read = 0, sync_write = 0; int err, ticks_cez; - int cs = cfg->cs; + int cs = cfg->cs, freq = *freq_ptr; u32 reg; + bool clk_dep = false; if (cfg->flags & ONENAND_SYNC_READ) { sync_read = 1; @@ -148,27 +194,7 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg, err = omap2_onenand_set_async_mode(cs, onenand_base); if (err) return err; - reg = readw(onenand_base + ONENAND_REG_VERSION_ID); - switch ((reg >> 4) & 0xf) { - case 0: - freq = 40; - break; - case 1: - freq = 54; - break; - case 2: - freq = 66; - break; - case 3: - freq = 83; - break; - case 4: - freq = 104; - break; - default: - freq = 54; - break; - } + freq = omap2_onenand_get_freq(cfg, onenand_base, &clk_dep); first_time = 1; } @@ -180,7 +206,7 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg, t_avdh = 2; t_ach = 3; t_aavdh = 6; - t_rdyo = 9; + t_rdyo = 6; break; case 83: min_gpmc_clk_period = 12000; /* 83 MHz */ @@ -217,16 +243,36 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg, gpmc_clk_ns = gpmc_ticks_to_ns(div); if (gpmc_clk_ns < 15) /* >66Mhz */ hf = 1; - if (hf) + if (gpmc_clk_ns < 12) /* >83Mhz */ + vhf = 1; + if (vhf) + latency = 8; + else if (hf) latency = 6; else if (gpmc_clk_ns >= 25) /* 40 MHz*/ latency = 3; else latency = 4; + if (clk_dep) { + if (gpmc_clk_ns < 12) { /* >83Mhz */ + t_ces = 3; + t_avds = 4; + } else if (gpmc_clk_ns < 15) { /* >66Mhz */ + t_ces = 5; + t_avds = 4; + } else if (gpmc_clk_ns < 25) { /* >40Mhz */ + t_ces = 6; + t_avds = 5; + } else { + t_ces = 7; + t_avds = 7; + } + } + if (first_time) set_onenand_cfg(onenand_base, latency, - sync_read, sync_write, hf); + sync_read, sync_write, hf, vhf); if (div == 1) { reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2); @@ -264,6 +310,9 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg, /* Read */ t.adv_rd_off = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_avdh)); t.oe_on = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_ach)); + /* Force at least 1 clk between AVD High to OE Low */ + if (t.oe_on <= t.adv_rd_off) + t.oe_on = t.adv_rd_off + gpmc_round_ns_to_ticks(1); t.access = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div); t.oe_off = t.access + gpmc_round_ns_to_ticks(1); t.cs_rd_off = t.oe_off; @@ -317,18 +366,20 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg, if (err) return err; - set_onenand_cfg(onenand_base, latency, sync_read, sync_write, hf); + set_onenand_cfg(onenand_base, latency, sync_read, sync_write, hf, vhf); + + *freq_ptr = freq; return 0; } -static int gpmc_onenand_setup(void __iomem *onenand_base, int freq) +static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr) { struct device *dev = &gpmc_onenand_device.dev; /* Set sync timings in GPMC */ if (omap2_onenand_set_sync_mode(gpmc_onenand_data, onenand_base, - freq) < 0) { + freq_ptr) < 0) { dev_err(dev, "Unable to set synchronous mode\n"); return -EINVAL; } diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 1b7b3e7d02f7..674174365f78 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -14,6 +14,7 @@ */ #undef DEBUG +#include <linux/irq.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/err.h> @@ -22,6 +23,7 @@ #include <linux/spinlock.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/interrupt.h> #include <asm/mach-types.h> #include <plat/gpmc.h> @@ -58,7 +60,6 @@ #define GPMC_CHUNK_SHIFT 24 /* 16 MB */ #define GPMC_SECTION_SHIFT 28 /* 128 MB */ -#define PREFETCH_FIFOTHRESHOLD (0x40 << 8) #define CS_NUM_SHIFT 24 #define ENABLE_PREFETCH (0x1 << 7) #define DMA_MPU_MODE 2 @@ -100,6 +101,8 @@ static void __iomem *gpmc_base; static struct clk *gpmc_l3_clk; +static irqreturn_t gpmc_handle_irq(int irq, void *dev); + static void gpmc_write_reg(int idx, u32 val) { __raw_writel(val, gpmc_base + idx); @@ -497,6 +500,10 @@ int gpmc_cs_configure(int cs, int cmd, int wval) u32 regval = 0; switch (cmd) { + case GPMC_ENABLE_IRQ: + gpmc_write_reg(GPMC_IRQENABLE, wval); + break; + case GPMC_SET_IRQ_STATUS: gpmc_write_reg(GPMC_IRQSTATUS, wval); break; @@ -598,15 +605,19 @@ EXPORT_SYMBOL(gpmc_nand_write); /** * gpmc_prefetch_enable - configures and starts prefetch transfer * @cs: cs (chip select) number + * @fifo_th: fifo threshold to be used for read/ write * @dma_mode: dma mode enable (1) or disable (0) * @u32_count: number of bytes to be transferred * @is_write: prefetch read(0) or write post(1) mode */ -int gpmc_prefetch_enable(int cs, int dma_mode, +int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write) { - if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { + if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) { + pr_err("gpmc: fifo threshold is not supported\n"); + return -1; + } else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { /* Set the amount of bytes to be prefetched */ gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); @@ -614,7 +625,7 @@ int gpmc_prefetch_enable(int cs, int dma_mode, * enable the engine. Set which cs is has requested for. */ gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) | - PREFETCH_FIFOTHRESHOLD | + PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH | (dma_mode << DMA_MPU_MODE) | (0x1 & is_write))); @@ -678,9 +689,10 @@ static void __init gpmc_mem_init(void) } } -void __init gpmc_init(void) +static int __init gpmc_init(void) { - u32 l; + u32 l, irq; + int cs, ret = -EINVAL; char *ck = NULL; if (cpu_is_omap24xx()) { @@ -698,7 +710,7 @@ void __init gpmc_init(void) } if (WARN_ON(!ck)) - return; + return ret; gpmc_l3_clk = clk_get(NULL, ck); if (IS_ERR(gpmc_l3_clk)) { @@ -723,6 +735,36 @@ void __init gpmc_init(void) l |= (0x02 << 3) | (1 << 0); gpmc_write_reg(GPMC_SYSCONFIG, l); gpmc_mem_init(); + + /* initalize the irq_chained */ + irq = OMAP_GPMC_IRQ_BASE; + for (cs = 0; cs < GPMC_CS_NUM; cs++) { + set_irq_handler(irq, handle_simple_irq); + set_irq_flags(irq, IRQF_VALID); + irq++; + } + + ret = request_irq(INT_34XX_GPMC_IRQ, + gpmc_handle_irq, IRQF_SHARED, "gpmc", gpmc_base); + if (ret) + pr_err("gpmc: irq-%d could not claim: err %d\n", + INT_34XX_GPMC_IRQ, ret); + return ret; +} +postcore_initcall(gpmc_init); + +static irqreturn_t gpmc_handle_irq(int irq, void *dev) +{ + u8 cs; + + if (irq != INT_34XX_GPMC_IRQ) + return IRQ_HANDLED; + /* check cs to invoke the irq */ + cs = ((gpmc_read_reg(GPMC_PREFETCH_CONFIG1)) >> CS_NUM_SHIFT) & 0x7; + if (OMAP_GPMC_IRQ_BASE+cs <= OMAP_GPMC_IRQ_END) + generic_handle_irq(OMAP_GPMC_IRQ_BASE+cs); + + return IRQ_HANDLED; } #ifdef CONFIG_ARCH_OMAP3 diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 34272e4863fd..5496bc7d40ad 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -350,6 +350,11 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) mmc->slots[0].after_set_reg = NULL; } break; + case 4: + case 5: + mmc->slots[0].before_set_reg = NULL; + mmc->slots[0].after_set_reg = NULL; + break; default: pr_err("MMC%d configuration not supported!\n", c->mmc); kfree(mmc); diff --git a/arch/arm/mach-omap2/hwspinlock.c b/arch/arm/mach-omap2/hwspinlock.c new file mode 100644 index 000000000000..06d4a80660a5 --- /dev/null +++ b/arch/arm/mach-omap2/hwspinlock.c @@ -0,0 +1,63 @@ +/* + * OMAP hardware spinlock device initialization + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com + * + * Contact: Simon Que <sque@ti.com> + * Hari Kanigeri <h-kanigeri2@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/err.h> + +#include <plat/omap_hwmod.h> +#include <plat/omap_device.h> + +struct omap_device_pm_latency omap_spinlock_latency[] = { + { + .deactivate_func = omap_device_idle_hwmods, + .activate_func = omap_device_enable_hwmods, + .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, + } +}; + +int __init hwspinlocks_init(void) +{ + int retval = 0; + struct omap_hwmod *oh; + struct omap_device *od; + const char *oh_name = "spinlock"; + const char *dev_name = "omap_hwspinlock"; + + /* + * Hwmod lookup will fail in case our platform doesn't support the + * hardware spinlock module, so it is safe to run this initcall + * on all omaps + */ + oh = omap_hwmod_lookup(oh_name); + if (oh == NULL) + return -EINVAL; + + od = omap_device_build(dev_name, 0, oh, NULL, 0, + omap_spinlock_latency, + ARRAY_SIZE(omap_spinlock_latency), false); + if (IS_ERR(od)) { + pr_err("Can't build omap_device for %s:%s\n", dev_name, + oh_name); + retval = PTR_ERR(od); + } + + return retval; +} +/* early board code might need to reserve specific hwspinlock instances */ +postcore_initcall(hwspinlocks_init); diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index b8b49e4ae928..657f3c84687c 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -30,7 +30,6 @@ #include <plat/sram.h> #include <plat/sdrc.h> -#include <plat/gpmc.h> #include <plat/serial.h> #include "clock2xxx.h" @@ -422,7 +421,6 @@ void __init omap2_init_common_devices(struct omap_sdrc_params *sdrc_cs0, omap2_sdrc_init(sdrc_cs0, sdrc_cs1); _omap2_init_reprogram_sdrc(); } - gpmc_init(); omap_irq_base_init(); } diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index b85c630b64d6..7fffd340c76f 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -18,6 +18,7 @@ #include <plat/serial.h> #include <plat/i2c.h> #include <plat/gpio.h> +#include <plat/mcspi.h> #include "omap_hwmod_common_data.h" @@ -44,6 +45,8 @@ static struct omap_hwmod omap2420_gpio2_hwmod; static struct omap_hwmod omap2420_gpio3_hwmod; static struct omap_hwmod omap2420_gpio4_hwmod; static struct omap_hwmod omap2420_dma_system_hwmod; +static struct omap_hwmod omap2420_mcspi1_hwmod; +static struct omap_hwmod omap2420_mcspi2_hwmod; /* L3 -> L4_CORE interface */ static struct omap_hwmod_ocp_if omap2420_l3_main__l4_core = { @@ -88,6 +91,42 @@ static struct omap_hwmod omap2420_uart3_hwmod; static struct omap_hwmod omap2420_i2c1_hwmod; static struct omap_hwmod omap2420_i2c2_hwmod; +/* l4 core -> mcspi1 interface */ +static struct omap_hwmod_addr_space omap2420_mcspi1_addr_space[] = { + { + .pa_start = 0x48098000, + .pa_end = 0x480980ff, + .flags = ADDR_TYPE_RT, + }, +}; + +static struct omap_hwmod_ocp_if omap2420_l4_core__mcspi1 = { + .master = &omap2420_l4_core_hwmod, + .slave = &omap2420_mcspi1_hwmod, + .clk = "mcspi1_ick", + .addr = omap2420_mcspi1_addr_space, + .addr_cnt = ARRAY_SIZE(omap2420_mcspi1_addr_space), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 core -> mcspi2 interface */ +static struct omap_hwmod_addr_space omap2420_mcspi2_addr_space[] = { + { + .pa_start = 0x4809a000, + .pa_end = 0x4809a0ff, + .flags = ADDR_TYPE_RT, + }, +}; + +static struct omap_hwmod_ocp_if omap2420_l4_core__mcspi2 = { + .master = &omap2420_l4_core_hwmod, + .slave = &omap2420_mcspi2_hwmod, + .clk = "mcspi2_ick", + .addr = omap2420_mcspi2_addr_space, + .addr_cnt = ARRAY_SIZE(omap2420_mcspi2_addr_space), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* L4_CORE -> L4_WKUP interface */ static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = { .master = &omap2420_l4_core_hwmod, @@ -864,6 +903,119 @@ static struct omap_hwmod omap2420_dma_system_hwmod = { .flags = HWMOD_NO_IDLEST, }; +/* + * 'mcspi' class + * multichannel serial port interface (mcspi) / master/slave synchronous serial + * bus + */ + +static struct omap_hwmod_class_sysconfig omap2420_mcspi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap2420_mcspi_class = { + .name = "mcspi", + .sysc = &omap2420_mcspi_sysc, + .rev = OMAP2_MCSPI_REV, +}; + +/* mcspi1 */ +static struct omap_hwmod_irq_info omap2420_mcspi1_mpu_irqs[] = { + { .irq = 65 }, +}; + +static struct omap_hwmod_dma_info omap2420_mcspi1_sdma_reqs[] = { + { .name = "tx0", .dma_req = 35 }, /* DMA_SPI1_TX0 */ + { .name = "rx0", .dma_req = 36 }, /* DMA_SPI1_RX0 */ + { .name = "tx1", .dma_req = 37 }, /* DMA_SPI1_TX1 */ + { .name = "rx1", .dma_req = 38 }, /* DMA_SPI1_RX1 */ + { .name = "tx2", .dma_req = 39 }, /* DMA_SPI1_TX2 */ + { .name = "rx2", .dma_req = 40 }, /* DMA_SPI1_RX2 */ + { .name = "tx3", .dma_req = 41 }, /* DMA_SPI1_TX3 */ + { .name = "rx3", .dma_req = 42 }, /* DMA_SPI1_RX3 */ +}; + +static struct omap_hwmod_ocp_if *omap2420_mcspi1_slaves[] = { + &omap2420_l4_core__mcspi1, +}; + +static struct omap2_mcspi_dev_attr omap_mcspi1_dev_attr = { + .num_chipselect = 4, +}; + +static struct omap_hwmod omap2420_mcspi1_hwmod = { + .name = "mcspi1_hwmod", + .mpu_irqs = omap2420_mcspi1_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap2420_mcspi1_mpu_irqs), + .sdma_reqs = omap2420_mcspi1_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap2420_mcspi1_sdma_reqs), + .main_clk = "mcspi1_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_MCSPI1_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_MCSPI1_SHIFT, + }, + }, + .slaves = omap2420_mcspi1_slaves, + .slaves_cnt = ARRAY_SIZE(omap2420_mcspi1_slaves), + .class = &omap2420_mcspi_class, + .dev_attr = &omap_mcspi1_dev_attr, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), +}; + +/* mcspi2 */ +static struct omap_hwmod_irq_info omap2420_mcspi2_mpu_irqs[] = { + { .irq = 66 }, +}; + +static struct omap_hwmod_dma_info omap2420_mcspi2_sdma_reqs[] = { + { .name = "tx0", .dma_req = 43 }, /* DMA_SPI2_TX0 */ + { .name = "rx0", .dma_req = 44 }, /* DMA_SPI2_RX0 */ + { .name = "tx1", .dma_req = 45 }, /* DMA_SPI2_TX1 */ + { .name = "rx1", .dma_req = 46 }, /* DMA_SPI2_RX1 */ +}; + +static struct omap_hwmod_ocp_if *omap2420_mcspi2_slaves[] = { + &omap2420_l4_core__mcspi2, +}; + +static struct omap2_mcspi_dev_attr omap_mcspi2_dev_attr = { + .num_chipselect = 2, +}; + +static struct omap_hwmod omap2420_mcspi2_hwmod = { + .name = "mcspi2_hwmod", + .mpu_irqs = omap2420_mcspi2_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap2420_mcspi2_mpu_irqs), + .sdma_reqs = omap2420_mcspi2_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap2420_mcspi2_sdma_reqs), + .main_clk = "mcspi2_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_MCSPI2_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_MCSPI2_SHIFT, + }, + }, + .slaves = omap2420_mcspi2_slaves, + .slaves_cnt = ARRAY_SIZE(omap2420_mcspi2_slaves), + .class = &omap2420_mcspi_class, + .dev_attr = &omap_mcspi2_dev_attr, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), +}; + static __initdata struct omap_hwmod *omap2420_hwmods[] = { &omap2420_l3_main_hwmod, &omap2420_l4_core_hwmod, @@ -885,6 +1037,10 @@ static __initdata struct omap_hwmod *omap2420_hwmods[] = { /* dma_system class*/ &omap2420_dma_system_hwmod, + + /* mcspi class */ + &omap2420_mcspi1_hwmod, + &omap2420_mcspi2_hwmod, NULL, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index 8ecfbcde13ba..7ba688a1c840 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -18,6 +18,7 @@ #include <plat/serial.h> #include <plat/i2c.h> #include <plat/gpio.h> +#include <plat/mcspi.h> #include "omap_hwmod_common_data.h" @@ -45,6 +46,9 @@ static struct omap_hwmod omap2430_gpio3_hwmod; static struct omap_hwmod omap2430_gpio4_hwmod; static struct omap_hwmod omap2430_gpio5_hwmod; static struct omap_hwmod omap2430_dma_system_hwmod; +static struct omap_hwmod omap2430_mcspi1_hwmod; +static struct omap_hwmod omap2430_mcspi2_hwmod; +static struct omap_hwmod omap2430_mcspi3_hwmod; /* L3 -> L4_CORE interface */ static struct omap_hwmod_ocp_if omap2430_l3_main__l4_core = { @@ -89,6 +93,16 @@ static struct omap_hwmod omap2430_uart3_hwmod; static struct omap_hwmod omap2430_i2c1_hwmod; static struct omap_hwmod omap2430_i2c2_hwmod; +static struct omap_hwmod omap2430_usbhsotg_hwmod; + +/* l3_core -> usbhsotg interface */ +static struct omap_hwmod_ocp_if omap2430_usbhsotg__l3 = { + .master = &omap2430_usbhsotg_hwmod, + .slave = &omap2430_l3_main_hwmod, + .clk = "core_l3_ck", + .user = OCP_USER_MPU, +}; + /* I2C IP block address space length (in bytes) */ #define OMAP2_I2C_AS_LEN 128 @@ -189,6 +203,35 @@ static struct omap_hwmod_ocp_if omap2_l4_core__uart3 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* +* usbhsotg interface data +*/ +static struct omap_hwmod_addr_space omap2430_usbhsotg_addrs[] = { + { + .pa_start = OMAP243X_HS_BASE, + .pa_end = OMAP243X_HS_BASE + SZ_4K - 1, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_core ->usbhsotg interface */ +static struct omap_hwmod_ocp_if omap2430_l4_core__usbhsotg = { + .master = &omap2430_l4_core_hwmod, + .slave = &omap2430_usbhsotg_hwmod, + .clk = "usb_l4_ick", + .addr = omap2430_usbhsotg_addrs, + .addr_cnt = ARRAY_SIZE(omap2430_usbhsotg_addrs), + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if *omap2430_usbhsotg_masters[] = { + &omap2430_usbhsotg__l3, +}; + +static struct omap_hwmod_ocp_if *omap2430_usbhsotg_slaves[] = { + &omap2430_l4_core__usbhsotg, +}; + /* Slave interfaces on the L4_CORE interconnect */ static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = { &omap2430_l3_main__l4_core, @@ -223,6 +266,60 @@ static struct omap_hwmod_ocp_if *omap2430_l4_wkup_slaves[] = { static struct omap_hwmod_ocp_if *omap2430_l4_wkup_masters[] = { }; +/* l4 core -> mcspi1 interface */ +static struct omap_hwmod_addr_space omap2430_mcspi1_addr_space[] = { + { + .pa_start = 0x48098000, + .pa_end = 0x480980ff, + .flags = ADDR_TYPE_RT, + }, +}; + +static struct omap_hwmod_ocp_if omap2430_l4_core__mcspi1 = { + .master = &omap2430_l4_core_hwmod, + .slave = &omap2430_mcspi1_hwmod, + .clk = "mcspi1_ick", + .addr = omap2430_mcspi1_addr_space, + .addr_cnt = ARRAY_SIZE(omap2430_mcspi1_addr_space), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 core -> mcspi2 interface */ +static struct omap_hwmod_addr_space omap2430_mcspi2_addr_space[] = { + { + .pa_start = 0x4809a000, + .pa_end = 0x4809a0ff, + .flags = ADDR_TYPE_RT, + }, +}; + +static struct omap_hwmod_ocp_if omap2430_l4_core__mcspi2 = { + .master = &omap2430_l4_core_hwmod, + .slave = &omap2430_mcspi2_hwmod, + .clk = "mcspi2_ick", + .addr = omap2430_mcspi2_addr_space, + .addr_cnt = ARRAY_SIZE(omap2430_mcspi2_addr_space), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 core -> mcspi3 interface */ +static struct omap_hwmod_addr_space omap2430_mcspi3_addr_space[] = { + { + .pa_start = 0x480b8000, + .pa_end = 0x480b80ff, + .flags = ADDR_TYPE_RT, + }, +}; + +static struct omap_hwmod_ocp_if omap2430_l4_core__mcspi3 = { + .master = &omap2430_l4_core_hwmod, + .slave = &omap2430_mcspi3_hwmod, + .clk = "mcspi3_ick", + .addr = omap2430_mcspi3_addr_space, + .addr_cnt = ARRAY_SIZE(omap2430_mcspi3_addr_space), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* L4 WKUP */ static struct omap_hwmod omap2430_l4_wkup_hwmod = { .name = "l4_wkup", @@ -919,6 +1016,220 @@ static struct omap_hwmod omap2430_dma_system_hwmod = { .flags = HWMOD_NO_IDLEST, }; +/* + * 'mcspi' class + * multichannel serial port interface (mcspi) / master/slave synchronous serial + * bus + */ + +static struct omap_hwmod_class_sysconfig omap2430_mcspi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap2430_mcspi_class = { + .name = "mcspi", + .sysc = &omap2430_mcspi_sysc, + .rev = OMAP2_MCSPI_REV, +}; + +/* mcspi1 */ +static struct omap_hwmod_irq_info omap2430_mcspi1_mpu_irqs[] = { + { .irq = 65 }, +}; + +static struct omap_hwmod_dma_info omap2430_mcspi1_sdma_reqs[] = { + { .name = "tx0", .dma_req = 35 }, /* DMA_SPI1_TX0 */ + { .name = "rx0", .dma_req = 36 }, /* DMA_SPI1_RX0 */ + { .name = "tx1", .dma_req = 37 }, /* DMA_SPI1_TX1 */ + { .name = "rx1", .dma_req = 38 }, /* DMA_SPI1_RX1 */ + { .name = "tx2", .dma_req = 39 }, /* DMA_SPI1_TX2 */ + { .name = "rx2", .dma_req = 40 }, /* DMA_SPI1_RX2 */ + { .name = "tx3", .dma_req = 41 }, /* DMA_SPI1_TX3 */ + { .name = "rx3", .dma_req = 42 }, /* DMA_SPI1_RX3 */ +}; + +static struct omap_hwmod_ocp_if *omap2430_mcspi1_slaves[] = { + &omap2430_l4_core__mcspi1, +}; + +static struct omap2_mcspi_dev_attr omap_mcspi1_dev_attr = { + .num_chipselect = 4, +}; + +static struct omap_hwmod omap2430_mcspi1_hwmod = { + .name = "mcspi1_hwmod", + .mpu_irqs = omap2430_mcspi1_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcspi1_mpu_irqs), + .sdma_reqs = omap2430_mcspi1_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcspi1_sdma_reqs), + .main_clk = "mcspi1_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_MCSPI1_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_MCSPI1_SHIFT, + }, + }, + .slaves = omap2430_mcspi1_slaves, + .slaves_cnt = ARRAY_SIZE(omap2430_mcspi1_slaves), + .class = &omap2430_mcspi_class, + .dev_attr = &omap_mcspi1_dev_attr, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), +}; + +/* mcspi2 */ +static struct omap_hwmod_irq_info omap2430_mcspi2_mpu_irqs[] = { + { .irq = 66 }, +}; + +static struct omap_hwmod_dma_info omap2430_mcspi2_sdma_reqs[] = { + { .name = "tx0", .dma_req = 43 }, /* DMA_SPI2_TX0 */ + { .name = "rx0", .dma_req = 44 }, /* DMA_SPI2_RX0 */ + { .name = "tx1", .dma_req = 45 }, /* DMA_SPI2_TX1 */ + { .name = "rx1", .dma_req = 46 }, /* DMA_SPI2_RX1 */ +}; + +static struct omap_hwmod_ocp_if *omap2430_mcspi2_slaves[] = { + &omap2430_l4_core__mcspi2, +}; + +static struct omap2_mcspi_dev_attr omap_mcspi2_dev_attr = { + .num_chipselect = 2, +}; + +static struct omap_hwmod omap2430_mcspi2_hwmod = { + .name = "mcspi2_hwmod", + .mpu_irqs = omap2430_mcspi2_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcspi2_mpu_irqs), + .sdma_reqs = omap2430_mcspi2_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcspi2_sdma_reqs), + .main_clk = "mcspi2_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_MCSPI2_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_MCSPI2_SHIFT, + }, + }, + .slaves = omap2430_mcspi2_slaves, + .slaves_cnt = ARRAY_SIZE(omap2430_mcspi2_slaves), + .class = &omap2430_mcspi_class, + .dev_attr = &omap_mcspi2_dev_attr, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), +}; + +/* mcspi3 */ +static struct omap_hwmod_irq_info omap2430_mcspi3_mpu_irqs[] = { + { .irq = 91 }, +}; + +static struct omap_hwmod_dma_info omap2430_mcspi3_sdma_reqs[] = { + { .name = "tx0", .dma_req = 15 }, /* DMA_SPI3_TX0 */ + { .name = "rx0", .dma_req = 16 }, /* DMA_SPI3_RX0 */ + { .name = "tx1", .dma_req = 23 }, /* DMA_SPI3_TX1 */ + { .name = "rx1", .dma_req = 24 }, /* DMA_SPI3_RX1 */ +}; + +static struct omap_hwmod_ocp_if *omap2430_mcspi3_slaves[] = { + &omap2430_l4_core__mcspi3, +}; + +static struct omap2_mcspi_dev_attr omap_mcspi3_dev_attr = { + .num_chipselect = 2, +}; + +static struct omap_hwmod omap2430_mcspi3_hwmod = { + .name = "mcspi3_hwmod", + .mpu_irqs = omap2430_mcspi3_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcspi3_mpu_irqs), + .sdma_reqs = omap2430_mcspi3_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcspi3_sdma_reqs), + .main_clk = "mcspi3_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 2, + .module_bit = OMAP2430_EN_MCSPI3_SHIFT, + .idlest_reg_id = 2, + .idlest_idle_bit = OMAP2430_ST_MCSPI3_SHIFT, + }, + }, + .slaves = omap2430_mcspi3_slaves, + .slaves_cnt = ARRAY_SIZE(omap2430_mcspi3_slaves), + .class = &omap2430_mcspi_class, + .dev_attr = &omap_mcspi3_dev_attr, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), +}; + +/* + * usbhsotg + */ +static struct omap_hwmod_class_sysconfig omap2430_usbhsotg_sysc = { + .rev_offs = 0x0400, + .sysc_offs = 0x0404, + .syss_offs = 0x0408, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE| + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class usbotg_class = { + .name = "usbotg", + .sysc = &omap2430_usbhsotg_sysc, +}; + +/* usb_otg_hs */ +static struct omap_hwmod_irq_info omap2430_usbhsotg_mpu_irqs[] = { + + { .name = "mc", .irq = 92 }, + { .name = "dma", .irq = 93 }, +}; + +static struct omap_hwmod omap2430_usbhsotg_hwmod = { + .name = "usb_otg_hs", + .mpu_irqs = omap2430_usbhsotg_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap2430_usbhsotg_mpu_irqs), + .main_clk = "usbhs_ick", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP2430_EN_USBHS_MASK, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP2430_ST_USBHS_SHIFT, + }, + }, + .masters = omap2430_usbhsotg_masters, + .masters_cnt = ARRAY_SIZE(omap2430_usbhsotg_masters), + .slaves = omap2430_usbhsotg_slaves, + .slaves_cnt = ARRAY_SIZE(omap2430_usbhsotg_slaves), + .class = &usbotg_class, + /* + * Erratum ID: i479 idle_req / idle_ack mechanism potentially + * broken when autoidle is enabled + * workaround is to disable the autoidle bit at module level. + */ + .flags = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE + | HWMOD_SWSUP_MSTANDBY, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) +}; + + + static __initdata struct omap_hwmod *omap2430_hwmods[] = { &omap2430_l3_main_hwmod, &omap2430_l4_core_hwmod, @@ -941,6 +1252,15 @@ static __initdata struct omap_hwmod *omap2430_hwmods[] = { /* dma_system class*/ &omap2430_dma_system_hwmod, + + /* mcspi class */ + &omap2430_mcspi1_hwmod, + &omap2430_mcspi2_hwmod, + &omap2430_mcspi3_hwmod, + + /* usbotg class*/ + &omap2430_usbhsotg_hwmod, + NULL, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 8d8181334f86..879f55f272e2 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -22,12 +22,14 @@ #include <plat/i2c.h> #include <plat/gpio.h> #include <plat/smartreflex.h> +#include <plat/mcspi.h> #include "omap_hwmod_common_data.h" #include "prm-regbits-34xx.h" #include "cm-regbits-34xx.h" #include "wd_timer.h" +#include <mach/am35xx.h> /* * OMAP3xxx hardware module integration data @@ -55,6 +57,11 @@ static struct omap_hwmod omap3xxx_gpio5_hwmod; static struct omap_hwmod omap3xxx_gpio6_hwmod; static struct omap_hwmod omap34xx_sr1_hwmod; static struct omap_hwmod omap34xx_sr2_hwmod; +static struct omap_hwmod omap34xx_mcspi1; +static struct omap_hwmod omap34xx_mcspi2; +static struct omap_hwmod omap34xx_mcspi3; +static struct omap_hwmod omap34xx_mcspi4; +static struct omap_hwmod am35xx_usbhsotg_hwmod; static struct omap_hwmod omap3xxx_dma_system_hwmod; @@ -107,7 +114,23 @@ static struct omap_hwmod omap3xxx_uart1_hwmod; static struct omap_hwmod omap3xxx_uart2_hwmod; static struct omap_hwmod omap3xxx_uart3_hwmod; static struct omap_hwmod omap3xxx_uart4_hwmod; +static struct omap_hwmod omap3xxx_usbhsotg_hwmod; +/* l3_core -> usbhsotg interface */ +static struct omap_hwmod_ocp_if omap3xxx_usbhsotg__l3 = { + .master = &omap3xxx_usbhsotg_hwmod, + .slave = &omap3xxx_l3_main_hwmod, + .clk = "core_l3_ick", + .user = OCP_USER_MPU, +}; + +/* l3_core -> am35xx_usbhsotg interface */ +static struct omap_hwmod_ocp_if am35xx_usbhsotg__l3 = { + .master = &am35xx_usbhsotg_hwmod, + .slave = &omap3xxx_l3_main_hwmod, + .clk = "core_l3_ick", + .user = OCP_USER_MPU, +}; /* L4_CORE -> L4_WKUP interface */ static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = { .master = &omap3xxx_l4_core_hwmod, @@ -301,6 +324,61 @@ static struct omap_hwmod_ocp_if omap3_l4_core__sr2 = { .user = OCP_USER_MPU, }; +/* +* usbhsotg interface data +*/ + +static struct omap_hwmod_addr_space omap3xxx_usbhsotg_addrs[] = { + { + .pa_start = OMAP34XX_HSUSB_OTG_BASE, + .pa_end = OMAP34XX_HSUSB_OTG_BASE + SZ_4K - 1, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_core -> usbhsotg */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__usbhsotg = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_usbhsotg_hwmod, + .clk = "l4_ick", + .addr = omap3xxx_usbhsotg_addrs, + .addr_cnt = ARRAY_SIZE(omap3xxx_usbhsotg_addrs), + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if *omap3xxx_usbhsotg_masters[] = { + &omap3xxx_usbhsotg__l3, +}; + +static struct omap_hwmod_ocp_if *omap3xxx_usbhsotg_slaves[] = { + &omap3xxx_l4_core__usbhsotg, +}; + +static struct omap_hwmod_addr_space am35xx_usbhsotg_addrs[] = { + { + .pa_start = AM35XX_IPSS_USBOTGSS_BASE, + .pa_end = AM35XX_IPSS_USBOTGSS_BASE + SZ_4K - 1, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_core -> usbhsotg */ +static struct omap_hwmod_ocp_if am35xx_l4_core__usbhsotg = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &am35xx_usbhsotg_hwmod, + .clk = "l4_ick", + .addr = am35xx_usbhsotg_addrs, + .addr_cnt = ARRAY_SIZE(am35xx_usbhsotg_addrs), + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_ocp_if *am35xx_usbhsotg_masters[] = { + &am35xx_usbhsotg__l3, +}; + +static struct omap_hwmod_ocp_if *am35xx_usbhsotg_slaves[] = { + &am35xx_l4_core__usbhsotg, +}; /* Slave interfaces on the L4_CORE interconnect */ static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = { &omap3xxx_l3_main__l4_core, @@ -1356,6 +1434,360 @@ static struct omap_hwmod omap36xx_sr2_hwmod = { .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1), }; +/* l4 core -> mcspi1 interface */ +static struct omap_hwmod_addr_space omap34xx_mcspi1_addr_space[] = { + { + .pa_start = 0x48098000, + .pa_end = 0x480980ff, + .flags = ADDR_TYPE_RT, + }, +}; + +static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi1 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap34xx_mcspi1, + .clk = "mcspi1_ick", + .addr = omap34xx_mcspi1_addr_space, + .addr_cnt = ARRAY_SIZE(omap34xx_mcspi1_addr_space), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 core -> mcspi2 interface */ +static struct omap_hwmod_addr_space omap34xx_mcspi2_addr_space[] = { + { + .pa_start = 0x4809a000, + .pa_end = 0x4809a0ff, + .flags = ADDR_TYPE_RT, + }, +}; + +static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi2 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap34xx_mcspi2, + .clk = "mcspi2_ick", + .addr = omap34xx_mcspi2_addr_space, + .addr_cnt = ARRAY_SIZE(omap34xx_mcspi2_addr_space), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 core -> mcspi3 interface */ +static struct omap_hwmod_addr_space omap34xx_mcspi3_addr_space[] = { + { + .pa_start = 0x480b8000, + .pa_end = 0x480b80ff, + .flags = ADDR_TYPE_RT, + }, +}; + +static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi3 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap34xx_mcspi3, + .clk = "mcspi3_ick", + .addr = omap34xx_mcspi3_addr_space, + .addr_cnt = ARRAY_SIZE(omap34xx_mcspi3_addr_space), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4 core -> mcspi4 interface */ +static struct omap_hwmod_addr_space omap34xx_mcspi4_addr_space[] = { + { + .pa_start = 0x480ba000, + .pa_end = 0x480ba0ff, + .flags = ADDR_TYPE_RT, + }, +}; + +static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi4 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap34xx_mcspi4, + .clk = "mcspi4_ick", + .addr = omap34xx_mcspi4_addr_space, + .addr_cnt = ARRAY_SIZE(omap34xx_mcspi4_addr_space), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* + * 'mcspi' class + * multichannel serial port interface (mcspi) / master/slave synchronous serial + * bus + */ + +static struct omap_hwmod_class_sysconfig omap34xx_mcspi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap34xx_mcspi_class = { + .name = "mcspi", + .sysc = &omap34xx_mcspi_sysc, + .rev = OMAP3_MCSPI_REV, +}; + +/* mcspi1 */ +static struct omap_hwmod_irq_info omap34xx_mcspi1_mpu_irqs[] = { + { .name = "irq", .irq = 65 }, +}; + +static struct omap_hwmod_dma_info omap34xx_mcspi1_sdma_reqs[] = { + { .name = "tx0", .dma_req = 35 }, + { .name = "rx0", .dma_req = 36 }, + { .name = "tx1", .dma_req = 37 }, + { .name = "rx1", .dma_req = 38 }, + { .name = "tx2", .dma_req = 39 }, + { .name = "rx2", .dma_req = 40 }, + { .name = "tx3", .dma_req = 41 }, + { .name = "rx3", .dma_req = 42 }, +}; + +static struct omap_hwmod_ocp_if *omap34xx_mcspi1_slaves[] = { + &omap34xx_l4_core__mcspi1, +}; + +static struct omap2_mcspi_dev_attr omap_mcspi1_dev_attr = { + .num_chipselect = 4, +}; + +static struct omap_hwmod omap34xx_mcspi1 = { + .name = "mcspi1", + .mpu_irqs = omap34xx_mcspi1_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_mcspi1_mpu_irqs), + .sdma_reqs = omap34xx_mcspi1_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap34xx_mcspi1_sdma_reqs), + .main_clk = "mcspi1_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MCSPI1_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MCSPI1_SHIFT, + }, + }, + .slaves = omap34xx_mcspi1_slaves, + .slaves_cnt = ARRAY_SIZE(omap34xx_mcspi1_slaves), + .class = &omap34xx_mcspi_class, + .dev_attr = &omap_mcspi1_dev_attr, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), +}; + +/* mcspi2 */ +static struct omap_hwmod_irq_info omap34xx_mcspi2_mpu_irqs[] = { + { .name = "irq", .irq = 66 }, +}; + +static struct omap_hwmod_dma_info omap34xx_mcspi2_sdma_reqs[] = { + { .name = "tx0", .dma_req = 43 }, + { .name = "rx0", .dma_req = 44 }, + { .name = "tx1", .dma_req = 45 }, + { .name = "rx1", .dma_req = 46 }, +}; + +static struct omap_hwmod_ocp_if *omap34xx_mcspi2_slaves[] = { + &omap34xx_l4_core__mcspi2, +}; + +static struct omap2_mcspi_dev_attr omap_mcspi2_dev_attr = { + .num_chipselect = 2, +}; + +static struct omap_hwmod omap34xx_mcspi2 = { + .name = "mcspi2", + .mpu_irqs = omap34xx_mcspi2_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_mcspi2_mpu_irqs), + .sdma_reqs = omap34xx_mcspi2_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap34xx_mcspi2_sdma_reqs), + .main_clk = "mcspi2_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MCSPI2_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MCSPI2_SHIFT, + }, + }, + .slaves = omap34xx_mcspi2_slaves, + .slaves_cnt = ARRAY_SIZE(omap34xx_mcspi2_slaves), + .class = &omap34xx_mcspi_class, + .dev_attr = &omap_mcspi2_dev_attr, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), +}; + +/* mcspi3 */ +static struct omap_hwmod_irq_info omap34xx_mcspi3_mpu_irqs[] = { + { .name = "irq", .irq = 91 }, /* 91 */ +}; + +static struct omap_hwmod_dma_info omap34xx_mcspi3_sdma_reqs[] = { + { .name = "tx0", .dma_req = 15 }, + { .name = "rx0", .dma_req = 16 }, + { .name = "tx1", .dma_req = 23 }, + { .name = "rx1", .dma_req = 24 }, +}; + +static struct omap_hwmod_ocp_if *omap34xx_mcspi3_slaves[] = { + &omap34xx_l4_core__mcspi3, +}; + +static struct omap2_mcspi_dev_attr omap_mcspi3_dev_attr = { + .num_chipselect = 2, +}; + +static struct omap_hwmod omap34xx_mcspi3 = { + .name = "mcspi3", + .mpu_irqs = omap34xx_mcspi3_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_mcspi3_mpu_irqs), + .sdma_reqs = omap34xx_mcspi3_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap34xx_mcspi3_sdma_reqs), + .main_clk = "mcspi3_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MCSPI3_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MCSPI3_SHIFT, + }, + }, + .slaves = omap34xx_mcspi3_slaves, + .slaves_cnt = ARRAY_SIZE(omap34xx_mcspi3_slaves), + .class = &omap34xx_mcspi_class, + .dev_attr = &omap_mcspi3_dev_attr, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), +}; + +/* SPI4 */ +static struct omap_hwmod_irq_info omap34xx_mcspi4_mpu_irqs[] = { + { .name = "irq", .irq = INT_34XX_SPI4_IRQ }, /* 48 */ +}; + +static struct omap_hwmod_dma_info omap34xx_mcspi4_sdma_reqs[] = { + { .name = "tx0", .dma_req = 70 }, /* DMA_SPI4_TX0 */ + { .name = "rx0", .dma_req = 71 }, /* DMA_SPI4_RX0 */ +}; + +static struct omap_hwmod_ocp_if *omap34xx_mcspi4_slaves[] = { + &omap34xx_l4_core__mcspi4, +}; + +static struct omap2_mcspi_dev_attr omap_mcspi4_dev_attr = { + .num_chipselect = 1, +}; + +static struct omap_hwmod omap34xx_mcspi4 = { + .name = "mcspi4", + .mpu_irqs = omap34xx_mcspi4_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_mcspi4_mpu_irqs), + .sdma_reqs = omap34xx_mcspi4_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap34xx_mcspi4_sdma_reqs), + .main_clk = "mcspi4_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_MCSPI4_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_MCSPI4_SHIFT, + }, + }, + .slaves = omap34xx_mcspi4_slaves, + .slaves_cnt = ARRAY_SIZE(omap34xx_mcspi4_slaves), + .class = &omap34xx_mcspi_class, + .dev_attr = &omap_mcspi4_dev_attr, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), +}; + +/* + * usbhsotg + */ +static struct omap_hwmod_class_sysconfig omap3xxx_usbhsotg_sysc = { + .rev_offs = 0x0400, + .sysc_offs = 0x0404, + .syss_offs = 0x0408, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE| + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class usbotg_class = { + .name = "usbotg", + .sysc = &omap3xxx_usbhsotg_sysc, +}; +/* usb_otg_hs */ +static struct omap_hwmod_irq_info omap3xxx_usbhsotg_mpu_irqs[] = { + + { .name = "mc", .irq = 92 }, + { .name = "dma", .irq = 93 }, +}; + +static struct omap_hwmod omap3xxx_usbhsotg_hwmod = { + .name = "usb_otg_hs", + .mpu_irqs = omap3xxx_usbhsotg_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_usbhsotg_mpu_irqs), + .main_clk = "hsotgusb_ick", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_HSOTGUSB_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT, + .idlest_stdby_bit = OMAP3430ES2_ST_HSOTGUSB_STDBY_SHIFT + }, + }, + .masters = omap3xxx_usbhsotg_masters, + .masters_cnt = ARRAY_SIZE(omap3xxx_usbhsotg_masters), + .slaves = omap3xxx_usbhsotg_slaves, + .slaves_cnt = ARRAY_SIZE(omap3xxx_usbhsotg_slaves), + .class = &usbotg_class, + + /* + * Erratum ID: i479 idle_req / idle_ack mechanism potentially + * broken when autoidle is enabled + * workaround is to disable the autoidle bit at module level. + */ + .flags = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE + | HWMOD_SWSUP_MSTANDBY, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) +}; + +/* usb_otg_hs */ +static struct omap_hwmod_irq_info am35xx_usbhsotg_mpu_irqs[] = { + + { .name = "mc", .irq = 71 }, +}; + +static struct omap_hwmod_class am35xx_usbotg_class = { + .name = "am35xx_usbotg", + .sysc = NULL, +}; + +static struct omap_hwmod am35xx_usbhsotg_hwmod = { + .name = "am35x_otg_hs", + .mpu_irqs = am35xx_usbhsotg_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(am35xx_usbhsotg_mpu_irqs), + .main_clk = NULL, + .prcm = { + .omap2 = { + }, + }, + .masters = am35xx_usbhsotg_masters, + .masters_cnt = ARRAY_SIZE(am35xx_usbhsotg_masters), + .slaves = am35xx_usbhsotg_slaves, + .slaves_cnt = ARRAY_SIZE(am35xx_usbhsotg_slaves), + .class = &am35xx_usbotg_class, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES3_1) +}; + static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { &omap3xxx_l3_main_hwmod, &omap3xxx_l4_core_hwmod, @@ -1387,6 +1819,19 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { /* dma_system class*/ &omap3xxx_dma_system_hwmod, + + /* mcspi class */ + &omap34xx_mcspi1, + &omap34xx_mcspi2, + &omap34xx_mcspi3, + &omap34xx_mcspi4, + + /* usbotg class */ + &omap3xxx_usbhsotg_hwmod, + + /* usbotg for am35x */ + &am35xx_usbhsotg_hwmod, + NULL, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 84e795cf0648..79a860178913 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -24,6 +24,7 @@ #include <plat/cpu.h> #include <plat/gpio.h> #include <plat/dma.h> +#include <plat/mcspi.h> #include "omap_hwmod_common_data.h" @@ -3114,6 +3115,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_mcspi_sysc = { static struct omap_hwmod_class omap44xx_mcspi_hwmod_class = { .name = "mcspi", .sysc = &omap44xx_mcspi_sysc, + .rev = OMAP4_MCSPI_REV, }; /* mcspi1 */ @@ -3156,6 +3158,11 @@ static struct omap_hwmod_ocp_if *omap44xx_mcspi1_slaves[] = { &omap44xx_l4_per__mcspi1, }; +/* mcspi1 dev_attr */ +static struct omap2_mcspi_dev_attr mcspi1_dev_attr = { + .num_chipselect = 4, +}; + static struct omap_hwmod omap44xx_mcspi1_hwmod = { .name = "mcspi1", .class = &omap44xx_mcspi_hwmod_class, @@ -3169,6 +3176,7 @@ static struct omap_hwmod omap44xx_mcspi1_hwmod = { .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI1_CLKCTRL, }, }, + .dev_attr = &mcspi1_dev_attr, .slaves = omap44xx_mcspi1_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_mcspi1_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -3210,6 +3218,11 @@ static struct omap_hwmod_ocp_if *omap44xx_mcspi2_slaves[] = { &omap44xx_l4_per__mcspi2, }; +/* mcspi2 dev_attr */ +static struct omap2_mcspi_dev_attr mcspi2_dev_attr = { + .num_chipselect = 2, +}; + static struct omap_hwmod omap44xx_mcspi2_hwmod = { .name = "mcspi2", .class = &omap44xx_mcspi_hwmod_class, @@ -3223,6 +3236,7 @@ static struct omap_hwmod omap44xx_mcspi2_hwmod = { .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI2_CLKCTRL, }, }, + .dev_attr = &mcspi2_dev_attr, .slaves = omap44xx_mcspi2_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_mcspi2_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -3264,6 +3278,11 @@ static struct omap_hwmod_ocp_if *omap44xx_mcspi3_slaves[] = { &omap44xx_l4_per__mcspi3, }; +/* mcspi3 dev_attr */ +static struct omap2_mcspi_dev_attr mcspi3_dev_attr = { + .num_chipselect = 2, +}; + static struct omap_hwmod omap44xx_mcspi3_hwmod = { .name = "mcspi3", .class = &omap44xx_mcspi_hwmod_class, @@ -3277,6 +3296,7 @@ static struct omap_hwmod omap44xx_mcspi3_hwmod = { .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI3_CLKCTRL, }, }, + .dev_attr = &mcspi3_dev_attr, .slaves = omap44xx_mcspi3_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_mcspi3_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -3316,6 +3336,11 @@ static struct omap_hwmod_ocp_if *omap44xx_mcspi4_slaves[] = { &omap44xx_l4_per__mcspi4, }; +/* mcspi4 dev_attr */ +static struct omap2_mcspi_dev_attr mcspi4_dev_attr = { + .num_chipselect = 1, +}; + static struct omap_hwmod omap44xx_mcspi4_hwmod = { .name = "mcspi4", .class = &omap44xx_mcspi_hwmod_class, @@ -3329,6 +3354,7 @@ static struct omap_hwmod omap44xx_mcspi4_hwmod = { .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI4_CLKCTRL, }, }, + .dev_attr = &mcspi4_dev_attr, .slaves = omap44xx_mcspi4_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_mcspi4_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -3963,6 +3989,7 @@ static struct omap_hwmod_ocp_if *omap44xx_timer1_slaves[] = { static struct omap_hwmod omap44xx_timer1_hwmod = { .name = "timer1", .class = &omap44xx_timer_1ms_hwmod_class, + .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, .mpu_irqs = omap44xx_timer1_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer1_irqs), .main_clk = "timer1_fck", diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c index 745252c60e32..f172ec06c06a 100644 --- a/arch/arm/mach-omap2/omap_phy_internal.c +++ b/arch/arm/mach-omap2/omap_phy_internal.c @@ -29,6 +29,7 @@ #include <linux/usb.h> #include <plat/usb.h> +#include "control.h" /* OMAP control module register for UTMI PHY */ #define CONTROL_DEV_CONF 0x300 @@ -147,3 +148,95 @@ int omap4430_phy_exit(struct device *dev) return 0; } + +void am35x_musb_reset(void) +{ + u32 regval; + + /* Reset the musb interface */ + regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); + + regval |= AM35XX_USBOTGSS_SW_RST; + omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET); + + regval &= ~AM35XX_USBOTGSS_SW_RST; + omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET); + + regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); +} + +void am35x_musb_phy_power(u8 on) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(100); + u32 devconf2; + + if (on) { + /* + * Start the on-chip PHY and its PLL. + */ + devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); + + devconf2 &= ~(CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN); + devconf2 |= CONF2_PHY_PLLON; + + omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); + + pr_info(KERN_INFO "Waiting for PHY clock good...\n"); + while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2) + & CONF2_PHYCLKGD)) { + cpu_relax(); + + if (time_after(jiffies, timeout)) { + pr_err(KERN_ERR "musb PHY clock good timed out\n"); + break; + } + } + } else { + /* + * Power down the on-chip PHY. + */ + devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); + + devconf2 &= ~CONF2_PHY_PLLON; + devconf2 |= CONF2_PHYPWRDN | CONF2_OTGPWRDN; + omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); + } +} + +void am35x_musb_clear_irq(void) +{ + u32 regval; + + regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); + regval |= AM35XX_USBOTGSS_INT_CLR; + omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR); + regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); +} + +void am35x_musb_set_mode(u8 musb_mode) +{ + u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); + + devconf2 &= ~CONF2_OTGMODE; + switch (musb_mode) { +#ifdef CONFIG_USB_MUSB_HDRC_HCD + case MUSB_HOST: /* Force VBUS valid, ID = 0 */ + devconf2 |= CONF2_FORCE_HOST; + break; +#endif +#ifdef CONFIG_USB_GADGET_MUSB_HDRC + case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */ + devconf2 |= CONF2_FORCE_DEVICE; + break; +#endif +#ifdef CONFIG_USB_MUSB_OTG + case MUSB_OTG: /* Don't override the VBUS/ID comparators */ + devconf2 |= CONF2_NO_OVERRIDE; + break; +#endif + default: + pr_info(KERN_INFO "Unsupported mode %u\n", musb_mode); + } + + omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); +} diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c index 5298949d4b11..a9d4d143086d 100644 --- a/arch/arm/mach-omap2/usb-musb.c +++ b/arch/arm/mach-omap2/usb-musb.c @@ -30,118 +30,11 @@ #include <mach/irqs.h> #include <mach/am35xx.h> #include <plat/usb.h> -#include "control.h" +#include <plat/omap_device.h> +#include "mux.h" #if defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined (CONFIG_USB_MUSB_AM35X) -static void am35x_musb_reset(void) -{ - u32 regval; - - /* Reset the musb interface */ - regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); - - regval |= AM35XX_USBOTGSS_SW_RST; - omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET); - - regval &= ~AM35XX_USBOTGSS_SW_RST; - omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET); - - regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); -} - -static void am35x_musb_phy_power(u8 on) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(100); - u32 devconf2; - - if (on) { - /* - * Start the on-chip PHY and its PLL. - */ - devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); - - devconf2 &= ~(CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN); - devconf2 |= CONF2_PHY_PLLON; - - omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); - - pr_info(KERN_INFO "Waiting for PHY clock good...\n"); - while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2) - & CONF2_PHYCLKGD)) { - cpu_relax(); - - if (time_after(jiffies, timeout)) { - pr_err(KERN_ERR "musb PHY clock good timed out\n"); - break; - } - } - } else { - /* - * Power down the on-chip PHY. - */ - devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); - - devconf2 &= ~CONF2_PHY_PLLON; - devconf2 |= CONF2_PHYPWRDN | CONF2_OTGPWRDN; - omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); - } -} - -static void am35x_musb_clear_irq(void) -{ - u32 regval; - - regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); - regval |= AM35XX_USBOTGSS_INT_CLR; - omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR); - regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); -} - -static void am35x_musb_set_mode(u8 musb_mode) -{ - u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); - - devconf2 &= ~CONF2_OTGMODE; - switch (musb_mode) { -#ifdef CONFIG_USB_MUSB_HDRC_HCD - case MUSB_HOST: /* Force VBUS valid, ID = 0 */ - devconf2 |= CONF2_FORCE_HOST; - break; -#endif -#ifdef CONFIG_USB_GADGET_MUSB_HDRC - case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */ - devconf2 |= CONF2_FORCE_DEVICE; - break; -#endif -#ifdef CONFIG_USB_MUSB_OTG - case MUSB_OTG: /* Don't override the VBUS/ID comparators */ - devconf2 |= CONF2_NO_OVERRIDE; - break; -#endif - default: - pr_info(KERN_INFO "Unsupported mode %u\n", musb_mode); - } - - omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); -} - -static struct resource musb_resources[] = { - [0] = { /* start and end set dynamically */ - .flags = IORESOURCE_MEM, - }, - [1] = { /* general IRQ */ - .start = INT_243X_HS_USB_MC, - .flags = IORESOURCE_IRQ, - .name = "mc", - }, - [2] = { /* DMA IRQ */ - .start = INT_243X_HS_USB_DMA, - .flags = IORESOURCE_IRQ, - .name = "dma", - }, -}; - static struct musb_hdrc_config musb_config = { .multipoint = 1, .dyn_fifo = 1, @@ -169,38 +62,65 @@ static struct musb_hdrc_platform_data musb_plat = { static u64 musb_dmamask = DMA_BIT_MASK(32); -static struct platform_device musb_device = { - .name = "musb-omap2430", - .id = -1, - .dev = { - .dma_mask = &musb_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &musb_plat, +static struct omap_device_pm_latency omap_musb_latency[] = { + { + .deactivate_func = omap_device_idle_hwmods, + .activate_func = omap_device_enable_hwmods, + .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, }, - .num_resources = ARRAY_SIZE(musb_resources), - .resource = musb_resources, }; +static void usb_musb_mux_init(struct omap_musb_board_data *board_data) +{ + switch (board_data->interface_type) { + case MUSB_INTERFACE_UTMI: + omap_mux_init_signal("usba0_otg_dp", OMAP_PIN_INPUT); + omap_mux_init_signal("usba0_otg_dm", OMAP_PIN_INPUT); + break; + case MUSB_INTERFACE_ULPI: + omap_mux_init_signal("usba0_ulpiphy_clk", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("usba0_ulpiphy_stp", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("usba0_ulpiphy_dir", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("usba0_ulpiphy_nxt", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("usba0_ulpiphy_dat0", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("usba0_ulpiphy_dat1", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("usba0_ulpiphy_dat2", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("usba0_ulpiphy_dat3", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("usba0_ulpiphy_dat4", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("usba0_ulpiphy_dat5", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("usba0_ulpiphy_dat6", + OMAP_PIN_INPUT_PULLDOWN); + omap_mux_init_signal("usba0_ulpiphy_dat7", + OMAP_PIN_INPUT_PULLDOWN); + break; + default: + break; + } +} + void __init usb_musb_init(struct omap_musb_board_data *board_data) { - if (cpu_is_omap243x()) { - musb_resources[0].start = OMAP243X_HS_BASE; - } else if (cpu_is_omap3517() || cpu_is_omap3505()) { - musb_device.name = "musb-am35x"; - musb_resources[0].start = AM35XX_IPSS_USBOTGSS_BASE; - musb_resources[1].start = INT_35XX_USBOTG_IRQ; - board_data->set_phy_power = am35x_musb_phy_power; - board_data->clear_irq = am35x_musb_clear_irq; - board_data->set_mode = am35x_musb_set_mode; - board_data->reset = am35x_musb_reset; - } else if (cpu_is_omap34xx()) { - musb_resources[0].start = OMAP34XX_HSUSB_OTG_BASE; + struct omap_hwmod *oh; + struct omap_device *od; + struct platform_device *pdev; + struct device *dev; + int bus_id = -1; + const char *oh_name, *name; + + if (cpu_is_omap3517() || cpu_is_omap3505()) { } else if (cpu_is_omap44xx()) { - musb_resources[0].start = OMAP44XX_HSUSB_OTG_BASE; - musb_resources[1].start = OMAP44XX_IRQ_HS_USB_MC_N; - musb_resources[2].start = OMAP44XX_IRQ_HS_USB_DMA_N; + usb_musb_mux_init(board_data); } - musb_resources[0].end = musb_resources[0].start + SZ_4K - 1; /* * REVISIT: This line can be removed once all the platforms using @@ -212,8 +132,35 @@ void __init usb_musb_init(struct omap_musb_board_data *board_data) musb_plat.mode = board_data->mode; musb_plat.extvbus = board_data->extvbus; - if (platform_device_register(&musb_device) < 0) - printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n"); + if (cpu_is_omap3517() || cpu_is_omap3505()) { + oh_name = "am35x_otg_hs"; + name = "musb-am35x"; + } else { + oh_name = "usb_otg_hs"; + name = "musb-omap2430"; + } + + oh = omap_hwmod_lookup(oh_name); + if (!oh) { + pr_err("Could not look up %s\n", oh_name); + return; + } + + od = omap_device_build(name, bus_id, oh, &musb_plat, + sizeof(musb_plat), omap_musb_latency, + ARRAY_SIZE(omap_musb_latency), false); + if (IS_ERR(od)) { + pr_err("Could not build omap_device for %s %s\n", + name, oh_name); + return; + } + + pdev = &od->pdev; + dev = &pdev->dev; + get_device(dev); + dev->dma_mask = &musb_dmamask; + dev->coherent_dma_mask = musb_dmamask; + put_device(dev); } #else diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 85ded598853e..12b316165037 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -41,6 +41,8 @@ #define GPMC_NAND_ADDRESS 0x0000000b #define GPMC_NAND_DATA 0x0000000c +#define GPMC_ENABLE_IRQ 0x0000000d + /* ECC commands */ #define GPMC_ECC_READ 0 /* Reset Hardware ECC for read */ #define GPMC_ECC_WRITE 1 /* Reset Hardware ECC for write */ @@ -78,6 +80,19 @@ #define WR_RD_PIN_MONITORING 0x00600000 #define GPMC_PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F) #define GPMC_PREFETCH_STATUS_COUNT(val) (val & 0x00003fff) +#define GPMC_IRQ_FIFOEVENTENABLE 0x01 +#define GPMC_IRQ_COUNT_EVENT 0x02 + +#define PREFETCH_FIFOTHRESHOLD_MAX 0x40 +#define PREFETCH_FIFOTHRESHOLD(val) ((val) << 8) + +enum omap_ecc { + /* 1-bit ecc: stored at end of spare area */ + OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */ + OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */ + /* 1-bit ecc: stored at begining of spare area as romcode */ + OMAP_ECC_HAMMING_CODE_HW_ROMCODE, /* gpmc method & romcode layout */ +}; /* * Note that all values in this struct are in nanoseconds except sync_clk @@ -130,12 +145,11 @@ 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 int gpmc_prefetch_enable(int cs, int dma_mode, +extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, unsigned int u32_count, int is_write); extern int gpmc_prefetch_reset(int cs); extern void omap3_gpmc_save_context(void); extern void omap3_gpmc_restore_context(void); -extern void gpmc_init(void); extern int gpmc_read_status(int cmd); extern int gpmc_cs_configure(int cs, int cmd, int wval); extern int gpmc_nand_read(int cs, int cmd); diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h index 69230d685538..19cbb5e9ece2 100644 --- a/arch/arm/plat-omap/include/plat/iommu.h +++ b/arch/arm/plat-omap/include/plat/iommu.h @@ -154,6 +154,8 @@ extern void flush_iotlb_range(struct iommu *obj, u32 start, u32 end); extern void flush_iotlb_all(struct iommu *obj); extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e); +extern void iopgtable_lookup_entry(struct iommu *obj, u32 da, u32 **ppgd, + u32 **ppte); extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova); extern int iommu_set_da_range(struct iommu *obj, u32 start, u32 end); diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h index 2910de921c52..1b911681e911 100644 --- a/arch/arm/plat-omap/include/plat/irqs.h +++ b/arch/arm/plat-omap/include/plat/irqs.h @@ -318,6 +318,7 @@ #define INT_34XX_PRCM_MPU_IRQ 11 #define INT_34XX_MCBSP1_IRQ 16 #define INT_34XX_MCBSP2_IRQ 17 +#define INT_34XX_GPMC_IRQ 20 #define INT_34XX_MCBSP3_IRQ 22 #define INT_34XX_MCBSP4_IRQ 23 #define INT_34XX_CAM_IRQ 24 @@ -411,7 +412,13 @@ #define TWL_IRQ_END TWL6030_IRQ_END #endif -#define NR_IRQS TWL_IRQ_END +/* GPMC related */ +#define OMAP_GPMC_IRQ_BASE (TWL_IRQ_END) +#define OMAP_GPMC_NR_IRQS 7 +#define OMAP_GPMC_IRQ_END (OMAP_GPMC_IRQ_BASE + OMAP_GPMC_NR_IRQS) + + +#define NR_IRQS OMAP_GPMC_IRQ_END #define OMAP_IRQ_BIT(irq) (1 << ((irq) % 32)) diff --git a/arch/arm/plat-omap/include/plat/mcspi.h b/arch/arm/plat-omap/include/plat/mcspi.h index 1254e4945b6f..3d51b18131cc 100644 --- a/arch/arm/plat-omap/include/plat/mcspi.h +++ b/arch/arm/plat-omap/include/plat/mcspi.h @@ -1,8 +1,19 @@ #ifndef _OMAP2_MCSPI_H #define _OMAP2_MCSPI_H +#define OMAP2_MCSPI_REV 0 +#define OMAP3_MCSPI_REV 1 +#define OMAP4_MCSPI_REV 2 + +#define OMAP4_MCSPI_REG_OFFSET 0x100 + struct omap2_mcspi_platform_config { unsigned short num_cs; + unsigned int regs_offset; +}; + +struct omap2_mcspi_dev_attr { + unsigned short num_chipselect; }; struct omap2_mcspi_device_config { diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 6562cd082bb1..d86d1ecf0068 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -8,8 +8,16 @@ * published by the Free Software Foundation. */ +#include <plat/gpmc.h> #include <linux/mtd/partitions.h> +enum nand_io { + NAND_OMAP_PREFETCH_POLLED = 0, /* prefetch polled mode, default */ + NAND_OMAP_POLLED, /* polled mode, without prefetch */ + NAND_OMAP_PREFETCH_DMA, /* prefetch enabled sDMA mode */ + NAND_OMAP_PREFETCH_IRQ /* prefetch enabled irq mode */ +}; + struct omap_nand_platform_data { unsigned int options; int cs; @@ -20,8 +28,11 @@ struct omap_nand_platform_data { int (*nand_setup)(void); int (*dev_ready)(struct omap_nand_platform_data *); int dma_channel; + int gpmc_irq; + enum nand_io xfer_type; unsigned long phys_base; int devsize; + enum omap_ecc ecc_opt; }; /* minimum size for IO mapping */ diff --git a/arch/arm/plat-omap/include/plat/onenand.h b/arch/arm/plat-omap/include/plat/onenand.h index affe87e9ece7..cbe897ca7f9e 100644 --- a/arch/arm/plat-omap/include/plat/onenand.h +++ b/arch/arm/plat-omap/include/plat/onenand.h @@ -15,12 +15,20 @@ #define ONENAND_SYNC_READ (1 << 0) #define ONENAND_SYNC_READWRITE (1 << 1) +struct onenand_freq_info { + u16 maf_id; + u16 dev_id; + u16 ver_id; +}; + struct omap_onenand_platform_data { int cs; int gpio_irq; struct mtd_partition *parts; int nr_parts; - int (*onenand_setup)(void __iomem *, int freq); + int (*onenand_setup)(void __iomem *, int *freq_ptr); + int (*get_freq)(const struct onenand_freq_info *freq_info, + bool *clk_dep); int dma_channel; u8 flags; u8 regulator_can_sleep; diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h index 450a332f1009..077192759afc 100644 --- a/arch/arm/plat-omap/include/plat/usb.h +++ b/arch/arm/plat-omap/include/plat/usb.h @@ -91,6 +91,10 @@ extern int omap4430_phy_exit(struct device *dev); #endif +extern void am35x_musb_reset(void); +extern void am35x_musb_phy_power(u8 on); +extern void am35x_musb_clear_irq(void); +extern void am35x_musb_set_mode(u8 musb_mode); /* * FIXME correct answer depends on hmc_mode, |