summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-13 10:59:11 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-13 10:59:11 -0800
commit698d601224824bc1a5bf17f3d86be902e2aabff0 (patch)
tree10262bd1f83fd26f874cbd898818e5925844a2ef /arch
parenta11da7df6543b5f71a150b47c0d08ecf0799a0f3 (diff)
parent4aa7cf79b1f760b5751d1686329351c2e060791b (diff)
downloadlinux-stable-698d601224824bc1a5bf17f3d86be902e2aabff0.tar.gz
linux-stable-698d601224824bc1a5bf17f3d86be902e2aabff0.tar.bz2
linux-stable-698d601224824bc1a5bf17f3d86be902e2aabff0.zip
Merge tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver specific changes from Olof Johansson: "A collection of mostly SoC-specific driver updates: - a handful of pincontrol and setup changes - new drivers for hwmon and reset controller for vexpress - timing support updates for OMAP (gpmc and other interfaces) - plus a collection of smaller cleanups" * tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (21 commits) ARM: ux500: fix pin warning ARM: OMAP2+: tusb6010: generic timing calculation ARM: OMAP2+: smc91x: generic timing calculation ARM: OMAP2+: onenand: generic timing calculation ARM: OMAP2+: gpmc: generic timing calculation ARM: OMAP2+: gpmc: handle additional timings ARM: OMAP2+: nand: remove redundant rounding gpio: samsung: use pr_* instead of printk ARM: ux500: fixup magnetometer pins ARM: ux500: add STM pin configuration ARM: ux500: 8500: add pinctrl support for uart1 and uart2 ARM: ux500: cosmetic fixups for uart0 gpio: samsung: Fix input mode setting function for GPIO int ARM: SAMSUNG: Insert bitmap_gpio_int member in samsung_gpio_chip ARM: ux500: 8500: define SDI sleep states ARM: vexpress: Reset driver ARM: ux500: 8500: update SKE keypad pinctrl table hwmon: Versatile Express hwmon driver ARM: ux500: delete duplicate macro ARM: ux500: 8500: add IDLE pin configuration for SPI ...
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/gpmc-nand.c26
-rw-r--r--arch/arm/mach-omap2/gpmc-onenand.c143
-rw-r--r--arch/arm/mach-omap2/gpmc-smc91x.c43
-rw-r--r--arch/arm/mach-omap2/gpmc.c373
-rw-r--r--arch/arm/mach-omap2/gpmc.h113
-rw-r--r--arch/arm/mach-omap2/usb-tusb6010.c181
-rw-r--r--arch/arm/mach-ux500/board-mop500-pins.c425
-rw-r--r--arch/arm/mach-vexpress/reset.c141
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-core.h2
-rw-r--r--arch/arm/plat-samsung/s5p-irq-gpioint.c8
10 files changed, 1096 insertions, 359 deletions
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 8607735b3ab3..db969a5c4998 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -52,27 +52,27 @@ static int omap2_nand_gpmc_retime(
memset(&t, 0, sizeof(t));
t.sync_clk = gpmc_t->sync_clk;
- t.cs_on = gpmc_round_ns_to_ticks(gpmc_t->cs_on);
- t.adv_on = gpmc_round_ns_to_ticks(gpmc_t->adv_on);
+ t.cs_on = gpmc_t->cs_on;
+ t.adv_on = gpmc_t->adv_on;
/* Read */
- t.adv_rd_off = gpmc_round_ns_to_ticks(gpmc_t->adv_rd_off);
+ t.adv_rd_off = gpmc_t->adv_rd_off;
t.oe_on = t.adv_on;
- t.access = gpmc_round_ns_to_ticks(gpmc_t->access);
- t.oe_off = gpmc_round_ns_to_ticks(gpmc_t->oe_off);
- t.cs_rd_off = gpmc_round_ns_to_ticks(gpmc_t->cs_rd_off);
- t.rd_cycle = gpmc_round_ns_to_ticks(gpmc_t->rd_cycle);
+ t.access = gpmc_t->access;
+ t.oe_off = gpmc_t->oe_off;
+ t.cs_rd_off = gpmc_t->cs_rd_off;
+ t.rd_cycle = gpmc_t->rd_cycle;
/* Write */
- t.adv_wr_off = gpmc_round_ns_to_ticks(gpmc_t->adv_wr_off);
+ t.adv_wr_off = gpmc_t->adv_wr_off;
t.we_on = t.oe_on;
if (cpu_is_omap34xx()) {
- t.wr_data_mux_bus = gpmc_round_ns_to_ticks(gpmc_t->wr_data_mux_bus);
- t.wr_access = gpmc_round_ns_to_ticks(gpmc_t->wr_access);
+ t.wr_data_mux_bus = gpmc_t->wr_data_mux_bus;
+ t.wr_access = gpmc_t->wr_access;
}
- t.we_off = gpmc_round_ns_to_ticks(gpmc_t->we_off);
- t.cs_wr_off = gpmc_round_ns_to_ticks(gpmc_t->cs_wr_off);
- t.wr_cycle = gpmc_round_ns_to_ticks(gpmc_t->wr_cycle);
+ t.we_off = gpmc_t->we_off;
+ 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)
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index d102183ed9a5..94a349e4dc96 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -33,7 +33,6 @@
static unsigned onenand_flags;
static unsigned latency;
-static int fclk_offset;
static struct omap_onenand_platform_data *gpmc_onenand_data;
@@ -50,6 +49,7 @@ static struct platform_device gpmc_onenand_device = {
static struct gpmc_timings omap2_onenand_calc_async_timings(void)
{
+ struct gpmc_device_timings dev_t;
struct gpmc_timings t;
const int t_cer = 15;
@@ -59,35 +59,24 @@ static struct gpmc_timings omap2_onenand_calc_async_timings(void)
const int t_aa = 76;
const int t_oe = 20;
const int t_cez = 20; /* max of t_cez, t_oez */
- const int t_ds = 30;
const int t_wpl = 40;
const int t_wph = 30;
- memset(&t, 0, sizeof(t));
- t.sync_clk = 0;
- t.cs_on = 0;
- t.adv_on = 0;
-
- /* Read */
- t.adv_rd_off = gpmc_round_ns_to_ticks(max_t(int, t_avdp, t_cer));
- t.oe_on = t.adv_rd_off + gpmc_round_ns_to_ticks(t_aavdh);
- t.access = t.adv_on + gpmc_round_ns_to_ticks(t_aa);
- t.access = max_t(int, t.access, t.cs_on + gpmc_round_ns_to_ticks(t_ce));
- t.access = max_t(int, t.access, t.oe_on + gpmc_round_ns_to_ticks(t_oe));
- t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
- t.cs_rd_off = t.oe_off;
- t.rd_cycle = t.cs_rd_off + gpmc_round_ns_to_ticks(t_cez);
-
- /* Write */
- t.adv_wr_off = t.adv_rd_off;
- t.we_on = t.oe_on;
- if (cpu_is_omap34xx()) {
- t.wr_data_mux_bus = t.we_on;
- t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
- }
- t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
- t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
- t.wr_cycle = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
+ 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;
+ dev_t.t_aa = t_aa * 1000;
+ dev_t.t_ce = t_ce * 1000;
+ dev_t.t_oe = t_oe * 1000;
+ dev_t.t_cez_r = t_cez * 1000;
+ dev_t.t_cez_w = dev_t.t_cez_r;
+ dev_t.t_wpl = t_wpl * 1000;
+ dev_t.t_wph = t_wph * 1000;
+
+ gpmc_calc_timings(&t, &dev_t);
return t;
}
@@ -173,18 +162,15 @@ static struct gpmc_timings
omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
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 */
- const int t_ds = 30;
const int t_wpl = 40;
const int t_wph = 30;
int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
- u32 reg;
- int div, fclk_offset_ns, gpmc_clk_ns;
- int ticks_cez;
- int cs = cfg->cs;
+ int div, gpmc_clk_ns;
if (cfg->flags & ONENAND_SYNC_READ)
onenand_flags = ONENAND_FLAG_SYNCREAD;
@@ -251,77 +237,35 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
latency = 4;
/* Set synchronous read timings */
- memset(&t, 0, sizeof(t));
-
- if (div == 1) {
- reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
- reg |= (1 << 7);
- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
- reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
- reg |= (1 << 7);
- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
- reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
- reg |= (1 << 7);
- reg |= (1 << 23);
- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
- } else {
- reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
- reg &= ~(1 << 7);
- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
- reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
- reg &= ~(1 << 7);
- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
- reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
- reg &= ~(1 << 7);
- reg &= ~(1 << 23);
- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
- }
+ memset(&dev_t, 0, sizeof(dev_t));
- t.sync_clk = min_gpmc_clk_period;
- t.cs_on = 0;
- t.adv_on = 0;
- fclk_offset_ns = gpmc_round_ns_to_ticks(max_t(int, t_ces, t_avds));
- fclk_offset = gpmc_ns_to_ticks(fclk_offset_ns);
- t.page_burst_access = gpmc_clk_ns;
-
- /* Read */
- t.adv_rd_off = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_avdh));
- t.oe_on = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_ach));
- /* Force at least 1 clk between AVD High to OE Low */
- if (t.oe_on <= t.adv_rd_off)
- t.oe_on = t.adv_rd_off + gpmc_round_ns_to_ticks(1);
- t.access = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div);
- t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
- t.cs_rd_off = t.oe_off;
- ticks_cez = ((gpmc_ns_to_ticks(t_cez) + div - 1) / div) * div;
- t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +
- ticks_cez);
-
- /* Write */
+ dev_t.mux = true;
+ dev_t.sync_read = true;
if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
- t.adv_wr_off = t.adv_rd_off;
- t.we_on = 0;
- t.we_off = t.cs_rd_off;
- t.cs_wr_off = t.cs_rd_off;
- t.wr_cycle = t.rd_cycle;
- if (cpu_is_omap34xx()) {
- t.wr_data_mux_bus = gpmc_ticks_to_ns(fclk_offset +
- gpmc_ps_to_ticks(min_gpmc_clk_period +
- t_rdyo * 1000));
- t.wr_access = t.access;
- }
+ dev_t.sync_write = true;
} else {
- t.adv_wr_off = gpmc_round_ns_to_ticks(max_t(int,
- t_avdp, t_cer));
- t.we_on = t.adv_wr_off + gpmc_round_ns_to_ticks(t_aavdh);
- t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
- t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
- t.wr_cycle = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
- if (cpu_is_omap34xx()) {
- t.wr_data_mux_bus = t.we_on;
- t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
- }
+ dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
+ dev_t.t_wpl = t_wpl * 1000;
+ dev_t.t_wph = t_wph * 1000;
+ dev_t.t_aavdh = t_aavdh * 1000;
}
+ dev_t.ce_xdelay = true;
+ dev_t.avd_xdelay = true;
+ dev_t.oe_xdelay = true;
+ dev_t.we_xdelay = true;
+ dev_t.clk = min_gpmc_clk_period;
+ dev_t.t_bacc = dev_t.clk;
+ dev_t.t_ces = t_ces * 1000;
+ dev_t.t_avds = t_avds * 1000;
+ dev_t.t_avdh = t_avdh * 1000;
+ dev_t.t_ach = t_ach * 1000;
+ dev_t.cyc_iaa = (latency + 1);
+ dev_t.t_cez_r = t_cez * 1000;
+ dev_t.t_cez_w = dev_t.t_cez_r;
+ 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;
}
@@ -338,7 +282,6 @@ static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t)
(sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) |
(sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
(sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
- GPMC_CONFIG1_CLKACTIVATIONTIME(fclk_offset) |
GPMC_CONFIG1_PAGE_LEN(2) |
(cpu_is_omap34xx() ? 0 :
(GPMC_CONFIG1_WAIT_READ_MON |
diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c
index 6eed907d594c..11d0b756f098 100644
--- a/arch/arm/mach-omap2/gpmc-smc91x.c
+++ b/arch/arm/mach-omap2/gpmc-smc91x.c
@@ -58,6 +58,7 @@ static struct platform_device gpmc_smc91x_device = {
static int smc91c96_gpmc_retime(void)
{
struct gpmc_timings t;
+ struct gpmc_device_timings dev_t;
const int t3 = 10; /* Figure 12.2 read and 12.4 write */
const int t4_r = 20; /* Figure 12.2 read */
const int t4_w = 5; /* Figure 12.4 write */
@@ -68,32 +69,6 @@ static int smc91c96_gpmc_retime(void)
const int t20 = 185; /* Figure 12.2 read and 12.4 write */
u32 l;
- memset(&t, 0, sizeof(t));
-
- /* Read timings */
- t.cs_on = 0;
- t.adv_on = t.cs_on;
- t.oe_on = t.adv_on + t3;
- t.access = t.oe_on + t5;
- t.oe_off = t.access;
- t.adv_rd_off = t.oe_off + max(t4_r, t6);
- t.cs_rd_off = t.oe_off;
- t.rd_cycle = t20 - t.oe_on;
-
- /* Write timings */
- t.we_on = t.adv_on + t3;
-
- if (cpu_is_omap34xx() && (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)) {
- t.wr_data_mux_bus = t.we_on;
- t.we_off = t.wr_data_mux_bus + t7;
- } else
- t.we_off = t.we_on + t7;
- if (cpu_is_omap34xx())
- t.wr_access = t.we_off;
- t.adv_wr_off = t.we_off + max(t4_w, t8);
- t.cs_wr_off = t.we_off + t4_w;
- t.wr_cycle = t20 - t.we_on;
-
l = GPMC_CONFIG1_DEVICESIZE_16;
if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
l |= GPMC_CONFIG1_MUXADDDATA;
@@ -115,6 +90,22 @@ static int smc91c96_gpmc_retime(void)
if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
return 0;
+ memset(&dev_t, 0, sizeof(dev_t));
+
+ dev_t.t_oeasu = t3 * 1000;
+ dev_t.t_oe = t5 * 1000;
+ dev_t.t_cez_r = t4_r * 1000;
+ dev_t.t_oez = t6 * 1000;
+ dev_t.t_rd_cycle = (t20 - t3) * 1000;
+
+ dev_t.t_weasu = t3 * 1000;
+ dev_t.t_wpl = t7 * 1000;
+ dev_t.t_wph = t8 * 1000;
+ dev_t.t_cez_w = t4_w * 1000;
+ dev_t.t_wr_cycle = (t20 - t3) * 1000;
+
+ gpmc_calc_timings(&t, &dev_t);
+
return gpmc_cs_set_timings(gpmc_cfg->cs, &t);
}
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index bf6117c32f4b..65468f6d7f0e 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -74,6 +74,13 @@
#define GPMC_ECC_CTRL_ECCREG8 0x008
#define GPMC_ECC_CTRL_ECCREG9 0x009
+#define GPMC_CONFIG2_CSEXTRADELAY BIT(7)
+#define GPMC_CONFIG3_ADVEXTRADELAY BIT(7)
+#define GPMC_CONFIG4_OEEXTRADELAY BIT(7)
+#define GPMC_CONFIG4_WEEXTRADELAY BIT(23)
+#define GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN BIT(6)
+#define GPMC_CONFIG6_CYCLE2CYCLESAMECSEN BIT(7)
+
#define GPMC_CS0_OFFSET 0x60
#define GPMC_CS_SIZE 0x30
#define GPMC_BCH_SIZE 0x10
@@ -223,6 +230,51 @@ unsigned int gpmc_round_ns_to_ticks(unsigned int 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();
+}
+
+static unsigned int gpmc_round_ps_to_ticks(unsigned int time_ps)
+{
+ unsigned long ticks = gpmc_ps_to_ticks(time_ps);
+
+ return ticks * gpmc_get_fclk_period();
+}
+
+static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value)
+{
+ u32 l;
+
+ l = gpmc_cs_read_reg(cs, reg);
+ if (value)
+ l |= mask;
+ else
+ l &= ~mask;
+ gpmc_cs_write_reg(cs, reg, l);
+}
+
+static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
+{
+ gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG1,
+ GPMC_CONFIG1_TIME_PARA_GRAN,
+ p->time_para_granularity);
+ gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG2,
+ GPMC_CONFIG2_CSEXTRADELAY, p->cs_extra_delay);
+ gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG3,
+ GPMC_CONFIG3_ADVEXTRADELAY, p->adv_extra_delay);
+ gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+ GPMC_CONFIG4_OEEXTRADELAY, p->oe_extra_delay);
+ gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+ GPMC_CONFIG4_OEEXTRADELAY, p->we_extra_delay);
+ gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
+ GPMC_CONFIG6_CYCLE2CYCLESAMECSEN,
+ p->cycle2cyclesamecsen);
+ gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
+ GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN,
+ p->cycle2cyclediffcsen);
+}
+
#ifdef DEBUG
static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
int time, const char *name)
@@ -316,6 +368,12 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
+ GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround);
+ GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay);
+
+ GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring);
+ GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation);
+
if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
if (gpmc_capability & GPMC_HAS_WR_ACCESS)
@@ -335,6 +393,8 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l);
}
+ gpmc_cs_bool_timings(cs, &t->bool_timings);
+
return 0;
}
@@ -748,6 +808,319 @@ static int __devinit gpmc_mem_init(void)
return 0;
}
+static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk)
+{
+ u32 temp;
+ int div;
+
+ div = gpmc_calc_divider(sync_clk);
+ temp = gpmc_ps_to_ticks(time_ps);
+ temp = (temp + div - 1) / div;
+ return gpmc_ticks_to_ps(temp * div);
+}
+
+/* XXX: can the cycles be avoided ? */
+static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
+ struct gpmc_device_timings *dev_t)
+{
+ bool mux = dev_t->mux;
+ u32 temp;
+
+ /* adv_rd_off */
+ temp = dev_t->t_avdp_r;
+ /* XXX: mux check required ? */
+ if (mux) {
+ /* XXX: t_avdp not to be required for sync, only added for tusb
+ * this indirectly necessitates requirement of t_avdp_r and
+ * t_avdp_w instead of having a single t_avdp
+ */
+ temp = max_t(u32, temp, gpmc_t->clk_activation + dev_t->t_avdh);
+ temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+ }
+ gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp);
+
+ /* oe_on */
+ temp = dev_t->t_oeasu; /* XXX: remove this ? */
+ if (mux) {
+ temp = max_t(u32, temp, gpmc_t->clk_activation + dev_t->t_ach);
+ temp = max_t(u32, temp, gpmc_t->adv_rd_off +
+ gpmc_ticks_to_ps(dev_t->cyc_aavdh_oe));
+ }
+ gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp);
+
+ /* access */
+ /* XXX: any scope for improvement ?, by combining oe_on
+ * and clk_activation, need to check whether
+ * access = clk_activation + round to sync clk ?
+ */
+ temp = max_t(u32, dev_t->t_iaa, dev_t->cyc_iaa * gpmc_t->sync_clk);
+ temp += gpmc_t->clk_activation;
+ if (dev_t->cyc_oe)
+ temp = max_t(u32, temp, gpmc_t->oe_on +
+ gpmc_ticks_to_ps(dev_t->cyc_oe));
+ gpmc_t->access = gpmc_round_ps_to_ticks(temp);
+
+ gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1);
+ gpmc_t->cs_rd_off = gpmc_t->oe_off;
+
+ /* rd_cycle */
+ temp = max_t(u32, dev_t->t_cez_r, dev_t->t_oez);
+ temp = gpmc_round_ps_to_sync_clk(temp, gpmc_t->sync_clk) +
+ gpmc_t->access;
+ /* XXX: barter t_ce_rdyz with t_cez_r ? */
+ if (dev_t->t_ce_rdyz)
+ temp = max_t(u32, temp, gpmc_t->cs_rd_off + dev_t->t_ce_rdyz);
+ gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp);
+
+ return 0;
+}
+
+static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
+ struct gpmc_device_timings *dev_t)
+{
+ bool mux = dev_t->mux;
+ u32 temp;
+
+ /* adv_wr_off */
+ temp = dev_t->t_avdp_w;
+ if (mux) {
+ temp = max_t(u32, temp,
+ gpmc_t->clk_activation + dev_t->t_avdh);
+ temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+ }
+ gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp);
+
+ /* wr_data_mux_bus */
+ temp = max_t(u32, dev_t->t_weasu,
+ gpmc_t->clk_activation + dev_t->t_rdyo);
+ /* XXX: shouldn't mux be kept as a whole for wr_data_mux_bus ?,
+ * and in that case remember to handle we_on properly
+ */
+ if (mux) {
+ temp = max_t(u32, temp,
+ gpmc_t->adv_wr_off + dev_t->t_aavdh);
+ temp = max_t(u32, temp, gpmc_t->adv_wr_off +
+ gpmc_ticks_to_ps(dev_t->cyc_aavdh_we));
+ }
+ gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp);
+
+ /* we_on */
+ if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
+ gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu);
+ else
+ gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
+
+ /* wr_access */
+ /* XXX: gpmc_capability check reqd ? , even if not, will not harm */
+ gpmc_t->wr_access = gpmc_t->access;
+
+ /* we_off */
+ temp = gpmc_t->we_on + dev_t->t_wpl;
+ temp = max_t(u32, temp,
+ gpmc_t->wr_access + gpmc_ticks_to_ps(1));
+ temp = max_t(u32, temp,
+ gpmc_t->we_on + gpmc_ticks_to_ps(dev_t->cyc_wpl));
+ gpmc_t->we_off = gpmc_round_ps_to_ticks(temp);
+
+ gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off +
+ dev_t->t_wph);
+
+ /* wr_cycle */
+ temp = gpmc_round_ps_to_sync_clk(dev_t->t_cez_w, gpmc_t->sync_clk);
+ temp += gpmc_t->wr_access;
+ /* XXX: barter t_ce_rdyz with t_cez_w ? */
+ if (dev_t->t_ce_rdyz)
+ temp = max_t(u32, temp,
+ gpmc_t->cs_wr_off + dev_t->t_ce_rdyz);
+ gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
+
+ return 0;
+}
+
+static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t,
+ struct gpmc_device_timings *dev_t)
+{
+ bool mux = dev_t->mux;
+ u32 temp;
+
+ /* adv_rd_off */
+ temp = dev_t->t_avdp_r;
+ if (mux)
+ temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+ gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp);
+
+ /* oe_on */
+ temp = dev_t->t_oeasu;
+ if (mux)
+ temp = max_t(u32, temp,
+ gpmc_t->adv_rd_off + dev_t->t_aavdh);
+ gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp);
+
+ /* access */
+ temp = max_t(u32, dev_t->t_iaa, /* XXX: remove t_iaa in async ? */
+ gpmc_t->oe_on + dev_t->t_oe);
+ temp = max_t(u32, temp,
+ gpmc_t->cs_on + dev_t->t_ce);
+ temp = max_t(u32, temp,
+ gpmc_t->adv_on + dev_t->t_aa);
+ gpmc_t->access = gpmc_round_ps_to_ticks(temp);
+
+ gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1);
+ gpmc_t->cs_rd_off = gpmc_t->oe_off;
+
+ /* rd_cycle */
+ temp = max_t(u32, dev_t->t_rd_cycle,
+ gpmc_t->cs_rd_off + dev_t->t_cez_r);
+ temp = max_t(u32, temp, gpmc_t->oe_off + dev_t->t_oez);
+ gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp);
+
+ return 0;
+}
+
+static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t,
+ struct gpmc_device_timings *dev_t)
+{
+ bool mux = dev_t->mux;
+ u32 temp;
+
+ /* adv_wr_off */
+ temp = dev_t->t_avdp_w;
+ if (mux)
+ temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+ gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp);
+
+ /* wr_data_mux_bus */
+ temp = dev_t->t_weasu;
+ if (mux) {
+ temp = max_t(u32, temp, gpmc_t->adv_wr_off + dev_t->t_aavdh);
+ temp = max_t(u32, temp, gpmc_t->adv_wr_off +
+ gpmc_ticks_to_ps(dev_t->cyc_aavdh_we));
+ }
+ gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp);
+
+ /* we_on */
+ if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
+ gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu);
+ else
+ gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
+
+ /* we_off */
+ temp = gpmc_t->we_on + dev_t->t_wpl;
+ gpmc_t->we_off = gpmc_round_ps_to_ticks(temp);
+
+ gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off +
+ dev_t->t_wph);
+
+ /* wr_cycle */
+ temp = max_t(u32, dev_t->t_wr_cycle,
+ gpmc_t->cs_wr_off + dev_t->t_cez_w);
+ gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
+
+ return 0;
+}
+
+static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t,
+ struct gpmc_device_timings *dev_t)
+{
+ u32 temp;
+
+ gpmc_t->sync_clk = gpmc_calc_divider(dev_t->clk) *
+ gpmc_get_fclk_period();
+
+ gpmc_t->page_burst_access = gpmc_round_ps_to_sync_clk(
+ dev_t->t_bacc,
+ gpmc_t->sync_clk);
+
+ temp = max_t(u32, dev_t->t_ces, dev_t->t_avds);
+ gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp);
+
+ if (gpmc_calc_divider(gpmc_t->sync_clk) != 1)
+ return 0;
+
+ if (dev_t->ce_xdelay)
+ gpmc_t->bool_timings.cs_extra_delay = true;
+ if (dev_t->avd_xdelay)
+ gpmc_t->bool_timings.adv_extra_delay = true;
+ if (dev_t->oe_xdelay)
+ gpmc_t->bool_timings.oe_extra_delay = true;
+ if (dev_t->we_xdelay)
+ gpmc_t->bool_timings.we_extra_delay = true;
+
+ return 0;
+}
+
+static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
+ struct gpmc_device_timings *dev_t)
+{
+ u32 temp;
+
+ /* cs_on */
+ gpmc_t->cs_on = gpmc_round_ps_to_ticks(dev_t->t_ceasu);
+
+ /* adv_on */
+ temp = dev_t->t_avdasu;
+ if (dev_t->t_ce_avd)
+ temp = max_t(u32, temp,
+ gpmc_t->cs_on + dev_t->t_ce_avd);
+ gpmc_t->adv_on = gpmc_round_ps_to_ticks(temp);
+
+ if (dev_t->sync_write || dev_t->sync_read)
+ gpmc_calc_sync_common_timings(gpmc_t, dev_t);
+
+ return 0;
+}
+
+/* TODO: remove this function once all peripherals are confirmed to
+ * work with generic timing. Simultaneously gpmc_cs_set_timings()
+ * has to be modified to handle timings in ps instead of ns
+*/
+static void gpmc_convert_ps_to_ns(struct gpmc_timings *t)
+{
+ t->cs_on /= 1000;
+ t->cs_rd_off /= 1000;
+ t->cs_wr_off /= 1000;
+ t->adv_on /= 1000;
+ t->adv_rd_off /= 1000;
+ t->adv_wr_off /= 1000;
+ t->we_on /= 1000;
+ t->we_off /= 1000;
+ t->oe_on /= 1000;
+ t->oe_off /= 1000;
+ t->page_burst_access /= 1000;
+ t->access /= 1000;
+ t->rd_cycle /= 1000;
+ t->wr_cycle /= 1000;
+ t->bus_turnaround /= 1000;
+ t->cycle2cycle_delay /= 1000;
+ t->wait_monitoring /= 1000;
+ t->clk_activation /= 1000;
+ t->wr_access /= 1000;
+ t->wr_data_mux_bus /= 1000;
+}
+
+int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
+ struct gpmc_device_timings *dev_t)
+{
+ memset(gpmc_t, 0, sizeof(*gpmc_t));
+
+ gpmc_calc_common_timings(gpmc_t, dev_t);
+
+ if (dev_t->sync_read)
+ gpmc_calc_sync_read_timings(gpmc_t, dev_t);
+ else
+ gpmc_calc_async_read_timings(gpmc_t, dev_t);
+
+ if (dev_t->sync_write)
+ gpmc_calc_sync_write_timings(gpmc_t, dev_t);
+ else
+ gpmc_calc_async_write_timings(gpmc_t, dev_t);
+
+ /* TODO: remove, see function definition */
+ gpmc_convert_ps_to_ns(gpmc_t);
+
+ return 0;
+}
+
static __devinit int gpmc_probe(struct platform_device *pdev)
{
int rc;
diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
index 79f4dfc2adb3..fe0a844d5007 100644
--- a/arch/arm/mach-omap2/gpmc.h
+++ b/arch/arm/mach-omap2/gpmc.h
@@ -74,6 +74,17 @@
#define GPMC_IRQ_COUNT_EVENT 0x02
+/* bool type time settings */
+struct gpmc_bool_timings {
+ bool cycle2cyclediffcsen;
+ bool cycle2cyclesamecsen;
+ bool we_extra_delay;
+ bool oe_extra_delay;
+ bool adv_extra_delay;
+ bool cs_extra_delay;
+ bool time_para_granularity;
+};
+
/*
* Note that all values in this struct are in nanoseconds except sync_clk
* (which is in picoseconds), while the register values are in gpmc_fck cycles.
@@ -83,34 +94,104 @@ struct gpmc_timings {
u32 sync_clk;
/* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
- u16 cs_on; /* Assertion time */
- u16 cs_rd_off; /* Read deassertion time */
- u16 cs_wr_off; /* Write deassertion time */
+ u32 cs_on; /* Assertion time */
+ u32 cs_rd_off; /* Read deassertion time */
+ u32 cs_wr_off; /* Write deassertion time */
/* ADV signal timings corresponding to GPMC_CONFIG3 */
- u16 adv_on; /* Assertion time */
- u16 adv_rd_off; /* Read deassertion time */
- u16 adv_wr_off; /* Write deassertion time */
+ u32 adv_on; /* Assertion time */
+ u32 adv_rd_off; /* Read deassertion time */
+ u32 adv_wr_off; /* Write deassertion time */
/* WE signals timings corresponding to GPMC_CONFIG4 */
- u16 we_on; /* WE assertion time */
- u16 we_off; /* WE deassertion time */
+ u32 we_on; /* WE assertion time */
+ u32 we_off; /* WE deassertion time */
/* OE signals timings corresponding to GPMC_CONFIG4 */
- u16 oe_on; /* OE assertion time */
- u16 oe_off; /* OE deassertion time */
+ u32 oe_on; /* OE assertion time */
+ u32 oe_off; /* OE deassertion time */
/* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
- u16 page_burst_access; /* Multiple access word delay */
- u16 access; /* Start-cycle to first data valid delay */
- u16 rd_cycle; /* Total read cycle time */
- u16 wr_cycle; /* Total write cycle time */
+ u32 page_burst_access; /* Multiple access word delay */
+ u32 access; /* Start-cycle to first data valid delay */
+ u32 rd_cycle; /* Total read cycle time */
+ u32 wr_cycle; /* Total write cycle time */
+
+ u32 bus_turnaround;
+ u32 cycle2cycle_delay;
+
+ u32 wait_monitoring;
+ u32 clk_activation;
/* The following are only on OMAP3430 */
- u16 wr_access; /* WRACCESSTIME */
- u16 wr_data_mux_bus; /* WRDATAONADMUXBUS */
+ u32 wr_access; /* WRACCESSTIME */
+ u32 wr_data_mux_bus; /* WRDATAONADMUXBUS */
+
+ struct gpmc_bool_timings bool_timings;
+};
+
+/* Device timings in picoseconds */
+struct gpmc_device_timings {
+ u32 t_ceasu; /* address setup to CS valid */
+ u32 t_avdasu; /* address setup to ADV valid */
+ /* XXX: try to combine t_avdp_r & t_avdp_w. Issue is
+ * of tusb using these timings even for sync whilst
+ * ideally for adv_rd/(wr)_off it should have considered
+ * t_avdh instead. This indirectly necessitates r/w
+ * variations of t_avdp as it is possible to have one
+ * sync & other async
+ */
+ u32 t_avdp_r; /* ADV low time (what about t_cer ?) */
+ u32 t_avdp_w;
+ u32 t_aavdh; /* address hold time */
+ u32 t_oeasu; /* address setup to OE valid */
+ u32 t_aa; /* access time from ADV assertion */
+ u32 t_iaa; /* initial access time */
+ u32 t_oe; /* access time from OE assertion */
+ u32 t_ce; /* access time from CS asertion */
+ u32 t_rd_cycle; /* read cycle time */
+ u32 t_cez_r; /* read CS deassertion to high Z */
+ u32 t_cez_w; /* write CS deassertion to high Z */
+ u32 t_oez; /* OE deassertion to high Z */
+ u32 t_weasu; /* address setup to WE valid */
+ u32 t_wpl; /* write assertion time */
+ u32 t_wph; /* write deassertion time */
+ u32 t_wr_cycle; /* write cycle time */
+
+ u32 clk;
+ u32 t_bacc; /* burst access valid clock to output delay */
+ u32 t_ces; /* CS setup time to clk */
+ u32 t_avds; /* ADV setup time to clk */
+ u32 t_avdh; /* ADV hold time from clk */
+ u32 t_ach; /* address hold time from clk */
+ u32 t_rdyo; /* clk to ready valid */
+
+ u32 t_ce_rdyz; /* XXX: description ?, or use t_cez instead */
+ u32 t_ce_avd; /* CS on to ADV on delay */
+
+ /* XXX: check the possibility of combining
+ * cyc_aavhd_oe & cyc_aavdh_we
+ */
+ u8 cyc_aavdh_oe;/* read address hold time in cycles */
+ u8 cyc_aavdh_we;/* write address hold time in cycles */
+ u8 cyc_oe; /* access time from OE assertion in cycles */
+ u8 cyc_wpl; /* write deassertion time in cycles */
+ u32 cyc_iaa; /* initial access time in cycles */
+
+ bool mux; /* address & data muxed */
+ bool sync_write;/* synchronous write */
+ bool sync_read; /* synchronous read */
+
+ /* extra delays */
+ bool ce_xdelay;
+ bool avd_xdelay;
+ bool oe_xdelay;
+ bool we_xdelay;
};
+extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
+ 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);
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index a8795ff19e6d..c5a3c6f9504e 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -27,180 +27,88 @@ static u8 async_cs, sync_cs;
static unsigned refclk_psec;
-/* t2_ps, when quantized to fclk units, must happen no earlier than
- * the clock after after t1_NS.
- *
- * Return a possibly updated value of t2_ps, converted to nsec.
- */
-static unsigned
-next_clk(unsigned t1_NS, unsigned t2_ps, unsigned fclk_ps)
-{
- unsigned t1_ps = t1_NS * 1000;
- unsigned t1_f, t2_f;
-
- if ((t1_ps + fclk_ps) < t2_ps)
- return t2_ps / 1000;
-
- t1_f = (t1_ps + fclk_ps - 1) / fclk_ps;
- t2_f = (t2_ps + fclk_ps - 1) / fclk_ps;
-
- if (t1_f >= t2_f)
- t2_f = t1_f + 1;
-
- return (t2_f * fclk_ps) / 1000;
-}
-
/* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */
-static int tusb_set_async_mode(unsigned sysclk_ps, unsigned fclk_ps)
+static int tusb_set_async_mode(unsigned sysclk_ps)
{
+ struct gpmc_device_timings dev_t;
struct gpmc_timings t;
unsigned t_acsnh_advnh = sysclk_ps + 3000;
- unsigned tmp;
-
- memset(&t, 0, sizeof(t));
-
- /* CS_ON = t_acsnh_acsnl */
- t.cs_on = 8;
- /* ADV_ON = t_acsnh_advnh - t_advn */
- t.adv_on = next_clk(t.cs_on, t_acsnh_advnh - 7000, fclk_ps);
-
- /*
- * READ ... from omap2420 TRM fig 12-13
- */
-
- /* ADV_RD_OFF = t_acsnh_advnh */
- t.adv_rd_off = next_clk(t.adv_on, t_acsnh_advnh, fclk_ps);
-
- /* OE_ON = t_acsnh_advnh + t_advn_oen (then wait for nRDY) */
- t.oe_on = next_clk(t.adv_on, t_acsnh_advnh + 1000, fclk_ps);
-
- /* ACCESS = counters continue only after nRDY */
- tmp = t.oe_on * 1000 + 300;
- t.access = next_clk(t.oe_on, tmp, fclk_ps);
-
- /* OE_OFF = after data gets sampled */
- tmp = t.access * 1000;
- t.oe_off = next_clk(t.access, tmp, fclk_ps);
-
- t.cs_rd_off = t.oe_off;
-
- tmp = t.cs_rd_off * 1000 + 7000 /* t_acsn_rdy_z */;
- t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps);
-
- /*
- * WRITE ... from omap2420 TRM fig 12-15
- */
-
- /* ADV_WR_OFF = t_acsnh_advnh */
- t.adv_wr_off = t.adv_rd_off;
- /* WE_ON = t_acsnh_advnh + t_advn_wen (then wait for nRDY) */
- t.we_on = next_clk(t.adv_wr_off, t_acsnh_advnh + 1000, fclk_ps);
+ memset(&dev_t, 0, sizeof(dev_t));
- /* WE_OFF = after data gets sampled */
- tmp = t.we_on * 1000 + 300;
- t.we_off = next_clk(t.we_on, tmp, fclk_ps);
+ dev_t.mux = true;
- t.cs_wr_off = t.we_off;
+ dev_t.t_ceasu = 8 * 1000;
+ dev_t.t_avdasu = t_acsnh_advnh - 7000;
+ dev_t.t_ce_avd = 1000;
+ dev_t.t_avdp_r = t_acsnh_advnh;
+ dev_t.t_oeasu = t_acsnh_advnh + 1000;
+ dev_t.t_oe = 300;
+ dev_t.t_cez_r = 7000;
+ dev_t.t_cez_w = dev_t.t_cez_r;
+ dev_t.t_avdp_w = t_acsnh_advnh;
+ dev_t.t_weasu = t_acsnh_advnh + 1000;
+ dev_t.t_wpl = 300;
+ dev_t.cyc_aavdh_we = 1;
- tmp = t.cs_wr_off * 1000 + 7000 /* t_acsn_rdy_z */;
- t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
+ gpmc_calc_timings(&t, &dev_t);
return gpmc_cs_set_timings(async_cs, &t);
}
-static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps)
+static int tusb_set_sync_mode(unsigned sysclk_ps)
{
+ struct gpmc_device_timings dev_t;
struct gpmc_timings t;
unsigned t_scsnh_advnh = sysclk_ps + 3000;
- unsigned tmp;
-
- memset(&t, 0, sizeof(t));
- t.cs_on = 8;
-
- /* ADV_ON = t_acsnh_advnh - t_advn */
- t.adv_on = next_clk(t.cs_on, t_scsnh_advnh - 7000, fclk_ps);
-
- /* GPMC_CLK rate = fclk rate / div */
- t.sync_clk = 11100 /* 11.1 nsec */;
- tmp = (t.sync_clk + fclk_ps - 1) / fclk_ps;
- if (tmp > 4)
- return -ERANGE;
- if (tmp == 0)
- tmp = 1;
- t.page_burst_access = (fclk_ps * tmp) / 1000;
-
- /*
- * READ ... based on omap2420 TRM fig 12-19, 12-20
- */
-
- /* ADV_RD_OFF = t_scsnh_advnh */
- t.adv_rd_off = next_clk(t.adv_on, t_scsnh_advnh, fclk_ps);
-
- /* OE_ON = t_scsnh_advnh + t_advn_oen * fclk_ps (then wait for nRDY) */
- tmp = (t.adv_rd_off * 1000) + (3 * fclk_ps);
- t.oe_on = next_clk(t.adv_on, tmp, fclk_ps);
-
- /* ACCESS = number of clock cycles after t_adv_eon */
- tmp = (t.oe_on * 1000) + (5 * fclk_ps);
- t.access = next_clk(t.oe_on, tmp, fclk_ps);
- /* OE_OFF = after data gets sampled */
- tmp = (t.access * 1000) + (1 * fclk_ps);
- t.oe_off = next_clk(t.access, tmp, fclk_ps);
-
- t.cs_rd_off = t.oe_off;
-
- tmp = t.cs_rd_off * 1000 + 7000 /* t_scsn_rdy_z */;
- t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps);
-
- /*
- * WRITE ... based on omap2420 TRM fig 12-21
- */
-
- /* ADV_WR_OFF = t_scsnh_advnh */
- t.adv_wr_off = t.adv_rd_off;
-
- /* WE_ON = t_scsnh_advnh + t_advn_wen * fclk_ps (then wait for nRDY) */
- tmp = (t.adv_wr_off * 1000) + (3 * fclk_ps);
- t.we_on = next_clk(t.adv_wr_off, tmp, fclk_ps);
-
- /* WE_OFF = number of clock cycles after t_adv_wen */
- tmp = (t.we_on * 1000) + (6 * fclk_ps);
- t.we_off = next_clk(t.we_on, tmp, fclk_ps);
-
- t.cs_wr_off = t.we_off;
-
- tmp = t.cs_wr_off * 1000 + 7000 /* t_scsn_rdy_z */;
- t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_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;
+ dev_t.t_ceasu = 8 * 1000;
+ dev_t.t_avdasu = t_scsnh_advnh - 7000;
+ dev_t.t_ce_avd = 1000;
+ dev_t.t_avdp_r = t_scsnh_advnh;
+ dev_t.cyc_aavdh_oe = 3;
+ dev_t.cyc_oe = 5;
+ dev_t.t_ce_rdyz = 7000;
+ dev_t.t_avdp_w = t_scsnh_advnh;
+ dev_t.cyc_aavdh_we = 3;
+ dev_t.cyc_wpl = 6;
+ dev_t.t_ce_rdyz = 7000;
+
+ gpmc_calc_timings(&t, &dev_t);
return gpmc_cs_set_timings(sync_cs, &t);
}
-extern unsigned long gpmc_get_fclk_period(void);
-
/* tusb driver calls this when it changes the chip's clocking */
int tusb6010_platform_retime(unsigned is_refclk)
{
static const char error[] =
KERN_ERR "tusb6010 %s retime error %d\n";
- unsigned fclk_ps = gpmc_get_fclk_period();
unsigned sysclk_ps;
int status;
- if (!refclk_psec || fclk_ps == 0)
+ if (!refclk_psec)
return -ENODEV;
sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60;
- status = tusb_set_async_mode(sysclk_ps, fclk_ps);
+ status = tusb_set_async_mode(sysclk_ps);
if (status < 0) {
printk(error, "async", status);
goto done;
}
- status = tusb_set_sync_mode(sysclk_ps, fclk_ps);
+ status = tusb_set_sync_mode(sysclk_ps);
if (status < 0)
printk(error, "sync", status);
done:
@@ -284,7 +192,6 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
| GPMC_CONFIG1_READTYPE_SYNC
| GPMC_CONFIG1_WRITEMULTIPLE_SUPP
| GPMC_CONFIG1_WRITETYPE_SYNC
- | GPMC_CONFIG1_CLKACTIVATIONTIME(1)
| GPMC_CONFIG1_PAGE_LEN(2)
| GPMC_CONFIG1_WAIT_READ_MON
| GPMC_CONFIG1_WAIT_WRITE_MON
diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c
index c34d4efd0d5c..0a3f30df1eb8 100644
--- a/arch/arm/mach-ux500/board-mop500-pins.c
+++ b/arch/arm/mach-ux500/board-mop500-pins.c
@@ -33,8 +33,6 @@ BIAS(in_nopull, PIN_INPUT_NOPULL);
BIAS(in_nopull_slpm_nowkup, PIN_INPUT_NOPULL|PIN_SLPM_WAKEUP_DISABLE);
BIAS(in_pu, PIN_INPUT_PULLUP);
BIAS(in_pd, PIN_INPUT_PULLDOWN);
-BIAS(in_pd_slpm_in_pu, PIN_INPUT_PULLDOWN|PIN_SLPM_INPUT_PULLUP);
-BIAS(in_pu_slpm_out_lo, PIN_INPUT_PULLUP|PIN_SLPM_OUTPUT_LOW);
BIAS(out_hi, PIN_OUTPUT_HIGH);
BIAS(out_lo, PIN_OUTPUT_LOW);
BIAS(out_lo_slpm_nowkup, PIN_OUTPUT_LOW|PIN_SLPM_WAKEUP_DISABLE);
@@ -46,14 +44,34 @@ BIAS(gpio_in_pd_slpm_gpio_nopull, PIN_INPUT_PULLDOWN|PIN_GPIOMODE_ENABLED|PIN_SL
BIAS(gpio_out_hi, PIN_OUTPUT_HIGH|PIN_GPIOMODE_ENABLED);
BIAS(gpio_out_lo, PIN_OUTPUT_LOW|PIN_GPIOMODE_ENABLED);
/* Sleep modes */
-BIAS(slpm_in_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_DIR_INPUT|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
-BIAS(slpm_in_nopull_wkup, PIN_SLEEPMODE_ENABLED|PIN_SLPM_DIR_INPUT|PIN_SLPM_PULL_NONE|PIN_SLPM_WAKEUP_ENABLE);
-BIAS(slpm_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
-BIAS(slpm_out_hi_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_OUTPUT_HIGH|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
-BIAS(slpm_out_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
-BIAS(slpm_out_lo_wkup, PIN_SLEEPMODE_ENABLED|PIN_SLPM_OUTPUT_LOW|PIN_SLPM_WAKEUP_ENABLE);
-BIAS(slpm_out_lo_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_OUTPUT_LOW|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
-BIAS(slpm_in_nopull_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_INPUT_NOPULL|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
+BIAS(slpm_in_nopull_wkup, PIN_SLEEPMODE_ENABLED|
+ PIN_SLPM_DIR_INPUT|PIN_SLPM_PULL_NONE|PIN_SLPM_WAKEUP_ENABLE);
+BIAS(slpm_in_wkup_pdis, PIN_SLEEPMODE_ENABLED|
+ PIN_SLPM_DIR_INPUT|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
+BIAS(slpm_wkup_pdis, PIN_SLEEPMODE_ENABLED|
+ PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
+BIAS(slpm_out_lo_pdis, PIN_SLEEPMODE_ENABLED|
+ PIN_SLPM_OUTPUT_LOW|PIN_SLPM_WAKEUP_DISABLE|PIN_SLPM_PDIS_DISABLED);
+BIAS(slpm_out_lo_wkup, PIN_SLEEPMODE_ENABLED|
+ PIN_SLPM_OUTPUT_LOW|PIN_SLPM_WAKEUP_ENABLE);
+BIAS(slpm_out_lo_wkup_pdis, PIN_SLEEPMODE_ENABLED|
+ PIN_SLPM_OUTPUT_LOW|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
+BIAS(slpm_out_hi_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_OUTPUT_HIGH|
+ PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
+BIAS(slpm_in_nopull_wkup_pdis, PIN_SLEEPMODE_ENABLED|
+ PIN_SLPM_INPUT_NOPULL|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
+BIAS(slpm_in_pu_wkup_pdis_en, PIN_SLEEPMODE_ENABLED|PIN_SLPM_INPUT_PULLUP|
+ PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_ENABLED);
+BIAS(slpm_out_wkup_pdis, PIN_SLEEPMODE_ENABLED|
+ PIN_SLPM_DIR_OUTPUT|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
+BIAS(out_lo_wkup_pdis, PIN_SLPM_OUTPUT_LOW|
+ PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
+BIAS(in_wkup_pdis_en, PIN_SLPM_DIR_INPUT|PIN_SLPM_WAKEUP_ENABLE|
+ PIN_SLPM_PDIS_ENABLED);
+BIAS(in_wkup_pdis, PIN_SLPM_DIR_INPUT|PIN_SLPM_WAKEUP_ENABLE|
+ PIN_SLPM_PDIS_DISABLED);
+BIAS(out_wkup_pdis, PIN_SLPM_DIR_OUTPUT|PIN_SLPM_WAKEUP_ENABLE|
+ PIN_SLPM_PDIS_DISABLED);
/* We use these to define hog settings that are always done on boot */
#define DB8500_MUX_HOG(group,func) \
@@ -69,13 +87,16 @@ BIAS(slpm_in_nopull_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_INPUT_NOPULL|PIN_S
PIN_MAP_MUX_GROUP_DEFAULT(dev, "pinctrl-db8500", group, func)
#define DB8500_PIN(pin,conf,dev) \
PIN_MAP_CONFIGS_PIN_DEFAULT(dev, "pinctrl-db8500", pin, conf)
-#define DB8500_PIN_SLEEP(pin, conf, dev) \
- PIN_MAP_CONFIGS_PIN(dev, PINCTRL_STATE_SLEEP, "pinctrl-db8500", \
+#define DB8500_PIN_IDLE(pin, conf, dev) \
+ PIN_MAP_CONFIGS_PIN(dev, PINCTRL_STATE_IDLE, "pinctrl-db8500", \
pin, conf)
-
-#define DB8500_PIN_SLEEP(pin,conf,dev) \
+#define DB8500_PIN_SLEEP(pin, conf, dev) \
PIN_MAP_CONFIGS_PIN(dev, PINCTRL_STATE_SLEEP, "pinctrl-db8500", \
pin, conf)
+#define DB8500_MUX_STATE(group, func, dev, state) \
+ PIN_MAP_MUX_GROUP(dev, state, "pinctrl-db8500", group, func)
+#define DB8500_PIN_STATE(pin, conf, dev, state) \
+ PIN_MAP_CONFIGS_PIN(dev, state, "pinctrl-db8500", pin, conf)
/* Pin control settings */
static struct pinctrl_map __initdata mop500_family_pinmap[] = {
@@ -112,7 +133,7 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = {
* UART0, we do not mux in u0 here.
* uart-0 pins gpio configuration should be kept intact to prevent
* a glitch in tx line when the tty dev is opened. Later these pins
- * are configured to uart mop500_pins_uart0
+ * are configured by uart driver
*/
DB8500_PIN_HOG("GPIO0_AJ5", in_pu), /* CTS */
DB8500_PIN_HOG("GPIO1_AJ3", out_hi), /* RTS */
@@ -123,12 +144,13 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = {
* TODO: is this used on U8500 variants and Snowball really?
* The setting on GPIO31 conflicts with magnetometer use on hrefv60
*/
- DB8500_MUX_HOG("u2rxtx_c_1", "u2"),
- DB8500_MUX_HOG("u2ctsrts_c_1", "u2"),
- DB8500_PIN_HOG("GPIO29_W2", in_pu), /* RXD */
- DB8500_PIN_HOG("GPIO30_W3", out_hi), /* TXD */
- DB8500_PIN_HOG("GPIO31_V3", in_pu), /* CTS */
- DB8500_PIN_HOG("GPIO32_V2", out_hi), /* RTS */
+ /* default state for UART2 */
+ DB8500_MUX("u2rxtx_c_1", "u2", "uart2"),
+ DB8500_PIN("GPIO29_W2", in_pu, "uart2"), /* RXD */
+ DB8500_PIN("GPIO30_W3", out_hi, "uart2"), /* TXD */
+ /* Sleep state for UART2 */
+ DB8500_PIN_SLEEP("GPIO29_W2", in_wkup_pdis, "uart2"),
+ DB8500_PIN_SLEEP("GPIO30_W3", out_wkup_pdis, "uart2"),
/*
* The following pin sets were known as "runtime pins" before being
* converted to the pinctrl model. Here we model them as "default"
@@ -140,11 +162,18 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = {
DB8500_PIN("GPIO1_AJ3", out_hi, "uart0"), /* RTS */
DB8500_PIN("GPIO2_AH4", in_pu, "uart0"), /* RXD */
DB8500_PIN("GPIO3_AH3", out_hi, "uart0"), /* TXD */
- /* UART0 sleep state */
+ /* Sleep state for UART0 */
DB8500_PIN_SLEEP("GPIO0_AJ5", slpm_in_wkup_pdis, "uart0"),
DB8500_PIN_SLEEP("GPIO1_AJ3", slpm_out_hi_wkup_pdis, "uart0"),
DB8500_PIN_SLEEP("GPIO2_AH4", slpm_in_wkup_pdis, "uart0"),
DB8500_PIN_SLEEP("GPIO3_AH3", slpm_out_wkup_pdis, "uart0"),
+ /* Mux in UART1 after initialization */
+ DB8500_MUX("u1rxtx_a_1", "u1", "uart1"),
+ DB8500_PIN("GPIO4_AH6", in_pu, "uart1"), /* RXD */
+ DB8500_PIN("GPIO5_AG6", out_hi, "uart1"), /* TXD */
+ /* Sleep state for UART1 */
+ DB8500_PIN_SLEEP("GPIO4_AH6", slpm_in_wkup_pdis, "uart1"),
+ DB8500_PIN_SLEEP("GPIO5_AG6", slpm_out_wkup_pdis, "uart1"),
/* MSP1 for ALSA codec */
DB8500_MUX("msp1txrx_a_1", "msp1", "ux500-msp-i2s.1"),
DB8500_MUX("msp1_a_1", "msp1", "ux500-msp-i2s.1"),
@@ -161,7 +190,10 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = {
DB8500_MUX("lcd_d8_d11_a_1", "lcd", "mcde-tvout"),
DB8500_MUX("lcdaclk_b_1", "lcda", "mcde-tvout"),
/* Mux in LCD VSI1 and pull it up for MCDE HDMI output */
- DB8500_MUX("lcdvsi1_a_1", "lcd", "av8100-hdmi"),
+ DB8500_MUX("lcdvsi1_a_1", "lcd", "0-0070"),
+ DB8500_PIN("GPIO69_E2", in_pu, "0-0070"),
+ /* LCD VSI1 sleep state */
+ DB8500_PIN_SLEEP("GPIO69_E2", slpm_in_wkup_pdis, "0-0070"),
/* Mux in i2c0 block, default state */
DB8500_MUX("i2c0_a_1", "i2c0", "nmk-i2c.0"),
/* i2c0 sleep state */
@@ -194,6 +226,18 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = {
DB8500_PIN("GPIO26_Y2", in_pu, "sdi0"), /* DAT1 */
DB8500_PIN("GPIO27_AA2", in_pu, "sdi0"), /* DAT2 */
DB8500_PIN("GPIO28_AA1", in_pu, "sdi0"), /* DAT3 */
+ /* SDI0 sleep state */
+ DB8500_PIN_SLEEP("GPIO18_AC2", slpm_out_hi_wkup_pdis, "sdi0"),
+ DB8500_PIN_SLEEP("GPIO19_AC1", slpm_out_hi_wkup_pdis, "sdi0"),
+ DB8500_PIN_SLEEP("GPIO20_AB4", slpm_out_hi_wkup_pdis, "sdi0"),
+ DB8500_PIN_SLEEP("GPIO22_AA3", slpm_in_wkup_pdis, "sdi0"),
+ DB8500_PIN_SLEEP("GPIO23_AA4", slpm_out_lo_wkup_pdis, "sdi0"),
+ DB8500_PIN_SLEEP("GPIO24_AB2", slpm_in_wkup_pdis, "sdi0"),
+ DB8500_PIN_SLEEP("GPIO25_Y4", slpm_in_wkup_pdis, "sdi0"),
+ DB8500_PIN_SLEEP("GPIO26_Y2", slpm_in_wkup_pdis, "sdi0"),
+ DB8500_PIN_SLEEP("GPIO27_AA2", slpm_in_wkup_pdis, "sdi0"),
+ DB8500_PIN_SLEEP("GPIO28_AA1", slpm_in_wkup_pdis, "sdi0"),
+
/* Mux in SDI1 (here called MC1) used for SDIO for CW1200 WLAN */
DB8500_MUX("mc1_a_1", "mc1", "sdi1"),
DB8500_PIN("GPIO208_AH16", out_lo, "sdi1"), /* CLK */
@@ -203,6 +247,15 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = {
DB8500_PIN("GPIO212_AF13", in_pu, "sdi1"), /* DAT1 */
DB8500_PIN("GPIO213_AG13", in_pu, "sdi1"), /* DAT2 */
DB8500_PIN("GPIO214_AH15", in_pu, "sdi1"), /* DAT3 */
+ /* SDI1 sleep state */
+ DB8500_PIN_SLEEP("GPIO208_AH16", slpm_out_lo_wkup_pdis, "sdi1"), /* CLK */
+ DB8500_PIN_SLEEP("GPIO209_AG15", slpm_in_wkup_pdis, "sdi1"), /* FBCLK */
+ DB8500_PIN_SLEEP("GPIO210_AJ15", slpm_in_wkup_pdis, "sdi1"), /* CMD */
+ DB8500_PIN_SLEEP("GPIO211_AG14", slpm_in_wkup_pdis, "sdi1"), /* DAT0 */
+ DB8500_PIN_SLEEP("GPIO212_AF13", slpm_in_wkup_pdis, "sdi1"), /* DAT1 */
+ DB8500_PIN_SLEEP("GPIO213_AG13", slpm_in_wkup_pdis, "sdi1"), /* DAT2 */
+ DB8500_PIN_SLEEP("GPIO214_AH15", slpm_in_wkup_pdis, "sdi1"), /* DAT3 */
+
/* Mux in SDI2 (here called MC2) used for for PoP eMMC */
DB8500_MUX("mc2_a_1", "mc2", "sdi2"),
DB8500_PIN("GPIO128_A5", out_lo, "sdi2"), /* CLK */
@@ -216,6 +269,19 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = {
DB8500_PIN("GPIO136_C7", in_pu, "sdi2"), /* DAT5 */
DB8500_PIN("GPIO137_A7", in_pu, "sdi2"), /* DAT6 */
DB8500_PIN("GPIO138_C5", in_pu, "sdi2"), /* DAT7 */
+ /* SDI2 sleep state */
+ DB8500_PIN_SLEEP("GPIO128_A5", out_lo_wkup_pdis, "sdi2"), /* CLK */
+ DB8500_PIN_SLEEP("GPIO129_B4", in_wkup_pdis_en, "sdi2"), /* CMD */
+ DB8500_PIN_SLEEP("GPIO130_C8", in_wkup_pdis_en, "sdi2"), /* FBCLK */
+ DB8500_PIN_SLEEP("GPIO131_A12", in_wkup_pdis, "sdi2"), /* DAT0 */
+ DB8500_PIN_SLEEP("GPIO132_C10", in_wkup_pdis, "sdi2"), /* DAT1 */
+ DB8500_PIN_SLEEP("GPIO133_B10", in_wkup_pdis, "sdi2"), /* DAT2 */
+ DB8500_PIN_SLEEP("GPIO134_B9", in_wkup_pdis, "sdi2"), /* DAT3 */
+ DB8500_PIN_SLEEP("GPIO135_A9", in_wkup_pdis, "sdi2"), /* DAT4 */
+ DB8500_PIN_SLEEP("GPIO136_C7", in_wkup_pdis, "sdi2"), /* DAT5 */
+ DB8500_PIN_SLEEP("GPIO137_A7", in_wkup_pdis, "sdi2"), /* DAT6 */
+ DB8500_PIN_SLEEP("GPIO138_C5", in_wkup_pdis, "sdi2"), /* DAT7 */
+
/* Mux in SDI4 (here called MC4) used for for PCB-mounted eMMC */
DB8500_MUX("mc4_a_1", "mc4", "sdi4"),
DB8500_PIN("GPIO197_AH24", in_pu, "sdi4"), /* DAT3 */
@@ -229,6 +295,19 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = {
DB8500_PIN("GPIO205_AG23", in_pu, "sdi4"), /* DAT6 */
DB8500_PIN("GPIO206_AG24", in_pu, "sdi4"), /* DAT5 */
DB8500_PIN("GPIO207_AJ23", in_pu, "sdi4"), /* DAT4 */
+ /*SDI4 sleep state */
+ DB8500_PIN_SLEEP("GPIO197_AH24", slpm_in_wkup_pdis, "sdi4"), /* DAT3 */
+ DB8500_PIN_SLEEP("GPIO198_AG25", slpm_in_wkup_pdis, "sdi4"), /* DAT2 */
+ DB8500_PIN_SLEEP("GPIO199_AH23", slpm_in_wkup_pdis, "sdi4"), /* DAT1 */
+ DB8500_PIN_SLEEP("GPIO200_AH26", slpm_in_wkup_pdis, "sdi4"), /* DAT0 */
+ DB8500_PIN_SLEEP("GPIO201_AF24", slpm_in_wkup_pdis, "sdi4"), /* CMD */
+ DB8500_PIN_SLEEP("GPIO202_AF25", slpm_in_wkup_pdis, "sdi4"), /* FBCLK */
+ DB8500_PIN_SLEEP("GPIO203_AE23", slpm_out_lo_wkup_pdis, "sdi4"), /* CLK */
+ DB8500_PIN_SLEEP("GPIO204_AF23", slpm_in_wkup_pdis, "sdi4"), /* DAT7 */
+ DB8500_PIN_SLEEP("GPIO205_AG23", slpm_in_wkup_pdis, "sdi4"), /* DAT6 */
+ DB8500_PIN_SLEEP("GPIO206_AG24", slpm_in_wkup_pdis, "sdi4"), /* DAT5 */
+ DB8500_PIN_SLEEP("GPIO207_AJ23", slpm_in_wkup_pdis, "sdi4"), /* DAT4 */
+
/* Mux in USB pins, drive STP high */
DB8500_MUX("usb_a_1", "usb", "musb-ux500.0"),
DB8500_PIN("GPIO257_AE29", out_hi, "musb-ux500.0"), /* STP */
@@ -238,10 +317,232 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = {
DB8500_PIN("GPIO218_AH11", in_pd, "spi2"), /* RXD */
DB8500_PIN("GPIO215_AH13", out_lo, "spi2"), /* TXD */
DB8500_PIN("GPIO217_AH12", out_lo, "spi2"), /* CLK */
+ /* SPI2 idle state */
+ DB8500_PIN_SLEEP("GPIO218_AH11", slpm_in_wkup_pdis, "spi2"), /* RXD */
+ DB8500_PIN_SLEEP("GPIO215_AH13", slpm_out_lo_wkup_pdis, "spi2"), /* TXD */
+ DB8500_PIN_SLEEP("GPIO217_AH12", slpm_wkup_pdis, "spi2"), /* CLK */
/* SPI2 sleep state */
+ DB8500_PIN_SLEEP("GPIO216_AG12", slpm_in_wkup_pdis, "spi2"), /* FRM */
DB8500_PIN_SLEEP("GPIO218_AH11", slpm_in_wkup_pdis, "spi2"), /* RXD */
DB8500_PIN_SLEEP("GPIO215_AH13", slpm_out_lo_wkup_pdis, "spi2"), /* TXD */
DB8500_PIN_SLEEP("GPIO217_AH12", slpm_wkup_pdis, "spi2"), /* CLK */
+
+ /* ske default state */
+ DB8500_MUX("kp_a_2", "kp", "nmk-ske-keypad"),
+ DB8500_PIN("GPIO153_B17", in_pd, "nmk-ske-keypad"), /* I7 */
+ DB8500_PIN("GPIO154_C16", in_pd, "nmk-ske-keypad"), /* I6 */
+ DB8500_PIN("GPIO155_C19", in_pd, "nmk-ske-keypad"), /* I5 */
+ DB8500_PIN("GPIO156_C17", in_pd, "nmk-ske-keypad"), /* I4 */
+ DB8500_PIN("GPIO161_D21", in_pd, "nmk-ske-keypad"), /* I3 */
+ DB8500_PIN("GPIO162_D20", in_pd, "nmk-ske-keypad"), /* I2 */
+ DB8500_PIN("GPIO163_C20", in_pd, "nmk-ske-keypad"), /* I1 */
+ DB8500_PIN("GPIO164_B21", in_pd, "nmk-ske-keypad"), /* I0 */
+ DB8500_PIN("GPIO157_A18", out_lo, "nmk-ske-keypad"), /* O7 */
+ DB8500_PIN("GPIO158_C18", out_lo, "nmk-ske-keypad"), /* O6 */
+ DB8500_PIN("GPIO159_B19", out_lo, "nmk-ske-keypad"), /* O5 */
+ DB8500_PIN("GPIO160_B20", out_lo, "nmk-ske-keypad"), /* O4 */
+ DB8500_PIN("GPIO165_C21", out_lo, "nmk-ske-keypad"), /* O3 */
+ DB8500_PIN("GPIO166_A22", out_lo, "nmk-ske-keypad"), /* O2 */
+ DB8500_PIN("GPIO167_B24", out_lo, "nmk-ske-keypad"), /* O1 */
+ DB8500_PIN("GPIO168_C22", out_lo, "nmk-ske-keypad"), /* O0 */
+ /* ske sleep state */
+ DB8500_PIN_SLEEP("GPIO153_B17", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I7 */
+ DB8500_PIN_SLEEP("GPIO154_C16", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I6 */
+ DB8500_PIN_SLEEP("GPIO155_C19", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I5 */
+ DB8500_PIN_SLEEP("GPIO156_C17", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I4 */
+ DB8500_PIN_SLEEP("GPIO161_D21", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I3 */
+ DB8500_PIN_SLEEP("GPIO162_D20", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I2 */
+ DB8500_PIN_SLEEP("GPIO163_C20", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I1 */
+ DB8500_PIN_SLEEP("GPIO164_B21", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I0 */
+ DB8500_PIN_SLEEP("GPIO157_A18", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O7 */
+ DB8500_PIN_SLEEP("GPIO158_C18", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O6 */
+ DB8500_PIN_SLEEP("GPIO159_B19", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O5 */
+ DB8500_PIN_SLEEP("GPIO160_B20", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O4 */
+ DB8500_PIN_SLEEP("GPIO165_C21", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O3 */
+ DB8500_PIN_SLEEP("GPIO166_A22", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O2 */
+ DB8500_PIN_SLEEP("GPIO167_B24", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O1 */
+ DB8500_PIN_SLEEP("GPIO168_C22", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O0 */
+
+ /* STM APE pins states */
+ DB8500_MUX_STATE("stmape_c_1", "stmape",
+ "stm", "ape_mipi34"),
+ DB8500_PIN_STATE("GPIO70_G5", in_nopull,
+ "stm", "ape_mipi34"), /* clk */
+ DB8500_PIN_STATE("GPIO71_G4", in_nopull,
+ "stm", "ape_mipi34"), /* dat3 */
+ DB8500_PIN_STATE("GPIO72_H4", in_nopull,
+ "stm", "ape_mipi34"), /* dat2 */
+ DB8500_PIN_STATE("GPIO73_H3", in_nopull,
+ "stm", "ape_mipi34"), /* dat1 */
+ DB8500_PIN_STATE("GPIO74_J3", in_nopull,
+ "stm", "ape_mipi34"), /* dat0 */
+
+ DB8500_PIN_STATE("GPIO70_G5", slpm_out_lo_pdis,
+ "stm", "ape_mipi34_sleep"), /* clk */
+ DB8500_PIN_STATE("GPIO71_G4", slpm_out_lo_pdis,
+ "stm", "ape_mipi34_sleep"), /* dat3 */
+ DB8500_PIN_STATE("GPIO72_H4", slpm_out_lo_pdis,
+ "stm", "ape_mipi34_sleep"), /* dat2 */
+ DB8500_PIN_STATE("GPIO73_H3", slpm_out_lo_pdis,
+ "stm", "ape_mipi34_sleep"), /* dat1 */
+ DB8500_PIN_STATE("GPIO74_J3", slpm_out_lo_pdis,
+ "stm", "ape_mipi34_sleep"), /* dat0 */
+
+ DB8500_MUX_STATE("stmape_oc1_1", "stmape",
+ "stm", "ape_microsd"),
+ DB8500_PIN_STATE("GPIO23_AA4", in_nopull,
+ "stm", "ape_microsd"), /* clk */
+ DB8500_PIN_STATE("GPIO25_Y4", in_nopull,
+ "stm", "ape_microsd"), /* dat0 */
+ DB8500_PIN_STATE("GPIO26_Y2", in_nopull,
+ "stm", "ape_microsd"), /* dat1 */
+ DB8500_PIN_STATE("GPIO27_AA2", in_nopull,
+ "stm", "ape_microsd"), /* dat2 */
+ DB8500_PIN_STATE("GPIO28_AA1", in_nopull,
+ "stm", "ape_microsd"), /* dat3 */
+
+ DB8500_PIN_STATE("GPIO23_AA4", slpm_out_lo_wkup_pdis,
+ "stm", "ape_microsd_sleep"), /* clk */
+ DB8500_PIN_STATE("GPIO25_Y4", slpm_in_wkup_pdis,
+ "stm", "ape_microsd_sleep"), /* dat0 */
+ DB8500_PIN_STATE("GPIO26_Y2", slpm_in_wkup_pdis,
+ "stm", "ape_microsd_sleep"), /* dat1 */
+ DB8500_PIN_STATE("GPIO27_AA2", slpm_in_wkup_pdis,
+ "stm", "ape_microsd_sleep"), /* dat2 */
+ DB8500_PIN_STATE("GPIO28_AA1", slpm_in_wkup_pdis,
+ "stm", "ape_microsd_sleep"), /* dat3 */
+
+ /* STM Modem pins states */
+ DB8500_MUX_STATE("stmmod_oc3_2", "stmmod",
+ "stm", "mod_mipi34"),
+ DB8500_MUX_STATE("uartmodrx_oc3_1", "uartmod",
+ "stm", "mod_mipi34"),
+ DB8500_MUX_STATE("uartmodtx_oc3_1", "uartmod",
+ "stm", "mod_mipi34"),
+ DB8500_PIN_STATE("GPIO70_G5", in_nopull,
+ "stm", "mod_mipi34"), /* clk */
+ DB8500_PIN_STATE("GPIO71_G4", in_nopull,
+ "stm", "mod_mipi34"), /* dat3 */
+ DB8500_PIN_STATE("GPIO72_H4", in_nopull,
+ "stm", "mod_mipi34"), /* dat2 */
+ DB8500_PIN_STATE("GPIO73_H3", in_nopull,
+ "stm", "mod_mipi34"), /* dat1 */
+ DB8500_PIN_STATE("GPIO74_J3", in_nopull,
+ "stm", "mod_mipi34"), /* dat0 */
+ DB8500_PIN_STATE("GPIO75_H2", in_pu,
+ "stm", "mod_mipi34"), /* uartmod rx */
+ DB8500_PIN_STATE("GPIO76_J2", out_lo,
+ "stm", "mod_mipi34"), /* uartmod tx */
+
+ DB8500_PIN_STATE("GPIO70_G5", slpm_out_lo_pdis,
+ "stm", "mod_mipi34_sleep"), /* clk */
+ DB8500_PIN_STATE("GPIO71_G4", slpm_out_lo_pdis,
+ "stm", "mod_mipi34_sleep"), /* dat3 */
+ DB8500_PIN_STATE("GPIO72_H4", slpm_out_lo_pdis,
+ "stm", "mod_mipi34_sleep"), /* dat2 */
+ DB8500_PIN_STATE("GPIO73_H3", slpm_out_lo_pdis,
+ "stm", "mod_mipi34_sleep"), /* dat1 */
+ DB8500_PIN_STATE("GPIO74_J3", slpm_out_lo_pdis,
+ "stm", "mod_mipi34_sleep"), /* dat0 */
+ DB8500_PIN_STATE("GPIO75_H2", slpm_in_wkup_pdis,
+ "stm", "mod_mipi34_sleep"), /* uartmod rx */
+ DB8500_PIN_STATE("GPIO76_J2", slpm_out_lo_wkup_pdis,
+ "stm", "mod_mipi34_sleep"), /* uartmod tx */
+
+ DB8500_MUX_STATE("stmmod_b_1", "stmmod",
+ "stm", "mod_microsd"),
+ DB8500_MUX_STATE("uartmodrx_oc3_1", "uartmod",
+ "stm", "mod_microsd"),
+ DB8500_MUX_STATE("uartmodtx_oc3_1", "uartmod",
+ "stm", "mod_microsd"),
+ DB8500_PIN_STATE("GPIO23_AA4", in_nopull,
+ "stm", "mod_microsd"), /* clk */
+ DB8500_PIN_STATE("GPIO25_Y4", in_nopull,
+ "stm", "mod_microsd"), /* dat0 */
+ DB8500_PIN_STATE("GPIO26_Y2", in_nopull,
+ "stm", "mod_microsd"), /* dat1 */
+ DB8500_PIN_STATE("GPIO27_AA2", in_nopull,
+ "stm", "mod_microsd"), /* dat2 */
+ DB8500_PIN_STATE("GPIO28_AA1", in_nopull,
+ "stm", "mod_microsd"), /* dat3 */
+ DB8500_PIN_STATE("GPIO75_H2", in_pu,
+ "stm", "mod_microsd"), /* uartmod rx */
+ DB8500_PIN_STATE("GPIO76_J2", out_lo,
+ "stm", "mod_microsd"), /* uartmod tx */
+
+ DB8500_PIN_STATE("GPIO23_AA4", slpm_out_lo_wkup_pdis,
+ "stm", "mod_microsd_sleep"), /* clk */
+ DB8500_PIN_STATE("GPIO25_Y4", slpm_in_wkup_pdis,
+ "stm", "mod_microsd_sleep"), /* dat0 */
+ DB8500_PIN_STATE("GPIO26_Y2", slpm_in_wkup_pdis,
+ "stm", "mod_microsd_sleep"), /* dat1 */
+ DB8500_PIN_STATE("GPIO27_AA2", slpm_in_wkup_pdis,
+ "stm", "mod_microsd_sleep"), /* dat2 */
+ DB8500_PIN_STATE("GPIO28_AA1", slpm_in_wkup_pdis,
+ "stm", "mod_microsd_sleep"), /* dat3 */
+ DB8500_PIN_STATE("GPIO75_H2", slpm_in_wkup_pdis,
+ "stm", "mod_microsd_sleep"), /* uartmod rx */
+ DB8500_PIN_STATE("GPIO76_J2", slpm_out_lo_wkup_pdis,
+ "stm", "mod_microsd_sleep"), /* uartmod tx */
+
+ /* STM dual Modem/APE pins state */
+ DB8500_MUX_STATE("stmmod_oc3_2", "stmmod",
+ "stm", "mod_mipi34_ape_mipi60"),
+ DB8500_MUX_STATE("stmape_c_2", "stmape",
+ "stm", "mod_mipi34_ape_mipi60"),
+ DB8500_MUX_STATE("uartmodrx_oc3_1", "uartmod",
+ "stm", "mod_mipi34_ape_mipi60"),
+ DB8500_MUX_STATE("uartmodtx_oc3_1", "uartmod",
+ "stm", "mod_mipi34_ape_mipi60"),
+ DB8500_PIN_STATE("GPIO70_G5", in_nopull,
+ "stm", "mod_mipi34_ape_mipi60"), /* clk */
+ DB8500_PIN_STATE("GPIO71_G4", in_nopull,
+ "stm", "mod_mipi34_ape_mipi60"), /* dat3 */
+ DB8500_PIN_STATE("GPIO72_H4", in_nopull,
+ "stm", "mod_mipi34_ape_mipi60"), /* dat2 */
+ DB8500_PIN_STATE("GPIO73_H3", in_nopull,
+ "stm", "mod_mipi34_ape_mipi60"), /* dat1 */
+ DB8500_PIN_STATE("GPIO74_J3", in_nopull,
+ "stm", "mod_mipi34_ape_mipi60"), /* dat0 */
+ DB8500_PIN_STATE("GPIO75_H2", in_pu,
+ "stm", "mod_mipi34_ape_mipi60"), /* uartmod rx */
+ DB8500_PIN_STATE("GPIO76_J2", out_lo,
+ "stm", "mod_mipi34_ape_mipi60"), /* uartmod tx */
+ DB8500_PIN_STATE("GPIO155_C19", in_nopull,
+ "stm", "mod_mipi34_ape_mipi60"), /* clk */
+ DB8500_PIN_STATE("GPIO156_C17", in_nopull,
+ "stm", "mod_mipi34_ape_mipi60"), /* dat3 */
+ DB8500_PIN_STATE("GPIO157_A18", in_nopull,
+ "stm", "mod_mipi34_ape_mipi60"), /* dat2 */
+ DB8500_PIN_STATE("GPIO158_C18", in_nopull,
+ "stm", "mod_mipi34_ape_mipi60"), /* dat1 */
+ DB8500_PIN_STATE("GPIO159_B19", in_nopull,
+ "stm", "mod_mipi34_ape_mipi60"), /* dat0 */
+
+ DB8500_PIN_STATE("GPIO70_G5", slpm_out_lo_pdis,
+ "stm", "mod_mipi34_ape_mipi60_sleep"), /* clk */
+ DB8500_PIN_STATE("GPIO71_G4", slpm_out_lo_pdis,
+ "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat3 */
+ DB8500_PIN_STATE("GPIO72_H4", slpm_out_lo_pdis,
+ "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat2 */
+ DB8500_PIN_STATE("GPIO73_H3", slpm_out_lo_pdis,
+ "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat1 */
+ DB8500_PIN_STATE("GPIO74_J3", slpm_out_lo_pdis,
+ "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat0 */
+ DB8500_PIN_STATE("GPIO75_H2", slpm_in_wkup_pdis,
+ "stm", "mod_mipi34_ape_mipi60_sleep"), /* uartmod rx */
+ DB8500_PIN_STATE("GPIO76_J2", slpm_out_lo_wkup_pdis,
+ "stm", "mod_mipi34_ape_mipi60_sleep"), /* uartmod tx */
+ DB8500_PIN_STATE("GPIO155_C19", slpm_in_wkup_pdis,
+ "stm", "mod_mipi34_ape_mipi60_sleep"), /* clk */
+ DB8500_PIN_STATE("GPIO156_C17", slpm_in_wkup_pdis,
+ "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat3 */
+ DB8500_PIN_STATE("GPIO157_A18", slpm_in_wkup_pdis,
+ "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat2 */
+ DB8500_PIN_STATE("GPIO158_C18", slpm_in_wkup_pdis,
+ "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat1 */
+ DB8500_PIN_STATE("GPIO159_B19", slpm_in_wkup_pdis,
+ "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat0 */
};
/*
@@ -267,32 +568,48 @@ static struct pinctrl_map __initdata mop500_pinmap[] = {
DB8500_PIN_HOG("GPIO217_AH12", gpio_in_pu),
/* Mux in UART1 and set the pull-ups */
DB8500_MUX_HOG("u1rxtx_a_1", "u1"),
- DB8500_MUX_HOG("u1ctsrts_a_1", "u1"),
DB8500_PIN_HOG("GPIO4_AH6", in_pu), /* RXD */
DB8500_PIN_HOG("GPIO5_AG6", out_hi), /* TXD */
- DB8500_PIN_HOG("GPIO6_AF6", in_pu), /* CTS */
- DB8500_PIN_HOG("GPIO7_AG5", out_hi), /* RTS */
/*
* Runtime stuff: make it possible to mux in the SKE keypad
* and bias the pins
*/
- DB8500_MUX("kp_a_2", "kp", "ske"),
- DB8500_PIN("GPIO153_B17", in_pd_slpm_in_pu, "ske"), /* I7 */
- DB8500_PIN("GPIO154_C16", in_pd_slpm_in_pu, "ske"), /* I6 */
- DB8500_PIN("GPIO155_C19", in_pd_slpm_in_pu, "ske"), /* I5 */
- DB8500_PIN("GPIO156_C17", in_pd_slpm_in_pu, "ske"), /* I4 */
- DB8500_PIN("GPIO161_D21", in_pd_slpm_in_pu, "ske"), /* I3 */
- DB8500_PIN("GPIO162_D20", in_pd_slpm_in_pu, "ske"), /* I2 */
- DB8500_PIN("GPIO163_C20", in_pd_slpm_in_pu, "ske"), /* I1 */
- DB8500_PIN("GPIO164_B21", in_pd_slpm_in_pu, "ske"), /* I0 */
- DB8500_PIN("GPIO157_A18", in_pu_slpm_out_lo, "ske"), /* O7 */
- DB8500_PIN("GPIO158_C18", in_pu_slpm_out_lo, "ske"), /* O6 */
- DB8500_PIN("GPIO159_B19", in_pu_slpm_out_lo, "ske"), /* O5 */
- DB8500_PIN("GPIO160_B20", in_pu_slpm_out_lo, "ske"), /* O4 */
- DB8500_PIN("GPIO165_C21", in_pu_slpm_out_lo, "ske"), /* O3 */
- DB8500_PIN("GPIO166_A22", in_pu_slpm_out_lo, "ske"), /* O2 */
- DB8500_PIN("GPIO167_B24", in_pu_slpm_out_lo, "ske"), /* O1 */
- DB8500_PIN("GPIO168_C22", in_pu_slpm_out_lo, "ske"), /* O0 */
+ /* ske default state */
+ DB8500_MUX("kp_a_2", "kp", "nmk-ske-keypad"),
+ DB8500_PIN("GPIO153_B17", in_pu, "nmk-ske-keypad"), /* I7 */
+ DB8500_PIN("GPIO154_C16", in_pu, "nmk-ske-keypad"), /* I6 */
+ DB8500_PIN("GPIO155_C19", in_pu, "nmk-ske-keypad"), /* I5 */
+ DB8500_PIN("GPIO156_C17", in_pu, "nmk-ske-keypad"), /* I4 */
+ DB8500_PIN("GPIO161_D21", in_pu, "nmk-ske-keypad"), /* I3 */
+ DB8500_PIN("GPIO162_D20", in_pu, "nmk-ske-keypad"), /* I2 */
+ DB8500_PIN("GPIO163_C20", in_pu, "nmk-ske-keypad"), /* I1 */
+ DB8500_PIN("GPIO164_B21", in_pu, "nmk-ske-keypad"), /* I0 */
+ DB8500_PIN("GPIO157_A18", out_lo, "nmk-ske-keypad"), /* O7 */
+ DB8500_PIN("GPIO158_C18", out_lo, "nmk-ske-keypad"), /* O6 */
+ DB8500_PIN("GPIO159_B19", out_lo, "nmk-ske-keypad"), /* O5 */
+ DB8500_PIN("GPIO160_B20", out_lo, "nmk-ske-keypad"), /* O4 */
+ DB8500_PIN("GPIO165_C21", out_lo, "nmk-ske-keypad"), /* O3 */
+ DB8500_PIN("GPIO166_A22", out_lo, "nmk-ske-keypad"), /* O2 */
+ DB8500_PIN("GPIO167_B24", out_lo, "nmk-ske-keypad"), /* O1 */
+ DB8500_PIN("GPIO168_C22", out_lo, "nmk-ske-keypad"), /* O0 */
+ /* ske sleep state */
+ DB8500_PIN_SLEEP("GPIO153_B17", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I7 */
+ DB8500_PIN_SLEEP("GPIO154_C16", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I6 */
+ DB8500_PIN_SLEEP("GPIO155_C19", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I5 */
+ DB8500_PIN_SLEEP("GPIO156_C17", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I4 */
+ DB8500_PIN_SLEEP("GPIO161_D21", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I3 */
+ DB8500_PIN_SLEEP("GPIO162_D20", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I2 */
+ DB8500_PIN_SLEEP("GPIO163_C20", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I1 */
+ DB8500_PIN_SLEEP("GPIO164_B21", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I0 */
+ DB8500_PIN_SLEEP("GPIO157_A18", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O7 */
+ DB8500_PIN_SLEEP("GPIO158_C18", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O6 */
+ DB8500_PIN_SLEEP("GPIO159_B19", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O5 */
+ DB8500_PIN_SLEEP("GPIO160_B20", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O4 */
+ DB8500_PIN_SLEEP("GPIO165_C21", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O3 */
+ DB8500_PIN_SLEEP("GPIO166_A22", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O2 */
+ DB8500_PIN_SLEEP("GPIO167_B24", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O1 */
+ DB8500_PIN_SLEEP("GPIO168_C22", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O0 */
+
/* Mux in and drive the SDI0 DAT31DIR line high at runtime */
DB8500_MUX("mc0dat31dir_a_1", "mc0", "sdi0"),
DB8500_PIN("GPIO21_AB3", out_hi, "sdi0"),
@@ -395,28 +712,6 @@ static struct pinctrl_map __initdata hrefv60_pinmap[] = {
DB8500_PIN("GPIO217_AH12", gpio_in_pu_slpm_gpio_nopull, "gpio-keys.0"),
DB8500_PIN("GPIO145_C13", gpio_in_pd_slpm_gpio_nopull, "gpio-keys.0"),
DB8500_PIN("GPIO139_C9", gpio_in_pu_slpm_gpio_nopull, "gpio-keys.0"),
- /*
- * Make it possible to mux in the SKE keypad and bias the pins
- * FIXME: what's the point with this on HREFv60? KP/SKE is already
- * muxed in at another place! Enabling this will bork.
- */
- DB8500_MUX("kp_a_2", "kp", "ske"),
- DB8500_PIN("GPIO153_B17", in_pd_slpm_in_pu, "ske"), /* I7 */
- DB8500_PIN("GPIO154_C16", in_pd_slpm_in_pu, "ske"), /* I6 */
- DB8500_PIN("GPIO155_C19", in_pd_slpm_in_pu, "ske"), /* I5 */
- DB8500_PIN("GPIO156_C17", in_pd_slpm_in_pu, "ske"), /* I4 */
- DB8500_PIN("GPIO161_D21", in_pd_slpm_in_pu, "ske"), /* I3 */
- DB8500_PIN("GPIO162_D20", in_pd_slpm_in_pu, "ske"), /* I2 */
- DB8500_PIN("GPIO163_C20", in_pd_slpm_in_pu, "ske"), /* I1 */
- DB8500_PIN("GPIO164_B21", in_pd_slpm_in_pu, "ske"), /* I0 */
- DB8500_PIN("GPIO157_A18", in_pu_slpm_out_lo, "ske"), /* O7 */
- DB8500_PIN("GPIO158_C18", in_pu_slpm_out_lo, "ske"), /* O6 */
- DB8500_PIN("GPIO159_B19", in_pu_slpm_out_lo, "ske"), /* O5 */
- DB8500_PIN("GPIO160_B20", in_pu_slpm_out_lo, "ske"), /* O4 */
- DB8500_PIN("GPIO165_C21", in_pu_slpm_out_lo, "ske"), /* O3 */
- DB8500_PIN("GPIO166_A22", in_pu_slpm_out_lo, "ske"), /* O2 */
- DB8500_PIN("GPIO167_B24", in_pu_slpm_out_lo, "ske"), /* O1 */
- DB8500_PIN("GPIO168_C22", in_pu_slpm_out_lo, "ske"), /* O0 */
};
static struct pinctrl_map __initdata u9500_pinmap[] = {
diff --git a/arch/arm/mach-vexpress/reset.c b/arch/arm/mach-vexpress/reset.c
new file mode 100644
index 000000000000..465923aa3819
--- /dev/null
+++ b/arch/arm/mach-vexpress/reset.c
@@ -0,0 +1,141 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+#include <linux/jiffies.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/stat.h>
+#include <linux/vexpress.h>
+
+static void vexpress_reset_do(struct device *dev, const char *what)
+{
+ int err = -ENOENT;
+ struct vexpress_config_func *func =
+ vexpress_config_func_get_by_dev(dev);
+
+ if (func) {
+ unsigned long timeout;
+
+ err = vexpress_config_write(func, 0, 0);
+
+ timeout = jiffies + HZ;
+ while (time_before(jiffies, timeout))
+ cpu_relax();
+ }
+
+ dev_emerg(dev, "Unable to %s (%d)\n", what, err);
+}
+
+static struct device *vexpress_power_off_device;
+
+void vexpress_power_off(void)
+{
+ vexpress_reset_do(vexpress_power_off_device, "power off");
+}
+
+static struct device *vexpress_restart_device;
+
+void vexpress_restart(char str, const char *cmd)
+{
+ vexpress_reset_do(vexpress_restart_device, "restart");
+}
+
+static ssize_t vexpress_reset_active_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", vexpress_restart_device == dev);
+}
+
+static ssize_t vexpress_reset_active_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ long value;
+ int err = kstrtol(buf, 0, &value);
+
+ if (!err && value)
+ vexpress_restart_device = dev;
+
+ return err ? err : count;
+}
+
+DEVICE_ATTR(active, S_IRUGO | S_IWUSR, vexpress_reset_active_show,
+ vexpress_reset_active_store);
+
+
+enum vexpress_reset_func { FUNC_RESET, FUNC_SHUTDOWN, FUNC_REBOOT };
+
+static struct of_device_id vexpress_reset_of_match[] = {
+ {
+ .compatible = "arm,vexpress-reset",
+ .data = (void *)FUNC_RESET,
+ }, {
+ .compatible = "arm,vexpress-shutdown",
+ .data = (void *)FUNC_SHUTDOWN
+ }, {
+ .compatible = "arm,vexpress-reboot",
+ .data = (void *)FUNC_REBOOT
+ },
+ {}
+};
+
+static int vexpress_reset_probe(struct platform_device *pdev)
+{
+ enum vexpress_reset_func func;
+ const struct of_device_id *match =
+ of_match_device(vexpress_reset_of_match, &pdev->dev);
+
+ if (match)
+ func = (enum vexpress_reset_func)match->data;
+ else
+ func = pdev->id_entry->driver_data;
+
+ switch (func) {
+ case FUNC_SHUTDOWN:
+ vexpress_power_off_device = &pdev->dev;
+ break;
+ case FUNC_RESET:
+ if (!vexpress_restart_device)
+ vexpress_restart_device = &pdev->dev;
+ device_create_file(&pdev->dev, &dev_attr_active);
+ break;
+ case FUNC_REBOOT:
+ vexpress_restart_device = &pdev->dev;
+ device_create_file(&pdev->dev, &dev_attr_active);
+ break;
+ };
+
+ return 0;
+}
+
+static const struct platform_device_id vexpress_reset_id_table[] = {
+ { .name = "vexpress-reset", .driver_data = FUNC_RESET, },
+ { .name = "vexpress-shutdown", .driver_data = FUNC_SHUTDOWN, },
+ { .name = "vexpress-reboot", .driver_data = FUNC_REBOOT, },
+ {}
+};
+
+static struct platform_driver vexpress_reset_driver = {
+ .probe = vexpress_reset_probe,
+ .driver = {
+ .name = "vexpress-reset",
+ .of_match_table = vexpress_reset_of_match,
+ },
+ .id_table = vexpress_reset_id_table,
+};
+
+static int __init vexpress_reset_init(void)
+{
+ return platform_driver_register(&vexpress_reset_driver);
+}
+device_initcall(vexpress_reset_init);
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index 1fe6917f6a2a..dfd8b7af8c7a 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -48,6 +48,7 @@ struct samsung_gpio_cfg;
* @config: special function and pull-resistor control information.
* @lock: Lock for exclusive access to this gpio bank.
* @pm_save: Save information for suspend/resume support.
+ * @bitmap_gpio_int: Bitmap for representing GPIO interrupt or not.
*
* This wrapper provides the necessary information for the Samsung
* specific gpios being registered with gpiolib.
@@ -71,6 +72,7 @@ struct samsung_gpio_chip {
#ifdef CONFIG_PM
u32 pm_save[4];
#endif
+ u32 bitmap_gpio_int;
};
static inline struct samsung_gpio_chip *to_samsung_gpio(struct gpio_chip *gpc)
diff --git a/arch/arm/plat-samsung/s5p-irq-gpioint.c b/arch/arm/plat-samsung/s5p-irq-gpioint.c
index 23557d30e44c..bae56131a50a 100644
--- a/arch/arm/plat-samsung/s5p-irq-gpioint.c
+++ b/arch/arm/plat-samsung/s5p-irq-gpioint.c
@@ -185,7 +185,7 @@ int __init s5p_register_gpio_interrupt(int pin)
/* check if the group has been already registered */
if (my_chip->irq_base)
- return my_chip->irq_base + offset;
+ goto success;
/* register gpio group */
ret = s5p_gpioint_add(my_chip);
@@ -193,9 +193,13 @@ int __init s5p_register_gpio_interrupt(int pin)
my_chip->chip.to_irq = samsung_gpiolib_to_irq;
printk(KERN_INFO "Registered interrupt support for gpio group %d.\n",
group);
- return my_chip->irq_base + offset;
+ goto success;
}
return ret;
+success:
+ my_chip->bitmap_gpio_int |= BIT(offset);
+
+ return my_chip->irq_base + offset;
}
int __init s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups)