• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 ASR Microelectronics (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 
16 #include "duet_psram.h"
17 #include "duet_pinmux.h"
18 
19 #define PSRAM_CMD_STOP           0
20 #define PSRAM_CMD_CMD            1
21 #define PSRAM_CMD_ADDR           2
22 #define PSRAM_CMD_DUMMY          3
23 #define PSRAM_CMD_MODE           4
24 #define PSRAM_CMD_MODE2          5
25 #define PSRAM_CMD_MODE4          6
26 #define PSRAM_CMD_READ           7
27 #define PSRAM_CMD_WRITE          8
28 #define PSRAM_CMD_JMP_ON_CS      9
29 #define PSRAM_CMD_ADDR_DDR       10
30 #define PSRAM_CMD_MODE_DDR       11
31 #define PSRAM_CMD_MODE2_DDR      12
32 #define PSRAM_CMD_MODE4_DDR      13
33 #define PSRAM_CMD_READ_DDR       14
34 #define PSRAM_CMD_WRITE_DDR      15
35 #define PSRAM_CMD_DATA_LEARN     16
36 #define PSRAM_CMD_CMD_DDR        17
37 #define PSRAM_CMD_CADDR          18
38 #define PSRAM_CMD_CADDR_DDR      19
39 
40 #define PSRAM_SEQ_ID_READ        5
41 #define PSRAM_SEQ_ID_WRITE_EVICT 6
42 #define PSRAM_SEQ_ID_WRITE       7
43 #define PSRAM_SEQ_ID_READ_ID     8
44 #define PSRAM_SEQ_ID_QUAD_ENABLE 9
45 #define PSRAM_SEQ_ID_QUAD_EXIT   10
46 #define PSRAM_SEQ_ID_MODE_REG_READ   11
47 #define PSRAM_SEQ_ID_MODE_REG_WRITE  12
48 
49 int mode_config = -1;
50 
psram_wait_finish(void)51 static void psram_wait_finish(void)
52 {
53     while (REG_RD(PSRAM_SR) & 0x2);
54     while (!(REG_RD(PSRAM_FR) & 0x1));
55     REG_WR(PSRAM_FR, 1);
56 }
57 
psram_init_lut_ps_read(unsigned int seq_id)58 static void psram_init_lut_ps_read(unsigned int seq_id)
59 {
60     REG_WR((PSRAM_LUT0 + 0x10 * seq_id),
61            ((PSRAM_CMD_ADDR << 26) | (0x0 << 24) | (0x18 << 16) | (PSRAM_CMD_CMD << 10) | (0x0 << 8) | FLASH_CMD_READ));
62     REG_WR((PSRAM_LUT1 + 0x10 * seq_id),
63            ((PSRAM_CMD_JMP_ON_CS << 26) | (0x0 << 24) | (0x00 << 16) | (PSRAM_CMD_READ << 10) | (0x0 << 8) | 0x20));
64     REG_WR((PSRAM_LUT2 + 0x10 * seq_id), 0);
65     REG_WR((PSRAM_LUT3 + 0x10 * seq_id), 0);
66 }
67 
psram_init_lut_ps_write(unsigned int seq_id)68 static void psram_init_lut_ps_write(unsigned int seq_id)
69 {
70     REG_WR((PSRAM_LUT0 + 0x10 * seq_id),
71            ((PSRAM_CMD_ADDR << 26) | (0x0 << 24) | (0x18 << 16) | (PSRAM_CMD_CMD << 10) | (0x0 << 8) | FLASH_CMD_WRITE));
72     REG_WR((PSRAM_LUT1 + 0x10 * seq_id),
73            ((PSRAM_CMD_JMP_ON_CS << 26) | (0x0 << 24) | (0x00 << 16) | (PSRAM_CMD_WRITE << 10) | (0x0 << 8) | 0x20));
74     REG_WR((PSRAM_LUT2 + 0x10 * seq_id), 0);
75     REG_WR((PSRAM_LUT3 + 0x10 * seq_id), 0);
76 }
77 
psram_init_lut_ps_write_evict(unsigned int seq_id)78 static void psram_init_lut_ps_write_evict(unsigned int seq_id)
79 {
80     REG_WR((PSRAM_LUT0 + 0x10 * seq_id),
81            ((PSRAM_CMD_ADDR << 26) | (0x0 << 24) | (0x18 << 16) | (PSRAM_CMD_CMD << 10) | (0x0 << 8) | FLASH_CMD_WRITE));
82     REG_WR((PSRAM_LUT1 + 0x10 * seq_id), ((PSRAM_CMD_JMP_ON_CS << 26) | (0 << 24) | (0x00 << 16) | (21 << 10) | (0 << 8) | 0x20));
83     REG_WR((PSRAM_LUT2 + 0x10 * seq_id), 0);
84     REG_WR((PSRAM_LUT3 + 0x10 * seq_id), 0);
85 }
86 
psram_init_lut_ps_mode_register_read(unsigned int seq_id)87 static void psram_init_lut_ps_mode_register_read(unsigned int seq_id)
88 {
89     REG_WR((PSRAM_LUT0 + 0x10 * seq_id),
90            ((PSRAM_CMD_ADDR << 26) | (0x0 << 24) | (0x18 << 16) | (PSRAM_CMD_CMD << 10) | (0x0 << 8) | FLASH_CMD_MODE_REG_READ));
91     REG_WR((PSRAM_LUT1 + 0x10 * seq_id),
92            ((PSRAM_CMD_READ << 26) | (0x0 << 24) | (0x2 << 16) | (PSRAM_CMD_DUMMY << 10) | (0x0 << 8) | (8 - 1)));
93     REG_WR((PSRAM_LUT2 + 0x10 * seq_id), ((PSRAM_CMD_JMP_ON_CS << 10) | (0x0 << 8) | 0x0));
94     REG_WR((PSRAM_LUT3 + 0x10 * seq_id), 0);
95 }
96 
psram_init_lut_ps_mode_register_write(unsigned int seq_id)97 static void psram_init_lut_ps_mode_register_write(unsigned int seq_id)
98 {
99     REG_WR((PSRAM_LUT0 + 0x10 * seq_id),
100            ((PSRAM_CMD_ADDR << 26) | (0x0 << 24) | (0x18 << 16) | (PSRAM_CMD_CMD << 10) | (0x0 << 8) | FLASH_CMD_MODE_REG_WRITE));
101     REG_WR((PSRAM_LUT1 + 0x10 * seq_id),
102            ((PSRAM_CMD_JMP_ON_CS << 26) | (0x0 << 24) | (0x00 << 16) | (PSRAM_CMD_WRITE << 10) | (0x0 << 8) | 0x20));
103     REG_WR((PSRAM_LUT2 + 0x10 * seq_id), 0);
104     REG_WR((PSRAM_LUT3 + 0x10 * seq_id), 0);
105 }
106 
psram_init_lut_ps_qmode_enable(unsigned int seq_id)107 static void psram_init_lut_ps_qmode_enable(unsigned int seq_id)
108 {
109     REG_WR((PSRAM_LUT0 + 0x10 * seq_id), ((PSRAM_CMD_CMD << 10) | (0 << 8) | FLASH_CMD_ENTER_QUAD_MODE));
110     REG_WR((PSRAM_LUT1 + 0x10 * seq_id), 0);
111     REG_WR((PSRAM_LUT2 + 0x10 * seq_id), 0);
112     REG_WR((PSRAM_LUT3 + 0x10 * seq_id), 0);
113 }
114 
psram_init_lut_ps_qmode_exit(unsigned int seq_id)115 static void psram_init_lut_ps_qmode_exit(unsigned int seq_id)
116 {
117     REG_WR((PSRAM_LUT0 + 0x10 * seq_id), ((PSRAM_CMD_CMD << 10) | (0x2 << 8) | FLASH_CMD_EXIT_QUAD_MODE));
118     REG_WR((PSRAM_LUT1 + 0x10 * seq_id), 0);
119     REG_WR((PSRAM_LUT2 + 0x10 * seq_id), 0);
120     REG_WR((PSRAM_LUT3 + 0x10 * seq_id), 0);
121 }
122 
psram_init_lut_ps_read_4x(unsigned int seq_id)123 static void psram_init_lut_ps_read_4x(unsigned int seq_id)
124 {
125     REG_WR((PSRAM_LUT0 + 0x10 * seq_id),
126            ((PSRAM_CMD_ADDR << 26) | (0x2 << 24) | (0x18 << 16) | (PSRAM_CMD_CMD << 10) | (0x2 << 8) | FLASH_CMD_FAST_READ_QUAD));
127     REG_WR((PSRAM_LUT1 + 0x10 * seq_id),
128            ((PSRAM_CMD_READ << 26) | (0x2 << 24) | (0x20 << 16) | (PSRAM_CMD_DUMMY << 10) | (0x2 << 8) | (6 - 1)));
129     REG_WR((PSRAM_LUT2 + 0x10 * seq_id), ((PSRAM_CMD_JMP_ON_CS << 10) | (0x2 << 8) | 0x00));
130     REG_WR((PSRAM_LUT3 + 0x10 * seq_id), 0);
131 }
132 
psram_init_lut_ps_write_4x(unsigned int seq_id)133 static void psram_init_lut_ps_write_4x(unsigned int seq_id)
134 {
135     REG_WR((PSRAM_LUT0 + 0x10 * seq_id),
136            ((PSRAM_CMD_ADDR << 26) | (0x2 << 24) | (0x18 << 16) | (PSRAM_CMD_CMD << 10) | (0x2 << 8) | FLASH_CMD_WRITE));
137     REG_WR((PSRAM_LUT1 + 0x10 * seq_id),
138            ((PSRAM_CMD_JMP_ON_CS << 26) | (0x2 << 24) | (0x00 << 16) | (PSRAM_CMD_WRITE << 10) | (0x2 << 8) | 0x20));
139     REG_WR((PSRAM_LUT2 + 0x10 * seq_id), 0);
140     REG_WR((PSRAM_LUT3 + 0x10 * seq_id), 0);
141 }
142 
psram_init_lut_ps_write_evict_4x(unsigned int seq_id)143 static void psram_init_lut_ps_write_evict_4x(unsigned int seq_id)
144 {
145     REG_WR((PSRAM_LUT0 + 0x10 * seq_id),
146            ((PSRAM_CMD_ADDR << 26) | (0x2 << 24) | (0x18 << 16) | (PSRAM_CMD_CMD << 10) | (0x2 << 8) | FLASH_CMD_WRITE));
147     REG_WR((PSRAM_LUT1 + 0x10 * seq_id), ((PSRAM_CMD_JMP_ON_CS << 26) | (0x2 << 24) | (0x00 << 16) | (21 << 10) | (0x2 << 8) | 0x20));
148     REG_WR((PSRAM_LUT2 + 0x10 * seq_id), 0);
149     REG_WR((PSRAM_LUT3 + 0x10 * seq_id), 0);
150 }
151 
psram_init_lut_ps_readid(unsigned int seq_id)152 static void psram_init_lut_ps_readid(unsigned int seq_id)
153 {
154     REG_WR((PSRAM_LUT0 + 0x10 * seq_id),
155            ((PSRAM_CMD_ADDR << 26) | (0x0 << 24) | (0x18 << 16) | (PSRAM_CMD_CMD << 10) | (0x0 << 8) | FLASH_CMD_READ_ID));
156     REG_WR((PSRAM_LUT1 + 0x10 * seq_id), ((PSRAM_CMD_READ << 10) | (0x0 << 8) | 0x9));
157     REG_WR((PSRAM_LUT2 + 0x10 * seq_id), 0);
158     REG_WR((PSRAM_LUT3 + 0x10 * seq_id), 0);
159 }
160 
psram_set_channel(duet_psram_channel channel)161 int psram_set_channel(duet_psram_channel channel)
162 {
163     if (channel != PSRAM_CHANNEL_4_9 && channel != PSRAM_CHANNEL_16_21) {
164         return -1;
165     }
166     REG_WR(ADC_SDIO_BLE_DEBUG_CTRL_REG, REG_RD(ADC_SDIO_BLE_DEBUG_CTRL_REG) & (~(1 << 3))); // disable sdio debug
167     if (channel == PSRAM_CHANNEL_4_9) {
168         duet_pinmux_config(PAD4, PF_PSRAM); // set pad4 mux to psram
169         duet_pinmux_config(PAD5, PF_PSRAM); // set pad5 mux to psram
170         duet_pinmux_config(PAD6, PF_PSRAM); // set pad6 mux to psram
171         duet_pinmux_config(PAD7, PF_PSRAM); // set pad7 mux to psram
172         duet_pinmux_config(PAD8, PF_PSRAM); // set pad8 mux to psram
173         duet_pinmux_config(PAD9, PF_PSRAM); // set pad9 mux to psram
174         REG_WR(HW_CTRL_PE_PS,REG_RD(HW_CTRL_PE_PS)& 0xfffffc0f); // set all pad pull up and down
175     } else { // set
176         duet_pinmux_config(PAD16, PF_PSRAM); // sett pad16 mux to psram
177         duet_pinmux_config(PAD17, PF_PSRAM); // set pad17 mux to psr// set
178         duet_pinmux_config(PAD18, PF_PSRAM); // set pad18 mux to psram
179         duet_pinmux_config(PAD19, PF_PSRAM); // set pad19 mux to psram
180         duet_pinmux_config(PAD20, PF_PSRAM); // set pad20 mux to psram
181         duet_pinmux_config(PAD21, PF_PSRAM); // set pad21 mux to psram
182         REG_WR(HW_CTRL_PE_PS,REG_RD(HW_CTRL_PE_PS)& 0xffc0ffff); // set all pad pull up and down
183     }// set
184     REG_WR(PERI_CLK_EN_REG0, (REG_RD(PERI_CLK_EN_REG0) | (0x0000203F))); //open clock of dma and psram
185 
186     return 0; // set
187 }
psram_config(duet_psram_mode mode)188 int psram_config(duet_psram_mode mode)
189 {
190     if (mode != PSRAM_MODE_SPI && mode != PSRAM_MODE_QSPI) {
191         return -1;
192     }
193     REG_WR(PSRAM_MCR, REG_RD(PSRAM_MCR) & (~(1 << 14))); // MCR,MDIS = 0
194 
195     REG_WR(PSRAM_MCR, REG_RD(PSRAM_MCR) | ((3))); // MCR , AHB and SF domain reset
196 
197     REG_WR(PSRAM_MCR, REG_RD(PSRAM_MCR) & 0xfffffffc); // clear AHB and SF reset
198 
199     REG_WR(PSRAM_MCR, REG_RD(PSRAM_MCR) | 1 << 14); // MCR , MDIS=1
200 
201     if (mode == PSRAM_MODE_SPI) { // the simple logic has been modified. set bit7 means to use the original logic
202         REG_WR(PSRAM_SMPR, 0x00000080);    // sampled by sfif_clk_b; half cycle delay
203     } else {
204         REG_WR(PSRAM_SMPR, 0x00000000);    // sampled by sfif_clk_b; half cycle delay
205     }
206 
207     REG_WR(PSRAM_FLSHCR, 0x00000000);  // set setup and hold time for psram
208 
209     // Give the default source address:
210     REG_WR(PSRAM_SFAR, PSRAM_FLASH_A1_BASE);  // set IDATSIZ
211 
212     // lijin: 2018_01_11-11:07 total buffer size is 64*64b = 512B = 0x200B
213     // config the ahb buffer// set
214     REG_WR(PSRAM_BUF0IND, 0x00000080);
215     REG_WR(PSRAM_BUF1IND, 0x00000100);
216     REG_WR(PSRAM_BUF2IND, 0x00000180);
217 
218     // lijin: 2018_01_11-11:07 each buffer is 8B * 16 = 128B = 0x80B
219 
220     // kzheng: TO DO, now hmaster[3:0] tie0, so need modified here
221     // mst id =0 is CPU
222     // PSRAM0_BUF0CR = 0x00001001; // CPU A9
223     REG_WR(PSRAM_BUF0CR, 0x00001000);  // CPU A9
224     REG_WR(PSRAM_BUF1CR, 0x00001006);  // CPU M4
225     REG_WR(PSRAM_BUF2CR, 0x00001003);  // SDMA
226     REG_WR(PSRAM_BUF3CR, 0x80001002);  // other masters
227 
228     // config the flash mmap
229     REG_WR(PSRAM_SFA1AD, PSRAM_FLASH_A1_TOP & 0xfffffc00);
230     REG_WR(PSRAM_SFA2AD, PSRAM_FLASH_A2_TOP & 0xfffffc00);
231     REG_WR(PSRAM_SFB1AD, PSRAM_FLASH_B1_TOP & 0xfffffc00);
232     REG_WR(PSRAM_SFB2AD, PSRAM_FLASH_B2_TOP & 0xfffffc00);
233 
234     // ISD3FB, ISD2FB, ISD3FA, ISD2FA = 1; ENDIAN = 'h3; END_CFG='h3
235     // DELAY_CLK4X_EN = 1
236     REG_WR(PSRAM_MCR, REG_RD(PSRAM_MCR) | 0x000F000C);
237 
238     // ddr_en   data aligned with 2x serial flash half clock
239     // REG_WR(PSRAM_FLSHCR, REG_RD(PSRAM_FLSHCR)| 0x00010000);
240 
241     // MCR SCLKCFG 0, dqs en =1
242     REG_WR(PSRAM_MCR, REG_RD(PSRAM_MCR) & 0xfbffffff);
243 
244     // dqs_loopback_en = 1, dqs_loopback_from_pad = 1
245     REG_WR(PSRAM_MCR, REG_RD(PSRAM_MCR) | (3 << 24));
246 
247     // ddr_en = 1, enable 2x and 4x clock
248     /// REG_WR(PSRAM_MCR, REG_RD(PSRAM_MCR)| 1<<7);
249 
250     // MDIS = 0, enable psram clocks,must clear MDIS to enable clock for transfer.
251     REG_WR(PSRAM_MCR, REG_RD(PSRAM_MCR) & 0xffffbfff);
252 
253     // printf("PSRAM initialize done. \n");
254     // printf("begin initialize LUT tables. \n");
255 
256     if (mode == PSRAM_MODE_SPI) {
257         psram_init_lut_ps_read(0);
258         psram_init_lut_ps_read(PSRAM_SEQ_ID_READ);
259         psram_init_lut_ps_write_evict(PSRAM_SEQ_ID_WRITE_EVICT);
260         psram_init_lut_ps_write(PSRAM_SEQ_ID_WRITE);
261         psram_init_lut_ps_readid(PSRAM_SEQ_ID_READ_ID);
262         psram_init_lut_ps_mode_register_read(PSRAM_SEQ_ID_MODE_REG_READ);
263         psram_init_lut_ps_mode_register_write(PSRAM_SEQ_ID_MODE_REG_WRITE);
264     } else {
265         psram_init_lut_ps_read_4x(0);
266         psram_init_lut_ps_read_4x(PSRAM_SEQ_ID_READ);
267         psram_init_lut_ps_write_evict_4x(PSRAM_SEQ_ID_WRITE_EVICT);
268         psram_init_lut_ps_write_4x(PSRAM_SEQ_ID_WRITE);
269     }
270     psram_init_lut_ps_qmode_enable(PSRAM_SEQ_ID_QUAD_ENABLE);
271     psram_init_lut_ps_qmode_exit(PSRAM_SEQ_ID_QUAD_EXIT);
272 
273     // printf(" initialize LUT tables done. \n");
274 
275     // set read miss cmd, evict is in next lut
276     REG_WR(PSRAM_BFGENCR, PSRAM_SEQ_ID_READ << 12);
277 
278     if (mode_config != mode) {
279         if (mode == PSRAM_MODE_SPI) {
280             REG_WR(PSRAM_SFAR, PSRAM_AMBA_BASE);
281             REG_WR(PSRAM_IPCR, PSRAM_SEQ_ID_QUAD_EXIT << 24);
282             psram_wait_finish();
283         } else {
284             REG_WR(PSRAM_SFAR, PSRAM_AMBA_BASE);
285             REG_WR(PSRAM_IPCR, PSRAM_SEQ_ID_QUAD_ENABLE << 24);
286             psram_wait_finish();
287         }
288     }
289     mode_config = mode;
290     return 0;
291 }
292