Date: Fri, 9 Jan 2009 10:20:51 +0000 (UTC) From: Rafal Jaworowski <raj@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r186932 - in head/sys/arm/mv: . orion Message-ID: <200901091020.n09AKpRa049618@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: raj Date: Fri Jan 9 10:20:51 2009 New Revision: 186932 URL: http://svn.freebsd.org/changeset/base/186932 Log: Improve Marvell SOCs PCI/PCIE driver. - Provide dedicated rmans for MEM and IO resources. - Convert PCI IRQ routing info into a table (from callback approach), provide config data for alternative DB- boards. - Fix a wrong boundary check error in pcib_mbus_init_bar() Obtained from: Semihalf Modified: head/sys/arm/mv/mv_pci.c head/sys/arm/mv/mvvar.h head/sys/arm/mv/orion/db88f5xxx.c head/sys/arm/mv/orion/orion.c Modified: head/sys/arm/mv/mv_pci.c ============================================================================== --- head/sys/arm/mv/mv_pci.c Fri Jan 9 10:16:19 2009 (r186931) +++ head/sys/arm/mv/mv_pci.c Fri Jan 9 10:20:51 2009 (r186932) @@ -95,10 +95,12 @@ __FBSDID("$FreeBSD$"); struct pcib_mbus_softc { device_t sc_dev; + struct rman sc_iomem_rman; bus_addr_t sc_iomem_base; bus_addr_t sc_iomem_size; bus_addr_t sc_iomem_alloc; /* Next allocation. */ + struct rman sc_ioport_rman; bus_addr_t sc_ioport_base; bus_addr_t sc_ioport_size; bus_addr_t sc_ioport_alloc; /* Next allocation. */ @@ -521,12 +523,39 @@ pcib_mbus_attach(device_t self) sc->sc_ioport_size = sc->sc_info->op_io_size; sc->sc_ioport_alloc = sc->sc_info->op_io_base; + sc->sc_iomem_rman.rm_type = RMAN_ARRAY; + err = rman_init(&sc->sc_iomem_rman); + if (err) + return (err); + + sc->sc_ioport_rman.rm_type = RMAN_ARRAY; + err = rman_init(&sc->sc_ioport_rman); + if (err) { + rman_fini(&sc->sc_iomem_rman); + return (err); + } + + err = rman_manage_region(&sc->sc_iomem_rman, sc->sc_iomem_base, + sc->sc_iomem_base + sc->sc_iomem_size - 1); + if (err) + goto error; + + err = rman_manage_region(&sc->sc_ioport_rman, sc->sc_ioport_base, + sc->sc_ioport_base + sc->sc_ioport_size - 1); + if (err) + goto error; + err = pcib_mbus_init(sc, sc->sc_busnr, pcib_mbus_maxslots(sc->sc_dev)); if (err) - return(err); + goto error; device_add_child(self, "pci", -1); return (bus_generic_attach(self)); + +error: + rman_fini(&sc->sc_iomem_rman); + rman_fini(&sc->sc_ioport_rman); + return (err); } static int @@ -570,7 +599,7 @@ pcib_mbus_init_bar(struct pcib_mbus_soft return (width); addr = (*allocp + mask) & ~mask; - if ((*allocp = addr + size) >= limit) + if ((*allocp = addr + size) > limit) return (-1); if (bootverbose) @@ -634,8 +663,10 @@ static int pcib_mbus_init_resources(struct pcib_mbus_softc *sc, int bus, int slot, int func, int hdrtype) { + const struct obio_pci_irq_map *map = sc->sc_info->op_pci_irq_map; int maxbar = (hdrtype & PCIM_HDRTYPE) ? 0 : 6; - int bar = 0, irq, pin, i; + int bar = 0, irq = -1; + int pin, i; /* Program the base address registers */ while (bar < maxbar) { @@ -652,8 +683,14 @@ pcib_mbus_init_resources(struct pcib_mbu pin = pcib_mbus_read_config(sc->sc_dev, bus, slot, func, PCIR_INTPIN, 1); - if (sc->sc_info->op_get_irq != NULL) - irq = sc->sc_info->op_get_irq(bus, slot, func, pin); + if (map != NULL) + while (map->opim_irq >= 0) { + if ((map->opim_slot == slot || map->opim_slot < 0) && + (map->opim_pin == pin || map->opim_pin < 0)) + irq = map->opim_irq; + + map++; + } else irq = sc->sc_info->op_irq; @@ -728,9 +765,37 @@ static struct resource * pcib_mbus_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { + struct pcib_mbus_softc *sc = device_get_softc(dev); + struct rman *rm = NULL; + struct resource *res; - return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, - type, rid, start, end, count, flags)); + switch (type) { + case SYS_RES_IOPORT: + rm = &sc->sc_ioport_rman; + break; + case SYS_RES_MEMORY: + rm = &sc->sc_iomem_rman; + break; + default: + return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, + type, rid, start, end, count, flags)); + }; + + res = rman_reserve_resource(rm, start, end, count, flags, child); + if (res == NULL) + return (NULL); + + rman_set_rid(res, *rid); + rman_set_bustag(res, obio_tag); + rman_set_bushandle(res, start); + + if (flags & RF_ACTIVE) + if (bus_activate_resource(child, type, *rid, res)) { + rman_release_resource(res); + return (NULL); + } + + return (res); } static int @@ -738,8 +803,11 @@ pcib_mbus_release_resource(device_t dev, struct resource *res) { - return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child, - type, rid, res)); + if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY) + return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child, + type, rid, res)); + + return (rman_release_resource(res)); } static int Modified: head/sys/arm/mv/mvvar.h ============================================================================== --- head/sys/arm/mv/mvvar.h Fri Jan 9 10:16:19 2009 (r186931) +++ head/sys/arm/mv/mvvar.h Fri Jan 9 10:20:51 2009 (r186932) @@ -63,7 +63,11 @@ struct obio_device { struct resource_list od_resources; }; -typedef int (*obio_get_irq_t)(u_int bus, u_int slot, u_int func, u_int pin); +struct obio_pci_irq_map { + int opim_slot; + int opim_pin; + int opim_irq; +}; struct obio_pci { int op_type; @@ -82,8 +86,8 @@ struct obio_pci { int op_mem_win_target; int op_mem_win_attr; - obio_get_irq_t op_get_irq; /* IRQ Mapping callback */ - int op_irq; /* used if callback is NULL */ + const struct obio_pci_irq_map *op_pci_irq_map; + int op_irq; /* used if IRQ map table is NULL */ }; struct gpio_config { Modified: head/sys/arm/mv/orion/db88f5xxx.c ============================================================================== --- head/sys/arm/mv/orion/db88f5xxx.c Fri Jan 9 10:16:19 2009 (r186931) +++ head/sys/arm/mv/orion/db88f5xxx.c Fri Jan 9 10:20:51 2009 (r186932) @@ -123,35 +123,32 @@ static const struct pmap_devmap pmap_dev { 0, 0, 0, 0, 0, } }; -int platform_pci_get_irq(u_int bus, u_int slot, u_int func, u_int pin) -{ - int irq; - - switch (slot) { - case 7: - irq = GPIO2IRQ(12); /* GPIO 0 for DB-88F5182 */ - break; /* GPIO 12 for DB-88F5281 */ - case 8: - case 9: - irq = GPIO2IRQ(13); /* GPIO 1 for DB-88F5182 */ - break; /* GPIO 13 for DB-88F5281 */ - default: - irq = -1; - break; - }; +/* + * The pci_irq_map table consists of 3 columns: + * - PCI slot number (less than zero means ANY). + * - PCI IRQ pin (less than zero means ANY). + * - PCI IRQ (less than zero marks end of table). + * + * IRQ number from the first matching entry is used to configure PCI device + */ - /* - * XXX This isn't the right place to setup GPIO, but it makes sure - * that PCI works on 5XXX targets where U-Boot doesn't set up the GPIO - * correctly to handle PCI IRQs (e.g., on 5182). This code will go - * away once we set up GPIO in a generic way in a proper place (TBD). - */ - if (irq >= 0) - mv_gpio_configure(IRQ2GPIO(irq), MV_GPIO_POLAR_LOW | - MV_GPIO_LEVEL, ~0u); +/* PCI IRQ Map for DB-88F5281 */ +const struct obio_pci_irq_map pci_irq_map[] = { + { 7, -1, GPIO2IRQ(12) }, + { 8, -1, GPIO2IRQ(13) }, + { 9, -1, GPIO2IRQ(13) }, + { -1, -1, -1 } +}; - return (irq); -} +#if 0 +/* PCI IRQ Map for DB-88F5182 */ +const struct obio_pci_irq_map pci_irq_map[] = { + { 7, -1, GPIO2IRQ(0) }, + { 8, -1, GPIO2IRQ(1) }, + { 9, -1, GPIO2IRQ(1) }, + { -1, -1, -1 } +}; +#endif /* * mv_gpio_config row structure: Modified: head/sys/arm/mv/orion/orion.c ============================================================================== --- head/sys/arm/mv/orion/orion.c Fri Jan 9 10:16:19 2009 (r186931) +++ head/sys/arm/mv/orion/orion.c Fri Jan 9 10:20:51 2009 (r186932) @@ -41,7 +41,7 @@ __FBSDID("$FreeBSD$"); #include <arm/mv/mvreg.h> #include <arm/mv/mvvar.h> -extern int platform_pci_get_irq(u_int bus, u_int slot, u_int func, u_int pin); +extern const struct obio_pci_irq_map pci_irq_map[]; struct obio_device obio_devices[] = { { "ic", MV_IC_BASE, MV_IC_SIZE, @@ -106,7 +106,7 @@ const struct obio_pci mv_pci_info[] = { MV_PCI_BASE, MV_PCI_SIZE, MV_PCI_IO_BASE, MV_PCI_IO_SIZE, 3, 0x51, MV_PCI_MEM_BASE, MV_PCI_MEM_SIZE, 3, 0x59, - platform_pci_get_irq, -1 + pci_irq_map, -1 }, { 0, 0, 0 }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200901091020.n09AKpRa049618>