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