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 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <common.h> 11 #include <asm/io.h> 12 #include <asm/arch/armada100.h> 13 14 DECLARE_GLOBAL_DATA_PTR; 15 16 /* 17 * ARMADA100 DRAM controller supports upto 8 banks 18 * for chip select 0 and 1 19 */ 20 21 /* 22 * DDR Memory Control Registers 23 * Refer Datasheet Appendix A.17 24 */ 25 struct armd1ddr_map_registers { 26 u32 cs; /* Memory Address Map Register -CS */ 27 u32 pad[3]; 28 }; 29 30 struct armd1ddr_registers { 31 u8 pad[0x100 - 0x000]; 32 struct armd1ddr_map_registers mmap[2]; 33 }; 34 35 /* 36 * armd1_sdram_base - reads SDRAM Base Address Register 37 */ 38 u32 armd1_sdram_base(int chip_sel) 39 { 40 struct armd1ddr_registers *ddr_regs = 41 (struct armd1ddr_registers *)ARMD1_DRAM_BASE; 42 u32 result = 0; 43 u32 CS_valid = 0x01 & readl(&ddr_regs->mmap[chip_sel].cs); 44 45 if (!CS_valid) 46 return 0; 47 48 result = readl(&ddr_regs->mmap[chip_sel].cs) & 0xFF800000; 49 return result; 50 } 51 52 /* 53 * armd1_sdram_size - reads SDRAM size 54 */ 55 u32 armd1_sdram_size(int chip_sel) 56 { 57 struct armd1ddr_registers *ddr_regs = 58 (struct armd1ddr_registers *)ARMD1_DRAM_BASE; 59 u32 result = 0; 60 u32 CS_valid = 0x01 & readl(&ddr_regs->mmap[chip_sel].cs); 61 62 if (!CS_valid) 63 return 0; 64 65 result = readl(&ddr_regs->mmap[chip_sel].cs); 66 result = (result >> 16) & 0xF; 67 if (result < 0x7) { 68 printf("Unknown DRAM Size\n"); 69 return -1; 70 } else { 71 return ((0x8 << (result - 0x7)) * 1024 * 1024); 72 } 73 } 74 75 #ifndef CONFIG_SYS_BOARD_DRAM_INIT 76 int dram_init(void) 77 { 78 int i; 79 80 gd->ram_size = 0; 81 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { 82 gd->bd->bi_dram[i].start = armd1_sdram_base(i); 83 gd->bd->bi_dram[i].size = armd1_sdram_size(i); 84 /* 85 * It is assumed that all memory banks are consecutive 86 * and without gaps. 87 * If the gap is found, ram_size will be reported for 88 * consecutive memory only 89 */ 90 if (gd->bd->bi_dram[i].start != gd->ram_size) 91 break; 92 93 gd->ram_size += gd->bd->bi_dram[i].size; 94 95 } 96 97 for (; i < CONFIG_NR_DRAM_BANKS; i++) { 98 /* If above loop terminated prematurely, we need to set 99 * remaining banks' start address & size as 0. Otherwise other 100 * u-boot functions and Linux kernel gets wrong values which 101 * could result in crash */ 102 gd->bd->bi_dram[i].start = 0; 103 gd->bd->bi_dram[i].size = 0; 104 } 105 return 0; 106 } 107 108 /* 109 * If this function is not defined here, 110 * board.c alters dram bank zero configuration defined above. 111 */ 112 void dram_init_banksize(void) 113 { 114 dram_init(); 115 } 116 #endif /* CONFIG_SYS_BOARD_DRAM_INIT */ 117