blob: 7144f331be7b5207bebf9f4e14b0f7c424218e7c [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001#include <common.h>
2#include <config.h>
3#include <ubi_uboot.h>
4#include <asm/arch/cpu.h>
5#include <asm/io.h>
6#include <malloc.h>
7#include "asr_geu.h"
8#include "asr_fuse.h"
9
10struct efuse_data efuse_data;
11
12static uint32_t fuse_bank0_read32(uint32_t word)
13{
14 uint32_t value = 0;
15 switch(word)
16 {
17 case 0:
18 //CP config[15:0]
19 value = (geu_read32(GEU_FUSE_APCFG3) >> 16)& 0xFFFF;
20 //AP config[15:0]
21 value |= (geu_read32(GEU_FUSE_APCFG1) & 0xFFFF) << 16;
22 break;
23 case 1:
24 //AP config[31:16]
25 value = (geu_read32(GEU_FUSE_APCFG1) >> 16)& 0xFFFF;
26 //AP config[47:32]
27 value |= (geu_read32(GEU_FUSE_APCFG2) & 0xFFFF)<< 16;
28 break;
29 case 2:
30 //AP config[63:48]
31 value = (geu_read32(GEU_FUSE_APCFG2) >> 16) & 0xFFFF;
32 //AP config[79:64]
33 value |= (geu_read32(GEU_FUSE_APCFG3) & 0xFFFF)<< 16;
34 break;
35 case 3:
36 value = geu_read32(GEU_FUSE_BANK0_127_96);
37 break;
38 case 4:
39 value = geu_read32(GEU_FUSE_BANK0_159_128);
40 break;
41 case 5:
42 value = geu_read32(GEU_FUSE_BANK0_191_160);
43 break;
44 case 6:
45 value = (geu_read32(GEU_FUSE_BANK0_239_208) & 0xFFFF) << 16;
46 value |= geu_read32(GEU_FUSE_BANK0_207_192) & 0xFFFF;
47 break;
48 case 7:
49 value = (geu_read32(GEU_FUSE_BANK0_255_240) &0xFFFF) << 16;
50 value |= (geu_read32(GEU_FUSE_BANK0_239_208) >> 16) & 0xFFFF;
51 break;
52 default:
53 printf("Read wrong word of bank0");
54 break;
55 }
56 return value;
57}
58
59static uint32_t fuse_bank1_read32(uint32_t word)
60{
61 uint32_t value;
62 if( word > 7 )
63 printf("Read wrong word of bank1");
64
65 value = geu_read32(GEU_FUSE_VAL_ROOT_KEY(word));
66
67 return value;
68}
69
70static uint32_t fuse_bank2_read32(uint32_t word)
71{
72 uint32_t value;
73 if( word > 7 )
74 printf("Read wrong word of bank2");
75
76 value = geu_read32(GEU_FUSE_VAL_OEM_HASH_KEY(word));
77
78 return value;
79}
80
81static int fuse_bank3_read32(uint32_t word)
82{
83 uint32_t value = 0;
84 switch(word)
85 {
86 case 0 ... 5:
87 value = geu_read32(GEU_BLOCK3_RESERVED(word));
88 break;
89 case 6:
90 value = geu_read32(GEU_FUSE_BANK3_223_192);
91 break;
92 case 7:
93 value = geu_read32(GEU_FUSE_BANK3_255_224);
94 break;
95 default:
96 printf("Read wrong word of bank2");
97 break;
98 }
99 return value;
100}
101
102int fuse_bank_read(uint32_t bank, uint8_t *buffer)
103{
104 uint32_t (*bank_read)(uint32_t);
105 uint32_t word[EFUSE_BANK_LEN_IN_WORD];
106 bank_read = fuse_bank0_read32;
107 switch(bank) {
108 case 0:
109 bank_read = fuse_bank0_read32;
110 break;
111 case 1:
112 bank_read = fuse_bank1_read32;
113 break;
114 case 2:
115 bank_read = fuse_bank2_read32;
116 break;
117 case 3:
118 bank_read = fuse_bank3_read32;
119 break;
120 default:
121 return -1;
122 }
123 for(int i = 0; i < EFUSE_BANK_LEN_IN_WORD; i++)
124 word[i] = bank_read(i);
125 memcpy(buffer, word, EFUSE_BANK_LEN_IN_BYTE);
126 return 0;
127}
128
129int asr_rkek_burned(void)
130{
131 uint32_t val;
132
133 /* If RKEK is burned, SW access to it must be disabled as well */
134 if (cpu_is_asr1901() || cpu_is_asr1906()) {
135 /* check if LCS_DM is burned */
136 val = geu_read32(GEU_KSTR_BANK6_LCS);
137 val >>= GEU_KSTR_LCS_DM_BASE;
138 val &= GEU_KSTR_LCS_MASK;
139 if (hweight32(val) > 1)
140 return 1;
141 } else { /* 1803, 1806, 1828, 1903 */
142 /* check if secure key access disable is burned */
143 val = geu_read32(GEU_FUSE_APCFG2);
144 if (val & GEU_SECURE_KEY_ACCESS_DISABLED)
145 return 1;
146 }
147
148 return 0;
149}
150
151int fuse_get_sim_lock(int *sim_lock)
152{
153 uint32_t value;
154
155 geu_enable_clk();
156 value = geu_read32(GEU_FUSE_APCFG1);
157 if(cpu_is_asr1826s() || cpu_is_asr1806() ||
158 cpu_is_asr1803() || cpu_is_asr1903()) {
159 value &= 1;
160 } else if (cpu_is_asr1901() || cpu_is_asr1906()) {
161 value = geu_read32(GEU_FUSE_WORD_BANK0);
162 value &= (1 << 23); /* bit23: sim lock */
163 value = (value) ? 1:0;
164 } else {
165 printf("sim lock is not supported by this platform\n");
166 value = -1;
167 }
168
169 *sim_lock = value;
170
171 geu_disable_clk();
172 return 0;
173}
174
175void geu_fuse_test(void)
176{
177 uint8_t bank_buf[EFUSE_BANK_LEN_IN_BYTE];
178 memset(bank_buf, 0, EFUSE_BANK_LEN_IN_BYTE);
179
180 for (uint32_t bank = 0; bank < 4; bank++) {
181 if (0 > fuse_bank_read(bank, bank_buf)) {
182 printf("fuse back bank read failed\n");
183 goto err;
184 }
185 for (uint32_t i = 0; i < EFUSE_BANK_LEN_IN_BYTE; i++) {
186 printf("%.2x", bank_buf[i]);
187 if ((i+1) % 4 == 0)
188 printf(" ");
189 }
190 printf("\n");
191 }
192 return;
193err:
194 return;
195}