xref: /rk3399_rockchip-uboot/arch/arm/mach-omap2/omap5/fdt.c (revision 0e00a84cdedf7a1949486746225b35984b351eca)
1983e3700STom Rini /*
2983e3700STom Rini  * Copyright 2016 Texas Instruments, Inc.
3983e3700STom Rini  *
4983e3700STom Rini  * SPDX-License-Identifier: GPL-2.0+
5983e3700STom Rini  */
6983e3700STom Rini 
7983e3700STom Rini #include <common.h>
8*0e00a84cSMasahiro Yamada #include <linux/libfdt.h>
9983e3700STom Rini #include <fdt_support.h>
10983e3700STom Rini #include <malloc.h>
11983e3700STom Rini 
12983e3700STom Rini #include <asm/omap_common.h>
13983e3700STom Rini #include <asm/arch-omap5/sys_proto.h>
14983e3700STom Rini 
15983e3700STom Rini #ifdef CONFIG_TI_SECURE_DEVICE
16983e3700STom Rini 
17983e3700STom Rini /* Give zero values if not already defined */
18983e3700STom Rini #ifndef TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ
19983e3700STom Rini #define TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ (0)
20983e3700STom Rini #endif
21983e3700STom Rini #ifndef CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ
22983e3700STom Rini #define CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ (0)
23983e3700STom Rini #endif
24983e3700STom Rini 
25983e3700STom Rini static u32 hs_irq_skip[] = {
26983e3700STom Rini 	8,	/* Secure violation reporting interrupt */
27983e3700STom Rini 	15,	/* One interrupt for SDMA by secure world */
28983e3700STom Rini 	118	/* One interrupt for Crypto DMA by secure world */
29983e3700STom Rini };
30983e3700STom Rini 
ft_hs_fixup_crossbar(void * fdt,bd_t * bd)31983e3700STom Rini static int ft_hs_fixup_crossbar(void *fdt, bd_t *bd)
32983e3700STom Rini {
33983e3700STom Rini 	const char *path;
34983e3700STom Rini 	int offs;
35983e3700STom Rini 	int ret;
36983e3700STom Rini 	int len, i, old_cnt, new_cnt;
37983e3700STom Rini 	u32 *temp;
38983e3700STom Rini 	const u32 *p_data;
39983e3700STom Rini 
40983e3700STom Rini 	/*
41983e3700STom Rini 	 * Increase the size of the fdt
42983e3700STom Rini 	 * so we have some breathing room
43983e3700STom Rini 	 */
44983e3700STom Rini 	ret = fdt_increase_size(fdt, 512);
45983e3700STom Rini 	if (ret < 0) {
46983e3700STom Rini 		printf("Could not increase size of device tree: %s\n",
47983e3700STom Rini 		       fdt_strerror(ret));
48983e3700STom Rini 		return ret;
49983e3700STom Rini 	}
50983e3700STom Rini 
51983e3700STom Rini 	/* Reserve IRQs that are used/needed by secure world */
52983e3700STom Rini 	path = "/ocp/crossbar";
53983e3700STom Rini 	offs = fdt_path_offset(fdt, path);
54983e3700STom Rini 	if (offs < 0) {
55983e3700STom Rini 		debug("Node %s not found.\n", path);
56983e3700STom Rini 		return 0;
57983e3700STom Rini 	}
58983e3700STom Rini 
59983e3700STom Rini 	/* Get current entries */
60983e3700STom Rini 	p_data = fdt_getprop(fdt, offs, "ti,irqs-skip", &len);
61983e3700STom Rini 	if (p_data)
62983e3700STom Rini 		old_cnt = len / sizeof(u32);
63983e3700STom Rini 	else
64983e3700STom Rini 		old_cnt = 0;
65983e3700STom Rini 
66983e3700STom Rini 	new_cnt = sizeof(hs_irq_skip) /
67983e3700STom Rini 				sizeof(hs_irq_skip[0]);
68983e3700STom Rini 
69983e3700STom Rini 	/* Create new/updated skip list for HS parts */
70983e3700STom Rini 	temp = malloc(sizeof(u32) * (old_cnt + new_cnt));
71983e3700STom Rini 	for (i = 0; i < new_cnt; i++)
72983e3700STom Rini 		temp[i] = cpu_to_fdt32(hs_irq_skip[i]);
73983e3700STom Rini 	for (i = 0; i < old_cnt; i++)
74983e3700STom Rini 		temp[i + new_cnt] = p_data[i];
75983e3700STom Rini 
76983e3700STom Rini 	/* Blow away old data and set new data */
77983e3700STom Rini 	fdt_delprop(fdt, offs, "ti,irqs-skip");
78983e3700STom Rini 	ret = fdt_setprop(fdt, offs, "ti,irqs-skip",
79983e3700STom Rini 			  temp,
80983e3700STom Rini 			  (old_cnt + new_cnt) * sizeof(u32));
81983e3700STom Rini 	free(temp);
82983e3700STom Rini 
83983e3700STom Rini 	/* Check if the update worked */
84983e3700STom Rini 	if (ret < 0) {
85983e3700STom Rini 		printf("Could not add ti,irqs-skip property to node %s: %s\n",
86983e3700STom Rini 		       path, fdt_strerror(ret));
87983e3700STom Rini 		return ret;
88983e3700STom Rini 	}
89983e3700STom Rini 
90983e3700STom Rini 	return 0;
91983e3700STom Rini }
92983e3700STom Rini 
93983e3700STom Rini #if ((TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ != 0) || \
94983e3700STom Rini     (CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ != 0))
ft_hs_fixup_sram(void * fdt,bd_t * bd)95983e3700STom Rini static int ft_hs_fixup_sram(void *fdt, bd_t *bd)
96983e3700STom Rini {
97983e3700STom Rini 	const char *path;
98983e3700STom Rini 	int offs;
99983e3700STom Rini 	int ret;
100983e3700STom Rini 	u32 temp[2];
101983e3700STom Rini 
102983e3700STom Rini 	/*
103983e3700STom Rini 	 * Update SRAM reservations on secure devices. The OCMC RAM
104983e3700STom Rini 	 * is always reserved for secure use from the start of that
105983e3700STom Rini 	 * memory region
106983e3700STom Rini 	 */
107983e3700STom Rini 	path = "/ocp/ocmcram@40300000/sram-hs";
108983e3700STom Rini 	offs = fdt_path_offset(fdt, path);
109983e3700STom Rini 	if (offs < 0) {
110983e3700STom Rini 		debug("Node %s not found.\n", path);
111983e3700STom Rini 		return 0;
112983e3700STom Rini 	}
113983e3700STom Rini 
114983e3700STom Rini 	/* relative start offset */
115983e3700STom Rini 	temp[0] = cpu_to_fdt32(0);
116983e3700STom Rini 	/* reservation size */
117983e3700STom Rini 	temp[1] = cpu_to_fdt32(max(TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ,
118983e3700STom Rini 				   CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ));
119983e3700STom Rini 	fdt_delprop(fdt, offs, "reg");
120983e3700STom Rini 	ret = fdt_setprop(fdt, offs, "reg", temp, 2 * sizeof(u32));
121983e3700STom Rini 	if (ret < 0) {
122983e3700STom Rini 		printf("Could not add reg property to node %s: %s\n",
123983e3700STom Rini 		       path, fdt_strerror(ret));
124983e3700STom Rini 		return ret;
125983e3700STom Rini 	}
126983e3700STom Rini 
127983e3700STom Rini 	return 0;
128983e3700STom Rini }
129983e3700STom Rini #else
ft_hs_fixup_sram(void * fdt,bd_t * bd)130983e3700STom Rini static int ft_hs_fixup_sram(void *fdt, bd_t *bd) { return 0; }
131983e3700STom Rini #endif
132983e3700STom Rini 
ft_hs_fixups(void * fdt,bd_t * bd)133983e3700STom Rini static void ft_hs_fixups(void *fdt, bd_t *bd)
134983e3700STom Rini {
135983e3700STom Rini 	/* Check we are running on an HS/EMU device type */
136983e3700STom Rini 	if (GP_DEVICE != get_device_type()) {
137983e3700STom Rini 		if ((ft_hs_fixup_crossbar(fdt, bd) == 0) &&
138983e3700STom Rini 		    (ft_hs_disable_rng(fdt, bd) == 0) &&
139983e3700STom Rini 		    (ft_hs_fixup_sram(fdt, bd) == 0) &&
140a8ff9685SAndrew F. Davis 		    (ft_hs_fixup_dram(fdt, bd) == 0) &&
141a8ff9685SAndrew F. Davis 		    (ft_hs_add_tee(fdt, bd) == 0))
142983e3700STom Rini 			return;
143983e3700STom Rini 	} else {
144983e3700STom Rini 		printf("ERROR: Incorrect device type (GP) detected!");
145983e3700STom Rini 	}
146983e3700STom Rini 	/* Fixup failed or wrong device type */
147983e3700STom Rini 	hang();
148983e3700STom Rini }
149983e3700STom Rini #else
ft_hs_fixups(void * fdt,bd_t * bd)150983e3700STom Rini static void ft_hs_fixups(void *fdt, bd_t *bd)
151983e3700STom Rini {
152983e3700STom Rini }
153983e3700STom Rini #endif /* #ifdef CONFIG_TI_SECURE_DEVICE */
154983e3700STom Rini 
1551b42ab3eSSuman Anna #if defined(CONFIG_TARGET_DRA7XX_EVM) || defined(CONFIG_TARGET_AM57XX_EVM)
1561b42ab3eSSuman Anna #define OPP_DSP_CLK_NUM	3
1571b42ab3eSSuman Anna #define OPP_IVA_CLK_NUM	2
1581b42ab3eSSuman Anna #define OPP_GPU_CLK_NUM	2
1591b42ab3eSSuman Anna 
1601b42ab3eSSuman Anna const char *dra7_opp_dsp_clk_names[OPP_DSP_CLK_NUM] = {
1611b42ab3eSSuman Anna 	"dpll_dsp_ck",
1621b42ab3eSSuman Anna 	"dpll_dsp_m2_ck",
1631b42ab3eSSuman Anna 	"dpll_dsp_m3x2_ck",
1641b42ab3eSSuman Anna };
1651b42ab3eSSuman Anna 
1661b42ab3eSSuman Anna const char *dra7_opp_iva_clk_names[OPP_IVA_CLK_NUM] = {
1671b42ab3eSSuman Anna 	"dpll_iva_ck",
1681b42ab3eSSuman Anna 	"dpll_iva_m2_ck",
1691b42ab3eSSuman Anna };
1701b42ab3eSSuman Anna 
1711b42ab3eSSuman Anna const char *dra7_opp_gpu_clk_names[OPP_GPU_CLK_NUM] = {
1721b42ab3eSSuman Anna 	"dpll_gpu_ck",
1731b42ab3eSSuman Anna 	"dpll_gpu_m2_ck",
1741b42ab3eSSuman Anna };
1751b42ab3eSSuman Anna 
1761b42ab3eSSuman Anna /* DSPEVE voltage domain */
1771b42ab3eSSuman Anna u32 dra7_opp_dsp_clk_rates[NUM_OPPS][OPP_DSP_CLK_NUM] = {
1781b42ab3eSSuman Anna 	{}, /*OPP_LOW */
1791b42ab3eSSuman Anna 	{600000000, 600000000, 400000000}, /* OPP_NOM */
1801b42ab3eSSuman Anna 	{700000000, 700000000, 466666667}, /* OPP_OD */
1811b42ab3eSSuman Anna 	{750000000, 750000000, 500000000}, /* OPP_HIGH */
1821b42ab3eSSuman Anna };
1831b42ab3eSSuman Anna 
1841b42ab3eSSuman Anna /* IVA voltage domain */
1851b42ab3eSSuman Anna u32 dra7_opp_iva_clk_rates[NUM_OPPS][OPP_IVA_CLK_NUM] = {
1861b42ab3eSSuman Anna 	{}, /* OPP_LOW */
1871b42ab3eSSuman Anna 	{1165000000, 388333334}, /* OPP_NOM */
1881b42ab3eSSuman Anna 	{860000000, 430000000}, /* OPP_OD */
1891b42ab3eSSuman Anna 	{1064000000, 532000000}, /* OPP_HIGH */
1901b42ab3eSSuman Anna };
1911b42ab3eSSuman Anna 
1921b42ab3eSSuman Anna /* GPU voltage domain */
1931b42ab3eSSuman Anna u32 dra7_opp_gpu_clk_rates[NUM_OPPS][OPP_GPU_CLK_NUM] = {
1941b42ab3eSSuman Anna 	{}, /* OPP_LOW */
1951b42ab3eSSuman Anna 	{1277000000, 425666667}, /* OPP_NOM */
1961b42ab3eSSuman Anna 	{1000000000, 500000000}, /* OPP_OD */
1971b42ab3eSSuman Anna 	{1064000000, 532000000}, /* OPP_HIGH */
1981b42ab3eSSuman Anna };
1991b42ab3eSSuman Anna 
ft_fixup_clocks(void * fdt,const char ** names,u32 * rates,int num)2001b42ab3eSSuman Anna static int ft_fixup_clocks(void *fdt, const char **names, u32 *rates, int num)
2011b42ab3eSSuman Anna {
2021b42ab3eSSuman Anna 	int offs, node_offs, ret, i;
2031b42ab3eSSuman Anna 	uint32_t phandle;
2041b42ab3eSSuman Anna 
2051b42ab3eSSuman Anna 	offs = fdt_path_offset(fdt, "/ocp/l4@4a000000/cm_core_aon@5000/clocks");
2061b42ab3eSSuman Anna 	if (offs < 0) {
2071b42ab3eSSuman Anna 		debug("Could not find cm_core_aon clocks node path offset : %s\n",
2081b42ab3eSSuman Anna 		      fdt_strerror(offs));
2091b42ab3eSSuman Anna 		return offs;
2101b42ab3eSSuman Anna 	}
2111b42ab3eSSuman Anna 
2121b42ab3eSSuman Anna 	for (i = 0; i < num; i++) {
2131b42ab3eSSuman Anna 		node_offs = fdt_subnode_offset(fdt, offs, names[i]);
2141b42ab3eSSuman Anna 		if (node_offs < 0) {
2151b42ab3eSSuman Anna 			debug("Could not find clock sub-node %s: %s\n",
2161b42ab3eSSuman Anna 			      names[i], fdt_strerror(node_offs));
2171b42ab3eSSuman Anna 			return offs;
2181b42ab3eSSuman Anna 		}
2191b42ab3eSSuman Anna 
2201b42ab3eSSuman Anna 		phandle = fdt_get_phandle(fdt, node_offs);
2211b42ab3eSSuman Anna 		if (!phandle) {
2221b42ab3eSSuman Anna 			debug("Could not find phandle for clock %s\n",
2231b42ab3eSSuman Anna 			      names[i]);
2241b42ab3eSSuman Anna 			return -1;
2251b42ab3eSSuman Anna 		}
2261b42ab3eSSuman Anna 
2271b42ab3eSSuman Anna 		ret = fdt_setprop_u32(fdt, node_offs, "assigned-clocks",
2281b42ab3eSSuman Anna 				      phandle);
2291b42ab3eSSuman Anna 		if (ret < 0) {
2301b42ab3eSSuman Anna 			debug("Could not add assigned-clocks property to clock node %s: %s\n",
2311b42ab3eSSuman Anna 			      names[i], fdt_strerror(ret));
2321b42ab3eSSuman Anna 			return ret;
2331b42ab3eSSuman Anna 		}
2341b42ab3eSSuman Anna 
2351b42ab3eSSuman Anna 		ret = fdt_setprop_u32(fdt, node_offs, "assigned-clock-rates",
2361b42ab3eSSuman Anna 				      rates[i]);
2371b42ab3eSSuman Anna 		if (ret < 0) {
2381b42ab3eSSuman Anna 			debug("Could not add assigned-clock-rates property to clock node %s: %s\n",
2391b42ab3eSSuman Anna 			      names[i], fdt_strerror(ret));
2401b42ab3eSSuman Anna 			return ret;
2411b42ab3eSSuman Anna 		}
2421b42ab3eSSuman Anna 	}
2431b42ab3eSSuman Anna 
2441b42ab3eSSuman Anna 	return 0;
2451b42ab3eSSuman Anna }
2461b42ab3eSSuman Anna 
ft_opp_clock_fixups(void * fdt,bd_t * bd)2471b42ab3eSSuman Anna static void ft_opp_clock_fixups(void *fdt, bd_t *bd)
2481b42ab3eSSuman Anna {
2491b42ab3eSSuman Anna 	const char **clk_names;
2501b42ab3eSSuman Anna 	u32 *clk_rates;
2511b42ab3eSSuman Anna 	int ret;
2521b42ab3eSSuman Anna 
2531b42ab3eSSuman Anna 	if (!is_dra72x() && !is_dra7xx())
2541b42ab3eSSuman Anna 		return;
2551b42ab3eSSuman Anna 
2561b42ab3eSSuman Anna 	/* fixup DSP clocks */
2571b42ab3eSSuman Anna 	clk_names = dra7_opp_dsp_clk_names;
2581b42ab3eSSuman Anna 	clk_rates = dra7_opp_dsp_clk_rates[get_voltrail_opp(VOLT_EVE)];
2591b42ab3eSSuman Anna 	ret = ft_fixup_clocks(fdt, clk_names, clk_rates, OPP_DSP_CLK_NUM);
2601b42ab3eSSuman Anna 	if (ret) {
2611b42ab3eSSuman Anna 		printf("ft_fixup_clocks failed for DSP voltage domain: %s\n",
2621b42ab3eSSuman Anna 		       fdt_strerror(ret));
2631b42ab3eSSuman Anna 		return;
2641b42ab3eSSuman Anna 	}
2651b42ab3eSSuman Anna 
2661b42ab3eSSuman Anna 	/* fixup IVA clocks */
2671b42ab3eSSuman Anna 	clk_names = dra7_opp_iva_clk_names;
2681b42ab3eSSuman Anna 	clk_rates = dra7_opp_iva_clk_rates[get_voltrail_opp(VOLT_IVA)];
2691b42ab3eSSuman Anna 	ret = ft_fixup_clocks(fdt, clk_names, clk_rates, OPP_IVA_CLK_NUM);
2701b42ab3eSSuman Anna 	if (ret) {
2711b42ab3eSSuman Anna 		printf("ft_fixup_clocks failed for IVA voltage domain: %s\n",
2721b42ab3eSSuman Anna 		       fdt_strerror(ret));
2731b42ab3eSSuman Anna 		return;
2741b42ab3eSSuman Anna 	}
2751b42ab3eSSuman Anna 
2761b42ab3eSSuman Anna 	/* fixup GPU clocks */
2771b42ab3eSSuman Anna 	clk_names = dra7_opp_gpu_clk_names;
2781b42ab3eSSuman Anna 	clk_rates = dra7_opp_gpu_clk_rates[get_voltrail_opp(VOLT_GPU)];
2791b42ab3eSSuman Anna 	ret = ft_fixup_clocks(fdt, clk_names, clk_rates, OPP_GPU_CLK_NUM);
2801b42ab3eSSuman Anna 	if (ret) {
2811b42ab3eSSuman Anna 		printf("ft_fixup_clocks failed for GPU voltage domain: %s\n",
2821b42ab3eSSuman Anna 		       fdt_strerror(ret));
2831b42ab3eSSuman Anna 		return;
2841b42ab3eSSuman Anna 	}
2851b42ab3eSSuman Anna }
2861b42ab3eSSuman Anna #else
ft_opp_clock_fixups(void * fdt,bd_t * bd)2871b42ab3eSSuman Anna static void ft_opp_clock_fixups(void *fdt, bd_t *bd) { }
2881b42ab3eSSuman Anna #endif /* CONFIG_TARGET_DRA7XX_EVM || CONFIG_TARGET_AM57XX_EVM */
2891b42ab3eSSuman Anna 
290983e3700STom Rini /*
291983e3700STom Rini  * Place for general cpu/SoC FDT fixups. Board specific
292983e3700STom Rini  * fixups should remain in the board files which is where
293983e3700STom Rini  * this function should be called from.
294983e3700STom Rini  */
ft_cpu_setup(void * fdt,bd_t * bd)295983e3700STom Rini void ft_cpu_setup(void *fdt, bd_t *bd)
296983e3700STom Rini {
297983e3700STom Rini 	ft_hs_fixups(fdt, bd);
2981b42ab3eSSuman Anna 	ft_opp_clock_fixups(fdt, bd);
299983e3700STom Rini }
300