The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/mv/common.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
    3  * All rights reserved.
    4  *
    5  * Developed by Semihalf.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. Neither the name of MARVELL nor the names of contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __FBSDID("$FreeBSD: releng/8.0/sys/arm/mv/common.c 197251 2009-09-16 12:07:58Z raj $");
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/bus.h>
   38 #include <sys/kernel.h>
   39 
   40 #include <machine/bus.h>
   41 
   42 #include <arm/mv/mvreg.h>
   43 #include <arm/mv/mvvar.h>
   44 #include <arm/mv/mvwin.h>
   45 
   46 static int win_eth_can_remap(int i);
   47 
   48 static int decode_win_cpu_valid(void);
   49 static int decode_win_usb_valid(void);
   50 static int decode_win_eth_valid(void);
   51 static int decode_win_pcie_valid(void);
   52 static int decode_win_sata_valid(void);
   53 static int decode_win_cesa_valid(void);
   54 
   55 static void decode_win_cpu_setup(void);
   56 static void decode_win_usb_setup(void);
   57 static void decode_win_eth_setup(uint32_t base);
   58 static void decode_win_pcie_setup(uint32_t base);
   59 static void decode_win_sata_setup(void);
   60 static void decode_win_cesa_setup(void);
   61 
   62 static void decode_win_cesa_dump(void);
   63 static void decode_win_usb_dump(void);
   64 
   65 static uint32_t used_cpu_wins;
   66 
   67 static __inline int
   68 pm_is_disabled(uint32_t mask)
   69 {
   70 
   71         return (soc_power_ctrl_get(mask) == mask ? 0 : 1);
   72 }
   73 
   74 static __inline uint32_t
   75 obio_get_pm_mask(uint32_t base)
   76 {
   77         struct obio_device *od;
   78 
   79         for (od = obio_devices; od->od_name != NULL; od++)
   80                 if (od->od_base == base)
   81                         return (od->od_pwr_mask);
   82 
   83         return (CPU_PM_CTRL_NONE);
   84 }
   85 
   86 /*
   87  * Disable device using power management register.
   88  * 1 - Device Power On
   89  * 0 - Device Power Off
   90  * Mask can be set in loader.
   91  * EXAMPLE:
   92  * loader> set hw.pm-disable-mask=0x2
   93  *
   94  * Common mask:
   95  * |-------------------------------|
   96  * | Device | Kirkwood | Discovery |
   97  * |-------------------------------|
   98  * | USB0   | 0x00008  | 0x020000  |
   99  * |-------------------------------|
  100  * | USB1   |     -    | 0x040000  |
  101  * |-------------------------------|
  102  * | USB2   |     -    | 0x080000  |
  103  * |-------------------------------|
  104  * | GE0    | 0x00001  | 0x000002  |
  105  * |-------------------------------|
  106  * | GE1    |     -    | 0x000004  |
  107  * |-------------------------------|
  108  * | IDMA   |     -    | 0x100000  |
  109  * |-------------------------------|
  110  * | XOR    | 0x10000  | 0x200000  |
  111  * |-------------------------------|
  112  * | CESA   | 0x20000  | 0x400000  |
  113  * |-------------------------------|
  114  * | SATA   | 0x04000  | 0x004000  |
  115  * --------------------------------|
  116  * This feature can be used only on Kirkwood and Discovery
  117  * machines.
  118  */
  119 static __inline void
  120 pm_disable_device(int mask)
  121 {
  122 #ifdef DIAGNOSTIC
  123         uint32_t reg;
  124 
  125         reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
  126         printf("Power Management Register: 0%x\n", reg);
  127 
  128         reg &= ~mask;
  129         soc_power_ctrl_set(reg);
  130         printf("Device %x is disabled\n", mask);
  131 
  132         reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
  133         printf("Power Management Register: 0%x\n", reg);
  134 #endif
  135 }
  136 
  137 uint32_t
  138 read_cpu_ctrl(uint32_t reg)
  139 {
  140 
  141         return (bus_space_read_4(obio_tag, MV_CPU_CONTROL_BASE, reg));
  142 }
  143 
  144 void
  145 write_cpu_ctrl(uint32_t reg, uint32_t val)
  146 {
  147 
  148         bus_space_write_4(obio_tag, MV_CPU_CONTROL_BASE, reg, val);
  149 }
  150 
  151 void
  152 cpu_reset(void)
  153 {
  154 
  155         write_cpu_ctrl(RSTOUTn_MASK, SOFT_RST_OUT_EN);
  156         write_cpu_ctrl(SYSTEM_SOFT_RESET, SYS_SOFT_RST);
  157         while (1);
  158 }
  159 
  160 uint32_t
  161 cpu_extra_feat(void)
  162 {
  163         uint32_t dev, rev;
  164         uint32_t ef = 0;
  165 
  166         soc_id(&dev, &rev);
  167         if (dev == MV_DEV_88F6281 || dev == MV_DEV_MV78100_Z0 ||
  168             dev == MV_DEV_MV78100)
  169                 __asm __volatile("mrc p15, 1, %0, c15, c1, 0" : "=r" (ef));
  170         else if (dev == MV_DEV_88F5182 || dev == MV_DEV_88F5281)
  171                 __asm __volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (ef));
  172         else if (bootverbose)
  173                 printf("This ARM Core does not support any extra features\n");
  174 
  175         return (ef);
  176 }
  177 
  178 /*
  179  * Get the power status of device. This feature is only supported on
  180  * Kirkwood and Discovery SoCs.
  181  */
  182 uint32_t
  183 soc_power_ctrl_get(uint32_t mask)
  184 {
  185 
  186 #ifndef SOC_MV_ORION
  187         if (mask != CPU_PM_CTRL_NONE)
  188                 mask &= read_cpu_ctrl(CPU_PM_CTRL);
  189 
  190         return (mask);
  191 #else
  192         return (mask);
  193 #endif
  194 }
  195 
  196 /*
  197  * Set the power status of device. This feature is only supported on
  198  * Kirkwood and Discovery SoCs.
  199  */
  200 void
  201 soc_power_ctrl_set(uint32_t mask)
  202 {
  203 
  204 #ifndef SOC_MV_ORION
  205         if (mask != CPU_PM_CTRL_NONE)
  206                 write_cpu_ctrl(CPU_PM_CTRL, mask);
  207 #endif
  208 }
  209 
  210 void
  211 soc_id(uint32_t *dev, uint32_t *rev)
  212 {
  213 
  214         /*
  215          * Notice: system identifiers are available in the registers range of
  216          * PCIE controller, so using this function is only allowed (and
  217          * possible) after the internal registers range has been mapped in via
  218          * pmap_devmap_bootstrap().
  219          */
  220         *dev = bus_space_read_4(obio_tag, MV_PCIE_BASE, 0) >> 16;
  221         *rev = bus_space_read_4(obio_tag, MV_PCIE_BASE, 8) & 0xff;
  222 }
  223 
  224 void
  225 soc_identify(void)
  226 {
  227         uint32_t d, r;
  228         const char *dev;
  229         const char *rev;
  230 
  231         soc_id(&d, &r);
  232 
  233         printf("SOC: ");
  234         if (bootverbose)
  235                 printf("(0x%4x:0x%02x) ", d, r);
  236 
  237         rev = "";
  238         switch (d) {
  239         case MV_DEV_88F5181:
  240                 dev = "Marvell 88F5181";
  241                 if (r == 3)
  242                         rev = "B1";
  243                 break;
  244         case MV_DEV_88F5182:
  245                 dev = "Marvell 88F5182";
  246                 if (r == 2)
  247                         rev = "A2";
  248                 break;
  249         case MV_DEV_88F5281:
  250                 dev = "Marvell 88F5281";
  251                 if (r == 4)
  252                         rev = "D0";
  253                 else if (r == 5)
  254                         rev = "D1";
  255                 else if (r == 6)
  256                         rev = "D2";
  257                 break;
  258         case MV_DEV_88F6281:
  259                 dev = "Marvell 88F6281";
  260                 if (r == 0)
  261                         rev = "Z0";
  262                 else if (r == 2)
  263                         rev = "A0";
  264                 break;
  265         case MV_DEV_MV78100_Z0:
  266                 dev = "Marvell MV78100 Z0";
  267                 break;
  268         case MV_DEV_MV78100:
  269                 dev = "Marvell MV78100";
  270                 break;
  271         default:
  272                 dev = "UNKNOWN";
  273                 break;
  274         }
  275 
  276         printf("%s", dev);
  277         if (*rev != '\0')
  278                 printf(" rev %s", rev);
  279         printf(", TClock %dMHz\n", get_tclk() / 1000 / 1000);
  280 
  281         /* TODO add info on currently set endianess */
  282 }
  283 
  284 int
  285 soc_decode_win(void)
  286 {
  287         uint32_t dev, rev;
  288         int mask;
  289 
  290         mask = 0;
  291         TUNABLE_INT_FETCH("hw.pm-disable-mask", &mask);
  292 
  293         if (mask != 0)
  294                 pm_disable_device(mask);
  295 
  296         /* Retrieve our ID: some windows facilities vary between SoC models */
  297         soc_id(&dev, &rev);
  298 
  299         if (decode_win_cpu_valid() != 1 || decode_win_usb_valid() != 1 ||
  300             decode_win_eth_valid() != 1 || decode_win_idma_valid() != 1 ||
  301             decode_win_pcie_valid() != 1 || decode_win_sata_valid() != 1 ||
  302             decode_win_cesa_valid() != 1)
  303                 return(-1);
  304 
  305         decode_win_cpu_setup();
  306         decode_win_usb_setup();
  307         decode_win_eth_setup(MV_ETH0_BASE);
  308         if (dev == MV_DEV_MV78100 || dev == MV_DEV_MV78100_Z0)
  309                 decode_win_eth_setup(MV_ETH1_BASE);
  310         if (dev == MV_DEV_88F6281 || dev == MV_DEV_MV78100 ||
  311             dev == MV_DEV_MV78100_Z0)
  312                 decode_win_cesa_setup();
  313 
  314         decode_win_idma_setup();
  315         decode_win_xor_setup();
  316 
  317         if (dev == MV_DEV_MV78100 || dev == MV_DEV_MV78100_Z0) {
  318                 decode_win_pcie_setup(MV_PCIE00_BASE);
  319                 decode_win_pcie_setup(MV_PCIE01_BASE);
  320                 decode_win_pcie_setup(MV_PCIE02_BASE);
  321                 decode_win_pcie_setup(MV_PCIE03_BASE);
  322                 decode_win_pcie_setup(MV_PCIE10_BASE);
  323                 decode_win_pcie_setup(MV_PCIE11_BASE);
  324                 decode_win_pcie_setup(MV_PCIE12_BASE);
  325                 decode_win_pcie_setup(MV_PCIE13_BASE);
  326         } else
  327                 decode_win_pcie_setup(MV_PCIE_BASE);
  328 
  329         if (dev != MV_DEV_88F5281)
  330                 decode_win_sata_setup();
  331 
  332         return (0);
  333 }
  334 
  335 /**************************************************************************
  336  * Decode windows registers accessors
  337  **************************************************************************/
  338 WIN_REG_IDX_RD(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
  339 WIN_REG_IDX_RD(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
  340 WIN_REG_IDX_RD(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
  341 WIN_REG_IDX_RD(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
  342 WIN_REG_IDX_WR(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
  343 WIN_REG_IDX_WR(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
  344 WIN_REG_IDX_WR(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
  345 WIN_REG_IDX_WR(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
  346 
  347 WIN_REG_IDX_RD(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
  348 WIN_REG_IDX_RD(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
  349 
  350 WIN_REG_IDX_RD2(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
  351 WIN_REG_IDX_RD2(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
  352 WIN_REG_IDX_WR2(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
  353 WIN_REG_IDX_WR2(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
  354 
  355 WIN_REG_IDX_RD(win_cesa, cr, MV_WIN_CESA_CTRL, MV_CESA_BASE)
  356 WIN_REG_IDX_RD(win_cesa, br, MV_WIN_CESA_BASE, MV_CESA_BASE)
  357 WIN_REG_IDX_WR(win_cesa, cr, MV_WIN_CESA_CTRL, MV_CESA_BASE)
  358 WIN_REG_IDX_WR(win_cesa, br, MV_WIN_CESA_BASE, MV_CESA_BASE)
  359 
  360 WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE)
  361 WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE)
  362 WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP)
  363 WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE)
  364 WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE)
  365 WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP)
  366 
  367 WIN_REG_IDX_RD2(win_xor, br, MV_WIN_XOR_BASE, MV_XOR_BASE)
  368 WIN_REG_IDX_RD2(win_xor, sz, MV_WIN_XOR_SIZE, MV_XOR_BASE)
  369 WIN_REG_IDX_RD2(win_xor, har, MV_WIN_XOR_REMAP, MV_XOR_BASE)
  370 WIN_REG_IDX_RD2(win_xor, ctrl, MV_WIN_XOR_CTRL, MV_XOR_BASE)
  371 WIN_REG_IDX_WR2(win_xor, br, MV_WIN_XOR_BASE, MV_XOR_BASE)
  372 WIN_REG_IDX_WR2(win_xor, sz, MV_WIN_XOR_SIZE, MV_XOR_BASE)
  373 WIN_REG_IDX_WR2(win_xor, har, MV_WIN_XOR_REMAP, MV_XOR_BASE)
  374 WIN_REG_IDX_WR2(win_xor, ctrl, MV_WIN_XOR_CTRL, MV_XOR_BASE)
  375 
  376 WIN_REG_BASE_RD(win_eth, bare, 0x290)
  377 WIN_REG_BASE_RD(win_eth, epap, 0x294)
  378 WIN_REG_BASE_WR(win_eth, bare, 0x290)
  379 WIN_REG_BASE_WR(win_eth, epap, 0x294)
  380 
  381 WIN_REG_BASE_IDX_RD(win_pcie, cr, MV_WIN_PCIE_CTRL);
  382 WIN_REG_BASE_IDX_RD(win_pcie, br, MV_WIN_PCIE_BASE);
  383 WIN_REG_BASE_IDX_RD(win_pcie, remap, MV_WIN_PCIE_REMAP);
  384 WIN_REG_BASE_IDX_WR(win_pcie, cr, MV_WIN_PCIE_CTRL);
  385 WIN_REG_BASE_IDX_WR(win_pcie, br, MV_WIN_PCIE_BASE);
  386 WIN_REG_BASE_IDX_WR(win_pcie, remap, MV_WIN_PCIE_REMAP);
  387 WIN_REG_BASE_IDX_WR(pcie, bar, MV_PCIE_BAR);
  388 
  389 WIN_REG_IDX_RD(win_idma, br, MV_WIN_IDMA_BASE, MV_IDMA_BASE)
  390 WIN_REG_IDX_RD(win_idma, sz, MV_WIN_IDMA_SIZE, MV_IDMA_BASE)
  391 WIN_REG_IDX_RD(win_idma, har, MV_WIN_IDMA_REMAP, MV_IDMA_BASE)
  392 WIN_REG_IDX_RD(win_idma, cap, MV_WIN_IDMA_CAP, MV_IDMA_BASE)
  393 WIN_REG_IDX_WR(win_idma, br, MV_WIN_IDMA_BASE, MV_IDMA_BASE)
  394 WIN_REG_IDX_WR(win_idma, sz, MV_WIN_IDMA_SIZE, MV_IDMA_BASE)
  395 WIN_REG_IDX_WR(win_idma, har, MV_WIN_IDMA_REMAP, MV_IDMA_BASE)
  396 WIN_REG_IDX_WR(win_idma, cap, MV_WIN_IDMA_CAP, MV_IDMA_BASE)
  397 WIN_REG_RD(win_idma, bare, 0xa80, MV_IDMA_BASE)
  398 WIN_REG_WR(win_idma, bare, 0xa80, MV_IDMA_BASE)
  399 
  400 WIN_REG_IDX_RD(win_sata, cr, MV_WIN_SATA_CTRL, MV_SATAHC_BASE);
  401 WIN_REG_IDX_RD(win_sata, br, MV_WIN_SATA_BASE, MV_SATAHC_BASE);
  402 WIN_REG_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL, MV_SATAHC_BASE);
  403 WIN_REG_IDX_WR(win_sata, br, MV_WIN_SATA_BASE, MV_SATAHC_BASE);
  404 
  405 /**************************************************************************
  406  * Decode windows helper routines
  407  **************************************************************************/
  408 void
  409 soc_dump_decode_win(void)
  410 {
  411         uint32_t dev, rev;
  412         int i;
  413 
  414         soc_id(&dev, &rev);
  415 
  416         for (i = 0; i < MV_WIN_CPU_MAX; i++) {
  417                 printf("CPU window#%d: c 0x%08x, b 0x%08x", i,
  418                     win_cpu_cr_read(i),
  419                     win_cpu_br_read(i));
  420 
  421                 if (win_cpu_can_remap(i))
  422                         printf(", rl 0x%08x, rh 0x%08x",
  423                             win_cpu_remap_l_read(i),
  424                             win_cpu_remap_h_read(i));
  425 
  426                 printf("\n");
  427         }
  428         printf("Internal regs base: 0x%08x\n",
  429             bus_space_read_4(obio_tag, MV_INTREGS_BASE, 0));
  430 
  431         for (i = 0; i < MV_WIN_DDR_MAX; i++)
  432                 printf("DDR CS#%d: b 0x%08x, s 0x%08x\n", i,
  433                     ddr_br_read(i), ddr_sz_read(i));
  434 
  435         for (i = 0; i < MV_WIN_ETH_MAX; i++) {
  436                 printf("ETH window#%d: b 0x%08x, s 0x%08x", i,
  437                     win_eth_br_read(MV_ETH0_BASE, i),
  438                     win_eth_sz_read(MV_ETH0_BASE, i));
  439 
  440                 if (win_eth_can_remap(i))
  441                         printf(", ha 0x%08x",
  442                             win_eth_har_read(MV_ETH0_BASE, i));
  443 
  444                 printf("\n");
  445         }
  446         printf("ETH windows: bare 0x%08x, epap 0x%08x\n",
  447             win_eth_bare_read(MV_ETH0_BASE),
  448             win_eth_epap_read(MV_ETH0_BASE));
  449 
  450         decode_win_idma_dump();
  451         decode_win_cesa_dump();
  452         decode_win_usb_dump();
  453         printf("\n");
  454 }
  455 
  456 /**************************************************************************
  457  * CPU windows routines
  458  **************************************************************************/
  459 int
  460 win_cpu_can_remap(int i)
  461 {
  462         uint32_t dev, rev;
  463 
  464         soc_id(&dev, &rev);
  465 
  466         /* Depending on the SoC certain windows have remap capability */
  467         if ((dev == MV_DEV_88F5182 && i < 2) ||
  468             (dev == MV_DEV_88F5281 && i < 4) ||
  469             (dev == MV_DEV_88F6281 && i < 4) ||
  470             (dev == MV_DEV_MV78100 && i < 8) ||
  471             (dev == MV_DEV_MV78100_Z0 && i < 8))
  472                 return (1);
  473 
  474         return (0);
  475 }
  476 
  477 /* XXX This should check for overlapping remap fields too.. */
  478 int
  479 decode_win_overlap(int win, int win_no, const struct decode_win *wintab)
  480 {
  481         const struct decode_win *tab;
  482         int i;
  483 
  484         tab = wintab;
  485 
  486         for (i = 0; i < win_no; i++, tab++) {
  487                 if (i == win)
  488                         /* Skip self */
  489                         continue;
  490 
  491                 if ((tab->base + tab->size - 1) < (wintab + win)->base)
  492                         continue;
  493 
  494                 else if (((wintab + win)->base + (wintab + win)->size - 1) <
  495                     tab->base)
  496                         continue;
  497                 else
  498                         return (i);
  499         }
  500 
  501         return (-1);
  502 }
  503 
  504 static int
  505 decode_win_cpu_valid(void)
  506 {
  507         int i, j, rv;
  508         uint32_t b, e, s;
  509 
  510         if (cpu_wins_no > MV_WIN_CPU_MAX) {
  511                 printf("CPU windows: too many entries: %d\n", cpu_wins_no);
  512                 return (-1);
  513         }
  514 
  515         rv = 1;
  516         for (i = 0; i < cpu_wins_no; i++) {
  517 
  518                 if (cpu_wins[i].target == 0) {
  519                         printf("CPU window#%d: DDR target window is not "
  520                             "supposed to be reprogrammed!\n", i);
  521                         rv = 0;
  522                 }
  523 
  524                 if (cpu_wins[i].remap >= 0 && win_cpu_can_remap(i) != 1) {
  525                         printf("CPU window#%d: not capable of remapping, but "
  526                             "val 0x%08x defined\n", i, cpu_wins[i].remap);
  527                         rv = 0;
  528                 }
  529 
  530                 s = cpu_wins[i].size;
  531                 b = cpu_wins[i].base;
  532                 e = b + s - 1;
  533                 if (s > (0xFFFFFFFF - b + 1)) {
  534                         /*
  535                          * XXX this boundary check should account for 64bit
  536                          * and remapping..
  537                          */
  538                         printf("CPU window#%d: no space for size 0x%08x at "
  539                             "0x%08x\n", i, s, b);
  540                         rv = 0;
  541                         continue;
  542                 }
  543 
  544                 j = decode_win_overlap(i, cpu_wins_no, &cpu_wins[0]);
  545                 if (j >= 0) {
  546                         printf("CPU window#%d: (0x%08x - 0x%08x) overlaps "
  547                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
  548                             cpu_wins[j].base,
  549                             cpu_wins[j].base + cpu_wins[j].size - 1);
  550                         rv = 0;
  551                 }
  552         }
  553 
  554         return (rv);
  555 }
  556 
  557 int
  558 decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size,
  559     int remap)
  560 {
  561         uint32_t br, cr;
  562         int win;
  563 
  564         if (used_cpu_wins >= MV_WIN_CPU_MAX)
  565                 return (-1);
  566 
  567         win = used_cpu_wins++;
  568 
  569         br = base & 0xffff0000;
  570         win_cpu_br_write(win, br);
  571 
  572         if (win_cpu_can_remap(win)) {
  573                 if (remap >= 0) {
  574                         win_cpu_remap_l_write(win, remap & 0xffff0000);
  575                         win_cpu_remap_h_write(win, 0);
  576                 } else {
  577                         /*
  578                          * Remap function is not used for a given window
  579                          * (capable of remapping) - set remap field with the
  580                          * same value as base.
  581                          */
  582                         win_cpu_remap_l_write(win, base & 0xffff0000);
  583                         win_cpu_remap_h_write(win, 0);
  584                 }
  585         }
  586 
  587         cr = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
  588         win_cpu_cr_write(win, cr);
  589 
  590         return (0);
  591 }
  592 
  593 static void
  594 decode_win_cpu_setup(void)
  595 {
  596         int i;
  597 
  598         used_cpu_wins = 0;
  599 
  600         /* Disable all CPU windows */
  601         for (i = 0; i < MV_WIN_CPU_MAX; i++) {
  602                 win_cpu_cr_write(i, 0);
  603                 win_cpu_br_write(i, 0);
  604                 if (win_cpu_can_remap(i)) {
  605                         win_cpu_remap_l_write(i, 0);
  606                         win_cpu_remap_h_write(i, 0);
  607                 }
  608         }
  609 
  610         for (i = 0; i < cpu_wins_no; i++)
  611                 if (cpu_wins[i].target > 0)
  612                         decode_win_cpu_set(cpu_wins[i].target,
  613                             cpu_wins[i].attr, cpu_wins[i].base,
  614                             cpu_wins[i].size, cpu_wins[i].remap);
  615 
  616 }
  617 
  618 /*
  619  * Check if we're able to cover all active DDR banks.
  620  */
  621 static int
  622 decode_win_can_cover_ddr(int max)
  623 {
  624         int i, c;
  625 
  626         c = 0;
  627         for (i = 0; i < MV_WIN_DDR_MAX; i++)
  628                 if (ddr_is_active(i))
  629                         c++;
  630 
  631         if (c > max) {
  632                 printf("Unable to cover all active DDR banks: "
  633                     "%d, available windows: %d\n", c, max);
  634                 return (0);
  635         }
  636 
  637         return (1);
  638 }
  639 
  640 /**************************************************************************
  641  * DDR windows routines
  642  **************************************************************************/
  643 int
  644 ddr_is_active(int i)
  645 {
  646 
  647         if (ddr_sz_read(i) & 0x1)
  648                 return (1);
  649 
  650         return (0);
  651 }
  652 
  653 uint32_t
  654 ddr_base(int i)
  655 {
  656 
  657         return (ddr_br_read(i) & 0xff000000);
  658 }
  659 
  660 uint32_t
  661 ddr_size(int i)
  662 {
  663 
  664         return ((ddr_sz_read(i) | 0x00ffffff) + 1);
  665 }
  666 
  667 uint32_t
  668 ddr_attr(int i)
  669 {
  670 
  671         return (i == 0 ? 0xe :
  672             (i == 1 ? 0xd :
  673             (i == 2 ? 0xb :
  674             (i == 3 ? 0x7 : 0xff))));
  675 }
  676 
  677 uint32_t
  678 ddr_target(int i)
  679 {
  680 
  681         /* Mbus unit ID is 0x0 for DDR SDRAM controller */
  682         return (0);
  683 }
  684 
  685 /**************************************************************************
  686  * USB windows routines
  687  **************************************************************************/
  688 static int
  689 decode_win_usb_valid(void)
  690 {
  691 
  692         return (decode_win_can_cover_ddr(MV_WIN_USB_MAX));
  693 }
  694 
  695 static __inline int
  696 usb_max_ports(void)
  697 {
  698         uint32_t dev, rev;
  699 
  700         soc_id(&dev, &rev);
  701         return ((dev == MV_DEV_MV78100 || dev == MV_DEV_MV78100_Z0) ? 3 : 1);
  702 }
  703 
  704 static void
  705 decode_win_usb_dump(void)
  706 {
  707         int i, p, m;
  708 
  709         m = usb_max_ports();
  710         for (p = 0; p < m; p++)
  711                 for (i = 0; i < MV_WIN_USB_MAX; i++)
  712                         printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
  713                             win_usb_cr_read(i, p), win_usb_br_read(i, p));
  714 }
  715 
  716 /*
  717  * Set USB decode windows.
  718  */
  719 static void
  720 decode_win_usb_setup(void)
  721 {
  722         uint32_t br, cr;
  723         int i, j, p, m;
  724 
  725         /* Disable and clear all USB windows for all ports */
  726         m = usb_max_ports();
  727 
  728         for (p = 0; p < m; p++) {
  729 
  730                 if (pm_is_disabled(CPU_PM_CTRL_USB(p)))
  731                         continue;
  732 
  733                 for (i = 0; i < MV_WIN_USB_MAX; i++) {
  734                         win_usb_cr_write(i, p, 0);
  735                         win_usb_br_write(i, p, 0);
  736                 }
  737 
  738                 /* Only access to active DRAM banks is required */
  739                 for (i = 0; i < MV_WIN_DDR_MAX; i++) {
  740                         if (ddr_is_active(i)) {
  741                                 br = ddr_base(i);
  742                                 /*
  743                                  * XXX for 6281 we should handle Mbus write
  744                                  * burst limit field in the ctrl reg
  745                                  */
  746                                 cr = (((ddr_size(i) - 1) & 0xffff0000) |
  747                                     (ddr_attr(i) << 8) |
  748                                     (ddr_target(i) << 4) | 1);
  749 
  750                                 /* Set the first free USB window */
  751                                 for (j = 0; j < MV_WIN_USB_MAX; j++) {
  752                                         if (win_usb_cr_read(j, p) & 0x1)
  753                                                 continue;
  754 
  755                                         win_usb_br_write(j, p, br);
  756                                         win_usb_cr_write(j, p, cr);
  757                                         break;
  758                                 }
  759                         }
  760                 }
  761         }
  762 }
  763 
  764 /**************************************************************************
  765  * ETH windows routines
  766  **************************************************************************/
  767 
  768 static int
  769 win_eth_can_remap(int i)
  770 {
  771 
  772         /* ETH encode windows 0-3 have remap capability */
  773         if (i < 4)
  774                 return (1);
  775         
  776         return (0);
  777 }
  778 
  779 static int
  780 eth_bare_read(uint32_t base, int i)
  781 {
  782         uint32_t v;
  783 
  784         v = win_eth_bare_read(base);
  785         v &= (1 << i);
  786 
  787         return (v >> i);
  788 }
  789 
  790 static void
  791 eth_bare_write(uint32_t base, int i, int val)
  792 {
  793         uint32_t v;
  794 
  795         v = win_eth_bare_read(base);
  796         v &= ~(1 << i);
  797         v |= (val << i);
  798         win_eth_bare_write(base, v);
  799 }
  800 
  801 static void
  802 eth_epap_write(uint32_t base, int i, int val)
  803 {
  804         uint32_t v;
  805 
  806         v = win_eth_epap_read(base);
  807         v &= ~(0x3 << (i * 2));
  808         v |= (val << (i * 2));
  809         win_eth_epap_write(base, v);
  810 }
  811 
  812 static void
  813 decode_win_eth_setup(uint32_t base)
  814 {
  815         uint32_t br, sz;
  816         int i, j;
  817 
  818         if (pm_is_disabled(obio_get_pm_mask(base)))
  819                 return;
  820 
  821         /* Disable, clear and revoke protection for all ETH windows */
  822         for (i = 0; i < MV_WIN_ETH_MAX; i++) {
  823 
  824                 eth_bare_write(base, i, 1);
  825                 eth_epap_write(base, i, 0);
  826                 win_eth_br_write(base, i, 0);
  827                 win_eth_sz_write(base, i, 0);
  828                 if (win_eth_can_remap(i))
  829                         win_eth_har_write(base, i, 0);
  830         }
  831 
  832         /* Only access to active DRAM banks is required */
  833         for (i = 0; i < MV_WIN_DDR_MAX; i++)
  834                 if (ddr_is_active(i)) {
  835 
  836                         br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
  837                         sz = ((ddr_size(i) - 1) & 0xffff0000);
  838 
  839                         /* Set the first free ETH window */
  840                         for (j = 0; j < MV_WIN_ETH_MAX; j++) {
  841                                 if (eth_bare_read(base, j) == 0)
  842                                         continue;
  843 
  844                                 win_eth_br_write(base, j, br);
  845                                 win_eth_sz_write(base, j, sz);
  846 
  847                                 /* XXX remapping ETH windows not supported */
  848 
  849                                 /* Set protection RW */
  850                                 eth_epap_write(base, j, 0x3);
  851 
  852                                 /* Enable window */
  853                                 eth_bare_write(base, j, 0);
  854                                 break;
  855                         }
  856                 }
  857 }
  858 
  859 static int
  860 decode_win_eth_valid(void)
  861 {
  862 
  863         return (decode_win_can_cover_ddr(MV_WIN_ETH_MAX));
  864 }
  865 
  866 /**************************************************************************
  867  * PCIE windows routines
  868  **************************************************************************/
  869 
  870 static void
  871 decode_win_pcie_setup(uint32_t base)
  872 {
  873         uint32_t size = 0;
  874         uint32_t cr, br;
  875         int i, j;
  876 
  877         for (i = 0; i < MV_PCIE_BAR_MAX; i++)
  878                 pcie_bar_write(base, i, 0);
  879 
  880         for (i = 0; i < MV_WIN_PCIE_MAX; i++) {
  881                 win_pcie_cr_write(base, i, 0);
  882                 win_pcie_br_write(base, i, 0);
  883                 win_pcie_remap_write(base, i, 0);
  884         }
  885 
  886         for (i = 0; i < MV_WIN_DDR_MAX; i++) {
  887                 if (ddr_is_active(i)) {
  888                         /* Map DDR to BAR 1 */
  889                         cr = (ddr_size(i) - 1) & 0xffff0000;
  890                         size += ddr_size(i) & 0xffff0000;
  891                         cr |= (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
  892                         br = ddr_base(i);
  893 
  894                         /* Use the first available PCIE window */
  895                         for (j = 0; j < MV_WIN_PCIE_MAX; j++) {
  896                                 if (win_pcie_cr_read(base, j) != 0)
  897                                         continue;
  898 
  899                                 win_pcie_br_write(base, j, br);
  900                                 win_pcie_cr_write(base, j, cr);
  901                                 break;
  902                         }
  903                 }
  904         }
  905 
  906         /*
  907          * Upper 16 bits in BAR register is interpreted as BAR size
  908          * (in 64 kB units) plus 64kB, so substract 0x10000
  909          * form value passed to register to get correct value.
  910          */
  911         size -= 0x10000;
  912         pcie_bar_write(base, 0, size | 1);
  913 }
  914 
  915 static int
  916 decode_win_pcie_valid(void)
  917 {
  918 
  919         return (decode_win_can_cover_ddr(MV_WIN_PCIE_MAX));
  920 }
  921 
  922 /**************************************************************************
  923  * IDMA windows routines
  924  **************************************************************************/
  925 #if defined(SOC_MV_ORION) || defined(SOC_MV_DISCOVERY)
  926 static int
  927 idma_bare_read(int i)
  928 {
  929         uint32_t v;
  930 
  931         v = win_idma_bare_read();
  932         v &= (1 << i);
  933 
  934         return (v >> i);
  935 }
  936 
  937 static void
  938 idma_bare_write(int i, int val)
  939 {
  940         uint32_t v;
  941 
  942         v = win_idma_bare_read();
  943         v &= ~(1 << i);
  944         v |= (val << i);
  945         win_idma_bare_write(v);
  946 }
  947 
  948 /*
  949  * Sets channel protection 'val' for window 'w' on channel 'c'
  950  */
  951 static void
  952 idma_cap_write(int c, int w, int val)
  953 {
  954         uint32_t v;
  955 
  956         v = win_idma_cap_read(c);
  957         v &= ~(0x3 << (w * 2));
  958         v |= (val << (w * 2));
  959         win_idma_cap_write(c, v);
  960 }
  961 
  962 /*
  963  * Set protection 'val' on all channels for window 'w'
  964  */
  965 static void
  966 idma_set_prot(int w, int val)
  967 {
  968         int c;
  969 
  970         for (c = 0; c < MV_IDMA_CHAN_MAX; c++)
  971                 idma_cap_write(c, w, val);
  972 }
  973 
  974 static int
  975 win_idma_can_remap(int i)
  976 {
  977 
  978         /* IDMA decode windows 0-3 have remap capability */
  979         if (i < 4)
  980                 return (1);
  981 
  982         return (0);
  983 }
  984 
  985 void
  986 decode_win_idma_setup(void)
  987 {
  988         uint32_t br, sz;
  989         int i, j;
  990 
  991         if (pm_is_disabled(CPU_PM_CTRL_IDMA))
  992                 return;
  993         /*
  994          * Disable and clear all IDMA windows, revoke protection for all channels
  995          */
  996         for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
  997 
  998                 idma_bare_write(i, 1);
  999                 win_idma_br_write(i, 0);
 1000                 win_idma_sz_write(i, 0);
 1001                 if (win_idma_can_remap(i) == 1)
 1002                         win_idma_har_write(i, 0);
 1003         }
 1004         for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
 1005                 win_idma_cap_write(i, 0);
 1006 
 1007         /*
 1008          * Set up access to all active DRAM banks
 1009          */
 1010         for (i = 0; i < MV_WIN_DDR_MAX; i++)
 1011                 if (ddr_is_active(i)) {
 1012                         br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
 1013                         sz = ((ddr_size(i) - 1) & 0xffff0000);
 1014 
 1015                         /* Place DDR entries in non-remapped windows */
 1016                         for (j = 0; j < MV_WIN_IDMA_MAX; j++)
 1017                                 if (win_idma_can_remap(j) != 1 &&
 1018                                     idma_bare_read(j) == 1) {
 1019 
 1020                                         /* Configure window */
 1021                                         win_idma_br_write(j, br);
 1022                                         win_idma_sz_write(j, sz);
 1023 
 1024                                         /* Set protection RW on all channels */
 1025                                         idma_set_prot(j, 0x3);
 1026 
 1027                                         /* Enable window */
 1028                                         idma_bare_write(j, 0);
 1029                                         break;
 1030                                 }
 1031                 }
 1032 
 1033         /*
 1034          * Remaining targets -- from statically defined table
 1035          */
 1036         for (i = 0; i < idma_wins_no; i++)
 1037                 if (idma_wins[i].target > 0) {
 1038                         br = (idma_wins[i].base & 0xffff0000) |
 1039                             (idma_wins[i].attr << 8) | idma_wins[i].target;
 1040                         sz = ((idma_wins[i].size - 1) & 0xffff0000);
 1041 
 1042                         /* Set the first free IDMA window */
 1043                         for (j = 0; j < MV_WIN_IDMA_MAX; j++) {
 1044                                 if (idma_bare_read(j) == 0)
 1045                                         continue;
 1046 
 1047                                 /* Configure window */
 1048                                 win_idma_br_write(j, br);
 1049                                 win_idma_sz_write(j, sz);
 1050                                 if (win_idma_can_remap(j) &&
 1051                                     idma_wins[j].remap >= 0)
 1052                                         win_idma_har_write(j, idma_wins[j].remap);
 1053 
 1054                                 /* Set protection RW on all channels */
 1055                                 idma_set_prot(j, 0x3);
 1056 
 1057                                 /* Enable window */
 1058                                 idma_bare_write(j, 0);
 1059                                 break;
 1060                         }
 1061                 }
 1062 }
 1063 
 1064 int
 1065 decode_win_idma_valid(void)
 1066 {
 1067         const struct decode_win *wintab;
 1068         int c, i, j, rv;
 1069         uint32_t b, e, s;
 1070 
 1071         if (idma_wins_no > MV_WIN_IDMA_MAX) {
 1072                 printf("IDMA windows: too many entries: %d\n", idma_wins_no);
 1073                 return (-1);
 1074         }
 1075         for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
 1076                 if (ddr_is_active(i))
 1077                         c++;
 1078 
 1079         if (idma_wins_no > (MV_WIN_IDMA_MAX - c)) {
 1080                 printf("IDMA windows: too many entries: %d, available: %d\n",
 1081                     idma_wins_no, MV_WIN_IDMA_MAX - c);
 1082                 return (-1);
 1083         }
 1084 
 1085         wintab = idma_wins;
 1086         rv = 1;
 1087         for (i = 0; i < idma_wins_no; i++, wintab++) {
 1088 
 1089                 if (wintab->target == 0) {
 1090                         printf("IDMA window#%d: DDR target window is not "
 1091                             "supposed to be reprogrammed!\n", i);
 1092                         rv = 0;
 1093                 }
 1094 
 1095                 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
 1096                         printf("IDMA window#%d: not capable of remapping, but "
 1097                             "val 0x%08x defined\n", i, wintab->remap);
 1098                         rv = 0;
 1099                 }
 1100 
 1101                 s = wintab->size;
 1102                 b = wintab->base;
 1103                 e = b + s - 1;
 1104                 if (s > (0xFFFFFFFF - b + 1)) {
 1105                         /* XXX this boundary check should account for 64bit and
 1106                          * remapping.. */
 1107                         printf("IDMA window#%d: no space for size 0x%08x at "
 1108                             "0x%08x\n", i, s, b);
 1109                         rv = 0;
 1110                         continue;
 1111                 }
 1112 
 1113                 j = decode_win_overlap(i, idma_wins_no, &idma_wins[0]);
 1114                 if (j >= 0) {
 1115                         printf("IDMA window#%d: (0x%08x - 0x%08x) overlaps "
 1116                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
 1117                             idma_wins[j].base,
 1118                             idma_wins[j].base + idma_wins[j].size - 1);
 1119                         rv = 0;
 1120                 }
 1121         }
 1122 
 1123         return (rv);
 1124 }
 1125 
 1126 void
 1127 decode_win_idma_dump(void)
 1128 {
 1129         int i;
 1130 
 1131         for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
 1132                 printf("IDMA window#%d: b 0x%08x, s 0x%08x", i,
 1133                     win_idma_br_read(i), win_idma_sz_read(i));
 1134                 
 1135                 if (win_idma_can_remap(i))
 1136                         printf(", ha 0x%08x", win_idma_har_read(i));
 1137 
 1138                 printf("\n");
 1139         }
 1140         for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
 1141                 printf("IDMA channel#%d: ap 0x%08x\n", i,
 1142                     win_idma_cap_read(i));
 1143         printf("IDMA windows: bare 0x%08x\n", win_idma_bare_read());
 1144 }
 1145 #else
 1146 
 1147 /* Provide dummy functions to satisfy the build for SoCs not equipped with IDMA */
 1148 int
 1149 decode_win_idma_valid(void)
 1150 {
 1151 
 1152         return (1);
 1153 }
 1154 
 1155 void
 1156 decode_win_idma_setup(void)
 1157 {
 1158 }
 1159 
 1160 void
 1161 decode_win_idma_dump(void)
 1162 {
 1163 }
 1164 #endif
 1165 
 1166 /**************************************************************************
 1167  * XOR windows routines
 1168  **************************************************************************/
 1169 #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
 1170 static int
 1171 xor_ctrl_read(int i, int c, int e)
 1172 {
 1173         uint32_t v;
 1174         v = win_xor_ctrl_read(c, e);
 1175         v &= (1 << i);
 1176 
 1177         return (v >> i);
 1178 }
 1179 
 1180 static void
 1181 xor_ctrl_write(int i, int c, int e, int val)
 1182 {
 1183         uint32_t v;
 1184 
 1185         v = win_xor_ctrl_read(c, e);
 1186         v &= ~(1 << i);
 1187         v |= (val << i);
 1188         win_xor_ctrl_write(c, e, v);
 1189 }
 1190 
 1191 /*
 1192  * Set channel protection 'val' for window 'w' on channel 'c'
 1193  */
 1194 
 1195 static void
 1196 xor_chan_write(int c, int e, int w, int val)
 1197 {
 1198         uint32_t v;
 1199 
 1200         v = win_xor_ctrl_read(c, e);
 1201         v &= ~(0x3 << (w * 2 + 16));
 1202         v |= (val << (w * 2 + 16));
 1203         win_xor_ctrl_write(c, e, v);
 1204 }
 1205 
 1206 /*
 1207  * Set protection 'val' on all channels for window 'w' on engine 'e'
 1208  */
 1209 static void
 1210 xor_set_prot(int w, int e, int val)
 1211 {
 1212         int c;
 1213 
 1214         for (c = 0; c < MV_XOR_CHAN_MAX; c++)
 1215                 xor_chan_write(c, e, w, val);
 1216 }
 1217 
 1218 static int
 1219 win_xor_can_remap(int i)
 1220 {
 1221 
 1222         /* XOR decode windows 0-3 have remap capability */
 1223         if (i < 4)
 1224                 return (1);
 1225 
 1226         return (0);
 1227 }
 1228 
 1229 static int
 1230 xor_max_eng(void)
 1231 {
 1232         uint32_t dev, rev;
 1233 
 1234         soc_id(&dev, &rev);
 1235         if (dev == MV_DEV_88F6281)
 1236                 return (2);
 1237         else if ((dev == MV_DEV_MV78100) || (dev == MV_DEV_MV78100_Z0))
 1238                 return (1);
 1239         else
 1240                 return (0);
 1241 }
 1242 
 1243 static void
 1244 xor_active_dram(int c, int e, int *window)
 1245 {
 1246         uint32_t br, sz;
 1247         int i, m, w;
 1248 
 1249         /*
 1250          * Set up access to all active DRAM banks
 1251          */
 1252         m = xor_max_eng();
 1253         for (i = 0; i < m; i++)
 1254                 if (ddr_is_active(i)) {
 1255                         br = ddr_base(i) | (ddr_attr(i) << 8) |
 1256                             ddr_target(i);
 1257                         sz = ((ddr_size(i) - 1) & 0xffff0000);
 1258 
 1259                         /* Place DDR entries in non-remapped windows */
 1260                         for (w = 0; w < MV_WIN_XOR_MAX; w++)
 1261                                 if (win_xor_can_remap(w) != 1 &&
 1262                                     (xor_ctrl_read(w, c, e) == 0) &&
 1263                                     w > *window) {
 1264                                         /* Configure window */
 1265                                         win_xor_br_write(w, e, br);
 1266                                         win_xor_sz_write(w, e, sz);
 1267 
 1268                                         /* Set protection RW on all channels */
 1269                                         xor_set_prot(w, e, 0x3);
 1270 
 1271                                         /* Enable window */
 1272                                         xor_ctrl_write(w, c, e, 1);
 1273                                         (*window)++;
 1274                                         break;
 1275                                 }
 1276                 }
 1277 }
 1278 
 1279 void
 1280 decode_win_xor_setup(void)
 1281 {
 1282         uint32_t br, sz;
 1283         int i, j, z, e = 1, m, window;
 1284 
 1285         if (pm_is_disabled(CPU_PM_CTRL_XOR))
 1286                 return;
 1287 
 1288         /*
 1289          * Disable and clear all XOR windows, revoke protection for all
 1290          * channels
 1291          */
 1292         m = xor_max_eng();
 1293         for (j = 0; j < m; j++, e--) {
 1294 
 1295                 /* Number of non-remaped windows */
 1296                 window = MV_XOR_NON_REMAP - 1;
 1297 
 1298                 for (i = 0; i < MV_WIN_XOR_MAX; i++) {
 1299                         win_xor_br_write(i, e, 0);
 1300                         win_xor_sz_write(i, e, 0);
 1301                 }
 1302 
 1303                 if (win_xor_can_remap(i) == 1)
 1304                         win_xor_har_write(i, e, 0);
 1305 
 1306                 for (i = 0; i < MV_XOR_CHAN_MAX; i++) {
 1307                         win_xor_ctrl_write(i, e, 0);
 1308                         xor_active_dram(i, e, &window);
 1309                 }
 1310 
 1311                 /*
 1312                  * Remaining targets -- from a statically defined table
 1313                  */
 1314                 for (i = 0; i < xor_wins_no; i++)
 1315                         if (xor_wins[i].target > 0) {
 1316                                 br = (xor_wins[i].base & 0xffff0000) |
 1317                                     (xor_wins[i].attr << 8) |
 1318                                     xor_wins[i].target;
 1319                                 sz = ((xor_wins[i].size - 1) & 0xffff0000);
 1320 
 1321                                 /* Set the first free XOR window */
 1322                                 for (z = 0; z < MV_WIN_XOR_MAX; z++) {
 1323                                         if (xor_ctrl_read(z, 0, e) &&
 1324                                             xor_ctrl_read(z, 1, e))
 1325                                                 continue;
 1326 
 1327                                         /* Configure window */
 1328                                         win_xor_br_write(z, e, br);
 1329                                         win_xor_sz_write(z, e, sz);
 1330                                         if (win_xor_can_remap(z) &&
 1331                                             xor_wins[z].remap >= 0)
 1332                                                 win_xor_har_write(z, e,
 1333                                                     xor_wins[z].remap);
 1334 
 1335                                         /* Set protection RW on all channels */
 1336                                         xor_set_prot(z, e, 0x3);
 1337 
 1338                                         /* Enable window */
 1339                                         xor_ctrl_write(z, 0, e, 1);
 1340                                         xor_ctrl_write(z, 1, e, 1);
 1341                                         break;
 1342                                 }
 1343                         }
 1344         }
 1345 }
 1346 
 1347 int
 1348 decode_win_xor_valid(void)
 1349 {
 1350         const struct decode_win *wintab;
 1351         int c, i, j, rv;
 1352         uint32_t b, e, s;
 1353 
 1354         if (xor_wins_no > MV_WIN_XOR_MAX) {
 1355                 printf("XOR windows: too many entries: %d\n", xor_wins_no);
 1356                 return (-1);
 1357         }
 1358         for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
 1359                 if (ddr_is_active(i))
 1360                         c++;
 1361 
 1362         if (xor_wins_no > (MV_WIN_XOR_MAX - c)) {
 1363                 printf("XOR windows: too many entries: %d, available: %d\n",
 1364                     xor_wins_no, MV_WIN_IDMA_MAX - c);
 1365                 return (-1);
 1366         }
 1367 
 1368         wintab = xor_wins;
 1369         rv = 1;
 1370         for (i = 0; i < xor_wins_no; i++, wintab++) {
 1371 
 1372                 if (wintab->target == 0) {
 1373                         printf("XOR window#%d: DDR target window is not "
 1374                             "supposed to be reprogrammed!\n", i);
 1375                         rv = 0;
 1376                 }
 1377 
 1378                 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
 1379                         printf("XOR window#%d: not capable of remapping, but "
 1380                             "val 0x%08x defined\n", i, wintab->remap);
 1381                         rv = 0;
 1382                 }
 1383 
 1384                 s = wintab->size;
 1385                 b = wintab->base;
 1386                 e = b + s - 1;
 1387                 if (s > (0xFFFFFFFF - b + 1)) {
 1388                         /*
 1389                          * XXX this boundary check should account for 64bit
 1390                          * and remapping..
 1391                          */
 1392                         printf("XOR window#%d: no space for size 0x%08x at "
 1393                             "0x%08x\n", i, s, b);
 1394                         rv = 0;
 1395                         continue;
 1396                 }
 1397 
 1398                 j = decode_win_overlap(i, xor_wins_no, &xor_wins[0]);
 1399                 if (j >= 0) {
 1400                         printf("XOR window#%d: (0x%08x - 0x%08x) overlaps "
 1401                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
 1402                             xor_wins[j].base,
 1403                             xor_wins[j].base + xor_wins[j].size - 1);
 1404                         rv = 0;
 1405                 }
 1406         }
 1407 
 1408         return (rv);
 1409 }
 1410 
 1411 void
 1412 decode_win_xor_dump(void)
 1413 {
 1414         int i, j;
 1415         int e = 1;
 1416 
 1417         for (j = 0; j < xor_max_eng(); j++, e--) {
 1418                 for (i = 0; i < MV_WIN_XOR_MAX; i++) {
 1419                         printf("XOR window#%d: b 0x%08x, s 0x%08x", i,
 1420                             win_xor_br_read(i, e), win_xor_sz_read(i, e));
 1421 
 1422                         if (win_xor_can_remap(i))
 1423                                 printf(", ha 0x%08x", win_xor_har_read(i, e));
 1424 
 1425                         printf("\n");
 1426                 }
 1427                 for (i = 0; i < MV_XOR_CHAN_MAX; i++)
 1428                         printf("XOR control#%d: 0x%08x\n", i,
 1429                             win_xor_ctrl_read(i, e));
 1430         }
 1431 }
 1432 
 1433 #else
 1434 /* Provide dummy functions to satisfy the build for SoCs not equipped with XOR */
 1435 int
 1436 decode_win_xor_valid(void)
 1437 {
 1438 
 1439         return (1);
 1440 }
 1441 
 1442 void
 1443 decode_win_xor_setup(void)
 1444 {
 1445 }
 1446 
 1447 void
 1448 decode_win_xor_dump(void)
 1449 {
 1450 }
 1451 #endif
 1452 
 1453 /**************************************************************************
 1454  * CESA TDMA windows routines
 1455  **************************************************************************/
 1456 #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
 1457 /*
 1458  * Dump CESA TDMA decode windows.
 1459  */
 1460 static void
 1461 decode_win_cesa_dump(void)
 1462 {
 1463         int i;
 1464 
 1465         for (i = 0; i < MV_WIN_CESA_MAX; i++)
 1466                 printf("CESA window#%d: c 0x%08x, b 0x%08x\n", i,
 1467                     win_cesa_cr_read(i), win_cesa_br_read(i));
 1468 }
 1469 
 1470 
 1471 /*
 1472  * Set CESA TDMA decode windows.
 1473  */
 1474 static void
 1475 decode_win_cesa_setup(void)
 1476 {
 1477         uint32_t br, cr;
 1478         int i, j;
 1479 
 1480         if (pm_is_disabled(CPU_PM_CTRL_CRYPTO))
 1481                 return;
 1482 
 1483         /* Disable and clear all CESA windows */
 1484         for (i = 0; i < MV_WIN_CESA_MAX; i++) {
 1485                 win_cesa_cr_write(i, 0);
 1486                 win_cesa_br_write(i, 0);
 1487         }
 1488 
 1489         /* Only access to active DRAM banks is required. */
 1490         for (i = 0; i < MV_WIN_DDR_MAX; i++)
 1491                 if (ddr_is_active(i)) {
 1492                         br = ddr_base(i);
 1493                         cr = (((ddr_size(i) - 1) & 0xffff0000) |
 1494                            (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1);
 1495 
 1496                         /* Set the first available CESA window */
 1497                         for (j = 0; j < MV_WIN_CESA_MAX; j++) {
 1498                                 if (win_cesa_cr_read(j) & 0x1)
 1499                                         continue;
 1500 
 1501                                 win_cesa_br_write(j, br);
 1502                                 win_cesa_cr_write(j, cr);
 1503                                 break;
 1504                         }
 1505                 }
 1506 }
 1507 
 1508 /*
 1509  * Check CESA TDMA decode windows.
 1510  */
 1511 static int
 1512 decode_win_cesa_valid(void)
 1513 {
 1514 
 1515         return (decode_win_can_cover_ddr(MV_WIN_CESA_MAX));
 1516 }
 1517 #else
 1518 
 1519 /*
 1520  * Provide dummy functions to satisfy the build for SoCs not equipped with
 1521  * CESA
 1522  */
 1523 
 1524 int
 1525 decode_win_cesa_valid(void)
 1526 {
 1527 
 1528         return (1);
 1529 }
 1530 
 1531 void
 1532 decode_win_cesa_setup(void)
 1533 {
 1534 }
 1535 
 1536 void
 1537 decode_win_cesa_dump(void)
 1538 {
 1539 }
 1540 #endif
 1541 
 1542 /**************************************************************************
 1543  * SATA windows routines
 1544  **************************************************************************/
 1545 static void
 1546 decode_win_sata_setup(void)
 1547 {
 1548         uint32_t cr, br;
 1549         int i, j;
 1550 
 1551         if (pm_is_disabled(CPU_PM_CTRL_SATA))
 1552                 return;
 1553 
 1554         for (i = 0; i < MV_WIN_SATA_MAX; i++) {
 1555                 win_sata_cr_write(i, 0);
 1556                 win_sata_br_write(i, 0);
 1557         }
 1558 
 1559         for (i = 0; i < MV_WIN_DDR_MAX; i++)
 1560                 if (ddr_is_active(i)) {
 1561                         cr = ((ddr_size(i) - 1) & 0xffff0000) |
 1562                             (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
 1563                         br = ddr_base(i);
 1564 
 1565                         /* Use the first available SATA window */
 1566                         for (j = 0; j < MV_WIN_SATA_MAX; j++) {
 1567                                 if ((win_sata_cr_read(j) & 1) != 0)
 1568                                         continue;
 1569 
 1570                                 win_sata_br_write(j, br);
 1571                                 win_sata_cr_write(j, cr);
 1572                                 break;
 1573                         }
 1574                 }
 1575 }
 1576 
 1577 static int
 1578 decode_win_sata_valid(void)
 1579 {
 1580         uint32_t dev, rev;
 1581 
 1582         soc_id(&dev, &rev);
 1583         if (dev == MV_DEV_88F5281)
 1584                 return (1);
 1585 
 1586         return (decode_win_can_cover_ddr(MV_WIN_SATA_MAX));
 1587 }

Cache object: 82aad0780dc4b2664cc82b464467e548


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