source: SVN/rincon/u-boot/cpu/leon3/ambapp.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 9.8 KB
Line 
1/* Gaisler AMBA Plug&Play bus scanning. Functions
2 * ending on _nomem is inteded to be used only during
3 * initialization, only registers are used (no ram).
4 *
5 * (C) Copyright 2007
6 * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
7 *
8 * See file CREDITS for list of people who contributed to this
9 * project.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24 * MA 02111-1307 USA
25 */
26
27#include <common.h>
28#include <command.h>
29#include <ambapp.h>
30
31#if defined(CONFIG_CMD_AMBAPP)
32extern void ambapp_print_apb(apbctrl_pp_dev * apb,
33                             ambapp_ahbdev * apbmst, int index);
34extern void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index);
35extern int ambapp_apb_print;
36extern int ambapp_ahb_print;
37#endif
38
39static int ambapp_apb_scan(unsigned int vendor, /* Plug&Play Vendor ID */
40                           unsigned int driver, /* Plug&Play Device ID */
41                           ambapp_apbdev * dev, /* Result(s) is placed here */
42                           int index,   /* Index of device to start copying Plug&Play
43                                         * info into dev
44                                         */
45                           int max_cnt  /* Maximal count that dev can hold, if dev
46                                         * is NULL function will stop scanning after
47                                         * max_cnt devices are found.
48                                         */
49    )
50{
51        int i, cnt = 0;
52        unsigned int apbmst_base;
53        ambapp_ahbdev apbmst;
54        apbctrl_pp_dev *apb;
55
56        if (max_cnt == 0)
57                return 0;
58
59        /* Get AMBA APB Master */
60        if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_APBMST, &apbmst) != 1) {
61                return 0;
62        }
63
64        /* Get APB CTRL Plug&Play info area */
65        apbmst_base = apbmst.address[0] & LEON3_IO_AREA;
66        apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA);
67
68        for (i = 0; i < LEON3_APB_SLAVES; i++) {
69#if defined(CONFIG_CMD_AMBAPP)
70                if (ambapp_apb_print && amba_vendor(apb->conf)
71                    && amba_device(apb->conf)) {
72                        ambapp_print_apb(apb, &apbmst, i);
73                }
74#endif
75                if ((amba_vendor(apb->conf) == vendor) &&
76                    (amba_device(apb->conf) == driver) && ((index < 0)
77                                                           || (index-- == 0))) {
78                        /* Convert Plug&Play info into a more readable format */
79                        cnt++;
80                        if (dev) {
81                                dev->irq = amba_irq(apb->conf);
82                                dev->ver = amba_ver(apb->conf);
83                                dev->address =
84                                    (apbmst_base |
85                                     (((apb->
86                                        bar & 0xfff00000) >> 12))) & (((apb->
87                                                                        bar &
88                                                                        0x0000fff0)
89                                                                       << 4) |
90                                                                      0xfff00000);
91                                dev++;
92                        }
93                        /* found max devices? */
94                        if (cnt >= max_cnt)
95                                return cnt;
96                }
97                /* Get next Plug&Play entry */
98                apb++;
99        }
100        return cnt;
101}
102
103unsigned int ambapp_apb_next_nomem(register unsigned int vendor,        /* Plug&Play Vendor ID */
104                                   register unsigned int driver,        /* Plug&Play Device ID */
105                                   register int index)
106{
107        register int i;
108        register ahbctrl_pp_dev *apbmst;
109        register apbctrl_pp_dev *apb;
110        register unsigned int apbmst_base;
111
112        /* APBMST is a AHB Slave */
113        apbmst = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0);
114        if (!apbmst)
115                return 0;
116
117        apbmst_base = amba_membar_start(apbmst->bars[0]);
118        if (amba_membar_type(apbmst->bars[0]) == AMBA_TYPE_AHBIO)
119                apbmst_base = AMBA_TYPE_AHBIO_ADDR(apbmst_base);
120        apbmst_base &= LEON3_IO_AREA;
121
122        /* Find the vendor/driver device on the first APB bus */
123        apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA);
124
125        for (i = 0; i < LEON3_APB_SLAVES; i++) {
126                if ((amba_vendor(apb->conf) == vendor) &&
127                    (amba_device(apb->conf) == driver) && ((index < 0)
128                                                           || (index-- == 0))) {
129                        /* Convert Plug&Play info info a more readable format */
130                        return (apbmst_base | (((apb->bar & 0xfff00000) >> 12)))
131                            & (((apb->bar & 0x0000fff0) << 4) | 0xfff00000);
132                }
133                /* Get next Plug&Play entry */
134                apb++;
135        }
136        return 0;
137}
138
139/****************************** APB SLAVES ******************************/
140
141int ambapp_apb_count(unsigned int vendor, unsigned int driver)
142{
143        return ambapp_apb_scan(vendor, driver, NULL, 0, LEON3_APB_SLAVES);
144}
145
146int ambapp_apb_first(unsigned int vendor,
147                     unsigned int driver, ambapp_apbdev * dev)
148{
149        return ambapp_apb_scan(vendor, driver, dev, 0, 1);
150}
151
152int ambapp_apb_next(unsigned int vendor,
153                    unsigned int driver, ambapp_apbdev * dev, int index)
154{
155        return ambapp_apb_scan(vendor, driver, dev, index, 1);
156}
157
158int ambapp_apbs_first(unsigned int vendor,
159                      unsigned int driver, ambapp_apbdev * dev, int max_cnt)
160{
161        return ambapp_apb_scan(vendor, driver, dev, 0, max_cnt);
162}
163
164enum {
165        AHB_SCAN_MASTER = 0,
166        AHB_SCAN_SLAVE = 1
167};
168
169/* Scan AMBA Plug&Play bus for AMBA AHB Masters or AHB Slaves
170 * for a certain matching Vendor and Device ID.
171 *
172 * Return number of devices found.
173 *
174 * Compact edition...
175 */
176static int ambapp_ahb_scan(unsigned int vendor, /* Plug&Play Vendor ID */
177                           unsigned int driver, /* Plug&Play Device ID */
178                           ambapp_ahbdev * dev, /* Result(s) is placed here */
179                           int index,   /* Index of device to start copying Plug&Play
180                                         * info into dev
181                                         */
182                           int max_cnt, /* Maximal count that dev can hold, if dev
183                                         * is NULL function will stop scanning after
184                                         * max_cnt devices are found.
185                                         */
186                           int type     /* Selectes what type of devices to scan.
187                                         * 0=AHB Masters
188                                         * 1=AHB Slaves
189                                         */
190    )
191{
192        int i, j, cnt = 0, max_pp_devs;
193        unsigned int addr;
194        ahbctrl_info *info = (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA);
195        ahbctrl_pp_dev *ahb;
196
197        if (max_cnt == 0)
198                return 0;
199
200        if (type == 0) {
201                max_pp_devs = LEON3_AHB_MASTERS;
202                ahb = info->masters;
203        } else {
204                max_pp_devs = LEON3_AHB_SLAVES;
205                ahb = info->slaves;
206        }
207
208        for (i = 0; i < max_pp_devs; i++) {
209#if defined(CONFIG_CMD_AMBAPP)
210                if (ambapp_ahb_print && amba_vendor(ahb->conf) &&
211                    amba_device(ahb->conf)) {
212                        ambapp_print_ahb(ahb, i);
213                }
214#endif
215                if ((amba_vendor(ahb->conf) == vendor) &&
216                    (amba_device(ahb->conf) == driver) &&
217                    ((index < 0) || (index-- == 0))) {
218                        /* Convert Plug&Play info info a more readable format */
219                        cnt++;
220                        if (dev) {
221                                dev->irq = amba_irq(ahb->conf);
222                                dev->ver = amba_ver(ahb->conf);
223                                dev->userdef[0] = ahb->userdef[0];
224                                dev->userdef[1] = ahb->userdef[1];
225                                dev->userdef[2] = ahb->userdef[2];
226                                for (j = 0; j < 4; j++) {
227                                        addr = amba_membar_start(ahb->bars[j]);
228                                        if (amba_membar_type(ahb->bars[j]) ==
229                                            AMBA_TYPE_AHBIO)
230                                                addr =
231                                                    AMBA_TYPE_AHBIO_ADDR(addr);
232                                        dev->address[j] = addr;
233                                }
234                                dev++;
235                        }
236                        /* found max devices? */
237                        if (cnt >= max_cnt)
238                                return cnt;
239                }
240                /* Get next Plug&Play entry */
241                ahb++;
242        }
243        return cnt;
244}
245
246unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info)
247{
248        register unsigned int ret;
249
250        if (!ahb)
251                return 0;
252
253        switch (info) {
254        default:
255                info = 0;
256        case 0:
257        case 1:
258        case 2:
259        case 3:
260                /* Get Address from PnP Info */
261                ret = amba_membar_start(ahb->bars[info]);
262                if (amba_membar_type(ahb->bars[info]) == AMBA_TYPE_AHBIO)
263                        ret = AMBA_TYPE_AHBIO_ADDR(ret);
264                return ret;
265        }
266        return 0;
267
268}
269
270ahbctrl_pp_dev *ambapp_ahb_next_nomem(register unsigned int vendor,     /* Plug&Play Vendor ID */
271                                      register unsigned int driver,     /* Plug&Play Device ID */
272                                      register unsigned int opts,       /* 1=slave, 0=master */
273                                      register int index)
274{
275        register ahbctrl_pp_dev *ahb;
276        register ahbctrl_info *info =
277            (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA);
278        register int i;
279        register int max_pp_devs;
280
281        if (opts == 0) {
282                max_pp_devs = LEON3_AHB_MASTERS;
283                ahb = info->masters;
284        } else {
285                max_pp_devs = LEON3_AHB_SLAVES;
286                ahb = info->slaves;
287        }
288
289        for (i = 0; i < max_pp_devs; i++) {
290                if ((amba_vendor(ahb->conf) == vendor) &&
291                    (amba_device(ahb->conf) == driver) &&
292                    ((index < 0) || (index-- == 0))) {
293                        /* Convert Plug&Play info info a more readable format */
294                        return ahb;
295                }
296                /* Get next Plug&Play entry */
297                ahb++;
298        }
299        return 0;
300}
301
302/****************************** AHB MASTERS ******************************/
303int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver)
304{
305        /* Get number of devices of this vendor&device ID */
306        return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_MASTERS,
307                               AHB_SCAN_MASTER);
308}
309
310int ambapp_ahbmst_first(unsigned int vendor, unsigned int driver,
311                        ambapp_ahbdev * dev)
312{
313        /* find first device of this */
314        return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_MASTER);
315}
316
317int ambapp_ahbmst_next(unsigned int vendor,
318                       unsigned int driver, ambapp_ahbdev * dev, int index)
319{
320        /* find first device of this */
321        return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_MASTER);
322}
323
324int ambapp_ahbmsts_first(unsigned int vendor,
325                         unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
326{
327        /* find first device of this */
328        return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt,
329                               AHB_SCAN_MASTER);
330}
331
332/****************************** AHB SLAVES ******************************/
333int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver)
334{
335        /* Get number of devices of this vendor&device ID */
336        return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_SLAVES,
337                               AHB_SCAN_SLAVE);
338}
339
340int ambapp_ahbslv_first(unsigned int vendor, unsigned int driver,
341                        ambapp_ahbdev * dev)
342{
343        /* find first device of this */
344        return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_SLAVE);
345}
346
347int ambapp_ahbslv_next(unsigned int vendor,
348                       unsigned int driver, ambapp_ahbdev * dev, int index)
349{
350        /* find first device of this */
351        return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_SLAVE);
352}
353
354int ambapp_ahbslvs_first(unsigned int vendor,
355                         unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
356{
357        /* find first device of this */
358        return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt, AHB_SCAN_SLAVE);
359}
Note: See TracBrowser for help on using the repository browser.