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/armadaxp/armadaxp.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) 2011 Semihalf.
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  * From: FreeBSD: src/sys/arm/mv/kirkwood/sheevaplug.c,v 1.2 2010/06/13 13:28:53
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD: releng/11.1/sys/arm/mv/armadaxp/armadaxp.c 298352 2016-04-20 15:45:55Z pfg $");
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/bus.h>
   35 
   36 #include <machine/bus.h>
   37 #include <machine/armreg.h>
   38 
   39 #include <arm/mv/mvwin.h>
   40 #include <arm/mv/mvreg.h>
   41 #include <arm/mv/mvvar.h>
   42 
   43 #include <dev/fdt/fdt_common.h>
   44 #include <dev/ofw/openfirm.h>
   45 
   46 #include <machine/fdt.h>
   47 
   48 #define CPU_FREQ_FIELD(sar)     (((0x01 & (sar >> 52)) << 3) | \
   49                                     (0x07 & (sar >> 21)))
   50 #define FAB_FREQ_FIELD(sar)     (((0x01 & (sar >> 51)) << 4) | \
   51                                     (0x0F & (sar >> 24)))
   52 
   53 static uint32_t count_l2clk(void);
   54 void armadaxp_l2_init(void);
   55 void armadaxp_init_coher_fabric(void);
   56 int platform_get_ncpus(void);
   57 
   58 #define ARMADAXP_L2_BASE                (MV_BASE + 0x8000)
   59 #define ARMADAXP_L2_CTRL                0x100
   60 #define L2_ENABLE                       (1 << 0)
   61 #define ARMADAXP_L2_AUX_CTRL            0x104
   62 #define L2_WBWT_MODE_MASK               (3 << 0)
   63 #define L2_WBWT_MODE_PAGE               0
   64 #define L2_WBWT_MODE_WB                 1
   65 #define L2_WBWT_MODE_WT                 2
   66 #define L2_REP_STRAT_MASK               (3 << 27)
   67 #define L2_REP_STRAT_LSFR               (1 << 27)
   68 #define L2_REP_STRAT_SEMIPLRU           (3 << 27)
   69 
   70 #define ARMADAXP_L2_CNTR_CTRL           0x200
   71 #define ARMADAXP_L2_CNTR_CONF(x)        (0x204 + (x) * 0xc)
   72 #define ARMADAXP_L2_CNTR2_VAL_LOW       (0x208 + (x) * 0xc)
   73 #define ARMADAXP_L2_CNTR2_VAL_HI        (0x20c + (x) * 0xc)
   74 
   75 #define ARMADAXP_L2_INT_CAUSE           0x220
   76 
   77 #define ARMADAXP_L2_SYNC_BARRIER        0x700
   78 #define ARMADAXP_L2_INV_WAY             0x778
   79 #define ARMADAXP_L2_CLEAN_WAY           0x7BC
   80 #define ARMADAXP_L2_FLUSH_PHYS          0x7F0
   81 #define ARMADAXP_L2_FLUSH_WAY           0x7FC
   82 
   83 #define MV_COHERENCY_FABRIC_BASE        (MV_MBUS_BRIDGE_BASE + 0x200)
   84 #define COHER_FABRIC_CTRL               0x00
   85 #define COHER_FABRIC_CONF               0x04
   86 #define COHER_FABRIC_CFU                0x28
   87 #define COHER_FABRIC_CIB_CTRL           0x80
   88 
   89 struct vco_freq_ratio {
   90         uint8_t vco_cpu;        /* VCO to CLK0(CPU) clock ratio */
   91         uint8_t vco_l2c;        /* VCO to NB(L2 cache) clock ratio */
   92         uint8_t vco_hcl;        /* VCO to HCLK(DDR controller) clock ratio */
   93         uint8_t vco_ddr;        /* VCO to DR(DDR memory) clock ratio */
   94 };
   95 
   96 static struct vco_freq_ratio freq_conf_table[] = {
   97 /*00*/  { 1, 1,  4,  2 },
   98 /*01*/  { 1, 2,  2,  2 },
   99 /*02*/  { 2, 2,  6,  3 },
  100 /*03*/  { 2, 2,  3,  3 },
  101 /*04*/  { 1, 2,  3,  3 },
  102 /*05*/  { 1, 2,  4,  2 },
  103 /*06*/  { 1, 1,  2,  2 },
  104 /*07*/  { 2, 3,  6,  6 },
  105 /*08*/  { 2, 3,  5,  5 },
  106 /*09*/  { 1, 2,  6,  3 },
  107 /*10*/  { 2, 4, 10,  5 },
  108 /*11*/  { 1, 3,  6,  6 },
  109 /*12*/  { 1, 2,  5,  5 },
  110 /*13*/  { 1, 3,  6,  3 },
  111 /*14*/  { 1, 2,  5,  5 },
  112 /*15*/  { 2, 2,  5,  5 },
  113 /*16*/  { 1, 1,  3,  3 },
  114 /*17*/  { 2, 5, 10, 10 },
  115 /*18*/  { 1, 3,  8,  4 },
  116 /*19*/  { 1, 1,  2,  1 },
  117 /*20*/  { 2, 3,  6,  3 },
  118 /*21*/  { 1, 2,  8,  4 },
  119 /*22*/  { 2, 5, 10,  5 }
  120 };
  121 
  122 static uint16_t cpu_clock_table[] = {
  123     1000, 1066, 1200, 1333, 1500, 1666, 1800, 2000, 600,  667,  800,  1600,
  124     2133, 2200, 2400 };
  125 
  126 uint32_t
  127 get_tclk(void)
  128 {
  129         uint32_t cputype;
  130 
  131         cputype = cpu_ident();
  132         cputype &= CPU_ID_CPU_MASK;
  133 
  134         if (cputype == CPU_ID_MV88SV584X_V7)
  135                 return (TCLK_250MHZ);
  136         else
  137                 return (TCLK_200MHZ);
  138 }
  139 
  140 static uint32_t
  141 count_l2clk(void)
  142 {
  143         uint64_t sar_reg;
  144         uint32_t freq_vco, freq_l2clk;
  145         uint8_t  sar_cpu_freq, sar_fab_freq, array_size;
  146 
  147         /* Get value of the SAR register and process it */
  148         sar_reg = get_sar_value();
  149         sar_cpu_freq = CPU_FREQ_FIELD(sar_reg);
  150         sar_fab_freq = FAB_FREQ_FIELD(sar_reg);
  151 
  152         /* Check if CPU frequency field has correct value */
  153         array_size = nitems(cpu_clock_table);
  154         if (sar_cpu_freq >= array_size)
  155                 panic("Reserved value in cpu frequency configuration field: "
  156                     "%d", sar_cpu_freq);
  157 
  158         /* Check if fabric frequency field has correct value */
  159         array_size = nitems(freq_conf_table);
  160         if (sar_fab_freq >= array_size)
  161                 panic("Reserved value in fabric frequency configuration field: "
  162                     "%d", sar_fab_freq);
  163 
  164         /* Get CPU clock frequency */
  165         freq_vco = cpu_clock_table[sar_cpu_freq] *
  166             freq_conf_table[sar_fab_freq].vco_cpu;
  167 
  168         /* Get L2CLK clock frequency */
  169         freq_l2clk = freq_vco / freq_conf_table[sar_fab_freq].vco_l2c;
  170 
  171         /* Round L2CLK value to integer MHz */
  172         if (((freq_vco % freq_conf_table[sar_fab_freq].vco_l2c) * 10 /
  173             freq_conf_table[sar_fab_freq].vco_l2c) >= 5)
  174                 freq_l2clk++;
  175 
  176         return (freq_l2clk * 1000000);
  177 }
  178 
  179 uint32_t
  180 get_l2clk(void)
  181 {
  182         static uint32_t l2clk_freq = 0;
  183 
  184         /* If get_l2clk is called first time get L2CLK value from register */
  185         if (l2clk_freq == 0)
  186                 l2clk_freq = count_l2clk();
  187 
  188         return (l2clk_freq);
  189 }
  190 
  191 static uint32_t
  192 read_coher_fabric(uint32_t reg)
  193 {
  194 
  195         return (bus_space_read_4(fdtbus_bs_tag, MV_COHERENCY_FABRIC_BASE, reg));
  196 }
  197 
  198 static void
  199 write_coher_fabric(uint32_t reg, uint32_t val)
  200 {
  201 
  202         bus_space_write_4(fdtbus_bs_tag, MV_COHERENCY_FABRIC_BASE, reg, val);
  203 }
  204 
  205 int
  206 platform_get_ncpus(void)
  207 {
  208 #if !defined(SMP)
  209         return (1);
  210 #else
  211         return ((read_coher_fabric(COHER_FABRIC_CONF) & 0xf) + 1);
  212 #endif
  213 }
  214 
  215 void
  216 armadaxp_init_coher_fabric(void)
  217 {
  218         uint32_t val, cpus, mask;
  219 
  220         cpus = platform_get_ncpus();
  221         mask = (1 << cpus) - 1;
  222         val = read_coher_fabric(COHER_FABRIC_CTRL);
  223         val |= (mask << 24);
  224         write_coher_fabric(COHER_FABRIC_CTRL, val);
  225 
  226         val = read_coher_fabric(COHER_FABRIC_CONF);
  227         val |= (mask << 24);
  228         val |= (1 << 15);
  229         write_coher_fabric(COHER_FABRIC_CONF, val);
  230 }
  231 
  232 #define ALL_WAYS        0xffffffff
  233 
  234 /* L2 cache configuration registers */
  235 static uint32_t
  236 read_l2_cache(uint32_t reg)
  237 {
  238 
  239         return (bus_space_read_4(fdtbus_bs_tag, ARMADAXP_L2_BASE, reg));
  240 }
  241 
  242 static void
  243 write_l2_cache(uint32_t reg, uint32_t val)
  244 {
  245 
  246         bus_space_write_4(fdtbus_bs_tag, ARMADAXP_L2_BASE, reg, val);
  247 }
  248 
  249 static void
  250 armadaxp_l2_idcache_inv_all(void)
  251 {
  252         write_l2_cache(ARMADAXP_L2_INV_WAY, ALL_WAYS);
  253 }
  254 
  255 void
  256 armadaxp_l2_init(void)
  257 {
  258         u_int32_t reg;
  259 
  260         /* Set L2 policy */
  261         reg = read_l2_cache(ARMADAXP_L2_AUX_CTRL);
  262         reg &= ~(L2_WBWT_MODE_MASK);
  263         reg &= ~(L2_REP_STRAT_MASK);
  264         reg |= L2_REP_STRAT_SEMIPLRU;
  265         reg |= L2_WBWT_MODE_WT;
  266         write_l2_cache(ARMADAXP_L2_AUX_CTRL, reg);
  267 
  268         /* Invalidate l2 cache */
  269         armadaxp_l2_idcache_inv_all();
  270 
  271         /* Clear pending L2 interrupts */
  272         write_l2_cache(ARMADAXP_L2_INT_CAUSE, 0x1ff);
  273 
  274         /* Enable l2 cache */
  275         reg = read_l2_cache(ARMADAXP_L2_CTRL);
  276         write_l2_cache(ARMADAXP_L2_CTRL, reg | L2_ENABLE);
  277 
  278         /*
  279          * For debug purposes
  280          * Configure and enable counter
  281          */
  282         write_l2_cache(ARMADAXP_L2_CNTR_CONF(0), 0xf0000 | (4 << 2));
  283         write_l2_cache(ARMADAXP_L2_CNTR_CONF(1), 0xf0000 | (2 << 2));
  284         write_l2_cache(ARMADAXP_L2_CNTR_CTRL, 0x303);
  285 
  286         /*
  287          * Enable Cache maintenance operation propagation in coherency fabric
  288          * Change point of coherency and point of unification to DRAM.
  289          */
  290         reg = read_coher_fabric(COHER_FABRIC_CFU);
  291         reg |= (1 << 17) | (1 << 18);
  292         write_coher_fabric(COHER_FABRIC_CFU, reg);
  293 
  294         /* Coherent IO Bridge initialization */
  295         reg = read_coher_fabric(COHER_FABRIC_CIB_CTRL);
  296         reg &= ~(7 << 16);
  297         reg |= (7 << 16);
  298         write_coher_fabric(COHER_FABRIC_CIB_CTRL, reg);
  299 }
  300 

Cache object: 05eb4da07e604e5138df22b2d45e2635


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