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