1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (C) 2018-2023, STMicroelectronics - All Rights Reserved 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <errno.h> 8*91f16700Schasinglulu 9*91f16700Schasinglulu #include <arch_helpers.h> 10*91f16700Schasinglulu #include <common/debug.h> 11*91f16700Schasinglulu #include <common/fdt_wrappers.h> 12*91f16700Schasinglulu #include <drivers/clk.h> 13*91f16700Schasinglulu #include <drivers/st/stm32mp1_ddr.h> 14*91f16700Schasinglulu #include <drivers/st/stm32mp1_ddr_helpers.h> 15*91f16700Schasinglulu #include <drivers/st/stm32mp1_ram.h> 16*91f16700Schasinglulu #include <drivers/st/stm32mp_ddr.h> 17*91f16700Schasinglulu #include <drivers/st/stm32mp_ddr_test.h> 18*91f16700Schasinglulu #include <drivers/st/stm32mp_ram.h> 19*91f16700Schasinglulu #include <lib/mmio.h> 20*91f16700Schasinglulu #include <libfdt.h> 21*91f16700Schasinglulu 22*91f16700Schasinglulu #include <platform_def.h> 23*91f16700Schasinglulu 24*91f16700Schasinglulu static struct stm32mp_ddr_priv ddr_priv_data; 25*91f16700Schasinglulu 26*91f16700Schasinglulu int stm32mp1_ddr_clk_enable(struct stm32mp_ddr_priv *priv, uint32_t mem_speed) 27*91f16700Schasinglulu { 28*91f16700Schasinglulu unsigned long ddrphy_clk, ddr_clk, mem_speed_hz; 29*91f16700Schasinglulu 30*91f16700Schasinglulu ddr_enable_clock(); 31*91f16700Schasinglulu 32*91f16700Schasinglulu ddrphy_clk = clk_get_rate(DDRPHYC); 33*91f16700Schasinglulu 34*91f16700Schasinglulu VERBOSE("DDR: mem_speed (%u kHz), RCC %lu kHz\n", 35*91f16700Schasinglulu mem_speed, ddrphy_clk / 1000U); 36*91f16700Schasinglulu 37*91f16700Schasinglulu mem_speed_hz = mem_speed * 1000U; 38*91f16700Schasinglulu 39*91f16700Schasinglulu /* Max 10% frequency delta */ 40*91f16700Schasinglulu if (ddrphy_clk > mem_speed_hz) { 41*91f16700Schasinglulu ddr_clk = ddrphy_clk - mem_speed_hz; 42*91f16700Schasinglulu } else { 43*91f16700Schasinglulu ddr_clk = mem_speed_hz - ddrphy_clk; 44*91f16700Schasinglulu } 45*91f16700Schasinglulu if (ddr_clk > (mem_speed_hz / 10)) { 46*91f16700Schasinglulu ERROR("DDR expected freq %u kHz, current is %lu kHz\n", 47*91f16700Schasinglulu mem_speed, ddrphy_clk / 1000U); 48*91f16700Schasinglulu return -1; 49*91f16700Schasinglulu } 50*91f16700Schasinglulu return 0; 51*91f16700Schasinglulu } 52*91f16700Schasinglulu 53*91f16700Schasinglulu static int stm32mp1_ddr_setup(void) 54*91f16700Schasinglulu { 55*91f16700Schasinglulu struct stm32mp_ddr_priv *priv = &ddr_priv_data; 56*91f16700Schasinglulu int ret; 57*91f16700Schasinglulu struct stm32mp_ddr_config config; 58*91f16700Schasinglulu int node; 59*91f16700Schasinglulu uintptr_t uret; 60*91f16700Schasinglulu size_t retsize; 61*91f16700Schasinglulu void *fdt; 62*91f16700Schasinglulu 63*91f16700Schasinglulu const struct stm32mp_ddr_param param[] = { 64*91f16700Schasinglulu CTL_PARAM(reg), 65*91f16700Schasinglulu CTL_PARAM(timing), 66*91f16700Schasinglulu CTL_PARAM(map), 67*91f16700Schasinglulu CTL_PARAM(perf), 68*91f16700Schasinglulu PHY_PARAM(reg), 69*91f16700Schasinglulu PHY_PARAM(timing), 70*91f16700Schasinglulu }; 71*91f16700Schasinglulu 72*91f16700Schasinglulu if (fdt_get_address(&fdt) == 0) { 73*91f16700Schasinglulu return -ENOENT; 74*91f16700Schasinglulu } 75*91f16700Schasinglulu 76*91f16700Schasinglulu node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT); 77*91f16700Schasinglulu if (node < 0) { 78*91f16700Schasinglulu ERROR("%s: Cannot read DDR node in DT\n", __func__); 79*91f16700Schasinglulu return -EINVAL; 80*91f16700Schasinglulu } 81*91f16700Schasinglulu 82*91f16700Schasinglulu ret = stm32mp_ddr_dt_get_info(fdt, node, &config.info); 83*91f16700Schasinglulu if (ret < 0) { 84*91f16700Schasinglulu return ret; 85*91f16700Schasinglulu } 86*91f16700Schasinglulu 87*91f16700Schasinglulu ret = stm32mp_ddr_dt_get_param(fdt, node, param, ARRAY_SIZE(param), (uintptr_t)&config); 88*91f16700Schasinglulu if (ret < 0) { 89*91f16700Schasinglulu return ret; 90*91f16700Schasinglulu } 91*91f16700Schasinglulu 92*91f16700Schasinglulu /* Disable axidcg clock gating during init */ 93*91f16700Schasinglulu mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); 94*91f16700Schasinglulu 95*91f16700Schasinglulu stm32mp1_ddr_init(priv, &config); 96*91f16700Schasinglulu 97*91f16700Schasinglulu /* Enable axidcg clock gating */ 98*91f16700Schasinglulu mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); 99*91f16700Schasinglulu 100*91f16700Schasinglulu priv->info.size = config.info.size; 101*91f16700Schasinglulu 102*91f16700Schasinglulu VERBOSE("%s : ram size(%x, %x)\n", __func__, 103*91f16700Schasinglulu (uint32_t)priv->info.base, (uint32_t)priv->info.size); 104*91f16700Schasinglulu 105*91f16700Schasinglulu if (stm32mp_map_ddr_non_cacheable() != 0) { 106*91f16700Schasinglulu panic(); 107*91f16700Schasinglulu } 108*91f16700Schasinglulu 109*91f16700Schasinglulu uret = stm32mp_ddr_test_data_bus(); 110*91f16700Schasinglulu if (uret != 0UL) { 111*91f16700Schasinglulu ERROR("DDR data bus test: can't access memory @ 0x%lx\n", 112*91f16700Schasinglulu uret); 113*91f16700Schasinglulu panic(); 114*91f16700Schasinglulu } 115*91f16700Schasinglulu 116*91f16700Schasinglulu uret = stm32mp_ddr_test_addr_bus(config.info.size); 117*91f16700Schasinglulu if (uret != 0UL) { 118*91f16700Schasinglulu ERROR("DDR addr bus test: can't access memory @ 0x%lx\n", 119*91f16700Schasinglulu uret); 120*91f16700Schasinglulu panic(); 121*91f16700Schasinglulu } 122*91f16700Schasinglulu 123*91f16700Schasinglulu retsize = stm32mp_ddr_check_size(); 124*91f16700Schasinglulu if (retsize < config.info.size) { 125*91f16700Schasinglulu ERROR("DDR size: 0x%zx does not match DT config: 0x%zx\n", 126*91f16700Schasinglulu retsize, config.info.size); 127*91f16700Schasinglulu panic(); 128*91f16700Schasinglulu } 129*91f16700Schasinglulu 130*91f16700Schasinglulu INFO("Memory size = 0x%zx (%zu MB)\n", retsize, retsize / (1024U * 1024U)); 131*91f16700Schasinglulu 132*91f16700Schasinglulu if (stm32mp_unmap_ddr() != 0) { 133*91f16700Schasinglulu panic(); 134*91f16700Schasinglulu } 135*91f16700Schasinglulu 136*91f16700Schasinglulu return 0; 137*91f16700Schasinglulu } 138*91f16700Schasinglulu 139*91f16700Schasinglulu int stm32mp1_ddr_probe(void) 140*91f16700Schasinglulu { 141*91f16700Schasinglulu struct stm32mp_ddr_priv *priv = &ddr_priv_data; 142*91f16700Schasinglulu 143*91f16700Schasinglulu VERBOSE("STM32MP DDR probe\n"); 144*91f16700Schasinglulu 145*91f16700Schasinglulu priv->ctl = (struct stm32mp_ddrctl *)stm32mp_ddrctrl_base(); 146*91f16700Schasinglulu priv->phy = (struct stm32mp_ddrphy *)stm32mp_ddrphyc_base(); 147*91f16700Schasinglulu priv->pwr = stm32mp_pwr_base(); 148*91f16700Schasinglulu priv->rcc = stm32mp_rcc_base(); 149*91f16700Schasinglulu 150*91f16700Schasinglulu priv->info.base = STM32MP_DDR_BASE; 151*91f16700Schasinglulu priv->info.size = 0; 152*91f16700Schasinglulu 153*91f16700Schasinglulu return stm32mp1_ddr_setup(); 154*91f16700Schasinglulu } 155