19 #include <grlib/grlib_impl.h> 21 #define AMBA_CONF_AREA 0xff000 22 #define AMBA_AHB_SLAVE_CONF_AREA (1 << 11) 23 #define AMBA_APB_SLAVES 16 26 static struct ambapp_dev *ambapp_alloc_dev_struct(
int dev_type)
29 size_t size =
sizeof(*dev);
31 if (dev_type == DEV_APB_SLV)
35 dev = grlib_calloc(1, size);
37 dev->dev_type = dev_type;
42 ambapp_addr_from (
struct ambapp_mmap *mmaps,
unsigned int address)
49 if ((address >= mmaps->remote_adr) &&
50 (address <= (mmaps->remote_adr + (mmaps->size - 1)))) {
51 return (address - mmaps->remote_adr) + mmaps->local_adr;
58 static void ambapp_ahb_dev_init(
68 unsigned int addr, mask, mbar;
71 dev->vendor = ambapp_pnp_vendor(ahb->id);
72 dev->device = ambapp_pnp_device(ahb->id);
73 ahb_info = DEV_TO_AHB(dev);
74 ahb_info->common.ver = ambapp_pnp_ver(ahb->id);
75 ahb_info->common.irq = ambapp_pnp_irq(ahb->id);
76 ahb_info->common.ahbidx = ahbidx;
77 ahb_info->custom[0] = (
unsigned int)ahb->custom[0];
78 ahb_info->custom[1] = (
unsigned int)ahb->custom[1];
79 ahb_info->custom[2] = (
unsigned int)ahb->custom[2];
82 for (bar=0; bar<4; bar++) {
83 mbar = ahb->mbar[bar];
88 addr = ambapp_pnp_start(mbar);
89 if (ambapp_pnp_mbar_type(mbar) == AMBA_TYPE_AHBIO) {
91 addr = AMBA_TYPE_AHBIO_ADDR(addr, ioarea);
92 mask = (((
unsigned int)(ambapp_pnp_mbar_mask(~mbar) << 8) | 0xff)) + 1;
95 addr = ambapp_addr_from(mmaps, addr);
96 mask = (~((
unsigned int)(ambapp_pnp_mbar_mask(mbar) << 20))) + 1;
99 ahb_info->start[bar] = addr;
100 ahb_info->mask[bar] = mask;
101 ahb_info->type[bar] = ambapp_pnp_mbar_type(mbar);
105 static void ambapp_apb_dev_init(
116 dev->vendor = ambapp_pnp_vendor(apb->id);
117 dev->device = ambapp_pnp_device(apb->id);
118 apb_info = DEV_TO_APB(dev);
119 apb_info->common.ver = ambapp_pnp_ver(apb->id);
120 apb_info->common.irq = ambapp_pnp_irq(apb->id);
121 apb_info->common.ahbidx = ahbidx;
122 apb_info->start = ambapp_pnp_apb_start(apb->iobar, base);
123 apb_info->mask = ambapp_pnp_apb_mask(apb->iobar);
126 static int ambapp_add_ahbbus(
132 for (i=0; i<AHB_BUS_MAX; i++) {
133 if (abus->ahbs[i].ioarea == 0) {
134 abus->ahbs[i].ioarea = ioarea;
136 }
else if (abus->ahbs[i].ioarea == ioarea) {
145 static int ambapp_scan2(
148 ambapp_memcpy_t memfunc,
155 struct ambapp_dev *dev, *prev, *prevapb, *apbdev;
158 unsigned int apbbase, bridge_adr;
168 ahbidx = ambapp_add_ahbbus(abus, ioarea);
178 for (i = 0; i < maxloops; i++, ahb++) {
184 dev = ambapp_alloc_dev_struct(DEV_AHB_MST);
188 ambapp_ahb_dev_init(ioarea, abus->mmaps, &ahb_buf, dev, ahbidx);
201 (ioarea | AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA);
202 for (i = 0; i < maxloops; i++, ahb++) {
208 dev = ambapp_alloc_dev_struct(DEV_AHB_SLV);
212 ambapp_ahb_dev_init(ioarea, abus->mmaps, &ahb_buf, dev, ahbidx);
222 ahb_info = DEV_TO_AHB(dev);
225 if (((dev->device == GAISLER_AHB2AHB) &&
226 (dev->vendor == VENDOR_GAISLER) && (ahb_info->common.ver > 0)) ||
227 ((dev->device == GAISLER_L2CACHE) &&
228 (dev->vendor == VENDOR_GAISLER)) ||
229 ((dev->device == GAISLER_GRIOMMU) &&
230 (dev->vendor == VENDOR_GAISLER))) {
234 if (ahb_info->custom[1] != 0) {
235 bridge_adr = ambapp_addr_from(abus->mmaps,
236 ahb_info->custom[1]);
238 if (ambapp_scan2(abus, bridge_adr, memfunc, dev,
242 }
else if ((dev->device == GAISLER_APBMST) &&
243 (dev->vendor == VENDOR_GAISLER)) {
248 apbbase = ahb_info->start[0];
252 (apbbase | AMBA_CONF_AREA);
253 for (j=0; j<AMBA_APB_SLAVES; j++, apb++) {
254 memfunc(&apb_buf, apb,
sizeof(*apb), abus);
258 apbdev = ambapp_alloc_dev_struct(DEV_APB_SLV);
262 ambapp_apb_dev_init(apbbase, abus->mmaps,
263 &apb_buf, apbdev, ahbidx);
266 prevapb->next = apbdev;
268 dev->children = apbdev;
269 apbdev->prev = prevapb;
276 abus->ahbs[ahbidx].dev = *root;
277 abus->ahbs[ahbidx].bridge = parent;
286 ambapp_memcpy_t memfunc,
290 memset(abus, 0,
sizeof(*abus));
295 memfunc = (ambapp_memcpy_t)memcpy;
297 return ambapp_scan2(abus, ioarea, memfunc, NULL, &abus->root);
301 static int ambapp_dev_match_options(
struct ambapp_dev *dev,
unsigned int options,
int vendor,
int device)
303 if ((((options & (OPTIONS_ALL_DEVS)) == OPTIONS_ALL_DEVS) ||
304 ((options & OPTIONS_AHB_MSTS) && (dev->dev_type == DEV_AHB_MST)) ||
305 ((options & OPTIONS_AHB_SLVS) && (dev->dev_type == DEV_AHB_SLV)) ||
306 ((options & OPTIONS_APB_SLVS) && (dev->dev_type == DEV_APB_SLV))) &&
307 ((vendor == -1) || (vendor == dev->vendor)) &&
308 ((device == -1) || (device == dev->device)) &&
309 (((options & OPTIONS_ALL) == OPTIONS_ALL) ||
310 ((options & OPTIONS_FREE) && DEV_IS_FREE(dev)) ||
311 ((options & OPTIONS_ALLOCATED) && DEV_IS_ALLOCATED(dev)))) {
318 static int ambapp_for_each_apb(
320 unsigned int options,
330 if (dev->children && (dev->children->dev_type == DEV_APB_SLV)) {
333 apbslv = dev->children;
335 if (ambapp_dev_match_options(apbslv, options,
336 vendor, device) == 1) {
337 ret = func(apbslv, index, arg);
342 apbslv = apbslv->next;
350 static int ambapp_for_each_dev(
352 unsigned int options,
372 if (options & (OPTIONS_AHB_MSTS|OPTIONS_AHB_SLVS|OPTIONS_DEPTH_FIRST)) {
376 if ((dev->dev_type == DEV_AHB_SLV) && !ahb_slave) {
385 if (ambapp_dev_match_options(dev, options, vendor, device) == 1) {
387 ret = func(dev, index, arg);
392 if ((options & OPTIONS_DEPTH_FIRST) && (options & OPTIONS_APB_SLVS)) {
396 ret = ambapp_for_each_apb(dev, options, vendor, device, func, arg);
401 if (options & OPTIONS_DEPTH_FIRST) {
402 if (dev->children && (dev->children->dev_type != DEV_APB_SLV)) {
404 ret = ambapp_for_each_dev(dev->children, options, vendor, device,
417 if ((options & OPTIONS_APB_SLVS) && !(options & OPTIONS_DEPTH_FIRST)) {
423 ret = ambapp_for_each_apb(dev, options, vendor, device, func, arg);
431 if (!(options & OPTIONS_DEPTH_FIRST)) {
434 if (dev->children && (dev->children->dev_type != DEV_APB_SLV)) {
436 ret = ambapp_for_each_dev(dev->children, options, vendor, device,
450 unsigned int options,
456 return ambapp_for_each_dev(abus->root, options, vendor, device, func, arg);