11573Srgrimes// SPDX-License-Identifier: GPL-2.0+
21573Srgrimes/*
31573Srgrimes * Copyright (C) 2022 - 2023 PHYTEC Messtechnik GmbH
41573Srgrimes * Author: Wadim Egorov <w.egorov@phytec.de>
51573Srgrimes */
61573Srgrimes
71573Srgrimes#include <asm/arch/hardware.h>
81573Srgrimes#include <asm/io.h>
91573Srgrimes#include <spl.h>
101573Srgrimes#include <fdt_support.h>
111573Srgrimes
121573Srgrimes#include "phycore-ddr-data.h"
131573Srgrimes#include "../common/k3/k3_ddrss_patch.h"
141573Srgrimes#include "../common/am6_som_detection.h"
151573Srgrimes
161573Srgrimes#define AM64_DDRSS_SS_BASE	0x0F300000
171573Srgrimes#define DDRSS_V2A_CTL_REG	0x0020
181573Srgrimes
191573SrgrimesDECLARE_GLOBAL_DATA_PTR;
201573Srgrimes
211573Srgrimesint board_init(void)
221573Srgrimes{
231573Srgrimes	return 0;
241573Srgrimes}
251573Srgrimes
261573Srgrimesstatic u8 phytec_get_am62_ddr_size_default(void)
271573Srgrimes{
281573Srgrimes	int ret;
291573Srgrimes	struct phytec_eeprom_data data;
301573Srgrimes
311573Srgrimes	if (IS_ENABLED(CONFIG_PHYCORE_AM62X_RAM_SIZE_FIX)) {
321573Srgrimes		if (IS_ENABLED(CONFIG_PHYCORE_AM62X_RAM_SIZE_1GB))
331573Srgrimes			return EEPROM_RAM_SIZE_1GB;
341573Srgrimes		else if (IS_ENABLED(CONFIG_PHYCORE_AM62X_RAM_SIZE_2GB))
351573Srgrimes			return EEPROM_RAM_SIZE_2GB;
361573Srgrimes		else if (IS_ENABLED(CONFIG_PHYCORE_AM62X_RAM_SIZE_4GB))
371573Srgrimes			return EEPROM_RAM_SIZE_4GB;
381573Srgrimes	}
391573Srgrimes
4086170Sobrien	ret = phytec_eeprom_data_setup(&data, 0, EEPROM_ADDR);
4186170Sobrien	if (!ret && data.valid)
421573Srgrimes		return phytec_get_am6_ddr_size(&data);
431573Srgrimes
441573Srgrimes	/* Default DDR size is 2GB */
451573Srgrimes	return EEPROM_RAM_SIZE_2GB;
461573Srgrimes}
471573Srgrimes
481573Srgrimesint dram_init(void)
491573Srgrimes{
501573Srgrimes	u8 ram_size;
511573Srgrimes
521573Srgrimes	if (!IS_ENABLED(CONFIG_CPU_V7R))
531573Srgrimes		return fdtdec_setup_mem_size_base();
541573Srgrimes
551573Srgrimes	ram_size = phytec_get_am62_ddr_size_default();
561573Srgrimes
571573Srgrimes	/*
581573Srgrimes	 * HACK: ddrss driver support 2GB RAM by default
591573Srgrimes	 * V2A_CTL_REG should be updated to support other RAM size
601573Srgrimes	 */
611573Srgrimes	if (IS_ENABLED(CONFIG_K3_AM64_DDRSS))
621573Srgrimes		if (ram_size == EEPROM_RAM_SIZE_4GB)
631573Srgrimes			writel(0x00000210, AM64_DDRSS_SS_BASE + DDRSS_V2A_CTL_REG);
641573Srgrimes
651573Srgrimes	switch (ram_size) {
661573Srgrimes	case EEPROM_RAM_SIZE_1GB:
671573Srgrimes		gd->ram_size = 0x40000000;
681573Srgrimes		break;
691573Srgrimes	case EEPROM_RAM_SIZE_2GB:
701573Srgrimes		gd->ram_size = 0x80000000;
711573Srgrimes		break;
721573Srgrimes	case EEPROM_RAM_SIZE_4GB:
7346079Simp#ifdef CONFIG_PHYS_64BIT
741573Srgrimes		gd->ram_size = 0x100000000;
7546079Simp#else
761573Srgrimes		gd->ram_size = 0x80000000;
771573Srgrimes#endif
781573Srgrimes		break;
791573Srgrimes	default:
801573Srgrimes		gd->ram_size = 0x80000000;
811573Srgrimes	}
821573Srgrimes
831573Srgrimes	return 0;
841573Srgrimes}
851573Srgrimes
861573Srgrimesphys_size_t board_get_usable_ram_top(phys_size_t total_size)
871573Srgrimes{
881573Srgrimes#ifdef CONFIG_PHYS_64BIT
891573Srgrimes	/* Limit RAM used by U-Boot to the DDR low region */
901573Srgrimes	if (gd->ram_top > 0x100000000)
918870Srgrimes		return 0x100000000;
921573Srgrimes#endif
931573Srgrimes	return gd->ram_top;
941573Srgrimes}
951573Srgrimes
961573Srgrimesint dram_init_banksize(void)
971573Srgrimes{
981573Srgrimes	u8 ram_size;
991573Srgrimes
1001573Srgrimes	if (!IS_ENABLED(CONFIG_CPU_V7R))
1011573Srgrimes		return fdtdec_setup_memory_banksize();
1021573Srgrimes
1031573Srgrimes	ram_size = phytec_get_am62_ddr_size_default();
1041573Srgrimes	switch (ram_size) {
1051573Srgrimes	case EEPROM_RAM_SIZE_1GB:
1061573Srgrimes		gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE;
1071573Srgrimes		gd->bd->bi_dram[0].size = 0x40000000;
1081573Srgrimes		gd->ram_size = 0x40000000;
1091573Srgrimes		break;
1101573Srgrimes
1111573Srgrimes	case EEPROM_RAM_SIZE_2GB:
11235923Sjb		gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE;
1131573Srgrimes		gd->bd->bi_dram[0].size = 0x80000000;
1141573Srgrimes		gd->ram_size = 0x80000000;
1151573Srgrimes		break;
1161573Srgrimes
1171573Srgrimes	case EEPROM_RAM_SIZE_4GB:
1181573Srgrimes		/* Bank 0 declares the memory available in the DDR low region */
1191573Srgrimes		gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE;
1201573Srgrimes		gd->bd->bi_dram[0].size = 0x80000000;
1211573Srgrimes		gd->ram_size = 0x80000000;
1221573Srgrimes
1231573Srgrimes#ifdef CONFIG_PHYS_64BIT
1241573Srgrimes		/* Bank 1 declares the memory available in the DDR upper region */
1251573Srgrimes		gd->bd->bi_dram[1].start = 0x880000000;
1261573Srgrimes		gd->bd->bi_dram[1].size = 0x80000000;
1271573Srgrimes		gd->ram_size = 0x100000000;
1281573Srgrimes#endif
1291573Srgrimes		break;
1301573Srgrimes	default:
1311573Srgrimes		/* Continue with default 2GB setup */
1321573Srgrimes		gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE;
1331573Srgrimes		gd->bd->bi_dram[0].size = 0x80000000;
1341573Srgrimes		gd->ram_size = 0x80000000;
135		printf("DDR size %d is not supported\n", ram_size);
136	}
137
138	return 0;
139}
140
141#if defined(CONFIG_K3_DDRSS)
142int update_ddrss_timings(void)
143{
144	int ret;
145	u8 ram_size;
146	struct ddrss *ddr_patch = NULL;
147	void *fdt = (void *)gd->fdt_blob;
148
149	ram_size = phytec_get_am62_ddr_size_default();
150	switch (ram_size) {
151	case EEPROM_RAM_SIZE_1GB:
152		ddr_patch = &phycore_ddrss_data[PHYCORE_1GB];
153		break;
154	case EEPROM_RAM_SIZE_2GB:
155		ddr_patch = NULL;
156		break;
157	case EEPROM_RAM_SIZE_4GB:
158		ddr_patch = &phycore_ddrss_data[PHYCORE_4GB];
159		break;
160	default:
161		break;
162	}
163
164	/* Nothing to patch */
165	if (!ddr_patch)
166		return 0;
167
168	debug("Applying DDRSS timings patch for ram_size %d\n", ram_size);
169
170	ret = fdt_apply_ddrss_timings_patch(fdt, ddr_patch);
171	if (ret < 0) {
172		printf("Failed to apply ddrs timings patch %d\n", ret);
173		return ret;
174	}
175
176	return 0;
177}
178
179int do_board_detect(void)
180{
181	return update_ddrss_timings();
182}
183#endif
184
185#if IS_ENABLED(CONFIG_SPL_BUILD)
186void spl_perform_fixups(struct spl_image_info *spl_image)
187{
188	u64 start[CONFIG_NR_DRAM_BANKS];
189	u64 size[CONFIG_NR_DRAM_BANKS];
190	int bank;
191	int ret;
192
193	dram_init();
194	dram_init_banksize();
195
196	for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
197		start[bank] = gd->bd->bi_dram[bank].start;
198		size[bank] = gd->bd->bi_dram[bank].size;
199	}
200
201	ret = fdt_fixup_memory_banks(spl_image->fdt_addr, start, size, CONFIG_NR_DRAM_BANKS);
202}
203#endif
204
205#define CTRLMMR_USB0_PHY_CTRL   0x43004008
206#define CTRLMMR_USB1_PHY_CTRL   0x43004018
207#define CORE_VOLTAGE            0x80000000
208
209#ifdef CONFIG_SPL_BOARD_INIT
210void spl_board_init(void)
211{
212	u32 val;
213
214	/* Set USB0 PHY core voltage to 0.85V */
215	val = readl(CTRLMMR_USB0_PHY_CTRL);
216	val &= ~(CORE_VOLTAGE);
217	writel(val, CTRLMMR_USB0_PHY_CTRL);
218
219	/* Set USB1 PHY core voltage to 0.85V */
220	val = readl(CTRLMMR_USB1_PHY_CTRL);
221	val &= ~(CORE_VOLTAGE);
222	writel(val, CTRLMMR_USB1_PHY_CTRL);
223
224	/* We have 32k crystal, so lets enable it */
225	val = readl(MCU_CTRL_LFXOSC_CTRL);
226	val &= ~(MCU_CTRL_LFXOSC_32K_DISABLE_VAL);
227	writel(val, MCU_CTRL_LFXOSC_CTRL);
228	/* Add any TRIM needed for the crystal here.. */
229	/* Make sure to mux up to take the SoC 32k from the crystal */
230	writel(MCU_CTRL_DEVICE_CLKOUT_LFOSC_SELECT_VAL,
231	       MCU_CTRL_DEVICE_CLKOUT_32K_CTRL);
232}
233#endif
234