aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2
diff options
context:
space:
mode:
authorAfzal Mohammed <afzal@ti.com>2012-08-17 02:46:14 -0400
committerAfzal Mohammed <afzal@ti.com>2012-11-09 07:37:23 -0500
commit47acde16726080e5157b602f23937d00a04cd2ed (patch)
tree956d19bef0f4fa5b070fd093b9ddfbca30090c32 /arch/arm/mach-omap2
parentac2d9ae1947288677ec78cd91a29490234ab9854 (diff)
ARM: OMAP2+: tusb6010: generic timing calculation
Generic gpmc timing calculation helper is available now, use it instead of custom timing calculation. Signed-off-by: Afzal Mohammed <afzal@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r--arch/arm/mach-omap2/usb-tusb6010.c182
1 files changed, 44 insertions, 138 deletions
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index 5be96c6e1416..c5a3c6f9504e 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -27,182 +27,88 @@ static u8 async_cs, sync_cs;
27static unsigned refclk_psec; 27static unsigned refclk_psec;
28 28
29 29
30/* t2_ps, when quantized to fclk units, must happen no earlier than
31 * the clock after after t1_NS.
32 *
33 * Return a possibly updated value of t2_ps, converted to nsec.
34 */
35static unsigned
36next_clk(unsigned t1_NS, unsigned t2_ps, unsigned fclk_ps)
37{
38 unsigned t1_ps = t1_NS * 1000;
39 unsigned t1_f, t2_f;
40
41 if ((t1_ps + fclk_ps) < t2_ps)
42 return t2_ps / 1000;
43
44 t1_f = (t1_ps + fclk_ps - 1) / fclk_ps;
45 t2_f = (t2_ps + fclk_ps - 1) / fclk_ps;
46
47 if (t1_f >= t2_f)
48 t2_f = t1_f + 1;
49
50 return (t2_f * fclk_ps) / 1000;
51}
52
53/* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */ 30/* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */
54 31
55static int tusb_set_async_mode(unsigned sysclk_ps, unsigned fclk_ps) 32static int tusb_set_async_mode(unsigned sysclk_ps)
56{ 33{
34 struct gpmc_device_timings dev_t;
57 struct gpmc_timings t; 35 struct gpmc_timings t;
58 unsigned t_acsnh_advnh = sysclk_ps + 3000; 36 unsigned t_acsnh_advnh = sysclk_ps + 3000;
59 unsigned tmp;
60
61 memset(&t, 0, sizeof(t));
62
63 /* CS_ON = t_acsnh_acsnl */
64 t.cs_on = 8;
65 /* ADV_ON = t_acsnh_advnh - t_advn */
66 t.adv_on = next_clk(t.cs_on, t_acsnh_advnh - 7000, fclk_ps);
67
68 /*
69 * READ ... from omap2420 TRM fig 12-13
70 */
71
72 /* ADV_RD_OFF = t_acsnh_advnh */
73 t.adv_rd_off = next_clk(t.adv_on, t_acsnh_advnh, fclk_ps);
74
75 /* OE_ON = t_acsnh_advnh + t_advn_oen (then wait for nRDY) */
76 t.oe_on = next_clk(t.adv_on, t_acsnh_advnh + 1000, fclk_ps);
77
78 /* ACCESS = counters continue only after nRDY */
79 tmp = t.oe_on * 1000 + 300;
80 t.access = next_clk(t.oe_on, tmp, fclk_ps);
81
82 /* OE_OFF = after data gets sampled */
83 tmp = t.access * 1000;
84 t.oe_off = next_clk(t.access, tmp, fclk_ps);
85
86 t.cs_rd_off = t.oe_off;
87
88 tmp = t.cs_rd_off * 1000 + 7000 /* t_acsn_rdy_z */;
89 t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps);
90
91 /*
92 * WRITE ... from omap2420 TRM fig 12-15
93 */
94 37
95 /* ADV_WR_OFF = t_acsnh_advnh */ 38 memset(&dev_t, 0, sizeof(dev_t));
96 t.adv_wr_off = t.adv_rd_off;
97 39
98 /* WE_ON = t_acsnh_advnh + t_advn_wen (then wait for nRDY) */ 40 dev_t.mux = true;
99 t.we_on = next_clk(t.adv_wr_off, t_acsnh_advnh + 1000, fclk_ps);
100 41
101 /* WE_OFF = after data gets sampled */ 42 dev_t.t_ceasu = 8 * 1000;
102 tmp = t.we_on * 1000 + 300; 43 dev_t.t_avdasu = t_acsnh_advnh - 7000;
103 t.we_off = next_clk(t.we_on, tmp, fclk_ps); 44 dev_t.t_ce_avd = 1000;
45 dev_t.t_avdp_r = t_acsnh_advnh;
46 dev_t.t_oeasu = t_acsnh_advnh + 1000;
47 dev_t.t_oe = 300;
48 dev_t.t_cez_r = 7000;
49 dev_t.t_cez_w = dev_t.t_cez_r;
50 dev_t.t_avdp_w = t_acsnh_advnh;
51 dev_t.t_weasu = t_acsnh_advnh + 1000;
52 dev_t.t_wpl = 300;
53 dev_t.cyc_aavdh_we = 1;
104 54
105 t.cs_wr_off = t.we_off; 55 gpmc_calc_timings(&t, &dev_t);
106
107 tmp = t.cs_wr_off * 1000 + 7000 /* t_acsn_rdy_z */;
108 t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
109 56
110 return gpmc_cs_set_timings(async_cs, &t); 57 return gpmc_cs_set_timings(async_cs, &t);
111} 58}
112 59
113static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps) 60static int tusb_set_sync_mode(unsigned sysclk_ps)
114{ 61{
62 struct gpmc_device_timings dev_t;
115 struct gpmc_timings t; 63 struct gpmc_timings t;
116 unsigned t_scsnh_advnh = sysclk_ps + 3000; 64 unsigned t_scsnh_advnh = sysclk_ps + 3000;
117 unsigned tmp;
118
119 memset(&t, 0, sizeof(t));
120 t.cs_on = 8;
121
122 /* ADV_ON = t_acsnh_advnh - t_advn */
123 t.adv_on = next_clk(t.cs_on, t_scsnh_advnh - 7000, fclk_ps);
124
125 /* GPMC_CLK rate = fclk rate / div */
126 t.sync_clk = 11100 /* 11.1 nsec */;
127 tmp = (t.sync_clk + fclk_ps - 1) / fclk_ps;
128 if (tmp > 4)
129 return -ERANGE;
130 if (tmp == 0)
131 tmp = 1;
132 t.page_burst_access = (fclk_ps * tmp) / 1000;
133
134 /*
135 * READ ... based on omap2420 TRM fig 12-19, 12-20
136 */
137
138 /* ADV_RD_OFF = t_scsnh_advnh */
139 t.adv_rd_off = next_clk(t.adv_on, t_scsnh_advnh, fclk_ps);
140
141 /* OE_ON = t_scsnh_advnh + t_advn_oen * fclk_ps (then wait for nRDY) */
142 tmp = (t.adv_rd_off * 1000) + (3 * fclk_ps);
143 t.oe_on = next_clk(t.adv_on, tmp, fclk_ps);
144
145 /* ACCESS = number of clock cycles after t_adv_eon */
146 tmp = (t.oe_on * 1000) + (5 * fclk_ps);
147 t.access = next_clk(t.oe_on, tmp, fclk_ps);
148
149 /* OE_OFF = after data gets sampled */
150 tmp = (t.access * 1000) + (1 * fclk_ps);
151 t.oe_off = next_clk(t.access, tmp, fclk_ps);
152 65
153 t.cs_rd_off = t.oe_off; 66 memset(&dev_t, 0, sizeof(dev_t));
154 67
155 tmp = t.cs_rd_off * 1000 + 7000 /* t_scsn_rdy_z */; 68 dev_t.mux = true;
156 t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps); 69 dev_t.sync_read = true;
157 70 dev_t.sync_write = true;
158 /* 71
159 * WRITE ... based on omap2420 TRM fig 12-21 72 dev_t.clk = 11100;
160 */ 73 dev_t.t_bacc = 1000;
161 74 dev_t.t_ces = 1000;
162 /* ADV_WR_OFF = t_scsnh_advnh */ 75 dev_t.t_ceasu = 8 * 1000;
163 t.adv_wr_off = t.adv_rd_off; 76 dev_t.t_avdasu = t_scsnh_advnh - 7000;
164 77 dev_t.t_ce_avd = 1000;
165 /* WE_ON = t_scsnh_advnh + t_advn_wen * fclk_ps (then wait for nRDY) */ 78 dev_t.t_avdp_r = t_scsnh_advnh;
166 tmp = (t.adv_wr_off * 1000) + (3 * fclk_ps); 79 dev_t.cyc_aavdh_oe = 3;
167 t.we_on = next_clk(t.adv_wr_off, tmp, fclk_ps); 80 dev_t.cyc_oe = 5;
168 81 dev_t.t_ce_rdyz = 7000;
169 /* WE_OFF = number of clock cycles after t_adv_wen */ 82 dev_t.t_avdp_w = t_scsnh_advnh;
170 tmp = (t.we_on * 1000) + (6 * fclk_ps); 83 dev_t.cyc_aavdh_we = 3;
171 t.we_off = next_clk(t.we_on, tmp, fclk_ps); 84 dev_t.cyc_wpl = 6;
172 85 dev_t.t_ce_rdyz = 7000;
173 t.cs_wr_off = t.we_off; 86
174 87 gpmc_calc_timings(&t, &dev_t);
175 tmp = t.cs_wr_off * 1000 + 7000 /* t_scsn_rdy_z */;
176 t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
177
178 t.clk_activation = gpmc_ticks_to_ns(1);
179 88
180 return gpmc_cs_set_timings(sync_cs, &t); 89 return gpmc_cs_set_timings(sync_cs, &t);
181} 90}
182 91
183extern unsigned long gpmc_get_fclk_period(void);
184
185/* tusb driver calls this when it changes the chip's clocking */ 92/* tusb driver calls this when it changes the chip's clocking */
186int tusb6010_platform_retime(unsigned is_refclk) 93int tusb6010_platform_retime(unsigned is_refclk)
187{ 94{
188 static const char error[] = 95 static const char error[] =
189 KERN_ERR "tusb6010 %s retime error %d\n"; 96 KERN_ERR "tusb6010 %s retime error %d\n";
190 97
191 unsigned fclk_ps = gpmc_get_fclk_period();
192 unsigned sysclk_ps; 98 unsigned sysclk_ps;
193 int status; 99 int status;
194 100
195 if (!refclk_psec || fclk_ps == 0) 101 if (!refclk_psec)
196 return -ENODEV; 102 return -ENODEV;
197 103
198 sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60; 104 sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60;
199 105
200 status = tusb_set_async_mode(sysclk_ps, fclk_ps); 106 status = tusb_set_async_mode(sysclk_ps);
201 if (status < 0) { 107 if (status < 0) {
202 printk(error, "async", status); 108 printk(error, "async", status);
203 goto done; 109 goto done;
204 } 110 }
205 status = tusb_set_sync_mode(sysclk_ps, fclk_ps); 111 status = tusb_set_sync_mode(sysclk_ps);
206 if (status < 0) 112 if (status < 0)
207 printk(error, "sync", status); 113 printk(error, "sync", status);
208done: 114done: