Home | History | Annotate | Line # | Download | only in marvell
pci_machdep.c revision 1.10.4.1
      1  1.10.4.1    bouyer /*	$NetBSD: pci_machdep.c,v 1.10.4.1 2017/04/21 16:53:23 bouyer Exp $	*/
      2       1.1  kiyohara /*
      3       1.1  kiyohara  * Copyright (c) 2008 KIYOHARA Takashi
      4       1.1  kiyohara  * All rights reserved.
      5       1.1  kiyohara  *
      6       1.1  kiyohara  * Redistribution and use in source and binary forms, with or without
      7       1.1  kiyohara  * modification, are permitted provided that the following conditions
      8       1.1  kiyohara  * are met:
      9       1.1  kiyohara  * 1. Redistributions of source code must retain the above copyright
     10       1.1  kiyohara  *    notice, this list of conditions and the following disclaimer.
     11       1.1  kiyohara  * 2. Redistributions in binary form must reproduce the above copyright
     12       1.1  kiyohara  *    notice, this list of conditions and the following disclaimer in the
     13       1.1  kiyohara  *    documentation and/or other materials provided with the distribution.
     14       1.1  kiyohara  *
     15       1.1  kiyohara  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16       1.1  kiyohara  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17       1.1  kiyohara  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18       1.1  kiyohara  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     19       1.1  kiyohara  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     20       1.1  kiyohara  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21       1.1  kiyohara  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22       1.1  kiyohara  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     23       1.1  kiyohara  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     24       1.1  kiyohara  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25       1.1  kiyohara  * POSSIBILITY OF SUCH DAMAGE.
     26       1.1  kiyohara  */
     27       1.1  kiyohara 
     28       1.1  kiyohara #include <sys/cdefs.h>
     29  1.10.4.1    bouyer __KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.10.4.1 2017/04/21 16:53:23 bouyer Exp $");
     30       1.1  kiyohara 
     31       1.1  kiyohara #include "opt_mvsoc.h"
     32       1.1  kiyohara #include "gtpci.h"
     33       1.1  kiyohara #include "mvpex.h"
     34       1.1  kiyohara #include "pci.h"
     35       1.1  kiyohara 
     36       1.1  kiyohara #include <sys/param.h>
     37       1.1  kiyohara #include <sys/device.h>
     38       1.1  kiyohara #include <sys/extent.h>
     39       1.1  kiyohara 
     40       1.1  kiyohara #include <dev/pci/pcivar.h>
     41       1.1  kiyohara #include <dev/pci/pciconf.h>
     42       1.1  kiyohara 
     43       1.1  kiyohara #include <arm/marvell/mvsocreg.h>
     44       1.1  kiyohara #include <arm/marvell/mvsocvar.h>
     45       1.1  kiyohara #include <arm/marvell/mvsocgppvar.h>
     46       1.1  kiyohara #if NGTPCI > 0
     47       1.1  kiyohara #include <dev/marvell/gtpcireg.h>
     48       1.1  kiyohara #include <dev/marvell/gtpcivar.h>
     49       1.1  kiyohara #endif
     50       1.1  kiyohara #if NMVPEX > 0
     51       1.1  kiyohara #include <dev/marvell/mvpexreg.h>
     52       1.1  kiyohara #include <dev/marvell/mvpexvar.h>
     53       1.1  kiyohara #endif
     54       1.1  kiyohara 
     55       1.1  kiyohara #include <machine/pci_machdep.h>
     56       1.1  kiyohara 
     57       1.1  kiyohara #if defined(ORION)
     58       1.1  kiyohara #include <arm/marvell/orionreg.h>
     59       1.1  kiyohara #endif
     60       1.1  kiyohara #if defined(KIRKWOOD)
     61       1.1  kiyohara #include <arm/marvell/kirkwoodreg.h>
     62       1.1  kiyohara #endif
     63       1.1  kiyohara #include <dev/marvell/marvellreg.h>
     64       1.1  kiyohara 
     65       1.1  kiyohara 
     66       1.1  kiyohara #if NGTPCI > 0
     67       1.1  kiyohara #if NGTPCI_MBUS > 0
     68       1.1  kiyohara static pcireg_t gtpci_mbus_conf_read(void *, pcitag_t, int);
     69       1.1  kiyohara static void gtpci_mbus_conf_write(void *, pcitag_t, int, pcireg_t);
     70       1.1  kiyohara #endif
     71       1.2    dyoung static int gtpci_gpp_intr_map(const struct pci_attach_args *,
     72       1.2    dyoung     pci_intr_handle_t *);
     73       1.8  christos static const char *gtpci_gpp_intr_string(void *, pci_intr_handle_t,
     74       1.8  christos     char *, size_t);
     75       1.1  kiyohara static const struct evcnt *gtpci_gpp_intr_evcnt(void *, pci_intr_handle_t);
     76       1.1  kiyohara static void *gtpci_gpp_intr_establish(void *, pci_intr_handle_t, int, int (*)(void *), void *);
     77       1.1  kiyohara static void gtpci_gpp_intr_disestablish(void *, void *);
     78       1.1  kiyohara 
     79       1.1  kiyohara struct arm32_pci_chipset arm32_gtpci_chipset = {
     80       1.1  kiyohara 	NULL,	/* conf_v */
     81       1.1  kiyohara 	gtpci_attach_hook,
     82       1.1  kiyohara 	gtpci_bus_maxdevs,
     83       1.1  kiyohara 	gtpci_make_tag,
     84       1.1  kiyohara 	gtpci_decompose_tag,
     85       1.1  kiyohara #if NGTPCI_MBUS > 0
     86       1.1  kiyohara 	gtpci_mbus_conf_read,		/* XXXX: always this functions */
     87       1.1  kiyohara 	gtpci_mbus_conf_write,
     88       1.1  kiyohara #else
     89       1.1  kiyohara 	gtpci_conf_read,
     90       1.1  kiyohara 	gtpci_conf_write,
     91       1.1  kiyohara #endif
     92       1.1  kiyohara 	NULL,	/* intr_v */
     93       1.1  kiyohara 	gtpci_gpp_intr_map,
     94       1.1  kiyohara 	gtpci_gpp_intr_string,
     95       1.1  kiyohara 	gtpci_gpp_intr_evcnt,
     96  1.10.4.1    bouyer 	NULL,	/* intr_setattr */
     97       1.1  kiyohara 	gtpci_gpp_intr_establish,
     98       1.1  kiyohara 	gtpci_gpp_intr_disestablish,
     99       1.1  kiyohara #ifdef __HAVE_PCI_CONF_HOOK
    100       1.1  kiyohara 	gtpci_conf_hook,
    101       1.1  kiyohara #endif
    102       1.3      matt 	gtpci_conf_interrupt,
    103       1.1  kiyohara };
    104       1.1  kiyohara #endif
    105       1.1  kiyohara 
    106       1.1  kiyohara #if NMVPEX > 0
    107       1.1  kiyohara #if NMVPEX_MBUS > 0
    108       1.1  kiyohara static pcireg_t mvpex_mbus_conf_read(void *, pcitag_t, int);
    109       1.1  kiyohara #endif
    110       1.1  kiyohara 
    111       1.1  kiyohara struct arm32_pci_chipset arm32_mvpex0_chipset = {
    112       1.1  kiyohara 	NULL,	/* conf_v */
    113       1.1  kiyohara 	mvpex_attach_hook,
    114       1.1  kiyohara 	mvpex_bus_maxdevs,
    115       1.1  kiyohara 	mvpex_make_tag,
    116       1.1  kiyohara 	mvpex_decompose_tag,
    117       1.1  kiyohara #if NMVPEX_MBUS > 0
    118       1.1  kiyohara 	mvpex_mbus_conf_read,		/* XXXX: always this functions */
    119       1.1  kiyohara #else
    120       1.1  kiyohara 	mvpex_conf_read,
    121       1.1  kiyohara #endif
    122       1.1  kiyohara 	mvpex_conf_write,
    123       1.1  kiyohara 	NULL,	/* intr_v */
    124       1.1  kiyohara 	mvpex_intr_map,
    125       1.1  kiyohara 	mvpex_intr_string,
    126       1.1  kiyohara 	mvpex_intr_evcnt,
    127  1.10.4.1    bouyer 	NULL,	/* intr_setattr */
    128       1.1  kiyohara 	mvpex_intr_establish,
    129       1.1  kiyohara 	mvpex_intr_disestablish,
    130       1.1  kiyohara #ifdef __HAVE_PCI_CONF_HOOK
    131       1.1  kiyohara 	mvpex_conf_hook,
    132       1.1  kiyohara #endif
    133       1.5   rkujawa 	mvpex_conf_interrupt,
    134       1.1  kiyohara };
    135       1.1  kiyohara struct arm32_pci_chipset arm32_mvpex1_chipset = {
    136       1.1  kiyohara 	NULL,	/* conf_v */
    137       1.1  kiyohara 	mvpex_attach_hook,
    138       1.1  kiyohara 	mvpex_bus_maxdevs,
    139       1.1  kiyohara 	mvpex_make_tag,
    140       1.1  kiyohara 	mvpex_decompose_tag,
    141       1.1  kiyohara #if NMVPEX_MBUS > 0
    142       1.1  kiyohara 	mvpex_mbus_conf_read,		/* XXXX: always this functions */
    143       1.1  kiyohara #else
    144       1.1  kiyohara 	mvpex_conf_read,
    145       1.1  kiyohara #endif
    146       1.1  kiyohara 	mvpex_conf_write,
    147       1.1  kiyohara 	NULL,	/* intr_v */
    148       1.1  kiyohara 	mvpex_intr_map,
    149       1.1  kiyohara 	mvpex_intr_string,
    150       1.1  kiyohara 	mvpex_intr_evcnt,
    151  1.10.4.1    bouyer 	NULL,	/* intr_setattr */
    152       1.1  kiyohara 	mvpex_intr_establish,
    153       1.1  kiyohara 	mvpex_intr_disestablish,
    154       1.1  kiyohara #ifdef __HAVE_PCI_CONF_HOOK
    155       1.1  kiyohara 	mvpex_conf_hook,
    156       1.1  kiyohara #endif
    157       1.3      matt 	mvpex_conf_interrupt,
    158       1.1  kiyohara };
    159       1.5   rkujawa struct arm32_pci_chipset arm32_mvpex2_chipset = {
    160       1.5   rkujawa 	NULL,	/* conf_v */
    161       1.5   rkujawa 	mvpex_attach_hook,
    162       1.5   rkujawa 	mvpex_bus_maxdevs,
    163       1.5   rkujawa 	mvpex_make_tag,
    164       1.5   rkujawa 	mvpex_decompose_tag,
    165       1.5   rkujawa #if NMVPEX_MBUS > 0
    166       1.5   rkujawa 	mvpex_mbus_conf_read,		/* XXXX: always this functions */
    167       1.5   rkujawa #else
    168       1.5   rkujawa 	mvpex_conf_read,
    169       1.1  kiyohara #endif
    170       1.5   rkujawa 	mvpex_conf_write,
    171       1.5   rkujawa 	NULL,	/* intr_v */
    172       1.5   rkujawa 	mvpex_intr_map,
    173       1.5   rkujawa 	mvpex_intr_string,
    174       1.5   rkujawa 	mvpex_intr_evcnt,
    175  1.10.4.1    bouyer 	NULL,	/* intr_setattr */
    176       1.5   rkujawa 	mvpex_intr_establish,
    177       1.5   rkujawa 	mvpex_intr_disestablish,
    178       1.5   rkujawa #ifdef __HAVE_PCI_CONF_HOOK
    179       1.5   rkujawa 	mvpex_conf_hook,
    180       1.5   rkujawa #endif
    181       1.5   rkujawa 	mvpex_conf_interrupt,
    182       1.5   rkujawa };
    183       1.5   rkujawa struct arm32_pci_chipset arm32_mvpex3_chipset = {
    184       1.5   rkujawa 	NULL,	/* conf_v */
    185       1.5   rkujawa 	mvpex_attach_hook,
    186       1.5   rkujawa 	mvpex_bus_maxdevs,
    187       1.5   rkujawa 	mvpex_make_tag,
    188       1.5   rkujawa 	mvpex_decompose_tag,
    189       1.5   rkujawa #if NMVPEX_MBUS > 0
    190       1.5   rkujawa 	mvpex_mbus_conf_read,		/* XXXX: always this functions */
    191       1.5   rkujawa #else
    192       1.5   rkujawa 	mvpex_conf_read,
    193       1.5   rkujawa #endif
    194       1.5   rkujawa 	mvpex_conf_write,
    195       1.5   rkujawa 	NULL,	/* intr_v */
    196       1.5   rkujawa 	mvpex_intr_map,
    197       1.5   rkujawa 	mvpex_intr_string,
    198       1.5   rkujawa 	mvpex_intr_evcnt,
    199  1.10.4.1    bouyer 	NULL,	/* intr_setattr */
    200       1.5   rkujawa 	mvpex_intr_establish,
    201       1.5   rkujawa 	mvpex_intr_disestablish,
    202       1.5   rkujawa #ifdef __HAVE_PCI_CONF_HOOK
    203       1.5   rkujawa 	mvpex_conf_hook,
    204       1.5   rkujawa #endif
    205       1.5   rkujawa 	mvpex_conf_interrupt,
    206       1.5   rkujawa };
    207       1.5   rkujawa struct arm32_pci_chipset arm32_mvpex4_chipset = {
    208       1.5   rkujawa 	NULL,	/* conf_v */
    209       1.5   rkujawa 	mvpex_attach_hook,
    210       1.5   rkujawa 	mvpex_bus_maxdevs,
    211       1.5   rkujawa 	mvpex_make_tag,
    212       1.5   rkujawa 	mvpex_decompose_tag,
    213       1.5   rkujawa #if NMVPEX_MBUS > 0
    214       1.5   rkujawa 	mvpex_mbus_conf_read,		/* XXXX: always this functions */
    215       1.5   rkujawa #else
    216       1.5   rkujawa 	mvpex_conf_read,
    217       1.5   rkujawa #endif
    218       1.5   rkujawa 	mvpex_conf_write,
    219       1.5   rkujawa 	NULL,	/* intr_v */
    220       1.5   rkujawa 	mvpex_intr_map,
    221       1.5   rkujawa 	mvpex_intr_string,
    222       1.5   rkujawa 	mvpex_intr_evcnt,
    223  1.10.4.1    bouyer 	NULL,	/* intr_setattr */
    224       1.5   rkujawa 	mvpex_intr_establish,
    225       1.5   rkujawa 	mvpex_intr_disestablish,
    226       1.5   rkujawa #ifdef __HAVE_PCI_CONF_HOOK
    227       1.5   rkujawa 	mvpex_conf_hook,
    228       1.5   rkujawa #endif
    229       1.5   rkujawa 	mvpex_conf_interrupt,
    230       1.5   rkujawa };
    231       1.5   rkujawa struct arm32_pci_chipset arm32_mvpex5_chipset = {
    232       1.5   rkujawa 	NULL,	/* conf_v */
    233       1.5   rkujawa 	mvpex_attach_hook,
    234       1.5   rkujawa 	mvpex_bus_maxdevs,
    235       1.5   rkujawa 	mvpex_make_tag,
    236       1.5   rkujawa 	mvpex_decompose_tag,
    237       1.5   rkujawa #if NMVPEX_MBUS > 0
    238       1.5   rkujawa 	mvpex_mbus_conf_read,		/* XXXX: always this functions */
    239       1.5   rkujawa #else
    240       1.5   rkujawa 	mvpex_conf_read,
    241       1.5   rkujawa #endif
    242       1.5   rkujawa 	mvpex_conf_write,
    243       1.5   rkujawa 	NULL,	/* intr_v */
    244       1.5   rkujawa 	mvpex_intr_map,
    245       1.5   rkujawa 	mvpex_intr_string,
    246       1.5   rkujawa 	mvpex_intr_evcnt,
    247  1.10.4.1    bouyer 	NULL,	/* intr_setattr */
    248  1.10.4.1    bouyer 	mvpex_intr_establish,
    249  1.10.4.1    bouyer 	mvpex_intr_disestablish,
    250  1.10.4.1    bouyer #ifdef __HAVE_PCI_CONF_HOOK
    251  1.10.4.1    bouyer 	mvpex_conf_hook,
    252  1.10.4.1    bouyer #endif
    253  1.10.4.1    bouyer 	mvpex_conf_interrupt,
    254  1.10.4.1    bouyer };
    255  1.10.4.1    bouyer struct arm32_pci_chipset arm32_mvpex6_chipset = {
    256  1.10.4.1    bouyer 	NULL,	/* conf_v */
    257  1.10.4.1    bouyer 	mvpex_attach_hook,
    258  1.10.4.1    bouyer 	mvpex_bus_maxdevs,
    259  1.10.4.1    bouyer 	mvpex_make_tag,
    260  1.10.4.1    bouyer 	mvpex_decompose_tag,
    261  1.10.4.1    bouyer #if NMVPEX_MBUS > 0
    262  1.10.4.1    bouyer 	mvpex_mbus_conf_read,		/* XXXX: always this functions */
    263  1.10.4.1    bouyer #else
    264  1.10.4.1    bouyer 	mvpex_conf_read,
    265  1.10.4.1    bouyer #endif
    266  1.10.4.1    bouyer 	mvpex_conf_write,
    267  1.10.4.1    bouyer 	NULL,	/* intr_v */
    268  1.10.4.1    bouyer 	mvpex_intr_map,
    269  1.10.4.1    bouyer 	mvpex_intr_string,
    270  1.10.4.1    bouyer 	mvpex_intr_evcnt,
    271  1.10.4.1    bouyer 	NULL,	/* intr_setattr */
    272       1.5   rkujawa 	mvpex_intr_establish,
    273       1.5   rkujawa 	mvpex_intr_disestablish,
    274       1.5   rkujawa #ifdef __HAVE_PCI_CONF_HOOK
    275       1.5   rkujawa 	mvpex_conf_hook,
    276       1.5   rkujawa #endif
    277       1.5   rkujawa 	mvpex_conf_interrupt,
    278       1.5   rkujawa };
    279       1.5   rkujawa #endif /* NMVPEX > 0 */
    280       1.1  kiyohara 
    281       1.4      matt #if NGTPCI > 0
    282       1.4      matt /* ARGSUSED */
    283       1.1  kiyohara void
    284       1.3      matt gtpci_conf_interrupt(void *v, int bus, int dev, int pin, int swiz, int *iline)
    285       1.1  kiyohara {
    286       1.1  kiyohara 
    287       1.1  kiyohara 	/* nothing */
    288       1.1  kiyohara }
    289       1.1  kiyohara 
    290       1.1  kiyohara #if NGTPCI_MBUS > 0
    291       1.1  kiyohara #define GTPCI_MBUS_CA		0x0c78	/* Configuration Address */
    292       1.1  kiyohara #define GTPCI_MBUS_CD		0x0c7c	/* Configuration Data */
    293       1.1  kiyohara 
    294       1.1  kiyohara static pcireg_t
    295       1.1  kiyohara gtpci_mbus_conf_read(void *v, pcitag_t tag, int reg)
    296       1.1  kiyohara {
    297       1.1  kiyohara 	struct gtpci_softc *sc = v;
    298       1.1  kiyohara 	const pcireg_t addr = tag | reg;
    299       1.1  kiyohara 
    300       1.9   msaitoh 	if ((unsigned int)reg >= PCI_CONF_SIZE)
    301       1.9   msaitoh 		return -1;
    302       1.9   msaitoh 
    303       1.1  kiyohara 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTPCI_MBUS_CA,
    304       1.1  kiyohara 	    addr | GTPCI_CA_CONFIGEN);
    305       1.1  kiyohara 	if ((addr | GTPCI_CA_CONFIGEN) !=
    306       1.1  kiyohara 	    bus_space_read_4(sc->sc_iot, sc->sc_ioh, GTPCI_MBUS_CA))
    307       1.1  kiyohara 		return -1;
    308       1.1  kiyohara 
    309       1.1  kiyohara 	return bus_space_read_4(sc->sc_iot, sc->sc_ioh, GTPCI_MBUS_CD);
    310       1.1  kiyohara }
    311       1.1  kiyohara 
    312       1.1  kiyohara static void
    313       1.1  kiyohara gtpci_mbus_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
    314       1.1  kiyohara {
    315       1.1  kiyohara 	struct gtpci_softc *sc = v;
    316       1.1  kiyohara 	pcireg_t addr = tag | (reg & 0xfc);
    317       1.1  kiyohara 
    318       1.9   msaitoh 	if ((unsigned int)reg >= PCI_CONF_SIZE)
    319       1.9   msaitoh 		return;
    320       1.9   msaitoh 
    321       1.1  kiyohara 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTPCI_MBUS_CA,
    322       1.1  kiyohara 	    addr | GTPCI_CA_CONFIGEN);
    323       1.1  kiyohara 	if ((addr | GTPCI_CA_CONFIGEN) !=
    324       1.1  kiyohara 	    bus_space_read_4(sc->sc_iot, sc->sc_ioh, GTPCI_MBUS_CA))
    325       1.1  kiyohara 		return;
    326       1.1  kiyohara 
    327       1.1  kiyohara 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTPCI_MBUS_CD, data);
    328       1.1  kiyohara }
    329       1.1  kiyohara #endif	/* NGTPCI_MBUS */
    330       1.1  kiyohara 
    331       1.1  kiyohara /*
    332       1.1  kiyohara  * We assume to use GPP interrupt as PCI interrupts.
    333       1.1  kiyohara  *   pci_intr_map() shall returns number of GPP between 0 and 31.  However
    334       1.1  kiyohara  *   returns 0xff, because we do not know the connected pin number for GPP
    335       1.1  kiyohara  *   of your board.
    336       1.1  kiyohara  *   pci_intr_string() shall returns string "gpp <num>".
    337       1.1  kiyohara  *   pci_intr_establish() established interrupt in the pin of all GPP.
    338       1.1  kiyohara  *   Moreover, the return value will be disregarded.  For instance, the
    339       1.1  kiyohara  *   setting for interrupt is not done.
    340       1.1  kiyohara  */
    341       1.1  kiyohara 
    342       1.1  kiyohara /* ARGSUSED */
    343       1.1  kiyohara static int
    344       1.2    dyoung gtpci_gpp_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp)
    345       1.1  kiyohara {
    346       1.1  kiyohara 
    347       1.1  kiyohara 	*ihp = pa->pa_intrpin;
    348       1.1  kiyohara 	return 0;
    349       1.1  kiyohara }
    350       1.1  kiyohara 
    351       1.1  kiyohara /* ARGSUSED */
    352       1.1  kiyohara static const char *
    353       1.7  christos gtpci_gpp_intr_string(void *v, pci_intr_handle_t pin, char *buf, size_t len)
    354       1.1  kiyohara {
    355       1.1  kiyohara 	struct gtpci_softc *sc = v;
    356       1.1  kiyohara 	prop_array_t int2gpp;
    357       1.1  kiyohara 	prop_object_t gpp;
    358       1.1  kiyohara 
    359       1.1  kiyohara 	int2gpp = prop_dictionary_get(device_properties(sc->sc_dev), "int2gpp");
    360       1.1  kiyohara 	gpp = prop_array_get(int2gpp, pin);
    361       1.7  christos 	snprintf(buf, len, "gpp %d", (int)prop_number_integer_value(gpp));
    362       1.1  kiyohara 
    363       1.7  christos 	return buf;
    364       1.1  kiyohara }
    365       1.1  kiyohara 
    366       1.1  kiyohara /* ARGSUSED */
    367       1.1  kiyohara static const struct evcnt *
    368       1.1  kiyohara gtpci_gpp_intr_evcnt(void *v, pci_intr_handle_t pin)
    369       1.1  kiyohara {
    370       1.1  kiyohara 
    371       1.1  kiyohara 	return NULL;
    372       1.1  kiyohara }
    373       1.1  kiyohara 
    374       1.1  kiyohara static void *
    375       1.1  kiyohara gtpci_gpp_intr_establish(void *v, pci_intr_handle_t int_pin, int ipl,
    376       1.1  kiyohara 		         int (*intrhand)(void *), void *intrarg)
    377       1.1  kiyohara {
    378       1.1  kiyohara 	struct gtpci_softc *sc = v;
    379       1.1  kiyohara 	prop_array_t int2gpp;
    380       1.1  kiyohara 	prop_object_t gpp;
    381       1.1  kiyohara 	int gpp_pin;
    382       1.1  kiyohara 
    383       1.1  kiyohara 	int2gpp = prop_dictionary_get(device_properties(sc->sc_dev), "int2gpp");
    384       1.1  kiyohara 	gpp = prop_array_get(int2gpp, int_pin);
    385       1.1  kiyohara 	gpp_pin = prop_number_integer_value(gpp);
    386      1.10  kiyohara 	return mvsocgpp_intr_establish(gpp_pin, ipl, IST_LEVEL_LOW, intrhand,
    387      1.10  kiyohara 	    intrarg);
    388       1.1  kiyohara }
    389       1.1  kiyohara 
    390       1.1  kiyohara static void
    391       1.1  kiyohara gtpci_gpp_intr_disestablish(void *v, void *ih)
    392       1.1  kiyohara {
    393       1.1  kiyohara 
    394       1.1  kiyohara 	mvsocgpp_intr_disestablish(ih);
    395       1.1  kiyohara }
    396       1.1  kiyohara #endif
    397       1.1  kiyohara 
    398       1.1  kiyohara #if NMVPEX_MBUS > 0
    399       1.4      matt /* ARGSUSED */
    400       1.4      matt void
    401       1.4      matt mvpex_conf_interrupt(void *v, int bus, int dev, int ipin, int swiz, int *ilinep)
    402       1.4      matt {
    403       1.4      matt 
    404       1.4      matt 	/* nothing */
    405       1.4      matt }
    406       1.4      matt 
    407       1.1  kiyohara static pcireg_t
    408       1.1  kiyohara mvpex_mbus_conf_read(void *v, pcitag_t tag, int reg)
    409       1.1  kiyohara {
    410       1.1  kiyohara 	struct mvpex_softc *sc = v;
    411       1.1  kiyohara 	pcireg_t addr, data, pci_cs;
    412       1.1  kiyohara 	uint32_t stat;
    413       1.1  kiyohara 	int bus, dev, func, pexbus, pexdev;
    414       1.1  kiyohara 
    415       1.9   msaitoh 	if ((unsigned int)reg >= PCI_CONF_SIZE)
    416       1.9   msaitoh 		return -1;
    417       1.9   msaitoh 
    418       1.1  kiyohara 	mvpex_decompose_tag(v, tag, &bus, &dev, &func);
    419       1.1  kiyohara 
    420       1.1  kiyohara 	stat = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVPEX_STAT);
    421       1.1  kiyohara 	pexbus = MVPEX_STAT_PEXBUSNUM(stat);
    422       1.1  kiyohara 	pexdev = MVPEX_STAT_PEXDEVNUM(stat);
    423       1.1  kiyohara 	if (bus != pexbus || dev != pexdev)
    424       1.1  kiyohara 		if (stat & MVPEX_STAT_DLDOWN)
    425       1.1  kiyohara 			return -1;
    426       1.1  kiyohara 
    427       1.1  kiyohara 	if (bus == pexbus) {
    428       1.1  kiyohara 		if (pexdev == 0) {
    429       1.1  kiyohara 			if (dev != 1 && dev != pexdev)
    430       1.1  kiyohara 				return -1;
    431       1.1  kiyohara 		} else {
    432       1.1  kiyohara 			if (dev != 0 && dev != pexdev)
    433       1.1  kiyohara 				return -1;
    434       1.1  kiyohara 		}
    435       1.1  kiyohara 		if (func != 0)
    436       1.1  kiyohara 			return -1;
    437       1.1  kiyohara 	}
    438       1.1  kiyohara 
    439       1.1  kiyohara 	addr = ((reg & 0xf00) << 24)  | tag | (reg & 0xfc);
    440       1.1  kiyohara 
    441       1.1  kiyohara #if defined(ORION)
    442       1.1  kiyohara 	/*
    443       1.1  kiyohara 	 * Guideline (GL# PCI Express-1) Erroneous Read Data on Configuration
    444       1.1  kiyohara 	 * This guideline is relevant for all devices except of the following
    445       1.1  kiyohara 	 * devices:
    446       1.1  kiyohara 	 *     88F5281-BO and above, and 88F5181L-A0 and above
    447       1.1  kiyohara 	 */
    448       1.1  kiyohara 	if ((bus != pexbus || dev != pexdev) &&
    449       1.1  kiyohara 	    !(sc->sc_model == MARVELL_ORION_2_88F5281 && sc->sc_rev == 1) &&
    450       1.1  kiyohara 	    !(sc->sc_model == MARVELL_ORION_1_88F5181 && sc->sc_rev == 8)) {
    451       1.1  kiyohara 
    452       1.1  kiyohara 		/* PCI-Express configuration read work-around */
    453       1.1  kiyohara 		/*
    454       1.1  kiyohara 		 * We will use one of the Punit (AHBToMbus) windows to
    455       1.1  kiyohara 		 * access the xbar and read the data from there
    456       1.1  kiyohara 		 *
    457       1.1  kiyohara 		 * Need to configure the 2 free Punit (AHB to MBus bridge)
    458       1.1  kiyohara 		 * address decoding windows:
    459       1.1  kiyohara 		 * Configure the flash Window to handle Configuration space
    460       1.1  kiyohara 		 * requests for PEX0/1:
    461       1.1  kiyohara 		 *
    462       1.1  kiyohara 		 * Configuration transactions from the CPU should write/read
    463       1.1  kiyohara 		 * the data to/from address of the form:
    464       1.1  kiyohara 		 *	addr[31:28]: 0x5 (for PEX0) or 0x6 (for PEX1)
    465       1.1  kiyohara 		 *	addr[27:24]: extended register number
    466       1.1  kiyohara 		 *	addr[23:16]: bus number
    467       1.1  kiyohara 		 *	addr[15:11]: device number
    468       1.1  kiyohara 		 *	addr[10: 8]: function number
    469       1.1  kiyohara 		 *	addr[ 7: 0]: register number
    470       1.1  kiyohara 		 */
    471       1.1  kiyohara 
    472       1.1  kiyohara 		struct mvsoc_softc *soc =
    473       1.1  kiyohara 		    device_private(device_parent(sc->sc_dev));;
    474       1.1  kiyohara 		bus_space_handle_t pcicfg_ioh;
    475       1.1  kiyohara 		uint32_t remapl, remaph, wc, pcicfg_addr, pcicfg_size;
    476       1.1  kiyohara 		int window, target, attr, base, size, s;
    477       1.1  kiyohara 		const int pex_pcicfg_tag =
    478       1.1  kiyohara 		    (sc->sc_model == MARVELL_ORION_1_88F1181) ?
    479       1.1  kiyohara 		    ORION_TAG_FLASH_CS : ORION_TAG_PEX0_MEM;
    480       1.1  kiyohara 
    481       1.1  kiyohara 		window = mvsoc_target(pex_pcicfg_tag,
    482       1.1  kiyohara 		    &target, &attr, &base, &size);
    483       1.1  kiyohara 		if (window >= nwindow) {
    484       1.1  kiyohara 			aprint_error_dev(sc->sc_dev,
    485       1.1  kiyohara 			    "can't read pcicfg space\n");
    486       1.1  kiyohara 			return -1;
    487       1.1  kiyohara 		}
    488       1.1  kiyohara 
    489       1.1  kiyohara 		s = splhigh();
    490       1.1  kiyohara 
    491       1.1  kiyohara 		remapl = remaph = 0;
    492       1.1  kiyohara 		if (window == 0 || window == 1) {
    493       1.1  kiyohara 			remapl = read_mlmbreg(MVSOC_MLMB_WRLR(window));
    494       1.1  kiyohara 			remaph = read_mlmbreg(MVSOC_MLMB_WRHR(window));
    495       1.1  kiyohara 		}
    496       1.1  kiyohara 
    497       1.1  kiyohara 		wc =
    498       1.1  kiyohara 		    MVSOC_MLMB_WCR_WINEN			|
    499       1.1  kiyohara 		    MVSOC_MLMB_WCR_ATTR(ORION_ATTR_PEX_CFG)	|
    500       1.1  kiyohara 		    MVSOC_MLMB_WCR_TARGET((soc->sc_addr + sc->sc_offset) >> 16);
    501       1.1  kiyohara 		if (sc->sc_model == MARVELL_ORION_1_88F1181) {
    502       1.1  kiyohara 			pcicfg_addr = base;
    503       1.1  kiyohara 			pcicfg_size = size;
    504       1.1  kiyohara 		} else if (sc->sc_model == MARVELL_ORION_1_88F5182) {
    505       1.1  kiyohara #define PEX_PCICFG_RW_WA_BASE		0x50000000
    506       1.1  kiyohara #define PEX_PCICFG_RW_WA_5182_BASE	0xf0000000
    507       1.1  kiyohara #define PEX_PCICFG_RW_WA_SIZE		(16 * 1024 * 1024)
    508       1.1  kiyohara 			pcicfg_addr = PEX_PCICFG_RW_WA_5182_BASE;
    509       1.1  kiyohara 			pcicfg_size = PEX_PCICFG_RW_WA_SIZE;
    510       1.1  kiyohara 		} else {
    511       1.1  kiyohara 			pcicfg_addr = PEX_PCICFG_RW_WA_BASE;
    512       1.1  kiyohara 			pcicfg_size = PEX_PCICFG_RW_WA_SIZE;
    513       1.1  kiyohara 		}
    514       1.1  kiyohara 		write_mlmbreg(MVSOC_MLMB_WCR(window),
    515       1.1  kiyohara 		    wc | MVSOC_MLMB_WCR_SIZE(pcicfg_size));
    516       1.1  kiyohara 		write_mlmbreg(MVSOC_MLMB_WBR(window), pcicfg_addr);
    517       1.1  kiyohara 
    518       1.1  kiyohara 		if (window == 0 || window == 1) {
    519       1.1  kiyohara 			write_mlmbreg(MVSOC_MLMB_WRLR(window), pcicfg_addr);
    520       1.1  kiyohara 			write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
    521       1.1  kiyohara 		}
    522       1.1  kiyohara 
    523       1.1  kiyohara 		if (bus_space_map(sc->sc_iot, pcicfg_addr, pcicfg_size, 0,
    524       1.1  kiyohara 		    &pcicfg_ioh) == 0) {
    525       1.1  kiyohara 			data = bus_space_read_4(sc->sc_iot, pcicfg_ioh, addr);
    526       1.1  kiyohara 			bus_space_unmap(sc->sc_iot, pcicfg_ioh, pcicfg_size);
    527       1.1  kiyohara 		} else
    528       1.1  kiyohara 			data = -1;
    529       1.1  kiyohara 
    530       1.1  kiyohara 		write_mlmbreg(MVSOC_MLMB_WCR(window),
    531       1.1  kiyohara 		    MVSOC_MLMB_WCR_WINEN		|
    532       1.1  kiyohara 		    MVSOC_MLMB_WCR_ATTR(attr)		|
    533       1.1  kiyohara 		    MVSOC_MLMB_WCR_TARGET(target)	|
    534       1.1  kiyohara 		    MVSOC_MLMB_WCR_SIZE(size));
    535       1.1  kiyohara 		write_mlmbreg(MVSOC_MLMB_WBR(window), base);
    536       1.1  kiyohara 		if (window == 0 || window == 1) {
    537       1.1  kiyohara 			write_mlmbreg(MVSOC_MLMB_WRLR(window), remapl);
    538       1.1  kiyohara 			write_mlmbreg(MVSOC_MLMB_WRHR(window), remaph);
    539       1.1  kiyohara 		}
    540       1.1  kiyohara 
    541       1.1  kiyohara 		splx(s);
    542       1.1  kiyohara #else
    543       1.1  kiyohara 	if (0) {
    544       1.1  kiyohara #endif
    545       1.1  kiyohara 	} else {
    546       1.1  kiyohara 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVPEX_CA,
    547       1.1  kiyohara 		    addr | MVPEX_CA_CONFIGEN);
    548       1.1  kiyohara 		if ((addr | MVPEX_CA_CONFIGEN) !=
    549       1.1  kiyohara 		    bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVPEX_CA))
    550       1.1  kiyohara 			return -1;
    551       1.1  kiyohara 
    552       1.1  kiyohara 		pci_cs = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
    553       1.1  kiyohara 		    PCI_COMMAND_STATUS_REG);
    554       1.1  kiyohara 		bus_space_write_4(sc->sc_iot, sc->sc_ioh,
    555       1.1  kiyohara 		    PCI_COMMAND_STATUS_REG, pci_cs | PCI_STATUS_MASTER_ABORT);
    556       1.1  kiyohara 
    557       1.1  kiyohara 		data = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVPEX_CD);
    558       1.1  kiyohara 	}
    559       1.1  kiyohara 
    560       1.1  kiyohara 	return data;
    561       1.1  kiyohara }
    562       1.1  kiyohara #endif
    563