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).
6 * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
8 * See file CREDITS for list of people who contributed to this
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.
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.
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,
31 #if defined(CONFIG_CMD_AMBAPP)
32 extern void ambapp_print_apb(apbctrl_pp_dev * apb,
33 ambapp_ahbdev * apbmst, int index);
34 extern void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index);
35 extern int ambapp_apb_print;
36 extern int ambapp_ahb_print;
39 static 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
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.
52 unsigned int apbmst_base;
59 /* Get AMBA APB Master */
60 if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_APBMST, &apbmst) != 1) {
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);
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);
75 if ((amba_vendor(apb->conf) == vendor) &&
76 (amba_device(apb->conf) == driver) && ((index < 0)
78 /* Convert Plug&Play info into a more readable format */
81 dev->irq = amba_irq(apb->conf);
82 dev->ver = amba_ver(apb->conf);
86 bar & 0xfff00000) >> 12))) & (((apb->
93 /* found max devices? */
97 /* Get next Plug&Play entry */
103 unsigned int ambapp_apb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */
104 register unsigned int driver, /* Plug&Play Device ID */
108 register ahbctrl_pp_dev *apbmst;
109 register apbctrl_pp_dev *apb;
110 register unsigned int apbmst_base;
112 /* APBMST is a AHB Slave */
113 apbmst = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0);
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;
122 /* Find the vendor/driver device on the first APB bus */
123 apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA);
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);
133 /* Get next Plug&Play entry */
139 /****************************** APB SLAVES ******************************/
141 int ambapp_apb_count(unsigned int vendor, unsigned int driver)
143 return ambapp_apb_scan(vendor, driver, NULL, 0, LEON3_APB_SLAVES);
146 int ambapp_apb_first(unsigned int vendor,
147 unsigned int driver, ambapp_apbdev * dev)
149 return ambapp_apb_scan(vendor, driver, dev, 0, 1);
152 int ambapp_apb_next(unsigned int vendor,
153 unsigned int driver, ambapp_apbdev * dev, int index)
155 return ambapp_apb_scan(vendor, driver, dev, index, 1);
158 int ambapp_apbs_first(unsigned int vendor,
159 unsigned int driver, ambapp_apbdev * dev, int max_cnt)
161 return ambapp_apb_scan(vendor, driver, dev, 0, max_cnt);
169 /* Scan AMBA Plug&Play bus for AMBA AHB Masters or AHB Slaves
170 * for a certain matching Vendor and Device ID.
172 * Return number of devices found.
176 static 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
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.
186 int type /* Selectes what type of devices to scan.
192 int i, j, cnt = 0, max_pp_devs;
194 ahbctrl_info *info = (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA);
201 max_pp_devs = LEON3_AHB_MASTERS;
204 max_pp_devs = LEON3_AHB_SLAVES;
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);
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 */
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]) ==
231 AMBA_TYPE_AHBIO_ADDR(addr);
232 dev->address[j] = addr;
236 /* found max devices? */
240 /* Get next Plug&Play entry */
246 unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info)
248 register unsigned int ret;
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);
270 ahbctrl_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 */
275 register ahbctrl_pp_dev *ahb;
276 register ahbctrl_info *info =
277 (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA);
279 register int max_pp_devs;
282 max_pp_devs = LEON3_AHB_MASTERS;
285 max_pp_devs = LEON3_AHB_SLAVES;
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 */
296 /* Get next Plug&Play entry */
302 /****************************** AHB MASTERS ******************************/
303 int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver)
305 /* Get number of devices of this vendor&device ID */
306 return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_MASTERS,
310 int ambapp_ahbmst_first(unsigned int vendor, unsigned int driver,
313 /* find first device of this */
314 return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_MASTER);
317 int ambapp_ahbmst_next(unsigned int vendor,
318 unsigned int driver, ambapp_ahbdev * dev, int index)
320 /* find first device of this */
321 return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_MASTER);
324 int ambapp_ahbmsts_first(unsigned int vendor,
325 unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
327 /* find first device of this */
328 return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt,
332 /****************************** AHB SLAVES ******************************/
333 int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver)
335 /* Get number of devices of this vendor&device ID */
336 return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_SLAVES,
340 int ambapp_ahbslv_first(unsigned int vendor, unsigned int driver,
343 /* find first device of this */
344 return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_SLAVE);
347 int ambapp_ahbslv_next(unsigned int vendor,
348 unsigned int driver, ambapp_ahbdev * dev, int index)
350 /* find first device of this */
351 return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_SLAVE);
354 int ambapp_ahbslvs_first(unsigned int vendor,
355 unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
357 /* find first device of this */
358 return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt, AHB_SCAN_SLAVE);