diff options
author | Jon Hunter <jon-hunter@ti.com> | 2013-02-21 14:46:22 -0500 |
---|---|---|
committer | Jon Hunter <jon-hunter@ti.com> | 2013-04-01 15:53:41 -0400 |
commit | c3be5b457ae1bb6dc93ef25bfa03e595969acbfc (patch) | |
tree | 8c06dd50cfd5c181be4b7cfe561d7a52cdf03fa0 /arch/arm/mach-omap2 | |
parent | 9f8331562aa1fd72e80dd6037c958cb3faf4cc38 (diff) |
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: Jon Hunter <jon-hunter@ti.com>
Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r-- | arch/arm/mach-omap2/gpmc-onenand.c | 18 | ||||
-rw-r--r-- | arch/arm/mach-omap2/gpmc-smc91x.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/gpmc.c | 45 | ||||
-rw-r--r-- | arch/arm/mach-omap2/gpmc.h | 28 | ||||
-rw-r--r-- | arch/arm/mach-omap2/usb-tusb6010.c | 19 |
5 files changed, 72 insertions, 40 deletions
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c index db52c4b28f8b..e175ceb0dc05 100644 --- a/arch/arm/mach-omap2/gpmc-onenand.c +++ b/arch/arm/mach-omap2/gpmc-onenand.c | |||
@@ -47,6 +47,15 @@ static struct platform_device gpmc_onenand_device = { | |||
47 | .resource = &gpmc_onenand_resource, | 47 | .resource = &gpmc_onenand_resource, |
48 | }; | 48 | }; |
49 | 49 | ||
50 | static struct gpmc_settings onenand_async = { | ||
51 | .mux_add_data = GPMC_MUX_AD, | ||
52 | }; | ||
53 | |||
54 | static struct gpmc_settings onenand_sync = { | ||
55 | .burst_read = true, | ||
56 | .mux_add_data = GPMC_MUX_AD, | ||
57 | }; | ||
58 | |||
50 | static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) | 59 | static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) |
51 | { | 60 | { |
52 | struct gpmc_device_timings dev_t; | 61 | struct gpmc_device_timings dev_t; |
@@ -63,7 +72,6 @@ static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) | |||
63 | 72 | ||
64 | memset(&dev_t, 0, sizeof(dev_t)); | 73 | memset(&dev_t, 0, sizeof(dev_t)); |
65 | 74 | ||
66 | dev_t.mux = true; | ||
67 | dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000; | 75 | dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000; |
68 | dev_t.t_avdp_w = dev_t.t_avdp_r; | 76 | dev_t.t_avdp_w = dev_t.t_avdp_r; |
69 | dev_t.t_aavdh = t_aavdh * 1000; | 77 | dev_t.t_aavdh = t_aavdh * 1000; |
@@ -75,7 +83,7 @@ static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) | |||
75 | dev_t.t_wpl = t_wpl * 1000; | 83 | dev_t.t_wpl = t_wpl * 1000; |
76 | dev_t.t_wph = t_wph * 1000; | 84 | dev_t.t_wph = t_wph * 1000; |
77 | 85 | ||
78 | gpmc_calc_timings(t, &dev_t); | 86 | gpmc_calc_timings(t, &onenand_async, &dev_t); |
79 | } | 87 | } |
80 | 88 | ||
81 | static int gpmc_set_async_mode(int cs, struct gpmc_timings *t) | 89 | 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, | |||
235 | /* Set synchronous read timings */ | 243 | /* Set synchronous read timings */ |
236 | memset(&dev_t, 0, sizeof(dev_t)); | 244 | memset(&dev_t, 0, sizeof(dev_t)); |
237 | 245 | ||
238 | dev_t.mux = true; | ||
239 | dev_t.sync_read = true; | ||
240 | if (onenand_flags & ONENAND_FLAG_SYNCWRITE) { | 246 | if (onenand_flags & ONENAND_FLAG_SYNCWRITE) { |
241 | dev_t.sync_write = true; | 247 | onenand_sync.sync_write = true; |
242 | } else { | 248 | } else { |
243 | dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000; | 249 | dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000; |
244 | dev_t.t_wpl = t_wpl * 1000; | 250 | dev_t.t_wpl = t_wpl * 1000; |
@@ -261,7 +267,7 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t, | |||
261 | dev_t.cyc_aavdh_oe = 1; | 267 | dev_t.cyc_aavdh_oe = 1; |
262 | dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period; | 268 | dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period; |
263 | 269 | ||
264 | gpmc_calc_timings(t, &dev_t); | 270 | gpmc_calc_timings(t, &onenand_sync, &dev_t); |
265 | } | 271 | } |
266 | 272 | ||
267 | static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t) | 273 | static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t) |
diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c index 11d0b756f098..4b7833873311 100644 --- a/arch/arm/mach-omap2/gpmc-smc91x.c +++ b/arch/arm/mach-omap2/gpmc-smc91x.c | |||
@@ -104,7 +104,7 @@ static int smc91c96_gpmc_retime(void) | |||
104 | dev_t.t_cez_w = t4_w * 1000; | 104 | dev_t.t_cez_w = t4_w * 1000; |
105 | dev_t.t_wr_cycle = (t20 - t3) * 1000; | 105 | dev_t.t_wr_cycle = (t20 - t3) * 1000; |
106 | 106 | ||
107 | gpmc_calc_timings(&t, &dev_t); | 107 | gpmc_calc_timings(&t, NULL, &dev_t); |
108 | 108 | ||
109 | return gpmc_cs_set_timings(gpmc_cfg->cs, &t); | 109 | return gpmc_cs_set_timings(gpmc_cfg->cs, &t); |
110 | } | 110 | } |
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 8833c349f23c..20747fbc686a 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c | |||
@@ -817,9 +817,9 @@ static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk) | |||
817 | 817 | ||
818 | /* XXX: can the cycles be avoided ? */ | 818 | /* XXX: can the cycles be avoided ? */ |
819 | static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t, | 819 | static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t, |
820 | struct gpmc_device_timings *dev_t) | 820 | struct gpmc_device_timings *dev_t, |
821 | bool mux) | ||
821 | { | 822 | { |
822 | bool mux = dev_t->mux; | ||
823 | u32 temp; | 823 | u32 temp; |
824 | 824 | ||
825 | /* adv_rd_off */ | 825 | /* adv_rd_off */ |
@@ -872,9 +872,9 @@ static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t, | |||
872 | } | 872 | } |
873 | 873 | ||
874 | static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t, | 874 | static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t, |
875 | struct gpmc_device_timings *dev_t) | 875 | struct gpmc_device_timings *dev_t, |
876 | bool mux) | ||
876 | { | 877 | { |
877 | bool mux = dev_t->mux; | ||
878 | u32 temp; | 878 | u32 temp; |
879 | 879 | ||
880 | /* adv_wr_off */ | 880 | /* adv_wr_off */ |
@@ -934,9 +934,9 @@ static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t, | |||
934 | } | 934 | } |
935 | 935 | ||
936 | static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t, | 936 | static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t, |
937 | struct gpmc_device_timings *dev_t) | 937 | struct gpmc_device_timings *dev_t, |
938 | bool mux) | ||
938 | { | 939 | { |
939 | bool mux = dev_t->mux; | ||
940 | u32 temp; | 940 | u32 temp; |
941 | 941 | ||
942 | /* adv_rd_off */ | 942 | /* adv_rd_off */ |
@@ -974,9 +974,9 @@ static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t, | |||
974 | } | 974 | } |
975 | 975 | ||
976 | static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t, | 976 | static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t, |
977 | struct gpmc_device_timings *dev_t) | 977 | struct gpmc_device_timings *dev_t, |
978 | bool mux) | ||
978 | { | 979 | { |
979 | bool mux = dev_t->mux; | ||
980 | u32 temp; | 980 | u32 temp; |
981 | 981 | ||
982 | /* adv_wr_off */ | 982 | /* adv_wr_off */ |
@@ -1046,7 +1046,8 @@ static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t, | |||
1046 | } | 1046 | } |
1047 | 1047 | ||
1048 | static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t, | 1048 | static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t, |
1049 | struct gpmc_device_timings *dev_t) | 1049 | struct gpmc_device_timings *dev_t, |
1050 | bool sync) | ||
1050 | { | 1051 | { |
1051 | u32 temp; | 1052 | u32 temp; |
1052 | 1053 | ||
@@ -1060,7 +1061,7 @@ static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t, | |||
1060 | gpmc_t->cs_on + dev_t->t_ce_avd); | 1061 | gpmc_t->cs_on + dev_t->t_ce_avd); |
1061 | gpmc_t->adv_on = gpmc_round_ps_to_ticks(temp); | 1062 | gpmc_t->adv_on = gpmc_round_ps_to_ticks(temp); |
1062 | 1063 | ||
1063 | if (dev_t->sync_write || dev_t->sync_read) | 1064 | if (sync) |
1064 | gpmc_calc_sync_common_timings(gpmc_t, dev_t); | 1065 | gpmc_calc_sync_common_timings(gpmc_t, dev_t); |
1065 | 1066 | ||
1066 | return 0; | 1067 | return 0; |
@@ -1095,21 +1096,29 @@ static void gpmc_convert_ps_to_ns(struct gpmc_timings *t) | |||
1095 | } | 1096 | } |
1096 | 1097 | ||
1097 | int gpmc_calc_timings(struct gpmc_timings *gpmc_t, | 1098 | int gpmc_calc_timings(struct gpmc_timings *gpmc_t, |
1098 | struct gpmc_device_timings *dev_t) | 1099 | struct gpmc_settings *gpmc_s, |
1100 | struct gpmc_device_timings *dev_t) | ||
1099 | { | 1101 | { |
1102 | bool mux = false, sync = false; | ||
1103 | |||
1104 | if (gpmc_s) { | ||
1105 | mux = gpmc_s->mux_add_data ? true : false; | ||
1106 | sync = (gpmc_s->sync_read || gpmc_s->sync_write); | ||
1107 | } | ||
1108 | |||
1100 | memset(gpmc_t, 0, sizeof(*gpmc_t)); | 1109 | memset(gpmc_t, 0, sizeof(*gpmc_t)); |
1101 | 1110 | ||
1102 | gpmc_calc_common_timings(gpmc_t, dev_t); | 1111 | gpmc_calc_common_timings(gpmc_t, dev_t, sync); |
1103 | 1112 | ||
1104 | if (dev_t->sync_read) | 1113 | if (gpmc_s && gpmc_s->sync_read) |
1105 | gpmc_calc_sync_read_timings(gpmc_t, dev_t); | 1114 | gpmc_calc_sync_read_timings(gpmc_t, dev_t, mux); |
1106 | else | 1115 | else |
1107 | gpmc_calc_async_read_timings(gpmc_t, dev_t); | 1116 | gpmc_calc_async_read_timings(gpmc_t, dev_t, mux); |
1108 | 1117 | ||
1109 | if (dev_t->sync_write) | 1118 | if (gpmc_s && gpmc_s->sync_write) |
1110 | gpmc_calc_sync_write_timings(gpmc_t, dev_t); | 1119 | gpmc_calc_sync_write_timings(gpmc_t, dev_t, mux); |
1111 | else | 1120 | else |
1112 | gpmc_calc_async_write_timings(gpmc_t, dev_t); | 1121 | gpmc_calc_async_write_timings(gpmc_t, dev_t, mux); |
1113 | 1122 | ||
1114 | /* TODO: remove, see function definition */ | 1123 | /* TODO: remove, see function definition */ |
1115 | gpmc_convert_ps_to_ns(gpmc_t); | 1124 | gpmc_convert_ps_to_ns(gpmc_t); |
diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h index 697ff4225d5d..39e4e04acdc9 100644 --- a/arch/arm/mach-omap2/gpmc.h +++ b/arch/arm/mach-omap2/gpmc.h | |||
@@ -60,8 +60,8 @@ | |||
60 | #define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0) | 60 | #define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0) |
61 | #define GPMC_CONFIG1_MUXTYPE(val) ((val & 3) << 8) | 61 | #define GPMC_CONFIG1_MUXTYPE(val) ((val & 3) << 8) |
62 | #define GPMC_CONFIG1_MUXNONMUX GPMC_CONFIG1_MUXTYPE(0) | 62 | #define GPMC_CONFIG1_MUXNONMUX GPMC_CONFIG1_MUXTYPE(0) |
63 | #define GPMC_CONFIG1_MUXAAD GPMC_CONFIG1_MUXTYPE(1) | 63 | #define GPMC_CONFIG1_MUXAAD GPMC_CONFIG1_MUXTYPE(GPMC_MUX_AAD) |
64 | #define GPMC_CONFIG1_MUXADDDATA GPMC_CONFIG1_MUXTYPE(2) | 64 | #define GPMC_CONFIG1_MUXADDDATA GPMC_CONFIG1_MUXTYPE(GPMC_MUX_AD) |
65 | #define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4) | 65 | #define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4) |
66 | #define GPMC_CONFIG1_FCLK_DIV(val) (val & 3) | 66 | #define GPMC_CONFIG1_FCLK_DIV(val) (val & 3) |
67 | #define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1)) | 67 | #define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1)) |
@@ -76,6 +76,8 @@ | |||
76 | #define GPMC_IRQ_FIFOEVENTENABLE 0x01 | 76 | #define GPMC_IRQ_FIFOEVENTENABLE 0x01 |
77 | #define GPMC_IRQ_COUNT_EVENT 0x02 | 77 | #define GPMC_IRQ_COUNT_EVENT 0x02 |
78 | 78 | ||
79 | #define GPMC_MUX_AAD 1 /* Addr-Addr-Data multiplex */ | ||
80 | #define GPMC_MUX_AD 2 /* Addr-Data multiplex */ | ||
79 | 81 | ||
80 | /* bool type time settings */ | 82 | /* bool type time settings */ |
81 | struct gpmc_bool_timings { | 83 | struct gpmc_bool_timings { |
@@ -181,10 +183,6 @@ struct gpmc_device_timings { | |||
181 | u8 cyc_wpl; /* write deassertion time in cycles */ | 183 | u8 cyc_wpl; /* write deassertion time in cycles */ |
182 | u32 cyc_iaa; /* initial access time in cycles */ | 184 | u32 cyc_iaa; /* initial access time in cycles */ |
183 | 185 | ||
184 | bool mux; /* address & data muxed */ | ||
185 | bool sync_write;/* synchronous write */ | ||
186 | bool sync_read; /* synchronous read */ | ||
187 | |||
188 | /* extra delays */ | 186 | /* extra delays */ |
189 | bool ce_xdelay; | 187 | bool ce_xdelay; |
190 | bool avd_xdelay; | 188 | bool avd_xdelay; |
@@ -192,8 +190,24 @@ struct gpmc_device_timings { | |||
192 | bool we_xdelay; | 190 | bool we_xdelay; |
193 | }; | 191 | }; |
194 | 192 | ||
193 | struct gpmc_settings { | ||
194 | bool burst_wrap; /* enables wrap bursting */ | ||
195 | bool burst_read; /* enables read page/burst mode */ | ||
196 | bool burst_write; /* enables write page/burst mode */ | ||
197 | bool device_nand; /* device is NAND */ | ||
198 | bool sync_read; /* enables synchronous reads */ | ||
199 | bool sync_write; /* enables synchronous writes */ | ||
200 | bool wait_on_read; /* monitor wait on reads */ | ||
201 | bool wait_on_write; /* monitor wait on writes */ | ||
202 | u32 burst_len; /* page/burst length */ | ||
203 | u32 device_width; /* device bus width (8 or 16 bit) */ | ||
204 | u32 mux_add_data; /* multiplex address & data */ | ||
205 | u32 wait_pin; /* wait-pin to be used */ | ||
206 | }; | ||
207 | |||
195 | extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t, | 208 | extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t, |
196 | struct gpmc_device_timings *dev_t); | 209 | struct gpmc_settings *gpmc_s, |
210 | struct gpmc_device_timings *dev_t); | ||
197 | 211 | ||
198 | extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs); | 212 | extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs); |
199 | extern int gpmc_get_client_irq(unsigned irq_config); | 213 | 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 c5a3c6f9504e..faaf96dca0fa 100644 --- a/arch/arm/mach-omap2/usb-tusb6010.c +++ b/arch/arm/mach-omap2/usb-tusb6010.c | |||
@@ -26,6 +26,15 @@ | |||
26 | static u8 async_cs, sync_cs; | 26 | static u8 async_cs, sync_cs; |
27 | static unsigned refclk_psec; | 27 | static unsigned refclk_psec; |
28 | 28 | ||
29 | static struct gpmc_settings tusb_async = { | ||
30 | .mux_add_data = GPMC_MUX_AD, | ||
31 | }; | ||
32 | |||
33 | static struct gpmc_settings tusb_sync = { | ||
34 | .sync_read = true, | ||
35 | .sync_write = true, | ||
36 | .mux_add_data = GPMC_MUX_AD, | ||
37 | }; | ||
29 | 38 | ||
30 | /* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */ | 39 | /* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */ |
31 | 40 | ||
@@ -37,8 +46,6 @@ static int tusb_set_async_mode(unsigned sysclk_ps) | |||
37 | 46 | ||
38 | memset(&dev_t, 0, sizeof(dev_t)); | 47 | memset(&dev_t, 0, sizeof(dev_t)); |
39 | 48 | ||
40 | dev_t.mux = true; | ||
41 | |||
42 | dev_t.t_ceasu = 8 * 1000; | 49 | dev_t.t_ceasu = 8 * 1000; |
43 | dev_t.t_avdasu = t_acsnh_advnh - 7000; | 50 | dev_t.t_avdasu = t_acsnh_advnh - 7000; |
44 | dev_t.t_ce_avd = 1000; | 51 | dev_t.t_ce_avd = 1000; |
@@ -52,7 +59,7 @@ static int tusb_set_async_mode(unsigned sysclk_ps) | |||
52 | dev_t.t_wpl = 300; | 59 | dev_t.t_wpl = 300; |
53 | dev_t.cyc_aavdh_we = 1; | 60 | dev_t.cyc_aavdh_we = 1; |
54 | 61 | ||
55 | gpmc_calc_timings(&t, &dev_t); | 62 | gpmc_calc_timings(&t, &tusb_async, &dev_t); |
56 | 63 | ||
57 | return gpmc_cs_set_timings(async_cs, &t); | 64 | return gpmc_cs_set_timings(async_cs, &t); |
58 | } | 65 | } |
@@ -65,10 +72,6 @@ static int tusb_set_sync_mode(unsigned sysclk_ps) | |||
65 | 72 | ||
66 | memset(&dev_t, 0, sizeof(dev_t)); | 73 | memset(&dev_t, 0, sizeof(dev_t)); |
67 | 74 | ||
68 | dev_t.mux = true; | ||
69 | dev_t.sync_read = true; | ||
70 | dev_t.sync_write = true; | ||
71 | |||
72 | dev_t.clk = 11100; | 75 | dev_t.clk = 11100; |
73 | dev_t.t_bacc = 1000; | 76 | dev_t.t_bacc = 1000; |
74 | dev_t.t_ces = 1000; | 77 | dev_t.t_ces = 1000; |
@@ -84,7 +87,7 @@ static int tusb_set_sync_mode(unsigned sysclk_ps) | |||
84 | dev_t.cyc_wpl = 6; | 87 | dev_t.cyc_wpl = 6; |
85 | dev_t.t_ce_rdyz = 7000; | 88 | dev_t.t_ce_rdyz = 7000; |
86 | 89 | ||
87 | gpmc_calc_timings(&t, &dev_t); | 90 | gpmc_calc_timings(&t, &tusb_sync, &dev_t); |
88 | 91 | ||
89 | return gpmc_cs_set_timings(sync_cs, &t); | 92 | return gpmc_cs_set_timings(sync_cs, &t); |
90 | } | 93 | } |