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-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 /*-
    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/9.0/sys/arm/mv/common.c 223665 2011-06-29 09:35:40Z kevlo $");
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/bus.h>
   38 #include <sys/kernel.h>
   39 
   40 #include <dev/fdt/fdt_common.h>
   41 #include <dev/ofw/openfirm.h>
   42 
   43 #include <machine/bus.h>
   44 #include <machine/fdt.h>
   45 
   46 #include <arm/mv/mvreg.h>
   47 #include <arm/mv/mvvar.h>
   48 #include <arm/mv/mvwin.h>
   49 
   50 #define MAX_CPU_WIN     5
   51 
   52 #define DEBUG
   53 #undef DEBUG
   54 
   55 #ifdef DEBUG
   56 #define debugf(fmt, args...) do { printf("%s(): ", __func__);   \
   57     printf(fmt,##args); } while (0)
   58 #else
   59 #define debugf(fmt, args...)
   60 #endif
   61 
   62 #ifdef DEBUG
   63 #define MV_DUMP_WIN     1
   64 #else
   65 #define MV_DUMP_WIN     0
   66 #endif
   67 
   68 static int win_eth_can_remap(int i);
   69 
   70 static int decode_win_cpu_valid(void);
   71 static int decode_win_usb_valid(void);
   72 static int decode_win_eth_valid(void);
   73 static int decode_win_pcie_valid(void);
   74 static int decode_win_sata_valid(void);
   75 static int decode_win_cesa_valid(void);
   76 static int decode_win_idma_valid(void);
   77 static int decode_win_xor_valid(void);
   78 
   79 static void decode_win_cpu_setup(void);
   80 static void decode_win_usb_setup(u_long);
   81 static void decode_win_eth_setup(u_long);
   82 static void decode_win_pcie_setup(u_long);
   83 static void decode_win_sata_setup(u_long);
   84 static void decode_win_cesa_setup(u_long);
   85 static void decode_win_idma_setup(u_long);
   86 static void decode_win_xor_setup(u_long);
   87 
   88 static void decode_win_cesa_dump(u_long);
   89 static void decode_win_usb_dump(u_long);
   90 static void decode_win_eth_dump(u_long base);
   91 static void decode_win_idma_dump(u_long base);
   92 static void decode_win_xor_dump(u_long base);
   93 
   94 static int fdt_get_ranges(const char *, void *, int, int *, int *);
   95 
   96 static int win_cpu_from_dt(void);
   97 static int fdt_win_setup(void);
   98 
   99 static uint32_t used_cpu_wins;
  100 static uint32_t dev_mask = 0;
  101 static int cpu_wins_no = 0;
  102 static int eth_port = 0;
  103 static int usb_port = 0;
  104 
  105 static struct decode_win cpu_win_tbl[MAX_CPU_WIN];
  106 
  107 static const struct decode_win *cpu_wins = cpu_win_tbl;
  108 
  109 typedef void (*decode_win_setup_t)(u_long);
  110 typedef void (*dump_win_t)(u_long);
  111 
  112 struct soc_node_spec {
  113         const char              *compat;
  114         decode_win_setup_t      decode_handler;
  115         dump_win_t              dump_handler;
  116 };
  117 
  118 static struct soc_node_spec soc_nodes[] = {
  119         { "mrvl,cesa", &decode_win_cesa_setup, &decode_win_cesa_dump },
  120         { "mrvl,ge", &decode_win_eth_setup, &decode_win_eth_dump },
  121         { "mrvl,usb-ehci", &decode_win_usb_setup, &decode_win_usb_dump },
  122         { "mrvl,sata", &decode_win_sata_setup, NULL },
  123         { "mrvl,xor", &decode_win_xor_setup, &decode_win_xor_dump },
  124         { "mrvl,idma", &decode_win_idma_setup, &decode_win_idma_dump },
  125         { "mrvl,pcie", &decode_win_pcie_setup, NULL },
  126         { NULL, NULL, NULL },
  127 };
  128 
  129 struct fdt_pm_mask_entry fdt_pm_mask_table[] = {
  130         { "mrvl,ge",            CPU_PM_CTRL_GE(0) },
  131         { "mrvl,ge",            CPU_PM_CTRL_GE(1) },
  132         { "mrvl,usb-ehci",      CPU_PM_CTRL_USB(0) },
  133         { "mrvl,usb-ehci",      CPU_PM_CTRL_USB(1) },
  134         { "mrvl,usb-ehci",      CPU_PM_CTRL_USB(2) },
  135         { "mrvl,cesa",          CPU_PM_CTRL_CRYPTO },
  136         { "mrvl,xor",           CPU_PM_CTRL_XOR },
  137         { "mrvl,sata",          CPU_PM_CTRL_SATA },
  138 
  139         { NULL, 0 }
  140 };
  141 
  142 static __inline int
  143 pm_is_disabled(uint32_t mask)
  144 {
  145 
  146         return (soc_power_ctrl_get(mask) == mask ? 0 : 1);
  147 }
  148 
  149 /*
  150  * Disable device using power management register.
  151  * 1 - Device Power On
  152  * 0 - Device Power Off
  153  * Mask can be set in loader.
  154  * EXAMPLE:
  155  * loader> set hw.pm-disable-mask=0x2
  156  *
  157  * Common mask:
  158  * |-------------------------------|
  159  * | Device | Kirkwood | Discovery |
  160  * |-------------------------------|
  161  * | USB0   | 0x00008  | 0x020000  |
  162  * |-------------------------------|
  163  * | USB1   |     -    | 0x040000  |
  164  * |-------------------------------|
  165  * | USB2   |     -    | 0x080000  |
  166  * |-------------------------------|
  167  * | GE0    | 0x00001  | 0x000002  |
  168  * |-------------------------------|
  169  * | GE1    |     -    | 0x000004  |
  170  * |-------------------------------|
  171  * | IDMA   |     -    | 0x100000  |
  172  * |-------------------------------|
  173  * | XOR    | 0x10000  | 0x200000  |
  174  * |-------------------------------|
  175  * | CESA   | 0x20000  | 0x400000  |
  176  * |-------------------------------|
  177  * | SATA   | 0x04000  | 0x004000  |
  178  * --------------------------------|
  179  * This feature can be used only on Kirkwood and Discovery
  180  * machines.
  181  */
  182 static __inline void
  183 pm_disable_device(int mask)
  184 {
  185 #ifdef DIAGNOSTIC
  186         uint32_t reg;
  187 
  188         reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
  189         printf("Power Management Register: 0%x\n", reg);
  190 
  191         reg &= ~mask;
  192         soc_power_ctrl_set(reg);
  193         printf("Device %x is disabled\n", mask);
  194 
  195         reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
  196         printf("Power Management Register: 0%x\n", reg);
  197 #endif
  198 }
  199 
  200 int
  201 fdt_pm(phandle_t node)
  202 {
  203         uint32_t cpu_pm_ctrl;
  204         int i, ena, compat;
  205 
  206         ena = 1;
  207         cpu_pm_ctrl = read_cpu_ctrl(CPU_PM_CTRL);
  208         for (i = 0; fdt_pm_mask_table[i].compat != NULL; i++) {
  209                 if (dev_mask & (1 << i))
  210                         continue;
  211 
  212                 compat = fdt_is_compatible(node, fdt_pm_mask_table[i].compat);
  213 
  214                 if (compat && (~cpu_pm_ctrl & fdt_pm_mask_table[i].mask)) {
  215                         dev_mask |= (1 << i);
  216                         ena = 0;
  217                         break;
  218                 } else if (compat) {
  219                         dev_mask |= (1 << i);
  220                         break;
  221                 }
  222         }
  223 
  224         return (ena);
  225 }
  226 
  227 uint32_t
  228 read_cpu_ctrl(uint32_t reg)
  229 {
  230 
  231         return (bus_space_read_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE, reg));
  232 }
  233 
  234 void
  235 write_cpu_ctrl(uint32_t reg, uint32_t val)
  236 {
  237 
  238         bus_space_write_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE, reg, val);
  239 }
  240 
  241 void
  242 cpu_reset(void)
  243 {
  244 
  245         write_cpu_ctrl(RSTOUTn_MASK, SOFT_RST_OUT_EN);
  246         write_cpu_ctrl(SYSTEM_SOFT_RESET, SYS_SOFT_RST);
  247         while (1);
  248 }
  249 
  250 uint32_t
  251 cpu_extra_feat(void)
  252 {
  253         uint32_t dev, rev;
  254         uint32_t ef = 0;
  255 
  256         soc_id(&dev, &rev);
  257         if (dev == MV_DEV_88F6281 || dev == MV_DEV_MV78100_Z0 ||
  258             dev == MV_DEV_MV78100)
  259                 __asm __volatile("mrc p15, 1, %0, c15, c1, 0" : "=r" (ef));
  260         else if (dev == MV_DEV_88F5182 || dev == MV_DEV_88F5281)
  261                 __asm __volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (ef));
  262         else if (bootverbose)
  263                 printf("This ARM Core does not support any extra features\n");
  264 
  265         return (ef);
  266 }
  267 
  268 /*
  269  * Get the power status of device. This feature is only supported on
  270  * Kirkwood and Discovery SoCs.
  271  */
  272 uint32_t
  273 soc_power_ctrl_get(uint32_t mask)
  274 {
  275 
  276 #ifndef SOC_MV_ORION
  277         if (mask != CPU_PM_CTRL_NONE)
  278                 mask &= read_cpu_ctrl(CPU_PM_CTRL);
  279 
  280         return (mask);
  281 #else
  282         return (mask);
  283 #endif
  284 }
  285 
  286 /*
  287  * Set the power status of device. This feature is only supported on
  288  * Kirkwood and Discovery SoCs.
  289  */
  290 void
  291 soc_power_ctrl_set(uint32_t mask)
  292 {
  293 
  294 #ifndef SOC_MV_ORION
  295         if (mask != CPU_PM_CTRL_NONE)
  296                 write_cpu_ctrl(CPU_PM_CTRL, mask);
  297 #endif
  298 }
  299 
  300 void
  301 soc_id(uint32_t *dev, uint32_t *rev)
  302 {
  303 
  304         /*
  305          * Notice: system identifiers are available in the registers range of
  306          * PCIE controller, so using this function is only allowed (and
  307          * possible) after the internal registers range has been mapped in via
  308          * pmap_devmap_bootstrap().
  309          */
  310         *dev = bus_space_read_4(fdtbus_bs_tag, MV_PCIE_BASE, 0) >> 16;
  311         *rev = bus_space_read_4(fdtbus_bs_tag, MV_PCIE_BASE, 8) & 0xff;
  312 }
  313 
  314 static void
  315 soc_identify(void)
  316 {
  317         uint32_t d, r;
  318         const char *dev;
  319         const char *rev;
  320 
  321         soc_id(&d, &r);
  322 
  323         printf("SOC: ");
  324         if (bootverbose)
  325                 printf("(0x%4x:0x%02x) ", d, r);
  326 
  327         rev = "";
  328         switch (d) {
  329         case MV_DEV_88F5181:
  330                 dev = "Marvell 88F5181";
  331                 if (r == 3)
  332                         rev = "B1";
  333                 break;
  334         case MV_DEV_88F5182:
  335                 dev = "Marvell 88F5182";
  336                 if (r == 2)
  337                         rev = "A2";
  338                 break;
  339         case MV_DEV_88F5281:
  340                 dev = "Marvell 88F5281";
  341                 if (r == 4)
  342                         rev = "D0";
  343                 else if (r == 5)
  344                         rev = "D1";
  345                 else if (r == 6)
  346                         rev = "D2";
  347                 break;
  348         case MV_DEV_88F6281:
  349                 dev = "Marvell 88F6281";
  350                 if (r == 0)
  351                         rev = "Z0";
  352                 else if (r == 2)
  353                         rev = "A0";
  354                 else if (r == 3)
  355                         rev = "A1";
  356                 break;
  357         case MV_DEV_MV78100_Z0:
  358                 dev = "Marvell MV78100 Z0";
  359                 break;
  360         case MV_DEV_MV78100:
  361                 dev = "Marvell MV78100";
  362                 break;
  363         default:
  364                 dev = "UNKNOWN";
  365                 break;
  366         }
  367 
  368         printf("%s", dev);
  369         if (*rev != '\0')
  370                 printf(" rev %s", rev);
  371         printf(", TClock %dMHz\n", get_tclk() / 1000 / 1000);
  372 
  373         /* TODO add info on currently set endianess */
  374 }
  375 
  376 static void
  377 platform_identify(void *dummy)
  378 {
  379 
  380         soc_identify();
  381 
  382         /*
  383          * XXX Board identification e.g. read out from FPGA or similar should
  384          * go here
  385          */
  386 }
  387 SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify,
  388     NULL);
  389 
  390 int
  391 soc_decode_win(void)
  392 {
  393         uint32_t dev, rev;
  394         int mask, err;
  395 
  396         mask = 0;
  397         TUNABLE_INT_FETCH("hw.pm-disable-mask", &mask);
  398 
  399         if (mask != 0)
  400                 pm_disable_device(mask);
  401 
  402         /* Retrieve data about physical addresses from device tree. */
  403         if ((err = win_cpu_from_dt()) != 0)
  404                 return (err);
  405 
  406         /* Retrieve our ID: some windows facilities vary between SoC models */
  407         soc_id(&dev, &rev);
  408 
  409         if (!decode_win_cpu_valid() || !decode_win_usb_valid() ||
  410             !decode_win_eth_valid() || !decode_win_idma_valid() ||
  411             !decode_win_pcie_valid() || !decode_win_sata_valid() ||
  412             !decode_win_cesa_valid() || !decode_win_xor_valid())
  413                 return (EINVAL);
  414 
  415         decode_win_cpu_setup();
  416         if (MV_DUMP_WIN)
  417                 soc_dump_decode_win();
  418 
  419         eth_port = 0;
  420         usb_port = 0;
  421         if ((err = fdt_win_setup()) != 0)
  422                 return (err);
  423 
  424         return (0);
  425 }
  426 
  427 /**************************************************************************
  428  * Decode windows registers accessors
  429  **************************************************************************/
  430 WIN_REG_IDX_RD(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
  431 WIN_REG_IDX_RD(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
  432 WIN_REG_IDX_RD(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
  433 WIN_REG_IDX_RD(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
  434 WIN_REG_IDX_WR(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
  435 WIN_REG_IDX_WR(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
  436 WIN_REG_IDX_WR(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
  437 WIN_REG_IDX_WR(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
  438 
  439 WIN_REG_IDX_RD(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
  440 WIN_REG_IDX_RD(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
  441 
  442 WIN_REG_BASE_IDX_RD(win_usb, cr, MV_WIN_USB_CTRL)
  443 WIN_REG_BASE_IDX_RD(win_usb, br, MV_WIN_USB_BASE)
  444 WIN_REG_BASE_IDX_WR(win_usb, cr, MV_WIN_USB_CTRL)
  445 WIN_REG_BASE_IDX_WR(win_usb, br, MV_WIN_USB_BASE)
  446 
  447 WIN_REG_BASE_IDX_RD(win_cesa, cr, MV_WIN_CESA_CTRL)
  448 WIN_REG_BASE_IDX_RD(win_cesa, br, MV_WIN_CESA_BASE)
  449 WIN_REG_BASE_IDX_WR(win_cesa, cr, MV_WIN_CESA_CTRL)
  450 WIN_REG_BASE_IDX_WR(win_cesa, br, MV_WIN_CESA_BASE)
  451 
  452 WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE)
  453 WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE)
  454 WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP)
  455 WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE)
  456 WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE)
  457 WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP)
  458 
  459 WIN_REG_BASE_IDX_RD2(win_xor, br, MV_WIN_XOR_BASE)
  460 WIN_REG_BASE_IDX_RD2(win_xor, sz, MV_WIN_XOR_SIZE)
  461 WIN_REG_BASE_IDX_RD2(win_xor, har, MV_WIN_XOR_REMAP)
  462 WIN_REG_BASE_IDX_RD2(win_xor, ctrl, MV_WIN_XOR_CTRL)
  463 WIN_REG_BASE_IDX_WR2(win_xor, br, MV_WIN_XOR_BASE)
  464 WIN_REG_BASE_IDX_WR2(win_xor, sz, MV_WIN_XOR_SIZE)
  465 WIN_REG_BASE_IDX_WR2(win_xor, har, MV_WIN_XOR_REMAP)
  466 WIN_REG_BASE_IDX_WR2(win_xor, ctrl, MV_WIN_XOR_CTRL)
  467 
  468 WIN_REG_BASE_RD(win_eth, bare, 0x290)
  469 WIN_REG_BASE_RD(win_eth, epap, 0x294)
  470 WIN_REG_BASE_WR(win_eth, bare, 0x290)
  471 WIN_REG_BASE_WR(win_eth, epap, 0x294)
  472 
  473 WIN_REG_BASE_IDX_RD(win_pcie, cr, MV_WIN_PCIE_CTRL);
  474 WIN_REG_BASE_IDX_RD(win_pcie, br, MV_WIN_PCIE_BASE);
  475 WIN_REG_BASE_IDX_RD(win_pcie, remap, MV_WIN_PCIE_REMAP);
  476 WIN_REG_BASE_IDX_WR(win_pcie, cr, MV_WIN_PCIE_CTRL);
  477 WIN_REG_BASE_IDX_WR(win_pcie, br, MV_WIN_PCIE_BASE);
  478 WIN_REG_BASE_IDX_WR(win_pcie, remap, MV_WIN_PCIE_REMAP);
  479 WIN_REG_BASE_IDX_WR(pcie, bar, MV_PCIE_BAR);
  480 
  481 WIN_REG_BASE_IDX_RD(win_idma, br, MV_WIN_IDMA_BASE)
  482 WIN_REG_BASE_IDX_RD(win_idma, sz, MV_WIN_IDMA_SIZE)
  483 WIN_REG_BASE_IDX_RD(win_idma, har, MV_WIN_IDMA_REMAP)
  484 WIN_REG_BASE_IDX_RD(win_idma, cap, MV_WIN_IDMA_CAP)
  485 WIN_REG_BASE_IDX_WR(win_idma, br, MV_WIN_IDMA_BASE)
  486 WIN_REG_BASE_IDX_WR(win_idma, sz, MV_WIN_IDMA_SIZE)
  487 WIN_REG_BASE_IDX_WR(win_idma, har, MV_WIN_IDMA_REMAP)
  488 WIN_REG_BASE_IDX_WR(win_idma, cap, MV_WIN_IDMA_CAP)
  489 WIN_REG_BASE_RD(win_idma, bare, 0xa80)
  490 WIN_REG_BASE_WR(win_idma, bare, 0xa80)
  491 
  492 WIN_REG_BASE_IDX_RD(win_sata, cr, MV_WIN_SATA_CTRL);
  493 WIN_REG_BASE_IDX_RD(win_sata, br, MV_WIN_SATA_BASE);
  494 WIN_REG_BASE_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL);
  495 WIN_REG_BASE_IDX_WR(win_sata, br, MV_WIN_SATA_BASE);
  496 
  497 /**************************************************************************
  498  * Decode windows helper routines
  499  **************************************************************************/
  500 void
  501 soc_dump_decode_win(void)
  502 {
  503         uint32_t dev, rev;
  504         int i;
  505 
  506         soc_id(&dev, &rev);
  507 
  508         for (i = 0; i < MV_WIN_CPU_MAX; i++) {
  509                 printf("CPU window#%d: c 0x%08x, b 0x%08x", i,
  510                     win_cpu_cr_read(i),
  511                     win_cpu_br_read(i));
  512 
  513                 if (win_cpu_can_remap(i))
  514                         printf(", rl 0x%08x, rh 0x%08x",
  515                             win_cpu_remap_l_read(i),
  516                             win_cpu_remap_h_read(i));
  517 
  518                 printf("\n");
  519         }
  520         printf("Internal regs base: 0x%08x\n",
  521             bus_space_read_4(fdtbus_bs_tag, MV_INTREGS_BASE, 0));
  522 
  523         for (i = 0; i < MV_WIN_DDR_MAX; i++)
  524                 printf("DDR CS#%d: b 0x%08x, s 0x%08x\n", i,
  525                     ddr_br_read(i), ddr_sz_read(i));
  526 }
  527 
  528 /**************************************************************************
  529  * CPU windows routines
  530  **************************************************************************/
  531 int
  532 win_cpu_can_remap(int i)
  533 {
  534         uint32_t dev, rev;
  535 
  536         soc_id(&dev, &rev);
  537 
  538         /* Depending on the SoC certain windows have remap capability */
  539         if ((dev == MV_DEV_88F5182 && i < 2) ||
  540             (dev == MV_DEV_88F5281 && i < 4) ||
  541             (dev == MV_DEV_88F6281 && i < 4) ||
  542             (dev == MV_DEV_MV78100 && i < 8) ||
  543             (dev == MV_DEV_MV78100_Z0 && i < 8))
  544                 return (1);
  545 
  546         return (0);
  547 }
  548 
  549 /* XXX This should check for overlapping remap fields too.. */
  550 int
  551 decode_win_overlap(int win, int win_no, const struct decode_win *wintab)
  552 {
  553         const struct decode_win *tab;
  554         int i;
  555 
  556         tab = wintab;
  557 
  558         for (i = 0; i < win_no; i++, tab++) {
  559                 if (i == win)
  560                         /* Skip self */
  561                         continue;
  562 
  563                 if ((tab->base + tab->size - 1) < (wintab + win)->base)
  564                         continue;
  565 
  566                 else if (((wintab + win)->base + (wintab + win)->size - 1) <
  567                     tab->base)
  568                         continue;
  569                 else
  570                         return (i);
  571         }
  572 
  573         return (-1);
  574 }
  575 
  576 static int
  577 decode_win_cpu_valid(void)
  578 {
  579         int i, j, rv;
  580         uint32_t b, e, s;
  581 
  582         if (cpu_wins_no > MV_WIN_CPU_MAX) {
  583                 printf("CPU windows: too many entries: %d\n", cpu_wins_no);
  584                 return (0);
  585         }
  586 
  587         rv = 1;
  588         for (i = 0; i < cpu_wins_no; i++) {
  589 
  590                 if (cpu_wins[i].target == 0) {
  591                         printf("CPU window#%d: DDR target window is not "
  592                             "supposed to be reprogrammed!\n", i);
  593                         rv = 0;
  594                 }
  595 
  596                 if (cpu_wins[i].remap >= 0 && win_cpu_can_remap(i) != 1) {
  597                         printf("CPU window#%d: not capable of remapping, but "
  598                             "val 0x%08x defined\n", i, cpu_wins[i].remap);
  599                         rv = 0;
  600                 }
  601 
  602                 s = cpu_wins[i].size;
  603                 b = cpu_wins[i].base;
  604                 e = b + s - 1;
  605                 if (s > (0xFFFFFFFF - b + 1)) {
  606                         /*
  607                          * XXX this boundary check should account for 64bit
  608                          * and remapping..
  609                          */
  610                         printf("CPU window#%d: no space for size 0x%08x at "
  611                             "0x%08x\n", i, s, b);
  612                         rv = 0;
  613                         continue;
  614                 }
  615 
  616                 j = decode_win_overlap(i, cpu_wins_no, &cpu_wins[0]);
  617                 if (j >= 0) {
  618                         printf("CPU window#%d: (0x%08x - 0x%08x) overlaps "
  619                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
  620                             cpu_wins[j].base,
  621                             cpu_wins[j].base + cpu_wins[j].size - 1);
  622                         rv = 0;
  623                 }
  624         }
  625 
  626         return (rv);
  627 }
  628 
  629 int
  630 decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size,
  631     int remap)
  632 {
  633         uint32_t br, cr;
  634         int win;
  635 
  636         if (used_cpu_wins >= MV_WIN_CPU_MAX)
  637                 return (0);
  638 
  639         win = used_cpu_wins++;
  640 
  641         br = base & 0xffff0000;
  642         win_cpu_br_write(win, br);
  643 
  644         if (win_cpu_can_remap(win)) {
  645                 if (remap >= 0) {
  646                         win_cpu_remap_l_write(win, remap & 0xffff0000);
  647                         win_cpu_remap_h_write(win, 0);
  648                 } else {
  649                         /*
  650                          * Remap function is not used for a given window
  651                          * (capable of remapping) - set remap field with the
  652                          * same value as base.
  653                          */
  654                         win_cpu_remap_l_write(win, base & 0xffff0000);
  655                         win_cpu_remap_h_write(win, 0);
  656                 }
  657         }
  658 
  659         cr = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
  660         win_cpu_cr_write(win, cr);
  661 
  662         return (0);
  663 }
  664 
  665 static void
  666 decode_win_cpu_setup(void)
  667 {
  668         int i;
  669 
  670         used_cpu_wins = 0;
  671 
  672         /* Disable all CPU windows */
  673         for (i = 0; i < MV_WIN_CPU_MAX; i++) {
  674                 win_cpu_cr_write(i, 0);
  675                 win_cpu_br_write(i, 0);
  676                 if (win_cpu_can_remap(i)) {
  677                         win_cpu_remap_l_write(i, 0);
  678                         win_cpu_remap_h_write(i, 0);
  679                 }
  680         }
  681 
  682         for (i = 0; i < cpu_wins_no; i++)
  683                 if (cpu_wins[i].target > 0)
  684                         decode_win_cpu_set(cpu_wins[i].target,
  685                             cpu_wins[i].attr, cpu_wins[i].base,
  686                             cpu_wins[i].size, cpu_wins[i].remap);
  687 
  688 }
  689 
  690 /*
  691  * Check if we're able to cover all active DDR banks.
  692  */
  693 static int
  694 decode_win_can_cover_ddr(int max)
  695 {
  696         int i, c;
  697 
  698         c = 0;
  699         for (i = 0; i < MV_WIN_DDR_MAX; i++)
  700                 if (ddr_is_active(i))
  701                         c++;
  702 
  703         if (c > max) {
  704                 printf("Unable to cover all active DDR banks: "
  705                     "%d, available windows: %d\n", c, max);
  706                 return (0);
  707         }
  708 
  709         return (1);
  710 }
  711 
  712 /**************************************************************************
  713  * DDR windows routines
  714  **************************************************************************/
  715 int
  716 ddr_is_active(int i)
  717 {
  718 
  719         if (ddr_sz_read(i) & 0x1)
  720                 return (1);
  721 
  722         return (0);
  723 }
  724 
  725 uint32_t
  726 ddr_base(int i)
  727 {
  728 
  729         return (ddr_br_read(i) & 0xff000000);
  730 }
  731 
  732 uint32_t
  733 ddr_size(int i)
  734 {
  735 
  736         return ((ddr_sz_read(i) | 0x00ffffff) + 1);
  737 }
  738 
  739 uint32_t
  740 ddr_attr(int i)
  741 {
  742 
  743         return (i == 0 ? 0xe :
  744             (i == 1 ? 0xd :
  745             (i == 2 ? 0xb :
  746             (i == 3 ? 0x7 : 0xff))));
  747 }
  748 
  749 uint32_t
  750 ddr_target(int i)
  751 {
  752 
  753         /* Mbus unit ID is 0x0 for DDR SDRAM controller */
  754         return (0);
  755 }
  756 
  757 /**************************************************************************
  758  * USB windows routines
  759  **************************************************************************/
  760 static int
  761 decode_win_usb_valid(void)
  762 {
  763 
  764         return (decode_win_can_cover_ddr(MV_WIN_USB_MAX));
  765 }
  766 
  767 static void
  768 decode_win_usb_dump(u_long base)
  769 {
  770         int i;
  771 
  772         if (pm_is_disabled(CPU_PM_CTRL_USB(usb_port - 1)))
  773                 return;
  774 
  775         for (i = 0; i < MV_WIN_USB_MAX; i++)
  776                 printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
  777                     win_usb_cr_read(base, i), win_usb_br_read(base, i));
  778 }
  779 
  780 /*
  781  * Set USB decode windows.
  782  */
  783 static void
  784 decode_win_usb_setup(u_long base)
  785 {
  786         uint32_t br, cr;
  787         int i, j;
  788 
  789 
  790         if (pm_is_disabled(CPU_PM_CTRL_USB(usb_port)))
  791                 return;
  792 
  793         usb_port++;
  794 
  795         for (i = 0; i < MV_WIN_USB_MAX; i++) {
  796                 win_usb_cr_write(base, i, 0);
  797                 win_usb_br_write(base, i, 0);
  798         }
  799 
  800         /* Only access to active DRAM banks is required */
  801         for (i = 0; i < MV_WIN_DDR_MAX; i++) {
  802                 if (ddr_is_active(i)) {
  803                         br = ddr_base(i);
  804                         /*
  805                          * XXX for 6281 we should handle Mbus write
  806                          * burst limit field in the ctrl reg
  807                          */
  808                         cr = (((ddr_size(i) - 1) & 0xffff0000) |
  809                             (ddr_attr(i) << 8) |
  810                             (ddr_target(i) << 4) | 1);
  811 
  812                         /* Set the first free USB window */
  813                         for (j = 0; j < MV_WIN_USB_MAX; j++) {
  814                                 if (win_usb_cr_read(base, j) & 0x1)
  815                                         continue;
  816 
  817                                 win_usb_br_write(base, j, br);
  818                                 win_usb_cr_write(base, j, cr);
  819                                 break;
  820                         }
  821                 }
  822         }
  823 }
  824 
  825 /**************************************************************************
  826  * ETH windows routines
  827  **************************************************************************/
  828 
  829 static int
  830 win_eth_can_remap(int i)
  831 {
  832 
  833         /* ETH encode windows 0-3 have remap capability */
  834         if (i < 4)
  835                 return (1);
  836         
  837         return (0);
  838 }
  839 
  840 static int
  841 eth_bare_read(uint32_t base, int i)
  842 {
  843         uint32_t v;
  844 
  845         v = win_eth_bare_read(base);
  846         v &= (1 << i);
  847 
  848         return (v >> i);
  849 }
  850 
  851 static void
  852 eth_bare_write(uint32_t base, int i, int val)
  853 {
  854         uint32_t v;
  855 
  856         v = win_eth_bare_read(base);
  857         v &= ~(1 << i);
  858         v |= (val << i);
  859         win_eth_bare_write(base, v);
  860 }
  861 
  862 static void
  863 eth_epap_write(uint32_t base, int i, int val)
  864 {
  865         uint32_t v;
  866 
  867         v = win_eth_epap_read(base);
  868         v &= ~(0x3 << (i * 2));
  869         v |= (val << (i * 2));
  870         win_eth_epap_write(base, v);
  871 }
  872 
  873 static void
  874 decode_win_eth_dump(u_long base)
  875 {
  876         int i;
  877 
  878         if (pm_is_disabled(CPU_PM_CTRL_GE(eth_port - 1)))
  879                 return;
  880 
  881         for (i = 0; i < MV_WIN_ETH_MAX; i++) {
  882                 printf("ETH window#%d: b 0x%08x, s 0x%08x", i,
  883                     win_eth_br_read(base, i),
  884                     win_eth_sz_read(base, i));
  885 
  886                 if (win_eth_can_remap(i))
  887                         printf(", ha 0x%08x",
  888                             win_eth_har_read(base, i));
  889 
  890                 printf("\n");
  891         }
  892         printf("ETH windows: bare 0x%08x, epap 0x%08x\n",
  893             win_eth_bare_read(base),
  894             win_eth_epap_read(base));
  895 }
  896 
  897 static void
  898 decode_win_eth_setup(u_long base)
  899 {
  900         uint32_t br, sz;
  901         int i, j;
  902 
  903         if (pm_is_disabled(CPU_PM_CTRL_GE(eth_port)))
  904                 return;
  905 
  906         eth_port++;
  907 
  908         /* Disable, clear and revoke protection for all ETH windows */
  909         for (i = 0; i < MV_WIN_ETH_MAX; i++) {
  910 
  911                 eth_bare_write(base, i, 1);
  912                 eth_epap_write(base, i, 0);
  913                 win_eth_br_write(base, i, 0);
  914                 win_eth_sz_write(base, i, 0);
  915                 if (win_eth_can_remap(i))
  916                         win_eth_har_write(base, i, 0);
  917         }
  918 
  919         /* Only access to active DRAM banks is required */
  920         for (i = 0; i < MV_WIN_DDR_MAX; i++)
  921                 if (ddr_is_active(i)) {
  922 
  923                         br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
  924                         sz = ((ddr_size(i) - 1) & 0xffff0000);
  925 
  926                         /* Set the first free ETH window */
  927                         for (j = 0; j < MV_WIN_ETH_MAX; j++) {
  928                                 if (eth_bare_read(base, j) == 0)
  929                                         continue;
  930 
  931                                 win_eth_br_write(base, j, br);
  932                                 win_eth_sz_write(base, j, sz);
  933 
  934                                 /* XXX remapping ETH windows not supported */
  935 
  936                                 /* Set protection RW */
  937                                 eth_epap_write(base, j, 0x3);
  938 
  939                                 /* Enable window */
  940                                 eth_bare_write(base, j, 0);
  941                                 break;
  942                         }
  943                 }
  944 }
  945 
  946 static int
  947 decode_win_eth_valid(void)
  948 {
  949 
  950         return (decode_win_can_cover_ddr(MV_WIN_ETH_MAX));
  951 }
  952 
  953 /**************************************************************************
  954  * PCIE windows routines
  955  **************************************************************************/
  956 
  957 static void
  958 decode_win_pcie_setup(u_long base)
  959 {
  960         uint32_t size = 0;
  961         uint32_t cr, br;
  962         int i, j;
  963 
  964         for (i = 0; i < MV_PCIE_BAR_MAX; i++)
  965                 pcie_bar_write(base, i, 0);
  966 
  967         for (i = 0; i < MV_WIN_PCIE_MAX; i++) {
  968                 win_pcie_cr_write(base, i, 0);
  969                 win_pcie_br_write(base, i, 0);
  970                 win_pcie_remap_write(base, i, 0);
  971         }
  972 
  973         for (i = 0; i < MV_WIN_DDR_MAX; i++) {
  974                 if (ddr_is_active(i)) {
  975                         /* Map DDR to BAR 1 */
  976                         cr = (ddr_size(i) - 1) & 0xffff0000;
  977                         size += ddr_size(i) & 0xffff0000;
  978                         cr |= (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
  979                         br = ddr_base(i);
  980 
  981                         /* Use the first available PCIE window */
  982                         for (j = 0; j < MV_WIN_PCIE_MAX; j++) {
  983                                 if (win_pcie_cr_read(base, j) != 0)
  984                                         continue;
  985 
  986                                 win_pcie_br_write(base, j, br);
  987                                 win_pcie_cr_write(base, j, cr);
  988                                 break;
  989                         }
  990                 }
  991         }
  992 
  993         /*
  994          * Upper 16 bits in BAR register is interpreted as BAR size
  995          * (in 64 kB units) plus 64kB, so substract 0x10000
  996          * form value passed to register to get correct value.
  997          */
  998         size -= 0x10000;
  999         pcie_bar_write(base, 0, size | 1);
 1000 }
 1001 
 1002 static int
 1003 decode_win_pcie_valid(void)
 1004 {
 1005 
 1006         return (decode_win_can_cover_ddr(MV_WIN_PCIE_MAX));
 1007 }
 1008 
 1009 /**************************************************************************
 1010  * IDMA windows routines
 1011  **************************************************************************/
 1012 #if defined(SOC_MV_ORION) || defined(SOC_MV_DISCOVERY)
 1013 static int
 1014 idma_bare_read(u_long base, int i)
 1015 {
 1016         uint32_t v;
 1017 
 1018         v = win_idma_bare_read(base);
 1019         v &= (1 << i);
 1020 
 1021         return (v >> i);
 1022 }
 1023 
 1024 static void
 1025 idma_bare_write(u_long base, int i, int val)
 1026 {
 1027         uint32_t v;
 1028 
 1029         v = win_idma_bare_read(base);
 1030         v &= ~(1 << i);
 1031         v |= (val << i);
 1032         win_idma_bare_write(base, v);
 1033 }
 1034 
 1035 /*
 1036  * Sets channel protection 'val' for window 'w' on channel 'c'
 1037  */
 1038 static void
 1039 idma_cap_write(u_long base, int c, int w, int val)
 1040 {
 1041         uint32_t v;
 1042 
 1043         v = win_idma_cap_read(base, c);
 1044         v &= ~(0x3 << (w * 2));
 1045         v |= (val << (w * 2));
 1046         win_idma_cap_write(base, c, v);
 1047 }
 1048 
 1049 /*
 1050  * Set protection 'val' on all channels for window 'w'
 1051  */
 1052 static void
 1053 idma_set_prot(u_long base, int w, int val)
 1054 {
 1055         int c;
 1056 
 1057         for (c = 0; c < MV_IDMA_CHAN_MAX; c++)
 1058                 idma_cap_write(base, c, w, val);
 1059 }
 1060 
 1061 static int
 1062 win_idma_can_remap(int i)
 1063 {
 1064 
 1065         /* IDMA decode windows 0-3 have remap capability */
 1066         if (i < 4)
 1067                 return (1);
 1068 
 1069         return (0);
 1070 }
 1071 
 1072 void
 1073 decode_win_idma_setup(u_long base)
 1074 {
 1075         uint32_t br, sz;
 1076         int i, j;
 1077 
 1078         if (pm_is_disabled(CPU_PM_CTRL_IDMA))
 1079                 return;
 1080         /*
 1081          * Disable and clear all IDMA windows, revoke protection for all channels
 1082          */
 1083         for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
 1084 
 1085                 idma_bare_write(base, i, 1);
 1086                 win_idma_br_write(base, i, 0);
 1087                 win_idma_sz_write(base, i, 0);
 1088                 if (win_idma_can_remap(i) == 1)
 1089                         win_idma_har_write(base, i, 0);
 1090         }
 1091         for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
 1092                 win_idma_cap_write(base, i, 0);
 1093 
 1094         /*
 1095          * Set up access to all active DRAM banks
 1096          */
 1097         for (i = 0; i < MV_WIN_DDR_MAX; i++)
 1098                 if (ddr_is_active(i)) {
 1099                         br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
 1100                         sz = ((ddr_size(i) - 1) & 0xffff0000);
 1101 
 1102                         /* Place DDR entries in non-remapped windows */
 1103                         for (j = 0; j < MV_WIN_IDMA_MAX; j++)
 1104                                 if (win_idma_can_remap(j) != 1 &&
 1105                                     idma_bare_read(base, j) == 1) {
 1106 
 1107                                         /* Configure window */
 1108                                         win_idma_br_write(base, j, br);
 1109                                         win_idma_sz_write(base, j, sz);
 1110 
 1111                                         /* Set protection RW on all channels */
 1112                                         idma_set_prot(base, j, 0x3);
 1113 
 1114                                         /* Enable window */
 1115                                         idma_bare_write(base, j, 0);
 1116                                         break;
 1117                                 }
 1118                 }
 1119 
 1120         /*
 1121          * Remaining targets -- from statically defined table
 1122          */
 1123         for (i = 0; i < idma_wins_no; i++)
 1124                 if (idma_wins[i].target > 0) {
 1125                         br = (idma_wins[i].base & 0xffff0000) |
 1126                             (idma_wins[i].attr << 8) | idma_wins[i].target;
 1127                         sz = ((idma_wins[i].size - 1) & 0xffff0000);
 1128 
 1129                         /* Set the first free IDMA window */
 1130                         for (j = 0; j < MV_WIN_IDMA_MAX; j++) {
 1131                                 if (idma_bare_read(base, j) == 0)
 1132                                         continue;
 1133 
 1134                                 /* Configure window */
 1135                                 win_idma_br_write(base, j, br);
 1136                                 win_idma_sz_write(base, j, sz);
 1137                                 if (win_idma_can_remap(j) &&
 1138                                     idma_wins[j].remap >= 0)
 1139                                         win_idma_har_write(base, j,
 1140                                             idma_wins[j].remap);
 1141 
 1142                                 /* Set protection RW on all channels */
 1143                                 idma_set_prot(base, j, 0x3);
 1144 
 1145                                 /* Enable window */
 1146                                 idma_bare_write(base, j, 0);
 1147                                 break;
 1148                         }
 1149                 }
 1150 }
 1151 
 1152 int
 1153 decode_win_idma_valid(void)
 1154 {
 1155         const struct decode_win *wintab;
 1156         int c, i, j, rv;
 1157         uint32_t b, e, s;
 1158 
 1159         if (idma_wins_no > MV_WIN_IDMA_MAX) {
 1160                 printf("IDMA windows: too many entries: %d\n", idma_wins_no);
 1161                 return (0);
 1162         }
 1163         for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
 1164                 if (ddr_is_active(i))
 1165                         c++;
 1166 
 1167         if (idma_wins_no > (MV_WIN_IDMA_MAX - c)) {
 1168                 printf("IDMA windows: too many entries: %d, available: %d\n",
 1169                     idma_wins_no, MV_WIN_IDMA_MAX - c);
 1170                 return (0);
 1171         }
 1172 
 1173         wintab = idma_wins;
 1174         rv = 1;
 1175         for (i = 0; i < idma_wins_no; i++, wintab++) {
 1176 
 1177                 if (wintab->target == 0) {
 1178                         printf("IDMA window#%d: DDR target window is not "
 1179                             "supposed to be reprogrammed!\n", i);
 1180                         rv = 0;
 1181                 }
 1182 
 1183                 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
 1184                         printf("IDMA window#%d: not capable of remapping, but "
 1185                             "val 0x%08x defined\n", i, wintab->remap);
 1186                         rv = 0;
 1187                 }
 1188 
 1189                 s = wintab->size;
 1190                 b = wintab->base;
 1191                 e = b + s - 1;
 1192                 if (s > (0xFFFFFFFF - b + 1)) {
 1193                         /* XXX this boundary check should account for 64bit and
 1194                          * remapping.. */
 1195                         printf("IDMA window#%d: no space for size 0x%08x at "
 1196                             "0x%08x\n", i, s, b);
 1197                         rv = 0;
 1198                         continue;
 1199                 }
 1200 
 1201                 j = decode_win_overlap(i, idma_wins_no, &idma_wins[0]);
 1202                 if (j >= 0) {
 1203                         printf("IDMA window#%d: (0x%08x - 0x%08x) overlaps "
 1204                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
 1205                             idma_wins[j].base,
 1206                             idma_wins[j].base + idma_wins[j].size - 1);
 1207                         rv = 0;
 1208                 }
 1209         }
 1210 
 1211         return (rv);
 1212 }
 1213 
 1214 void
 1215 decode_win_idma_dump(u_long base)
 1216 {
 1217         int i;
 1218 
 1219         if (pm_is_disabled(CPU_PM_CTRL_IDMA))
 1220                 return;
 1221 
 1222         for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
 1223                 printf("IDMA window#%d: b 0x%08x, s 0x%08x", i,
 1224                     win_idma_br_read(base, i), win_idma_sz_read(base, i));
 1225                 
 1226                 if (win_idma_can_remap(i))
 1227                         printf(", ha 0x%08x", win_idma_har_read(base, i));
 1228 
 1229                 printf("\n");
 1230         }
 1231         for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
 1232                 printf("IDMA channel#%d: ap 0x%08x\n", i,
 1233                     win_idma_cap_read(base, i));
 1234         printf("IDMA windows: bare 0x%08x\n", win_idma_bare_read(base));
 1235 }
 1236 #else
 1237 
 1238 /* Provide dummy functions to satisfy the build for SoCs not equipped with IDMA */
 1239 int
 1240 decode_win_idma_valid(void)
 1241 {
 1242 
 1243         return (1);
 1244 }
 1245 
 1246 void
 1247 decode_win_idma_setup(u_long base)
 1248 {
 1249 }
 1250 
 1251 void
 1252 decode_win_idma_dump(u_long base)
 1253 {
 1254 }
 1255 #endif
 1256 
 1257 /**************************************************************************
 1258  * XOR windows routines
 1259  **************************************************************************/
 1260 #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
 1261 static int
 1262 xor_ctrl_read(u_long base, int i, int c, int e)
 1263 {
 1264         uint32_t v;
 1265         v = win_xor_ctrl_read(base, c, e);
 1266         v &= (1 << i);
 1267 
 1268         return (v >> i);
 1269 }
 1270 
 1271 static void
 1272 xor_ctrl_write(u_long base, int i, int c, int e, int val)
 1273 {
 1274         uint32_t v;
 1275 
 1276         v = win_xor_ctrl_read(base, c, e);
 1277         v &= ~(1 << i);
 1278         v |= (val << i);
 1279         win_xor_ctrl_write(base, c, e, v);
 1280 }
 1281 
 1282 /*
 1283  * Set channel protection 'val' for window 'w' on channel 'c'
 1284  */
 1285 
 1286 static void
 1287 xor_chan_write(u_long base, int c, int e, int w, int val)
 1288 {
 1289         uint32_t v;
 1290 
 1291         v = win_xor_ctrl_read(base, c, e);
 1292         v &= ~(0x3 << (w * 2 + 16));
 1293         v |= (val << (w * 2 + 16));
 1294         win_xor_ctrl_write(base, c, e, v);
 1295 }
 1296 
 1297 /*
 1298  * Set protection 'val' on all channels for window 'w' on engine 'e'
 1299  */
 1300 static void
 1301 xor_set_prot(u_long base, int w, int e, int val)
 1302 {
 1303         int c;
 1304 
 1305         for (c = 0; c < MV_XOR_CHAN_MAX; c++)
 1306                 xor_chan_write(base, c, e, w, val);
 1307 }
 1308 
 1309 static int
 1310 win_xor_can_remap(int i)
 1311 {
 1312 
 1313         /* XOR decode windows 0-3 have remap capability */
 1314         if (i < 4)
 1315                 return (1);
 1316 
 1317         return (0);
 1318 }
 1319 
 1320 static int
 1321 xor_max_eng(void)
 1322 {
 1323         uint32_t dev, rev;
 1324 
 1325         soc_id(&dev, &rev);
 1326         if (dev == MV_DEV_88F6281)
 1327                 return (2);
 1328         else if ((dev == MV_DEV_MV78100) || (dev == MV_DEV_MV78100_Z0))
 1329                 return (1);
 1330         else
 1331                 return (0);
 1332 }
 1333 
 1334 static void
 1335 xor_active_dram(u_long base, int c, int e, int *window)
 1336 {
 1337         uint32_t br, sz;
 1338         int i, m, w;
 1339 
 1340         /*
 1341          * Set up access to all active DRAM banks
 1342          */
 1343         m = xor_max_eng();
 1344         for (i = 0; i < m; i++)
 1345                 if (ddr_is_active(i)) {
 1346                         br = ddr_base(i) | (ddr_attr(i) << 8) |
 1347                             ddr_target(i);
 1348                         sz = ((ddr_size(i) - 1) & 0xffff0000);
 1349 
 1350                         /* Place DDR entries in non-remapped windows */
 1351                         for (w = 0; w < MV_WIN_XOR_MAX; w++)
 1352                                 if (win_xor_can_remap(w) != 1 &&
 1353                                     (xor_ctrl_read(base, w, c, e) == 0) &&
 1354                                     w > *window) {
 1355                                         /* Configure window */
 1356                                         win_xor_br_write(base, w, e, br);
 1357                                         win_xor_sz_write(base, w, e, sz);
 1358 
 1359                                         /* Set protection RW on all channels */
 1360                                         xor_set_prot(base, w, e, 0x3);
 1361 
 1362                                         /* Enable window */
 1363                                         xor_ctrl_write(base, w, c, e, 1);
 1364                                         (*window)++;
 1365                                         break;
 1366                                 }
 1367                 }
 1368 }
 1369 
 1370 void
 1371 decode_win_xor_setup(u_long base)
 1372 {
 1373         uint32_t br, sz;
 1374         int i, j, z, e = 1, m, window;
 1375 
 1376         if (pm_is_disabled(CPU_PM_CTRL_XOR))
 1377                 return;
 1378 
 1379         /*
 1380          * Disable and clear all XOR windows, revoke protection for all
 1381          * channels
 1382          */
 1383         m = xor_max_eng();
 1384         for (j = 0; j < m; j++, e--) {
 1385 
 1386                 /* Number of non-remaped windows */
 1387                 window = MV_XOR_NON_REMAP - 1;
 1388 
 1389                 for (i = 0; i < MV_WIN_XOR_MAX; i++) {
 1390                         win_xor_br_write(base, i, e, 0);
 1391                         win_xor_sz_write(base, i, e, 0);
 1392                 }
 1393 
 1394                 if (win_xor_can_remap(i) == 1)
 1395                         win_xor_har_write(base, i, e, 0);
 1396 
 1397                 for (i = 0; i < MV_XOR_CHAN_MAX; i++) {
 1398                         win_xor_ctrl_write(base, i, e, 0);
 1399                         xor_active_dram(base, i, e, &window);
 1400                 }
 1401 
 1402                 /*
 1403                  * Remaining targets -- from a statically defined table
 1404                  */
 1405                 for (i = 0; i < xor_wins_no; i++)
 1406                         if (xor_wins[i].target > 0) {
 1407                                 br = (xor_wins[i].base & 0xffff0000) |
 1408                                     (xor_wins[i].attr << 8) |
 1409                                     xor_wins[i].target;
 1410                                 sz = ((xor_wins[i].size - 1) & 0xffff0000);
 1411 
 1412                                 /* Set the first free XOR window */
 1413                                 for (z = 0; z < MV_WIN_XOR_MAX; z++) {
 1414                                         if (xor_ctrl_read(base, z, 0, e) &&
 1415                                             xor_ctrl_read(base, z, 1, e))
 1416                                                 continue;
 1417 
 1418                                         /* Configure window */
 1419                                         win_xor_br_write(base, z, e, br);
 1420                                         win_xor_sz_write(base, z, e, sz);
 1421                                         if (win_xor_can_remap(z) &&
 1422                                             xor_wins[z].remap >= 0)
 1423                                                 win_xor_har_write(base, z, e,
 1424                                                     xor_wins[z].remap);
 1425 
 1426                                         /* Set protection RW on all channels */
 1427                                         xor_set_prot(base, z, e, 0x3);
 1428 
 1429                                         /* Enable window */
 1430                                         xor_ctrl_write(base, z, 0, e, 1);
 1431                                         xor_ctrl_write(base, z, 1, e, 1);
 1432                                         break;
 1433                                 }
 1434                         }
 1435         }
 1436 }
 1437 
 1438 int
 1439 decode_win_xor_valid(void)
 1440 {
 1441         const struct decode_win *wintab;
 1442         int c, i, j, rv;
 1443         uint32_t b, e, s;
 1444 
 1445         if (xor_wins_no > MV_WIN_XOR_MAX) {
 1446                 printf("XOR windows: too many entries: %d\n", xor_wins_no);
 1447                 return (0);
 1448         }
 1449         for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
 1450                 if (ddr_is_active(i))
 1451                         c++;
 1452 
 1453         if (xor_wins_no > (MV_WIN_XOR_MAX - c)) {
 1454                 printf("XOR windows: too many entries: %d, available: %d\n",
 1455                     xor_wins_no, MV_WIN_IDMA_MAX - c);
 1456                 return (0);
 1457         }
 1458 
 1459         wintab = xor_wins;
 1460         rv = 1;
 1461         for (i = 0; i < xor_wins_no; i++, wintab++) {
 1462 
 1463                 if (wintab->target == 0) {
 1464                         printf("XOR window#%d: DDR target window is not "
 1465                             "supposed to be reprogrammed!\n", i);
 1466                         rv = 0;
 1467                 }
 1468 
 1469                 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
 1470                         printf("XOR window#%d: not capable of remapping, but "
 1471                             "val 0x%08x defined\n", i, wintab->remap);
 1472                         rv = 0;
 1473                 }
 1474 
 1475                 s = wintab->size;
 1476                 b = wintab->base;
 1477                 e = b + s - 1;
 1478                 if (s > (0xFFFFFFFF - b + 1)) {
 1479                         /*
 1480                          * XXX this boundary check should account for 64bit
 1481                          * and remapping..
 1482                          */
 1483                         printf("XOR window#%d: no space for size 0x%08x at "
 1484                             "0x%08x\n", i, s, b);
 1485                         rv = 0;
 1486                         continue;
 1487                 }
 1488 
 1489                 j = decode_win_overlap(i, xor_wins_no, &xor_wins[0]);
 1490                 if (j >= 0) {
 1491                         printf("XOR window#%d: (0x%08x - 0x%08x) overlaps "
 1492                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
 1493                             xor_wins[j].base,
 1494                             xor_wins[j].base + xor_wins[j].size - 1);
 1495                         rv = 0;
 1496                 }
 1497         }
 1498 
 1499         return (rv);
 1500 }
 1501 
 1502 void
 1503 decode_win_xor_dump(u_long base)
 1504 {
 1505         int i, j;
 1506         int e = 1;
 1507 
 1508         if (pm_is_disabled(CPU_PM_CTRL_XOR))
 1509                 return;
 1510 
 1511         for (j = 0; j < xor_max_eng(); j++, e--) {
 1512                 for (i = 0; i < MV_WIN_XOR_MAX; i++) {
 1513                         printf("XOR window#%d: b 0x%08x, s 0x%08x", i,
 1514                             win_xor_br_read(base, i, e), win_xor_sz_read(base, i, e));
 1515 
 1516                         if (win_xor_can_remap(i))
 1517                                 printf(", ha 0x%08x", win_xor_har_read(base, i, e));
 1518 
 1519                         printf("\n");
 1520                 }
 1521                 for (i = 0; i < MV_XOR_CHAN_MAX; i++)
 1522                         printf("XOR control#%d: 0x%08x\n", i,
 1523                             win_xor_ctrl_read(base, i, e));
 1524         }
 1525 }
 1526 
 1527 #else
 1528 /* Provide dummy functions to satisfy the build for SoCs not equipped with XOR */
 1529 static int
 1530 decode_win_xor_valid(void)
 1531 {
 1532 
 1533         return (1);
 1534 }
 1535 
 1536 static void
 1537 decode_win_xor_setup(u_long base)
 1538 {
 1539 }
 1540 
 1541 static void
 1542 decode_win_xor_dump(u_long base)
 1543 {
 1544 }
 1545 #endif
 1546 
 1547 /**************************************************************************
 1548  * CESA TDMA windows routines
 1549  **************************************************************************/
 1550 #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
 1551 /*
 1552  * Dump CESA TDMA decode windows.
 1553  */
 1554 static void
 1555 decode_win_cesa_dump(u_long base)
 1556 {
 1557         int i;
 1558 
 1559         if (pm_is_disabled(CPU_PM_CTRL_CRYPTO))
 1560                 return;
 1561 
 1562         for (i = 0; i < MV_WIN_CESA_MAX; i++)
 1563                 printf("CESA window#%d: c 0x%08x, b 0x%08x\n", i,
 1564                     win_cesa_cr_read(base, i), win_cesa_br_read(base, i));
 1565 }
 1566 
 1567 
 1568 /*
 1569  * Set CESA TDMA decode windows.
 1570  */
 1571 static void
 1572 decode_win_cesa_setup(u_long base)
 1573 {
 1574         uint32_t br, cr;
 1575         int i, j;
 1576 
 1577         if (pm_is_disabled(CPU_PM_CTRL_CRYPTO))
 1578                 return;
 1579 
 1580         /* Disable and clear all CESA windows */
 1581         for (i = 0; i < MV_WIN_CESA_MAX; i++) {
 1582                 win_cesa_cr_write(base, i, 0);
 1583                 win_cesa_br_write(base, i, 0);
 1584         }
 1585 
 1586         /* Only access to active DRAM banks is required. */
 1587         for (i = 0; i < MV_WIN_DDR_MAX; i++)
 1588                 if (ddr_is_active(i)) {
 1589                         br = ddr_base(i);
 1590                         cr = (((ddr_size(i) - 1) & 0xffff0000) |
 1591                            (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1);
 1592 
 1593                         /* Set the first available CESA window */
 1594                         for (j = 0; j < MV_WIN_CESA_MAX; j++) {
 1595                                 if (win_cesa_cr_read(base, j) & 0x1)
 1596                                         continue;
 1597 
 1598                                 win_cesa_br_write(base, j, br);
 1599                                 win_cesa_cr_write(base, j, cr);
 1600                                 break;
 1601                         }
 1602                 }
 1603 }
 1604 
 1605 /*
 1606  * Check CESA TDMA decode windows.
 1607  */
 1608 static int
 1609 decode_win_cesa_valid(void)
 1610 {
 1611 
 1612         return (decode_win_can_cover_ddr(MV_WIN_CESA_MAX));
 1613 }
 1614 #else
 1615 
 1616 /*
 1617  * Provide dummy functions to satisfy the build for SoCs not equipped with
 1618  * CESA
 1619  */
 1620 
 1621 static int
 1622 decode_win_cesa_valid(void)
 1623 {
 1624 
 1625         return (1);
 1626 }
 1627 
 1628 static void
 1629 decode_win_cesa_setup(u_long base)
 1630 {
 1631 }
 1632 
 1633 static void
 1634 decode_win_cesa_dump(u_long base)
 1635 {
 1636 }
 1637 #endif
 1638 
 1639 /**************************************************************************
 1640  * SATA windows routines
 1641  **************************************************************************/
 1642 static void
 1643 decode_win_sata_setup(u_long base)
 1644 {
 1645         uint32_t cr, br;
 1646         int i, j;
 1647 
 1648         if (pm_is_disabled(CPU_PM_CTRL_SATA))
 1649                 return;
 1650 
 1651         for (i = 0; i < MV_WIN_SATA_MAX; i++) {
 1652                 win_sata_cr_write(base, i, 0);
 1653                 win_sata_br_write(base, i, 0);
 1654         }
 1655 
 1656         for (i = 0; i < MV_WIN_DDR_MAX; i++)
 1657                 if (ddr_is_active(i)) {
 1658                         cr = ((ddr_size(i) - 1) & 0xffff0000) |
 1659                             (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
 1660                         br = ddr_base(i);
 1661 
 1662                         /* Use the first available SATA window */
 1663                         for (j = 0; j < MV_WIN_SATA_MAX; j++) {
 1664                                 if ((win_sata_cr_read(base, j) & 1) != 0)
 1665                                         continue;
 1666 
 1667                                 win_sata_br_write(base, j, br);
 1668                                 win_sata_cr_write(base, j, cr);
 1669                                 break;
 1670                         }
 1671                 }
 1672 }
 1673 
 1674 static int
 1675 decode_win_sata_valid(void)
 1676 {
 1677         uint32_t dev, rev;
 1678 
 1679         soc_id(&dev, &rev);
 1680         if (dev == MV_DEV_88F5281)
 1681                 return (1);
 1682 
 1683         return (decode_win_can_cover_ddr(MV_WIN_SATA_MAX));
 1684 }
 1685 
 1686 /**************************************************************************
 1687  * FDT parsing routines.
 1688  **************************************************************************/
 1689 
 1690 static int
 1691 fdt_get_ranges(const char *nodename, void *buf, int size, int *tuples,
 1692     int *tuplesize)
 1693 {
 1694         phandle_t node;
 1695         pcell_t addr_cells, par_addr_cells, size_cells;
 1696         int len, tuple_size, tuples_count;
 1697 
 1698         node = OF_finddevice(nodename);
 1699         if (node <= 0)
 1700                 return (EINVAL);
 1701 
 1702         if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
 1703                 return (ENXIO);
 1704 
 1705         par_addr_cells = fdt_parent_addr_cells(node);
 1706         if (par_addr_cells > 2)
 1707                 return (ERANGE);
 1708 
 1709         tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells +
 1710             size_cells);
 1711 
 1712         /* Note the OF_getprop_alloc() cannot be used at this early stage. */
 1713         len = OF_getprop(node, "ranges", buf, size);
 1714 
 1715         /*
 1716          * XXX this does not handle the empty 'ranges;' case, which is
 1717          * legitimate and should be allowed.
 1718          */
 1719         tuples_count = len / tuple_size;
 1720         if (tuples_count <= 0)
 1721                 return (ERANGE);
 1722 
 1723         if (fdt_ranges_verify(buf, tuples_count, par_addr_cells,
 1724             addr_cells, size_cells) != 0)
 1725                 return (ERANGE);
 1726 
 1727         *tuples = tuples_count;
 1728         *tuplesize = tuple_size;
 1729         return (0);
 1730 }
 1731 
 1732 static int
 1733 win_cpu_from_dt(void)
 1734 {
 1735         pcell_t ranges[48];
 1736         u_long sram_base, sram_size;
 1737         phandle_t node;
 1738         int i, entry_size, err, t, tuple_size, tuples;
 1739 
 1740         /* Retrieve 'ranges' property of '/localbus' node. */
 1741         if ((err = fdt_get_ranges("/localbus", ranges, sizeof(ranges),
 1742             &tuples, &tuple_size)) != 0)
 1743                 return (err);
 1744 
 1745         /*
 1746          * Fill CPU decode windows table.
 1747          */
 1748         bzero((void *)&cpu_win_tbl, sizeof(cpu_win_tbl));
 1749 
 1750         entry_size = tuple_size / sizeof(pcell_t);
 1751         cpu_wins_no = tuples;
 1752 
 1753         for (i = 0, t = 0; t < tuples; i += entry_size, t++) {
 1754                 cpu_win_tbl[t].target = 1;
 1755                 cpu_win_tbl[t].attr = fdt32_to_cpu(ranges[i + 1]);
 1756                 cpu_win_tbl[t].base = fdt32_to_cpu(ranges[i + 2]);
 1757                 cpu_win_tbl[t].size = fdt32_to_cpu(ranges[i + 3]);
 1758                 cpu_win_tbl[t].remap = -1;
 1759                 debugf("target = 0x%0x attr = 0x%0x base = 0x%0x "
 1760                     "size = 0x%0x remap = %d\n", cpu_win_tbl[t].target,
 1761                     cpu_win_tbl[t].attr, cpu_win_tbl[t].base,
 1762                     cpu_win_tbl[t].size, cpu_win_tbl[t].remap);
 1763         }
 1764 
 1765         /*
 1766          * Retrieve CESA SRAM data.
 1767          */
 1768         if ((node = OF_finddevice("sram")) != 0)
 1769                 if (fdt_is_compatible(node, "mrvl,cesa-sram"))
 1770                         goto moveon;
 1771 
 1772         if ((node = OF_finddevice("/")) == 0)
 1773                 return (ENXIO);
 1774 
 1775         if ((node = fdt_find_compatible(node, "mrvl,cesa-sram", 0)) == 0)
 1776                 /* SRAM block is not always present. */
 1777                 return (0);
 1778 moveon:
 1779         sram_base = sram_size = 0;
 1780         if (fdt_regsize(node, &sram_base, &sram_size) != 0)
 1781                 return (EINVAL);
 1782 
 1783         cpu_win_tbl[++t].target = MV_WIN_CESA_TARGET;
 1784         cpu_win_tbl[t].attr = MV_WIN_CESA_ATTR;
 1785         cpu_win_tbl[t].base = sram_base;
 1786         cpu_win_tbl[t].size = sram_size;
 1787         cpu_win_tbl[t].remap = -1;
 1788         debugf("sram: base = 0x%0lx size = 0x%0lx\n", sram_base, sram_size);
 1789 
 1790         return (0);
 1791 }
 1792 
 1793 static int
 1794 fdt_win_setup(void)
 1795 {
 1796         phandle_t node, child;
 1797         struct soc_node_spec *soc_node;
 1798         u_long size, base;
 1799         int err, i;
 1800 
 1801         node = OF_finddevice("/");
 1802         if (node == 0)
 1803                 panic("fdt_win_setup: no root node");
 1804 
 1805         node = fdt_find_compatible(node, "simple-bus", 1);
 1806         if (node == 0)
 1807                 return (ENXIO);
 1808 
 1809         /*
 1810          * Traverse through all children of simple-bus node, and retrieve
 1811          * decode windows data for devices (if applicable).
 1812          */
 1813         for (child = OF_child(node); child != 0; child = OF_peer(child))
 1814                 for (i = 0; soc_nodes[i].compat != NULL; i++) {
 1815 
 1816                         soc_node = &soc_nodes[i];
 1817 
 1818                         if (!fdt_is_compatible(child, soc_node->compat))
 1819                                 continue;
 1820 
 1821                         err = fdt_regsize(child, &base, &size);
 1822                         if (err != 0)
 1823                                 return (err);
 1824 
 1825                         base += fdt_immr_va;
 1826                         if (soc_node->decode_handler != NULL)
 1827                                 soc_node->decode_handler(base);
 1828                         else
 1829                                 return (ENXIO);
 1830 
 1831                         if (MV_DUMP_WIN && (soc_node->dump_handler != NULL))
 1832                                 soc_node->dump_handler(base);
 1833                 }
 1834 
 1835         return (0);
 1836 }
 1837 
 1838 static void
 1839 fdt_fixup_busfreq(phandle_t root)
 1840 {
 1841         phandle_t sb;
 1842         pcell_t freq;
 1843 
 1844         /*
 1845          * This fixup sets the simple-bus bus-frequency property.
 1846          */
 1847 
 1848         if ((sb = fdt_find_compatible(root, "simple-bus", 1)) == 0)
 1849                 return;
 1850 
 1851         freq = cpu_to_fdt32(get_tclk());
 1852         OF_setprop(sb, "bus-frequency", (void *)&freq, sizeof(freq));
 1853 }
 1854 
 1855 struct fdt_fixup_entry fdt_fixup_table[] = {
 1856         { "mrvl,DB-88F6281", &fdt_fixup_busfreq },
 1857         { NULL, NULL }
 1858 };
 1859 
 1860 static int
 1861 fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
 1862     int *pol)
 1863 {
 1864 
 1865         if (!fdt_is_compatible(node, "mrvl,pic"))
 1866                 return (ENXIO);
 1867 
 1868         *interrupt = fdt32_to_cpu(intr[0]);
 1869         *trig = INTR_TRIGGER_CONFORM;
 1870         *pol = INTR_POLARITY_CONFORM;
 1871 
 1872         return (0);
 1873 }
 1874 
 1875 fdt_pic_decode_t fdt_pic_table[] = {
 1876         &fdt_pic_decode_ic,
 1877         NULL
 1878 };

Cache object: 8fba6d04443d2478ecc3b5fc0ddf43f0


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