summaryrefslogtreecommitdiff
path: root/board/phytec/phycore_am62x/phycore-am62x.c
blob: 3cdcbf2ecc973ffe11768fde4857a957d316f68f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2022 - 2023 PHYTEC Messtechnik GmbH
 * Author: Wadim Egorov <[email protected]>
 */

#include <asm/arch/hardware.h>
#include <asm/io.h>
#include <spl.h>
#include <asm/arch/k3-ddr.h>
#include <fdt_support.h>

#include "phycore-ddr-data.h"
#include "../common/k3/k3_ddrss_patch.h"
#include "../common/am6_som_detection.h"

#define AM64_DDRSS_SS_BASE	0x0F300000
#define DDRSS_V2A_CTL_REG	0x0020

DECLARE_GLOBAL_DATA_PTR;

static u8 phytec_get_am62_ddr_size_default(void)
{
	int ret;
	struct phytec_eeprom_data data;

	if (IS_ENABLED(CONFIG_PHYCORE_AM62X_RAM_SIZE_FIX)) {
		if (IS_ENABLED(CONFIG_PHYCORE_AM62X_RAM_SIZE_1GB))
			return EEPROM_RAM_SIZE_1GB;
		else if (IS_ENABLED(CONFIG_PHYCORE_AM62X_RAM_SIZE_2GB))
			return EEPROM_RAM_SIZE_2GB;
		else if (IS_ENABLED(CONFIG_PHYCORE_AM62X_RAM_SIZE_4GB))
			return EEPROM_RAM_SIZE_4GB;
	}

	ret = phytec_eeprom_data_setup(&data, 0, EEPROM_ADDR);
	if (!ret && data.valid)
		return phytec_get_am6_ddr_size(&data);

	/* Default DDR size is 2GB */
	return EEPROM_RAM_SIZE_2GB;
}

int dram_init(void)
{
	u8 ram_size;

	if (!IS_ENABLED(CONFIG_CPU_V7R))
		return fdtdec_setup_mem_size_base();

	ram_size = phytec_get_am62_ddr_size_default();

	/*
	 * HACK: ddrss driver support 2GB RAM by default
	 * V2A_CTL_REG should be updated to support other RAM size
	 */
	if (IS_ENABLED(CONFIG_K3_AM64_DDRSS))
		if (ram_size == EEPROM_RAM_SIZE_4GB)
			writel(0x00000210, AM64_DDRSS_SS_BASE + DDRSS_V2A_CTL_REG);

	switch (ram_size) {
	case EEPROM_RAM_SIZE_1GB:
		gd->ram_size = 0x40000000;
		break;
	case EEPROM_RAM_SIZE_2GB:
		gd->ram_size = 0x80000000;
		break;
	case EEPROM_RAM_SIZE_4GB:
#ifdef CONFIG_PHYS_64BIT
		gd->ram_size = 0x100000000;
#else
		gd->ram_size = 0x80000000;
#endif
		break;
	default:
		gd->ram_size = 0x80000000;
	}

	return 0;
}

phys_size_t board_get_usable_ram_top(phys_size_t total_size)
{
#ifdef CONFIG_PHYS_64BIT
	/* Limit RAM used by U-Boot to the DDR low region */
	if (gd->ram_top > 0x100000000)
		return 0x100000000;
#endif
	return gd->ram_top;
}

int dram_init_banksize(void)
{
	u8 ram_size;

	memset(gd->bd->bi_dram, 0, sizeof(gd->bd->bi_dram[0]) * CONFIG_NR_DRAM_BANKS);

	if (!IS_ENABLED(CONFIG_CPU_V7R))
		return fdtdec_setup_memory_banksize();

	ram_size = phytec_get_am62_ddr_size_default();
	switch (ram_size) {
	case EEPROM_RAM_SIZE_1GB:
		gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE;
		gd->bd->bi_dram[0].size = 0x40000000;
		gd->ram_size = 0x40000000;
		break;

	case EEPROM_RAM_SIZE_2GB:
		gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE;
		gd->bd->bi_dram[0].size = 0x80000000;
		gd->ram_size = 0x80000000;
		break;

	case EEPROM_RAM_SIZE_4GB:
		/* Bank 0 declares the memory available in the DDR low region */
		gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE;
		gd->bd->bi_dram[0].size = 0x80000000;
		gd->ram_size = 0x80000000;

#ifdef CONFIG_PHYS_64BIT
		/* Bank 1 declares the memory available in the DDR upper region */
		gd->bd->bi_dram[1].start = 0x880000000;
		gd->bd->bi_dram[1].size = 0x80000000;
		gd->ram_size = 0x100000000;
#endif
		break;
	default:
		/* Continue with default 2GB setup */
		gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE;
		gd->bd->bi_dram[0].size = 0x80000000;
		gd->ram_size = 0x80000000;
		printf("DDR size %d is not supported\n", ram_size);
	}

	return 0;
}

