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, &params->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, &params->aoe, "AOE_B");
105     ret |= urj_bus_generic_attach_sig (part, &params->are, "ARE_B");
106     ret |= urj_bus_generic_attach_sig (part, &params->awe, "AWE_B");
107 
108     if (params->sdram)
109     {
110         ret |= urj_bus_generic_attach_sig (part, &params->scas, "SCAS_B");
111         ret |= urj_bus_generic_attach_sig (part, &params->sras, "SRAS_B");
112         ret |= urj_bus_generic_attach_sig (part, &params->swe, "SWE_B");
113         if (!params->sms_cnt)
114         {
115             ret |= urj_bus_generic_attach_sig (part, &params->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