1 | /* |
---|
2 | * SMFD board hardware initialization. |
---|
3 | * |
---|
4 | * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia |
---|
5 | * Author: Victor V. Vengerov <vvv@oktet.ru> |
---|
6 | * Alexandra Kossovsky <sasha@oktet.ru> |
---|
7 | * |
---|
8 | * The license and distribution terms for this file may be |
---|
9 | * found in the file LICENSE in this distribution or at |
---|
10 | * http://www.OARcorp.com/rtems/license.html. |
---|
11 | * |
---|
12 | * @(#) $Id$ |
---|
13 | */ |
---|
14 | |
---|
15 | #include "rtems/score/sh7750_regs.h" |
---|
16 | #include "rtems/score/sh_io.h" |
---|
17 | #include "sdram.h" |
---|
18 | #include "bsp.h" |
---|
19 | |
---|
20 | /* early_hw_init -- |
---|
21 | * Perform initial hardware initialization: |
---|
22 | * - setup clock generator |
---|
23 | * - initialize bus state controller, memory settings, SDRAM |
---|
24 | * - disable DMA |
---|
25 | * - setup external ports, etc. |
---|
26 | * - initialize interrupt controller |
---|
27 | * |
---|
28 | * This function should not access the memory! It should be compiled |
---|
29 | * with -fomit-frame-pointer to avoid stack access. |
---|
30 | * |
---|
31 | * PARAMETERS: |
---|
32 | * none |
---|
33 | * |
---|
34 | * RETURNS: |
---|
35 | * none |
---|
36 | */ |
---|
37 | void |
---|
38 | early_hw_init(void) |
---|
39 | { |
---|
40 | /* Explicitly turn off the MMU */ |
---|
41 | write32(0, SH7750_MMUCR); |
---|
42 | |
---|
43 | /* Disable instruction and operand caches */ |
---|
44 | write32(0, SH7750_CCR); |
---|
45 | |
---|
46 | /* Setup Clock Generator */ |
---|
47 | /* |
---|
48 | * Input clock frequency is 16 MHz, MD0=1, |
---|
49 | * CPU clock frequency already selected to 96MHz. |
---|
50 | * Bus clock frequency should be set to 48 MHz, therefore divider 2 |
---|
51 | * should be applied (bus frequency is 48 MHz, clock period is 20.84ns). |
---|
52 | * Peripheral frequency should be set to 24 MHz, therefore divider 4 |
---|
53 | * should be used. |
---|
54 | */ |
---|
55 | /* Prepare watchdog timer for frequency changing */ |
---|
56 | write16((read8(SH7750_WTCSR) & ~SH7750_WTCSR_TME) | |
---|
57 | SH7750_WTCSR_KEY, SH7750_WTCSR); |
---|
58 | write16(SH7750_WTCSR_MODE_IT | SH7750_WTCSR_CKS_DIV4096 | |
---|
59 | SH7750_WTCSR_KEY, SH7750_WTCSR); |
---|
60 | |
---|
61 | /* Turn PLL1 on */ |
---|
62 | write16(0x40 | SH7750_WTCNT_KEY, SH7750_WTCNT); |
---|
63 | write16(read16(SH7750_FRQCR) | SH7750_FRQCR_PLL1EN, SH7750_FRQCR); |
---|
64 | |
---|
65 | /* Perform Frequency Selection */ |
---|
66 | write16(0x40 | SH7750_WTCNT_KEY, SH7750_WTCNT); |
---|
67 | write16(SH7750_FRQCR_CKOEN | SH7750_FRQCR_PLL1EN | |
---|
68 | SH7750_FRQCR_IFCDIV1 | SH7750_FRQCR_BFCDIV2 | SH7750_FRQCR_PFCDIV4, |
---|
69 | SH7750_FRQCR); |
---|
70 | |
---|
71 | /* Turn PLL2 on */ |
---|
72 | write16(0x40 | SH7750_WTCNT_KEY, SH7750_WTCNT); |
---|
73 | write16(read16(SH7750_FRQCR) | SH7750_FRQCR_PLL2EN, SH7750_FRQCR); |
---|
74 | |
---|
75 | /* Bus State Controller Initialization */ |
---|
76 | /* |
---|
77 | * Area assignments: |
---|
78 | * Area 0: Flash memory, SRAM interface |
---|
79 | * Area 1: GDC |
---|
80 | * Area 2: SDRAM |
---|
81 | * Area 3-6: unused |
---|
82 | */ |
---|
83 | write32( |
---|
84 | /* Pull-ups (IPUP, OPUP) enabled */ |
---|
85 | /* No Byte-Control SRAM mode for Area 1 and Area 3 */ |
---|
86 | SH7750_BCR1_BREQEN | /* Enable external bus requests */ |
---|
87 | /* No Partial Sharing Mode */ |
---|
88 | /* No MPX interface */ |
---|
89 | /* Memory and Control Signals are in HiZ */ |
---|
90 | SH7750_BCR1_A0BST_SRAM | /* No burst ROM in flash */ |
---|
91 | SH7750_BCR1_A5BST_SRAM | /* Area 5 is not in use */ |
---|
92 | SH7750_BCR1_A6BST_SRAM | /* Area 6 is not in use */ |
---|
93 | SH7750_BCR1_DRAMTP_2SDRAM_3SDRAM /* Select Area 2 SDRAM type */ |
---|
94 | /* Area 5,6 programmed as a SRAM interface (not PCMCIA) */, |
---|
95 | SH7750_BCR1); |
---|
96 | |
---|
97 | write16( |
---|
98 | (SH7750_BCR2_SZ_8 << SH7750_BCR2_A0SZ_S) | /* These bits is read-only |
---|
99 | and set during reset */ |
---|
100 | (SH7750_BCR2_SZ_32 << SH7750_BCR2_A6SZ_S) | /* Area 6 not used */ |
---|
101 | (SH7750_BCR2_SZ_32 << SH7750_BCR2_A5SZ_S) | /* Area 5 not used */ |
---|
102 | (SH7750_BCR2_SZ_32 << SH7750_BCR2_A4SZ_S) | /* Area 4 not used */ |
---|
103 | (SH7750_BCR2_SZ_32 << SH7750_BCR2_A3SZ_S) | /* Area 3 not used */ |
---|
104 | (SH7750_BCR2_SZ_32 << SH7750_BCR2_A2SZ_S) | /* SDRAM is 32-bit width */ |
---|
105 | (SH7750_BCR2_SZ_32 << SH7750_BCR2_A1SZ_S) | /* GDC is 32-bit width */ |
---|
106 | SH7750_BCR2_PORTEN, /* Use D32-D51 as a port */ |
---|
107 | SH7750_BCR2); |
---|
108 | |
---|
109 | write32( |
---|
110 | (0 << SH7750_WCR1_DMAIW_S) | /* 0 required for SDRAM RAS down mode */ |
---|
111 | (7 << SH7750_WCR1_A6IW_S) | /* Area 6 not used */ |
---|
112 | (7 << SH7750_WCR1_A5IW_S) | /* Area 5 not used */ |
---|
113 | (7 << SH7750_WCR1_A4IW_S) | /* Area 4 not used */ |
---|
114 | (7 << SH7750_WCR1_A3IW_S) | /* Area 3 not used */ |
---|
115 | (1 << SH7750_WCR1_A2IW_S) | /* 1 idle cycles inserted between acc */ |
---|
116 | (7 << SH7750_WCR1_A1IW_S) | /* Don't have GDC specs... Set safer. */ |
---|
117 | (1 << SH7750_WCR1_A0IW_S), /* 1 idle cycles inserted between acc */ |
---|
118 | SH7750_WCR1); |
---|
119 | |
---|
120 | write32( |
---|
121 | (SH7750_WCR2_WS15 << SH7750_WCR2_A6W_S) | /* Area 6 not used */ |
---|
122 | (SH7750_WCR2_BPWS7 << SH7750_WCR2_A6B_S) | |
---|
123 | (SH7750_WCR2_WS15 << SH7750_WCR2_A5W_S) | /* Area 5 not used */ |
---|
124 | (SH7750_WCR2_BPWS7 << SH7750_WCR2_A5B_S) | |
---|
125 | (SH7750_WCR2_WS15 << SH7750_WCR2_A4W_S) | /* Area 4 not used */ |
---|
126 | (SH7750_WCR2_WS15 << SH7750_WCR2_A3W_S) | /*Area 3 not used*/ |
---|
127 | (SH7750_WCR2_SDRAM_CAS_LAT2 << SH7750_WCR2_A2W_S) | /* SDRAM CL = 2 */ |
---|
128 | (SH7750_WCR2_WS15 << SH7750_WCR2_A1W_S) | /* Area 1 (GDC) |
---|
129 | requirements not known*/ |
---|
130 | (SH7750_WCR2_WS6 << SH7750_WCR2_A0W_S) | /* 4 wait states required |
---|
131 | at 48MHz for 70ns mem., |
---|
132 | set closest greater */ |
---|
133 | (SH7750_WCR2_BPWS7 << SH7750_WCR2_A0B_S), /* burst mode disabled for |
---|
134 | Area 0 flash ROM */ |
---|
135 | SH7750_WCR2); |
---|
136 | write32( |
---|
137 | SH7750_WCR3_A6S | /* Area 6 not used */ |
---|
138 | (SH7750_WCR3_DHWS_3 << SH7750_WCR3_A6H_S) | |
---|
139 | SH7750_WCR3_A5S | /* Area 5 not used */ |
---|
140 | (SH7750_WCR3_DHWS_3 << SH7750_WCR3_A5H_S) | |
---|
141 | SH7750_WCR3_A4S | /* Area 4 not used */ |
---|
142 | (SH7750_WCR3_DHWS_3 << SH7750_WCR3_A4H_S) | |
---|
143 | SH7750_WCR3_A3S | /* Area 3 not used */ |
---|
144 | (SH7750_WCR3_DHWS_3 << SH7750_WCR3_A3H_S) | |
---|
145 | SH7750_WCR3_A2S | /* SDRAM - ignored */ |
---|
146 | (SH7750_WCR3_DHWS_3 << SH7750_WCR3_A2H_S) | |
---|
147 | SH7750_WCR3_A1S | /* GDC - unknown, set max*/ |
---|
148 | (SH7750_WCR3_DHWS_3 << SH7750_WCR3_A1H_S) | |
---|
149 | 0 | /* flash ROM - no write strobe setup time required */ |
---|
150 | (SH7750_WCR3_DHWS_0 << SH7750_WCR3_A0H_S), |
---|
151 | SH7750_WCR3); |
---|
152 | |
---|
153 | #define MCRDEF \ |
---|
154 | /* SH7750_MCR_RASD | */ /* Set RAS Down mode */ \ |
---|
155 | (SH7750_MCR_TRC_0 | SH7750_MCR_TRAS_SDRAM_TRC_4 | \ |
---|
156 | /* RAS precharge time is 63ns; it corresponds to 4 clocks */ \ |
---|
157 | /* TCAS valid only for DRAM interface */ \ |
---|
158 | SH7750_MCR_TPC_SDRAM_1 | /* TPC = 20ns = 1 clock */ \ |
---|
159 | SH7750_MCR_RCD_SDRAM_2 | /* RCD = 21ns = 2 clock */ \ |
---|
160 | /* After write, next active command is not issued for a period of \ |
---|
161 | TPC + TRWL. SDRAM specifies that it should be BL+Trp clocks when \ |
---|
162 | CL=2. Trp = 20ns = 1clock; BL=8. Therefore we should wait 9 \ |
---|
163 | clocks. Don't know why, but 6 clocks (TRWL=5 and TPC=1) seems \ |
---|
164 | working. May be, something wrong in documentation? */ \ |
---|
165 | SH7750_MCR_TRWL_5 | /* TRWL = 5 clock */ \ |
---|
166 | SH7750_MCR_BE | /* Always enabled for SDRAM */ \ |
---|
167 | SH7750_MCR_SZ_32 | /* Memory data size is 32 bit */ \ |
---|
168 | (4 << SH7750_MCR_AMX_S) | /* Select memory device type */ \ |
---|
169 | SH7750_MCR_RFSH | /* Refresh is performed */ \ |
---|
170 | SH7750_MCR_RMODE_NORMAL) /* Auto-Refresh mode */ |
---|
171 | |
---|
172 | /* Clear refresh timer counter */ |
---|
173 | write16(SH7750_RTCNT_KEY | 0, SH7750_RTCNT); |
---|
174 | |
---|
175 | /* Time between auto-refresh commands is 15.6 microseconds; refresh |
---|
176 | timer counter frequency is 12 MHz; 1.56e-5*1.2e7= 187.2, therefore |
---|
177 | program the refresh timer divider to 187 */ |
---|
178 | write16(SH7750_RTCOR_KEY | 187, SH7750_RTCOR); |
---|
179 | |
---|
180 | /* Clear refresh counter */ |
---|
181 | write16(SH7750_RFCR_KEY | 0, SH7750_RFCR); |
---|
182 | |
---|
183 | /* Select refresh counter base frequency as bus frequency/4 = 12 MHz */ |
---|
184 | write16(SH7750_RTCSR_CKS_CKIO_DIV4 | SH7750_RTCSR_KEY, SH7750_RTCSR); |
---|
185 | |
---|
186 | /* Initialize Memory Control Register; disable refresh */ |
---|
187 | write32((MCRDEF & ~SH7750_MCR_RFSH) | SH7750_MCR_PALL, SH7750_MCR); |
---|
188 | |
---|
189 | /* SDRAM power-up initialization require 100 microseconds delay after |
---|
190 | stable power and clock fed; 100 microseconds corresponds to 7 refresh |
---|
191 | intervals */ |
---|
192 | while (read16(SH7750_RFCR) <= 7); |
---|
193 | |
---|
194 | /* Clear refresh timer counter */ |
---|
195 | write16(SH7750_RTCNT_KEY | 0, SH7750_RTCNT); |
---|
196 | |
---|
197 | /* Clear refresh counter */ |
---|
198 | write16(SH7750_RFCR_KEY | 0, SH7750_RFCR); |
---|
199 | |
---|
200 | /* Execute Precharge All command */ |
---|
201 | write32(0, SH7750_SDRAM_MODE_A2_32BIT(0)); |
---|
202 | |
---|
203 | /* Initialize Memory Control Register; enable refresh, prepare to |
---|
204 | SDRAM mode register setting */ |
---|
205 | write32(MCRDEF | SH7750_MCR_MRSET, SH7750_MCR); |
---|
206 | |
---|
207 | /* Wait until at least 2 auto-refresh commands to be executed */ |
---|
208 | while (read16(SH7750_RFCR) <= 10); |
---|
209 | |
---|
210 | /* SDRAM data width is 32 bit (4 bytes), cache line size is 32 bytes, |
---|
211 | therefore burst length is 8 (32 / 4) */ |
---|
212 | write8(0,SH7750_SDRAM_MODE_A2_32BIT( |
---|
213 | SDRAM_MODE_BL_8 | |
---|
214 | SDRAM_MODE_BT_SEQ | /* Only sequential burst mode supported |
---|
215 | in SH7750 */ |
---|
216 | SDRAM_MODE_CL_2 | /* CAS latency is 2 */ |
---|
217 | SDRAM_MODE_OPC_BRBW) /* Burst read/burst write */ |
---|
218 | ); |
---|
219 | /* Bus State Controller initialized now */ |
---|
220 | |
---|
221 | /* Disable DMA controller */ |
---|
222 | write32(0, SH7750_DMAOR); |
---|
223 | |
---|
224 | /* I/O port setup */ |
---|
225 | /* Configure all port bits as output - to fasciliate debugging */ |
---|
226 | write32( |
---|
227 | SH7750_PCTRA_PBOUT(0) | SH7750_PCTRA_PBOUT(1) | |
---|
228 | SH7750_PCTRA_PBOUT(2) | SH7750_PCTRA_PBOUT(3) | |
---|
229 | SH7750_PCTRA_PBOUT(4) | SH7750_PCTRA_PBOUT(5) | |
---|
230 | SH7750_PCTRA_PBOUT(6) | SH7750_PCTRA_PBOUT(7) | |
---|
231 | SH7750_PCTRA_PBOUT(8) | SH7750_PCTRA_PBOUT(9) | |
---|
232 | SH7750_PCTRA_PBOUT(10) | SH7750_PCTRA_PBOUT(11) | |
---|
233 | SH7750_PCTRA_PBOUT(12) | SH7750_PCTRA_PBOUT(13) | |
---|
234 | SH7750_PCTRA_PBOUT(14) | SH7750_PCTRA_PBOUT(15), |
---|
235 | SH7750_PCTRA); |
---|
236 | write32( |
---|
237 | SH7750_PCTRB_PBOUT(16) | SH7750_PCTRB_PBOUT(17) | |
---|
238 | SH7750_PCTRB_PBOUT(18) | SH7750_PCTRB_PBOUT(19), |
---|
239 | SH7750_PCTRB); |
---|
240 | /* Clear data in port */ |
---|
241 | write32(0, SH7750_PDTRA); |
---|
242 | write32(0, SH7750_PDTRB); |
---|
243 | |
---|
244 | /* Interrupt Controller Initialization */ |
---|
245 | write16(SH7750_ICR_IRLM, SH7750_ICR); /* IRLs serves as an independent |
---|
246 | interrupt request lines */ |
---|
247 | /* Mask all requests at this time */ |
---|
248 | write16( |
---|
249 | (0 << SH7750_IPRA_TMU0_S) | |
---|
250 | (0 << SH7750_IPRA_TMU1_S) | |
---|
251 | (0 << SH7750_IPRA_TMU2_S) | |
---|
252 | (0 << SH7750_IPRA_RTC_S), |
---|
253 | SH7750_IPRA); |
---|
254 | write16( |
---|
255 | (0 << SH7750_IPRB_WDT_S) | |
---|
256 | (0 << SH7750_IPRB_REF_S) | |
---|
257 | (0 << SH7750_IPRB_SCI1_S), |
---|
258 | SH7750_IPRB); |
---|
259 | write16( |
---|
260 | (0 << SH7750_IPRC_GPIO_S) | |
---|
261 | (0 << SH7750_IPRC_DMAC_S) | |
---|
262 | (0 << SH7750_IPRC_SCIF_S) | |
---|
263 | (0 << SH7750_IPRC_HUDI_S), |
---|
264 | SH7750_IPRC); |
---|
265 | |
---|
266 | } |
---|
267 | |
---|
268 | /* |
---|
269 | * cache_on -- |
---|
270 | * Enable instruction and operand caches |
---|
271 | */ |
---|
272 | void bsp_cache_on(void) |
---|
273 | { |
---|
274 | switch (boot_mode) |
---|
275 | { |
---|
276 | case SH4_BOOT_MODE_FLASH: |
---|
277 | write32(SH7750_CCR_ICI | SH7750_CCR_ICE | |
---|
278 | SH7750_CCR_OCI | SH7750_CCR_CB | SH7750_CCR_OCE, |
---|
279 | SH7750_CCR); |
---|
280 | break; |
---|
281 | case SH4_BOOT_MODE_IPL: |
---|
282 | asm volatile ( |
---|
283 | "mov #6, r0\n" |
---|
284 | "xor r4, r4\n" |
---|
285 | "trapa #0x3f\n" |
---|
286 | : : : "r0", "r4"); |
---|
287 | break; |
---|
288 | default: /* unreachable */ |
---|
289 | break; |
---|
290 | } |
---|
291 | } |
---|