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