diff options
Diffstat (limited to 'arch/arm/mach-omap2')
22 files changed, 43 insertions, 3153 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index f4d06aea846..6e249324fdd 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -79,7 +79,9 @@ config ARCH_OMAP2PLUS select CLKSRC_MMIO select GENERIC_IRQ_CHIP select MACH_OMAP_GENERIC + select MEMORY select OMAP_DM_TIMER + select OMAP_GPMC select PINCTRL select SOC_BUS select TI_PRIV_EDMA @@ -235,12 +237,6 @@ config MACH_TOUCHBOOK default y select OMAP_PACKAGE_CBB -config MACH_OMAP_3430SDP - bool "OMAP 3430 SDP board" - depends on ARCH_OMAP3 - default y - select OMAP_PACKAGE_CBB - config MACH_NOKIA_N810 bool @@ -282,16 +278,6 @@ config MACH_SBC3530 default y select OMAP_PACKAGE_CUS -config MACH_TI8168EVM - bool "TI8168 Evaluation Module" - depends on SOC_TI81XX - default y - -config MACH_TI8148EVM - bool "TI8148 Evaluation Module" - depends on SOC_TI81XX - default y - config OMAP3_EMU bool "OMAP3 debugging peripherals" depends on ARCH_OMAP3 diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 3b653b3ac26..08cc94474d1 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -6,7 +6,7 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \ -I$(srctree)/arch/arm/plat-omap/include # Common support -obj-y := id.o io.o control.o mux.o devices.o fb.o serial.o gpmc.o timer.o pm.o \ +obj-y := id.o io.o control.o mux.o devices.o fb.o serial.o timer.o pm.o \ common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \ omap_device.o sram.o drm.o @@ -246,7 +246,6 @@ obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o obj-$(CONFIG_MACH_OVERO) += board-overo.o obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o -obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o sdram-nokia.o obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-peripherals.o @@ -260,8 +259,6 @@ obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o -obj-$(CONFIG_MACH_TI8168EVM) += board-ti8168evm.o -obj-$(CONFIG_MACH_TI8148EVM) += board-ti8168evm.o # Platform specific device init code @@ -284,9 +281,6 @@ obj-y += $(onenand-m) $(onenand-y) nand-$(CONFIG_MTD_NAND_OMAP2) := gpmc-nand.o obj-y += $(nand-m) $(nand-y) -smc91x-$(CONFIG_SMC91X) := gpmc-smc91x.o -obj-y += $(smc91x-m) $(smc91x-y) - smsc911x-$(CONFIG_SMSC911X) := gpmc-smsc911x.o obj-y += $(smsc911x-m) $(smsc911x-y) ifneq ($(CONFIG_HWSPINLOCK_OMAP),) diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c deleted file mode 100644 index d21a3048d06..00000000000 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ /dev/null @@ -1,632 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/board-3430sdp.c - * - * Copyright (C) 2007 Texas Instruments - * - * Modified from mach-omap2/board-generic.c - * - * Initial code: Syed Mohammed Khasim - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/delay.h> -#include <linux/input.h> -#include <linux/input/matrix_keypad.h> -#include <linux/spi/spi.h> -#include <linux/i2c/twl.h> -#include <linux/regulator/machine.h> -#include <linux/io.h> -#include <linux/gpio.h> -#include <linux/mmc/host.h> -#include <linux/platform_data/spi-omap2-mcspi.h> -#include <linux/platform_data/omap-twl4030.h> -#include <linux/usb/phy.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include "common.h" -#include <linux/omap-dma.h> -#include <video/omapdss.h> -#include <video/omap-panel-data.h> - -#include "gpmc.h" -#include "gpmc-smc91x.h" - -#include "soc.h" -#include "board-flash.h" -#include "mux.h" -#include "sdram-qimonda-hyb18m512160af-6.h" -#include "hsmmc.h" -#include "pm.h" -#include "control.h" -#include "common-board-devices.h" - -#define CONFIG_DISABLE_HFCLK 1 - -#define SDP3430_TS_GPIO_IRQ_SDPV1 3 -#define SDP3430_TS_GPIO_IRQ_SDPV2 2 - -#define ENABLE_VAUX3_DEDICATED 0x03 -#define ENABLE_VAUX3_DEV_GRP 0x20 - -#define TWL4030_MSECURE_GPIO 22 - -static uint32_t board_keymap[] = { - KEY(0, 0, KEY_LEFT), - KEY(0, 1, KEY_RIGHT), - KEY(0, 2, KEY_A), - KEY(0, 3, KEY_B), - KEY(0, 4, KEY_C), - KEY(1, 0, KEY_DOWN), - KEY(1, 1, KEY_UP), - KEY(1, 2, KEY_E), - KEY(1, 3, KEY_F), - KEY(1, 4, KEY_G), - KEY(2, 0, KEY_ENTER), - KEY(2, 1, KEY_I), - KEY(2, 2, KEY_J), - KEY(2, 3, KEY_K), - KEY(2, 4, KEY_3), - KEY(3, 0, KEY_M), - KEY(3, 1, KEY_N), - KEY(3, 2, KEY_O), - KEY(3, 3, KEY_P), - KEY(3, 4, KEY_Q), - KEY(4, 0, KEY_R), - KEY(4, 1, KEY_4), - KEY(4, 2, KEY_T), - KEY(4, 3, KEY_U), - KEY(4, 4, KEY_D), - KEY(5, 0, KEY_V), - KEY(5, 1, KEY_W), - KEY(5, 2, KEY_L), - KEY(5, 3, KEY_S), - KEY(5, 4, KEY_H), - 0 -}; - -static struct matrix_keymap_data board_map_data = { - .keymap = board_keymap, - .keymap_size = ARRAY_SIZE(board_keymap), -}; - -static struct twl4030_keypad_data sdp3430_kp_data = { - .keymap_data = &board_map_data, - .rows = 5, - .cols = 6, - .rep = 1, -}; - -#define SDP3430_LCD_PANEL_BACKLIGHT_GPIO 8 -#define SDP3430_LCD_PANEL_ENABLE_GPIO 5 - -static void __init sdp3430_display_init(void) -{ - int r; - - /* - * the backlight GPIO doesn't directly go to the panel, it enables - * an internal circuit on 3430sdp to create the signal V_BKL_28V, - * this is connected to LED+ pin of the sharp panel. This GPIO - * is left enabled in the board file, and not passed to the panel - * as platform_data. - */ - r = gpio_request_one(SDP3430_LCD_PANEL_BACKLIGHT_GPIO, - GPIOF_OUT_INIT_HIGH, "LCD Backlight"); - if (r) - pr_err("failed to get LCD Backlight GPIO\n"); - -} - -static struct panel_sharp_ls037v7dw01_platform_data sdp3430_lcd_pdata = { - .name = "lcd", - .source = "dpi.0", - - .data_lines = 16, - - .resb_gpio = SDP3430_LCD_PANEL_ENABLE_GPIO, - .ini_gpio = -1, - .mo_gpio = -1, - .lr_gpio = -1, - .ud_gpio = -1, -}; - -static struct platform_device sdp3430_lcd_device = { - .name = "panel-sharp-ls037v7dw01", - .id = 0, - .dev.platform_data = &sdp3430_lcd_pdata, -}; - -static struct connector_dvi_platform_data sdp3430_dvi_connector_pdata = { - .name = "dvi", - .source = "tfp410.0", - .i2c_bus_num = -1, -}; - -static struct platform_device sdp3430_dvi_connector_device = { - .name = "connector-dvi", - .id = 0, - .dev.platform_data = &sdp3430_dvi_connector_pdata, -}; - -static struct encoder_tfp410_platform_data sdp3430_tfp410_pdata = { - .name = "tfp410.0", - .source = "dpi.0", - .data_lines = 24, - .power_down_gpio = -1, -}; - -static struct platform_device sdp3430_tfp410_device = { - .name = "tfp410", - .id = 0, - .dev.platform_data = &sdp3430_tfp410_pdata, -}; - -static struct connector_atv_platform_data sdp3430_tv_pdata = { - .name = "tv", - .source = "venc.0", - .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, - .invert_polarity = false, -}; - -static struct platform_device sdp3430_tv_connector_device = { - .name = "connector-analog-tv", - .id = 0, - .dev.platform_data = &sdp3430_tv_pdata, -}; - -static struct omap_dss_board_info sdp3430_dss_data = { - .default_display_name = "lcd", -}; - -static struct omap2_hsmmc_info mmc[] = { - { - .mmc = 1, - /* 8 bits (default) requires S6.3 == ON, - * so the SIM card isn't used; else 4 bits. - */ - .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, - .gpio_wp = 4, - .deferred = true, - }, - { - .mmc = 2, - .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, - .gpio_wp = 7, - .deferred = true, - }, - {} /* Terminator */ -}; - -static struct omap_tw4030_pdata omap_twl4030_audio_data = { - .voice_connected = true, - .custom_routing = true, - - .has_hs = OMAP_TWL4030_LEFT | OMAP_TWL4030_RIGHT, - .has_hf = OMAP_TWL4030_LEFT | OMAP_TWL4030_RIGHT, - - .has_mainmic = true, - .has_submic = true, - .has_hsmic = true, - .has_linein = OMAP_TWL4030_LEFT | OMAP_TWL4030_RIGHT, -}; - -static int sdp3430_twl_gpio_setup(struct device *dev, - unsigned gpio, unsigned ngpio) -{ - /* gpio + 0 is "mmc0_cd" (input/IRQ), - * gpio + 1 is "mmc1_cd" (input/IRQ) - */ - mmc[0].gpio_cd = gpio + 0; - mmc[1].gpio_cd = gpio + 1; - omap_hsmmc_late_init(mmc); - - /* gpio + 7 is "sub_lcd_en_bkl" (output/PWM1) */ - gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "sub_lcd_en_bkl"); - - /* gpio + 15 is "sub_lcd_nRST" (output) */ - gpio_request_one(gpio + 15, GPIOF_OUT_INIT_LOW, "sub_lcd_nRST"); - - omap_twl4030_audio_data.jack_detect = gpio + 2; - omap_twl4030_audio_init("SDP3430", &omap_twl4030_audio_data); - - return 0; -} - -static struct twl4030_gpio_platform_data sdp3430_gpio_data = { - .pulldowns = BIT(2) | BIT(6) | BIT(8) | BIT(13) - | BIT(16) | BIT(17), - .setup = sdp3430_twl_gpio_setup, -}; - -/* 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_vmmc1_supplies[] = { - REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), -}; - -static struct regulator_consumer_supply sdp3430_vsim_supplies[] = { - REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"), -}; - -static struct regulator_consumer_supply sdp3430_vmmc2_supplies[] = { - REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"), -}; - -/* - * Apply all the fixed voltages since most versions of U-Boot - * don't bother with that initialization. - */ - -/* VAUX1 for mainboard (irda and sub-lcd) */ -static struct regulator_init_data sdp3430_vaux1 = { - .constraints = { - .min_uV = 2800000, - .max_uV = 2800000, - .apply_uV = true, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, -}; - -/* VAUX2 for camera module */ -static struct regulator_init_data sdp3430_vaux2 = { - .constraints = { - .min_uV = 2800000, - .max_uV = 2800000, - .apply_uV = true, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, -}; - -/* VAUX3 for LCD board */ -static struct regulator_init_data sdp3430_vaux3 = { - .constraints = { - .min_uV = 2800000, - .max_uV = 2800000, - .apply_uV = true, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(sdp3430_vaux3_supplies), - .consumer_supplies = sdp3430_vaux3_supplies, -}; - -/* VAUX4 for OMAP VDD_CSI2 (camera) */ -static struct regulator_init_data sdp3430_vaux4 = { - .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, - }, -}; - -/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */ -static struct regulator_init_data sdp3430_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(sdp3430_vmmc1_supplies), - .consumer_supplies = sdp3430_vmmc1_supplies, -}; - -/* VMMC2 for MMC2 card */ -static struct regulator_init_data sdp3430_vmmc2 = { - .constraints = { - .min_uV = 1850000, - .max_uV = 1850000, - .apply_uV = true, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(sdp3430_vmmc2_supplies), - .consumer_supplies = sdp3430_vmmc2_supplies, -}; - -/* VSIM for OMAP VDD_MMC1A (i/o for DAT4..DAT7) */ -static struct regulator_init_data sdp3430_vsim = { - .constraints = { - .min_uV = 1800000, - .max_uV = 3000000, - .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(sdp3430_vsim_supplies), - .consumer_supplies = sdp3430_vsim_supplies, -}; - -static struct twl4030_platform_data sdp3430_twldata = { - /* platform_data for children goes here */ - .gpio = &sdp3430_gpio_data, - .keypad = &sdp3430_kp_data, - - .vaux1 = &sdp3430_vaux1, - .vaux2 = &sdp3430_vaux2, - .vaux3 = &sdp3430_vaux3, - .vaux4 = &sdp3430_vaux4, - .vmmc1 = &sdp3430_vmmc1, - .vmmc2 = &sdp3430_vmmc2, - .vsim = &sdp3430_vsim, -}; - -static int __init omap3430_i2c_init(void) -{ - /* i2c1 for PMIC only */ - omap3_pmic_get_config(&sdp3430_twldata, - TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_BCI | - TWL_COMMON_PDATA_MADC | TWL_COMMON_PDATA_AUDIO, - TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2); - sdp3430_twldata.vdac->constraints.apply_uV = true; - sdp3430_twldata.vpll2->constraints.apply_uV = true; - sdp3430_twldata.vpll2->constraints.name = "VDVI"; - - sdp3430_twldata.audio->codec->hs_extmute = 1; - sdp3430_twldata.audio->codec->hs_extmute_gpio = -EINVAL; - - omap3_pmic_init("twl4030", &sdp3430_twldata); - - /* i2c2 on camera connector (for sensor control) and optional isp1301 */ - omap_register_i2c_bus(2, 400, NULL, 0); - /* i2c3 on display connector (for DVI, tfp410) */ - omap_register_i2c_bus(3, 400, NULL, 0); - return 0; -} - -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) - -static struct omap_smc91x_platform_data board_smc91x_data = { - .cs = 3, - .flags = GPMC_MUX_ADD_DATA | GPMC_TIMINGS_SMC91C96 | - IORESOURCE_IRQ_LOWLEVEL, -}; - -static void __init board_smc91x_init(void) -{ - if (omap_rev() > OMAP3430_REV_ES1_0) - board_smc91x_data.gpio_irq = 6; - else - board_smc91x_data.gpio_irq = 29; - - gpmc_smc91x_init(&board_smc91x_data); -} - -#else - -static inline void board_smc91x_init(void) -{ -} - -#endif - -static void enable_board_wakeup_source(void) -{ - /* T2 interrupt line (keypad) */ - omap_mux_init_signal("sys_nirq", - OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); -} - -static struct usbhs_phy_data phy_data[] __initdata = { - { - .port = 1, - .reset_gpio = 57, - .vcc_gpio = -EINVAL, - }, - { - .port = 2, - .reset_gpio = 61, - .vcc_gpio = -EINVAL, - }, -}; - -static struct usbhs_omap_platform_data usbhs_bdata __initdata = { - - .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, -}; - -#ifdef CONFIG_OMAP_MUX -static struct omap_board_mux board_mux[] __initdata = { - { .reg_offset = OMAP_MUX_TERMINATOR }, -}; -#else -#define board_mux NULL -#endif - -/* - * SDP3430 V2 Board CS organization - * Different from SDP3430 V1. Now 4 switches used to specify CS - * - * See also the Switch S8 settings in the comments. - */ -static char chip_sel_3430[][GPMC_CS_NUM] = { - {PDC_NOR, PDC_NAND, PDC_ONENAND, DBG_MPDB, 0, 0, 0, 0}, /* S8:1111 */ - {PDC_ONENAND, PDC_NAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1110 */ - {PDC_NAND, PDC_ONENAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1101 */ -}; - -static struct mtd_partition sdp_nor_partitions[] = { - /* bootloader (U-Boot, etc) in first sector */ - { - .name = "Bootloader-NOR", - .offset = 0, - .size = SZ_256K, - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, - /* bootloader params in the next sector */ - { - .name = "Params-NOR", - .offset = MTDPART_OFS_APPEND, - .size = SZ_256K, - .mask_flags = 0, - }, - /* kernel */ - { - .name = "Kernel-NOR", - .offset = MTDPART_OFS_APPEND, - .size = SZ_2M, - .mask_flags = 0 - }, - /* file system */ - { - .name = "Filesystem-NOR", - .offset = MTDPART_OFS_APPEND, - .size = MTDPART_SIZ_FULL, - .mask_flags = 0 - } -}; - -static struct mtd_partition sdp_onenand_partitions[] = { - { - .name = "X-Loader-OneNAND", - .offset = 0, - .size = 4 * (64 * 2048), - .mask_flags = MTD_WRITEABLE /* force read-only */ - }, - { - .name = "U-Boot-OneNAND", - .offset = MTDPART_OFS_APPEND, - .size = 2 * (64 * 2048), - .mask_flags = MTD_WRITEABLE /* force read-only */ - }, - { - .name = "U-Boot Environment-OneNAND", - .offset = MTDPART_OFS_APPEND, - .size = 1 * (64 * 2048), - }, - { - .name = "Kernel-OneNAND", - .offset = MTDPART_OFS_APPEND, - .size = 16 * (64 * 2048), - }, - { - .name = "File System-OneNAND", - .offset = MTDPART_OFS_APPEND, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct mtd_partition sdp_nand_partitions[] = { - /* All the partition sizes are listed in terms of NAND block size */ - { - .name = "X-Loader-NAND", - .offset = 0, - .size = 4 * (64 * 2048), - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, - { - .name = "U-Boot-NAND", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */ - .size = 10 * (64 * 2048), - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, - { - .name = "Boot Env-NAND", - - .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c0000 */ - .size = 6 * (64 * 2048), - }, - { - .name = "Kernel-NAND", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */ - .size = 40 * (64 * 2048), - }, - { - .name = "File System - NAND", - .size = MTDPART_SIZ_FULL, - .offset = MTDPART_OFS_APPEND, /* Offset = 0x780000 */ - }, -}; - -static struct flash_partitions sdp_flash_partitions[] = { - { - .parts = sdp_nor_partitions, - .nr_parts = ARRAY_SIZE(sdp_nor_partitions), - }, - { - .parts = sdp_onenand_partitions, - .nr_parts = ARRAY_SIZE(sdp_onenand_partitions), - }, - { - .parts = sdp_nand_partitions, - .nr_parts = ARRAY_SIZE(sdp_nand_partitions), - }, -}; - -static void __init omap_3430sdp_init(void) -{ - int gpio_pendown; - - omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); - omap_hsmmc_init(mmc); - omap3430_i2c_init(); - omap_display_init(&sdp3430_dss_data); - platform_device_register(&sdp3430_lcd_device); - platform_device_register(&sdp3430_tfp410_device); - platform_device_register(&sdp3430_dvi_connector_device); - platform_device_register(&sdp3430_tv_connector_device); - - if (omap_rev() > OMAP3430_REV_ES1_0) - gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV2; - else - gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV1; - omap_ads7846_init(1, gpio_pendown, 310, NULL); - omap_serial_init(); - omap_sdrc_init(hyb18m512160af6_sdrc_params, NULL); - usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); - usb_musb_init(NULL); - board_smc91x_init(); - board_flash_init(sdp_flash_partitions, chip_sel_3430, 0); - sdp3430_display_init(); - enable_board_wakeup_source(); - - usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); - usbhs_init(&usbhs_bdata); -} - -MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board") - /* Maintainer: Syed Khasim - Texas Instruments Inc */ - .atag_offset = 0x100, - .reserve = omap_reserve, - .map_io = omap3_map_io, - .init_early = omap3430_init_early, - .init_irq = omap3_init_irq, - .init_machine = omap_3430sdp_init, - .init_late = omap3430_init_late, - .init_time = omap3_sync32k_timer_init, - .restart = omap3xxx_restart, -MACHINE_END diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c index 212c3160de1..8168ddabaed 100644 --- a/arch/arm/mach-omap2/board-am3517crane.c +++ b/arch/arm/mach-omap2/board-am3517crane.c @@ -24,6 +24,7 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> #include <linux/mtd/partitions.h> +#include <linux/omap-gpmc.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index c6df8eec455..91738a14ecb 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -25,6 +25,7 @@ #include <linux/input/matrix_keypad.h> #include <linux/delay.h> #include <linux/gpio.h> +#include <linux/omap-gpmc.h> #include <linux/platform_data/gpio-omap.h> #include <linux/platform_data/at24.h> @@ -51,8 +52,6 @@ #include "sdram-micron-mt46h32m32lf-6.h" #include "hsmmc.h" #include "common-board-devices.h" -#include "gpmc.h" -#include "gpmc-nand.h" #define CM_T35_GPIO_PENDOWN 57 #define SB_T35_USB_HUB_RESET_GPIO 167 diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c index 8a2c1677964..794756df852 100644 --- a/arch/arm/mach-omap2/board-cm-t3517.c +++ b/arch/arm/mach-omap2/board-cm-t3517.c @@ -28,6 +28,7 @@ #include <linux/delay.h> #include <linux/gpio.h> #include <linux/leds.h> +#include <linux/omap-gpmc.h> #include <linux/rtc-v3020.h> #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> @@ -41,7 +42,6 @@ #include "common.h" #include <linux/platform_data/mtd-nand-omap2.h> -#include "gpmc.h" #include "am35xx.h" @@ -50,7 +50,6 @@ #include "hsmmc.h" #include "common-board-devices.h" #include "am35xx-emac.h" -#include "gpmc-nand.h" #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) static struct gpio_led cm_t3517_leds[] = { diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index 2d245c2e641..70b21cc279b 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -13,6 +13,7 @@ */ #include <linux/kernel.h> +#include <linux/omap-gpmc.h> #include <linux/platform_device.h> #include <linux/mtd/physmap.h> #include <linux/io.h> @@ -23,8 +24,6 @@ #include "soc.h" #include "common.h" #include "board-flash.h" -#include "gpmc-onenand.h" -#include "gpmc-nand.h" #define REG_FPGA_REV 0x10 #define REG_FPGA_DIP_SWITCH_INPUT2 0x60 diff --git a/arch/arm/mach-omap2/board-flash.h b/arch/arm/mach-omap2/board-flash.h index 2fb5d41a9fa..ea9aaebe11e 100644 --- a/arch/arm/mach-omap2/board-flash.h +++ b/arch/arm/mach-omap2/board-flash.h @@ -12,7 +12,6 @@ */ #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> -#include "gpmc.h" #define PDC_NOR 1 #define PDC_NAND 2 diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index e0ad64fde20..b6443a4e0c7 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -23,7 +23,6 @@ #include <linux/usb/musb.h> #include <linux/mmc/host.h> #include <linux/platform_data/spi-omap2-mcspi.h> -#include <linux/platform_data/mtd-onenand-omap2.h> #include <linux/platform_data/mmc-omap.h> #include <linux/mfd/menelaus.h> #include <sound/tlv320aic3x.h> @@ -34,7 +33,6 @@ #include "common.h" #include "mmc.h" #include "soc.h" -#include "gpmc-onenand.h" #include "common-board-devices.h" #define TUSB6010_ASYNC_CS 1 diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index f32201656cf..7f1708738c3 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -24,6 +24,7 @@ #include <linux/spi/spi.h> #include <linux/regulator/machine.h> #include <linux/i2c/twl.h> +#include <linux/omap-gpmc.h> #include <linux/wl12xx.h> #include <linux/mtd/partitions.h> #include <linux/mtd/nand.h> @@ -51,7 +52,6 @@ #include "sdram-micron-mt46h32m32lf-6.h" #include "hsmmc.h" #include "common-board-devices.h" -#include "gpmc-nand.h" #define PANDORA_WIFI_IRQ_GPIO 21 #define PANDORA_WIFI_NRESET_GPIO 23 diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index 3d5040f82e9..03502abe4f2 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -23,6 +23,7 @@ #include <linux/regulator/machine.h> #include <linux/gpio.h> #include <linux/gpio_keys.h> +#include <linux/omap-gpmc.h> #include <linux/mmc/host.h> #include <linux/power/isp1704_charger.h> #include <linux/platform_data/spi-omap2-mcspi.h> @@ -32,7 +33,6 @@ #include "common.h" #include <linux/omap-dma.h> -#include "gpmc-smc91x.h" #include "board-rx51.h" @@ -55,8 +55,6 @@ #include "omap-pm.h" #include "hsmmc.h" #include "common-board-devices.h" -#include "gpmc.h" -#include "gpmc-onenand.h" #include "soc.h" #include "omap-secure.h" @@ -1144,33 +1142,6 @@ static struct omap_onenand_platform_data board_onenand_data[] = { }; #endif -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) - -static struct omap_smc91x_platform_data board_smc91x_data = { - .cs = 1, - .gpio_irq = 54, - .gpio_pwrdwn = 86, - .gpio_reset = 164, - .flags = GPMC_TIMINGS_SMC91C96 | IORESOURCE_IRQ_HIGHLEVEL, -}; - -static void __init board_smc91x_init(void) -{ - omap_mux_init_gpio(54, OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_gpio(86, OMAP_PIN_OUTPUT); - omap_mux_init_gpio(164, OMAP_PIN_OUTPUT); - - gpmc_smc91x_init(&board_smc91x_data); -} - -#else - -static inline void board_smc91x_init(void) -{ -} - -#endif - static struct gpio rx51_wl1251_gpios[] __initdata = { { RX51_WL1251_IRQ_GPIO, GPIOF_IN, "wl1251 irq" }, }; @@ -1301,7 +1272,6 @@ void __init rx51_peripherals_init(void) rx51_i2c_init(); regulator_has_full_constraints(); gpmc_onenand_init(board_onenand_data); - board_smc91x_init(); rx51_add_gpio_keys(); rx51_init_wl1251(); rx51_init_tsc2005(); diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c deleted file mode 100644 index 6273c286e1d..00000000000 --- a/arch/arm/mach-omap2/board-ti8168evm.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Code for TI8168/TI8148 EVM. - * - * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/ - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/usb/musb.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include "common.h" - -static struct omap_musb_board_data musb_board_data = { - .set_phy_power = ti81xx_musb_phy_power, - .interface_type = MUSB_INTERFACE_ULPI, - .mode = MUSB_OTG, - .power = 500, -}; - -static void __init ti81xx_evm_init(void) -{ - omap_serial_init(); - omap_sdrc_init(NULL, NULL); - usb_musb_init(&musb_board_data); -} - -MACHINE_START(TI8168EVM, "ti8168evm") - /* Maintainer: Texas Instruments */ - .atag_offset = 0x100, - .map_io = ti81xx_map_io, - .init_early = ti81xx_init_early, - .init_irq = ti81xx_init_irq, - .init_time = omap3_sync32k_timer_init, - .init_machine = ti81xx_evm_init, - .init_late = ti81xx_init_late, - .restart = omap44xx_restart, -MACHINE_END - -MACHINE_START(TI8148EVM, "ti8148evm") - /* Maintainer: Texas Instruments */ - .atag_offset = 0x100, - .map_io = ti81xx_map_io, - .init_early = ti81xx_init_early, - .init_irq = ti81xx_init_irq, - .init_time = omap3_sync32k_timer_init, - .init_machine = ti81xx_evm_init, - .init_late = ti81xx_init_late, - .restart = omap44xx_restart, -MACHINE_END diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 492ef160711..a7bc4ce81e1 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -411,3 +411,29 @@ static int __init omap2_init_devices(void) return 0; } omap_arch_initcall(omap2_init_devices); + +static int __init omap_gpmc_init(void) +{ + struct omap_hwmod *oh; + struct platform_device *pdev; + char *oh_name = "gpmc"; + + /* + * if the board boots up with a populated DT, do not + * manually add the device from this initcall + */ + if (of_have_populated_dt()) + return -ENODEV; + + oh = omap_hwmod_lookup(oh_name); + if (!oh) { + pr_err("Could not look up %s\n", oh_name); + return -ENODEV; + } + + pdev = omap_device_build("omap-gpmc", -1, oh, NULL, 0); + WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); + + return PTR_RET(pdev); +} +omap_postcore_initcall(omap_gpmc_init); diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c index cb7764314f1..d5951b17b73 100644 --- a/arch/arm/mach-omap2/gpmc-nand.c +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -12,14 +12,13 @@ #include <linux/kernel.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/omap-gpmc.h> #include <linux/mtd/nand.h> #include <linux/platform_data/mtd-nand-omap2.h> #include <asm/mach/flash.h> -#include "gpmc.h" #include "soc.h" -#include "gpmc-nand.h" /* minimum size for IO mapping */ #define NAND_IO_SIZE 4 diff --git a/arch/arm/mach-omap2/gpmc-nand.h b/arch/arm/mach-omap2/gpmc-nand.h deleted file mode 100644 index d59e1281e85..00000000000 --- a/arch/arm/mach-omap2/gpmc-nand.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * arch/arm/mach-omap2/gpmc-nand.h - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef __OMAP2_GPMC_NAND_H -#define __OMAP2_GPMC_NAND_H - -#include "gpmc.h" -#include <linux/platform_data/mtd-nand-omap2.h> - -#if IS_ENABLED(CONFIG_MTD_NAND_OMAP2) -extern int gpmc_nand_init(struct omap_nand_platform_data *d, - struct gpmc_timings *gpmc_t); -#else -static inline int gpmc_nand_init(struct omap_nand_platform_data *d, - struct gpmc_timings *gpmc_t) -{ - return 0; -} -#endif - -#endif diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c index 8b6876c98ce..53d197e0c1f 100644 --- a/arch/arm/mach-omap2/gpmc-onenand.c +++ b/arch/arm/mach-omap2/gpmc-onenand.c @@ -15,14 +15,13 @@ #include <linux/platform_device.h> #include <linux/mtd/onenand_regs.h> #include <linux/io.h> +#include <linux/omap-gpmc.h> #include <linux/platform_data/mtd-onenand-omap2.h> #include <linux/err.h> #include <asm/mach/flash.h> -#include "gpmc.h" #include "soc.h" -#include "gpmc-onenand.h" #define ONENAND_IO_SIZE SZ_128K diff --git a/arch/arm/mach-omap2/gpmc-onenand.h b/arch/arm/mach-omap2/gpmc-onenand.h deleted file mode 100644 index 216f23a8b45..00000000000 --- a/arch/arm/mach-omap2/gpmc-onenand.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * arch/arm/mach-omap2/gpmc-onenand.h - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef __OMAP2_GPMC_ONENAND_H -#define __OMAP2_GPMC_ONENAND_H - -#include <linux/platform_data/mtd-onenand-omap2.h> - -#if IS_ENABLED(CONFIG_MTD_ONENAND_OMAP2) -extern void gpmc_onenand_init(struct omap_onenand_platform_data *d); -#else -#define board_onenand_data NULL -static inline void gpmc_onenand_init(struct omap_onenand_platform_data *d) -{ -} -#endif - -#endif diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c deleted file mode 100644 index 61a063595e6..00000000000 --- a/arch/arm/mach-omap2/gpmc-smc91x.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/gpmc-smc91x.c - * - * Copyright (C) 2009 Nokia Corporation - * Contact: Tony Lindgren - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/gpio.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/io.h> -#include <linux/smc91x.h> - -#include "gpmc.h" -#include "gpmc-smc91x.h" - -#include "soc.h" - -static struct omap_smc91x_platform_data *gpmc_cfg; - -static struct resource gpmc_smc91x_resources[] = { - [0] = { - .flags = IORESOURCE_MEM, - }, - [1] = { - .flags = IORESOURCE_IRQ, - }, -}; - -static struct smc91x_platdata gpmc_smc91x_info = { - .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_IO_SHIFT_0, - .leda = RPC_LED_100_10, - .ledb = RPC_LED_TX_RX, -}; - -static struct platform_device gpmc_smc91x_device = { - .name = "smc91x", - .id = -1, - .dev = { - .platform_data = &gpmc_smc91x_info, - }, - .num_resources = ARRAY_SIZE(gpmc_smc91x_resources), - .resource = gpmc_smc91x_resources, -}; - -static struct gpmc_settings smc91x_settings = { - .device_width = GPMC_DEVWIDTH_16BIT, -}; - -/* - * Set the gpmc timings for smc91c96. The timings are taken - * from the data sheet available at: - * http://www.smsc.com/main/catalog/lan91c96.html - * REVISIT: Level shifters can add at least to the access latency. - */ -static int smc91c96_gpmc_retime(void) -{ - struct gpmc_timings t; - struct gpmc_device_timings dev_t; - const int t3 = 10; /* Figure 12.2 read and 12.4 write */ - const int t4_r = 20; /* Figure 12.2 read */ - const int t4_w = 5; /* Figure 12.4 write */ - const int t5 = 25; /* Figure 12.2 read */ - const int t6 = 15; /* Figure 12.2 read */ - const int t7 = 5; /* Figure 12.4 write */ - const int t8 = 5; /* Figure 12.4 write */ - const int t20 = 185; /* Figure 12.2 read and 12.4 write */ - - /* - * FIXME: Calculate the address and data bus muxed timings. - * Note that at least adv_rd_off needs to be changed according - * to omap3430 TRM Figure 11-11. Are the sdp boards using the - * FPGA in between smc91x and omap as the timings are different - * from above? - */ - if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA) - return 0; - - memset(&dev_t, 0, sizeof(dev_t)); - - dev_t.t_oeasu = t3 * 1000; - dev_t.t_oe = t5 * 1000; - dev_t.t_cez_r = t4_r * 1000; - dev_t.t_oez = t6 * 1000; - dev_t.t_rd_cycle = (t20 - t3) * 1000; - - dev_t.t_weasu = t3 * 1000; - dev_t.t_wpl = t7 * 1000; - dev_t.t_wph = t8 * 1000; - dev_t.t_cez_w = t4_w * 1000; - dev_t.t_wr_cycle = (t20 - t3) * 1000; - - gpmc_calc_timings(&t, &smc91x_settings, &dev_t); - - return gpmc_cs_set_timings(gpmc_cfg->cs, &t); -} - -/* - * Initialize smc91x device connected to the GPMC. Note that we - * assume that pin multiplexing is done in the board-*.c file, - * or in the bootloader. - */ -void __init gpmc_smc91x_init(struct omap_smc91x_platform_data *board_data) -{ - unsigned long cs_mem_base; - int ret; - - gpmc_cfg = board_data; - - if (gpmc_cfg->flags & GPMC_TIMINGS_SMC91C96) - gpmc_cfg->retime = smc91c96_gpmc_retime; - - if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) { - printk(KERN_ERR "Failed to request GPMC mem for smc91x\n"); - return; - } - - gpmc_smc91x_resources[0].start = cs_mem_base + 0x300; - gpmc_smc91x_resources[0].end = cs_mem_base + 0x30f; - gpmc_smc91x_resources[1].flags |= (gpmc_cfg->flags & IRQF_TRIGGER_MASK); - - if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA) - smc91x_settings.mux_add_data = GPMC_MUX_AD; - if (gpmc_cfg->flags & GPMC_READ_MON) - smc91x_settings.wait_on_read = true; - if (gpmc_cfg->flags & GPMC_WRITE_MON) - smc91x_settings.wait_on_write = true; - if (gpmc_cfg->wait_pin) - smc91x_settings.wait_pin = gpmc_cfg->wait_pin; - ret = gpmc_cs_program_settings(gpmc_cfg->cs, &smc91x_settings); - if (ret < 0) - goto free1; - - if (gpmc_cfg->retime) { - ret = gpmc_cfg->retime(); - if (ret != 0) - goto free1; - } - - if (gpio_request_one(gpmc_cfg->gpio_irq, GPIOF_IN, "SMC91X irq") < 0) - goto free1; - - gpmc_smc91x_resources[1].start = gpio_to_irq(gpmc_cfg->gpio_irq); - - if (gpmc_cfg->gpio_pwrdwn) { - ret = gpio_request_one(gpmc_cfg->gpio_pwrdwn, - GPIOF_OUT_INIT_LOW, "SMC91X powerdown"); - if (ret) - goto free2; - } - - if (gpmc_cfg->gpio_reset) { - ret = gpio_request_one(gpmc_cfg->gpio_reset, - GPIOF_OUT_INIT_LOW, "SMC91X reset"); - if (ret) - goto free3; - - gpio_set_value(gpmc_cfg->gpio_reset, 1); - msleep(100); - gpio_set_value(gpmc_cfg->gpio_reset, 0); - } - - if (platform_device_register(&gpmc_smc91x_device) < 0) { - printk(KERN_ERR "Unable to register smc91x device\n"); - gpio_free(gpmc_cfg->gpio_reset); - goto free3; - } - - return; - -free3: - if (gpmc_cfg->gpio_pwrdwn) - gpio_free(gpmc_cfg->gpio_pwrdwn); -free2: - gpio_free(gpmc_cfg->gpio_irq); -free1: - gpmc_cs_free(gpmc_cfg->cs); - - printk(KERN_ERR "Could not initialize smc91x\n"); -} diff --git a/arch/arm/mach-omap2/gpmc-smc91x.h b/arch/arm/mach-omap2/gpmc-smc91x.h deleted file mode 100644 index b64fbee4d56..00000000000 --- a/arch/arm/mach-omap2/gpmc-smc91x.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * arch/arm/plat-omap/include/mach/gpmc-smc91x.h - * - * Copyright (C) 2009 Nokia Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __ASM_ARCH_OMAP_GPMC_SMC91X_H__ - -#define GPMC_TIMINGS_SMC91C96 (1 << 4) -#define GPMC_MUX_ADD_DATA (1 << 5) /* GPMC_CONFIG1_MUXADDDATA */ -#define GPMC_READ_MON (1 << 6) /* GPMC_CONFIG1_WAIT_READ_MON */ -#define GPMC_WRITE_MON (1 << 7) /* GPMC_CONFIG1_WAIT_WRITE_MON */ - -struct omap_smc91x_platform_data { - int cs; - int gpio_irq; - int gpio_pwrdwn; - int gpio_reset; - int wait_pin; /* Optional GPMC_CONFIG1_WAITPINSELECT */ - u32 flags; - int (*retime)(void); -}; - -#if defined(CONFIG_SMC91X) || \ - defined(CONFIG_SMC91X_MODULE) - -extern void gpmc_smc91x_init(struct omap_smc91x_platform_data *d); - -#else - -#define board_smc91x_data NULL - -static inline void gpmc_smc91x_init(struct omap_smc91x_platform_data *d) -{ -} - -#endif -#endif diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c deleted file mode 100644 index 8fb5bbce102..00000000000 --- a/arch/arm/mach-omap2/gpmc.c +++ /dev/null @@ -1,1889 +0,0 @@ -/* - * GPMC support functions - * - * Copyright (C) 2005-2006 Nokia Corporation - * - * Author: Juha Yrjola - * - * Copyright (C) 2009 Texas Instruments - * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#undef DEBUG - -#include <linux/irq.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/err.h> -#include <linux/clk.h> -#include <linux/ioport.h> -#include <linux/spinlock.h> -#include <linux/io.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_mtd.h> -#include <linux/of_device.h> -#include <linux/mtd/nand.h> -#include <linux/pm_runtime.h> - -#include <linux/platform_data/mtd-nand-omap2.h> - -#include <asm/mach-types.h> - -#include "soc.h" -#include "common.h" -#include "omap_device.h" -#include "gpmc.h" -#include "gpmc-nand.h" -#include "gpmc-onenand.h" - -#define DEVICE_NAME "omap-gpmc" - -/* GPMC register offsets */ -#define GPMC_REVISION 0x00 -#define GPMC_SYSCONFIG 0x10 -#define GPMC_SYSSTATUS 0x14 -#define GPMC_IRQSTATUS 0x18 -#define GPMC_IRQENABLE 0x1c -#define GPMC_TIMEOUT_CONTROL 0x40 -#define GPMC_ERR_ADDRESS 0x44 -#define GPMC_ERR_TYPE 0x48 -#define GPMC_CONFIG 0x50 -#define GPMC_STATUS 0x54 -#define GPMC_PREFETCH_CONFIG1 0x1e0 -#define GPMC_PREFETCH_CONFIG2 0x1e4 -#define GPMC_PREFETCH_CONTROL 0x1ec -#define GPMC_PREFETCH_STATUS 0x1f0 -#define GPMC_ECC_CONFIG 0x1f4 -#define GPMC_ECC_CONTROL 0x1f8 -#define GPMC_ECC_SIZE_CONFIG 0x1fc -#define GPMC_ECC1_RESULT 0x200 -#define GPMC_ECC_BCH_RESULT_0 0x240 /* not available on OMAP2 */ -#define GPMC_ECC_BCH_RESULT_1 0x244 /* not available on OMAP2 */ -#define GPMC_ECC_BCH_RESULT_2 0x248 /* not available on OMAP2 */ -#define GPMC_ECC_BCH_RESULT_3 0x24c /* not available on OMAP2 */ -#define GPMC_ECC_BCH_RESULT_4 0x300 /* not available on OMAP2 */ -#define GPMC_ECC_BCH_RESULT_5 0x304 /* not available on OMAP2 */ -#define GPMC_ECC_BCH_RESULT_6 0x308 /* not available on OMAP2 */ - -/* GPMC ECC control settings */ -#define GPMC_ECC_CTRL_ECCCLEAR 0x100 -#define GPMC_ECC_CTRL_ECCDISABLE 0x000 -#define GPMC_ECC_CTRL_ECCREG1 0x001 -#define GPMC_ECC_CTRL_ECCREG2 0x002 -#define GPMC_ECC_CTRL_ECCREG3 0x003 -#define GPMC_ECC_CTRL_ECCREG4 0x004 -#define GPMC_ECC_CTRL_ECCREG5 0x005 -#define GPMC_ECC_CTRL_ECCREG6 0x006 -#define GPMC_ECC_CTRL_ECCREG7 0x007 -#define GPMC_ECC_CTRL_ECCREG8 0x008 -#define GPMC_ECC_CTRL_ECCREG9 0x009 - -#define GPMC_CONFIG2_CSEXTRADELAY BIT(7) -#define GPMC_CONFIG3_ADVEXTRADELAY BIT(7) -#define GPMC_CONFIG4_OEEXTRADELAY BIT(7) -#define GPMC_CONFIG4_WEEXTRADELAY BIT(23) -#define GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN BIT(6) -#define GPMC_CONFIG6_CYCLE2CYCLESAMECSEN BIT(7) - -#define GPMC_CS0_OFFSET 0x60 -#define GPMC_CS_SIZE 0x30 -#define GPMC_BCH_SIZE 0x10 - -#define GPMC_MEM_END 0x3FFFFFFF - -#define GPMC_CHUNK_SHIFT 24 /* 16 MB */ -#define GPMC_SECTION_SHIFT 28 /* 128 MB */ - -#define CS_NUM_SHIFT 24 -#define ENABLE_PREFETCH (0x1 << 7) -#define DMA_MPU_MODE 2 - -#define GPMC_REVISION_MAJOR(l) ((l >> 4) & 0xf) -#define GPMC_REVISION_MINOR(l) (l & 0xf) - -#define GPMC_HAS_WR_ACCESS 0x1 -#define GPMC_HAS_WR_DATA_MUX_BUS 0x2 -#define GPMC_HAS_MUX_AAD 0x4 - -#define GPMC_NR_WAITPINS 4 - -/* XXX: Only NAND irq has been considered,currently these are the only ones used - */ -#define GPMC_NR_IRQ 2 - -struct gpmc_client_irq { - unsigned irq; - u32 bitmask; -}; - -/* Structure to save gpmc cs context */ -struct gpmc_cs_config { - u32 config1; - u32 config2; - u32 config3; - u32 config4; - u32 config5; - u32 config6; - u32 config7; - int is_valid; -}; - -/* - * Structure to save/restore gpmc context - * to support core off on OMAP3 - */ -struct omap3_gpmc_regs { - u32 sysconfig; - u32 irqenable; - u32 timeout_ctrl; - u32 config; - u32 prefetch_config1; - u32 prefetch_config2; - u32 prefetch_control; - struct gpmc_cs_config cs_context[GPMC_CS_NUM]; -}; - -static struct gpmc_client_irq gpmc_client_irq[GPMC_NR_IRQ]; -static struct irq_chip gpmc_irq_chip; -static int gpmc_irq_start; - -static struct resource gpmc_mem_root; -static struct resource gpmc_cs_mem[GPMC_CS_NUM]; -static DEFINE_SPINLOCK(gpmc_mem_lock); -/* Define chip-selects as reserved by default until probe completes */ -static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1); -static unsigned int gpmc_cs_num = GPMC_CS_NUM; -static unsigned int gpmc_nr_waitpins; -static struct device *gpmc_dev; -static int gpmc_irq; -static resource_size_t phys_base, mem_size; -static unsigned gpmc_capability; -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) -{ - writel_relaxed(val, gpmc_base + idx); -} - -static u32 gpmc_read_reg(int idx) -{ - return readl_relaxed(gpmc_base + idx); -} - -void gpmc_cs_write_reg(int cs, int idx, u32 val) -{ - void __iomem *reg_addr; - - reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; - writel_relaxed(val, reg_addr); -} - -static u32 gpmc_cs_read_reg(int cs, int idx) -{ - void __iomem *reg_addr; - - reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; - return readl_relaxed(reg_addr); -} - -/* TODO: Add support for gpmc_fck to clock framework and use it */ -static unsigned long gpmc_get_fclk_period(void) -{ - unsigned long rate = clk_get_rate(gpmc_l3_clk); - - if (rate == 0) { - printk(KERN_WARNING "gpmc_l3_clk not enabled\n"); - return 0; - } - - rate /= 1000; - rate = 1000000000 / rate; /* In picoseconds */ - - return rate; -} - -static unsigned int gpmc_ns_to_ticks(unsigned int time_ns) -{ - unsigned long tick_ps; - - /* Calculate in picosecs to yield more exact results */ - tick_ps = gpmc_get_fclk_period(); - - return (time_ns * 1000 + tick_ps - 1) / tick_ps; -} - -static unsigned int gpmc_ps_to_ticks(unsigned int time_ps) -{ - unsigned long tick_ps; - - /* Calculate in picosecs to yield more exact results */ - tick_ps = gpmc_get_fclk_period(); - - return (time_ps + tick_ps - 1) / tick_ps; -} - -unsigned int gpmc_ticks_to_ns(unsigned int ticks) -{ - return ticks * gpmc_get_fclk_period() / 1000; -} - -static unsigned int gpmc_ticks_to_ps(unsigned int ticks) -{ - return ticks * gpmc_get_fclk_period(); -} - -static unsigned int gpmc_round_ps_to_ticks(unsigned int time_ps) -{ - unsigned long ticks = gpmc_ps_to_ticks(time_ps); - - return ticks * gpmc_get_fclk_period(); -} - -static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value) -{ - u32 l; - - l = gpmc_cs_read_reg(cs, reg); - if (value) - l |= mask; - else - l &= ~mask; - gpmc_cs_write_reg(cs, reg, l); -} - -static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p) -{ - gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG1, - GPMC_CONFIG1_TIME_PARA_GRAN, - p->time_para_granularity); - gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG2, - GPMC_CONFIG2_CSEXTRADELAY, p->cs_extra_delay); - gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG3, - GPMC_CONFIG3_ADVEXTRADELAY, p->adv_extra_delay); - gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4, - GPMC_CONFIG4_OEEXTRADELAY, p->oe_extra_delay); - gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4, - GPMC_CONFIG4_OEEXTRADELAY, p->we_extra_delay); - gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6, - GPMC_CONFIG6_CYCLE2CYCLESAMECSEN, - p->cycle2cyclesamecsen); - gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6, - GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN, - p->cycle2cyclediffcsen); -} - -#ifdef DEBUG -static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, - int time, const char *name) -#else -static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, - int time) -#endif -{ - u32 l; - int ticks, mask, nr_bits; - - if (time == 0) - ticks = 0; - else - ticks = gpmc_ns_to_ticks(time); - nr_bits = end_bit - st_bit + 1; - if (ticks >= 1 << nr_bits) { -#ifdef DEBUG - printk(KERN_INFO "GPMC CS%d: %-10s* %3d ns, %3d ticks >= %d\n", - cs, name, time, ticks, 1 << nr_bits); -#endif - return -1; - } - - mask = (1 << nr_bits) - 1; - l = gpmc_cs_read_reg(cs, reg); -#ifdef DEBUG - printk(KERN_INFO - "GPMC CS%d: %-10s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n", - cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000, - (l >> st_bit) & mask, time); -#endif - l &= ~(mask << st_bit); - l |= ticks << st_bit; - gpmc_cs_write_reg(cs, reg, l); - - return 0; -} - -#ifdef DEBUG -#define GPMC_SET_ONE(reg, st, end, field) \ - if (set_gpmc_timing_reg(cs, (reg), (st), (end), \ - t->field, #field) < 0) \ - return -1 -#else -#define GPMC_SET_ONE(reg, st, end, field) \ - if (set_gpmc_timing_reg(cs, (reg), (st), (end), t->field) < 0) \ - return -1 -#endif - -int gpmc_calc_divider(unsigned int sync_clk) -{ - int div; - u32 l; - - l = sync_clk + (gpmc_get_fclk_period() - 1); - div = l / gpmc_get_fclk_period(); - if (div > 4) - return -1; - if (div <= 0) - div = 1; - - return div; -} - -int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) -{ - int div; - u32 l; - - div = gpmc_calc_divider(t->sync_clk); - if (div < 0) - return div; - - GPMC_SET_ONE(GPMC_CS_CONFIG2, 0, 3, cs_on); - GPMC_SET_ONE(GPMC_CS_CONFIG2, 8, 12, cs_rd_off); - GPMC_SET_ONE(GPMC_CS_CONFIG2, 16, 20, cs_wr_off); - - GPMC_SET_ONE(GPMC_CS_CONFIG3, 0, 3, adv_on); - GPMC_SET_ONE(GPMC_CS_CONFIG3, 8, 12, adv_rd_off); - GPMC_SET_ONE(GPMC_CS_CONFIG3, 16, 20, adv_wr_off); - - GPMC_SET_ONE(GPMC_CS_CONFIG4, 0, 3, oe_on); - GPMC_SET_ONE(GPMC_CS_CONFIG4, 8, 12, oe_off); - GPMC_SET_ONE(GPMC_CS_CONFIG4, 16, 19, we_on); - GPMC_SET_ONE(GPMC_CS_CONFIG4, 24, 28, we_off); - - GPMC_SET_ONE(GPMC_CS_CONFIG5, 0, 4, rd_cycle); - GPMC_SET_ONE(GPMC_CS_CONFIG5, 8, 12, wr_cycle); - GPMC_SET_ONE(GPMC_CS_CONFIG5, 16, 20, access); - - GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access); - - GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround); - GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay); - - GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring); - GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation); - - if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS) - GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus); - if (gpmc_capability & GPMC_HAS_WR_ACCESS) - GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access); - - /* caller is expected to have initialized CONFIG1 to cover - * at least sync vs async - */ - l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); - if (l & (GPMC_CONFIG1_READTYPE_SYNC | GPMC_CONFIG1_WRITETYPE_SYNC)) { -#ifdef DEBUG - printk(KERN_INFO "GPMC CS%d CLK period is %lu ns (div %d)\n", - cs, (div * gpmc_get_fclk_period()) / 1000, div); -#endif - l &= ~0x03; - l |= (div - 1); - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l); - } - - gpmc_cs_bool_timings(cs, &t->bool_timings); - - return 0; -} - -static int gpmc_cs_enable_mem(int cs, u32 base, u32 size) -{ - u32 l; - u32 mask; - - /* - * Ensure that base address is aligned on a - * boundary equal to or greater than size. - */ - if (base & (size - 1)) - return -EINVAL; - - mask = (1 << GPMC_SECTION_SHIFT) - size; - l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); - l &= ~0x3f; - l = (base >> GPMC_CHUNK_SHIFT) & 0x3f; - l &= ~(0x0f << 8); - l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8; - l |= GPMC_CONFIG7_CSVALID; - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); - - return 0; -} - -static void gpmc_cs_disable_mem(int cs) -{ - u32 l; - - l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); - l &= ~GPMC_CONFIG7_CSVALID; - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); -} - -static void gpmc_cs_get_memconf(int cs, u32 *base, u32 *size) -{ - u32 l; - u32 mask; - - l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); - *base = (l & 0x3f) << GPMC_CHUNK_SHIFT; - mask = (l >> 8) & 0x0f; - *size = (1 << GPMC_SECTION_SHIFT) - (mask << GPMC_CHUNK_SHIFT); -} - -static int gpmc_cs_mem_enabled(int cs) -{ - u32 l; - - l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); - return l & GPMC_CONFIG7_CSVALID; -} - -static void gpmc_cs_set_reserved(int cs, int reserved) -{ - gpmc_cs_map &= ~(1 << cs); - gpmc_cs_map |= (reserved ? 1 : 0) << cs; -} - -static bool gpmc_cs_reserved(int cs) -{ - return gpmc_cs_map & (1 << cs); -} - -static unsigned long gpmc_mem_align(unsigned long size) -{ - int order; - - size = (size - 1) >> (GPMC_CHUNK_SHIFT - 1); - order = GPMC_CHUNK_SHIFT - 1; - do { - size >>= 1; - order++; - } while (size); - size = 1 << order; - return size; -} - -static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size) -{ - struct resource *res = &gpmc_cs_mem[cs]; - int r; - - size = gpmc_mem_align(size); - spin_lock(&gpmc_mem_lock); - res->start = base; - res->end = base + size - 1; - r = request_resource(&gpmc_mem_root, res); - spin_unlock(&gpmc_mem_lock); - - return r; -} - -static int gpmc_cs_delete_mem(int cs) -{ - struct resource *res = &gpmc_cs_mem[cs]; - int r; - - spin_lock(&gpmc_mem_lock); - r = release_resource(res); - res->start = 0; - res->end = 0; - spin_unlock(&gpmc_mem_lock); - - return r; -} - -/** - * gpmc_cs_remap - remaps a chip-select physical base address - * @cs: chip-select to remap - * @base: physical base address to re-map chip-select to - * - * Re-maps a chip-select to a new physical base address specified by - * "base". Returns 0 on success and appropriate negative error code - * on failure. - */ -static int gpmc_cs_remap(int cs, u32 base) -{ - int ret; - u32 old_base, size; - - if (cs > gpmc_cs_num) { - pr_err("%s: requested chip-select is disabled\n", __func__); - return -ENODEV; - } - - /* - * Make sure we ignore any device offsets from the GPMC partition - * allocated for the chip select and that the new base confirms - * to the GPMC 16MB minimum granularity. - */ - base &= ~(SZ_16M - 1); - - gpmc_cs_get_memconf(cs, &old_base, &size); - if (base == old_base) - return 0; - gpmc_cs_disable_mem(cs); - ret = gpmc_cs_delete_mem(cs); - if (ret < 0) - return ret; - ret = gpmc_cs_insert_mem(cs, base, size); - if (ret < 0) - return ret; - ret = gpmc_cs_enable_mem(cs, base, size); - if (ret < 0) - return ret; - - return 0; -} - -int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) -{ - struct resource *res = &gpmc_cs_mem[cs]; - int r = -1; - - if (cs > gpmc_cs_num) { - pr_err("%s: requested chip-select is disabled\n", __func__); - return -ENODEV; - } - size = gpmc_mem_align(size); - if (size > (1 << GPMC_SECTION_SHIFT)) - return -ENOMEM; - - spin_lock(&gpmc_mem_lock); - if (gpmc_cs_reserved(cs)) { - r = -EBUSY; - goto out; - } - if (gpmc_cs_mem_enabled(cs)) - r = adjust_resource(res, res->start & ~(size - 1), size); - if (r < 0) - r = allocate_resource(&gpmc_mem_root, res, size, 0, ~0, - size, NULL, NULL); - if (r < 0) - goto out; - - r = gpmc_cs_enable_mem(cs, res->start, resource_size(res)); - if (r < 0) { - release_resource(res); - goto out; - } - - *base = res->start; - gpmc_cs_set_reserved(cs, 1); -out: - spin_unlock(&gpmc_mem_lock); - return r; -} -EXPORT_SYMBOL(gpmc_cs_request); - -void gpmc_cs_free(int cs) -{ - struct resource *res = &gpmc_cs_mem[cs]; - - spin_lock(&gpmc_mem_lock); - if (cs >= gpmc_cs_num || cs < 0 || !gpmc_cs_reserved(cs)) { - printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs); - BUG(); - spin_unlock(&gpmc_mem_lock); - return; - } - gpmc_cs_disable_mem(cs); - if (res->flags) - release_resource(res); - gpmc_cs_set_reserved(cs, 0); - spin_unlock(&gpmc_mem_lock); -} -EXPORT_SYMBOL(gpmc_cs_free); - -/** - * gpmc_configure - write request to configure gpmc - * @cmd: command type - * @wval: value to write - * @return status of the operation - */ -int gpmc_configure(int cmd, int wval) -{ - u32 regval; - - 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; - - case GPMC_CONFIG_WP: - regval = gpmc_read_reg(GPMC_CONFIG); - if (wval) - regval &= ~GPMC_CONFIG_WRITEPROTECT; /* WP is ON */ - else - regval |= GPMC_CONFIG_WRITEPROTECT; /* WP is OFF */ - gpmc_write_reg(GPMC_CONFIG, regval); - break; - - default: - pr_err("%s: command not supported\n", __func__); - return -EINVAL; - } - - return 0; -} -EXPORT_SYMBOL(gpmc_configure); - -void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs) -{ - int i; - - reg->gpmc_status = gpmc_base + GPMC_STATUS; - reg->gpmc_nand_command = gpmc_base + GPMC_CS0_OFFSET + - GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs; - reg->gpmc_nand_address = gpmc_base + GPMC_CS0_OFFSET + - GPMC_CS_NAND_ADDRESS + GPMC_CS_SIZE * cs; - reg->gpmc_nand_data = gpmc_base + GPMC_CS0_OFFSET + - GPMC_CS_NAND_DATA + GPMC_CS_SIZE * cs; - reg->gpmc_prefetch_config1 = gpmc_base + GPMC_PREFETCH_CONFIG1; - reg->gpmc_prefetch_config2 = gpmc_base + GPMC_PREFETCH_CONFIG2; - reg->gpmc_prefetch_control = gpmc_base + GPMC_PREFETCH_CONTROL; - reg->gpmc_prefetch_status = gpmc_base + GPMC_PREFETCH_STATUS; - reg->gpmc_ecc_config = gpmc_base + GPMC_ECC_CONFIG; - reg->gpmc_ecc_control = gpmc_base + GPMC_ECC_CONTROL; - reg->gpmc_ecc_size_config = gpmc_base + GPMC_ECC_SIZE_CONFIG; - reg->gpmc_ecc1_result = gpmc_base + GPMC_ECC1_RESULT; - - for (i = 0; i < GPMC_BCH_NUM_REMAINDER; i++) { - reg->gpmc_bch_result0[i] = gpmc_base + GPMC_ECC_BCH_RESULT_0 + - GPMC_BCH_SIZE * i; - reg->gpmc_bch_result1[i] = gpmc_base + GPMC_ECC_BCH_RESULT_1 + - GPMC_BCH_SIZE * i; - reg->gpmc_bch_result2[i] = gpmc_base + GPMC_ECC_BCH_RESULT_2 + - GPMC_BCH_SIZE * i; - reg->gpmc_bch_result3[i] = gpmc_base + GPMC_ECC_BCH_RESULT_3 + - GPMC_BCH_SIZE * i; - reg->gpmc_bch_result4[i] = gpmc_base + GPMC_ECC_BCH_RESULT_4 + - i * GPMC_BCH_SIZE; - reg->gpmc_bch_result5[i] = gpmc_base + GPMC_ECC_BCH_RESULT_5 + - i * GPMC_BCH_SIZE; - reg->gpmc_bch_result6[i] = gpmc_base + GPMC_ECC_BCH_RESULT_6 + - i * GPMC_BCH_SIZE; - } -} - -int gpmc_get_client_irq(unsigned irq_config) -{ - int i; - - if (hweight32(irq_config) > 1) - return 0; - - for (i = 0; i < GPMC_NR_IRQ; i++) - if (gpmc_client_irq[i].bitmask & irq_config) - return gpmc_client_irq[i].irq; - - return 0; -} - -static int gpmc_irq_endis(unsigned irq, bool endis) -{ - int i; - u32 regval; - - for (i = 0; i < GPMC_NR_IRQ; i++) - if (irq == gpmc_client_irq[i].irq) { - regval = gpmc_read_reg(GPMC_IRQENABLE); - if (endis) - regval |= gpmc_client_irq[i].bitmask; - else - regval &= ~gpmc_client_irq[i].bitmask; - gpmc_write_reg(GPMC_IRQENABLE, regval); - break; - } - - return 0; -} - -static void gpmc_irq_disable(struct irq_data *p) -{ - gpmc_irq_endis(p->irq, false); -} - -static void gpmc_irq_enable(struct irq_data *p) -{ - gpmc_irq_endis(p->irq, true); -} - -static void gpmc_irq_noop(struct irq_data *data) { } - -static unsigned int gpmc_irq_noop_ret(struct irq_data *data) { return 0; } - -static int gpmc_setup_irq(void) -{ - int i; - u32 regval; - - if (!gpmc_irq) - return -EINVAL; - - gpmc_irq_start = irq_alloc_descs(-1, 0, GPMC_NR_IRQ, 0); - if (gpmc_irq_start < 0) { - pr_err("irq_alloc_descs failed\n"); - return gpmc_irq_start; - } - - gpmc_irq_chip.name = "gpmc"; - gpmc_irq_chip.irq_startup = gpmc_irq_noop_ret; - gpmc_irq_chip.irq_enable = gpmc_irq_enable; - gpmc_irq_chip.irq_disable = gpmc_irq_disable; - gpmc_irq_chip.irq_shutdown = gpmc_irq_noop; - gpmc_irq_chip.irq_ack = gpmc_irq_noop; - gpmc_irq_chip.irq_mask = gpmc_irq_noop; - gpmc_irq_chip.irq_unmask = gpmc_irq_noop; - - gpmc_client_irq[0].bitmask = GPMC_IRQ_FIFOEVENTENABLE; - gpmc_client_irq[1].bitmask = GPMC_IRQ_COUNT_EVENT; - - for (i = 0; i < GPMC_NR_IRQ; i++) { - gpmc_client_irq[i].irq = gpmc_irq_start + i; - irq_set_chip_and_handler(gpmc_client_irq[i].irq, - &gpmc_irq_chip, handle_simple_irq); - set_irq_flags(gpmc_client_irq[i].irq, - IRQF_VALID | IRQF_NOAUTOEN); - } - - /* Disable interrupts */ - gpmc_write_reg(GPMC_IRQENABLE, 0); - - /* clear interrupts */ - regval = gpmc_read_reg(GPMC_IRQSTATUS); - gpmc_write_reg(GPMC_IRQSTATUS, regval); - - return request_irq(gpmc_irq, gpmc_handle_irq, 0, "gpmc", NULL); -} - -static int gpmc_free_irq(void) -{ - int i; - - if (gpmc_irq) - free_irq(gpmc_irq, NULL); - - for (i = 0; i < GPMC_NR_IRQ; i++) { - irq_set_handler(gpmc_client_irq[i].irq, NULL); - irq_set_chip(gpmc_client_irq[i].irq, &no_irq_chip); - irq_modify_status(gpmc_client_irq[i].irq, 0, 0); - } - - irq_free_descs(gpmc_irq_start, GPMC_NR_IRQ); - - return 0; -} - -static void gpmc_mem_exit(void) -{ - int cs; - - for (cs = 0; cs < gpmc_cs_num; cs++) { - if (!gpmc_cs_mem_enabled(cs)) - continue; - gpmc_cs_delete_mem(cs); - } - -} - -static void gpmc_mem_init(void) -{ - int cs; - - /* - * The first 1MB of GPMC address space is typically mapped to - * the internal ROM. Never allocate the first page, to - * facilitate bug detection; even if we didn't boot from ROM. - */ - gpmc_mem_root.start = SZ_1M; - gpmc_mem_root.end = GPMC_MEM_END; - - /* Reserve all regions that has been set up by bootloader */ - for (cs = 0; cs < gpmc_cs_num; cs++) { - u32 base, size; - - if (!gpmc_cs_mem_enabled(cs)) - continue; - gpmc_cs_get_memconf(cs, &base, &size); - if (gpmc_cs_insert_mem(cs, base, size)) { - pr_warn("%s: disabling cs %d mapped at 0x%x-0x%x\n", - __func__, cs, base, base + size); - gpmc_cs_disable_mem(cs); - } - } -} - -static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk) -{ - u32 temp; - int div; - - div = gpmc_calc_divider(sync_clk); - temp = gpmc_ps_to_ticks(time_ps); - temp = (temp + div - 1) / div; - return gpmc_ticks_to_ps(temp * div); -} - -/* XXX: can the cycles be avoided ? */ -static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t, - bool mux) -{ - u32 temp; - - /* adv_rd_off */ - temp = dev_t->t_avdp_r; - /* XXX: mux check required ? */ - if (mux) { - /* XXX: t_avdp not to be required for sync, only added for tusb - * this indirectly necessitates requirement of t_avdp_r and - * t_avdp_w instead of having a single t_avdp - */ - temp = max_t(u32, temp, gpmc_t->clk_activation + dev_t->t_avdh); - temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp); - } - gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp); - - /* oe_on */ - temp = dev_t->t_oeasu; /* XXX: remove this ? */ - if (mux) { - temp = max_t(u32, temp, gpmc_t->clk_activation + dev_t->t_ach); - temp = max_t(u32, temp, gpmc_t->adv_rd_off + - gpmc_ticks_to_ps(dev_t->cyc_aavdh_oe)); - } - gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp); - - /* access */ - /* XXX: any scope for improvement ?, by combining oe_on - * and clk_activation, need to check whether - * access = clk_activation + round to sync clk ? - */ - temp = max_t(u32, dev_t->t_iaa, dev_t->cyc_iaa * gpmc_t->sync_clk); - temp += gpmc_t->clk_activation; - if (dev_t->cyc_oe) - temp = max_t(u32, temp, gpmc_t->oe_on + - gpmc_ticks_to_ps(dev_t->cyc_oe)); - gpmc_t->access = gpmc_round_ps_to_ticks(temp); - - gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1); - gpmc_t->cs_rd_off = gpmc_t->oe_off; - - /* rd_cycle */ - temp = max_t(u32, dev_t->t_cez_r, dev_t->t_oez); - temp = gpmc_round_ps_to_sync_clk(temp, gpmc_t->sync_clk) + - gpmc_t->access; - /* XXX: barter t_ce_rdyz with t_cez_r ? */ - if (dev_t->t_ce_rdyz) - temp = max_t(u32, temp, gpmc_t->cs_rd_off + dev_t->t_ce_rdyz); - gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp); - - return 0; -} - -static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t, - bool mux) -{ - u32 temp; - - /* adv_wr_off */ - temp = dev_t->t_avdp_w; - if (mux) { - temp = max_t(u32, temp, - gpmc_t->clk_activation + dev_t->t_avdh); - temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp); - } - gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp); - - /* wr_data_mux_bus */ - temp = max_t(u32, dev_t->t_weasu, - gpmc_t->clk_activation + dev_t->t_rdyo); - /* XXX: shouldn't mux be kept as a whole for wr_data_mux_bus ?, - * and in that case remember to handle we_on properly - */ - if (mux) { - temp = max_t(u32, temp, - gpmc_t->adv_wr_off + dev_t->t_aavdh); - temp = max_t(u32, temp, gpmc_t->adv_wr_off + - gpmc_ticks_to_ps(dev_t->cyc_aavdh_we)); - } - gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp); - - /* we_on */ - if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS) - gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu); - else - gpmc_t->we_on = gpmc_t->wr_data_mux_bus; - - /* wr_access */ - /* XXX: gpmc_capability check reqd ? , even if not, will not harm */ - gpmc_t->wr_access = gpmc_t->access; - - /* we_off */ - temp = gpmc_t->we_on + dev_t->t_wpl; - temp = max_t(u32, temp, - gpmc_t->wr_access + gpmc_ticks_to_ps(1)); - temp = max_t(u32, temp, - gpmc_t->we_on + gpmc_ticks_to_ps(dev_t->cyc_wpl)); - gpmc_t->we_off = gpmc_round_ps_to_ticks(temp); - - gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off + - dev_t->t_wph); - - /* wr_cycle */ - temp = gpmc_round_ps_to_sync_clk(dev_t->t_cez_w, gpmc_t->sync_clk); - temp += gpmc_t->wr_access; - /* XXX: barter t_ce_rdyz with t_cez_w ? */ - if (dev_t->t_ce_rdyz) - temp = max_t(u32, temp, - gpmc_t->cs_wr_off + dev_t->t_ce_rdyz); - gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp); - - return 0; -} - -static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t, - bool mux) -{ - u32 temp; - - /* adv_rd_off */ - temp = dev_t->t_avdp_r; - if (mux) - temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp); - gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp); - - /* oe_on */ - temp = dev_t->t_oeasu; - if (mux) - temp = max_t(u32, temp, - gpmc_t->adv_rd_off + dev_t->t_aavdh); - gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp); - - /* access */ - temp = max_t(u32, dev_t->t_iaa, /* XXX: remove t_iaa in async ? */ - gpmc_t->oe_on + dev_t->t_oe); - temp = max_t(u32, temp, - gpmc_t->cs_on + dev_t->t_ce); - temp = max_t(u32, temp, - gpmc_t->adv_on + dev_t->t_aa); - gpmc_t->access = gpmc_round_ps_to_ticks(temp); - - gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1); - gpmc_t->cs_rd_off = gpmc_t->oe_off; - - /* rd_cycle */ - temp = max_t(u32, dev_t->t_rd_cycle, - gpmc_t->cs_rd_off + dev_t->t_cez_r); - temp = max_t(u32, temp, gpmc_t->oe_off + dev_t->t_oez); - gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp); - - return 0; -} - -static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t, - bool mux) -{ - u32 temp; - - /* adv_wr_off */ - temp = dev_t->t_avdp_w; - if (mux) - temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp); - gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp); - - /* wr_data_mux_bus */ - temp = dev_t->t_weasu; - if (mux) { - temp = max_t(u32, temp, gpmc_t->adv_wr_off + dev_t->t_aavdh); - temp = max_t(u32, temp, gpmc_t->adv_wr_off + - gpmc_ticks_to_ps(dev_t->cyc_aavdh_we)); - } - gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp); - - /* we_on */ - if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS) - gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu); - else - gpmc_t->we_on = gpmc_t->wr_data_mux_bus; - - /* we_off */ - temp = gpmc_t->we_on + dev_t->t_wpl; - gpmc_t->we_off = gpmc_round_ps_to_ticks(temp); - - gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off + - dev_t->t_wph); - - /* wr_cycle */ - temp = max_t(u32, dev_t->t_wr_cycle, - gpmc_t->cs_wr_off + dev_t->t_cez_w); - gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp); - - return 0; -} - -static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t) -{ - u32 temp; - - gpmc_t->sync_clk = gpmc_calc_divider(dev_t->clk) * - gpmc_get_fclk_period(); - - gpmc_t->page_burst_access = gpmc_round_ps_to_sync_clk( - dev_t->t_bacc, - gpmc_t->sync_clk); - - temp = max_t(u32, dev_t->t_ces, dev_t->t_avds); - gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp); - - if (gpmc_calc_divider(gpmc_t->sync_clk) != 1) - return 0; - - if (dev_t->ce_xdelay) - gpmc_t->bool_timings.cs_extra_delay = true; - if (dev_t->avd_xdelay) - gpmc_t->bool_timings.adv_extra_delay = true; - if (dev_t->oe_xdelay) - gpmc_t->bool_timings.oe_extra_delay = true; - if (dev_t->we_xdelay) - gpmc_t->bool_timings.we_extra_delay = true; - - return 0; -} - -static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t, - bool sync) -{ - u32 temp; - - /* cs_on */ - gpmc_t->cs_on = gpmc_round_ps_to_ticks(dev_t->t_ceasu); - - /* adv_on */ - temp = dev_t->t_avdasu; - if (dev_t->t_ce_avd) - temp = max_t(u32, temp, - gpmc_t->cs_on + dev_t->t_ce_avd); - gpmc_t->adv_on = gpmc_round_ps_to_ticks(temp); - - if (sync) - gpmc_calc_sync_common_timings(gpmc_t, dev_t); - - return 0; -} - -/* TODO: remove this function once all peripherals are confirmed to - * work with generic timing. Simultaneously gpmc_cs_set_timings() - * has to be modified to handle timings in ps instead of ns -*/ -static void gpmc_convert_ps_to_ns(struct gpmc_timings *t) -{ - t->cs_on /= 1000; - t->cs_rd_off /= 1000; - t->cs_wr_off /= 1000; - t->adv_on /= 1000; - t->adv_rd_off /= 1000; - t->adv_wr_off /= 1000; - t->we_on /= 1000; - t->we_off /= 1000; - t->oe_on /= 1000; - t->oe_off /= 1000; - t->page_burst_access /= 1000; - t->access /= 1000; - t->rd_cycle /= 1000; - t->wr_cycle /= 1000; - t->bus_turnaround /= 1000; - t->cycle2cycle_delay /= 1000; - t->wait_monitoring /= 1000; - t->clk_activation /= 1000; - t->wr_access /= 1000; - t->wr_data_mux_bus /= 1000; -} - -int gpmc_calc_timings(struct gpmc_timings *gpmc_t, - struct gpmc_settings *gpmc_s, - struct gpmc_device_timings *dev_t) -{ - bool mux = false, sync = false; - - if (gpmc_s) { - mux = gpmc_s->mux_add_data ? true : false; - sync = (gpmc_s->sync_read || gpmc_s->sync_write); - } - - memset(gpmc_t, 0, sizeof(*gpmc_t)); - - gpmc_calc_common_timings(gpmc_t, dev_t, sync); - - if (gpmc_s && gpmc_s->sync_read) - gpmc_calc_sync_read_timings(gpmc_t, dev_t, mux); - else - gpmc_calc_async_read_timings(gpmc_t, dev_t, mux); - - if (gpmc_s && gpmc_s->sync_write) - gpmc_calc_sync_write_timings(gpmc_t, dev_t, mux); - else - gpmc_calc_async_write_timings(gpmc_t, dev_t, mux); - - /* TODO: remove, see function definition */ - gpmc_convert_ps_to_ns(gpmc_t); - - return 0; -} - -/** - * gpmc_cs_program_settings - programs non-timing related settings - * @cs: GPMC chip-select to program - * @p: pointer to GPMC settings structure - * - * Programs non-timing related settings for a GPMC chip-select, such as - * bus-width, burst configuration, etc. Function should be called once - * for each chip-select that is being used and must be called before - * calling gpmc_cs_set_timings() as timing parameters in the CONFIG1 - * register will be initialised to zero by this function. Returns 0 on - * success and appropriate negative error code on failure. - */ -int gpmc_cs_program_settings(int cs, struct gpmc_settings *p) -{ - u32 config1; - - if ((!p->device_width) || (p->device_width > GPMC_DEVWIDTH_16BIT)) { - pr_err("%s: invalid width %d!", __func__, p->device_width); - return -EINVAL; - } - - /* Address-data multiplexing not supported for NAND devices */ - if (p->device_nand && p->mux_add_data) { - pr_err("%s: invalid configuration!\n", __func__); - return -EINVAL; - } - - if ((p->mux_add_data > GPMC_MUX_AD) || - ((p->mux_add_data == GPMC_MUX_AAD) && - !(gpmc_capability & GPMC_HAS_MUX_AAD))) { - pr_err("%s: invalid multiplex configuration!\n", __func__); - return -EINVAL; - } - - /* Page/burst mode supports lengths of 4, 8 and 16 bytes */ - if (p->burst_read || p->burst_write) { - switch (p->burst_len) { - case GPMC_BURST_4: - case GPMC_BURST_8: - case GPMC_BURST_16: - break; - default: - pr_err("%s: invalid page/burst-length (%d)\n", - __func__, p->burst_len); - return -EINVAL; - } - } - - if (p->wait_pin > gpmc_nr_waitpins) { - pr_err("%s: invalid wait-pin (%d)\n", __func__, p->wait_pin); - return -EINVAL; - } - - config1 = GPMC_CONFIG1_DEVICESIZE((p->device_width - 1)); - - if (p->sync_read) - config1 |= GPMC_CONFIG1_READTYPE_SYNC; - if (p->sync_write) - config1 |= GPMC_CONFIG1_WRITETYPE_SYNC; - if (p->wait_on_read) - config1 |= GPMC_CONFIG1_WAIT_READ_MON; - if (p->wait_on_write) - config1 |= GPMC_CONFIG1_WAIT_WRITE_MON; - if (p->wait_on_read || p->wait_on_write) - config1 |= GPMC_CONFIG1_WAIT_PIN_SEL(p->wait_pin); - if (p->device_nand) - config1 |= GPMC_CONFIG1_DEVICETYPE(GPMC_DEVICETYPE_NAND); - if (p->mux_add_data) - config1 |= GPMC_CONFIG1_MUXTYPE(p->mux_add_data); - if (p->burst_read) - config1 |= GPMC_CONFIG1_READMULTIPLE_SUPP; - if (p->burst_write) - config1 |= GPMC_CONFIG1_WRITEMULTIPLE_SUPP; - if (p->burst_read || p->burst_write) { - config1 |= GPMC_CONFIG1_PAGE_LEN(p->burst_len >> 3); - config1 |= p->burst_wrap ? GPMC_CONFIG1_WRAPBURST_SUPP : 0; - } - - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, config1); - - return 0; -} - -#ifdef CONFIG_OF -static const struct of_device_id gpmc_dt_ids[] = { - { .compatible = "ti,omap2420-gpmc" }, - { .compatible = "ti,omap2430-gpmc" }, - { .compatible = "ti,omap3430-gpmc" }, /* omap3430 & omap3630 */ - { .compatible = "ti,omap4430-gpmc" }, /* omap4430 & omap4460 & omap543x */ - { .compatible = "ti,am3352-gpmc" }, /* am335x devices */ - { } -}; -MODULE_DEVICE_TABLE(of, gpmc_dt_ids); - -/** - * gpmc_read_settings_dt - read gpmc settings from device-tree - * @np: pointer to device-tree node for a gpmc child device - * @p: pointer to gpmc settings structure - * - * Reads the GPMC settings for a GPMC child device from device-tree and - * stores them in the GPMC settings structure passed. The GPMC settings - * structure is initialised to zero by this function and so any - * previously stored settings will be cleared. - */ -void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p) -{ - memset(p, 0, sizeof(struct gpmc_settings)); - - p->sync_read = of_property_read_bool(np, "gpmc,sync-read"); - p->sync_write = of_property_read_bool(np, "gpmc,sync-write"); - of_property_read_u32(np, "gpmc,device-width", &p->device_width); - of_property_read_u32(np, "gpmc,mux-add-data", &p->mux_add_data); - - if (!of_property_read_u32(np, "gpmc,burst-length", &p->burst_len)) { - p->burst_wrap = of_property_read_bool(np, "gpmc,burst-wrap"); - p->burst_read = of_property_read_bool(np, "gpmc,burst-read"); - p->burst_write = of_property_read_bool(np, "gpmc,burst-write"); - if (!p->burst_read && !p->burst_write) - pr_warn("%s: page/burst-length set but not used!\n", - __func__); - } - - if (!of_property_read_u32(np, "gpmc,wait-pin", &p->wait_pin)) { - p->wait_on_read = of_property_read_bool(np, - "gpmc,wait-on-read"); - p->wait_on_write = of_property_read_bool(np, - "gpmc,wait-on-write"); - if (!p->wait_on_read && !p->wait_on_write) - pr_debug("%s: rd/wr wait monitoring not enabled!\n", - __func__); - } -} - -static void __maybe_unused gpmc_read_timings_dt(struct device_node *np, - struct gpmc_timings *gpmc_t) -{ - struct gpmc_bool_timings *p; - - if (!np || !gpmc_t) - return; - - memset(gpmc_t, 0, sizeof(*gpmc_t)); - - /* minimum clock period for syncronous mode */ - of_property_read_u32(np, "gpmc,sync-clk-ps", &gpmc_t->sync_clk); - - /* chip select timtings */ - of_property_read_u32(np, "gpmc,cs-on-ns", &gpmc_t->cs_on); - of_property_read_u32(np, "gpmc,cs-rd-off-ns", &gpmc_t->cs_rd_off); - of_property_read_u32(np, "gpmc,cs-wr-off-ns", &gpmc_t->cs_wr_off); - - /* ADV signal timings */ - of_property_read_u32(np, "gpmc,adv-on-ns", &gpmc_t->adv_on); - of_property_read_u32(np, "gpmc,adv-rd-off-ns", &gpmc_t->adv_rd_off); - of_property_read_u32(np, "gpmc,adv-wr-off-ns", &gpmc_t->adv_wr_off); - - /* WE signal timings */ - of_property_read_u32(np, "gpmc,we-on-ns", &gpmc_t->we_on); - of_property_read_u32(np, "gpmc,we-off-ns", &gpmc_t->we_off); - - /* OE signal timings */ - of_property_read_u32(np, "gpmc,oe-on-ns", &gpmc_t->oe_on); - of_property_read_u32(np, "gpmc,oe-off-ns", &gpmc_t->oe_off); - - /* access and cycle timings */ - of_property_read_u32(np, "gpmc,page-burst-access-ns", - &gpmc_t->page_burst_access); - of_property_read_u32(np, "gpmc,access-ns", &gpmc_t->access); - of_property_read_u32(np, "gpmc,rd-cycle-ns", &gpmc_t->rd_cycle); - of_property_read_u32(np, "gpmc,wr-cycle-ns", &gpmc_t->wr_cycle); - of_property_read_u32(np, "gpmc,bus-turnaround-ns", - &gpmc_t->bus_turnaround); - of_property_read_u32(np, "gpmc,cycle2cycle-delay-ns", - &gpmc_t->cycle2cycle_delay); - of_property_read_u32(np, "gpmc,wait-monitoring-ns", - &gpmc_t->wait_monitoring); - of_property_read_u32(np, "gpmc,clk-activation-ns", - &gpmc_t->clk_activation); - - /* only applicable to OMAP3+ */ - of_property_read_u32(np, "gpmc,wr-access-ns", &gpmc_t->wr_access); - of_property_read_u32(np, "gpmc,wr-data-mux-bus-ns", - &gpmc_t->wr_data_mux_bus); - - /* bool timing parameters */ - p = &gpmc_t->bool_timings; - - p->cycle2cyclediffcsen = - of_property_read_bool(np, "gpmc,cycle2cycle-diffcsen"); - p->cycle2cyclesamecsen = - of_property_read_bool(np, "gpmc,cycle2cycle-samecsen"); - p->we_extra_delay = of_property_read_bool(np, "gpmc,we-extra-delay"); - p->oe_extra_delay = of_property_read_bool(np, "gpmc,oe-extra-delay"); - p->adv_extra_delay = of_property_read_bool(np, "gpmc,adv-extra-delay"); - p->cs_extra_delay = of_property_read_bool(np, "gpmc,cs-extra-delay"); - p->time_para_granularity = - of_property_read_bool(np, "gpmc,time-para-granularity"); -} - -#if IS_ENABLED(CONFIG_MTD_NAND) - -static const char * const nand_xfer_types[] = { - [NAND_OMAP_PREFETCH_POLLED] = "prefetch-polled", - [NAND_OMAP_POLLED] = "polled", - [NAND_OMAP_PREFETCH_DMA] = "prefetch-dma", - [NAND_OMAP_PREFETCH_IRQ] = "prefetch-irq", -}; - -static int gpmc_probe_nand_child(struct platform_device *pdev, - struct device_node *child) -{ - u32 val; - const char *s; - struct gpmc_timings gpmc_t; - struct omap_nand_platform_data *gpmc_nand_data; - - if (of_property_read_u32(child, "reg", &val) < 0) { - dev_err(&pdev->dev, "%s has no 'reg' property\n", - child->full_name); - return -ENODEV; - } - - gpmc_nand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_nand_data), - GFP_KERNEL); - if (!gpmc_nand_data) - return -ENOMEM; - - gpmc_nand_data->cs = val; - gpmc_nand_data->of_node = child; - - /* Detect availability of ELM module */ - gpmc_nand_data->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0); - if (gpmc_nand_data->elm_of_node == NULL) - gpmc_nand_data->elm_of_node = - of_parse_phandle(child, "elm_id", 0); - - /* select ecc-scheme for NAND */ - if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) { - pr_err("%s: ti,nand-ecc-opt not found\n", __func__); - return -ENODEV; - } - - if (!strcmp(s, "sw")) - gpmc_nand_data->ecc_opt = OMAP_ECC_HAM1_CODE_SW; - else if (!strcmp(s, "ham1") || - !strcmp(s, "hw") || !strcmp(s, "hw-romcode")) - gpmc_nand_data->ecc_opt = - OMAP_ECC_HAM1_CODE_HW; - else if (!strcmp(s, "bch4")) - if (gpmc_nand_data->elm_of_node) - gpmc_nand_data->ecc_opt = - OMAP_ECC_BCH4_CODE_HW; - else - gpmc_nand_data->ecc_opt = - OMAP_ECC_BCH4_CODE_HW_DETECTION_SW; - else if (!strcmp(s, "bch8")) - if (gpmc_nand_data->elm_of_node) - gpmc_nand_data->ecc_opt = - OMAP_ECC_BCH8_CODE_HW; - else - gpmc_nand_data->ecc_opt = - OMAP_ECC_BCH8_CODE_HW_DETECTION_SW; - else if (!strcmp(s, "bch16")) - if (gpmc_nand_data->elm_of_node) - gpmc_nand_data->ecc_opt = - OMAP_ECC_BCH16_CODE_HW; - else - pr_err("%s: BCH16 requires ELM support\n", __func__); - else - pr_err("%s: ti,nand-ecc-opt invalid value\n", __func__); - - /* select data transfer mode for NAND controller */ - if (!of_property_read_string(child, "ti,nand-xfer-type", &s)) - for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++) - if (!strcasecmp(s, nand_xfer_types[val])) { - gpmc_nand_data->xfer_type = val; - break; - } - - gpmc_nand_data->flash_bbt = of_get_nand_on_flash_bbt(child); - - val = of_get_nand_bus_width(child); - if (val == 16) - gpmc_nand_data->devsize = NAND_BUSWIDTH_16; - - gpmc_read_timings_dt(child, &gpmc_t); - gpmc_nand_init(gpmc_nand_data, &gpmc_t); - - return 0; -} -#else -static int gpmc_probe_nand_child(struct platform_device *pdev, - struct device_node *child) -{ - return 0; -} -#endif - -#if IS_ENABLED(CONFIG_MTD_ONENAND) -static int gpmc_probe_onenand_child(struct platform_device *pdev, - struct device_node *child) -{ - u32 val; - struct omap_onenand_platform_data *gpmc_onenand_data; - - if (of_property_read_u32(child, "reg", &val) < 0) { - dev_err(&pdev->dev, "%s has no 'reg' property\n", - child->full_name); - return -ENODEV; - } - - gpmc_onenand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_onenand_data), - GFP_KERNEL); - if (!gpmc_onenand_data) - return -ENOMEM; - - gpmc_onenand_data->cs = val; - gpmc_onenand_data->of_node = child; - gpmc_onenand_data->dma_channel = -1; - - if (!of_property_read_u32(child, "dma-channel", &val)) - gpmc_onenand_data->dma_channel = val; - - gpmc_onenand_init(gpmc_onenand_data); - - return 0; -} -#else -static int gpmc_probe_onenand_child(struct platform_device *pdev, - struct device_node *child) -{ - return 0; -} -#endif - -/** - * gpmc_probe_generic_child - configures the gpmc for a child device - * @pdev: pointer to gpmc platform device - * @child: pointer to device-tree node for child device - * - * Allocates and configures a GPMC chip-select for a child device. - * Returns 0 on success and appropriate negative error code on failure. - */ -static int gpmc_probe_generic_child(struct platform_device *pdev, - struct device_node *child) -{ - struct gpmc_settings gpmc_s; - struct gpmc_timings gpmc_t; - struct resource res; - unsigned long base; - int ret, cs; - - if (of_property_read_u32(child, "reg", &cs) < 0) { - dev_err(&pdev->dev, "%s has no 'reg' property\n", - child->full_name); - return -ENODEV; - } - - if (of_address_to_resource(child, 0, &res) < 0) { - dev_err(&pdev->dev, "%s has malformed 'reg' property\n", - child->full_name); - return -ENODEV; - } - - ret = gpmc_cs_request(cs, resource_size(&res), &base); - if (ret < 0) { - dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs); - return ret; - } - - /* - * For some GPMC devices we still need to rely on the bootloader - * timings because the devices can be connected via FPGA. So far - * the list is smc91x on the omap2 SDP boards, and 8250 on zooms. - * REVISIT: Add timing support from slls644g.pdf and from the - * lan91c96 manual. - */ - if (of_device_is_compatible(child, "ns16550a") || - of_device_is_compatible(child, "smsc,lan91c94") || - of_device_is_compatible(child, "smsc,lan91c111")) { - dev_warn(&pdev->dev, - "%s using bootloader timings on CS%d\n", - child->name, cs); - goto no_timings; - } - - /* - * FIXME: gpmc_cs_request() will map the CS to an arbitary - * location in the gpmc address space. When booting with - * device-tree we want the NOR flash to be mapped to the - * location specified in the device-tree blob. So remap the - * CS to this location. Once DT migration is complete should - * just make gpmc_cs_request() map a specific address. - */ - ret = gpmc_cs_remap(cs, res.start); - if (ret < 0) { - dev_err(&pdev->dev, "cannot remap GPMC CS %d to %pa\n", - cs, &res.start); - goto err; - } - - gpmc_read_settings_dt(child, &gpmc_s); - - ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width); - if (ret < 0) - goto err; - - ret = gpmc_cs_program_settings(cs, &gpmc_s); - if (ret < 0) - goto err; - - gpmc_read_timings_dt(child, &gpmc_t); - gpmc_cs_set_timings(cs, &gpmc_t); - -no_timings: - if (of_platform_device_create(child, NULL, &pdev->dev)) - return 0; - - dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name); - ret = -ENODEV; - -err: - gpmc_cs_free(cs); - - return ret; -} - -static int gpmc_probe_dt(struct platform_device *pdev) -{ - int ret; - struct device_node *child; - const struct of_device_id *of_id = - of_match_device(gpmc_dt_ids, &pdev->dev); - - if (!of_id) - return 0; - - ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-cs", - &gpmc_cs_num); - if (ret < 0) { - pr_err("%s: number of chip-selects not defined\n", __func__); - return ret; - } else if (gpmc_cs_num < 1) { - pr_err("%s: all chip-selects are disabled\n", __func__); - return -EINVAL; - } else if (gpmc_cs_num > GPMC_CS_NUM) { - pr_err("%s: number of supported chip-selects cannot be > %d\n", - __func__, GPMC_CS_NUM); - return -EINVAL; - } - - ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-waitpins", - &gpmc_nr_waitpins); - if (ret < 0) { - pr_err("%s: number of wait pins not found!\n", __func__); - return ret; - } - - for_each_available_child_of_node(pdev->dev.of_node, child) { - - if (!child->name) - continue; - - if (of_node_cmp(child->name, "nand") == 0) - ret = gpmc_probe_nand_child(pdev, child); - else if (of_node_cmp(child->name, "onenand") == 0) - ret = gpmc_probe_onenand_child(pdev, child); - else if (of_node_cmp(child->name, "ethernet") == 0 || - of_node_cmp(child->name, "nor") == 0 || - of_node_cmp(child->name, "uart") == 0) - ret = gpmc_probe_generic_child(pdev, child); - - if (WARN(ret < 0, "%s: probing gpmc child %s failed\n", - __func__, child->full_name)) - of_node_put(child); - } - - return 0; -} -#else -static int gpmc_probe_dt(struct platform_device *pdev) -{ - return 0; -} -#endif - -static int gpmc_probe(struct platform_device *pdev) -{ - int rc; - u32 l; - struct resource *res; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) - return -ENOENT; - - phys_base = res->start; - mem_size = resource_size(res); - - gpmc_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(gpmc_base)) - return PTR_ERR(gpmc_base); - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (res == NULL) - dev_warn(&pdev->dev, "Failed to get resource: irq\n"); - else - gpmc_irq = res->start; - - gpmc_l3_clk = clk_get(&pdev->dev, "fck"); - if (IS_ERR(gpmc_l3_clk)) { - dev_err(&pdev->dev, "error: clk_get\n"); - gpmc_irq = 0; - return PTR_ERR(gpmc_l3_clk); - } - - pm_runtime_enable(&pdev->dev); - pm_runtime_get_sync(&pdev->dev); - - gpmc_dev = &pdev->dev; - - l = gpmc_read_reg(GPMC_REVISION); - - /* - * FIXME: Once device-tree migration is complete the below flags - * should be populated based upon the device-tree compatible - * string. For now just use the IP revision. OMAP3+ devices have - * the wr_access and wr_data_mux_bus register fields. OMAP4+ - * devices support the addr-addr-data multiplex protocol. - * - * GPMC IP revisions: - * - OMAP24xx = 2.0 - * - OMAP3xxx = 5.0 - * - OMAP44xx/54xx/AM335x = 6.0 - */ - if (GPMC_REVISION_MAJOR(l) > 0x4) - gpmc_capability = GPMC_HAS_WR_ACCESS | GPMC_HAS_WR_DATA_MUX_BUS; - if (GPMC_REVISION_MAJOR(l) > 0x5) - gpmc_capability |= GPMC_HAS_MUX_AAD; - dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l), - GPMC_REVISION_MINOR(l)); - - gpmc_mem_init(); - - if (gpmc_setup_irq() < 0) - dev_warn(gpmc_dev, "gpmc_setup_irq failed\n"); - - /* Now the GPMC is initialised, unreserve the chip-selects */ - gpmc_cs_map = 0; - - if (!pdev->dev.of_node) { - gpmc_cs_num = GPMC_CS_NUM; - gpmc_nr_waitpins = GPMC_NR_WAITPINS; - } - - rc = gpmc_probe_dt(pdev); - if (rc < 0) { - pm_runtime_put_sync(&pdev->dev); - clk_put(gpmc_l3_clk); - dev_err(gpmc_dev, "failed to probe DT parameters\n"); - return rc; - } - - return 0; -} - -static int gpmc_remove(struct platform_device *pdev) -{ - gpmc_free_irq(); - gpmc_mem_exit(); - pm_runtime_put_sync(&pdev->dev); - pm_runtime_disable(&pdev->dev); - gpmc_dev = NULL; - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int gpmc_suspend(struct device *dev) -{ - omap3_gpmc_save_context(); - pm_runtime_put_sync(dev); - return 0; -} - -static int gpmc_resume(struct device *dev) -{ - pm_runtime_get_sync(dev); - omap3_gpmc_restore_context(); - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(gpmc_pm_ops, gpmc_suspend, gpmc_resume); - -static struct platform_driver gpmc_driver = { - .probe = gpmc_probe, - .remove = gpmc_remove, - .driver = { - .name = DEVICE_NAME, - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(gpmc_dt_ids), - .pm = &gpmc_pm_ops, - }, -}; - -static __init int gpmc_init(void) -{ - return platform_driver_register(&gpmc_driver); -} - -static __exit void gpmc_exit(void) -{ - platform_driver_unregister(&gpmc_driver); - -} - -omap_postcore_initcall(gpmc_init); -module_exit(gpmc_exit); - -static int __init omap_gpmc_init(void) -{ - struct omap_hwmod *oh; - struct platform_device *pdev; - char *oh_name = "gpmc"; - - /* - * if the board boots up with a populated DT, do not - * manually add the device from this initcall - */ - if (of_have_populated_dt()) - return -ENODEV; - - oh = omap_hwmod_lookup(oh_name); - if (!oh) { - pr_err("Could not look up %s\n", oh_name); - return -ENODEV; - } - - pdev = omap_device_build(DEVICE_NAME, -1, oh, NULL, 0); - WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); - - return PTR_RET(pdev); -} -omap_postcore_initcall(omap_gpmc_init); - -static irqreturn_t gpmc_handle_irq(int irq, void *dev) -{ - int i; - u32 regval; - - regval = gpmc_read_reg(GPMC_IRQSTATUS); - - if (!regval) - return IRQ_NONE; - - for (i = 0; i < GPMC_NR_IRQ; i++) - if (regval & gpmc_client_irq[i].bitmask) - generic_handle_irq(gpmc_client_irq[i].irq); - - gpmc_write_reg(GPMC_IRQSTATUS, regval); - - return IRQ_HANDLED; -} - -static struct omap3_gpmc_regs gpmc_context; - -void omap3_gpmc_save_context(void) -{ - int i; - - gpmc_context.sysconfig = gpmc_read_reg(GPMC_SYSCONFIG); - gpmc_context.irqenable = gpmc_read_reg(GPMC_IRQENABLE); - gpmc_context.timeout_ctrl = gpmc_read_reg(GPMC_TIMEOUT_CONTROL); - gpmc_context.config = gpmc_read_reg(GPMC_CONFIG); - gpmc_context.prefetch_config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1); - gpmc_context.prefetch_config2 = gpmc_read_reg(GPMC_PREFETCH_CONFIG2); - gpmc_context.prefetch_control = gpmc_read_reg(GPMC_PREFETCH_CONTROL); - for (i = 0; i < gpmc_cs_num; i++) { - gpmc_context.cs_context[i].is_valid = gpmc_cs_mem_enabled(i); - if (gpmc_context.cs_context[i].is_valid) { - gpmc_context.cs_context[i].config1 = - gpmc_cs_read_reg(i, GPMC_CS_CONFIG1); - gpmc_context.cs_context[i].config2 = - gpmc_cs_read_reg(i, GPMC_CS_CONFIG2); - gpmc_context.cs_context[i].config3 = - gpmc_cs_read_reg(i, GPMC_CS_CONFIG3); - gpmc_context.cs_context[i].config4 = - gpmc_cs_read_reg(i, GPMC_CS_CONFIG4); - gpmc_context.cs_context[i].config5 = - gpmc_cs_read_reg(i, GPMC_CS_CONFIG5); - gpmc_context.cs_context[i].config6 = - gpmc_cs_read_reg(i, GPMC_CS_CONFIG6); - gpmc_context.cs_context[i].config7 = - gpmc_cs_read_reg(i, GPMC_CS_CONFIG7); - } - } -} - -void omap3_gpmc_restore_context(void) -{ - int i; - - gpmc_write_reg(GPMC_SYSCONFIG, gpmc_context.sysconfig); - gpmc_write_reg(GPMC_IRQENABLE, gpmc_context.irqenable); - gpmc_write_reg(GPMC_TIMEOUT_CONTROL, gpmc_context.timeout_ctrl); - gpmc_write_reg(GPMC_CONFIG, gpmc_context.config); - gpmc_write_reg(GPMC_PREFETCH_CONFIG1, gpmc_context.prefetch_config1); - gpmc_write_reg(GPMC_PREFETCH_CONFIG2, gpmc_context.prefetch_config2); - gpmc_write_reg(GPMC_PREFETCH_CONTROL, gpmc_context.prefetch_control); - for (i = 0; i < gpmc_cs_num; i++) { - if (gpmc_context.cs_context[i].is_valid) { - gpmc_cs_write_reg(i, GPMC_CS_CONFIG1, - gpmc_context.cs_context[i].config1); - gpmc_cs_write_reg(i, GPMC_CS_CONFIG2, - gpmc_context.cs_context[i].config2); - gpmc_cs_write_reg(i, GPMC_CS_CONFIG3, - gpmc_context.cs_context[i].config3); - gpmc_cs_write_reg(i, GPMC_CS_CONFIG4, - gpmc_context.cs_context[i].config4); - gpmc_cs_write_reg(i, GPMC_CS_CONFIG5, - gpmc_context.cs_context[i].config5); - gpmc_cs_write_reg(i, GPMC_CS_CONFIG6, - gpmc_context.cs_context[i].config6); - gpmc_cs_write_reg(i, GPMC_CS_CONFIG7, - gpmc_context.cs_context[i].config7); - } - } -} diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h index 707f6d58edd..9caa41a6cb0 100644 --- a/arch/arm/mach-omap2/gpmc.h +++ b/arch/arm/mach-omap2/gpmc.h @@ -6,226 +6,9 @@ * 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. + * + * Do not include this file in any new code, this will get removed + * once omap3 boots in device tree only mode. + * */ - -#ifndef __OMAP2_GPMC_H -#define __OMAP2_GPMC_H - -#include <linux/platform_data/mtd-nand-omap2.h> - -/* Maximum Number of Chip Selects */ -#define GPMC_CS_NUM 8 - -#define GPMC_CS_CONFIG1 0x00 -#define GPMC_CS_CONFIG2 0x04 -#define GPMC_CS_CONFIG3 0x08 -#define GPMC_CS_CONFIG4 0x0c -#define GPMC_CS_CONFIG5 0x10 -#define GPMC_CS_CONFIG6 0x14 -#define GPMC_CS_CONFIG7 0x18 -#define GPMC_CS_NAND_COMMAND 0x1c -#define GPMC_CS_NAND_ADDRESS 0x20 -#define GPMC_CS_NAND_DATA 0x24 - -/* Control Commands */ -#define GPMC_CONFIG_RDY_BSY 0x00000001 -#define GPMC_CONFIG_DEV_SIZE 0x00000002 -#define GPMC_CONFIG_DEV_TYPE 0x00000003 -#define GPMC_SET_IRQ_STATUS 0x00000004 -#define GPMC_CONFIG_WP 0x00000005 - -#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 */ -#define GPMC_ECC_READSYN 2 /* Reset before syndrom is read back */ - -#define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31) -#define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 30) -#define GPMC_CONFIG1_READTYPE_ASYNC (0 << 29) -#define GPMC_CONFIG1_READTYPE_SYNC (1 << 29) -#define GPMC_CONFIG1_WRITEMULTIPLE_SUPP (1 << 28) -#define GPMC_CONFIG1_WRITETYPE_ASYNC (0 << 27) -#define GPMC_CONFIG1_WRITETYPE_SYNC (1 << 27) -#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25) -#define GPMC_CONFIG1_PAGE_LEN(val) ((val & 3) << 23) -#define GPMC_CONFIG1_WAIT_READ_MON (1 << 22) -#define GPMC_CONFIG1_WAIT_WRITE_MON (1 << 21) -#define GPMC_CONFIG1_WAIT_MON_IIME(val) ((val & 3) << 18) -#define GPMC_CONFIG1_WAIT_PIN_SEL(val) ((val & 3) << 16) -#define GPMC_CONFIG1_DEVICESIZE(val) ((val & 3) << 12) -#define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1) -#define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10) -#define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0) -#define GPMC_CONFIG1_MUXTYPE(val) ((val & 3) << 8) -#define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4) -#define GPMC_CONFIG1_FCLK_DIV(val) (val & 3) -#define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1)) -#define GPMC_CONFIG1_FCLK_DIV3 (GPMC_CONFIG1_FCLK_DIV(2)) -#define GPMC_CONFIG1_FCLK_DIV4 (GPMC_CONFIG1_FCLK_DIV(3)) -#define GPMC_CONFIG7_CSVALID (1 << 6) - -#define GPMC_DEVICETYPE_NOR 0 -#define GPMC_DEVICETYPE_NAND 2 -#define GPMC_CONFIG_WRITEPROTECT 0x00000010 -#define WR_RD_PIN_MONITORING 0x00600000 -#define GPMC_IRQ_FIFOEVENTENABLE 0x01 -#define GPMC_IRQ_COUNT_EVENT 0x02 - -#define GPMC_BURST_4 4 /* 4 word burst */ -#define GPMC_BURST_8 8 /* 8 word burst */ -#define GPMC_BURST_16 16 /* 16 word burst */ -#define GPMC_DEVWIDTH_8BIT 1 /* 8-bit device width */ -#define GPMC_DEVWIDTH_16BIT 2 /* 16-bit device width */ -#define GPMC_MUX_AAD 1 /* Addr-Addr-Data multiplex */ -#define GPMC_MUX_AD 2 /* Addr-Data multiplex */ - -/* bool type time settings */ -struct gpmc_bool_timings { - bool cycle2cyclediffcsen; - bool cycle2cyclesamecsen; - bool we_extra_delay; - bool oe_extra_delay; - bool adv_extra_delay; - bool cs_extra_delay; - bool time_para_granularity; -}; - -/* - * Note that all values in this struct are in nanoseconds except sync_clk - * (which is in picoseconds), while the register values are in gpmc_fck cycles. - */ -struct gpmc_timings { - /* Minimum clock period for synchronous mode (in picoseconds) */ - u32 sync_clk; - - /* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */ - u32 cs_on; /* Assertion time */ - u32 cs_rd_off; /* Read deassertion time */ - u32 cs_wr_off; /* Write deassertion time */ - - /* ADV signal timings corresponding to GPMC_CONFIG3 */ - u32 adv_on; /* Assertion time */ - u32 adv_rd_off; /* Read deassertion time */ - u32 adv_wr_off; /* Write deassertion time */ - - /* WE signals timings corresponding to GPMC_CONFIG4 */ - u32 we_on; /* WE assertion time */ - u32 we_off; /* WE deassertion time */ - - /* OE signals timings corresponding to GPMC_CONFIG4 */ - u32 oe_on; /* OE assertion time */ - u32 oe_off; /* OE deassertion time */ - - /* Access time and cycle time timings corresponding to GPMC_CONFIG5 */ - u32 page_burst_access; /* Multiple access word delay */ - u32 access; /* Start-cycle to first data valid delay */ - u32 rd_cycle; /* Total read cycle time */ - u32 wr_cycle; /* Total write cycle time */ - - u32 bus_turnaround; - u32 cycle2cycle_delay; - - u32 wait_monitoring; - u32 clk_activation; - - /* The following are only on OMAP3430 */ - u32 wr_access; /* WRACCESSTIME */ - u32 wr_data_mux_bus; /* WRDATAONADMUXBUS */ - - struct gpmc_bool_timings bool_timings; -}; - -/* Device timings in picoseconds */ -struct gpmc_device_timings { - u32 t_ceasu; /* address setup to CS valid */ - u32 t_avdasu; /* address setup to ADV valid */ - /* XXX: try to combine t_avdp_r & t_avdp_w. Issue is - * of tusb using these timings even for sync whilst - * ideally for adv_rd/(wr)_off it should have considered - * t_avdh instead. This indirectly necessitates r/w - * variations of t_avdp as it is possible to have one - * sync & other async - */ - u32 t_avdp_r; /* ADV low time (what about t_cer ?) */ - u32 t_avdp_w; - u32 t_aavdh; /* address hold time */ - u32 t_oeasu; /* address setup to OE valid */ - u32 t_aa; /* access time from ADV assertion */ - u32 t_iaa; /* initial access time */ - u32 t_oe; /* access time from OE assertion */ - u32 t_ce; /* access time from CS asertion */ - u32 t_rd_cycle; /* read cycle time */ - u32 t_cez_r; /* read CS deassertion to high Z */ - u32 t_cez_w; /* write CS deassertion to high Z */ - u32 t_oez; /* OE deassertion to high Z */ - u32 t_weasu; /* address setup to WE valid */ - u32 t_wpl; /* write assertion time */ - u32 t_wph; /* write deassertion time */ - u32 t_wr_cycle; /* write cycle time */ - - u32 clk; - u32 t_bacc; /* burst access valid clock to output delay */ - u32 t_ces; /* CS setup time to clk */ - u32 t_avds; /* ADV setup time to clk */ - u32 t_avdh; /* ADV hold time from clk */ - u32 t_ach; /* address hold time from clk */ - u32 t_rdyo; /* clk to ready valid */ - - u32 t_ce_rdyz; /* XXX: description ?, or use t_cez instead */ - u32 t_ce_avd; /* CS on to ADV on delay */ - - /* XXX: check the possibility of combining - * cyc_aavhd_oe & cyc_aavdh_we - */ - u8 cyc_aavdh_oe;/* read address hold time in cycles */ - u8 cyc_aavdh_we;/* write address hold time in cycles */ - u8 cyc_oe; /* access time from OE assertion in cycles */ - u8 cyc_wpl; /* write deassertion time in cycles */ - u32 cyc_iaa; /* initial access time in cycles */ - - /* extra delays */ - bool ce_xdelay; - bool avd_xdelay; - bool oe_xdelay; - bool we_xdelay; -}; - -struct gpmc_settings { - bool burst_wrap; /* enables wrap bursting */ - bool burst_read; /* enables read page/burst mode */ - bool burst_write; /* enables write page/burst mode */ - bool device_nand; /* device is NAND */ - bool sync_read; /* enables synchronous reads */ - bool sync_write; /* enables synchronous writes */ - bool wait_on_read; /* monitor wait on reads */ - bool wait_on_write; /* monitor wait on writes */ - u32 burst_len; /* page/burst length */ - u32 device_width; /* device bus width (8 or 16 bit) */ - u32 mux_add_data; /* multiplex address & data */ - u32 wait_pin; /* wait-pin to be used */ -}; - -extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t, - struct gpmc_settings *gpmc_s, - struct gpmc_device_timings *dev_t); - -extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs); -extern int gpmc_get_client_irq(unsigned irq_config); - -extern unsigned int gpmc_ticks_to_ns(unsigned int ticks); - -extern void gpmc_cs_write_reg(int cs, int idx, u32 val); -extern int gpmc_calc_divider(unsigned int sync_clk); -extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t); -extern int gpmc_cs_program_settings(int cs, struct gpmc_settings *p); -extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base); -extern void gpmc_cs_free(int cs); -extern void omap3_gpmc_save_context(void); -extern void omap3_gpmc_restore_context(void); -extern int gpmc_configure(int cmd, int wval); -extern void gpmc_read_settings_dt(struct device_node *np, - struct gpmc_settings *p); - -#endif +#include <linux/omap-gpmc.h> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 175564c88a3..88721df6001 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -29,6 +29,7 @@ #include <linux/delay.h> #include <linux/slab.h> #include <linux/omap-dma.h> +#include <linux/omap-gpmc.h> #include <linux/platform_data/gpio-omap.h> #include <trace/events/power.h> @@ -43,7 +44,6 @@ #include "common.h" #include "cm3xxx.h" #include "cm-regbits-34xx.h" -#include "gpmc.h" #include "prm-regbits-34xx.h" #include "prm3xxx.h" #include "pm.h" |