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/arm/mv/common.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
    3  * All rights reserved.
    4  *
    5  * Developed by Semihalf.
    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. Neither the name of MARVELL nor the names of contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __FBSDID("$FreeBSD: releng/8.1/sys/arm/mv/common.c 205192 2010-03-15 19:51:24Z raj $");
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/bus.h>
   38 #include <sys/kernel.h>
   39 
   40 #include <machine/bus.h>
   41 
   42 #include <arm/mv/mvreg.h>
   43 #include <arm/mv/mvvar.h>
   44 #include <arm/mv/mvwin.h>
   45 
   46 static int win_eth_can_remap(int i);
   47 
   48 static int decode_win_cpu_valid(void);
   49 static int decode_win_usb_valid(void);
   50 static int decode_win_eth_valid(void);
   51 static int decode_win_pcie_valid(void);
   52 static int decode_win_sata_valid(void);
   53 static int decode_win_cesa_valid(void);
   54 
   55 static void decode_win_cpu_setup(void);
   56 static void decode_win_usb_setup(void);
   57 static void decode_win_eth_setup(uint32_t base);
   58 static void decode_win_pcie_setup(uint32_t base);
   59 static void decode_win_sata_setup(void);
   60 static void decode_win_cesa_setup(void);
   61 
   62 static void decode_win_cesa_dump(void);
   63 static void decode_win_usb_dump(void);
   64 
   65 static uint32_t used_cpu_wins;
   66 
   67 static __inline int
   68 pm_is_disabled(uint32_t mask)
   69 {
   70 
   71         return (soc_power_ctrl_get(mask) == mask ? 0 : 1);
   72 }
   73 
   74 static __inline uint32_t
   75 obio_get_pm_mask(uint32_t base)
   76 {
   77         struct obio_device *od;
   78 
   79         for (od = obio_devices; od->od_name != NULL; od++)
   80                 if (od->od_base == base)
   81                         return (od->od_pwr_mask);
   82 
   83         return (CPU_PM_CTRL_NONE);
   84 }
   85 
   86 /*
   87  * Disable device using power management register.
   88  * 1 - Device Power On
   89  * 0 - Device Power Off
   90  * Mask can be set in loader.
   91  * EXAMPLE:
   92  * loader> set hw.pm-disable-mask=0x2
   93  *
   94  * Common mask:
   95  * |-------------------------------|
   96  * | Device | Kirkwood | Discovery |
   97  * |-------------------------------|
   98  * | USB0   | 0x00008  | 0x020000  |
   99  * |-------------------------------|
  100  * | USB1   |     -    | 0x040000  |
  101  * |-------------------------------|
  102  * | USB2   |     -    | 0x080000  |
  103  * |-------------------------------|
  104  * | GE0    | 0x00001  | 0x000002  |
  105  * |-------------------------------|
  106  * | GE1    |     -    | 0x000004  |
  107  * |-------------------------------|
  108  * | IDMA   |     -    | 0x100000  |
  109  * |-------------------------------|
  110  * | XOR    | 0x10000  | 0x200000  |
  111  * |-------------------------------|
  112  * | CESA   | 0x20000  | 0x400000  |
  113  * |-------------------------------|
  114  * | SATA   | 0x04000  | 0x004000  |
  115  * --------------------------------|
  116  * This feature can be used only on Kirkwood and Discovery
  117  * machines.
  118  */
  119 static __inline void
  120 pm_disable_device(int mask)
  121 {
  122 #ifdef DIAGNOSTIC
  123         uint32_t reg;
  124 
  125         reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
  126         printf("Power Management Register: 0%x\n", reg);
  127 
  128         reg &= ~mask;
  129         soc_power_ctrl_set(reg);
  130         printf("Device %x is disabled\n", mask);
  131 
  132         reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
  133         printf("Power Management Register: 0%x\n", reg);
  134 #endif
  135 }
  136 
  137 uint32_t
  138 read_cpu_ctrl(uint32_t reg)
  139 {
  140 
  141         return (bus_space_read_4(obio_tag, MV_CPU_CONTROL_BASE, reg));
  142 }
  143 
  144 void
  145 write_cpu_ctrl(uint32_t reg, uint32_t val)
  146 {
  147 
  148         bus_space_write_4(obio_tag, MV_CPU_CONTROL_BASE, reg, val);
  149 }
  150 
  151 void
  152 cpu_reset(void)
  153 {
  154 
  155         write_cpu_ctrl(RSTOUTn_MASK, SOFT_RST_OUT_EN);
  156         write_cpu_ctrl(SYSTEM_SOFT_RESET, SYS_SOFT_RST);
  157         while (1);
  158 }
  159 
  160 uint32_t
  161 cpu_extra_feat(void)
  162 {
  163         uint32_t dev, rev;
  164         uint32_t ef = 0;
  165 
  166         soc_id(&dev, &rev);
  167         if (dev == MV_DEV_88F6281 || dev == MV_DEV_MV78100_Z0 ||
  168             dev == MV_DEV_MV78100)
  169                 __asm __volatile("mrc p15, 1, %0, c15, c1, 0" : "=r" (ef));
  170         else if (dev == MV_DEV_88F5182 || dev == MV_DEV_88F5281)
  171                 __asm __volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (ef));
  172         else if (bootverbose)
  173                 printf("This ARM Core does not support any extra features\n");
  174 
  175         return (ef);
  176 }
  177 
  178 /*
  179  * Get the power status of device. This feature is only supported on
  180  * Kirkwood and Discovery SoCs.
  181  */
  182 uint32_t
  183 soc_power_ctrl_get(uint32_t mask)
  184 {
  185 
  186 #ifndef SOC_MV_ORION
  187         if (mask != CPU_PM_CTRL_NONE)
  188                 mask &= read_cpu_ctrl(CPU_PM_CTRL);
  189 
  190         return (mask);
  191 #else
  192         return (mask);
  193 #endif
  194 }
  195 
  196 /*
  197  * Set the power status of device. This feature is only supported on
  198  * Kirkwood and Discovery SoCs.
  199  */
  200 void
  201 soc_power_ctrl_set(uint32_t mask)
  202 {
  203 
  204 #ifndef SOC_MV_ORION
  205         if (mask != CPU_PM_CTRL_NONE)
  206                 write_cpu_ctrl(CPU_PM_CTRL, mask);
  207 #endif
  208 }
  209 
  210 void
  211 soc_id(uint32_t *dev, uint32_t *rev)
  212 {
  213 
  214         /*
  215          * Notice: system identifiers are available in the registers range of
  216          * PCIE controller, so using this function is only allowed (and
  217          * possible) after the internal registers range has been mapped in via
  218          * pmap_devmap_bootstrap().
  219          */
  220         *dev = bus_space_read_4(obio_tag, MV_PCIE_BASE, 0) >> 16;
  221         *rev = bus_space_read_4(obio_tag, MV_PCIE_BASE, 8) & 0xff;
  222 }
  223 
  224 void
  225 soc_identify(void)
  226 {
  227         uint32_t d, r;
  228         const char *dev;
  229         const char *rev;
  230 
  231         soc_id(&d, &r);
  232 
  233         printf("SOC: ");
  234         if (bootverbose)
  235                 printf("(0x%4x:0x%02x) ", d, r);
  236 
  237         rev = "";
  238         switch (d) {
  239         case MV_DEV_88F5181:
  240                 dev = "Marvell 88F5181";
  241                 if (r == 3)
  242                         rev = "B1";
  243                 break;
  244         case MV_DEV_88F5182:
  245                 dev = "Marvell 88F5182";
  246                 if (r == 2)
  247                         rev = "A2";
  248                 break;
  249         case MV_DEV_88F5281:
  250                 dev = "Marvell 88F5281";
  251                 if (r == 4)
  252                         rev = "D0";
  253                 else if (r == 5)
  254                         rev = "D1";
  255                 else if (r == 6)
  256                         rev = "D2";
  257                 break;
  258         case MV_DEV_88F6281:
  259                 dev = "Marvell 88F6281";
  260                 if (r == 0)
  261                         rev = "Z0";
  262                 else if (r == 2)
  263                         rev = "A0";
  264                 else if (r == 3)
  265                         rev = "A1";
  266                 break;
  267         case MV_DEV_MV78100_Z0:
  268                 dev = "Marvell MV78100 Z0";
  269                 break;
  270         case MV_DEV_MV78100:
  271                 dev = "Marvell MV78100";
  272                 break;
  273         default:
  274                 dev = "UNKNOWN";
  275                 break;
  276         }
  277 
  278         printf("%s", dev);
  279         if (*rev != '\0')
  280                 printf(" rev %s", rev);
  281         printf(", TClock %dMHz\n", get_tclk() / 1000 / 1000);
  282 
  283         /* TODO add info on currently set endianess */
  284 }
  285 
  286 int
  287 soc_decode_win(void)
  288 {
  289         uint32_t dev, rev;
  290         int mask;
  291 
  292         mask = 0;
  293         TUNABLE_INT_FETCH("hw.pm-disable-mask", &mask);
  294 
  295         if (mask != 0)
  296                 pm_disable_device(mask);
  297 
  298         /* Retrieve our ID: some windows facilities vary between SoC models */
  299         soc_id(&dev, &rev);
  300 
  301         if (decode_win_cpu_valid() != 1 || decode_win_usb_valid() != 1 ||
  302             decode_win_eth_valid() != 1 || decode_win_idma_valid() != 1 ||
  303             decode_win_pcie_valid() != 1 || decode_win_sata_valid() != 1 ||
  304             decode_win_cesa_valid() != 1)
  305                 return(-1);
  306 
  307         decode_win_cpu_setup();
  308         decode_win_usb_setup();
  309         decode_win_eth_setup(MV_ETH0_BASE);
  310         if (dev == MV_DEV_MV78100 || dev == MV_DEV_MV78100_Z0)
  311                 decode_win_eth_setup(MV_ETH1_BASE);
  312         if (dev == MV_DEV_88F6281 || dev == MV_DEV_MV78100 ||
  313             dev == MV_DEV_MV78100_Z0)
  314                 decode_win_cesa_setup();
  315 
  316         decode_win_idma_setup();
  317         decode_win_xor_setup();
  318 
  319         if (dev == MV_DEV_MV78100 || dev == MV_DEV_MV78100_Z0) {
  320                 decode_win_pcie_setup(MV_PCIE00_BASE);
  321                 decode_win_pcie_setup(MV_PCIE01_BASE);
  322                 decode_win_pcie_setup(MV_PCIE02_BASE);
  323                 decode_win_pcie_setup(MV_PCIE03_BASE);
  324                 decode_win_pcie_setup(MV_PCIE10_BASE);
  325                 decode_win_pcie_setup(MV_PCIE11_BASE);
  326                 decode_win_pcie_setup(MV_PCIE12_BASE);
  327                 decode_win_pcie_setup(MV_PCIE13_BASE);
  328         } else
  329                 decode_win_pcie_setup(MV_PCIE_BASE);
  330 
  331         if (dev != MV_DEV_88F5281)
  332                 decode_win_sata_setup();
  333 
  334         return (0);
  335 }
  336 
  337 /**************************************************************************
  338  * Decode windows registers accessors
  339  **************************************************************************/
  340 WIN_REG_IDX_RD(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
  341 WIN_REG_IDX_RD(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
  342 WIN_REG_IDX_RD(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
  343 WIN_REG_IDX_RD(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
  344 WIN_REG_IDX_WR(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
  345 WIN_REG_IDX_WR(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
  346 WIN_REG_IDX_WR(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
  347 WIN_REG_IDX_WR(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
  348 
  349 WIN_REG_IDX_RD(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
  350 WIN_REG_IDX_RD(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
  351 
  352 WIN_REG_IDX_RD2(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
  353 WIN_REG_IDX_RD2(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
  354 WIN_REG_IDX_WR2(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
  355 WIN_REG_IDX_WR2(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
  356 
  357 WIN_REG_IDX_RD(win_cesa, cr, MV_WIN_CESA_CTRL, MV_CESA_BASE)
  358 WIN_REG_IDX_RD(win_cesa, br, MV_WIN_CESA_BASE, MV_CESA_BASE)
  359 WIN_REG_IDX_WR(win_cesa, cr, MV_WIN_CESA_CTRL, MV_CESA_BASE)
  360 WIN_REG_IDX_WR(win_cesa, br, MV_WIN_CESA_BASE, MV_CESA_BASE)
  361 
  362 WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE)
  363 WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE)
  364 WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP)
  365 WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE)
  366 WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE)
  367 WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP)
  368 
  369 WIN_REG_IDX_RD2(win_xor, br, MV_WIN_XOR_BASE, MV_XOR_BASE)
  370 WIN_REG_IDX_RD2(win_xor, sz, MV_WIN_XOR_SIZE, MV_XOR_BASE)
  371 WIN_REG_IDX_RD2(win_xor, har, MV_WIN_XOR_REMAP, MV_XOR_BASE)
  372 WIN_REG_IDX_RD2(win_xor, ctrl, MV_WIN_XOR_CTRL, MV_XOR_BASE)
  373 WIN_REG_IDX_WR2(win_xor, br, MV_WIN_XOR_BASE, MV_XOR_BASE)
  374 WIN_REG_IDX_WR2(win_xor, sz, MV_WIN_XOR_SIZE, MV_XOR_BASE)
  375 WIN_REG_IDX_WR2(win_xor, har, MV_WIN_XOR_REMAP, MV_XOR_BASE)
  376 WIN_REG_IDX_WR2(win_xor, ctrl, MV_WIN_XOR_CTRL, MV_XOR_BASE)
  377 
  378 WIN_REG_BASE_RD(win_eth, bare, 0x290)
  379 WIN_REG_BASE_RD(win_eth, epap, 0x294)
  380 WIN_REG_BASE_WR(win_eth, bare, 0x290)
  381 WIN_REG_BASE_WR(win_eth, epap, 0x294)
  382 
  383 WIN_REG_BASE_IDX_RD(win_pcie, cr, MV_WIN_PCIE_CTRL);
  384 WIN_REG_BASE_IDX_RD(win_pcie, br, MV_WIN_PCIE_BASE);
  385 WIN_REG_BASE_IDX_RD(win_pcie, remap, MV_WIN_PCIE_REMAP);
  386 WIN_REG_BASE_IDX_WR(win_pcie, cr, MV_WIN_PCIE_CTRL);
  387 WIN_REG_BASE_IDX_WR(win_pcie, br, MV_WIN_PCIE_BASE);
  388 WIN_REG_BASE_IDX_WR(win_pcie, remap, MV_WIN_PCIE_REMAP);
  389 WIN_REG_BASE_IDX_WR(pcie, bar, MV_PCIE_BAR);
  390 
  391 WIN_REG_IDX_RD(win_idma, br, MV_WIN_IDMA_BASE, MV_IDMA_BASE)
  392 WIN_REG_IDX_RD(win_idma, sz, MV_WIN_IDMA_SIZE, MV_IDMA_BASE)
  393 WIN_REG_IDX_RD(win_idma, har, MV_WIN_IDMA_REMAP, MV_IDMA_BASE)
  394 WIN_REG_IDX_RD(win_idma, cap, MV_WIN_IDMA_CAP, MV_IDMA_BASE)
  395 WIN_REG_IDX_WR(win_idma, br, MV_WIN_IDMA_BASE, MV_IDMA_BASE)
  396 WIN_REG_IDX_WR(win_idma, sz, MV_WIN_IDMA_SIZE, MV_IDMA_BASE)
  397 WIN_REG_IDX_WR(win_idma, har, MV_WIN_IDMA_REMAP, MV_IDMA_BASE)
  398 WIN_REG_IDX_WR(win_idma, cap, MV_WIN_IDMA_CAP, MV_IDMA_BASE)
  399 WIN_REG_RD(win_idma, bare, 0xa80, MV_IDMA_BASE)
  400 WIN_REG_WR(win_idma, bare, 0xa80, MV_IDMA_BASE)
  401 
  402 WIN_REG_IDX_RD(win_sata, cr, MV_WIN_SATA_CTRL, MV_SATAHC_BASE);
  403 WIN_REG_IDX_RD(win_sata, br, MV_WIN_SATA_BASE, MV_SATAHC_BASE);
  404 WIN_REG_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL, MV_SATAHC_BASE);
  405 WIN_REG_IDX_WR(win_sata, br, MV_WIN_SATA_BASE, MV_SATAHC_BASE);
  406 
  407 /**************************************************************************
  408  * Decode windows helper routines
  409  **************************************************************************/
  410 void
  411 soc_dump_decode_win(void)
  412 {
  413         uint32_t dev, rev;
  414         int i;
  415 
  416         soc_id(&dev, &rev);
  417 
  418         for (i = 0; i < MV_WIN_CPU_MAX; i++) {
  419                 printf("CPU window#%d: c 0x%08x, b 0x%08x", i,
  420                     win_cpu_cr_read(i),
  421                     win_cpu_br_read(i));
  422 
  423                 if (win_cpu_can_remap(i))
  424                         printf(", rl 0x%08x, rh 0x%08x",
  425                             win_cpu_remap_l_read(i),
  426                             win_cpu_remap_h_read(i));
  427 
  428                 printf("\n");
  429         }
  430         printf("Internal regs base: 0x%08x\n",
  431             bus_space_read_4(obio_tag, MV_INTREGS_BASE, 0));
  432 
  433         for (i = 0; i < MV_WIN_DDR_MAX; i++)
  434                 printf("DDR CS#%d: b 0x%08x, s 0x%08x\n", i,
  435                     ddr_br_read(i), ddr_sz_read(i));
  436 
  437         for (i = 0; i < MV_WIN_ETH_MAX; i++) {
  438                 printf("ETH window#%d: b 0x%08x, s 0x%08x", i,
  439                     win_eth_br_read(MV_ETH0_BASE, i),
  440                     win_eth_sz_read(MV_ETH0_BASE, i));
  441 
  442                 if (win_eth_can_remap(i))
  443                         printf(", ha 0x%08x",
  444                             win_eth_har_read(MV_ETH0_BASE, i));
  445 
  446                 printf("\n");
  447         }
  448         printf("ETH windows: bare 0x%08x, epap 0x%08x\n",
  449             win_eth_bare_read(MV_ETH0_BASE),
  450             win_eth_epap_read(MV_ETH0_BASE));
  451 
  452         decode_win_idma_dump();
  453         decode_win_cesa_dump();
  454         decode_win_usb_dump();
  455         printf("\n");
  456 }
  457 
  458 /**************************************************************************
  459  * CPU windows routines
  460  **************************************************************************/
  461 int
  462 win_cpu_can_remap(int i)
  463 {
  464         uint32_t dev, rev;
  465 
  466         soc_id(&dev, &rev);
  467 
  468         /* Depending on the SoC certain windows have remap capability */
  469         if ((dev == MV_DEV_88F5182 && i < 2) ||
  470             (dev == MV_DEV_88F5281 && i < 4) ||
  471             (dev == MV_DEV_88F6281 && i < 4) ||
  472             (dev == MV_DEV_MV78100 && i < 8) ||
  473             (dev == MV_DEV_MV78100_Z0 && i < 8))
  474                 return (1);
  475 
  476         return (0);
  477 }
  478 
  479 /* XXX This should check for overlapping remap fields too.. */
  480 int
  481 decode_win_overlap(int win, int win_no, const struct decode_win *wintab)
  482 {
  483         const struct decode_win *tab;
  484         int i;
  485 
  486         tab = wintab;
  487 
  488         for (i = 0; i < win_no; i++, tab++) {
  489                 if (i == win)
  490                         /* Skip self */
  491                         continue;
  492 
  493                 if ((tab->base + tab->size - 1) < (wintab + win)->base)
  494                         continue;
  495 
  496                 else if (((wintab + win)->base + (wintab + win)->size - 1) <
  497                     tab->base)
  498                         continue;
  499                 else
  500                         return (i);
  501         }
  502 
  503         return (-1);
  504 }
  505 
  506 static int
  507 decode_win_cpu_valid(void)
  508 {
  509         int i, j, rv;
  510         uint32_t b, e, s;
  511 
  512         if (cpu_wins_no > MV_WIN_CPU_MAX) {
  513                 printf("CPU windows: too many entries: %d\n", cpu_wins_no);
  514                 return (-1);
  515         }
  516 
  517         rv = 1;
  518         for (i = 0; i < cpu_wins_no; i++) {
  519 
  520                 if (cpu_wins[i].target == 0) {
  521                         printf("CPU window#%d: DDR target window is not "
  522                             "supposed to be reprogrammed!\n", i);
  523                         rv = 0;
  524                 }
  525 
  526                 if (cpu_wins[i].remap >= 0 && win_cpu_can_remap(i) != 1) {
  527                         printf("CPU window#%d: not capable of remapping, but "
  528                             "val 0x%08x defined\n", i, cpu_wins[i].remap);
  529                         rv = 0;
  530                 }
  531 
  532                 s = cpu_wins[i].size;
  533                 b = cpu_wins[i].base;
  534                 e = b + s - 1;
  535                 if (s > (0xFFFFFFFF - b + 1)) {
  536                         /*
  537                          * XXX this boundary check should account for 64bit
  538                          * and remapping..
  539                          */
  540                         printf("CPU window#%d: no space for size 0x%08x at "
  541                             "0x%08x\n", i, s, b);
  542                         rv = 0;
  543                         continue;
  544                 }
  545 
  546                 j = decode_win_overlap(i, cpu_wins_no, &cpu_wins[0]);
  547                 if (j >= 0) {
  548                         printf("CPU window#%d: (0x%08x - 0x%08x) overlaps "
  549                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
  550                             cpu_wins[j].base,
  551                             cpu_wins[j].base + cpu_wins[j].size - 1);
  552                         rv = 0;
  553                 }
  554         }
  555 
  556         return (rv);
  557 }
  558 
  559 int
  560 decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size,
  561     int remap)
  562 {
  563         uint32_t br, cr;
  564         int win;
  565 
  566         if (used_cpu_wins >= MV_WIN_CPU_MAX)
  567                 return (-1);
  568 
  569         win = used_cpu_wins++;
  570 
  571         br = base & 0xffff0000;
  572         win_cpu_br_write(win, br);
  573 
  574         if (win_cpu_can_remap(win)) {
  575                 if (remap >= 0) {
  576                         win_cpu_remap_l_write(win, remap & 0xffff0000);
  577                         win_cpu_remap_h_write(win, 0);
  578                 } else {
  579                         /*
  580                          * Remap function is not used for a given window
  581                          * (capable of remapping) - set remap field with the
  582                          * same value as base.
  583                          */
  584                         win_cpu_remap_l_write(win, base & 0xffff0000);
  585                         win_cpu_remap_h_write(win, 0);
  586                 }
  587         }
  588 
  589         cr = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
  590         win_cpu_cr_write(win, cr);
  591 
  592         return (0);
  593 }
  594 
  595 static void
  596 decode_win_cpu_setup(void)
  597 {
  598         int i;
  599 
  600         used_cpu_wins = 0;
  601 
  602         /* Disable all CPU windows */
  603         for (i = 0; i < MV_WIN_CPU_MAX; i++) {
  604                 win_cpu_cr_write(i, 0);
  605                 win_cpu_br_write(i, 0);
  606                 if (win_cpu_can_remap(i)) {
  607                         win_cpu_remap_l_write(i, 0);
  608                         win_cpu_remap_h_write(i, 0);
  609                 }
  610         }
  611 
  612         for (i = 0; i < cpu_wins_no; i++)
  613                 if (cpu_wins[i].target > 0)
  614                         decode_win_cpu_set(cpu_wins[i].target,
  615                             cpu_wins[i].attr, cpu_wins[i].base,
  616                             cpu_wins[i].size, cpu_wins[i].remap);
  617 
  618 }
  619 
  620 /*
  621  * Check if we're able to cover all active DDR banks.
  622  */
  623 static int
  624 decode_win_can_cover_ddr(int max)
  625 {
  626         int i, c;
  627 
  628         c = 0;
  629         for (i = 0; i < MV_WIN_DDR_MAX; i++)
  630                 if (ddr_is_active(i))
  631                         c++;
  632 
  633         if (c > max) {
  634                 printf("Unable to cover all active DDR banks: "
  635                     "%d, available windows: %d\n", c, max);
  636                 return (0);
  637         }
  638 
  639         return (1);
  640 }
  641 
  642 /**************************************************************************
  643  * DDR windows routines
  644  **************************************************************************/
  645 int
  646 ddr_is_active(int i)
  647 {
  648 
  649         if (ddr_sz_read(i) & 0x1)
  650                 return (1);
  651 
  652         return (0);
  653 }
  654 
  655 uint32_t
  656 ddr_base(int i)
  657 {
  658 
  659         return (ddr_br_read(i) & 0xff000000);
  660 }
  661 
  662 uint32_t
  663 ddr_size(int i)
  664 {
  665 
  666         return ((ddr_sz_read(i) | 0x00ffffff) + 1);
  667 }
  668 
  669 uint32_t
  670 ddr_attr(int i)
  671 {
  672 
  673         return (i == 0 ? 0xe :
  674             (i == 1 ? 0xd :
  675             (i == 2 ? 0xb :
  676             (i == 3 ? 0x7 : 0xff))));
  677 }
  678 
  679 uint32_t
  680 ddr_target(int i)
  681 {
  682 
  683         /* Mbus unit ID is 0x0 for DDR SDRAM controller */
  684         return (0);
  685 }
  686 
  687 /**************************************************************************
  688  * USB windows routines
  689  **************************************************************************/
  690 static int
  691 decode_win_usb_valid(void)
  692 {
  693 
  694         return (decode_win_can_cover_ddr(MV_WIN_USB_MAX));
  695 }
  696 
  697 static __inline int
  698 usb_max_ports(void)
  699 {
  700         uint32_t dev, rev;
  701 
  702         soc_id(&dev, &rev);
  703         return ((dev == MV_DEV_MV78100 || dev == MV_DEV_MV78100_Z0) ? 3 : 1);
  704 }
  705 
  706 static void
  707 decode_win_usb_dump(void)
  708 {
  709         int i, p, m;
  710 
  711         m = usb_max_ports();
  712         for (p = 0; p < m; p++)
  713                 for (i = 0; i < MV_WIN_USB_MAX; i++)
  714                         printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
  715                             win_usb_cr_read(i, p), win_usb_br_read(i, p));
  716 }
  717 
  718 /*
  719  * Set USB decode windows.
  720  */
  721 static void
  722 decode_win_usb_setup(void)
  723 {
  724         uint32_t br, cr;
  725         int i, j, p, m;
  726 
  727         /* Disable and clear all USB windows for all ports */
  728         m = usb_max_ports();
  729 
  730         for (p = 0; p < m; p++) {
  731 
  732                 if (pm_is_disabled(CPU_PM_CTRL_USB(p)))
  733                         continue;
  734 
  735                 for (i = 0; i < MV_WIN_USB_MAX; i++) {
  736                         win_usb_cr_write(i, p, 0);
  737                         win_usb_br_write(i, p, 0);
  738                 }
  739 
  740                 /* Only access to active DRAM banks is required */
  741                 for (i = 0; i < MV_WIN_DDR_MAX; i++) {
  742                         if (ddr_is_active(i)) {
  743                                 br = ddr_base(i);
  744                                 /*
  745                                  * XXX for 6281 we should handle Mbus write
  746                                  * burst limit field in the ctrl reg
  747                                  */
  748                                 cr = (((ddr_size(i) - 1) & 0xffff0000) |
  749                                     (ddr_attr(i) << 8) |
  750                                     (ddr_target(i) << 4) | 1);
  751 
  752                                 /* Set the first free USB window */
  753                                 for (j = 0; j < MV_WIN_USB_MAX; j++) {
  754                                         if (win_usb_cr_read(j, p) & 0x1)
  755                                                 continue;
  756 
  757                                         win_usb_br_write(j, p, br);
  758                                         win_usb_cr_write(j, p, cr);
  759                                         break;
  760                                 }
  761                         }
  762                 }
  763         }
  764 }
  765 
  766 /**************************************************************************
  767  * ETH windows routines
  768  **************************************************************************/
  769 
  770 static int
  771 win_eth_can_remap(int i)
  772 {
  773 
  774         /* ETH encode windows 0-3 have remap capability */
  775         if (i < 4)
  776                 return (1);
  777         
  778         return (0);
  779 }
  780 
  781 static int
  782 eth_bare_read(uint32_t base, int i)
  783 {
  784         uint32_t v;
  785 
  786         v = win_eth_bare_read(base);
  787         v &= (1 << i);
  788 
  789         return (v >> i);
  790 }
  791 
  792 static void
  793 eth_bare_write(uint32_t base, int i, int val)
  794 {
  795         uint32_t v;
  796 
  797         v = win_eth_bare_read(base);
  798         v &= ~(1 << i);
  799         v |= (val << i);
  800         win_eth_bare_write(base, v);
  801 }
  802 
  803 static void
  804 eth_epap_write(uint32_t base, int i, int val)
  805 {
  806         uint32_t v;
  807 
  808         v = win_eth_epap_read(base);
  809         v &= ~(0x3 << (i * 2));
  810         v |= (val << (i * 2));
  811         win_eth_epap_write(base, v);
  812 }
  813 
  814 static void
  815 decode_win_eth_setup(uint32_t base)
  816 {
  817         uint32_t br, sz;
  818         int i, j;
  819 
  820         if (pm_is_disabled(obio_get_pm_mask(base)))
  821                 return;
  822 
  823         /* Disable, clear and revoke protection for all ETH windows */
  824         for (i = 0; i < MV_WIN_ETH_MAX; i++) {
  825 
  826                 eth_bare_write(base, i, 1);
  827                 eth_epap_write(base, i, 0);
  828                 win_eth_br_write(base, i, 0);
  829                 win_eth_sz_write(base, i, 0);
  830                 if (win_eth_can_remap(i))
  831                         win_eth_har_write(base, i, 0);
  832         }
  833 
  834         /* Only access to active DRAM banks is required */
  835         for (i = 0; i < MV_WIN_DDR_MAX; i++)
  836                 if (ddr_is_active(i)) {
  837 
  838                         br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
  839                         sz = ((ddr_size(i) - 1) & 0xffff0000);
  840 
  841                         /* Set the first free ETH window */
  842                         for (j = 0; j < MV_WIN_ETH_MAX; j++) {
  843                                 if (eth_bare_read(base, j) == 0)
  844                                         continue;
  845 
  846                                 win_eth_br_write(base, j, br);
  847                                 win_eth_sz_write(base, j, sz);
  848 
  849                                 /* XXX remapping ETH windows not supported */
  850 
  851                                 /* Set protection RW */
  852                                 eth_epap_write(base, j, 0x3);
  853 
  854                                 /* Enable window */
  855                                 eth_bare_write(base, j, 0);
  856                                 break;
  857                         }
  858                 }
  859 }
  860 
  861 static int
  862 decode_win_eth_valid(void)
  863 {
  864 
  865         return (decode_win_can_cover_ddr(MV_WIN_ETH_MAX));
  866 }
  867 
  868 /**************************************************************************
  869  * PCIE windows routines
  870  **************************************************************************/
  871 
  872 static void
  873 decode_win_pcie_setup(uint32_t base)
  874 {
  875         uint32_t size = 0;
  876         uint32_t cr, br;
  877         int i, j;
  878 
  879         for (i = 0; i < MV_PCIE_BAR_MAX; i++)
  880                 pcie_bar_write(base, i, 0);
  881 
  882         for (i = 0; i < MV_WIN_PCIE_MAX; i++) {
  883                 win_pcie_cr_write(base, i, 0);
  884                 win_pcie_br_write(base, i, 0);
  885                 win_pcie_remap_write(base, i, 0);
  886         }
  887 
  888         for (i = 0; i < MV_WIN_DDR_MAX; i++) {
  889                 if (ddr_is_active(i)) {
  890                         /* Map DDR to BAR 1 */
  891                         cr = (ddr_size(i) - 1) & 0xffff0000;
  892                         size += ddr_size(i) & 0xffff0000;
  893                         cr |= (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
  894                         br = ddr_base(i);
  895 
  896                         /* Use the first available PCIE window */
  897                         for (j = 0; j < MV_WIN_PCIE_MAX; j++) {
  898                                 if (win_pcie_cr_read(base, j) != 0)
  899                                         continue;
  900 
  901                                 win_pcie_br_write(base, j, br);
  902                                 win_pcie_cr_write(base, j, cr);
  903                                 break;
  904                         }
  905                 }
  906         }
  907 
  908         /*
  909          * Upper 16 bits in BAR register is interpreted as BAR size
  910          * (in 64 kB units) plus 64kB, so substract 0x10000
  911          * form value passed to register to get correct value.
  912          */
  913         size -= 0x10000;
  914         pcie_bar_write(base, 0, size | 1);
  915 }
  916 
  917 static int
  918 decode_win_pcie_valid(void)
  919 {
  920 
  921         return (decode_win_can_cover_ddr(MV_WIN_PCIE_MAX));
  922 }
  923 
  924 /**************************************************************************
  925  * IDMA windows routines
  926  **************************************************************************/
  927 #if defined(SOC_MV_ORION) || defined(SOC_MV_DISCOVERY)
  928 static int
  929 idma_bare_read(int i)
  930 {
  931         uint32_t v;
  932 
  933         v = win_idma_bare_read();
  934         v &= (1 << i);
  935 
  936         return (v >> i);
  937 }
  938 
  939 static void
  940 idma_bare_write(int i, int val)
  941 {
  942         uint32_t v;
  943 
  944         v = win_idma_bare_read();
  945         v &= ~(1 << i);
  946         v |= (val << i);
  947         win_idma_bare_write(v);
  948 }
  949 
  950 /*
  951  * Sets channel protection 'val' for window 'w' on channel 'c'
  952  */
  953 static void
  954 idma_cap_write(int c, int w, int val)
  955 {
  956         uint32_t v;
  957 
  958         v = win_idma_cap_read(c);
  959         v &= ~(0x3 << (w * 2));
  960         v |= (val << (w * 2));
  961         win_idma_cap_write(c, v);
  962 }
  963 
  964 /*
  965  * Set protection 'val' on all channels for window 'w'
  966  */
  967 static void
  968 idma_set_prot(int w, int val)
  969 {
  970         int c;
  971 
  972         for (c = 0; c < MV_IDMA_CHAN_MAX; c++)
  973                 idma_cap_write(c, w, val);
  974 }
  975 
  976 static int
  977 win_idma_can_remap(int i)
  978 {
  979 
  980         /* IDMA decode windows 0-3 have remap capability */
  981         if (i < 4)
  982                 return (1);
  983 
  984         return (0);
  985 }
  986 
  987 void
  988 decode_win_idma_setup(void)
  989 {
  990         uint32_t br, sz;
  991         int i, j;
  992 
  993         if (pm_is_disabled(CPU_PM_CTRL_IDMA))
  994                 return;
  995         /*
  996          * Disable and clear all IDMA windows, revoke protection for all channels
  997          */
  998         for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
  999 
 1000                 idma_bare_write(i, 1);
 1001                 win_idma_br_write(i, 0);
 1002                 win_idma_sz_write(i, 0);
 1003                 if (win_idma_can_remap(i) == 1)
 1004                         win_idma_har_write(i, 0);
 1005         }
 1006         for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
 1007                 win_idma_cap_write(i, 0);
 1008 
 1009         /*
 1010          * Set up access to all active DRAM banks
 1011          */
 1012         for (i = 0; i < MV_WIN_DDR_MAX; i++)
 1013                 if (ddr_is_active(i)) {
 1014                         br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
 1015                         sz = ((ddr_size(i) - 1) & 0xffff0000);
 1016 
 1017                         /* Place DDR entries in non-remapped windows */
 1018                         for (j = 0; j < MV_WIN_IDMA_MAX; j++)
 1019                                 if (win_idma_can_remap(j) != 1 &&
 1020                                     idma_bare_read(j) == 1) {
 1021 
 1022                                         /* Configure window */
 1023                                         win_idma_br_write(j, br);
 1024                                         win_idma_sz_write(j, sz);
 1025 
 1026                                         /* Set protection RW on all channels */
 1027                                         idma_set_prot(j, 0x3);
 1028 
 1029                                         /* Enable window */
 1030                                         idma_bare_write(j, 0);
 1031                                         break;
 1032                                 }
 1033                 }
 1034 
 1035         /*
 1036          * Remaining targets -- from statically defined table
 1037          */
 1038         for (i = 0; i < idma_wins_no; i++)
 1039                 if (idma_wins[i].target > 0) {
 1040                         br = (idma_wins[i].base & 0xffff0000) |
 1041                             (idma_wins[i].attr << 8) | idma_wins[i].target;
 1042                         sz = ((idma_wins[i].size - 1) & 0xffff0000);
 1043 
 1044                         /* Set the first free IDMA window */
 1045                         for (j = 0; j < MV_WIN_IDMA_MAX; j++) {
 1046                                 if (idma_bare_read(j) == 0)
 1047                                         continue;
 1048 
 1049                                 /* Configure window */
 1050                                 win_idma_br_write(j, br);
 1051                                 win_idma_sz_write(j, sz);
 1052                                 if (win_idma_can_remap(j) &&
 1053                                     idma_wins[j].remap >= 0)
 1054                                         win_idma_har_write(j, idma_wins[j].remap);
 1055 
 1056                                 /* Set protection RW on all channels */
 1057                                 idma_set_prot(j, 0x3);
 1058 
 1059                                 /* Enable window */
 1060                                 idma_bare_write(j, 0);
 1061                                 break;
 1062                         }
 1063                 }
 1064 }
 1065 
 1066 int
 1067 decode_win_idma_valid(void)
 1068 {
 1069         const struct decode_win *wintab;
 1070         int c, i, j, rv;
 1071         uint32_t b, e, s;
 1072 
 1073         if (idma_wins_no > MV_WIN_IDMA_MAX) {
 1074                 printf("IDMA windows: too many entries: %d\n", idma_wins_no);
 1075                 return (-1);
 1076         }
 1077         for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
 1078                 if (ddr_is_active(i))
 1079                         c++;
 1080 
 1081         if (idma_wins_no > (MV_WIN_IDMA_MAX - c)) {
 1082                 printf("IDMA windows: too many entries: %d, available: %d\n",
 1083                     idma_wins_no, MV_WIN_IDMA_MAX - c);
 1084                 return (-1);
 1085         }
 1086 
 1087         wintab = idma_wins;
 1088         rv = 1;
 1089         for (i = 0; i < idma_wins_no; i++, wintab++) {
 1090 
 1091                 if (wintab->target == 0) {
 1092                         printf("IDMA window#%d: DDR target window is not "
 1093                             "supposed to be reprogrammed!\n", i);
 1094                         rv = 0;
 1095                 }
 1096 
 1097                 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
 1098                         printf("IDMA window#%d: not capable of remapping, but "
 1099                             "val 0x%08x defined\n", i, wintab->remap);
 1100                         rv = 0;
 1101                 }
 1102 
 1103                 s = wintab->size;
 1104                 b = wintab->base;
 1105                 e = b + s - 1;
 1106                 if (s > (0xFFFFFFFF - b + 1)) {
 1107                         /* XXX this boundary check should account for 64bit and
 1108                          * remapping.. */
 1109                         printf("IDMA window#%d: no space for size 0x%08x at "
 1110                             "0x%08x\n", i, s, b);
 1111                         rv = 0;
 1112                         continue;
 1113                 }
 1114 
 1115                 j = decode_win_overlap(i, idma_wins_no, &idma_wins[0]);
 1116                 if (j >= 0) {
 1117                         printf("IDMA window#%d: (0x%08x - 0x%08x) overlaps "
 1118                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
 1119                             idma_wins[j].base,
 1120                             idma_wins[j].base + idma_wins[j].size - 1);
 1121                         rv = 0;
 1122                 }
 1123         }
 1124 
 1125         return (rv);
 1126 }
 1127 
 1128 void
 1129 decode_win_idma_dump(void)
 1130 {
 1131         int i;
 1132 
 1133         for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
 1134                 printf("IDMA window#%d: b 0x%08x, s 0x%08x", i,
 1135                     win_idma_br_read(i), win_idma_sz_read(i));
 1136                 
 1137                 if (win_idma_can_remap(i))
 1138                         printf(", ha 0x%08x", win_idma_har_read(i));
 1139 
 1140                 printf("\n");
 1141         }
 1142         for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
 1143                 printf("IDMA channel#%d: ap 0x%08x\n", i,
 1144                     win_idma_cap_read(i));
 1145         printf("IDMA windows: bare 0x%08x\n", win_idma_bare_read());
 1146 }
 1147 #else
 1148 
 1149 /* Provide dummy functions to satisfy the build for SoCs not equipped with IDMA */
 1150 int
 1151 decode_win_idma_valid(void)
 1152 {
 1153 
 1154         return (1);
 1155 }
 1156 
 1157 void
 1158 decode_win_idma_setup(void)
 1159 {
 1160 }
 1161 
 1162 void
 1163 decode_win_idma_dump(void)
 1164 {
 1165 }
 1166 #endif
 1167 
 1168 /**************************************************************************
 1169  * XOR windows routines
 1170  **************************************************************************/
 1171 #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
 1172 static int
 1173 xor_ctrl_read(int i, int c, int e)
 1174 {
 1175         uint32_t v;
 1176         v = win_xor_ctrl_read(c, e);
 1177         v &= (1 << i);
 1178 
 1179         return (v >> i);
 1180 }
 1181 
 1182 static void
 1183 xor_ctrl_write(int i, int c, int e, int val)
 1184 {
 1185         uint32_t v;
 1186 
 1187         v = win_xor_ctrl_read(c, e);
 1188         v &= ~(1 << i);
 1189         v |= (val << i);
 1190         win_xor_ctrl_write(c, e, v);
 1191 }
 1192 
 1193 /*
 1194  * Set channel protection 'val' for window 'w' on channel 'c'
 1195  */
 1196 
 1197 static void
 1198 xor_chan_write(int c, int e, int w, int val)
 1199 {
 1200         uint32_t v;
 1201 
 1202         v = win_xor_ctrl_read(c, e);
 1203         v &= ~(0x3 << (w * 2 + 16));
 1204         v |= (val << (w * 2 + 16));
 1205         win_xor_ctrl_write(c, e, v);
 1206 }
 1207 
 1208 /*
 1209  * Set protection 'val' on all channels for window 'w' on engine 'e'
 1210  */
 1211 static void
 1212 xor_set_prot(int w, int e, int val)
 1213 {
 1214         int c;
 1215 
 1216         for (c = 0; c < MV_XOR_CHAN_MAX; c++)
 1217                 xor_chan_write(c, e, w, val);
 1218 }
 1219 
 1220 static int
 1221 win_xor_can_remap(int i)
 1222 {
 1223 
 1224         /* XOR decode windows 0-3 have remap capability */
 1225         if (i < 4)
 1226                 return (1);
 1227 
 1228         return (0);
 1229 }
 1230 
 1231 static int
 1232 xor_max_eng(void)
 1233 {
 1234         uint32_t dev, rev;
 1235 
 1236         soc_id(&dev, &rev);
 1237         if (dev == MV_DEV_88F6281)
 1238                 return (2);
 1239         else if ((dev == MV_DEV_MV78100) || (dev == MV_DEV_MV78100_Z0))
 1240                 return (1);
 1241         else
 1242                 return (0);
 1243 }
 1244 
 1245 static void
 1246 xor_active_dram(int c, int e, int *window)
 1247 {
 1248         uint32_t br, sz;
 1249         int i, m, w;
 1250 
 1251         /*
 1252          * Set up access to all active DRAM banks
 1253          */
 1254         m = xor_max_eng();
 1255         for (i = 0; i < m; i++)
 1256                 if (ddr_is_active(i)) {
 1257                         br = ddr_base(i) | (ddr_attr(i) << 8) |
 1258                             ddr_target(i);
 1259                         sz = ((ddr_size(i) - 1) & 0xffff0000);
 1260 
 1261                         /* Place DDR entries in non-remapped windows */
 1262                         for (w = 0; w < MV_WIN_XOR_MAX; w++)
 1263                                 if (win_xor_can_remap(w) != 1 &&
 1264                                     (xor_ctrl_read(w, c, e) == 0) &&
 1265                                     w > *window) {
 1266                                         /* Configure window */
 1267                                         win_xor_br_write(w, e, br);
 1268                                         win_xor_sz_write(w, e, sz);
 1269 
 1270                                         /* Set protection RW on all channels */
 1271                                         xor_set_prot(w, e, 0x3);
 1272 
 1273                                         /* Enable window */
 1274                                         xor_ctrl_write(w, c, e, 1);
 1275                                         (*window)++;
 1276                                         break;
 1277                                 }
 1278                 }
 1279 }
 1280 
 1281 void
 1282 decode_win_xor_setup(void)
 1283 {
 1284         uint32_t br, sz;
 1285         int i, j, z, e = 1, m, window;
 1286 
 1287         if (pm_is_disabled(CPU_PM_CTRL_XOR))
 1288                 return;
 1289 
 1290         /*
 1291          * Disable and clear all XOR windows, revoke protection for all
 1292          * channels
 1293          */
 1294         m = xor_max_eng();
 1295         for (j = 0; j < m; j++, e--) {
 1296 
 1297                 /* Number of non-remaped windows */
 1298                 window = MV_XOR_NON_REMAP - 1;
 1299 
 1300                 for (i = 0; i < MV_WIN_XOR_MAX; i++) {
 1301                         win_xor_br_write(i, e, 0);
 1302                         win_xor_sz_write(i, e, 0);
 1303                 }
 1304 
 1305                 if (win_xor_can_remap(i) == 1)
 1306                         win_xor_har_write(i, e, 0);
 1307 
 1308                 for (i = 0; i < MV_XOR_CHAN_MAX; i++) {
 1309                         win_xor_ctrl_write(i, e, 0);
 1310                         xor_active_dram(i, e, &window);
 1311                 }
 1312 
 1313                 /*
 1314                  * Remaining targets -- from a statically defined table
 1315                  */
 1316                 for (i = 0; i < xor_wins_no; i++)
 1317                         if (xor_wins[i].target > 0) {
 1318                                 br = (xor_wins[i].base & 0xffff0000) |
 1319                                     (xor_wins[i].attr << 8) |
 1320                                     xor_wins[i].target;
 1321                                 sz = ((xor_wins[i].size - 1) & 0xffff0000);
 1322 
 1323                                 /* Set the first free XOR window */
 1324                                 for (z = 0; z < MV_WIN_XOR_MAX; z++) {
 1325                                         if (xor_ctrl_read(z, 0, e) &&
 1326                                             xor_ctrl_read(z, 1, e))
 1327                                                 continue;
 1328 
 1329                                         /* Configure window */
 1330                                         win_xor_br_write(z, e, br);
 1331                                         win_xor_sz_write(z, e, sz);
 1332                                         if (win_xor_can_remap(z) &&
 1333                                             xor_wins[z].remap >= 0)
 1334                                                 win_xor_har_write(z, e,
 1335                                                     xor_wins[z].remap);
 1336 
 1337                                         /* Set protection RW on all channels */
 1338                                         xor_set_prot(z, e, 0x3);
 1339 
 1340                                         /* Enable window */
 1341                                         xor_ctrl_write(z, 0, e, 1);
 1342                                         xor_ctrl_write(z, 1, e, 1);
 1343                                         break;
 1344                                 }
 1345                         }
 1346         }
 1347 }
 1348 
 1349 int
 1350 decode_win_xor_valid(void)
 1351 {
 1352         const struct decode_win *wintab;
 1353         int c, i, j, rv;
 1354         uint32_t b, e, s;
 1355 
 1356         if (xor_wins_no > MV_WIN_XOR_MAX) {
 1357                 printf("XOR windows: too many entries: %d\n", xor_wins_no);
 1358                 return (-1);
 1359         }
 1360         for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
 1361                 if (ddr_is_active(i))
 1362                         c++;
 1363 
 1364         if (xor_wins_no > (MV_WIN_XOR_MAX - c)) {
 1365                 printf("XOR windows: too many entries: %d, available: %d\n",
 1366                     xor_wins_no, MV_WIN_IDMA_MAX - c);
 1367                 return (-1);
 1368         }
 1369 
 1370         wintab = xor_wins;
 1371         rv = 1;
 1372         for (i = 0; i < xor_wins_no; i++, wintab++) {
 1373 
 1374                 if (wintab->target == 0) {
 1375                         printf("XOR window#%d: DDR target window is not "
 1376                             "supposed to be reprogrammed!\n", i);
 1377                         rv = 0;
 1378                 }
 1379 
 1380                 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
 1381                         printf("XOR window#%d: not capable of remapping, but "
 1382                             "val 0x%08x defined\n", i, wintab->remap);
 1383                         rv = 0;
 1384                 }
 1385 
 1386                 s = wintab->size;
 1387                 b = wintab->base;
 1388                 e = b + s - 1;
 1389                 if (s > (0xFFFFFFFF - b + 1)) {
 1390                         /*
 1391                          * XXX this boundary check should account for 64bit
 1392                          * and remapping..
 1393                          */
 1394                         printf("XOR window#%d: no space for size 0x%08x at "
 1395                             "0x%08x\n", i, s, b);
 1396                         rv = 0;
 1397                         continue;
 1398                 }
 1399 
 1400                 j = decode_win_overlap(i, xor_wins_no, &xor_wins[0]);
 1401                 if (j >= 0) {
 1402                         printf("XOR window#%d: (0x%08x - 0x%08x) overlaps "
 1403                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
 1404                             xor_wins[j].base,
 1405                             xor_wins[j].base + xor_wins[j].size - 1);
 1406                         rv = 0;
 1407                 }
 1408         }
 1409 
 1410         return (rv);
 1411 }
 1412 
 1413 void
 1414 decode_win_xor_dump(void)
 1415 {
 1416         int i, j;
 1417         int e = 1;
 1418 
 1419         for (j = 0; j < xor_max_eng(); j++, e--) {
 1420                 for (i = 0; i < MV_WIN_XOR_MAX; i++) {
 1421                         printf("XOR window#%d: b 0x%08x, s 0x%08x", i,
 1422                             win_xor_br_read(i, e), win_xor_sz_read(i, e));
 1423 
 1424                         if (win_xor_can_remap(i))
 1425                                 printf(", ha 0x%08x", win_xor_har_read(i, e));
 1426 
 1427                         printf("\n");
 1428                 }
 1429                 for (i = 0; i < MV_XOR_CHAN_MAX; i++)
 1430                         printf("XOR control#%d: 0x%08x\n", i,
 1431                             win_xor_ctrl_read(i, e));
 1432         }
 1433 }
 1434 
 1435 #else
 1436 /* Provide dummy functions to satisfy the build for SoCs not equipped with XOR */
 1437 int
 1438 decode_win_xor_valid(void)
 1439 {
 1440 
 1441         return (1);
 1442 }
 1443 
 1444 void
 1445 decode_win_xor_setup(void)
 1446 {
 1447 }
 1448 
 1449 void
 1450 decode_win_xor_dump(void)
 1451 {
 1452 }
 1453 #endif
 1454 
 1455 /**************************************************************************
 1456  * CESA TDMA windows routines
 1457  **************************************************************************/
 1458 #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
 1459 /*
 1460  * Dump CESA TDMA decode windows.
 1461  */
 1462 static void
 1463 decode_win_cesa_dump(void)
 1464 {
 1465         int i;
 1466 
 1467         for (i = 0; i < MV_WIN_CESA_MAX; i++)
 1468                 printf("CESA window#%d: c 0x%08x, b 0x%08x\n", i,
 1469                     win_cesa_cr_read(i), win_cesa_br_read(i));
 1470 }
 1471 
 1472 
 1473 /*
 1474  * Set CESA TDMA decode windows.
 1475  */
 1476 static void
 1477 decode_win_cesa_setup(void)
 1478 {
 1479         uint32_t br, cr;
 1480         int i, j;
 1481 
 1482         if (pm_is_disabled(CPU_PM_CTRL_CRYPTO))
 1483                 return;
 1484 
 1485         /* Disable and clear all CESA windows */
 1486         for (i = 0; i < MV_WIN_CESA_MAX; i++) {
 1487                 win_cesa_cr_write(i, 0);
 1488                 win_cesa_br_write(i, 0);
 1489         }
 1490 
 1491         /* Only access to active DRAM banks is required. */
 1492         for (i = 0; i < MV_WIN_DDR_MAX; i++)
 1493                 if (ddr_is_active(i)) {
 1494                         br = ddr_base(i);
 1495                         cr = (((ddr_size(i) - 1) & 0xffff0000) |
 1496                            (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1);
 1497 
 1498                         /* Set the first available CESA window */
 1499                         for (j = 0; j < MV_WIN_CESA_MAX; j++) {
 1500                                 if (win_cesa_cr_read(j) & 0x1)
 1501                                         continue;
 1502 
 1503                                 win_cesa_br_write(j, br);
 1504                                 win_cesa_cr_write(j, cr);
 1505                                 break;
 1506                         }
 1507                 }
 1508 }
 1509 
 1510 /*
 1511  * Check CESA TDMA decode windows.
 1512  */
 1513 static int
 1514 decode_win_cesa_valid(void)
 1515 {
 1516 
 1517         return (decode_win_can_cover_ddr(MV_WIN_CESA_MAX));
 1518 }
 1519 #else
 1520 
 1521 /*
 1522  * Provide dummy functions to satisfy the build for SoCs not equipped with
 1523  * CESA
 1524  */
 1525 
 1526 int
 1527 decode_win_cesa_valid(void)
 1528 {
 1529 
 1530         return (1);
 1531 }
 1532 
 1533 void
 1534 decode_win_cesa_setup(void)
 1535 {
 1536 }
 1537 
 1538 void
 1539 decode_win_cesa_dump(void)
 1540 {
 1541 }
 1542 #endif
 1543 
 1544 /**************************************************************************
 1545  * SATA windows routines
 1546  **************************************************************************/
 1547 static void
 1548 decode_win_sata_setup(void)
 1549 {
 1550         uint32_t cr, br;
 1551         int i, j;
 1552 
 1553         if (pm_is_disabled(CPU_PM_CTRL_SATA))
 1554                 return;
 1555 
 1556         for (i = 0; i < MV_WIN_SATA_MAX; i++) {
 1557                 win_sata_cr_write(i, 0);
 1558                 win_sata_br_write(i, 0);
 1559         }
 1560 
 1561         for (i = 0; i < MV_WIN_DDR_MAX; i++)
 1562                 if (ddr_is_active(i)) {
 1563                         cr = ((ddr_size(i) - 1) & 0xffff0000) |
 1564                             (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
 1565                         br = ddr_base(i);
 1566 
 1567                         /* Use the first available SATA window */
 1568                         for (j = 0; j < MV_WIN_SATA_MAX; j++) {
 1569                                 if ((win_sata_cr_read(j) & 1) != 0)
 1570                                         continue;
 1571 
 1572                                 win_sata_br_write(j, br);
 1573                                 win_sata_cr_write(j, cr);
 1574                                 break;
 1575                         }
 1576                 }
 1577 }
 1578 
 1579 static int
 1580 decode_win_sata_valid(void)
 1581 {
 1582         uint32_t dev, rev;
 1583 
 1584         soc_id(&dev, &rev);
 1585         if (dev == MV_DEV_88F5281)
 1586                 return (1);
 1587 
 1588         return (decode_win_can_cover_ddr(MV_WIN_SATA_MAX));
 1589 }

Cache object: 91fec703fdc8bcff1dacbf7d27e80577


[ 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.