1 /*
2 * Routines to access hardware
3 *
4 * Copyright (c) 2013 Realtek Semiconductor Corp.
5 *
6 * This module is a confidential and proprietary property of RealTek and
7 * possession or use of this module requires written permission of RealTek.
8 */
9
10 #include "ameba_soc.h"
11
12 static FlashInfo_TypeDef *current_IC;
13
14 /* Flag to check configuration register or not. Necessary for wide-range VCC MXIC flash */
15 static u8 check_config_reg = 0;
16
17 extern FlashInfo_TypeDef Flash_AVL[];
18 extern u16 Flash_ReadMode;
19 extern u16 Flash_Speed;
20
21
22 IMAGE2_RAM_TEXT_SECTION
_flash_calibration_highspeed(u8 SpicBitMode,u8 div)23 BOOL _flash_calibration_highspeed(u8 SpicBitMode, u8 div)
24 {
25 u32 window_size = 0;
26 u32 phase_shift_idx = 0;
27 u32 line_delay = 0;
28 u32 line_delay_temp = 0;
29 u32 window_temp = 0;
30 u32 window_size_temp = 0;
31 //u32 window_start_temp = 0;
32 //u32 window_end_temp = 0;
33
34 /* init last point before calibration */
35 FLASH_CalibrationInit(30);
36
37 /* 4.808 ms take when enter this function */
38 /* 511us will take for flash full calibration */
39 for (line_delay_temp = 1; line_delay_temp <= 5; line_delay_temp++) {
40 window_temp = FLASH_CalibrationNew(&flash_init_para, SpicBitMode, div, 2, line_delay_temp, 1);
41
42 window_size_temp = (window_temp & 0xFF);
43 //window_start_temp = ((window_temp >> 16) & 0xFF);
44 //window_end_temp = ((window_temp >> 24) & 0xFF);
45
46 if (flash_init_para.phase_shift_idx != 0) {
47 flash_init_para.phase_shift_idx |= BIT(0); /* odd is better */
48 }
49
50 //DBG_8195A("calibration_result:[%d:%d:%d][%x:%x] \n", line_delay_temp, window_size_temp, flash_init_para.phase_shift_idx,
51 // window_start_temp, window_end_temp);
52 //BKUP_Write(BKUP_REG3, ((window_start_temp << 24) | (line_delay_temp << 16) | (window_size_temp << 8) | flash_init_para.phase_shift_idx));
53
54 if (window_size_temp > window_size) {
55 window_size = window_size_temp;
56 line_delay = line_delay_temp;
57 phase_shift_idx = flash_init_para.phase_shift_idx;
58 }
59
60 flash_init_para.phase_shift_idx = 0;
61 }
62 if (window_size > 0) {
63 DBG_8195A("calibration_ok:[%d:%d:%d] \n", line_delay, window_size, phase_shift_idx);
64
65 flash_init_para.phase_shift_idx = phase_shift_idx;
66 flash_init_para.FLASH_rd_sample_phase_cal = line_delay;
67 flash_init_para.FLASH_rd_sample_phase = flash_init_para.FLASH_rd_sample_phase_cal;
68
69 return _TRUE;
70 } else {
71 flash_init_para.phase_shift_idx = 0;
72 flash_init_para.FLASH_rd_sample_phase = SPIC_LOWSPEED_SAMPLE_PHASE;
73 }
74
75 return _FALSE;
76 }
77
flash_calibration_backup(u8 flash_speed,u8 read_mode)78 void flash_calibration_backup(u8 flash_speed, u8 read_mode)
79 {
80 RRAM_TypeDef* RRAM = ((RRAM_TypeDef *) RRAM_BASE);
81
82 DBG_8195A("RRAM: %x %dB \n", RRAM_BASE, sizeof(RRAM_TypeDef));
83
84 RRAM->FLASH_ClockDiv = flash_speed;
85 RRAM->FLASH_ReadMode = read_mode;
86 RRAM->FLASH_phase_shift_idx = flash_init_para.phase_shift_idx;
87 RRAM->FLASH_rd_sample_phase_cal = flash_init_para.FLASH_rd_sample_phase;
88 RRAM->FLASH_cur_bitmode = flash_init_para.FLASH_cur_bitmode;
89
90 RRAM->FLASH_cur_cmd = flash_init_para.FLASH_cur_cmd;
91 RRAM->FALSH_quad_valid_cmd = flash_init_para.FALSH_quad_valid_cmd;
92 RRAM->FALSH_dual_valid_cmd = flash_init_para.FALSH_dual_valid_cmd;
93 RRAM->FLASH_pseudo_prm_en = flash_init_para.FLASH_pseudo_prm_en;
94 RRAM->FLASH_addr_phase_len = flash_init_para.FLASH_addr_phase_len;
95 RRAM->FLASH_cmd_wr_status2 = flash_init_para.FLASH_cmd_wr_status2;
96 RRAM->FLASH_QuadEn_bit = flash_init_para.FLASH_QuadEn_bit;
97
98 RRAM->FLASH_rd_dummy_cyle0 = flash_init_para.FLASH_rd_dummy_cyle[0];
99 RRAM->FLASH_rd_dummy_cyle1 = flash_init_para.FLASH_rd_dummy_cyle[1];
100 RRAM->FLASH_rd_dummy_cyle2 = flash_init_para.FLASH_rd_dummy_cyle[2];
101 }
102
103 IMAGE2_RAM_TEXT_SECTION
flash_calibration_highspeed(u8 div)104 u32 flash_calibration_highspeed(u8 div)
105 {
106 u32 Ret = _SUCCESS;
107 u8 spic_mode = flash_init_para.FLASH_cur_bitmode;
108
109
110 flash_init_para.debug = 0;
111
112 /* SPIC clock switch to PLL */
113 FLASH_ClockDiv(div);
114
115 if (_flash_calibration_highspeed(spic_mode, div) == _TRUE) {
116 /* we should open calibration new first, and then set phase index */
117 FLASH_CalibrationNewCmd(ENABLE);
118 FLASH_CalibrationPhaseIdx(flash_init_para.phase_shift_idx);
119
120 /* this code is rom code, so it is safe */
121 FLASH_Init(spic_mode);
122
123 DBG_8195A("FLASH CALIB[NEW OK]\n");
124 } else {
125 /* calibration fail, revert SPIC clock to XTAL */
126 RCC_PeriphClockSource_SPIC(BIT_SHIFT_FLASH_CLK_XTAL);
127
128 DBG_8195A("FLASH CALIB[NEW FAIL]\n");
129
130 Ret = _FAIL;
131 }
132
133
134 return Ret;
135 }
136
flash_get_option(u32 sys_data,BOOL is_speed)137 static u8 flash_get_option(u32 sys_data, BOOL is_speed)
138 {
139 u16 tmp = 0x8000;
140 u8 cnt = 0;
141
142 while(tmp){
143 if((sys_data & tmp) != 0){
144 break;
145 }else{
146 tmp = tmp >> 1;
147 cnt++;
148 }
149 }
150
151 if(is_speed) {
152 if(cnt == 0)
153 cnt = 1;
154 else if(cnt == 1)
155 cnt = 0;
156 else if(cnt > 4)
157 cnt = 4;
158 }
159
160 return cnt;
161 }
162
flash_get_chip_info(u32 flash_id)163 static FlashInfo_TypeDef *flash_get_chip_info(u32 flash_id)
164 {
165 u32 i = 0;
166 u32 temp;
167
168 while(Flash_AVL[i].flash_class != FlashClassNone) {
169 temp = flash_id & Flash_AVL[i].id_mask;
170 if(Flash_AVL[i].flash_id == temp)
171 return &Flash_AVL[i];
172
173 i++;
174 }
175
176 return NULL;
177 }
178
flash_get_vendor(void)179 static void flash_get_vendor(void)
180 {
181 RRAM_TypeDef* RRAM = ((RRAM_TypeDef *) RRAM_BASE);
182 u8 flash_ID[4];
183
184 /* Read flash ID */
185 FLASH_RxCmd(flash_init_para.FLASH_cmd_rd_id, 3, flash_ID);
186
187 DBG_8195A("Flash ID:%x, %x, %x\n", flash_ID[0], flash_ID[1], flash_ID[2]);
188
189 /* Get flash chip information */
190 current_IC = flash_get_chip_info((flash_ID[2] << 16) |(flash_ID[1] << 8) |flash_ID[0]);
191 if(current_IC == NULL) {
192 DBG_8195A("This flash type is not supported!\n");
193 assert_param(0);
194 }
195 RRAM->FLASH_class = current_IC->flash_class;
196 RRAM->FLASH_ID2 = flash_ID[2];
197
198 /* Re-initialize flash init structure according to classification */
199 switch (current_IC->flash_class) {
200 case FlashClass1:
201 FLASH_StructInit(&flash_init_para);
202 RRAM->FLASH_StructInit = (u32)FLASH_StructInit;
203 break;
204 case FlashClass2:
205 FLASH_StructInit_GD(&flash_init_para);
206 if(flash_ID[2] > 0x15) /* GD capacity more than 2MB */
207 flash_init_para.FLASH_cmd_wr_status2 = 0x31;
208 RRAM->FLASH_StructInit = (u32)FLASH_StructInit_GD;
209 break;
210 case FlashClass3:
211 FLASH_StructInit_MXIC(&flash_init_para);
212 RRAM->FLASH_StructInit = (u32)FLASH_StructInit_MXIC;
213 break;
214 case FlashClass4: /* EON without QE bit */
215 FLASH_StructInit_MXIC(&flash_init_para);
216 flash_init_para.FLASH_QuadEn_bit = 0;
217 RRAM->FLASH_StructInit = (u32)FLASH_StructInit_MXIC;
218 break;
219 case FlashClass5:
220 FLASH_StructInit_Micron(&flash_init_para);
221 RRAM->FLASH_StructInit = (u32)FLASH_StructInit_Micron;
222 break;
223 case FlashClass6: /* MXIC wide-range VCC chip */
224 FLASH_StructInit_MXIC(&flash_init_para);
225 check_config_reg = 1;
226 RRAM->FLASH_StructInit = (u32)FLASH_StructInit_MXIC;
227 break;
228 case FlashClassUser:
229 assert_param(current_IC->FlashInitHandler != NULL);
230 current_IC->FlashInitHandler();
231 RRAM->FLASH_StructInit = (u32)NULL;
232 break;
233 default:
234 break;
235 }
236
237 if(HAL_READ32(SYSTEM_CTRL_BASE_LP, REG_SYS_EFUSE_SYSCFG3) & BIT_SYS_SPIC_ADDR_4BYTE_EN)
238 flash_init_para.FLASH_addr_phase_len = ADDR_4_BYTE;
239
240 }
241
flash_set_status_register(void)242 static void flash_set_status_register(void)
243 {
244 u8 StatusLen = 1;
245 u32 data = 0;
246 u32 status;
247 u32 mask = current_IC->sta_mask;
248
249 if (flash_init_para.FLASH_QuadEn_bit !=0)
250 data |= flash_init_para.FLASH_QuadEn_bit;
251
252 /* read status1 register */
253 FLASH_RxCmd(flash_init_para.FLASH_cmd_rd_status, 1, (u8*)&status);
254
255 /* check if status2 exist */
256 if (flash_init_para.FLASH_Status2_exist) {
257 StatusLen = 2;
258 FLASH_RxCmd(flash_init_para.FLASH_cmd_rd_status2, 1, ((u8*)&status) + 1);
259
260 } else if (check_config_reg) { /* for MXIC wide-range flash, 1 status register + 2 config register */
261 /* Read configuration register */
262 FLASH_RxCmd(0x15, 2, ((u8*)&status) + 1);
263 StatusLen = 3;
264
265 /* L/H Switch */
266 data |= (BIT(9) << 8);
267 }
268
269 status &= mask;
270 if(_memcmp((void*)&status, (void*)&data, StatusLen)) {
271 if(!flash_init_para.FLASH_cmd_wr_status2) {
272 FLASH_SetStatus(flash_init_para.FLASH_cmd_wr_status, StatusLen, (u8*)&data);
273 } else {
274 FLASH_SetStatus(flash_init_para.FLASH_cmd_wr_status, 1, (u8*)&data);
275 FLASH_SetStatus(flash_init_para.FLASH_cmd_wr_status2, 1, ((u8*)&data) + 1);
276 }
277 }
278 }
279
280 IMAGE2_RAM_TEXT_SECTION
flash_rx_mode_switch(u8 read_mode)281 u32 flash_rx_mode_switch(u8 read_mode)
282 {
283 u32 Ret = _SUCCESS;
284 u8 tmp_dc = 0, status = 0, spic_mode = 0, i;
285 u32 pdata[2];
286
287 for(i = read_mode; i < 5; i++) {
288 if(i == ReadQuadIOMode){
289 flash_init_para.FLASH_pseudo_prm_en = 1;
290 flash_init_para.FALSH_quad_valid_cmd = (BIT_WR_BLOCKING | BIT_RD_QUAD_IO | BIT_PRM_EN);
291
292 tmp_dc = flash_init_para.FLASH_rd_dummy_cyle[2];
293 flash_init_para.FLASH_rd_dummy_cyle[2] -= QUAD_PRM_CYCLE_NUM;
294
295 spic_mode = SpicQuadBitMode;
296 flash_init_para.FLASH_cur_cmd = FLASH_CMD_4READ;
297
298 }else if(i == ReadQuadOMode){
299 flash_init_para.FLASH_pseudo_prm_en = 0;
300 flash_init_para.FALSH_quad_valid_cmd = (BIT_WR_BLOCKING | BIT_RD_QUAD_O);
301
302 flash_init_para.FLASH_rd_dummy_cyle[2] = FLASH_DM_CYCLE_4O;
303 tmp_dc = flash_init_para.FLASH_rd_dummy_cyle[2];
304
305 spic_mode = SpicQuadBitMode;
306 flash_init_para.FLASH_cur_cmd = FLASH_CMD_QREAD;
307
308 }else if(i == ReadDualIOMode){
309 flash_init_para.FLASH_pseudo_prm_en = 1;
310 flash_init_para.FALSH_dual_valid_cmd = (BIT_WR_BLOCKING |BIT_FRD_SINGEL | BIT_CTRLR0_CH | BIT_PRM_EN);
311
312 tmp_dc = flash_init_para.FLASH_rd_dummy_cyle[1];
313 flash_init_para.FLASH_rd_dummy_cyle[1] -= DUAL_PRM_CYCLE_NUM;
314
315 spic_mode = SpicDualBitMode;
316 flash_init_para.FLASH_cur_cmd = FLASH_CMD_2READ;
317
318 }else if(i == ReadDualOMode){
319 flash_init_para.FLASH_pseudo_prm_en = 0;
320 flash_init_para.FALSH_dual_valid_cmd = (BIT_WR_BLOCKING | BIT_RD_DUAL_I);
321
322 flash_init_para.FLASH_rd_dummy_cyle[1] = FLASH_DM_CYCLE_2O;
323 tmp_dc = flash_init_para.FLASH_rd_dummy_cyle[1];
324
325 spic_mode = SpicDualBitMode;
326 flash_init_para.FLASH_cur_cmd = FLASH_CMD_DREAD;
327 }else{
328 flash_init_para.FLASH_pseudo_prm_en = 0;
329
330 tmp_dc = flash_init_para.FLASH_rd_dummy_cyle[0];
331 spic_mode = SpicOneBitMode;
332 flash_init_para.FLASH_cur_cmd = FLASH_CMD_READ;
333 }
334
335 if(flash_init_para.FLASH_Id == FLASH_ID_MICRON){
336 FLASH_RxCmd(0x85, 1, &status);
337
338 status = (status & 0x0f) | (tmp_dc << 4);
339 FLASH_SetStatus(0x81, 1, &status);
340 }
341
342 flash_init_para.FLASH_rd_sample_phase = SPIC_LOWSPEED_SAMPLE_PHASE;
343 FLASH_Init(spic_mode);
344
345 DCache_Invalidate(SPI_FLASH_BASE, 8);
346 pdata[0] = HAL_READ32(SPI_FLASH_BASE, 0x00);
347 pdata[1] = HAL_READ32(SPI_FLASH_BASE, 0x04);
348
349 if(_memcmp(pdata, SPIC_CALIB_PATTERN, 8) == 0) {
350 DBG_8195A("read_mode:%d\n", i);
351 break;
352 } else {
353 if(flash_init_para.debug)
354 DBG_8195A("read mode %d fail\n", i);
355 }
356 }
357
358 if(i == 5) {
359 DBG_8195A("Flash read mode switch FAIL!\n");
360 Ret = _FAIL;
361 }
362
363 return Ret;
364 }
365
flash_operation_config(void)366 void flash_operation_config(void)
367 {
368 u8 read_mode;
369 u8 flash_speed;
370
371 if (SOCPS_DsleepWakeStatusGet() == TRUE) {
372 return;
373 }
374
375 read_mode = flash_get_option(Flash_ReadMode, _FALSE);
376 flash_speed = flash_get_option(Flash_Speed, _TRUE);
377 //DBG_8195A("flash_speed: %d\n", flash_speed);
378 __asm volatile( "cpsid i" );
379 /* Get flash ID to reinitialize FLASH_InitTypeDef structure */
380 flash_get_vendor();
381
382 /* Set flash status register: set QE, clear protection bits */
383 if (SOCPS_DsleepWakeStatusGet() == FALSE) {
384 flash_set_status_register();
385 }
386
387 /* Set flash I/O mode and high-speed calibration */
388 flash_rx_mode_switch(read_mode);
389 flash_calibration_highspeed(flash_speed);
390 flash_calibration_backup(flash_speed, read_mode);
391 __asm volatile( "cpsie i" );
392 }
393
394