The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/mips/rt305x/rt305x_pci.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2015 Stanislav Galabov.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
   10  *    notice, this list of conditions and the following disclaimer in the
   11  *    documentation and/or other materials provided with the distribution.
   12  *
   13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   23  * SUCH DAMAGE.
   24  *
   25  * This is based on the pci allocator code from sys/dev/arm/mv/:
   26  *
   27  * Copyright (c) 2008 MARVELL INTERNATIONAL LTD.
   28  * Copyright (c) 2010 The FreeBSD Foundation
   29  * Copyright (c) 2010-2012 Semihalf
   30  * All rights reserved.
   31  *
   32  * Developed by Semihalf.
   33  */
   34 #include <sys/cdefs.h>
   35 __FBSDID("$FreeBSD$");
   36 
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 
   40 #include <sys/bus.h>
   41 #include <sys/interrupt.h>
   42 #include <sys/malloc.h>
   43 #include <sys/kernel.h>
   44 #include <sys/module.h>
   45 #include <sys/rman.h>
   46 #include <sys/lock.h>
   47 #include <sys/mutex.h>
   48 #include <sys/endian.h>
   49 
   50 #include <vm/vm.h>
   51 #include <vm/pmap.h>
   52 #include <vm/vm_extern.h>
   53 
   54 #include <machine/bus.h>
   55 #include <machine/cpu.h>
   56 #include <machine/intr_machdep.h>
   57 
   58 #include <dev/pci/pcivar.h>
   59 #include <dev/pci/pcireg.h>
   60 
   61 #include <dev/pci/pcib_private.h>
   62 #include "pcib_if.h"
   63 
   64 #include <mips/rt305x/rt305xreg.h>
   65 #include <mips/rt305x/rt305x_pcireg.h>
   66 #include <mips/rt305x/rt305x_sysctlvar.h>
   67 
   68 struct mtx rt305x_pci_mtx;
   69 MTX_SYSINIT(rt305x_pci_mtx, &rt305x_pci_mtx, "rt305x PCI/PCIe mutex", MTX_SPIN);
   70 
   71 struct rt305x_pci_softc {
   72         device_t                sc_dev;
   73 
   74         bus_space_tag_t         sc_bst;
   75         bus_space_handle_t      sc_bsh;
   76 
   77         int                     sc_busno;
   78 
   79         struct rman             sc_mem_rman;
   80         struct rman             sc_io_rman;
   81         struct rman             sc_irq_rman;
   82 
   83         bus_addr_t              sc_mem_base;
   84         bus_addr_t              sc_mem_size;
   85         uint32_t                sc_mem_map[(256*1024*1024) /
   86                                 (PCI_MIN_MEM_ALLOC * BITS_PER_UINT32)];
   87 
   88         bus_addr_t              sc_io_base;
   89         bus_addr_t              sc_io_size;
   90         uint32_t                sc_io_map[(16*1024*1024) /
   91                                 (PCI_MIN_IO_ALLOC * BITS_PER_UINT32)];
   92 
   93         struct intr_event       *sc_eventstab[RT305X_PCI_NIRQS];
   94         mips_intrcnt_t          sc_intr_counter[RT305X_PCI_NIRQS];
   95 
   96         int                     pcie_link_status;
   97 };
   98 
   99 static void rt305x_pci_phy_init(device_t);
  100 static void rt305x_pci_init(device_t);
  101 static int rt305x_pcib_init(device_t, int, int);
  102 static int rt305x_pci_intr(void *);
  103 
  104 static void rt305x_pci_dump_regs(device_t);
  105 
  106 static struct rt305x_pci_softc *rt_sc = NULL;
  107 
  108 static int
  109 rt305x_pci_probe(device_t dev)
  110 {
  111 
  112         return (BUS_PROBE_NOWILDCARD);
  113 }
  114 
  115 static int
  116 rt305x_pci_attach(device_t dev)
  117 {
  118         struct rt305x_pci_softc *sc = device_get_softc(dev);
  119 
  120         rt_sc = sc;
  121 
  122         sc->sc_dev = dev;
  123         sc->sc_mem_base = PCIE_MEM_BASE;
  124         sc->sc_mem_size = 0x10000000;
  125         sc->sc_io_base = PCIE_IO_BASE;
  126         sc->sc_io_size = 0x10000;
  127 
  128         sc->sc_bsh = MIPS_PHYS_TO_KSEG1(PCIE_BASE);
  129         sc->sc_bst = mips_bus_space_generic;
  130 
  131         sc->sc_mem_rman.rm_type = RMAN_ARRAY;
  132         sc->sc_mem_rman.rm_descr = "rt305x pci memory window";
  133         if (rman_init(&sc->sc_mem_rman) != 0 ||
  134             rman_manage_region(&sc->sc_mem_rman, sc->sc_mem_base,
  135                 sc->sc_mem_base + sc->sc_mem_size - 1) != 0) {
  136                 panic("%s: failed to set up memory rman", __FUNCTION__);
  137         }
  138 
  139         sc->sc_io_rman.rm_type = RMAN_ARRAY;
  140         sc->sc_io_rman.rm_descr = "rt305x pci io window";
  141         if (rman_init(&sc->sc_io_rman) != 0 ||
  142             rman_manage_region(&sc->sc_io_rman, sc->sc_io_base,
  143                 sc->sc_io_base + sc->sc_io_size - 1) != 0) {
  144                 panic("%s: failed to set up io rman", __FUNCTION__);
  145         }
  146 
  147         sc->sc_irq_rman.rm_type = RMAN_ARRAY;
  148         sc->sc_irq_rman.rm_descr = "rt305x pci irqs";
  149         if (rman_init(&sc->sc_irq_rman) != 0 ||
  150             rman_manage_region(&sc->sc_irq_rman, RT305X_PCIE0_IRQ,
  151                 RT305X_PCIE0_IRQ) != 0) {
  152                 panic("%s: failed to set up irq rman", __FUNCTION__);
  153         }
  154 
  155         cpu_establish_hardintr("pci", rt305x_pci_intr, NULL, sc,
  156                 RT305X_PCI_INTR_PIN, INTR_TYPE_MISC | INTR_EXCL, NULL);
  157 
  158         rt305x_pci_phy_init(dev);
  159 
  160         rt305x_pci_init(dev);
  161 
  162         rt305x_pci_dump_regs(dev);
  163 
  164         rt305x_pcib_init(dev, 0, PCI_SLOTMAX);
  165 
  166         device_add_child(dev, "pci", -1);
  167 
  168         return (bus_generic_attach(dev));
  169 }
  170 
  171 static int
  172 rt305x_pci_read_ivar(device_t dev, device_t child, int which,
  173         uintptr_t *result)
  174 {
  175         struct rt305x_pci_softc *sc = device_get_softc(dev);
  176 
  177         switch (which) {
  178         case PCIB_IVAR_DOMAIN:
  179                 *result = device_get_unit(dev);
  180                 return (0);
  181         case PCIB_IVAR_BUS:
  182                 *result = sc->sc_busno;
  183                 return (0);
  184         }
  185 
  186         return (ENOENT);
  187 }
  188 
  189 static int
  190 rt305x_pci_write_ivar(device_t dev, device_t child, int which,
  191         uintptr_t result)
  192 {
  193         struct rt305x_pci_softc *sc = device_get_softc(dev);
  194 
  195         switch (which) {
  196         case PCIB_IVAR_BUS:
  197                 sc->sc_busno = result;
  198                 return (0);
  199         }
  200 
  201         return (ENOENT);
  202 }
  203 
  204 static struct resource *
  205 rt305x_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
  206         rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
  207 {
  208         struct rt305x_pci_softc *sc = device_get_softc(bus);
  209         struct resource *rv;
  210         struct rman *rm;
  211         vm_offset_t va;
  212 
  213         switch (type) {
  214         case SYS_RES_IRQ:
  215                 rm = &sc->sc_irq_rman;
  216                 break;
  217         case SYS_RES_IOPORT:
  218                 rm = &sc->sc_io_rman;
  219                 break;
  220         case SYS_RES_MEMORY:
  221                 rm = &sc->sc_mem_rman;
  222                 break;
  223         default:
  224                 return (NULL);
  225         }
  226 
  227         rv = rman_reserve_resource(rm, start, end, count, flags, child);
  228 
  229         if (rv == NULL)
  230                 return (NULL);
  231 
  232         rman_set_rid(rv, *rid);
  233 
  234         if (type != SYS_RES_IRQ) {
  235                 if (type == SYS_RES_MEMORY) {
  236                         va = (vm_offset_t)pmap_mapdev(start, count);
  237                 } else if (type == SYS_RES_IOPORT){
  238                         va = (vm_offset_t)MIPS_PHYS_TO_KSEG1(start);
  239                 }
  240                 rman_set_bushandle(rv, va);
  241                 rman_set_virtual(rv, (void *)va);
  242                 rman_set_bustag(rv, mips_bus_space_generic);
  243         }
  244 
  245         if (flags & RF_ACTIVE) {
  246                 if (bus_activate_resource(child, type, *rid, rv)) {
  247                         rman_release_resource(rv);
  248                         return (NULL);
  249                 }
  250         }
  251 
  252         return (rv);
  253 }
  254 
  255 static int
  256 rt305x_pci_activate_resource(device_t bus, device_t child, int type, int rid,
  257         struct resource *r)
  258 {
  259 
  260         return rman_activate_resource(r);
  261 }
  262 
  263 static inline int
  264 rt305x_idx_to_irq(int idx)
  265 {
  266 
  267         return ((idx == 0) ? RT305X_PCIE0_IRQ :
  268                 (idx == 1) ? RT305X_PCIE1_IRQ :
  269                 (idx == 2) ? RT305X_PCIE2_IRQ : -1);
  270 }
  271 
  272 static inline int
  273 rt305x_irq_to_idx(int irq)
  274 {
  275 
  276         return ((irq == RT305X_PCIE0_IRQ) ? 0 :
  277                 (irq == RT305X_PCIE1_IRQ) ? 1 :
  278                 (irq == RT305X_PCIE2_IRQ) ? 2 : -1);
  279 }
  280 
  281 static void
  282 rt305x_pci_mask_irq(void *source)
  283 {
  284 
  285         RT_WRITE32(rt_sc, RT305X_PCI_PCIENA,
  286                 RT_READ32(rt_sc, RT305X_PCI_PCIENA) & ~(1<<((int)source)));
  287 }
  288 
  289 static void
  290 rt305x_pci_unmask_irq(void *source)
  291 {
  292 
  293         RT_WRITE32(rt_sc, RT305X_PCI_PCIENA,
  294                 RT_READ32(rt_sc, RT305X_PCI_PCIENA) | (1<<((int)source)));
  295 }
  296 
  297 static int
  298 rt305x_pci_setup_intr(device_t bus, device_t child, struct resource *ires,
  299         int flags, driver_filter_t *filt, driver_intr_t *handler,
  300         void *arg, void **cookiep)
  301 {
  302         struct rt305x_pci_softc *sc = device_get_softc(bus);
  303         struct intr_event *event;
  304         int irq, error, irqidx;
  305 
  306         irq = rman_get_start(ires);
  307 
  308         if ((irqidx = rt305x_irq_to_idx(irq)) == -1)
  309                 panic("%s: bad irq %d", __FUNCTION__, irq);
  310 
  311         event = sc->sc_eventstab[irqidx];
  312         if (event == NULL) {
  313                 error = intr_event_create(&event, (void *)irq, 0, irq,
  314                     rt305x_pci_mask_irq, rt305x_pci_unmask_irq, NULL, NULL,
  315                     "pci intr%d:", irq);
  316 
  317                 if (error == 0) {
  318                         sc->sc_eventstab[irqidx] = event;
  319                         sc->sc_intr_counter[irqidx] =
  320                             mips_intrcnt_create(event->ie_name);
  321                 }
  322                 else
  323                         return (error);
  324         }
  325 
  326         intr_event_add_handler(event, device_get_nameunit(child), filt,
  327                 handler, arg, intr_priority(flags), flags, cookiep);
  328 
  329         mips_intrcnt_setname(sc->sc_intr_counter[irqidx], event->ie_fullname);
  330 
  331         rt305x_pci_unmask_irq((void*)irq);
  332 
  333         return (0);
  334 }
  335 
  336 static int
  337 rt305x_pci_teardown_intr(device_t dev, device_t child, struct resource *ires,
  338         void *cookie)
  339 {
  340         struct rt305x_pci_softc *sc = device_get_softc(dev);
  341         int irq, result, irqidx;
  342 
  343         irq = rman_get_start(ires);
  344         if ((irqidx = rt305x_irq_to_idx(irq)) == -1)
  345                 panic("%s: bad irq %d", __FUNCTION__, irq);
  346 
  347         if (sc->sc_eventstab[irqidx] == NULL)
  348                 panic("Trying to teardown unoccupied IRQ");
  349 
  350         rt305x_pci_mask_irq((void*)irq);
  351 
  352         result = intr_event_remove_handler(cookie);
  353         if (!result)
  354                 sc->sc_eventstab[irqidx] = NULL;
  355 
  356         return (result);
  357 }
  358 
  359 static inline uint32_t
  360 rt305x_pci_make_addr(int bus, int slot, int func, int reg)
  361 {
  362         uint32_t addr;
  363 
  364         addr = (((reg & 0xf00) >> 8) << 24) | (bus << 16) | (slot << 11) |
  365                 (func << 8) | (reg & 0xfc) | (1 << 31);
  366 
  367         return (addr);
  368 }
  369 
  370 static int
  371 rt305x_pci_maxslots(device_t dev)
  372 {
  373 
  374         return (PCI_SLOTMAX);
  375 }
  376 
  377 static uint32_t
  378 rt305x_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func,
  379         u_int reg, int bytes)
  380 {
  381         struct rt305x_pci_softc *sc = device_get_softc(dev);
  382         uint32_t addr = 0, data = 0;
  383 
  384         if (bus == 0 && (sc->pcie_link_status & (1<<slot)) == 0)
  385                 return (~0U);
  386 
  387         mtx_lock_spin(&rt305x_pci_mtx);
  388         addr = rt305x_pci_make_addr(bus, slot, func, (reg & ~3));
  389         RT_WRITE32(sc, RT305X_PCI_CFGADDR, addr);
  390         switch (bytes % 4) {
  391         case 0:
  392                 data = RT_READ32(sc, RT305X_PCI_CFGDATA);
  393                 break;
  394         case 1:
  395                 data = RT_READ8(sc, RT305X_PCI_CFGDATA + (reg & 0x3));
  396                 break;
  397         case 2:
  398                 data = RT_READ16(sc, RT305X_PCI_CFGDATA + (reg & 0x3));
  399                 break;
  400         default:
  401                 panic("%s(): Wrong number of bytes (%d) requested!\n",
  402                         __FUNCTION__, bytes % 4);
  403         }
  404         mtx_unlock_spin(&rt305x_pci_mtx);
  405 
  406         return (data);
  407 }
  408 
  409 static void
  410 rt305x_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func,
  411         u_int reg, uint32_t val, int bytes)
  412 {
  413         struct rt305x_pci_softc *sc = device_get_softc(dev);
  414         uint32_t addr = 0, data = val;
  415 
  416         if (bus == 0 && (sc->pcie_link_status & (1<<slot)) == 0)
  417                 return;
  418 
  419         mtx_lock_spin(&rt305x_pci_mtx);
  420         addr = rt305x_pci_make_addr(bus, slot, func, (reg & ~3));
  421         RT_WRITE32(sc, RT305X_PCI_CFGADDR, addr);
  422         switch (bytes % 4) {
  423         case 0:
  424                 RT_WRITE32(sc, RT305X_PCI_CFGDATA, data);
  425                 break;
  426         case 1:
  427                 RT_WRITE8(sc, RT305X_PCI_CFGDATA + (reg & 0x3), data);
  428                 break;
  429         case 2:
  430                 RT_WRITE16(sc, RT305X_PCI_CFGDATA + (reg & 0x3), data);
  431                 break;
  432         default:
  433                 panic("%s(): Wrong number of bytes (%d) requested!\n",
  434                         __FUNCTION__, bytes % 4);
  435         }
  436         mtx_unlock_spin(&rt305x_pci_mtx);
  437 }
  438 
  439 static int
  440 rt305x_pci_route_interrupt(device_t pcib, device_t device, int pin)
  441 {
  442         //struct rt305x_pci_softc *sc = device_get_softc(pcib);
  443         int bus, sl;
  444 
  445         bus = pci_get_bus(device);
  446         sl = pci_get_slot(device);
  447 
  448         if (bus != 0)
  449                 panic("Unexpected bus number %d\n", bus);
  450 
  451         //printf("%s: not done yet.\n", __FUNCTION__);
  452 
  453         switch (sl) {
  454         case 0: return RT305X_PCIE0_IRQ;
  455         default: return (-1);
  456         }
  457 
  458         return (-1);
  459 }
  460 
  461 static device_method_t rt305x_pci_methods[] = {
  462         /* Device interface */
  463         DEVMETHOD(device_probe,         rt305x_pci_probe),
  464         DEVMETHOD(device_attach,        rt305x_pci_attach),
  465         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
  466         DEVMETHOD(device_suspend,       bus_generic_suspend),
  467         DEVMETHOD(device_resume,        bus_generic_resume),
  468 
  469         /* Bus interface */
  470         DEVMETHOD(bus_read_ivar,        rt305x_pci_read_ivar),
  471         DEVMETHOD(bus_write_ivar,       rt305x_pci_write_ivar),
  472         DEVMETHOD(bus_alloc_resource,   rt305x_pci_alloc_resource),
  473         DEVMETHOD(bus_release_resource, bus_generic_release_resource),
  474         DEVMETHOD(bus_activate_resource,   rt305x_pci_activate_resource),
  475         DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
  476         DEVMETHOD(bus_setup_intr,       rt305x_pci_setup_intr),
  477         DEVMETHOD(bus_teardown_intr,    rt305x_pci_teardown_intr),
  478 
  479         /* pcib interface */
  480         DEVMETHOD(pcib_maxslots,        rt305x_pci_maxslots),
  481         DEVMETHOD(pcib_read_config,     rt305x_pci_read_config),
  482         DEVMETHOD(pcib_write_config,    rt305x_pci_write_config),
  483         DEVMETHOD(pcib_route_interrupt, rt305x_pci_route_interrupt),
  484 
  485         DEVMETHOD_END
  486 };
  487 
  488 static driver_t rt305x_pci_driver = {
  489         "pcib",
  490         rt305x_pci_methods,
  491         sizeof(struct rt305x_pci_softc),
  492 };
  493 
  494 static devclass_t rt305x_pci_devclass;
  495 
  496 DRIVER_MODULE(rt305x_pci, nexus, rt305x_pci_driver, rt305x_pci_devclass, 0, 0);
  497 
  498 static void
  499 rt305x_pci_dump_regs(device_t dev)
  500 {
  501 #if 0
  502         struct rt305x_pci_softc *sc = device_get_softc(dev);
  503         uint32_t reg = 0;
  504 
  505         reg = 0x0000;
  506         printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
  507 
  508         reg = 0x0008;
  509         printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
  510 
  511         reg = 0x000c;
  512         printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
  513 
  514         reg = 0x0020;
  515         printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
  516 
  517         reg = 0x0024;
  518         printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
  519 
  520         reg = 0x0028;
  521         printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
  522 
  523         reg = 0x002c;
  524         printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
  525 
  526         reg = 0x2010;
  527         printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
  528 
  529         reg = 0x2014;
  530         printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
  531 
  532         reg = 0x2018;
  533         printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
  534 
  535         reg = 0x2030;
  536         printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
  537 
  538         reg = 0x2034;
  539         printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
  540 
  541         reg = 0x2038;
  542         printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
  543 
  544         reg = 0x2050;
  545         printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
  546 
  547         reg = 0x2060;
  548         printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
  549 
  550         reg = 0x2064;
  551         printf("0x%04x: 0x%08x\n", reg, RT_READ32(sc, reg));
  552 #endif
  553 }
  554 
  555 static void
  556 rt305x_pci_init(device_t dev)
  557 {
  558         struct rt305x_pci_softc *sc = device_get_softc(dev);
  559         uint32_t tmp;
  560 
  561         rt305x_sysctl_set(SYSCTL_SYSCFG1,
  562                 rt305x_sysctl_get(SYSCTL_SYSCFG1) | (1 << 8));
  563 
  564         rt305x_sysctl_set(SYSCTL_GPIOMODE,
  565                 rt305x_sysctl_get(SYSCTL_GPIOMODE) & ~(0x3 << 16));
  566         rt305x_sysctl_set(SYSCTL_RSTCTRL,
  567                 rt305x_sysctl_get(SYSCTL_RSTCTRL) & ~(1<<26));
  568         rt305x_sysctl_set(SYSCTL_CLKCFG1,
  569                 rt305x_sysctl_get(SYSCTL_CLKCFG1) | (1<<26));
  570 
  571         tmp = rt305x_sysctl_get(SYSCTL_PPLL_CFG1);
  572         if ((tmp & (1<<23)) == 0) {
  573                 device_printf(dev, "PPLL not locked\n");
  574                 return;
  575         }
  576 
  577         tmp = rt305x_sysctl_get(SYSCTL_PPLL_DRV);
  578         tmp |= (1<<19);
  579         rt305x_sysctl_set(SYSCTL_PPLL_DRV, tmp);
  580         tmp &= ~(1<<18);
  581         rt305x_sysctl_set(SYSCTL_PPLL_DRV, tmp);
  582         tmp &= ~(1<<17);
  583         rt305x_sysctl_set(SYSCTL_PPLL_DRV, tmp);
  584         tmp|= (1<<31);
  585         rt305x_sysctl_set(SYSCTL_PPLL_DRV, tmp);
  586 
  587         RT_WRITE32(sc, RT305X_PCI_MEMBASE, sc->sc_mem_base);
  588         RT_WRITE32(sc, RT305X_PCI_IOBASE, sc->sc_io_base);
  589 
  590         RT_WRITE32(sc, RT305X_PCI_PCICFG, RT_READ32(sc, 0) & ~(1<<1));
  591         DELAY(500000);
  592         if ((RT_READ32(sc, RT305X_PCI_PCIE0_STATUS) & 0x1) == 1)
  593                 sc->pcie_link_status = 1;
  594         else
  595                 sc->pcie_link_status = 0;
  596 
  597         RT_WRITE32(sc, RT305X_PCI_PCIE0_BAR0SETUP, 0x7FFF0001);
  598         RT_WRITE32(sc, RT305X_PCI_PCIE0_BAR1SETUP, 0x00000000);
  599         RT_WRITE32(sc, RT305X_PCI_PCIE0_IMBASEBAR0, 0x00000000);
  600         RT_WRITE32(sc, RT305X_PCI_PCIE0_CLASS, 0x06040001);
  601 
  602         tmp = rt305x_pci_read_config(dev, 0, 0, 0, 4, 4);
  603         rt305x_pci_write_config(dev, 0, 0, 0, 4, tmp | 0x7, 4);
  604         tmp = rt305x_pci_read_config(dev, 0, 0, 0, 0x70c, 4);
  605         tmp &= ~(0xff)<<8;
  606         tmp |= 0x50<<8;
  607         rt305x_pci_write_config(dev, 0, 0, 0, 0x70c, tmp, 4);
  608         tmp = rt305x_pci_read_config(dev, 0, 0, 0, 0x70c, 4);
  609 
  610         rt305x_pci_write_config(dev, 0, 0, 0, PCIR_BAR(0), 0, 4);
  611 }
  612 
  613 static inline uint32_t
  614 pcib_bit_get(uint32_t *map, uint32_t bit)
  615 {
  616         uint32_t n = bit / BITS_PER_UINT32;
  617 
  618         bit = bit % BITS_PER_UINT32;
  619         return (map[n] & (1 << bit));
  620 }
  621 
  622 static inline void
  623 pcib_bit_set(uint32_t *map, uint32_t bit)
  624 {
  625         uint32_t n = bit / BITS_PER_UINT32;
  626 
  627         bit = bit % BITS_PER_UINT32;
  628         map[n] |= (1 << bit);
  629 }
  630 
  631 static inline uint32_t
  632 pcib_map_check(uint32_t *map, uint32_t start, uint32_t bits)
  633 {
  634         uint32_t i;
  635 
  636         for (i = start; i < start + bits; i++)
  637                 if (pcib_bit_get(map, i))
  638                         return (0);
  639 
  640         return (1);
  641 }
  642 
  643 static inline void
  644 pcib_map_set(uint32_t *map, uint32_t start, uint32_t bits)
  645 {
  646         uint32_t i;
  647 
  648         for (i = start; i < start + bits; i++)
  649                 pcib_bit_set(map, i);
  650 }
  651 
  652 static bus_addr_t
  653 pcib_alloc(device_t dev, uint32_t smask)
  654 {
  655         struct rt305x_pci_softc *sc = device_get_softc(dev);
  656         uint32_t bits, bits_limit, i, *map, min_alloc, size;
  657         bus_addr_t addr = 0;
  658         bus_addr_t base;
  659 
  660         if (smask & 1) {
  661                 base = sc->sc_io_base;
  662                 min_alloc = PCI_MIN_IO_ALLOC;
  663                 bits_limit = sc->sc_io_size / min_alloc;
  664                 map = sc->sc_io_map;
  665                 smask &= ~0x3;
  666         } else {
  667                 base = sc->sc_mem_base;
  668                 min_alloc = PCI_MIN_MEM_ALLOC;
  669                 bits_limit = sc->sc_mem_size / min_alloc;
  670                 map = sc->sc_mem_map;
  671                 smask &= ~0xF;
  672         }
  673 
  674         size = ~smask + 1;
  675         bits = size / min_alloc;
  676 
  677         for (i = 0; i + bits <= bits_limit; i+= bits)
  678                 if (pcib_map_check(map, i, bits)) {
  679                         pcib_map_set(map, i, bits);
  680                         addr = base + (i * min_alloc);
  681                         return (addr);
  682                 }
  683 
  684         return (addr);
  685 }
  686 
  687 static int
  688 rt305x_pcib_init_bar(device_t dev, int bus, int slot, int func, int barno)
  689 {
  690         uint32_t addr, bar;
  691         int reg, width;
  692 
  693         reg = PCIR_BAR(barno);
  694 
  695         rt305x_pci_write_config(dev, bus, slot, func, reg, ~0, 4);
  696         bar = rt305x_pci_read_config(dev, bus, slot, func, reg, 4);
  697         if (bar == 0)
  698                 return (1);
  699 
  700         /* Calculate BAR size: 64 or 32 bit (in 32-bit units) */
  701         width = ((bar & 7) == 4) ? 2 : 1;
  702 
  703         addr = pcib_alloc(dev, bar);
  704         if (!addr)
  705                 return (-1);
  706 
  707         if (bootverbose)
  708                 printf("PCI %u:%u:%u: reg %x: smask=%08x: addr=%08x\n",
  709                     bus, slot, func, reg, bar, addr);
  710 
  711         rt305x_pci_write_config(dev, bus, slot, func, reg, addr, 4);
  712         if (width == 2)
  713                 rt305x_pci_write_config(dev, bus, slot, func, reg + 4, 0, 4);
  714 
  715         return (width);
  716 }
  717 
  718 static int
  719 rt305x_pcib_init_all_bars(device_t dev, int bus, int slot, int func,
  720         int hdrtype)
  721 {
  722         int maxbar, bar, i;
  723 
  724         maxbar = (hdrtype & PCIM_HDRTYPE) ? 0 : 6;
  725         bar = 0;
  726 
  727         while (bar < maxbar) {
  728                 i = rt305x_pcib_init_bar(dev, bus, slot, func, bar);
  729                 bar += i;
  730                 if (i < 0) {
  731                         device_printf(dev, "PCI IO/Memory space exhausted\n");
  732                         return (ENOMEM);
  733                 }
  734         }
  735 
  736         return (0);
  737 }
  738 
  739 static inline int
  740 rt305x_pci_slot_has_link(device_t dev, int slot)
  741 {
  742         struct rt305x_pci_softc *sc = device_get_softc(dev);
  743 
  744         return !!(sc->pcie_link_status & (1<<slot));
  745 }
  746 
  747 static int cur_secbus = 0;
  748 
  749 static void
  750 rt305x_pcib_init_bridge(device_t dev, int bus, int slot, int func)
  751 {
  752         struct rt305x_pci_softc *sc = device_get_softc(dev);
  753         bus_addr_t io_base, mem_base;
  754         uint32_t io_limit, mem_limit;
  755         int secbus;
  756 
  757         if (bus == 0 && !rt305x_pci_slot_has_link(dev, slot)) {
  758                 device_printf(dev, "Skip bus %d due to no link\n",++cur_secbus);
  759                 return;
  760         }
  761 
  762         io_base = sc->sc_io_base;
  763         io_limit = io_base + sc->sc_io_size - 1;
  764         mem_base = sc->sc_mem_base;
  765         mem_limit = mem_base + sc->sc_mem_size - 1;
  766 
  767         rt305x_pci_write_config(dev, bus, slot, func, PCIR_IOBASEL_1,
  768                 io_base >> 8, 1);
  769         rt305x_pci_write_config(dev, bus, slot, func, PCIR_IOBASEH_1,
  770                 io_base >> 16, 2);
  771         rt305x_pci_write_config(dev, bus, slot, func, PCIR_IOLIMITL_1,
  772                 io_limit >> 8, 1);
  773         rt305x_pci_write_config(dev, bus, slot, func, PCIR_IOLIMITH_1,
  774                 io_limit >> 16, 2);
  775 
  776         rt305x_pci_write_config(dev, bus, slot, func, PCIR_MEMBASE_1,
  777                 mem_base >> 16, 2);
  778         rt305x_pci_write_config(dev, bus, slot, func, PCIR_MEMLIMIT_1,
  779                 mem_limit >> 16, 2);
  780 
  781         rt305x_pci_write_config(dev, bus, slot, func, PCIR_PMBASEL_1,
  782                 0x10, 2);
  783         rt305x_pci_write_config(dev, bus, slot, func, PCIR_PMBASEH_1,
  784                 0x0, 4);
  785         rt305x_pci_write_config(dev, bus, slot, func, PCIR_PMLIMITL_1,
  786                 0xF, 2);
  787         rt305x_pci_write_config(dev, bus, slot, func, PCIR_PMLIMITH_1,
  788                 0x0, 4);
  789 
  790         secbus = rt305x_pci_read_config(dev, bus, slot, func, PCIR_SECBUS_1, 1);
  791 
  792         if (secbus == 0) {
  793                 rt305x_pci_write_config(dev, bus, slot, func, PCIR_SECBUS_1,
  794                         ++cur_secbus, 1);
  795                 rt305x_pci_write_config(dev, bus, slot, func, PCIR_SUBBUS_1,
  796                         cur_secbus, 1);
  797                 secbus = cur_secbus;
  798         }
  799 
  800         rt305x_pcib_init(dev, secbus, PCI_SLOTMAX);
  801 }
  802 
  803 static int
  804 rt305x_pcib_init(device_t dev, int bus, int maxslot)
  805 {
  806         int slot, func, maxfunc, error;
  807         uint8_t hdrtype, command, class, subclass;
  808 
  809         for (slot = 0; slot <= maxslot; slot++) {
  810                 maxfunc = 0;
  811                 for (func = 0; func <= maxfunc; func++) {
  812                         hdrtype = rt305x_pci_read_config(dev, bus, slot, func,
  813                                 PCIR_HDRTYPE, 1);
  814 
  815                         if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
  816                                 continue;
  817 
  818                         if (func == 0 && (hdrtype & PCIM_MFDEV))
  819                                 maxfunc = PCI_FUNCMAX;
  820 
  821                         command = rt305x_pci_read_config(dev, bus, slot, func,
  822                                 PCIR_COMMAND, 1);
  823                         command &= ~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN);
  824                         rt305x_pci_write_config(dev, bus, slot, func,
  825                                 PCIR_COMMAND, command, 1);
  826 
  827                         error = rt305x_pcib_init_all_bars(dev, bus, slot, func,
  828                                 hdrtype);
  829 
  830                         if (error)
  831                                 return (error);
  832 
  833                         command |= PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN |
  834                                 PCIM_CMD_PORTEN;
  835                         rt305x_pci_write_config(dev, bus, slot, func,
  836                                 PCIR_COMMAND, command, 1);
  837 
  838                         rt305x_pci_write_config(dev, bus, slot, func,
  839                                 PCIR_CACHELNSZ, 16, 1);
  840 
  841                         class = rt305x_pci_read_config(dev, bus, slot, func,
  842                                 PCIR_CLASS, 1);
  843                         subclass = rt305x_pci_read_config(dev, bus, slot, func,
  844                                 PCIR_SUBCLASS, 1);
  845 
  846                         if (class != PCIC_BRIDGE || subclass != PCIS_BRIDGE_PCI)
  847                                 continue;
  848 
  849                         rt305x_pcib_init_bridge(dev, bus, slot, func);
  850                 }
  851         }
  852 
  853         return (0);
  854 }
  855 
  856 #define BUSY            0x80000000
  857 #define WAITRETRY_MAX   10
  858 #define WRITE_MODE      (1<<23)
  859 #define DATA_SHIFT      0
  860 #define ADDR_SHIFT      8
  861 
  862 static int
  863 rt305x_wait_pci_phy_busy(struct rt305x_pci_softc *sc)
  864 {
  865         uint32_t reg_value = 0x0, retry = 0;
  866 
  867         while (1) {
  868                 reg_value = RT_READ32(sc, RT305X_PCI_PHY0_CFG);
  869                 if (reg_value & BUSY)
  870                         DELAY(100000);
  871                 else
  872                         break;
  873                 if (retry++ > WAITRETRY_MAX) {
  874                         printf("PHY retry failed\n");
  875                         return (-1);
  876                 }
  877         }
  878         return (0);
  879 }
  880 
  881 static uint32_t
  882 rt305x_pci_phy(struct rt305x_pci_softc *sc, char rwmode, uint32_t addr,
  883                 uint32_t val)
  884 {
  885         uint32_t reg_value = 0x0;
  886 
  887         rt305x_wait_pci_phy_busy(sc);
  888         if (rwmode == 'w') {
  889                 reg_value |= WRITE_MODE;
  890                 reg_value |= (val) << DATA_SHIFT;
  891         }
  892         reg_value |= (addr) << ADDR_SHIFT;
  893 
  894         RT_WRITE32(sc, RT305X_PCI_PHY0_CFG, reg_value);
  895         DELAY(1000);
  896 
  897         rt305x_wait_pci_phy_busy(sc);
  898 
  899         if (rwmode == 'r') {
  900                 reg_value = RT_READ32(sc, RT305X_PCI_PHY0_CFG);
  901                 return (reg_value);
  902         }
  903 
  904         return (0);
  905 }
  906 
  907 static void
  908 rt305x_pci_phy_init(device_t dev)
  909 {
  910         struct rt305x_pci_softc *sc = device_get_softc(dev);
  911         uint32_t tmp;
  912 
  913         rt305x_pci_phy(sc, 'w', 0x00, 0x80);
  914         rt305x_pci_phy(sc, 'w', 0x01, 0x04);
  915         rt305x_pci_phy(sc, 'w', 0x68, 0x84);
  916 
  917         rt305x_sysctl_set(SYSCTL_RSTCTRL,
  918                 rt305x_sysctl_get(SYSCTL_RSTCTRL) | (1<<26));
  919         rt305x_sysctl_set(SYSCTL_CLKCFG1,
  920                 rt305x_sysctl_get(SYSCTL_CLKCFG1) & ~(1<<26));
  921 
  922         tmp = rt305x_sysctl_get(SYSCTL_PPLL_CFG1);
  923         tmp &= ~(1<<19);
  924         rt305x_sysctl_set(SYSCTL_PPLL_CFG1, tmp);
  925         tmp |= (1<<31);
  926         rt305x_sysctl_set(SYSCTL_PPLL_CFG1, tmp);
  927 }
  928 
  929 static int
  930 rt305x_pci_intr(void *arg)
  931 {
  932         struct rt305x_pci_softc *sc = arg;
  933         struct intr_event *event;
  934         uint32_t reg, irq, irqidx;
  935 
  936         reg = RT_READ32(sc, RT305X_PCI_PCIINT);
  937 
  938         for (irqidx = 0; irqidx < RT305X_PCI_NIRQS; irqidx++) {
  939                 irq = rt305x_idx_to_irq(irqidx);
  940                 if (reg & (1<<irq)) {
  941                         event = sc->sc_eventstab[irqidx];
  942                         if (!event || TAILQ_EMPTY(&event->ie_handlers)) {
  943                                 if (irq != 0)
  944                                         printf("Stray PCI IRQ %d\n", irq);
  945                                 continue;
  946                         }
  947 
  948                         intr_event_handle(event, NULL);
  949                         mips_intrcnt_inc(sc->sc_intr_counter[irqidx]);
  950                 }
  951         }
  952 
  953         return (FILTER_HANDLED);
  954 }

Cache object: 5f52ab82fc18d3e69067baa27df99bea


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.