16c08d5dcSPrafulla Wadaskar /* 26c08d5dcSPrafulla Wadaskar * (C) Copyright 2010 36c08d5dcSPrafulla Wadaskar * Marvell Semiconductor <www.marvell.com> 46c08d5dcSPrafulla Wadaskar * Written-by: Prafulla Wadaskar <prafulla@marvell.com>, 56c08d5dcSPrafulla Wadaskar * Contributor: Mahavir Jain <mjain@marvell.com> 66c08d5dcSPrafulla Wadaskar * 71a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 86c08d5dcSPrafulla Wadaskar */ 96c08d5dcSPrafulla Wadaskar 106c08d5dcSPrafulla Wadaskar #include <common.h> 11ab1b9552SLei Wen #include <asm/io.h> 126c08d5dcSPrafulla Wadaskar #include <asm/arch/armada100.h> 136c08d5dcSPrafulla Wadaskar 146c08d5dcSPrafulla Wadaskar DECLARE_GLOBAL_DATA_PTR; 156c08d5dcSPrafulla Wadaskar 166c08d5dcSPrafulla Wadaskar /* 176c08d5dcSPrafulla Wadaskar * ARMADA100 DRAM controller supports upto 8 banks 186c08d5dcSPrafulla Wadaskar * for chip select 0 and 1 196c08d5dcSPrafulla Wadaskar */ 206c08d5dcSPrafulla Wadaskar 216c08d5dcSPrafulla Wadaskar /* 226c08d5dcSPrafulla Wadaskar * DDR Memory Control Registers 236c08d5dcSPrafulla Wadaskar * Refer Datasheet Appendix A.17 246c08d5dcSPrafulla Wadaskar */ 256c08d5dcSPrafulla Wadaskar struct armd1ddr_map_registers { 266c08d5dcSPrafulla Wadaskar u32 cs; /* Memory Address Map Register -CS */ 276c08d5dcSPrafulla Wadaskar u32 pad[3]; 286c08d5dcSPrafulla Wadaskar }; 296c08d5dcSPrafulla Wadaskar 306c08d5dcSPrafulla Wadaskar struct armd1ddr_registers { 316c08d5dcSPrafulla Wadaskar u8 pad[0x100 - 0x000]; 326c08d5dcSPrafulla Wadaskar struct armd1ddr_map_registers mmap[2]; 336c08d5dcSPrafulla Wadaskar }; 346c08d5dcSPrafulla Wadaskar 356c08d5dcSPrafulla Wadaskar /* 366c08d5dcSPrafulla Wadaskar * armd1_sdram_base - reads SDRAM Base Address Register 376c08d5dcSPrafulla Wadaskar */ 386c08d5dcSPrafulla Wadaskar u32 armd1_sdram_base(int chip_sel) 396c08d5dcSPrafulla Wadaskar { 406c08d5dcSPrafulla Wadaskar struct armd1ddr_registers *ddr_regs = 416c08d5dcSPrafulla Wadaskar (struct armd1ddr_registers *)ARMD1_DRAM_BASE; 426c08d5dcSPrafulla Wadaskar u32 result = 0; 436c08d5dcSPrafulla Wadaskar u32 CS_valid = 0x01 & readl(&ddr_regs->mmap[chip_sel].cs); 446c08d5dcSPrafulla Wadaskar 456c08d5dcSPrafulla Wadaskar if (!CS_valid) 466c08d5dcSPrafulla Wadaskar return 0; 476c08d5dcSPrafulla Wadaskar 486c08d5dcSPrafulla Wadaskar result = readl(&ddr_regs->mmap[chip_sel].cs) & 0xFF800000; 496c08d5dcSPrafulla Wadaskar return result; 506c08d5dcSPrafulla Wadaskar } 516c08d5dcSPrafulla Wadaskar 526c08d5dcSPrafulla Wadaskar /* 536c08d5dcSPrafulla Wadaskar * armd1_sdram_size - reads SDRAM size 546c08d5dcSPrafulla Wadaskar */ 556c08d5dcSPrafulla Wadaskar u32 armd1_sdram_size(int chip_sel) 566c08d5dcSPrafulla Wadaskar { 576c08d5dcSPrafulla Wadaskar struct armd1ddr_registers *ddr_regs = 586c08d5dcSPrafulla Wadaskar (struct armd1ddr_registers *)ARMD1_DRAM_BASE; 596c08d5dcSPrafulla Wadaskar u32 result = 0; 606c08d5dcSPrafulla Wadaskar u32 CS_valid = 0x01 & readl(&ddr_regs->mmap[chip_sel].cs); 616c08d5dcSPrafulla Wadaskar 626c08d5dcSPrafulla Wadaskar if (!CS_valid) 636c08d5dcSPrafulla Wadaskar return 0; 646c08d5dcSPrafulla Wadaskar 656c08d5dcSPrafulla Wadaskar result = readl(&ddr_regs->mmap[chip_sel].cs); 666c08d5dcSPrafulla Wadaskar result = (result >> 16) & 0xF; 676c08d5dcSPrafulla Wadaskar if (result < 0x7) { 686c08d5dcSPrafulla Wadaskar printf("Unknown DRAM Size\n"); 696c08d5dcSPrafulla Wadaskar return -1; 706c08d5dcSPrafulla Wadaskar } else { 716c08d5dcSPrafulla Wadaskar return ((0x8 << (result - 0x7)) * 1024 * 1024); 726c08d5dcSPrafulla Wadaskar } 736c08d5dcSPrafulla Wadaskar } 746c08d5dcSPrafulla Wadaskar 756c08d5dcSPrafulla Wadaskar int dram_init(void) 766c08d5dcSPrafulla Wadaskar { 776c08d5dcSPrafulla Wadaskar int i; 786c08d5dcSPrafulla Wadaskar 796c08d5dcSPrafulla Wadaskar gd->ram_size = 0; 806c08d5dcSPrafulla Wadaskar for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { 816c08d5dcSPrafulla Wadaskar gd->bd->bi_dram[i].start = armd1_sdram_base(i); 826c08d5dcSPrafulla Wadaskar gd->bd->bi_dram[i].size = armd1_sdram_size(i); 836c08d5dcSPrafulla Wadaskar /* 846c08d5dcSPrafulla Wadaskar * It is assumed that all memory banks are consecutive 856c08d5dcSPrafulla Wadaskar * and without gaps. 866c08d5dcSPrafulla Wadaskar * If the gap is found, ram_size will be reported for 876c08d5dcSPrafulla Wadaskar * consecutive memory only 886c08d5dcSPrafulla Wadaskar */ 896c08d5dcSPrafulla Wadaskar if (gd->bd->bi_dram[i].start != gd->ram_size) 906c08d5dcSPrafulla Wadaskar break; 916c08d5dcSPrafulla Wadaskar 926c08d5dcSPrafulla Wadaskar gd->ram_size += gd->bd->bi_dram[i].size; 936c08d5dcSPrafulla Wadaskar 946c08d5dcSPrafulla Wadaskar } 956c08d5dcSPrafulla Wadaskar 966c08d5dcSPrafulla Wadaskar for (; i < CONFIG_NR_DRAM_BANKS; i++) { 976c08d5dcSPrafulla Wadaskar /* If above loop terminated prematurely, we need to set 986c08d5dcSPrafulla Wadaskar * remaining banks' start address & size as 0. Otherwise other 996c08d5dcSPrafulla Wadaskar * u-boot functions and Linux kernel gets wrong values which 1006c08d5dcSPrafulla Wadaskar * could result in crash */ 1016c08d5dcSPrafulla Wadaskar gd->bd->bi_dram[i].start = 0; 1026c08d5dcSPrafulla Wadaskar gd->bd->bi_dram[i].size = 0; 1036c08d5dcSPrafulla Wadaskar } 1046c08d5dcSPrafulla Wadaskar return 0; 1056c08d5dcSPrafulla Wadaskar } 1066c08d5dcSPrafulla Wadaskar 1076c08d5dcSPrafulla Wadaskar /* 1086c08d5dcSPrafulla Wadaskar * If this function is not defined here, 1096c08d5dcSPrafulla Wadaskar * board.c alters dram bank zero configuration defined above. 1106c08d5dcSPrafulla Wadaskar */ 111*76b00acaSSimon Glass int dram_init_banksize(void) 1126c08d5dcSPrafulla Wadaskar { 1136c08d5dcSPrafulla Wadaskar dram_init(); 114*76b00acaSSimon Glass 115*76b00acaSSimon Glass return 0; 1166c08d5dcSPrafulla Wadaskar } 117