The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/marvell/gt.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: gt.c,v 1.6 2004/03/20 01:55:00 matt Exp $      */
    2 
    3 /*
    4  * Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. All advertising materials mentioning features or use of this software
   16  *    must display the following acknowledgement:
   17  *      This product includes software developed for the NetBSD Project by
   18  *      Allegro Networks, Inc., and Wasabi Systems, Inc.
   19  * 4. The name of Allegro Networks, Inc. may not be used to endorse
   20  *    or promote products derived from this software without specific prior
   21  *    written permission.
   22  * 5. The name of Wasabi Systems, Inc. may not be used to endorse
   23  *    or promote products derived from this software without specific prior
   24  *    written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
   27  * WASABI SYSTEMS, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
   28  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
   29  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   30  * IN NO EVENT SHALL EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 /*
   41  * gt.c -- GT system controller driver
   42  */
   43 
   44 #include <sys/cdefs.h>
   45 __KERNEL_RCSID(0, "$NetBSD: gt.c,v 1.6 2004/03/20 01:55:00 matt Exp $");
   46 
   47 #include "opt_marvell.h"
   48 
   49 #include <sys/param.h>
   50 #include <sys/types.h>
   51 #include <sys/cdefs.h>
   52 #include <sys/extent.h>
   53 #include <sys/device.h>
   54 #include <sys/kernel.h>
   55 #include <sys/malloc.h>
   56 
   57 #define _BUS_SPACE_PRIVATE
   58 #define _BUS_DMA_PRIVATE
   59 #include <machine/bus.h>
   60 
   61 #include <powerpc/spr.h>
   62 #include <powerpc/oea/hid.h>
   63 
   64 #include <dev/marvell/gtreg.h>
   65 #include <dev/marvell/gtintrreg.h>
   66 #include <dev/marvell/gtvar.h>
   67 #include <dev/marvell/gtethreg.h>
   68 
   69 #ifdef DEBUG
   70 #include <sys/systm.h>  /* for Debugger() */
   71 #endif
   72 
   73 #if ((GT_MPP_WATCHDOG & 0xf0f0f0f0) != 0)
   74 # error         /* unqualified: configuration botch! */
   75 #endif
   76 #if ((GT_MPP_WATCHDOG & GT_MPP_INTERRUPTS) != 0)
   77 # error         /* conflict: configuration botch! */
   78 #endif
   79 
   80 static void     gt_comm_intr_enb(struct gt_softc *);
   81 static void     gt_devbus_intr_enb(struct gt_softc *);
   82 #ifdef GT_ECC
   83 static void     gt_ecc_intr_enb(struct gt_softc *);
   84 #endif
   85 
   86 
   87 void gt_init_hostid (struct gt_softc *);
   88 void gt_init_interrupt (struct gt_softc *);
   89 static int gt_comm_intr (void *);
   90 
   91 void gt_watchdog_init(struct gt_softc *);
   92 void gt_watchdog_enable(void);
   93 void gt_watchdog_disable(void);
   94 void gt_watchdog_reset(void);
   95 
   96 extern struct cfdriver gt_cd;
   97 
   98 static int gtfound = 0;
   99 
  100 static struct gt_softc *gt_watchdog_sc = 0;
  101 static int gt_watchdog_state = 0;
  102 
  103 int
  104 gt_cfprint (void *aux, const char *pnp)
  105 {
  106         struct gt_attach_args *ga = aux;
  107 
  108         if (pnp) {
  109                 aprint_normal("%s at %s", ga->ga_name, pnp);
  110         }
  111 
  112         aprint_normal(" unit %d", ga->ga_unit);
  113         return (UNCONF);
  114 }
  115 
  116 
  117 static int
  118 gt_cfsearch(struct device *parent, struct cfdata *cf, void *aux)
  119 {
  120         struct gt_softc *gt = (struct gt_softc *) parent;
  121         struct gt_attach_args ga;
  122 
  123         ga.ga_name = cf->cf_name;
  124         ga.ga_dmat = gt->gt_dmat;
  125         ga.ga_memt = gt->gt_memt;
  126         ga.ga_memh = gt->gt_memh;
  127         ga.ga_unit = cf->cf_loc[GTCF_UNIT];
  128 
  129         if (config_match(parent, cf, &ga) > 0)
  130                 config_attach(parent, cf, &ga, gt_cfprint);
  131 
  132         return (0);
  133 }
  134 
  135 void
  136 gt_attach_common(struct gt_softc *gt)
  137 {
  138         uint32_t cpucfg, cpumode, cpumstr;
  139 #ifdef DEBUG
  140         uint32_t loaddr, hiaddr;
  141 #endif
  142 
  143         gtfound = 1;
  144 
  145         cpumode = gt_read(gt, GT_CPU_Mode);
  146         aprint_normal(": id %d", GT_CPUMode_MultiGTID_GET(cpumode));
  147         if (cpumode & GT_CPUMode_MultiGT)
  148                 aprint_normal (" (multi)");
  149         switch (GT_CPUMode_CPUType_GET(cpumode)) {
  150         case 4: aprint_normal(", 60x bus"); break;
  151         case 5: aprint_normal(", MPX bus"); break;
  152         default: aprint_normal(", %#x(?) bus", GT_CPUMode_CPUType_GET(cpumode)); break;
  153         }
  154 
  155         cpumstr = gt_read(gt, GT_CPU_Master_Ctl);
  156         cpumstr &= ~(GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock);
  157 #if 0
  158         cpumstr |= GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock;
  159 #endif
  160         gt_write(gt, GT_CPU_Master_Ctl, cpumstr);
  161 
  162         switch (cpumstr & (GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock)) {
  163         case 0: break;
  164         case GT_CPUMstrCtl_CleanBlock: aprint_normal(", snoop=clean"); break;
  165         case GT_CPUMstrCtl_FlushBlock: aprint_normal(", snoop=flush"); break;
  166         case GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock:
  167                 aprint_normal(", snoop=clean&flush"); break;
  168         }
  169         aprint_normal(" wdog=%#x,%#x\n",
  170                 gt_read(gt, GT_WDOG_Config),
  171                 gt_read(gt, GT_WDOG_Value));
  172 
  173 #if DEBUG
  174         loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS0_Low_Decode));
  175         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS0_High_Decode));
  176         aprint_normal("%s:      scs[0]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
  177 
  178         loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS1_Low_Decode));
  179         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS1_High_Decode));
  180         aprint_normal("%s:      scs[1]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
  181 
  182         loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS2_Low_Decode));
  183         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS2_High_Decode));
  184         aprint_normal("%s:      scs[2]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
  185 
  186         loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS3_Low_Decode));
  187         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS3_High_Decode));
  188         aprint_normal("%s:      scs[3]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
  189 
  190         loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS0_Low_Decode));
  191         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS0_High_Decode));
  192         aprint_normal("%s:       cs[0]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
  193 
  194         loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS1_Low_Decode));
  195         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS1_High_Decode));
  196         aprint_normal("%s:       cs[1]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
  197 
  198         loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS2_Low_Decode));
  199         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS2_High_Decode));
  200         aprint_normal("%s:       cs[2]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
  201 
  202         loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS3_Low_Decode));
  203         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS3_High_Decode));
  204         aprint_normal("%s:       cs[3]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
  205 
  206         loaddr = GT_LowAddr_GET(gt_read(gt, GT_BootCS_Low_Decode));
  207         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_BootCS_High_Decode));
  208         aprint_normal("%s:      bootcs=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
  209 
  210         loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_IO_Low_Decode));
  211         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_IO_High_Decode));
  212         aprint_normal("%s:      pci0io=%#10x-%#10x  ", gt->gt_dev.dv_xname, loaddr, hiaddr);
  213 
  214         loaddr = gt_read(gt, GT_PCI0_IO_Remap);
  215         aprint_normal("remap=%#010x\n", loaddr);
  216 
  217         loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem0_Low_Decode));
  218         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem0_High_Decode));
  219         aprint_normal("%s:  pci0mem[0]=%#10x-%#10x  ", gt->gt_dev.dv_xname, loaddr, hiaddr);
  220 
  221         loaddr = gt_read(gt, GT_PCI0_Mem0_Remap_Low);
  222         hiaddr = gt_read(gt, GT_PCI0_Mem0_Remap_High);
  223         aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
  224 
  225         loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem1_Low_Decode));
  226         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem1_High_Decode));
  227         aprint_normal("%s:  pci0mem[1]=%#10x-%#10x  ", gt->gt_dev.dv_xname, loaddr, hiaddr);
  228 
  229         loaddr = gt_read(gt, GT_PCI0_Mem1_Remap_Low);
  230         hiaddr = gt_read(gt, GT_PCI0_Mem1_Remap_High);
  231         aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
  232 
  233         loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem2_Low_Decode));
  234         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem2_High_Decode));
  235         aprint_normal("%s:  pci0mem[2]=%#10x-%#10x  ", gt->gt_dev.dv_xname, loaddr, hiaddr);
  236 
  237         loaddr = gt_read(gt, GT_PCI0_Mem2_Remap_Low);
  238         hiaddr = gt_read(gt, GT_PCI0_Mem2_Remap_High);
  239         aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
  240 
  241         loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem3_Low_Decode));
  242         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem3_High_Decode));
  243         aprint_normal("%s:  pci0mem[3]=%#10x-%#10x  ", gt->gt_dev.dv_xname, loaddr, hiaddr);
  244 
  245         loaddr = gt_read(gt, GT_PCI0_Mem3_Remap_Low);
  246         hiaddr = gt_read(gt, GT_PCI0_Mem3_Remap_High);
  247         aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
  248 
  249         loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_IO_Low_Decode));
  250         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_IO_High_Decode));
  251         aprint_normal("%s:      pci1io=%#10x-%#10x  ", gt->gt_dev.dv_xname, loaddr, hiaddr);
  252 
  253         loaddr = gt_read(gt, GT_PCI1_IO_Remap);
  254         aprint_normal("remap=%#010x\n", loaddr);
  255 
  256         loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem0_Low_Decode));
  257         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem0_High_Decode));
  258         aprint_normal("%s:  pci1mem[0]=%#10x-%#10x  ", gt->gt_dev.dv_xname, loaddr, hiaddr);
  259 
  260         loaddr = gt_read(gt, GT_PCI1_Mem0_Remap_Low);
  261         hiaddr = gt_read(gt, GT_PCI1_Mem0_Remap_High);
  262         aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
  263 
  264         loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem1_Low_Decode));
  265         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem1_High_Decode));
  266         aprint_normal("%s:  pci1mem[1]=%#10x-%#10x  ", gt->gt_dev.dv_xname, loaddr, hiaddr);
  267 
  268         loaddr = gt_read(gt, GT_PCI1_Mem1_Remap_Low);
  269         hiaddr = gt_read(gt, GT_PCI1_Mem1_Remap_High);
  270         aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
  271 
  272         loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem2_Low_Decode));
  273         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem2_High_Decode));
  274         aprint_normal("%s:  pci1mem[2]=%#10x-%#10x  ", gt->gt_dev.dv_xname, loaddr, hiaddr);
  275 
  276         loaddr = gt_read(gt, GT_PCI1_Mem2_Remap_Low);
  277         hiaddr = gt_read(gt, GT_PCI1_Mem2_Remap_High);
  278         aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
  279 
  280         loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem3_Low_Decode));
  281         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem3_High_Decode));
  282         aprint_normal("%s:  pci1mem[3]=%#10x-%#10x  ", gt->gt_dev.dv_xname, loaddr, hiaddr);
  283 
  284         loaddr = gt_read(gt, GT_PCI1_Mem3_Remap_Low);
  285         hiaddr = gt_read(gt, GT_PCI1_Mem3_Remap_High);
  286         aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
  287 
  288         loaddr = GT_LowAddr_GET(gt_read(gt, GT_Internal_Decode));
  289         aprint_normal("%s:    internal=%#10x-%#10x\n", gt->gt_dev.dv_xname,
  290                 loaddr, loaddr+256*1024);
  291 
  292         loaddr = GT_LowAddr_GET(gt_read(gt, GT_CPU0_Low_Decode));
  293         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CPU0_High_Decode));
  294         aprint_normal("%s:        cpu0=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
  295 
  296         loaddr = GT_LowAddr_GET(gt_read(gt, GT_CPU1_Low_Decode));
  297         hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CPU1_High_Decode));
  298         aprint_normal("%s:        cpu1=%#10x-%#10x", gt->gt_dev.dv_xname, loaddr, hiaddr);
  299 #endif
  300 
  301         aprint_normal("%s:", gt->gt_dev.dv_xname);
  302 
  303         cpucfg = gt_read(gt, GT_CPU_Cfg);
  304         cpucfg |= GT_CPUCfg_ConfSBDis;          /* per errata #46 */
  305         cpucfg |= GT_CPUCfg_AACKDelay;          /* per restriction #18 */
  306         gt_write(gt, GT_CPU_Cfg, cpucfg);
  307         if (cpucfg & GT_CPUCfg_Pipeline)
  308                 aprint_normal(" pipeline");
  309         if (cpucfg & GT_CPUCfg_AACKDelay)
  310                 aprint_normal(" aack-delay");
  311         if (cpucfg & GT_CPUCfg_RdOOO)
  312                 aprint_normal(" read-ooo");
  313         if (cpucfg & GT_CPUCfg_IOSBDis)
  314                 aprint_normal(" io-sb-dis");
  315         if (cpucfg & GT_CPUCfg_ConfSBDis)
  316                 aprint_normal(" conf-sb-dis");
  317         if (cpucfg & GT_CPUCfg_ClkSync)
  318                 aprint_normal(" clk-sync");
  319         aprint_normal("\n");
  320 
  321         gt_init_hostid(gt);
  322 
  323         gt_watchdog_init(gt);
  324 
  325         gt_init_interrupt(gt);
  326 
  327 #ifdef GT_ECC
  328         gt_ecc_intr_enb(gt);
  329 #endif
  330 
  331         gt_comm_intr_enb(gt);
  332         gt_devbus_intr_enb(gt);
  333 
  334         gt_watchdog_disable();
  335         config_search(gt_cfsearch, &gt->gt_dev, NULL);
  336         gt_watchdog_service();
  337         gt_watchdog_enable();
  338 }
  339 
  340 void
  341 gt_init_hostid(struct gt_softc *gt)
  342 {
  343 
  344         hostid = 1;     /* XXX: Used by i2c; needs work -- AKB */
  345 }
  346 
  347 void
  348 gt_init_interrupt(struct gt_softc *gt)
  349 {
  350         u_int32_t mppirpts = GT_MPP_INTERRUPTS;         /* from config */
  351         u_int32_t r;
  352         u_int32_t mppbit;
  353         u_int32_t mask;
  354         u_int32_t mppsel;
  355         u_int32_t regoff;
  356 
  357         gt_write(gt, ICR_CIM_LO, 0);
  358         gt_write(gt, ICR_CIM_HI, 0);
  359 
  360         /*
  361          * configure the GPP interrupts:
  362          * - set the configured MPP pins in GPP mode
  363          * - set the configured GPP pins to input, active low, interrupt enbl
  364          */
  365 #ifdef DEBUG
  366         printf("%s: mpp cfg ", gt->gt_dev.dv_xname);
  367         for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4)
  368                 printf("%#x ", gt_read(gt, regoff));
  369         printf(", mppirpts 0x%x\n", mppirpts);
  370 #endif
  371         mppbit = 0x1;
  372         for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4) {
  373                 mask = 0;
  374                 for (mppsel = 0xf; mppsel; mppsel <<= 4) {
  375                         if (mppirpts & mppbit)
  376                                 mask |= mppsel;
  377                         mppbit <<= 1;
  378                 }
  379                 if (mask) {
  380                         r = gt_read(gt, regoff);
  381                         r &= ~mask;
  382                         gt_write(gt, regoff, r);
  383                 }
  384         }
  385 
  386         r = gt_read(gt, GT_GPP_IO_Control);
  387         r &= ~mppirpts;
  388         gt_write(gt, GT_GPP_IO_Control, r);
  389 
  390         r = gt_read(gt, GT_GPP_Level_Control);
  391         r |= mppirpts;
  392         gt_write(gt, GT_GPP_Level_Control, r);
  393 
  394         r = gt_read(gt, GT_GPP_Interrupt_Mask);
  395         r |= mppirpts;
  396         gt_write(gt, GT_GPP_Interrupt_Mask, r);
  397 }
  398 
  399 uint32_t
  400 gt_read_mpp (void)
  401 {
  402         return gt_read((struct gt_softc *)gt_cd.cd_devs[0], GT_GPP_Value);
  403 }
  404 
  405 #if 0
  406 int
  407 gt_bs_extent_init(struct discovery_bus_space *bs, char *name)
  408 {
  409         u_long start, end;
  410         int i, j, error;
  411 
  412         if (bs->bs_nregion == 0) {
  413                 bs->bs_extent = extent_create(name, 0xffffffffUL, 0xffffffffUL,
  414                     M_DEVBUF, NULL, 0, EX_NOCOALESCE|EX_WAITOK);
  415                 KASSERT(bs->bs_extent != NULL);
  416                 return 0;
  417         }
  418         /*
  419          * Find the top and bottoms of this bus space.
  420          */
  421         start = bs->bs_regions[0].br_start;
  422         end = bs->bs_regions[0].br_end;
  423 #ifdef DEBUG
  424         if (gtpci_debug > 1)
  425                 printf("gtpci_bs_extent_init: %s: region %d: %#lx-%#lx\n",
  426                         name, 0, bs->bs_regions[0].br_start,
  427                         bs->bs_regions[0].br_end);
  428 #endif
  429         for (i = 1; i < bs->bs_nregion; i++) {
  430                 if (bs->bs_regions[i].br_start < start)
  431                         start = bs->bs_regions[i].br_start;
  432                 if (bs->bs_regions[i].br_end > end)
  433                         end = bs->bs_regions[i].br_end;
  434 #ifdef DEBUG
  435                 if (gtpci_debug > 1)
  436                         printf("gtpci_bs_extent_init: %s: region %d:"
  437                                 " %#lx-%#lx\n",
  438                                 name, i, bs->bs_regions[i].br_start,
  439                                 bs->bs_regions[i].br_end);
  440 #endif
  441         }
  442         /*
  443          * Now that we have the top and bottom limits of this
  444          * bus space, create the extent map that will manage this
  445          * space for us.
  446          */
  447 #ifdef DEBUG
  448         if (gtpci_debug > 1)
  449                 printf("gtpci_bs_extent_init: %s: create: %#lx-%#lx\n",
  450                         name, start, end);
  451 #endif
  452         bs->bs_extent = extent_create(name, start, end, M_DEVBUF,
  453                 NULL, 0, EX_NOCOALESCE|EX_WAITOK);
  454         KASSERT(bs->bs_extent != NULL);
  455 
  456         /* If there was more than one bus space region, then there
  457          * might gaps in between them.  Allocate the gap so that
  458          * they will not be legal addresses in the extent.
  459          */
  460         for (i = 0; i < bs->bs_nregion && bs->bs_nregion > 1; i++) {
  461                 /* Initial start is "infinity" and the inital end is
  462                  * is the end of this bus region.
  463                  */ 
  464                 start = ~0UL;
  465                 end = bs->bs_regions[i].br_end;
  466                 /* For each region, if it starts after this region but less
  467                  * than the saved start, use its start address.  If the start
  468                  * address is one past the end address, then we're done
  469                  */
  470                 for (j = 0; j < bs->bs_nregion && start > end + 1; j++) {
  471                         if (i == j)
  472                                 continue;
  473                         if (bs->bs_regions[j].br_start > end &&
  474                             bs->bs_regions[j].br_start < start)
  475                                 start = bs->bs_regions[j].br_start;
  476                 }
  477                 /*
  478                  * If we found a gap, allocate it away.
  479                  */
  480                 if (start != ~0UL && start != end + 1) {
  481 #ifdef DEBUG
  482                         if (gtpci_debug > 1)
  483                                 printf("gtpci_bs_extent_init: %s: alloc(hole): %#lx-%#lx\n",
  484                                         name, end + 1, start - 1);
  485 #endif
  486                         error = extent_alloc_region(bs->bs_extent, end + 1,
  487                                 start - (end + 1), EX_NOWAIT);
  488                         KASSERT(error == 0);
  489                 }
  490         }
  491         return 1;
  492 }
  493 #endif
  494 
  495 /*
  496  * unknown board, enable everything
  497  */
  498 # define GT_CommUnitIntr_DFLT   GT_CommUnitIntr_S0|GT_CommUnitIntr_S1 \
  499                                 |GT_CommUnitIntr_E0|GT_CommUnitIntr_E1 \
  500                                 |GT_CommUnitIntr_E2
  501 
  502 static const char * const gt_comm_subunit_name[8] = {
  503         "ethernet 0",
  504         "ethernet 1",
  505         "ethernet 2",
  506         "(reserved)",
  507         "MPSC 0",
  508         "MPSC 1",
  509         "(reserved)",
  510         "(sel)",
  511 };
  512 
  513 static int
  514 gt_comm_intr(void *arg)
  515 {
  516         struct gt_softc *gt = (struct gt_softc *)arg;
  517         u_int32_t cause;
  518         u_int32_t addr;
  519         unsigned int mask;
  520         int i;
  521 
  522         cause = gt_read(gt, GT_CommUnitIntr_Cause);
  523         gt_write(gt, GT_CommUnitIntr_Cause, ~cause);
  524         addr = gt_read(gt, GT_CommUnitIntr_ErrAddr);
  525 
  526         printf("%s: Comm Unit irpt, cause %#x addr %#x\n",
  527                 gt->gt_dev.dv_xname, cause, addr);
  528 
  529         cause &= GT_CommUnitIntr_DFLT;
  530         if (cause == 0)
  531                 return 0;
  532 
  533         mask = 0x7;
  534         for (i=0; i<7; i++) {
  535                 if (cause & mask) {
  536                         printf("%s: Comm Unit %s:", gt->gt_dev.dv_xname,
  537                                 gt_comm_subunit_name[i]);
  538                         if (cause & 1) 
  539                                 printf(" AddrMiss");
  540                         if (cause & 2) 
  541                                 printf(" AccProt");
  542                         if (cause & 4) 
  543                                 printf(" WrProt");
  544                         printf("\n");
  545                 }
  546                 cause >>= 4;
  547         }
  548         return 1;
  549 }
  550 
  551 /*
  552  * gt_comm_intr_init - enable GT-64260 Comm Unit interrupts
  553  */
  554 static void
  555 gt_comm_intr_enb(struct gt_softc *gt)
  556 {
  557         u_int32_t cause;
  558 
  559         cause = gt_read(gt, GT_CommUnitIntr_Cause);
  560         if (cause)
  561                 gt_write(gt, GT_CommUnitIntr_Cause, ~cause);
  562         gt_write(gt, GT_CommUnitIntr_Mask, GT_CommUnitIntr_DFLT);
  563         (void)gt_read(gt, GT_CommUnitIntr_ErrAddr);
  564 
  565         intr_establish(IRQ_COMM, IST_LEVEL, IPL_GTERR, gt_comm_intr, gt);
  566         printf("%s: Comm Unit irpt at %d\n", gt->gt_dev.dv_xname, IRQ_COMM);
  567 }
  568 
  569 #ifdef GT_ECC
  570 static char *gt_ecc_intr_str[4] = {
  571         "(none)",
  572         "single bit",
  573         "double bit",
  574         "(reserved)"
  575 };
  576 
  577 static int
  578 gt_ecc_intr(void *arg)
  579 {
  580         struct gt_softc *gt = (struct gt_softc *)arg;
  581         u_int32_t addr;
  582         u_int32_t dlo;
  583         u_int32_t dhi;
  584         u_int32_t rec;
  585         u_int32_t calc;
  586         u_int32_t count;
  587         int err;
  588 
  589         count = gt_read(gt, GT_ECC_Count);
  590         dlo   = gt_read(gt, GT_ECC_Data_Lo);
  591         dhi   = gt_read(gt, GT_ECC_Data_Hi);
  592         rec   = gt_read(gt, GT_ECC_Rec);
  593         calc  = gt_read(gt, GT_ECC_Calc);
  594         addr  = gt_read(gt, GT_ECC_Addr);       /* read last! */
  595         gt_write(gt, GT_ECC_Addr, 0);           /* clear irpt */
  596 
  597         err = addr & 0x3;
  598 
  599         printf("%s: ECC error: %s: "
  600                 "addr %#x data %#x.%#x rec %#x calc %#x cnt %#x\n",
  601                 gt->gt_dev.dv_xname, gt_ecc_intr_str[err],
  602                 addr, dhi, dlo, rec, calc, count);
  603 
  604         if (err == 2)
  605                 panic("ecc");
  606 
  607         return (err == 1);
  608 }
  609 
  610 /*
  611  * gt_ecc_intr_enb - enable GT-64260 ECC interrupts
  612  */
  613 static void
  614 gt_ecc_intr_enb(struct gt_softc *gt)
  615 {
  616         u_int32_t ctl;
  617 
  618         ctl = gt_read(gt, GT_ECC_Ctl);
  619         ctl |= 1 << 16;         /* XXX 1-bit threshold == 1 */
  620         gt_write(gt, GT_ECC_Ctl, ctl);
  621         (void)gt_read(gt, GT_ECC_Data_Lo);
  622         (void)gt_read(gt, GT_ECC_Data_Hi);
  623         (void)gt_read(gt, GT_ECC_Rec);
  624         (void)gt_read(gt, GT_ECC_Calc);
  625         (void)gt_read(gt, GT_ECC_Addr); /* read last! */
  626         gt_write(gt, GT_ECC_Addr, 0);           /* clear irpt */
  627 
  628         intr_establish(IRQ_ECC, IST_LEVEL, IPL_GTERR, gt_ecc_intr, gt);
  629         printf("%s: ECC irpt at %d\n", gt->gt_dev.dv_xname, IRQ_ECC);
  630 }
  631 #endif  /* GT_ECC */
  632 
  633 
  634 #ifndef GT_MPP_WATCHDOG
  635 void
  636 gt_watchdog_init(struct gt_softc *gt)
  637 {
  638         u_int32_t r;
  639         unsigned int omsr;
  640 
  641         omsr = extintr_disable();
  642 
  643         printf("%s: watchdog", gt->gt_dev.dv_xname);
  644 
  645         /*
  646          * handle case where firmware started watchdog
  647          */
  648         r = gt_read(gt, GT_WDOG_Config);
  649         printf(" status %#x,%#x:",
  650                 r, gt_read(gt, GT_WDOG_Value));
  651         if ((r & 0x80000000) != 0) {
  652                 gt_watchdog_sc = gt;            /* enabled */
  653                 gt_watchdog_state = 1;
  654                 printf(" firmware-enabled\n");
  655                 gt_watchdog_service();
  656                 return;
  657         } else {
  658                 printf(" firmware-disabled\n");
  659         }
  660 
  661         extintr_restore(omsr);
  662 }
  663 
  664 #else   /* GT_MPP_WATCHDOG */
  665 
  666 void
  667 gt_watchdog_init(struct gt_softc *gt)
  668 {
  669         u_int32_t mpp_watchdog = GT_MPP_WATCHDOG;       /* from config */
  670         u_int32_t r;
  671         u_int32_t cfgbits;
  672         u_int32_t mppbits;
  673         u_int32_t mppmask=0;
  674         u_int32_t regoff;
  675         unsigned int omsr;
  676 
  677         printf("%s: watchdog", gt->gt_dev.dv_xname);
  678 
  679         if (mpp_watchdog == 0) {
  680                 printf(" not configured\n");
  681                 return;
  682         }
  683 
  684 #if 0
  685         if (afw_wdog_ctl == 1) {
  686                 printf(" admin disabled\n");
  687                 return;
  688         }
  689 #endif
  690 
  691         omsr = extintr_disable();
  692 
  693         /*
  694          * if firmware started watchdog, we disable and start
  695          * from scratch to get it in a known state.
  696          *
  697          * on GT-64260A we always see 0xffffffff
  698          * in both the GT_WDOG_Config_Enb and GT_WDOG_Value regsiters.
  699          * Use AFW-supplied flag to determine run state.
  700          */
  701         r = gt_read(gt, GT_WDOG_Config);
  702         if (r != ~0) {
  703                 if ((r & GT_WDOG_Config_Enb) != 0) {
  704                         gt_write(gt, GT_WDOG_Config,
  705                                 (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
  706                         gt_write(gt, GT_WDOG_Config,
  707                                 (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
  708                 }
  709         } else {
  710 #if 0
  711                 if (afw_wdog_state == 1) {
  712                         gt_write(gt, GT_WDOG_Config,
  713                                 (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
  714                         gt_write(gt, GT_WDOG_Config,
  715                                 (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
  716                 }
  717 #endif
  718         }
  719 
  720         /*
  721          * "the watchdog timer can be activated only after
  722          * configuring two MPP pins to act as WDE and WDNMI"
  723          */
  724         mppbits = 0;
  725         cfgbits = 0x3;
  726         for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4) {
  727                 if ((mpp_watchdog & cfgbits) == cfgbits) {
  728                         mppbits = 0x99;
  729                         mppmask = 0xff;
  730                         break;
  731                 }
  732                 cfgbits <<= 2;
  733                 if ((mpp_watchdog & cfgbits) == cfgbits) {
  734                         mppbits = 0x9900;
  735                         mppmask = 0xff00;
  736                         break;
  737                 }
  738                 cfgbits <<= 6;  /* skip unqualified bits */
  739         }
  740         if (mppbits == 0) {
  741                 printf(" config error\n");
  742                 extintr_restore(omsr);
  743                 return;
  744         }
  745 
  746         r = gt_read(gt, regoff);
  747         r &= ~mppmask;
  748         r |= mppbits;
  749         gt_write(gt, regoff, r);
  750         printf(" mpp %#x %#x", regoff, mppbits);
  751 
  752         gt_write(gt, GT_WDOG_Value, GT_WDOG_NMI_DFLT);
  753 
  754         gt_write(gt, GT_WDOG_Config,
  755                 (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
  756         gt_write(gt, GT_WDOG_Config,
  757                 (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
  758 
  759 
  760         r = gt_read(gt, GT_WDOG_Config),
  761         printf(" status %#x,%#x: %s",
  762                 r, gt_read(gt, GT_WDOG_Value),
  763                 ((r & GT_WDOG_Config_Enb) != 0) ? "enabled" : "botch");
  764 
  765         if ((r & GT_WDOG_Config_Enb) != 0) {
  766                 register_t hid0;
  767 
  768                 gt_watchdog_sc = gt;            /* enabled */
  769                 gt_watchdog_state = 1;
  770 
  771                 /*
  772                  * configure EMCP in HID0 in case it's not already set
  773                  */
  774                 __asm __volatile("sync");
  775                 hid0 = mfspr(SPR_HID0);
  776                 if ((hid0 & HID0_EMCP) == 0) {
  777                         hid0 |= HID0_EMCP;
  778                         __asm __volatile("sync"); mtspr(SPR_HID0, hid0);
  779                         __asm __volatile("sync"); hid0 = mfspr(SPR_HID0);
  780                         printf(", EMCP set");
  781                 }
  782         }
  783         printf("\n");
  784 
  785         extintr_restore(omsr);
  786 }
  787 #endif  /* GT_MPP_WATCHDOG */
  788 
  789 #ifdef DEBUG
  790 u_int32_t hid0_print(void);
  791 u_int32_t
  792 hid0_print()
  793 {
  794         u_int32_t hid0;
  795         __asm __volatile("sync; mfspr %0,1008;" : "=r"(hid0));
  796         printf("hid0: %#x\n", hid0);
  797         return hid0;
  798 }
  799 #endif
  800 
  801 void
  802 gt_watchdog_enable(void)
  803 {
  804         struct gt_softc *gt;
  805         unsigned int omsr;
  806 
  807         omsr = extintr_disable();
  808         gt = gt_watchdog_sc;
  809         if ((gt != NULL) && (gt_watchdog_state == 0)) {
  810                 gt_watchdog_state = 1;
  811 
  812                 gt_write(gt, GT_WDOG_Config,
  813                         (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
  814                 gt_write(gt, GT_WDOG_Config,
  815                         (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
  816         }
  817         extintr_restore(omsr);
  818 }
  819 
  820 void
  821 gt_watchdog_disable(void)
  822 {
  823         struct gt_softc *gt;
  824         unsigned int omsr;
  825 
  826         omsr = extintr_disable();
  827         gt = gt_watchdog_sc;
  828         if ((gt != NULL) && (gt_watchdog_state != 0)) {
  829                 gt_watchdog_state = 0;
  830 
  831                 gt_write(gt, GT_WDOG_Config,
  832                         (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
  833                 gt_write(gt, GT_WDOG_Config,
  834                         (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
  835         }
  836         extintr_restore(omsr);
  837 }
  838 
  839 #ifdef DEBUG
  840 int inhibit_watchdog_service = 0;
  841 #endif
  842 void
  843 gt_watchdog_service(void)
  844 {
  845         struct gt_softc *gt = gt_watchdog_sc;
  846 
  847         if ((gt == NULL) || (gt_watchdog_state == 0))
  848                 return;         /* not enabled */
  849 #ifdef DEBUG
  850         if (inhibit_watchdog_service)
  851                 return;
  852 #endif
  853         
  854         gt_write(gt, GT_WDOG_Config,
  855                 (GT_WDOG_Config_Ctl2a | GT_WDOG_Preset_DFLT));
  856         gt_write(gt, GT_WDOG_Config,
  857                 (GT_WDOG_Config_Ctl2b | GT_WDOG_Preset_DFLT));
  858 }
  859 
  860 /*
  861  * gt_watchdog_reset - force a watchdog reset using Preset_VAL=0
  862  */
  863 void
  864 gt_watchdog_reset()
  865 {
  866         struct gt_softc *gt = gt_watchdog_sc;
  867         u_int32_t r;
  868 
  869         (void)extintr_disable();
  870         r = gt_read(gt, GT_WDOG_Config);
  871         gt_write(gt, GT_WDOG_Config, (GT_WDOG_Config_Ctl1a | 0));
  872         gt_write(gt, GT_WDOG_Config, (GT_WDOG_Config_Ctl1b | 0));
  873         if ((r & GT_WDOG_Config_Enb) != 0) {
  874                 /*
  875                  * was enabled, we just toggled it off, toggle on again
  876                  */
  877                 gt_write(gt, GT_WDOG_Config,
  878                         (GT_WDOG_Config_Ctl1a | 0));
  879                 gt_write(gt, GT_WDOG_Config,
  880                         (GT_WDOG_Config_Ctl1b | 0));
  881         }
  882         for(;;);
  883 }
  884 
  885 static int
  886 gt_devbus_intr(void *arg)
  887 {
  888         struct gt_softc *gt = (struct gt_softc *)arg;
  889         u_int32_t cause;
  890         u_int32_t addr;
  891 
  892         cause = gt_read(gt, GT_DEVBUS_ICAUSE);
  893         addr = gt_read(gt, GT_DEVBUS_ERR_ADDR);
  894         gt_write(gt, GT_DEVBUS_ICAUSE, 0);      /* clear irpt */
  895 
  896         if (cause & GT_DEVBUS_DBurstErr) {
  897                 printf("%s: Device Bus error: burst violation",
  898                         gt->gt_dev.dv_xname);
  899                 if ((cause & GT_DEVBUS_Sel) == 0)
  900                         printf(", addr %#x", addr);
  901                 printf("\n");
  902         }
  903         if (cause & GT_DEVBUS_DRdyErr) {
  904                 printf("%s: Device Bus error: ready timer expired",
  905                         gt->gt_dev.dv_xname);
  906                 if ((cause & GT_DEVBUS_Sel) != 0)
  907                         printf(", addr %#x\n", addr);
  908                 printf("\n");
  909         }
  910 
  911         return (cause != 0);
  912 }
  913 
  914 /*
  915  * gt_ecc_intr_enb - enable GT-64260 ECC interrupts
  916  */
  917 static void
  918 gt_devbus_intr_enb(struct gt_softc *gt)
  919 {
  920         gt_write(gt, GT_DEVBUS_IMASK,
  921                 GT_DEVBUS_DBurstErr|GT_DEVBUS_DRdyErr);
  922         (void)gt_read(gt, GT_DEVBUS_ERR_ADDR);  /* clear addr */
  923         gt_write(gt, GT_ECC_Addr, 0);           /* clear irpt */
  924 
  925         intr_establish(IRQ_DEV, IST_LEVEL, IPL_GTERR, gt_devbus_intr, gt);
  926         printf("%s: Device Bus Error irpt at %d\n",
  927                 gt->gt_dev.dv_xname, IRQ_DEV);
  928 }
  929 
  930 
  931 int
  932 gt_mii_read(
  933         struct device *child,
  934         struct device *parent,
  935         int phy,
  936         int reg)
  937 {
  938         struct gt_softc * const gt = (struct gt_softc *) parent;
  939         uint32_t data;
  940         int count = 10000;
  941 
  942         do {
  943                 DELAY(10);
  944                 data = gt_read(gt, ETH_ESMIR);
  945         } while ((data & ETH_ESMIR_Busy) && count-- > 0);
  946 
  947         if (count == 0) {
  948                 printf("%s: mii read for phy %d reg %d busied out\n",
  949                         child->dv_xname, phy, reg);
  950                 return ETH_ESMIR_Value_GET(data);
  951         }
  952 
  953         gt_write(gt, ETH_ESMIR, ETH_ESMIR_READ(phy, reg));
  954 
  955         count = 10000;
  956         do {
  957                 DELAY(10);
  958                 data = gt_read(gt, ETH_ESMIR);
  959         } while ((data & ETH_ESMIR_ReadValid) == 0 && count-- > 0);
  960 
  961         if (count == 0)
  962                 printf("%s: mii read for phy %d reg %d timed out\n",
  963                         child->dv_xname, phy, reg);
  964 #if defined(GTMIIDEBUG)
  965         printf("%s: mii_read(%d, %d): %#x data %#x\n",
  966                 child->dv_xname, phy, reg, 
  967                 data, ETH_ESMIR_Value_GET(data));
  968 #endif
  969         return ETH_ESMIR_Value_GET(data);
  970 }
  971 
  972 void
  973 gt_mii_write (
  974         struct device *child,
  975         struct device *parent,
  976         int phy, int reg,
  977         int value)
  978 {
  979         struct gt_softc * const gt = (struct gt_softc *) parent;
  980         uint32_t data;
  981         int count = 10000;
  982 
  983         do {
  984                 DELAY(10);
  985                 data = gt_read(gt, ETH_ESMIR);
  986         } while ((data & ETH_ESMIR_Busy) && count-- > 0);
  987 
  988         if (count == 0) {
  989                 printf("%s: mii write for phy %d reg %d busied out (busy)\n",
  990                         child->dv_xname, phy, reg);
  991                 return;
  992         }
  993 
  994         gt_write(gt, ETH_ESMIR,
  995                  ETH_ESMIR_WRITE(phy, reg, value));
  996 
  997         count = 10000;
  998         do {
  999                 DELAY(10);
 1000                 data = gt_read(gt, ETH_ESMIR);
 1001         } while ((data & ETH_ESMIR_Busy) && count-- > 0);
 1002 
 1003         if (count == 0)
 1004                 printf("%s: mii write for phy %d reg %d timed out\n",
 1005                         child->dv_xname, phy, reg);
 1006 #if defined(GTMIIDEBUG)
 1007         printf("%s: mii_write(%d, %d, %#x)\n", 
 1008                 child->dv_xname, phy, reg, value);
 1009 #endif
 1010 }
 1011 
 1012 /*
 1013  * Since the memory and pci spaces are mapped 1:1 we just need
 1014  * to return unity here
 1015  */
 1016 bus_addr_t
 1017 gt_dma_phys_to_bus_mem(bus_dma_tag_t t, bus_addr_t a)
 1018 {
 1019         return a;
 1020 }
 1021 bus_addr_t
 1022 gt_dma_bus_mem_to_phys(bus_dma_tag_t t, bus_addr_t a)
 1023 {
 1024         return a;
 1025 }

Cache object: c3d8c9f840c14302d001a29054f00933


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.