1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2013-05-19     Bernard      The first version for LPC40xx
9  */
10 
11 #include <rtthread.h>
12 
13 #ifdef BSP_USING_SDRAM
14 #include "drv_sdram.h"
15 
16 #include <lpc_emc.h>
17 #include <lpc_timer.h>
18 
sdram_gpio_config(void)19 static void  sdram_gpio_config(void)
20 {
21     LPC_IOCON->P3_0 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D0 @ P3.0 */
22     LPC_IOCON->P3_1 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D1 @ P3.1 */
23     LPC_IOCON->P3_2 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D2 @ P3.2 */
24     LPC_IOCON->P3_3 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D3 @ P3.3 */
25 
26     LPC_IOCON->P3_4 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D4 @ P3.4 */
27     LPC_IOCON->P3_5 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D5 @ P3.5 */
28     LPC_IOCON->P3_6 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D6 @ P3.6 */
29     LPC_IOCON->P3_7 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D7 @ P3.7 */
30 
31     LPC_IOCON->P3_8 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D8 @ P3.8 */
32     LPC_IOCON->P3_9 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D9 @ P3.9 */
33     LPC_IOCON->P3_10 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D10 @ P3.10 */
34     LPC_IOCON->P3_11 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D11 @ P3.11 */
35 
36     LPC_IOCON->P3_12 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D12 @ P3.12 */
37     LPC_IOCON->P3_13 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D13 @ P3.13 */
38     LPC_IOCON->P3_14 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D14 @ P3.14 */
39     LPC_IOCON->P3_15 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D15 @ P3.15 */
40 
41 
42     LPC_IOCON->P4_0 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A0 @ P4.0 */
43     LPC_IOCON->P4_1 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A1 @ P4.1 */
44     LPC_IOCON->P4_2 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A2 @ P4.2 */
45     LPC_IOCON->P4_3 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A3 @ P4.3 */
46 
47     LPC_IOCON->P4_4 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A4 @ P4.4 */
48     LPC_IOCON->P4_5 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A5 @ P4.5 */
49     LPC_IOCON->P4_6 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A6 @ P4.6 */
50     LPC_IOCON->P4_7 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A7 @ P4.7 */
51 
52     LPC_IOCON->P4_8 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A8 @ P4.8 */
53     LPC_IOCON->P4_9 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A9 @ P4.9 */
54     LPC_IOCON->P4_10 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A10 @ P4.10 */
55     LPC_IOCON->P4_11 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A11 @ P4.11 */
56 
57     LPC_IOCON->P4_12 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A12 @ P4.12 */
58     LPC_IOCON->P4_13 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A13 @ P4.13 */
59     LPC_IOCON->P4_14 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A14 @ P4.14 */
60 
61     LPC_IOCON->P4_25 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* WEN @ P4.25 */
62 
63     LPC_IOCON->P2_16 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* CASN @ P2.16 */
64     LPC_IOCON->P2_17 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* RASN @ P2.17 */
65     LPC_IOCON->P2_18 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* CLK[0] @ P2.18 */
66     LPC_IOCON->P2_19 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* CLK[1] @ P2.19 */
67 
68     LPC_IOCON->P2_20 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* DYCSN[0] @ P2.20 */
69     LPC_IOCON->P2_24 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* CKE[0] @ P2.24 */
70 
71     LPC_IOCON->P2_28 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* DQM[0] @ P2.28 */
72     LPC_IOCON->P2_29 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* DQM[1] @ P2.29 */
73 }
74 
rt_hw_sdram_init(void)75 void rt_hw_sdram_init(void)
76 {
77     volatile uint32_t i;
78     volatile uint32_t dwtemp;
79     uint16_t wtemp = wtemp;
80     TIM_TIMERCFG_Type TIM_ConfigStruct;
81 
82     TIM_ConfigStruct.PrescaleOption = TIM_PRESCALE_USVAL;
83     TIM_ConfigStruct.PrescaleValue  = 1;
84 
85     /* Set configuration for Tim_config and Tim_MatchConfig */
86     TIM_Init(LPC_TIM0, TIM_TIMER_MODE, &TIM_ConfigStruct);
87 
88     LPC_SC->PCONP      |= 0x00000800;
89     LPC_SC->EMCDLYCTL   = 0x00001010;
90     LPC_EMC->Control = 0x00000001;
91     LPC_EMC->Config  = 0x00000000;
92 
93     sdram_gpio_config();
94 
95     LPC_EMC->DynamicRP         = EMC_NS2CLK(20);        /* 20ns  */
96     LPC_EMC->DynamicRAS        =  15;                   /* EMC_NS2CLK(42, nsPerClk),42ns to 100K ns  */
97     LPC_EMC->DynamicSREX       = 1 - 1;                 /* tSRE, 1clk */
98     LPC_EMC->DynamicAPR        = 2 - 1;                 /* Not found!!! Estimated as 2clk */
99     LPC_EMC->DynamicDAL        = EMC_NS2CLK(20) + 2;    /* tDAL = tRP + tDPL = 20ns + 2clk  */
100     LPC_EMC->DynamicWR         = 2 - 1;                 /* 2CLK */
101     LPC_EMC->DynamicRC         = EMC_NS2CLK(63);        /* H57V2562GTR-75C tRC=63ns(min)*/
102     LPC_EMC->DynamicRFC        = EMC_NS2CLK(63);        /* H57V2562GTR-75C tRFC=tRC */
103     LPC_EMC->DynamicXSR        = 0x0000000F;            /* exit self-refresh to active */
104     LPC_EMC->DynamicRRD        = EMC_NS2CLK(63);        /* 3clk, tRRD=15ns(min) */
105     LPC_EMC->DynamicMRD        = 2 - 1;                 /* 2clk, tMRD=2clk(min) */
106 
107     LPC_EMC->DynamicReadConfig = 0x00000001;            /* Command delayed strategy, using EMCCLKDELAY */
108     /* H57V2562GTR-75C: tCL=3CLK, tRCD=20ns(min), 3 CLK=24ns */
109     LPC_EMC->DynamicRasCas0    = 0x303;
110 
111     /* For Manley lpc1778 SDRAM: H57V2562GTR-75C, 256Mb, 16Mx16, 4 banks, row=13, column=9 */
112 #ifdef SDRAM_CONFIG_16BIT
113     LPC_EMC->DynamicConfig0    = 0x680;                 /* 256Mb, 16Mx16, 4 banks, row=13, column=9, RBC */
114 #elif defined SDRAM_CONFIG_32BIT
115     LPC_EMC->DynamicConfig0 = 0x4680;                   /* 256Mb, 16Mx16, 4 banks, row=13, column=9, RBC */
116 #endif
117     TIM_Waitms(100);
118 
119     LPC_EMC->DynamicControl    = 0x00000183;            /* Issue NOP command */
120     TIM_Waitms(200);                                    /* wait 200ms */
121 
122     LPC_EMC->DynamicControl    = 0x00000103;            /* Issue PALL command */
123 
124     LPC_EMC->DynamicRefresh    = 0x00000002;            /* ( n * 16 ) -> 32 clock cycles */
125     for (i = 0; i < 0x80; i++);                         /* wait 128 AHB clock cycles */
126 
127     LPC_EMC->DynamicRefresh    = EMC_SDRAM_REFRESH(64);
128 
129     LPC_EMC->DynamicControl    = 0x00000083;            /* Issue MODE command */
130 
131 #ifdef SDRAM_CONFIG_16BIT
132     wtemp = *((volatile uint16_t *)(EXT_SDRAM_BEGIN | (0x33 << 12)));   /* 8 burst, 3 CAS latency */
133 #elif defined SDRAM_CONFIG_32BIT
134     dwtemp = *((volatile uint32_t *)(SDRAM_BASE | (0x32 << 13)));       /* 4 burst, 3 CAS latency */
135 #endif
136 
137     LPC_EMC->DynamicControl    = 0x00000000;                            /* Issue NORMAL command */
138 
139     LPC_EMC->DynamicConfig0 |= 0x80000;                                 /* enable buffer */
140     TIM_Waitms(1);
141 
142     TIM_DeInit(LPC_TIM0);
143 }
144 
145 #endif /* BSP_USING_SDRAM */
146