diff options
Diffstat (limited to 'arch/arm/mach-omap2/gpmc-onenand.c')
| -rw-r--r-- | arch/arm/mach-omap2/gpmc-onenand.c | 122 | 
1 files changed, 61 insertions, 61 deletions
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c index fadd87435cd..64b5a834698 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,12 +272,20 @@ 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); -	if (IS_ERR_VALUE(ret)) +	ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t); +	if (ret < 0)  		return ret;  	omap2_onenand_set_async_mode(onenand_base); @@ -322,10 +304,26 @@ 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; +	} + +	omap2_onenand_calc_sync_timings(&t, gpmc_onenand_data->flags, freq); -	ret = gpmc_set_sync_mode(gpmc_onenand_data->cs, &t); -	if (IS_ERR_VALUE(ret)) +	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;  	set_onenand_cfg(onenand_base); @@ -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;  	}  |