]>
Commit | Line | Data |
---|---|---|
80421fcc XL |
1 | /* |
2 | * Jz4740 common routines | |
3 | * Copyright (c) 2006 Ingenic Semiconductor, <jlwei@ingenic.cn> | |
4 | * | |
1a459660 | 5 | * SPDX-License-Identifier: GPL-2.0+ |
80421fcc XL |
6 | */ |
7 | ||
8 | #include <config.h> | |
9 | #include <common.h> | |
10 | #include <asm/io.h> | |
11 | #include <asm/jz4740.h> | |
12 | ||
13 | void enable_interrupts(void) | |
14 | { | |
15 | } | |
16 | ||
17 | int disable_interrupts(void) | |
18 | { | |
19 | return 0; | |
20 | } | |
21 | ||
22 | /* | |
23 | * PLL output clock = EXTAL * NF / (NR * NO) | |
24 | * NF = FD + 2, NR = RD + 2 | |
25 | * NO = 1 (if OD = 0), NO = 2 (if OD = 1 or 2), NO = 4 (if OD = 3) | |
26 | */ | |
27 | void pll_init(void) | |
28 | { | |
29 | struct jz4740_cpm *cpm = (struct jz4740_cpm *)JZ4740_CPM_BASE; | |
30 | ||
31 | register unsigned int cfcr, plcr1; | |
32 | int n2FR[33] = { | |
33 | 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0, | |
34 | 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, | |
35 | 9 | |
36 | }; | |
37 | int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */ | |
38 | int nf, pllout2; | |
39 | ||
40 | cfcr = CPM_CPCCR_CLKOEN | | |
41 | CPM_CPCCR_PCS | | |
42 | (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) | | |
43 | (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) | | |
44 | (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) | | |
45 | (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) | | |
46 | (n2FR[div[4]] << CPM_CPCCR_LDIV_BIT); | |
47 | ||
48 | pllout2 = (cfcr & CPM_CPCCR_PCS) ? | |
49 | CONFIG_SYS_CPU_SPEED : (CONFIG_SYS_CPU_SPEED / 2); | |
50 | ||
51 | /* Init USB Host clock, pllout2 must be n*48MHz */ | |
52 | writel(pllout2 / 48000000 - 1, &cpm->uhccdr); | |
53 | ||
54 | nf = CONFIG_SYS_CPU_SPEED * 2 / CONFIG_SYS_EXTAL; | |
55 | plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */ | |
56 | (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */ | |
57 | (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */ | |
58 | (0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */ | |
59 | CPM_CPPCR_PLLEN; /* enable PLL */ | |
60 | ||
61 | /* init PLL */ | |
62 | writel(cfcr, &cpm->cpccr); | |
63 | writel(plcr1, &cpm->cppcr); | |
64 | } | |
65 | ||
66 | void sdram_init(void) | |
67 | { | |
68 | struct jz4740_emc *emc = (struct jz4740_emc *)JZ4740_EMC_BASE; | |
69 | ||
70 | register unsigned int dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns; | |
71 | ||
72 | unsigned int cas_latency_sdmr[2] = { | |
73 | EMC_SDMR_CAS_2, | |
74 | EMC_SDMR_CAS_3, | |
75 | }; | |
76 | ||
77 | unsigned int cas_latency_dmcr[2] = { | |
78 | 1 << EMC_DMCR_TCL_BIT, /* CAS latency is 2 */ | |
79 | 2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */ | |
80 | }; | |
81 | ||
82 | int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; | |
83 | ||
84 | cpu_clk = CONFIG_SYS_CPU_SPEED; | |
85 | mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()]; | |
86 | ||
87 | writel(0, &emc->bcr); /* Disable bus release */ | |
88 | writew(0, &emc->rtcsr); /* Disable clock for counting */ | |
89 | ||
90 | /* Fault DMCR value for mode register setting*/ | |
91 | #define SDRAM_ROW0 11 | |
92 | #define SDRAM_COL0 8 | |
93 | #define SDRAM_BANK40 0 | |
94 | ||
95 | dmcr0 = ((SDRAM_ROW0 - 11) << EMC_DMCR_RA_BIT) | | |
96 | ((SDRAM_COL0 - 8) << EMC_DMCR_CA_BIT) | | |
97 | (SDRAM_BANK40 << EMC_DMCR_BA_BIT) | | |
98 | (SDRAM_BW16 << EMC_DMCR_BW_BIT) | | |
99 | EMC_DMCR_EPIN | | |
100 | cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)]; | |
101 | ||
102 | /* Basic DMCR value */ | |
103 | dmcr = ((SDRAM_ROW - 11) << EMC_DMCR_RA_BIT) | | |
104 | ((SDRAM_COL - 8) << EMC_DMCR_CA_BIT) | | |
105 | (SDRAM_BANK4 << EMC_DMCR_BA_BIT) | | |
106 | (SDRAM_BW16 << EMC_DMCR_BW_BIT) | | |
107 | EMC_DMCR_EPIN | | |
108 | cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)]; | |
109 | ||
110 | /* SDRAM timimg */ | |
111 | ns = 1000000000 / mem_clk; | |
112 | tmp = SDRAM_TRAS / ns; | |
113 | if (tmp < 4) | |
114 | tmp = 4; | |
115 | if (tmp > 11) | |
116 | tmp = 11; | |
117 | dmcr |= (tmp - 4) << EMC_DMCR_TRAS_BIT; | |
118 | tmp = SDRAM_RCD / ns; | |
119 | ||
120 | if (tmp > 3) | |
121 | tmp = 3; | |
122 | dmcr |= tmp << EMC_DMCR_RCD_BIT; | |
123 | tmp = SDRAM_TPC / ns; | |
124 | ||
125 | if (tmp > 7) | |
126 | tmp = 7; | |
127 | dmcr |= tmp << EMC_DMCR_TPC_BIT; | |
128 | tmp = SDRAM_TRWL / ns; | |
129 | ||
130 | if (tmp > 3) | |
131 | tmp = 3; | |
132 | dmcr |= tmp << EMC_DMCR_TRWL_BIT; | |
133 | tmp = (SDRAM_TRAS + SDRAM_TPC) / ns; | |
134 | ||
135 | if (tmp > 14) | |
136 | tmp = 14; | |
137 | dmcr |= ((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT; | |
138 | ||
139 | /* SDRAM mode value */ | |
140 | sdmode = EMC_SDMR_BT_SEQ | | |
141 | EMC_SDMR_OM_NORMAL | | |
142 | EMC_SDMR_BL_4 | | |
143 | cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)]; | |
144 | ||
145 | /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */ | |
146 | writel(dmcr, &emc->dmcr); | |
147 | writeb(0, JZ4740_EMC_SDMR0 | sdmode); | |
148 | ||
149 | /* Wait for precharge, > 200us */ | |
150 | tmp = (cpu_clk / 1000000) * 1000; | |
151 | while (tmp--) | |
152 | ; | |
153 | ||
154 | /* Stage 2. Enable auto-refresh */ | |
155 | writel(dmcr | EMC_DMCR_RFSH, &emc->dmcr); | |
156 | ||
157 | tmp = SDRAM_TREF / ns; | |
158 | tmp = tmp / 64 + 1; | |
159 | if (tmp > 0xff) | |
160 | tmp = 0xff; | |
161 | writew(tmp, &emc->rtcor); | |
162 | writew(0, &emc->rtcnt); | |
163 | /* Divisor is 64, CKO/64 */ | |
164 | writew(EMC_RTCSR_CKS_64, &emc->rtcsr); | |
165 | ||
166 | /* Wait for number of auto-refresh cycles */ | |
167 | tmp = (cpu_clk / 1000000) * 1000; | |
168 | while (tmp--) | |
169 | ; | |
170 | ||
171 | /* Stage 3. Mode Register Set */ | |
172 | writel(dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET, &emc->dmcr); | |
173 | writeb(0, JZ4740_EMC_SDMR0 | sdmode); | |
174 | ||
175 | /* Set back to basic DMCR value */ | |
176 | writel(dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET, &emc->dmcr); | |
177 | ||
178 | /* everything is ok now */ | |
179 | } | |
180 | ||
181 | DECLARE_GLOBAL_DATA_PTR; | |
182 | ||
183 | void calc_clocks(void) | |
184 | { | |
185 | unsigned int pllout; | |
186 | unsigned int div[10] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; | |
187 | ||
188 | pllout = __cpm_get_pllout(); | |
189 | ||
190 | gd->cpu_clk = pllout / div[__cpm_get_cdiv()]; | |
97b920da DS |
191 | gd->arch.sys_clk = pllout / div[__cpm_get_hdiv()]; |
192 | gd->arch.per_clk = pllout / div[__cpm_get_pdiv()]; | |
80421fcc | 193 | gd->mem_clk = pllout / div[__cpm_get_mdiv()]; |
97b920da | 194 | gd->arch.dev_clk = CONFIG_SYS_EXTAL; |
80421fcc XL |
195 | } |
196 | ||
197 | void rtc_init(void) | |
198 | { | |
199 | struct jz4740_rtc *rtc = (struct jz4740_rtc *)JZ4740_RTC_BASE; | |
200 | ||
201 | while (!(readl(&rtc->rcr) & RTC_RCR_WRDY)) | |
202 | ; | |
203 | writel(readl(&rtc->rcr) | RTC_RCR_AE, &rtc->rcr); /* enable alarm */ | |
204 | ||
205 | while (!(readl(&rtc->rcr) & RTC_RCR_WRDY)) | |
206 | ; | |
207 | writel(0x00007fff, &rtc->rgr); /* type value */ | |
208 | ||
209 | while (!(readl(&rtc->rcr) & RTC_RCR_WRDY)) | |
210 | ; | |
211 | writel(0x0000ffe0, &rtc->hwfcr); /* Power on delay 2s */ | |
212 | ||
213 | while (!(readl(&rtc->rcr) & RTC_RCR_WRDY)) | |
214 | ; | |
215 | writel(0x00000fe0, &rtc->hrcr); /* reset delay 125ms */ | |
216 | } | |
217 | ||
218 | /* U-Boot common routines */ | |
219 | phys_size_t initdram(int board_type) | |
220 | { | |
221 | struct jz4740_emc *emc = (struct jz4740_emc *)JZ4740_EMC_BASE; | |
222 | u32 dmcr; | |
223 | u32 rows, cols, dw, banks; | |
224 | ulong size; | |
225 | ||
226 | dmcr = readl(&emc->dmcr); | |
227 | rows = 11 + ((dmcr & EMC_DMCR_RA_MASK) >> EMC_DMCR_RA_BIT); | |
228 | cols = 8 + ((dmcr & EMC_DMCR_CA_MASK) >> EMC_DMCR_CA_BIT); | |
229 | dw = (dmcr & EMC_DMCR_BW) ? 2 : 4; | |
230 | banks = (dmcr & EMC_DMCR_BA) ? 4 : 2; | |
231 | ||
232 | size = (1 << (rows + cols)) * dw * banks; | |
233 | ||
234 | return size; | |
235 | } |