• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 // Copyright (C) 2022 Beken Corporation
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <common/bk_include.h>
16 #include "bk_arm_arch.h"
17 #include <common/sys_config.h>
18 #include "flash_bypass.h"
19 #include "sys_driver.h"
20 #include "gpio_driver.h"
21 #include <driver/spi.h>
22 #include "spi_hal.h"
23 
flash_bypass_init(void)24 void flash_bypass_init(void) {
25 	char *text_ptr, temp_buf = 0;
26 	uint32_t reg;
27 
28 	/*step 2, resident cache*/
29 	REG_WRITE(SPI_R_CTRL(0), 0);
30 	do {
31 		text_ptr = (char *)flash_bypass_quad_enable;
32 		for (uint32_t i = 0; i < CURRENT_ROUTINE_TEXT_SIZE; i ++)
33 			temp_buf += text_ptr[i];
34 
35 		REG_WRITE(SPI_R_INT_STATUS(0), temp_buf);
36 	} while (0);
37 
38 	/*step 3, config spi master*/
39 	/*  clear spi status*/
40 	REG_WRITE(SPI_R_CTRL(0), 0);
41 	reg = REG_READ(SPI_R_INT_STATUS(0));
42 	REG_WRITE(SPI_R_INT_STATUS(0), reg);
43 	REG_WRITE(SPI_R_CFG(0), 0);
44 
45 	spi_config_t config = {0};
46 	config.role = SPI_ROLE_MASTER;
47 	config.bit_width = SPI_BIT_WIDTH_8BITS;
48 	config.polarity = 1;
49 	config.phase = 1;
50 	config.wire_mode = SPI_4WIRE_MODE;
51 	config.baud_rate = 1000000;
52 	config.bit_order = SPI_MSB_FIRST;
53 	bk_spi_driver_init();
54 	bk_spi_init(0, &config);
55 
56 	/*step 4, gpioi of SPI0 are set as high-impedance state or input state ,
57 	          for spi mux with them*/
58 	gpio_dev_unmap(SPI0_LL_CSN_PIN);
59 	gpio_dev_unmap(SPI0_LL_SCK_PIN);
60 	gpio_dev_unmap(SPI0_LL_MOSI_PIN);
61 	gpio_dev_unmap(SPI0_LL_MISO_PIN);
62 }
63 
flash_bypass_quad_enable(void)64 __attribute__((section(".itcm_sec_code"))) void flash_bypass_quad_enable(void)
65 {
66 	uint32_t reg;
67 	uint32_t reg_ctrl, reg_dat;
68 	uint32_t reg_stat, reg_cfg;
69 	uint32_t int_status = 0;
70 	uint32_t spi_status = 0;
71 	volatile uint32_t i, j, delay_count;
72 
73 	int_status =  rtos_disable_int();
74 
75 	/*step 1, save spi register configuration*/
76 	reg_ctrl = REG_READ(SPI_R_CTRL(0));
77 	reg_stat = REG_READ(SPI_R_INT_STATUS(0));
78 	reg_dat  = REG_READ(SPI_R_DATA(0));
79 	reg_cfg  = REG_READ(SPI_R_CFG(0));
80 
81 	flash_bypass_init();
82 
83 	/*step 5, switch flash interface to spi
84 	 *        Pay attention to prefetch instruction destination, the text can not
85 	 *        fetch from flash space after this timepoint.
86 	 */
87 	sys_drv_set_cpu_storage_connect_op_select_flash_sel(1);
88 
89 	/*step 6, write enable for status register: 06H*/
90 	reg = REG_READ(SPI_R_INT_STATUS(0));
91 	REG_WRITE(SPI_R_INT_STATUS(0), reg);
92 	REG_WRITE(SPI_R_CFG(0), SPI_CFG_TX_EN_ONE_BYTE);
93 	REG_WRITE(SPI_R_DATA(0), FLASH_CMD_WR_EN_SR);
94 
95 	/*step 7, write cmd 31H, data 0x02*/
96 	for(i = 0; i < 500; i++) {
97 		spi_status = REG_READ(SPI_R_INT_STATUS(0));
98 		if(0 != (spi_status & SPI_STATUS_TX_FINISH_INT)) {
99 			break;
100 		}
101 	}
102 	for(delay_count = 0; delay_count < 20000; delay_count ++)
103 	{
104 		for(j = 0; j < 8; j ++)
105 		;
106 	}
107 
108 	REG_WRITE(SPI_R_CFG(0), 0);
109 	reg = REG_READ(SPI_R_INT_STATUS(0));
110 	REG_WRITE(SPI_R_INT_STATUS(0), reg);
111 
112 	REG_WRITE(SPI_R_CFG(0), SPI_CFG_TX_EN_TWO_BYTE);
113 	REG_WRITE(SPI_R_DATA(0), FLASH_CMD_WR_SR);
114 	REG_WRITE(SPI_R_DATA(0), FLASH_GD25Q32C_SR_QUAD_EN);
115 
116 	for(i = 0; i < 500; i++) {
117 		spi_status = REG_READ(SPI_R_INT_STATUS(0));
118 		if(0 != (spi_status & SPI_STATUS_TX_FINISH_INT)) {
119 			break;
120 		}
121 	}
122 	for(delay_count = 0; delay_count < 20000; delay_count ++)
123 	{
124 		for(j = 0; j < 8; j ++)
125 		;
126 	}
127 	REG_WRITE(SPI_R_CFG(0), 0);
128 	reg = REG_READ(SPI_R_INT_STATUS(0));
129 	REG_WRITE(SPI_R_INT_STATUS(0), reg);
130 
131 	/*step 8, switch flash interface to flash controller */
132 	sys_drv_set_cpu_storage_connect_op_select_flash_sel(0);
133 
134 	/*step 9, restore spi register configuration*/
135 	REG_WRITE(SPI_R_CTRL(0), reg_ctrl);
136 	REG_WRITE(SPI_R_INT_STATUS(0), reg_stat);
137 	REG_WRITE(SPI_R_DATA(0), reg_dat);
138 	REG_WRITE(SPI_R_CFG(0), reg_cfg);
139 	rtos_enable_int(int_status);
140 }
141 
142 
flash_bypass_quad_test(uint32_t quad_enable,uint32_t delay_cycle1,uint32_t delay_cycle2)143 __attribute__((section(".itcm_sec_code"))) void flash_bypass_quad_test(uint32_t quad_enable, uint32_t delay_cycle1, uint32_t delay_cycle2)
144 {
145 	uint32_t reg;
146 	uint32_t reg_ctrl, reg_dat;
147 	uint32_t reg_stat, reg_cfg;
148 	uint32_t int_status = 0;
149 	uint32_t spi_status = 0;
150 	volatile uint32_t i, j, delay_count;
151 
152 	int_status =  rtos_disable_int();
153 
154 	/*step 1, save spi register configuration*/
155 	reg_ctrl = REG_READ(SPI_R_CTRL(0));
156 	reg_stat = REG_READ(SPI_R_INT_STATUS(0));
157 	reg_dat  = REG_READ(SPI_R_DATA(0));
158 	reg_cfg  = REG_READ(SPI_R_CFG(0));
159 
160 	flash_bypass_init();
161 
162 	/*step 5, switch flash interface to spi
163 	 *        Pay attention to prefetch instruction destination, the text can not
164 	 *        fetch from flash space after this timepoint.
165 	 */
166 	sys_drv_set_cpu_storage_connect_op_select_flash_sel(1);
167 
168 	/*step 6, write enable for status register: 06H*/
169 	reg = REG_READ(SPI_R_INT_STATUS(0));
170 	REG_WRITE(SPI_R_INT_STATUS(0), reg);
171 	REG_WRITE(SPI_R_CFG(0), SPI_CFG_TX_EN_ONE_BYTE);
172 	REG_WRITE(SPI_R_DATA(0), FLASH_CMD_WR_EN_SR);
173 
174 	/*step 7, write cmd 31H, data 0x02*/
175 	for(i = 0; i < delay_cycle1; i++) {
176 		spi_status = REG_READ(SPI_R_INT_STATUS(0));
177 		if(0 != (spi_status & SPI_STATUS_TX_FINISH_INT)) {
178 			break;
179 		}
180 	}
181 	for(delay_count = 0; delay_count < delay_cycle2; delay_count ++)
182 	{
183 		for(j = 0; j < 8; j ++)
184 		;
185 	}
186 
187 	REG_WRITE(SPI_R_CFG(0), 0);
188 	reg = REG_READ(SPI_R_INT_STATUS(0));
189 	REG_WRITE(SPI_R_INT_STATUS(0), reg);
190 
191 	REG_WRITE(SPI_R_CFG(0), SPI_CFG_TX_EN_TWO_BYTE);
192 	REG_WRITE(SPI_R_DATA(0), FLASH_CMD_WR_SR);
193 	if (quad_enable) {
194 		REG_WRITE(SPI_R_DATA(0), FLASH_GD25Q32C_SR_QUAD_EN);
195 	} else {
196 		REG_WRITE(SPI_R_DATA(0), 0);
197 	}
198 
199 	for(i = 0; i < delay_cycle1; i++) {
200 		spi_status = REG_READ(SPI_R_INT_STATUS(0));
201 		if(0 != (spi_status & SPI_STATUS_TX_FINISH_INT)) {
202 			break;
203 		}
204 	}
205 	for(delay_count = 0; delay_count < delay_cycle2; delay_count ++)
206 	{
207 		for(j = 0; j < 8; j ++)
208 		;
209 	}
210 	REG_WRITE(SPI_R_CFG(0), 0);
211 	reg = REG_READ(SPI_R_INT_STATUS(0));
212 	REG_WRITE(SPI_R_INT_STATUS(0), reg);
213 
214 	/*step 8, switch flash interface to flash controller */
215 	sys_drv_set_cpu_storage_connect_op_select_flash_sel(0);
216 
217 	/*step 9, restore spi register configuration*/
218 	REG_WRITE(SPI_R_CTRL(0), reg_ctrl);
219 	REG_WRITE(SPI_R_INT_STATUS(0), reg_stat);
220 	REG_WRITE(SPI_R_DATA(0), reg_dat);
221 	REG_WRITE(SPI_R_CFG(0), reg_cfg);
222 	rtos_enable_int(int_status);
223 }
224