1 /* 2 * Copyright (C) 2017 Rockchip Electronics Co., Ltd. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <bidram.h> 9 #include <dm.h> 10 #include <ram.h> 11 #include <asm/io.h> 12 #include <asm/arch/param.h> 13 #include <asm/arch/rk_atags.h> 14 #include <asm/arch/sdram.h> 15 #include <dm/uclass-internal.h> 16 17 DECLARE_GLOBAL_DATA_PTR; 18 #define PARAM_DRAM_INFO_OFFSET 0x2000000 19 #define TRUST_PARAMETER_OFFSET (34 * 1024 * 1024) 20 21 size_t rockchip_sdram_size(phys_addr_t reg) 22 { 23 u32 rank, cs0_col, bk, cs0_row, cs1_row, bw, row_3_4; 24 size_t chipsize_mb = 0; 25 size_t size_mb = 0; 26 u32 ch; 27 u32 cs1_col = 0; 28 u32 bg = 0; 29 u32 dbw, dram_type; 30 u32 sys_reg = readl(reg); 31 u32 sys_reg1 = readl(reg + 4); 32 u32 ch_num = 1 + ((sys_reg >> SYS_REG_NUM_CH_SHIFT) 33 & SYS_REG_NUM_CH_MASK); 34 35 dram_type = (sys_reg >> SYS_REG_DDRTYPE_SHIFT) & SYS_REG_DDRTYPE_MASK; 36 debug("%s %x %x\n", __func__, (u32)reg, sys_reg); 37 for (ch = 0; ch < ch_num; ch++) { 38 rank = 1 + (sys_reg >> SYS_REG_RANK_SHIFT(ch) & 39 SYS_REG_RANK_MASK); 40 cs0_col = 9 + (sys_reg >> SYS_REG_COL_SHIFT(ch) & SYS_REG_COL_MASK); 41 cs1_col = cs0_col; 42 bk = 3 - ((sys_reg >> SYS_REG_BK_SHIFT(ch)) & SYS_REG_BK_MASK); 43 if ((sys_reg1 >> SYS_REG1_VERSION_SHIFT & 44 SYS_REG1_VERSION_MASK) == 0x2) { 45 cs1_col = 9 + (sys_reg1 >> SYS_REG1_CS1_COL_SHIFT(ch) & 46 SYS_REG1_CS1_COL_MASK); 47 if (((sys_reg1 >> SYS_REG1_EXTEND_CS0_ROW_SHIFT(ch) & 48 SYS_REG1_EXTEND_CS0_ROW_MASK) << 2) + (sys_reg >> 49 SYS_REG_CS0_ROW_SHIFT(ch) & 50 SYS_REG_CS0_ROW_MASK) == 7) 51 cs0_row = 12; 52 else 53 cs0_row = 13 + (sys_reg >> 54 SYS_REG_CS0_ROW_SHIFT(ch) & 55 SYS_REG_CS0_ROW_MASK) + 56 ((sys_reg1 >> 57 SYS_REG1_EXTEND_CS0_ROW_SHIFT(ch) & 58 SYS_REG1_EXTEND_CS0_ROW_MASK) << 2); 59 if (((sys_reg1 >> SYS_REG1_EXTEND_CS1_ROW_SHIFT(ch) & 60 SYS_REG1_EXTEND_CS1_ROW_MASK) << 2) + (sys_reg >> 61 SYS_REG_CS1_ROW_SHIFT(ch) & 62 SYS_REG_CS1_ROW_MASK) == 7) 63 cs1_row = 12; 64 else 65 cs1_row = 13 + (sys_reg >> 66 SYS_REG_CS1_ROW_SHIFT(ch) & 67 SYS_REG_CS1_ROW_MASK) + 68 ((sys_reg1 >> 69 SYS_REG1_EXTEND_CS1_ROW_SHIFT(ch) & 70 SYS_REG1_EXTEND_CS1_ROW_MASK) << 2); 71 } 72 else { 73 cs0_row = 13 + (sys_reg >> SYS_REG_CS0_ROW_SHIFT(ch) & 74 SYS_REG_CS0_ROW_MASK); 75 cs1_row = 13 + (sys_reg >> SYS_REG_CS1_ROW_SHIFT(ch) & 76 SYS_REG_CS1_ROW_MASK); 77 } 78 bw = (2 >> ((sys_reg >> SYS_REG_BW_SHIFT(ch)) & 79 SYS_REG_BW_MASK)); 80 row_3_4 = sys_reg >> SYS_REG_ROW_3_4_SHIFT(ch) & 81 SYS_REG_ROW_3_4_MASK; 82 if (dram_type == DDR4) { 83 dbw = (sys_reg >> SYS_REG_DBW_SHIFT(ch)) & 84 SYS_REG_DBW_MASK; 85 bg = (dbw == 2) ? 2 : 1; 86 } 87 chipsize_mb = (1 << (cs0_row + cs0_col + bk + bg + bw - 20)); 88 89 if (rank > 1) 90 chipsize_mb += chipsize_mb >> ((cs0_row - cs1_row) + 91 (cs0_col - cs1_col)); 92 if (row_3_4) 93 chipsize_mb = chipsize_mb * 3 / 4; 94 size_mb += chipsize_mb; 95 if (rank > 1) 96 debug("rank %d cs0_col %d cs1_col %d bk %d cs0_row %d\ 97 cs1_row %d bw %d row_3_4 %d\n", 98 rank, cs0_col, cs1_col, bk, cs0_row, 99 cs1_row, bw, row_3_4); 100 else 101 debug("rank %d cs0_col %d bk %d cs0_row %d\ 102 bw %d row_3_4 %d\n", 103 rank, cs0_col, bk, cs0_row, 104 bw, row_3_4); 105 } 106 107 /* Handle 4GB size, or else size will be 0 after <<20 in 32bit system */ 108 if (size_mb > (SDRAM_MAX_SIZE >> 20)) 109 size_mb = (SDRAM_MAX_SIZE >> 20); 110 111 return (size_t)size_mb << 20; 112 } 113 114 static unsigned int get_ddr_os_reg(void) 115 { 116 u32 os_reg = 0; 117 118 #if defined(CONFIG_ROCKCHIP_PX30) 119 os_reg = readl(0xff010208); 120 #elif defined(CONFIG_ROCKCHIP_RK3328) 121 os_reg = readl(0xff1005d0); 122 #elif defined(CONFIG_ROCKCHIP_RK3399) 123 os_reg = readl(0xff320308); 124 #elif defined(CONFIG_ROCKCHIP_RK322X) 125 os_reg = readl(0x110005d0); 126 #elif defined(CONFIG_ROCKCHIP_RK3368) 127 os_reg = readl(0xff738208); 128 #elif defined(CONFIG_ROCKCHIP_RK3288) 129 os_reg = readl(0x20004048); 130 #elif defined(CONFIG_ROCKCHIP_RK3036) 131 os_reg = readl(0x200081cc); 132 #elif defined(CONFIG_ROCKCHIP_RK3308) 133 os_reg = readl(0xff000508); 134 #elif defined(CONFIG_ROCKCHIP_RK1808) 135 os_reg = readl(0xfe020208); 136 #else 137 printf("unsupported chip type, get page size fail\n"); 138 #endif 139 140 return os_reg; 141 } 142 143 unsigned int get_page_size(void) 144 { 145 u32 os_reg; 146 u32 col, bw; 147 int page_size; 148 149 os_reg = get_ddr_os_reg(); 150 if (!os_reg) 151 return 0; 152 153 col = 9 + (os_reg >> SYS_REG_COL_SHIFT(0) & SYS_REG_COL_MASK); 154 bw = (2 >> ((os_reg >> SYS_REG_BW_SHIFT(0)) & SYS_REG_BW_MASK)); 155 page_size = 1u << (col + bw); 156 157 return page_size; 158 } 159 160 unsigned int get_ddr_bw(void) 161 { 162 u32 os_reg; 163 u32 bw = 2; 164 165 os_reg = get_ddr_os_reg(); 166 if (os_reg) 167 bw = 2 >> ((os_reg >> SYS_REG_BW_SHIFT(0)) & SYS_REG_BW_MASK); 168 return bw; 169 } 170 171 #if defined(CONFIG_SPL_FRAMEWORK) || !defined(CONFIG_SPL_OF_PLATDATA) 172 int dram_init_banksize(void) 173 { 174 #ifdef CONFIG_BIDRAM 175 bidram_gen_gd_bi_dram(); 176 #else 177 param_simple_parse_ddr_mem(1); 178 #endif 179 return 0; 180 } 181 182 int dram_init(void) 183 { 184 #ifdef CONFIG_BIDRAM 185 gd->ram_size = bidram_get_ram_size(); 186 #else 187 gd->ram_size = param_simple_parse_ddr_mem(0); 188 #endif 189 if (!gd->ram_size) 190 return -ENOMEM; 191 192 return 0; 193 } 194 #endif 195 196 uint64_t board_get_usable_ram_top(ulong total_size) 197 { 198 uint64_t top = CONFIG_SYS_SDRAM_BASE + SDRAM_MAX_SIZE; 199 200 return (gd->ram_top > top) ? top : gd->ram_top; 201 } 202 203 int rockchip_setup_ddr_param(struct ddr_param *info) 204 { 205 u32 i; 206 struct ddr_param *dinfo = (struct ddr_param *)(CONFIG_SYS_SDRAM_BASE + 207 PARAM_DRAM_INFO_OFFSET); 208 209 dinfo->count = info->count; 210 for (i = 0; i < (info->count * 2); i++) 211 dinfo->para[i] = info->para[i]; 212 213 return 0; 214 } 215