1 /* 2 * Copyright (C) 2018-2023, 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/stm32mp1_ddr.h> 14 #include <drivers/st/stm32mp1_ddr_helpers.h> 15 #include <drivers/st/stm32mp1_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 #include <lib/mmio.h> 20 #include <libfdt.h> 21 22 #include <platform_def.h> 23 24 static struct stm32mp_ddr_priv ddr_priv_data; 25 26 int stm32mp1_ddr_clk_enable(struct stm32mp_ddr_priv *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 = clk_get_rate(DDRPHYC); 33 34 VERBOSE("DDR: mem_speed (%u kHz), RCC %lu 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 %u kHz, current is %lu kHz\n", 47 mem_speed, ddrphy_clk / 1000U); 48 return -1; 49 } 50 return 0; 51 } 52 53 static int stm32mp1_ddr_setup(void) 54 { 55 struct stm32mp_ddr_priv *priv = &ddr_priv_data; 56 int ret; 57 struct stm32mp_ddr_config config; 58 int node; 59 uintptr_t uret; 60 size_t retsize; 61 void *fdt; 62 63 const struct stm32mp_ddr_param param[] = { 64 CTL_PARAM(reg), 65 CTL_PARAM(timing), 66 CTL_PARAM(map), 67 CTL_PARAM(perf), 68 PHY_PARAM(reg), 69 PHY_PARAM(timing), 70 }; 71 72 if (fdt_get_address(&fdt) == 0) { 73 return -ENOENT; 74 } 75 76 node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT); 77 if (node < 0) { 78 ERROR("%s: Cannot read DDR node in DT\n", __func__); 79 return -EINVAL; 80 } 81 82 ret = stm32mp_ddr_dt_get_info(fdt, node, &config.info); 83 if (ret < 0) { 84 return ret; 85 } 86 87 ret = stm32mp_ddr_dt_get_param(fdt, node, param, ARRAY_SIZE(param), (uintptr_t)&config); 88 if (ret < 0) { 89 return ret; 90 } 91 92 /* Disable axidcg clock gating during init */ 93 mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); 94 95 stm32mp1_ddr_init(priv, &config); 96 97 /* Enable axidcg clock gating */ 98 mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); 99 100 priv->info.size = config.info.size; 101 102 VERBOSE("%s : ram size(%x, %x)\n", __func__, 103 (uint32_t)priv->info.base, (uint32_t)priv->info.size); 104 105 if (stm32mp_map_ddr_non_cacheable() != 0) { 106 panic(); 107 } 108 109 uret = stm32mp_ddr_test_data_bus(); 110 if (uret != 0UL) { 111 ERROR("DDR data bus test: can't access memory @ 0x%lx\n", 112 uret); 113 panic(); 114 } 115 116 uret = stm32mp_ddr_test_addr_bus(config.info.size); 117 if (uret != 0UL) { 118 ERROR("DDR addr bus test: can't access memory @ 0x%lx\n", 119 uret); 120 panic(); 121 } 122 123 retsize = stm32mp_ddr_check_size(); 124 if (retsize < config.info.size) { 125 ERROR("DDR size: 0x%zx does not match DT config: 0x%zx\n", 126 retsize, config.info.size); 127 panic(); 128 } 129 130 INFO("Memory size = 0x%zx (%zu MB)\n", retsize, retsize / (1024U * 1024U)); 131 132 if (stm32mp_unmap_ddr() != 0) { 133 panic(); 134 } 135 136 return 0; 137 } 138 139 int stm32mp1_ddr_probe(void) 140 { 141 struct stm32mp_ddr_priv *priv = &ddr_priv_data; 142 143 VERBOSE("STM32MP DDR probe\n"); 144 145 priv->ctl = (struct stm32mp_ddrctl *)stm32mp_ddrctrl_base(); 146 priv->phy = (struct stm32mp_ddrphy *)stm32mp_ddrphyc_base(); 147 priv->pwr = stm32mp_pwr_base(); 148 priv->rcc = stm32mp_rcc_base(); 149 150 priv->info.base = STM32MP_DDR_BASE; 151 priv->info.size = 0; 152 153 return stm32mp1_ddr_setup(); 154 } 155