1 /*
2 * SPDX-FileCopyrightText: 2019-2025 SiFli Technologies(Nanjing) Co., Ltd
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "bf0_hal.h"
8
9 /** @addtogroup BF0_HAL_Driver
10 * @{
11 */
12
13 /** @defgroup PSRAM PSRAM
14 * @brief PSRAM HAL module driver
15 * @{
16 */
17 #if defined(HAL_PSRAM_MODULE_ENABLED)||defined(_SIFLI_DOXYGEN_)
18 #include "bf0_hal_psram.h"
19
HAL_PSRAM_Init(PSRAM_HandleTypeDef * hpsram)20 HAL_StatusTypeDef HAL_PSRAM_Init(PSRAM_HandleTypeDef *hpsram)
21 {
22 uint32_t temp;
23
24 if (hpsram == NULL)
25 return HAL_ERROR;
26
27 if (hpsram->State == HAL_PSRAM_STATE_READY) // initialized before.
28 return HAL_OK;
29
30 hpsram->Instance = PSRAM;
31 hpsram->State = HAL_PSRAM_STATE_READY;
32 hpsram->Lock = HAL_UNLOCKED;
33
34 HAL_RCC_HCPU_reset(HPSYS_RCC_RSTR1_PSRAMC, 1);
35 HAL_RCC_HCPU_reset(HPSYS_RCC_RSTR1_PSRAMC, 0);
36
37 HAL_RCC_HCPU_enable(HPSYS_RCC_ENR1_PSRAMC, 1);
38
39 //hpsram->Init.delay = ;
40
41 /* setting merge from simulation */
42 //set cre
43 hpsram->Instance->CRE = PSRAMC_CRE_CRE;
44
45 hpsram->Instance->PSRAM_CFG |= (0x3 << PSRAMC_PSRAM_CFG_PSRAM_DENSITY_Pos) ;
46
47 temp = hpsram->Instance->PSRAM_CFG;
48 if (hpsram->dual_psram)
49 {
50 MODIFY_REG(temp, PSRAMC_PSRAM_CFG_PACKAGE_TYPE_Msk,
51 PSRAMC_PSRAM_CFG_DUAL_PACKAGE_TYPE);
52 }
53 else
54 {
55 MODIFY_REG(temp, PSRAMC_PSRAM_CFG_PACKAGE_TYPE_Msk,
56 PSRAMC_PSRAM_CFG_SINGLE_PACKAGE_TYPE);
57 }
58
59 if (!hpsram->is_xccela)
60 {
61 temp &= ~PSRAMC_PSRAM_CFG_XCCELA_PSRAM_EN;
62 hpsram->Instance->CTRL_TIME &= ~PSRAMC_CTRL_TIME_W_TCPH;
63 hpsram->Instance->CTRL_TIME |= 0x6 << PSRAMC_CTRL_TIME_W_TCPH_Pos;
64 }
65
66 /* enable hold to improve performance */
67 temp |= PSRAMC_PSRAM_CFG_RD_HOLD_EN;
68 MODIFY_REG(temp, PSRAMC_PSRAM_CFG_TCE_MAX_LENGTH_Msk,
69 MAKE_REG_VAL(0xB0, PSRAMC_PSRAM_CFG_TCE_MAX_LENGTH_Msk, PSRAMC_PSRAM_CFG_TCE_MAX_LENGTH_Pos));
70
71 hpsram->Instance->PSRAM_CFG = temp;
72
73 //hpsram->Instance->DELAY_FINAL_ADD |= 0x15 << PSRAMC_DELAY_FINAL_ADD_DELAY_FINAL_ADD_DQS_I_Pos;
74 MODIFY_REG(hpsram->Instance->DELAY_FINAL_ADD, PSRAMC_DELAY_FINAL_ADD_DELAY_FINAL_ADD_DQS_I_Msk,
75 0x17 << PSRAMC_DELAY_FINAL_ADD_DELAY_FINAL_ADD_DQS_I_Pos);
76 if (!hpsram->is_xccela)
77 {
78 hpsram->Instance->DELAY_FINAL_ADD &= ~PSRAMC_DELAY_FINAL_ADD_DELAY_FINAL_ADD_CLK_Msk;
79 hpsram->Instance->DELAY_FINAL_ADD |= 0x5 << PSRAMC_DELAY_FINAL_ADD_DELAY_FINAL_ADD_CLK_Pos;
80 }
81
82 HAL_PSRAM_MspInit(hpsram);
83
84 //set read fifo depth trigger to 2
85 hpsram->Instance->READ_CTRL |= PSRAMC_READ_CTRL_RD_START_MODE;
86 hpsram->Instance->READ_CTRL &= ~PSRAMC_READ_CTRL_OPT_LENGTH_Msk;
87 hpsram->Instance->READ_CTRL |= 2 << PSRAMC_READ_CTRL_OPT_LENGTH_Pos;
88 hpsram->Instance->READ_CTRL &= ~PSRAMC_READ_CTRL_RD_START_NUM_Msk;
89 hpsram->Instance->READ_CTRL |= 1 << PSRAMC_READ_CTRL_RD_START_NUM_Pos;
90
91 // from psramc_tst_drv.c psramc_init setting
92 if (hpsram->is_xccela)
93 {
94 uint32_t rdata;
95 uint32_t tce_max = 0xf0; // FPGA: 0x30; //2us * 24M /// ASIC: 0xF0; //2us * 120M //XCLK default freq shall be set to 120M
96 hpsram->Instance->CTRL_TIME &= ~PSRAMC_CTRL_TIME_WL;
97 hpsram->Instance->PSRAM_CFG &= ~PSRAMC_PSRAM_CFG_TCE_MAX_LENGTH;
98 hpsram->Instance->PSRAM_CFG |= tce_max << PSRAMC_PSRAM_CFG_TCE_MAX_LENGTH_Pos;
99 if (hpsram->wakeup)
100 {
101 //restore refresh rate
102 hwp_psramc->MR4 = 0x00400040UL;
103 }
104
105 //change xccela psram wrap size
106 rdata = hpsram->Instance->MR0 ;
107 //rdata[1:0] = 'h0;
108 //rdata[17:16] = 'h0;
109 rdata &= 0xfffcfffc;
110 if (hpsram->dual_psram) //dual psram needs fixed latency to sync
111 rdata |= 0x00200020;
112 hpsram->Instance->MR0 = rdata;
113 //hwp_psramc->MR0 = 0x00280028;//rdata;
114 rdata = hpsram->Instance->MR8 ;
115 //rdata[2:0] = 'h3;
116 //rdata[18:16] = 'h3;
117 rdata &= 0xfff8fff8;
118 rdata |= 0x00030003;
119 hpsram->Instance->MR8 = rdata;
120
121 //write wl code for xccela psram
122 hpsram->Instance->CTRL_TIME |= (7 << PSRAMC_CTRL_TIME_WL_Pos) ;
123 }
124 else if (hpsram->wakeup)
125 {
126 /* restore refresh rate */
127 hpsram->Instance->MR4 &= ~0x8UL;
128 }
129
130 //reset cre
131 hpsram->Instance->CRE = 0;
132
133 return HAL_OK;
134 }
135
HAL_PSRAM_DeInit(PSRAM_HandleTypeDef * hpsram)136 HAL_StatusTypeDef HAL_PSRAM_DeInit(PSRAM_HandleTypeDef *hpsram)
137 {
138 hpsram->State = HAL_PSRAM_STATE_RESET;
139 return HAL_OK;
140 }
141
HAL_PSRAM_Config(PSRAM_HandleTypeDef * hpsram,PSRAM_CONFIG_HAL_T * conf)142 HAL_StatusTypeDef HAL_PSRAM_Config(PSRAM_HandleTypeDef *hpsram, PSRAM_CONFIG_HAL_T *conf)
143 {
144 if (hpsram == NULL || conf == NULL)
145 return HAL_ERROR;
146
147 hpsram->Instance->CTRL_TIME = conf->ctrl_time;
148 hpsram->Instance->READ_CTRL = conf->read_ctrl;
149 hpsram->Instance->DELAY_FINAL_ADD = conf->delay_final_add;
150 hpsram->Instance->DQS_CTRL = conf->dqs_ctrl;
151 hpsram->Instance->CLK_CTRL = conf->clk_ctrl;
152 hpsram->Instance->POWER_UP = conf->power_up;
153 hpsram->Instance->POWER_TIME = conf->power_time;
154 hpsram->Instance->REG_TIME = conf->reg_time;
155 hpsram->Instance->IMR = conf->imr;
156 return HAL_OK;
157 }
158
HAL_PSRAM_READ_CTRL(PSRAM_HandleTypeDef * hpsram,uint32_t value)159 HAL_StatusTypeDef HAL_PSRAM_READ_CTRL(PSRAM_HandleTypeDef *hpsram, uint32_t value)
160 {
161 if (hpsram == NULL)
162 return HAL_ERROR;
163
164
165 return HAL_OK;
166 }
167
HAL_PSRAM_SET_DELAY(PSRAM_HandleTypeDef * hpsram,uint32_t value)168 HAL_StatusTypeDef HAL_PSRAM_SET_DELAY(PSRAM_HandleTypeDef *hpsram, uint32_t value)
169 {
170 if (hpsram == NULL)
171 return HAL_ERROR;
172
173 return HAL_OK;
174 }
175
HAL_PSRAM_CHECK_POWER(PSRAM_HandleTypeDef * hpsram)176 HAL_StatusTypeDef HAL_PSRAM_CHECK_POWER(PSRAM_HandleTypeDef *hpsram)
177 {
178 if (hpsram == NULL)
179 return HAL_ERROR;
180
181 return HAL_OK;
182 }
183
HAL_PSRAM_SET_CLOCK(PSRAM_HandleTypeDef * hpsram,uint32_t value)184 HAL_StatusTypeDef HAL_PSRAM_SET_CLOCK(PSRAM_HandleTypeDef *hpsram, uint32_t value)
185 {
186 if (hpsram == NULL)
187 return HAL_ERROR;
188
189 return HAL_OK;
190 }
191
192 /**
193 * @brief Initialize the UART MSP.
194 * @param huart UART handle.
195 * @retval None
196 */
HAL_PSRAM_MspInit(PSRAM_HandleTypeDef * hpsram)197 __weak void HAL_PSRAM_MspInit(PSRAM_HandleTypeDef *hpsram)
198 {
199 uint32_t state;
200
201
202 //temp add for delay offset of i_dq_l
203
204 //enable train using default setting
205 //*(volatile uint32_t *) 0x40003040 |= 0x2;
206 hpsram->Instance->DELAY_TRAIN |= PSRAMC_DELAY_TRAIN_TRAINING_EN;
207
208 //enable auto_cfg
209 //*(volatile uint32_t *) 0x40003040 |= 0x80000000;
210 hpsram->Instance->DELAY_TRAIN |= PSRAMC_DELAY_TRAIN_AUTO_CFG;
211
212 //wait delay train done
213 //dll_state = (*(volatile uint32_t *) 0x40003044 ) & 0x10000;
214 do
215 {
216 state = hpsram->Instance->DLL_STATE & PSRAMC_DLL_STATE_DLL_LOCKED_Msk;
217 }
218 while (!state);
219
220 //disable train
221 //*(volatile uint32_t *) 0x40003040 &= 0xfffffffd;
222 hpsram->Instance->DELAY_TRAIN &= ~PSRAMC_DELAY_TRAIN_TRAINING_EN;
223
224 // read phy state
225 //state = *(volatile uint32_t *) 0x40003038;
226 do
227 {
228 state = hpsram->Instance->PSRAM_FREE & PSRAMC_PSRAM_FREE_PSRAM_FREE_Msk;
229 }
230 while (!state);
231
232 if (!hpsram->wakeup)
233 {
234 //write to globle reset psram
235 //*(volatile uint32_t *) 0x40003014 |= 0x10;
236 hpsram->Instance->POWER_UP |= PSRAMC_POWER_UP_HW_POWER_PULSE;
237 // read init state
238 //state = *(volatile uint32_t *) 0x40003028;
239 do
240 {
241 state = hpsram->Instance->POWER_UP & PSRAMC_POWER_UP_INIT_DONE_STATE_Msk;
242 }
243 while (!state);
244 }
245
246 //set psram drive stength
247 hpsram->Instance->MR0 &= 0xFFFFFFFC;
248 //hpsram->Instance->MR0 |= 0xFFFFFFF1;
249 hpsram->Instance->MR0 |= 0x1;
250
251 //hpsram->Instance->DEBUG_SEL = 0x1; //TODO, actually needed?
252 //hpsram->Instance->DELAY_TRAIN &= ~PSRAMC_DELAY_TRAIN_AUTO_CFG ;
253 //hpsram->Instance->CLK_CTRL = 0x0404;
254 //hpsram->Instance->DQS_CTRL = 0x04040303;
255
256 }
257
258 #endif
259
260 /// @} PSRAM
261
262 /// @} BF0_HAL_Driver
263
264 /// @} file