xref: /rk3399_ARM-atf/plat/mediatek/drivers/apusys/mt8196/apusys_ammu.h (revision 999503d285475f8920111f3fd760312ddf1d5b5b)
1 /*
2  * Copyright (c) 2024, MediaTek Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef APUSYS_AMMU_H
8 #define APUSYS_AMMU_H
9 
10 #include <platform_def.h>
11 
12 /* CMU */
13 #define APUMMU_CMU_TOP_BASE		(APU_CMU_TOP)
14 #define APUMMU_CMU_TOP_TOPOLOGY		(APUMMU_CMU_TOP_BASE + 0x04)
15 #define APUMMU_VSID_ENABLE_OFFSET	(0x50)
16 #define APUMMU_VSID_VALID_OFFSET	(0xb0)
17 
18 #define VSID_OFFSET(vsid_idx)		(((vsid_idx) >> 5) * 0x4)
19 
20 #define APUMMU_VSID_ENABLE_BASE(vsid_idx) \
21 	(APUMMU_CMU_TOP_BASE + VSID_OFFSET(vsid_idx) + APUMMU_VSID_ENABLE_OFFSET)
22 #define APUMMU_VSID_VALID_BASE(vsid_idx) \
23 	(APUMMU_CMU_TOP_BASE + VSID_OFFSET(vsid_idx) + APUMMU_VSID_VALID_OFFSET)
24 
25 /* VSID SRAM */
26 #define APUMMU_VSID_BASE		(APUMMU_CMU_TOP_BASE + 0x1000)
27 #define APUMMU_VSID_DESC_BASE		(APUMMU_VSID_BASE + 0x400)
28 #define APUMMU_VSID_SRAM_SZIE		(0x5C00)
29 #define APUMMU_VSID_TBL_SZIE		(0xF4)
30 
31 #define APUMMU_VSID(vsid_idx)		(APUMMU_VSID_BASE + (vsid_idx) * 4)
32 #define APUMMU_VSID_DESC(vsid_idx) \
33 	(APUMMU_VSID_DESC_BASE + (vsid_idx) * APUMMU_VSID_TBL_SZIE)
34 
35 /* TCU RCX */
36 #define APU_VCORE_CONFIG_BASE		(APU_RCX_VCORE_CONFIG)
37 #define APUMMU_RCX_EXTM_TCU_BASE	(APU_RCX_EXTM_TCU)
38 #define APUMMU_RCX_UPRV_TCU_BASE	(APU_RCX_UPRV_TCU)
39 
40 #define APUMMU_SSID_SID_WIDTH_CTRL	(0xCC0)
41 #define CSR_SMMU_AXMMUSID_WIDTH		BIT(7)
42 #define APUMMU_1M_SIZE			(0x100000)
43 
44 #define SMMU_NORMAL_0_1G_SID		(0x8)
45 #define SMMU_NORMAL_1_4G_SID		(0x9)
46 #define SMMU_NORMAL_4_16G_SID		(0xA)
47 
48 enum apummu_page_size {
49 	APUMMU_PAGE_LEN_128KB = 0,
50 	APUMMU_PAGE_LEN_256KB,
51 	APUMMU_PAGE_LEN_512KB,
52 	APUMMU_PAGE_LEN_1MB,
53 	APUMMU_PAGE_LEN_128MB,
54 	APUMMU_PAGE_LEN_256MB,
55 	APUMMU_PAGE_LEN_512MB,
56 	APUMMU_PAGE_LEN_4GB,
57 };
58 
59 #define APUMMU_VSID_SEGMENT_BASE(vsid_idx, seg_idx, seg_offset) \
60 	(APUMMU_VSID_DESC(vsid_idx) + (seg_idx) * 0xC + (seg_offset) * 0x04 + 0x4)
61 
62 #define APUMMU_VSID_SEGMENT_ENABLE(vsid_idx)	(APUMMU_VSID_DESC(vsid_idx))
63 
64 #define APUMMU_VSID_SRAM_TOTAL		(APUMMU_VSID_SRAM_SZIE / APUMMU_VSID_TBL_SZIE)
65 #define APUMMU_RSV_VSID_DESC_IDX_END	(APUMMU_VSID_SRAM_TOTAL - 1)
66 #define APUMMU_UPRV_RSV_DESC_IDX	(APUMMU_RSV_VSID_DESC_IDX_END)		/* 53 */
67 #define APUMMU_LOGGER_RSV_DESC_IDX	(APUMMU_RSV_VSID_DESC_IDX_END - 1)
68 #define APUMMU_APMCU_RSV_DESC_IDX	(APUMMU_RSV_VSID_DESC_IDX_END - 2)
69 #define APUMMU_GPU_RSV_DESC_IDX		(APUMMU_RSV_VSID_DESC_IDX_END - 3)
70 
71 #define APUMMU_SEG_OFFSET_0		(0)
72 #define APUMMU_SEG_OFFSET_1		(1)
73 #define APUMMU_SEG_OFFSET_2		(2)
74 #define APUMMU_VSID_EN_MASK		(0x1f)
75 
76 #define APUMMU_HW_THREAD_MAX		(7)
77 #define APUMMU_SEG_MAX			(9)
78 #define APUMMU_ADDR_SHIFT		(12)
79 
80 #define VSID_THREAD_SZ			(0x4)
81 #define VSID_CORID_MASK			(0x7f)
82 #define VSID_CORID_OFF			(11)
83 #define VSID_IDX_MASK			(0xff)
84 #define VSID_IDX_OFF			(3)
85 #define VSID_VALID_MASK			(0x1)
86 #define VSID_COR_VALID_OFF		(1)
87 #define VSID_VALID_OFF			(0)
88 
89 #define APUMMU_VSID_ACTIVE		(32)
90 #define APUMMU_VSID_RSV			(4)
91 #define APUMMU_VSID_UNUSED		(12)
92 #define APUMMU_VSID_USE_MAX		(APUMMU_VSID_ACTIVE + APUMMU_VSID_RSV)
93 
94 #if ((APUMMU_VSID_RSV + APUMMU_VSID_ACTIVE + APUMMU_VSID_UNUSED + 1) > APUMMU_VSID_SRAM_TOTAL)
95 #error APUMMU VSID Overflow
96 #endif
97 
98 #define APUMMU_RSV_VSID_IDX_END		(254)
99 #define APUMMU_RSV_VSID_IDX_START	(APUMMU_RSV_VSID_IDX_END - APUMMU_VSID_RSV + 1)
100 
101 #if ((APUMMU_RSV_VSID_IDX_END - APUMMU_RSV_VSID_IDX_START) > APUMMU_VSID_RSV)
102 #error APUMMU VSID RSV Overflow
103 #endif
104 
105 /* Reserve */
106 #define APUMMU_UPRV_RSV_VSID		(APUMMU_RSV_VSID_IDX_END)
107 #define APUMMU_LOGGER_RSV_VSID		(APUMMU_RSV_VSID_IDX_END - 1)
108 #define APUMMU_APMCU_RSV_VSID		(APUMMU_RSV_VSID_IDX_END - 2)
109 #define APUMMU_GPU_RSV_VSID		(APUMMU_RSV_VSID_IDX_END - 3)
110 
111 /* VSID bit mask */
112 #define APUMMU_VSID_MAX_MASK_WORD	((APUMMU_VSID_USE_MAX + 32 - 1) / 32)
113 
114 /* VSID fields */
115 #define READ_VSID_FIELD(vids, sg, offset, shift, mask) \
116 	((mmio_read_32(APUMMU_VSID_SEGMENT_BASE(vsid, seg, offset)) >> sift) & mask)
117 #define READ_VSID_FIELD_OFFESET0(vids, sg, shift, mask) \
118 	READ_VSID_FIELD(vids, sg, 0, shift, mask)
119 #define READ_VSID_FIELD_OFFESET1(vids, sg, shift, mask) \
120 	READ_VSID_FIELD(vids, sg, 1, shift, mask)
121 #define READ_VSID_FIELD_OFFESET2(vids, sg, shift, mask) \
122 	READ_VSID_FIELD(vids, sg, 2, shift, mask)
123 
124 /* Get segment offset 0 data - 0x00 */
125 #define APUMMU_SEGMENT_GET_INPUT(vsid, seg) \
126 	READ_VSID_FIELD_OFFESET0(vsid, seg, 10, 0x3FFFFF)
127 #define APUMMU_SEGMENT_GET_OFFSET0_RSRV(vsid, seg) \
128 	READ_VSID_FIELD_OFFESET0(vsid, seg, 6, 0xF)
129 #define APUMMU_SEGMENT_GET_PAGELEN(vsid, seg) \
130 	READ_VSID_FIELD_OFFESET0(vsid, seg, 0, 0x7)
131 #define APUMMU_SEGMENT_GET_PAGESEL(vsid, seg) \
132 	READ_VSID_FIELD_OFFESET0(vsid, seg, 3, 0x7)
133 
134 /* Get segment offset 1 data - 0x04 */
135 #define APUMMU_SEGMENT_GET_IOMMU_EN(vsid, seg) \
136 	READ_VSID_FIELD_OFFESET1(vsid, seg, 1, 0x1)
137 #define APUMMU_SEGMENT_GET_OFFSET1_RSRV0(vsid, seg) \
138 	READ_VSID_FIELD_OFFESET1(vsid, seg, 2, 0xFF)
139 #define APUMMU_SEGMENT_GET_OFFSET1_RSRV1(vsid, seg) \
140 	READ_VSID_FIELD_OFFESET1(vsid, seg, 0, 0x1)
141 #define APUMMU_SEGMENT_GET_OUTPUT(vsid, seg) \
142 	READ_VSID_FIELD_OFFESET1(vsid, seg, 10, 0x3FFFFF)
143 
144 /* Get segment offset 2 data - 0x08 */
145 #define APUMMU_SEGMENT_GET_ACP_EN(vsid, seg) \
146 	READ_VSID_FIELD_OFFESET2(vsid, seg, 12, 0x1)
147 #define APUMMU_SEGMENT_GET_AR_CACHE_ALLOC(vsid, seg) \
148 	READ_VSID_FIELD_OFFESET2(vsid, seg, 4, 0x1)
149 #define APUMMU_SEGMENT_GET_AR_EXCLU(vsid, seg) \
150 	READ_VSID_FIELD_OFFESET2(vsid, seg, 9, 0x1)
151 #define APUMMU_SEGMENT_GET_AR_SEPCU(vsid, seg) \
152 	READ_VSID_FIELD_OFFESET2(vsid, seg, 8, 0x1)
153 #define APUMMU_SEGMENT_GET_AR_SLB_EN(vsid, seg) \
154 	READ_VSID_FIELD_OFFESET2(vsid, seg, 2, 0x1)
155 #define APUMMU_SEGMENT_GET_AR_SLC_EN(vsid, seg) \
156 	READ_VSID_FIELD_OFFESET2(vsid, seg, 3, 0x1)
157 #define APUMMU_SEGMENT_GET_AW_CACHE_ALLOC(vsid, seg) \
158 	READ_VSID_FIELD_OFFESET2(vsid, seg, 7, 0x1)
159 #define APUMMU_SEGMENT_GET_AW_CLR(vsid, seg) \
160 	READ_VSID_FIELD_OFFESET2(vsid, seg, 11, 0x1)
161 #define APUMMU_SEGMENT_GET_AW_INVALID(vsid, seg) \
162 	READ_VSID_FIELD_OFFESET2(vsid, seg, 10, 0x1)
163 #define APUMMU_SEGMENT_GET_AW_SLB_EN(vsid, seg) \
164 	READ_VSID_FIELD_OFFESET2(vsid, seg, 5, 0x1)
165 #define APUMMU_SEGMENT_GET_AW_SLC_EN(vsid, seg) \
166 	READ_VSID_FIELD_OFFESET2(vsid, seg, 6, 0x1)
167 #define APUMMU_SEGMENT_GET_DOMAIN(vsid, seg) \
168 	READ_VSID_FIELD_OFFESET2(vsid, seg, 13, 0xF)
169 #define APUMMU_SEGMENT_GET_NS(vsid, seg) \
170 	READ_VSID_FIELD_OFFESET2(vsid, seg, 0, 0x1)
171 
172 /* Build segment data */
173 /* Build segment offset 0 (0x00) data */
174 #define APUMMU_VSID_SEGMENT_00_INPUT(input_adr)		(((input_adr) & 0x3fffff) << 10)
175 #define APUMMU_VSID_SEGMENT_00_PAGESEL(page_sel)	(((page_sel) & 0x7) << 3)
176 #define APUMMU_VSID_SEGMENT_00_PAGELEN(page_len)	(((page_len) & 0x7) << 0)
177 #define APUMMU_VSID_SEGMENT_00_RESV(resv)		(((resv) & 0xf) << 6)
178 
179 #define APUMMU_BUILD_SEGMENT_OFFSET0(input_adr, resv, page_sel, page_len) \
180 				(APUMMU_VSID_SEGMENT_00_INPUT(input_adr) | \
181 				 APUMMU_VSID_SEGMENT_00_RESV(resv) | \
182 				 APUMMU_VSID_SEGMENT_00_PAGESEL(page_sel) | \
183 				 APUMMU_VSID_SEGMENT_00_PAGELEN(page_len))
184 
185 /* Build segment offset 1 (0x04) data */
186 #define APUMMU_VSID_SEGMENT_04_IOMMU_EN(iommu_en)	(((iommu_en) & 0x1) << 1)
187 #define APUMMU_VSID_SEGMENT_04_OUTPUT(output_adr)	(((output_adr) & 0x3fffff) << 10)
188 #define APUMMU_VSID_SEGMENT_04_RESV0(resv0)		(((resv0) & 0xff) << 2)
189 #define APUMMU_VSID_SEGMENT_04_RESV1(resv1)		(((resv1) & 0x1) << 0)
190 
191 #define APUMMU_BUILD_SEGMENT_OFFSET1(output_adr, resv0, iommu_en, resv1) \
192 				(APUMMU_VSID_SEGMENT_04_OUTPUT(output_adr) | \
193 				 APUMMU_VSID_SEGMENT_04_RESV0(resv0) | \
194 				 APUMMU_VSID_SEGMENT_04_IOMMU_EN(iommu_en) | \
195 				 APUMMU_VSID_SEGMENT_04_RESV1(resv1))
196 
197 /* Build segment offset 2 (0x08) data */
198 #define APUMMU_VSID_SEGMENT_08_DOMAIN_MASK	(0xf)
199 #define APUMMU_VSID_SEGMENT_08_DOMAIN_SHIFT	(13)
200 #define APUMMU_VSID_SEGMENT_08_RESV_MASK	(0x7fff)
201 #define APUMMU_VSID_SEGMENT_08_RESV_SHIFT	(17)
202 
203 #define APUMMU_VSID_SEGMENT_08_DOMAIN(domain) \
204 	(((domain) & APUMMU_VSID_SEGMENT_08_DOMAIN_MASK) << APUMMU_VSID_SEGMENT_08_DOMAIN_SHIFT)
205 #define APUMMU_VSID_SEGMENT_08_RESV(resv) \
206 	(((resv) & APUMMU_VSID_SEGMENT_08_RESV_MASK) << APUMMU_VSID_SEGMENT_08_RESV_SHIFT)
207 
208 #define APUMMU_VSID_SEGMENT_08_ACP_EN(acp_en)		(((acp_en) & 0x1) << 12)
209 #define APUMMU_VSID_SEGMENT_08_AR_EXCLU(ar_exclu)	(((ar_exclu) & 0x1) << 9)
210 #define APUMMU_VSID_SEGMENT_08_AR_SEPCU(ar_sepcu)	(((ar_sepcu) & 0x1) << 8)
211 #define APUMMU_VSID_SEGMENT_08_AR_SLB_EN(ar_slb_en)	(((ar_slb_en) & 0x1) << 2)
212 #define APUMMU_VSID_SEGMENT_08_AR_SLC_EN(ar_slc_en)	(((ar_slc_en) & 0x1) << 3)
213 #define APUMMU_VSID_SEGMENT_08_AW_CLR(aw_clr)		(((aw_clr) & 0x1) << 11)
214 #define APUMMU_VSID_SEGMENT_08_AW_INVALID(aw_invalid)	(((aw_invalid) & 0x1) << 10)
215 #define APUMMU_VSID_SEGMENT_08_AW_SLB_EN(aw_slb_en)	(((aw_slb_en) & 0x1) << 5)
216 #define APUMMU_VSID_SEGMENT_08_AW_SLC_EN(aw_slc_en)	(((aw_slc_en) & 0x1) << 6)
217 #define APUMMU_VSID_SEGMENT_08_NS(ns)			(((ns) & 0x1) << 0)
218 #define APUMMU_VSID_SEGMENT_08_RO(ro)			(((ro) & 0x1) << 1)
219 
220 #define APUMMU_VSID_SEGMENT_08_AR_CACHE_ALLOCATE(ar_cache_allocate) \
221 	(((ar_cache_allocate) & 0x1) << 4)
222 #define APUMMU_VSID_SEGMENT_08_AW_CACHE_ALLOCATE(aw_cache_allocate) \
223 	(((aw_cache_allocate) & 0x1) << 7)
224 
225 #define APUMMU_BUILD_SEGMENT_OFFSET2(resv, domain, acp_en, aw_clr, \
226 		aw_invalid, ar_exclu, ar_sepcu, \
227 		aw_cache_allocate, aw_slc_en, aw_slb_en, ar_cache_allocate, \
228 		ar_slc_en, ar_slb_en, ro, ns) \
229 		((APUMMU_VSID_SEGMENT_08_RESV(resv)) |\
230 		 (APUMMU_VSID_SEGMENT_08_DOMAIN(domain)) |\
231 		 (APUMMU_VSID_SEGMENT_08_ACP_EN(acp_en)) |\
232 		 (APUMMU_VSID_SEGMENT_08_AW_CLR(aw_clr)) |\
233 		 (APUMMU_VSID_SEGMENT_08_AW_INVALID(aw_invalid)) |\
234 		 (APUMMU_VSID_SEGMENT_08_AR_EXCLU(ar_exclu)) |\
235 		 (APUMMU_VSID_SEGMENT_08_AR_SEPCU(ar_sepcu)) |\
236 		 (APUMMU_VSID_SEGMENT_08_AW_CACHE_ALLOCATE(aw_cache_allocate)) |\
237 		 (APUMMU_VSID_SEGMENT_08_AW_SLC_EN(aw_slc_en)) |\
238 		 (APUMMU_VSID_SEGMENT_08_AW_SLB_EN(aw_slb_en)) |\
239 		 (APUMMU_VSID_SEGMENT_08_AR_CACHE_ALLOCATE(ar_cache_allocate)) |\
240 		 (APUMMU_VSID_SEGMENT_08_AR_SLC_EN(ar_slc_en)) |\
241 		 (APUMMU_VSID_SEGMENT_08_AR_SLB_EN(ar_slb_en)) |\
242 		 (APUMMU_VSID_SEGMENT_08_RO(ro)) | (APUMMU_VSID_SEGMENT_08_NS(ns)))
243 
244 /* Build segment offset 3 (0x0c) data */
245 #define APUMMU_VSID_SEGMENT_0C_RESV(rsv)		(((rsv) & 0x7fffffff) << 0)
246 #define APUMMU_VSID_SEGMENT_0C_SEG_VALID(seg_valid)	(((seg_valid) & 0x1U) << 31)
247 #define APUMMU_BUILD_SEGMENT_OFFSET3(seg_valid, rsv) \
248 	((uint32_t)APUMMU_VSID_SEGMENT_0C_SEG_VALID(seg_valid) | \
249 	 APUMMU_VSID_SEGMENT_0C_RESV(rsv))
250 
251 #define APUMMU_INT_D2T_TBL0_OFS	(0x40)
252 
253 #define APUSYS_TCM		(0x4d100000)
254 
255 enum {
256 	APUMMU_THD_ID_APMCU_NORMAL = 0,
257 	APUMMU_THD_ID_TEE,
258 };
259 
260 int rv_boot(uint32_t uP_seg_output, uint8_t uP_hw_thread,
261 	    enum apummu_page_size logger_page_size, uint32_t XPU_seg_output,
262 	    enum apummu_page_size XPU_page_size);
263 
264 #endif
265