1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2019-2021, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "juno_id.h"
9 #include "juno_scc.h"
10 #include "v2m_sys_regs.h"
11 
12 #include <fwk_assert.h>
13 #include <fwk_status.h>
14 
15 #include <stddef.h>
16 
17 /* SYS_ID Rev Field description */
18 enum juno_id_board_rev {
19     JUNO_BOARD_REV_A_SOC_R0 = 0,
20     JUNO_BOARD_REV_B_SOC_R0,
21     JUNO_BOARD_REV_C_SOC_R1,
22     JUNO_BOARD_REV_D_SOC_R2,
23     JUNO_BOARD_REV_COUNT,
24 };
25 
juno_id_get_platform(enum juno_idx_platform * platform)26 int juno_id_get_platform(enum juno_idx_platform *platform)
27 {
28     unsigned int plat;
29 
30     if (!fwk_expect(platform != NULL)) {
31         return FWK_E_PARAM;
32     }
33 
34     plat = (SCC->GPR0 & SCC_GPR0_PLATFORM_ID_PLAT) >>
35         SCC_GPR0_PLATFORM_ID_PLAT_POS;
36 
37     if (plat >= JUNO_IDX_PLATFORM_COUNT) {
38         /*
39          * The GPR0 register has been configured with an invalid platform
40          * index.
41          */
42         return FWK_E_DATA;
43     }
44 
45     *platform = (enum juno_idx_platform)plat;
46 
47     return FWK_SUCCESS;
48 }
49 
juno_id_get_revision(enum juno_idx_revision * revision)50 int juno_id_get_revision(enum juno_idx_revision *revision)
51 {
52     static enum juno_idx_revision revision_cached = JUNO_IDX_REVISION_COUNT;
53     enum juno_idx_platform platform;
54     unsigned int board_rev;
55     int status = FWK_SUCCESS;
56 
57     if (revision == NULL) {
58         status = FWK_E_PARAM;
59         goto exit;
60     }
61 
62     if (revision_cached != JUNO_IDX_REVISION_COUNT) {
63         *revision = revision_cached;
64 
65         goto exit;
66     }
67 
68     status = juno_id_get_platform(&platform);
69     if (status != FWK_SUCCESS) {
70         goto exit;
71     }
72 
73     if (platform != JUNO_IDX_PLATFORM_RTL) {
74         revision_cached = JUNO_IDX_REVISION_R0;
75         *revision = revision_cached;
76 
77         goto exit;
78     }
79 
80     /* NOTE: SYSTOP must be powered ON for this register to be accessible. */
81     board_rev = V2M_SYS_REGS->ID >> V2M_SYS_REGS_ID_REV_POS;
82 
83     if (board_rev == JUNO_BOARD_REV_A_SOC_R0) {
84         status = FWK_E_SUPPORT;
85 
86         goto exit;
87     }
88 
89     if (board_rev >= JUNO_BOARD_REV_COUNT) {
90         status = FWK_E_PANIC;
91 
92         goto exit;
93     }
94 
95     revision_cached = (enum juno_idx_revision)(board_rev - 1);
96     *revision = revision_cached;
97 
98 exit:
99     fwk_check(status == FWK_SUCCESS);
100 
101     return status;
102 }
103 
juno_id_get_variant(enum juno_idx_variant * variant)104 int juno_id_get_variant(enum juno_idx_variant *variant)
105 {
106     static enum juno_idx_variant variant_cached = JUNO_IDX_VARIANT_COUNT;
107     enum juno_idx_platform platform;
108     unsigned int var;
109     int status;
110 
111     if (!fwk_expect(variant != NULL)) {
112         return FWK_E_PARAM;
113     }
114 
115     if (variant_cached != JUNO_IDX_VARIANT_COUNT) {
116         *variant = variant_cached;
117 
118         return FWK_SUCCESS;
119     }
120 
121     status = juno_id_get_platform(&platform);
122     if (status != FWK_SUCCESS) {
123         return FWK_E_PANIC;
124     }
125 
126     if (platform != JUNO_IDX_PLATFORM_RTL) {
127         variant_cached = JUNO_IDX_VARIANT_A;
128         *variant = variant_cached;
129 
130         return FWK_SUCCESS;
131     }
132 
133     /* NOTE: SYSTOP must be powered ON for this register to be accessible. */
134     var = (V2M_SYS_REGS->ID & (uint32_t)V2M_SYS_REGS_ID_VAR_MASK) >>
135         V2M_SYS_REGS_ID_VAR_POS;
136 
137     if (!fwk_expect(var < JUNO_IDX_VARIANT_COUNT)) {
138         return FWK_E_DATA;
139     }
140 
141     variant_cached = (enum juno_idx_variant)var;
142     *variant = variant_cached;
143 
144     return FWK_SUCCESS;
145 }
146