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

Cache object: 9d4c78060b5e81fd24055ee06d5d4c95


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