summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r--arch/arm/mach-omap2/Makefile3
-rw-r--r--arch/arm/mach-omap2/board-2430sdp.c45
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c55
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c6
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c77
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c63
-rw-r--r--arch/arm/mach-omap2/board-devkit8000.c30
-rw-r--r--arch/arm/mach-omap2/board-h4.c2
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c2
-rw-r--r--arch/arm/mach-omap2/board-ldp.c63
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c72
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c7
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c14
-rw-r--r--arch/arm/mach-omap2/board-overo.c61
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c4
-rw-r--r--arch/arm/mach-omap2/board-rx51-video.c26
-rw-r--r--arch/arm/mach-omap2/board-zoom-display.c94
-rw-r--r--arch/arm/mach-omap2/board-zoom-peripherals.c53
-rw-r--r--arch/arm/mach-omap2/cclock44xx_data.c20
-rw-r--r--arch/arm/mach-omap2/common.h3
-rw-r--r--arch/arm/mach-omap2/dss-common.c58
-rw-r--r--arch/arm/mach-omap2/gpmc-nand.c42
-rw-r--r--arch/arm/mach-omap2/gpmc-onenand.c118
-rw-r--r--arch/arm/mach-omap2/gpmc-smc91x.c30
-rw-r--r--arch/arm/mach-omap2/gpmc.c544
-rw-r--r--arch/arm/mach-omap2/gpmc.h43
-rw-r--r--arch/arm/mach-omap2/io.c18
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c7
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.h9
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c7
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c6
-rw-r--r--arch/arm/mach-omap2/timer.c7
-rw-r--r--arch/arm/mach-omap2/usb-tusb6010.c62
34 files changed, 820 insertions, 833 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index b068b7fe99ef..62bb352c2d37 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -229,7 +229,6 @@ obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o
obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o
obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o
obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o
-obj-$(CONFIG_MACH_ENCORE) += board-omap3encore.o
obj-$(CONFIG_MACH_OVERO) += board-overo.o
obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o
obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o
@@ -255,8 +254,6 @@ obj-$(CONFIG_MACH_TOUCHBOOK) += board-omap3touchbook.o
obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o
obj-$(CONFIG_MACH_OMAP4_PANDA) += board-omap4panda.o
-obj-$(CONFIG_MACH_PCM049) += board-omap4pcm049.o
-
obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o
obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index cb0596b631cf..244d8a5aa54b 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -38,7 +38,7 @@
#include "gpmc-smc91x.h"
#include <video/omapdss.h>
-#include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-data.h>
#include "mux.h"
#include "hsmmc.h"
@@ -108,24 +108,13 @@ static struct platform_device *sdp2430_devices[] __initdata = {
#define SDP2430_LCD_PANEL_BACKLIGHT_GPIO 91
#define SDP2430_LCD_PANEL_ENABLE_GPIO 154
-static int sdp2430_panel_enable_lcd(struct omap_dss_device *dssdev)
-{
- gpio_direction_output(SDP2430_LCD_PANEL_ENABLE_GPIO, 1);
- gpio_direction_output(SDP2430_LCD_PANEL_BACKLIGHT_GPIO, 1);
-
- return 0;
-}
-
-static void sdp2430_panel_disable_lcd(struct omap_dss_device *dssdev)
-{
- gpio_direction_output(SDP2430_LCD_PANEL_ENABLE_GPIO, 0);
- gpio_direction_output(SDP2430_LCD_PANEL_BACKLIGHT_GPIO, 0);
-}
-
static struct panel_generic_dpi_data sdp2430_panel_data = {
.name = "nec_nl2432dr22-11b",
- .platform_enable = sdp2430_panel_enable_lcd,
- .platform_disable = sdp2430_panel_disable_lcd,
+ .num_gpios = 2,
+ .gpios = {
+ SDP2430_LCD_PANEL_ENABLE_GPIO,
+ SDP2430_LCD_PANEL_BACKLIGHT_GPIO,
+ },
};
static struct omap_dss_device sdp2430_lcd_device = {
@@ -146,26 +135,6 @@ static struct omap_dss_board_info sdp2430_dss_data = {
.default_device = &sdp2430_lcd_device,
};
-static void __init sdp2430_display_init(void)
-{
- int r;
-
- static struct gpio gpios[] __initdata = {
- { SDP2430_LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW,
- "LCD reset" },
- { SDP2430_LCD_PANEL_BACKLIGHT_GPIO, GPIOF_OUT_INIT_LOW,
- "LCD Backlight" },
- };
-
- r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
- if (r) {
- pr_err("Cannot request LCD GPIOs, error %d\n", r);
- return;
- }
-
- omap_display_init(&sdp2430_dss_data);
-}
-
#if IS_ENABLED(CONFIG_SMC91X)
static struct omap_smc91x_platform_data board_smc91x_data = {
@@ -273,7 +242,7 @@ static void __init omap_2430sdp_init(void)
gpio_request_one(SECONDARY_LCD_GPIO, GPIOF_OUT_INIT_LOW,
"Secondary LCD backlight");
- sdp2430_display_init();
+ omap_display_init(&sdp2430_dss_data);
}
MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board")
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 7eb9651dd0f7..23b004afa3f8 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -35,7 +35,7 @@
#include "common.h"
#include <linux/omap-dma.h>
#include <video/omapdss.h>
-#include <video/omap-panel-tfp410.h>
+#include <video/omap-panel-data.h>
#include "gpmc.h"
#include "gpmc-smc91x.h"
@@ -108,53 +108,38 @@ static struct twl4030_keypad_data sdp3430_kp_data = {
#define SDP3430_LCD_PANEL_BACKLIGHT_GPIO 8
#define SDP3430_LCD_PANEL_ENABLE_GPIO 5
-static struct gpio sdp3430_dss_gpios[] __initdata = {
- {SDP3430_LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW, "LCD reset" },
- {SDP3430_LCD_PANEL_BACKLIGHT_GPIO, GPIOF_OUT_INIT_LOW, "LCD Backlight"},
-};
-
static void __init sdp3430_display_init(void)
{
int r;
- r = gpio_request_array(sdp3430_dss_gpios,
- ARRAY_SIZE(sdp3430_dss_gpios));
+ /*
+ * 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)
- printk(KERN_ERR "failed to get LCD control GPIOs\n");
-
-}
+ pr_err("failed to get LCD Backlight GPIO\n");
-static int sdp3430_panel_enable_lcd(struct omap_dss_device *dssdev)
-{
- gpio_direction_output(SDP3430_LCD_PANEL_ENABLE_GPIO, 1);
- gpio_direction_output(SDP3430_LCD_PANEL_BACKLIGHT_GPIO, 1);
-
- return 0;
-}
-
-static void sdp3430_panel_disable_lcd(struct omap_dss_device *dssdev)
-{
- gpio_direction_output(SDP3430_LCD_PANEL_ENABLE_GPIO, 0);
- gpio_direction_output(SDP3430_LCD_PANEL_BACKLIGHT_GPIO, 0);
-}
-
-static int sdp3430_panel_enable_tv(struct omap_dss_device *dssdev)
-{
- return 0;
-}
-
-static void sdp3430_panel_disable_tv(struct omap_dss_device *dssdev)
-{
}
+static struct panel_sharp_ls037v7dw01_data sdp3430_lcd_data = {
+ .resb_gpio = SDP3430_LCD_PANEL_ENABLE_GPIO,
+ .ini_gpio = -1,
+ .mo_gpio = -1,
+ .lr_gpio = -1,
+ .ud_gpio = -1,
+};
static struct omap_dss_device sdp3430_lcd_device = {
.name = "lcd",
.driver_name = "sharp_ls_panel",
.type = OMAP_DISPLAY_TYPE_DPI,
.phy.dpi.data_lines = 16,
- .platform_enable = sdp3430_panel_enable_lcd,
- .platform_disable = sdp3430_panel_disable_lcd,
+ .data = &sdp3430_lcd_data,
};
static struct tfp410_platform_data dvi_panel = {
@@ -175,8 +160,6 @@ static struct omap_dss_device sdp3430_tv_device = {
.driver_name = "venc",
.type = OMAP_DISPLAY_TYPE_VENC,
.phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
- .platform_enable = sdp3430_panel_enable_tv,
- .platform_disable = sdp3430_panel_disable_tv,
};
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 306df0b40935..56a9a4f855c7 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -291,6 +291,10 @@ static struct platform_device sdp4430_leds_pwm = {
},
};
+/* Dummy regulator for pwm-backlight driver */
+static struct regulator_consumer_supply backlight_supply =
+ REGULATOR_SUPPLY("enable", "pwm-backlight");
+
static struct platform_pwm_backlight_data sdp4430_backlight_data = {
.max_brightness = 127,
.dft_brightness = 127,
@@ -718,6 +722,8 @@ static void __init omap_4430sdp_init(void)
omap4_i2c_init();
omap_sfh7741prox_init();
+ regulator_register_always_on(0, "backlight-enable",
+ &backlight_supply, 1, 0);
platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
omap_serial_init();
omap_sdrc_init(NULL, NULL);
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 191f9762ba63..d63f14b534b5 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -35,8 +35,7 @@
#include "common.h"
#include <video/omapdss.h>
-#include <video/omap-panel-generic-dpi.h>
-#include <video/omap-panel-tfp410.h>
+#include <video/omap-panel-data.h>
#include "am35xx-emac.h"
#include "mux.h"
@@ -121,63 +120,14 @@ static int __init am3517_evm_i2c_init(void)
return 0;
}
-static int lcd_enabled;
-static int dvi_enabled;
-
-#if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \
- defined(CONFIG_PANEL_SHARP_LQ043T1DG01_MODULE)
-static struct gpio am3517_evm_dss_gpios[] __initdata = {
- /* GPIO 182 = LCD Backlight Power */
- { LCD_PANEL_BKLIGHT_PWR, GPIOF_OUT_INIT_HIGH, "lcd_backlight_pwr" },
- /* GPIO 181 = LCD Panel PWM */
- { LCD_PANEL_PWM, GPIOF_OUT_INIT_HIGH, "lcd bl enable" },
- /* GPIO 176 = LCD Panel Power enable pin */
- { LCD_PANEL_PWR, GPIOF_OUT_INIT_HIGH, "dvi enable" },
-};
-
-static void __init am3517_evm_display_init(void)
-{
- int r;
-
- omap_mux_init_gpio(LCD_PANEL_PWR, OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_gpio(LCD_PANEL_BKLIGHT_PWR, OMAP_PIN_INPUT_PULLDOWN);
- omap_mux_init_gpio(LCD_PANEL_PWM, OMAP_PIN_INPUT_PULLDOWN);
-
- r = gpio_request_array(am3517_evm_dss_gpios,
- ARRAY_SIZE(am3517_evm_dss_gpios));
- if (r) {
- printk(KERN_ERR "failed to get DSS panel control GPIOs\n");
- return;
- }
-
- printk(KERN_INFO "Display initialized successfully\n");
-}
-#else
-static void __init am3517_evm_display_init(void) {}
-#endif
-
-static int am3517_evm_panel_enable_lcd(struct omap_dss_device *dssdev)
-{
- if (dvi_enabled) {
- printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
- return -EINVAL;
- }
- gpio_set_value(LCD_PANEL_PWR, 1);
- lcd_enabled = 1;
-
- return 0;
-}
-
-static void am3517_evm_panel_disable_lcd(struct omap_dss_device *dssdev)
-{
- gpio_set_value(LCD_PANEL_PWR, 0);
- lcd_enabled = 0;
-}
-
static struct panel_generic_dpi_data lcd_panel = {
.name = "sharp_lq",
- .platform_enable = am3517_evm_panel_enable_lcd,
- .platform_disable = am3517_evm_panel_disable_lcd,
+ .num_gpios = 3,
+ .gpios = {
+ LCD_PANEL_PWR,
+ LCD_PANEL_BKLIGHT_PWR,
+ LCD_PANEL_PWM,
+ },
};
static struct omap_dss_device am3517_evm_lcd_device = {
@@ -188,22 +138,11 @@ static struct omap_dss_device am3517_evm_lcd_device = {
.phy.dpi.data_lines = 16,
};
-static int am3517_evm_panel_enable_tv(struct omap_dss_device *dssdev)
-{
- return 0;
-}
-
-static void am3517_evm_panel_disable_tv(struct omap_dss_device *dssdev)
-{
-}
-
static struct omap_dss_device am3517_evm_tv_device = {
.type = OMAP_DISPLAY_TYPE_VENC,
.name = "tv",
.driver_name = "venc",
.phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
- .platform_enable = am3517_evm_panel_enable_tv,
- .platform_disable = am3517_evm_panel_disable_tv,
};
static struct tfp410_platform_data dvi_panel = {
@@ -366,8 +305,6 @@ static void __init am3517_evm_init(void)
usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
usbhs_init(&usbhs_bdata);
am3517_evm_hecc_init(&am3517_evm_hecc_pdata);
- /* DSS */
- am3517_evm_display_init();
/* RTC - S35390A */
am3517_evm_rtc_init();
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 7fda3f5f8a7f..ee6218c74807 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -41,8 +41,7 @@
#include <linux/platform_data/mtd-nand-omap2.h>
#include <video/omapdss.h>
-#include <video/omap-panel-generic-dpi.h>
-#include <video/omap-panel-tfp410.h>
+#include <video/omap-panel-data.h>
#include <linux/platform_data/spi-omap2-mcspi.h>
#include "common.h"
@@ -191,45 +190,12 @@ static inline void cm_t35_init_nand(void) {}
#define CM_T35_LCD_BL_GPIO 58
#define CM_T35_DVI_EN_GPIO 54
-static int lcd_enabled;
-static int dvi_enabled;
-
-static int cm_t35_panel_enable_lcd(struct omap_dss_device *dssdev)
-{
- if (dvi_enabled) {
- printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
- return -EINVAL;
- }
-
- gpio_set_value(CM_T35_LCD_EN_GPIO, 1);
- gpio_set_value(CM_T35_LCD_BL_GPIO, 1);
-
- lcd_enabled = 1;
-
- return 0;
-}
-
-static void cm_t35_panel_disable_lcd(struct omap_dss_device *dssdev)
-{
- lcd_enabled = 0;
-
- gpio_set_value(CM_T35_LCD_BL_GPIO, 0);
- gpio_set_value(CM_T35_LCD_EN_GPIO, 0);
-}
-
-static int cm_t35_panel_enable_tv(struct omap_dss_device *dssdev)
-{
- return 0;
-}
-
-static void cm_t35_panel_disable_tv(struct omap_dss_device *dssdev)
-{
-}
-
static struct panel_generic_dpi_data lcd_panel = {
.name = "toppoly_tdo35s",
- .platform_enable = cm_t35_panel_enable_lcd,
- .platform_disable = cm_t35_panel_disable_lcd,
+ .num_gpios = 1,
+ .gpios = {
+ CM_T35_LCD_BL_GPIO,
+ },
};
static struct omap_dss_device cm_t35_lcd_device = {
@@ -258,8 +224,6 @@ static struct omap_dss_device cm_t35_tv_device = {
.driver_name = "venc",
.type = OMAP_DISPLAY_TYPE_VENC,
.phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
- .platform_enable = cm_t35_panel_enable_tv,
- .platform_disable = cm_t35_panel_disable_tv,
};
static struct omap_dss_device *cm_t35_dss_devices[] = {
@@ -293,11 +257,6 @@ static struct spi_board_info cm_t35_lcd_spi_board_info[] __initdata = {
},
};
-static struct gpio cm_t35_dss_gpios[] __initdata = {
- { CM_T35_LCD_EN_GPIO, GPIOF_OUT_INIT_LOW, "lcd enable" },
- { CM_T35_LCD_BL_GPIO, GPIOF_OUT_INIT_LOW, "lcd bl enable" },
-};
-
static void __init cm_t35_init_display(void)
{
int err;
@@ -305,23 +264,21 @@ static void __init cm_t35_init_display(void)
spi_register_board_info(cm_t35_lcd_spi_board_info,
ARRAY_SIZE(cm_t35_lcd_spi_board_info));
- err = gpio_request_array(cm_t35_dss_gpios,
- ARRAY_SIZE(cm_t35_dss_gpios));
+
+ err = gpio_request_one(CM_T35_LCD_EN_GPIO, GPIOF_OUT_INIT_LOW,
+ "lcd bl enable");
if (err) {
- pr_err("CM-T35: failed to request DSS control GPIOs\n");
+ pr_err("CM-T35: failed to request LCD EN GPIO\n");
return;
}
- gpio_export(CM_T35_LCD_EN_GPIO, 0);
- gpio_export(CM_T35_LCD_BL_GPIO, 0);
-
msleep(50);
gpio_set_value(CM_T35_LCD_EN_GPIO, 1);
err = omap_display_init(&cm_t35_dss_data);
if (err) {
pr_err("CM-T35: failed to register DSS device\n");
- gpio_free_array(cm_t35_dss_gpios, ARRAY_SIZE(cm_t35_dss_gpios));
+ gpio_free(CM_T35_LCD_EN_GPIO);
}
}
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 42fbf1ef12a9..576420544178 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -43,8 +43,7 @@
#include "gpmc.h"
#include <linux/platform_data/mtd-nand-omap2.h>
#include <video/omapdss.h>
-#include <video/omap-panel-generic-dpi.h>
-#include <video/omap-panel-tfp410.h>
+#include <video/omap-panel-data.h>
#include <linux/platform_data/spi-omap2-mcspi.h>
#include <linux/input/matrix_keypad.h>
@@ -104,19 +103,6 @@ static struct omap2_hsmmc_info mmc[] = {
{} /* Terminator */
};
-static int devkit8000_panel_enable_lcd(struct omap_dss_device *dssdev)
-{
- if (gpio_is_valid(dssdev->reset_gpio))
- gpio_set_value_cansleep(dssdev->reset_gpio, 1);
- return 0;
-}
-
-static void devkit8000_panel_disable_lcd(struct omap_dss_device *dssdev)
-{
- if (gpio_is_valid(dssdev->reset_gpio))
- gpio_set_value_cansleep(dssdev->reset_gpio, 0);
-}
-
static struct regulator_consumer_supply devkit8000_vmmc1_supply[] = {
REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
};
@@ -128,8 +114,7 @@ static struct regulator_consumer_supply devkit8000_vio_supply[] = {
static struct panel_generic_dpi_data lcd_panel = {
.name = "innolux_at070tn83",
- .platform_enable = devkit8000_panel_enable_lcd,
- .platform_disable = devkit8000_panel_disable_lcd,
+ /* gpios filled in code */
};
static struct omap_dss_device devkit8000_lcd_device = {
@@ -211,8 +196,6 @@ static struct gpio_led gpio_leds[];
static int devkit8000_twl_gpio_setup(struct device *dev,
unsigned gpio, unsigned ngpio)
{
- int ret;
-
/* gpio + 0 is "mmc0_cd" (input/IRQ) */
mmc[0].gpio_cd = gpio + 0;
omap_hsmmc_late_init(mmc);
@@ -221,13 +204,8 @@ static int devkit8000_twl_gpio_setup(struct device *dev,
gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
/* TWL4030_GPIO_MAX + 0 is "LCD_PWREN" (out, active high) */
- devkit8000_lcd_device.reset_gpio = gpio + TWL4030_GPIO_MAX + 0;
- ret = gpio_request_one(devkit8000_lcd_device.reset_gpio,
- GPIOF_OUT_INIT_LOW, "LCD_PWREN");
- if (ret < 0) {
- devkit8000_lcd_device.reset_gpio = -EINVAL;
- printk(KERN_ERR "Failed to request GPIO for LCD_PWRN\n");
- }
+ lcd_panel.num_gpios = 1;
+ lcd_panel.gpios[0] = gpio + TWL4030_GPIO_MAX + 0;
/* gpio + 7 is "DVI_PD" (out, active low) */
dvi_panel.power_down_gpio = gpio + 7;
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 5b4ec51c385f..69c0acf5aa63 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -34,7 +34,7 @@
#include <asm/mach/map.h>
#include <video/omapdss.h>
-#include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-data.h>
#include "common.h"
#include "mux.h"
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 95ccec0eeab9..b54562d1235e 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -31,7 +31,7 @@
#include <asm/mach/arch.h>
#include <video/omapdss.h>
-#include <video/omap-panel-tfp410.h>
+#include <video/omap-panel-data.h>
#include <linux/platform_data/mtd-onenand-omap2.h>
#include "common.h"
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index b12fe966a7b9..d0d17bc58d9b 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -41,7 +41,7 @@
#include "gpmc-smsc911x.h"
#include <video/omapdss.h>
-#include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-data.h>
#include "board-flash.h"
#include "mux.h"
@@ -181,34 +181,13 @@ static inline void __init ldp_init_smsc911x(void)
/* LCD */
-static int ldp_backlight_gpio;
-static int ldp_lcd_enable_gpio;
-
#define LCD_PANEL_RESET_GPIO 55
#define LCD_PANEL_QVGA_GPIO 56
-static int ldp_panel_enable_lcd(struct omap_dss_device *dssdev)
-{
- if (gpio_is_valid(ldp_lcd_enable_gpio))
- gpio_direction_output(ldp_lcd_enable_gpio, 1);
- if (gpio_is_valid(ldp_backlight_gpio))
- gpio_direction_output(ldp_backlight_gpio, 1);
-
- return 0;
-}
-
-static void ldp_panel_disable_lcd(struct omap_dss_device *dssdev)
-{
- if (gpio_is_valid(ldp_lcd_enable_gpio))
- gpio_direction_output(ldp_lcd_enable_gpio, 0);
- if (gpio_is_valid(ldp_backlight_gpio))
- gpio_direction_output(ldp_backlight_gpio, 0);
-}
-
static struct panel_generic_dpi_data ldp_panel_data = {
.name = "nec_nl2432dr22-11b",
- .platform_enable = ldp_panel_enable_lcd,
- .platform_disable = ldp_panel_disable_lcd,
+ .num_gpios = 4,
+ /* gpios filled in code */
};
static struct omap_dss_device ldp_lcd_device = {
@@ -231,41 +210,19 @@ static struct omap_dss_board_info ldp_dss_data = {
static void __init ldp_display_init(void)
{
- int r;
-
- static struct gpio gpios[] __initdata = {
- {LCD_PANEL_RESET_GPIO, GPIOF_OUT_INIT_HIGH, "LCD RESET"},
- {LCD_PANEL_QVGA_GPIO, GPIOF_OUT_INIT_HIGH, "LCD QVGA"},
- };
-
- r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
- if (r) {
- pr_err("Cannot request LCD GPIOs, error %d\n", r);
- return;
- }
+ ldp_panel_data.gpios[2] = LCD_PANEL_RESET_GPIO;
+ ldp_panel_data.gpios[3] = LCD_PANEL_QVGA_GPIO;
omap_display_init(&ldp_dss_data);
}
static int ldp_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio)
{
- int r;
-
- struct gpio gpios[] = {
- {gpio + 7 , GPIOF_OUT_INIT_LOW, "LCD ENABLE"},
- {gpio + 15, GPIOF_OUT_INIT_LOW, "LCD BACKLIGHT"},
- };
-
- r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
- if (r) {
- pr_err("Cannot request LCD GPIOs, error %d\n", r);
- ldp_backlight_gpio = -EINVAL;
- ldp_lcd_enable_gpio = -EINVAL;
- return r;
- }
-
- ldp_backlight_gpio = gpio + 15;
- ldp_lcd_enable_gpio = gpio + 7;
+ ldp_panel_data.gpios[0] = gpio + 7;
+ ldp_panel_data.gpio_invert[0] = true;
+
+ ldp_panel_data.gpios[1] = gpio + 15;
+ ldp_panel_data.gpio_invert[1] = true;
return 0;
}
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 6955a428f534..6de78605c0af 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -44,7 +44,7 @@
#include <asm/mach/flash.h>
#include <video/omapdss.h>
-#include <video/omap-panel-tfp410.h>
+#include <video/omap-panel-data.h>
#include <linux/platform_data/mtd-nand-omap2.h>
#include "common.h"
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 2de92facc8a3..f76d0de7b406 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -51,7 +51,7 @@
#include "common.h"
#include <linux/platform_data/spi-omap2-mcspi.h>
#include <video/omapdss.h>
-#include <video/omap-panel-tfp410.h>
+#include <video/omap-panel-data.h>
#include "soc.h"
#include "mux.h"
@@ -155,61 +155,43 @@ static inline void __init omap3evm_init_smsc911x(void) { return; }
#define OMAP3EVM_LCD_PANEL_LR 2
#define OMAP3EVM_LCD_PANEL_UD 3
#define OMAP3EVM_LCD_PANEL_INI 152
-#define OMAP3EVM_LCD_PANEL_ENVDD 153
#define OMAP3EVM_LCD_PANEL_QVGA 154
#define OMAP3EVM_LCD_PANEL_RESB 155
+
+#define OMAP3EVM_LCD_PANEL_ENVDD 153
#define OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO 210
+
+/*
+ * OMAP3EVM DVI control signals
+ */
#define OMAP3EVM_DVI_PANEL_EN_GPIO 199
-static struct gpio omap3_evm_dss_gpios[] __initdata = {
- { OMAP3EVM_LCD_PANEL_RESB, GPIOF_OUT_INIT_HIGH, "lcd_panel_resb" },
- { OMAP3EVM_LCD_PANEL_INI, GPIOF_OUT_INIT_HIGH, "lcd_panel_ini" },
- { OMAP3EVM_LCD_PANEL_QVGA, GPIOF_OUT_INIT_LOW, "lcd_panel_qvga" },
- { OMAP3EVM_LCD_PANEL_LR, GPIOF_OUT_INIT_HIGH, "lcd_panel_lr" },
- { OMAP3EVM_LCD_PANEL_UD, GPIOF_OUT_INIT_HIGH, "lcd_panel_ud" },
- { OMAP3EVM_LCD_PANEL_ENVDD, GPIOF_OUT_INIT_LOW, "lcd_panel_envdd" },
+static struct panel_sharp_ls037v7dw01_data omap3_evm_lcd_data = {
+ .resb_gpio = OMAP3EVM_LCD_PANEL_RESB,
+ .ini_gpio = OMAP3EVM_LCD_PANEL_INI,
+ .mo_gpio = OMAP3EVM_LCD_PANEL_QVGA,
+ .lr_gpio = OMAP3EVM_LCD_PANEL_LR,
+ .ud_gpio = OMAP3EVM_LCD_PANEL_UD,
};
-static int lcd_enabled;
-static int dvi_enabled;
-
static void __init omap3_evm_display_init(void)
{
int r;
- r = gpio_request_array(omap3_evm_dss_gpios,
- ARRAY_SIZE(omap3_evm_dss_gpios));
+ r = gpio_request_one(OMAP3EVM_LCD_PANEL_ENVDD, GPIOF_OUT_INIT_LOW,
+ "lcd_panel_envdd");
if (r)
- printk(KERN_ERR "failed to get lcd_panel_* gpios\n");
-}
+ pr_err("failed to get lcd_panel_envdd GPIO\n");
-static int omap3_evm_enable_lcd(struct omap_dss_device *dssdev)
-{
- if (dvi_enabled) {
- printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
- return -EINVAL;
- }
- gpio_set_value(OMAP3EVM_LCD_PANEL_ENVDD, 0);
+ r = gpio_request_one(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO,
+ GPIOF_OUT_INIT_LOW, "lcd_panel_bklight");
+ if (r)
+ pr_err("failed to get lcd_panel_bklight GPIO\n");
if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2)
gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0);
else
gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1);
-
- lcd_enabled = 1;
- return 0;
-}
-
-static void omap3_evm_disable_lcd(struct omap_dss_device *dssdev)
-{
- gpio_set_value(OMAP3EVM_LCD_PANEL_ENVDD, 1);
-
- if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2)
- gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1);
- else
- gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0);
-
- lcd_enabled = 0;
}
static struct omap_dss_device omap3_evm_lcd_device = {
@@ -217,26 +199,14 @@ static struct omap_dss_device omap3_evm_lcd_device = {
.driver_name = "sharp_ls_panel",
.type = OMAP_DISPLAY_TYPE_DPI,
.phy.dpi.data_lines = 18,
- .platform_enable = omap3_evm_enable_lcd,
- .platform_disable = omap3_evm_disable_lcd,
+ .data = &omap3_evm_lcd_data,
};
-static int omap3_evm_enable_tv(struct omap_dss_device *dssdev)
-{
- return 0;
-}
-
-static void omap3_evm_disable_tv(struct omap_dss_device *dssdev)
-{
-}
-
static struct omap_dss_device omap3_evm_tv_device = {
.name = "tv",
.driver_name = "venc",
.type = OMAP_DISPLAY_TYPE_VENC,
.phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
- .platform_enable = omap3_evm_enable_tv,
- .platform_disable = omap3_evm_disable_tv,
};
static struct tfp410_platform_data dvi_panel = {
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 1004d2aaa68f..28133d5b4fed 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -44,6 +44,7 @@
#include "common.h"
#include <video/omapdss.h>
+#include <video/omap-panel-data.h>
#include <linux/platform_data/mtd-nand-omap2.h>
#include "mux.h"
@@ -230,12 +231,16 @@ static struct twl4030_keypad_data pandora_kp_data = {
.rep = 1,
};
+static struct panel_tpo_td043_data lcd_data = {
+ .nreset_gpio = 157,
+};
+
static struct omap_dss_device pandora_lcd_device = {
.name = "lcd",
.driver_name = "tpo_td043mtea1_panel",
.type = OMAP_DISPLAY_TYPE_DPI,
.phy.dpi.data_lines = 24,
- .reset_gpio = 157,
+ .data = &lcd_data,
};
static struct omap_dss_device pandora_tv_device = {
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index bf0956489899..d37e6b187ae4 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -44,8 +44,7 @@
#include "gpmc.h"
#include <linux/platform_data/mtd-nand-omap2.h>
#include <video/omapdss.h>
-#include <video/omap-panel-generic-dpi.h>
-#include <video/omap-panel-tfp410.h>
+#include <video/omap-panel-data.h>
#include <linux/platform_data/spi-omap2-mcspi.h>
@@ -95,15 +94,6 @@ static void __init omap3_stalker_display_init(void)
return;
}
-static int omap3_stalker_enable_tv(struct omap_dss_device *dssdev)
-{
- return 0;
-}
-
-static void omap3_stalker_disable_tv(struct omap_dss_device *dssdev)
-{
-}
-
static struct omap_dss_device omap3_stalker_tv_device = {
.name = "tv",
.driver_name = "venc",
@@ -113,8 +103,6 @@ static struct omap_dss_device omap3_stalker_tv_device = {
#elif defined(CONFIG_OMAP2_VENC_OUT_TYPE_COMPOSITE)
.u.venc.type = OMAP_DSS_VENC_TYPE_COMPOSITE,
#endif
- .platform_enable = omap3_stalker_enable_tv,
- .platform_disable = omap3_stalker_disable_tv,
};
static struct tfp410_platform_data dvi_panel = {
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index ab79a4422bcc..4ca6b680aa72 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -47,8 +47,7 @@
#include <asm/mach/map.h>
#include <video/omapdss.h>
-#include <video/omap-panel-generic-dpi.h>
-#include <video/omap-panel-tfp410.h>
+#include <video/omap-panel-data.h>
#include "common.h"
#include "mux.h"
@@ -146,28 +145,9 @@ static inline void __init overo_init_smsc911x(void) { return; }
#endif
/* DSS */
-static int lcd_enabled;
-static int dvi_enabled;
-
#define OVERO_GPIO_LCD_EN 144
#define OVERO_GPIO_LCD_BL 145
-static struct gpio overo_dss_gpios[] __initdata = {
- { OVERO_GPIO_LCD_EN, GPIOF_OUT_INIT_HIGH, "OVERO_GPIO_LCD_EN" },
- { OVERO_GPIO_LCD_BL, GPIOF_OUT_INIT_HIGH, "OVERO_GPIO_LCD_BL" },
-};
-
-static void __init overo_display_init(void)
-{
- if (gpio_request_array(overo_dss_gpios, ARRAY_SIZE(overo_dss_gpios))) {
- printk(KERN_ERR "could not obtain DSS control GPIOs\n");
- return;
- }
-
- gpio_export(OVERO_GPIO_LCD_EN, 0);
- gpio_export(OVERO_GPIO_LCD_BL, 0);
-}
-
static struct tfp410_platform_data dvi_panel = {
.i2c_bus_num = 3,
.power_down_gpio = -1,
@@ -188,30 +168,13 @@ static struct omap_dss_device overo_tv_device = {
.phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
};
-static int overo_panel_enable_lcd(struct omap_dss_device *dssdev)
-{
- if (dvi_enabled) {
- printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
- return -EINVAL;
- }
-
- gpio_set_value(OVERO_GPIO_LCD_EN, 1);
- gpio_set_value(OVERO_GPIO_LCD_BL, 1);
- lcd_enabled = 1;
- return 0;
-}
-
-static void overo_panel_disable_lcd(struct omap_dss_device *dssdev)
-{
- gpio_set_value(OVERO_GPIO_LCD_EN, 0);
- gpio_set_value(OVERO_GPIO_LCD_BL, 0);
- lcd_enabled = 0;
-}
-
static struct panel_generic_dpi_data lcd43_panel = {
.name = "samsung_lte430wq_f0c",
- .platform_enable = overo_panel_enable_lcd,
- .platform_disable = overo_panel_disable_lcd,
+ .num_gpios = 2,
+ .gpios = {
+ OVERO_GPIO_LCD_EN,
+ OVERO_GPIO_LCD_BL
+ },
};
static struct omap_dss_device overo_lcd43_device = {
@@ -224,13 +187,20 @@ static struct omap_dss_device overo_lcd43_device = {
#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
+static struct panel_generic_dpi_data lcd35_panel = {
+ .num_gpios = 2,
+ .gpios = {
+ OVERO_GPIO_LCD_EN,
+ OVERO_GPIO_LCD_BL
+ },
+};
+
static struct omap_dss_device overo_lcd35_device = {
.type = OMAP_DISPLAY_TYPE_DPI,
.name = "lcd35",
.driver_name = "lgphilips_lb035q02_panel",
.phy.dpi.data_lines = 24,
- .platform_enable = overo_panel_enable_lcd,
- .platform_disable = overo_panel_disable_lcd,
+ .data = &lcd35_panel,
};
#endif
@@ -509,7 +479,6 @@ static void __init overo_init(void)
usbhs_init(&usbhs_bdata);
overo_spi_init();
overo_init_smsc911x();
- overo_display_init();
overo_init_led();
overo_init_keys();
omap_twl4030_audio_init("overo", NULL);
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 3a077df6b8df..1a884670a6c4 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -547,12 +547,16 @@ static struct regulator_consumer_supply rx51_vio_supplies[] = {
REGULATOR_SUPPLY("DVDD", "2-0019"),
/* Si4713 IO supply */
REGULATOR_SUPPLY("vio", "2-0063"),
+ /* lis3lv02d */
+ REGULATOR_SUPPLY("Vdd_IO", "3-001d"),
};
static struct regulator_consumer_supply rx51_vaux1_consumers[] = {
REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
/* Si4713 supply */
REGULATOR_SUPPLY("vdd", "2-0063"),
+ /* lis3lv02d */
+ REGULATOR_SUPPLY("Vdd", "3-001d"),
};
static struct regulator_init_data rx51_vaux1 = {
diff --git a/arch/arm/mach-omap2/board-rx51-video.c b/arch/arm/mach-omap2/board-rx51-video.c
index eb667261df08..bd74f9f6063b 100644
--- a/arch/arm/mach-omap2/board-rx51-video.c
+++ b/arch/arm/mach-omap2/board-rx51-video.c
@@ -16,6 +16,8 @@
#include <linux/mm.h>
#include <asm/mach-types.h>
#include <video/omapdss.h>
+#include <video/omap-panel-data.h>
+
#include <linux/platform_data/spi-omap2-mcspi.h>
#include "soc.h"
@@ -27,25 +29,16 @@
#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
-static int rx51_lcd_enable(struct omap_dss_device *dssdev)
-{
- gpio_set_value(dssdev->reset_gpio, 1);
- return 0;
-}
-
-static void rx51_lcd_disable(struct omap_dss_device *dssdev)
-{
- gpio_set_value(dssdev->reset_gpio, 0);
-}
+static struct panel_acx565akm_data lcd_data = {
+ .reset_gpio = RX51_LCD_RESET_GPIO,
+};
static struct omap_dss_device rx51_lcd_device = {
.name = "lcd",
.driver_name = "panel-acx565akm",
.type = OMAP_DISPLAY_TYPE_SDI,
.phy.sdi.datapairs = 2,
- .reset_gpio = RX51_LCD_RESET_GPIO,
- .platform_enable = rx51_lcd_enable,
- .platform_disable = rx51_lcd_disable,
+ .data = &lcd_data,
};
static struct omap_dss_device rx51_tv_device = {
@@ -76,13 +69,8 @@ static int __init rx51_video_init(void)
return 0;
}
- if (gpio_request_one(RX51_LCD_RESET_GPIO, GPIOF_OUT_INIT_HIGH,
- "LCD ACX565AKM reset")) {
- pr_err("%s failed to get LCD Reset GPIO\n", __func__);
- return 0;
- }
-
omap_display_init(&rx51_dss_board_info);
+
return 0;
}
diff --git a/arch/arm/mach-omap2/board-zoom-display.c b/arch/arm/mach-omap2/board-zoom-display.c
index 8cef477d6b00..c2a079cb76fc 100644
--- a/arch/arm/mach-omap2/board-zoom-display.c
+++ b/arch/arm/mach-omap2/board-zoom-display.c
@@ -12,12 +12,12 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
-#include <linux/i2c/twl.h>
#include <linux/spi/spi.h>
#include <linux/platform_data/spi-omap2-mcspi.h>
#include <video/omapdss.h>
-#include "board-zoom.h"
+#include <video/omap-panel-data.h>
+#include "board-zoom.h"
#include "soc.h"
#include "common.h"
@@ -25,92 +25,17 @@
#define LCD_PANEL_RESET_GPIO_PILOT 55
#define LCD_PANEL_QVGA_GPIO 56
-static struct gpio zoom_lcd_gpios[] __initdata = {
- { -EINVAL, GPIOF_OUT_INIT_HIGH, "lcd reset" },
- { LCD_PANEL_QVGA_GPIO, GPIOF_OUT_INIT_HIGH, "lcd qvga" },
+static struct panel_nec_nl8048_data zoom_lcd_data = {
+ /* res_gpio filled in code */
+ .qvga_gpio = LCD_PANEL_QVGA_GPIO,
};
-static void __init zoom_lcd_panel_init(void)
-{
- zoom_lcd_gpios[0].gpio = (omap_rev() > OMAP3430_REV_ES3_0) ?
- LCD_PANEL_RESET_GPIO_PROD :
- LCD_PANEL_RESET_GPIO_PILOT;
-
- if (gpio_request_array(zoom_lcd_gpios, ARRAY_SIZE(zoom_lcd_gpios)))
- pr_err("%s: Failed to get LCD GPIOs.\n", __func__);
-}
-
-static int zoom_panel_enable_lcd(struct omap_dss_device *dssdev)
-{
- return 0;
-}
-
-static void zoom_panel_disable_lcd(struct omap_dss_device *dssdev)
-{
-}
-
-/* Register offsets in TWL4030_MODULE_INTBR */
-#define TWL_INTBR_PMBR1 0xD
-#define TWL_INTBR_GPBR1 0xC
-
-/* Register offsets in TWL_MODULE_PWM */
-#define TWL_LED_PWMON 0x3
-#define TWL_LED_PWMOFF 0x4
-
-static int zoom_set_bl_intensity(struct omap_dss_device *dssdev, int level)
-{
-#ifdef CONFIG_TWL4030_CORE
- unsigned char c;
- u8 mux_pwm, enb_pwm;
-
- if (level > 100)
- return -1;
-
- twl_i2c_read_u8(TWL4030_MODULE_INTBR, &mux_pwm, TWL_INTBR_PMBR1);
- twl_i2c_read_u8(TWL4030_MODULE_INTBR, &enb_pwm, TWL_INTBR_GPBR1);
-
- if (level == 0) {
- /* disable pwm1 output and clock */
- enb_pwm = enb_pwm & 0xF5;
- /* change pwm1 pin to gpio pin */
- mux_pwm = mux_pwm & 0xCF;
- twl_i2c_write_u8(TWL4030_MODULE_INTBR,
- enb_pwm, TWL_INTBR_GPBR1);
- twl_i2c_write_u8(TWL4030_MODULE_INTBR,
- mux_pwm, TWL_INTBR_PMBR1);
- return 0;
- }
-
- if (!((enb_pwm & 0xA) && (mux_pwm & 0x30))) {
- /* change gpio pin to pwm1 pin */
- mux_pwm = mux_pwm | 0x30;
- /* enable pwm1 output and clock*/
- enb_pwm = enb_pwm | 0x0A;
- twl_i2c_write_u8(TWL4030_MODULE_INTBR,
- mux_pwm, TWL_INTBR_PMBR1);
- twl_i2c_write_u8(TWL4030_MODULE_INTBR,
- enb_pwm, TWL_INTBR_GPBR1);
- }
-
- c = ((50 * (100 - level)) / 100) + 1;
- twl_i2c_write_u8(TWL_MODULE_PWM, 0x7F, TWL_LED_PWMOFF);
- twl_i2c_write_u8(TWL_MODULE_PWM, c, TWL_LED_PWMON);
-#else
- pr_warn("Backlight not enabled\n");
-#endif
-
- return 0;
-}
-
static struct omap_dss_device zoom_lcd_device = {
.name = "lcd",
.driver_name = "NEC_8048_panel",
.type = OMAP_DISPLAY_TYPE_DPI,
.phy.dpi.data_lines = 24,
- .platform_enable = zoom_panel_enable_lcd,
- .platform_disable = zoom_panel_disable_lcd,
- .max_backlight_level = 100,
- .set_backlight = zoom_set_bl_intensity,
+ .data = &zoom_lcd_data,
};
static struct omap_dss_device *zoom_dss_devices[] = {
@@ -123,6 +48,13 @@ static struct omap_dss_board_info zoom_dss_data = {
.default_device = &zoom_lcd_device,
};
+static void __init zoom_lcd_panel_init(void)
+{
+ zoom_lcd_data.res_gpio = (omap_rev() > OMAP3430_REV_ES3_0) ?
+ LCD_PANEL_RESET_GPIO_PROD :
+ LCD_PANEL_RESET_GPIO_PILOT;
+}
+
static struct omap2_mcspi_device_config dss_lcd_mcspi_config = {
.turbo_mode = 1,
};
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index cdc0c1021863..a90375d5b2b6 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -22,6 +22,9 @@
#include <linux/platform_data/gpio-omap.h>
#include <linux/platform_data/omap-twl4030.h>
#include <linux/usb/phy.h>
+#include <linux/pwm.h>
+#include <linux/leds_pwm.h>
+#include <linux/pwm_backlight.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -193,6 +196,53 @@ static struct platform_device omap_vwlan_device = {
},
};
+static struct pwm_lookup zoom_pwm_lookup[] = {
+ PWM_LOOKUP("twl-pwm", 0, "leds_pwm", "zoom::keypad"),
+ PWM_LOOKUP("twl-pwm", 1, "pwm-backlight", "backlight"),
+};
+
+static struct led_pwm zoom_pwm_leds[] = {
+ {
+ .name = "zoom::keypad",
+ .max_brightness = 127,
+ .pwm_period_ns = 7812500,
+ },
+};
+
+static struct led_pwm_platform_data zoom_pwm_data = {
+ .num_leds = ARRAY_SIZE(zoom_pwm_leds),
+ .leds = zoom_pwm_leds,
+};
+
+static struct platform_device zoom_leds_pwm = {
+ .name = "leds_pwm",
+ .id = -1,
+ .dev = {
+ .platform_data = &zoom_pwm_data,
+ },
+};
+
+static struct platform_pwm_backlight_data zoom_backlight_data = {
+ .pwm_id = 1,
+ .max_brightness = 127,
+ .dft_brightness = 127,
+ .pwm_period_ns = 7812500,
+};
+
+static struct platform_device zoom_backlight_pwm = {
+ .name = "pwm-backlight",
+ .id = -1,
+ .dev = {
+ .platform_data = &zoom_backlight_data,
+ },
+};
+
+static struct platform_device *zoom_devices[] __initdata = {
+ &omap_vwlan_device,
+ &zoom_leds_pwm,
+ &zoom_backlight_pwm,
+};
+
static struct wl12xx_platform_data omap_zoom_wlan_data __initdata = {
.board_ref_clock = WL12XX_REFCLOCK_26, /* 26 MHz */
};
@@ -301,7 +351,8 @@ void __init zoom_peripherals_init(void)
omap_hsmmc_init(mmc);
omap_i2c_init();
- platform_device_register(&omap_vwlan_device);
+ pwm_add_table(zoom_pwm_lookup, ARRAY_SIZE(zoom_pwm_lookup));
+ platform_add_devices(zoom_devices, ARRAY_SIZE(zoom_devices));
usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
usb_musb_init(NULL);
enable_board_wakeup_source();
diff --git a/arch/arm/mach-omap2/cclock44xx_data.c b/arch/arm/mach-omap2/cclock44xx_data.c
index 3d58f335f173..0c6834ae1fc4 100644
--- a/arch/arm/mach-omap2/cclock44xx_data.c
+++ b/arch/arm/mach-omap2/cclock44xx_data.c
@@ -52,6 +52,13 @@
*/
#define OMAP4_DPLL_ABE_DEFFREQ 98304000
+/*
+ * OMAP4 USB DPLL default frequency. In OMAP4430 TRM version V, section
+ * "3.6.3.9.5 DPLL_USB Preferred Settings" shows that the preferred
+ * locked frequency for the USB DPLL is 960MHz.
+ */
+#define OMAP4_DPLL_USB_DEFFREQ 960000000
+
/* Root clocks */
DEFINE_CLK_FIXED_RATE(extalt_clkin_ck, CLK_IS_ROOT, 59000000, 0x0);
@@ -1011,6 +1018,10 @@ DEFINE_CLK_OMAP_MUX(hsmmc2_fclk, "l3_init_clkdm", hsmmc1_fclk_sel,
OMAP4430_CM_L3INIT_MMC2_CLKCTRL, OMAP4430_CLKSEL_MASK,
hsmmc1_fclk_parents, func_dmic_abe_gfclk_ops);
+DEFINE_CLK_GATE(ocp2scp_usb_phy_phy_48m, "func_48m_fclk", &func_48m_fclk, 0x0,
+ OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
+ OMAP4430_OPTFCLKEN_PHY_48M_SHIFT, 0x0, NULL);
+
DEFINE_CLK_GATE(sha2md5_fck, "l3_div_ck", &l3_div_ck, 0x0,
OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL,
OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
@@ -1538,6 +1549,7 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL, "per_mcbsp4_gfclk", &per_mcbsp4_gfclk, CK_443X),
CLK(NULL, "hsmmc1_fclk", &hsmmc1_fclk, CK_443X),
CLK(NULL, "hsmmc2_fclk", &hsmmc2_fclk, CK_443X),
+ CLK(NULL, "ocp2scp_usb_phy_phy_48m", &ocp2scp_usb_phy_phy_48m, CK_443X),
CLK(NULL, "sha2md5_fck", &sha2md5_fck, CK_443X),
CLK(NULL, "slimbus1_fclk_1", &slimbus1_fclk_1, CK_443X),
CLK(NULL, "slimbus1_fclk_0", &slimbus1_fclk_0, CK_443X),
@@ -1705,5 +1717,13 @@ int __init omap4xxx_clk_init(void)
if (rc)
pr_err("%s: failed to configure ABE DPLL!\n", __func__);
+ /*
+ * Lock USB DPLL on OMAP4 devices so that the L3INIT power
+ * domain can transition to retention state when not in use.
+ */
+ rc = clk_set_rate(&dpll_usb_ck, OMAP4_DPLL_USB_DEFFREQ);
+ if (rc)
+ pr_err("%s: failed to configure USB DPLL!\n", __func__);
+
return 0;
}
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index bf70e2b57ff8..272490e72ee0 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -292,5 +292,8 @@ extern void omap_reserve(void);
struct omap_hwmod;
extern int omap_dss_reset(struct omap_hwmod *);
+/* SoC specific clock initializer */
+extern int (*omap_clk_init)(void);
+
#endif /* __ASSEMBLER__ */
#endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */
diff --git a/arch/arm/mach-omap2/dss-common.c b/arch/arm/mach-omap2/dss-common.c
index 4be5cfc81ab8..393aeefaebb0 100644
--- a/arch/arm/mach-omap2/dss-common.c
+++ b/arch/arm/mach-omap2/dss-common.c
@@ -27,9 +27,7 @@
#include <linux/gpio.h>
#include <video/omapdss.h>
-#include <video/omap-panel-tfp410.h>
-#include <video/omap-panel-nokia-dsi.h>
-#include <video/omap-panel-picodlp.h>
+#include <video/omap-panel-data.h>
#include "soc.h"
#include "dss-common.h"
@@ -54,7 +52,6 @@ static struct omap_dss_device omap4_panda_dvi_device = {
.driver_name = "tfp410",
.data = &omap4_dvi_panel,
.phy.dpi.data_lines = 24,
- .reset_gpio = PANDA_DVI_TFP410_POWER_DOWN_GPIO,
.channel = OMAP_DSS_CHANNEL_LCD2,
};
@@ -179,45 +176,12 @@ static struct picodlp_panel_data sdp4430_picodlp_pdata = {
.pwrgood_gpio = 45,
};
-static void sdp4430_picodlp_init(void)
-{
- int r;
- const struct gpio picodlp_gpios[] = {
- {DLP_POWER_ON_GPIO, GPIOF_OUT_INIT_LOW,
- "DLP POWER ON"},
- {sdp4430_picodlp_pdata.emu_done_gpio, GPIOF_IN,
- "DLP EMU DONE"},
- {sdp4430_picodlp_pdata.pwrgood_gpio, GPIOF_OUT_INIT_LOW,
- "DLP PWRGOOD"},
- };
-
- r = gpio_request_array(picodlp_gpios, ARRAY_SIZE(picodlp_gpios));
- if (r)
- pr_err("Cannot request PicoDLP GPIOs, error %d\n", r);
-}
-
-static int sdp4430_panel_enable_picodlp(struct omap_dss_device *dssdev)
-{
- gpio_set_value(DISPLAY_SEL_GPIO, 0);
- gpio_set_value(DLP_POWER_ON_GPIO, 1);
-
- return 0;
-}
-
-static void sdp4430_panel_disable_picodlp(struct omap_dss_device *dssdev)
-{
- gpio_set_value(DLP_POWER_ON_GPIO, 0);
- gpio_set_value(DISPLAY_SEL_GPIO, 1);
-}
-
static struct omap_dss_device sdp4430_picodlp_device = {
.name = "picodlp",
.driver_name = "picodlp_panel",
.type = OMAP_DISPLAY_TYPE_DPI,
.phy.dpi.data_lines = 24,
.channel = OMAP_DSS_CHANNEL_LCD2,
- .platform_enable = sdp4430_panel_enable_picodlp,
- .platform_disable = sdp4430_panel_disable_picodlp,
.data = &sdp4430_picodlp_pdata,
};
@@ -234,17 +198,26 @@ static struct omap_dss_board_info sdp4430_dss_data = {
.default_device = &sdp4430_lcd_device,
};
+/*
+ * we select LCD2 by default (instead of Pico DLP) by setting DISPLAY_SEL_GPIO.
+ * Setting DLP_POWER_ON gpio enables the VDLP_2V5 VDLP_1V8 and VDLP_1V0 rails
+ * used by picodlp on the 4430sdp platform. Keep this gpio disabled as LCD2 is
+ * selected by default
+ */
void __init omap_4430sdp_display_init(void)
{
int r;
- /* Enable LCD2 by default (instead of Pico DLP) */
r = gpio_request_one(DISPLAY_SEL_GPIO, GPIOF_OUT_INIT_HIGH,
"display_sel");
if (r)
pr_err("%s: Could not get display_sel GPIO\n", __func__);
- sdp4430_picodlp_init();
+ r = gpio_request_one(DLP_POWER_ON_GPIO, GPIOF_OUT_INIT_LOW,
+ "DLP POWER ON");
+ if (r)
+ pr_err("%s: Could not get DLP POWER ON GPIO\n", __func__);
+
omap_display_init(&sdp4430_dss_data);
/*
* OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and
@@ -264,12 +237,15 @@ void __init omap_4430sdp_display_init_of(void)
{
int r;
- /* Enable LCD2 by default (instead of Pico DLP) */
r = gpio_request_one(DISPLAY_SEL_GPIO, GPIOF_OUT_INIT_HIGH,
"display_sel");
if (r)
pr_err("%s: Could not get display_sel GPIO\n", __func__);
- sdp4430_picodlp_init();
+ r = gpio_request_one(DLP_POWER_ON_GPIO, GPIOF_OUT_INIT_LOW,
+ "DLP POWER ON");
+ if (r)
+ pr_err("%s: Could not get DLP POWER ON GPIO\n", __func__);
+
omap_display_init(&sdp4430_dss_data);
}
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index afc1e8c32d6c..d9c27195caf0 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -74,14 +74,6 @@ static int omap2_nand_gpmc_retime(
t.cs_wr_off = gpmc_t->cs_wr_off;
t.wr_cycle = gpmc_t->wr_cycle;
- /* Configure GPMC */
- if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
- gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_DEV_SIZE, 1);
- else
- gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_DEV_SIZE, 0);
- gpmc_cs_configure(gpmc_nand_data->cs,
- GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND);
- gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_WP, 0);
err = gpmc_cs_set_timings(gpmc_nand_data->cs, &t);
if (err)
return err;
@@ -115,14 +107,18 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
struct gpmc_timings *gpmc_t)
{
int err = 0;
+ struct gpmc_settings s;
struct device *dev = &gpmc_nand_device.dev;
+ memset(&s, 0, sizeof(struct gpmc_settings));
+
gpmc_nand_device.dev.platform_data = gpmc_nand_data;
err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE,
(unsigned long *)&gpmc_nand_resource[0].start);
if (err < 0) {
- dev_err(dev, "Cannot request GPMC CS\n");
+ dev_err(dev, "Cannot request GPMC CS %d, error %d\n",
+ gpmc_nand_data->cs, err);
return err;
}
@@ -140,11 +136,31 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
dev_err(dev, "Unable to set gpmc timings: %d\n", err);
return err;
}
- }
- /* Enable RD PIN Monitoring Reg */
- if (gpmc_nand_data->dev_ready) {
- gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_RDY_BSY, 1);
+ if (gpmc_nand_data->of_node) {
+ gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
+ } else {
+ s.device_nand = true;
+
+ /* Enable RD PIN Monitoring Reg */
+ if (gpmc_nand_data->dev_ready) {
+ s.wait_on_read = true;
+ s.wait_on_write = true;
+ }
+ }
+
+ if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
+ s.device_width = GPMC_DEVWIDTH_16BIT;
+ else
+ s.device_width = GPMC_DEVWIDTH_8BIT;
+
+ err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s);
+ if (err < 0)
+ goto out_free_cs;
+
+ err = gpmc_configure(GPMC_CONFIG_WP, 0);
+ if (err < 0)
+ goto out_free_cs;
}
gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs);
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 0d75889c0a6f..64b5a8346982 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -47,11 +47,23 @@ static struct platform_device gpmc_onenand_device = {
.resource = &gpmc_onenand_resource,
};
-static struct gpmc_timings omap2_onenand_calc_async_timings(void)
+static struct gpmc_settings onenand_async = {
+ .device_width = GPMC_DEVWIDTH_16BIT,
+ .mux_add_data = GPMC_MUX_AD,
+};
+
+static struct gpmc_settings onenand_sync = {
+ .burst_read = true,
+ .burst_wrap = true,
+ .burst_len = GPMC_BURST_16,
+ .device_width = GPMC_DEVWIDTH_16BIT,
+ .mux_add_data = GPMC_MUX_AD,
+ .wait_pin = 0,
+};
+
+static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
{
struct gpmc_device_timings dev_t;
- struct gpmc_timings t;
-
const int t_cer = 15;
const int t_avdp = 12;
const int t_aavdh = 7;
@@ -64,7 +76,6 @@ static struct gpmc_timings omap2_onenand_calc_async_timings(void)
memset(&dev_t, 0, sizeof(dev_t));
- dev_t.mux = true;
dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000;
dev_t.t_avdp_w = dev_t.t_avdp_r;
dev_t.t_aavdh = t_aavdh * 1000;
@@ -76,19 +87,7 @@ static struct gpmc_timings omap2_onenand_calc_async_timings(void)
dev_t.t_wpl = t_wpl * 1000;
dev_t.t_wph = t_wph * 1000;
- gpmc_calc_timings(&t, &dev_t);
-
- return t;
-}
-
-static int gpmc_set_async_mode(int cs, struct gpmc_timings *t)
-{
- /* Configure GPMC for asynchronous read */
- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
- GPMC_CONFIG1_DEVICESIZE_16 |
- GPMC_CONFIG1_MUXADDDATA);
-
- return gpmc_cs_set_timings(cs, t);
+ gpmc_calc_timings(t, &onenand_async, &dev_t);
}
static void omap2_onenand_set_async_mode(void __iomem *onenand_base)
@@ -158,12 +157,11 @@ static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
return freq;
}
-static struct gpmc_timings
-omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
- int freq)
+static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t,
+ unsigned int flags,
+ int freq)
{
struct gpmc_device_timings dev_t;
- struct gpmc_timings t;
const int t_cer = 15;
const int t_avdp = 12;
const int t_cez = 20; /* max of t_cez, t_oez */
@@ -172,9 +170,9 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
int div, gpmc_clk_ns;
- if (cfg->flags & ONENAND_SYNC_READ)
+ if (flags & ONENAND_SYNC_READ)
onenand_flags = ONENAND_FLAG_SYNCREAD;
- else if (cfg->flags & ONENAND_SYNC_READWRITE)
+ else if (flags & ONENAND_SYNC_READWRITE)
onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE;
switch (freq) {
@@ -239,10 +237,11 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
/* Set synchronous read timings */
memset(&dev_t, 0, sizeof(dev_t));
- dev_t.mux = true;
- dev_t.sync_read = true;
+ if (onenand_flags & ONENAND_FLAG_SYNCREAD)
+ onenand_sync.sync_read = true;
if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
- dev_t.sync_write = true;
+ onenand_sync.sync_write = true;
+ onenand_sync.burst_write = true;
} else {
dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
dev_t.t_wpl = t_wpl * 1000;
@@ -265,32 +264,7 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
dev_t.cyc_aavdh_oe = 1;
dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
- gpmc_calc_timings(&t, &dev_t);
-
- return t;
-}
-
-static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t)
-{
- unsigned sync_read = onenand_flags & ONENAND_FLAG_SYNCREAD;
- unsigned sync_write = onenand_flags & ONENAND_FLAG_SYNCWRITE;
-
- /* Configure GPMC for synchronous read */
- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
- GPMC_CONFIG1_WRAPBURST_SUPP |
- GPMC_CONFIG1_READMULTIPLE_SUPP |
- (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) |
- (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
- (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
- GPMC_CONFIG1_PAGE_LEN(2) |
- (cpu_is_omap34xx() ? 0 :
- (GPMC_CONFIG1_WAIT_READ_MON |
- GPMC_CONFIG1_WAIT_PIN_SEL(0))) |
- GPMC_CONFIG1_DEVICESIZE_16 |
- GPMC_CONFIG1_DEVICETYPE_NOR |
- GPMC_CONFIG1_MUXADDDATA);
-
- return gpmc_cs_set_timings(cs, t);
+ gpmc_calc_timings(t, &onenand_sync, &dev_t);
}
static int omap2_onenand_setup_async(void __iomem *onenand_base)
@@ -298,11 +272,19 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base)
struct gpmc_timings t;
int ret;
+ if (gpmc_onenand_data->of_node)
+ gpmc_read_settings_dt(gpmc_onenand_data->of_node,
+ &onenand_async);
+
omap2_onenand_set_async_mode(onenand_base);
- t = omap2_onenand_calc_async_timings();
+ omap2_onenand_calc_async_timings(&t);
+
+ ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_async);
+ if (ret < 0)
+ return ret;
- ret = gpmc_set_async_mode(gpmc_onenand_data->cs, &t);
+ ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t);
if (ret < 0)
return ret;
@@ -322,9 +304,25 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
set_onenand_cfg(onenand_base);
}
- t = omap2_onenand_calc_sync_timings(gpmc_onenand_data, freq);
+ if (gpmc_onenand_data->of_node) {
+ gpmc_read_settings_dt(gpmc_onenand_data->of_node,
+ &onenand_sync);
+ } else {
+ /*
+ * FIXME: Appears to be legacy code from initial ONENAND commit.
+ * Unclear what boards this is for and if this can be removed.
+ */
+ if (!cpu_is_omap34xx())
+ onenand_sync.wait_on_read = true;
+ }
- ret = gpmc_set_sync_mode(gpmc_onenand_data->cs, &t);
+ omap2_onenand_calc_sync_timings(&t, gpmc_onenand_data->flags, freq);
+
+ ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_sync);
+ if (ret < 0)
+ return ret;
+
+ ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t);
if (ret < 0)
return ret;
@@ -359,6 +357,7 @@ static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr)
void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
{
int err;
+ struct device *dev = &gpmc_onenand_device.dev;
gpmc_onenand_data = _onenand_data;
gpmc_onenand_data->onenand_setup = gpmc_onenand_setup;
@@ -366,7 +365,7 @@ void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
if (cpu_is_omap24xx() &&
(gpmc_onenand_data->flags & ONENAND_SYNC_READWRITE)) {
- printk(KERN_ERR "Onenand using only SYNC_READ on 24xx\n");
+ dev_warn(dev, "OneNAND using only SYNC_READ on 24xx\n");
gpmc_onenand_data->flags &= ~ONENAND_SYNC_READWRITE;
gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
}
@@ -379,7 +378,8 @@ void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
err = gpmc_cs_request(gpmc_onenand_data->cs, ONENAND_IO_SIZE,
(unsigned long *)&gpmc_onenand_resource.start);
if (err < 0) {
- pr_err("%s: Cannot request GPMC CS\n", __func__);
+ dev_err(dev, "Cannot request GPMC CS %d, error %d\n",
+ gpmc_onenand_data->cs, err);
return;
}
@@ -387,7 +387,7 @@ void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
ONENAND_IO_SIZE - 1;
if (platform_device_register(&gpmc_onenand_device) < 0) {
- pr_err("%s: Unable to register OneNAND device\n", __func__);
+ dev_err(dev, "Unable to register OneNAND device\n");
gpmc_cs_free(gpmc_onenand_data->cs);
return;
}
diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c
index 11d0b756f098..61a063595e66 100644
--- a/arch/arm/mach-omap2/gpmc-smc91x.c
+++ b/arch/arm/mach-omap2/gpmc-smc91x.c
@@ -49,6 +49,10 @@ static struct platform_device gpmc_smc91x_device = {
.resource = gpmc_smc91x_resources,
};
+static struct gpmc_settings smc91x_settings = {
+ .device_width = GPMC_DEVWIDTH_16BIT,
+};
+
/*
* Set the gpmc timings for smc91c96. The timings are taken
* from the data sheet available at:
@@ -67,18 +71,6 @@ static int smc91c96_gpmc_retime(void)
const int t7 = 5; /* Figure 12.4 write */
const int t8 = 5; /* Figure 12.4 write */
const int t20 = 185; /* Figure 12.2 read and 12.4 write */
- u32 l;
-
- l = GPMC_CONFIG1_DEVICESIZE_16;
- if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
- l |= GPMC_CONFIG1_MUXADDDATA;
- if (gpmc_cfg->flags & GPMC_READ_MON)
- l |= GPMC_CONFIG1_WAIT_READ_MON;
- if (gpmc_cfg->flags & GPMC_WRITE_MON)
- l |= GPMC_CONFIG1_WAIT_WRITE_MON;
- if (gpmc_cfg->wait_pin)
- l |= GPMC_CONFIG1_WAIT_PIN_SEL(gpmc_cfg->wait_pin);
- gpmc_cs_write_reg(gpmc_cfg->cs, GPMC_CS_CONFIG1, l);
/*
* FIXME: Calculate the address and data bus muxed timings.
@@ -104,7 +96,7 @@ static int smc91c96_gpmc_retime(void)
dev_t.t_cez_w = t4_w * 1000;
dev_t.t_wr_cycle = (t20 - t3) * 1000;
- gpmc_calc_timings(&t, &dev_t);
+ gpmc_calc_timings(&t, &smc91x_settings, &dev_t);
return gpmc_cs_set_timings(gpmc_cfg->cs, &t);
}
@@ -133,6 +125,18 @@ void __init gpmc_smc91x_init(struct omap_smc91x_platform_data *board_data)
gpmc_smc91x_resources[0].end = cs_mem_base + 0x30f;
gpmc_smc91x_resources[1].flags |= (gpmc_cfg->flags & IRQF_TRIGGER_MASK);
+ if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
+ smc91x_settings.mux_add_data = GPMC_MUX_AD;
+ if (gpmc_cfg->flags & GPMC_READ_MON)
+ smc91x_settings.wait_on_read = true;
+ if (gpmc_cfg->flags & GPMC_WRITE_MON)
+ smc91x_settings.wait_on_write = true;
+ if (gpmc_cfg->wait_pin)
+ smc91x_settings.wait_pin = gpmc_cfg->wait_pin;
+ ret = gpmc_cs_program_settings(gpmc_cfg->cs, &smc91x_settings);
+ if (ret < 0)
+ goto free1;
+
if (gpmc_cfg->retime) {
ret = gpmc_cfg->retime();
if (ret != 0)
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 6de31739b45c..ed946df5ad8a 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -26,6 +26,7 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/of_mtd.h>
#include <linux/of_device.h>
#include <linux/mtd/nand.h>
@@ -91,9 +92,7 @@
#define GPMC_CS_SIZE 0x30
#define GPMC_BCH_SIZE 0x10
-#define GPMC_MEM_START 0x00000000
#define GPMC_MEM_END 0x3FFFFFFF
-#define BOOT_ROM_SPACE 0x100000 /* 1MB */
#define GPMC_CHUNK_SHIFT 24 /* 16 MB */
#define GPMC_SECTION_SHIFT 28 /* 128 MB */
@@ -107,6 +106,9 @@
#define GPMC_HAS_WR_ACCESS 0x1
#define GPMC_HAS_WR_DATA_MUX_BUS 0x2
+#define GPMC_HAS_MUX_AAD 0x4
+
+#define GPMC_NR_WAITPINS 4
/* XXX: Only NAND irq has been considered,currently these are the only ones used
*/
@@ -153,6 +155,7 @@ static struct resource gpmc_cs_mem[GPMC_CS_NUM];
static DEFINE_SPINLOCK(gpmc_mem_lock);
/* Define chip-selects as reserved by default until probe completes */
static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1);
+static unsigned int gpmc_nr_waitpins;
static struct device *gpmc_dev;
static int gpmc_irq;
static resource_size_t phys_base, mem_size;
@@ -181,7 +184,7 @@ void gpmc_cs_write_reg(int cs, int idx, u32 val)
__raw_writel(val, reg_addr);
}
-u32 gpmc_cs_read_reg(int cs, int idx)
+static u32 gpmc_cs_read_reg(int cs, int idx)
{
void __iomem *reg_addr;
@@ -190,7 +193,7 @@ u32 gpmc_cs_read_reg(int cs, int idx)
}
/* TODO: Add support for gpmc_fck to clock framework and use it */
-unsigned long gpmc_get_fclk_period(void)
+static unsigned long gpmc_get_fclk_period(void)
{
unsigned long rate = clk_get_rate(gpmc_l3_clk);
@@ -205,7 +208,7 @@ unsigned long gpmc_get_fclk_period(void)
return rate;
}
-unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
+static unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
{
unsigned long tick_ps;
@@ -215,7 +218,7 @@ unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
return (time_ns * 1000 + tick_ps - 1) / tick_ps;
}
-unsigned int gpmc_ps_to_ticks(unsigned int time_ps)
+static unsigned int gpmc_ps_to_ticks(unsigned int time_ps)
{
unsigned long tick_ps;
@@ -230,13 +233,6 @@ unsigned int gpmc_ticks_to_ns(unsigned int ticks)
return ticks * gpmc_get_fclk_period() / 1000;
}
-unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
-{
- unsigned long ticks = gpmc_ns_to_ticks(time_ns);
-
- return ticks * gpmc_get_fclk_period() / 1000;
-}
-
static unsigned int gpmc_ticks_to_ps(unsigned int ticks)
{
return ticks * gpmc_get_fclk_period();
@@ -405,11 +401,18 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
return 0;
}
-static void gpmc_cs_enable_mem(int cs, u32 base, u32 size)
+static int gpmc_cs_enable_mem(int cs, u32 base, u32 size)
{
u32 l;
u32 mask;
+ /*
+ * Ensure that base address is aligned on a
+ * boundary equal to or greater than size.
+ */
+ if (base & (size - 1))
+ return -EINVAL;
+
mask = (1 << GPMC_SECTION_SHIFT) - size;
l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
l &= ~0x3f;
@@ -418,6 +421,8 @@ static void gpmc_cs_enable_mem(int cs, u32 base, u32 size)
l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8;
l |= GPMC_CONFIG7_CSVALID;
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l);
+
+ return 0;
}
static void gpmc_cs_disable_mem(int cs)
@@ -448,22 +453,14 @@ static int gpmc_cs_mem_enabled(int cs)
return l & GPMC_CONFIG7_CSVALID;
}
-int gpmc_cs_set_reserved(int cs, int reserved)
+static void gpmc_cs_set_reserved(int cs, int reserved)
{
- if (cs > GPMC_CS_NUM)
- return -ENODEV;
-
gpmc_cs_map &= ~(1 << cs);
gpmc_cs_map |= (reserved ? 1 : 0) << cs;
-
- return 0;
}
-int gpmc_cs_reserved(int cs)
+static bool gpmc_cs_reserved(int cs)
{
- if (cs > GPMC_CS_NUM)
- return -ENODEV;
-
return gpmc_cs_map & (1 << cs);
}
@@ -510,6 +507,39 @@ static int gpmc_cs_delete_mem(int cs)
return r;
}
+/**
+ * gpmc_cs_remap - remaps a chip-select physical base address
+ * @cs: chip-select to remap
+ * @base: physical base address to re-map chip-select to
+ *
+ * Re-maps a chip-select to a new physical base address specified by
+ * "base". Returns 0 on success and appropriate negative error code
+ * on failure.
+ */
+static int gpmc_cs_remap(int cs, u32 base)
+{
+ int ret;
+ u32 old_base, size;
+
+ if (cs > GPMC_CS_NUM)
+ return -ENODEV;
+ gpmc_cs_get_memconf(cs, &old_base, &size);
+ if (base == old_base)
+ return 0;
+ gpmc_cs_disable_mem(cs);
+ ret = gpmc_cs_delete_mem(cs);
+ if (ret < 0)
+ return ret;
+ ret = gpmc_cs_insert_mem(cs, base, size);
+ if (ret < 0)
+ return ret;
+ ret = gpmc_cs_enable_mem(cs, base, size);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
{
struct resource *res = &gpmc_cs_mem[cs];
@@ -535,7 +565,12 @@ int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
if (r < 0)
goto out;
- gpmc_cs_enable_mem(cs, res->start, resource_size(res));
+ r = gpmc_cs_enable_mem(cs, res->start, resource_size(res));
+ if (r < 0) {
+ release_resource(res);
+ goto out;
+ }
+
*base = res->start;
gpmc_cs_set_reserved(cs, 1);
out:
@@ -561,16 +596,14 @@ void gpmc_cs_free(int cs)
EXPORT_SYMBOL(gpmc_cs_free);
/**
- * gpmc_cs_configure - write request to configure gpmc
- * @cs: chip select number
+ * gpmc_configure - write request to configure gpmc
* @cmd: command type
* @wval: value to write
* @return status of the operation
*/
-int gpmc_cs_configure(int cs, int cmd, int wval)
+int gpmc_configure(int cmd, int wval)
{
- int err = 0;
- u32 regval = 0;
+ u32 regval;
switch (cmd) {
case GPMC_ENABLE_IRQ:
@@ -590,43 +623,14 @@ int gpmc_cs_configure(int cs, int cmd, int wval)
gpmc_write_reg(GPMC_CONFIG, regval);
break;
- case GPMC_CONFIG_RDY_BSY:
- regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
- if (wval)
- regval |= WR_RD_PIN_MONITORING;
- else
- regval &= ~WR_RD_PIN_MONITORING;
- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval);
- break;
-
- case GPMC_CONFIG_DEV_SIZE:
- regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
-
- /* clear 2 target bits */
- regval &= ~GPMC_CONFIG1_DEVICESIZE(3);
-
- /* set the proper value */
- regval |= GPMC_CONFIG1_DEVICESIZE(wval);
-
- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval);
- break;
-
- case GPMC_CONFIG_DEV_TYPE:
- regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
- regval |= GPMC_CONFIG1_DEVICETYPE(wval);
- if (wval == GPMC_DEVICETYPE_NOR)
- regval |= GPMC_CONFIG1_MUXADDDATA;
- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval);
- break;
-
default:
- printk(KERN_ERR "gpmc_configure_cs: Not supported\n");
- err = -EINVAL;
+ pr_err("%s: command not supported\n", __func__);
+ return -EINVAL;
}
- return err;
+ return 0;
}
-EXPORT_SYMBOL(gpmc_cs_configure);
+EXPORT_SYMBOL(gpmc_configure);
void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
{
@@ -781,16 +785,16 @@ static void gpmc_mem_exit(void)
}
-static int gpmc_mem_init(void)
+static void gpmc_mem_init(void)
{
- int cs, rc;
- unsigned long boot_rom_space = 0;
+ int cs;
- /* never allocate the first page, to facilitate bug detection;
- * even if we didn't boot from ROM.
+ /*
+ * The first 1MB of GPMC address space is typically mapped to
+ * the internal ROM. Never allocate the first page, to
+ * facilitate bug detection; even if we didn't boot from ROM.
*/
- boot_rom_space = BOOT_ROM_SPACE;
- gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space;
+ gpmc_mem_root.start = SZ_1M;
gpmc_mem_root.end = GPMC_MEM_END;
/* Reserve all regions that has been set up by bootloader */
@@ -800,16 +804,12 @@ static int gpmc_mem_init(void)
if (!gpmc_cs_mem_enabled(cs))
continue;
gpmc_cs_get_memconf(cs, &base, &size);
- rc = gpmc_cs_insert_mem(cs, base, size);
- if (rc < 0) {
- while (--cs >= 0)
- if (gpmc_cs_mem_enabled(cs))
- gpmc_cs_delete_mem(cs);
- return rc;
+ if (gpmc_cs_insert_mem(cs, base, size)) {
+ pr_warn("%s: disabling cs %d mapped at 0x%x-0x%x\n",
+ __func__, cs, base, base + size);
+ gpmc_cs_disable_mem(cs);
}
}
-
- return 0;
}
static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk)
@@ -825,9 +825,9 @@ static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk)
/* XXX: can the cycles be avoided ? */
static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
- struct gpmc_device_timings *dev_t)
+ struct gpmc_device_timings *dev_t,
+ bool mux)
{
- bool mux = dev_t->mux;
u32 temp;
/* adv_rd_off */
@@ -880,9 +880,9 @@ static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
}
static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
- struct gpmc_device_timings *dev_t)
+ struct gpmc_device_timings *dev_t,
+ bool mux)
{
- bool mux = dev_t->mux;
u32 temp;
/* adv_wr_off */
@@ -942,9 +942,9 @@ static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
}
static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t,
- struct gpmc_device_timings *dev_t)
+ struct gpmc_device_timings *dev_t,
+ bool mux)
{
- bool mux = dev_t->mux;
u32 temp;
/* adv_rd_off */
@@ -982,9 +982,9 @@ static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t,
}
static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t,
- struct gpmc_device_timings *dev_t)
+ struct gpmc_device_timings *dev_t,
+ bool mux)
{
- bool mux = dev_t->mux;
u32 temp;
/* adv_wr_off */
@@ -1054,7 +1054,8 @@ static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t,
}
static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
- struct gpmc_device_timings *dev_t)
+ struct gpmc_device_timings *dev_t,
+ bool sync)
{
u32 temp;
@@ -1068,7 +1069,7 @@ static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
gpmc_t->cs_on + dev_t->t_ce_avd);
gpmc_t->adv_on = gpmc_round_ps_to_ticks(temp);
- if (dev_t->sync_write || dev_t->sync_read)
+ if (sync)
gpmc_calc_sync_common_timings(gpmc_t, dev_t);
return 0;
@@ -1103,21 +1104,29 @@ static void gpmc_convert_ps_to_ns(struct gpmc_timings *t)
}
int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
- struct gpmc_device_timings *dev_t)
+ struct gpmc_settings *gpmc_s,
+ struct gpmc_device_timings *dev_t)
{
+ bool mux = false, sync = false;
+
+ if (gpmc_s) {
+ mux = gpmc_s->mux_add_data ? true : false;
+ sync = (gpmc_s->sync_read || gpmc_s->sync_write);
+ }
+
memset(gpmc_t, 0, sizeof(*gpmc_t));
- gpmc_calc_common_timings(gpmc_t, dev_t);
+ gpmc_calc_common_timings(gpmc_t, dev_t, sync);
- if (dev_t->sync_read)
- gpmc_calc_sync_read_timings(gpmc_t, dev_t);
+ if (gpmc_s && gpmc_s->sync_read)
+ gpmc_calc_sync_read_timings(gpmc_t, dev_t, mux);
else
- gpmc_calc_async_read_timings(gpmc_t, dev_t);
+ gpmc_calc_async_read_timings(gpmc_t, dev_t, mux);
- if (dev_t->sync_write)
- gpmc_calc_sync_write_timings(gpmc_t, dev_t);
+ if (gpmc_s && gpmc_s->sync_write)
+ gpmc_calc_sync_write_timings(gpmc_t, dev_t, mux);
else
- gpmc_calc_async_write_timings(gpmc_t, dev_t);
+ gpmc_calc_async_write_timings(gpmc_t, dev_t, mux);
/* TODO: remove, see function definition */
gpmc_convert_ps_to_ns(gpmc_t);
@@ -1125,6 +1134,90 @@ int gpmc_calc_timings(struct gpmc_timings *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_on_read || p->wait_on_write) &&
+ (p->wait_pin > gpmc_nr_waitpins)) {
+ pr_err("%s: invalid wait-pin (%d)\n", __func__, p->wait_pin);
+ return -EINVAL;
+ }
+
+ config1 = GPMC_CONFIG1_DEVICESIZE((p->device_width - 1));
+
+ if (p->sync_read)
+ config1 |= GPMC_CONFIG1_READTYPE_SYNC;
+ if (p->sync_write)
+ config1 |= GPMC_CONFIG1_WRITETYPE_SYNC;
+ if (p->wait_on_read)
+ config1 |= GPMC_CONFIG1_WAIT_READ_MON;
+ if (p->wait_on_write)
+ config1 |= GPMC_CONFIG1_WAIT_WRITE_MON;
+ if (p->wait_on_read || p->wait_on_write)
+ config1 |= GPMC_CONFIG1_WAIT_PIN_SEL(p->wait_pin);
+ if (p->device_nand)
+ config1 |= GPMC_CONFIG1_DEVICETYPE(GPMC_DEVICETYPE_NAND);
+ if (p->mux_add_data)
+ config1 |= GPMC_CONFIG1_MUXTYPE(p->mux_add_data);
+ if (p->burst_read)
+ config1 |= GPMC_CONFIG1_READMULTIPLE_SUPP;
+ if (p->burst_write)
+ config1 |= GPMC_CONFIG1_WRITEMULTIPLE_SUPP;
+ if (p->burst_read || p->burst_write) {
+ config1 |= GPMC_CONFIG1_PAGE_LEN(p->burst_len >> 3);
+ config1 |= p->burst_wrap ? GPMC_CONFIG1_WRAPBURST_SUPP : 0;
+ }
+
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, config1);
+
+ return 0;
+}
+
#ifdef CONFIG_OF
static struct of_device_id gpmc_dt_ids[] = {
{ .compatible = "ti,omap2420-gpmc" },
@@ -1136,70 +1229,110 @@ static struct of_device_id gpmc_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, gpmc_dt_ids);
+/**
+ * gpmc_read_settings_dt - read gpmc settings from device-tree
+ * @np: pointer to device-tree node for a gpmc child device
+ * @p: pointer to gpmc settings structure
+ *
+ * Reads the GPMC settings for a GPMC child device from device-tree and
+ * stores them in the GPMC settings structure passed. The GPMC settings
+ * structure is initialised to zero by this function and so any
+ * previously stored settings will be cleared.
+ */
+void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p)
+{
+ memset(p, 0, sizeof(struct gpmc_settings));
+
+ p->sync_read = of_property_read_bool(np, "gpmc,sync-read");
+ p->sync_write = of_property_read_bool(np, "gpmc,sync-write");
+ p->device_nand = of_property_read_bool(np, "gpmc,device-nand");
+ of_property_read_u32(np, "gpmc,device-width", &p->device_width);
+ of_property_read_u32(np, "gpmc,mux-add-data", &p->mux_add_data);
+
+ if (!of_property_read_u32(np, "gpmc,burst-length", &p->burst_len)) {
+ p->burst_wrap = of_property_read_bool(np, "gpmc,burst-wrap");
+ p->burst_read = of_property_read_bool(np, "gpmc,burst-read");
+ p->burst_write = of_property_read_bool(np, "gpmc,burst-write");
+ if (!p->burst_read && !p->burst_write)
+ pr_warn("%s: page/burst-length set but not used!\n",
+ __func__);
+ }
+
+ if (!of_property_read_u32(np, "gpmc,wait-pin", &p->wait_pin)) {
+ p->wait_on_read = of_property_read_bool(np,
+ "gpmc,wait-on-read");
+ p->wait_on_write = of_property_read_bool(np,
+ "gpmc,wait-on-write");
+ if (!p->wait_on_read && !p->wait_on_write)
+ pr_warn("%s: read/write wait monitoring not enabled!\n",
+ __func__);
+ }
+}
+
static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
struct gpmc_timings *gpmc_t)
{
- u32 val;
+ struct gpmc_bool_timings *p;
+
+ if (!np || !gpmc_t)
+ return;
memset(gpmc_t, 0, sizeof(*gpmc_t));
/* minimum clock period for syncronous mode */
- if (!of_property_read_u32(np, "gpmc,sync-clk", &val))
- gpmc_t->sync_clk = val;
+ of_property_read_u32(np, "gpmc,sync-clk-ps", &gpmc_t->sync_clk);
/* chip select timtings */
- if (!of_property_read_u32(np, "gpmc,cs-on", &val))
- gpmc_t->cs_on = val;
-
- if (!of_property_read_u32(np, "gpmc,cs-rd-off", &val))
- gpmc_t->cs_rd_off = val;
-
- if (!of_property_read_u32(np, "gpmc,cs-wr-off", &val))
- gpmc_t->cs_wr_off = val;
+ of_property_read_u32(np, "gpmc,cs-on-ns", &gpmc_t->cs_on);
+ of_property_read_u32(np, "gpmc,cs-rd-off-ns", &gpmc_t->cs_rd_off);
+ of_property_read_u32(np, "gpmc,cs-wr-off-ns", &gpmc_t->cs_wr_off);
/* ADV signal timings */
- if (!of_property_read_u32(np, "gpmc,adv-on", &val))
- gpmc_t->adv_on = val;
-
- if (!of_property_read_u32(np, "gpmc,adv-rd-off", &val))
- gpmc_t->adv_rd_off = val;
-
- if (!of_property_read_u32(np, "gpmc,adv-wr-off", &val))
- gpmc_t->adv_wr_off = val;
+ of_property_read_u32(np, "gpmc,adv-on-ns", &gpmc_t->adv_on);
+ of_property_read_u32(np, "gpmc,adv-rd-off-ns", &gpmc_t->adv_rd_off);
+ of_property_read_u32(np, "gpmc,adv-wr-off-ns", &gpmc_t->adv_wr_off);
/* WE signal timings */
- if (!of_property_read_u32(np, "gpmc,we-on", &val))
- gpmc_t->we_on = val;
-
- if (!of_property_read_u32(np, "gpmc,we-off", &val))
- gpmc_t->we_off = val;
+ of_property_read_u32(np, "gpmc,we-on-ns", &gpmc_t->we_on);
+ of_property_read_u32(np, "gpmc,we-off-ns", &gpmc_t->we_off);
/* OE signal timings */
- if (!of_property_read_u32(np, "gpmc,oe-on", &val))
- gpmc_t->oe_on = val;
-
- if (!of_property_read_u32(np, "gpmc,oe-off", &val))
- gpmc_t->oe_off = val;
+ of_property_read_u32(np, "gpmc,oe-on-ns", &gpmc_t->oe_on);
+ of_property_read_u32(np, "gpmc,oe-off-ns", &gpmc_t->oe_off);
/* access and cycle timings */
- if (!of_property_read_u32(np, "gpmc,page-burst-access", &val))
- gpmc_t->page_burst_access = val;
-
- if (!of_property_read_u32(np, "gpmc,access", &val))
- gpmc_t->access = val;
-
- if (!of_property_read_u32(np, "gpmc,rd-cycle", &val))
- gpmc_t->rd_cycle = val;
-
- if (!of_property_read_u32(np, "gpmc,wr-cycle", &val))
- gpmc_t->wr_cycle = val;
-
- /* only for OMAP3430 */
- if (!of_property_read_u32(np, "gpmc,wr-access", &val))
- gpmc_t->wr_access = val;
-
- if (!of_property_read_u32(np, "gpmc,wr-data-mux-bus", &val))
- gpmc_t->wr_data_mux_bus = val;
+ of_property_read_u32(np, "gpmc,page-burst-access-ns",
+ &gpmc_t->page_burst_access);
+ of_property_read_u32(np, "gpmc,access-ns", &gpmc_t->access);
+ of_property_read_u32(np, "gpmc,rd-cycle-ns", &gpmc_t->rd_cycle);
+ of_property_read_u32(np, "gpmc,wr-cycle-ns", &gpmc_t->wr_cycle);
+ of_property_read_u32(np, "gpmc,bus-turnaround-ns",
+ &gpmc_t->bus_turnaround);
+ of_property_read_u32(np, "gpmc,cycle2cycle-delay-ns",
+ &gpmc_t->cycle2cycle_delay);
+ of_property_read_u32(np, "gpmc,wait-monitoring-ns",
+ &gpmc_t->wait_monitoring);
+ of_property_read_u32(np, "gpmc,clk-activation-ns",
+ &gpmc_t->clk_activation);
+
+ /* only applicable to OMAP3+ */
+ of_property_read_u32(np, "gpmc,wr-access-ns", &gpmc_t->wr_access);
+ of_property_read_u32(np, "gpmc,wr-data-mux-bus-ns",
+ &gpmc_t->wr_data_mux_bus);
+
+ /* bool timing parameters */
+ p = &gpmc_t->bool_timings;
+
+ p->cycle2cyclediffcsen =
+ of_property_read_bool(np, "gpmc,cycle2cycle-diffcsen");
+ p->cycle2cyclesamecsen =
+ of_property_read_bool(np, "gpmc,cycle2cycle-samecsen");
+ p->we_extra_delay = of_property_read_bool(np, "gpmc,we-extra-delay");
+ p->oe_extra_delay = of_property_read_bool(np, "gpmc,oe-extra-delay");
+ p->adv_extra_delay = of_property_read_bool(np, "gpmc,adv-extra-delay");
+ p->cs_extra_delay = of_property_read_bool(np, "gpmc,cs-extra-delay");
+ p->time_para_granularity =
+ of_property_read_bool(np, "gpmc,time-para-granularity");
}
#ifdef CONFIG_MTD_NAND
@@ -1295,6 +1428,81 @@ static int gpmc_probe_onenand_child(struct platform_device *pdev,
}
#endif
+/**
+ * gpmc_probe_generic_child - configures the gpmc for a child device
+ * @pdev: pointer to gpmc platform device
+ * @child: pointer to device-tree node for child device
+ *
+ * Allocates and configures a GPMC chip-select for a child device.
+ * Returns 0 on success and appropriate negative error code on failure.
+ */
+static int gpmc_probe_generic_child(struct platform_device *pdev,
+ struct device_node *child)
+{
+ struct gpmc_settings gpmc_s;
+ struct gpmc_timings gpmc_t;
+ struct resource res;
+ unsigned long base;
+ int ret, cs;
+
+ if (of_property_read_u32(child, "reg", &cs) < 0) {
+ dev_err(&pdev->dev, "%s has no 'reg' property\n",
+ child->full_name);
+ return -ENODEV;
+ }
+
+ if (of_address_to_resource(child, 0, &res) < 0) {
+ dev_err(&pdev->dev, "%s has malformed 'reg' property\n",
+ child->full_name);
+ return -ENODEV;
+ }
+
+ ret = gpmc_cs_request(cs, resource_size(&res), &base);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs);
+ return ret;
+ }
+
+ /*
+ * FIXME: gpmc_cs_request() will map the CS to an arbitary
+ * location in the gpmc address space. When booting with
+ * device-tree we want the NOR flash to be mapped to the
+ * location specified in the device-tree blob. So remap the
+ * CS to this location. Once DT migration is complete should
+ * just make gpmc_cs_request() map a specific address.
+ */
+ ret = gpmc_cs_remap(cs, res.start);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "cannot remap GPMC CS %d to 0x%x\n",
+ cs, res.start);
+ goto err;
+ }
+
+ gpmc_read_settings_dt(child, &gpmc_s);
+
+ ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width);
+ if (ret < 0)
+ goto err;
+
+ ret = gpmc_cs_program_settings(cs, &gpmc_s);
+ if (ret < 0)
+ goto err;
+
+ gpmc_read_timings_dt(child, &gpmc_t);
+ gpmc_cs_set_timings(cs, &gpmc_t);
+
+ if (of_platform_device_create(child, NULL, &pdev->dev))
+ return 0;
+
+ dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name);
+ ret = -ENODEV;
+
+err:
+ gpmc_cs_free(cs);
+
+ return ret;
+}
+
static int gpmc_probe_dt(struct platform_device *pdev)
{
int ret;
@@ -1305,6 +1513,13 @@ static int gpmc_probe_dt(struct platform_device *pdev)
if (!of_id)
return 0;
+ ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-waitpins",
+ &gpmc_nr_waitpins);
+ if (ret < 0) {
+ pr_err("%s: number of wait pins not found!\n", __func__);
+ return ret;
+ }
+
for_each_node_by_name(child, "nand") {
ret = gpmc_probe_nand_child(pdev, child);
if (ret < 0) {
@@ -1320,6 +1535,23 @@ static int gpmc_probe_dt(struct platform_device *pdev)
return ret;
}
}
+
+ for_each_node_by_name(child, "nor") {
+ ret = gpmc_probe_generic_child(pdev, child);
+ if (ret < 0) {
+ of_node_put(child);
+ return ret;
+ }
+ }
+
+ for_each_node_by_name(child, "ethernet") {
+ ret = gpmc_probe_generic_child(pdev, child);
+ if (ret < 0) {
+ of_node_put(child);
+ return ret;
+ }
+ }
+
return 0;
}
#else
@@ -1364,18 +1596,27 @@ static int gpmc_probe(struct platform_device *pdev)
gpmc_dev = &pdev->dev;
l = gpmc_read_reg(GPMC_REVISION);
+
+ /*
+ * FIXME: Once device-tree migration is complete the below flags
+ * should be populated based upon the device-tree compatible
+ * string. For now just use the IP revision. OMAP3+ devices have
+ * the wr_access and wr_data_mux_bus register fields. OMAP4+
+ * devices support the addr-addr-data multiplex protocol.
+ *
+ * GPMC IP revisions:
+ * - OMAP24xx = 2.0
+ * - OMAP3xxx = 5.0
+ * - OMAP44xx/54xx/AM335x = 6.0
+ */
if (GPMC_REVISION_MAJOR(l) > 0x4)
gpmc_capability = GPMC_HAS_WR_ACCESS | GPMC_HAS_WR_DATA_MUX_BUS;
+ if (GPMC_REVISION_MAJOR(l) > 0x5)
+ gpmc_capability |= GPMC_HAS_MUX_AAD;
dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l),
GPMC_REVISION_MINOR(l));
- rc = gpmc_mem_init();
- if (rc < 0) {
- clk_disable_unprepare(gpmc_l3_clk);
- clk_put(gpmc_l3_clk);
- dev_err(gpmc_dev, "failed to reserve memory\n");
- return rc;
- }
+ gpmc_mem_init();
if (gpmc_setup_irq() < 0)
dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");
@@ -1383,6 +1624,9 @@ static int gpmc_probe(struct platform_device *pdev)
/* Now the GPMC is initialised, unreserve the chip-selects */
gpmc_cs_map = 0;
+ if (!pdev->dev.of_node)
+ gpmc_nr_waitpins = GPMC_NR_WAITPINS;
+
rc = gpmc_probe_dt(pdev);
if (rc < 0) {
clk_disable_unprepare(gpmc_l3_clk);
diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
index fe0a844d5007..707f6d58edd5 100644
--- a/arch/arm/mach-omap2/gpmc.h
+++ b/arch/arm/mach-omap2/gpmc.h
@@ -58,7 +58,7 @@
#define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1)
#define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10)
#define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0)
-#define GPMC_CONFIG1_MUXADDDATA (1 << 9)
+#define GPMC_CONFIG1_MUXTYPE(val) ((val & 3) << 8)
#define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4)
#define GPMC_CONFIG1_FCLK_DIV(val) (val & 3)
#define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1))
@@ -73,6 +73,13 @@
#define GPMC_IRQ_FIFOEVENTENABLE 0x01
#define GPMC_IRQ_COUNT_EVENT 0x02
+#define GPMC_BURST_4 4 /* 4 word burst */
+#define GPMC_BURST_8 8 /* 8 word burst */
+#define GPMC_BURST_16 16 /* 16 word burst */
+#define GPMC_DEVWIDTH_8BIT 1 /* 8-bit device width */
+#define GPMC_DEVWIDTH_16BIT 2 /* 16-bit device width */
+#define GPMC_MUX_AAD 1 /* Addr-Addr-Data multiplex */
+#define GPMC_MUX_AD 2 /* Addr-Data multiplex */
/* bool type time settings */
struct gpmc_bool_timings {
@@ -178,10 +185,6 @@ struct gpmc_device_timings {
u8 cyc_wpl; /* write deassertion time in cycles */
u32 cyc_iaa; /* initial access time in cycles */
- bool mux; /* address & data muxed */
- bool sync_write;/* synchronous write */
- bool sync_read; /* synchronous read */
-
/* extra delays */
bool ce_xdelay;
bool avd_xdelay;
@@ -189,28 +192,40 @@ struct gpmc_device_timings {
bool we_xdelay;
};
+struct gpmc_settings {
+ bool burst_wrap; /* enables wrap bursting */
+ bool burst_read; /* enables read page/burst mode */
+ bool burst_write; /* enables write page/burst mode */
+ bool device_nand; /* device is NAND */
+ bool sync_read; /* enables synchronous reads */
+ bool sync_write; /* enables synchronous writes */
+ bool wait_on_read; /* monitor wait on reads */
+ bool wait_on_write; /* monitor wait on writes */
+ u32 burst_len; /* page/burst length */
+ u32 device_width; /* device bus width (8 or 16 bit) */
+ u32 mux_add_data; /* multiplex address & data */
+ u32 wait_pin; /* wait-pin to be used */
+};
+
extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
- struct gpmc_device_timings *dev_t);
+ struct gpmc_settings *gpmc_s,
+ struct gpmc_device_timings *dev_t);
extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
extern int gpmc_get_client_irq(unsigned irq_config);
-extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
-extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps);
extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
-extern unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns);
-extern unsigned long gpmc_get_fclk_period(void);
extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
-extern u32 gpmc_cs_read_reg(int cs, int idx);
extern int gpmc_calc_divider(unsigned int sync_clk);
extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t);
+extern int gpmc_cs_program_settings(int cs, struct gpmc_settings *p);
extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
extern void gpmc_cs_free(int cs);
-extern int gpmc_cs_set_reserved(int cs, int reserved);
-extern int gpmc_cs_reserved(int cs);
extern void omap3_gpmc_save_context(void);
extern void omap3_gpmc_restore_context(void);
-extern int gpmc_cs_configure(int cs, int cmd, int wval);
+extern int gpmc_configure(int cmd, int wval);
+extern void gpmc_read_settings_dt(struct device_node *np,
+ struct gpmc_settings *p);
#endif
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 2bef5a7e6af8..e210fa830f8d 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -55,6 +55,12 @@
#include "prm44xx.h"
/*
+ * omap_clk_init: points to a function that does the SoC-specific
+ * clock initializations
+ */
+int (*omap_clk_init)(void);
+
+/*
* The machine specific code may provide the extra mapping besides the
* default mapping provided here.
*/
@@ -406,7 +412,7 @@ void __init omap2420_init_early(void)
omap242x_clockdomains_init();
omap2420_hwmod_init();
omap_hwmod_init_postsetup();
- omap2420_clk_init();
+ omap_clk_init = omap2420_clk_init;
}
void __init omap2420_init_late(void)
@@ -436,7 +442,7 @@ void __init omap2430_init_early(void)
omap243x_clockdomains_init();
omap2430_hwmod_init();
omap_hwmod_init_postsetup();
- omap2430_clk_init();
+ omap_clk_init = omap2430_clk_init;
}
void __init omap2430_init_late(void)
@@ -471,7 +477,7 @@ void __init omap3_init_early(void)
omap3xxx_clockdomains_init();
omap3xxx_hwmod_init();
omap_hwmod_init_postsetup();
- omap3xxx_clk_init();
+ omap_clk_init = omap3xxx_clk_init;
}
void __init omap3430_init_early(void)
@@ -509,7 +515,7 @@ void __init ti81xx_init_early(void)
omap3xxx_clockdomains_init();
omap3xxx_hwmod_init();
omap_hwmod_init_postsetup();
- omap3xxx_clk_init();
+ omap_clk_init = omap3xxx_clk_init;
}
void __init omap3_init_late(void)
@@ -577,7 +583,7 @@ void __init am33xx_init_early(void)
am33xx_clockdomains_init();
am33xx_hwmod_init();
omap_hwmod_init_postsetup();
- am33xx_clk_init();
+ omap_clk_init = am33xx_clk_init;
}
#endif
@@ -602,7 +608,7 @@ void __init omap4430_init_early(void)
omap44xx_clockdomains_init();
omap44xx_hwmod_init();
omap_hwmod_init_postsetup();
- omap4xxx_clk_init();
+ omap_clk_init = omap4xxx_clk_init;
}
void __init omap4430_init_late(void)
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 2520d46c8508..3f50f680372e 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1364,7 +1364,9 @@ static void _enable_sysc(struct omap_hwmod *oh)
}
if (sf & SYSC_HAS_MIDLEMODE) {
- if (oh->flags & HWMOD_SWSUP_MSTANDBY) {
+ if (oh->flags & HWMOD_FORCE_MSTANDBY) {
+ idlemode = HWMOD_IDLEMODE_FORCE;
+ } else if (oh->flags & HWMOD_SWSUP_MSTANDBY) {
idlemode = HWMOD_IDLEMODE_NO;
} else {
if (sf & SYSC_HAS_ENAWAKEUP)
@@ -1436,7 +1438,8 @@ static void _idle_sysc(struct omap_hwmod *oh)
}
if (sf & SYSC_HAS_MIDLEMODE) {
- if (oh->flags & HWMOD_SWSUP_MSTANDBY) {
+ if ((oh->flags & HWMOD_SWSUP_MSTANDBY) ||
+ (oh->flags & HWMOD_FORCE_MSTANDBY)) {
idlemode = HWMOD_IDLEMODE_FORCE;
} else {
if (sf & SYSC_HAS_ENAWAKEUP)
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h
index 28f4dea0512e..fe5962921f07 100644
--- a/arch/arm/mach-omap2/omap_hwmod.h
+++ b/arch/arm/mach-omap2/omap_hwmod.h
@@ -427,8 +427,8 @@ struct omap_hwmod_omap4_prcm {
*
* HWMOD_SWSUP_SIDLE: omap_hwmod code should manually bring module in and out
* of idle, rather than relying on module smart-idle
- * HWMOD_SWSUP_MSTDBY: omap_hwmod code should manually bring module in and out
- * of standby, rather than relying on module smart-standby
+ * HWMOD_SWSUP_MSTANDBY: omap_hwmod code should manually bring module in and
+ * out of standby, rather than relying on module smart-standby
* HWMOD_INIT_NO_RESET: don't reset this module at boot - important for
* SDRAM controller, etc. XXX probably belongs outside the main hwmod file
* XXX Should be HWMOD_SETUP_NO_RESET
@@ -459,6 +459,10 @@ struct omap_hwmod_omap4_prcm {
* correctly, or this is being abused to deal with some PM latency
* issues -- but we're currently suffering from a shortage of
* folks who are able to track these issues down properly.
+ * HWMOD_FORCE_MSTANDBY: Always keep MIDLEMODE bits cleared so that device
+ * is kept in force-standby mode. Failing to do so causes PM problems
+ * with musb on OMAP3630 at least. Note that musb has a dedicated register
+ * to control MSTANDBY signal when MIDLEMODE is set to force-standby.
*/
#define HWMOD_SWSUP_SIDLE (1 << 0)
#define HWMOD_SWSUP_MSTANDBY (1 << 1)
@@ -471,6 +475,7 @@ struct omap_hwmod_omap4_prcm {
#define HWMOD_16BIT_REG (1 << 8)
#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9)
#define HWMOD_BLOCK_WFI (1 << 10)
+#define HWMOD_FORCE_MSTANDBY (1 << 11)
/*
* omap_hwmod._int_flags definitions
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index ac7e03ec952f..5112d04e7b79 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -1707,9 +1707,14 @@ static struct omap_hwmod omap3xxx_usbhsotg_hwmod = {
* Erratum ID: i479 idle_req / idle_ack mechanism potentially
* broken when autoidle is enabled
* workaround is to disable the autoidle bit at module level.
+ *
+ * Enabling the device in any other MIDLEMODE setting but force-idle
+ * causes core_pwrdm not enter idle states at least on OMAP3630.
+ * Note that musb has OTG_FORCESTDBY register that controls MSTANDBY
+ * signal when MIDLEMODE is set to force-idle.
*/
.flags = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE
- | HWMOD_SWSUP_MSTANDBY,
+ | HWMOD_FORCE_MSTANDBY,
};
/* usb_otg_hs */
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 0e47d2e1687c..9e0576569e07 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -2714,6 +2714,10 @@ static struct omap_ocp2scp_dev ocp2scp_dev_attr[] = {
{ }
};
+static struct omap_hwmod_opt_clk ocp2scp_usb_phy_opt_clks[] = {
+ { .role = "48mhz", .clk = "ocp2scp_usb_phy_phy_48m" },
+};
+
/* ocp2scp_usb_phy */
static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
.name = "ocp2scp_usb_phy",
@@ -2728,6 +2732,8 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
},
},
.dev_attr = ocp2scp_dev_attr,
+ .opt_clks = ocp2scp_usb_phy_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(ocp2scp_usb_phy_opt_clks),
};
/*
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 31ae76481737..fdf1c039062c 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -46,7 +46,6 @@
#include <asm/smp_twd.h>
#include <asm/sched_clock.h>
-#include <asm/arch_timer.h>
#include "omap_hwmod.h"
#include "omap_device.h"
#include <plat/counter-32k.h>
@@ -626,14 +625,10 @@ void __init omap4_local_timer_init(void)
#ifdef CONFIG_SOC_OMAP5
void __init omap5_realtime_timer_init(void)
{
- int err;
-
omap4_sync32k_timer_init();
realtime_counter_init();
- err = arch_timer_of_register();
- if (err)
- pr_err("%s: arch_timer_register failed %d\n", __func__, err);
+ clocksource_of_init();
}
#endif /* CONFIG_SOC_OMAP5 */
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index c5a3c6f9504e..e832bc7b8e2d 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -8,6 +8,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/err.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/errno.h>
@@ -26,6 +27,24 @@
static u8 async_cs, sync_cs;
static unsigned refclk_psec;
+static struct gpmc_settings tusb_async = {
+ .wait_on_read = true,
+ .wait_on_write = true,
+ .device_width = GPMC_DEVWIDTH_16BIT,
+ .mux_add_data = GPMC_MUX_AD,
+};
+
+static struct gpmc_settings tusb_sync = {
+ .burst_read = true,
+ .burst_write = true,
+ .sync_read = true,
+ .sync_write = true,
+ .wait_on_read = true,
+ .wait_on_write = true,
+ .burst_len = GPMC_BURST_16,
+ .device_width = GPMC_DEVWIDTH_16BIT,
+ .mux_add_data = GPMC_MUX_AD,
+};
/* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */
@@ -37,8 +56,6 @@ static int tusb_set_async_mode(unsigned sysclk_ps)
memset(&dev_t, 0, sizeof(dev_t));
- dev_t.mux = true;
-
dev_t.t_ceasu = 8 * 1000;
dev_t.t_avdasu = t_acsnh_advnh - 7000;
dev_t.t_ce_avd = 1000;
@@ -52,7 +69,7 @@ static int tusb_set_async_mode(unsigned sysclk_ps)
dev_t.t_wpl = 300;
dev_t.cyc_aavdh_we = 1;
- gpmc_calc_timings(&t, &dev_t);
+ gpmc_calc_timings(&t, &tusb_async, &dev_t);
return gpmc_cs_set_timings(async_cs, &t);
}
@@ -65,10 +82,6 @@ static int tusb_set_sync_mode(unsigned sysclk_ps)
memset(&dev_t, 0, sizeof(dev_t));
- dev_t.mux = true;
- dev_t.sync_read = true;
- dev_t.sync_write = true;
-
dev_t.clk = 11100;
dev_t.t_bacc = 1000;
dev_t.t_ces = 1000;
@@ -84,7 +97,7 @@ static int tusb_set_sync_mode(unsigned sysclk_ps)
dev_t.cyc_wpl = 6;
dev_t.t_ce_rdyz = 7000;
- gpmc_calc_timings(&t, &dev_t);
+ gpmc_calc_timings(&t, &tusb_sync, &dev_t);
return gpmc_cs_set_timings(sync_cs, &t);
}
@@ -165,18 +178,12 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
return status;
}
tusb_resources[0].end = tusb_resources[0].start + 0x9ff;
+ tusb_async.wait_pin = waitpin;
async_cs = async;
- gpmc_cs_write_reg(async, GPMC_CS_CONFIG1,
- GPMC_CONFIG1_PAGE_LEN(2)
- | GPMC_CONFIG1_WAIT_READ_MON
- | GPMC_CONFIG1_WAIT_WRITE_MON
- | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin)
- | GPMC_CONFIG1_READTYPE_ASYNC
- | GPMC_CONFIG1_WRITETYPE_ASYNC
- | GPMC_CONFIG1_DEVICESIZE_16
- | GPMC_CONFIG1_DEVICETYPE_NOR
- | GPMC_CONFIG1_MUXADDDATA);
+ status = gpmc_cs_program_settings(async_cs, &tusb_async);
+ if (status < 0)
+ return status;
/* SYNC region, primarily for DMA */
status = gpmc_cs_request(sync, SZ_16M, (unsigned long *)
@@ -186,21 +193,12 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
return status;
}
tusb_resources[1].end = tusb_resources[1].start + 0x9ff;
+ tusb_sync.wait_pin = waitpin;
sync_cs = sync;
- gpmc_cs_write_reg(sync, GPMC_CS_CONFIG1,
- GPMC_CONFIG1_READMULTIPLE_SUPP
- | GPMC_CONFIG1_READTYPE_SYNC
- | GPMC_CONFIG1_WRITEMULTIPLE_SUPP
- | GPMC_CONFIG1_WRITETYPE_SYNC
- | GPMC_CONFIG1_PAGE_LEN(2)
- | GPMC_CONFIG1_WAIT_READ_MON
- | GPMC_CONFIG1_WAIT_WRITE_MON
- | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin)
- | GPMC_CONFIG1_DEVICESIZE_16
- | GPMC_CONFIG1_DEVICETYPE_NOR
- | GPMC_CONFIG1_MUXADDDATA
- /* fclk divider gets set later */
- );
+
+ status = gpmc_cs_program_settings(sync_cs, &tusb_sync);
+ if (status < 0)
+ return status;
/* IRQ */
status = gpio_request_one(irq, GPIOF_IN, "TUSB6010 irq");