[BACK]Return to i80321_pci.c CVS log [TXT][DIR] Up to [local] / sys / arch / arm / xscale

Annotation of sys/arch/arm/xscale/i80321_pci.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: i80321_pci.c,v 1.3 2007/08/06 08:28:09 tom Exp $      */
                      2: /*     $NetBSD: i80321_pci.c,v 1.7 2005/12/15 01:44:00 briggs Exp $    */
                      3:
                      4: /*
                      5:  * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *     This product includes software developed for the NetBSD Project by
                     21:  *     Wasabi Systems, Inc.
                     22:  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
                     23:  *    or promote products derived from this software without specific prior
                     24:  *    written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
                     27:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
                     30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     36:  * POSSIBILITY OF SUCH DAMAGE.
                     37:  */
                     38:
                     39: /*
                     40:  * PCI configuration support for i80321 I/O Processor chip.
                     41:  */
                     42:
                     43: #include <sys/param.h>
                     44: #include <sys/systm.h>
                     45: #include <sys/device.h>
                     46: #include <sys/extent.h>
                     47: #include <sys/malloc.h>
                     48:
                     49: #include <uvm/uvm_extern.h>
                     50:
                     51: #include <machine/bus.h>
                     52:
                     53: #include <arm/xscale/i80321reg.h>
                     54: #include <arm/xscale/i80321var.h>
                     55:
                     56: #include <dev/pci/ppbreg.h>
                     57:
                     58: #include "pci.h"
                     59:
                     60: void           i80321_pci_attach_hook(struct device *, struct device *,
                     61:                    struct pcibus_attach_args *);
                     62: int            i80321_pci_bus_maxdevs(void *, int);
                     63: pcitag_t       i80321_pci_make_tag(void *, int, int, int);
                     64: void           i80321_pci_decompose_tag(void *, pcitag_t, int *, int *,
                     65:                    int *);
                     66: pcireg_t       i80321_pci_conf_read(void *, pcitag_t, int);
                     67: void           i80321_pci_conf_write(void *, pcitag_t, int, pcireg_t);
                     68:
                     69: #define        PCI_CONF_LOCK(s)        (s) = disable_interrupts(I32_bit)
                     70: #define        PCI_CONF_UNLOCK(s)      restore_interrupts((s))
                     71:
                     72: void
                     73: i80321_pci_init(pci_chipset_tag_t pc, void *cookie)
                     74: {
                     75: #if NPCI > 0 && defined(PCI_NETBSD_CONFIGURE)
                     76:        struct i80321_softc *sc = cookie;
                     77:        struct extent *ioext, *memext;
                     78:        uint32_t busno;
                     79: #endif
                     80:
                     81:        pc->pc_conf_v = cookie;
                     82:        pc->pc_attach_hook = i80321_pci_attach_hook;
                     83:        pc->pc_bus_maxdevs = i80321_pci_bus_maxdevs;
                     84:        pc->pc_make_tag = i80321_pci_make_tag;
                     85:        pc->pc_decompose_tag = i80321_pci_decompose_tag;
                     86:        pc->pc_conf_read = i80321_pci_conf_read;
                     87:        pc->pc_conf_write = i80321_pci_conf_write;
                     88:
                     89: #if NPCI > 0 && defined(PCI_NETBSD_CONFIGURE)
                     90:        /*
                     91:         * Configure the PCI bus.
                     92:         *
                     93:         * XXX We need to revisit this.  We only configure the Secondary
                     94:         * bus (and its children).  The bus configure code needs changes
                     95:         * to support how the busses are arranged on this chip.  We also
                     96:         * need to only configure devices in the private device space on
                     97:         * the Secondary bus.
                     98:         */
                     99:
                    100:        busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
                    101:        busno = PCIXSR_BUSNO(busno);
                    102:        if (busno == 0xff)
                    103:                busno = 0;
                    104:
                    105:        ioext  = extent_create("pciio",
                    106:            sc->sc_ioout_xlate + sc->sc_ioout_xlate_offset,
                    107:            sc->sc_ioout_xlate + VERDE_OUT_XLATE_IO_WIN_SIZE - 1,
                    108:            M_DEVBUF, NULL, 0, EX_NOWAIT);
                    109:        memext = extent_create("pcimem", sc->sc_owin[0].owin_xlate_lo,
                    110:            sc->sc_owin[0].owin_xlate_lo + VERDE_OUT_XLATE_MEM_WIN_SIZE - 1,
                    111:            M_DEVBUF, NULL, 0, EX_NOWAIT);
                    112:
                    113:        aprint_normal("%s: configuring PCI bus\n", sc->sc_dev.dv_xname);
                    114:        pci_configure_bus(pc, ioext, memext, NULL, busno, arm_dcache_align);
                    115:
                    116:        extent_destroy(ioext);
                    117:        extent_destroy(memext);
                    118: #endif
                    119: }
                    120:
                    121: void
                    122: i80321_pci_attach_hook(struct device *parent, struct device *self,
                    123:     struct pcibus_attach_args *pba)
                    124: {
                    125:
                    126:        /* Nothing to do. */
                    127: }
                    128:
                    129: int
                    130: i80321_pci_bus_maxdevs(void *v, int busno)
                    131: {
                    132:
                    133:        return (32);
                    134: }
                    135:
                    136: pcitag_t
                    137: i80321_pci_make_tag(void *v, int b, int d, int f)
                    138: {
                    139:
                    140:        return ((b << 16) | (d << 11) | (f << 8));
                    141: }
                    142:
                    143: void
                    144: i80321_pci_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp)
                    145: {
                    146:
                    147:        if (bp != NULL)
                    148:                *bp = (tag >> 16) & 0xff;
                    149:        if (dp != NULL)
                    150:                *dp = (tag >> 11) & 0x1f;
                    151:        if (fp != NULL)
                    152:                *fp = (tag >> 8) & 0x7;
                    153: }
                    154:
                    155: struct pciconf_state {
                    156:        uint32_t ps_addr_val;
                    157:
                    158:        int ps_b, ps_d, ps_f;
                    159: };
                    160:
                    161: static int
                    162: i80321_pci_conf_setup(struct i80321_softc *sc, pcitag_t tag, int offset,
                    163:     struct pciconf_state *ps)
                    164: {
                    165:        uint32_t busno;
                    166:
                    167:        i80321_pci_decompose_tag(sc, tag, &ps->ps_b, &ps->ps_d, &ps->ps_f);
                    168:
                    169:        busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
                    170:        busno = PCIXSR_BUSNO(busno);
                    171:        if (busno == 0xff)
                    172:                busno = 0;
                    173:
                    174:        /*
                    175:         * If the bus # is the same as our own, then use Type 0 cycles,
                    176:         * else use Type 1.
                    177:         *
                    178:         * XXX We should filter out all non-private devices here!
                    179:         * XXX How does private space interact with PCI-PCI bridges?
                    180:         */
                    181:        if (ps->ps_b == busno) {
                    182:                if (ps->ps_d > (31 - 16))
                    183:                        return (1);
                    184:                /*
                    185:                 * NOTE: PCI-X requires that devices update their
                    186:                 * PCIXSR on every config write with the device number
                    187:                 * specified in AD[15:11].  If we don't set this field,
                    188:                 * each device could end of thinking it is at device 0,
                    189:                 * which can cause a number of problems.  Doing this
                    190:                 * unconditionally should be OK when only PCI devices
                    191:                 * are present.
                    192:                 */
                    193:                ps->ps_addr_val = (1U << (ps->ps_d + 16)) |
                    194:                    (ps->ps_d << 11) | (ps->ps_f << 8) | offset;
                    195:        } else {
                    196:                /* The tag is already in the correct format. */
                    197:                ps->ps_addr_val = tag | offset | 1;
                    198:        }
                    199:
                    200:        return (0);
                    201: }
                    202:
                    203: pcireg_t
                    204: i80321_pci_conf_read(void *v, pcitag_t tag, int offset)
                    205: {
                    206:        struct i80321_softc *sc = v;
                    207:        struct pciconf_state ps;
                    208:        vaddr_t va;
                    209:        uint32_t isr;
                    210:        pcireg_t rv;
                    211:        u_int s;
                    212:
                    213:        if (i80321_pci_conf_setup(sc, tag, offset, &ps))
                    214:                return ((pcireg_t) -1);
                    215:
                    216:        PCI_CONF_LOCK(s);
                    217:
                    218:        bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OCCAR,
                    219:            ps.ps_addr_val);
                    220:
                    221:        va = (vaddr_t) bus_space_vaddr(sc->sc_st, sc->sc_atu_sh);
                    222:        if (badaddr_read((void *) (va + ATU_OCCDR), sizeof(rv), &rv)) {
                    223:                isr = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUISR);
                    224:                bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUISR,
                    225:                    isr & (ATUISR_P_SERR_DET|ATUISR_PMA|ATUISR_PTAM|
                    226:                           ATUISR_PTAT|ATUISR_PMPE));
                    227: #if 0
                    228:                printf("conf_read: %d/%d/%d bad address\n",
                    229:                    ps.ps_b, ps.ps_d, ps.ps_f);
                    230: #endif
                    231:                rv = (pcireg_t) -1;
                    232:        }
                    233:
                    234:        PCI_CONF_UNLOCK(s);
                    235:
                    236: #if 0
                    237:        if (rv != 0xffffffff)
                    238:                printf("conf read %x %x %x %x: %x\n",
                    239:                    ps.ps_b, ps.ps_d, ps.ps_f, offset, rv);
                    240: #endif
                    241:
                    242:        return (rv);
                    243: }
                    244:
                    245: void
                    246: i80321_pci_conf_write(void *v, pcitag_t tag, int offset, pcireg_t val)
                    247: {
                    248:        struct i80321_softc *sc = v;
                    249:        struct pciconf_state ps;
                    250:        u_int s;
                    251:
                    252:        if (i80321_pci_conf_setup(sc, tag, offset, &ps))
                    253:                return;
                    254:
                    255:        PCI_CONF_LOCK(s);
                    256:
                    257:        bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OCCAR,
                    258:            ps.ps_addr_val);
                    259:        bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OCCDR, val);
                    260:
                    261:        PCI_CONF_UNLOCK(s);
                    262: }

CVSweb