1 1.30 thorpej /* $NetBSD: gt.c,v 1.30 2021/08/07 16:19:13 thorpej Exp $ */ 2 1.1 matt 3 1.1 matt /* 4 1.1 matt * Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc. 5 1.1 matt * All rights reserved. 6 1.1 matt * 7 1.1 matt * Redistribution and use in source and binary forms, with or without 8 1.1 matt * modification, are permitted provided that the following conditions 9 1.1 matt * are met: 10 1.1 matt * 1. Redistributions of source code must retain the above copyright 11 1.1 matt * notice, this list of conditions and the following disclaimer. 12 1.1 matt * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 matt * notice, this list of conditions and the following disclaimer in the 14 1.1 matt * documentation and/or other materials provided with the distribution. 15 1.1 matt * 3. All advertising materials mentioning features or use of this software 16 1.1 matt * must display the following acknowledgement: 17 1.1 matt * This product includes software developed for the NetBSD Project by 18 1.1 matt * Allegro Networks, Inc., and Wasabi Systems, Inc. 19 1.1 matt * 4. The name of Allegro Networks, Inc. may not be used to endorse 20 1.1 matt * or promote products derived from this software without specific prior 21 1.1 matt * written permission. 22 1.1 matt * 5. The name of Wasabi Systems, Inc. may not be used to endorse 23 1.1 matt * or promote products derived from this software without specific prior 24 1.1 matt * written permission. 25 1.1 matt * 26 1.1 matt * THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND 27 1.1 matt * WASABI SYSTEMS, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 28 1.1 matt * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 29 1.1 matt * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 30 1.1 matt * IN NO EVENT SHALL EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC. 31 1.1 matt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 1.1 matt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 1.1 matt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 1.1 matt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 1.1 matt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 1.1 matt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 1.1 matt * POSSIBILITY OF SUCH DAMAGE. 38 1.1 matt */ 39 1.1 matt 40 1.1 matt /* 41 1.1 matt * gt.c -- GT system controller driver 42 1.1 matt */ 43 1.5 lukem 44 1.5 lukem #include <sys/cdefs.h> 45 1.30 thorpej __KERNEL_RCSID(0, "$NetBSD: gt.c,v 1.30 2021/08/07 16:19:13 thorpej Exp $"); 46 1.1 matt 47 1.1 matt #include "opt_marvell.h" 48 1.23 kiyohara #include "gtmpsc.h" 49 1.24 kiyohara #include "opt_multiprocessor.h" 50 1.8 jmc #include "locators.h" 51 1.1 matt 52 1.1 matt #include <sys/param.h> 53 1.23 kiyohara #include <sys/bus.h> 54 1.1 matt #include <sys/device.h> 55 1.1 matt #include <sys/kernel.h> 56 1.23 kiyohara #include <sys/types.h> 57 1.1 matt 58 1.23 kiyohara #include <dev/marvell/gtintrreg.h> 59 1.23 kiyohara #include <dev/marvell/gtsdmareg.h> 60 1.23 kiyohara #if NGTMPSC > 0 61 1.23 kiyohara #include <dev/marvell/gtmpscreg.h> 62 1.23 kiyohara #include <dev/marvell/gtmpscvar.h> 63 1.23 kiyohara #endif 64 1.23 kiyohara #include <dev/marvell/gtpcireg.h> 65 1.1 matt #include <dev/marvell/gtreg.h> 66 1.1 matt #include <dev/marvell/gtvar.h> 67 1.23 kiyohara #include <dev/marvell/marvellreg.h> 68 1.23 kiyohara #include <dev/marvell/marvellvar.h> 69 1.23 kiyohara 70 1.23 kiyohara #include <dev/pci/pcireg.h> 71 1.1 matt 72 1.1 matt #if ((GT_MPP_WATCHDOG & 0xf0f0f0f0) != 0) 73 1.1 matt # error /* unqualified: configuration botch! */ 74 1.1 matt #endif 75 1.1 matt 76 1.23 kiyohara #define gt_read(sc,r) bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (r)) 77 1.23 kiyohara #define gt_write(sc,r,v) bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (r), (v)) 78 1.23 kiyohara 79 1.23 kiyohara 80 1.23 kiyohara static int gt_cfprint(void *, const char *); 81 1.23 kiyohara static int gt_cfsearch(device_t, cfdata_t, const int *, void *); 82 1.23 kiyohara static void gt_attach_peripherals(struct gt_softc *); 83 1.23 kiyohara 84 1.23 kiyohara #ifdef GT_DEVBUS 85 1.23 kiyohara static int gt_devbus_intr(void *); 86 1.3 matt static void gt_devbus_intr_enb(struct gt_softc *); 87 1.23 kiyohara #endif 88 1.1 matt #ifdef GT_ECC 89 1.23 kiyohara static int gt_ecc_intr(void *); 90 1.3 matt static void gt_ecc_intr_enb(struct gt_softc *); 91 1.1 matt #endif 92 1.23 kiyohara #if NGTMPSC > 0 93 1.23 kiyohara static void gt_sdma_intr_enb(struct gt_softc *); 94 1.23 kiyohara #endif 95 1.23 kiyohara #ifdef GT_COMM 96 1.23 kiyohara static int gt_comm_intr(void *); 97 1.23 kiyohara static void gt_comm_intr_enb(struct gt_softc *); 98 1.23 kiyohara #endif 99 1.23 kiyohara 100 1.1 matt 101 1.23 kiyohara #ifdef GT_WATCHDOG 102 1.23 kiyohara static void gt_watchdog_init(struct gt_softc *); 103 1.23 kiyohara static void gt_watchdog_enable(struct gt_softc *); 104 1.23 kiyohara #ifndef GT_MPP_WATCHDOG 105 1.23 kiyohara static void gt_watchdog_disable(struct gt_softc *); 106 1.23 kiyohara #endif 107 1.6 matt 108 1.23 kiyohara static struct gt_softc *gt_watchdog_sc = NULL; 109 1.23 kiyohara static int gt_watchdog_state = 0; 110 1.23 kiyohara #endif 111 1.1 matt 112 1.1 matt 113 1.25 kiyohara #define OFFSET_DEFAULT MVA_OFFSET_DEFAULT 114 1.25 kiyohara #define IRQ_DEFAULT MVA_IRQ_DEFAULT 115 1.23 kiyohara static const struct gt_dev { 116 1.23 kiyohara int model; 117 1.23 kiyohara const char *name; 118 1.23 kiyohara int unit; 119 1.23 kiyohara bus_size_t offset; 120 1.23 kiyohara int irq; 121 1.23 kiyohara } gt_devs[] = { 122 1.23 kiyohara { MARVELL_DISCOVERY, "gfec", 0, 0x0000, IRQ_DEFAULT }, 123 1.23 kiyohara { MARVELL_DISCOVERY, "gtidmac", 0, 0x0000, 4 /*...7 */ }, 124 1.23 kiyohara { MARVELL_DISCOVERY, "gtmpsc", 0, 0x8000, 40 }, 125 1.23 kiyohara { MARVELL_DISCOVERY, "gtmpsc", 1, 0x9000, 42 }, 126 1.23 kiyohara { MARVELL_DISCOVERY, "gtpci", 0, OFFSET_DEFAULT, IRQ_DEFAULT }, 127 1.23 kiyohara { MARVELL_DISCOVERY, "gtpci", 1, OFFSET_DEFAULT, IRQ_DEFAULT }, 128 1.23 kiyohara { MARVELL_DISCOVERY, "gttwsi", 0, 0xc000, 37 }, 129 1.23 kiyohara { MARVELL_DISCOVERY, "obio", 0, OFFSET_DEFAULT, IRQ_DEFAULT }, 130 1.23 kiyohara { MARVELL_DISCOVERY, "obio", 1, OFFSET_DEFAULT, IRQ_DEFAULT }, 131 1.23 kiyohara { MARVELL_DISCOVERY, "obio", 2, OFFSET_DEFAULT, IRQ_DEFAULT }, 132 1.23 kiyohara { MARVELL_DISCOVERY, "obio", 3, OFFSET_DEFAULT, IRQ_DEFAULT }, 133 1.23 kiyohara { MARVELL_DISCOVERY, "obio", 4, OFFSET_DEFAULT, IRQ_DEFAULT }, 134 1.23 kiyohara 135 1.23 kiyohara { MARVELL_DISCOVERY_II, "gtidmac", 0, 0x0000, 4 /*...7 */ }, 136 1.23 kiyohara { MARVELL_DISCOVERY_II, "gtmpsc", 0, 0x8000, 40 }, 137 1.23 kiyohara { MARVELL_DISCOVERY_II, "gtmpsc", 1, 0x9000, 42 }, 138 1.23 kiyohara { MARVELL_DISCOVERY_II, "gtpci", 0, OFFSET_DEFAULT, IRQ_DEFAULT }, 139 1.23 kiyohara { MARVELL_DISCOVERY_II, "gtpci", 1, OFFSET_DEFAULT, IRQ_DEFAULT }, 140 1.23 kiyohara { MARVELL_DISCOVERY_II, "gttwsi", 0, 0xc000, 37 }, 141 1.23 kiyohara { MARVELL_DISCOVERY_II, "mvgbec", 0, 0x0000, IRQ_DEFAULT }, 142 1.1 matt 143 1.23 kiyohara { MARVELL_DISCOVERY_III,"gtidmac", 0, 0x0000, 4 /*...7 */ }, 144 1.23 kiyohara { MARVELL_DISCOVERY_III,"gtmpsc", 0, 0x8000, 40 }, 145 1.23 kiyohara { MARVELL_DISCOVERY_III,"gtmpsc", 1, 0x9000, 42 }, 146 1.23 kiyohara { MARVELL_DISCOVERY_III,"gtpci", 0, OFFSET_DEFAULT, IRQ_DEFAULT }, 147 1.23 kiyohara { MARVELL_DISCOVERY_III,"gtpci", 1, OFFSET_DEFAULT, IRQ_DEFAULT }, 148 1.23 kiyohara { MARVELL_DISCOVERY_III,"gttwsi", 0, 0xc000, 37 }, 149 1.23 kiyohara { MARVELL_DISCOVERY_III,"mvgbec", 0, 0x0000, IRQ_DEFAULT }, 150 1.26 kiyohara 151 1.26 kiyohara #if 0 /* XXXXXX: from www.marvell.com */ 152 1.26 kiyohara /* Discovery LT (Discovery Light) MV644[23]0 */ 153 1.26 kiyohara { MARVELL_DISCOVERY_LT, "gtidmac", 0, 0x?000, ? /*...? */ }, 154 1.26 kiyohara { MARVELL_DISCOVERY_LT, "gtmpsc", 0, 0x?000, ? }, 155 1.26 kiyohara { MARVELL_DISCOVERY_LT, "gtmpsc", 1, 0x?000, ? }, 156 1.26 kiyohara { MARVELL_DISCOVERY_LT, "gtpci", 0, OFFSET_DEFAULT, IRQ_DEFAULT }, 157 1.26 kiyohara { MARVELL_DISCOVERY_LT, "gtpci", 1, OFFSET_DEFAULT, IRQ_DEFAULT }, 158 1.26 kiyohara { MARVELL_DISCOVERY_LT, "gttwsi", 0, 0x?000, ? }, 159 1.26 kiyohara { MARVELL_DISCOVERY_LT, "mvgbec", 0, 0x?000, IRQ_DEFAULT }, 160 1.26 kiyohara 161 1.26 kiyohara /* Discovery V MV64560 */ 162 1.26 kiyohara { MARVELL_DISCOVERY_V, "com", ?, 0x?0000, ? }, 163 1.26 kiyohara { MARVELL_DISCOVERY_V, "ehci", 0, 0x?0000, ? }, 164 1.26 kiyohara { MARVELL_DISCOVERY_V, "ehci", 1, 0x?0000, ? }, 165 1.26 kiyohara { MARVELL_DISCOVERY_V, "gtidmac", 0, 0x?0000, ? /*...? */ }, 166 1.26 kiyohara { MARVELL_DISCOVERY_V, "gtpci", 0, 0x?0000, IRQ_DEFAULT }, 167 1.26 kiyohara { MARVELL_DISCOVERY_V, "gttwsi", 0, 0x?0000, ? }, 168 1.26 kiyohara { MARVELL_DISCOVERY_V, "mvgbec", 0, 0x?0000, IRQ_DEFAULT }, 169 1.26 kiyohara { MARVELL_DISCOVERY_V, "mvpex or gtpci?", 0, 0x?0000, IRQ_DEFAULT }, 170 1.26 kiyohara { MARVELL_DISCOVERY_V, "obio", 0, OFFSET_DEFAULT, IRQ_DEFAULT }, 171 1.26 kiyohara 172 1.26 kiyohara /* Discovery VI MV64660 */ 173 1.26 kiyohara /* MV64560 + SATA? */ 174 1.26 kiyohara { MARVELL_DISCOVERY_VI, "mvsata", 0, 0x?0000, ? }, 175 1.26 kiyohara #endif 176 1.23 kiyohara }; 177 1.1 matt 178 1.1 matt 179 1.23 kiyohara static int 180 1.23 kiyohara gt_cfprint(void *aux, const char *pnp) 181 1.1 matt { 182 1.23 kiyohara struct marvell_attach_args *mva = aux; 183 1.1 matt 184 1.23 kiyohara if (pnp) 185 1.23 kiyohara aprint_normal("%s at %s unit %d", 186 1.23 kiyohara mva->mva_name, pnp, mva->mva_unit); 187 1.23 kiyohara else { 188 1.25 kiyohara if (mva->mva_unit != MVA_UNIT_DEFAULT) 189 1.23 kiyohara aprint_normal(" unit %d", mva->mva_unit); 190 1.25 kiyohara if (mva->mva_offset != MVA_OFFSET_DEFAULT) { 191 1.23 kiyohara aprint_normal(" offset 0x%04x", mva->mva_offset); 192 1.23 kiyohara if (mva->mva_size > 0) 193 1.23 kiyohara aprint_normal("-0x%04x", 194 1.23 kiyohara mva->mva_offset + mva->mva_size - 1); 195 1.23 kiyohara } 196 1.25 kiyohara if (mva->mva_irq != MVA_IRQ_DEFAULT) 197 1.23 kiyohara aprint_normal(" irq %d", mva->mva_irq); 198 1.1 matt } 199 1.1 matt 200 1.23 kiyohara return UNCONF; 201 1.1 matt } 202 1.1 matt 203 1.1 matt 204 1.23 kiyohara /* ARGSUSED */ 205 1.1 matt static int 206 1.23 kiyohara gt_cfsearch(device_t parent, cfdata_t cf, const int *ldesc, void *aux) 207 1.1 matt { 208 1.23 kiyohara struct marvell_attach_args *mva = aux; 209 1.23 kiyohara 210 1.25 kiyohara if (cf->cf_loc[GTCF_IRQ] != MVA_IRQ_DEFAULT) 211 1.23 kiyohara mva->mva_irq = cf->cf_loc[GTCF_IRQ]; 212 1.1 matt 213 1.23 kiyohara return config_match(parent, cf, aux); 214 1.23 kiyohara } 215 1.23 kiyohara 216 1.23 kiyohara static void 217 1.23 kiyohara gt_attach_peripherals(struct gt_softc *sc) 218 1.23 kiyohara { 219 1.23 kiyohara struct marvell_attach_args mva; 220 1.23 kiyohara int i; 221 1.1 matt 222 1.23 kiyohara for (i = 0; i < __arraycount(gt_devs); i++) { 223 1.23 kiyohara if (gt_devs[i].model != sc->sc_model) 224 1.23 kiyohara continue; 225 1.23 kiyohara 226 1.23 kiyohara mva.mva_name = gt_devs[i].name; 227 1.23 kiyohara mva.mva_model = sc->sc_model; 228 1.23 kiyohara mva.mva_revision = sc->sc_rev; 229 1.23 kiyohara mva.mva_iot = sc->sc_iot; 230 1.23 kiyohara mva.mva_ioh = sc->sc_ioh; 231 1.23 kiyohara mva.mva_unit = gt_devs[i].unit; 232 1.23 kiyohara mva.mva_addr = sc->sc_addr; 233 1.23 kiyohara mva.mva_offset = gt_devs[i].offset; 234 1.23 kiyohara mva.mva_size = 0; 235 1.23 kiyohara mva.mva_dmat = sc->sc_dmat; 236 1.23 kiyohara mva.mva_irq = gt_devs[i].irq; 237 1.1 matt 238 1.29 thorpej config_found(sc->sc_dev, &mva, gt_cfprint, 239 1.30 thorpej CFARGS(.submatch = gt_cfsearch)); 240 1.23 kiyohara } 241 1.1 matt } 242 1.1 matt 243 1.1 matt void 244 1.1 matt gt_attach_common(struct gt_softc *gt) 245 1.1 matt { 246 1.1 matt uint32_t cpucfg, cpumode, cpumstr; 247 1.24 kiyohara #ifdef GT_DEBUG 248 1.1 matt uint32_t loaddr, hiaddr; 249 1.1 matt #endif 250 1.1 matt 251 1.23 kiyohara gt_write(gt, GTPCI_CA(0), PCI_ID_REG); 252 1.23 kiyohara gt->sc_model = PCI_PRODUCT(gt_read(gt, GTPCI_CD(0))); 253 1.23 kiyohara gt_write(gt, GTPCI_CA(0), PCI_CLASS_REG); 254 1.23 kiyohara gt->sc_rev = PCI_REVISION(gt_read(gt, GTPCI_CD(0))); 255 1.23 kiyohara 256 1.23 kiyohara aprint_naive("\n"); 257 1.23 kiyohara switch (gt->sc_model) { 258 1.23 kiyohara case MARVELL_DISCOVERY: 259 1.23 kiyohara aprint_normal(": GT-6426x%c Discovery\n", 260 1.23 kiyohara (gt->sc_rev == MARVELL_DISCOVERY_REVA) ? 'A' : 'B'); 261 1.23 kiyohara break; 262 1.23 kiyohara case MARVELL_DISCOVERY_II: 263 1.23 kiyohara aprint_normal(": MV6436x Discovery II\n"); 264 1.23 kiyohara break; 265 1.23 kiyohara 266 1.24 kiyohara case MARVELL_DISCOVERY_III: 267 1.24 kiyohara aprint_normal(": MV6446x Discovery III\n"); 268 1.24 kiyohara break; 269 1.23 kiyohara #if 0 270 1.23 kiyohara case MARVELL_DISCOVERY_LT: 271 1.23 kiyohara case MARVELL_DISCOVERY_V: 272 1.23 kiyohara case MARVELL_DISCOVERY_VI: 273 1.23 kiyohara #endif 274 1.23 kiyohara 275 1.23 kiyohara default: 276 1.23 kiyohara aprint_normal(": type unknown\n"); break; 277 1.23 kiyohara } 278 1.1 matt 279 1.3 matt cpumode = gt_read(gt, GT_CPU_Mode); 280 1.23 kiyohara aprint_normal_dev(gt->sc_dev, 281 1.23 kiyohara "id %d", GT_CPUMode_MultiGTID_GET(cpumode)); 282 1.1 matt if (cpumode & GT_CPUMode_MultiGT) 283 1.3 matt aprint_normal (" (multi)"); 284 1.1 matt switch (GT_CPUMode_CPUType_GET(cpumode)) { 285 1.3 matt case 4: aprint_normal(", 60x bus"); break; 286 1.3 matt case 5: aprint_normal(", MPX bus"); break; 287 1.23 kiyohara 288 1.23 kiyohara default: 289 1.23 kiyohara aprint_normal(", %#x(?) bus", GT_CPUMode_CPUType_GET(cpumode)); 290 1.23 kiyohara break; 291 1.1 matt } 292 1.1 matt 293 1.3 matt cpumstr = gt_read(gt, GT_CPU_Master_Ctl); 294 1.1 matt switch (cpumstr & (GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock)) { 295 1.1 matt case 0: break; 296 1.3 matt case GT_CPUMstrCtl_CleanBlock: aprint_normal(", snoop=clean"); break; 297 1.3 matt case GT_CPUMstrCtl_FlushBlock: aprint_normal(", snoop=flush"); break; 298 1.1 matt case GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock: 299 1.3 matt aprint_normal(", snoop=clean&flush"); break; 300 1.1 matt } 301 1.3 matt aprint_normal(" wdog=%#x,%#x\n", 302 1.24 kiyohara gt_read(gt, GT_WDOG_Config), gt_read(gt, GT_WDOG_Value)); 303 1.1 matt 304 1.24 kiyohara #ifdef GT_DEBUG 305 1.24 kiyohara loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS0_Low_Decode), gt->sc_model); 306 1.24 kiyohara hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS0_High_Decode), gt->sc_model); 307 1.23 kiyohara aprint_normal_dev(gt->sc_dev, " scs[0]=%#10x-%#10x\n", 308 1.23 kiyohara loaddr, hiaddr); 309 1.3 matt 310 1.24 kiyohara loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS1_Low_Decode), gt->sc_model); 311 1.24 kiyohara hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS1_High_Decode), gt->sc_model); 312 1.23 kiyohara aprint_normal_dev(gt->sc_dev, " scs[1]=%#10x-%#10x\n", 313 1.23 kiyohara loaddr, hiaddr); 314 1.3 matt 315 1.24 kiyohara loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS2_Low_Decode), gt->sc_model); 316 1.24 kiyohara hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS2_High_Decode), gt->sc_model); 317 1.23 kiyohara aprint_normal_dev(gt->sc_dev, " scs[2]=%#10x-%#10x\n", 318 1.23 kiyohara loaddr, hiaddr); 319 1.3 matt 320 1.24 kiyohara loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS3_Low_Decode), gt->sc_model); 321 1.24 kiyohara hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS3_High_Decode), gt->sc_model); 322 1.23 kiyohara aprint_normal_dev(gt->sc_dev, " scs[3]=%#10x-%#10x\n", 323 1.23 kiyohara loaddr, hiaddr); 324 1.3 matt 325 1.24 kiyohara loaddr = GT_LADDR_GET(gt_read(gt, GT_CS0_Low_Decode), gt->sc_model); 326 1.24 kiyohara hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS0_High_Decode), gt->sc_model); 327 1.23 kiyohara aprint_normal_dev(gt->sc_dev, " cs[0]=%#10x-%#10x\n", 328 1.23 kiyohara loaddr, hiaddr); 329 1.3 matt 330 1.24 kiyohara loaddr = GT_LADDR_GET(gt_read(gt, GT_CS1_Low_Decode), gt->sc_model); 331 1.24 kiyohara hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS1_High_Decode), gt->sc_model); 332 1.23 kiyohara aprint_normal_dev(gt->sc_dev, " cs[1]=%#10x-%#10x\n", 333 1.23 kiyohara loaddr, hiaddr); 334 1.3 matt 335 1.24 kiyohara loaddr = GT_LADDR_GET(gt_read(gt, GT_CS2_Low_Decode), gt->sc_model); 336 1.24 kiyohara hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS2_High_Decode), gt->sc_model); 337 1.23 kiyohara aprint_normal_dev(gt->sc_dev, " cs[2]=%#10x-%#10x\n", 338 1.23 kiyohara loaddr, hiaddr); 339 1.3 matt 340 1.24 kiyohara loaddr = GT_LADDR_GET(gt_read(gt, GT_CS3_Low_Decode), gt->sc_model); 341 1.24 kiyohara hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS3_High_Decode), gt->sc_model); 342 1.23 kiyohara aprint_normal_dev(gt->sc_dev, " cs[3]=%#10x-%#10x\n", 343 1.23 kiyohara loaddr, hiaddr); 344 1.3 matt 345 1.24 kiyohara loaddr = GT_LADDR_GET(gt_read(gt, GT_BootCS_Low_Decode), gt->sc_model); 346 1.24 kiyohara hiaddr = GT_HADDR_GET(gt_read(gt, GT_BootCS_High_Decode), gt->sc_model); 347 1.24 kiyohara aprint_normal_dev(gt->sc_dev, " bootcs=%#10x-%#10x\n", 348 1.23 kiyohara loaddr, hiaddr); 349 1.3 matt 350 1.24 kiyohara loaddr = GT_LADDR_GET(gt_read(gt, GT_PCI0_IO_Low_Decode), gt->sc_model); 351 1.24 kiyohara hiaddr = 352 1.24 kiyohara GT_HADDR_GET(gt_read(gt, GT_PCI0_IO_High_Decode), gt->sc_model); 353 1.24 kiyohara aprint_normal_dev(gt->sc_dev, " pci0io=%#10x-%#10x ", 354 1.23 kiyohara loaddr, hiaddr); 355 1.3 matt 356 1.3 matt loaddr = gt_read(gt, GT_PCI0_IO_Remap); 357 1.3 matt aprint_normal("remap=%#010x\n", loaddr); 358 1.3 matt 359 1.24 kiyohara loaddr = 360 1.24 kiyohara GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem0_Low_Decode), gt->sc_model); 361 1.24 kiyohara hiaddr = 362 1.24 kiyohara GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem0_High_Decode), gt->sc_model); 363 1.24 kiyohara aprint_normal_dev(gt->sc_dev, " pci0mem[0]=%#10x-%#10x ", 364 1.23 kiyohara loaddr, hiaddr); 365 1.3 matt 366 1.3 matt loaddr = gt_read(gt, GT_PCI0_Mem0_Remap_Low); 367 1.3 matt hiaddr = gt_read(gt, GT_PCI0_Mem0_Remap_High); 368 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 369 1.3 matt 370 1.24 kiyohara loaddr = 371 1.24 kiyohara GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem1_Low_Decode), gt->sc_model); 372 1.24 kiyohara hiaddr = 373 1.24 kiyohara GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem1_High_Decode), gt->sc_model); 374 1.24 kiyohara aprint_normal_dev(gt->sc_dev, " pci0mem[1]=%#10x-%#10x ", 375 1.23 kiyohara loaddr, hiaddr); 376 1.3 matt 377 1.3 matt loaddr = gt_read(gt, GT_PCI0_Mem1_Remap_Low); 378 1.3 matt hiaddr = gt_read(gt, GT_PCI0_Mem1_Remap_High); 379 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 380 1.3 matt 381 1.24 kiyohara loaddr = 382 1.24 kiyohara GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem2_Low_Decode), gt->sc_model); 383 1.24 kiyohara hiaddr = 384 1.24 kiyohara GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem2_High_Decode), gt->sc_model); 385 1.24 kiyohara aprint_normal_dev(gt->sc_dev, " pci0mem[2]=%#10x-%#10x ", 386 1.23 kiyohara loaddr, hiaddr); 387 1.3 matt 388 1.3 matt loaddr = gt_read(gt, GT_PCI0_Mem2_Remap_Low); 389 1.3 matt hiaddr = gt_read(gt, GT_PCI0_Mem2_Remap_High); 390 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 391 1.3 matt 392 1.24 kiyohara loaddr = 393 1.24 kiyohara GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem3_Low_Decode), gt->sc_model); 394 1.24 kiyohara hiaddr = 395 1.24 kiyohara GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem3_High_Decode), gt->sc_model); 396 1.24 kiyohara aprint_normal_dev(gt->sc_dev, " pci0mem[3]=%#10x-%#10x ", 397 1.23 kiyohara loaddr, hiaddr); 398 1.3 matt 399 1.3 matt loaddr = gt_read(gt, GT_PCI0_Mem3_Remap_Low); 400 1.3 matt hiaddr = gt_read(gt, GT_PCI0_Mem3_Remap_High); 401 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 402 1.3 matt 403 1.24 kiyohara loaddr = GT_LADDR_GET(gt_read(gt, GT_PCI1_IO_Low_Decode), gt->sc_model); 404 1.24 kiyohara hiaddr = 405 1.24 kiyohara GT_HADDR_GET(gt_read(gt, GT_PCI1_IO_High_Decode), gt->sc_model); 406 1.24 kiyohara aprint_normal_dev(gt->sc_dev, " pci1io=%#10x-%#10x ", 407 1.23 kiyohara loaddr, hiaddr); 408 1.3 matt 409 1.3 matt loaddr = gt_read(gt, GT_PCI1_IO_Remap); 410 1.3 matt aprint_normal("remap=%#010x\n", loaddr); 411 1.3 matt 412 1.24 kiyohara loaddr = 413 1.24 kiyohara GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem0_Low_Decode), gt->sc_model); 414 1.24 kiyohara hiaddr = 415 1.24 kiyohara GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem0_High_Decode), gt->sc_model); 416 1.24 kiyohara aprint_normal_dev(gt->sc_dev, " pci1mem[0]=%#10x-%#10x ", 417 1.23 kiyohara loaddr, hiaddr); 418 1.3 matt 419 1.3 matt loaddr = gt_read(gt, GT_PCI1_Mem0_Remap_Low); 420 1.3 matt hiaddr = gt_read(gt, GT_PCI1_Mem0_Remap_High); 421 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 422 1.3 matt 423 1.24 kiyohara loaddr = 424 1.24 kiyohara GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem1_Low_Decode), gt->sc_model); 425 1.24 kiyohara hiaddr = 426 1.24 kiyohara GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem1_High_Decode), gt->sc_model); 427 1.24 kiyohara aprint_normal_dev(gt->sc_dev, " pci1mem[1]=%#10x-%#10x ", 428 1.23 kiyohara loaddr, hiaddr); 429 1.3 matt 430 1.3 matt loaddr = gt_read(gt, GT_PCI1_Mem1_Remap_Low); 431 1.3 matt hiaddr = gt_read(gt, GT_PCI1_Mem1_Remap_High); 432 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 433 1.3 matt 434 1.24 kiyohara loaddr = 435 1.24 kiyohara GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem2_Low_Decode), gt->sc_model); 436 1.24 kiyohara hiaddr = 437 1.24 kiyohara GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem2_High_Decode), gt->sc_model); 438 1.24 kiyohara aprint_normal_dev(gt->sc_dev, " pci1mem[2]=%#10x-%#10x ", 439 1.23 kiyohara loaddr, hiaddr); 440 1.3 matt 441 1.3 matt loaddr = gt_read(gt, GT_PCI1_Mem2_Remap_Low); 442 1.3 matt hiaddr = gt_read(gt, GT_PCI1_Mem2_Remap_High); 443 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 444 1.3 matt 445 1.24 kiyohara loaddr = 446 1.24 kiyohara GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem3_Low_Decode), gt->sc_model); 447 1.24 kiyohara hiaddr = 448 1.24 kiyohara GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem3_High_Decode), gt->sc_model); 449 1.24 kiyohara aprint_normal_dev(gt->sc_dev, " pci1mem[3]=%#10x-%#10x ", 450 1.23 kiyohara loaddr, hiaddr); 451 1.3 matt 452 1.3 matt loaddr = gt_read(gt, GT_PCI1_Mem3_Remap_Low); 453 1.3 matt hiaddr = gt_read(gt, GT_PCI1_Mem3_Remap_High); 454 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 455 1.1 matt 456 1.24 kiyohara loaddr = GT_LADDR_GET(gt_read(gt, GT_Internal_Decode), gt->sc_model); 457 1.24 kiyohara aprint_normal_dev(gt->sc_dev, " internal=%#10x-%#10x\n", 458 1.23 kiyohara loaddr, loaddr + 256 * 1024); 459 1.1 matt 460 1.24 kiyohara loaddr = GT_LADDR_GET(gt_read(gt, GT_CPU0_Low_Decode), gt->sc_model); 461 1.24 kiyohara hiaddr = GT_HADDR_GET(gt_read(gt, GT_CPU0_High_Decode), gt->sc_model); 462 1.24 kiyohara aprint_normal_dev(gt->sc_dev, " cpu0=%#10x-%#10x\n", 463 1.23 kiyohara loaddr, hiaddr); 464 1.1 matt 465 1.24 kiyohara #ifdef MULTIPROCESSOR 466 1.24 kiyohara loaddr = GT_LADDR_GET(gt_read(gt, GT_CPU1_Low_Decode), gt->sc_model); 467 1.24 kiyohara hiaddr = GT_HADDR_GET(gt_read(gt, GT_CPU1_High_Decode), gt->sc_model); 468 1.23 kiyohara aprint_normal_dev(gt->sc_dev, " cpu1=%#10x-%#10x", 469 1.23 kiyohara loaddr, hiaddr); 470 1.1 matt #endif 471 1.24 kiyohara #endif 472 1.1 matt 473 1.23 kiyohara aprint_normal("%s:", device_xname(gt->sc_dev)); 474 1.1 matt 475 1.3 matt cpucfg = gt_read(gt, GT_CPU_Cfg); 476 1.1 matt cpucfg |= GT_CPUCfg_ConfSBDis; /* per errata #46 */ 477 1.1 matt cpucfg |= GT_CPUCfg_AACKDelay; /* per restriction #18 */ 478 1.3 matt gt_write(gt, GT_CPU_Cfg, cpucfg); 479 1.1 matt if (cpucfg & GT_CPUCfg_Pipeline) 480 1.3 matt aprint_normal(" pipeline"); 481 1.1 matt if (cpucfg & GT_CPUCfg_AACKDelay) 482 1.3 matt aprint_normal(" aack-delay"); 483 1.1 matt if (cpucfg & GT_CPUCfg_RdOOO) 484 1.3 matt aprint_normal(" read-ooo"); 485 1.1 matt if (cpucfg & GT_CPUCfg_IOSBDis) 486 1.3 matt aprint_normal(" io-sb-dis"); 487 1.1 matt if (cpucfg & GT_CPUCfg_ConfSBDis) 488 1.3 matt aprint_normal(" conf-sb-dis"); 489 1.1 matt if (cpucfg & GT_CPUCfg_ClkSync) 490 1.3 matt aprint_normal(" clk-sync"); 491 1.3 matt aprint_normal("\n"); 492 1.1 matt 493 1.23 kiyohara #ifdef GT_WATCHDOG 494 1.1 matt gt_watchdog_init(gt); 495 1.23 kiyohara #endif 496 1.1 matt 497 1.23 kiyohara #ifdef GT_DEVBUS 498 1.23 kiyohara gt_devbus_intr_enb(gt); 499 1.23 kiyohara #endif 500 1.1 matt #ifdef GT_ECC 501 1.1 matt gt_ecc_intr_enb(gt); 502 1.1 matt #endif 503 1.23 kiyohara #if NGTMPSC > 0 504 1.23 kiyohara gt_sdma_intr_enb(gt); 505 1.23 kiyohara #endif 506 1.23 kiyohara #ifdef GT_COMM 507 1.23 kiyohara gt_comm_intr_enb(gt); 508 1.23 kiyohara #endif 509 1.1 matt 510 1.23 kiyohara gt_attach_peripherals(gt); 511 1.1 matt 512 1.23 kiyohara #ifdef GT_WATCHDOG 513 1.1 matt gt_watchdog_service(); 514 1.23 kiyohara gt_watchdog_enable(gt); 515 1.23 kiyohara #endif 516 1.1 matt } 517 1.1 matt 518 1.23 kiyohara 519 1.23 kiyohara #ifdef GT_DEVBUS 520 1.23 kiyohara static int 521 1.23 kiyohara gt_devbus_intr(void *arg) 522 1.23 kiyohara { 523 1.23 kiyohara struct gt_softc *gt = (struct gt_softc *)arg; 524 1.23 kiyohara u_int32_t cause; 525 1.23 kiyohara u_int32_t addr; 526 1.23 kiyohara 527 1.23 kiyohara cause = gt_read(gt, GT_DEVBUS_ICAUSE); 528 1.23 kiyohara addr = gt_read(gt, GT_DEVBUS_ERR_ADDR); 529 1.23 kiyohara gt_write(gt, GT_DEVBUS_ICAUSE, 0); /* clear intr */ 530 1.23 kiyohara 531 1.23 kiyohara if (cause & GT_DEVBUS_DBurstErr) { 532 1.23 kiyohara aprint_error_dev(gt->sc_dev, 533 1.23 kiyohara "Device Bus error: burst violation"); 534 1.23 kiyohara if ((cause & GT_DEVBUS_Sel) == 0) 535 1.23 kiyohara aprint_error(", addr %#x", addr); 536 1.23 kiyohara aprint_error("\n"); 537 1.23 kiyohara } 538 1.23 kiyohara if (cause & GT_DEVBUS_DRdyErr) { 539 1.23 kiyohara aprint_error_dev(gt->sc_dev, 540 1.23 kiyohara "Device Bus error: ready timer expired"); 541 1.23 kiyohara if ((cause & GT_DEVBUS_Sel) != 0) 542 1.23 kiyohara aprint_error(", addr %#x\n", addr); 543 1.23 kiyohara aprint_error("\n"); 544 1.23 kiyohara } 545 1.23 kiyohara 546 1.23 kiyohara return cause != 0; 547 1.23 kiyohara } 548 1.23 kiyohara 549 1.23 kiyohara /* 550 1.23 kiyohara * gt_devbus_intr_enb - enable GT-64260 Device Bus interrupts 551 1.23 kiyohara */ 552 1.23 kiyohara static void 553 1.23 kiyohara gt_devbus_intr_enb(struct gt_softc *gt) 554 1.1 matt { 555 1.23 kiyohara gt_write(gt, GT_DEVBUS_IMASK, 556 1.23 kiyohara GT_DEVBUS_DBurstErr|GT_DEVBUS_DRdyErr); 557 1.23 kiyohara (void)gt_read(gt, GT_DEVBUS_ERR_ADDR); /* clear addr */ 558 1.23 kiyohara gt_write(gt, GT_DEVBUS_ICAUSE, 0); /* clear intr */ 559 1.1 matt 560 1.23 kiyohara (void)marvell_intr_establish(IRQ_DEV, IPL_VM, gt_devbus_intr, gt); 561 1.1 matt } 562 1.23 kiyohara #endif /* GT_DEVBUS */ 563 1.23 kiyohara 564 1.23 kiyohara #ifdef GT_ECC 565 1.23 kiyohara const static char *gt_ecc_intr_str[4] = { 566 1.23 kiyohara "(none)", 567 1.23 kiyohara "single bit", 568 1.23 kiyohara "double bit", 569 1.23 kiyohara "(reserved)" 570 1.23 kiyohara }; 571 1.1 matt 572 1.23 kiyohara static int 573 1.23 kiyohara gt_ecc_intr(void *arg) 574 1.1 matt { 575 1.23 kiyohara struct gt_softc *gt = (struct gt_softc *)arg; 576 1.23 kiyohara uint32_t addr, dlo, dhi, rec, calc, count; 577 1.23 kiyohara int err; 578 1.23 kiyohara 579 1.23 kiyohara count = gt_read(gt, GT_ECC_Count); 580 1.23 kiyohara dlo = gt_read(gt, GT_ECC_Data_Lo); 581 1.23 kiyohara dhi = gt_read(gt, GT_ECC_Data_Hi); 582 1.23 kiyohara rec = gt_read(gt, GT_ECC_Rec); 583 1.23 kiyohara calc = gt_read(gt, GT_ECC_Calc); 584 1.23 kiyohara addr = gt_read(gt, GT_ECC_Addr); /* read last! */ 585 1.23 kiyohara gt_write(gt, GT_ECC_Addr, 0); /* clear intr */ 586 1.23 kiyohara 587 1.23 kiyohara err = addr & 0x3; 588 1.1 matt 589 1.23 kiyohara aprint_error_dev(gt->sc_dev, 590 1.23 kiyohara "ECC error: %s: addr %#x data %#x.%#x rec %#x calc %#x cnt %#x\n", 591 1.23 kiyohara gt_ecc_intr_str[err], addr, dhi, dlo, rec, calc, count); 592 1.1 matt 593 1.23 kiyohara if (err == 2) 594 1.23 kiyohara panic("ecc"); 595 1.1 matt 596 1.23 kiyohara return err == 1; 597 1.1 matt } 598 1.1 matt 599 1.23 kiyohara /* 600 1.23 kiyohara * gt_ecc_intr_enb - enable GT-64260 ECC interrupts 601 1.23 kiyohara */ 602 1.23 kiyohara static void 603 1.23 kiyohara gt_ecc_intr_enb(struct gt_softc *gt) 604 1.1 matt { 605 1.23 kiyohara uint32_t ctl; 606 1.23 kiyohara 607 1.23 kiyohara ctl = gt_read(gt, GT_ECC_Ctl); 608 1.23 kiyohara ctl |= 1 << 16; /* XXX 1-bit threshold == 1 */ 609 1.23 kiyohara gt_write(gt, GT_ECC_Ctl, ctl); 610 1.23 kiyohara (void)gt_read(gt, GT_ECC_Data_Lo); 611 1.23 kiyohara (void)gt_read(gt, GT_ECC_Data_Hi); 612 1.23 kiyohara (void)gt_read(gt, GT_ECC_Rec); 613 1.23 kiyohara (void)gt_read(gt, GT_ECC_Calc); 614 1.23 kiyohara (void)gt_read(gt, GT_ECC_Addr); /* read last! */ 615 1.23 kiyohara gt_write(gt, GT_ECC_Addr, 0); /* clear intr */ 616 1.23 kiyohara 617 1.23 kiyohara (void)marvell_intr_establish(IRQ_ECC, IPL_VM, gt_ecc_intr, gt); 618 1.1 matt } 619 1.23 kiyohara #endif /* GT_ECC */ 620 1.1 matt 621 1.23 kiyohara #if NGTMPSC > 0 622 1.23 kiyohara /* 623 1.23 kiyohara * gt_sdma_intr_enb - enable GT-64260 SDMA interrupts 624 1.23 kiyohara */ 625 1.23 kiyohara static void 626 1.23 kiyohara gt_sdma_intr_enb(struct gt_softc *gt) 627 1.1 matt { 628 1.1 matt 629 1.23 kiyohara (void)marvell_intr_establish(IRQ_SDMA, IPL_SERIAL, gtmpsc_intr, gt); 630 1.1 matt } 631 1.1 matt #endif 632 1.1 matt 633 1.23 kiyohara #ifdef GT_COMM 634 1.1 matt /* 635 1.1 matt * unknown board, enable everything 636 1.1 matt */ 637 1.23 kiyohara # define GT_CommUnitIntr_DFLT \ 638 1.23 kiyohara GT_CommUnitIntr_S0 |\ 639 1.23 kiyohara GT_CommUnitIntr_S1 |\ 640 1.23 kiyohara GT_CommUnitIntr_E0 |\ 641 1.23 kiyohara GT_CommUnitIntr_E1 |\ 642 1.23 kiyohara GT_CommUnitIntr_E2 643 1.1 matt 644 1.1 matt static const char * const gt_comm_subunit_name[8] = { 645 1.1 matt "ethernet 0", 646 1.1 matt "ethernet 1", 647 1.1 matt "ethernet 2", 648 1.1 matt "(reserved)", 649 1.1 matt "MPSC 0", 650 1.1 matt "MPSC 1", 651 1.1 matt "(reserved)", 652 1.1 matt "(sel)", 653 1.1 matt }; 654 1.1 matt 655 1.1 matt static int 656 1.1 matt gt_comm_intr(void *arg) 657 1.1 matt { 658 1.1 matt struct gt_softc *gt = (struct gt_softc *)arg; 659 1.23 kiyohara uint32_t cause, addr; 660 1.1 matt unsigned int mask; 661 1.1 matt int i; 662 1.1 matt 663 1.3 matt cause = gt_read(gt, GT_CommUnitIntr_Cause); 664 1.3 matt gt_write(gt, GT_CommUnitIntr_Cause, ~cause); 665 1.3 matt addr = gt_read(gt, GT_CommUnitIntr_ErrAddr); 666 1.1 matt 667 1.23 kiyohara aprint_error_dev(gt->sc_dev, 668 1.23 kiyohara "Communications Unit Controller interrupt, cause %#x addr %#x\n", 669 1.23 kiyohara cause, addr); 670 1.1 matt 671 1.1 matt cause &= GT_CommUnitIntr_DFLT; 672 1.1 matt if (cause == 0) 673 1.1 matt return 0; 674 1.3 matt 675 1.1 matt mask = 0x7; 676 1.1 matt for (i=0; i<7; i++) { 677 1.1 matt if (cause & mask) { 678 1.23 kiyohara printf("%s: Comm Unit %s:", device_xname(gt->sc_dev), 679 1.1 matt gt_comm_subunit_name[i]); 680 1.9 perry if (cause & 1) 681 1.1 matt printf(" AddrMiss"); 682 1.9 perry if (cause & 2) 683 1.1 matt printf(" AccProt"); 684 1.9 perry if (cause & 4) 685 1.1 matt printf(" WrProt"); 686 1.1 matt printf("\n"); 687 1.1 matt } 688 1.1 matt cause >>= 4; 689 1.1 matt } 690 1.1 matt return 1; 691 1.1 matt } 692 1.1 matt 693 1.1 matt /* 694 1.1 matt * gt_comm_intr_init - enable GT-64260 Comm Unit interrupts 695 1.1 matt */ 696 1.1 matt static void 697 1.1 matt gt_comm_intr_enb(struct gt_softc *gt) 698 1.1 matt { 699 1.23 kiyohara uint32_t cause; 700 1.1 matt 701 1.3 matt cause = gt_read(gt, GT_CommUnitIntr_Cause); 702 1.1 matt if (cause) 703 1.3 matt gt_write(gt, GT_CommUnitIntr_Cause, ~cause); 704 1.3 matt gt_write(gt, GT_CommUnitIntr_Mask, GT_CommUnitIntr_DFLT); 705 1.3 matt (void)gt_read(gt, GT_CommUnitIntr_ErrAddr); 706 1.1 matt 707 1.23 kiyohara (void)marvell_intr_establish(IRQ_COMM, IPL_VM, gt_comm_intr, gt); 708 1.1 matt } 709 1.23 kiyohara #endif /* GT_COMM */ 710 1.1 matt 711 1.1 matt 712 1.23 kiyohara #ifdef GT_WATCHDOG 713 1.23 kiyohara #ifndef GT_MPP_WATCHDOG 714 1.1 matt static void 715 1.3 matt gt_watchdog_init(struct gt_softc *gt) 716 1.1 matt { 717 1.1 matt u_int32_t r; 718 1.1 matt 719 1.23 kiyohara aprint_normal_dev(gt->sc_dev, "watchdog"); 720 1.1 matt 721 1.1 matt /* 722 1.1 matt * handle case where firmware started watchdog 723 1.1 matt */ 724 1.3 matt r = gt_read(gt, GT_WDOG_Config); 725 1.23 kiyohara aprint_normal(" status %#x,%#x:", r, gt_read(gt, GT_WDOG_Value)); 726 1.1 matt if ((r & 0x80000000) != 0) { 727 1.3 matt gt_watchdog_sc = gt; /* enabled */ 728 1.1 matt gt_watchdog_state = 1; 729 1.23 kiyohara aprint_normal(" firmware-enabled\n"); 730 1.23 kiyohara gt_watchdog_disable(gt); 731 1.23 kiyohara } else 732 1.23 kiyohara aprint_normal(" firmware-disabled\n"); 733 1.23 kiyohara } 734 1.23 kiyohara 735 1.23 kiyohara #elif GT_MPP_WATCHDOG == 0 736 1.23 kiyohara 737 1.23 kiyohara static void 738 1.23 kiyohara gt_watchdog_init(struct gt_softc *gt) 739 1.23 kiyohara { 740 1.1 matt 741 1.23 kiyohara aprint_normal_dev(gt->sc_dev, "watchdog not configured\n"); 742 1.23 kiyohara return; 743 1.1 matt } 744 1.1 matt 745 1.23 kiyohara #else /* GT_MPP_WATCHDOG > 0 */ 746 1.1 matt 747 1.23 kiyohara static void 748 1.3 matt gt_watchdog_init(struct gt_softc *gt) 749 1.1 matt { 750 1.1 matt u_int32_t mpp_watchdog = GT_MPP_WATCHDOG; /* from config */ 751 1.23 kiyohara u_int32_t cfgbits, mppbits, mppmask, regoff, r; 752 1.1 matt 753 1.23 kiyohara mppmask = 0; 754 1.1 matt 755 1.23 kiyohara aprint_normal_dev(gt->sc_dev, "watchdog"); 756 1.1 matt 757 1.1 matt /* 758 1.1 matt * if firmware started watchdog, we disable and start 759 1.1 matt * from scratch to get it in a known state. 760 1.1 matt * 761 1.1 matt * on GT-64260A we always see 0xffffffff 762 1.27 kamil * in both the GT_WDOG_Config_Enb and GT_WDOG_Value registers. 763 1.1 matt */ 764 1.3 matt r = gt_read(gt, GT_WDOG_Config); 765 1.1 matt if (r != ~0) { 766 1.1 matt if ((r & GT_WDOG_Config_Enb) != 0) { 767 1.3 matt gt_write(gt, GT_WDOG_Config, 768 1.23 kiyohara GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT); 769 1.3 matt gt_write(gt, GT_WDOG_Config, 770 1.23 kiyohara GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT); 771 1.1 matt } 772 1.1 matt } 773 1.1 matt 774 1.1 matt /* 775 1.1 matt * "the watchdog timer can be activated only after 776 1.1 matt * configuring two MPP pins to act as WDE and WDNMI" 777 1.1 matt */ 778 1.1 matt mppbits = 0; 779 1.1 matt cfgbits = 0x3; 780 1.1 matt for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4) { 781 1.1 matt if ((mpp_watchdog & cfgbits) == cfgbits) { 782 1.1 matt mppbits = 0x99; 783 1.1 matt mppmask = 0xff; 784 1.1 matt break; 785 1.1 matt } 786 1.1 matt cfgbits <<= 2; 787 1.1 matt if ((mpp_watchdog & cfgbits) == cfgbits) { 788 1.1 matt mppbits = 0x9900; 789 1.1 matt mppmask = 0xff00; 790 1.1 matt break; 791 1.1 matt } 792 1.1 matt cfgbits <<= 6; /* skip unqualified bits */ 793 1.1 matt } 794 1.1 matt if (mppbits == 0) { 795 1.23 kiyohara aprint_error(" config error\n"); 796 1.1 matt return; 797 1.1 matt } 798 1.1 matt 799 1.3 matt r = gt_read(gt, regoff); 800 1.1 matt r &= ~mppmask; 801 1.1 matt r |= mppbits; 802 1.3 matt gt_write(gt, regoff, r); 803 1.23 kiyohara aprint_normal(" mpp %#x %#x", regoff, mppbits); 804 1.1 matt 805 1.3 matt gt_write(gt, GT_WDOG_Value, GT_WDOG_NMI_DFLT); 806 1.1 matt 807 1.23 kiyohara gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1a|GT_WDOG_Preset_DFLT); 808 1.23 kiyohara gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1b|GT_WDOG_Preset_DFLT); 809 1.1 matt 810 1.28 christos r = gt_read(gt, GT_WDOG_Config); 811 1.23 kiyohara aprint_normal(" status %#x,%#x: %s\n", 812 1.23 kiyohara r, gt_read(gt, GT_WDOG_Value), 813 1.23 kiyohara ((r & GT_WDOG_Config_Enb) != 0) ? "enabled" : "botch"); 814 1.1 matt } 815 1.1 matt #endif /* GT_MPP_WATCHDOG */ 816 1.1 matt 817 1.23 kiyohara static void 818 1.23 kiyohara gt_watchdog_enable(struct gt_softc *gt) 819 1.1 matt { 820 1.1 matt 821 1.23 kiyohara if (gt_watchdog_state == 0) { 822 1.1 matt gt_watchdog_state = 1; 823 1.1 matt 824 1.3 matt gt_write(gt, GT_WDOG_Config, 825 1.23 kiyohara GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT); 826 1.3 matt gt_write(gt, GT_WDOG_Config, 827 1.23 kiyohara GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT); 828 1.1 matt } 829 1.1 matt } 830 1.1 matt 831 1.23 kiyohara #ifndef GT_MPP_WATCHDOG 832 1.23 kiyohara static void 833 1.23 kiyohara gt_watchdog_disable(struct gt_softc *gt) 834 1.1 matt { 835 1.1 matt 836 1.23 kiyohara if (gt_watchdog_state != 0) { 837 1.1 matt gt_watchdog_state = 0; 838 1.1 matt 839 1.3 matt gt_write(gt, GT_WDOG_Config, 840 1.23 kiyohara GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT); 841 1.3 matt gt_write(gt, GT_WDOG_Config, 842 1.23 kiyohara GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT); 843 1.1 matt } 844 1.1 matt } 845 1.23 kiyohara #endif 846 1.23 kiyohara 847 1.23 kiyohara /* 848 1.23 kiyohara * XXXX: gt_watchdog_service/reset functions need mutex lock... 849 1.23 kiyohara */ 850 1.1 matt 851 1.24 kiyohara #ifdef GT_DEBUG 852 1.1 matt int inhibit_watchdog_service = 0; 853 1.1 matt #endif 854 1.1 matt void 855 1.1 matt gt_watchdog_service(void) 856 1.1 matt { 857 1.3 matt struct gt_softc *gt = gt_watchdog_sc; 858 1.1 matt 859 1.3 matt if ((gt == NULL) || (gt_watchdog_state == 0)) 860 1.1 matt return; /* not enabled */ 861 1.24 kiyohara #ifdef GT_DEBUG 862 1.1 matt if (inhibit_watchdog_service) 863 1.1 matt return; 864 1.1 matt #endif 865 1.9 perry 866 1.23 kiyohara gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl2a|GT_WDOG_Preset_DFLT); 867 1.23 kiyohara gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl2b|GT_WDOG_Preset_DFLT); 868 1.1 matt } 869 1.1 matt 870 1.1 matt /* 871 1.1 matt * gt_watchdog_reset - force a watchdog reset using Preset_VAL=0 872 1.1 matt */ 873 1.1 matt void 874 1.19 cegger gt_watchdog_reset(void) 875 1.1 matt { 876 1.3 matt struct gt_softc *gt = gt_watchdog_sc; 877 1.1 matt u_int32_t r; 878 1.1 matt 879 1.3 matt r = gt_read(gt, GT_WDOG_Config); 880 1.23 kiyohara gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1a); 881 1.23 kiyohara gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1b); 882 1.1 matt if ((r & GT_WDOG_Config_Enb) != 0) { 883 1.1 matt /* 884 1.1 matt * was enabled, we just toggled it off, toggle on again 885 1.1 matt */ 886 1.23 kiyohara gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1a); 887 1.23 kiyohara gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1b); 888 1.1 matt } 889 1.1 matt for(;;); 890 1.1 matt } 891 1.23 kiyohara #endif 892 1.1 matt 893 1.1 matt 894 1.1 matt int 895 1.23 kiyohara marvell_winparams_by_tag(device_t dev, int tag, int *target, int *attr, 896 1.23 kiyohara uint64_t *base, uint32_t *size) 897 1.1 matt { 898 1.23 kiyohara static const struct { 899 1.23 kiyohara int tag; 900 1.23 kiyohara uint32_t attribute; 901 1.23 kiyohara uint32_t basereg; 902 1.23 kiyohara uint32_t sizereg; 903 1.23 kiyohara } tagtbl[] = { 904 1.23 kiyohara { MARVELL_TAG_SDRAM_CS0, MARVELL_ATTR_SDRAM_CS0, 905 1.23 kiyohara GT_SCS0_Low_Decode, GT_SCS0_High_Decode }, 906 1.23 kiyohara { MARVELL_TAG_SDRAM_CS1, MARVELL_ATTR_SDRAM_CS1, 907 1.23 kiyohara GT_SCS1_Low_Decode, GT_SCS1_High_Decode }, 908 1.23 kiyohara { MARVELL_TAG_SDRAM_CS2, MARVELL_ATTR_SDRAM_CS2, 909 1.23 kiyohara GT_SCS2_Low_Decode, GT_SCS2_High_Decode }, 910 1.23 kiyohara { MARVELL_TAG_SDRAM_CS3, MARVELL_ATTR_SDRAM_CS3, 911 1.23 kiyohara GT_SCS3_Low_Decode, GT_SCS3_High_Decode }, 912 1.23 kiyohara 913 1.23 kiyohara { MARVELL_TAG_UNDEFINED, 0, 0 } 914 1.23 kiyohara }; 915 1.23 kiyohara struct gt_softc *sc = device_private(dev); 916 1.23 kiyohara int i; 917 1.1 matt 918 1.23 kiyohara for (i = 0; tagtbl[i].tag != MARVELL_TAG_UNDEFINED; i++) 919 1.23 kiyohara if (tag == tagtbl[i].tag) 920 1.23 kiyohara break; 921 1.23 kiyohara if (tagtbl[i].tag == MARVELL_TAG_UNDEFINED) 922 1.23 kiyohara return -1; 923 1.1 matt 924 1.23 kiyohara if (target != NULL) 925 1.23 kiyohara *target = 0; 926 1.23 kiyohara if (attr != NULL) 927 1.23 kiyohara *attr = tagtbl[i].attribute; 928 1.23 kiyohara if (base != NULL) 929 1.23 kiyohara *base = gt_read(sc, tagtbl[i].basereg) << 930 1.23 kiyohara (sc->sc_model == MARVELL_DISCOVERY ? 20 : 16); 931 1.23 kiyohara if (size != NULL) { 932 1.23 kiyohara const uint32_t s = gt_read(sc, tagtbl[i].sizereg); 933 1.23 kiyohara 934 1.23 kiyohara if (s != 0) 935 1.23 kiyohara *size = (s + 1) << 936 1.23 kiyohara (sc->sc_model == MARVELL_DISCOVERY ? 20 : 16); 937 1.23 kiyohara else 938 1.23 kiyohara *size = 0; 939 1.1 matt } 940 1.1 matt 941 1.23 kiyohara return 0; 942 1.6 matt } 943