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

Cache object: f46b79da2e91560210bc9d4cd5ca9d51


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