xref: /rk3399_ARM-atf/plat/socionext/uniphier/uniphier_bl2_setup.c (revision c64873ab94cbb7cc7860ed348f0c55a9dec146e4)
1 /*
2  * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <errno.h>
8 
9 #include <platform_def.h>
10 
11 #include <common/bl_common.h>
12 #include <common/debug.h>
13 #include <common/desc_image_load.h>
14 #include <common/image_decompress.h>
15 #include <drivers/io/io_storage.h>
16 #include <lib/xlat_tables/xlat_tables_v2.h>
17 #include <plat/common/platform.h>
18 #ifdef UNIPHIER_DECOMPRESS_GZIP
19 #include <tf_gunzip.h>
20 #endif
21 
22 #include "uniphier.h"
23 
24 #define UNIPHIER_IMAGE_BUF_BASE		0x84300000UL
25 #define UNIPHIER_IMAGE_BUF_SIZE		0x00100000UL
26 
27 static int uniphier_bl2_kick_scp;
28 
29 void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
30 				  u_register_t x2, u_register_t x3)
31 {
32 	uniphier_console_setup();
33 }
34 
35 void bl2_el3_plat_arch_setup(void)
36 {
37 	unsigned int soc;
38 	int skip_scp = 0;
39 	int ret;
40 
41 	uniphier_mmap_setup();
42 	enable_mmu_el3(0);
43 
44 	soc = uniphier_get_soc_id();
45 	if (soc == UNIPHIER_SOC_UNKNOWN) {
46 		ERROR("unsupported SoC\n");
47 		plat_error_handler(-ENOTSUP);
48 	}
49 
50 	ret = uniphier_io_setup(soc);
51 	if (ret) {
52 		ERROR("failed to setup io devices\n");
53 		plat_error_handler(ret);
54 	}
55 
56 	switch (uniphier_get_boot_master(soc)) {
57 	case UNIPHIER_BOOT_MASTER_THIS:
58 		INFO("Booting from this SoC\n");
59 		skip_scp = 1;
60 		break;
61 	case UNIPHIER_BOOT_MASTER_SCP:
62 		INFO("Booting from on-chip SCP\n");
63 		if (uniphier_scp_is_running()) {
64 			INFO("SCP is already running. SCP_BL2 load will be skipped.\n");
65 			skip_scp = 1;
66 		}
67 
68 		/*
69 		 * SCP must be kicked every time even if it is already running
70 		 * because it polls this event after the reboot of the backend.
71 		 */
72 		uniphier_bl2_kick_scp = 1;
73 		break;
74 	case UNIPHIER_BOOT_MASTER_EXT:
75 		INFO("Booting from external SCP\n");
76 		skip_scp = 1;
77 		break;
78 	default:
79 		plat_error_handler(-ENOTSUP);
80 		break;
81 	}
82 
83 	if (skip_scp) {
84 		struct image_info *image_info;
85 
86 		image_info = uniphier_get_image_info(SCP_BL2_IMAGE_ID);
87 		image_info->h.attr |= IMAGE_ATTRIB_SKIP_LOADING;
88 	}
89 }
90 
91 void bl2_platform_setup(void)
92 {
93 }
94 
95 void plat_flush_next_bl_params(void)
96 {
97 	flush_bl_params_desc();
98 }
99 
100 bl_load_info_t *plat_get_bl_image_load_info(void)
101 {
102 	return get_bl_load_info_from_mem_params_desc();
103 }
104 
105 bl_params_t *plat_get_next_bl_params(void)
106 {
107 	return get_next_bl_params_from_mem_params_desc();
108 }
109 
110 void bl2_plat_preload_setup(void)
111 {
112 #ifdef UNIPHIER_DECOMPRESS_GZIP
113 	int ret;
114 
115 	ret = mmap_add_dynamic_region(UNIPHIER_IMAGE_BUF_BASE,
116 				      UNIPHIER_IMAGE_BUF_BASE,
117 				      UNIPHIER_IMAGE_BUF_SIZE,
118 				      MT_MEMORY | MT_RW | MT_NS);
119 	if (ret)
120 		plat_error_handler(ret);
121 
122 	image_decompress_init(UNIPHIER_IMAGE_BUF_BASE,
123 			      UNIPHIER_IMAGE_BUF_SIZE,
124 			      gunzip);
125 #endif
126 }
127 
128 int bl2_plat_handle_pre_image_load(unsigned int image_id)
129 {
130 	struct image_info *image_info;
131 	int ret;
132 
133 	image_info = uniphier_get_image_info(image_id);
134 
135 	ret = mmap_add_dynamic_region(image_info->image_base,
136 				      image_info->image_base,
137 				      image_info->image_max_size,
138 				      MT_MEMORY | MT_RW | MT_NS);
139 	if (ret)
140 		return ret;
141 
142 #ifdef UNIPHIER_DECOMPRESS_GZIP
143 	image_decompress_prepare(image_info);
144 #endif
145 	return 0;
146 }
147 
148 int bl2_plat_handle_post_image_load(unsigned int image_id)
149 {
150 	struct image_info *image_info = uniphier_get_image_info(image_id);
151 #ifdef UNIPHIER_DECOMPRESS_GZIP
152 	int ret;
153 
154 	if (!(image_info->h.attr & IMAGE_ATTRIB_SKIP_LOADING)) {
155 		ret = image_decompress(uniphier_get_image_info(image_id));
156 		if (ret)
157 			return ret;
158 	}
159 #endif
160 
161 	if (image_id == SCP_BL2_IMAGE_ID && uniphier_bl2_kick_scp)
162 		uniphier_scp_start(image_info->image_base);
163 
164 	return 0;
165 }
166