diff options
| -rw-r--r-- | arch/arm/mach-omap2/gpmc-onenand.c | 30 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/gpmc.c | 48 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/gpmc.h | 19 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/usb-tusb6010.c | 3 | 
4 files changed, 75 insertions, 25 deletions
| diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c index d102183ed9a5..206008837294 100644 --- a/arch/arm/mach-omap2/gpmc-onenand.c +++ b/arch/arm/mach-omap2/gpmc-onenand.c @@ -181,10 +181,8 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,  	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;  	if (cfg->flags & ONENAND_SYNC_READ)  		onenand_flags = ONENAND_FLAG_SYNCREAD; @@ -254,27 +252,10 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,  	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); +		t.bool_timings.cs_extra_delay = true; +		t.bool_timings.adv_extra_delay = true; +		t.bool_timings.oe_extra_delay = true; +		t.bool_timings.we_extra_delay = true;  	}  	t.sync_clk = min_gpmc_clk_period; @@ -297,6 +278,8 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,  	t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +  		     ticks_cez); +	t.clk_activation = fclk_offset_ns; +  	/* Write */  	if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {  		t.adv_wr_off = t.adv_rd_off; @@ -338,7 +321,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.c b/arch/arm/mach-omap2/gpmc.c index bf6117c32f4b..5619d1b48668 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,39 @@ unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)  	return ticks * gpmc_get_fclk_period() / 1000;  } +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 +356,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 +381,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;  } diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h index 79f4dfc2adb3..e08a51a7a76a 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. @@ -106,9 +117,17 @@ struct gpmc_timings {  	u16 rd_cycle;		/* Total read cycle time */  	u16 wr_cycle;		/* Total write cycle time */ +	u16 bus_turnaround; +	u16 cycle2cycle_delay; + +	u16 wait_monitoring; +	u16 clk_activation; +  	/* The following are only on OMAP3430 */  	u16 wr_access;		/* WRACCESSTIME */  	u16 wr_data_mux_bus;	/* WRDATAONADMUXBUS */ + +	struct gpmc_bool_timings bool_timings;  };  extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs); diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c index a8795ff19e6d..5be96c6e1416 100644 --- a/arch/arm/mach-omap2/usb-tusb6010.c +++ b/arch/arm/mach-omap2/usb-tusb6010.c @@ -175,6 +175,8 @@ static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps)  	tmp = t.cs_wr_off * 1000 + 7000 /* t_scsn_rdy_z */;  	t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps); +	t.clk_activation = gpmc_ticks_to_ns(1); +  	return gpmc_cs_set_timings(sync_cs, &t);  } @@ -284,7 +286,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 | 
