1 |
1026 |
ivang |
/*
|
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 |
|
|
* @(#) hw_init.c,v 1.2 2001/10/26 13:41:07 joel Exp
|
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 |
|
|
|
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 |
|
|
}
|