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  * SPDX-License-Identifier: BSD-3-Clause
    3  *
    4  * Copyright (C) 2008-2011 MARVELL INTERNATIONAL LTD.
    5  * All rights reserved.
    6  *
    7  * Developed by Semihalf.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 3. Neither the name of MARVELL nor the names of contributors
   18  *    may be used to endorse or promote products derived from this software
   19  *    without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
   25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31  * SUCH DAMAGE.
   32  */
   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 #include <dev/ofw/ofw_bus_subr.h>
   48 
   49 #include <machine/bus.h>
   50 #include <machine/fdt.h>
   51 #include <machine/vmparam.h>
   52 #include <machine/intr.h>
   53 
   54 #include <arm/mv/mvreg.h>
   55 #include <arm/mv/mvvar.h>
   56 #include <arm/mv/mvwin.h>
   57 
   58 
   59 MALLOC_DEFINE(M_IDMA, "idma", "idma dma test memory");
   60 
   61 #define IDMA_DEBUG
   62 #undef IDMA_DEBUG
   63 
   64 #define MAX_CPU_WIN     5
   65 
   66 #ifdef DEBUG
   67 #define debugf(fmt, args...) do { printf("%s(): ", __func__);   \
   68     printf(fmt,##args); } while (0)
   69 #else
   70 #define debugf(fmt, args...)
   71 #endif
   72 
   73 #ifdef DEBUG
   74 #define MV_DUMP_WIN     1
   75 #else
   76 #define MV_DUMP_WIN     0
   77 #endif
   78 
   79 struct soc_node_spec;
   80 
   81 static enum soc_family soc_family;
   82 
   83 static int mv_win_cesa_attr(int wng_sel);
   84 static int mv_win_cesa_attr_armv5(int eng_sel);
   85 static int mv_win_cesa_attr_armada38x(int eng_sel);
   86 static int mv_win_cesa_attr_armadaxp(int eng_sel);
   87 
   88 uint32_t read_cpu_ctrl_armv5(uint32_t reg);
   89 uint32_t read_cpu_ctrl_armv7(uint32_t reg);
   90 
   91 void write_cpu_ctrl_armv5(uint32_t reg, uint32_t val);
   92 void write_cpu_ctrl_armv7(uint32_t reg, uint32_t val);
   93 
   94 static int win_eth_can_remap(int i);
   95 
   96 static int decode_win_cesa_valid(void);
   97 static int decode_win_cpu_valid(void);
   98 static int decode_win_usb_valid(void);
   99 static int decode_win_usb3_valid(void);
  100 static int decode_win_eth_valid(void);
  101 static int decode_win_pcie_valid(void);
  102 static int decode_win_sata_valid(void);
  103 static int decode_win_sdhci_valid(void);
  104 
  105 static int decode_win_idma_valid(void);
  106 static int decode_win_xor_valid(void);
  107 
  108 static void decode_win_cpu_setup(void);
  109 static int decode_win_sdram_fixup(void);
  110 static void decode_win_cesa_setup(u_long);
  111 static void decode_win_a38x_cesa_setup(u_long);
  112 static void decode_win_usb_setup(u_long);
  113 static void decode_win_usb3_setup(u_long);
  114 static void decode_win_eth_setup(u_long);
  115 static void decode_win_neta_setup(u_long);
  116 static void decode_win_sata_setup(u_long);
  117 static void decode_win_ahci_setup(u_long);
  118 static void decode_win_sdhci_setup(u_long);
  119 
  120 static void decode_win_idma_setup(u_long);
  121 static void decode_win_xor_setup(u_long);
  122 
  123 static void decode_win_cesa_dump(u_long);
  124 static void decode_win_a38x_cesa_dump(u_long);
  125 static void decode_win_usb_dump(u_long);
  126 static void decode_win_usb3_dump(u_long);
  127 static void decode_win_eth_dump(u_long base);
  128 static void decode_win_neta_dump(u_long base);
  129 static void decode_win_idma_dump(u_long base);
  130 static void decode_win_xor_dump(u_long base);
  131 static void decode_win_ahci_dump(u_long base);
  132 static void decode_win_sdhci_dump(u_long);
  133 static void decode_win_pcie_dump(u_long);
  134 
  135 static uint32_t win_cpu_cr_read(int);
  136 static uint32_t win_cpu_armv5_cr_read(int);
  137 static uint32_t win_cpu_armv7_cr_read(int);
  138 static uint32_t win_cpu_br_read(int);
  139 static uint32_t win_cpu_armv5_br_read(int);
  140 static uint32_t win_cpu_armv7_br_read(int);
  141 static uint32_t win_cpu_remap_l_read(int);
  142 static uint32_t win_cpu_armv5_remap_l_read(int);
  143 static uint32_t win_cpu_armv7_remap_l_read(int);
  144 static uint32_t win_cpu_remap_h_read(int);
  145 static uint32_t win_cpu_armv5_remap_h_read(int);
  146 static uint32_t win_cpu_armv7_remap_h_read(int);
  147 
  148 static void win_cpu_cr_write(int, uint32_t);
  149 static void win_cpu_armv5_cr_write(int, uint32_t);
  150 static void win_cpu_armv7_cr_write(int, uint32_t);
  151 static void win_cpu_br_write(int, uint32_t);
  152 static void win_cpu_armv5_br_write(int, uint32_t);
  153 static void win_cpu_armv7_br_write(int, uint32_t);
  154 static void win_cpu_remap_l_write(int, uint32_t);
  155 static void win_cpu_armv5_remap_l_write(int, uint32_t);
  156 static void win_cpu_armv7_remap_l_write(int, uint32_t);
  157 static void win_cpu_remap_h_write(int, uint32_t);
  158 static void win_cpu_armv5_remap_h_write(int, uint32_t);
  159 static void win_cpu_armv7_remap_h_write(int, uint32_t);
  160 
  161 static uint32_t ddr_br_read(int);
  162 static uint32_t ddr_sz_read(int);
  163 static uint32_t ddr_armv5_br_read(int);
  164 static uint32_t ddr_armv5_sz_read(int);
  165 static uint32_t ddr_armv7_br_read(int);
  166 static uint32_t ddr_armv7_sz_read(int);
  167 static void ddr_br_write(int, uint32_t);
  168 static void ddr_sz_write(int, uint32_t);
  169 static void ddr_armv5_br_write(int, uint32_t);
  170 static void ddr_armv5_sz_write(int, uint32_t);
  171 static void ddr_armv7_br_write(int, uint32_t);
  172 static void ddr_armv7_sz_write(int, uint32_t);
  173 
  174 static int fdt_get_ranges(const char *, void *, int, int *, int *);
  175 int gic_decode_fdt(phandle_t iparent, pcell_t *intr, int *interrupt,
  176     int *trig, int *pol);
  177 
  178 static int win_cpu_from_dt(void);
  179 static int fdt_win_setup(void);
  180 
  181 static int fdt_win_process_child(phandle_t, struct soc_node_spec *, const char*);
  182 
  183 static void soc_identify(uint32_t, uint32_t);
  184 
  185 static uint32_t dev_mask = 0;
  186 static int cpu_wins_no = 0;
  187 static int eth_port = 0;
  188 static int usb_port = 0;
  189 static boolean_t platform_io_coherent = false;
  190 
  191 static struct decode_win cpu_win_tbl[MAX_CPU_WIN];
  192 
  193 const struct decode_win *cpu_wins = cpu_win_tbl;
  194 
  195 typedef void (*decode_win_setup_t)(u_long);
  196 typedef void (*dump_win_t)(u_long);
  197 typedef int (*valid_t)(void);
  198 
  199 /*
  200  * The power status of device feature is only supported on
  201  * Kirkwood and Discovery SoCs.
  202  */
  203 #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
  204 #define SOC_MV_POWER_STAT_SUPPORTED             1
  205 #else
  206 #define SOC_MV_POWER_STAT_SUPPORTED             0
  207 #endif
  208 
  209 struct soc_node_spec {
  210         const char              *compat;
  211         decode_win_setup_t      decode_handler;
  212         dump_win_t              dump_handler;
  213         valid_t                 valid_handler;
  214 };
  215 
  216 static struct soc_node_spec soc_nodes[] = {
  217         { "mrvl,ge", &decode_win_eth_setup, &decode_win_eth_dump, &decode_win_eth_valid},
  218         { "marvell,armada-370-neta", &decode_win_neta_setup,
  219             &decode_win_neta_dump, NULL },
  220         { "mrvl,usb-ehci", &decode_win_usb_setup, &decode_win_usb_dump, &decode_win_usb_valid},
  221         { "marvell,orion-ehci", &decode_win_usb_setup, &decode_win_usb_dump, &decode_win_usb_valid },
  222         { "marvell,armada-380-xhci", &decode_win_usb3_setup,
  223             &decode_win_usb3_dump, &decode_win_usb3_valid },
  224         { "marvell,armada-380-ahci", &decode_win_ahci_setup,
  225             &decode_win_ahci_dump, NULL },
  226         { "marvell,armada-380-sdhci", &decode_win_sdhci_setup,
  227             &decode_win_sdhci_dump, &decode_win_sdhci_valid},
  228         { "mrvl,sata", &decode_win_sata_setup, NULL, &decode_win_sata_valid},
  229         { "mrvl,xor", &decode_win_xor_setup, &decode_win_xor_dump, &decode_win_xor_valid},
  230         { "mrvl,idma", &decode_win_idma_setup, &decode_win_idma_dump, &decode_win_idma_valid},
  231         { "mrvl,cesa", &decode_win_cesa_setup, &decode_win_cesa_dump, &decode_win_cesa_valid},
  232         { "mrvl,pcie", &decode_win_pcie_setup, &decode_win_pcie_dump, &decode_win_pcie_valid},
  233         { "marvell,armada-38x-crypto", &decode_win_a38x_cesa_setup,
  234             &decode_win_a38x_cesa_dump, &decode_win_cesa_valid},
  235         { NULL, NULL, NULL, NULL },
  236 };
  237 
  238 #define SOC_NODE_PCIE_ENTRY_IDX         11
  239 
  240 typedef uint32_t(*read_cpu_ctrl_t)(uint32_t);
  241 typedef void(*write_cpu_ctrl_t)(uint32_t, uint32_t);
  242 typedef uint32_t (*win_read_t)(int);
  243 typedef void (*win_write_t)(int, uint32_t);
  244 typedef int (*win_cesa_attr_t)(int);
  245 typedef uint32_t (*get_t)(void);
  246 
  247 struct decode_win_spec {
  248         read_cpu_ctrl_t  read_cpu_ctrl;
  249         write_cpu_ctrl_t write_cpu_ctrl;
  250         win_read_t      cr_read;
  251         win_read_t      br_read;
  252         win_read_t      remap_l_read;
  253         win_read_t      remap_h_read;
  254         win_write_t     cr_write;
  255         win_write_t     br_write;
  256         win_write_t     remap_l_write;
  257         win_write_t     remap_h_write;
  258         uint32_t        mv_win_cpu_max;
  259         win_cesa_attr_t win_cesa_attr;
  260         int             win_cesa_target;
  261         win_read_t      ddr_br_read;
  262         win_read_t      ddr_sz_read;
  263         win_write_t     ddr_br_write;
  264         win_write_t     ddr_sz_write;
  265 #if __ARM_ARCH >= 6
  266         get_t           get_tclk;
  267         get_t           get_cpu_freq;
  268 #endif
  269 };
  270 
  271 struct decode_win_spec *soc_decode_win_spec;
  272 
  273 static struct decode_win_spec decode_win_specs[] =
  274 {
  275         {
  276                 &read_cpu_ctrl_armv7,
  277                 &write_cpu_ctrl_armv7,
  278                 &win_cpu_armv7_cr_read,
  279                 &win_cpu_armv7_br_read,
  280                 &win_cpu_armv7_remap_l_read,
  281                 &win_cpu_armv7_remap_h_read,
  282                 &win_cpu_armv7_cr_write,
  283                 &win_cpu_armv7_br_write,
  284                 &win_cpu_armv7_remap_l_write,
  285                 &win_cpu_armv7_remap_h_write,
  286                 MV_WIN_CPU_MAX_ARMV7,
  287                 &mv_win_cesa_attr_armada38x,
  288                 MV_WIN_CESA_TARGET_ARMADA38X,
  289                 &ddr_armv7_br_read,
  290                 &ddr_armv7_sz_read,
  291                 &ddr_armv7_br_write,
  292                 &ddr_armv7_sz_write,
  293 #if __ARM_ARCH >= 6
  294                 &get_tclk_armada38x,
  295                 &get_cpu_freq_armada38x,
  296 #endif
  297         },
  298         {
  299                 &read_cpu_ctrl_armv7,
  300                 &write_cpu_ctrl_armv7,
  301                 &win_cpu_armv7_cr_read,
  302                 &win_cpu_armv7_br_read,
  303                 &win_cpu_armv7_remap_l_read,
  304                 &win_cpu_armv7_remap_h_read,
  305                 &win_cpu_armv7_cr_write,
  306                 &win_cpu_armv7_br_write,
  307                 &win_cpu_armv7_remap_l_write,
  308                 &win_cpu_armv7_remap_h_write,
  309                 MV_WIN_CPU_MAX_ARMV7,
  310                 &mv_win_cesa_attr_armadaxp,
  311                 MV_WIN_CESA_TARGET_ARMADAXP,
  312                 &ddr_armv7_br_read,
  313                 &ddr_armv7_sz_read,
  314                 &ddr_armv7_br_write,
  315                 &ddr_armv7_sz_write,
  316 #if __ARM_ARCH >= 6
  317                 &get_tclk_armadaxp,
  318                 &get_cpu_freq_armadaxp,
  319 #endif
  320         },
  321         {
  322                 &read_cpu_ctrl_armv5,
  323                 &write_cpu_ctrl_armv5,
  324                 &win_cpu_armv5_cr_read,
  325                 &win_cpu_armv5_br_read,
  326                 &win_cpu_armv5_remap_l_read,
  327                 &win_cpu_armv5_remap_h_read,
  328                 &win_cpu_armv5_cr_write,
  329                 &win_cpu_armv5_br_write,
  330                 &win_cpu_armv5_remap_l_write,
  331                 &win_cpu_armv5_remap_h_write,
  332                 MV_WIN_CPU_MAX,
  333                 &mv_win_cesa_attr_armv5,
  334                 MV_WIN_CESA_TARGET,
  335                 &ddr_armv5_br_read,
  336                 &ddr_armv5_sz_read,
  337                 &ddr_armv5_br_write,
  338                 &ddr_armv5_sz_write,
  339 #if __ARM_ARCH >= 6
  340                 NULL,
  341                 NULL,
  342 #endif
  343         },
  344 };
  345 
  346 struct fdt_pm_mask_entry {
  347         char            *compat;
  348         uint32_t        mask;
  349 };
  350 
  351 static struct fdt_pm_mask_entry fdt_pm_mask_table[] = {
  352         { "mrvl,ge",            CPU_PM_CTRL_GE(0) },
  353         { "mrvl,ge",            CPU_PM_CTRL_GE(1) },
  354         { "mrvl,usb-ehci",      CPU_PM_CTRL_USB(0) },
  355         { "mrvl,usb-ehci",      CPU_PM_CTRL_USB(1) },
  356         { "mrvl,usb-ehci",      CPU_PM_CTRL_USB(2) },
  357         { "mrvl,xor",           CPU_PM_CTRL_XOR },
  358         { "mrvl,sata",          CPU_PM_CTRL_SATA },
  359 
  360         { NULL, 0 }
  361 };
  362 
  363 static __inline int
  364 pm_is_disabled(uint32_t mask)
  365 {
  366 #if SOC_MV_POWER_STAT_SUPPORTED
  367         return (soc_power_ctrl_get(mask) == mask ? 0 : 1);
  368 #else
  369         return (0);
  370 #endif
  371 }
  372 
  373 /*
  374  * Disable device using power management register.
  375  * 1 - Device Power On
  376  * 0 - Device Power Off
  377  * Mask can be set in loader.
  378  * EXAMPLE:
  379  * loader> set hw.pm-disable-mask=0x2
  380  *
  381  * Common mask:
  382  * |-------------------------------|
  383  * | Device | Kirkwood | Discovery |
  384  * |-------------------------------|
  385  * | USB0   | 0x00008  | 0x020000  |
  386  * |-------------------------------|
  387  * | USB1   |     -    | 0x040000  |
  388  * |-------------------------------|
  389  * | USB2   |     -    | 0x080000  |
  390  * |-------------------------------|
  391  * | GE0    | 0x00001  | 0x000002  |
  392  * |-------------------------------|
  393  * | GE1    |     -    | 0x000004  |
  394  * |-------------------------------|
  395  * | IDMA   |     -    | 0x100000  |
  396  * |-------------------------------|
  397  * | XOR    | 0x10000  | 0x200000  |
  398  * |-------------------------------|
  399  * | CESA   | 0x20000  | 0x400000  |
  400  * |-------------------------------|
  401  * | SATA   | 0x04000  | 0x004000  |
  402  * --------------------------------|
  403  * This feature can be used only on Kirkwood and Discovery
  404  * machines.
  405  */
  406 
  407 static int mv_win_cesa_attr(int eng_sel)
  408 {
  409 
  410         if (soc_decode_win_spec->win_cesa_attr != NULL)
  411                 return (soc_decode_win_spec->win_cesa_attr(eng_sel));
  412 
  413         return (-1);
  414 }
  415 
  416 static int mv_win_cesa_attr_armv5(int eng_sel)
  417 {
  418 
  419         return MV_WIN_CESA_ATTR(eng_sel);
  420 }
  421 
  422 static int mv_win_cesa_attr_armada38x(int eng_sel)
  423 {
  424 
  425         return MV_WIN_CESA_ATTR_ARMADA38X(eng_sel);
  426 }
  427 
  428 static int mv_win_cesa_attr_armadaxp(int eng_sel)
  429 {
  430 
  431         return MV_WIN_CESA_ATTR_ARMADAXP(eng_sel);
  432 }
  433 
  434 enum soc_family
  435 mv_check_soc_family(void)
  436 {
  437         uint32_t dev, rev;
  438 
  439         soc_id(&dev, &rev);
  440         switch (dev) {
  441         case MV_DEV_MV78230:
  442         case MV_DEV_MV78260:
  443         case MV_DEV_MV78460:
  444                 soc_decode_win_spec = &decode_win_specs[MV_SOC_ARMADA_XP];
  445                 soc_family = MV_SOC_ARMADA_XP;
  446                 break;
  447         case MV_DEV_88F6828:
  448         case MV_DEV_88F6820:
  449         case MV_DEV_88F6810:
  450                 soc_decode_win_spec = &decode_win_specs[MV_SOC_ARMADA_38X];
  451                 soc_family = MV_SOC_ARMADA_38X;
  452                 break;
  453         case MV_DEV_88F5181:
  454         case MV_DEV_88F5182:
  455         case MV_DEV_88F5281:
  456         case MV_DEV_88F6281:
  457         case MV_DEV_88RC8180:
  458         case MV_DEV_88RC9480:
  459         case MV_DEV_88RC9580:
  460         case MV_DEV_88F6781:
  461         case MV_DEV_88F6282:
  462         case MV_DEV_MV78100_Z0:
  463         case MV_DEV_MV78100:
  464         case MV_DEV_MV78160:
  465                 soc_decode_win_spec = &decode_win_specs[MV_SOC_ARMV5];
  466                 soc_family = MV_SOC_ARMV5;
  467                 break;
  468         default:
  469                 soc_family = MV_SOC_UNSUPPORTED;
  470                 return (MV_SOC_UNSUPPORTED);
  471         }
  472 
  473         soc_identify(dev, rev);
  474 
  475         return (soc_family);
  476 }
  477 
  478 static __inline void
  479 pm_disable_device(int mask)
  480 {
  481 #ifdef DIAGNOSTIC
  482         uint32_t reg;
  483 
  484         reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
  485         printf("Power Management Register: 0%x\n", reg);
  486 
  487         reg &= ~mask;
  488         soc_power_ctrl_set(reg);
  489         printf("Device %x is disabled\n", mask);
  490 
  491         reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
  492         printf("Power Management Register: 0%x\n", reg);
  493 #endif
  494 }
  495 
  496 int
  497 mv_fdt_is_type(phandle_t node, const char *typestr)
  498 {
  499 #define FDT_TYPE_LEN    64
  500         char type[FDT_TYPE_LEN];
  501 
  502         if (OF_getproplen(node, "device_type") <= 0)
  503                 return (0);
  504 
  505         if (OF_getprop(node, "device_type", type, FDT_TYPE_LEN) < 0)
  506                 return (0);
  507 
  508         if (strncasecmp(type, typestr, FDT_TYPE_LEN) == 0)
  509                 /* This fits. */
  510                 return (1);
  511 
  512         return (0);
  513 #undef FDT_TYPE_LEN
  514 }
  515 
  516 int
  517 mv_fdt_pm(phandle_t node)
  518 {
  519         uint32_t cpu_pm_ctrl;
  520         int i, ena, compat;
  521 
  522         ena = 1;
  523         cpu_pm_ctrl = read_cpu_ctrl(CPU_PM_CTRL);
  524         for (i = 0; fdt_pm_mask_table[i].compat != NULL; i++) {
  525                 if (dev_mask & (1 << i))
  526                         continue;
  527 
  528                 compat = ofw_bus_node_is_compatible(node,
  529                     fdt_pm_mask_table[i].compat);
  530 #if defined(SOC_MV_KIRKWOOD)
  531                 if (compat && (cpu_pm_ctrl & fdt_pm_mask_table[i].mask)) {
  532                         dev_mask |= (1 << i);
  533                         ena = 0;
  534                         break;
  535                 } else if (compat) {
  536                         dev_mask |= (1 << i);
  537                         break;
  538                 }
  539 #else
  540                 if (compat && (~cpu_pm_ctrl & fdt_pm_mask_table[i].mask)) {
  541                         dev_mask |= (1 << i);
  542                         ena = 0;
  543                         break;
  544                 } else if (compat) {
  545                         dev_mask |= (1 << i);
  546                         break;
  547                 }
  548 #endif
  549         }
  550 
  551         return (ena);
  552 }
  553 
  554 uint32_t
  555 read_cpu_ctrl(uint32_t reg)
  556 {
  557 
  558         if (soc_decode_win_spec->read_cpu_ctrl != NULL)
  559                 return (soc_decode_win_spec->read_cpu_ctrl(reg));
  560         return (-1);
  561 }
  562 
  563 uint32_t
  564 read_cpu_ctrl_armv5(uint32_t reg)
  565 {
  566 
  567         return (bus_space_read_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE, reg));
  568 }
  569 
  570 uint32_t
  571 read_cpu_ctrl_armv7(uint32_t reg)
  572 {
  573 
  574         return (bus_space_read_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE_ARMV7, reg));
  575 }
  576 
  577 void
  578 write_cpu_ctrl(uint32_t reg, uint32_t val)
  579 {
  580 
  581         if (soc_decode_win_spec->write_cpu_ctrl != NULL)
  582                 soc_decode_win_spec->write_cpu_ctrl(reg, val);
  583 }
  584 
  585 void
  586 write_cpu_ctrl_armv5(uint32_t reg, uint32_t val)
  587 {
  588 
  589         bus_space_write_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE, reg, val);
  590 }
  591 
  592 void
  593 write_cpu_ctrl_armv7(uint32_t reg, uint32_t val)
  594 {
  595 
  596         bus_space_write_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE_ARMV7, reg, val);
  597 }
  598 
  599 uint32_t
  600 read_cpu_mp_clocks(uint32_t reg)
  601 {
  602 
  603         return (bus_space_read_4(fdtbus_bs_tag, MV_MP_CLOCKS_BASE, reg));
  604 }
  605 
  606 void
  607 write_cpu_mp_clocks(uint32_t reg, uint32_t val)
  608 {
  609 
  610         bus_space_write_4(fdtbus_bs_tag, MV_MP_CLOCKS_BASE, reg, val);
  611 }
  612 
  613 uint32_t
  614 read_cpu_misc(uint32_t reg)
  615 {
  616 
  617         return (bus_space_read_4(fdtbus_bs_tag, MV_MISC_BASE, reg));
  618 }
  619 
  620 void
  621 write_cpu_misc(uint32_t reg, uint32_t val)
  622 {
  623 
  624         bus_space_write_4(fdtbus_bs_tag, MV_MISC_BASE, reg, val);
  625 }
  626 
  627 uint32_t
  628 cpu_extra_feat(void)
  629 {
  630         uint32_t dev, rev;
  631         uint32_t ef = 0;
  632 
  633         soc_id(&dev, &rev);
  634 
  635         switch (dev) {
  636         case MV_DEV_88F6281:
  637         case MV_DEV_88F6282:
  638         case MV_DEV_88RC8180:
  639         case MV_DEV_MV78100_Z0:
  640         case MV_DEV_MV78100:
  641                 __asm __volatile("mrc p15, 1, %0, c15, c1, 0" : "=r" (ef));
  642                 break;
  643         case MV_DEV_88F5182:
  644         case MV_DEV_88F5281:
  645                 __asm __volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (ef));
  646                 break;
  647         default:
  648                 if (bootverbose)
  649                         printf("This ARM Core does not support any extra features\n");
  650         }
  651 
  652         return (ef);
  653 }
  654 
  655 /*
  656  * Get the power status of device. This feature is only supported on
  657  * Kirkwood and Discovery SoCs.
  658  */
  659 uint32_t
  660 soc_power_ctrl_get(uint32_t mask)
  661 {
  662 
  663 #if SOC_MV_POWER_STAT_SUPPORTED
  664         if (mask != CPU_PM_CTRL_NONE)
  665                 mask &= read_cpu_ctrl(CPU_PM_CTRL);
  666 
  667         return (mask);
  668 #else
  669         return (mask);
  670 #endif
  671 }
  672 
  673 /*
  674  * Set the power status of device. This feature is only supported on
  675  * Kirkwood and Discovery SoCs.
  676  */
  677 void
  678 soc_power_ctrl_set(uint32_t mask)
  679 {
  680 
  681 #if !defined(SOC_MV_ORION)
  682         if (mask != CPU_PM_CTRL_NONE)
  683                 write_cpu_ctrl(CPU_PM_CTRL, mask);
  684 #endif
  685 }
  686 
  687 void
  688 soc_id(uint32_t *dev, uint32_t *rev)
  689 {
  690         uint64_t mv_pcie_base = MV_PCIE_BASE;
  691         phandle_t node;
  692 
  693         /*
  694          * Notice: system identifiers are available in the registers range of
  695          * PCIE controller, so using this function is only allowed (and
  696          * possible) after the internal registers range has been mapped in via
  697          * devmap_bootstrap().
  698          */
  699         *dev = 0;
  700         *rev = 0;
  701         if ((node = OF_finddevice("/")) == -1)
  702                 return;
  703         if (ofw_bus_node_is_compatible(node, "marvell,armada380"))
  704                 mv_pcie_base = MV_PCIE_BASE_ARMADA38X;
  705 
  706         *dev = bus_space_read_4(fdtbus_bs_tag, mv_pcie_base, 0) >> 16;
  707         *rev = bus_space_read_4(fdtbus_bs_tag, mv_pcie_base, 8) & 0xff;
  708 }
  709 
  710 static void
  711 soc_identify(uint32_t d, uint32_t r)
  712 {
  713         uint32_t size, mode, freq;
  714         const char *dev;
  715         const char *rev;
  716 
  717         printf("SOC: ");
  718         if (bootverbose)
  719                 printf("(0x%4x:0x%02x) ", d, r);
  720 
  721         rev = "";
  722         switch (d) {
  723         case MV_DEV_88F5181:
  724                 dev = "Marvell 88F5181";
  725                 if (r == 3)
  726                         rev = "B1";
  727                 break;
  728         case MV_DEV_88F5182:
  729                 dev = "Marvell 88F5182";
  730                 if (r == 2)
  731                         rev = "A2";
  732                 break;
  733         case MV_DEV_88F5281:
  734                 dev = "Marvell 88F5281";
  735                 if (r == 4)
  736                         rev = "D0";
  737                 else if (r == 5)
  738                         rev = "D1";
  739                 else if (r == 6)
  740                         rev = "D2";
  741                 break;
  742         case MV_DEV_88F6281:
  743                 dev = "Marvell 88F6281";
  744                 if (r == 0)
  745                         rev = "Z0";
  746                 else if (r == 2)
  747                         rev = "A0";
  748                 else if (r == 3)
  749                         rev = "A1";
  750                 break;
  751         case MV_DEV_88RC8180:
  752                 dev = "Marvell 88RC8180";
  753                 break;
  754         case MV_DEV_88RC9480:
  755                 dev = "Marvell 88RC9480";
  756                 break;
  757         case MV_DEV_88RC9580:
  758                 dev = "Marvell 88RC9580";
  759                 break;
  760         case MV_DEV_88F6781:
  761                 dev = "Marvell 88F6781";
  762                 if (r == 2)
  763                         rev = "Y0";
  764                 break;
  765         case MV_DEV_88F6282:
  766                 dev = "Marvell 88F6282";
  767                 if (r == 0)
  768                         rev = "A0";
  769                 else if (r == 1)
  770                         rev = "A1";
  771                 break;
  772         case MV_DEV_88F6828:
  773                 dev = "Marvell 88F6828";
  774                 break;
  775         case MV_DEV_88F6820:
  776                 dev = "Marvell 88F6820";
  777                 break;
  778         case MV_DEV_88F6810:
  779                 dev = "Marvell 88F6810";
  780                 break;
  781         case MV_DEV_MV78100_Z0:
  782                 dev = "Marvell MV78100 Z0";
  783                 break;
  784         case MV_DEV_MV78100:
  785                 dev = "Marvell MV78100";
  786                 break;
  787         case MV_DEV_MV78160:
  788                 dev = "Marvell MV78160";
  789                 break;
  790         case MV_DEV_MV78260:
  791                 dev = "Marvell MV78260";
  792                 break;
  793         case MV_DEV_MV78460:
  794                 dev = "Marvell MV78460";
  795                 break;
  796         default:
  797                 dev = "UNKNOWN";
  798                 break;
  799         }
  800 
  801         printf("%s", dev);
  802         if (*rev != '\0')
  803                 printf(" rev %s", rev);
  804         printf(", TClock %dMHz", get_tclk() / 1000 / 1000);
  805         freq = get_cpu_freq();
  806         if (freq != 0)
  807                 printf(", Frequency %dMHz", freq / 1000 / 1000);
  808         printf("\n");
  809 
  810         mode = read_cpu_ctrl(CPU_CONFIG);
  811         printf("  Instruction cache prefetch %s, data cache prefetch %s\n",
  812             (mode & CPU_CONFIG_IC_PREF) ? "enabled" : "disabled",
  813             (mode & CPU_CONFIG_DC_PREF) ? "enabled" : "disabled");
  814 
  815         switch (d) {
  816         case MV_DEV_88F6281:
  817         case MV_DEV_88F6282:
  818                 mode = read_cpu_ctrl(CPU_L2_CONFIG) & CPU_L2_CONFIG_MODE;
  819                 printf("  256KB 4-way set-associative %s unified L2 cache\n",
  820                     mode ? "write-through" : "write-back");
  821                 break;
  822         case MV_DEV_MV78100:
  823                 mode = read_cpu_ctrl(CPU_CONTROL);
  824                 size = mode & CPU_CONTROL_L2_SIZE;
  825                 mode = mode & CPU_CONTROL_L2_MODE;
  826                 printf("  %s set-associative %s unified L2 cache\n",
  827                     size ? "256KB 4-way" : "512KB 8-way",
  828                     mode ? "write-through" : "write-back");
  829                 break;
  830         default:
  831                 break;
  832         }
  833 }
  834 
  835 #ifdef KDB
  836 static void
  837 mv_enter_debugger(void *dummy)
  838 {
  839 
  840         if (boothowto & RB_KDB)
  841                 kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
  842 }
  843 SYSINIT(mv_enter_debugger, SI_SUB_CPU, SI_ORDER_ANY, mv_enter_debugger, NULL);
  844 #endif
  845 
  846 int
  847 soc_decode_win(void)
  848 {
  849         uint32_t dev, rev;
  850         int mask, err;
  851 
  852         mask = 0;
  853         TUNABLE_INT_FETCH("hw.pm-disable-mask", &mask);
  854 
  855         if (mask != 0)
  856                 pm_disable_device(mask);
  857 
  858         /* Retrieve data about physical addresses from device tree. */
  859         if ((err = win_cpu_from_dt()) != 0)
  860                 return (err);
  861 
  862         /* Retrieve our ID: some windows facilities vary between SoC models */
  863         soc_id(&dev, &rev);
  864 
  865         if (soc_family == MV_SOC_ARMADA_XP)
  866                 if ((err = decode_win_sdram_fixup()) != 0)
  867                         return(err);
  868 
  869 
  870         decode_win_cpu_setup();
  871         if (MV_DUMP_WIN)
  872                 soc_dump_decode_win();
  873 
  874         eth_port = 0;
  875         usb_port = 0;
  876         if ((err = fdt_win_setup()) != 0)
  877                 return (err);
  878 
  879         return (0);
  880 }
  881 
  882 /**************************************************************************
  883  * Decode windows registers accessors
  884  **************************************************************************/
  885 WIN_REG_IDX_RD(win_cpu_armv5, cr, MV_WIN_CPU_CTRL_ARMV5, MV_MBUS_BRIDGE_BASE)
  886 WIN_REG_IDX_RD(win_cpu_armv5, br, MV_WIN_CPU_BASE_ARMV5, MV_MBUS_BRIDGE_BASE)
  887 WIN_REG_IDX_RD(win_cpu_armv5, remap_l, MV_WIN_CPU_REMAP_LO_ARMV5, MV_MBUS_BRIDGE_BASE)
  888 WIN_REG_IDX_RD(win_cpu_armv5, remap_h, MV_WIN_CPU_REMAP_HI_ARMV5, MV_MBUS_BRIDGE_BASE)
  889 WIN_REG_IDX_WR(win_cpu_armv5, cr, MV_WIN_CPU_CTRL_ARMV5, MV_MBUS_BRIDGE_BASE)
  890 WIN_REG_IDX_WR(win_cpu_armv5, br, MV_WIN_CPU_BASE_ARMV5, MV_MBUS_BRIDGE_BASE)
  891 WIN_REG_IDX_WR(win_cpu_armv5, remap_l, MV_WIN_CPU_REMAP_LO_ARMV5, MV_MBUS_BRIDGE_BASE)
  892 WIN_REG_IDX_WR(win_cpu_armv5, remap_h, MV_WIN_CPU_REMAP_HI_ARMV5, MV_MBUS_BRIDGE_BASE)
  893 
  894 WIN_REG_IDX_RD(win_cpu_armv7, cr, MV_WIN_CPU_CTRL_ARMV7, MV_MBUS_BRIDGE_BASE)
  895 WIN_REG_IDX_RD(win_cpu_armv7, br, MV_WIN_CPU_BASE_ARMV7, MV_MBUS_BRIDGE_BASE)
  896 WIN_REG_IDX_RD(win_cpu_armv7, remap_l, MV_WIN_CPU_REMAP_LO_ARMV7, MV_MBUS_BRIDGE_BASE)
  897 WIN_REG_IDX_RD(win_cpu_armv7, remap_h, MV_WIN_CPU_REMAP_HI_ARMV7, MV_MBUS_BRIDGE_BASE)
  898 WIN_REG_IDX_WR(win_cpu_armv7, cr, MV_WIN_CPU_CTRL_ARMV7, MV_MBUS_BRIDGE_BASE)
  899 WIN_REG_IDX_WR(win_cpu_armv7, br, MV_WIN_CPU_BASE_ARMV7, MV_MBUS_BRIDGE_BASE)
  900 WIN_REG_IDX_WR(win_cpu_armv7, remap_l, MV_WIN_CPU_REMAP_LO_ARMV7, MV_MBUS_BRIDGE_BASE)
  901 WIN_REG_IDX_WR(win_cpu_armv7, remap_h, MV_WIN_CPU_REMAP_HI_ARMV7, MV_MBUS_BRIDGE_BASE)
  902 
  903 static uint32_t
  904 win_cpu_cr_read(int i)
  905 {
  906 
  907         if (soc_decode_win_spec->cr_read != NULL)
  908                 return (soc_decode_win_spec->cr_read(i));
  909         return (-1);
  910 }
  911 
  912 static uint32_t
  913 win_cpu_br_read(int i)
  914 {
  915 
  916         if (soc_decode_win_spec->br_read != NULL)
  917                 return (soc_decode_win_spec->br_read(i));
  918         return (-1);
  919 }
  920 
  921 static uint32_t
  922 win_cpu_remap_l_read(int i)
  923 {
  924 
  925         if (soc_decode_win_spec->remap_l_read != NULL)
  926                 return (soc_decode_win_spec->remap_l_read(i));
  927         return (-1);
  928 }
  929 
  930 static uint32_t
  931 win_cpu_remap_h_read(int i)
  932 {
  933 
  934         if (soc_decode_win_spec->remap_h_read != NULL)
  935                 return soc_decode_win_spec->remap_h_read(i);
  936         return (-1);
  937 }
  938 
  939 static void
  940 win_cpu_cr_write(int i, uint32_t val)
  941 {
  942 
  943         if (soc_decode_win_spec->cr_write != NULL)
  944                 soc_decode_win_spec->cr_write(i, val);
  945 }
  946 
  947 static void
  948 win_cpu_br_write(int i, uint32_t val)
  949 {
  950 
  951         if (soc_decode_win_spec->br_write != NULL)
  952                 soc_decode_win_spec->br_write(i, val);
  953 }
  954 
  955 static void
  956 win_cpu_remap_l_write(int i, uint32_t val)
  957 {
  958 
  959         if (soc_decode_win_spec->remap_l_write != NULL)
  960                 soc_decode_win_spec->remap_l_write(i, val);
  961 }
  962 
  963 static void
  964 win_cpu_remap_h_write(int i, uint32_t val)
  965 {
  966 
  967         if (soc_decode_win_spec->remap_h_write != NULL)
  968                 soc_decode_win_spec->remap_h_write(i, val);
  969 }
  970 
  971 WIN_REG_BASE_IDX_RD(win_cesa, cr, MV_WIN_CESA_CTRL)
  972 WIN_REG_BASE_IDX_RD(win_cesa, br, MV_WIN_CESA_BASE)
  973 WIN_REG_BASE_IDX_WR(win_cesa, cr, MV_WIN_CESA_CTRL)
  974 WIN_REG_BASE_IDX_WR(win_cesa, br, MV_WIN_CESA_BASE)
  975 
  976 WIN_REG_BASE_IDX_RD(win_usb, cr, MV_WIN_USB_CTRL)
  977 WIN_REG_BASE_IDX_RD(win_usb, br, MV_WIN_USB_BASE)
  978 WIN_REG_BASE_IDX_WR(win_usb, cr, MV_WIN_USB_CTRL)
  979 WIN_REG_BASE_IDX_WR(win_usb, br, MV_WIN_USB_BASE)
  980 
  981 WIN_REG_BASE_IDX_RD(win_usb3, cr, MV_WIN_USB3_CTRL)
  982 WIN_REG_BASE_IDX_RD(win_usb3, br, MV_WIN_USB3_BASE)
  983 WIN_REG_BASE_IDX_WR(win_usb3, cr, MV_WIN_USB3_CTRL)
  984 WIN_REG_BASE_IDX_WR(win_usb3, br, MV_WIN_USB3_BASE)
  985 
  986 WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE)
  987 WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE)
  988 WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP)
  989 WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE)
  990 WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE)
  991 WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP)
  992 
  993 WIN_REG_BASE_IDX_RD2(win_xor, br, MV_WIN_XOR_BASE)
  994 WIN_REG_BASE_IDX_RD2(win_xor, sz, MV_WIN_XOR_SIZE)
  995 WIN_REG_BASE_IDX_RD2(win_xor, har, MV_WIN_XOR_REMAP)
  996 WIN_REG_BASE_IDX_RD2(win_xor, ctrl, MV_WIN_XOR_CTRL)
  997 WIN_REG_BASE_IDX_WR2(win_xor, br, MV_WIN_XOR_BASE)
  998 WIN_REG_BASE_IDX_WR2(win_xor, sz, MV_WIN_XOR_SIZE)
  999 WIN_REG_BASE_IDX_WR2(win_xor, har, MV_WIN_XOR_REMAP)
 1000 WIN_REG_BASE_IDX_WR2(win_xor, ctrl, MV_WIN_XOR_CTRL)
 1001 
 1002 WIN_REG_BASE_RD(win_eth, bare, 0x290)
 1003 WIN_REG_BASE_RD(win_eth, epap, 0x294)
 1004 WIN_REG_BASE_WR(win_eth, bare, 0x290)
 1005 WIN_REG_BASE_WR(win_eth, epap, 0x294)
 1006 
 1007 WIN_REG_BASE_IDX_RD(win_pcie, cr, MV_WIN_PCIE_CTRL);
 1008 WIN_REG_BASE_IDX_RD(win_pcie, br, MV_WIN_PCIE_BASE);
 1009 WIN_REG_BASE_IDX_RD(win_pcie, remap, MV_WIN_PCIE_REMAP);
 1010 WIN_REG_BASE_IDX_WR(win_pcie, cr, MV_WIN_PCIE_CTRL);
 1011 WIN_REG_BASE_IDX_WR(win_pcie, br, MV_WIN_PCIE_BASE);
 1012 WIN_REG_BASE_IDX_WR(win_pcie, remap, MV_WIN_PCIE_REMAP);
 1013 WIN_REG_BASE_IDX_RD(pcie_bar, br, MV_PCIE_BAR_BASE);
 1014 WIN_REG_BASE_IDX_RD(pcie_bar, brh, MV_PCIE_BAR_BASE_H);
 1015 WIN_REG_BASE_IDX_RD(pcie_bar, cr, MV_PCIE_BAR_CTRL);
 1016 WIN_REG_BASE_IDX_WR(pcie_bar, br, MV_PCIE_BAR_BASE);
 1017 WIN_REG_BASE_IDX_WR(pcie_bar, brh, MV_PCIE_BAR_BASE_H);
 1018 WIN_REG_BASE_IDX_WR(pcie_bar, cr, MV_PCIE_BAR_CTRL);
 1019 
 1020 WIN_REG_BASE_IDX_RD(win_idma, br, MV_WIN_IDMA_BASE)
 1021 WIN_REG_BASE_IDX_RD(win_idma, sz, MV_WIN_IDMA_SIZE)
 1022 WIN_REG_BASE_IDX_RD(win_idma, har, MV_WIN_IDMA_REMAP)
 1023 WIN_REG_BASE_IDX_RD(win_idma, cap, MV_WIN_IDMA_CAP)
 1024 WIN_REG_BASE_IDX_WR(win_idma, br, MV_WIN_IDMA_BASE)
 1025 WIN_REG_BASE_IDX_WR(win_idma, sz, MV_WIN_IDMA_SIZE)
 1026 WIN_REG_BASE_IDX_WR(win_idma, har, MV_WIN_IDMA_REMAP)
 1027 WIN_REG_BASE_IDX_WR(win_idma, cap, MV_WIN_IDMA_CAP)
 1028 WIN_REG_BASE_RD(win_idma, bare, 0xa80)
 1029 WIN_REG_BASE_WR(win_idma, bare, 0xa80)
 1030 
 1031 WIN_REG_BASE_IDX_RD(win_sata, cr, MV_WIN_SATA_CTRL);
 1032 WIN_REG_BASE_IDX_RD(win_sata, br, MV_WIN_SATA_BASE);
 1033 WIN_REG_BASE_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL);
 1034 WIN_REG_BASE_IDX_WR(win_sata, br, MV_WIN_SATA_BASE);
 1035 
 1036 WIN_REG_BASE_IDX_RD(win_sata_armada38x, sz, MV_WIN_SATA_SIZE_ARMADA38X);
 1037 WIN_REG_BASE_IDX_WR(win_sata_armada38x, sz, MV_WIN_SATA_SIZE_ARMADA38X);
 1038 WIN_REG_BASE_IDX_RD(win_sata_armada38x, cr, MV_WIN_SATA_CTRL_ARMADA38X);
 1039 WIN_REG_BASE_IDX_RD(win_sata_armada38x, br, MV_WIN_SATA_BASE_ARMADA38X);
 1040 WIN_REG_BASE_IDX_WR(win_sata_armada38x, cr, MV_WIN_SATA_CTRL_ARMADA38X);
 1041 WIN_REG_BASE_IDX_WR(win_sata_armada38x, br, MV_WIN_SATA_BASE_ARMADA38X);
 1042 
 1043 WIN_REG_BASE_IDX_RD(win_sdhci, cr, MV_WIN_SDHCI_CTRL);
 1044 WIN_REG_BASE_IDX_RD(win_sdhci, br, MV_WIN_SDHCI_BASE);
 1045 WIN_REG_BASE_IDX_WR(win_sdhci, cr, MV_WIN_SDHCI_CTRL);
 1046 WIN_REG_BASE_IDX_WR(win_sdhci, br, MV_WIN_SDHCI_BASE);
 1047 
 1048 #ifndef SOC_MV_DOVE
 1049 WIN_REG_IDX_RD(ddr_armv5, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
 1050 WIN_REG_IDX_RD(ddr_armv5, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
 1051 WIN_REG_IDX_WR(ddr_armv5, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
 1052 WIN_REG_IDX_WR(ddr_armv5, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
 1053 
 1054 WIN_REG_IDX_RD(ddr_armv7, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE_ARMV7)
 1055 WIN_REG_IDX_RD(ddr_armv7, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE_ARMV7)
 1056 WIN_REG_IDX_WR(ddr_armv7, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE_ARMV7)
 1057 WIN_REG_IDX_WR(ddr_armv7, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE_ARMV7)
 1058 
 1059 static inline uint32_t
 1060 ddr_br_read(int i)
 1061 {
 1062 
 1063         if (soc_decode_win_spec->ddr_br_read != NULL)
 1064                 return (soc_decode_win_spec->ddr_br_read(i));
 1065         return (-1);
 1066 }
 1067 
 1068 static inline uint32_t
 1069 ddr_sz_read(int i)
 1070 {
 1071 
 1072         if (soc_decode_win_spec->ddr_sz_read != NULL)
 1073                 return (soc_decode_win_spec->ddr_sz_read(i));
 1074         return (-1);
 1075 }
 1076 
 1077 static inline void
 1078 ddr_br_write(int i, uint32_t val)
 1079 {
 1080 
 1081         if (soc_decode_win_spec->ddr_br_write != NULL)
 1082                 soc_decode_win_spec->ddr_br_write(i, val);
 1083 }
 1084 
 1085 static inline void
 1086 ddr_sz_write(int i, uint32_t val)
 1087 {
 1088 
 1089         if (soc_decode_win_spec->ddr_sz_write != NULL)
 1090                 soc_decode_win_spec->ddr_sz_write(i, val);
 1091 }
 1092 #else
 1093 /*
 1094  * On 88F6781 (Dove) SoC DDR Controller is accessed through
 1095  * single MBUS <-> AXI bridge. In this case we provide emulated
 1096  * ddr_br_read() and ddr_sz_read() functions to keep compatibility
 1097  * with common decoding windows setup code.
 1098  */
 1099 
 1100 static inline uint32_t ddr_br_read(int i)
 1101 {
 1102         uint32_t mmap;
 1103 
 1104         /* Read Memory Address Map Register for CS i */
 1105         mmap = bus_space_read_4(fdtbus_bs_tag, MV_DDR_CADR_BASE + (i * 0x10), 0);
 1106 
 1107         /* Return CS i base address */
 1108         return (mmap & 0xFF000000);
 1109 }
 1110 
 1111 static inline uint32_t ddr_sz_read(int i)
 1112 {
 1113         uint32_t mmap, size;
 1114 
 1115         /* Read Memory Address Map Register for CS i */
 1116         mmap = bus_space_read_4(fdtbus_bs_tag, MV_DDR_CADR_BASE + (i * 0x10), 0);
 1117 
 1118         /* Extract size of CS space in 64kB units */
 1119         size = (1 << ((mmap >> 16) & 0x0F));
 1120 
 1121         /* Return CS size and enable/disable status */
 1122         return (((size - 1) << 16) | (mmap & 0x01));
 1123 }
 1124 #endif
 1125 
 1126 /**************************************************************************
 1127  * Decode windows helper routines
 1128  **************************************************************************/
 1129 void
 1130 soc_dump_decode_win(void)
 1131 {
 1132         int i;
 1133 
 1134         for (i = 0; i < soc_decode_win_spec->mv_win_cpu_max; i++) {
 1135                 printf("CPU window#%d: c 0x%08x, b 0x%08x", i,
 1136                     win_cpu_cr_read(i),
 1137                     win_cpu_br_read(i));
 1138 
 1139                 if (win_cpu_can_remap(i))
 1140                         printf(", rl 0x%08x, rh 0x%08x",
 1141                             win_cpu_remap_l_read(i),
 1142                             win_cpu_remap_h_read(i));
 1143 
 1144                 printf("\n");
 1145         }
 1146         printf("Internal regs base: 0x%08x\n",
 1147             bus_space_read_4(fdtbus_bs_tag, MV_INTREGS_BASE, 0));
 1148 
 1149         for (i = 0; i < MV_WIN_DDR_MAX; i++)
 1150                 printf("DDR CS#%d: b 0x%08x, s 0x%08x\n", i,
 1151                     ddr_br_read(i), ddr_sz_read(i));
 1152 }
 1153 
 1154 /**************************************************************************
 1155  * CPU windows routines
 1156  **************************************************************************/
 1157 int
 1158 win_cpu_can_remap(int i)
 1159 {
 1160         uint32_t dev, rev;
 1161 
 1162         soc_id(&dev, &rev);
 1163 
 1164         /* Depending on the SoC certain windows have remap capability */
 1165         if ((dev == MV_DEV_88F5182 && i < 2) ||
 1166             (dev == MV_DEV_88F5281 && i < 4) ||
 1167             (dev == MV_DEV_88F6281 && i < 4) ||
 1168             (dev == MV_DEV_88F6282 && i < 4) ||
 1169             (dev == MV_DEV_88F6828 && i < 20) ||
 1170             (dev == MV_DEV_88F6820 && i < 20) ||
 1171             (dev == MV_DEV_88F6810 && i < 20) ||
 1172             (dev == MV_DEV_88RC8180 && i < 2) ||
 1173             (dev == MV_DEV_88F6781 && i < 4) ||
 1174             (dev == MV_DEV_MV78100_Z0 && i < 8) ||
 1175             ((dev & MV_DEV_FAMILY_MASK) == MV_DEV_DISCOVERY && i < 8))
 1176                 return (1);
 1177 
 1178         return (0);
 1179 }
 1180 
 1181 /* XXX This should check for overlapping remap fields too.. */
 1182 int
 1183 decode_win_overlap(int win, int win_no, const struct decode_win *wintab)
 1184 {
 1185         const struct decode_win *tab;
 1186         int i;
 1187 
 1188         tab = wintab;
 1189 
 1190         for (i = 0; i < win_no; i++, tab++) {
 1191                 if (i == win)
 1192                         /* Skip self */
 1193                         continue;
 1194 
 1195                 if ((tab->base + tab->size - 1) < (wintab + win)->base)
 1196                         continue;
 1197 
 1198                 else if (((wintab + win)->base + (wintab + win)->size - 1) <
 1199                     tab->base)
 1200                         continue;
 1201                 else
 1202                         return (i);
 1203         }
 1204 
 1205         return (-1);
 1206 }
 1207 
 1208 static int
 1209 decode_win_cpu_valid(void)
 1210 {
 1211         int i, j, rv;
 1212         uint32_t b, e, s;
 1213 
 1214         if (cpu_wins_no > soc_decode_win_spec->mv_win_cpu_max) {
 1215                 printf("CPU windows: too many entries: %d\n", cpu_wins_no);
 1216                 return (0);
 1217         }
 1218 
 1219         rv = 1;
 1220         for (i = 0; i < cpu_wins_no; i++) {
 1221 
 1222                 if (cpu_wins[i].target == 0) {
 1223                         printf("CPU window#%d: DDR target window is not "
 1224                             "supposed to be reprogrammed!\n", i);
 1225                         rv = 0;
 1226                 }
 1227 
 1228                 if (cpu_wins[i].remap != ~0 && win_cpu_can_remap(i) != 1) {
 1229                         printf("CPU window#%d: not capable of remapping, but "
 1230                             "val 0x%08x defined\n", i, cpu_wins[i].remap);
 1231                         rv = 0;
 1232                 }
 1233 
 1234                 s = cpu_wins[i].size;
 1235                 b = cpu_wins[i].base;
 1236                 e = b + s - 1;
 1237                 if (s > (0xFFFFFFFF - b + 1)) {
 1238                         /*
 1239                          * XXX this boundary check should account for 64bit
 1240                          * and remapping..
 1241                          */
 1242                         printf("CPU window#%d: no space for size 0x%08x at "
 1243                             "0x%08x\n", i, s, b);
 1244                         rv = 0;
 1245                         continue;
 1246                 }
 1247 
 1248                 if (b != rounddown2(b, s)) {
 1249                         printf("CPU window#%d: address 0x%08x is not aligned "
 1250                             "to 0x%08x\n", i, b, s);
 1251                         rv = 0;
 1252                         continue;
 1253                 }
 1254 
 1255                 j = decode_win_overlap(i, cpu_wins_no, &cpu_wins[0]);
 1256                 if (j >= 0) {
 1257                         printf("CPU window#%d: (0x%08x - 0x%08x) overlaps "
 1258                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
 1259                             cpu_wins[j].base,
 1260                             cpu_wins[j].base + cpu_wins[j].size - 1);
 1261                         rv = 0;
 1262                 }
 1263         }
 1264 
 1265         return (rv);
 1266 }
 1267 
 1268 int
 1269 decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size,
 1270     vm_paddr_t remap)
 1271 {
 1272         uint32_t br, cr;
 1273         int win, i;
 1274 
 1275         if (remap == ~0) {
 1276                 win = soc_decode_win_spec->mv_win_cpu_max - 1;
 1277                 i = -1;
 1278         } else {
 1279                 win = 0;
 1280                 i = 1;
 1281         }
 1282 
 1283         while ((win >= 0) && (win < soc_decode_win_spec->mv_win_cpu_max)) {
 1284                 cr = win_cpu_cr_read(win);
 1285                 if ((cr & MV_WIN_CPU_ENABLE_BIT) == 0)
 1286                         break;
 1287                 if ((cr & ((0xff << MV_WIN_CPU_ATTR_SHIFT) |
 1288                     (0x1f << MV_WIN_CPU_TARGET_SHIFT))) ==
 1289                     ((attr << MV_WIN_CPU_ATTR_SHIFT) |
 1290                     (target << MV_WIN_CPU_TARGET_SHIFT)))
 1291                         break;
 1292                 win += i;
 1293         }
 1294         if ((win < 0) || (win >= soc_decode_win_spec->mv_win_cpu_max) ||
 1295             ((remap != ~0) && (win_cpu_can_remap(win) == 0)))
 1296                 return (-1);
 1297 
 1298         br = base & 0xffff0000;
 1299         win_cpu_br_write(win, br);
 1300 
 1301         if (win_cpu_can_remap(win)) {
 1302                 if (remap != ~0) {
 1303                         win_cpu_remap_l_write(win, remap & 0xffff0000);
 1304                         win_cpu_remap_h_write(win, 0);
 1305                 } else {
 1306                         /*
 1307                          * Remap function is not used for a given window
 1308                          * (capable of remapping) - set remap field with the
 1309                          * same value as base.
 1310                          */
 1311                         win_cpu_remap_l_write(win, base & 0xffff0000);
 1312                         win_cpu_remap_h_write(win, 0);
 1313                 }
 1314         }
 1315 
 1316         cr = ((size - 1) & 0xffff0000) | (attr << MV_WIN_CPU_ATTR_SHIFT) |
 1317             (target << MV_WIN_CPU_TARGET_SHIFT) | MV_WIN_CPU_ENABLE_BIT;
 1318         win_cpu_cr_write(win, cr);
 1319 
 1320         return (0);
 1321 }
 1322 
 1323 static void
 1324 decode_win_cpu_setup(void)
 1325 {
 1326         int i;
 1327 
 1328         /* Disable all CPU windows */
 1329         for (i = 0; i < soc_decode_win_spec->mv_win_cpu_max; i++) {
 1330                 win_cpu_cr_write(i, 0);
 1331                 win_cpu_br_write(i, 0);
 1332                 if (win_cpu_can_remap(i)) {
 1333                         win_cpu_remap_l_write(i, 0);
 1334                         win_cpu_remap_h_write(i, 0);
 1335                 }
 1336         }
 1337 
 1338         for (i = 0; i < cpu_wins_no; i++)
 1339                 if (cpu_wins[i].target > 0)
 1340                         decode_win_cpu_set(cpu_wins[i].target,
 1341                             cpu_wins[i].attr, cpu_wins[i].base,
 1342                             cpu_wins[i].size, cpu_wins[i].remap);
 1343 
 1344 }
 1345 
 1346 static int
 1347 decode_win_sdram_fixup(void)
 1348 {
 1349         struct mem_region mr[FDT_MEM_REGIONS];
 1350         uint8_t window_valid[MV_WIN_DDR_MAX];
 1351         int mr_cnt, err, i, j;
 1352         uint32_t valid_win_num = 0;
 1353 
 1354         /* Grab physical memory regions information from device tree. */
 1355         err = fdt_get_mem_regions(mr, &mr_cnt, NULL);
 1356         if (err != 0)
 1357                 return (err);
 1358 
 1359         for (i = 0; i < MV_WIN_DDR_MAX; i++)
 1360                 window_valid[i] = 0;
 1361 
 1362         /* Try to match entries from device tree with settings from u-boot */
 1363         for (i = 0; i < mr_cnt; i++) {
 1364                 for (j = 0; j < MV_WIN_DDR_MAX; j++) {
 1365                         if (ddr_is_active(j) &&
 1366                             (ddr_base(j) == mr[i].mr_start) &&
 1367                             (ddr_size(j) == mr[i].mr_size)) {
 1368                                 window_valid[j] = 1;
 1369                                 valid_win_num++;
 1370                         }
 1371                 }
 1372         }
 1373 
 1374         if (mr_cnt != valid_win_num)
 1375                 return (EINVAL);
 1376 
 1377         /* Destroy windows without corresponding device tree entry */
 1378         for (j = 0; j < MV_WIN_DDR_MAX; j++) {
 1379                 if (ddr_is_active(j) && (window_valid[j] != 1)) {
 1380                         printf("Disabling SDRAM decoding window: %d\n", j);
 1381                         ddr_disable(j);
 1382                 }
 1383         }
 1384 
 1385         return (0);
 1386 }
 1387 /*
 1388  * Check if we're able to cover all active DDR banks.
 1389  */
 1390 static int
 1391 decode_win_can_cover_ddr(int max)
 1392 {
 1393         int i, c;
 1394 
 1395         c = 0;
 1396         for (i = 0; i < MV_WIN_DDR_MAX; i++)
 1397                 if (ddr_is_active(i))
 1398                         c++;
 1399 
 1400         if (c > max) {
 1401                 printf("Unable to cover all active DDR banks: "
 1402                     "%d, available windows: %d\n", c, max);
 1403                 return (0);
 1404         }
 1405 
 1406         return (1);
 1407 }
 1408 
 1409 /**************************************************************************
 1410  * DDR windows routines
 1411  **************************************************************************/
 1412 int
 1413 ddr_is_active(int i)
 1414 {
 1415 
 1416         if (ddr_sz_read(i) & 0x1)
 1417                 return (1);
 1418 
 1419         return (0);
 1420 }
 1421 
 1422 void
 1423 ddr_disable(int i)
 1424 {
 1425 
 1426         ddr_sz_write(i, 0);
 1427         ddr_br_write(i, 0);
 1428 }
 1429 
 1430 uint32_t
 1431 ddr_base(int i)
 1432 {
 1433 
 1434         return (ddr_br_read(i) & 0xff000000);
 1435 }
 1436 
 1437 uint32_t
 1438 ddr_size(int i)
 1439 {
 1440 
 1441         return ((ddr_sz_read(i) | 0x00ffffff) + 1);
 1442 }
 1443 
 1444 uint32_t
 1445 ddr_attr(int i)
 1446 {
 1447         uint32_t dev, rev, attr;
 1448 
 1449         soc_id(&dev, &rev);
 1450         if (dev == MV_DEV_88RC8180)
 1451                 return ((ddr_sz_read(i) & 0xf0) >> 4);
 1452         if (dev == MV_DEV_88F6781)
 1453                 return (0);
 1454 
 1455         attr = (i == 0 ? 0xe :
 1456             (i == 1 ? 0xd :
 1457             (i == 2 ? 0xb :
 1458             (i == 3 ? 0x7 : 0xff))));
 1459         if (platform_io_coherent)
 1460                 attr |= 0x10;
 1461 
 1462         return (attr);
 1463 }
 1464 
 1465 uint32_t
 1466 ddr_target(int i)
 1467 {
 1468         uint32_t dev, rev;
 1469 
 1470         soc_id(&dev, &rev);
 1471         if (dev == MV_DEV_88RC8180) {
 1472                 i = (ddr_sz_read(i) & 0xf0) >> 4;
 1473                 return (i == 0xe ? 0xc :
 1474                     (i == 0xd ? 0xd :
 1475                     (i == 0xb ? 0xe :
 1476                     (i == 0x7 ? 0xf : 0xc))));
 1477         }
 1478 
 1479         /*
 1480          * On SOCs other than 88RC8180 Mbus unit ID for
 1481          * DDR SDRAM controller is always 0x0.
 1482          */
 1483         return (0);
 1484 }
 1485 
 1486 /**************************************************************************
 1487  * CESA windows routines
 1488  **************************************************************************/
 1489 static int
 1490 decode_win_cesa_valid(void)
 1491 {
 1492 
 1493         return (decode_win_can_cover_ddr(MV_WIN_CESA_MAX));
 1494 }
 1495 
 1496 static void
 1497 decode_win_cesa_dump(u_long base)
 1498 {
 1499         int i;
 1500 
 1501         for (i = 0; i < MV_WIN_CESA_MAX; i++)
 1502                 printf("CESA window#%d: c 0x%08x, b 0x%08x\n", i,
 1503                     win_cesa_cr_read(base, i), win_cesa_br_read(base, i));
 1504 }
 1505 
 1506 /*
 1507  * Set CESA decode windows.
 1508  */
 1509 static void
 1510 decode_win_cesa_setup(u_long base)
 1511 {
 1512         uint32_t br, cr;
 1513         uint64_t size;
 1514         int i, j;
 1515 
 1516         for (i = 0; i < MV_WIN_CESA_MAX; i++) {
 1517                 win_cesa_cr_write(base, i, 0);
 1518                 win_cesa_br_write(base, i, 0);
 1519         }
 1520 
 1521         /* Only access to active DRAM banks is required */
 1522         for (i = 0; i < MV_WIN_DDR_MAX; i++) {
 1523                 if (ddr_is_active(i)) {
 1524                         br = ddr_base(i);
 1525 
 1526                         size = ddr_size(i);
 1527                         /*
 1528                          * Armada 38x SoC's equipped with 4GB DRAM
 1529                          * suffer freeze during CESA operation, if
 1530                          * MBUS window opened at given DRAM CS reaches
 1531                          * end of the address space. Apply a workaround
 1532                          * by setting the window size to the closest possible
 1533                          * value, i.e. divide it by 2.
 1534                          */
 1535                         if ((soc_family == MV_SOC_ARMADA_38X) &&
 1536                             (size + ddr_base(i) == 0x100000000ULL))
 1537                                 size /= 2;
 1538 
 1539                         cr = (((size - 1) & 0xffff0000) |
 1540                             (ddr_attr(i) << IO_WIN_ATTR_SHIFT) |
 1541                             (ddr_target(i) << IO_WIN_TGT_SHIFT) |
 1542                             IO_WIN_ENA_MASK);
 1543 
 1544                         /* Set the first free CESA window */
 1545                         for (j = 0; j < MV_WIN_CESA_MAX; j++) {
 1546                                 if (win_cesa_cr_read(base, j) & 0x1)
 1547                                         continue;
 1548 
 1549                                 win_cesa_br_write(base, j, br);
 1550                                 win_cesa_cr_write(base, j, cr);
 1551                                 break;
 1552                         }
 1553                 }
 1554         }
 1555 }
 1556 
 1557 static void
 1558 decode_win_a38x_cesa_setup(u_long base)
 1559 {
 1560         decode_win_cesa_setup(base);
 1561         decode_win_cesa_setup(base + MV_WIN_CESA_OFFSET);
 1562 }
 1563 
 1564 static void
 1565 decode_win_a38x_cesa_dump(u_long base)
 1566 {
 1567         decode_win_cesa_dump(base);
 1568         decode_win_cesa_dump(base + MV_WIN_CESA_OFFSET);
 1569 }
 1570 
 1571 /**************************************************************************
 1572  * USB windows routines
 1573  **************************************************************************/
 1574 static int
 1575 decode_win_usb_valid(void)
 1576 {
 1577 
 1578         return (decode_win_can_cover_ddr(MV_WIN_USB_MAX));
 1579 }
 1580 
 1581 static void
 1582 decode_win_usb_dump(u_long base)
 1583 {
 1584         int i;
 1585 
 1586         if (pm_is_disabled(CPU_PM_CTRL_USB(usb_port - 1)))
 1587                 return;
 1588 
 1589         for (i = 0; i < MV_WIN_USB_MAX; i++)
 1590                 printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
 1591                     win_usb_cr_read(base, i), win_usb_br_read(base, i));
 1592 }
 1593 
 1594 /*
 1595  * Set USB decode windows.
 1596  */
 1597 static void
 1598 decode_win_usb_setup(u_long base)
 1599 {
 1600         uint32_t br, cr;
 1601         int i, j;
 1602 
 1603         if (pm_is_disabled(CPU_PM_CTRL_USB(usb_port)))
 1604                 return;
 1605 
 1606         usb_port++;
 1607 
 1608         for (i = 0; i < MV_WIN_USB_MAX; i++) {
 1609                 win_usb_cr_write(base, i, 0);
 1610                 win_usb_br_write(base, i, 0);
 1611         }
 1612 
 1613         /* Only access to active DRAM banks is required */
 1614         for (i = 0; i < MV_WIN_DDR_MAX; i++) {
 1615                 if (ddr_is_active(i)) {
 1616                         br = ddr_base(i);
 1617                         /*
 1618                          * XXX for 6281 we should handle Mbus write
 1619                          * burst limit field in the ctrl reg
 1620                          */
 1621                         cr = (((ddr_size(i) - 1) & 0xffff0000) |
 1622                             (ddr_attr(i) << 8) |
 1623                             (ddr_target(i) << 4) | 1);
 1624 
 1625                         /* Set the first free USB window */
 1626                         for (j = 0; j < MV_WIN_USB_MAX; j++) {
 1627                                 if (win_usb_cr_read(base, j) & 0x1)
 1628                                         continue;
 1629 
 1630                                 win_usb_br_write(base, j, br);
 1631                                 win_usb_cr_write(base, j, cr);
 1632                                 break;
 1633                         }
 1634                 }
 1635         }
 1636 }
 1637 
 1638 /**************************************************************************
 1639  * USB3 windows routines
 1640  **************************************************************************/
 1641 static int
 1642 decode_win_usb3_valid(void)
 1643 {
 1644 
 1645         return (decode_win_can_cover_ddr(MV_WIN_USB3_MAX));
 1646 }
 1647 
 1648 static void
 1649 decode_win_usb3_dump(u_long base)
 1650 {
 1651         int i;
 1652 
 1653         for (i = 0; i < MV_WIN_USB3_MAX; i++)
 1654                 printf("USB3.0 window#%d: c 0x%08x, b 0x%08x\n", i,
 1655                     win_usb3_cr_read(base, i), win_usb3_br_read(base, i));
 1656 }
 1657 
 1658 /*
 1659  * Set USB3 decode windows
 1660  */
 1661 static void
 1662 decode_win_usb3_setup(u_long base)
 1663 {
 1664         uint32_t br, cr;
 1665         int i, j;
 1666 
 1667         for (i = 0; i < MV_WIN_USB3_MAX; i++) {
 1668                 win_usb3_cr_write(base, i, 0);
 1669                 win_usb3_br_write(base, i, 0);
 1670         }
 1671 
 1672         /* Only access to active DRAM banks is required */
 1673         for (i = 0; i < MV_WIN_DDR_MAX; i++) {
 1674                 if (ddr_is_active(i)) {
 1675                         br = ddr_base(i);
 1676                         cr = (((ddr_size(i) - 1) &
 1677                             (IO_WIN_SIZE_MASK << IO_WIN_SIZE_SHIFT)) |
 1678                             (ddr_attr(i) << IO_WIN_ATTR_SHIFT) |
 1679                             (ddr_target(i) << IO_WIN_TGT_SHIFT) |
 1680                             IO_WIN_ENA_MASK);
 1681 
 1682                         /* Set the first free USB3.0 window */
 1683                         for (j = 0; j < MV_WIN_USB3_MAX; j++) {
 1684                                 if (win_usb3_cr_read(base, j) & IO_WIN_ENA_MASK)
 1685                                         continue;
 1686 
 1687                                 win_usb3_br_write(base, j, br);
 1688                                 win_usb3_cr_write(base, j, cr);
 1689                                 break;
 1690                         }
 1691                 }
 1692         }
 1693 }
 1694 
 1695 
 1696 /**************************************************************************
 1697  * ETH windows routines
 1698  **************************************************************************/
 1699 
 1700 static int
 1701 win_eth_can_remap(int i)
 1702 {
 1703 
 1704         /* ETH encode windows 0-3 have remap capability */
 1705         if (i < 4)
 1706                 return (1);
 1707 
 1708         return (0);
 1709 }
 1710 
 1711 static int
 1712 eth_bare_read(uint32_t base, int i)
 1713 {
 1714         uint32_t v;
 1715 
 1716         v = win_eth_bare_read(base);
 1717         v &= (1 << i);
 1718 
 1719         return (v >> i);
 1720 }
 1721 
 1722 static void
 1723 eth_bare_write(uint32_t base, int i, int val)
 1724 {
 1725         uint32_t v;
 1726 
 1727         v = win_eth_bare_read(base);
 1728         v &= ~(1 << i);
 1729         v |= (val << i);
 1730         win_eth_bare_write(base, v);
 1731 }
 1732 
 1733 static void
 1734 eth_epap_write(uint32_t base, int i, int val)
 1735 {
 1736         uint32_t v;
 1737 
 1738         v = win_eth_epap_read(base);
 1739         v &= ~(0x3 << (i * 2));
 1740         v |= (val << (i * 2));
 1741         win_eth_epap_write(base, v);
 1742 }
 1743 
 1744 static void
 1745 decode_win_eth_dump(u_long base)
 1746 {
 1747         int i;
 1748 
 1749         if (pm_is_disabled(CPU_PM_CTRL_GE(eth_port - 1)))
 1750                 return;
 1751 
 1752         for (i = 0; i < MV_WIN_ETH_MAX; i++) {
 1753                 printf("ETH window#%d: b 0x%08x, s 0x%08x", i,
 1754                     win_eth_br_read(base, i),
 1755                     win_eth_sz_read(base, i));
 1756 
 1757                 if (win_eth_can_remap(i))
 1758                         printf(", ha 0x%08x",
 1759                             win_eth_har_read(base, i));
 1760 
 1761                 printf("\n");
 1762         }
 1763         printf("ETH windows: bare 0x%08x, epap 0x%08x\n",
 1764             win_eth_bare_read(base),
 1765             win_eth_epap_read(base));
 1766 }
 1767 
 1768 #define MV_WIN_ETH_DDR_TRGT(n)  ddr_target(n)
 1769 
 1770 static void
 1771 decode_win_eth_setup(u_long base)
 1772 {
 1773         uint32_t br, sz;
 1774         int i, j;
 1775 
 1776         if (pm_is_disabled(CPU_PM_CTRL_GE(eth_port)))
 1777                 return;
 1778 
 1779         eth_port++;
 1780 
 1781         /* Disable, clear and revoke protection for all ETH windows */
 1782         for (i = 0; i < MV_WIN_ETH_MAX; i++) {
 1783 
 1784                 eth_bare_write(base, i, 1);
 1785                 eth_epap_write(base, i, 0);
 1786                 win_eth_br_write(base, i, 0);
 1787                 win_eth_sz_write(base, i, 0);
 1788                 if (win_eth_can_remap(i))
 1789                         win_eth_har_write(base, i, 0);
 1790         }
 1791 
 1792         /* Only access to active DRAM banks is required */
 1793         for (i = 0; i < MV_WIN_DDR_MAX; i++)
 1794                 if (ddr_is_active(i)) {
 1795 
 1796                         br = ddr_base(i) | (ddr_attr(i) << 8) | MV_WIN_ETH_DDR_TRGT(i);
 1797                         sz = ((ddr_size(i) - 1) & 0xffff0000);
 1798 
 1799                         /* Set the first free ETH window */
 1800                         for (j = 0; j < MV_WIN_ETH_MAX; j++) {
 1801                                 if (eth_bare_read(base, j) == 0)
 1802                                         continue;
 1803 
 1804                                 win_eth_br_write(base, j, br);
 1805                                 win_eth_sz_write(base, j, sz);
 1806 
 1807                                 /* XXX remapping ETH windows not supported */
 1808 
 1809                                 /* Set protection RW */
 1810                                 eth_epap_write(base, j, 0x3);
 1811 
 1812                                 /* Enable window */
 1813                                 eth_bare_write(base, j, 0);
 1814                                 break;
 1815                         }
 1816                 }
 1817 }
 1818 
 1819 static void
 1820 decode_win_neta_dump(u_long base)
 1821 {
 1822 
 1823         decode_win_eth_dump(base + MV_WIN_NETA_OFFSET);
 1824 }
 1825 
 1826 static void
 1827 decode_win_neta_setup(u_long base)
 1828 {
 1829 
 1830         decode_win_eth_setup(base + MV_WIN_NETA_OFFSET);
 1831 }
 1832 
 1833 static int
 1834 decode_win_eth_valid(void)
 1835 {
 1836 
 1837         return (decode_win_can_cover_ddr(MV_WIN_ETH_MAX));
 1838 }
 1839 
 1840 /**************************************************************************
 1841  * PCIE windows routines
 1842  **************************************************************************/
 1843 static void
 1844 decode_win_pcie_dump(u_long base)
 1845 {
 1846         int i;
 1847 
 1848         printf("PCIE windows base 0x%08lx\n", base);
 1849         for (i = 0; i < MV_WIN_PCIE_MAX; i++)
 1850                 printf("PCIE window#%d: cr 0x%08x br 0x%08x remap 0x%08x\n",
 1851                     i, win_pcie_cr_read(base, i),
 1852                     win_pcie_br_read(base, i), win_pcie_remap_read(base, i));
 1853 
 1854         for (i = 0; i < MV_PCIE_BAR_MAX; i++)
 1855                 printf("PCIE bar#%d: cr 0x%08x br 0x%08x brh 0x%08x\n",
 1856                     i, pcie_bar_cr_read(base, i),
 1857                     pcie_bar_br_read(base, i), pcie_bar_brh_read(base, i));
 1858 }
 1859 
 1860 void
 1861 decode_win_pcie_setup(u_long base)
 1862 {
 1863         uint32_t size = 0, ddrbase = ~0;
 1864         uint32_t cr, br;
 1865         int i, j;
 1866 
 1867         for (i = 0; i < MV_PCIE_BAR_MAX; i++) {
 1868                 pcie_bar_br_write(base, i,
 1869                     MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN);
 1870                 if (i < 3)
 1871                         pcie_bar_brh_write(base, i, 0);
 1872                 if (i > 0)
 1873                         pcie_bar_cr_write(base, i, 0);
 1874         }
 1875 
 1876         for (i = 0; i < MV_WIN_PCIE_MAX; i++) {
 1877                 win_pcie_cr_write(base, i, 0);
 1878                 win_pcie_br_write(base, i, 0);
 1879                 win_pcie_remap_write(base, i, 0);
 1880         }
 1881 
 1882         /* On End-Point only set BAR size to 1MB regardless of DDR size */
 1883         if ((bus_space_read_4(fdtbus_bs_tag, base, MV_PCIE_CONTROL)
 1884             & MV_PCIE_ROOT_CMPLX) == 0) {
 1885                 pcie_bar_cr_write(base, 1, 0xf0000 | 1);
 1886                 return;
 1887         }
 1888 
 1889         for (i = 0; i < MV_WIN_DDR_MAX; i++) {
 1890                 if (ddr_is_active(i)) {
 1891                         /* Map DDR to BAR 1 */
 1892                         cr = (ddr_size(i) - 1) & 0xffff0000;
 1893                         size += ddr_size(i) & 0xffff0000;
 1894                         cr |= (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
 1895                         br = ddr_base(i);
 1896                         if (br < ddrbase)
 1897                                 ddrbase = br;
 1898 
 1899                         /* Use the first available PCIE window */
 1900                         for (j = 0; j < MV_WIN_PCIE_MAX; j++) {
 1901                                 if (win_pcie_cr_read(base, j) != 0)
 1902                                         continue;
 1903 
 1904                                 win_pcie_br_write(base, j, br);
 1905                                 win_pcie_cr_write(base, j, cr);
 1906                                 break;
 1907                         }
 1908                 }
 1909         }
 1910 
 1911         /*
 1912          * Upper 16 bits in BAR register is interpreted as BAR size
 1913          * (in 64 kB units) plus 64kB, so subtract 0x10000
 1914          * form value passed to register to get correct value.
 1915          */
 1916         size -= 0x10000;
 1917         pcie_bar_cr_write(base, 1, size | 1);
 1918         pcie_bar_br_write(base, 1, ddrbase |
 1919             MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN);
 1920         pcie_bar_br_write(base, 0, fdt_immr_pa |
 1921             MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN);
 1922 }
 1923 
 1924 static int
 1925 decode_win_pcie_valid(void)
 1926 {
 1927 
 1928         return (decode_win_can_cover_ddr(MV_WIN_PCIE_MAX));
 1929 }
 1930 
 1931 /**************************************************************************
 1932  * IDMA windows routines
 1933  **************************************************************************/
 1934 #if defined(SOC_MV_ORION) || defined(SOC_MV_DISCOVERY)
 1935 static int
 1936 idma_bare_read(u_long base, int i)
 1937 {
 1938         uint32_t v;
 1939 
 1940         v = win_idma_bare_read(base);
 1941         v &= (1 << i);
 1942 
 1943         return (v >> i);
 1944 }
 1945 
 1946 static void
 1947 idma_bare_write(u_long base, int i, int val)
 1948 {
 1949         uint32_t v;
 1950 
 1951         v = win_idma_bare_read(base);
 1952         v &= ~(1 << i);
 1953         v |= (val << i);
 1954         win_idma_bare_write(base, v);
 1955 }
 1956 
 1957 /*
 1958  * Sets channel protection 'val' for window 'w' on channel 'c'
 1959  */
 1960 static void
 1961 idma_cap_write(u_long base, int c, int w, int val)
 1962 {
 1963         uint32_t v;
 1964 
 1965         v = win_idma_cap_read(base, c);
 1966         v &= ~(0x3 << (w * 2));
 1967         v |= (val << (w * 2));
 1968         win_idma_cap_write(base, c, v);
 1969 }
 1970 
 1971 /*
 1972  * Set protection 'val' on all channels for window 'w'
 1973  */
 1974 static void
 1975 idma_set_prot(u_long base, int w, int val)
 1976 {
 1977         int c;
 1978 
 1979         for (c = 0; c < MV_IDMA_CHAN_MAX; c++)
 1980                 idma_cap_write(base, c, w, val);
 1981 }
 1982 
 1983 static int
 1984 win_idma_can_remap(int i)
 1985 {
 1986 
 1987         /* IDMA decode windows 0-3 have remap capability */
 1988         if (i < 4)
 1989                 return (1);
 1990 
 1991         return (0);
 1992 }
 1993 
 1994 void
 1995 decode_win_idma_setup(u_long base)
 1996 {
 1997         uint32_t br, sz;
 1998         int i, j;
 1999 
 2000         if (pm_is_disabled(CPU_PM_CTRL_IDMA))
 2001                 return;
 2002         /*
 2003          * Disable and clear all IDMA windows, revoke protection for all channels
 2004          */
 2005         for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
 2006 
 2007                 idma_bare_write(base, i, 1);
 2008                 win_idma_br_write(base, i, 0);
 2009                 win_idma_sz_write(base, i, 0);
 2010                 if (win_idma_can_remap(i) == 1)
 2011                         win_idma_har_write(base, i, 0);
 2012         }
 2013         for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
 2014                 win_idma_cap_write(base, i, 0);
 2015 
 2016         /*
 2017          * Set up access to all active DRAM banks
 2018          */
 2019         for (i = 0; i < MV_WIN_DDR_MAX; i++)
 2020                 if (ddr_is_active(i)) {
 2021                         br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
 2022                         sz = ((ddr_size(i) - 1) & 0xffff0000);
 2023 
 2024                         /* Place DDR entries in non-remapped windows */
 2025                         for (j = 0; j < MV_WIN_IDMA_MAX; j++)
 2026                                 if (win_idma_can_remap(j) != 1 &&
 2027                                     idma_bare_read(base, j) == 1) {
 2028 
 2029                                         /* Configure window */
 2030                                         win_idma_br_write(base, j, br);
 2031                                         win_idma_sz_write(base, j, sz);
 2032 
 2033                                         /* Set protection RW on all channels */
 2034                                         idma_set_prot(base, j, 0x3);
 2035 
 2036                                         /* Enable window */
 2037                                         idma_bare_write(base, j, 0);
 2038                                         break;
 2039                                 }
 2040                 }
 2041 
 2042         /*
 2043          * Remaining targets -- from statically defined table
 2044          */
 2045         for (i = 0; i < idma_wins_no; i++)
 2046                 if (idma_wins[i].target > 0) {
 2047                         br = (idma_wins[i].base & 0xffff0000) |
 2048                             (idma_wins[i].attr << 8) | idma_wins[i].target;
 2049                         sz = ((idma_wins[i].size - 1) & 0xffff0000);
 2050 
 2051                         /* Set the first free IDMA window */
 2052                         for (j = 0; j < MV_WIN_IDMA_MAX; j++) {
 2053                                 if (idma_bare_read(base, j) == 0)
 2054                                         continue;
 2055 
 2056                                 /* Configure window */
 2057                                 win_idma_br_write(base, j, br);
 2058                                 win_idma_sz_write(base, j, sz);
 2059                                 if (win_idma_can_remap(j) &&
 2060                                     idma_wins[j].remap >= 0)
 2061                                         win_idma_har_write(base, j,
 2062                                             idma_wins[j].remap);
 2063 
 2064                                 /* Set protection RW on all channels */
 2065                                 idma_set_prot(base, j, 0x3);
 2066 
 2067                                 /* Enable window */
 2068                                 idma_bare_write(base, j, 0);
 2069                                 break;
 2070                         }
 2071                 }
 2072 }
 2073 
 2074 int
 2075 decode_win_idma_valid(void)
 2076 {
 2077         const struct decode_win *wintab;
 2078         int c, i, j, rv;
 2079         uint32_t b, e, s;
 2080 
 2081         if (idma_wins_no > MV_WIN_IDMA_MAX) {
 2082                 printf("IDMA windows: too many entries: %d\n", idma_wins_no);
 2083                 return (0);
 2084         }
 2085         for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
 2086                 if (ddr_is_active(i))
 2087                         c++;
 2088 
 2089         if (idma_wins_no > (MV_WIN_IDMA_MAX - c)) {
 2090                 printf("IDMA windows: too many entries: %d, available: %d\n",
 2091                     idma_wins_no, MV_WIN_IDMA_MAX - c);
 2092                 return (0);
 2093         }
 2094 
 2095         wintab = idma_wins;
 2096         rv = 1;
 2097         for (i = 0; i < idma_wins_no; i++, wintab++) {
 2098 
 2099                 if (wintab->target == 0) {
 2100                         printf("IDMA window#%d: DDR target window is not "
 2101                             "supposed to be reprogrammed!\n", i);
 2102                         rv = 0;
 2103                 }
 2104 
 2105                 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
 2106                         printf("IDMA window#%d: not capable of remapping, but "
 2107                             "val 0x%08x defined\n", i, wintab->remap);
 2108                         rv = 0;
 2109                 }
 2110 
 2111                 s = wintab->size;
 2112                 b = wintab->base;
 2113                 e = b + s - 1;
 2114                 if (s > (0xFFFFFFFF - b + 1)) {
 2115                         /* XXX this boundary check should account for 64bit and
 2116                          * remapping.. */
 2117                         printf("IDMA window#%d: no space for size 0x%08x at "
 2118                             "0x%08x\n", i, s, b);
 2119                         rv = 0;
 2120                         continue;
 2121                 }
 2122 
 2123                 j = decode_win_overlap(i, idma_wins_no, &idma_wins[0]);
 2124                 if (j >= 0) {
 2125                         printf("IDMA window#%d: (0x%08x - 0x%08x) overlaps "
 2126                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
 2127                             idma_wins[j].base,
 2128                             idma_wins[j].base + idma_wins[j].size - 1);
 2129                         rv = 0;
 2130                 }
 2131         }
 2132 
 2133         return (rv);
 2134 }
 2135 
 2136 void
 2137 decode_win_idma_dump(u_long base)
 2138 {
 2139         int i;
 2140 
 2141         if (pm_is_disabled(CPU_PM_CTRL_IDMA))
 2142                 return;
 2143 
 2144         for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
 2145                 printf("IDMA window#%d: b 0x%08x, s 0x%08x", i,
 2146                     win_idma_br_read(base, i), win_idma_sz_read(base, i));
 2147                 
 2148                 if (win_idma_can_remap(i))
 2149                         printf(", ha 0x%08x", win_idma_har_read(base, i));
 2150 
 2151                 printf("\n");
 2152         }
 2153         for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
 2154                 printf("IDMA channel#%d: ap 0x%08x\n", i,
 2155                     win_idma_cap_read(base, i));
 2156         printf("IDMA windows: bare 0x%08x\n", win_idma_bare_read(base));
 2157 }
 2158 #else
 2159 
 2160 /* Provide dummy functions to satisfy the build for SoCs not equipped with IDMA */
 2161 int
 2162 decode_win_idma_valid(void)
 2163 {
 2164 
 2165         return (1);
 2166 }
 2167 
 2168 void
 2169 decode_win_idma_setup(u_long base)
 2170 {
 2171 }
 2172 
 2173 void
 2174 decode_win_idma_dump(u_long base)
 2175 {
 2176 }
 2177 #endif
 2178 
 2179 /**************************************************************************
 2180  * XOR windows routines
 2181  **************************************************************************/
 2182 #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
 2183 static int
 2184 xor_ctrl_read(u_long base, int i, int c, int e)
 2185 {
 2186         uint32_t v;
 2187         v = win_xor_ctrl_read(base, c, e);
 2188         v &= (1 << i);
 2189 
 2190         return (v >> i);
 2191 }
 2192 
 2193 static void
 2194 xor_ctrl_write(u_long base, int i, int c, int e, int val)
 2195 {
 2196         uint32_t v;
 2197 
 2198         v = win_xor_ctrl_read(base, c, e);
 2199         v &= ~(1 << i);
 2200         v |= (val << i);
 2201         win_xor_ctrl_write(base, c, e, v);
 2202 }
 2203 
 2204 /*
 2205  * Set channel protection 'val' for window 'w' on channel 'c'
 2206  */
 2207 static void
 2208 xor_chan_write(u_long base, int c, int e, int w, int val)
 2209 {
 2210         uint32_t v;
 2211 
 2212         v = win_xor_ctrl_read(base, c, e);
 2213         v &= ~(0x3 << (w * 2 + 16));
 2214         v |= (val << (w * 2 + 16));
 2215         win_xor_ctrl_write(base, c, e, v);
 2216 }
 2217 
 2218 /*
 2219  * Set protection 'val' on all channels for window 'w' on engine 'e'
 2220  */
 2221 static void
 2222 xor_set_prot(u_long base, int w, int e, int val)
 2223 {
 2224         int c;
 2225 
 2226         for (c = 0; c < MV_XOR_CHAN_MAX; c++)
 2227                 xor_chan_write(base, c, e, w, val);
 2228 }
 2229 
 2230 static int
 2231 win_xor_can_remap(int i)
 2232 {
 2233 
 2234         /* XOR decode windows 0-3 have remap capability */
 2235         if (i < 4)
 2236                 return (1);
 2237 
 2238         return (0);
 2239 }
 2240 
 2241 static int
 2242 xor_max_eng(void)
 2243 {
 2244         uint32_t dev, rev;
 2245 
 2246         soc_id(&dev, &rev);
 2247         switch (dev) {
 2248         case MV_DEV_88F6281:
 2249         case MV_DEV_88F6282:
 2250         case MV_DEV_MV78130:
 2251         case MV_DEV_MV78160:
 2252         case MV_DEV_MV78230:
 2253         case MV_DEV_MV78260:
 2254         case MV_DEV_MV78460:
 2255                 return (2);
 2256         case MV_DEV_MV78100:
 2257         case MV_DEV_MV78100_Z0:
 2258                 return (1);
 2259         default:
 2260                 return (0);
 2261         }
 2262 }
 2263 
 2264 static void
 2265 xor_active_dram(u_long base, int c, int e, int *window)
 2266 {
 2267         uint32_t br, sz;
 2268         int i, m, w;
 2269 
 2270         /*
 2271          * Set up access to all active DRAM banks
 2272          */
 2273         m = xor_max_eng();
 2274         for (i = 0; i < m; i++)
 2275                 if (ddr_is_active(i)) {
 2276                         br = ddr_base(i) | (ddr_attr(i) << 8) |
 2277                             ddr_target(i);
 2278                         sz = ((ddr_size(i) - 1) & 0xffff0000);
 2279 
 2280                         /* Place DDR entries in non-remapped windows */
 2281                         for (w = 0; w < MV_WIN_XOR_MAX; w++)
 2282                                 if (win_xor_can_remap(w) != 1 &&
 2283                                     (xor_ctrl_read(base, w, c, e) == 0) &&
 2284                                     w > *window) {
 2285                                         /* Configure window */
 2286                                         win_xor_br_write(base, w, e, br);
 2287                                         win_xor_sz_write(base, w, e, sz);
 2288 
 2289                                         /* Set protection RW on all channels */
 2290                                         xor_set_prot(base, w, e, 0x3);
 2291 
 2292                                         /* Enable window */
 2293                                         xor_ctrl_write(base, w, c, e, 1);
 2294                                         (*window)++;
 2295                                         break;
 2296                                 }
 2297                 }
 2298 }
 2299 
 2300 void
 2301 decode_win_xor_setup(u_long base)
 2302 {
 2303         uint32_t br, sz;
 2304         int i, j, z, e = 1, m, window;
 2305 
 2306         if (pm_is_disabled(CPU_PM_CTRL_XOR))
 2307                 return;
 2308 
 2309         /*
 2310          * Disable and clear all XOR windows, revoke protection for all
 2311          * channels
 2312          */
 2313         m = xor_max_eng();
 2314         for (j = 0; j < m; j++, e--) {
 2315 
 2316                 /* Number of non-remaped windows */
 2317                 window = MV_XOR_NON_REMAP - 1;
 2318 
 2319                 for (i = 0; i < MV_WIN_XOR_MAX; i++) {
 2320                         win_xor_br_write(base, i, e, 0);
 2321                         win_xor_sz_write(base, i, e, 0);
 2322                 }
 2323 
 2324                 if (win_xor_can_remap(i) == 1)
 2325                         win_xor_har_write(base, i, e, 0);
 2326 
 2327                 for (i = 0; i < MV_XOR_CHAN_MAX; i++) {
 2328                         win_xor_ctrl_write(base, i, e, 0);
 2329                         xor_active_dram(base, i, e, &window);
 2330                 }
 2331 
 2332                 /*
 2333                  * Remaining targets -- from a statically defined table
 2334                  */
 2335                 for (i = 0; i < xor_wins_no; i++)
 2336                         if (xor_wins[i].target > 0) {
 2337                                 br = (xor_wins[i].base & 0xffff0000) |
 2338                                     (xor_wins[i].attr << 8) |
 2339                                     xor_wins[i].target;
 2340                                 sz = ((xor_wins[i].size - 1) & 0xffff0000);
 2341 
 2342                                 /* Set the first free XOR window */
 2343                                 for (z = 0; z < MV_WIN_XOR_MAX; z++) {
 2344                                         if (xor_ctrl_read(base, z, 0, e) &&
 2345                                             xor_ctrl_read(base, z, 1, e))
 2346                                                 continue;
 2347 
 2348                                         /* Configure window */
 2349                                         win_xor_br_write(base, z, e, br);
 2350                                         win_xor_sz_write(base, z, e, sz);
 2351                                         if (win_xor_can_remap(z) &&
 2352                                             xor_wins[z].remap >= 0)
 2353                                                 win_xor_har_write(base, z, e,
 2354                                                     xor_wins[z].remap);
 2355 
 2356                                         /* Set protection RW on all channels */
 2357                                         xor_set_prot(base, z, e, 0x3);
 2358 
 2359                                         /* Enable window */
 2360                                         xor_ctrl_write(base, z, 0, e, 1);
 2361                                         xor_ctrl_write(base, z, 1, e, 1);
 2362                                         break;
 2363                                 }
 2364                         }
 2365         }
 2366 }
 2367 
 2368 int
 2369 decode_win_xor_valid(void)
 2370 {
 2371         const struct decode_win *wintab;
 2372         int c, i, j, rv;
 2373         uint32_t b, e, s;
 2374 
 2375         if (xor_wins_no > MV_WIN_XOR_MAX) {
 2376                 printf("XOR windows: too many entries: %d\n", xor_wins_no);
 2377                 return (0);
 2378         }
 2379         for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
 2380                 if (ddr_is_active(i))
 2381                         c++;
 2382 
 2383         if (xor_wins_no > (MV_WIN_XOR_MAX - c)) {
 2384                 printf("XOR windows: too many entries: %d, available: %d\n",
 2385                     xor_wins_no, MV_WIN_IDMA_MAX - c);
 2386                 return (0);
 2387         }
 2388 
 2389         wintab = xor_wins;
 2390         rv = 1;
 2391         for (i = 0; i < xor_wins_no; i++, wintab++) {
 2392 
 2393                 if (wintab->target == 0) {
 2394                         printf("XOR window#%d: DDR target window is not "
 2395                             "supposed to be reprogrammed!\n", i);
 2396                         rv = 0;
 2397                 }
 2398 
 2399                 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
 2400                         printf("XOR window#%d: not capable of remapping, but "
 2401                             "val 0x%08x defined\n", i, wintab->remap);
 2402                         rv = 0;
 2403                 }
 2404 
 2405                 s = wintab->size;
 2406                 b = wintab->base;
 2407                 e = b + s - 1;
 2408                 if (s > (0xFFFFFFFF - b + 1)) {
 2409                         /*
 2410                          * XXX this boundary check should account for 64bit
 2411                          * and remapping..
 2412                          */
 2413                         printf("XOR window#%d: no space for size 0x%08x at "
 2414                             "0x%08x\n", i, s, b);
 2415                         rv = 0;
 2416                         continue;
 2417                 }
 2418 
 2419                 j = decode_win_overlap(i, xor_wins_no, &xor_wins[0]);
 2420                 if (j >= 0) {
 2421                         printf("XOR window#%d: (0x%08x - 0x%08x) overlaps "
 2422                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
 2423                             xor_wins[j].base,
 2424                             xor_wins[j].base + xor_wins[j].size - 1);
 2425                         rv = 0;
 2426                 }
 2427         }
 2428 
 2429         return (rv);
 2430 }
 2431 
 2432 void
 2433 decode_win_xor_dump(u_long base)
 2434 {
 2435         int i, j;
 2436         int e = 1;
 2437 
 2438         if (pm_is_disabled(CPU_PM_CTRL_XOR))
 2439                 return;
 2440 
 2441         for (j = 0; j < xor_max_eng(); j++, e--) {
 2442                 for (i = 0; i < MV_WIN_XOR_MAX; i++) {
 2443                         printf("XOR window#%d: b 0x%08x, s 0x%08x", i,
 2444                             win_xor_br_read(base, i, e), win_xor_sz_read(base, i, e));
 2445 
 2446                         if (win_xor_can_remap(i))
 2447                                 printf(", ha 0x%08x", win_xor_har_read(base, i, e));
 2448 
 2449                         printf("\n");
 2450                 }
 2451                 for (i = 0; i < MV_XOR_CHAN_MAX; i++)
 2452                         printf("XOR control#%d: 0x%08x\n", i,
 2453                             win_xor_ctrl_read(base, i, e));
 2454         }
 2455 }
 2456 
 2457 #else
 2458 /* Provide dummy functions to satisfy the build for SoCs not equipped with XOR */
 2459 static int
 2460 decode_win_xor_valid(void)
 2461 {
 2462 
 2463         return (1);
 2464 }
 2465 
 2466 static void
 2467 decode_win_xor_setup(u_long base)
 2468 {
 2469 }
 2470 
 2471 static void
 2472 decode_win_xor_dump(u_long base)
 2473 {
 2474 }
 2475 #endif
 2476 
 2477 /**************************************************************************
 2478  * SATA windows routines
 2479  **************************************************************************/
 2480 static void
 2481 decode_win_sata_setup(u_long base)
 2482 {
 2483         uint32_t cr, br;
 2484         int i, j;
 2485 
 2486         if (pm_is_disabled(CPU_PM_CTRL_SATA))
 2487                 return;
 2488 
 2489         for (i = 0; i < MV_WIN_SATA_MAX; i++) {
 2490                 win_sata_cr_write(base, i, 0);
 2491                 win_sata_br_write(base, i, 0);
 2492         }
 2493 
 2494         for (i = 0; i < MV_WIN_DDR_MAX; i++)
 2495                 if (ddr_is_active(i)) {
 2496                         cr = ((ddr_size(i) - 1) & 0xffff0000) |
 2497                             (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
 2498                         br = ddr_base(i);
 2499 
 2500                         /* Use the first available SATA window */
 2501                         for (j = 0; j < MV_WIN_SATA_MAX; j++) {
 2502                                 if ((win_sata_cr_read(base, j) & 1) != 0)
 2503                                         continue;
 2504 
 2505                                 win_sata_br_write(base, j, br);
 2506                                 win_sata_cr_write(base, j, cr);
 2507                                 break;
 2508                         }
 2509                 }
 2510 }
 2511 
 2512 /*
 2513  * Configure AHCI decoding windows
 2514  */
 2515 static void
 2516 decode_win_ahci_setup(u_long base)
 2517 {
 2518         uint32_t br, cr, sz;
 2519         int i, j;
 2520 
 2521         for (i = 0; i < MV_WIN_SATA_MAX_ARMADA38X; i++) {
 2522                 win_sata_armada38x_cr_write(base, i, 0);
 2523                 win_sata_armada38x_br_write(base, i, 0);
 2524                 win_sata_armada38x_sz_write(base, i, 0);
 2525         }
 2526 
 2527         for (i = 0; i < MV_WIN_DDR_MAX; i++) {
 2528                 if (ddr_is_active(i)) {
 2529                         cr = (ddr_attr(i) << IO_WIN_ATTR_SHIFT) |
 2530                             (ddr_target(i) << IO_WIN_TGT_SHIFT) |
 2531                             IO_WIN_ENA_MASK;
 2532                         br = ddr_base(i);
 2533                         sz = (ddr_size(i) - 1) &
 2534                             (IO_WIN_SIZE_MASK << IO_WIN_SIZE_SHIFT);
 2535 
 2536                         /* Use first available SATA window */
 2537                         for (j = 0; j < MV_WIN_SATA_MAX_ARMADA38X; j++) {
 2538                                 if (win_sata_armada38x_cr_read(base, j) & IO_WIN_ENA_MASK)
 2539                                         continue;
 2540 
 2541                                 /* BASE is set to DRAM base (0x00000000) */
 2542                                 win_sata_armada38x_br_write(base, j, br);
 2543                                 /* CTRL targets DRAM ctrl with 0x0E or 0x0D */
 2544                                 win_sata_armada38x_cr_write(base, j, cr);
 2545                                 /* SIZE is set to 16MB - max value */
 2546                                 win_sata_armada38x_sz_write(base, j, sz);
 2547                                 break;
 2548                         }
 2549                 }
 2550         }
 2551 }
 2552 
 2553 static void
 2554 decode_win_ahci_dump(u_long base)
 2555 {
 2556         int i;
 2557 
 2558         for (i = 0; i < MV_WIN_SATA_MAX_ARMADA38X; i++)
 2559                 printf("SATA window#%d: cr 0x%08x, br 0x%08x, sz 0x%08x\n", i,
 2560                     win_sata_armada38x_cr_read(base, i), win_sata_br_read(base, i),
 2561                     win_sata_armada38x_sz_read(base,i));
 2562 }
 2563 
 2564 static int
 2565 decode_win_sata_valid(void)
 2566 {
 2567         uint32_t dev, rev;
 2568 
 2569         soc_id(&dev, &rev);
 2570         if (dev == MV_DEV_88F5281)
 2571                 return (1);
 2572 
 2573         return (decode_win_can_cover_ddr(MV_WIN_SATA_MAX));
 2574 }
 2575 
 2576 static void
 2577 decode_win_sdhci_setup(u_long base)
 2578 {
 2579         uint32_t cr, br;
 2580         int i, j;
 2581 
 2582         for (i = 0; i < MV_WIN_SDHCI_MAX; i++) {
 2583                 win_sdhci_cr_write(base, i, 0);
 2584                 win_sdhci_br_write(base, i, 0);
 2585         }
 2586 
 2587         for (i = 0; i < MV_WIN_DDR_MAX; i++)
 2588                 if (ddr_is_active(i)) {
 2589                         br = ddr_base(i);
 2590                         cr = (((ddr_size(i) - 1) &
 2591                             (IO_WIN_SIZE_MASK << IO_WIN_SIZE_SHIFT)) |
 2592                             (ddr_attr(i) << IO_WIN_ATTR_SHIFT) |
 2593                             (ddr_target(i) << IO_WIN_TGT_SHIFT) |
 2594                             IO_WIN_ENA_MASK);
 2595 
 2596                         /* Use the first available SDHCI window */
 2597                         for (j = 0; j < MV_WIN_SDHCI_MAX; j++) {
 2598                                 if (win_sdhci_cr_read(base, j) & IO_WIN_ENA_MASK)
 2599                                         continue;
 2600 
 2601                                 win_sdhci_cr_write(base, j, cr);
 2602                                 win_sdhci_br_write(base, j, br);
 2603                                 break;
 2604                         }
 2605                 }
 2606 }
 2607 
 2608 static void
 2609 decode_win_sdhci_dump(u_long base)
 2610 {
 2611         int i;
 2612 
 2613         for (i = 0; i < MV_WIN_SDHCI_MAX; i++)
 2614                 printf("SDHCI window#%d: c 0x%08x, b 0x%08x\n", i,
 2615                     win_sdhci_cr_read(base, i), win_sdhci_br_read(base, i));
 2616 }
 2617 
 2618 static int
 2619 decode_win_sdhci_valid(void)
 2620 {
 2621 
 2622         return (decode_win_can_cover_ddr(MV_WIN_SDHCI_MAX));
 2623 }
 2624 
 2625 /**************************************************************************
 2626  * FDT parsing routines.
 2627  **************************************************************************/
 2628 
 2629 static int
 2630 fdt_get_ranges(const char *nodename, void *buf, int size, int *tuples,
 2631     int *tuplesize)
 2632 {
 2633         phandle_t node;
 2634         pcell_t addr_cells, par_addr_cells, size_cells;
 2635         int len, tuple_size, tuples_count;
 2636 
 2637         node = OF_finddevice(nodename);
 2638         if (node == -1)
 2639                 return (EINVAL);
 2640 
 2641         if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
 2642                 return (ENXIO);
 2643 
 2644         par_addr_cells = fdt_parent_addr_cells(node);
 2645         if (par_addr_cells > 2)
 2646                 return (ERANGE);
 2647 
 2648         tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells +
 2649             size_cells);
 2650 
 2651         /* Note the OF_getprop_alloc() cannot be used at this early stage. */
 2652         len = OF_getprop(node, "ranges", buf, size);
 2653 
 2654         /*
 2655          * XXX this does not handle the empty 'ranges;' case, which is
 2656          * legitimate and should be allowed.
 2657          */
 2658         tuples_count = len / tuple_size;
 2659         if (tuples_count <= 0)
 2660                 return (ERANGE);
 2661 
 2662         if (par_addr_cells > 2 || addr_cells > 2 || size_cells > 2)
 2663                 return (ERANGE);
 2664 
 2665         *tuples = tuples_count;
 2666         *tuplesize = tuple_size;
 2667         return (0);
 2668 }
 2669 
 2670 static int
 2671 win_cpu_from_dt(void)
 2672 {
 2673         pcell_t ranges[48];
 2674         phandle_t node;
 2675         int i, entry_size, err, t, tuple_size, tuples;
 2676         u_long sram_base, sram_size;
 2677 
 2678         t = 0;
 2679         /* Retrieve 'ranges' property of '/localbus' node. */
 2680         if ((err = fdt_get_ranges("/localbus", ranges, sizeof(ranges),
 2681             &tuples, &tuple_size)) == 0) {
 2682                 /*
 2683                  * Fill CPU decode windows table.
 2684                  */
 2685                 bzero((void *)&cpu_win_tbl, sizeof(cpu_win_tbl));
 2686 
 2687                 entry_size = tuple_size / sizeof(pcell_t);
 2688                 cpu_wins_no = tuples;
 2689 
 2690                 /* Check range */
 2691                 if (tuples > nitems(cpu_win_tbl)) {
 2692                         debugf("too many tuples to fit into cpu_win_tbl\n");
 2693                         return (ENOMEM);
 2694                 }
 2695 
 2696                 for (i = 0, t = 0; t < tuples; i += entry_size, t++) {
 2697                         cpu_win_tbl[t].target = 1;
 2698                         cpu_win_tbl[t].attr = fdt32_to_cpu(ranges[i + 1]);
 2699                         cpu_win_tbl[t].base = fdt32_to_cpu(ranges[i + 2]);
 2700                         cpu_win_tbl[t].size = fdt32_to_cpu(ranges[i + 3]);
 2701                         cpu_win_tbl[t].remap = ~0;
 2702                         debugf("target = 0x%0x attr = 0x%0x base = 0x%0x "
 2703                             "size = 0x%0x remap = 0x%0x\n",
 2704                             cpu_win_tbl[t].target,
 2705                             cpu_win_tbl[t].attr, cpu_win_tbl[t].base,
 2706                             cpu_win_tbl[t].size, cpu_win_tbl[t].remap);
 2707                 }
 2708         }
 2709 
 2710         /*
 2711          * Retrieve CESA SRAM data.
 2712          */
 2713         if ((node = OF_finddevice("sram")) != -1)
 2714                 if (ofw_bus_node_is_compatible(node, "mrvl,cesa-sram"))
 2715                         goto moveon;
 2716 
 2717         if ((node = OF_finddevice("/")) == -1)
 2718                 return (ENXIO);
 2719 
 2720         if ((node = fdt_find_compatible(node, "mrvl,cesa-sram", 0)) == 0)
 2721                 /* SRAM block is not always present. */
 2722                 return (0);
 2723 moveon:
 2724         sram_base = sram_size = 0;
 2725         if (fdt_regsize(node, &sram_base, &sram_size) != 0)
 2726                 return (EINVAL);
 2727 
 2728         /* Check range */
 2729         if (t >= nitems(cpu_win_tbl)) {
 2730                 debugf("cannot fit CESA tuple into cpu_win_tbl\n");
 2731                 return (ENOMEM);
 2732         }
 2733 
 2734         cpu_win_tbl[t].target = soc_decode_win_spec->win_cesa_target;
 2735         if (soc_family == MV_SOC_ARMADA_38X)
 2736                 cpu_win_tbl[t].attr = soc_decode_win_spec->win_cesa_attr(0);
 2737         else
 2738                 cpu_win_tbl[t].attr = soc_decode_win_spec->win_cesa_attr(1);
 2739         cpu_win_tbl[t].base = sram_base;
 2740         cpu_win_tbl[t].size = sram_size;
 2741         cpu_win_tbl[t].remap = ~0;
 2742         cpu_wins_no++;
 2743         debugf("sram: base = 0x%0lx size = 0x%0lx\n", sram_base, sram_size);
 2744 
 2745         /* Check if there is a second CESA node */
 2746         while ((node = OF_peer(node)) != 0) {
 2747                 if (ofw_bus_node_is_compatible(node, "mrvl,cesa-sram")) {
 2748                         if (fdt_regsize(node, &sram_base, &sram_size) != 0)
 2749                                 return (EINVAL);
 2750                         break;
 2751                 }
 2752         }
 2753 
 2754         if (node == 0)
 2755                 return (0);
 2756 
 2757         t++;
 2758         if (t >= nitems(cpu_win_tbl)) {
 2759                 debugf("cannot fit CESA tuple into cpu_win_tbl\n");
 2760                 return (ENOMEM);
 2761         }
 2762 
 2763         /* Configure window for CESA1 */
 2764         cpu_win_tbl[t].target = soc_decode_win_spec->win_cesa_target;
 2765         cpu_win_tbl[t].attr = soc_decode_win_spec->win_cesa_attr(1);
 2766         cpu_win_tbl[t].base = sram_base;
 2767         cpu_win_tbl[t].size = sram_size;
 2768         cpu_win_tbl[t].remap = ~0;
 2769         cpu_wins_no++;
 2770         debugf("sram: base = 0x%0lx size = 0x%0lx\n", sram_base, sram_size);
 2771 
 2772         return (0);
 2773 }
 2774 
 2775 static int
 2776 fdt_win_process(phandle_t child)
 2777 {
 2778         int i, ret;
 2779 
 2780         for (i = 0; soc_nodes[i].compat != NULL; i++) {
 2781                 /* Setup only for enabled devices */
 2782                 if (ofw_bus_node_status_okay(child) == 0)
 2783                         continue;
 2784 
 2785                 if (!ofw_bus_node_is_compatible(child, soc_nodes[i].compat))
 2786                         continue;
 2787 
 2788                 ret = fdt_win_process_child(child, &soc_nodes[i], "reg");
 2789                 if (ret != 0)
 2790                         return (ret);
 2791         }
 2792 
 2793         return (0);
 2794 }
 2795 
 2796 static int
 2797 fdt_win_process_child(phandle_t child, struct soc_node_spec *soc_node,
 2798     const char* mimo_reg_source)
 2799 {
 2800         int addr_cells, size_cells;
 2801         pcell_t reg[8];
 2802         u_long size, base;
 2803 
 2804         if (fdt_addrsize_cells(OF_parent(child), &addr_cells,
 2805             &size_cells))
 2806                 return (ENXIO);
 2807 
 2808         if ((sizeof(pcell_t) * (addr_cells + size_cells)) > sizeof(reg))
 2809                 return (ENOMEM);
 2810         if (OF_getprop(child, mimo_reg_source, &reg, sizeof(reg)) <= 0)
 2811                 return (EINVAL);
 2812 
 2813         if (addr_cells <= 2)
 2814                 base = fdt_data_get(&reg[0], addr_cells);
 2815         else
 2816                 base = fdt_data_get(&reg[addr_cells - 2], 2);
 2817         size = fdt_data_get(&reg[addr_cells], size_cells);
 2818 
 2819         if (soc_node->valid_handler != NULL)
 2820                 if (!soc_node->valid_handler())
 2821                         return (EINVAL);
 2822 
 2823         base = (base & 0x000fffff) | fdt_immr_va;
 2824         if (soc_node->decode_handler != NULL)
 2825                 soc_node->decode_handler(base);
 2826         else
 2827                 return (ENXIO);
 2828 
 2829         if (MV_DUMP_WIN && (soc_node->dump_handler != NULL))
 2830                 soc_node->dump_handler(base);
 2831 
 2832         return (0);
 2833 }
 2834 
 2835 static int
 2836 fdt_win_setup(void)
 2837 {
 2838         phandle_t node, child, sb;
 2839         phandle_t child_pci;
 2840         int err;
 2841 
 2842         sb = 0;
 2843         node = OF_finddevice("/");
 2844         if (node == -1)
 2845                 panic("fdt_win_setup: no root node");
 2846 
 2847         /* Allow for coherent transactions on the A38x MBUS */
 2848         if (ofw_bus_node_is_compatible(node, "marvell,armada380"))
 2849                 platform_io_coherent = true;
 2850 
 2851         /*
 2852          * Traverse through all children of root and simple-bus nodes.
 2853          * For each found device retrieve decode windows data (if applicable).
 2854          */
 2855         child = OF_child(node);
 2856         while (child != 0) {
 2857                 /* Lookup for callback and run */
 2858                 err = fdt_win_process(child);
 2859                 if (err != 0)
 2860                         return (err);
 2861 
 2862                 /* Process Marvell Armada-XP/38x PCIe controllers */
 2863                 if (ofw_bus_node_is_compatible(child, "marvell,armada-370-pcie")) {
 2864                         child_pci = OF_child(child);
 2865                         while (child_pci != 0) {
 2866                                 err = fdt_win_process_child(child_pci,
 2867                                     &soc_nodes[SOC_NODE_PCIE_ENTRY_IDX],
 2868                                     "assigned-addresses");
 2869                                 if (err != 0)
 2870                                         return (err);
 2871 
 2872                                 child_pci = OF_peer(child_pci);
 2873                         }
 2874                 }
 2875 
 2876                 /*
 2877                  * Once done with root-level children let's move down to
 2878                  * simple-bus and its children.
 2879                  */
 2880                 child = OF_peer(child);
 2881                 if ((child == 0) && (node == OF_finddevice("/"))) {
 2882                         sb = node = fdt_find_compatible(node, "simple-bus", 0);
 2883                         if (node == 0)
 2884                                 return (ENXIO);
 2885                         child = OF_child(node);
 2886                 }
 2887                 /*
 2888                  * Next, move one more level down to internal-regs node (if
 2889                  * it is present) and its children. This node also have
 2890                  * "simple-bus" compatible.
 2891                  */
 2892                 if ((child == 0) && (node == sb)) {
 2893                         node = fdt_find_compatible(node, "simple-bus", 0);
 2894                         if (node == 0)
 2895                                 return (0);
 2896                         child = OF_child(node);
 2897                 }
 2898         }
 2899 
 2900         return (0);
 2901 }
 2902 
 2903 static void
 2904 fdt_fixup_busfreq(phandle_t root)
 2905 {
 2906         phandle_t sb;
 2907         pcell_t freq;
 2908 
 2909         freq = cpu_to_fdt32(get_tclk());
 2910 
 2911         /*
 2912          * Fix bus speed in cpu node
 2913          */
 2914         if ((sb = OF_finddevice("cpu")) != -1)
 2915                 if (fdt_is_compatible_strict(sb, "ARM,88VS584"))
 2916                         OF_setprop(sb, "bus-frequency", (void *)&freq,
 2917                             sizeof(freq));
 2918 
 2919         /*
 2920          * This fixup sets the simple-bus bus-frequency property.
 2921          */
 2922         if ((sb = fdt_find_compatible(root, "simple-bus", 1)) != 0)
 2923                 OF_setprop(sb, "bus-frequency", (void *)&freq, sizeof(freq));
 2924 }
 2925 
 2926 static void
 2927 fdt_fixup_ranges(phandle_t root)
 2928 {
 2929         phandle_t node;
 2930         pcell_t par_addr_cells, addr_cells, size_cells;
 2931         pcell_t ranges[3], reg[2], *rangesptr;
 2932         int len, tuple_size, tuples_count;
 2933         uint32_t base;
 2934 
 2935         /* Fix-up SoC ranges according to real fdt_immr_pa */
 2936         if ((node = fdt_find_compatible(root, "simple-bus", 1)) != 0) {
 2937                 if (fdt_addrsize_cells(node, &addr_cells, &size_cells) == 0 &&
 2938                     ((par_addr_cells = fdt_parent_addr_cells(node)) <= 2)) {
 2939                         tuple_size = sizeof(pcell_t) * (par_addr_cells +
 2940                            addr_cells + size_cells);
 2941                         len = OF_getprop(node, "ranges", ranges,
 2942                             sizeof(ranges));
 2943                         tuples_count = len / tuple_size;
 2944                         /* Unexpected settings are not supported */
 2945                         if (tuples_count != 1)
 2946                                 goto fixup_failed;
 2947 
 2948                         rangesptr = &ranges[0];
 2949                         rangesptr += par_addr_cells;
 2950                         base = fdt_data_get((void *)rangesptr, addr_cells);
 2951                         *rangesptr = cpu_to_fdt32(fdt_immr_pa);
 2952                         if (OF_setprop(node, "ranges", (void *)&ranges[0],
 2953                             sizeof(ranges)) < 0)
 2954                                 goto fixup_failed;
 2955                 }
 2956         }
 2957 
 2958         /* Fix-up PCIe reg according to real PCIe registers' PA */
 2959         if ((node = fdt_find_compatible(root, "mrvl,pcie", 1)) != 0) {
 2960                 if (fdt_addrsize_cells(OF_parent(node), &par_addr_cells,
 2961                     &size_cells) == 0) {
 2962                         tuple_size = sizeof(pcell_t) * (par_addr_cells +
 2963                             size_cells);
 2964                         len = OF_getprop(node, "reg", reg, sizeof(reg));
 2965                         tuples_count = len / tuple_size;
 2966                         /* Unexpected settings are not supported */
 2967                         if (tuples_count != 1)
 2968                                 goto fixup_failed;
 2969 
 2970                         base = fdt_data_get((void *)&reg[0], par_addr_cells);
 2971                         base &= ~0xFF000000;
 2972                         base |= fdt_immr_pa;
 2973                         reg[0] = cpu_to_fdt32(base);
 2974                         if (OF_setprop(node, "reg", (void *)&reg[0],
 2975                             sizeof(reg)) < 0)
 2976                                 goto fixup_failed;
 2977                 }
 2978         }
 2979         /* Fix-up succeeded. May return and continue */
 2980         return;
 2981 
 2982 fixup_failed:
 2983         while (1) {
 2984                 /*
 2985                  * In case of any error while fixing ranges just hang.
 2986                  *      1. No message can be displayed yet since console
 2987                  *         is not initialized.
 2988                  *      2. Going further will cause failure on bus_space_map()
 2989                  *         relying on the wrong ranges or data abort when
 2990                  *         accessing PCIe registers.
 2991                  */
 2992         }
 2993 }
 2994 
 2995 struct fdt_fixup_entry fdt_fixup_table[] = {
 2996         { "mrvl,DB-88F6281", &fdt_fixup_busfreq },
 2997         { "mrvl,DB-78460", &fdt_fixup_busfreq },
 2998         { "mrvl,DB-78460", &fdt_fixup_ranges },
 2999         { NULL, NULL }
 3000 };
 3001 
 3002 #if __ARM_ARCH >= 6
 3003 uint32_t
 3004 get_tclk(void)
 3005 {
 3006 
 3007         if (soc_decode_win_spec->get_tclk != NULL)
 3008                 return soc_decode_win_spec->get_tclk();
 3009         else
 3010                 return -1;
 3011 }
 3012 
 3013 uint32_t
 3014 get_cpu_freq(void)
 3015 {
 3016 
 3017         if (soc_decode_win_spec->get_cpu_freq != NULL)
 3018                 return soc_decode_win_spec->get_cpu_freq();
 3019         else
 3020                 return -1;
 3021 }
 3022 #endif
 3023 
 3024 #ifndef INTRNG
 3025 static int
 3026 fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
 3027     int *pol)
 3028 {
 3029 
 3030         if (!ofw_bus_node_is_compatible(node, "mrvl,pic") &&
 3031             !ofw_bus_node_is_compatible(node, "mrvl,mpic"))
 3032                 return (ENXIO);
 3033 
 3034         *interrupt = fdt32_to_cpu(intr[0]);
 3035         *trig = INTR_TRIGGER_CONFORM;
 3036         *pol = INTR_POLARITY_CONFORM;
 3037 
 3038         return (0);
 3039 }
 3040 
 3041 fdt_pic_decode_t fdt_pic_table[] = {
 3042         &fdt_pic_decode_ic,
 3043         NULL
 3044 };
 3045 #endif

Cache object: 4264fbe18fb34d04e70a0dd5eb6a63ff


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