1 /* 2 * Copyright (C) 2021-2024, 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 <arch_helpers.h> 10 #include <common/debug.h> 11 #include <common/fdt_wrappers.h> 12 #include <drivers/clk.h> 13 #include <drivers/st/stm32mp2_ddr.h> 14 #include <drivers/st/stm32mp2_ddr_helpers.h> 15 #include <drivers/st/stm32mp2_ram.h> 16 #include <drivers/st/stm32mp_ddr.h> 17 #include <drivers/st/stm32mp_ddr_test.h> 18 #include <drivers/st/stm32mp_ram.h> 19 20 #include <lib/mmio.h> 21 #include <libfdt.h> 22 23 #include <platform_def.h> 24 25 static struct stm32mp_ddr_priv ddr_priv_data; 26 static bool ddr_self_refresh; 27 28 static int ddr_dt_get_ui_param(void *fdt, int node, struct stm32mp_ddr_config *config) 29 { 30 int ret; 31 uint32_t size; 32 33 size = sizeof(struct user_input_basic) / sizeof(int); 34 ret = fdt_read_uint32_array(fdt, node, "st,phy-basic", size, (uint32_t *)&config->uib); 35 36 VERBOSE("%s: %s[0x%x] = %d\n", __func__, "st,phy-basic", size, ret); 37 if (ret != 0) { 38 ERROR("%s: can't read %s, error=%d\n", __func__, "st,phy-basic", ret); 39 return -EINVAL; 40 } 41 42 size = sizeof(struct user_input_advanced) / sizeof(int); 43 ret = fdt_read_uint32_array(fdt, node, "st,phy-advanced", size, (uint32_t *)&config->uia); 44 45 VERBOSE("%s: %s[0x%x] = %d\n", __func__, "st,phy-advanced", size, ret); 46 if (ret != 0) { 47 ERROR("%s: can't read %s, error=%d\n", __func__, "st,phy-advanced", ret); 48 return -EINVAL; 49 } 50 51 size = sizeof(struct user_input_mode_register) / sizeof(int); 52 ret = fdt_read_uint32_array(fdt, node, "st,phy-mr", size, (uint32_t *)&config->uim); 53 54 VERBOSE("%s: %s[0x%x] = %d\n", __func__, "st,phy-mr", size, ret); 55 if (ret != 0) { 56 ERROR("%s: can't read %s, error=%d\n", __func__, "st,phy-mr", ret); 57 return -EINVAL; 58 } 59 60 size = sizeof(struct user_input_swizzle) / sizeof(int); 61 ret = fdt_read_uint32_array(fdt, node, "st,phy-swizzle", size, (uint32_t *)&config->uis); 62 63 VERBOSE("%s: %s[0x%x] = %d\n", __func__, "st,phy-swizzle", size, ret); 64 if (ret != 0) { 65 ERROR("%s: can't read %s, error=%d\n", __func__, "st,phy-swizzle", ret); 66 return -EINVAL; 67 } 68 69 return 0; 70 } 71 72 static int stm32mp2_ddr_setup(void) 73 { 74 struct stm32mp_ddr_priv *priv = &ddr_priv_data; 75 int ret; 76 struct stm32mp_ddr_config config; 77 int node; 78 uintptr_t uret; 79 void *fdt; 80 81 const struct stm32mp_ddr_param param[] = { 82 CTL_PARAM(reg), 83 CTL_PARAM(timing), 84 CTL_PARAM(map), 85 CTL_PARAM(perf) 86 }; 87 88 if (fdt_get_address(&fdt) == 0) { 89 return -ENOENT; 90 } 91 92 node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT); 93 if (node < 0) { 94 ERROR("%s: can't read DDR node in DT\n", __func__); 95 return -EINVAL; 96 } 97 98 ret = stm32mp_ddr_dt_get_info(fdt, node, &config.info); 99 if (ret < 0) { 100 return ret; 101 } 102 103 ret = stm32mp_ddr_dt_get_param(fdt, node, param, ARRAY_SIZE(param), (uintptr_t)&config); 104 if (ret < 0) { 105 return ret; 106 } 107 108 ret = ddr_dt_get_ui_param(fdt, node, &config); 109 if (ret < 0) { 110 return ret; 111 } 112 113 config.self_refresh = false; 114 115 if (stm32mp_is_wakeup_from_standby()) { 116 config.self_refresh = true; 117 } 118 119 /* Map dynamically RETRAM area to save or restore PHY retention registers */ 120 if (stm32mp_map_retram() != 0) { 121 panic(); 122 } 123 124 stm32mp2_ddr_init(priv, &config); 125 126 /* Unmap RETRAM, no more used until next DDR initialization call */ 127 if (stm32mp_unmap_retram() != 0) { 128 panic(); 129 } 130 131 priv->info.size = config.info.size; 132 133 VERBOSE("%s : ram size(%lx, %lx)\n", __func__, priv->info.base, priv->info.size); 134 135 if (stm32mp_map_ddr_non_cacheable() != 0) { 136 panic(); 137 } 138 139 if (config.self_refresh) { 140 uret = stm32mp_ddr_test_rw_access(); 141 if (uret != 0UL) { 142 ERROR("DDR rw test: can't access memory @ 0x%lx\n", uret); 143 panic(); 144 } 145 146 /* TODO Restore area overwritten by training */ 147 //stm32_restore_ddr_training_area(); 148 } else { 149 size_t retsize; 150 151 uret = stm32mp_ddr_test_data_bus(); 152 if (uret != 0UL) { 153 ERROR("DDR data bus test: can't access memory @ 0x%lx\n", uret); 154 panic(); 155 } 156 157 uret = stm32mp_ddr_test_addr_bus(config.info.size); 158 if (uret != 0UL) { 159 ERROR("DDR addr bus test: can't access memory @ 0x%lx\n", uret); 160 panic(); 161 } 162 163 retsize = stm32mp_ddr_check_size(); 164 if (retsize < config.info.size) { 165 ERROR("DDR size: 0x%zx does not match DT config: 0x%zx\n", 166 retsize, config.info.size); 167 panic(); 168 } 169 170 INFO("Memory size = 0x%zx (%zu MB)\n", retsize, retsize / (1024U * 1024U)); 171 } 172 173 /* 174 * Initialization sequence has configured DDR registers with settings. 175 * The Self Refresh (SR) mode corresponding to these settings has now 176 * to be set. 177 */ 178 ddr_set_sr_mode(ddr_read_sr_mode()); 179 180 if (stm32mp_unmap_ddr() != 0) { 181 panic(); 182 } 183 184 /* Save DDR self_refresh state */ 185 ddr_self_refresh = config.self_refresh; 186 187 return 0; 188 } 189 190 bool stm32mp2_ddr_is_restored(void) 191 { 192 return ddr_self_refresh; 193 } 194 195 int stm32mp2_ddr_probe(void) 196 { 197 struct stm32mp_ddr_priv *priv = &ddr_priv_data; 198 199 VERBOSE("STM32MP DDR probe\n"); 200 201 priv->ctl = (struct stm32mp_ddrctl *)stm32mp_ddrctrl_base(); 202 priv->phy = (struct stm32mp_ddrphy *)stm32mp_ddrphyc_base(); 203 priv->pwr = stm32mp_pwr_base(); 204 priv->rcc = stm32mp_rcc_base(); 205 206 priv->info.base = STM32MP_DDR_BASE; 207 priv->info.size = 0; 208 209 return stm32mp2_ddr_setup(); 210 } 211