Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c3be5b45 authored by Jon Hunter's avatar Jon Hunter
Browse files

ARM: OMAP2+: Add structure for storing GPMC settings



The GPMC has various different configuration options such as bus-width,
synchronous or asychronous mode selection, burst mode options etc.
Currently, there is no central structure for storing all these options
when configuring the GPMC for a given device. Some of the options are
stored in the GPMC timing structure and some are directly programmed
into the GPMC configuration register. Add a new structure to store
these options and convert code to use this structure. Adding this
structure will allow us to create a common function for configuring
these options.

Signed-off-by: default avatarJon Hunter <jon-hunter@ti.com>
Tested-by: default avatarEzequiel Garcia <ezequiel.garcia@free-electrons.com>
parent 9f833156
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -47,6 +47,15 @@ static struct platform_device gpmc_onenand_device = {
	.resource	= &gpmc_onenand_resource,
};

static struct gpmc_settings onenand_async = {
	.mux_add_data	= GPMC_MUX_AD,
};

static struct gpmc_settings onenand_sync = {
	.burst_read	= true,
	.mux_add_data	= GPMC_MUX_AD,
};

static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
{
	struct gpmc_device_timings dev_t;
@@ -63,7 +72,6 @@ static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)

	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;
@@ -75,7 +83,7 @@ static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
	dev_t.t_wpl = t_wpl * 1000;
	dev_t.t_wph = t_wph * 1000;

	gpmc_calc_timings(t, &dev_t);
	gpmc_calc_timings(t, &onenand_async, &dev_t);
}

static int gpmc_set_async_mode(int cs, struct gpmc_timings *t)
@@ -235,10 +243,8 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t,
	/* 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_SYNCWRITE) {
		dev_t.sync_write = true;
		onenand_sync.sync_write = true;
	} else {
		dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
		dev_t.t_wpl = t_wpl * 1000;
@@ -261,7 +267,7 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t,
	dev_t.cyc_aavdh_oe = 1;
	dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;

	gpmc_calc_timings(t, &dev_t);
	gpmc_calc_timings(t, &onenand_sync, &dev_t);
}

static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t)
+1 −1
Original line number Diff line number Diff line
@@ -104,7 +104,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, NULL, &dev_t);

	return gpmc_cs_set_timings(gpmc_cfg->cs, &t);
}
+27 −18
Original line number Diff line number Diff line
@@ -817,9 +817,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 */
@@ -872,9 +872,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 */
@@ -934,9 +934,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 */
@@ -974,9 +974,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 */
@@ -1046,7 +1046,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;

@@ -1060,7 +1061,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;
@@ -1095,21 +1096,29 @@ static void gpmc_convert_ps_to_ns(struct gpmc_timings *t)
}

int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
		      struct gpmc_settings *gpmc_s,
		      struct gpmc_device_timings *dev_t)
{
	bool mux = false, sync = false;

	if (gpmc_s) {
		mux = gpmc_s->mux_add_data ? true : false;
		sync = (gpmc_s->sync_read || gpmc_s->sync_write);
	}

	memset(gpmc_t, 0, sizeof(*gpmc_t));

	gpmc_calc_common_timings(gpmc_t, dev_t);
	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);
+21 −7
Original line number Diff line number Diff line
@@ -60,8 +60,8 @@
#define GPMC_CONFIG1_DEVICETYPE_NOR     GPMC_CONFIG1_DEVICETYPE(0)
#define GPMC_CONFIG1_MUXTYPE(val)       ((val & 3) << 8)
#define GPMC_CONFIG1_MUXNONMUX          GPMC_CONFIG1_MUXTYPE(0)
#define GPMC_CONFIG1_MUXAAD             GPMC_CONFIG1_MUXTYPE(1)
#define GPMC_CONFIG1_MUXADDDATA         GPMC_CONFIG1_MUXTYPE(2)
#define GPMC_CONFIG1_MUXAAD             GPMC_CONFIG1_MUXTYPE(GPMC_MUX_AAD)
#define GPMC_CONFIG1_MUXADDDATA         GPMC_CONFIG1_MUXTYPE(GPMC_MUX_AD)
#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))
@@ -76,6 +76,8 @@
#define GPMC_IRQ_FIFOEVENTENABLE	0x01
#define GPMC_IRQ_COUNT_EVENT		0x02

#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 {
@@ -181,10 +183,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;
@@ -192,7 +190,23 @@ 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_settings *gpmc_s,
			     struct gpmc_device_timings *dev_t);

extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
+11 −8
Original line number Diff line number Diff line
@@ -26,6 +26,15 @@
static u8		async_cs, sync_cs;
static unsigned		refclk_psec;

static struct gpmc_settings tusb_async = {
	.mux_add_data	= GPMC_MUX_AD,
};

static struct gpmc_settings tusb_sync = {
	.sync_read	= true,
	.sync_write	= true,
	.mux_add_data	= GPMC_MUX_AD,
};

/* NOTE:  timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */

@@ -37,8 +46,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 +59,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 +72,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 +87,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);
}