Home | History | Annotate | Line # | Download | only in starfive
      1  1.2  skrll /* $NetBSD: jh7110_pcie.c,v 1.2 2025/01/09 10:39:01 skrll Exp $ */
      2  1.1  skrll 
      3  1.1  skrll /*-
      4  1.1  skrll  * Copyright (c) 2024 The NetBSD Foundation, Inc.
      5  1.1  skrll  * All rights reserved.
      6  1.1  skrll  *
      7  1.1  skrll  * This code is derived from software contributed to The NetBSD Foundation
      8  1.1  skrll  * by Nick Hudson
      9  1.1  skrll  *
     10  1.1  skrll  * Redistribution and use in source and binary forms, with or without
     11  1.1  skrll  * modification, are permitted provided that the following conditions
     12  1.1  skrll  * are met:
     13  1.1  skrll  * 1. Redistributions of source code must retain the above copyright
     14  1.1  skrll  *    notice, this list of conditions and the following disclaimer.
     15  1.1  skrll  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1  skrll  *    notice, this list of conditions and the following disclaimer in the
     17  1.1  skrll  *    documentation and/or other materials provided with the distribution.
     18  1.1  skrll  *
     19  1.1  skrll  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  1.1  skrll  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  1.1  skrll  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  1.1  skrll  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  1.1  skrll  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  1.1  skrll  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  1.1  skrll  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  1.1  skrll  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  1.1  skrll  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  1.1  skrll  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  1.1  skrll  * POSSIBILITY OF SUCH DAMAGE.
     30  1.1  skrll  */
     31  1.1  skrll 
     32  1.1  skrll #include <sys/cdefs.h>
     33  1.2  skrll __KERNEL_RCSID(0, "$NetBSD: jh7110_pcie.c,v 1.2 2025/01/09 10:39:01 skrll Exp $");
     34  1.1  skrll 
     35  1.1  skrll #include <sys/param.h>
     36  1.1  skrll 
     37  1.1  skrll #include <sys/bitops.h>
     38  1.1  skrll #include <sys/kmem.h>
     39  1.1  skrll 
     40  1.1  skrll #include <dev/fdt/fdtvar.h>
     41  1.1  skrll #include <dev/fdt/syscon.h>
     42  1.1  skrll 
     43  1.1  skrll #include <dev/pci/pcivar.h>
     44  1.1  skrll #include <dev/pci/pciconf.h>
     45  1.1  skrll 
     46  1.1  skrll #include <riscv/fdt/pcihost_fdtvar.h>
     47  1.1  skrll 
     48  1.1  skrll struct jh7110_pcie_irq {
     49  1.1  skrll 	struct jh7110_pcie_softc *
     50  1.1  skrll 				jpi_sc;
     51  1.1  skrll 	void			*jpi_arg;
     52  1.1  skrll 	int			(*jpi_fn)(void *);
     53  1.1  skrll 	int			jpi_mpsafe;
     54  1.1  skrll };
     55  1.1  skrll 
     56  1.1  skrll struct jh7110_pcie_softc {
     57  1.1  skrll 	bus_space_tag_t		sc_bst;
     58  1.1  skrll 
     59  1.1  skrll 	struct pcihost_softc	sc_phsc;
     60  1.1  skrll 
     61  1.1  skrll 	bus_space_handle_t	sc_apb_bsh;
     62  1.1  skrll 	bus_addr_t		sc_apb_addr;
     63  1.1  skrll 	bus_size_t		sc_apb_size;
     64  1.1  skrll 
     65  1.1  skrll 	bus_space_handle_t	sc_cfg_bsh;
     66  1.1  skrll 	bus_addr_t		sc_cfg_addr;
     67  1.1  skrll 	bus_size_t		sc_cfg_size;
     68  1.1  skrll 
     69  1.1  skrll 	// syscon
     70  1.1  skrll 	const struct syscon *	sc_syscon;
     71  1.1  skrll 	bus_size_t		sc_stg_base;
     72  1.1  skrll 
     73  1.1  skrll 	struct fdtbus_gpio_pin *sc_perst_gpio;
     74  1.1  skrll 
     75  1.1  skrll 	// # pins
     76  1.1  skrll 	struct jh7110_pcie_irq	*sc_irq[PCI_INTERRUPT_PIN_MAX];
     77  1.1  skrll };
     78  1.1  skrll 
     79  1.1  skrll #define	RD4(sc, reg)							      \
     80  1.1  skrll     bus_space_read_4((sc)->sc_bst, (sc)->sc_apb_bsh, (reg))
     81  1.1  skrll #define	WR4(sc, reg, val)						      \
     82  1.1  skrll     bus_space_write_4((sc)->sc_bst, (sc)->sc_apb_bsh, (reg), (val))
     83  1.1  skrll 
     84  1.1  skrll #define SET4(sc, off, mask)						      \
     85  1.1  skrll     WR4((sc), (off), RD4((sc), (off)) | (mask))
     86  1.1  skrll #define CLR4(sc, off, mask)						      \
     87  1.1  skrll     WR4((sc), (off), RD4((sc), (off)) & ~(mask))
     88  1.1  skrll #define UPD4(sc, off, clr, set)						      \
     89  1.1  skrll     WR4((sc), (off), (RD4((sc), (off)) & ~(clr)) | (set))
     90  1.1  skrll 
     91  1.1  skrll #define JH7110_PCIE0_CFG_BASE	0x940000000UL
     92  1.1  skrll #define JH7110_PCIE1_CFG_BASE	0x9c0000000UL
     93  1.1  skrll 
     94  1.1  skrll /* PLDA register definitions */
     95  1.1  skrll #define PLDA_GEN_SETTINGS			0x80
     96  1.1  skrll #define  PLDA_GEN_RP_ENABLE			1
     97  1.1  skrll #define PLDA_PCI_IDS				0x9c
     98  1.1  skrll #define  PLDA_PCI_IDS_REVISION_MASK		__BITS( 7, 0)
     99  1.1  skrll #define  PLDA_PCI_IDS_CLASSCODE_MASK		__BITS(31, 8)
    100  1.1  skrll #define PLDA_MISC				0xb4
    101  1.1  skrll #define  PLDA_MISC_PHYFUNC_DISABLE		__BIT(15)
    102  1.1  skrll #define PLDA_WINROM				0xfc
    103  1.1  skrll #define  PLDA_WINROM_PREF64SUPPORT		__BIT(3)
    104  1.1  skrll 
    105  1.1  skrll #define PLDA_IMASK_LOCAL			0x180
    106  1.1  skrll #define  PLDA_IMASK_INT_INTA			__BIT(24)
    107  1.1  skrll #define  PLDA_IMASK_INT_INTB			__BIT(25)
    108  1.1  skrll #define  PLDA_IMASK_INT_INTC			__BIT(26)
    109  1.1  skrll #define  PLDA_IMASK_INT_INTD			__BIT(27)
    110  1.1  skrll #define  PLDA_IMASK_INT_INTX			__BITS(27, 24)
    111  1.1  skrll #define  PLDA_IMASK_INT_MSI			__BIT(28)
    112  1.1  skrll #define PLDA_ISTATUS_LOCAL			0x184
    113  1.1  skrll #define  PLDA_ISTATUS_INT_INTA			__BIT(24)
    114  1.1  skrll #define  PLDA_ISTATUS_INT_INTB			__BIT(25)
    115  1.1  skrll #define  PLDA_ISTATUS_INT_INTC			__BIT(26)
    116  1.1  skrll #define  PLDA_ISTATUS_INT_INTD			__BIT(27)
    117  1.1  skrll #define  PLDA_ISTATUS_INT_INTX			__BITS(27, 24)
    118  1.1  skrll #define  PLDA_ISTATUS_INT_MSI			__BIT(28)
    119  1.1  skrll #define PLDA_IMASK_HOST				0x188
    120  1.1  skrll #define PLDA_ISTATUS_HOST			0x18c
    121  1.1  skrll #define PLDA_IMSI_ADDR				0x190
    122  1.1  skrll #define PLDA_ISTATUS_MSI			0x194
    123  1.1  skrll #define PLDA_PMSG_SUPPORT_RX			0x3f0
    124  1.1  skrll #define  PLDA_PMSG_LTR_SUPPORT			__BIT(2)
    125  1.1  skrll 
    126  1.1  skrll /* PCIe Master table init defines */
    127  1.1  skrll #define PLDA_ATR0_PCIE_WIN0_SRCADDR_PARAM	0x600
    128  1.1  skrll #define  PLDA_ATR0_PCIE_ATR_SIZE		0x25
    129  1.1  skrll #define  PLDA_ATR0_PCIE_ATR_SIZE_SHIFT		1
    130  1.1  skrll #define PLDA_ATR0_PCIE_WIN0_SRC_ADDR		0x604
    131  1.1  skrll #define PLDA_ATR0_PCIE_WIN0_TRSL_ADDR_LSB	0x608
    132  1.1  skrll #define PLDA_ATR0_PCIE_WIN0_TRSL_ADDR_UDW	0x60c
    133  1.1  skrll #define PLDA_ATR0_PCIE_WIN0_TRSL_PARAM		0x610
    134  1.1  skrll 
    135  1.1  skrll #define PLDA_ATR_AXI4_SLV0_SRC_ADDR_LO(n)	(0x800 + (n) * 0x20)
    136  1.1  skrll #define  PLDA_ATR_SIZE_SRC_MASK			__BITS(31, 12)
    137  1.1  skrll #define  PLDA_ATR_SIZE_MASK			__BITS(6, 1)
    138  1.1  skrll #define  PLDA_ATR_IMPL				__BIT(0)
    139  1.1  skrll #define PLDA_ATR_AXI4_SLV0_SRC_ADDR_HI(n)	(0x804 + (n) * 0x20)
    140  1.1  skrll #define PLDA_ATR_AXI4_SLV0_TRSL_ADDR_LO(n)	(0x808 + (n) * 0x20)
    141  1.1  skrll #define PLDA_ATR_AXI4_SLV0_TRSL_ADDR_HI(n)	(0x80c + (n) * 0x20)
    142  1.1  skrll #define PLDA_ATR_AXI4_SLV0_TRSL_PARAM(n)	(0x810 + (n) * 0x20)
    143  1.1  skrll #define  PLDA_TRSL_ID_PCIE_RX_TX		0
    144  1.1  skrll #define  PLDA_TRSL_ID_PCIE_CONFIG		1
    145  1.1  skrll 
    146  1.1  skrll #define PCIE_FUNC_NUM				4
    147  1.1  skrll 
    148  1.1  skrll /* system control */
    149  1.1  skrll #define STG_SYSCON_PCIE0_BASE			0x0048
    150  1.1  skrll #define STG_SYSCON_PCIE1_BASE			0x01f8
    151  1.1  skrll 
    152  1.1  skrll #define STG_SYSCON_AR_OFFSET			0x0078
    153  1.1  skrll #define STG_SYSCON_AXI4_SLVL_AR_MASK		__BITS(22, 8)
    154  1.1  skrll #define  STG_SYSCON_AXI4_SLVL_PHY_AR_MASK	__BITS(20,17)
    155  1.1  skrll #define  STG_SYSCON_AXI4_SLVL_PHY_AR(x)		\
    156  1.1  skrll     __SHIFTIN((x), STG_SYSCON_AXI4_SLVL_PHY_AR_MASK)
    157  1.1  skrll 
    158  1.1  skrll #define STG_SYSCON_AW_OFFSET			0x007c
    159  1.1  skrll #define STG_SYSCON_CLKREQ			__BIT(22)
    160  1.1  skrll #define STG_SYSCON_CKREF_SRC_MASK		__BITS(19, 18)
    161  1.1  skrll #define STG_SYSCON_AXI4_SLVL_AW_MASK		__BITS(14,  0)
    162  1.1  skrll #define  STG_SYSCON_AXI4_SLVL_PHY_AW_MASK	__BITS(12,  9)
    163  1.1  skrll #define  STG_SYSCON_AXI4_SLVL_PHY_AW(x)		\
    164  1.1  skrll     __SHIFTIN((x), STG_SYSCON_AXI4_SLVL_PHY_AW_MASK)
    165  1.1  skrll 
    166  1.1  skrll #define STG_SYSCON_RP_NEP_OFFSET		0x00e8
    167  1.1  skrll #define STG_SYSCON_K_RP_NEP			__BIT(8)
    168  1.1  skrll 
    169  1.1  skrll #define STG_SYSCON_LNKSTA_OFFSET		0x0170
    170  1.1  skrll #define DATA_LINK_ACTIVE			__BIT(5)
    171  1.1  skrll 
    172  1.1  skrll #define ECAM_BUS_MASK				__BITS(27, 20)
    173  1.1  skrll #define ECAM_DEV_MASK				__BITS(19, 15)
    174  1.1  skrll #define ECAM_FUNC_MASK				__BITS(14, 12)
    175  1.1  skrll #define ECAM_OFFSET_MASK			__BITS(11,  0)
    176  1.1  skrll 
    177  1.1  skrll static int
    178  1.1  skrll jh7110_pcie_bus_maxdevs(void *v, int bus)
    179  1.1  skrll {
    180  1.1  skrll 	struct pcihost_softc * const phsc = v;
    181  1.1  skrll 
    182  1.1  skrll 	if (bus >= phsc->sc_bus_min || bus <= phsc->sc_bus_max)
    183  1.1  skrll 		return 1;
    184  1.1  skrll 	return 0;
    185  1.1  skrll }
    186  1.1  skrll 
    187  1.1  skrll static pcitag_t
    188  1.1  skrll jh7110_pcie_make_tag(void *v, int bus, int dev, int fn)
    189  1.1  skrll {
    190  1.1  skrll //	struct pcihost_softc * const phsc = v;
    191  1.1  skrll 
    192  1.1  skrll 	/* Return ECAM address. */
    193  1.1  skrll 	return
    194  1.1  skrll 	    __SHIFTIN(bus, ECAM_BUS_MASK) |
    195  1.1  skrll 	    __SHIFTIN(dev, ECAM_DEV_MASK) |
    196  1.1  skrll 	    __SHIFTIN(fn, ECAM_FUNC_MASK) |
    197  1.1  skrll 	    0;
    198  1.1  skrll }
    199  1.1  skrll 
    200  1.1  skrll static void
    201  1.1  skrll jh7110_pcie_decompose_tag(void *v, pcitag_t tag,
    202  1.1  skrll     int *busp, int *devp, int *fnp)
    203  1.1  skrll {
    204  1.1  skrll //	struct pcihost_softc * const phsc = v;
    205  1.1  skrll 
    206  1.1  skrll 	if (busp != NULL)
    207  1.1  skrll 		*busp = __SHIFTOUT(tag, ECAM_BUS_MASK);
    208  1.1  skrll 	if (devp != NULL)
    209  1.1  skrll 		*devp = __SHIFTOUT(tag, ECAM_DEV_MASK);
    210  1.1  skrll 	if (fnp != NULL)
    211  1.1  skrll 		*fnp = __SHIFTOUT(tag, ECAM_FUNC_MASK);
    212  1.1  skrll }
    213  1.1  skrll 
    214  1.1  skrll static bool
    215  1.1  skrll jh7110_pcie_conf_ok(struct jh7110_pcie_softc *sc,
    216  1.1  skrll     int bus, int dev, int fn, int offset)
    217  1.1  skrll {
    218  1.1  skrll 
    219  1.1  skrll 	/* Only one device on root port and the first subordinate port. */
    220  1.1  skrll 	if (bus < 2 && dev < 1)
    221  1.1  skrll 		return true;
    222  1.1  skrll 
    223  1.1  skrll 	return false;
    224  1.1  skrll }
    225  1.1  skrll 
    226  1.1  skrll static pcireg_t
    227  1.1  skrll jh7110_pcie_conf_read(void *v, pcitag_t tag, int offset)
    228  1.1  skrll {
    229  1.1  skrll 	struct pcihost_softc * const phsc = v;
    230  1.1  skrll 	struct jh7110_pcie_softc * const sc =
    231  1.1  skrll 	    container_of(phsc, struct jh7110_pcie_softc, sc_phsc);
    232  1.1  skrll 	int bus, dev, fn;
    233  1.1  skrll 
    234  1.1  skrll 	KASSERT(offset >= 0);
    235  1.1  skrll 	KASSERT(offset < PCI_EXTCONF_SIZE);
    236  1.1  skrll 
    237  1.1  skrll 	jh7110_pcie_decompose_tag(phsc, tag, &bus, &dev, &fn);
    238  1.1  skrll 
    239  1.1  skrll 	if (!jh7110_pcie_conf_ok(sc, bus, dev, fn, offset))
    240  1.1  skrll 		return 0xffffffff;
    241  1.1  skrll 
    242  1.1  skrll 	bus_size_t reg =
    243  1.1  skrll 	    __SHIFTIN(bus, ECAM_BUS_MASK) |
    244  1.1  skrll 	    __SHIFTIN(dev, ECAM_DEV_MASK) |
    245  1.1  skrll 	    __SHIFTIN(fn, ECAM_FUNC_MASK) |
    246  1.1  skrll 	    offset;
    247  1.1  skrll 
    248  1.1  skrll 	return bus_space_read_4(sc->sc_bst, sc->sc_cfg_bsh, reg);
    249  1.1  skrll }
    250  1.1  skrll 
    251  1.1  skrll static void
    252  1.1  skrll jh7110_pcie_conf_write(void *v, pcitag_t tag, int offset, pcireg_t data)
    253  1.1  skrll {
    254  1.1  skrll 	struct pcihost_softc * const phsc = v;
    255  1.1  skrll 	struct jh7110_pcie_softc * const sc =
    256  1.1  skrll 	    container_of(phsc, struct jh7110_pcie_softc, sc_phsc);
    257  1.1  skrll 	int bus, dev, fn;
    258  1.1  skrll 
    259  1.1  skrll 	KASSERT(offset >= 0);
    260  1.1  skrll 	KASSERT(offset < PCI_EXTCONF_SIZE);
    261  1.1  skrll 
    262  1.1  skrll 	jh7110_pcie_decompose_tag(phsc, tag, &bus, &dev, &fn);
    263  1.1  skrll 
    264  1.1  skrll 	if (!jh7110_pcie_conf_ok(sc, bus, dev, fn, offset))
    265  1.1  skrll 		return;
    266  1.1  skrll 
    267  1.1  skrll 	bus_size_t reg =
    268  1.1  skrll 	    __SHIFTIN(bus, ECAM_BUS_MASK) |
    269  1.1  skrll 	    __SHIFTIN(dev, ECAM_DEV_MASK) |
    270  1.1  skrll 	    __SHIFTIN(fn, ECAM_FUNC_MASK) |
    271  1.1  skrll 	    offset;
    272  1.1  skrll 
    273  1.1  skrll 	bus_space_write_4(sc->sc_bst, sc->sc_cfg_bsh, reg, data);
    274  1.1  skrll }
    275  1.1  skrll 
    276  1.1  skrll /* INTx interrupt controller */
    277  1.1  skrll static void *
    278  1.1  skrll jh7110_pcie_intx_establish(device_t dev, u_int *specifier, int ipl, int flags,
    279  1.1  skrll     int (*func)(void *), void *arg, const char *xname)
    280  1.1  skrll {
    281  1.1  skrll 	struct jh7110_pcie_softc * const sc = device_private(dev);
    282  1.1  skrll 	const u_int mpsafe = (flags & FDT_INTR_MPSAFE) ? IST_MPSAFE : 0;
    283  1.1  skrll 	const u_int pin = be32toh(specifier[0]) - 1;
    284  1.1  skrll 
    285  1.1  skrll 	KASSERT((RD4(sc, PLDA_IMASK_LOCAL) & (PLDA_IMASK_INT_INTA << pin)) == 0);
    286  1.1  skrll 
    287  1.1  skrll 	struct jh7110_pcie_irq *jpi = sc->sc_irq[pin];
    288  1.1  skrll 	if (jpi == NULL) {
    289  1.1  skrll 		jpi = kmem_alloc(sizeof(*jpi), KM_SLEEP);
    290  1.1  skrll 		jpi->jpi_sc = sc;
    291  1.1  skrll 		jpi->jpi_fn = func;
    292  1.1  skrll 		jpi->jpi_arg = arg;
    293  1.1  skrll 		jpi->jpi_mpsafe = mpsafe;
    294  1.1  skrll 
    295  1.1  skrll 		sc->sc_irq[pin] = jpi;
    296  1.1  skrll 	} else {
    297  1.1  skrll 		device_printf(dev, "shared interrupts not supported\n");
    298  1.1  skrll 		return NULL;
    299  1.1  skrll 	}
    300  1.1  skrll 
    301  1.1  skrll 	/* Unmask the interrupt. */
    302  1.1  skrll 	SET4(sc, PLDA_IMASK_LOCAL, (PLDA_IMASK_INT_INTA << pin));
    303  1.1  skrll 
    304  1.1  skrll 	return jpi;
    305  1.1  skrll }
    306  1.1  skrll 
    307  1.1  skrll 
    308  1.1  skrll static void
    309  1.1  skrll jh7110_pcie_intx_disestablish(device_t dev, void *ih)
    310  1.1  skrll {
    311  1.1  skrll 	struct jh7110_pcie_softc * const sc = device_private(dev);
    312  1.1  skrll 	struct pcihost_softc * const phsc = &sc->sc_phsc;
    313  1.1  skrll 
    314  1.1  skrll 	device_printf(dev, "%s\n", __func__);
    315  1.1  skrll 
    316  1.1  skrll 	fdtbus_intr_disestablish(phsc->sc_phandle, ih);
    317  1.1  skrll }
    318  1.1  skrll 
    319  1.1  skrll static bool
    320  1.1  skrll jh7110_pcie_intx_string(device_t dev, u_int *specifier, char *buf,
    321  1.1  skrll     size_t buflen)
    322  1.1  skrll {
    323  1.1  skrll 	struct jh7110_pcie_softc * const sc = device_private(dev);
    324  1.1  skrll 	struct pcihost_softc * const phsc = &sc->sc_phsc;
    325  1.1  skrll 
    326  1.1  skrll 	fdtbus_intr_str(phsc->sc_phandle, 0, buf, buflen);
    327  1.1  skrll 
    328  1.1  skrll 	return true;
    329  1.1  skrll }
    330  1.1  skrll 
    331  1.1  skrll static int
    332  1.1  skrll jh7110_pcie_intx_intr(struct jh7110_pcie_softc *sc, uint32_t status)
    333  1.1  skrll {
    334  1.1  skrll 	int handled = 0;
    335  1.1  skrll 	u_int pin;
    336  1.1  skrll 
    337  1.1  skrll 	CTASSERT(__arraycount(sc->sc_irq) == 4);
    338  1.1  skrll 	for (pin = 0; pin < __arraycount(sc->sc_irq); pin++) {
    339  1.1  skrll 		if ((status & (PLDA_IMASK_INT_INTA << pin)) == 0)
    340  1.1  skrll 			continue;
    341  1.1  skrll 
    342  1.1  skrll 		struct jh7110_pcie_irq *jpi = sc->sc_irq[pin];
    343  1.1  skrll 
    344  1.1  skrll 		if (jpi == NULL)
    345  1.1  skrll 			continue;
    346  1.1  skrll 
    347  1.1  skrll 		if (!jpi->jpi_mpsafe)
    348  1.1  skrll 			KERNEL_LOCK(1, NULL);
    349  1.1  skrll 		handled |= jpi->jpi_fn(jpi->jpi_arg);
    350  1.1  skrll 		if (!jpi->jpi_mpsafe)
    351  1.1  skrll 			KERNEL_UNLOCK_ONE(NULL);
    352  1.1  skrll 	}
    353  1.1  skrll 
    354  1.1  skrll 	return handled;
    355  1.1  skrll }
    356  1.1  skrll 
    357  1.1  skrll 
    358  1.1  skrll static int
    359  1.1  skrll jh7110_pcie_intr(void *v)
    360  1.1  skrll {
    361  1.1  skrll 	struct jh7110_pcie_softc * const sc = v;
    362  1.1  skrll 	int handled = 0;
    363  1.1  skrll 
    364  1.1  skrll 	uint32_t status = RD4(sc, PLDA_ISTATUS_LOCAL);
    365  1.1  skrll 	if (status == 0)
    366  1.1  skrll 		return 0;
    367  1.1  skrll 
    368  1.1  skrll 	if (status & PLDA_ISTATUS_INT_INTX)
    369  1.1  skrll 		handled |= jh7110_pcie_intx_intr(sc, status);
    370  1.1  skrll 
    371  1.1  skrll 	WR4(sc, PLDA_ISTATUS_LOCAL, status);
    372  1.1  skrll 
    373  1.1  skrll 	return handled;
    374  1.1  skrll }
    375  1.1  skrll 
    376  1.1  skrll static struct fdtbus_interrupt_controller_func jh7110_pcie_intxfuncs = {
    377  1.1  skrll 	.establish = jh7110_pcie_intx_establish,
    378  1.1  skrll 	.disestablish = jh7110_pcie_intx_disestablish,
    379  1.1  skrll 	.intrstr = jh7110_pcie_intx_string,
    380  1.1  skrll };
    381  1.1  skrll 
    382  1.1  skrll #define SCRD4(sc, off)		syscon_read_4((sc), (off))
    383  1.1  skrll #define SCWR4(sc, off, val)	syscon_write_4((sc), (off), (val))
    384  1.1  skrll 
    385  1.1  skrll #define SCSET4(sc, off, mask)						      \
    386  1.1  skrll     SCWR4((sc), (off), SCRD4((sc), (off)) | (mask))
    387  1.1  skrll #define SCCLR4(sc, off, mask)						      \
    388  1.1  skrll     SCWR4((sc), (off), SCRD4((sc), (off)) & ~(mask))
    389  1.1  skrll #define SCUPD4(sc, off, clr, set)					      \
    390  1.1  skrll     SCWR4((sc), (off), (SCRD4((sc), (off)) & ~(clr)) | (set))
    391  1.1  skrll 
    392  1.1  skrll 
    393  1.1  skrll static int
    394  1.1  skrll jh7110_pcie_host_init(struct jh7110_pcie_softc *sc)
    395  1.1  skrll {
    396  1.1  skrll 	struct pcihost_softc * const phsc = &sc->sc_phsc;
    397  1.1  skrll 
    398  1.1  skrll 	syscon_lock(sc->sc_syscon);
    399  1.1  skrll 	SCSET4(sc->sc_syscon, sc->sc_stg_base + STG_SYSCON_RP_NEP_OFFSET,
    400  1.1  skrll 	    STG_SYSCON_K_RP_NEP);
    401  1.1  skrll 
    402  1.1  skrll 	SCUPD4(sc->sc_syscon, sc->sc_stg_base + STG_SYSCON_AW_OFFSET,
    403  1.1  skrll 	    STG_SYSCON_CKREF_SRC_MASK,
    404  1.1  skrll 	    __SHIFTIN(2, STG_SYSCON_CKREF_SRC_MASK));
    405  1.1  skrll 
    406  1.1  skrll 	SCSET4(sc->sc_syscon, sc->sc_stg_base + STG_SYSCON_AW_OFFSET,
    407  1.1  skrll 	    STG_SYSCON_CLKREQ);
    408  1.1  skrll 
    409  1.1  skrll 	/* enable clocks */
    410  1.1  skrll 	struct clk *clk;
    411  1.1  skrll 	fdtbus_clock_assign(phsc->sc_phandle);
    412  1.1  skrll 	for (u_int c = 0;
    413  1.1  skrll 	    (clk = fdtbus_clock_get_index(phsc->sc_phandle, c)) != NULL;
    414  1.1  skrll 	    c++) {
    415  1.1  skrll 		if (clk_enable(clk) != 0) {
    416  1.1  skrll 			aprint_error_dev(phsc->sc_dev,
    417  1.2  skrll 			    "couldn't enable clock #%d\n", c);
    418  1.1  skrll 			return ENXIO;
    419  1.1  skrll 		}
    420  1.1  skrll 	}
    421  1.1  skrll 	/* de-assert resets */
    422  1.1  skrll 	struct fdtbus_reset *rst;
    423  1.1  skrll 	for (u_int r = 0;
    424  1.1  skrll 	    (rst = fdtbus_reset_get_index(phsc->sc_phandle, r)) != NULL;
    425  1.1  skrll 	    r++) {
    426  1.1  skrll 		if (fdtbus_reset_deassert(rst) != 0) {
    427  1.1  skrll 			aprint_error_dev(phsc->sc_dev,
    428  1.2  skrll 			    "couldn't de-assert reset #%d\n", r);
    429  1.1  skrll 			return ENXIO;
    430  1.1  skrll 		}
    431  1.1  skrll 	}
    432  1.1  skrll 
    433  1.1  skrll 	fdtbus_gpio_write(sc->sc_perst_gpio, 1);
    434  1.1  skrll 
    435  1.1  skrll 	/* Disable additional functions. */
    436  1.1  skrll 	for (u_int i = 1; i < PCIE_FUNC_NUM; i++) {
    437  1.1  skrll 
    438  1.1  skrll 		SCUPD4(sc->sc_syscon, sc->sc_stg_base + STG_SYSCON_AR_OFFSET,
    439  1.1  skrll 		    STG_SYSCON_AXI4_SLVL_AR_MASK,
    440  1.1  skrll 		    __SHIFTIN(i, STG_SYSCON_AXI4_SLVL_PHY_AR_MASK));
    441  1.1  skrll 
    442  1.1  skrll 		SCUPD4(sc->sc_syscon, sc->sc_stg_base + STG_SYSCON_AW_OFFSET,
    443  1.1  skrll 		    STG_SYSCON_AXI4_SLVL_AW_MASK,
    444  1.1  skrll 		    __SHIFTIN(i, STG_SYSCON_AXI4_SLVL_PHY_AW_MASK));
    445  1.1  skrll 
    446  1.1  skrll 		SET4(sc, PLDA_MISC, PLDA_MISC_PHYFUNC_DISABLE);
    447  1.1  skrll 	}
    448  1.1  skrll 
    449  1.1  skrll 	SCCLR4(sc->sc_syscon, sc->sc_stg_base + STG_SYSCON_AR_OFFSET,
    450  1.1  skrll 	    STG_SYSCON_AXI4_SLVL_AR_MASK);
    451  1.1  skrll 
    452  1.1  skrll 	SCCLR4(sc->sc_syscon, sc->sc_stg_base + STG_SYSCON_AW_OFFSET,
    453  1.1  skrll 	    STG_SYSCON_AXI4_SLVL_AW_MASK);
    454  1.1  skrll 
    455  1.1  skrll 	/* Configure controller as root port. */
    456  1.1  skrll 	UPD4(sc, PLDA_GEN_SETTINGS, PLDA_GEN_RP_ENABLE, PLDA_GEN_RP_ENABLE);
    457  1.1  skrll 	uint64_t base_addr = 0;
    458  1.1  skrll 
    459  1.1  skrll #define CONFIG_SPACE_ADDR_OFFSET 0x1000
    460  1.1  skrll 
    461  1.1  skrll 	SET4(sc, CONFIG_SPACE_ADDR_OFFSET + 0x10, BUS_ADDR_LO32(base_addr));
    462  1.1  skrll 	SET4(sc, CONFIG_SPACE_ADDR_OFFSET + 0x14, BUS_ADDR_HI32(base_addr));
    463  1.1  skrll 
    464  1.1  skrll 	/* Configure as PCI bridge. */
    465  1.1  skrll 	UPD4(sc, PLDA_PCI_IDS,
    466  1.1  skrll 	    PLDA_PCI_IDS_CLASSCODE_MASK,
    467  1.1  skrll 	    PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
    468  1.1  skrll 		PCI_SUBCLASS_BRIDGE_PCI,
    469  1.1  skrll 		PCI_INTERFACE_BRIDGE_PCI_PCI));
    470  1.1  skrll 
    471  1.1  skrll 	/* Enable prefetchable memory windows. */
    472  1.1  skrll 	SET4(sc, PLDA_WINROM, PLDA_WINROM_PREF64SUPPORT);
    473  1.1  skrll 
    474  1.1  skrll 	/* Disable LTR message forwarding. */
    475  1.1  skrll 	CLR4(sc, PLDA_PMSG_SUPPORT_RX, PLDA_PMSG_LTR_SUPPORT);
    476  1.1  skrll 
    477  1.1  skrll 	/*
    478  1.1  skrll 	 * PERST# must remain asserted for at least 100us after the
    479  1.1  skrll 	 * reference clock becomes stable.  But also has to remain
    480  1.1  skrll 	 * active at least 100ms after power up.  Since we may have
    481  1.1  skrll 	 * just powered on the device, play it safe and use 100ms.
    482  1.1  skrll 	 */
    483  1.1  skrll 	delay(100 * 1000);
    484  1.1  skrll 
    485  1.1  skrll 	/* Deassert PERST#. */
    486  1.1  skrll 	fdtbus_gpio_write(sc->sc_perst_gpio, 0);
    487  1.1  skrll 
    488  1.1  skrll 	/* Wait for link to come up. */
    489  1.1  skrll 	uint32_t reg;
    490  1.1  skrll 	for (int timo = 100; timo > 0; timo--) {
    491  1.1  skrll 		reg = SCRD4(sc->sc_syscon,
    492  1.1  skrll 		    sc->sc_stg_base + STG_SYSCON_LNKSTA_OFFSET);
    493  1.1  skrll 		if (reg & DATA_LINK_ACTIVE)
    494  1.1  skrll 			break;
    495  1.1  skrll 		delay(1000);
    496  1.1  skrll 	}
    497  1.1  skrll 
    498  1.1  skrll 	syscon_unlock(sc->sc_syscon);
    499  1.1  skrll 
    500  1.1  skrll 	if ((reg & DATA_LINK_ACTIVE) == 0) {
    501  1.2  skrll 		aprint_error_dev(phsc->sc_dev, "link not up\n");
    502  1.1  skrll 		    return ENXIO;
    503  1.1  skrll 	}
    504  1.1  skrll 
    505  1.1  skrll 	return 0;
    506  1.1  skrll }
    507  1.1  skrll 
    508  1.1  skrll static int
    509  1.1  skrll jh7110_pcie_atr_init(struct jh7110_pcie_softc *sc)
    510  1.1  skrll {
    511  1.1  skrll 	const uint32_t *ranges;
    512  1.1  skrll 	bus_addr_t phyaddr;	// PADDR?
    513  1.1  skrll 	bus_addr_t pciaddr;
    514  1.1  skrll 	bus_size_t size;
    515  1.1  skrll 
    516  1.1  skrll 	WR4(sc, PLDA_ATR_AXI4_SLV0_SRC_ADDR_LO(0),
    517  1.1  skrll 	    PLDA_ATR_IMPL |
    518  1.1  skrll 	    __SHIFTIN(ilog2(sc->sc_cfg_size) - 1, PLDA_ATR_SIZE_MASK) |
    519  1.1  skrll 	    BUS_ADDR_LO32(sc->sc_cfg_addr));
    520  1.1  skrll 	WR4(sc, PLDA_ATR_AXI4_SLV0_SRC_ADDR_HI(0), BUS_ADDR_HI32(sc->sc_cfg_addr));
    521  1.1  skrll 	WR4(sc, PLDA_ATR_AXI4_SLV0_TRSL_ADDR_LO(0), 0);
    522  1.1  skrll 	WR4(sc, PLDA_ATR_AXI4_SLV0_TRSL_ADDR_HI(0), 0);
    523  1.1  skrll 	WR4(sc, PLDA_ATR_AXI4_SLV0_TRSL_PARAM(0), PLDA_TRSL_ID_PCIE_CONFIG);
    524  1.1  skrll 
    525  1.1  skrll 	struct pcihost_softc * const phsc = &sc->sc_phsc;
    526  1.1  skrll 	int ranges_len;
    527  1.1  skrll 	ranges = fdtbus_get_prop(phsc->sc_phandle, "ranges", &ranges_len);
    528  1.1  skrll 	if (ranges == NULL) {
    529  1.1  skrll 		aprint_error_dev(phsc->sc_dev,
    530  1.2  skrll 		    "couldn't find 'ranges' property\n");
    531  1.1  skrll 		return ENXIO;
    532  1.1  skrll 	}
    533  1.1  skrll 	const int ranges_cells = ranges_len / sizeof(uint32_t);
    534  1.1  skrll 
    535  1.1  skrll 	for (u_int i = 0, n = 1; i < ranges_cells && n < 8; i += 7, n++) {
    536  1.1  skrll 		pciaddr =
    537  1.1  skrll 		    __SHIFTIN(be32toh(ranges[i + 1]), __BITS(63, 32)) |
    538  1.1  skrll 		    __SHIFTIN(be32toh(ranges[i + 2]), __BITS(31,  0));
    539  1.1  skrll 		phyaddr =
    540  1.1  skrll 		    __SHIFTIN(be32toh(ranges[i + 3]), __BITS(63, 32)) |
    541  1.1  skrll 		    __SHIFTIN(be32toh(ranges[i + 4]), __BITS(31,  0));
    542  1.1  skrll 		size = be32toh(ranges[i + 6]);
    543  1.1  skrll 
    544  1.1  skrll 		WR4(sc, PLDA_ATR_AXI4_SLV0_SRC_ADDR_LO(n),
    545  1.1  skrll 		    PLDA_ATR_IMPL |
    546  1.1  skrll 		    __SHIFTIN(ilog2(size) /* - 1 */, PLDA_ATR_SIZE_MASK) |
    547  1.1  skrll 		    BUS_ADDR_LO32(phyaddr));
    548  1.1  skrll 		WR4(sc, PLDA_ATR_AXI4_SLV0_SRC_ADDR_HI(n), BUS_ADDR_HI32(phyaddr));
    549  1.1  skrll 		WR4(sc, PLDA_ATR_AXI4_SLV0_TRSL_ADDR_LO(n), BUS_ADDR_LO32(pciaddr));
    550  1.1  skrll 		WR4(sc, PLDA_ATR_AXI4_SLV0_TRSL_ADDR_HI(n), BUS_ADDR_HI32(pciaddr));
    551  1.1  skrll 		WR4(sc, PLDA_ATR_AXI4_SLV0_TRSL_PARAM(n), PLDA_TRSL_ID_PCIE_RX_TX);
    552  1.1  skrll 	}
    553  1.1  skrll 
    554  1.1  skrll 	uint32_t val;
    555  1.1  skrll 	val = RD4(sc, PLDA_ATR0_PCIE_WIN0_SRCADDR_PARAM);
    556  1.1  skrll 	val |= (PLDA_ATR0_PCIE_ATR_SIZE << PLDA_ATR0_PCIE_ATR_SIZE_SHIFT);
    557  1.1  skrll 	WR4(sc, PLDA_ATR0_PCIE_WIN0_SRCADDR_PARAM, val);
    558  1.1  skrll 	WR4(sc, PLDA_ATR0_PCIE_WIN0_SRC_ADDR, 0);
    559  1.1  skrll 
    560  1.1  skrll 	return 0;
    561  1.1  skrll }
    562  1.1  skrll 
    563  1.1  skrll /* Compat string(s) */
    564  1.1  skrll static const struct device_compatible_entry compat_data[] = {
    565  1.1  skrll 	{ .compat = "starfive,jh7110-pcie" },
    566  1.1  skrll 	DEVICE_COMPAT_EOL
    567  1.1  skrll };
    568  1.1  skrll 
    569  1.1  skrll 
    570  1.1  skrll static int
    571  1.1  skrll jh7110_pcie_match(device_t parent, cfdata_t cf, void *aux)
    572  1.1  skrll {
    573  1.1  skrll 	struct fdt_attach_args * const faa = aux;
    574  1.1  skrll 
    575  1.1  skrll 	return of_compatible_match(faa->faa_phandle, compat_data);
    576  1.1  skrll }
    577  1.1  skrll 
    578  1.1  skrll static void
    579  1.1  skrll jh7110_pcie_attach(device_t parent, device_t self, void *aux)
    580  1.1  skrll {
    581  1.1  skrll 	struct jh7110_pcie_softc * const sc = device_private(self);
    582  1.1  skrll 	struct pcihost_softc * const phsc = &sc->sc_phsc;
    583  1.1  skrll 	struct fdt_attach_args * const faa = aux;
    584  1.1  skrll 	const int phandle = faa->faa_phandle;
    585  1.1  skrll 	int error;
    586  1.1  skrll 
    587  1.1  skrll 	sc->sc_bst = faa->faa_bst;
    588  1.1  skrll 
    589  1.1  skrll 	phsc->sc_dev = self;
    590  1.1  skrll 	phsc->sc_bst = faa->faa_bst;
    591  1.1  skrll 	phsc->sc_pci_bst = faa->faa_bst;
    592  1.1  skrll 	phsc->sc_dmat = faa->faa_dmat;
    593  1.1  skrll 	phsc->sc_phandle = faa->faa_phandle;
    594  1.1  skrll 
    595  1.1  skrll 	/* Handle old and new binding names. */
    596  1.1  skrll 	if (fdtbus_get_reg_byname(phandle, "apb",
    597  1.1  skrll 	    &sc->sc_apb_addr, &sc->sc_apb_size) != 0) {
    598  1.1  skrll 		aprint_error(": couldn't get apb registers\n");
    599  1.1  skrll 		return;
    600  1.1  skrll 	}
    601  1.1  skrll 	if (fdtbus_get_reg_byname(phandle, "cfg",
    602  1.1  skrll 	    &sc->sc_cfg_addr, &sc->sc_cfg_size) != 0) {
    603  1.1  skrll 		aprint_error(": couldn't get cfg registers\n");
    604  1.1  skrll 		return;
    605  1.1  skrll 	}
    606  1.1  skrll 
    607  1.1  skrll 	const int mapflags = 0 /*BUS_SPACE_MAP_NONPOSTED*/;
    608  1.1  skrll 	error = bus_space_map(sc->sc_bst, sc->sc_apb_addr,
    609  1.1  skrll 	    sc->sc_apb_size, mapflags, &sc->sc_apb_bsh);
    610  1.1  skrll 	if (error) {
    611  1.1  skrll 		aprint_error(": can't map APB registers\n");
    612  1.1  skrll 		return;
    613  1.1  skrll 	}
    614  1.1  skrll 	error = bus_space_map(sc->sc_bst, sc->sc_cfg_addr,
    615  1.1  skrll 	    sc->sc_cfg_size, mapflags, &sc->sc_cfg_bsh);
    616  1.1  skrll 	if (error) {
    617  1.1  skrll 		aprint_error(": can't map CFG registers\n");
    618  1.1  skrll 		return;
    619  1.1  skrll 	}
    620  1.1  skrll 	int len;
    621  1.1  skrll 	const char *stgsyscon = "starfive,stg-syscon";
    622  1.1  skrll 	const u_int *stgsyscon_data =
    623  1.1  skrll 	    fdtbus_get_prop(phandle, stgsyscon, &len);
    624  1.1  skrll 	if (stgsyscon_data == NULL) {
    625  1.1  skrll 		aprint_error(": couldn't get '%s' property\n", stgsyscon);
    626  1.1  skrll 		return;
    627  1.1  skrll 	}
    628  1.1  skrll 
    629  1.1  skrll 	if (len != 1 * sizeof(uint32_t)) {
    630  1.1  skrll 		aprint_error(": incorrect '%s' data (len = %u)\n", stgsyscon,
    631  1.1  skrll 		    len);
    632  1.1  skrll 		return;
    633  1.1  skrll 	}
    634  1.1  skrll 	int syscon_phandle =
    635  1.1  skrll 	    fdtbus_get_phandle_from_native(be32dec(&stgsyscon_data[0]));
    636  1.1  skrll 
    637  1.1  skrll 	sc->sc_syscon = fdtbus_syscon_lookup(syscon_phandle);
    638  1.1  skrll 	if (sc->sc_syscon == NULL) {
    639  1.1  skrll 		aprint_error(": couldn't get '%s' (%d)\n", stgsyscon,
    640  1.1  skrll 		    syscon_phandle);
    641  1.1  skrll 		return;
    642  1.1  skrll 	}
    643  1.1  skrll 
    644  1.1  skrll 	sc->sc_perst_gpio = fdtbus_gpio_acquire(phandle,
    645  1.1  skrll 	    "perst-gpios", GPIO_PIN_OUTPUT);
    646  1.1  skrll 	if (sc->sc_perst_gpio == NULL) {
    647  1.1  skrll 		aprint_error(": couldn't get 'perst-gpios'");
    648  1.1  skrll 		return;
    649  1.1  skrll 	}
    650  1.1  skrll 
    651  1.1  skrll 	switch (sc->sc_cfg_addr) {
    652  1.1  skrll 	case JH7110_PCIE0_CFG_BASE:
    653  1.1  skrll 		sc->sc_stg_base = STG_SYSCON_PCIE0_BASE;
    654  1.1  skrll 		break;
    655  1.1  skrll 	case JH7110_PCIE1_CFG_BASE:
    656  1.1  skrll 		sc->sc_stg_base = STG_SYSCON_PCIE1_BASE;
    657  1.1  skrll 		break;
    658  1.1  skrll 	default:
    659  1.1  skrll 		aprint_error(": unknown controller at 0x%lx\n",
    660  1.1  skrll 		    sc->sc_cfg_addr);
    661  1.1  skrll 		return;
    662  1.1  skrll 	}
    663  1.1  skrll 
    664  1.1  skrll 	aprint_naive("\n");
    665  1.1  skrll 	aprint_normal(": PCIe\n");
    666  1.1  skrll 
    667  1.1  skrll 	error = jh7110_pcie_host_init(sc);
    668  1.1  skrll 	if (error) {
    669  1.1  skrll 		/* error already printed */
    670  1.1  skrll 		return;
    671  1.1  skrll 	}
    672  1.1  skrll 
    673  1.1  skrll 	/* Configure Address Translation. */
    674  1.1  skrll 	error = jh7110_pcie_atr_init(sc);
    675  1.1  skrll 	if (error) {
    676  1.1  skrll 
    677  1.1  skrll 	}
    678  1.1  skrll 
    679  1.1  skrll 	/* Mask and acknowledge all interrupts. */
    680  1.1  skrll 	WR4(sc, PLDA_IMASK_LOCAL, 0);
    681  1.1  skrll 	WR4(sc, PLDA_ISTATUS_LOCAL, 0xffffffff);
    682  1.1  skrll 
    683  1.1  skrll 	char intrstr[128];
    684  1.1  skrll 	if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
    685  1.1  skrll 		aprint_error(": failed to decode interrupt\n");
    686  1.1  skrll 		return;
    687  1.1  skrll 	}
    688  1.1  skrll 	void *ih = fdtbus_intr_establish_xname(phandle, 0, IPL_VM,
    689  1.1  skrll 	    FDT_INTR_MPSAFE, jh7110_pcie_intr, sc, device_xname(self));
    690  1.1  skrll 	if (ih == NULL) {
    691  1.1  skrll 		aprint_error_dev(self, "failed to establish interrupt on %s\n",
    692  1.1  skrll 		    intrstr);
    693  1.1  skrll 		// XXXNH unwind
    694  1.1  skrll 		return;
    695  1.1  skrll 	}
    696  1.1  skrll 	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
    697  1.1  skrll 
    698  1.1  skrll 	fdtbus_register_interrupt_controller(self,
    699  1.1  skrll 	    OF_child(phsc->sc_phandle), &jh7110_pcie_intxfuncs);
    700  1.1  skrll 
    701  1.1  skrll 	phsc->sc_type = PCIHOST_ECAM;
    702  1.1  skrll 	pcihost_init(&phsc->sc_pc, phsc);
    703  1.1  skrll 
    704  1.1  skrll 	phsc->sc_pc.pc_bus_maxdevs = jh7110_pcie_bus_maxdevs;
    705  1.1  skrll 	phsc->sc_pc.pc_make_tag = jh7110_pcie_make_tag;
    706  1.1  skrll 	phsc->sc_pc.pc_decompose_tag = jh7110_pcie_decompose_tag;
    707  1.1  skrll 	phsc->sc_pc.pc_conf_read = jh7110_pcie_conf_read;
    708  1.1  skrll 	phsc->sc_pc.pc_conf_write = jh7110_pcie_conf_write;
    709  1.1  skrll 
    710  1.1  skrll 	pcihost_init2(phsc);
    711  1.1  skrll }
    712  1.1  skrll 
    713  1.1  skrll CFATTACH_DECL_NEW(jh7110_pcie, sizeof(struct jh7110_pcie_softc),
    714  1.1  skrll 	jh7110_pcie_match, jh7110_pcie_attach, NULL, NULL);
    715