• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Bestechnic (Shanghai) Co., Ltd. All rights reserved.
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 #if defined(CHIP_HAS_PSRAM) && (CHIP_PSRAM_CTRL_VER == 2 || CHIP_PSRAM_CTRL_VER == 3)
16 
17 #include "plat_types.h"
18 #include "plat_addr_map.h"
19 #include "cmsis.h"
20 #include "hal_location.h"
21 #include "hal_psram.h"
22 #include "hal_timer.h"
23 #include "hal_trace.h"
24 #include "hal_cache.h"
25 #include "hal_chipid.h"
26 #include "pmu.h"
27 #include "reg_psram_mc_v2.h"
28 #include "reg_psram_phy_v2.h"
29 #include "string.h"
30 
31 #define PSRAM_RESET
32 //#define PSRAM_DUAL_8BIT
33 #ifdef CHIP_BEST2003
34     #ifndef PSRAM_APS3208K
35         #define PSRAM_WRAP_ENABLE
36     #endif
37 #endif
38 
39 #ifndef PSRAM_PAGE_SIZE
40 #ifdef PSRAM_XCCELA_MODE
41 // APS128xxN APS256xxN APS512xxN
42 #define PSRAM_PAGE_SIZE                     2048
43 #else /* PSRAM_XCCELA_MODE */
44 // APS3208K APS6408L
45 #define PSRAM_PAGE_SIZE                     1024
46 #endif /* PSRAM_XCCELA_MODE */
47 #endif
48 
49 #ifdef PSRAM_DEBUG
50     #define PSRAM_TRACE TRACE_IMM
51 #else
52     #define PSRAM_TRACE(...)
53 #endif
54 
55 #ifdef PSRAM_DEBUG
56     #define PSRAM_TRACENOCRLF_NOTS REL_TRACE_NOCRLF_NOTS
57 #else
58     #define PSRAM_TRACENOCRLF_NOTS(...)
59 #endif
60 
61 #define TX_FIFO_DEPTH                       8
62 #define RX_FIFO_DEPTH                       8
63 
64 // MR0
65 #define MR0_DRIVE_STR_SHIFT                 0
66 #define MR0_DRIVE_STR_MASK                  (0x3 << MR0_DRIVE_STR_SHIFT)
67 #define MR0_DRIVE_STR(n)                    BITFIELD_VAL(MR0_DRIVE_STR, n)
68 #define MR0_READ_LATENCY_SHIFT              2
69 #define MR0_READ_LATENCY_MASK               (0x7 << MR0_READ_LATENCY_SHIFT)
70 #define MR0_READ_LATENCY(n)                 BITFIELD_VAL(MR0_READ_LATENCY, n)
71 #define MR0_LT                              (1 << 5)
72 #define MR0_FIXED_00_SHIFT                  6
73 #define MR0_FIXED_00_MASK                   (0x3 << MR0_FIXED_00_SHIFT)
74 #define MR0_FIXED_00(n)                     BITFIELD_VAL(MR0_FIXED_00, n)
75 
76 // MR1
77 #define MR1_VENDOR_ID_SHIFT                 0
78 #define MR1_VENDOR_ID_MASK                  (0x1F << MR1_VENDOR_ID_SHIFT)
79 #define MR1_VENDOR_ID(n)                    BITFIELD_VAL(MR1_VENDOR_ID, n)
80 #define MR1_DENSITY_SHIFT                   5
81 #define MR1_DENSITY_MASK                    (0x3 << MR1_DENSITY_SHIFT)
82 #define MR1_DENSITY(n)                      BITFIELD_VAL(MR1_DENSITY, n)
83 #define MR1_ULP                             (1 << 7)
84 
85 // MR2
86 #define MR2_VENDOR_ID_SHIFT                 0
87 #define MR2_VENDOR_ID_MASK                  (0x7 << MR2_VENDOR_ID_SHIFT)
88 #define MR2_VENDOR_ID(n)                    BITFIELD_VAL(MR2_VENDOR_ID, n)
89 #define MR2_DEV_ID_SHIFT                    3
90 #define MR2_DEV_ID_MASK                     (0x3 << MR2_DEV_ID_SHIFT)
91 #define MR2_DEV_ID(n)                       BITFIELD_VAL(MR2_DEV_ID, n)
92 #define MR2_RSVD                            (1 << 5)
93 #define MR2_FIXED_1                         (1 << 6)
94 #define MR2_GB                              (1 << 7)
95 
96 // MR4
97 #define MR4_PASR_SHIFT                      0
98 #define MR4_PASR_MASK                       (0x7 << MR4_PASR_SHIFT)
99 #define MR4_PASR(n)                         BITFIELD_VAL(MR4_PASR, n)
100 #define MR4_RF                              (1 << 3)
101 #define MR4_FIXED_0                         (1 << 4)
102 #define MR4_WRITE_LATENCY_SHIFT             5
103 #define MR4_WRITE_LATENCY_MASK              (0x7 << MR4_WRITE_LATENCY_SHIFT)
104 #define MR4_WRITE_LATENCY(n)                BITFIELD_VAL(MR4_WRITE_LATENCY, n)
105 
106 // MR6
107 #define MR6_RSVD_SHIFT                      0
108 #define MR6_RSVD_MASK                       (0xF << MR6_RSVD_SHIFT)
109 #define MR6_RSVD(n)                         BITFIELD_VAL(MR6_RSVD, n)
110 #define MR6_HALF_SLEEP_SHIFT                4
111 #define MR6_HALF_SLEEP_MASK                 (0xF << MR6_HALF_SLEEP_SHIFT)
112 #define MR6_HALF_SLEEP(n)                   BITFIELD_VAL(MR6_HALF_SLEEP, n)
113 
114 // MR8
115 #define MR8_BL_SHIFT                        0
116 #define MR8_BL_MASK                         (0x3 << MR8_BL_SHIFT)
117 #define MR8_BL(n)                           BITFIELD_VAL(MR8_BL, n)
118 #define MR8_BT                              (1 << 2)
119 #define MR8_FIXED_0                         (1 << 3)
120 #define MR8_RSVD_SHIFT                      4
121 #define MR8_RSVD_MASK                       (0x7 << MR8_RSVD_SHIFT)
122 #define MR8_RSVD(n)                         BITFIELD_VAL(MR8_RSVD, n)
123 #define MR8_FIXED_00                        (1 << 7)
124 
125 enum PSRAM_CMD_T {
126     PSRAM_CMD_SYNC_READ     = 0x00,
127     PSRAM_CMD_SYNC_WRITE    = 0x80,
128     PSRAM_CMD_4BYTE_READ    = 0x3F,
129     PSRAM_CMD_4BYTE_WRITE   = 0xBF,
130     PSRAM_CMD_REG_READ      = 0x40,
131     PSRAM_CMD_REG_WRITE     = 0xC0,
132     PSRAM_CMD_GLOBAL_RESET  = 0xFF,
133 };
134 
135 enum CP_FSM_STATE_T {
136     CP_FSM_STATE_SELF_REFRESH   = 1,
137     CP_FSM_STATE_PD             = 2,
138     CP_FSM_STATE_READY          = 4,
139 };
140 
141 enum MEMIF_CMD_T {
142     MEMIF_NO_CMD        = 0x00,
143     MEMIF_WRITE         = 0x01,
144     MEMIF_READ          = 0x02,
145     MEMIF_MRS           = 0x05,
146     MEMIF_MRR           = 0x06,
147     MEMIF_REF           = 0x08,
148     MEMIF_SREF          = 0x09,
149     MEMIF_PD            = 0x10,
150     MEMIF_NOP           = 0x20,
151     MEMIF_RST           = 0xFF,
152     MEMIF_ZQCL          = 0x85,
153     MEMIF_ZQCS          = 0x45,
154     MEMIF_ZQCRST        = 0x25,
155     MEMIF_START_CLOCK   = 0x40,
156     MEMIF_STOP_CLOCK    = 0x80,
157     MEMIF_NEW_CMD       = 0x7F,
158 };
159 
160 static struct PSRAM_MC_T *const psram_mc = (struct PSRAM_MC_T *)PSRAM_CTRL_BASE;
161 static struct PSRAM_PHY_T *const psram_phy = (struct PSRAM_PHY_T *)(PSRAM_CTRL_BASE + 0x8000);
162 
163 #ifdef FPGA
164     static const uint32_t psram_cfg_clk = 20 * 1000 * 1000;
165     static const uint32_t psram_run_clk = 20 * 1000 * 1000;
166 #else /*FPGA*/
167     #if (PSRAM_SPEED != 0)
168         static const uint32_t psram_cfg_clk = 48 * 1000 * 1000;
169         static const uint32_t psram_run_clk = PSRAM_SPEED * 1000 * 1000;
170     #else
171         #error "invalid PSRAM_SPEED"
172     #endif
173 #endif /*FPGA*/
174 
175 static void psram_chip_timing_config(uint32_t clk, bool psram_first);
176 
hal_psramip_mc_busy(void)177 int hal_psramip_mc_busy(void)
178 {
179     return !!(psram_mc->REG_404 & PSRAM_ULP_MC_BUSY);
180 }
181 
hal_psramip_wb_busy(void)182 static int hal_psramip_wb_busy(void)
183 {
184     return !!(psram_mc->REG_404 & PSRAM_ULP_MC_WB_FILL_LEVEL_MASK);
185 }
186 
hal_psramip_mc_in_sleep(void)187 int hal_psramip_mc_in_sleep(void)
188 {
189     return GET_BITFIELD(psram_mc->REG_404, PSRAM_ULP_MC_CP_FSM_STATE) == CP_FSM_STATE_PD;
190 }
191 
hal_psramip_rx_fifo_empty(void)192 int hal_psramip_rx_fifo_empty(void)
193 {
194     return !!(psram_mc->REG_404 & PSRAM_ULP_MC_MGR_RXFIFO_R_EMPTY);
195 }
196 
hal_psramip_tx_fifo_full(void)197 int hal_psramip_tx_fifo_full(void)
198 {
199     return !!(psram_mc->REG_404 & PSRAM_ULP_MC_MGR_TXFIFO_W_FULL);
200 }
201 
hal_psramip_get_rx_fifo_len(void)202 uint32_t hal_psramip_get_rx_fifo_len(void)
203 {
204     return GET_BITFIELD(psram_mc->REG_404, PSRAM_ULP_MC_MGR_RXFIFO_FULL_CNT);
205 }
206 
hal_psramip_get_tx_fifo_free_len(void)207 uint32_t hal_psramip_get_tx_fifo_free_len(void)
208 {
209     return GET_BITFIELD(psram_mc->REG_404, PSRAM_ULP_MC_MGR_TXFIFO_EMPTY_CNT);
210 }
211 
hal_psramip_mc_busy_wait(void)212 void hal_psramip_mc_busy_wait(void)
213 {
214     while (hal_psramip_mc_busy());
215 }
216 
hal_psramip_wb_busy_wait(void)217 void hal_psramip_wb_busy_wait(void)
218 {
219     while (hal_psramip_wb_busy());
220 }
221 
hal_psramip_flush_tx_fifo(void)222 void hal_psramip_flush_tx_fifo(void)
223 {
224     hal_psramip_mc_busy_wait();
225     psram_mc->REG_01C = PSRAM_ULP_MC_MGR_TX_FIFO_CLR;
226     hal_psramip_mc_busy_wait();
227 }
228 
hal_psramip_flush_rx_fifo(void)229 void hal_psramip_flush_rx_fifo(void)
230 {
231     hal_psramip_mc_busy_wait();
232     psram_mc->REG_01C = PSRAM_ULP_MC_MGR_RX_FIFO_CLR;
233     hal_psramip_mc_busy_wait();
234 }
235 
hal_psramip_flush_all_fifo(void)236 void hal_psramip_flush_all_fifo(void)
237 {
238     hal_psramip_mc_busy_wait();
239     psram_mc->REG_01C = PSRAM_ULP_MC_MGR_TX_FIFO_CLR | PSRAM_ULP_MC_MGR_RX_FIFO_CLR;
240     hal_psramip_mc_busy_wait();
241 }
242 
hal_psramip_xfer_addr_len(uint32_t addr,uint32_t len)243 void hal_psramip_xfer_addr_len(uint32_t addr, uint32_t len)
244 {
245     psram_mc->REG_008 = addr;
246     psram_mc->REG_00C = len;
247 }
248 
hal_psramip_write_fifo(uint32_t * data,uint32_t len)249 void hal_psramip_write_fifo(uint32_t *data, uint32_t len)
250 {
251     for (uint32_t i = 0; i < len; i++) {
252         psram_mc->REG_014 = *data++;
253     }
254 }
255 
hal_psramip_read_fifo(uint32_t * data,uint32_t len)256 void hal_psramip_read_fifo(uint32_t *data, uint32_t len)
257 {
258     for (uint32_t i = 0; i < len; i++) {
259         *data++ = psram_mc->REG_018;
260     }
261 }
262 
hal_psramip_set_reg_data_mask(void)263 void hal_psramip_set_reg_data_mask(void)
264 {
265 #ifdef PSRAM_DUAL_8BIT
266     psram_mc->REG_010 = 0xFC;
267 #else
268     psram_mc->REG_010 = 0xFE;
269 #endif
270 }
271 
hal_psramip_set_mem_data_mask(void)272 void hal_psramip_set_mem_data_mask(void)
273 {
274     psram_mc->REG_010 = 0;
275 }
276 
hal_psramip_set_cmd(enum MEMIF_CMD_T cmd)277 void hal_psramip_set_cmd(enum MEMIF_CMD_T cmd)
278 {
279     psram_mc->REG_004 = cmd;
280 }
281 
psram_read_reg(uint32_t reg,uint32_t * val)282 POSSIBLY_UNUSED void psram_read_reg(uint32_t reg, uint32_t *val)
283 {
284     hal_psramip_flush_all_fifo();
285     hal_psramip_xfer_addr_len(reg, 1);
286     hal_psramip_set_cmd(MEMIF_MRR);
287     while (hal_psramip_rx_fifo_empty());
288     hal_psramip_read_fifo(val, 1);
289 }
290 
psram_send_cmd_reg(enum MEMIF_CMD_T cmd,uint32_t reg,uint32_t val)291 static void psram_send_cmd_reg(enum MEMIF_CMD_T cmd, uint32_t reg, uint32_t val)
292 {
293 #ifdef PSRAM_DUAL_8BIT
294     val &= 0xFF;
295     val |= (val << 8);
296 #endif
297     hal_psramip_flush_all_fifo();
298     //hal_psramip_set_reg_data_mask();
299     hal_psramip_write_fifo(&val, 1);
300     hal_psramip_xfer_addr_len(reg, 1);
301     hal_psramip_set_cmd(cmd);
302     while (hal_psramip_get_tx_fifo_free_len() != TX_FIFO_DEPTH);
303     hal_psramip_mc_busy_wait();
304     //hal_psramip_set_mem_data_mask();
305 }
306 
psram_write_reg(uint32_t reg,uint32_t val)307 static void psram_write_reg(uint32_t reg, uint32_t val)
308 {
309     psram_send_cmd_reg(MEMIF_MRS, reg, val);
310 }
311 
psram_single_cmd(enum MEMIF_CMD_T cmd)312 static void psram_single_cmd(enum MEMIF_CMD_T cmd)
313 {
314     hal_psramip_flush_all_fifo();
315     hal_psramip_set_cmd(cmd);
316     hal_psramip_mc_busy_wait();
317 }
318 
psram_reset(void)319 static POSSIBLY_UNUSED void psram_reset(void)
320 {
321     psram_single_cmd(MEMIF_RST);
322 #ifdef PSRAM_APS3208K
323     hal_sys_timer_delay_us(1);
324     psram_single_cmd(MEMIF_RST);
325 #endif
326 }
327 
psram_set_timing(uint32_t clk)328 static void psram_set_timing(uint32_t clk)
329 {
330     uint32_t reg;
331     uint32_t val;
332 #ifdef PSRAM_XCCELA_MODE
333     reg = 8;
334 #ifdef PSRAM_WRAP_ENABLE
335     // Wrap 32
336     val = MR8_BL(1);
337 #else
338     // Wrap 1k
339     val = MR8_BL(0x3);
340 #endif
341     psram_write_reg(reg, val);
342 
343     reg = 0;
344     if (clk <= 66000000) {
345         val = 0;
346     } else if (clk <= 109000000) {
347         val = 1;
348     } else if (clk <= 133000000) {
349         val = 2;
350     } else if (clk <= 166000000) {
351         val = 3;
352     } else {
353         val = 4;
354     }
355     // Latency type: Variable
356     val = MR0_DRIVE_STR(3) | MR0_READ_LATENCY(val);
357     psram_write_reg(reg, val);
358 
359     reg = 4;
360     if (clk <= 66000000) {
361         val = 0;
362     } else if (clk <= 109000000) {
363         val = 4;
364     } else if (clk <= 133000000) {
365         val = 2;
366     } else if (clk <= 166000000) {
367         val = 6;
368     } else {
369         val = 1;
370     }
371     //Always 4x Refresh
372     val = MR4_PASR(0) | MR4_WRITE_LATENCY(val);
373     psram_write_reg(reg, val);
374 #else /*PSRAM_XCCELA_MODE*/
375 #ifndef PSRAM_APS3208K
376     reg = 8;
377 #ifdef PSRAM_WRAP_ENABLE
378     // Wrap 32
379     val = MR8_BL(1);
380 #else
381     // Wrap 1k
382     val = MR8_BL(0x3);
383 #endif
384     psram_write_reg(reg, val);
385 #endif /* PSRAM_APS3208K */
386     reg = 0;
387     if (clk <= 66000000) {
388         val = 2;
389     } else if (clk <= 109000000) {
390         val = 3;
391     } else if (clk <= 133000000) {
392         val = 4;
393     } else if (clk <= 166000000) {
394         val = 5;
395     } else {
396         val = 6;
397     }
398     // Latency type: Variable
399     val = MR0_DRIVE_STR(3) | MR0_READ_LATENCY(val);
400     psram_write_reg(reg, val);
401 
402     reg = 4;
403     if (clk <= 166000000) {
404         val = 0;
405     } else {
406         val = 4;
407     }
408     //Fast Refresh,
409     val = MR4_PASR(0) | MR4_WRITE_LATENCY(val);
410     psram_write_reg(reg, val);
411 #endif /*PSRAM_XCCELA_MODE*/
412 }
413 
hal_psram_phy_read_reg(__I uint32_t * addr)414 static uint32_t hal_psram_phy_read_reg(__I uint32_t *addr)
415 {
416 #if defined(CHIP_BEST2003) || defined(CHIP_BEST2006)
417     *addr;
418 #endif
419     return *addr;
420 }
421 
hal_psram_phy_dll_config(uint32_t clk)422 static void hal_psram_phy_dll_config(uint32_t clk)
423 {
424     uint32_t phy_clk;
425     uint32_t range;
426     uint32_t val;
427 
428     val = hal_psram_phy_read_reg(&psram_phy->REG_050);
429     val &= ~PSRAM_ULP_PHY_REG_DLL_RESETB | PSRAM_ULP_PHY_REG_DLL_CK_RDY;
430     psram_phy->REG_050 = val;
431     phy_clk = clk;
432     if (phy_clk <= 100000000 / 2) {
433         range = 3;
434     } else if (phy_clk <= 150000000 / 2) {
435         range = 2;
436     } else if (phy_clk <= 300000000 / 2) {
437         range = 1;
438     } else {
439         range = 1;
440     }
441     val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_DLL_RANGE, range);
442     psram_phy->REG_050 = val;
443     hal_sys_timer_delay_us(100);
444     val |= PSRAM_ULP_PHY_REG_DLL_RESETB | PSRAM_ULP_PHY_REG_DLL_CK_RDY;
445     psram_phy->REG_050 = val;
446     hal_sys_timer_delay_us(100);
447 }
448 
hal_psram_phy_init(uint32_t clk)449 static void hal_psram_phy_init(uint32_t clk)
450 {
451     uint32_t val;
452     val = hal_psram_phy_read_reg(&psram_phy->REG_048);
453     val |= PSRAM_ULP_PHY_REG_LDO_PU | PSRAM_ULP_PHY_REG_LDO_PRECHARGE;
454     psram_phy->REG_048 = val;
455     hal_sys_timer_delay_us(100);
456 
457     val &= ~PSRAM_ULP_PHY_REG_LDO_PRECHARGE;
458     val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_LDO_IEN1, 0xd);
459     val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_LDO_IEN2, 0x7);
460     val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_LDO_VTUNE, 0x2);
461 #if CHIP_PSRAM_CTRL_VER >= 3
462     val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_LDO_RES, 0x4);
463 #endif
464     psram_phy->REG_048 = val;
465     hal_sys_timer_delay_us(100);
466 
467 #if CHIP_PSRAM_CTRL_VER >= 3
468 #ifdef CHIP_BEST2003
469     // chip 2006
470     if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_8) {
471         psram_mc->REG_200 |= PSRAM_ULP_PHY_REG_CEB_PU;
472     }
473 #endif
474 #endif
475     val = hal_psram_phy_read_reg(&psram_phy->REG_04C);
476     val |= PSRAM_ULP_PHY_REG_PSRAM_PU;
477     //val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_PSRAM_SWRC, 0x3);
478     val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_PSRAM_TXDRV, 0x3);
479     psram_phy->REG_04C = val;
480     hal_sys_timer_delay_us(100);
481 
482     val = hal_psram_phy_read_reg(&psram_phy->REG_050);
483     val |= PSRAM_ULP_PHY_REG_DLL_PU;
484     val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_DLL_SWRC, 0x0);
485     val &= ~PSRAM_ULP_PHY_REG_BYPASS_DECIMATION;
486     psram_phy->REG_050 = val;
487     hal_sys_timer_delay_us(100);
488 
489     val |= PSRAM_ULP_PHY_REG_DLL_RESETB;
490     psram_phy->REG_050 = val;
491     hal_sys_timer_delay_us(100);
492 
493     hal_psram_phy_dll_config(clk);
494     hal_sys_timer_delay_us(500);
495 }
hal_psram_phy_sleep()496 POSSIBLY_UNUSED void hal_psram_phy_sleep()
497 {
498     uint32_t val;
499 
500     val = hal_psram_phy_read_reg(&psram_phy->REG_04C);
501     val &= ~PSRAM_ULP_PHY_REG_PSRAM_PU;
502     psram_phy->REG_04C = val;
503 
504     val = hal_psram_phy_read_reg(&psram_phy->REG_050);
505     val &= ~PSRAM_ULP_PHY_REG_DLL_PU;
506     psram_phy->REG_050 = val;
507 
508     val = hal_psram_phy_read_reg(&psram_phy->REG_048);
509     val &= ~PSRAM_ULP_PHY_REG_LDO_PU;
510     psram_phy->REG_048 = val;
511 }
512 
hal_psram_digphy_init()513 static void hal_psram_digphy_init()
514 {
515 #if CHIP_PSRAM_CTRL_VER >= 3
516     uint32_t val;
517     val = hal_psram_phy_read_reg(&psram_phy->REG_004);
518 #ifdef PSRAM_XCCELA_MODE
519     val |= PSRAM_ULP_PHY_ADDR_4BYTES_EN | PSRAM_ULP_PHY_DQS_DM_MERGE_EN;
520     val &= ~PSRAM_ULP_PHY_PHY_DUMMY_CYC_EN;
521 #endif
522     val |= PSRAM_ULP_PHY_CTRL_DELAY(1);
523     val &= ~PSRAM_ULP_PHY_PHY_DLY_AUTO_EN;
524     psram_phy->REG_004 = val;
525 #endif
526 }
hal_psram_phy_wakeup()527 POSSIBLY_UNUSED static void hal_psram_phy_wakeup()
528 {
529     uint32_t val;
530     val = hal_psram_phy_read_reg(&psram_phy->REG_048);
531     val |= PSRAM_ULP_PHY_REG_LDO_PU | PSRAM_ULP_PHY_REG_LDO_PRECHARGE;
532     psram_phy->REG_048 = val;
533     hal_sys_timer_delay_us(10);
534 
535     val &= ~PSRAM_ULP_PHY_REG_LDO_PRECHARGE;
536     val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_LDO_IEN1, 0xd);
537     val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_LDO_IEN2, 0x7);
538     val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_LDO_VTUNE, 0x2);
539     psram_phy->REG_048 = val;
540 
541     val = hal_psram_phy_read_reg(&psram_phy->REG_04C);
542     val |= PSRAM_ULP_PHY_REG_PSRAM_PU;
543     //val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_PSRAM_SWRC, 0x3);
544     val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_PSRAM_TXDRV, 0x3);
545     psram_phy->REG_04C = val;
546 
547     val = hal_psram_phy_read_reg(&psram_phy->REG_050);
548     val |= PSRAM_ULP_PHY_REG_DLL_PU;
549     //val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_DLL_SWRC, 0x3);
550     psram_phy->REG_050 = val;
551     hal_sys_timer_delay_us(2);
552 
553     val |= PSRAM_ULP_PHY_REG_DLL_RESETB;
554     psram_phy->REG_050 = val;
555     hal_sys_timer_delay_us(20);
556 
557     do {
558         val = hal_psram_phy_read_reg(&psram_phy->REG_058);
559     } while ((val & PSRAM_ULP_PHY_DLL_LOCK) == 0);
560 }
hal_psram_mc_set_timing(uint32_t clk,bool init)561 static void hal_psram_mc_set_timing(uint32_t clk, bool init)
562 {
563     uint32_t val;
564 #ifdef PSRAM_XCCELA_MODE
565     if (init) {
566         val = PSRAM_ULP_MC_WRITE_LATENCY(1);
567     } else {
568         if (clk <= 66000000) {
569             val = PSRAM_ULP_MC_WRITE_LATENCY(3);
570         } else if (clk <= 109000000) {
571             val = PSRAM_ULP_MC_WRITE_LATENCY(4);
572         } else if (clk <= 133000000) {
573             val = PSRAM_ULP_MC_WRITE_LATENCY(5);
574         } else if (clk <= 166000000) {
575             val = PSRAM_ULP_MC_WRITE_LATENCY(6);
576         } else {
577             val = PSRAM_ULP_MC_WRITE_LATENCY(7);
578         }
579     }
580     psram_mc->REG_028 = val;
581     if (clk <= 66000000) {
582         val = PSRAM_ULP_MC_READ_LATENCY(3);
583     } else if (clk <= 109000000) {
584         val = PSRAM_ULP_MC_READ_LATENCY(4);
585     } else if (clk <= 133000000) {
586         val = PSRAM_ULP_MC_READ_LATENCY(5);
587     } else if (clk <= 166000000) {
588         val = PSRAM_ULP_MC_READ_LATENCY(6);
589     } else {
590         val = PSRAM_ULP_MC_READ_LATENCY(7);
591     }
592     psram_mc->REG_02C = val;
593     // tCPH >= 24 ns
594     val = (clk / 1000000 * 24 + (1000 - 1)) / 1000;
595     psram_mc->REG_058 = PSRAM_ULP_MC_T_CPHR(val);
596     psram_mc->REG_060 = PSRAM_ULP_MC_T_CPHW(val);
597     psram_mc->REG_068 = PSRAM_ULP_MC_T_MRR(val);
598     psram_mc->REG_06C = PSRAM_ULP_MC_T_MRS(val);
599 #else /*PSRAM_XCCELA_MODE*/
600     if (clk <= 166000000) {
601         val = PSRAM_ULP_MC_WRITE_LATENCY(0);
602     } else {
603         val = PSRAM_ULP_MC_WRITE_LATENCY(2);
604     }
605     psram_mc->REG_028 = val;
606     if (clk <= 66000000) {
607         val = PSRAM_ULP_MC_READ_LATENCY(2);
608     } else if (clk <= 109000000) {
609         val = PSRAM_ULP_MC_READ_LATENCY(3);
610     } else if (clk <= 133000000) {
611         val = PSRAM_ULP_MC_READ_LATENCY(4);
612     } else if (clk <= 166000000) {
613         val = PSRAM_ULP_MC_READ_LATENCY(5);
614     } else {
615         val = PSRAM_ULP_MC_READ_LATENCY(6);
616     }
617     psram_mc->REG_02C = val;
618     // tCPH
619     val = 2;
620     psram_mc->REG_058 = PSRAM_ULP_MC_T_CPHR(val);
621     psram_mc->REG_068 = PSRAM_ULP_MC_T_MRR(val);
622     val = 6;
623     psram_mc->REG_060 = PSRAM_ULP_MC_T_CPHW(val);
624 #if CHIP_PSRAM_CTRL_VER == 2
625     val += 1;
626 #endif
627     psram_mc->REG_06C = PSRAM_ULP_MC_T_MRS(val);
628 #endif /*PSRAM_XCCELA_MODE*/
629     // tRC >= 55 ns
630     val = (clk / 1000000 * 55 + (1000 - 1)) / 1000;
631     psram_mc->REG_050 = PSRAM_ULP_MC_T_RC(val);
632     // tCEM <= 2.5 us
633     val = clk / 1000000 * 25 / 10;
634     psram_mc->REG_070 = PSRAM_ULP_MC_T_CEM(val);
635     // tRST >= 2 us
636     val = clk / 1000000 * 2 + 1;
637     psram_mc->REG_074 = PSRAM_ULP_MC_T_RST(val);
638     // tHS >= 2 us
639     val = clk / 1000000 * 2 + 1;
640     psram_mc->REG_080 = PSRAM_ULP_MC_T_HS(val);
641     // tXPHS in [60 ns, 2 us]
642     val = (clk / 1000000 * 60 + (1000 - 1)) / 1000;
643     psram_mc->REG_084 = PSRAM_ULP_MC_T_XPHS(val);
644     // tXHS >= 100 us
645     val = clk / 1000000 * 100 + 1;
646     psram_mc->REG_088 = PSRAM_ULP_MC_T_XHS(val);
647     psram_mc->REG_09C = PSRAM_ULP_MC_WR_DMY_CYC(1);
648     // NOP dummy cycles, same as tXPHS in [60 ns, 2 us]
649     val = (clk / 1000000 * 60 + (1000 - 1)) / 1000;
650     psram_mc->REG_0A0 = PSRAM_ULP_MC_STOP_CLK_IN_NOP |
651 #ifdef PSRAM_XCCELA_MODE
652                         PSRAM_ULP_MC_STOP_CLK_IN_TCPH |
653 #endif
654                         PSRAM_ULP_MC_NOP_DMY_CYC(val);
655     psram_mc->REG_0A4 = PSRAM_ULP_MC_QUEUE_IDLE_CYCLE(5000);
656 }
657 
hal_psram_phy_wait_lock()658 static void hal_psram_phy_wait_lock()
659 {
660 #ifndef PROGRAMMER
661     uint32_t val;
662     uint32_t val_50;
663     uint32_t count = 0;
664     val = hal_psram_phy_read_reg(&psram_phy->REG_048);
665     val_50 = hal_psram_phy_read_reg(&psram_phy->REG_050);
666 #endif
667     while (1) {
668         uint32_t val_58;
669         val_58 = hal_psram_phy_read_reg(&psram_phy->REG_058);
670         if ((val_58 & PSRAM_ULP_PHY_DLL_LOCK))
671             break;
672 #ifndef PROGRAMMER
673         if (count++ > 20) {
674             if (GET_BITFIELD(val, PSRAM_ULP_PHY_REG_LDO_VTUNE) == 0x2) {
675                 val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_LDO_VTUNE, 0x1);
676                 psram_phy->REG_048 = val;
677             } else if (GET_BITFIELD(val, PSRAM_ULP_PHY_REG_LDO_VTUNE) == 0x1) {
678                 val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_LDO_VTUNE, 0x2);
679                 psram_phy->REG_048 = val;
680                 if (GET_BITFIELD(val_50, PSRAM_ULP_PHY_REG_DLL_RANGE) == 0x1) {
681                     val_50 = SET_BITFIELD(val_50, PSRAM_ULP_PHY_REG_DLL_RANGE, 0x2);
682                     psram_phy->REG_050 = val_50;
683                 }
684             }
685             count = 0;
686         }
687 #endif
688         hal_sys_timer_delay_us(100);
689     }
690 }
691 
692 POSSIBLY_UNUSED
hal_psram_init_calib(void)693 static void hal_psram_init_calib(void)
694 {
695     uint32_t val;
696     uint32_t delay;
697 
698     hal_psram_phy_wait_lock();
699     val = hal_psram_phy_read_reg(&psram_phy->REG_058);
700     delay = GET_BITFIELD(val, PSRAM_ULP_PHY_DLL_DLY_IN);
701     //ASSERT(delay < (PSRAM_ULP_PHY_DLL_DLY_IN_MASK >> PSRAM_ULP_PHY_DLL_DLY_IN_SHIFT),
702     //    "%s: Bad DLL_DLY_IN=0x%X reg=0x%08X", __func__, delay, psram_phy->REG_058);
703 
704     delay /= 2;
705     psram_phy->REG_054 = PSRAM_ULP_PHY_REG_PSRAM_TX_CEB_DLY(delay) | PSRAM_ULP_PHY_REG_PSRAM_TX_CLK_DLY(delay) |
706                          PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY(delay) | PSRAM_ULP_PHY_REG_PSRAM_RX_DQS_DLY(delay);
707     hal_sys_timer_delay_us(100);
708 }
709 
hal_psram_mc_init(uint32_t clk)710 static void hal_psram_mc_init(uint32_t clk)
711 {
712     uint32_t val = 0;
713 #if CHIP_PSRAM_CTRL_VER >= 3
714 #if defined(PSRAM_DUAL_8BIT)
715     val |= PSRAM_ULP_MC_CHIP_BIT;
716 #elif defined(PSRAM_X16_MODE)
717     val |= PSRAM_ULP_MC_CHIP_X16;
718 #endif
719 #ifdef PSRAM_SQPI_MODE
720     val |= PSRAM_ULP_MC_SQPI_MODE;
721     val |= (PSRAM_ULP_PHY_IDLE_DQ_OEN | PSRAM_ULP_PHY_IDLE_DQS_OEN);
722 #else /* PSRAM_SQPI_MODE */
723     val |= PSRAM_ULP_MC_OPI_MODE;
724     val = SET_BITFIELD(val, PSRAM_ULP_MC_CHIP_CA_PATTERN, 0x1);
725 #endif /* PSRAM_SQPI_MODE */
726 #else /* CHIP_PSRAM_CTRL_VER == 2 */
727 #if defined(PSRAM_DUAL_8BIT)
728     val |= PSRAM_ULP_MC_CHIP_BIT;
729 #endif
730 #endif /* CHIP_PSRAM_CTRL_VER >= 3 */
731     psram_mc->REG_000 = val;
732     psram_mc->REG_020 = 0;
733     psram_mc->REG_024 =
734 #if CHIP_PSRAM_CTRL_VER >= 3
735         //PSRAM_ULP_MC_ENTRY_SLEEP_IDLE |
736 #endif
737         PSRAM_ULP_MC_AUTOWAKEUP_EN |
738         PSRAM_ULP_MC_PD_MR(6) | PSRAM_ULP_MC_PD_CMD(0xF0);
739 #ifdef PSRAM_WRAP_ENABLE
740     // Burst len: 32 bytes, page: 1K
741     val = PSRAM_ULP_MC_BURST_LENGTH(1);
742 #else
743     if (PSRAM_PAGE_SIZE == 512) {
744         val = PSRAM_ULP_MC_BURST_LENGTH(7);
745     } else if (PSRAM_PAGE_SIZE == 1024) {
746         val = PSRAM_ULP_MC_BURST_LENGTH(4);
747     } else if (PSRAM_PAGE_SIZE == 2048) {
748         val = PSRAM_ULP_MC_BURST_LENGTH(5);
749     } else {
750         // 4K
751         val = PSRAM_ULP_MC_BURST_LENGTH(6);
752     }
753 #endif /* PSRAM_WRAP_ENABLE */
754     if (PSRAM_PAGE_SIZE == 512) {
755         val |= PSRAM_ULP_MC_PAGE_BOUNDARY(3);
756     } else if (PSRAM_PAGE_SIZE == 1024) {
757         val |= PSRAM_ULP_MC_PAGE_BOUNDARY(0);
758     } else if (PSRAM_PAGE_SIZE == 2048) {
759         val |= PSRAM_ULP_MC_PAGE_BOUNDARY(1);
760     } else {
761         // 4K
762         val |= PSRAM_ULP_MC_PAGE_BOUNDARY(2);
763     }
764     psram_mc->REG_034 = val;
765     // AHB bus width: 32 bits
766     psram_mc->REG_038 = 0;
767     // Write buffer level with high priority: 0~7
768 #if CHIP_PSRAM_CTRL_VER == 2
769     psram_mc->REG_03C = PSRAM_ULP_MC_HIGH_PRI_LEVEL(1);
770 #else
771     psram_mc->REG_03C = PSRAM_ULP_MC_HIGH_PRI_LEVEL(7);
772 #endif
773 #ifdef PSRAM_WRAP_ENABLE
774     psram_mc->REG_040 = PSRAM_ULP_MC_CP_WRAP_EN;
775 #else
776     psram_mc->REG_040 = PSRAM_ULP_MC_WRAP_CRT_RET_EN;
777 #endif
778     psram_mc->REG_044 = 0;
779     psram_mc->REG_048 = 0;
780 
781     hal_psramip_set_reg_data_mask();
782     hal_sys_timer_delay_us(100);
783 
784     hal_psram_mc_set_timing(clk, true);
785     hal_sys_timer_delay_us(100);
786 
787     psram_mc->REG_400 = PSRAM_ULP_MC_INIT_COMPLETE;
788     hal_sys_timer_delay_us(100);
789 }
790 
hal_psram_sleep(void)791 void hal_psram_sleep(void)
792 {
793     hal_psramip_mc_busy_wait();
794     if (!hal_psramip_mc_in_sleep()) {
795 #if CHIP_PSRAM_CTRL_VER >= 3
796         //psram_mc->REG_024 &= ~PSRAM_ULP_MC_ENTRY_SLEEP_IDLE;
797 #endif
798         hal_psramip_mc_busy_wait();
799 #if CHIP_PSRAM_CTRL_VER >= 3
800 #ifdef PSRAM_XCCELA_MODE
801         int val = psram_mc->REG_028;
802         psram_mc->REG_028 = PSRAM_ULP_MC_WRITE_LATENCY(1);
803         __DSB();
804         hal_psramip_mc_busy_wait();
805 #endif /* PSRAM_XCCELA_MODE */
806         psram_write_reg(0x6, 0xF0);
807         hal_psramip_mc_busy_wait();
808 #ifdef PSRAM_XCCELA_MODE
809         psram_mc->REG_028 = val;
810         hal_psramip_mc_busy_wait();
811 #endif /* PSRAM_XCCELA_MODE */
812 #else
813         hal_psramip_set_cmd(MEMIF_PD);
814         hal_psramip_mc_busy_wait();
815 #endif
816     }
817     hal_psram_phy_sleep();
818 }
819 
hal_psram_wakeup(void)820 void hal_psram_wakeup(void)
821 {
822     hal_psram_phy_wakeup();
823     hal_psramip_set_cmd(MEMIF_NOP);
824     hal_psramip_mc_busy_wait();
825 #if CHIP_PSRAM_CTRL_VER >= 3
826     //psram_mc->REG_024 |= PSRAM_ULP_MC_ENTRY_SLEEP_IDLE;
827 #endif
828 }
829 
psram_chip_timing_config(uint32_t clk,bool update_psram_first)830 static void psram_chip_timing_config(uint32_t clk, bool update_psram_first)
831 {
832     enum HAL_CMU_FREQ_T freq;
833 
834     if (clk <= 52000000) {
835         freq = HAL_CMU_FREQ_104M;
836     } else if (clk <= 104000000) {
837         freq = HAL_CMU_FREQ_208M;
838     } else {
839 #ifdef HAL_CMU_FREQ_390M
840         freq = HAL_CMU_FREQ_390M;
841 #else
842         freq = HAL_CMU_FREQ_208M;
843 #endif
844     }
845 
846     if (update_psram_first) {
847         psram_set_timing(clk);
848     }
849 
850     hal_cmu_mem_set_freq(freq);
851     hal_sys_timer_delay_us(500);
852     hal_psram_phy_dll_config(clk);
853 
854 #if !defined(FPGA) && !defined(SIMU)
855     hal_psram_init_calib();
856 #endif
857     hal_psram_mc_set_timing(clk, false);
858     if (!update_psram_first) {
859         psram_set_timing(clk);
860     }
861     hal_sys_timer_delay_us(100);
862 }
hal_psram_snoop_enable()863 void hal_psram_snoop_enable()
864 {
865 #if CHIP_PSRAM_CTRL_VER >= 3
866     psram_mc->REG_044 &= ~PSRAM_ULP_MC_SNP_DISABLE;
867 #endif
868 }
hal_psram_snoop_disable()869 void hal_psram_snoop_disable()
870 {
871     psram_mc->REG_044 |= PSRAM_ULP_MC_SNP_DISABLE;
872 }
873 
hal_psram_write_buffer_invalidate(void)874 void hal_psram_write_buffer_invalidate(void)
875 {
876     uint32_t level;
877     uint32_t start = hal_sys_timer_get();
878 
879     __DSB();
880     do {
881         level = GET_BITFIELD(psram_mc->REG_404, PSRAM_ULP_MC_WB_FILL_LEVEL);
882         if (level == 0) {
883             break;
884         }
885     } while (hal_sys_timer_get() - start < MS_TO_TICKS(1));
886 
887     ASSERT(level == 0, "%s: Drain timeout: level=%u status=0x%08X", __func__, level, psram_mc->REG_404);
888 
889     psram_mc->REG_044 |= PSRAM_ULP_MC_WB_INVALID;
890     __DSB();
891 }
892 
hal_psram_phy_restore_range(uint32_t range)893 static void hal_psram_phy_restore_range(uint32_t range)
894 {
895     uint32_t val;
896 
897     val = hal_psram_phy_read_reg(&psram_phy->REG_050);
898     val &= ~PSRAM_ULP_PHY_REG_DLL_RESETB | PSRAM_ULP_PHY_REG_DLL_CK_RDY;
899     psram_phy->REG_050 = val;
900     val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_DLL_RANGE, range);
901     psram_phy->REG_050 = val;
902     val |= PSRAM_ULP_PHY_REG_DLL_RESETB | PSRAM_ULP_PHY_REG_DLL_CK_RDY;
903     psram_phy->REG_050 = val;
904 }
905 
psram_mc_reset(uint32_t range)906 static void psram_mc_reset(uint32_t range)
907 {
908     hal_cmu_reset_set(HAL_CMU_MOD_H_PSRAM);
909     hal_cmu_reset_set(HAL_CMU_MOD_O_PSRAM);
910     hal_cmu_reset_clear(HAL_CMU_MOD_H_PSRAM);
911     hal_cmu_reset_clear(HAL_CMU_MOD_O_PSRAM);
912 
913     hal_cmu_mem_set_freq(HAL_CMU_FREQ_104M);
914     hal_psram_phy_init(psram_cfg_clk);
915     hal_sys_timer_delay_us(30);
916     hal_psram_mc_init(psram_cfg_clk);
917 #if !defined(FPGA) && !defined(SIMU)
918     hal_psram_init_calib();
919 #endif
920     psram_reset();
921     psram_chip_timing_config(psram_run_clk, true);
922     hal_psram_phy_restore_range(range);
923 #if !defined(FPGA) && !defined(SIMU)
924     hal_psram_init_calib();
925 #endif
926 
927     hal_psram_snoop_disable();
928 }
psramphy_check_tx_ceb_valid(uint32_t range)929 POSSIBLY_UNUSED static bool psramphy_check_tx_ceb_valid(uint32_t range)
930 {
931     int retry = 2;
932     while (retry--) {
933         int count = 0;
934         hal_psramip_flush_all_fifo();
935         hal_psramip_xfer_addr_len(0x100000, 8);
936         hal_psramip_set_cmd(MEMIF_READ);
937         while (hal_psramip_rx_fifo_empty()) {
938             if (count++ > 10) {
939                 //PSRAM_TRACE(1, "%s, rx fifo empty, return false", __FUNCTION__);
940                 psram_mc_reset(range);
941                 hal_psram_snoop_disable();
942                 return false;
943             }
944         }
945     }
946     return true;
947 }
psramphy_check_tx_clk_valid(uint32_t range)948 POSSIBLY_UNUSED static bool psramphy_check_tx_clk_valid(uint32_t range)
949 {
950     uint32_t time;
951     uint32_t val;
952 
953     time = hal_fast_sys_timer_get();
954     psram_mc->REG_01C = PSRAM_ULP_MC_MGR_TX_FIFO_CLR | PSRAM_ULP_MC_MGR_RX_FIFO_CLR;
955     hal_psramip_xfer_addr_len(0xAA55AA55, 1);
956     hal_psramip_set_cmd(MEMIF_READ);
957     while (hal_psramip_rx_fifo_empty()) {
958         if (FAST_TICKS_TO_US(hal_fast_sys_timer_get() - time) > 5) {
959             val = hal_psram_phy_read_reg(&psram_phy->REG_004);
960             val |= PSRAM_ULP_PHY_PHY_LOOPBACK_EN;
961             psram_phy->REG_004 = val;
962             while (hal_psramip_mc_busy());
963             val &= ~PSRAM_ULP_PHY_PHY_LOOPBACK_EN;
964             psram_phy->REG_004 = val;
965             return false;
966         }
967     }
968     return true;
969 }
psramphy_check_write_valid()970 static bool psramphy_check_write_valid()
971 {
972     uint32_t i;
973     uint32_t val, val0, val1;
974     uint32_t val2, val3;
975     volatile uint32_t *psram_base = (volatile uint32_t *)PSRAM_NC_BASE;
976     volatile uint32_t *psram_base1 = (volatile uint32_t *)(PSRAM_NC_BASE + 0x100000);
977 
978     for (i = 0; i < 0x100; ++i) {
979         *(psram_base + i) = 0xffffffff;
980         *(psram_base1 + i) = 0xffffffff;
981     }
982     for (i = 0; i < 0x100; ++i) {
983         val = i & 0xFF;
984         val = val | (val << 8) | (val << 16) | (val << 24);
985         val0 = (val & 0x00FF00FF) | ((~val) & 0xFF00FF00);
986         val1 = (val & 0xFF0000FF) | ((~val) & 0x00FFFF00);
987         *(psram_base + i) = val0;
988         *(psram_base1 + i) = val1;
989     }
990 
991     hal_psramip_wb_busy_wait();
992     hal_psramip_mc_busy_wait();
993     for (i = 0; i < 0x100; ++i) {
994         val = i & 0xFF;
995         val = val | (val << 8) | (val << 16) | (val << 24);
996         val0 = (val & 0x00FF00FF) | ((~val) & 0xFF00FF00);
997         val1 = (val & 0xFF0000FF) | ((~val) & 0x00FFFF00);
998         val2 = *(psram_base + i);
999         val3 = *(psram_base1 + i);
1000         if (val2 != val0) {
1001             //PSRAM_TRACE(3, "%s, i:%d, 0x%x, 0x%x", __FUNCTION__, i, val2, val0);
1002             return false;
1003         }
1004         if (val3 != val1) {
1005             //PSRAM_TRACE(3, "%s, i:%d, 0x%x, 0x%x", __FUNCTION__, i, val3, val1);
1006             return false;
1007         }
1008     }
1009     return true;
1010 }
1011 
hal_psram_calib_range(uint32_t range)1012 static void hal_psram_calib_range(uint32_t range)
1013 {
1014     #define BUFFER_SIZE  0x20
1015     uint32_t val;
1016     uint32_t delay;
1017     POSSIBLY_UNUSED uint8_t tx_dqs, rx_dqs, tx_ceb, tx_clk;
1018     uint8_t inc_delay, volume;
1019     POSSIBLY_UNUSED int8_t left_bound;
1020     POSSIBLY_UNUSED int8_t right_bound;
1021     bool cali_valid[BUFFER_SIZE][BUFFER_SIZE];
1022     uint8_t cali_value[BUFFER_SIZE][BUFFER_SIZE];
1023     POSSIBLY_UNUSED bool valid_array[BUFFER_SIZE];
1024 
1025 #ifdef PSRAM_WINDOW_TEST
1026     static int8_t last_left_bound = 0;
1027     static int8_t last_right_bound = 0;
1028     uint8_t dqs_point = 0;
1029     uint8_t dqs_len = 0;
1030     static uint8_t last_dqs_point = 0;
1031     static uint8_t last_dqs_len = 0;
1032     POSSIBLY_UNUSED static uint8_t cali_data[BUFFER_SIZE][BUFFER_SIZE];
1033 #endif
1034 
1035     ASSERT(range <= (PSRAM_ULP_PHY_REG_DLL_RANGE_MASK >> PSRAM_ULP_PHY_REG_DLL_RANGE_SHIFT), "ERROR, bad ana phy range:%d", range);
1036 
1037     val = hal_psram_phy_read_reg(&psram_phy->REG_050);
1038     val &= ~(PSRAM_ULP_PHY_REG_DLL_RESETB | PSRAM_ULP_PHY_REG_DLL_CK_RDY);
1039     psram_phy->REG_050 = val;
1040     val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_DLL_RANGE, range);
1041     psram_phy->REG_050 = val;
1042     hal_sys_timer_delay_us(100);
1043     val |= (PSRAM_ULP_PHY_REG_DLL_RESETB | PSRAM_ULP_PHY_REG_DLL_CK_RDY);
1044     psram_phy->REG_050 = val;
1045 
1046     hal_sys_timer_delay_us(100);
1047     hal_sys_timer_delay_us(100);
1048 
1049     hal_psram_phy_wait_lock();
1050 
1051     val = hal_psram_phy_read_reg(&psram_phy->REG_058);
1052     if ((val & PSRAM_ULP_PHY_DLL_ALL_ONE)) {
1053         PSRAM_TRACE(2, "%s: all one, increase range=%d", __func__, range + 1);
1054         return hal_psram_calib_range(range + 1);
1055     }
1056 
1057     delay = GET_BITFIELD(val, PSRAM_ULP_PHY_DLL_DLY_IN);
1058     PSRAM_TRACE(4, "%s, range:%d, T/4 = 0x%x(psram_phy->REG_058:0x%x)", __func__, range, delay / 2, val);
1059 #ifdef PSRAM_WINDOW_TEST
1060     TRACE_IMM(TR_ATTR_NO_LF | TR_ATTR_NO_TS | TR_ATTR_NO_ID, ", T/4=0x%02x", delay / 2);
1061 #endif
1062     if (delay > (PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY_MASK >> PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY_SHIFT) && range < 3) {
1063         PSRAM_TRACE(2, "%s: bad delay (T/2 > 0x1f). increase range=%d", __func__, range + 1);
1064         return hal_psram_calib_range(range + 1);
1065     }
1066 
1067     inc_delay = delay / 8;
1068     if (inc_delay == 0)
1069         inc_delay = 1;
1070 
1071 #if CHIP_PSRAM_CTRL_VER >= 3
1072     tx_ceb = delay / 2;
1073     tx_clk = delay / 2 + 2;
1074 #else /*CHIP_PSRAM_CTRL_VER == 2*/
1075     tx_ceb = delay * 5 / 6; // t/4 + t/6
1076     tx_clk = (delay * 11 + 8) / 16;// t/4 + t/8 - t/32
1077 #endif
1078 
1079     volume = (PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY_MASK >> PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY_SHIFT) / inc_delay;
1080     //PSRAM_TRACE(2, "volume:%d, inc_delay:%d", volume, inc_delay);
1081 
1082 #if 0
1083     //calibrate tx_ceb
1084     PSRAM_TRACE(0, "cali tx_ceb");
1085     left_bound = -1;
1086     right_bound = -1;
1087     memset(valid_array, 0, sizeof(valid_array));
1088     for (tx_ceb = 0; tx_ceb <= volume; tx_ceb++) {
1089         bool valid;
1090 
1091         psram_phy->REG_054 = PSRAM_ULP_PHY_REG_PSRAM_TX_CEB_DLY(tx_ceb * inc_delay) | PSRAM_ULP_PHY_REG_PSRAM_TX_CLK_DLY(delay / 2) |
1092                              PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY(delay / 2) | PSRAM_ULP_PHY_REG_PSRAM_RX_DQS_DLY(delay / 2);
1093 
1094         valid = psramphy_check_tx_ceb_valid(range);
1095         PSRAM_TRACE(3, "%s, tx_ceb:0x%x, valid:%d", __FUNCTION__, (tx_ceb * inc_delay), valid);
1096         valid_array[tx_ceb] = valid;
1097         if (tx_ceb == 0) {
1098             if (valid) {
1099                 left_bound = tx_ceb;
1100                 PSRAM_TRACE(1, "left_bound:0x%x", left_bound * inc_delay);
1101             }
1102         } else if (tx_ceb == volume) {
1103             if (valid) {
1104                 right_bound = tx_ceb;//find right bound
1105                 PSRAM_TRACE(1, "right_bound:0x%x", right_bound * inc_delay);
1106             } else {
1107                 if (valid_array[tx_ceb - 1]) {
1108                     right_bound = tx_ceb - 1; //find right bound
1109                     PSRAM_TRACE(1, "right_bound:0x%x", right_bound * inc_delay);
1110                 }
1111             }
1112         } else {
1113             if (valid && !valid_array[tx_ceb - 1]) {
1114                 left_bound = tx_ceb;//find left bound
1115                 PSRAM_TRACE(1, "left_bound:0x%x", left_bound * inc_delay);
1116             } else if (!valid && valid_array[tx_ceb - 1]) {
1117                 right_bound = tx_ceb - 1; //find right bound
1118                 PSRAM_TRACE(1, "right_bound:0x%x", right_bound * inc_delay);
1119                 break;
1120             }
1121         }
1122     }
1123     if (left_bound != -1 && right_bound != -1) { // && (right_bound-left_bound>1)) {
1124         tx_ceb = (left_bound + right_bound) / 2;
1125         PSRAM_TRACE(3, "cali tx_ceb done, tx_ceb:0x%x(0x%x-0x%x)", tx_ceb * inc_delay, left_bound * inc_delay, right_bound * inc_delay);
1126     } else {
1127         ASSERT(false, "ERROR, tx_ceb need do more cali");
1128     }
1129     tx_ceb *= inc_delay;
1130 #endif
1131 #if 0
1132     //calibrate tx_clk
1133     PSRAM_TRACE(0, "cali tx_clk");
1134     left_bound = -1;
1135     right_bound = -1;
1136     memset(valid_array, 0, sizeof(valid_array));
1137     for (tx_clk = 0; tx_clk <= volume; tx_clk++) {
1138         bool valid;
1139 
1140         psram_phy->REG_054 = PSRAM_ULP_PHY_REG_PSRAM_TX_CEB_DLY(tx_ceb) | PSRAM_ULP_PHY_REG_PSRAM_TX_CLK_DLY(tx_clk * inc_delay) |
1141                              PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY(delay / 2) | PSRAM_ULP_PHY_REG_PSRAM_RX_DQS_DLY(delay / 2);
1142         valid = psramphy_check_tx_ceb_valid(range);
1143         //PSRAM_TRACE(3, "%s, tx_clk:0x%x, valid:%d", __FUNCTION__, (tx_clk*inc_delay), valid);
1144         valid_array[tx_clk] = valid;
1145         if (tx_clk == 0) {
1146             if (valid) {
1147                 left_bound = tx_clk;
1148                 PSRAM_TRACE(1, "left_bound:0x%x", left_bound * inc_delay);
1149             }
1150         } else if (tx_clk == volume) {
1151             if (valid) {
1152                 right_bound = tx_clk;//find right bound
1153                 PSRAM_TRACE(1, "right_bound:0x%x", right_bound * inc_delay);
1154             } else {
1155                 if (valid_array[tx_clk - 1]) {
1156                     right_bound = tx_clk - 1; //find right bound
1157                     PSRAM_TRACE(1, "right_bound:0x%x", right_bound * inc_delay);
1158                 }
1159             }
1160         } else {
1161             if (valid && !valid_array[tx_clk - 1]) {
1162                 left_bound = tx_clk;//find left bound
1163                 PSRAM_TRACE(1, "left_bound:0x%x", left_bound * inc_delay);
1164             } else if (!valid && valid_array[tx_clk - 1]) {
1165                 right_bound = tx_clk - 1; //find right bound
1166                 PSRAM_TRACE(1, "right_bound:0x%x", right_bound * inc_delay);
1167                 break;
1168             }
1169         }
1170     }
1171     if (left_bound != -1 && right_bound != -1) { // && (right_bound-left_bound>1)) {
1172         tx_clk = (left_bound + right_bound) / 2;
1173         PSRAM_TRACE(3, "cali tx_clk done, tx_clk:0x%x(0x%x-0x%x)", tx_clk * inc_delay, left_bound * inc_delay, right_bound * inc_delay);
1174     } else {
1175         ASSERT(false, "ERROR, tx_clk need do more cali");
1176     }
1177     tx_clk *= inc_delay;
1178 #endif
1179 
1180 #ifdef PSRAM_WINDOW_TEST    //new added,Use when testing window,2021-08-28
1181     volume = (PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY_MASK >> PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY_SHIFT) / inc_delay;
1182     PSRAM_TRACE(2, "volume:%d, inc_delay:%d", volume, inc_delay);
1183 
1184     //calibrate tx_clk
1185     PSRAM_TRACE(0, "cali tx_clk");
1186     left_bound = -1;
1187     right_bound = -1;
1188     memset(valid_array, 0, sizeof(valid_array));
1189     for (tx_clk = 1; tx_clk <= volume; tx_clk++) {
1190         bool valid;
1191         tx_ceb = tx_clk - 1;
1192         psram_phy->REG_054 = PSRAM_ULP_PHY_REG_PSRAM_TX_CEB_DLY(tx_ceb * inc_delay) | PSRAM_ULP_PHY_REG_PSRAM_TX_CLK_DLY(tx_clk * inc_delay) |
1193                              PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY(delay / 2) | PSRAM_ULP_PHY_REG_PSRAM_RX_DQS_DLY(delay / 2);
1194         valid = psramphy_check_tx_clk_valid(range);
1195         //PSRAM_TRACE(3, "tx_clk:0x%x, valid:%d", (tx_clk*inc_delay), valid);
1196         valid_array[tx_clk] = valid;
1197         if (tx_clk == 1) {
1198             if (valid) {
1199                 left_bound = tx_clk;
1200                 PSRAM_TRACE(1, "left_bound:0x%x", left_bound * inc_delay);
1201             }
1202         } else if (tx_clk == volume) {
1203             if (valid) {
1204                 right_bound = tx_clk;//find right bound
1205                 PSRAM_TRACE(1, "right_bound:0x%x", right_bound * inc_delay);
1206             } else {
1207                 if (valid_array[tx_clk - 1]) {
1208                     right_bound = tx_clk - 1; //find right bound
1209                     PSRAM_TRACE(1, "right_bound:0x%x", right_bound * inc_delay);
1210                 }
1211             }
1212         } else {
1213             if (valid && !valid_array[tx_clk - 1]) {
1214                 left_bound = tx_clk;//find left bound
1215                 PSRAM_TRACE(1, "left_bound:0x%x", left_bound * inc_delay);
1216             } else if (!valid && valid_array[tx_clk - 1]) {
1217                 right_bound = tx_clk - 1; //find right bound
1218                 PSRAM_TRACE(1, "right_bound:0x%x", right_bound * inc_delay);
1219                 break;
1220             }
1221         }
1222     }
1223     if (left_bound != -1 && right_bound != -1) {// && (right_bound-left_bound>1)) {
1224         tx_clk = (left_bound + right_bound) / 2;
1225         PSRAM_TRACE(3, "cali tx_clk done, tx_clk:0x%x(0x%x-0x%x)", tx_clk * inc_delay, left_bound * inc_delay, right_bound * inc_delay);
1226 
1227 #ifdef PSRAM_WINDOW_TEST
1228         if ((last_left_bound != left_bound) || (last_right_bound != right_bound)) {
1229             last_left_bound = left_bound;
1230             last_right_bound = right_bound;
1231             TRACE_IMM(TR_ATTR_NO_LF | TR_ATTR_NO_TS | TR_ATTR_NO_ID, ", tx_clk:0x%02x(0x%02x-0x%02x)", tx_clk * inc_delay, left_bound * inc_delay, right_bound * inc_delay);
1232         } else {
1233             TRACE_IMM(TR_ATTR_NO_LF | TR_ATTR_NO_TS | TR_ATTR_NO_ID, ", **********************");
1234         }
1235 #endif
1236     } else {
1237         ASSERT(false, "ERROR, tx_clk need do more cali");
1238     }
1239     tx_ceb = (tx_clk - 1) * inc_delay;
1240     tx_clk = tx_clk * inc_delay;
1241 #endif
1242 
1243     PSRAM_TRACE(2, "tx_ceb:0x%x, tx_clk:0x%x", tx_ceb, tx_clk);
1244 
1245     volume = MIN(delay, (PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY_MASK >> PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY_SHIFT)) / inc_delay;
1246     PSRAM_TRACE(2, "volume:%d, inc_delay:%d", volume, inc_delay);
1247 
1248     //calibrate tx_dqs and rx_dqs
1249     uint8_t all_valid = 1;
1250     memset(cali_valid, 0, sizeof(cali_valid));
1251     for (tx_dqs = 0; tx_dqs <= volume; tx_dqs++) {
1252         for (rx_dqs = 0; rx_dqs <= volume; rx_dqs++) {
1253 #ifdef PSRAM_XCCELA_MODE
1254             psram_phy->REG_054 = PSRAM_ULP_PHY_REG_PSRAM_TX_CEB_DLY(tx_ceb) | PSRAM_ULP_PHY_REG_PSRAM_TX_CLK_DLY(tx_dqs * inc_delay) |
1255                                  PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY(0) | PSRAM_ULP_PHY_REG_PSRAM_RX_DQS_DLY(rx_dqs * inc_delay);
1256 #else
1257             psram_phy->REG_054 = PSRAM_ULP_PHY_REG_PSRAM_TX_CEB_DLY(tx_ceb) | PSRAM_ULP_PHY_REG_PSRAM_TX_CLK_DLY(tx_clk) |
1258                                  PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY(tx_dqs * inc_delay) | PSRAM_ULP_PHY_REG_PSRAM_RX_DQS_DLY(rx_dqs * inc_delay);
1259 #endif
1260             cali_valid[tx_dqs][rx_dqs] = psramphy_check_write_valid();
1261             //PSRAM_TRACE(3, "tx_dqs:0x%x, rx_dqs:0x%x, valid:%d", tx_dqs*inc_delay, rx_dqs*inc_delay, cali_valid[tx_dqs][rx_dqs]);
1262             if (cali_valid[tx_dqs][rx_dqs] == false)
1263                 all_valid = 0;
1264         }
1265     }
1266 
1267     if (all_valid && range < (PSRAM_ULP_PHY_DLL_DLY_IN_MASK >> PSRAM_ULP_PHY_DLL_DLY_IN_SHIFT)) {
1268         //PSRAM_TRACE(2, "%s: all valid increase range=%d", __func__, range+1);
1269         //return hal_psram_calib_range(range+1);
1270     }
1271 
1272     memset(cali_value, 0, sizeof(cali_value));
1273     PSRAM_TRACENOCRLF_NOTS(0, "\r\n\r\n ---------------------------------------------------------------------- \r\n");
1274     PSRAM_TRACENOCRLF_NOTS(0, "    rx_dqs");
1275     for (tx_dqs = 0; tx_dqs <= volume; tx_dqs++) {
1276         PSRAM_TRACENOCRLF_NOTS(1, " %2d ", tx_dqs * inc_delay);
1277     }
1278     PSRAM_TRACENOCRLF_NOTS(0, "\r\n");
1279     for (tx_dqs = 0; tx_dqs <= volume; tx_dqs++) {
1280         PSRAM_TRACENOCRLF_NOTS(1, "tx_dqs:%2d ", tx_dqs * inc_delay);
1281         for (rx_dqs = 0; rx_dqs <= volume; rx_dqs++) {
1282             PSRAM_TRACENOCRLF_NOTS(1, "  %d ", cali_valid[tx_dqs][rx_dqs]);
1283             if (cali_valid[tx_dqs][rx_dqs]) {
1284                 uint8_t len_from_zero;
1285                 int8_t p;
1286                 p = tx_dqs;
1287                 while (p >= 0) {
1288                     if (cali_valid[p][rx_dqs] == false)
1289                         break;
1290                     p--;
1291                 }
1292                 len_from_zero = tx_dqs - p;
1293                 cali_value[tx_dqs][rx_dqs] = len_from_zero;
1294 
1295                 p = tx_dqs;
1296                 while (p <= volume) {
1297                     if (cali_valid[p][rx_dqs] == false)
1298                         break;
1299                     p++;
1300                 }
1301                 len_from_zero = p - tx_dqs;
1302                 cali_value[tx_dqs][rx_dqs] = MIN(cali_value[tx_dqs][rx_dqs], len_from_zero);
1303 
1304                 p = rx_dqs;
1305                 while (p >= 0) {
1306                     if (cali_valid[tx_dqs][p] == false)
1307                         break;
1308                     p--;
1309                 }
1310                 len_from_zero = rx_dqs - p;
1311                 cali_value[tx_dqs][rx_dqs] = MIN(cali_value[tx_dqs][rx_dqs], len_from_zero);
1312 
1313                 p = rx_dqs;
1314                 while (p <= volume) {
1315                     if (cali_valid[tx_dqs][p] == false)
1316                         break;
1317                     p++;
1318                 }
1319                 len_from_zero = p - rx_dqs;
1320                 cali_value[tx_dqs][rx_dqs] = MIN(cali_value[tx_dqs][rx_dqs], len_from_zero);
1321             }
1322         }
1323         PSRAM_TRACENOCRLF_NOTS(0, "\r\n");
1324     }
1325     PSRAM_TRACENOCRLF_NOTS(0, " -------------------------------------------------------------------------- \r\n");
1326 
1327 #ifdef PSRAM_WINDOW_TEST
1328     //Processing window data
1329     uint8_t cp_volume = volume + 1;
1330     uint8_t enable_clear_circle = 0;
1331     uint8_t enable_print_window = 0;
1332     uint8_t rows;
1333 
1334 #if 1   //Window inner bag 0 test,2021-08-30
1335     #define HW_READ_REG(_Reg)           (*((volatile uint32_t*)(_Reg)))
1336     #define HW_WRITE_REG(_Reg,_Value)   (*((volatile uint32_t*)(_Reg)) = (uint32_t)(_Value))
1337     if (HW_READ_REG(0x400000F4) == 0xCAFE) {
1338         HW_WRITE_REG(0x400000F4, 0x9A55);
1339         cali_valid[4][4] = 0;//Central point clear
1340     }
1341 #endif
1342 
1343     for (tx_dqs = 0; tx_dqs < cp_volume; tx_dqs++) {
1344         for (rx_dqs = 0; rx_dqs < cp_volume; rx_dqs++) {
1345             cali_data[tx_dqs][rx_dqs] = cali_valid[tx_dqs][rx_dqs] + '0';
1346         }
1347     }
1348 
1349     if (cp_volume % 2) {
1350         rows = cp_volume / 2;
1351     } else {
1352         rows = cp_volume / 2 - 1;
1353     }
1354     for (tx_dqs = 0; tx_dqs < rows; tx_dqs++) {
1355         //Check the starting line
1356         for (rx_dqs = tx_dqs; rx_dqs < cp_volume - tx_dqs; rx_dqs++) {
1357             if (cali_data[tx_dqs][rx_dqs] == '0') {
1358                 break;
1359             }
1360         }
1361 
1362         if (rx_dqs >= cp_volume - tx_dqs) {
1363             //Check the end of the line
1364             for (rx_dqs = tx_dqs; rx_dqs < cp_volume - tx_dqs; rx_dqs++) {
1365                 if (cali_data[volume - tx_dqs][rx_dqs] == '0') {
1366                     break;
1367                 }
1368             }
1369             if (rx_dqs >= cp_volume - tx_dqs) {
1370                 //Check the starting column
1371                 for (rx_dqs = tx_dqs; rx_dqs < cp_volume - tx_dqs; rx_dqs++) {
1372                     if (cali_data[rx_dqs][tx_dqs] == '0') {
1373                         break;
1374                     }
1375                 }
1376                 if (rx_dqs >= cp_volume - tx_dqs) {
1377                     //Check the end of the column
1378                     for (rx_dqs = tx_dqs; rx_dqs < cp_volume - tx_dqs; rx_dqs++) {
1379                         if (cali_data[rx_dqs][volume - tx_dqs] == '0') {
1380                             break;
1381                         }
1382                     }
1383                     if (rx_dqs >= cp_volume - tx_dqs) {
1384                         enable_clear_circle = 0;
1385                     } else {
1386                         enable_clear_circle = 1;
1387                     }
1388                 } else {
1389                     enable_clear_circle = 1;
1390                 }
1391             } else {
1392                 enable_clear_circle = 1;
1393             }
1394         } else {
1395             enable_clear_circle = 1;
1396         }
1397 
1398         //The current line has 0, directly clear the current circle
1399         if (enable_clear_circle) {
1400             enable_clear_circle = 0;
1401 
1402             //clear the starting line
1403             for (rx_dqs = tx_dqs; rx_dqs < cp_volume - tx_dqs; rx_dqs++) {
1404                 cali_data[tx_dqs][rx_dqs] = ' ';
1405             }
1406 
1407             //clear the end of the line
1408             for (rx_dqs = tx_dqs; rx_dqs < cp_volume - tx_dqs; rx_dqs++) {
1409                 cali_data[volume - tx_dqs][rx_dqs] = ' ';
1410             }
1411 
1412             //clear the starting column
1413             for (rx_dqs = tx_dqs + 1; rx_dqs < cp_volume - tx_dqs - 1; rx_dqs++) {
1414                 cali_data[rx_dqs][tx_dqs] = ' ';
1415             }
1416 
1417             //clear the end of the column
1418             for (rx_dqs = tx_dqs + 1; rx_dqs < cp_volume - tx_dqs - 1; rx_dqs++) {
1419                 cali_data[rx_dqs][volume - tx_dqs] = ' ';
1420             }
1421         } else {
1422             //Check if there is 0 in the middle of the ring
1423             uint8_t i;
1424 
1425             enable_print_window = 0;
1426             for (i = tx_dqs; i < cp_volume - tx_dqs * 2 + tx_dqs; i++) {
1427                 //Check the remaining rows
1428                 for (rx_dqs = tx_dqs; rx_dqs < cp_volume - tx_dqs * 2 + tx_dqs; rx_dqs++) {
1429                     if (cali_data[i][rx_dqs] == '0') {
1430                         break;
1431                     }
1432                 }
1433                 if (rx_dqs < cp_volume - tx_dqs * 2 + tx_dqs) {
1434                     enable_print_window = 1;
1435                     break;
1436                 }
1437             }
1438             break;
1439         }
1440     }
1441 
1442     //Only the middle window is left, print it out forcibly
1443     if (tx_dqs >= rows) {
1444         enable_print_window = 1;
1445     }
1446 
1447     dqs_point = tx_dqs;
1448     dqs_len = cp_volume - tx_dqs * 2;
1449 
1450     if (last_dqs_point != dqs_point) {
1451         last_dqs_point = dqs_point;
1452 
1453         TRACE_IMM(TR_ATTR_NO_LF | TR_ATTR_NO_TS | TR_ATTR_NO_ID, ", rx_dqs:(%02d,%02d)~(%02d,%02d)",
1454                   dqs_point * inc_delay, dqs_point * inc_delay,
1455                   (dqs_point + dqs_len - 1)*inc_delay, dqs_point * inc_delay);
1456     } else {
1457         TRACE_IMM(TR_ATTR_NO_LF | TR_ATTR_NO_TS | TR_ATTR_NO_ID, ", ++++++++++++++++++++++");
1458     }
1459 
1460     if (last_dqs_len != dqs_len) {
1461         last_dqs_len = dqs_len;
1462 
1463         if (enable_print_window) {
1464             TRACE_IMM(TR_ATTR_NO_LF | TR_ATTR_NO_TS | TR_ATTR_NO_ID, ", tx_dqs:(%02d,%02d)~(%02d,%02d), abnormal",
1465                       dqs_point * inc_delay, dqs_point * inc_delay,
1466                       dqs_point * inc_delay, (dqs_point + dqs_len - 1)*inc_delay);
1467         } else {
1468             TRACE_IMM(TR_ATTR_NO_LF | TR_ATTR_NO_TS | TR_ATTR_NO_ID, ", tx_dqs:(%02d,%02d)~(%02d,%02d), normal",
1469                       dqs_point * inc_delay, dqs_point * inc_delay,
1470                       dqs_point * inc_delay, (dqs_point + dqs_len - 1)*inc_delay);
1471         }
1472     } else {
1473         if (enable_print_window) {
1474             TRACE_IMM(TR_ATTR_NO_LF | TR_ATTR_NO_TS | TR_ATTR_NO_ID, ", ----------------------, abnormal");
1475         } else {
1476             TRACE_IMM(TR_ATTR_NO_LF | TR_ATTR_NO_TS | TR_ATTR_NO_ID, ", ----------------------, ######");
1477         }
1478     }
1479     TRACE_IMM(TR_ATTR_NO_TS | TR_ATTR_NO_ID, ", vol:%02d, delay:%02d", volume, inc_delay);
1480 
1481     if (enable_print_window) {
1482         enable_print_window = 0;
1483 
1484         //Print original window data
1485         REL_TRACE_NOTS(0, " ");
1486         REL_TRACE_NOCRLF_NOTS(0, "   rx_dqs ");
1487         for (tx_dqs = 0; tx_dqs <= volume; tx_dqs++) {
1488             REL_TRACE_NOCRLF_NOTS(1, " %2d ", tx_dqs * inc_delay);
1489         }
1490         REL_TRACE_NOCRLF_NOTS(0, "\r\n");
1491         for (tx_dqs = 0; tx_dqs <= volume; tx_dqs++) {
1492             REL_TRACE_NOCRLF_NOTS(1, "tx_dqs:%2d ", tx_dqs * inc_delay);
1493             for (rx_dqs = 0; rx_dqs <= volume; rx_dqs++) {
1494                 REL_TRACE_NOCRLF_NOTS(1, "  %d ", cali_valid[tx_dqs][rx_dqs]);
1495             }
1496             REL_TRACE_NOCRLF_NOTS(0, "\r\n");
1497         }
1498         REL_TRACE_NOTS(0, " ");
1499 
1500         //Print new window data
1501         REL_TRACE_NOCRLF_NOTS(0, "   rx_dqs ");
1502         for (tx_dqs = 0; tx_dqs <= volume; tx_dqs++) {
1503             REL_TRACE_NOCRLF_NOTS(1, " %2d ", tx_dqs * inc_delay);
1504         }
1505         REL_TRACE_NOCRLF_NOTS(0, "\r\n");
1506         for (tx_dqs = 0; tx_dqs <= volume; tx_dqs++) {
1507             REL_TRACE_NOCRLF_NOTS(1, "tx_dqs:%2d ", tx_dqs * inc_delay);
1508             for (rx_dqs = 0; rx_dqs <= volume; rx_dqs++) {
1509                 REL_TRACE_NOCRLF_NOTS(1, "  %c ", cali_data[tx_dqs][rx_dqs]);
1510             }
1511             REL_TRACE_NOCRLF_NOTS(0, "\r\n");
1512         }
1513         REL_TRACE_NOTS(0, " ");
1514     }
1515 #endif
1516 
1517 #if 0
1518     //Print cali_value window data
1519     PSRAM_TRACENOCRLF_NOTS(0, "\r\n\r\n ---------------------------------------------------------------------- \r\n");
1520     PSRAM_TRACENOCRLF_NOTS(0, "    rx_dqs");
1521     for (tx_dqs = 0; tx_dqs <= volume; tx_dqs++) {
1522         PSRAM_TRACENOCRLF_NOTS(1, " %2d ", tx_dqs * inc_delay);
1523     }
1524     PSRAM_TRACENOCRLF_NOTS(0, "\r\n");
1525     for (tx_dqs = 0; tx_dqs <= volume; tx_dqs++) {
1526         PSRAM_TRACENOCRLF_NOTS(1, "tx_dqs:%2d ", tx_dqs * inc_delay);
1527         for (rx_dqs = 0; rx_dqs <= volume; rx_dqs++) {
1528             PSRAM_TRACENOCRLF_NOTS(1, "  %d ", cali_value[tx_dqs][rx_dqs]);
1529         }
1530         PSRAM_TRACENOCRLF_NOTS(0, "\r\n");
1531     }
1532     PSRAM_TRACENOCRLF_NOTS(0, " -------------------------------------------------------------------------- \r\n");
1533 #endif
1534 
1535     uint32_t position = 0;
1536     uint8_t max_value = 0;
1537     for (tx_dqs = 0; tx_dqs <= volume; tx_dqs++) {
1538         for (rx_dqs = 0; rx_dqs <= volume; rx_dqs++) {
1539             if (cali_value[tx_dqs][rx_dqs] > max_value) {
1540                 max_value = cali_value[tx_dqs][rx_dqs];
1541                 position = tx_dqs * (volume + 1) + rx_dqs;
1542             }
1543         }
1544     }
1545     PSRAM_TRACENOCRLF_NOTS(1, "position:%d\r\n", position);
1546     tx_dqs = position / (volume + 1) * inc_delay;
1547     rx_dqs = (position % (volume + 1)) * inc_delay;
1548     PSRAM_TRACENOCRLF_NOTS(2, "most optimal position. tx_dqs:%d, rx_dqs:%d\r\n", tx_dqs, rx_dqs);
1549 #ifdef PSRAM_XCCELA_MODE
1550     psram_phy->REG_054 = PSRAM_ULP_PHY_REG_PSRAM_TX_CEB_DLY(tx_ceb) | PSRAM_ULP_PHY_REG_PSRAM_TX_CLK_DLY(tx_dqs) |
1551                          PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY(0) | PSRAM_ULP_PHY_REG_PSRAM_RX_DQS_DLY(rx_dqs);
1552 #else
1553     psram_phy->REG_054 = PSRAM_ULP_PHY_REG_PSRAM_TX_CEB_DLY(tx_ceb) | PSRAM_ULP_PHY_REG_PSRAM_TX_CLK_DLY(tx_clk) |
1554                          PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY(tx_dqs) | PSRAM_ULP_PHY_REG_PSRAM_RX_DQS_DLY(rx_dqs);
1555 #endif
1556 
1557 #if 0
1558     volume = (PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY_MASK >> PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY_SHIFT) / inc_delay;
1559     PSRAM_TRACE(2, "volume:%d, inc_delay:%d", volume, inc_delay);
1560 
1561     //calibrate tx_clk
1562     PSRAM_TRACE(0, "cali tx_clk");
1563     left_bound = -1;
1564     right_bound = -1;
1565     memset(valid_array, 0, sizeof(valid_array));
1566     for (tx_clk = 1; tx_clk <= volume; tx_clk++) {
1567         bool valid;
1568         //tx_ceb = tx_clk;
1569         psram_phy->REG_054 = PSRAM_ULP_PHY_REG_PSRAM_TX_CEB_DLY(tx_ceb * inc_delay) | PSRAM_ULP_PHY_REG_PSRAM_TX_CLK_DLY(tx_clk * inc_delay) |
1570                              PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY(delay / 2) | PSRAM_ULP_PHY_REG_PSRAM_RX_DQS_DLY(delay / 2);
1571         valid = psramphy_check_write_valid(range);
1572         PSRAM_TRACE(3, "tx_clk:0x%x, valid:%d", (tx_clk * inc_delay), valid);
1573         valid_array[tx_clk] = valid;
1574         if (tx_clk == 1) {
1575             if (valid) {
1576                 left_bound = tx_clk;
1577                 PSRAM_TRACE(1, "left_bound:0x%x", left_bound * inc_delay);
1578             }
1579         } else if (tx_clk == volume) {
1580             if (valid) {
1581                 right_bound = tx_clk;//find right bound
1582                 PSRAM_TRACE(1, "right_bound:0x%x", right_bound * inc_delay);
1583             } else {
1584                 if (valid_array[tx_clk - 1]) {
1585                     right_bound = tx_clk - 1; //find right bound
1586                     PSRAM_TRACE(1, "right_bound:0x%x", right_bound * inc_delay);
1587                 }
1588             }
1589         } else {
1590             if (valid && !valid_array[tx_clk - 1]) {
1591                 left_bound = tx_clk;//find left bound
1592                 PSRAM_TRACE(1, "left_bound:0x%x", left_bound * inc_delay);
1593             } else if (!valid && valid_array[tx_clk - 1]) {
1594                 right_bound = tx_clk - 1; //find right bound
1595                 PSRAM_TRACE(1, "right_bound:0x%x", right_bound * inc_delay);
1596                 break;
1597             }
1598         }
1599     }
1600     if (left_bound != -1 && right_bound != -1) {// && (right_bound-left_bound>1)) {
1601         tx_clk = (left_bound + right_bound) / 2;
1602         PSRAM_TRACE(3, "cali tx_clk done, tx_clk:0x%x(0x%x-0x%x)", tx_clk * inc_delay, left_bound * inc_delay, right_bound * inc_delay);
1603     } else {
1604         ASSERT(false, "ERROR, tx_clk need do more cali");
1605     }
1606     //tx_ceb = tx_clk * inc_delay;
1607     tx_clk = tx_clk * inc_delay;
1608 #endif
1609 }
hal_psram_calib(uint32_t clk)1610 void hal_psram_calib(uint32_t clk)
1611 {
1612     uint32_t phy_clk;
1613     uint32_t range;
1614     PSRAM_TRACE(2, "%s, speed:%d", __func__, clk);
1615     phy_clk = clk;
1616     if (phy_clk <= 100000000 / 2) {
1617         range = 3;
1618     } else if (phy_clk <= 150000000 / 2) {
1619         range = 2;
1620     } else if (phy_clk <= 300000000 / 2) {
1621         range = 1;
1622     } else {
1623         range = 1;
1624     }
1625 #ifdef PSRAM_WINDOW_TEST
1626     TRACE_IMM(TR_ATTR_NO_LF, "clk:%d, range:%d", clk, range);
1627 #endif
1628     hal_psram_calib_range(range);
1629 }
1630 
hal_psram_init(void)1631 void hal_psram_init(void)
1632 {
1633     hal_cache_wrap_enable(HAL_CACHE_ID_I_CACHE);
1634     hal_cache_wrap_enable(HAL_CACHE_ID_D_CACHE);
1635 
1636     hal_cmu_mem_set_freq(HAL_CMU_FREQ_104M);
1637     hal_cmu_clock_enable(HAL_CMU_MOD_O_PSRAM);
1638     hal_cmu_clock_enable(HAL_CMU_MOD_H_PSRAM);
1639     hal_cmu_reset_clear(HAL_CMU_MOD_O_PSRAM);
1640     hal_cmu_reset_clear(HAL_CMU_MOD_H_PSRAM);
1641 
1642 #ifndef FPGA
1643     hal_psram_phy_init(psram_cfg_clk);
1644     hal_sys_timer_delay_us(100);
1645 #endif
1646     hal_psram_digphy_init();
1647     hal_psram_mc_init(psram_cfg_clk);
1648 #if !defined(FPGA) && !defined(SIMU)
1649     hal_psram_init_calib();
1650 #endif
1651 
1652 #ifdef PSRAM_RESET
1653     psram_reset();
1654     psram_chip_timing_config(psram_run_clk, true);
1655 #else
1656     uint32_t reg;
1657     uint32_t val;
1658 
1659     reg = 4;
1660     psram_read_reg(reg, &val);
1661     if (val & MR4_WL) {
1662         psram_chip_timing_config(psram_run_clk, false);
1663     } else {
1664         psram_chip_timing_config(psram_run_clk, true);
1665     }
1666 #endif
1667 
1668     hal_psram_snoop_disable();
1669 #if !defined(FPGA) && !defined(SIMU)
1670     hal_psram_calib(psram_run_clk);
1671 #endif
1672     hal_psram_snoop_enable();
1673 }
1674 
1675 #endif
1676 
1677