#if defined(CONFIG_K3_DDRSS)
int update_ddrss_timings(void)
{
	int ret;
	u8 ram_size;
	struct ddrss *ddr_patch = NULL;
	void *fdt = (void *)gd->fdt_blob;

	ram_size = phytec_get_am62_ddr_size_default();
	switch (ram_size) {
	case EEPROM_RAM_SIZE_1GB:
		ddr_patch = &phycore_ddrss_data[PHYCORE_1GB];
		break;
	case EEPROM_RAM_SIZE_2GB:
		ddr_patch = NULL;
		break;
	case EEPROM_RAM_SIZE_4GB:
		ddr_patch = &phycore_ddrss_data[PHYCORE_4GB];
		break;
	default:
		break;
	}

	/* Nothing to patch */
	if (!ddr_patch)
		return 0;

	debug("Applying DDRSS timings patch for ram_size %d\n", ram_size);

	ret = fdt_apply_ddrss_timings_patch(fdt, ddr_patch);
	if (ret < 0) {
		printf("Failed to apply ddrs timings patch %d\n", ret);
		return ret;
	}

	return 0;
}

int do_board_detect(void)
{
	int ret;
	void *fdt = (void *)gd->fdt_blob;
	int bank;
	u64 start[CONFIG_NR_DRAM_BANKS];
	u64 size[CONFIG_NR_DRAM_BANKS];

	dram_init();
	dram_init_banksize();

	for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
		start[bank] = gd->bd->bi_dram[bank].start;
		size[bank] = gd->bd->bi_dram[bank].size;
	}

	ret = fdt_fixup_memory_banks(fdt, start, size, CONFIG_NR_DRAM_BANKS);
	if (ret)
		return ret;

	return update_ddrss_timings();
}
#endif

#if IS_ENABLED(CONFIG_XPL_BUILD)
void spl_perform_board_fixups(struct spl_image_info *spl_image)
{
	if (IS_ENABLED(CONFIG_K3_DDRSS) && IS_ENABLED(CONFIG_K3_INLINE_ECC))
		fixup_ddr_driver_for_ecc(spl_image);
	else
		fixup_memory_node(spl_image);
}
#endif

#define CTRLMMR_USB0_PHY_CTRL   0x43004008
#define CTRLMMR_USB1_PHY_CTRL   0x43004018
#define CORE_VOLTAGE            0x80000000

#ifdef CONFIG_SPL_BOARD_INIT
void spl_board_init(void)
{
	u32 val;

	/* Set USB0 PHY core voltage to 0.85V */
	val = readl(CTRLMMR_USB0_PHY_CTRL);
	val &= ~(CORE_VOLTAGE);
	writel(val, CTRLMMR_USB0_PHY_CTRL);

	/* Set USB1 PHY core voltage to 0.85V */
	val = readl(CTRLMMR_USB1_PHY_CTRL);
	val &= ~(CORE_VOLTAGE);
	writel(val, CTRLMMR_USB1_PHY_CTRL);

	/* We have 32k crystal, so lets enable it */
	val = readl(MCU_CTRL_LFXOSC_CTRL);
	val &= ~(MCU_CTRL_LFXOSC_32K_DISABLE_VAL);
	writel(val, MCU_CTRL_LFXOSC_CTRL);
	/* Add any TRIM needed for the crystal here.. */
	/* Make sure to mux up to take the SoC 32k from the crystal */
	writel(MCU_CTRL_DEVICE_CLKOUT_LFOSC_SELECT_VAL,
	       MCU_CTRL_DEVICE_CLKOUT_32K_CTRL);
}
#endif