1*dfd1d0fcSMichal Meloun /*- 2*dfd1d0fcSMichal Meloun * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*dfd1d0fcSMichal Meloun * 4*dfd1d0fcSMichal Meloun * Copyright (c) 2019 Michal Meloun <mmel@FreeBSD.org> 5*dfd1d0fcSMichal Meloun * 6*dfd1d0fcSMichal Meloun * Redistribution and use in source and binary forms, with or without 7*dfd1d0fcSMichal Meloun * modification, are permitted provided that the following conditions 8*dfd1d0fcSMichal Meloun * are met: 9*dfd1d0fcSMichal Meloun * 1. Redistributions of source code must retain the above copyright 10*dfd1d0fcSMichal Meloun * notice, this list of conditions and the following disclaimer. 11*dfd1d0fcSMichal Meloun * 2. Redistributions in binary form must reproduce the above copyright 12*dfd1d0fcSMichal Meloun * notice, this list of conditions and the following disclaimer in the 13*dfd1d0fcSMichal Meloun * documentation and/or other materials provided with the distribution. 14*dfd1d0fcSMichal Meloun * 15*dfd1d0fcSMichal Meloun * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16*dfd1d0fcSMichal Meloun * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*dfd1d0fcSMichal Meloun * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*dfd1d0fcSMichal Meloun * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19*dfd1d0fcSMichal Meloun * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*dfd1d0fcSMichal Meloun * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*dfd1d0fcSMichal Meloun * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*dfd1d0fcSMichal Meloun * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*dfd1d0fcSMichal Meloun * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*dfd1d0fcSMichal Meloun * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*dfd1d0fcSMichal Meloun * SUCH DAMAGE. 26*dfd1d0fcSMichal Meloun * 27*dfd1d0fcSMichal Meloun */ 28*dfd1d0fcSMichal Meloun 29*dfd1d0fcSMichal Meloun /* Rockchip PCIe controller driver */ 30*dfd1d0fcSMichal Meloun 31*dfd1d0fcSMichal Meloun #include <sys/cdefs.h> 32*dfd1d0fcSMichal Meloun __FBSDID("$FreeBSD$"); 33*dfd1d0fcSMichal Meloun 34*dfd1d0fcSMichal Meloun #include <sys/param.h> 35*dfd1d0fcSMichal Meloun #include <sys/systm.h> 36*dfd1d0fcSMichal Meloun #include <sys/bus.h> 37*dfd1d0fcSMichal Meloun #include <sys/gpio.h> 38*dfd1d0fcSMichal Meloun #include <sys/proc.h> 39*dfd1d0fcSMichal Meloun #include <sys/kernel.h> 40*dfd1d0fcSMichal Meloun #include <sys/lock.h> 41*dfd1d0fcSMichal Meloun #include <sys/malloc.h> 42*dfd1d0fcSMichal Meloun #include <sys/module.h> 43*dfd1d0fcSMichal Meloun #include <sys/mutex.h> 44*dfd1d0fcSMichal Meloun #include <sys/rman.h> 45*dfd1d0fcSMichal Meloun 46*dfd1d0fcSMichal Meloun #include <machine/bus.h> 47*dfd1d0fcSMichal Meloun #include <machine/intr.h> 48*dfd1d0fcSMichal Meloun #include <machine/resource.h> 49*dfd1d0fcSMichal Meloun 50*dfd1d0fcSMichal Meloun #include <dev/extres/clk/clk.h> 51*dfd1d0fcSMichal Meloun #include <dev/extres/hwreset/hwreset.h> 52*dfd1d0fcSMichal Meloun #include <dev/extres/phy/phy.h> 53*dfd1d0fcSMichal Meloun #include <dev/extres/regulator/regulator.h> 54*dfd1d0fcSMichal Meloun #include <dev/gpio/gpiobusvar.h> 55*dfd1d0fcSMichal Meloun #include <dev/ofw/ofw_bus.h> 56*dfd1d0fcSMichal Meloun #include <dev/ofw/ofw_bus_subr.h> 57*dfd1d0fcSMichal Meloun #include <dev/ofw/ofw_pci.h> 58*dfd1d0fcSMichal Meloun #include <dev/ofw/ofwpci.h> 59*dfd1d0fcSMichal Meloun #include <dev/pci/pcivar.h> 60*dfd1d0fcSMichal Meloun #include <dev/pci/pcireg.h> 61*dfd1d0fcSMichal Meloun #include <dev/pci/pcib_private.h> 62*dfd1d0fcSMichal Meloun 63*dfd1d0fcSMichal Meloun #include <dev/ofw/ofw_bus.h> 64*dfd1d0fcSMichal Meloun 65*dfd1d0fcSMichal Meloun #include "pcib_if.h" 66*dfd1d0fcSMichal Meloun 67*dfd1d0fcSMichal Meloun #define ATU_CFG_BUS(x) (((x) & 0x0ff) << 20) 68*dfd1d0fcSMichal Meloun #define ATU_CFG_SLOT(x) (((x) & 0x01f) << 15) 69*dfd1d0fcSMichal Meloun #define ATU_CFG_FUNC(x) (((x) & 0x007) << 12) 70*dfd1d0fcSMichal Meloun #define ATU_CFG_REG(x) (((x) & 0xfff) << 0) 71*dfd1d0fcSMichal Meloun 72*dfd1d0fcSMichal Meloun #define ATU_TYPE_MEM 0x2 73*dfd1d0fcSMichal Meloun #define ATU_TYPE_IO 0x6 74*dfd1d0fcSMichal Meloun #define ATU_TYPE_CFG0 0xA 75*dfd1d0fcSMichal Meloun #define ATU_TYPE_CFG1 0xB 76*dfd1d0fcSMichal Meloun #define ATY_TYPE_NOR_MSG 0xC 77*dfd1d0fcSMichal Meloun 78*dfd1d0fcSMichal Meloun #define ATU_OB_REGIONS 33 79*dfd1d0fcSMichal Meloun #define ATU_OB_REGION_SHIFT 20 80*dfd1d0fcSMichal Meloun #define ATU_OB_REGION_SIZE (1 << ATU_OB_REGION_SHIFT) 81*dfd1d0fcSMichal Meloun #define ATU_OB_REGION_0_SIZE (( ATU_OB_REGIONS - 1) * ATU_OB_REGION_SIZE) 82*dfd1d0fcSMichal Meloun 83*dfd1d0fcSMichal Meloun #define ATU_IB_REGIONS 3 84*dfd1d0fcSMichal Meloun 85*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_BASIC_STRAP_CONF 0x000000 86*dfd1d0fcSMichal Meloun #define STRAP_CONF_GEN_2 (1 << 7) 87*dfd1d0fcSMichal Meloun #define STRAP_CONF_MODE_RC (1 << 6) 88*dfd1d0fcSMichal Meloun #define STRAP_CONF_LANES(n) ((((n) / 2) & 0x3) << 4) 89*dfd1d0fcSMichal Meloun #define STRAP_CONF_ARI_EN (1 << 3) 90*dfd1d0fcSMichal Meloun #define STRAP_CONF_SR_IOV_EN (1 << 2) 91*dfd1d0fcSMichal Meloun #define STRAP_CONF_LINK_TRAIN_EN (1 << 1) 92*dfd1d0fcSMichal Meloun #define STRAP_CONF_CONF_EN (1 << 0) 93*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_HOT_RESET_CTRL 0x000018 94*dfd1d0fcSMichal Meloun #define HOT_RESET_CTRL_LINK_DOWN_RESET (1 << 1) 95*dfd1d0fcSMichal Meloun #define HOT_RESET_CTRL_HOT_RESET_IN (1 << 0) 96*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_BASIC_STATUS0 0x000044 97*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_BASIC_STATUS1 0x000048 98*dfd1d0fcSMichal Meloun #define STATUS1_LINK_ST_GET(x) (((x) >> 20) & 0x3) 99*dfd1d0fcSMichal Meloun #define STATUS1_LINK_ST_UP 3 100*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_MASK 0x00004C 101*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_STATUS 0x000050 102*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_LEGACY_DONE (1 << 15) 103*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_MSG (1 << 14) 104*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_HOT_RST (1 << 13) 105*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_DPA (1 << 12) 106*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_FATAL_ERR (1 << 11) 107*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_NFATAL_ERR (1 << 10) 108*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_CORR_ERR (1 << 9) 109*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_INTD (1 << 8) 110*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_INTC (1 << 7) 111*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_INTB (1 << 6) 112*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_INTA (1 << 5) 113*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_LOCAL (1 << 4) 114*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_UDMA (1 << 3) 115*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_PHY (1 << 2) 116*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_HOT_PLUG (1 << 1) 117*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_PWR_STCG (1 << 0) 118*dfd1d0fcSMichal Meloun #define PCIE_CLIENT_INT_LEGACY (PCIE_CLIENT_INT_INTA | \ 119*dfd1d0fcSMichal Meloun PCIE_CLIENT_INT_INTB | \ 120*dfd1d0fcSMichal Meloun PCIE_CLIENT_INT_INTC | \ 121*dfd1d0fcSMichal Meloun PCIE_CLIENT_INT_INTD) 122*dfd1d0fcSMichal Meloun 123*dfd1d0fcSMichal Meloun #define PCIE_CORE_CTRL0 0x900000 124*dfd1d0fcSMichal Meloun #define CORE_CTRL_LANES_GET(x) (((x) >> 20) & 0x3) 125*dfd1d0fcSMichal Meloun #define PCIE_CORE_CTRL1 0x900004 126*dfd1d0fcSMichal Meloun #define PCIE_CORE_CONFIG_VENDOR 0x900044 127*dfd1d0fcSMichal Meloun #define PCIE_CORE_INT_STATUS 0x90020c 128*dfd1d0fcSMichal Meloun #define PCIE_CORE_INT_PRFPE (1 << 0) 129*dfd1d0fcSMichal Meloun #define PCIE_CORE_INT_CRFPE (1 << 1) 130*dfd1d0fcSMichal Meloun #define PCIE_CORE_INT_RRPE (1 << 2) 131*dfd1d0fcSMichal Meloun #define PCIE_CORE_INT_PRFO (1 << 3) 132*dfd1d0fcSMichal Meloun #define PCIE_CORE_INT_CRFO (1 << 4) 133*dfd1d0fcSMichal Meloun #define PCIE_CORE_INT_RT (1 << 5) 134*dfd1d0fcSMichal Meloun #define PCIE_CORE_INT_RTR (1 << 6) 135*dfd1d0fcSMichal Meloun #define PCIE_CORE_INT_PE (1 << 7) 136*dfd1d0fcSMichal Meloun #define PCIE_CORE_INT_MTR (1 << 8) 137*dfd1d0fcSMichal Meloun #define PCIE_CORE_INT_UCR (1 << 9) 138*dfd1d0fcSMichal Meloun #define PCIE_CORE_INT_FCE (1 << 10) 139*dfd1d0fcSMichal Meloun #define PCIE_CORE_INT_CT (1 << 11) 140*dfd1d0fcSMichal Meloun #define PCIE_CORE_INT_UTC (1 << 18) 141*dfd1d0fcSMichal Meloun #define PCIE_CORE_INT_MMVC (1 << 19) 142*dfd1d0fcSMichal Meloun #define PCIE_CORE_INT_MASK 0x900210 143*dfd1d0fcSMichal Meloun #define PCIE_CORE_PHY_FUNC_CONF 0x9002C0 144*dfd1d0fcSMichal Meloun #define PCIE_CORE_RC_BAR_CONF 0x900300 145*dfd1d0fcSMichal Meloun 146*dfd1d0fcSMichal Meloun #define PCIE_RC_CONFIG_STD_BASE 0x800000 147*dfd1d0fcSMichal Meloun #define PCIE_RC_CONFIG_PRIV_BASE 0xA00000 148*dfd1d0fcSMichal Meloun #define PCIE_RC_CONFIG_DCSR 0xA000C8 149*dfd1d0fcSMichal Meloun #define PCIE_RC_CONFIG_DCSR_MPS_MASK (0x7 << 5) 150*dfd1d0fcSMichal Meloun #define PCIE_RC_CONFIG_DCSR_MPS_128 (0 << 5) 151*dfd1d0fcSMichal Meloun #define PCIE_RC_CONFIG_DCSR_MPS_256 (1 << 5) 152*dfd1d0fcSMichal Meloun #define PCIE_RC_CONFIG_LINK_CAP 0xA00CC 153*dfd1d0fcSMichal Meloun #define PCIE_RC_CONFIG_LINK_CAP_L0S (1 << 10) 154*dfd1d0fcSMichal Meloun 155*dfd1d0fcSMichal Meloun #define PCIE_RC_CONFIG_LCS 0xA000D0 156*dfd1d0fcSMichal Meloun #define PCIE_RC_CONFIG_THP_CAP 0xA00274 157*dfd1d0fcSMichal Meloun #define PCIE_RC_CONFIG_THP_CAP_NEXT_MASK 0xFFF00000 158*dfd1d0fcSMichal Meloun 159*dfd1d0fcSMichal Meloun #define PCIE_CORE_OB_ADDR0(n) (0xC00000 + 0x20 * (n) + 0x00) 160*dfd1d0fcSMichal Meloun #define PCIE_CORE_OB_ADDR1(n) (0xC00000 + 0x20 * (n) + 0x04) 161*dfd1d0fcSMichal Meloun #define PCIE_CORE_OB_DESC0(n) (0xC00000 + 0x20 * (n) + 0x08) 162*dfd1d0fcSMichal Meloun #define PCIE_CORE_OB_DESC1(n) (0xC00000 + 0x20 * (n) + 0x0C) 163*dfd1d0fcSMichal Meloun #define PCIE_CORE_OB_DESC2(n) (0xC00000 + 0x20 * (n) + 0x10) 164*dfd1d0fcSMichal Meloun #define PCIE_CORE_OB_DESC3(n) (0xC00000 + 0x20 * (n) + 0x14) 165*dfd1d0fcSMichal Meloun 166*dfd1d0fcSMichal Meloun #define PCIE_CORE_IB_ADDR0(n) (0xC00800 + 0x8 * (n) + 0x00) 167*dfd1d0fcSMichal Meloun #define PCIE_CORE_IB_ADDR1(n) (0xC00800 + 0x8 * (n) + 0x04) 168*dfd1d0fcSMichal Meloun 169*dfd1d0fcSMichal Meloun #define PRIV_CFG_RD4(sc, reg) \ 170*dfd1d0fcSMichal Meloun (uint32_t)rk_pcie_local_cfg_read(sc, true, reg, 4) 171*dfd1d0fcSMichal Meloun #define PRIV_CFG_RD2(sc, reg) \ 172*dfd1d0fcSMichal Meloun (uint16_t)rk_pcie_local_cfg_read(sc, true, reg, 2) 173*dfd1d0fcSMichal Meloun #define PRIV_CFG_RD1(sc, reg) \ 174*dfd1d0fcSMichal Meloun (uint8_t)rk_pcie_local_cfg_read(sc, true, reg, 1) 175*dfd1d0fcSMichal Meloun #define PRIV_CFG_WR4(sc, reg, val) \ 176*dfd1d0fcSMichal Meloun rk_pcie_local_cfg_write(sc, true, reg, val, 4) 177*dfd1d0fcSMichal Meloun #define PRIV_CFG_WR2(sc, reg, val) \ 178*dfd1d0fcSMichal Meloun rk_pcie_local_cfg_write(sc, true, reg, val, 2) 179*dfd1d0fcSMichal Meloun #define PRIV_CFG_WR1(sc, reg, val) \ 180*dfd1d0fcSMichal Meloun rk_pcie_local_cfg_write(sc, true, reg, val, 1) 181*dfd1d0fcSMichal Meloun 182*dfd1d0fcSMichal Meloun #define APB_WR4(_sc, _r, _v) bus_write_4((_sc)->apb_mem_res, (_r), (_v)) 183*dfd1d0fcSMichal Meloun #define APB_RD4(_sc, _r) bus_read_4((_sc)->apb_mem_res, (_r)) 184*dfd1d0fcSMichal Meloun 185*dfd1d0fcSMichal Meloun #define MAX_LANES 4 186*dfd1d0fcSMichal Meloun 187*dfd1d0fcSMichal Meloun #define RK_PCIE_ENABLE_MSI 188*dfd1d0fcSMichal Meloun #define RK_PCIE_ENABLE_MSIX 189*dfd1d0fcSMichal Meloun 190*dfd1d0fcSMichal Meloun struct rk_pcie_softc { 191*dfd1d0fcSMichal Meloun struct ofw_pci_softc ofw_pci; /* Must be first */ 192*dfd1d0fcSMichal Meloun 193*dfd1d0fcSMichal Meloun struct resource *axi_mem_res; 194*dfd1d0fcSMichal Meloun struct resource *apb_mem_res; 195*dfd1d0fcSMichal Meloun struct resource *client_irq_res; 196*dfd1d0fcSMichal Meloun struct resource *legacy_irq_res; 197*dfd1d0fcSMichal Meloun struct resource *sys_irq_res; 198*dfd1d0fcSMichal Meloun void *client_irq_cookie; 199*dfd1d0fcSMichal Meloun void *legacy_irq_cookie; 200*dfd1d0fcSMichal Meloun void *sys_irq_cookie; 201*dfd1d0fcSMichal Meloun 202*dfd1d0fcSMichal Meloun device_t dev; 203*dfd1d0fcSMichal Meloun phandle_t node; 204*dfd1d0fcSMichal Meloun struct mtx mtx; 205*dfd1d0fcSMichal Meloun 206*dfd1d0fcSMichal Meloun 207*dfd1d0fcSMichal Meloun struct ofw_pci_range mem_range; 208*dfd1d0fcSMichal Meloun struct ofw_pci_range pref_mem_range; 209*dfd1d0fcSMichal Meloun struct ofw_pci_range io_range; 210*dfd1d0fcSMichal Meloun 211*dfd1d0fcSMichal Meloun bool coherent; 212*dfd1d0fcSMichal Meloun bus_dma_tag_t dmat; 213*dfd1d0fcSMichal Meloun 214*dfd1d0fcSMichal Meloun int num_lanes; 215*dfd1d0fcSMichal Meloun bool link_is_gen2; 216*dfd1d0fcSMichal Meloun bool no_l0s; 217*dfd1d0fcSMichal Meloun 218*dfd1d0fcSMichal Meloun u_int bus_start; 219*dfd1d0fcSMichal Meloun u_int bus_end; 220*dfd1d0fcSMichal Meloun u_int root_bus; 221*dfd1d0fcSMichal Meloun u_int sub_bus; 222*dfd1d0fcSMichal Meloun 223*dfd1d0fcSMichal Meloun regulator_t supply_12v; 224*dfd1d0fcSMichal Meloun regulator_t supply_3v3; 225*dfd1d0fcSMichal Meloun regulator_t supply_1v8; 226*dfd1d0fcSMichal Meloun regulator_t supply_0v9; 227*dfd1d0fcSMichal Meloun hwreset_t hwreset_core; 228*dfd1d0fcSMichal Meloun hwreset_t hwreset_mgmt; 229*dfd1d0fcSMichal Meloun hwreset_t hwreset_mgmt_sticky; 230*dfd1d0fcSMichal Meloun hwreset_t hwreset_pipe; 231*dfd1d0fcSMichal Meloun hwreset_t hwreset_pm; 232*dfd1d0fcSMichal Meloun hwreset_t hwreset_aclk; 233*dfd1d0fcSMichal Meloun hwreset_t hwreset_pclk; 234*dfd1d0fcSMichal Meloun clk_t clk_aclk; 235*dfd1d0fcSMichal Meloun clk_t clk_aclk_perf; 236*dfd1d0fcSMichal Meloun clk_t clk_hclk; 237*dfd1d0fcSMichal Meloun clk_t clk_pm; 238*dfd1d0fcSMichal Meloun phy_t phys[MAX_LANES]; 239*dfd1d0fcSMichal Meloun gpio_pin_t gpio_ep; 240*dfd1d0fcSMichal Meloun }; 241*dfd1d0fcSMichal Meloun 242*dfd1d0fcSMichal Meloun /* Compatible devices. */ 243*dfd1d0fcSMichal Meloun static struct ofw_compat_data compat_data[] = { 244*dfd1d0fcSMichal Meloun {"rockchip,rk3399-pcie", 1}, 245*dfd1d0fcSMichal Meloun {NULL, 0}, 246*dfd1d0fcSMichal Meloun }; 247*dfd1d0fcSMichal Meloun 248*dfd1d0fcSMichal Meloun 249*dfd1d0fcSMichal Meloun static uint32_t 250*dfd1d0fcSMichal Meloun rk_pcie_local_cfg_read(struct rk_pcie_softc *sc, bool priv, u_int reg, 251*dfd1d0fcSMichal Meloun int bytes) 252*dfd1d0fcSMichal Meloun { 253*dfd1d0fcSMichal Meloun uint32_t val; 254*dfd1d0fcSMichal Meloun bus_addr_t base; 255*dfd1d0fcSMichal Meloun 256*dfd1d0fcSMichal Meloun if (priv) 257*dfd1d0fcSMichal Meloun base = PCIE_RC_CONFIG_PRIV_BASE; 258*dfd1d0fcSMichal Meloun else 259*dfd1d0fcSMichal Meloun base = PCIE_RC_CONFIG_STD_BASE; 260*dfd1d0fcSMichal Meloun 261*dfd1d0fcSMichal Meloun switch (bytes) { 262*dfd1d0fcSMichal Meloun case 4: 263*dfd1d0fcSMichal Meloun val = bus_read_4(sc->apb_mem_res, base + reg); 264*dfd1d0fcSMichal Meloun break; 265*dfd1d0fcSMichal Meloun case 2: 266*dfd1d0fcSMichal Meloun val = bus_read_2(sc->apb_mem_res, base + reg); 267*dfd1d0fcSMichal Meloun break; 268*dfd1d0fcSMichal Meloun case 1: 269*dfd1d0fcSMichal Meloun val = bus_read_1(sc->apb_mem_res, base + reg); 270*dfd1d0fcSMichal Meloun break; 271*dfd1d0fcSMichal Meloun default: 272*dfd1d0fcSMichal Meloun val = 0xFFFFFFFF; 273*dfd1d0fcSMichal Meloun } 274*dfd1d0fcSMichal Meloun return (val); 275*dfd1d0fcSMichal Meloun } 276*dfd1d0fcSMichal Meloun 277*dfd1d0fcSMichal Meloun static void 278*dfd1d0fcSMichal Meloun rk_pcie_local_cfg_write(struct rk_pcie_softc *sc, bool priv, u_int reg, 279*dfd1d0fcSMichal Meloun uint32_t val, int bytes) 280*dfd1d0fcSMichal Meloun { 281*dfd1d0fcSMichal Meloun uint32_t val2; 282*dfd1d0fcSMichal Meloun bus_addr_t base; 283*dfd1d0fcSMichal Meloun 284*dfd1d0fcSMichal Meloun if (priv) 285*dfd1d0fcSMichal Meloun base = PCIE_RC_CONFIG_PRIV_BASE; 286*dfd1d0fcSMichal Meloun else 287*dfd1d0fcSMichal Meloun base = PCIE_RC_CONFIG_STD_BASE; 288*dfd1d0fcSMichal Meloun 289*dfd1d0fcSMichal Meloun switch (bytes) { 290*dfd1d0fcSMichal Meloun case 4: 291*dfd1d0fcSMichal Meloun bus_write_4(sc->apb_mem_res, base + reg, val); 292*dfd1d0fcSMichal Meloun break; 293*dfd1d0fcSMichal Meloun case 2: 294*dfd1d0fcSMichal Meloun val2 = bus_read_4(sc->apb_mem_res, base + (reg & ~3)); 295*dfd1d0fcSMichal Meloun val2 &= ~(0xffff << ((reg & 3) << 3)); 296*dfd1d0fcSMichal Meloun val2 |= ((val & 0xffff) << ((reg & 3) << 3)); 297*dfd1d0fcSMichal Meloun bus_write_4(sc->apb_mem_res, base + (reg & ~3), val2); 298*dfd1d0fcSMichal Meloun break; 299*dfd1d0fcSMichal Meloun case 1: 300*dfd1d0fcSMichal Meloun val2 = bus_read_4(sc->apb_mem_res, base + (reg & ~3)); 301*dfd1d0fcSMichal Meloun val2 &= ~(0xff << ((reg & 3) << 3)); 302*dfd1d0fcSMichal Meloun val2 |= ((val & 0xff) << ((reg & 3) << 3)); 303*dfd1d0fcSMichal Meloun bus_write_4(sc->apb_mem_res, base + (reg & ~3), val2); 304*dfd1d0fcSMichal Meloun break; 305*dfd1d0fcSMichal Meloun } 306*dfd1d0fcSMichal Meloun } 307*dfd1d0fcSMichal Meloun 308*dfd1d0fcSMichal Meloun 309*dfd1d0fcSMichal Meloun static bool 310*dfd1d0fcSMichal Meloun rk_pcie_check_dev(struct rk_pcie_softc *sc, u_int bus, u_int slot, u_int func, 311*dfd1d0fcSMichal Meloun u_int reg) 312*dfd1d0fcSMichal Meloun { 313*dfd1d0fcSMichal Meloun uint32_t val; 314*dfd1d0fcSMichal Meloun 315*dfd1d0fcSMichal Meloun if (bus < sc->bus_start || bus > sc->bus_end || slot > PCI_SLOTMAX || 316*dfd1d0fcSMichal Meloun func > PCI_FUNCMAX || reg > PCI_REGMAX) 317*dfd1d0fcSMichal Meloun return (false); 318*dfd1d0fcSMichal Meloun 319*dfd1d0fcSMichal Meloun if (bus == sc->root_bus) { 320*dfd1d0fcSMichal Meloun /* we have only 1 device with 1 function root port */ 321*dfd1d0fcSMichal Meloun if (slot > 0 || func > 0) 322*dfd1d0fcSMichal Meloun return (false); 323*dfd1d0fcSMichal Meloun return (true); 324*dfd1d0fcSMichal Meloun } 325*dfd1d0fcSMichal Meloun 326*dfd1d0fcSMichal Meloun /* link is needed for accessing non-root busses */ 327*dfd1d0fcSMichal Meloun val = APB_RD4(sc, PCIE_CLIENT_BASIC_STATUS1); 328*dfd1d0fcSMichal Meloun if (STATUS1_LINK_ST_GET(val) != STATUS1_LINK_ST_UP) 329*dfd1d0fcSMichal Meloun return (false); 330*dfd1d0fcSMichal Meloun 331*dfd1d0fcSMichal Meloun /* only one device is on first subordinate bus */ 332*dfd1d0fcSMichal Meloun if (bus == sc->sub_bus && slot) 333*dfd1d0fcSMichal Meloun return (false); 334*dfd1d0fcSMichal Meloun return (true); 335*dfd1d0fcSMichal Meloun } 336*dfd1d0fcSMichal Meloun 337*dfd1d0fcSMichal Meloun 338*dfd1d0fcSMichal Meloun static void 339*dfd1d0fcSMichal Meloun rk_pcie_map_out_atu(struct rk_pcie_softc *sc, int idx, int type, 340*dfd1d0fcSMichal Meloun int num_bits, uint64_t pa) 341*dfd1d0fcSMichal Meloun { 342*dfd1d0fcSMichal Meloun uint32_t addr0; 343*dfd1d0fcSMichal Meloun uint64_t max_size; 344*dfd1d0fcSMichal Meloun 345*dfd1d0fcSMichal Meloun 346*dfd1d0fcSMichal Meloun /* Check HW constrains */ 347*dfd1d0fcSMichal Meloun max_size = idx == 0 ? ATU_OB_REGION_0_SIZE: ATU_OB_REGION_SIZE; 348*dfd1d0fcSMichal Meloun KASSERT(idx < ATU_OB_REGIONS, ("Invalid region index: %d\n", idx)); 349*dfd1d0fcSMichal Meloun KASSERT(num_bits >= 7 && num_bits <= 63, 350*dfd1d0fcSMichal Meloun ("Bit width of region is invalid: %d\n", num_bits)); 351*dfd1d0fcSMichal Meloun KASSERT(max_size <= (1ULL << (num_bits + 1)), 352*dfd1d0fcSMichal Meloun ("Bit width is invalid for given region[%d]: %d\n", idx, num_bits)); 353*dfd1d0fcSMichal Meloun 354*dfd1d0fcSMichal Meloun addr0 = (uint32_t)pa & 0xFFFFFF00; 355*dfd1d0fcSMichal Meloun addr0 |= num_bits; 356*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CORE_OB_ADDR0(idx), addr0); 357*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CORE_OB_ADDR1(idx), (uint32_t)(pa >> 32)); 358*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CORE_OB_DESC0(idx), 1 << 23 | type); 359*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CORE_OB_DESC1(idx), sc->root_bus); 360*dfd1d0fcSMichal Meloun 361*dfd1d0fcSMichal Meloun /* Readback for sync */ 362*dfd1d0fcSMichal Meloun APB_RD4(sc, PCIE_CORE_OB_DESC1(idx)); 363*dfd1d0fcSMichal Meloun } 364*dfd1d0fcSMichal Meloun 365*dfd1d0fcSMichal Meloun static void 366*dfd1d0fcSMichal Meloun rk_pcie_map_cfg_atu(struct rk_pcie_softc *sc, int idx, int type) 367*dfd1d0fcSMichal Meloun { 368*dfd1d0fcSMichal Meloun 369*dfd1d0fcSMichal Meloun /* Check HW constrains */ 370*dfd1d0fcSMichal Meloun KASSERT(idx < ATU_OB_REGIONS, ("Invalid region index: %d\n", idx)); 371*dfd1d0fcSMichal Meloun 372*dfd1d0fcSMichal Meloun /* 373*dfd1d0fcSMichal Meloun * Config window is only 25 bits width, so we cannot encode full bus 374*dfd1d0fcSMichal Meloun * range into it. Remaining bits of bus number should be taken from 375*dfd1d0fcSMichal Meloun * DESC1 field. 376*dfd1d0fcSMichal Meloun */ 377*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CORE_OB_ADDR0(idx), 25 - 1); 378*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CORE_OB_ADDR1(idx), 0); 379*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CORE_OB_DESC0(idx), 1 << 23 | type); 380*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CORE_OB_DESC1(idx), sc->root_bus); 381*dfd1d0fcSMichal Meloun 382*dfd1d0fcSMichal Meloun /* Readback for sync */ 383*dfd1d0fcSMichal Meloun APB_RD4(sc, PCIE_CORE_OB_DESC1(idx)); 384*dfd1d0fcSMichal Meloun 385*dfd1d0fcSMichal Meloun } 386*dfd1d0fcSMichal Meloun 387*dfd1d0fcSMichal Meloun static void 388*dfd1d0fcSMichal Meloun rk_pcie_map_in_atu(struct rk_pcie_softc *sc, int idx, int num_bits, uint64_t pa) 389*dfd1d0fcSMichal Meloun { 390*dfd1d0fcSMichal Meloun uint32_t addr0; 391*dfd1d0fcSMichal Meloun 392*dfd1d0fcSMichal Meloun /* Check HW constrains */ 393*dfd1d0fcSMichal Meloun KASSERT(idx < ATU_IB_REGIONS, ("Invalid region index: %d\n", idx)); 394*dfd1d0fcSMichal Meloun KASSERT(num_bits >= 7 && num_bits <= 63, 395*dfd1d0fcSMichal Meloun ("Bit width of region is invalid: %d\n", num_bits)); 396*dfd1d0fcSMichal Meloun 397*dfd1d0fcSMichal Meloun addr0 = (uint32_t)pa & 0xFFFFFF00; 398*dfd1d0fcSMichal Meloun addr0 |= num_bits; 399*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CORE_IB_ADDR0(idx), addr0); 400*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CORE_IB_ADDR1(idx), (uint32_t)(pa >> 32)); 401*dfd1d0fcSMichal Meloun 402*dfd1d0fcSMichal Meloun /* Readback for sync */ 403*dfd1d0fcSMichal Meloun APB_RD4(sc, PCIE_CORE_IB_ADDR1(idx)); 404*dfd1d0fcSMichal Meloun } 405*dfd1d0fcSMichal Meloun 406*dfd1d0fcSMichal Meloun static int 407*dfd1d0fcSMichal Meloun rk_pcie_decode_ranges(struct rk_pcie_softc *sc, struct ofw_pci_range *ranges, 408*dfd1d0fcSMichal Meloun int nranges) 409*dfd1d0fcSMichal Meloun { 410*dfd1d0fcSMichal Meloun int i; 411*dfd1d0fcSMichal Meloun 412*dfd1d0fcSMichal Meloun for (i = 0; i < nranges; i++) { 413*dfd1d0fcSMichal Meloun if ((ranges[i].pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) == 414*dfd1d0fcSMichal Meloun OFW_PCI_PHYS_HI_SPACE_IO) { 415*dfd1d0fcSMichal Meloun if (sc->io_range.size != 0) { 416*dfd1d0fcSMichal Meloun device_printf(sc->dev, 417*dfd1d0fcSMichal Meloun "Duplicated IO range found in DT\n"); 418*dfd1d0fcSMichal Meloun return (ENXIO); 419*dfd1d0fcSMichal Meloun } 420*dfd1d0fcSMichal Meloun sc->io_range = ranges[i]; 421*dfd1d0fcSMichal Meloun } 422*dfd1d0fcSMichal Meloun if (((ranges[i].pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) == 423*dfd1d0fcSMichal Meloun OFW_PCI_PHYS_HI_SPACE_MEM64)) { 424*dfd1d0fcSMichal Meloun if (ranges[i].pci_hi & OFW_PCI_PHYS_HI_PREFETCHABLE) { 425*dfd1d0fcSMichal Meloun if (sc->pref_mem_range.size != 0) { 426*dfd1d0fcSMichal Meloun device_printf(sc->dev, 427*dfd1d0fcSMichal Meloun "Duplicated memory range found " 428*dfd1d0fcSMichal Meloun "in DT\n"); 429*dfd1d0fcSMichal Meloun return (ENXIO); 430*dfd1d0fcSMichal Meloun } 431*dfd1d0fcSMichal Meloun sc->pref_mem_range = ranges[i]; 432*dfd1d0fcSMichal Meloun } else { 433*dfd1d0fcSMichal Meloun if (sc->mem_range.size != 0) { 434*dfd1d0fcSMichal Meloun device_printf(sc->dev, 435*dfd1d0fcSMichal Meloun "Duplicated memory range found " 436*dfd1d0fcSMichal Meloun "in DT\n"); 437*dfd1d0fcSMichal Meloun return (ENXIO); 438*dfd1d0fcSMichal Meloun } 439*dfd1d0fcSMichal Meloun sc->mem_range = ranges[i]; 440*dfd1d0fcSMichal Meloun } 441*dfd1d0fcSMichal Meloun } 442*dfd1d0fcSMichal Meloun } 443*dfd1d0fcSMichal Meloun if (sc->mem_range.size == 0) { 444*dfd1d0fcSMichal Meloun device_printf(sc->dev, 445*dfd1d0fcSMichal Meloun " At least memory range should be defined in DT.\n"); 446*dfd1d0fcSMichal Meloun return (ENXIO); 447*dfd1d0fcSMichal Meloun } 448*dfd1d0fcSMichal Meloun return (0); 449*dfd1d0fcSMichal Meloun } 450*dfd1d0fcSMichal Meloun 451*dfd1d0fcSMichal Meloun /*----------------------------------------------------------------------------- 452*dfd1d0fcSMichal Meloun * 453*dfd1d0fcSMichal Meloun * P C I B I N T E R F A C E 454*dfd1d0fcSMichal Meloun */ 455*dfd1d0fcSMichal Meloun static uint32_t 456*dfd1d0fcSMichal Meloun rk_pcie_read_config(device_t dev, u_int bus, u_int slot, 457*dfd1d0fcSMichal Meloun u_int func, u_int reg, int bytes) 458*dfd1d0fcSMichal Meloun { 459*dfd1d0fcSMichal Meloun struct rk_pcie_softc *sc; 460*dfd1d0fcSMichal Meloun uint32_t data; 461*dfd1d0fcSMichal Meloun uint64_t addr; 462*dfd1d0fcSMichal Meloun int type; 463*dfd1d0fcSMichal Meloun 464*dfd1d0fcSMichal Meloun sc = device_get_softc(dev); 465*dfd1d0fcSMichal Meloun 466*dfd1d0fcSMichal Meloun if (!rk_pcie_check_dev(sc, bus, slot, func, reg)) 467*dfd1d0fcSMichal Meloun return (0xFFFFFFFFU); 468*dfd1d0fcSMichal Meloun 469*dfd1d0fcSMichal Meloun if (bus == sc->root_bus) 470*dfd1d0fcSMichal Meloun return (rk_pcie_local_cfg_read(sc, false, reg, bytes)); 471*dfd1d0fcSMichal Meloun 472*dfd1d0fcSMichal Meloun addr = ATU_CFG_BUS(bus) | ATU_CFG_SLOT(slot) | ATU_CFG_FUNC(func) | 473*dfd1d0fcSMichal Meloun ATU_CFG_REG(reg); 474*dfd1d0fcSMichal Meloun if (bus == sc->sub_bus) { 475*dfd1d0fcSMichal Meloun type = ATU_TYPE_CFG0; 476*dfd1d0fcSMichal Meloun } else { 477*dfd1d0fcSMichal Meloun type = ATU_TYPE_CFG1; 478*dfd1d0fcSMichal Meloun /* 479*dfd1d0fcSMichal Meloun * XXX FIXME: any attempt to generate type1 configuration 480*dfd1d0fcSMichal Meloun * access causes external data abort 481*dfd1d0fcSMichal Meloun */ 482*dfd1d0fcSMichal Meloun return (0xFFFFFFFFU); 483*dfd1d0fcSMichal Meloun } 484*dfd1d0fcSMichal Meloun rk_pcie_map_cfg_atu(sc, 0, type); 485*dfd1d0fcSMichal Meloun 486*dfd1d0fcSMichal Meloun switch (bytes) { 487*dfd1d0fcSMichal Meloun case 1: 488*dfd1d0fcSMichal Meloun data = bus_read_1(sc->axi_mem_res, addr); 489*dfd1d0fcSMichal Meloun break; 490*dfd1d0fcSMichal Meloun case 2: 491*dfd1d0fcSMichal Meloun data = bus_read_2(sc->axi_mem_res, addr); 492*dfd1d0fcSMichal Meloun break; 493*dfd1d0fcSMichal Meloun case 4: 494*dfd1d0fcSMichal Meloun data = bus_read_4(sc->axi_mem_res, addr); 495*dfd1d0fcSMichal Meloun break; 496*dfd1d0fcSMichal Meloun default: 497*dfd1d0fcSMichal Meloun data = 0xFFFFFFFFU; 498*dfd1d0fcSMichal Meloun } 499*dfd1d0fcSMichal Meloun return (data); 500*dfd1d0fcSMichal Meloun } 501*dfd1d0fcSMichal Meloun 502*dfd1d0fcSMichal Meloun static void 503*dfd1d0fcSMichal Meloun rk_pcie_write_config(device_t dev, u_int bus, u_int slot, 504*dfd1d0fcSMichal Meloun u_int func, u_int reg, uint32_t val, int bytes) 505*dfd1d0fcSMichal Meloun { 506*dfd1d0fcSMichal Meloun struct rk_pcie_softc *sc; 507*dfd1d0fcSMichal Meloun uint64_t addr; 508*dfd1d0fcSMichal Meloun int type; 509*dfd1d0fcSMichal Meloun 510*dfd1d0fcSMichal Meloun sc = device_get_softc(dev); 511*dfd1d0fcSMichal Meloun 512*dfd1d0fcSMichal Meloun if (!rk_pcie_check_dev(sc, bus, slot, func, reg)) 513*dfd1d0fcSMichal Meloun return; 514*dfd1d0fcSMichal Meloun 515*dfd1d0fcSMichal Meloun if (bus == sc->root_bus) 516*dfd1d0fcSMichal Meloun return (rk_pcie_local_cfg_write(sc, false, reg, val, bytes)); 517*dfd1d0fcSMichal Meloun 518*dfd1d0fcSMichal Meloun addr = ATU_CFG_BUS(bus) | ATU_CFG_SLOT(slot) | ATU_CFG_FUNC(func) | 519*dfd1d0fcSMichal Meloun ATU_CFG_REG(reg); 520*dfd1d0fcSMichal Meloun if (bus == sc->sub_bus){ 521*dfd1d0fcSMichal Meloun type = ATU_TYPE_CFG0; 522*dfd1d0fcSMichal Meloun } else { 523*dfd1d0fcSMichal Meloun type = ATU_TYPE_CFG1; 524*dfd1d0fcSMichal Meloun /* 525*dfd1d0fcSMichal Meloun * XXX FIXME: any attempt to generate type1 configuration 526*dfd1d0fcSMichal Meloun * access causes external data abort 527*dfd1d0fcSMichal Meloun */ 528*dfd1d0fcSMichal Meloun return; 529*dfd1d0fcSMichal Meloun } 530*dfd1d0fcSMichal Meloun rk_pcie_map_cfg_atu(sc, 0, type); 531*dfd1d0fcSMichal Meloun 532*dfd1d0fcSMichal Meloun switch (bytes) { 533*dfd1d0fcSMichal Meloun case 1: 534*dfd1d0fcSMichal Meloun bus_write_1(sc->axi_mem_res, addr, val); 535*dfd1d0fcSMichal Meloun break; 536*dfd1d0fcSMichal Meloun case 2: 537*dfd1d0fcSMichal Meloun bus_write_2(sc->axi_mem_res, addr, val); 538*dfd1d0fcSMichal Meloun break; 539*dfd1d0fcSMichal Meloun case 4: 540*dfd1d0fcSMichal Meloun bus_write_4(sc->axi_mem_res, addr, val); 541*dfd1d0fcSMichal Meloun break; 542*dfd1d0fcSMichal Meloun default: 543*dfd1d0fcSMichal Meloun break; 544*dfd1d0fcSMichal Meloun } 545*dfd1d0fcSMichal Meloun } 546*dfd1d0fcSMichal Meloun 547*dfd1d0fcSMichal Meloun #ifdef RK_PCIE_ENABLE_MSI 548*dfd1d0fcSMichal Meloun static int 549*dfd1d0fcSMichal Meloun rk_pcie_alloc_msi(device_t pci, device_t child, int count, 550*dfd1d0fcSMichal Meloun int maxcount, int *irqs) 551*dfd1d0fcSMichal Meloun { 552*dfd1d0fcSMichal Meloun phandle_t msi_parent; 553*dfd1d0fcSMichal Meloun int rv; 554*dfd1d0fcSMichal Meloun 555*dfd1d0fcSMichal Meloun rv = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), 556*dfd1d0fcSMichal Meloun &msi_parent, NULL); 557*dfd1d0fcSMichal Meloun if (rv != 0) 558*dfd1d0fcSMichal Meloun return (rv); 559*dfd1d0fcSMichal Meloun 560*dfd1d0fcSMichal Meloun rv = intr_alloc_msi(pci, child, msi_parent, count, maxcount,irqs); 561*dfd1d0fcSMichal Meloun return (rv); 562*dfd1d0fcSMichal Meloun } 563*dfd1d0fcSMichal Meloun 564*dfd1d0fcSMichal Meloun static int 565*dfd1d0fcSMichal Meloun rk_pcie_release_msi(device_t pci, device_t child, int count, int *irqs) 566*dfd1d0fcSMichal Meloun { 567*dfd1d0fcSMichal Meloun phandle_t msi_parent; 568*dfd1d0fcSMichal Meloun int rv; 569*dfd1d0fcSMichal Meloun 570*dfd1d0fcSMichal Meloun rv = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), 571*dfd1d0fcSMichal Meloun &msi_parent, NULL); 572*dfd1d0fcSMichal Meloun if (rv != 0) 573*dfd1d0fcSMichal Meloun return (rv); 574*dfd1d0fcSMichal Meloun rv = intr_release_msi(pci, child, msi_parent, count, irqs); 575*dfd1d0fcSMichal Meloun return (rv); 576*dfd1d0fcSMichal Meloun } 577*dfd1d0fcSMichal Meloun #endif 578*dfd1d0fcSMichal Meloun 579*dfd1d0fcSMichal Meloun static int 580*dfd1d0fcSMichal Meloun rk_pcie_map_msi(device_t pci, device_t child, int irq, uint64_t *addr, 581*dfd1d0fcSMichal Meloun uint32_t *data) 582*dfd1d0fcSMichal Meloun { 583*dfd1d0fcSMichal Meloun phandle_t msi_parent; 584*dfd1d0fcSMichal Meloun int rv; 585*dfd1d0fcSMichal Meloun 586*dfd1d0fcSMichal Meloun rv = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), 587*dfd1d0fcSMichal Meloun &msi_parent, NULL); 588*dfd1d0fcSMichal Meloun if (rv != 0) 589*dfd1d0fcSMichal Meloun return (rv); 590*dfd1d0fcSMichal Meloun rv = intr_map_msi(pci, child, msi_parent, irq, addr, data); 591*dfd1d0fcSMichal Meloun return (rv); 592*dfd1d0fcSMichal Meloun } 593*dfd1d0fcSMichal Meloun 594*dfd1d0fcSMichal Meloun #ifdef RK_PCIE_ENABLE_MSIX 595*dfd1d0fcSMichal Meloun static int 596*dfd1d0fcSMichal Meloun rk_pcie_alloc_msix(device_t pci, device_t child, int *irq) 597*dfd1d0fcSMichal Meloun { 598*dfd1d0fcSMichal Meloun phandle_t msi_parent; 599*dfd1d0fcSMichal Meloun int rv; 600*dfd1d0fcSMichal Meloun 601*dfd1d0fcSMichal Meloun rv = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), 602*dfd1d0fcSMichal Meloun &msi_parent, NULL); 603*dfd1d0fcSMichal Meloun if (rv != 0) 604*dfd1d0fcSMichal Meloun return (rv); 605*dfd1d0fcSMichal Meloun rv = intr_alloc_msix(pci, child, msi_parent, irq); 606*dfd1d0fcSMichal Meloun return (rv); 607*dfd1d0fcSMichal Meloun } 608*dfd1d0fcSMichal Meloun 609*dfd1d0fcSMichal Meloun static int 610*dfd1d0fcSMichal Meloun rk_pcie_release_msix(device_t pci, device_t child, int irq) 611*dfd1d0fcSMichal Meloun { 612*dfd1d0fcSMichal Meloun phandle_t msi_parent; 613*dfd1d0fcSMichal Meloun int rv; 614*dfd1d0fcSMichal Meloun 615*dfd1d0fcSMichal Meloun rv = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), 616*dfd1d0fcSMichal Meloun &msi_parent, NULL); 617*dfd1d0fcSMichal Meloun if (rv != 0) 618*dfd1d0fcSMichal Meloun return (rv); 619*dfd1d0fcSMichal Meloun rv = intr_release_msix(pci, child, msi_parent, irq); 620*dfd1d0fcSMichal Meloun return (rv); 621*dfd1d0fcSMichal Meloun } 622*dfd1d0fcSMichal Meloun #endif 623*dfd1d0fcSMichal Meloun 624*dfd1d0fcSMichal Meloun static int 625*dfd1d0fcSMichal Meloun rk_pcie_get_id(device_t pci, device_t child, enum pci_id_type type, 626*dfd1d0fcSMichal Meloun uintptr_t *id) 627*dfd1d0fcSMichal Meloun { 628*dfd1d0fcSMichal Meloun phandle_t node; 629*dfd1d0fcSMichal Meloun int rv; 630*dfd1d0fcSMichal Meloun uint32_t rid; 631*dfd1d0fcSMichal Meloun uint16_t pci_rid; 632*dfd1d0fcSMichal Meloun 633*dfd1d0fcSMichal Meloun if (type != PCI_ID_MSI) 634*dfd1d0fcSMichal Meloun return (pcib_get_id(pci, child, type, id)); 635*dfd1d0fcSMichal Meloun 636*dfd1d0fcSMichal Meloun node = ofw_bus_get_node(pci); 637*dfd1d0fcSMichal Meloun pci_rid = pci_get_rid(child); 638*dfd1d0fcSMichal Meloun 639*dfd1d0fcSMichal Meloun rv = ofw_bus_msimap(node, pci_rid, NULL, &rid); 640*dfd1d0fcSMichal Meloun if (rv != 0) 641*dfd1d0fcSMichal Meloun return (rv); 642*dfd1d0fcSMichal Meloun 643*dfd1d0fcSMichal Meloun *id = rid; 644*dfd1d0fcSMichal Meloun return (0); 645*dfd1d0fcSMichal Meloun } 646*dfd1d0fcSMichal Meloun 647*dfd1d0fcSMichal Meloun static int 648*dfd1d0fcSMichal Meloun rk_pcie_route_interrupt(device_t bus, device_t dev, int pin) 649*dfd1d0fcSMichal Meloun { 650*dfd1d0fcSMichal Meloun struct rk_pcie_softc *sc; 651*dfd1d0fcSMichal Meloun u_int irq; 652*dfd1d0fcSMichal Meloun 653*dfd1d0fcSMichal Meloun sc = device_get_softc(bus); 654*dfd1d0fcSMichal Meloun irq = intr_map_clone_irq(rman_get_start(sc->legacy_irq_res)); 655*dfd1d0fcSMichal Meloun device_printf(bus, "route pin %d for device %d.%d to %u\n", 656*dfd1d0fcSMichal Meloun pin, pci_get_slot(dev), pci_get_function(dev), irq); 657*dfd1d0fcSMichal Meloun 658*dfd1d0fcSMichal Meloun return (irq); 659*dfd1d0fcSMichal Meloun } 660*dfd1d0fcSMichal Meloun 661*dfd1d0fcSMichal Meloun /*----------------------------------------------------------------------------- 662*dfd1d0fcSMichal Meloun * 663*dfd1d0fcSMichal Meloun * B U S / D E V I C E I N T E R F A C E 664*dfd1d0fcSMichal Meloun */ 665*dfd1d0fcSMichal Meloun static int 666*dfd1d0fcSMichal Meloun rk_pcie_parse_fdt_resources(struct rk_pcie_softc *sc) 667*dfd1d0fcSMichal Meloun { 668*dfd1d0fcSMichal Meloun int i, rv; 669*dfd1d0fcSMichal Meloun char buf[16]; 670*dfd1d0fcSMichal Meloun 671*dfd1d0fcSMichal Meloun /* Regulators. All are optional. */ 672*dfd1d0fcSMichal Meloun rv = regulator_get_by_ofw_property(sc->dev, 0, 673*dfd1d0fcSMichal Meloun "vpcie12v-supply", &sc->supply_12v); 674*dfd1d0fcSMichal Meloun if (rv != 0 && rv != ENOENT) { 675*dfd1d0fcSMichal Meloun device_printf(sc->dev,"Cannot get 'vpcie12' regulator\n"); 676*dfd1d0fcSMichal Meloun return (ENXIO); 677*dfd1d0fcSMichal Meloun } 678*dfd1d0fcSMichal Meloun rv = regulator_get_by_ofw_property(sc->dev, 0, 679*dfd1d0fcSMichal Meloun "vpcie3v3-supply", &sc->supply_3v3); 680*dfd1d0fcSMichal Meloun if (rv != 0 && rv != ENOENT) { 681*dfd1d0fcSMichal Meloun device_printf(sc->dev,"Cannot get 'vpcie3v3' regulator\n"); 682*dfd1d0fcSMichal Meloun return (ENXIO); 683*dfd1d0fcSMichal Meloun } 684*dfd1d0fcSMichal Meloun rv = regulator_get_by_ofw_property(sc->dev, 0, 685*dfd1d0fcSMichal Meloun "vpcie1v8-supply", &sc->supply_1v8); 686*dfd1d0fcSMichal Meloun if (rv != 0 && rv != ENOENT) { 687*dfd1d0fcSMichal Meloun device_printf(sc->dev,"Cannot get 'vpcie1v8' regulator\n"); 688*dfd1d0fcSMichal Meloun return (ENXIO); 689*dfd1d0fcSMichal Meloun } 690*dfd1d0fcSMichal Meloun rv = regulator_get_by_ofw_property(sc->dev, 0, 691*dfd1d0fcSMichal Meloun "vpcie0v9-supply", &sc->supply_0v9); 692*dfd1d0fcSMichal Meloun if (rv != 0 && rv != ENOENT) { 693*dfd1d0fcSMichal Meloun device_printf(sc->dev,"Cannot get 'vpcie0v9' regulator\n"); 694*dfd1d0fcSMichal Meloun return (ENXIO); 695*dfd1d0fcSMichal Meloun } 696*dfd1d0fcSMichal Meloun 697*dfd1d0fcSMichal Meloun /* Resets. */ 698*dfd1d0fcSMichal Meloun rv = hwreset_get_by_ofw_name(sc->dev, 0, "core", &sc->hwreset_core); 699*dfd1d0fcSMichal Meloun if (rv != 0) { 700*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot get 'core' reset\n"); 701*dfd1d0fcSMichal Meloun return (ENXIO); 702*dfd1d0fcSMichal Meloun } 703*dfd1d0fcSMichal Meloun rv = hwreset_get_by_ofw_name(sc->dev, 0, "mgmt", &sc->hwreset_mgmt); 704*dfd1d0fcSMichal Meloun if (rv != 0) { 705*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot get 'mgmt' reset\n"); 706*dfd1d0fcSMichal Meloun return (ENXIO); 707*dfd1d0fcSMichal Meloun } 708*dfd1d0fcSMichal Meloun rv = hwreset_get_by_ofw_name(sc->dev, 0, "mgmt-sticky", 709*dfd1d0fcSMichal Meloun &sc->hwreset_mgmt_sticky); 710*dfd1d0fcSMichal Meloun if (rv != 0) { 711*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot get 'mgmt-sticky' reset\n"); 712*dfd1d0fcSMichal Meloun return (ENXIO); 713*dfd1d0fcSMichal Meloun } 714*dfd1d0fcSMichal Meloun rv = hwreset_get_by_ofw_name(sc->dev, 0, "pipe", &sc->hwreset_pipe); 715*dfd1d0fcSMichal Meloun if (rv != 0) { 716*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot get 'pipe' reset\n"); 717*dfd1d0fcSMichal Meloun return (ENXIO); 718*dfd1d0fcSMichal Meloun } 719*dfd1d0fcSMichal Meloun rv = hwreset_get_by_ofw_name(sc->dev, 0, "pm", &sc->hwreset_pm); 720*dfd1d0fcSMichal Meloun if (rv != 0) { 721*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot get 'pm' reset\n"); 722*dfd1d0fcSMichal Meloun return (ENXIO); 723*dfd1d0fcSMichal Meloun } 724*dfd1d0fcSMichal Meloun rv = hwreset_get_by_ofw_name(sc->dev, 0, "aclk", &sc->hwreset_aclk); 725*dfd1d0fcSMichal Meloun if (rv != 0) { 726*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot get 'aclk' reset\n"); 727*dfd1d0fcSMichal Meloun return (ENXIO); 728*dfd1d0fcSMichal Meloun } 729*dfd1d0fcSMichal Meloun rv = hwreset_get_by_ofw_name(sc->dev, 0, "pclk", &sc->hwreset_pclk); 730*dfd1d0fcSMichal Meloun if (rv != 0) { 731*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot get 'pclk' reset\n"); 732*dfd1d0fcSMichal Meloun return (ENXIO); 733*dfd1d0fcSMichal Meloun } 734*dfd1d0fcSMichal Meloun 735*dfd1d0fcSMichal Meloun /* Clocks. */ 736*dfd1d0fcSMichal Meloun rv = clk_get_by_ofw_name(sc->dev, 0, "aclk", &sc->clk_aclk); 737*dfd1d0fcSMichal Meloun if (rv != 0) { 738*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot get 'aclk' clock\n"); 739*dfd1d0fcSMichal Meloun return (ENXIO); 740*dfd1d0fcSMichal Meloun } 741*dfd1d0fcSMichal Meloun rv = clk_get_by_ofw_name(sc->dev, 0, "aclk-perf", &sc->clk_aclk_perf); 742*dfd1d0fcSMichal Meloun if (rv != 0) { 743*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot get 'aclk-perf' clock\n"); 744*dfd1d0fcSMichal Meloun return (ENXIO); 745*dfd1d0fcSMichal Meloun } 746*dfd1d0fcSMichal Meloun rv = clk_get_by_ofw_name(sc->dev, 0, "hclk", &sc->clk_hclk); 747*dfd1d0fcSMichal Meloun if (rv != 0) { 748*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot get 'hclk' clock\n"); 749*dfd1d0fcSMichal Meloun return (ENXIO); 750*dfd1d0fcSMichal Meloun } 751*dfd1d0fcSMichal Meloun rv = clk_get_by_ofw_name(sc->dev, 0, "pm", &sc->clk_pm); 752*dfd1d0fcSMichal Meloun if (rv != 0) { 753*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot get 'pm' clock\n"); 754*dfd1d0fcSMichal Meloun return (ENXIO); 755*dfd1d0fcSMichal Meloun } 756*dfd1d0fcSMichal Meloun 757*dfd1d0fcSMichal Meloun /* Phys. */ 758*dfd1d0fcSMichal Meloun for (i = 0; i < MAX_LANES; i++ ) { 759*dfd1d0fcSMichal Meloun sprintf (buf, "pcie-phy-%d", i); 760*dfd1d0fcSMichal Meloun rv = phy_get_by_ofw_name(sc->dev, 0, buf, sc->phys + i); 761*dfd1d0fcSMichal Meloun if (rv != 0) { 762*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot get '%s' phy\n", buf); 763*dfd1d0fcSMichal Meloun return (ENXIO); 764*dfd1d0fcSMichal Meloun } 765*dfd1d0fcSMichal Meloun } 766*dfd1d0fcSMichal Meloun 767*dfd1d0fcSMichal Meloun /* GPIO for PERST#. Optional */ 768*dfd1d0fcSMichal Meloun rv = gpio_pin_get_by_ofw_property(sc->dev, sc->node, "ep-gpios", 769*dfd1d0fcSMichal Meloun &sc->gpio_ep); 770*dfd1d0fcSMichal Meloun if (rv != 0 && rv != ENOENT) { 771*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot get 'ep-gpios' gpio\n"); 772*dfd1d0fcSMichal Meloun return (ENXIO); 773*dfd1d0fcSMichal Meloun } 774*dfd1d0fcSMichal Meloun 775*dfd1d0fcSMichal Meloun return (0); 776*dfd1d0fcSMichal Meloun } 777*dfd1d0fcSMichal Meloun 778*dfd1d0fcSMichal Meloun static int 779*dfd1d0fcSMichal Meloun rk_pcie_enable_resources(struct rk_pcie_softc *sc) 780*dfd1d0fcSMichal Meloun { 781*dfd1d0fcSMichal Meloun int i, rv; 782*dfd1d0fcSMichal Meloun uint32_t val; 783*dfd1d0fcSMichal Meloun 784*dfd1d0fcSMichal Meloun /* Assert all resets */ 785*dfd1d0fcSMichal Meloun rv = hwreset_assert(sc->hwreset_pclk); 786*dfd1d0fcSMichal Meloun if (rv != 0) { 787*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot assert 'pclk' reset\n"); 788*dfd1d0fcSMichal Meloun return (rv); 789*dfd1d0fcSMichal Meloun } 790*dfd1d0fcSMichal Meloun rv = hwreset_assert(sc->hwreset_aclk); 791*dfd1d0fcSMichal Meloun if (rv != 0) { 792*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot assert 'aclk' reset\n"); 793*dfd1d0fcSMichal Meloun return (rv); 794*dfd1d0fcSMichal Meloun } 795*dfd1d0fcSMichal Meloun rv = hwreset_assert(sc->hwreset_pm); 796*dfd1d0fcSMichal Meloun if (rv != 0) { 797*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot assert 'pm' reset\n"); 798*dfd1d0fcSMichal Meloun return (rv); 799*dfd1d0fcSMichal Meloun } 800*dfd1d0fcSMichal Meloun rv = hwreset_assert(sc->hwreset_pipe); 801*dfd1d0fcSMichal Meloun if (rv != 0) { 802*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot assert 'pipe' reset\n"); 803*dfd1d0fcSMichal Meloun return (rv); 804*dfd1d0fcSMichal Meloun } 805*dfd1d0fcSMichal Meloun rv = hwreset_assert(sc->hwreset_mgmt_sticky); 806*dfd1d0fcSMichal Meloun if (rv != 0) { 807*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot assert 'mgmt_sticky' reset\n"); 808*dfd1d0fcSMichal Meloun return (rv); 809*dfd1d0fcSMichal Meloun } 810*dfd1d0fcSMichal Meloun rv = hwreset_assert(sc->hwreset_mgmt); 811*dfd1d0fcSMichal Meloun if (rv != 0) { 812*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot assert 'hmgmt' reset\n"); 813*dfd1d0fcSMichal Meloun return (rv); 814*dfd1d0fcSMichal Meloun } 815*dfd1d0fcSMichal Meloun rv = hwreset_assert(sc->hwreset_core); 816*dfd1d0fcSMichal Meloun if (rv != 0) { 817*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot assert 'hcore' reset\n"); 818*dfd1d0fcSMichal Meloun return (rv); 819*dfd1d0fcSMichal Meloun } 820*dfd1d0fcSMichal Meloun DELAY(10000); 821*dfd1d0fcSMichal Meloun 822*dfd1d0fcSMichal Meloun /* Enable clockls */ 823*dfd1d0fcSMichal Meloun rv = clk_enable(sc->clk_aclk); 824*dfd1d0fcSMichal Meloun if (rv != 0) { 825*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot enable 'aclk' clock\n"); 826*dfd1d0fcSMichal Meloun return (rv); 827*dfd1d0fcSMichal Meloun } 828*dfd1d0fcSMichal Meloun rv = clk_enable(sc->clk_aclk_perf); 829*dfd1d0fcSMichal Meloun if (rv != 0) { 830*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot enable 'aclk_perf' clock\n"); 831*dfd1d0fcSMichal Meloun return (rv); 832*dfd1d0fcSMichal Meloun } 833*dfd1d0fcSMichal Meloun rv = clk_enable(sc->clk_hclk); 834*dfd1d0fcSMichal Meloun if (rv != 0) { 835*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot enable 'hclk' clock\n"); 836*dfd1d0fcSMichal Meloun return (rv); 837*dfd1d0fcSMichal Meloun } 838*dfd1d0fcSMichal Meloun rv = clk_enable(sc->clk_pm); 839*dfd1d0fcSMichal Meloun if (rv != 0) { 840*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot enable 'pm' clock\n"); 841*dfd1d0fcSMichal Meloun return (rv); 842*dfd1d0fcSMichal Meloun } 843*dfd1d0fcSMichal Meloun 844*dfd1d0fcSMichal Meloun /* Power up regulators */ 845*dfd1d0fcSMichal Meloun if (sc->supply_12v != NULL) { 846*dfd1d0fcSMichal Meloun rv = regulator_enable(sc->supply_12v); 847*dfd1d0fcSMichal Meloun if (rv != 0) { 848*dfd1d0fcSMichal Meloun device_printf(sc->dev, 849*dfd1d0fcSMichal Meloun "Cannot enable 'vpcie12' regulator\n"); 850*dfd1d0fcSMichal Meloun return (rv); 851*dfd1d0fcSMichal Meloun } 852*dfd1d0fcSMichal Meloun } 853*dfd1d0fcSMichal Meloun if (sc->supply_3v3 != NULL) { 854*dfd1d0fcSMichal Meloun rv = regulator_enable(sc->supply_3v3); 855*dfd1d0fcSMichal Meloun if (rv != 0) { 856*dfd1d0fcSMichal Meloun device_printf(sc->dev, 857*dfd1d0fcSMichal Meloun "Cannot enable 'vpcie3v3' regulator\n"); 858*dfd1d0fcSMichal Meloun return (rv); 859*dfd1d0fcSMichal Meloun } 860*dfd1d0fcSMichal Meloun } 861*dfd1d0fcSMichal Meloun if (sc->supply_1v8 != NULL) { 862*dfd1d0fcSMichal Meloun rv = regulator_enable(sc->supply_1v8); 863*dfd1d0fcSMichal Meloun if (rv != 0) { 864*dfd1d0fcSMichal Meloun device_printf(sc->dev, 865*dfd1d0fcSMichal Meloun "Cannot enable 'vpcie1v8' regulator\n"); 866*dfd1d0fcSMichal Meloun return (rv); 867*dfd1d0fcSMichal Meloun } 868*dfd1d0fcSMichal Meloun } 869*dfd1d0fcSMichal Meloun if (sc->supply_0v9 != NULL) { 870*dfd1d0fcSMichal Meloun rv = regulator_enable(sc->supply_0v9); 871*dfd1d0fcSMichal Meloun if (rv != 0) { 872*dfd1d0fcSMichal Meloun device_printf(sc->dev, 873*dfd1d0fcSMichal Meloun "Cannot enable 'vpcie1v8' regulator\n"); 874*dfd1d0fcSMichal Meloun return (rv); 875*dfd1d0fcSMichal Meloun } 876*dfd1d0fcSMichal Meloun } 877*dfd1d0fcSMichal Meloun DELAY(1000); 878*dfd1d0fcSMichal Meloun 879*dfd1d0fcSMichal Meloun /* Deassert basic resets*/ 880*dfd1d0fcSMichal Meloun rv = hwreset_deassert(sc->hwreset_pm); 881*dfd1d0fcSMichal Meloun if (rv != 0) { 882*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot deassert 'pm' reset\n"); 883*dfd1d0fcSMichal Meloun return (rv); 884*dfd1d0fcSMichal Meloun } 885*dfd1d0fcSMichal Meloun rv = hwreset_deassert(sc->hwreset_aclk); 886*dfd1d0fcSMichal Meloun if (rv != 0) { 887*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot deassert 'aclk' reset\n"); 888*dfd1d0fcSMichal Meloun return (rv); 889*dfd1d0fcSMichal Meloun } 890*dfd1d0fcSMichal Meloun rv = hwreset_deassert(sc->hwreset_pclk); 891*dfd1d0fcSMichal Meloun if (rv != 0) { 892*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot deassert 'pclk' reset\n"); 893*dfd1d0fcSMichal Meloun return (rv); 894*dfd1d0fcSMichal Meloun } 895*dfd1d0fcSMichal Meloun 896*dfd1d0fcSMichal Meloun /* Set basic PCIe core mode (RC, lanes, gen1 or 2) */ 897*dfd1d0fcSMichal Meloun val = STRAP_CONF_GEN_2 << 16 | 898*dfd1d0fcSMichal Meloun sc->link_is_gen2 ? STRAP_CONF_GEN_2: 0; 899*dfd1d0fcSMichal Meloun val |= STRAP_CONF_MODE_RC << 16 | STRAP_CONF_MODE_RC; 900*dfd1d0fcSMichal Meloun val |= STRAP_CONF_LANES(~0) << 16 | STRAP_CONF_LANES(sc->num_lanes); 901*dfd1d0fcSMichal Meloun val |= STRAP_CONF_ARI_EN << 16 | STRAP_CONF_ARI_EN; 902*dfd1d0fcSMichal Meloun val |= STRAP_CONF_CONF_EN << 16 | STRAP_CONF_CONF_EN; 903*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CLIENT_BASIC_STRAP_CONF, val); 904*dfd1d0fcSMichal Meloun 905*dfd1d0fcSMichal Meloun for (i = 0; i < MAX_LANES; i++) { 906*dfd1d0fcSMichal Meloun rv = phy_enable(sc->phys[i]); 907*dfd1d0fcSMichal Meloun if (rv != 0) { 908*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot enable phy %d\n", i); 909*dfd1d0fcSMichal Meloun return (rv); 910*dfd1d0fcSMichal Meloun } 911*dfd1d0fcSMichal Meloun } 912*dfd1d0fcSMichal Meloun 913*dfd1d0fcSMichal Meloun /* Deassert rest of resets - order is important ! */ 914*dfd1d0fcSMichal Meloun rv = hwreset_deassert(sc->hwreset_mgmt_sticky); 915*dfd1d0fcSMichal Meloun if (rv != 0) { 916*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot deassert 'mgmt_sticky' reset\n"); 917*dfd1d0fcSMichal Meloun return (rv); 918*dfd1d0fcSMichal Meloun } 919*dfd1d0fcSMichal Meloun rv = hwreset_deassert(sc->hwreset_core); 920*dfd1d0fcSMichal Meloun if (rv != 0) { 921*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot deassert 'core' reset\n"); 922*dfd1d0fcSMichal Meloun return (rv); 923*dfd1d0fcSMichal Meloun } 924*dfd1d0fcSMichal Meloun rv = hwreset_deassert(sc->hwreset_mgmt); 925*dfd1d0fcSMichal Meloun if (rv != 0) { 926*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot deassert 'mgmt' reset\n"); 927*dfd1d0fcSMichal Meloun return (rv); 928*dfd1d0fcSMichal Meloun } 929*dfd1d0fcSMichal Meloun rv = hwreset_deassert(sc->hwreset_pipe); 930*dfd1d0fcSMichal Meloun if (rv != 0) { 931*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot deassert 'pipe' reset\n"); 932*dfd1d0fcSMichal Meloun return (rv); 933*dfd1d0fcSMichal Meloun } 934*dfd1d0fcSMichal Meloun return (0); 935*dfd1d0fcSMichal Meloun } 936*dfd1d0fcSMichal Meloun 937*dfd1d0fcSMichal Meloun static int 938*dfd1d0fcSMichal Meloun rk_pcie_setup_hw(struct rk_pcie_softc *sc) 939*dfd1d0fcSMichal Meloun { 940*dfd1d0fcSMichal Meloun uint32_t val; 941*dfd1d0fcSMichal Meloun int i, rv; 942*dfd1d0fcSMichal Meloun 943*dfd1d0fcSMichal Meloun /* Assert PERST# if defined */ 944*dfd1d0fcSMichal Meloun if (sc->gpio_ep != NULL) { 945*dfd1d0fcSMichal Meloun rv = gpio_pin_set_active(sc->gpio_ep, 0); 946*dfd1d0fcSMichal Meloun if (rv != 0) { 947*dfd1d0fcSMichal Meloun device_printf(sc->dev, 948*dfd1d0fcSMichal Meloun "Cannot clear 'gpio-ep' gpio\n"); 949*dfd1d0fcSMichal Meloun return (rv); 950*dfd1d0fcSMichal Meloun } 951*dfd1d0fcSMichal Meloun } 952*dfd1d0fcSMichal Meloun 953*dfd1d0fcSMichal Meloun rv = rk_pcie_enable_resources(sc); 954*dfd1d0fcSMichal Meloun if (rv != 0) 955*dfd1d0fcSMichal Meloun return(rv); 956*dfd1d0fcSMichal Meloun 957*dfd1d0fcSMichal Meloun /* Fix wrong default value for transmited FTS for L0s exit */ 958*dfd1d0fcSMichal Meloun val = APB_RD4(sc, PCIE_CORE_CTRL1); 959*dfd1d0fcSMichal Meloun val |= 0xFFFF << 8; 960*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CORE_CTRL1, val); 961*dfd1d0fcSMichal Meloun 962*dfd1d0fcSMichal Meloun /* Setup PCIE Link Status & Control register */ 963*dfd1d0fcSMichal Meloun val = APB_RD4(sc, PCIE_RC_CONFIG_LCS); 964*dfd1d0fcSMichal Meloun val |= PCIEM_LINK_CTL_COMMON_CLOCK; 965*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_RC_CONFIG_LCS, val); 966*dfd1d0fcSMichal Meloun val = APB_RD4(sc, PCIE_RC_CONFIG_LCS); 967*dfd1d0fcSMichal Meloun val |= PCIEM_LINK_CTL_RCB; 968*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_RC_CONFIG_LCS, val); 969*dfd1d0fcSMichal Meloun 970*dfd1d0fcSMichal Meloun /* Enable training for GEN1 */ 971*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CLIENT_BASIC_STRAP_CONF, 972*dfd1d0fcSMichal Meloun STRAP_CONF_LINK_TRAIN_EN << 16 | STRAP_CONF_LINK_TRAIN_EN); 973*dfd1d0fcSMichal Meloun 974*dfd1d0fcSMichal Meloun /* Deassert PERST# if defined */ 975*dfd1d0fcSMichal Meloun if (sc->gpio_ep != NULL) { 976*dfd1d0fcSMichal Meloun rv = gpio_pin_set_active(sc->gpio_ep, 1); 977*dfd1d0fcSMichal Meloun if (rv != 0) { 978*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Cannot set 'gpio-ep' gpio\n"); 979*dfd1d0fcSMichal Meloun return (rv); 980*dfd1d0fcSMichal Meloun } 981*dfd1d0fcSMichal Meloun } 982*dfd1d0fcSMichal Meloun 983*dfd1d0fcSMichal Meloun /* Wait for link */ 984*dfd1d0fcSMichal Meloun for (i = 500; i > 0; i--) { 985*dfd1d0fcSMichal Meloun val = APB_RD4(sc, PCIE_CLIENT_BASIC_STATUS1); 986*dfd1d0fcSMichal Meloun if (STATUS1_LINK_ST_GET(val) == STATUS1_LINK_ST_UP) 987*dfd1d0fcSMichal Meloun break; 988*dfd1d0fcSMichal Meloun DELAY(1000); 989*dfd1d0fcSMichal Meloun } 990*dfd1d0fcSMichal Meloun if (i <= 0) { 991*dfd1d0fcSMichal Meloun device_printf(sc->dev, 992*dfd1d0fcSMichal Meloun "Gen1 link training timeouted: 0x%08X.\n", val); 993*dfd1d0fcSMichal Meloun return (0); 994*dfd1d0fcSMichal Meloun } 995*dfd1d0fcSMichal Meloun 996*dfd1d0fcSMichal Meloun if (sc->link_is_gen2) { 997*dfd1d0fcSMichal Meloun val = APB_RD4(sc, PCIE_RC_CONFIG_LCS); 998*dfd1d0fcSMichal Meloun val |= PCIEM_LINK_CTL_RETRAIN_LINK; 999*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_RC_CONFIG_LCS, val); 1000*dfd1d0fcSMichal Meloun 1001*dfd1d0fcSMichal Meloun /* Wait for link */ 1002*dfd1d0fcSMichal Meloun for (i = 500; i > 0; i--) { 1003*dfd1d0fcSMichal Meloun val = APB_RD4(sc, PCIE_CLIENT_BASIC_STATUS1); 1004*dfd1d0fcSMichal Meloun if (STATUS1_LINK_ST_GET(val) == 1005*dfd1d0fcSMichal Meloun STATUS1_LINK_ST_UP) 1006*dfd1d0fcSMichal Meloun break; 1007*dfd1d0fcSMichal Meloun DELAY(1000); 1008*dfd1d0fcSMichal Meloun } 1009*dfd1d0fcSMichal Meloun if (i <= 0) 1010*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Gen2 link training " 1011*dfd1d0fcSMichal Meloun "timeouted: 0x%08X.\n", val); 1012*dfd1d0fcSMichal Meloun } 1013*dfd1d0fcSMichal Meloun 1014*dfd1d0fcSMichal Meloun val = APB_RD4(sc, PCIE_CORE_CTRL0); 1015*dfd1d0fcSMichal Meloun val = CORE_CTRL_LANES_GET(val); 1016*dfd1d0fcSMichal Meloun if (bootverbose) 1017*dfd1d0fcSMichal Meloun device_printf(sc->dev, "Link width: %d\n", 1 << val); 1018*dfd1d0fcSMichal Meloun 1019*dfd1d0fcSMichal Meloun return (0); 1020*dfd1d0fcSMichal Meloun } 1021*dfd1d0fcSMichal Meloun 1022*dfd1d0fcSMichal Meloun static int 1023*dfd1d0fcSMichal Meloun rk_pcie_setup_sw(struct rk_pcie_softc *sc) 1024*dfd1d0fcSMichal Meloun { 1025*dfd1d0fcSMichal Meloun uint32_t val; 1026*dfd1d0fcSMichal Meloun int i, region; 1027*dfd1d0fcSMichal Meloun 1028*dfd1d0fcSMichal Meloun pcib_bridge_init(sc->dev); 1029*dfd1d0fcSMichal Meloun 1030*dfd1d0fcSMichal Meloun 1031*dfd1d0fcSMichal Meloun /* Setup config registers */ 1032*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CORE_CONFIG_VENDOR, 0x1D87); /* Rockchip vendor ID*/ 1033*dfd1d0fcSMichal Meloun PRIV_CFG_WR1(sc, PCIR_CLASS, PCIC_BRIDGE); 1034*dfd1d0fcSMichal Meloun PRIV_CFG_WR1(sc, PCIR_SUBCLASS, PCIS_BRIDGE_PCI); 1035*dfd1d0fcSMichal Meloun PRIV_CFG_WR1(sc, PCIR_PRIBUS_1, sc->root_bus); 1036*dfd1d0fcSMichal Meloun PRIV_CFG_WR1(sc, PCIR_SECBUS_1, sc->sub_bus); 1037*dfd1d0fcSMichal Meloun PRIV_CFG_WR1(sc, PCIR_SUBBUS_1, sc->bus_end); 1038*dfd1d0fcSMichal Meloun PRIV_CFG_WR2(sc, PCIR_COMMAND, PCIM_CMD_MEMEN | 1039*dfd1d0fcSMichal Meloun PCIM_CMD_BUSMASTEREN | PCIM_CMD_SERRESPEN); 1040*dfd1d0fcSMichal Meloun 1041*dfd1d0fcSMichal Meloun /* Don't advertise L1 power substate */ 1042*dfd1d0fcSMichal Meloun val = APB_RD4(sc, PCIE_RC_CONFIG_THP_CAP); 1043*dfd1d0fcSMichal Meloun val &= ~PCIE_RC_CONFIG_THP_CAP_NEXT_MASK; 1044*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_RC_CONFIG_THP_CAP, val); 1045*dfd1d0fcSMichal Meloun 1046*dfd1d0fcSMichal Meloun /* Don't advertise L0s */ 1047*dfd1d0fcSMichal Meloun if (sc->no_l0s) { 1048*dfd1d0fcSMichal Meloun val = APB_RD4(sc, PCIE_RC_CONFIG_LINK_CAP); 1049*dfd1d0fcSMichal Meloun val &= ~PCIE_RC_CONFIG_THP_CAP_NEXT_MASK; 1050*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_RC_CONFIG_LINK_CAP_L0S, val); 1051*dfd1d0fcSMichal Meloun } 1052*dfd1d0fcSMichal Meloun 1053*dfd1d0fcSMichal Meloun /*Adjust maximum payload size*/ 1054*dfd1d0fcSMichal Meloun val = APB_RD4(sc, PCIE_RC_CONFIG_DCSR); 1055*dfd1d0fcSMichal Meloun val &= ~PCIE_RC_CONFIG_DCSR_MPS_MASK; 1056*dfd1d0fcSMichal Meloun val |= PCIE_RC_CONFIG_DCSR_MPS_128; 1057*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_RC_CONFIG_DCSR, val); 1058*dfd1d0fcSMichal Meloun 1059*dfd1d0fcSMichal Meloun /* 1060*dfd1d0fcSMichal Meloun * Prepare IB ATU 1061*dfd1d0fcSMichal Meloun * map whole address range in 1:1 mappings 1062*dfd1d0fcSMichal Meloun */ 1063*dfd1d0fcSMichal Meloun rk_pcie_map_in_atu(sc, 2, 64 - 1, 0); 1064*dfd1d0fcSMichal Meloun 1065*dfd1d0fcSMichal Meloun /* Prepare OB ATU */ 1066*dfd1d0fcSMichal Meloun /* - region 0 (32 MB) is used for config access */ 1067*dfd1d0fcSMichal Meloun region = 0; 1068*dfd1d0fcSMichal Meloun rk_pcie_map_out_atu(sc, region++, ATU_TYPE_CFG0, 25 - 1, 0); 1069*dfd1d0fcSMichal Meloun 1070*dfd1d0fcSMichal Meloun /* - then map memory (by using 1MB regions */ 1071*dfd1d0fcSMichal Meloun for (i = 0; i < sc->mem_range.size / ATU_OB_REGION_SIZE; i++) { 1072*dfd1d0fcSMichal Meloun rk_pcie_map_out_atu(sc, region++, ATU_TYPE_MEM, 1073*dfd1d0fcSMichal Meloun ATU_OB_REGION_SHIFT - 1, 1074*dfd1d0fcSMichal Meloun sc->mem_range.pci + ATU_OB_REGION_SIZE * i); 1075*dfd1d0fcSMichal Meloun } 1076*dfd1d0fcSMichal Meloun 1077*dfd1d0fcSMichal Meloun /* - IO space is next, one region typically*/ 1078*dfd1d0fcSMichal Meloun for (i = 0; i < sc->io_range.size / ATU_OB_REGION_SIZE; i++) { 1079*dfd1d0fcSMichal Meloun rk_pcie_map_out_atu(sc, region++, ATU_TYPE_IO, 1080*dfd1d0fcSMichal Meloun ATU_OB_REGION_SHIFT - 1, 1081*dfd1d0fcSMichal Meloun sc->io_range.pci + ATU_OB_REGION_SIZE * i); 1082*dfd1d0fcSMichal Meloun } 1083*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CORE_RC_BAR_CONF, 0); 1084*dfd1d0fcSMichal Meloun return (0); 1085*dfd1d0fcSMichal Meloun } 1086*dfd1d0fcSMichal Meloun 1087*dfd1d0fcSMichal Meloun static int 1088*dfd1d0fcSMichal Meloun rk_pcie_sys_irq(void *arg) 1089*dfd1d0fcSMichal Meloun { 1090*dfd1d0fcSMichal Meloun struct rk_pcie_softc *sc; 1091*dfd1d0fcSMichal Meloun uint32_t irq; 1092*dfd1d0fcSMichal Meloun 1093*dfd1d0fcSMichal Meloun sc = (struct rk_pcie_softc *)arg; 1094*dfd1d0fcSMichal Meloun irq = APB_RD4(sc, PCIE_CLIENT_INT_STATUS); 1095*dfd1d0fcSMichal Meloun if (irq & PCIE_CLIENT_INT_LOCAL) { 1096*dfd1d0fcSMichal Meloun irq = APB_RD4(sc, PCIE_CORE_INT_STATUS); 1097*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CORE_INT_STATUS, irq); 1098*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CLIENT_INT_STATUS, PCIE_CLIENT_INT_LOCAL); 1099*dfd1d0fcSMichal Meloun 1100*dfd1d0fcSMichal Meloun device_printf(sc->dev, "'sys' interrupt received: 0x%04X\n", 1101*dfd1d0fcSMichal Meloun irq); 1102*dfd1d0fcSMichal Meloun } 1103*dfd1d0fcSMichal Meloun 1104*dfd1d0fcSMichal Meloun return (FILTER_HANDLED); 1105*dfd1d0fcSMichal Meloun } 1106*dfd1d0fcSMichal Meloun 1107*dfd1d0fcSMichal Meloun static int 1108*dfd1d0fcSMichal Meloun rk_pcie_client_irq(void *arg) 1109*dfd1d0fcSMichal Meloun { 1110*dfd1d0fcSMichal Meloun struct rk_pcie_softc *sc; 1111*dfd1d0fcSMichal Meloun uint32_t irq; 1112*dfd1d0fcSMichal Meloun 1113*dfd1d0fcSMichal Meloun sc = (struct rk_pcie_softc *)arg; 1114*dfd1d0fcSMichal Meloun irq = APB_RD4(sc, PCIE_CLIENT_INT_STATUS); 1115*dfd1d0fcSMichal Meloun /* Clear causes handled by other interrups */ 1116*dfd1d0fcSMichal Meloun irq &= ~PCIE_CLIENT_INT_LOCAL; 1117*dfd1d0fcSMichal Meloun irq &= ~PCIE_CLIENT_INT_LEGACY; 1118*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CLIENT_INT_STATUS, irq); 1119*dfd1d0fcSMichal Meloun 1120*dfd1d0fcSMichal Meloun device_printf(sc->dev, "'client' interrupt received: 0x%04X\n", irq); 1121*dfd1d0fcSMichal Meloun 1122*dfd1d0fcSMichal Meloun return (FILTER_HANDLED); 1123*dfd1d0fcSMichal Meloun } 1124*dfd1d0fcSMichal Meloun 1125*dfd1d0fcSMichal Meloun static int 1126*dfd1d0fcSMichal Meloun rk_pcie_legacy_irq(void *arg) 1127*dfd1d0fcSMichal Meloun { 1128*dfd1d0fcSMichal Meloun struct rk_pcie_softc *sc; 1129*dfd1d0fcSMichal Meloun uint32_t irq; 1130*dfd1d0fcSMichal Meloun 1131*dfd1d0fcSMichal Meloun sc = (struct rk_pcie_softc *)arg; 1132*dfd1d0fcSMichal Meloun irq = APB_RD4(sc, PCIE_CLIENT_INT_STATUS); 1133*dfd1d0fcSMichal Meloun irq &= PCIE_CLIENT_INT_LEGACY; 1134*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CLIENT_INT_STATUS, irq); 1135*dfd1d0fcSMichal Meloun 1136*dfd1d0fcSMichal Meloun /* all legacy interrupt are shared, do nothing */ 1137*dfd1d0fcSMichal Meloun return (FILTER_STRAY); 1138*dfd1d0fcSMichal Meloun } 1139*dfd1d0fcSMichal Meloun 1140*dfd1d0fcSMichal Meloun 1141*dfd1d0fcSMichal Meloun static bus_dma_tag_t 1142*dfd1d0fcSMichal Meloun rk_pcie_get_dma_tag(device_t dev, device_t child) 1143*dfd1d0fcSMichal Meloun { 1144*dfd1d0fcSMichal Meloun struct rk_pcie_softc *sc; 1145*dfd1d0fcSMichal Meloun 1146*dfd1d0fcSMichal Meloun sc = device_get_softc(dev); 1147*dfd1d0fcSMichal Meloun return (sc->dmat); 1148*dfd1d0fcSMichal Meloun } 1149*dfd1d0fcSMichal Meloun 1150*dfd1d0fcSMichal Meloun 1151*dfd1d0fcSMichal Meloun static int 1152*dfd1d0fcSMichal Meloun rk_pcie_probe(device_t dev) 1153*dfd1d0fcSMichal Meloun { 1154*dfd1d0fcSMichal Meloun 1155*dfd1d0fcSMichal Meloun if (!ofw_bus_status_okay(dev)) 1156*dfd1d0fcSMichal Meloun return (ENXIO); 1157*dfd1d0fcSMichal Meloun 1158*dfd1d0fcSMichal Meloun if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) 1159*dfd1d0fcSMichal Meloun return (ENXIO); 1160*dfd1d0fcSMichal Meloun 1161*dfd1d0fcSMichal Meloun device_set_desc(dev, "Rockchip PCIe controller"); 1162*dfd1d0fcSMichal Meloun return (BUS_PROBE_DEFAULT); 1163*dfd1d0fcSMichal Meloun } 1164*dfd1d0fcSMichal Meloun 1165*dfd1d0fcSMichal Meloun static int 1166*dfd1d0fcSMichal Meloun rk_pcie_attach(device_t dev) 1167*dfd1d0fcSMichal Meloun { struct rk_pcie_softc *sc; 1168*dfd1d0fcSMichal Meloun uint32_t val; 1169*dfd1d0fcSMichal Meloun int rv, rid, max_speed; 1170*dfd1d0fcSMichal Meloun 1171*dfd1d0fcSMichal Meloun sc = device_get_softc(dev); 1172*dfd1d0fcSMichal Meloun sc->dev = dev; 1173*dfd1d0fcSMichal Meloun sc->node = ofw_bus_get_node(dev); 1174*dfd1d0fcSMichal Meloun 1175*dfd1d0fcSMichal Meloun mtx_init(&sc->mtx, "rk_pcie_mtx", NULL, MTX_DEF); 1176*dfd1d0fcSMichal Meloun 1177*dfd1d0fcSMichal Meloun /* XXX Should not be this configurable ? */ 1178*dfd1d0fcSMichal Meloun sc->bus_start = 0; 1179*dfd1d0fcSMichal Meloun sc->bus_end = 0x1F; 1180*dfd1d0fcSMichal Meloun sc->root_bus = sc->bus_start; 1181*dfd1d0fcSMichal Meloun sc->sub_bus = 1; 1182*dfd1d0fcSMichal Meloun 1183*dfd1d0fcSMichal Meloun /* Read FDT properties */ 1184*dfd1d0fcSMichal Meloun rv = rk_pcie_parse_fdt_resources(sc); 1185*dfd1d0fcSMichal Meloun if (rv != 0) 1186*dfd1d0fcSMichal Meloun return (rv); 1187*dfd1d0fcSMichal Meloun 1188*dfd1d0fcSMichal Meloun sc->coherent = OF_hasprop(sc->node, "dma-coherent"); 1189*dfd1d0fcSMichal Meloun sc->no_l0s = OF_hasprop(sc->node, "aspm-no-l0s"); 1190*dfd1d0fcSMichal Meloun rv = OF_getencprop(sc->node, "num-lanes", &sc->num_lanes, 1191*dfd1d0fcSMichal Meloun sizeof(sc->num_lanes)); 1192*dfd1d0fcSMichal Meloun if (rv != sizeof(sc->num_lanes)) 1193*dfd1d0fcSMichal Meloun sc->num_lanes = 1; 1194*dfd1d0fcSMichal Meloun if (sc->num_lanes != 1 && sc->num_lanes != 2 && sc->num_lanes != 4) { 1195*dfd1d0fcSMichal Meloun device_printf(dev, 1196*dfd1d0fcSMichal Meloun "invalid number of lanes: %d\n",sc->num_lanes); 1197*dfd1d0fcSMichal Meloun sc->num_lanes = 0; 1198*dfd1d0fcSMichal Meloun rv = ENXIO; 1199*dfd1d0fcSMichal Meloun goto out; 1200*dfd1d0fcSMichal Meloun } 1201*dfd1d0fcSMichal Meloun 1202*dfd1d0fcSMichal Meloun rv = OF_getencprop(sc->node, "max-link-speed", &max_speed, 1203*dfd1d0fcSMichal Meloun sizeof(max_speed)); 1204*dfd1d0fcSMichal Meloun if (rv != sizeof(max_speed) || max_speed != 1) 1205*dfd1d0fcSMichal Meloun sc->link_is_gen2 = true; 1206*dfd1d0fcSMichal Meloun else 1207*dfd1d0fcSMichal Meloun sc->link_is_gen2 = false; 1208*dfd1d0fcSMichal Meloun 1209*dfd1d0fcSMichal Meloun rv = ofw_bus_find_string_index(sc->node, "reg-names", "axi-base", &rid); 1210*dfd1d0fcSMichal Meloun if (rv != 0) { 1211*dfd1d0fcSMichal Meloun device_printf(dev, "Cannot get 'axi-base' memory\n"); 1212*dfd1d0fcSMichal Meloun rv = ENXIO; 1213*dfd1d0fcSMichal Meloun goto out; 1214*dfd1d0fcSMichal Meloun } 1215*dfd1d0fcSMichal Meloun sc->axi_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 1216*dfd1d0fcSMichal Meloun RF_ACTIVE); 1217*dfd1d0fcSMichal Meloun if (sc->axi_mem_res == NULL) { 1218*dfd1d0fcSMichal Meloun device_printf(dev, "Cannot allocate 'axi-base' (rid: %d)\n", 1219*dfd1d0fcSMichal Meloun rid); 1220*dfd1d0fcSMichal Meloun rv = ENXIO; 1221*dfd1d0fcSMichal Meloun goto out; 1222*dfd1d0fcSMichal Meloun } 1223*dfd1d0fcSMichal Meloun rv = ofw_bus_find_string_index(sc->node, "reg-names", "apb-base", &rid); 1224*dfd1d0fcSMichal Meloun if (rv != 0) { 1225*dfd1d0fcSMichal Meloun device_printf(dev, "Cannot get 'apb-base' memory\n"); 1226*dfd1d0fcSMichal Meloun rv = ENXIO; 1227*dfd1d0fcSMichal Meloun goto out; 1228*dfd1d0fcSMichal Meloun } 1229*dfd1d0fcSMichal Meloun sc->apb_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 1230*dfd1d0fcSMichal Meloun RF_ACTIVE); 1231*dfd1d0fcSMichal Meloun if (sc->apb_mem_res == NULL) { 1232*dfd1d0fcSMichal Meloun device_printf(dev, "Cannot allocate 'apb-base' (rid: %d)\n", 1233*dfd1d0fcSMichal Meloun rid); 1234*dfd1d0fcSMichal Meloun rv = ENXIO; 1235*dfd1d0fcSMichal Meloun goto out; 1236*dfd1d0fcSMichal Meloun } 1237*dfd1d0fcSMichal Meloun 1238*dfd1d0fcSMichal Meloun rv = ofw_bus_find_string_index(sc->node, "interrupt-names", 1239*dfd1d0fcSMichal Meloun "client", &rid); 1240*dfd1d0fcSMichal Meloun if (rv != 0) { 1241*dfd1d0fcSMichal Meloun device_printf(dev, "Cannot get 'client' IRQ\n"); 1242*dfd1d0fcSMichal Meloun rv = ENXIO; 1243*dfd1d0fcSMichal Meloun goto out; 1244*dfd1d0fcSMichal Meloun } 1245*dfd1d0fcSMichal Meloun sc->client_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 1246*dfd1d0fcSMichal Meloun RF_ACTIVE | RF_SHAREABLE); 1247*dfd1d0fcSMichal Meloun if (sc->client_irq_res == NULL) { 1248*dfd1d0fcSMichal Meloun device_printf(dev, "Cannot allocate 'client' IRQ resource\n"); 1249*dfd1d0fcSMichal Meloun rv = ENXIO; 1250*dfd1d0fcSMichal Meloun goto out; 1251*dfd1d0fcSMichal Meloun } 1252*dfd1d0fcSMichal Meloun 1253*dfd1d0fcSMichal Meloun rv = ofw_bus_find_string_index(sc->node, "interrupt-names", 1254*dfd1d0fcSMichal Meloun "legacy", &rid); 1255*dfd1d0fcSMichal Meloun if (rv != 0) { 1256*dfd1d0fcSMichal Meloun device_printf(dev, "Cannot get 'legacy' IRQ\n"); 1257*dfd1d0fcSMichal Meloun rv = ENXIO; 1258*dfd1d0fcSMichal Meloun goto out; 1259*dfd1d0fcSMichal Meloun } 1260*dfd1d0fcSMichal Meloun sc->legacy_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 1261*dfd1d0fcSMichal Meloun RF_ACTIVE | RF_SHAREABLE); 1262*dfd1d0fcSMichal Meloun if (sc->legacy_irq_res == NULL) { 1263*dfd1d0fcSMichal Meloun device_printf(dev, "Cannot allocate 'legacy' IRQ resource\n"); 1264*dfd1d0fcSMichal Meloun rv = ENXIO; 1265*dfd1d0fcSMichal Meloun goto out; 1266*dfd1d0fcSMichal Meloun } 1267*dfd1d0fcSMichal Meloun 1268*dfd1d0fcSMichal Meloun rv = ofw_bus_find_string_index(sc->node, "interrupt-names", 1269*dfd1d0fcSMichal Meloun "sys", &rid); 1270*dfd1d0fcSMichal Meloun if (rv != 0) { 1271*dfd1d0fcSMichal Meloun device_printf(dev, "Cannot get 'sys' IRQ\n"); 1272*dfd1d0fcSMichal Meloun rv = ENXIO; 1273*dfd1d0fcSMichal Meloun goto out; 1274*dfd1d0fcSMichal Meloun } 1275*dfd1d0fcSMichal Meloun sc->sys_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 1276*dfd1d0fcSMichal Meloun RF_ACTIVE | RF_SHAREABLE); 1277*dfd1d0fcSMichal Meloun if (sc->sys_irq_res == NULL) { 1278*dfd1d0fcSMichal Meloun device_printf(dev, "Cannot allocate 'sys' IRQ resource\n"); 1279*dfd1d0fcSMichal Meloun rv = ENXIO; 1280*dfd1d0fcSMichal Meloun goto out; 1281*dfd1d0fcSMichal Meloun } 1282*dfd1d0fcSMichal Meloun 1283*dfd1d0fcSMichal Meloun if (bootverbose) 1284*dfd1d0fcSMichal Meloun device_printf(dev, "Bus is%s cache-coherent\n", 1285*dfd1d0fcSMichal Meloun sc->coherent ? "" : " not"); 1286*dfd1d0fcSMichal Meloun rv = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ 1287*dfd1d0fcSMichal Meloun 1, 0, /* alignment, bounds */ 1288*dfd1d0fcSMichal Meloun BUS_SPACE_MAXADDR, /* lowaddr */ 1289*dfd1d0fcSMichal Meloun BUS_SPACE_MAXADDR, /* highaddr */ 1290*dfd1d0fcSMichal Meloun NULL, NULL, /* filter, filterarg */ 1291*dfd1d0fcSMichal Meloun BUS_SPACE_MAXSIZE, /* maxsize */ 1292*dfd1d0fcSMichal Meloun BUS_SPACE_UNRESTRICTED, /* nsegments */ 1293*dfd1d0fcSMichal Meloun BUS_SPACE_MAXSIZE, /* maxsegsize */ 1294*dfd1d0fcSMichal Meloun sc->coherent ? BUS_DMA_COHERENT : 0, /* flags */ 1295*dfd1d0fcSMichal Meloun NULL, NULL, /* lockfunc, lockarg */ 1296*dfd1d0fcSMichal Meloun &sc->dmat); 1297*dfd1d0fcSMichal Meloun if (rv != 0) 1298*dfd1d0fcSMichal Meloun goto out; 1299*dfd1d0fcSMichal Meloun 1300*dfd1d0fcSMichal Meloun rv = ofw_pci_init(dev); 1301*dfd1d0fcSMichal Meloun if (rv != 0) 1302*dfd1d0fcSMichal Meloun goto out; 1303*dfd1d0fcSMichal Meloun 1304*dfd1d0fcSMichal Meloun rv = rk_pcie_decode_ranges(sc, sc->ofw_pci.sc_range, 1305*dfd1d0fcSMichal Meloun sc->ofw_pci.sc_nrange); 1306*dfd1d0fcSMichal Meloun if (rv != 0) 1307*dfd1d0fcSMichal Meloun goto out; 1308*dfd1d0fcSMichal Meloun rv = rk_pcie_setup_hw(sc); 1309*dfd1d0fcSMichal Meloun if (rv != 0) 1310*dfd1d0fcSMichal Meloun goto out; 1311*dfd1d0fcSMichal Meloun 1312*dfd1d0fcSMichal Meloun rv = rk_pcie_setup_sw(sc); 1313*dfd1d0fcSMichal Meloun if (rv != 0) 1314*dfd1d0fcSMichal Meloun goto out; 1315*dfd1d0fcSMichal Meloun 1316*dfd1d0fcSMichal Meloun rv = bus_setup_intr(dev, sc->client_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, 1317*dfd1d0fcSMichal Meloun rk_pcie_client_irq, NULL, sc, &sc->client_irq_cookie); 1318*dfd1d0fcSMichal Meloun if (rv != 0) { 1319*dfd1d0fcSMichal Meloun device_printf(dev, "cannot setup client interrupt handler\n"); 1320*dfd1d0fcSMichal Meloun rv = ENXIO; 1321*dfd1d0fcSMichal Meloun goto out; 1322*dfd1d0fcSMichal Meloun } 1323*dfd1d0fcSMichal Meloun 1324*dfd1d0fcSMichal Meloun rv = bus_setup_intr(dev, sc->legacy_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, 1325*dfd1d0fcSMichal Meloun rk_pcie_legacy_irq, NULL, sc, &sc->legacy_irq_cookie); 1326*dfd1d0fcSMichal Meloun if (rv != 0) { 1327*dfd1d0fcSMichal Meloun device_printf(dev, "cannot setup client interrupt handler\n"); 1328*dfd1d0fcSMichal Meloun rv = ENXIO; 1329*dfd1d0fcSMichal Meloun goto out; 1330*dfd1d0fcSMichal Meloun } 1331*dfd1d0fcSMichal Meloun 1332*dfd1d0fcSMichal Meloun rv = bus_setup_intr(dev, sc->sys_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, 1333*dfd1d0fcSMichal Meloun rk_pcie_sys_irq, NULL, sc, &sc->sys_irq_cookie); 1334*dfd1d0fcSMichal Meloun if (rv != 0) { 1335*dfd1d0fcSMichal Meloun device_printf(dev, "cannot setup client interrupt handler\n"); 1336*dfd1d0fcSMichal Meloun rv = ENXIO; 1337*dfd1d0fcSMichal Meloun goto out; 1338*dfd1d0fcSMichal Meloun } 1339*dfd1d0fcSMichal Meloun 1340*dfd1d0fcSMichal Meloun /* Enable interrupts */ 1341*dfd1d0fcSMichal Meloun val = 1342*dfd1d0fcSMichal Meloun PCIE_CLIENT_INT_CORR_ERR | PCIE_CLIENT_INT_NFATAL_ERR | 1343*dfd1d0fcSMichal Meloun PCIE_CLIENT_INT_FATAL_ERR | PCIE_CLIENT_INT_DPA | 1344*dfd1d0fcSMichal Meloun PCIE_CLIENT_INT_HOT_RST | PCIE_CLIENT_INT_MSG | 1345*dfd1d0fcSMichal Meloun PCIE_CLIENT_INT_LEGACY_DONE | PCIE_CLIENT_INT_INTA | 1346*dfd1d0fcSMichal Meloun PCIE_CLIENT_INT_INTB | PCIE_CLIENT_INT_INTC | 1347*dfd1d0fcSMichal Meloun PCIE_CLIENT_INT_INTD | PCIE_CLIENT_INT_PHY; 1348*dfd1d0fcSMichal Meloun 1349*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CLIENT_INT_MASK, (val << 16) & ~val); 1350*dfd1d0fcSMichal Meloun 1351*dfd1d0fcSMichal Meloun val = 1352*dfd1d0fcSMichal Meloun PCIE_CORE_INT_PRFPE | PCIE_CORE_INT_CRFPE | 1353*dfd1d0fcSMichal Meloun PCIE_CORE_INT_RRPE | PCIE_CORE_INT_CRFO | 1354*dfd1d0fcSMichal Meloun PCIE_CORE_INT_RT | PCIE_CORE_INT_RTR | 1355*dfd1d0fcSMichal Meloun PCIE_CORE_INT_PE | PCIE_CORE_INT_MTR | 1356*dfd1d0fcSMichal Meloun PCIE_CORE_INT_UCR | PCIE_CORE_INT_FCE | 1357*dfd1d0fcSMichal Meloun PCIE_CORE_INT_CT | PCIE_CORE_INT_UTC | 1358*dfd1d0fcSMichal Meloun PCIE_CORE_INT_MMVC; 1359*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_CORE_INT_MASK, ~(val)); 1360*dfd1d0fcSMichal Meloun 1361*dfd1d0fcSMichal Meloun val = APB_RD4(sc, PCIE_RC_CONFIG_LCS); 1362*dfd1d0fcSMichal Meloun val |= PCIEM_LINK_CTL_LBMIE | PCIEM_LINK_CTL_LABIE; 1363*dfd1d0fcSMichal Meloun APB_WR4(sc, PCIE_RC_CONFIG_LCS, val); 1364*dfd1d0fcSMichal Meloun 1365*dfd1d0fcSMichal Meloun DELAY(250000); 1366*dfd1d0fcSMichal Meloun device_add_child(dev, "pci", -1); 1367*dfd1d0fcSMichal Meloun return (bus_generic_attach(dev)); 1368*dfd1d0fcSMichal Meloun out: 1369*dfd1d0fcSMichal Meloun /* XXX Cleanup */ 1370*dfd1d0fcSMichal Meloun return (rv); 1371*dfd1d0fcSMichal Meloun } 1372*dfd1d0fcSMichal Meloun 1373*dfd1d0fcSMichal Meloun 1374*dfd1d0fcSMichal Meloun static device_method_t rk_pcie_methods[] = { 1375*dfd1d0fcSMichal Meloun /* Device interface */ 1376*dfd1d0fcSMichal Meloun DEVMETHOD(device_probe, rk_pcie_probe), 1377*dfd1d0fcSMichal Meloun DEVMETHOD(device_attach, rk_pcie_attach), 1378*dfd1d0fcSMichal Meloun 1379*dfd1d0fcSMichal Meloun /* Bus interface */ 1380*dfd1d0fcSMichal Meloun DEVMETHOD(bus_get_dma_tag, rk_pcie_get_dma_tag), 1381*dfd1d0fcSMichal Meloun 1382*dfd1d0fcSMichal Meloun /* pcib interface */ 1383*dfd1d0fcSMichal Meloun DEVMETHOD(pcib_read_config, rk_pcie_read_config), 1384*dfd1d0fcSMichal Meloun DEVMETHOD(pcib_write_config, rk_pcie_write_config), 1385*dfd1d0fcSMichal Meloun DEVMETHOD(pcib_route_interrupt, rk_pcie_route_interrupt), 1386*dfd1d0fcSMichal Meloun #ifdef RK_PCIE_ENABLE_MSI 1387*dfd1d0fcSMichal Meloun DEVMETHOD(pcib_alloc_msi, rk_pcie_alloc_msi), 1388*dfd1d0fcSMichal Meloun DEVMETHOD(pcib_release_msi, rk_pcie_release_msi), 1389*dfd1d0fcSMichal Meloun #endif 1390*dfd1d0fcSMichal Meloun #ifdef RK_PCIE_ENABLE_MSIX 1391*dfd1d0fcSMichal Meloun DEVMETHOD(pcib_alloc_msix, rk_pcie_alloc_msix), 1392*dfd1d0fcSMichal Meloun DEVMETHOD(pcib_release_msix, rk_pcie_release_msix), 1393*dfd1d0fcSMichal Meloun #endif 1394*dfd1d0fcSMichal Meloun DEVMETHOD(pcib_map_msi, rk_pcie_map_msi), 1395*dfd1d0fcSMichal Meloun DEVMETHOD(pcib_get_id, rk_pcie_get_id), 1396*dfd1d0fcSMichal Meloun 1397*dfd1d0fcSMichal Meloun /* OFW bus interface */ 1398*dfd1d0fcSMichal Meloun DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), 1399*dfd1d0fcSMichal Meloun DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), 1400*dfd1d0fcSMichal Meloun DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), 1401*dfd1d0fcSMichal Meloun DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), 1402*dfd1d0fcSMichal Meloun DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), 1403*dfd1d0fcSMichal Meloun 1404*dfd1d0fcSMichal Meloun DEVMETHOD_END 1405*dfd1d0fcSMichal Meloun }; 1406*dfd1d0fcSMichal Meloun 1407*dfd1d0fcSMichal Meloun DEFINE_CLASS_1(pcib, rk_pcie_driver, rk_pcie_methods, 1408*dfd1d0fcSMichal Meloun sizeof(struct rk_pcie_softc), ofw_pci_driver); 1409*dfd1d0fcSMichal Meloun static devclass_t rk_pcie_devclass; 1410*dfd1d0fcSMichal Meloun DRIVER_MODULE( rk_pcie, simplebus, rk_pcie_driver, rk_pcie_devclass, 1411*dfd1d0fcSMichal Meloun NULL, NULL);