1 /*
2 * Analog Devices unified Blackfin bus functions
3 *
4 * Copyright (C) 2008-2011 Analog Devices, Inc.
5 * Licensed under the GPL-2 or later.
6 *
7 * Written by Mike Frysinger <vapier@gentoo.org> heavily leveraging
8 * the work of Jie Zhang <jie.zhang@analog.com>.
9 */
10
11 #include "blackfin.h"
12
13 #define IS_ASYNC_ADDR(params, adr) \
14 ({ \
15 unsigned long __addr = (unsigned long) (adr); \
16 bfin_bus_params_t *__params = (void *) (params); \
17 __addr >= __params->async_base && \
18 __addr < __params->async_base + __params->async_size; \
19 })
20 #define ASYNC_BANK(params, adr) (((adr) & (((bfin_bus_params_t *)(params))->async_size - 1)) >> 20)
21
22 static int
bfin_bus_attach_sigs(urj_part_t * part,urj_part_signal_t ** pins,int pin_cnt,const char * spin,int off)23 bfin_bus_attach_sigs (urj_part_t *part, urj_part_signal_t **pins, int pin_cnt,
24 const char *spin, int off)
25 {
26 int i;
27 char buf[16];
28 int ret = 0;
29
30 for (i = 0; i < pin_cnt; ++i)
31 {
32 sprintf (buf, "%s%i", spin, i + off);
33 ret |= urj_bus_generic_attach_sig (part, &pins[i], buf);
34 }
35
36 return ret;
37 }
38
39 int
bfin_bus_new(urj_bus_t * bus,const urj_param_t * cmd_params[],const bfin_bus_default_t * defaults)40 bfin_bus_new (urj_bus_t *bus, const urj_param_t *cmd_params[],
41 const bfin_bus_default_t *defaults)
42 {
43 bfin_bus_params_t *params = bus->params;
44 urj_part_t *part = bus->part;
45 const urj_param_t **p[2] = {NULL, cmd_params};
46 int ret = 0;
47 size_t i, j;
48
49 if (defaults != NULL)
50 {
51 ret = urj_param_init (p);
52 if (ret != URJ_STATUS_OK)
53 return ret;
54
55 for (i = 0; defaults[i].bus_name != NULL; ++i)
56 {
57 if (strcmp (defaults[i].bus_name, bus->driver->name))
58 continue;
59
60 ret = urj_param_push (&urj_bus_param_list, p,
61 defaults[i].param);
62 if (ret != URJ_STATUS_OK)
63 {
64 urj_param_clear (p);
65 return ret;
66 }
67 }
68 }
69
70 for (j = 0; j < 2; j++)
71 {
72 if (!p[j])
73 continue;
74
75 for (i = 0; p[j][i]; ++i)
76 switch (p[j][i]->key)
77 {
78 case URJ_BUS_PARAM_KEY_HWAIT:
79 {
80 const char *hwait = p[j][i]->value.string;
81
82 params->hwait_level = (hwait[0] == '/');
83 if (params->hwait_level)
84 ++hwait;
85
86 ret |= urj_bus_generic_attach_sig (part, ¶ms->hwait, hwait);
87 break;
88 }
89 default:
90 urj_error_set (URJ_ERROR_SYNTAX, _("unknown bus parameter"));
91 return 1;
92 }
93 }
94
95 if (!params->async_base)
96 params->async_base = 0x20000000;
97
98 /* Most signals start at 0, but ADDR starts at 1 (because it's 16bit) */
99 ret |= bfin_bus_attach_sigs (part, params->ams, params->ams_cnt, "AMS_B", 0);
100 ret |= bfin_bus_attach_sigs (part, params->abe, params->abe_cnt, "ABE_B", 0);
101 ret |= bfin_bus_attach_sigs (part, params->data, params->data_cnt, "DATA", 0);
102 ret |= bfin_bus_attach_sigs (part, params->addr, params->addr_cnt, "ADDR", 1);
103
104 ret |= urj_bus_generic_attach_sig (part, ¶ms->aoe, "AOE_B");
105 ret |= urj_bus_generic_attach_sig (part, ¶ms->are, "ARE_B");
106 ret |= urj_bus_generic_attach_sig (part, ¶ms->awe, "AWE_B");
107
108 if (params->sdram)
109 {
110 ret |= urj_bus_generic_attach_sig (part, ¶ms->scas, "SCAS_B");
111 ret |= urj_bus_generic_attach_sig (part, ¶ms->sras, "SRAS_B");
112 ret |= urj_bus_generic_attach_sig (part, ¶ms->swe, "SWE_B");
113 if (!params->sms_cnt)
114 {
115 ret |= urj_bus_generic_attach_sig (part, ¶ms->sms[0], "SMS_B");
116 params->sms_cnt = 1;
117 }
118 else
119 ret |= bfin_bus_attach_sigs (part, params->sms, params->sms_cnt, "SMS_B", 0);
120 }
121
122 return ret;
123 }
124
125 int
bfin_bus_area(urj_bus_t * bus,uint32_t adr,urj_bus_area_t * area)126 bfin_bus_area (urj_bus_t *bus, uint32_t adr, urj_bus_area_t *area)
127 {
128 bfin_bus_params_t *params = bus->params;
129
130 if (adr < params->async_base)
131 {
132 /* we can only wiggle SDRAM pins directly, so cannot drive it */
133 urj_error_set (URJ_ERROR_OUT_OF_BOUNDS,
134 _("reading external memory not supported"));
135 return URJ_STATUS_FAIL;
136 }
137 else if (IS_ASYNC_ADDR(params, adr))
138 {
139 area->description = "asynchronous memory";
140 area->start = params->async_base;
141 area->length = params->async_size;
142 area->width = 16;
143 }
144 else
145 {
146 /* L1 needs core to access it */
147 urj_error_set (URJ_ERROR_OUT_OF_BOUNDS,
148 _("reading on-chip memory not supported"));
149 return URJ_STATUS_FAIL;
150 }
151
152 return URJ_STATUS_OK;
153 }
154
155 static void
bfin_select_flash_sdram(urj_bus_t * bus)156 bfin_select_flash_sdram (urj_bus_t *bus)
157 {
158 bfin_bus_params_t *params = bus->params;
159 urj_part_t *part = bus->part;
160 int i;
161
162 if (params->sdram)
163 {
164 urj_part_set_signal_high (part, params->sras);
165 urj_part_set_signal_high (part, params->scas);
166 urj_part_set_signal_high (part, params->swe);
167 for (i = 0; i < params->sms_cnt; ++i)
168 urj_part_set_signal_high (part, params->sms[0]);
169 }
170 }
171
172 void
bfin_select_flash(urj_bus_t * bus,uint32_t adr)173 bfin_select_flash (urj_bus_t *bus, uint32_t adr)
174 {
175 bfin_bus_params_t *params = bus->params;
176 urj_part_t *part = bus->part;
177 int i;
178
179 for (i = 0; i < params->ams_cnt; ++i)
180 urj_part_set_signal (part, params->ams[i], 1,
181 !(ASYNC_BANK(params, adr) == i));
182
183 for (i = 0; i < params->abe_cnt; ++i)
184 urj_part_set_signal_low (part, params->abe[i]);
185
186 if (params->hwait)
187 urj_part_set_signal (part, params->hwait, 1, params->hwait_level);
188
189 bfin_select_flash_sdram (bus);
190
191 if (params->select_flash)
192 params->select_flash (bus, adr);
193 }
194
195 void
bfin_unselect_flash(urj_bus_t * bus)196 bfin_unselect_flash (urj_bus_t *bus)
197 {
198 bfin_bus_params_t *params = bus->params;
199 urj_part_t *part = bus->part;
200 int i;
201
202 for (i = 0; i < params->ams_cnt; ++i)
203 urj_part_set_signal_high (part, params->ams[i]);
204
205 for (i = 0; i < params->abe_cnt; ++i)
206 urj_part_set_signal_high (part, params->abe[i]);
207
208 if (params->hwait)
209 urj_part_set_signal (part, params->hwait, 1, params->hwait_level);
210
211 bfin_select_flash_sdram (bus);
212
213 if (params->unselect_flash)
214 params->unselect_flash (bus);
215 }
216
217 void
bfin_setup_address(urj_bus_t * bus,uint32_t adr)218 bfin_setup_address (urj_bus_t *bus, uint32_t adr)
219 {
220 bfin_bus_params_t *params = bus->params;
221 urj_part_t *part = bus->part;
222 int i;
223
224 for (i = 0; i < params->addr_cnt; ++i)
225 urj_part_set_signal (part, params->addr[i], 1, (adr >> (i + 1)) & 1);
226 }
227
228 void
bfin_set_data_in(urj_bus_t * bus)229 bfin_set_data_in (urj_bus_t *bus)
230 {
231 bfin_bus_params_t *params = bus->params;
232 urj_part_t *part = bus->part;
233 int i;
234
235 for (i = 0; i < params->data_cnt; ++i)
236 urj_part_set_signal_input (part, params->data[i]);
237 }
238
239 void
bfin_setup_data(urj_bus_t * bus,uint32_t data)240 bfin_setup_data (urj_bus_t *bus, uint32_t data)
241 {
242 bfin_bus_params_t *params = bus->params;
243 urj_part_t *part = bus->part;
244 int i;
245
246 for (i = 0; i < params->data_cnt; ++i)
247 urj_part_set_signal (part, params->data[i], 1, (data >> i) & 1);
248
249 }
250
251 static int
bfin_part_maybe_set_signal(urj_part_t * part,urj_part_signal_t * signal,int out,int val)252 bfin_part_maybe_set_signal (urj_part_t *part, urj_part_signal_t *signal,
253 int out, int val)
254 {
255 if (signal)
256 return urj_part_set_signal (part, signal, out, val);
257 return URJ_STATUS_OK;
258 }
259
260 int
bfin_bus_read_start(urj_bus_t * bus,uint32_t adr)261 bfin_bus_read_start (urj_bus_t *bus, uint32_t adr)
262 {
263 bfin_bus_params_t *params = bus->params;
264 urj_part_t *part = bus->part;
265 urj_chain_t *chain = bus->chain;
266
267 bfin_select_flash (bus, adr);
268
269 bfin_part_maybe_set_signal (part, params->are, 1, 0);
270 bfin_part_maybe_set_signal (part, params->awe, 1, 1);
271 bfin_part_maybe_set_signal (part, params->aoe, 1, 0);
272
273 bfin_setup_address (bus, adr);
274 bfin_set_data_in (bus);
275
276 urj_tap_chain_shift_data_registers (chain, 0);
277
278 return URJ_STATUS_OK;
279 }
280
281 uint32_t
bfin_bus_read_end(urj_bus_t * bus)282 bfin_bus_read_end (urj_bus_t *bus)
283 {
284 bfin_bus_params_t *params = bus->params;
285 urj_part_t *part = bus->part;
286 urj_chain_t *chain = bus->chain;
287 int i;
288 uint32_t d = 0;
289
290 bfin_unselect_flash (bus);
291
292 bfin_part_maybe_set_signal (part, params->are, 1, 1);
293 bfin_part_maybe_set_signal (part, params->awe, 1, 1);
294 bfin_part_maybe_set_signal (part, params->aoe, 1, 1);
295
296 urj_tap_chain_shift_data_registers (chain, 1);
297
298 for (i = 0; i < params->data_cnt; ++i)
299 d |= (uint32_t) (urj_part_get_signal (part, params->data[i]) << i);
300
301 return d;
302 }
303
304 uint32_t
bfin_bus_read_next(urj_bus_t * bus,uint32_t adr)305 bfin_bus_read_next (urj_bus_t *bus, uint32_t adr)
306 {
307 bfin_bus_params_t *params = bus->params;
308 urj_part_t *part = bus->part;
309 urj_chain_t *chain = bus->chain;
310 int i;
311 uint32_t d = 0;
312
313 bfin_setup_address (bus, adr);
314 urj_tap_chain_shift_data_registers (chain, 1);
315
316 for (i = 0; i < params->data_cnt; ++i)
317 d |= (uint32_t) (urj_part_get_signal (part, params->data[i]) << i);
318
319 return d;
320 }
321
322 void
bfin_bus_write(urj_bus_t * bus,uint32_t adr,uint32_t data)323 bfin_bus_write (urj_bus_t *bus, uint32_t adr, uint32_t data)
324 {
325 bfin_bus_params_t *params = bus->params;
326 urj_part_t *part = bus->part;
327 urj_chain_t *chain = bus->chain;
328
329 bfin_select_flash (bus, adr);
330 urj_part_set_signal_high (part, params->aoe);
331 urj_part_set_signal_high (part, params->are);
332 urj_part_set_signal_high (part, params->awe);
333
334 bfin_setup_address (bus, adr);
335 bfin_setup_data (bus, data);
336
337 urj_tap_chain_shift_data_registers (chain, 0);
338
339 urj_part_set_signal_low (part, params->awe);
340 urj_part_set_signal_low (part, params->aoe);
341 urj_tap_chain_shift_data_registers (chain, 0);
342 urj_part_set_signal_high (part, params->awe);
343 urj_part_set_signal_high (part, params->aoe);
344 bfin_unselect_flash (bus);
345 urj_tap_chain_shift_data_registers (chain, 0);
346 }
347
348 void
bfin_bus_printinfo(urj_log_level_t ll,urj_bus_t * bus)349 bfin_bus_printinfo (urj_log_level_t ll, urj_bus_t *bus)
350 {
351 int i;
352
353 for (i = 0; i < bus->chain->parts->len; i++)
354 if (bus->part == bus->chain->parts->parts[i])
355 break;
356
357 urj_log (ll, _("%s (JTAG part No. %d)\n"), bus->driver->description, i);
358 }
359