uboot/arch/arm/cpu/arm926ejs/armada100/dram.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2010
   3 * Marvell Semiconductor <www.marvell.com>
   4 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>,
   5 * Contributor: Mahavir Jain <mjain@marvell.com>
   6 *
   7 * See file CREDITS for list of people who contributed to this
   8 * project.
   9 *
  10 * This program is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU General Public License as
  12 * published by the Free Software Foundation; either version 2 of
  13 * the License, or (at your option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18 * GNU General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU General Public License
  21 * along with this program; if not, write to the Free Software
  22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  23 * MA 02110-1301 USA
  24 */
  25
  26#include <common.h>
  27#include <asm/io.h>
  28#include <asm/arch/armada100.h>
  29
  30DECLARE_GLOBAL_DATA_PTR;
  31
  32/*
  33 * ARMADA100 DRAM controller supports upto 8 banks
  34 * for chip select 0 and 1
  35 */
  36
  37/*
  38 * DDR Memory Control Registers
  39 * Refer Datasheet Appendix A.17
  40 */
  41struct armd1ddr_map_registers {
  42        u32     cs;     /* Memory Address Map Register -CS */
  43        u32     pad[3];
  44};
  45
  46struct armd1ddr_registers {
  47        u8      pad[0x100 - 0x000];
  48        struct armd1ddr_map_registers mmap[2];
  49};
  50
  51/*
  52 * armd1_sdram_base - reads SDRAM Base Address Register
  53 */
  54u32 armd1_sdram_base(int chip_sel)
  55{
  56        struct armd1ddr_registers *ddr_regs =
  57                (struct armd1ddr_registers *)ARMD1_DRAM_BASE;
  58        u32 result = 0;
  59        u32 CS_valid = 0x01 & readl(&ddr_regs->mmap[chip_sel].cs);
  60
  61        if (!CS_valid)
  62                return 0;
  63
  64        result = readl(&ddr_regs->mmap[chip_sel].cs) & 0xFF800000;
  65        return result;
  66}
  67
  68/*
  69 * armd1_sdram_size - reads SDRAM size
  70 */
  71u32 armd1_sdram_size(int chip_sel)
  72{
  73        struct armd1ddr_registers *ddr_regs =
  74                (struct armd1ddr_registers *)ARMD1_DRAM_BASE;
  75        u32 result = 0;
  76        u32 CS_valid = 0x01 & readl(&ddr_regs->mmap[chip_sel].cs);
  77
  78        if (!CS_valid)
  79                return 0;
  80
  81        result = readl(&ddr_regs->mmap[chip_sel].cs);
  82        result = (result >> 16) & 0xF;
  83        if (result < 0x7) {
  84                printf("Unknown DRAM Size\n");
  85                return -1;
  86        } else {
  87                return ((0x8 << (result - 0x7)) * 1024 * 1024);
  88        }
  89}
  90
  91#ifndef CONFIG_SYS_BOARD_DRAM_INIT
  92int dram_init(void)
  93{
  94        int i;
  95
  96        gd->ram_size = 0;
  97        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
  98                gd->bd->bi_dram[i].start = armd1_sdram_base(i);
  99                gd->bd->bi_dram[i].size = armd1_sdram_size(i);
 100                /*
 101                 * It is assumed that all memory banks are consecutive
 102                 * and without gaps.
 103                 * If the gap is found, ram_size will be reported for
 104                 * consecutive memory only
 105                 */
 106                if (gd->bd->bi_dram[i].start != gd->ram_size)
 107                        break;
 108
 109                gd->ram_size += gd->bd->bi_dram[i].size;
 110
 111        }
 112
 113        for (; i < CONFIG_NR_DRAM_BANKS; i++) {
 114                /* If above loop terminated prematurely, we need to set
 115                 * remaining banks' start address & size as 0. Otherwise other
 116                 * u-boot functions and Linux kernel gets wrong values which
 117                 * could result in crash */
 118                gd->bd->bi_dram[i].start = 0;
 119                gd->bd->bi_dram[i].size = 0;
 120        }
 121        return 0;
 122}
 123
 124/*
 125 * If this function is not defined here,
 126 * board.c alters dram bank zero configuration defined above.
 127 */
 128void dram_init_banksize(void)
 129{
 130        dram_init();
 131}
 132#endif /* CONFIG_SYS_BOARD_DRAM_INIT */
 133