• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * J721E: SoC specific initialization
4  *
5  * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
6  *	Lokesh Vutla <lokeshvutla@ti.com>
7  */
8 
9 #include <common.h>
10 #include <spl.h>
11 #include <asm/io.h>
12 #include <asm/armv7_mpu.h>
13 #include <asm/arch/hardware.h>
14 #include <asm/arch/sysfw-loader.h>
15 #include "common.h"
16 #include <asm/arch/sys_proto.h>
17 #include <linux/soc/ti/ti_sci_protocol.h>
18 #include <dm.h>
19 #include <dm/uclass-internal.h>
20 #include <dm/pinctrl.h>
21 
22 #ifdef CONFIG_SPL_BUILD
mmr_unlock(u32 base,u32 partition)23 static void mmr_unlock(u32 base, u32 partition)
24 {
25 	/* Translate the base address */
26 	phys_addr_t part_base = base + partition * CTRL_MMR0_PARTITION_SIZE;
27 
28 	/* Unlock the requested partition if locked using two-step sequence */
29 	writel(CTRLMMR_LOCK_KICK0_UNLOCK_VAL, part_base + CTRLMMR_LOCK_KICK0);
30 	writel(CTRLMMR_LOCK_KICK1_UNLOCK_VAL, part_base + CTRLMMR_LOCK_KICK1);
31 }
32 
ctrl_mmr_unlock(void)33 static void ctrl_mmr_unlock(void)
34 {
35 	/* Unlock all WKUP_CTRL_MMR0 module registers */
36 	mmr_unlock(WKUP_CTRL_MMR0_BASE, 0);
37 	mmr_unlock(WKUP_CTRL_MMR0_BASE, 1);
38 	mmr_unlock(WKUP_CTRL_MMR0_BASE, 2);
39 	mmr_unlock(WKUP_CTRL_MMR0_BASE, 3);
40 	mmr_unlock(WKUP_CTRL_MMR0_BASE, 4);
41 	mmr_unlock(WKUP_CTRL_MMR0_BASE, 6);
42 	mmr_unlock(WKUP_CTRL_MMR0_BASE, 7);
43 
44 	/* Unlock all MCU_CTRL_MMR0 module registers */
45 	mmr_unlock(MCU_CTRL_MMR0_BASE, 0);
46 	mmr_unlock(MCU_CTRL_MMR0_BASE, 1);
47 	mmr_unlock(MCU_CTRL_MMR0_BASE, 2);
48 	mmr_unlock(MCU_CTRL_MMR0_BASE, 3);
49 	mmr_unlock(MCU_CTRL_MMR0_BASE, 4);
50 
51 	/* Unlock all CTRL_MMR0 module registers */
52 	mmr_unlock(CTRL_MMR0_BASE, 0);
53 	mmr_unlock(CTRL_MMR0_BASE, 1);
54 	mmr_unlock(CTRL_MMR0_BASE, 2);
55 	mmr_unlock(CTRL_MMR0_BASE, 3);
56 	mmr_unlock(CTRL_MMR0_BASE, 4);
57 	mmr_unlock(CTRL_MMR0_BASE, 5);
58 	mmr_unlock(CTRL_MMR0_BASE, 6);
59 	mmr_unlock(CTRL_MMR0_BASE, 7);
60 }
61 
62 /*
63  * This uninitialized global variable would normal end up in the .bss section,
64  * but the .bss is cleared between writing and reading this variable, so move
65  * it to the .data section.
66  */
67 u32 bootindex __attribute__((section(".data")));
68 
store_boot_index_from_rom(void)69 static void store_boot_index_from_rom(void)
70 {
71 	bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX);
72 }
73 
board_init_f(ulong dummy)74 void board_init_f(ulong dummy)
75 {
76 #if defined(CONFIG_K3_J721E_DDRSS) || defined(CONFIG_K3_LOAD_SYSFW)
77 	struct udevice *dev;
78 	int ret;
79 #endif
80 	/*
81 	 * Cannot delay this further as there is a chance that
82 	 * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section.
83 	 */
84 	store_boot_index_from_rom();
85 
86 	/* Make all control module registers accessible */
87 	ctrl_mmr_unlock();
88 
89 #ifdef CONFIG_CPU_V7R
90 	disable_linefill_optimization();
91 	setup_k3_mpu_regions();
92 #endif
93 
94 	/* Init DM early */
95 	spl_early_init();
96 
97 #ifdef CONFIG_K3_LOAD_SYSFW
98 	/*
99 	 * Process pinctrl for the serial0 a.k.a. MCU_UART0 module and continue
100 	 * regardless of the result of pinctrl. Do this without probing the
101 	 * device, but instead by searching the device that would request the
102 	 * given sequence number if probed. The UART will be used by the system
103 	 * firmware (SYSFW) image for various purposes and SYSFW depends on us
104 	 * to initialize its pin settings.
105 	 */
106 	ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, true, &dev);
107 	if (!ret)
108 		pinctrl_select_state(dev, "default");
109 
110 	/*
111 	 * Load, start up, and configure system controller firmware. Provide
112 	 * the U-Boot console init function to the SYSFW post-PM configuration
113 	 * callback hook, effectively switching on (or over) the console
114 	 * output.
115 	 */
116 	k3_sysfw_loader(preloader_console_init);
117 #else
118 	/* Prepare console output */
119 	preloader_console_init();
120 #endif
121 
122 #if defined(CONFIG_CPU_V7R) && defined(CONFIG_K3_AVS0)
123 	ret = uclass_get_device_by_driver(UCLASS_MISC, DM_GET_DRIVER(k3_avs),
124 					  &dev);
125 	if (ret)
126 		printf("AVS init failed: %d\n", ret);
127 #endif
128 
129 #if defined(CONFIG_K3_J721E_DDRSS)
130 	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
131 	if (ret)
132 		panic("DRAM init failed: %d\n", ret);
133 #endif
134 }
135 
spl_boot_mode(const u32 boot_device)136 u32 spl_boot_mode(const u32 boot_device)
137 {
138 	switch (boot_device) {
139 	case BOOT_DEVICE_MMC1:
140 		return MMCSD_MODE_EMMCBOOT;
141 	case BOOT_DEVICE_MMC2:
142 		return MMCSD_MODE_FS;
143 	default:
144 		return MMCSD_MODE_RAW;
145 	}
146 }
147 
__get_primary_bootmedia(u32 main_devstat,u32 wkup_devstat)148 static u32 __get_primary_bootmedia(u32 main_devstat, u32 wkup_devstat)
149 {
150 
151 	u32 bootmode = (wkup_devstat & WKUP_DEVSTAT_PRIMARY_BOOTMODE_MASK) >>
152 			WKUP_DEVSTAT_PRIMARY_BOOTMODE_SHIFT;
153 
154 	bootmode |= (main_devstat & MAIN_DEVSTAT_BOOT_MODE_B_MASK) <<
155 			BOOT_MODE_B_SHIFT;
156 
157 	if (bootmode == BOOT_DEVICE_OSPI || bootmode ==	BOOT_DEVICE_QSPI)
158 		bootmode = BOOT_DEVICE_SPI;
159 
160 	if (bootmode == BOOT_DEVICE_MMC2) {
161 		u32 port = (main_devstat &
162 			    MAIN_DEVSTAT_PRIM_BOOTMODE_MMC_PORT_MASK) >>
163 			   MAIN_DEVSTAT_PRIM_BOOTMODE_PORT_SHIFT;
164 		if (port == 0x0)
165 			bootmode = BOOT_DEVICE_MMC1;
166 	}
167 
168 	return bootmode;
169 }
170 
spl_boot_device(void)171 u32 spl_boot_device(void)
172 {
173 	u32 wkup_devstat = readl(CTRLMMR_WKUP_DEVSTAT);
174 	u32 main_devstat;
175 
176 	if (wkup_devstat & WKUP_DEVSTAT_MCU_OMLY_MASK) {
177 		printf("ERROR: MCU only boot is not yet supported\n");
178 		return BOOT_DEVICE_RAM;
179 	}
180 
181 	/* MAIN CTRL MMR can only be read if MCU ONLY is 0 */
182 	main_devstat = readl(CTRLMMR_MAIN_DEVSTAT);
183 
184 	/* ToDo: Add support for backup boot media */
185 	return __get_primary_bootmedia(main_devstat, wkup_devstat);
186 }
187 #endif
188 
189 #ifdef CONFIG_SYS_K3_SPL_ATF
190 
191 #define J721E_DEV_MCU_RTI0			262
192 #define J721E_DEV_MCU_RTI1			263
193 #define J721E_DEV_MCU_ARMSS0_CPU0		250
194 #define J721E_DEV_MCU_ARMSS0_CPU1		251
195 
release_resources_for_core_shutdown(void)196 void release_resources_for_core_shutdown(void)
197 {
198 	struct ti_sci_handle *ti_sci;
199 	struct ti_sci_dev_ops *dev_ops;
200 	struct ti_sci_proc_ops *proc_ops;
201 	int ret;
202 	u32 i;
203 
204 	const u32 put_device_ids[] = {
205 		J721E_DEV_MCU_RTI0,
206 		J721E_DEV_MCU_RTI1,
207 	};
208 
209 	ti_sci = get_ti_sci_handle();
210 	dev_ops = &ti_sci->ops.dev_ops;
211 	proc_ops = &ti_sci->ops.proc_ops;
212 
213 	/* Iterate through list of devices to put (shutdown) */
214 	for (i = 0; i < ARRAY_SIZE(put_device_ids); i++) {
215 		u32 id = put_device_ids[i];
216 
217 		ret = dev_ops->put_device(ti_sci, id);
218 		if (ret)
219 			panic("Failed to put device %u (%d)\n", id, ret);
220 	}
221 
222 	const u32 put_core_ids[] = {
223 		J721E_DEV_MCU_ARMSS0_CPU1,
224 		J721E_DEV_MCU_ARMSS0_CPU0,	/* Handle CPU0 after CPU1 */
225 	};
226 
227 	/* Iterate through list of cores to put (shutdown) */
228 	for (i = 0; i < ARRAY_SIZE(put_core_ids); i++) {
229 		u32 id = put_core_ids[i];
230 
231 		/*
232 		 * Queue up the core shutdown request. Note that this call
233 		 * needs to be followed up by an actual invocation of an WFE
234 		 * or WFI CPU instruction.
235 		 */
236 		ret = proc_ops->proc_shutdown_no_wait(ti_sci, id);
237 		if (ret)
238 			panic("Failed sending core %u shutdown message (%d)\n",
239 			      id, ret);
240 	}
241 }
242 #endif
243