1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2010 4 * Marvell Semiconductor <www.marvell.com> 5 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>, 6 * Contributor: Mahavir Jain <mjain@marvell.com> 7 */ 8 9 #include <common.h> 10 #include <init.h> 11 #include <asm/global_data.h> 12 #include <asm/io.h> 13 #include <asm/arch/armada100.h> 14 15 DECLARE_GLOBAL_DATA_PTR; 16 17 /* 18 * ARMADA100 DRAM controller supports upto 8 banks 19 * for chip select 0 and 1 20 */ 21 22 /* 23 * DDR Memory Control Registers 24 * Refer Datasheet Appendix A.17 25 */ 26 struct armd1ddr_map_registers { 27 u32 cs; /* Memory Address Map Register -CS */ 28 u32 pad[3]; 29 }; 30 31 struct armd1ddr_registers { 32 u8 pad[0x100 - 0x000]; 33 struct armd1ddr_map_registers mmap[2]; 34 }; 35 36 /* 37 * armd1_sdram_base - reads SDRAM Base Address Register 38 */ armd1_sdram_base(int chip_sel)39u32 armd1_sdram_base(int chip_sel) 40 { 41 struct armd1ddr_registers *ddr_regs = 42 (struct armd1ddr_registers *)ARMD1_DRAM_BASE; 43 u32 result = 0; 44 u32 CS_valid = 0x01 & readl(&ddr_regs->mmap[chip_sel].cs); 45 46 if (!CS_valid) 47 return 0; 48 49 result = readl(&ddr_regs->mmap[chip_sel].cs) & 0xFF800000; 50 return result; 51 } 52 53 /* 54 * armd1_sdram_size - reads SDRAM size 55 */ armd1_sdram_size(int chip_sel)56u32 armd1_sdram_size(int chip_sel) 57 { 58 struct armd1ddr_registers *ddr_regs = 59 (struct armd1ddr_registers *)ARMD1_DRAM_BASE; 60 u32 result = 0; 61 u32 CS_valid = 0x01 & readl(&ddr_regs->mmap[chip_sel].cs); 62 63 if (!CS_valid) 64 return 0; 65 66 result = readl(&ddr_regs->mmap[chip_sel].cs); 67 result = (result >> 16) & 0xF; 68 if (result < 0x7) { 69 printf("Unknown DRAM Size\n"); 70 return -1; 71 } else { 72 return ((0x8 << (result - 0x7)) * 1024 * 1024); 73 } 74 } 75 dram_init(void)76int 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 */ dram_init_banksize(void)112int dram_init_banksize(void) 113 { 114 dram_init(); 115 116 return 0; 117 } 118