1 /* 2 * Copyright (C) 2018-2020, STMicroelectronics - All Rights Reserved 3 * 4 * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause 5 */ 6 7 #include <errno.h> 8 9 #include <libfdt.h> 10 11 #include <platform_def.h> 12 13 #include <arch_helpers.h> 14 #include <common/debug.h> 15 #include <common/fdt_wrappers.h> 16 #include <drivers/st/stm32mp1_ddr.h> 17 #include <drivers/st/stm32mp1_ddr_helpers.h> 18 #include <drivers/st/stm32mp1_ram.h> 19 #include <lib/mmio.h> 20 21 #define DDR_PATTERN 0xAAAAAAAAU 22 #define DDR_ANTIPATTERN 0x55555555U 23 24 static struct ddr_info ddr_priv_data; 25 26 int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed) 27 { 28 unsigned long ddrphy_clk, ddr_clk, mem_speed_hz; 29 30 ddr_enable_clock(); 31 32 ddrphy_clk = stm32mp_clk_get_rate(DDRPHYC); 33 34 VERBOSE("DDR: mem_speed (%d kHz), RCC %ld kHz\n", 35 mem_speed, ddrphy_clk / 1000U); 36 37 mem_speed_hz = mem_speed * 1000U; 38 39 /* Max 10% frequency delta */ 40 if (ddrphy_clk > mem_speed_hz) { 41 ddr_clk = ddrphy_clk - mem_speed_hz; 42 } else { 43 ddr_clk = mem_speed_hz - ddrphy_clk; 44 } 45 if (ddr_clk > (mem_speed_hz / 10)) { 46 ERROR("DDR expected freq %d kHz, current is %ld kHz\n", 47 mem_speed, ddrphy_clk / 1000U); 48 return -1; 49 } 50 return 0; 51 } 52 53 /******************************************************************************* 54 * This function tests the DDR data bus wiring. 55 * This is inspired from the Data Bus Test algorithm written by Michael Barr 56 * in "Programming Embedded Systems in C and C++" book. 57 * resources.oreilly.com/examples/9781565923546/blob/master/Chapter6/ 58 * File: memtest.c - This source code belongs to Public Domain. 59 * Returns 0 if success, and address value else. 60 ******************************************************************************/ 61 static uint32_t ddr_test_data_bus(void) 62 { 63 uint32_t pattern; 64 65 for (pattern = 1U; pattern != 0U; pattern <<= 1) { 66 mmio_write_32(STM32MP_DDR_BASE, pattern); 67 68 if (mmio_read_32(STM32MP_DDR_BASE) != pattern) { 69 return (uint32_t)STM32MP_DDR_BASE; 70 } 71 } 72 73 return 0; 74 } 75 76 /******************************************************************************* 77 * This function tests the DDR address bus wiring. 78 * This is inspired from the Data Bus Test algorithm written by Michael Barr 79 * in "Programming Embedded Systems in C and C++" book. 80 * resources.oreilly.com/examples/9781565923546/blob/master/Chapter6/ 81 * File: memtest.c - This source code belongs to Public Domain. 82 * Returns 0 if success, and address value else. 83 ******************************************************************************/ 84 static uint32_t ddr_test_addr_bus(void) 85 { 86 uint64_t addressmask = (ddr_priv_data.info.size - 1U); 87 uint64_t offset; 88 uint64_t testoffset = 0; 89 90 /* Write the default pattern at each of the power-of-two offsets. */ 91 for (offset = sizeof(uint32_t); (offset & addressmask) != 0U; 92 offset <<= 1) { 93 mmio_write_32(STM32MP_DDR_BASE + (uint32_t)offset, 94 DDR_PATTERN); 95 } 96 97 /* Check for address bits stuck high. */ 98 mmio_write_32(STM32MP_DDR_BASE + (uint32_t)testoffset, 99 DDR_ANTIPATTERN); 100 101 for (offset = sizeof(uint32_t); (offset & addressmask) != 0U; 102 offset <<= 1) { 103 if (mmio_read_32(STM32MP_DDR_BASE + (uint32_t)offset) != 104 DDR_PATTERN) { 105 return (uint32_t)(STM32MP_DDR_BASE + offset); 106 } 107 } 108 109 mmio_write_32(STM32MP_DDR_BASE + (uint32_t)testoffset, DDR_PATTERN); 110 111 /* Check for address bits stuck low or shorted. */ 112 for (testoffset = sizeof(uint32_t); (testoffset & addressmask) != 0U; 113 testoffset <<= 1) { 114 mmio_write_32(STM32MP_DDR_BASE + (uint32_t)testoffset, 115 DDR_ANTIPATTERN); 116 117 if (mmio_read_32(STM32MP_DDR_BASE) != DDR_PATTERN) { 118 return STM32MP_DDR_BASE; 119 } 120 121 for (offset = sizeof(uint32_t); (offset & addressmask) != 0U; 122 offset <<= 1) { 123 if ((mmio_read_32(STM32MP_DDR_BASE + 124 (uint32_t)offset) != DDR_PATTERN) && 125 (offset != testoffset)) { 126 return (uint32_t)(STM32MP_DDR_BASE + offset); 127 } 128 } 129 130 mmio_write_32(STM32MP_DDR_BASE + (uint32_t)testoffset, 131 DDR_PATTERN); 132 } 133 134 return 0; 135 } 136 137 /******************************************************************************* 138 * This function checks the DDR size. It has to be run with Data Cache off. 139 * This test is run before data have been put in DDR, and is only done for 140 * cold boot. The DDR data can then be overwritten, and it is not useful to 141 * restore its content. 142 * Returns DDR computed size. 143 ******************************************************************************/ 144 static uint32_t ddr_check_size(void) 145 { 146 uint32_t offset = sizeof(uint32_t); 147 148 mmio_write_32(STM32MP_DDR_BASE, DDR_PATTERN); 149 150 while (offset < STM32MP_DDR_MAX_SIZE) { 151 mmio_write_32(STM32MP_DDR_BASE + offset, DDR_ANTIPATTERN); 152 dsb(); 153 154 if (mmio_read_32(STM32MP_DDR_BASE) != DDR_PATTERN) { 155 break; 156 } 157 158 offset <<= 1; 159 } 160 161 INFO("Memory size = 0x%x (%d MB)\n", offset, offset / (1024U * 1024U)); 162 163 return offset; 164 } 165 166 static int stm32mp1_ddr_setup(void) 167 { 168 struct ddr_info *priv = &ddr_priv_data; 169 int ret; 170 struct stm32mp1_ddr_config config; 171 int node, len; 172 uint32_t uret, idx; 173 void *fdt; 174 175 #define PARAM(x, y) \ 176 { \ 177 .name = x, \ 178 .offset = offsetof(struct stm32mp1_ddr_config, y), \ 179 .size = sizeof(config.y) / sizeof(uint32_t) \ 180 } 181 182 #define CTL_PARAM(x) PARAM("st,ctl-"#x, c_##x) 183 #define PHY_PARAM(x) PARAM("st,phy-"#x, p_##x) 184 185 const struct { 186 const char *name; /* Name in DT */ 187 const uint32_t offset; /* Offset in config struct */ 188 const uint32_t size; /* Size of parameters */ 189 } param[] = { 190 CTL_PARAM(reg), 191 CTL_PARAM(timing), 192 CTL_PARAM(map), 193 CTL_PARAM(perf), 194 PHY_PARAM(reg), 195 PHY_PARAM(timing), 196 PHY_PARAM(cal) 197 }; 198 199 if (fdt_get_address(&fdt) == 0) { 200 return -ENOENT; 201 } 202 203 node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT); 204 if (node < 0) { 205 ERROR("%s: Cannot read DDR node in DT\n", __func__); 206 return -EINVAL; 207 } 208 209 config.info.speed = fdt_read_uint32_default(node, "st,mem-speed", 0); 210 if (!config.info.speed) { 211 VERBOSE("%s: no st,mem-speed\n", __func__); 212 return -EINVAL; 213 } 214 config.info.size = fdt_read_uint32_default(node, "st,mem-size", 0); 215 if (!config.info.size) { 216 VERBOSE("%s: no st,mem-size\n", __func__); 217 return -EINVAL; 218 } 219 config.info.name = fdt_getprop(fdt, node, "st,mem-name", &len); 220 if (config.info.name == NULL) { 221 VERBOSE("%s: no st,mem-name\n", __func__); 222 return -EINVAL; 223 } 224 INFO("RAM: %s\n", config.info.name); 225 226 for (idx = 0; idx < ARRAY_SIZE(param); idx++) { 227 ret = fdt_read_uint32_array(fdt, node, param[idx].name, 228 param[idx].size, 229 (void *)((uintptr_t)&config + 230 param[idx].offset)); 231 232 VERBOSE("%s: %s[0x%x] = %d\n", __func__, 233 param[idx].name, param[idx].size, ret); 234 if (ret != 0) { 235 ERROR("%s: Cannot read %s\n", 236 __func__, param[idx].name); 237 return -EINVAL; 238 } 239 } 240 241 /* Disable axidcg clock gating during init */ 242 mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); 243 244 stm32mp1_ddr_init(priv, &config); 245 246 /* Enable axidcg clock gating */ 247 mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); 248 249 priv->info.size = config.info.size; 250 251 VERBOSE("%s : ram size(%x, %x)\n", __func__, 252 (uint32_t)priv->info.base, (uint32_t)priv->info.size); 253 254 if (stm32mp_map_ddr_non_cacheable() != 0) { 255 panic(); 256 } 257 258 uret = ddr_test_data_bus(); 259 if (uret != 0U) { 260 ERROR("DDR data bus test: can't access memory @ 0x%x\n", 261 uret); 262 panic(); 263 } 264 265 uret = ddr_test_addr_bus(); 266 if (uret != 0U) { 267 ERROR("DDR addr bus test: can't access memory @ 0x%x\n", 268 uret); 269 panic(); 270 } 271 272 uret = ddr_check_size(); 273 if (uret < config.info.size) { 274 ERROR("DDR size: 0x%x does not match DT config: 0x%x\n", 275 uret, config.info.size); 276 panic(); 277 } 278 279 if (stm32mp_unmap_ddr() != 0) { 280 panic(); 281 } 282 283 return 0; 284 } 285 286 int stm32mp1_ddr_probe(void) 287 { 288 struct ddr_info *priv = &ddr_priv_data; 289 290 VERBOSE("STM32MP DDR probe\n"); 291 292 priv->ctl = (struct stm32mp1_ddrctl *)stm32mp_ddrctrl_base(); 293 priv->phy = (struct stm32mp1_ddrphy *)stm32mp_ddrphyc_base(); 294 priv->pwr = stm32mp_pwr_base(); 295 priv->rcc = stm32mp_rcc_base(); 296 297 priv->info.base = STM32MP_DDR_BASE; 298 priv->info.size = 0; 299 300 return stm32mp1_ddr_setup(); 301 } 302