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

Cache object: 0e0a55257450bf46aba58779c63d7d75


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