uboot/arch/arm/mach-mvebu/dram.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2009
   4 * Marvell Semiconductor <www.marvell.com>
   5 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
   6 */
   7
   8#include <config.h>
   9#include <common.h>
  10#include <asm/io.h>
  11#include <asm/arch/cpu.h>
  12#include <asm/arch/soc.h>
  13
  14#if defined(CONFIG_ARCH_MVEBU)
  15/* Use common XOR definitions for A3x and AXP */
  16#include "../../../drivers/ddr/marvell/axp/xor.h"
  17#include "../../../drivers/ddr/marvell/axp/xor_regs.h"
  18#endif
  19
  20DECLARE_GLOBAL_DATA_PTR;
  21
  22struct sdram_bank {
  23        u32     win_bar;
  24        u32     win_sz;
  25};
  26
  27struct sdram_addr_dec {
  28        struct sdram_bank sdram_bank[4];
  29};
  30
  31#define REG_CPUCS_WIN_ENABLE            (1 << 0)
  32#define REG_CPUCS_WIN_WR_PROTECT        (1 << 1)
  33#define REG_CPUCS_WIN_WIN0_CS(x)        (((x) & 0x3) << 2)
  34#define REG_CPUCS_WIN_SIZE(x)           (((x) & 0xff) << 24)
  35
  36#ifndef MVEBU_SDRAM_SIZE_MAX
  37#define MVEBU_SDRAM_SIZE_MAX            0xc0000000
  38#endif
  39
  40#define SCRUB_MAGIC             0xbeefdead
  41
  42#define SCRB_XOR_UNIT           0
  43#define SCRB_XOR_CHAN           1
  44#define SCRB_XOR_WIN            0
  45
  46#define XEBARX_BASE_OFFS        16
  47
  48/*
  49 * mvebu_sdram_bar - reads SDRAM Base Address Register
  50 */
  51u32 mvebu_sdram_bar(enum memory_bank bank)
  52{
  53        struct sdram_addr_dec *base =
  54                (struct sdram_addr_dec *)MVEBU_SDRAM_BASE;
  55        u32 result = 0;
  56        u32 enable = 0x01 & readl(&base->sdram_bank[bank].win_sz);
  57
  58        if ((!enable) || (bank > BANK3))
  59                return 0;
  60
  61        result = readl(&base->sdram_bank[bank].win_bar);
  62        return result;
  63}
  64
  65/*
  66 * mvebu_sdram_bs_set - writes SDRAM Bank size
  67 */
  68static void mvebu_sdram_bs_set(enum memory_bank bank, u32 size)
  69{
  70        struct sdram_addr_dec *base =
  71                (struct sdram_addr_dec *)MVEBU_SDRAM_BASE;
  72        /* Read current register value */
  73        u32 reg = readl(&base->sdram_bank[bank].win_sz);
  74
  75        /* Clear window size */
  76        reg &= ~REG_CPUCS_WIN_SIZE(0xFF);
  77
  78        /* Set new window size */
  79        reg |= REG_CPUCS_WIN_SIZE((size - 1) >> 24);
  80
  81        writel(reg, &base->sdram_bank[bank].win_sz);
  82}
  83
  84/*
  85 * mvebu_sdram_bs - reads SDRAM Bank size
  86 */
  87u32 mvebu_sdram_bs(enum memory_bank bank)
  88{
  89        struct sdram_addr_dec *base =
  90                (struct sdram_addr_dec *)MVEBU_SDRAM_BASE;
  91        u32 result = 0;
  92        u32 enable = 0x01 & readl(&base->sdram_bank[bank].win_sz);
  93
  94        if ((!enable) || (bank > BANK3))
  95                return 0;
  96        result = 0xff000000 & readl(&base->sdram_bank[bank].win_sz);
  97        result += 0x01000000;
  98        return result;
  99}
 100
 101void mvebu_sdram_size_adjust(enum memory_bank bank)
 102{
 103        u32 size;
 104
 105        /* probe currently equipped RAM size */
 106        size = get_ram_size((void *)mvebu_sdram_bar(bank),
 107                            mvebu_sdram_bs(bank));
 108
 109        /* adjust SDRAM window size accordingly */
 110        mvebu_sdram_bs_set(bank, size);
 111}
 112
 113#if defined(CONFIG_ARCH_MVEBU)
 114static u32 xor_ctrl_save;
 115static u32 xor_base_save;
 116static u32 xor_mask_save;
 117
 118static void mv_xor_init2(u32 cs)
 119{
 120        u32 reg, base, size, base2;
 121        u32 bank_attr[4] = { 0xe00, 0xd00, 0xb00, 0x700 };
 122
 123        xor_ctrl_save = reg_read(XOR_WINDOW_CTRL_REG(SCRB_XOR_UNIT,
 124                                                     SCRB_XOR_CHAN));
 125        xor_base_save = reg_read(XOR_BASE_ADDR_REG(SCRB_XOR_UNIT,
 126                                                   SCRB_XOR_WIN));
 127        xor_mask_save = reg_read(XOR_SIZE_MASK_REG(SCRB_XOR_UNIT,
 128                                                   SCRB_XOR_WIN));
 129
 130        /* Enable Window x for each CS */
 131        reg = 0x1;
 132        reg |= (0x3 << 16);
 133        reg_write(XOR_WINDOW_CTRL_REG(SCRB_XOR_UNIT, SCRB_XOR_CHAN), reg);
 134
 135        base = 0;
 136        size = mvebu_sdram_bs(cs) - 1;
 137        if (size) {
 138                base2 = ((base / (64 << 10)) << XEBARX_BASE_OFFS) |
 139                        bank_attr[cs];
 140                reg_write(XOR_BASE_ADDR_REG(SCRB_XOR_UNIT, SCRB_XOR_WIN),
 141                          base2);
 142
 143                base += size + 1;
 144                size = (size / (64 << 10)) << 16;
 145                /* Window x - size - 256 MB */
 146                reg_write(XOR_SIZE_MASK_REG(SCRB_XOR_UNIT, SCRB_XOR_WIN), size);
 147        }
 148
 149        mv_xor_hal_init(0);
 150
 151        return;
 152}
 153
 154static void mv_xor_finish2(void)
 155{
 156        reg_write(XOR_WINDOW_CTRL_REG(SCRB_XOR_UNIT, SCRB_XOR_CHAN),
 157                  xor_ctrl_save);
 158        reg_write(XOR_BASE_ADDR_REG(SCRB_XOR_UNIT, SCRB_XOR_WIN),
 159                  xor_base_save);
 160        reg_write(XOR_SIZE_MASK_REG(SCRB_XOR_UNIT, SCRB_XOR_WIN),
 161                  xor_mask_save);
 162}
 163
 164static void dram_ecc_scrubbing(void)
 165{
 166        int cs;
 167        u32 size, temp;
 168        u32 total_mem = 0;
 169        u64 total;
 170        u32 start_addr;
 171
 172        /*
 173         * The DDR training code from the bin_hdr / SPL already
 174         * scrubbed the DDR till 0x1000000. And the main U-Boot
 175         * is loaded to an address < 0x1000000. So we need to
 176         * skip this range to not re-scrub this area again.
 177         */
 178        temp = reg_read(REG_SDRAM_CONFIG_ADDR);
 179        temp |= (1 << REG_SDRAM_CONFIG_IERR_OFFS);
 180        reg_write(REG_SDRAM_CONFIG_ADDR, temp);
 181
 182        for (cs = 0; cs < CONFIG_NR_DRAM_BANKS; cs++) {
 183                size = mvebu_sdram_bs(cs);
 184                if (size == 0)
 185                        continue;
 186
 187                total = (u64)size;
 188                total_mem += (u32)(total / (1 << 30));
 189                start_addr = 0;
 190                mv_xor_init2(cs);
 191
 192                /* Skip first 16 MiB */
 193                if (0 == cs) {
 194                        start_addr = 0x1000000;
 195                        size -= start_addr;
 196                }
 197
 198                mv_xor_mem_init(SCRB_XOR_CHAN, start_addr, size - 1,
 199                                SCRUB_MAGIC, SCRUB_MAGIC);
 200
 201                /* Wait for previous transfer completion */
 202                while (mv_xor_state_get(SCRB_XOR_CHAN) != MV_IDLE)
 203                        ;
 204
 205                mv_xor_finish2();
 206        }
 207
 208        temp = reg_read(REG_SDRAM_CONFIG_ADDR);
 209        temp &= ~(1 << REG_SDRAM_CONFIG_IERR_OFFS);
 210        reg_write(REG_SDRAM_CONFIG_ADDR, temp);
 211}
 212
 213static int ecc_enabled(void)
 214{
 215        if (reg_read(REG_SDRAM_CONFIG_ADDR) & (1 << REG_SDRAM_CONFIG_ECC_OFFS))
 216                return 1;
 217
 218        return 0;
 219}
 220
 221/* Return the width of the DRAM bus, or 0 for unknown. */
 222static int bus_width(void)
 223{
 224        int full_width = 0;
 225
 226        if (reg_read(REG_SDRAM_CONFIG_ADDR) & (1 << REG_SDRAM_CONFIG_WIDTH_OFFS))
 227                full_width = 1;
 228
 229        switch (mvebu_soc_family()) {
 230        case MVEBU_SOC_AXP:
 231            return full_width ? 64 : 32;
 232            break;
 233        case MVEBU_SOC_A375:
 234        case MVEBU_SOC_A38X:
 235        case MVEBU_SOC_MSYS:
 236            return full_width ? 32 : 16;
 237        default:
 238            return 0;
 239        }
 240}
 241
 242static int cycle_mode(void)
 243{
 244        int val = reg_read(REG_DUNIT_CTRL_LOW_ADDR);
 245
 246        return (val >> REG_DUNIT_CTRL_LOW_2T_OFFS) & REG_DUNIT_CTRL_LOW_2T_MASK;
 247}
 248
 249#else
 250static void dram_ecc_scrubbing(void)
 251{
 252}
 253
 254static int ecc_enabled(void)
 255{
 256        return 0;
 257}
 258#endif
 259
 260int dram_init(void)
 261{
 262        u64 size = 0;
 263        int i;
 264
 265        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 266                /*
 267                 * It is assumed that all memory banks are consecutive
 268                 * and without gaps.
 269                 * If the gap is found, ram_size will be reported for
 270                 * consecutive memory only
 271                 */
 272                if (mvebu_sdram_bar(i) != size)
 273                        break;
 274
 275                /*
 276                 * Don't report more than 3GiB of SDRAM, otherwise there is no
 277                 * address space left for the internal registers etc.
 278                 */
 279                size += mvebu_sdram_bs(i);
 280                if (size > MVEBU_SDRAM_SIZE_MAX)
 281                        size = MVEBU_SDRAM_SIZE_MAX;
 282        }
 283
 284        for (; i < CONFIG_NR_DRAM_BANKS; i++) {
 285                /* If above loop terminated prematurely, we need to set
 286                 * remaining banks' start address & size as 0. Otherwise other
 287                 * u-boot functions and Linux kernel gets wrong values which
 288                 * could result in crash */
 289                gd->bd->bi_dram[i].start = 0;
 290                gd->bd->bi_dram[i].size = 0;
 291        }
 292
 293
 294        if (ecc_enabled())
 295                dram_ecc_scrubbing();
 296
 297        gd->ram_size = size;
 298
 299        return 0;
 300}
 301
 302/*
 303 * If this function is not defined here,
 304 * board.c alters dram bank zero configuration defined above.
 305 */
 306int dram_init_banksize(void)
 307{
 308        u64 size = 0;
 309        int i;
 310
 311        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 312                gd->bd->bi_dram[i].start = mvebu_sdram_bar(i);
 313                gd->bd->bi_dram[i].size = mvebu_sdram_bs(i);
 314
 315                /* Clip the banksize to 1GiB if it exceeds the max size */
 316                size += gd->bd->bi_dram[i].size;
 317                if (size > MVEBU_SDRAM_SIZE_MAX)
 318                        mvebu_sdram_bs_set(i, 0x40000000);
 319        }
 320
 321        return 0;
 322}
 323
 324#if defined(CONFIG_ARCH_MVEBU)
 325void board_add_ram_info(int use_default)
 326{
 327        struct sar_freq_modes sar_freq;
 328        int mode;
 329        int width;
 330
 331        get_sar_freq(&sar_freq);
 332        printf(" (%d MHz, ", sar_freq.d_clk);
 333
 334        width = bus_width();
 335        if (width)
 336                printf("%d-bit, ", width);
 337
 338        mode = cycle_mode();
 339        /* Mode 0 = Single cycle
 340         * Mode 1 = Two cycles   (2T)
 341         * Mode 2 = Three cycles (3T)
 342         */
 343        if (mode == 1)
 344                printf("2T, ");
 345        if (mode == 2)
 346                printf("3T, ");
 347
 348        if (ecc_enabled())
 349                printf("ECC");
 350        else
 351                printf("ECC not");
 352        printf(" enabled)");
 353}
 354#endif
 355