1 /* 2 * Copyright (C) 2018-2022, 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 uint32_t uret; 60 void *fdt; 61 62 const struct stm32mp_ddr_param param[] = { 63 CTL_PARAM(reg), 64 CTL_PARAM(timing), 65 CTL_PARAM(map), 66 CTL_PARAM(perf), 67 PHY_PARAM(reg), 68 PHY_PARAM(timing), 69 }; 70 71 if (fdt_get_address(&fdt) == 0) { 72 return -ENOENT; 73 } 74 75 node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT); 76 if (node < 0) { 77 ERROR("%s: Cannot read DDR node in DT\n", __func__); 78 return -EINVAL; 79 } 80 81 ret = stm32mp_ddr_dt_get_info(fdt, node, &config.info); 82 if (ret < 0) { 83 return ret; 84 } 85 86 ret = stm32mp_ddr_dt_get_param(fdt, node, param, ARRAY_SIZE(param), (uintptr_t)&config); 87 if (ret < 0) { 88 return ret; 89 } 90 91 /* Disable axidcg clock gating during init */ 92 mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); 93 94 stm32mp1_ddr_init(priv, &config); 95 96 /* Enable axidcg clock gating */ 97 mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); 98 99 priv->info.size = config.info.size; 100 101 VERBOSE("%s : ram size(%x, %x)\n", __func__, 102 (uint32_t)priv->info.base, (uint32_t)priv->info.size); 103 104 if (stm32mp_map_ddr_non_cacheable() != 0) { 105 panic(); 106 } 107 108 uret = stm32mp_ddr_test_data_bus(); 109 if (uret != 0U) { 110 ERROR("DDR data bus test: can't access memory @ 0x%x\n", 111 uret); 112 panic(); 113 } 114 115 uret = stm32mp_ddr_test_addr_bus(config.info.size); 116 if (uret != 0U) { 117 ERROR("DDR addr bus test: can't access memory @ 0x%x\n", 118 uret); 119 panic(); 120 } 121 122 uret = stm32mp_ddr_check_size(); 123 if (uret < config.info.size) { 124 ERROR("DDR size: 0x%x does not match DT config: 0x%x\n", 125 uret, config.info.size); 126 panic(); 127 } 128 129 if (stm32mp_unmap_ddr() != 0) { 130 panic(); 131 } 132 133 return 0; 134 } 135 136 int stm32mp1_ddr_probe(void) 137 { 138 struct stm32mp_ddr_priv *priv = &ddr_priv_data; 139 140 VERBOSE("STM32MP DDR probe\n"); 141 142 priv->ctl = (struct stm32mp_ddrctl *)stm32mp_ddrctrl_base(); 143 priv->phy = (struct stm32mp_ddrphy *)stm32mp_ddrphyc_base(); 144 priv->pwr = stm32mp_pwr_base(); 145 priv->rcc = stm32mp_rcc_base(); 146 147 priv->info.base = STM32MP_DDR_BASE; 148 priv->info.size = 0; 149 150 return stm32mp1_ddr_setup(); 151 } 152