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