ARM: OMAP2+: Add structure for storing GPMC settings
authorJon Hunter <jon-hunter@ti.com>
Thu, 21 Feb 2013 19:46:22 +0000 (13:46 -0600)
committerJon Hunter <jon-hunter@ti.com>
Mon, 1 Apr 2013 19:53:41 +0000 (14:53 -0500)
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: Jon Hunter <jon-hunter@ti.com>
Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
arch/arm/mach-omap2/gpmc-onenand.c
arch/arm/mach-omap2/gpmc-smc91x.c
arch/arm/mach-omap2/gpmc.c
arch/arm/mach-omap2/gpmc.h
arch/arm/mach-omap2/usb-tusb6010.c

index db52c4b28f8b0be124b2dce4501b0e24fff2b9b5..e175ceb0dc0541cd80de178e0a5c86ee21fd47a0 100644 (file)
@@ -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)
index 11d0b756f09897be435075302392131a35aa686b..4b78338733113e40b82fc3c0d19f948d2bca0516 100644 (file)
@@ -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);
 }
index 8833c349f23c22ba33c1bea2385c027a882dc3a9..20747fbc686af7cdd12a3ab448e2537191696729 100644 (file)
@@ -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_device_timings *dev_t)
+                     struct gpmc_settings *gpmc_s,
+                     struct gpmc_device_timings *dev_t)
 {
+       bool mux = false, sync = false;
+
+       if (gpmc_s) {
+               mux = gpmc_s->mux_add_data ? true : false;
+               sync = (gpmc_s->sync_read || gpmc_s->sync_write);
+       }
+
        memset(gpmc_t, 0, sizeof(*gpmc_t));
 
-       gpmc_calc_common_timings(gpmc_t, dev_t);
+       gpmc_calc_common_timings(gpmc_t, dev_t, sync);
 
-       if (dev_t->sync_read)
-               gpmc_calc_sync_read_timings(gpmc_t, dev_t);
+       if (gpmc_s && gpmc_s->sync_read)
+               gpmc_calc_sync_read_timings(gpmc_t, dev_t, mux);
        else
-               gpmc_calc_async_read_timings(gpmc_t, dev_t);
+               gpmc_calc_async_read_timings(gpmc_t, dev_t, mux);
 
-       if (dev_t->sync_write)
-               gpmc_calc_sync_write_timings(gpmc_t, dev_t);
+       if (gpmc_s && gpmc_s->sync_write)
+               gpmc_calc_sync_write_timings(gpmc_t, dev_t, mux);
        else
-               gpmc_calc_async_write_timings(gpmc_t, dev_t);
+               gpmc_calc_async_write_timings(gpmc_t, dev_t, mux);
 
        /* TODO: remove, see function definition */
        gpmc_convert_ps_to_ns(gpmc_t);
index 697ff4225d5db3281ccac5c3c3d811079a01d62b..39e4e04acdc92600c3ba119c7e131e7e945a009b 100644 (file)
@@ -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,8 +190,24 @@ struct gpmc_device_timings {
        bool we_xdelay;
 };
 
+struct gpmc_settings {
+       bool burst_wrap;        /* enables wrap bursting */
+       bool burst_read;        /* enables read page/burst mode */
+       bool burst_write;       /* enables write page/burst mode */
+       bool device_nand;       /* device is NAND */
+       bool sync_read;         /* enables synchronous reads */
+       bool sync_write;        /* enables synchronous writes */
+       bool wait_on_read;      /* monitor wait on reads */
+       bool wait_on_write;     /* monitor wait on writes */
+       u32 burst_len;          /* page/burst length */
+       u32 device_width;       /* device bus width (8 or 16 bit) */
+       u32 mux_add_data;       /* multiplex address & data */
+       u32 wait_pin;           /* wait-pin to be used */
+};
+
 extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
-                               struct gpmc_device_timings *dev_t);
+                            struct gpmc_settings *gpmc_s,
+                            struct gpmc_device_timings *dev_t);
 
 extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
 extern int gpmc_get_client_irq(unsigned irq_config);
index c5a3c6f9504e79c8085e12e0aac10904a5177ab3..faaf96dca0fa146b0f29efc7e4726a1aaa2140c8 100644 (file)
 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);
 }