1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2022 - 2023 PHYTEC Messtechnik GmbH
4 * Author: Wadim Egorov <w.egorov@phytec.de>
5 */
6
7 #include <asm/arch/hardware.h>
8 #include <asm/io.h>
9 #include <spl.h>
10 #include <asm/arch/k3-ddr.h>
11 #include <fdt_support.h>
12
13 #include "phycore-ddr-data.h"
14 #include "../common/k3/k3_ddrss_patch.h"
15 #include "../common/am6_som_detection.h"
16
17 #define AM64_DDRSS_SS_BASE 0x0F300000
18 #define DDRSS_V2A_CTL_REG 0x0020
19
20 DECLARE_GLOBAL_DATA_PTR;
21
phytec_get_am62_ddr_size_default(void)22 static u8 phytec_get_am62_ddr_size_default(void)
23 {
24 int ret;
25 struct phytec_eeprom_data data;
26
27 if (IS_ENABLED(CONFIG_PHYCORE_AM62X_RAM_SIZE_FIX)) {
28 if (IS_ENABLED(CONFIG_PHYCORE_AM62X_RAM_SIZE_1GB))
29 return EEPROM_RAM_SIZE_1GB;
30 else if (IS_ENABLED(CONFIG_PHYCORE_AM62X_RAM_SIZE_2GB))
31 return EEPROM_RAM_SIZE_2GB;
32 else if (IS_ENABLED(CONFIG_PHYCORE_AM62X_RAM_SIZE_4GB))
33 return EEPROM_RAM_SIZE_4GB;
34 }
35
36 ret = phytec_eeprom_data_setup(&data, 0, EEPROM_ADDR);
37 if (!ret && data.valid)
38 return phytec_get_am6_ddr_size(&data);
39
40 /* Default DDR size is 2GB */
41 return EEPROM_RAM_SIZE_2GB;
42 }
43
dram_init(void)44 int dram_init(void)
45 {
46 u8 ram_size;
47
48 if (!IS_ENABLED(CONFIG_CPU_V7R))
49 return fdtdec_setup_mem_size_base();
50
51 ram_size = phytec_get_am62_ddr_size_default();
52
53 /*
54 * HACK: ddrss driver support 2GB RAM by default
55 * V2A_CTL_REG should be updated to support other RAM size
56 */
57 if (IS_ENABLED(CONFIG_K3_AM64_DDRSS))
58 if (ram_size == EEPROM_RAM_SIZE_4GB)
59 writel(0x00000210, AM64_DDRSS_SS_BASE + DDRSS_V2A_CTL_REG);
60
61 switch (ram_size) {
62 case EEPROM_RAM_SIZE_1GB:
63 gd->ram_size = 0x40000000;
64 break;
65 case EEPROM_RAM_SIZE_2GB:
66 gd->ram_size = 0x80000000;
67 break;
68 case EEPROM_RAM_SIZE_4GB:
69 #ifdef CONFIG_PHYS_64BIT
70 gd->ram_size = 0x100000000;
71 #else
72 gd->ram_size = 0x80000000;
73 #endif
74 break;
75 default:
76 gd->ram_size = 0x80000000;
77 }
78
79 return 0;
80 }
81
board_get_usable_ram_top(phys_size_t total_size)82 phys_size_t board_get_usable_ram_top(phys_size_t total_size)
83 {
84 #ifdef CONFIG_PHYS_64BIT
85 /* Limit RAM used by U-Boot to the DDR low region */
86 if (gd->ram_top > 0x100000000)
87 return 0x100000000;
88 #endif
89 return gd->ram_top;
90 }
91
dram_init_banksize(void)92 int dram_init_banksize(void)
93 {
94 u8 ram_size;
95
96 memset(gd->bd->bi_dram, 0, sizeof(gd->bd->bi_dram[0]) * CONFIG_NR_DRAM_BANKS);
97
98 if (!IS_ENABLED(CONFIG_CPU_V7R))
99 return fdtdec_setup_memory_banksize();
100
101 ram_size = phytec_get_am62_ddr_size_default();
102 switch (ram_size) {
103 case EEPROM_RAM_SIZE_1GB:
104 gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE;
105 gd->bd->bi_dram[0].size = 0x40000000;
106 gd->ram_size = 0x40000000;
107 break;
108
109 case EEPROM_RAM_SIZE_2GB:
110 gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE;
111 gd->bd->bi_dram[0].size = 0x80000000;
112 gd->ram_size = 0x80000000;
113 break;
114
115 case EEPROM_RAM_SIZE_4GB:
116 /* Bank 0 declares the memory available in the DDR low region */
117 gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE;
118 gd->bd->bi_dram[0].size = 0x80000000;
119 gd->ram_size = 0x80000000;
120
121 #ifdef CONFIG_PHYS_64BIT
122 /* Bank 1 declares the memory available in the DDR upper region */
123 gd->bd->bi_dram[1].start = 0x880000000;
124 gd->bd->bi_dram[1].size = 0x80000000;
125 gd->ram_size = 0x100000000;
126 #endif
127 break;
128 default:
129 /* Continue with default 2GB setup */
130 gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE;
131 gd->bd->bi_dram[0].size = 0x80000000;
132 gd->ram_size = 0x80000000;
133 printf("DDR size %d is not supported\n", ram_size);
134 }
135
136 return 0;
137 }
138
139 #if defined(CONFIG_K3_DDRSS)
update_ddrss_timings(void)140 int update_ddrss_timings(void)
141 {
142 int ret;
143 u8 ram_size;
144 struct ddrss *ddr_patch = NULL;
145 void *fdt = (void *)gd->fdt_blob;
146
147 ram_size = phytec_get_am62_ddr_size_default();
148 switch (ram_size) {
149 case EEPROM_RAM_SIZE_1GB:
150 ddr_patch = &phycore_ddrss_data[PHYCORE_1GB];
151 break;
152 case EEPROM_RAM_SIZE_2GB:
153 ddr_patch = NULL;
154 break;
155 case EEPROM_RAM_SIZE_4GB:
156 ddr_patch = &phycore_ddrss_data[PHYCORE_4GB];
157 break;
158 default:
159 break;
160 }
161
162 /* Nothing to patch */
163 if (!ddr_patch)
164 return 0;
165
166 debug("Applying DDRSS timings patch for ram_size %d\n", ram_size);
167
168 ret = fdt_apply_ddrss_timings_patch(fdt, ddr_patch);
169 if (ret < 0) {
170 printf("Failed to apply ddrs timings patch %d\n", ret);
171 return ret;
172 }
173
174 return 0;
175 }
176
do_board_detect(void)177 int do_board_detect(void)
178 {
179 int ret;
180 void *fdt = (void *)gd->fdt_blob;
181 int bank;
182 u64 start[CONFIG_NR_DRAM_BANKS];
183 u64 size[CONFIG_NR_DRAM_BANKS];
184
185 dram_init();
186 dram_init_banksize();
187
188 for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
189 start[bank] = gd->bd->bi_dram[bank].start;
190 size[bank] = gd->bd->bi_dram[bank].size;
191 }
192
193 ret = fdt_fixup_memory_banks(fdt, start, size, CONFIG_NR_DRAM_BANKS);
194 if (ret)
195 return ret;
196
197 return update_ddrss_timings();
198 }
199 #endif
200
201 #if IS_ENABLED(CONFIG_XPL_BUILD)
spl_perform_fixups(struct spl_image_info * spl_image)202 void spl_perform_fixups(struct spl_image_info *spl_image)
203 {
204 if (IS_ENABLED(CONFIG_K3_DDRSS) && IS_ENABLED(CONFIG_K3_INLINE_ECC))
205 fixup_ddr_driver_for_ecc(spl_image);
206 else
207 fixup_memory_node(spl_image);
208 }
209 #endif
210
211 #define CTRLMMR_USB0_PHY_CTRL 0x43004008
212 #define CTRLMMR_USB1_PHY_CTRL 0x43004018
213 #define CORE_VOLTAGE 0x80000000
214
215 #ifdef CONFIG_SPL_BOARD_INIT
spl_board_init(void)216 void spl_board_init(void)
217 {
218 u32 val;
219
220 /* Set USB0 PHY core voltage to 0.85V */
221 val = readl(CTRLMMR_USB0_PHY_CTRL);
222 val &= ~(CORE_VOLTAGE);
223 writel(val, CTRLMMR_USB0_PHY_CTRL);
224
225 /* Set USB1 PHY core voltage to 0.85V */
226 val = readl(CTRLMMR_USB1_PHY_CTRL);
227 val &= ~(CORE_VOLTAGE);
228 writel(val, CTRLMMR_USB1_PHY_CTRL);
229
230 /* We have 32k crystal, so lets enable it */
231 val = readl(MCU_CTRL_LFXOSC_CTRL);
232 val &= ~(MCU_CTRL_LFXOSC_32K_DISABLE_VAL);
233 writel(val, MCU_CTRL_LFXOSC_CTRL);
234 /* Add any TRIM needed for the crystal here.. */
235 /* Make sure to mux up to take the SoC 32k from the crystal */
236 writel(MCU_CTRL_DEVICE_CLKOUT_LFOSC_SELECT_VAL,
237 MCU_CTRL_DEVICE_CLKOUT_32K_CTRL);
238 }
239 #endif
240