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
stm32mp1_ddr_clk_enable(struct stm32mp_ddr_priv * priv,uint32_t mem_speed)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
stm32mp1_ddr_setup(void)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
stm32mp1_ddr_probe(void)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