xref: /rk3399_ARM-atf/plat/amd/versal2/plat_ocm_coherency.c (revision 3b06438dd1e038a7453d3b812ca6ef2da54f6ba8)
1 /*
2  * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 #include <common/debug.h>
7 #include <lib/mmio.h>
8 
9 #include <plat_ocm_coherency.h>
10 #include <platform_def.h>
11 
12 /*
13  * Register non hash mem regions addresses
14  */
15 #define POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12    U(0xF8168000)
16 #define NON_HASH_MEM_REGION_REG0        U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC08)
17 #define NON_HASH_MEM_REGION_REG1        U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC0C)
18 #define NON_HASH_MEM_REGION_REG2        U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC10)
19 #define NON_HASH_MEM_REGION_REG3        U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC14)
20 #define NON_HASH_MEM_REGION_REG4        U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC18)
21 #define NON_HASH_MEM_REGION_REG5        U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC1C)
22 #define NON_HASH_MEM_REGION_REG6        U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC20)
23 #define NON_HASH_MEM_REGION_REG7        U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC24)
24 
25 #define REGION_BASE_ADDR_VALUE	U(0x2E)
26 #define REGION_BASE_ADDR_SHIFT	9
27 
28 #define REGION_BASE_ADDRESS_MASK	GENMASK(30, REGION_BASE_ADDR_SHIFT)
29 #define REGION_VALID_BIT		BIT(0)
30 
31 /*
32  * verify the register configured as non-hashed
33  */
34 #define IS_NON_HASHED_REGION(reg) \
35 ((FIELD_GET(REGION_BASE_ADDRESS_MASK, mmio_read_32(reg)) == REGION_BASE_ADDR_VALUE) && \
36 						(mmio_read_32(reg) & REGION_VALID_BIT))
37 
38 /*
39  * Splitter registers
40  */
41 #define FPX_SPLITTER_0          U(0xECC20000)
42 #define FPX_SPLITTER_1          U(0xECD20000)
43 #define FPX_SPLITTER_2          U(0xECE20000)
44 #define FPX_SPLITTER_3          U(0xECF20000)
45 #define OCM_ADDR_DIST_MODE      BIT(16)
46 
47 #define OCM_COHERENT	0
48 #define OCM_NOT_COHERENT	1
49 #define TFA_NOT_IN_OCM	2
50 
51 /*
52  * Function that verifies the OCM is coherent or not with the following checks:
53  * verify that OCM is in non hashed region or not if not then verify
54  * OCM_ADDR_DIST_MODE bit in splitter registers is set.
55  */
56 int32_t check_ocm_coherency(void)
57 {
58 	int32_t status = OCM_COHERENT;
59 	/* isolation should be disabled in order to read these registers */
60 	if ((IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG0) ||
61 	     IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG1) ||
62 	     IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG2) ||
63 	     IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG3) ||
64 	     IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG4) ||
65 	     IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG5) ||
66 	     IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG6) ||
67 	     IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG7))) {
68 		WARN("OCM is not configured as coherent\n");
69 		status = OCM_NOT_COHERENT;
70 	} else {
71 		/* verify OCM_ADDR_DIST_MODE bit in splitter registers is set */
72 		if (!((mmio_read_32(FPX_SPLITTER_0) & OCM_ADDR_DIST_MODE) &&
73 		      (mmio_read_32(FPX_SPLITTER_1) & OCM_ADDR_DIST_MODE) &&
74 		      (mmio_read_32(FPX_SPLITTER_2) & OCM_ADDR_DIST_MODE) &&
75 		      (mmio_read_32(FPX_SPLITTER_3) & OCM_ADDR_DIST_MODE))) {
76 			WARN("OCM is not configured as coherent\n");
77 			status = OCM_NOT_COHERENT;
78 		}
79 	}
80 	return status;
81 }
82 
83