1 //==========================================================================
5 // HAL misc board support code for ARM9/SMDK2410
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
43 // Author(s): michael anburaj <michaelanburaj@hotmail.com>
44 // Contributors: michael anburaj <michaelanburaj@hotmail.com>
46 // Purpose: HAL board support
47 // Description: Implementations of HAL board interfaces
49 //####DESCRIPTIONEND####
51 //==========================================================================
53 #include <pkgconf/hal.h>
54 #include <pkgconf/system.h>
55 #include CYGBLD_HAL_PLATFORM_H
57 #include <cyg/infra/cyg_type.h> // base types
58 #include <cyg/infra/cyg_trac.h> // tracing macros
59 #include <cyg/infra/cyg_ass.h> // assertion macros
61 #include <cyg/hal/hal_io.h> // IO macros
62 #include <cyg/hal/hal_arch.h> // Register state info
63 #include <cyg/hal/hal_diag.h>
64 #include <cyg/hal/hal_intr.h> // Interrupt names
65 #include <cyg/hal/hal_cache.h>
66 #include <cyg/hal/s3c2410x.h> // Platform specifics
68 #include <cyg/infra/diag.h> // diag_printf
70 #include <string.h> // memset
72 // -------------------------------------------------------------------------
73 // MMU initialization:
75 // These structures are laid down in memory to define the translation
79 // ARM Translation Table Base Bit Masks
80 #define ARM_TRANSLATION_TABLE_MASK 0xFFFFC000
82 // ARM Domain Access Control Bit Masks
83 #define ARM_ACCESS_TYPE_NO_ACCESS(domain_num) (0x0 << (domain_num)*2)
84 #define ARM_ACCESS_TYPE_CLIENT(domain_num) (0x1 << (domain_num)*2)
85 #define ARM_ACCESS_TYPE_MANAGER(domain_num) (0x3 << (domain_num)*2)
87 struct ARM_MMU_FIRST_LEVEL_FAULT {
91 #define ARM_MMU_FIRST_LEVEL_FAULT_ID 0x0
93 struct ARM_MMU_FIRST_LEVEL_PAGE_TABLE {
98 int base_address : 23;
100 #define ARM_MMU_FIRST_LEVEL_PAGE_TABLE_ID 0x1
102 struct ARM_MMU_FIRST_LEVEL_SECTION {
111 int base_address : 12;
113 #define ARM_MMU_FIRST_LEVEL_SECTION_ID 0x2
115 struct ARM_MMU_FIRST_LEVEL_RESERVED {
119 #define ARM_MMU_FIRST_LEVEL_RESERVED_ID 0x3
121 #define ARM_MMU_FIRST_LEVEL_DESCRIPTOR_ADDRESS(ttb_base, table_index) \
122 (unsigned long *)((unsigned long)(ttb_base) + ((table_index) << 2))
124 #define ARM_FIRST_LEVEL_PAGE_TABLE_SIZE 0x4000
126 #define ARM_MMU_SECTION(ttb_base, actual_base, virtual_base, \
127 cacheable, bufferable, perm) \
129 register union ARM_MMU_FIRST_LEVEL_DESCRIPTOR desc; \
132 desc.section.id = ARM_MMU_FIRST_LEVEL_SECTION_ID; \
133 desc.section.imp = 1; \
134 desc.section.domain = 0; \
135 desc.section.c = (cacheable); \
136 desc.section.b = (bufferable); \
137 desc.section.ap = (perm); \
138 desc.section.base_address = (actual_base); \
139 *ARM_MMU_FIRST_LEVEL_DESCRIPTOR_ADDRESS(ttb_base, (virtual_base)) \
143 #define X_ARM_MMU_SECTION(abase,vbase,size,cache,buff,access) \
144 { int i; int j = abase; int k = vbase; \
145 for (i = size; i > 0 ; i--,j++,k++) \
147 ARM_MMU_SECTION(ttb_base, j, k, cache, buff, access); \
151 union ARM_MMU_FIRST_LEVEL_DESCRIPTOR {
153 struct ARM_MMU_FIRST_LEVEL_FAULT fault;
154 struct ARM_MMU_FIRST_LEVEL_PAGE_TABLE page_table;
155 struct ARM_MMU_FIRST_LEVEL_SECTION section;
156 struct ARM_MMU_FIRST_LEVEL_RESERVED reserved;
159 #define ARM_UNCACHEABLE 0
160 #define ARM_CACHEABLE 1
161 #define ARM_UNBUFFERABLE 0
162 #define ARM_BUFFERABLE 1
164 #define ARM_ACCESS_PERM_NONE_NONE 0
165 #define ARM_ACCESS_PERM_RO_NONE 0
166 #define ARM_ACCESS_PERM_RO_RO 0
167 #define ARM_ACCESS_PERM_RW_NONE 1
168 #define ARM_ACCESS_PERM_RW_RO 2
169 #define ARM_ACCESS_PERM_RW_RW 3
174 unsigned long ttb_base = SMDK2410_SDRAM_PHYS_BASE + 0x4000;
177 // Set the TTB register
178 asm volatile ("mcr p15,0,%0,c2,c0,0" : : "r"(ttb_base) /*:*/);
180 // Set the Domain Access Control Register
181 i = ARM_ACCESS_TYPE_MANAGER(0) |
182 ARM_ACCESS_TYPE_NO_ACCESS(1) |
183 ARM_ACCESS_TYPE_NO_ACCESS(2) |
184 ARM_ACCESS_TYPE_NO_ACCESS(3) |
185 ARM_ACCESS_TYPE_NO_ACCESS(4) |
186 ARM_ACCESS_TYPE_NO_ACCESS(5) |
187 ARM_ACCESS_TYPE_NO_ACCESS(6) |
188 ARM_ACCESS_TYPE_NO_ACCESS(7) |
189 ARM_ACCESS_TYPE_NO_ACCESS(8) |
190 ARM_ACCESS_TYPE_NO_ACCESS(9) |
191 ARM_ACCESS_TYPE_NO_ACCESS(10) |
192 ARM_ACCESS_TYPE_NO_ACCESS(11) |
193 ARM_ACCESS_TYPE_NO_ACCESS(12) |
194 ARM_ACCESS_TYPE_NO_ACCESS(13) |
195 ARM_ACCESS_TYPE_NO_ACCESS(14) |
196 ARM_ACCESS_TYPE_NO_ACCESS(15);
197 asm volatile ("mcr p15,0,%0,c3,c0,0" : : "r"(i) /*:*/);
199 // First clear all TT entries - ie Set them to Faulting
200 memset((void *)ttb_base, 0, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE);
202 // Memory layout after MMU is turned on
204 // SDRAM_BASE_ADDRESS: 0x00000000, 64M
205 // SRAM_BASE_ADDRESS: 0x40000000, 4K
206 // SFR_BASE_ADDRESS: 0x48000000, 512M
207 // FLASH_BASE_ADDRESS: 0x80000000, 2M
209 // Actual Virtual Size Attributes Function
210 // Base Base MB cached? buffered? access permissions
212 X_ARM_MMU_SECTION(0x000, 0x800, 2, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // Flash
213 X_ARM_MMU_SECTION(0x300, 0x000, 64, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); // SDRAM
214 X_ARM_MMU_SECTION(0x400, 0x400, 1, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); // SRAM
215 X_ARM_MMU_SECTION(0x480, 0x480, 512, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // SFRs
216 X_ARM_MMU_SECTION(0x300, 0x300, 64, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // Raw SDRAM
219 //----------------------------------------------------------------------------
220 // Platform specific initialization
222 // This routine sets the default GPIO condition
223 static void port_init(void)
225 // Note: Follow the configuration order for setting the ports.
226 // 1) Set data register (GPnDAT)
227 // 2) Set control register (GPnCON)
228 // 3) Configure pull-up's (GPnUP)
231 //Ports : GPA22 GPA21 GPA20 GPA19 GPA18 GPA17 GPA16 GPA15 GPA14 GPA13 GPA12
232 //Signal : nFCE nRSTOUT nFRE nFWE ALE CLE nGCS5 nGCS4 nGCS3 nGCS2 nGCS1
233 //Binary : 1 1 1 1 1 1 1 1 1 1 1
234 //-----------------------------------------------------------------------------------------
235 //Ports : GPA11 GPA10 GPA9 GPA8 GPA7 GPA6 GPA5 GPA4 GPA3 GPA2 GPA1 GPA0
236 //Signal : ADDR26 ADDR25 ADDR24 ADDR23 ADDR22 ADDR21 ADDR20 ADDR19 ADDR18 ADDR17 ADDR16 ADDR0
237 //Binary : 1 1 1 1 1 1 1 1 1 1 1 1
238 HAL_WRITE_UINT32(GPACON, 0x7fffff);
241 //Ports : GPB10 GPB9 GPB8 GPB7 GPB6 GPB5 GPB4 GPB3 GPB2 GPB1 GPB0
242 //Signal : nXDREQ0 nXDACK0 nXDREQ1 nXDACK1 nSS_KBD nDIS_OFF L3CLOCK L3DATA L3MODE nIrDATXDEN Keyboard
243 //Setting: INPUT OUTPUT INPUT OUTPUT INPUT OUTPUT OUTPUT OUTPUT OUTPUT OUTPUT OUTPUT
244 //Binary : 00 01 00 01 00 01 01 01 01 01 01
245 HAL_WRITE_UINT32(GPBCON, 0x044555);
246 HAL_WRITE_UINT32(GPBUP, 0x7ff); // The pull up function is disabled GPB[10:0]
249 //Ports : GPC15 GPC14 GPC13 GPC12 GPC11 GPC10 GPC9 GPC8 GPC7 GPC6 GPC5 GPC4 GPC3 GPC2 GPC1 GPC0
250 //Signal : VD7 VD6 VD5 VD4 VD3 VD2 VD1 VD0 LCDVF2 LCDVF1 LCDVF0 VM VFRAME VLINE VCLK LEND
251 //Binary : 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
252 HAL_WRITE_UINT32(GPCCON, 0xaaaaaaaa);
253 HAL_WRITE_UINT32(GPCUP, 0xffff); // The pull up function is disabled GPC[15:0]
256 //Ports : GPD15 GPD14 GPD13 GPD12 GPD11 GPD10 GPD9 GPD8 GPD7 GPD6 GPD5 GPD4 GPD3 GPD2 GPD1 GPD0
257 //Signal : VD23 VD22 VD21 VD20 VD19 VD18 VD17 VD16 VD15 VD14 VD13 VD12 VD11 VD10 VD9 VD8
258 //Binary : 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
259 HAL_WRITE_UINT32(GPDCON, 0xaaaaaaaa);
260 HAL_WRITE_UINT32(GPDUP, 0xffff); // The pull up function is disabled GPD[15:0]
263 //Ports : GPE15 GPE14 GPE13 GPE12 GPE11 GPE10 GPE9 GPE8 GPE7 GPE6 GPE5 GPE4
264 //Signal : IICSDA IICSCL SPICLK SPIMOSI SPIMISO SDDATA3 SDDATA2 SDDATA1 SDDATA0 SDCMD SDCLK I2SSDO
265 //Binary : 10 10 10 10 10 10 10 10 10 10 10 10
266 //------------------------------------------------------------------------------------------------
267 //Ports : GPE3 GPE2 GPE1 GPE0
268 //Signal : I2SSDI CDCLK I2SSCLK I2SLRCK
269 //Binary : 10 10 10 10
270 HAL_WRITE_UINT32(GPECON, 0xaaaaaaaa);
271 HAL_WRITE_UINT32(GPEUP, 0xffff); // The pull up function is disabled GPE[15:0]
274 //Ports : GPF7 GPF6 GPF5 GPF4 GPF3 GPF2 GPF1 GPF0
275 //Signal : nLED_8 nLED_4 nLED_2 nLED_1 nIRQ_PCMCIA EINT2 KBDINT EINT0
276 //Setting: Output Output Output Output EINT3 EINT2 EINT1 EINT0
277 //Binary : 01 01 01 01 10 10 10 10
278 HAL_WRITE_UINT32(GPFCON, 0x55aa);
279 HAL_WRITE_UINT32(GPFUP, 0xff); // The pull up function is disabled GPF[7:0]
282 //Ports : GPG15 GPG14 GPG13 GPG12 GPG11 GPG10 GPG9 GPG8 GPG7 GPG6
283 //Signal : nYPON YMON nXPON XMON EINT19 DMAMODE1 DMAMODE0 DMASTART KBDSPICLK KBDSPIMOSI
284 //Setting: nYPON YMON nXPON XMON EINT19 Output Output Output SPICLK1 SPIMOSI1
285 //Binary : 11 11 11 11 10 01 01 01 11 11
286 //-----------------------------------------------------------------------------------------
287 //Ports : GPG5 GPG4 GPG3 GPG2 GPG1 GPG0
288 //Signal : KBDSPIMISO LCD_PWREN EINT11 nSS_SPI IRQ_LAN IRQ_PCMCIA
289 //Setting: SPIMISO1 LCD_PWRDN EINT11 nSS0 EINT9 EINT8
290 //Binary : 11 11 10 11 10 10
291 HAL_WRITE_UINT32(GPGCON, 0xff95ffba);
292 HAL_WRITE_UINT32(GPGUP, 0xffff); // The pull up function is disabled GPG[15:0]
295 //Ports : GPH10 GPH9 GPH8 GPH7 GPH6 GPH5 GPH4 GPH3 GPH2 GPH1 GPH0
296 //Signal : CLKOUT1 CLKOUT0 UCLK nCTS1 nRTS1 RXD1 TXD1 RXD0 TXD0 nRTS0 nCTS0
297 //Binary : 10 10 10 11 11 10 10 10 10 10 10
298 HAL_WRITE_UINT32(GPHCON, 0x2afaaa);
299 HAL_WRITE_UINT32(GPHUP, 0x7ff); // The pull up function is disabled GPH[10:0]
301 //External interrupts will be falling edge triggered.
302 HAL_WRITE_UINT32(EXTINT0, 0x22222222); // EINT[7:0]
303 HAL_WRITE_UINT32(EXTINT1, 0x22222222); // EINT[15:8]
304 HAL_WRITE_UINT32(EXTINT2, 0x22222222); // EINT[23:16]
308 plf_hardware_init(void)
310 HAL_WRITE_UINT32(INTMOD, 0x0); //All=IRQ mode
311 HAL_WRITE_UINT32(INTMSK, BIT_ALLMSK); //All interrupt is masked.
312 HAL_WRITE_UINT32(INTSUBMSK, BIT_SUB_ALLMSK); //All sub-interrupt is masked.
316 // Initialize real-time clock (for delays, etc, even if kernel doesn't use it)
317 hal_clock_initialize(CYGNUM_HAL_RTC_PERIOD);
320 // -------------------------------------------------------------------------
321 // Use Timer4 for system clock
323 hal_clock_initialize(cyg_uint32 period)
327 // Configure the Prescaler1
328 HAL_READ_UINT32(TCFG0, temp);
330 temp |= (CYGNUM_HAL_ARM_SMDK2410_TIMER_PRESCALE<<8);
331 HAL_WRITE_UINT32(TCFG0, temp);
333 // Configure the MUX to select the 1/2 divider
334 HAL_READ_UINT32(TCFG1, temp);
337 HAL_WRITE_UINT32(TCFG1, temp);
339 // Set up the Timer4 for period
340 HAL_WRITE_UINT32(TCNTB4, period);
343 HAL_READ_UINT32(TCON, temp);
344 temp &= ~(0xf << 20);
345 HAL_WRITE_UINT32(TCON, (temp|(6<<20)));
346 HAL_WRITE_UINT32(TCON, (temp|(5<<20)));
348 // Unmask Timer4 interrupt, need not be done here
349 //HAL_INTERRUPT_CONFIGURE( CYGNUM_HAL_INTERRUPT_RTC, 1, 1 );
350 //HAL_INTERRUPT_UNMASK( CYGNUM_HAL_INTERRUPT_RTC );
353 // This routine is called during a clock interrupt.
355 hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
360 // Read the current value of the clock, returning the number of hardware
361 // "ticks" that have occurred (i.e. how far away the current value is from
364 hal_clock_read(cyg_uint32 *pvalue)
368 // Read Timer4's current value
369 HAL_READ_UINT32(TCNTO4, clock_val);
371 *pvalue = CYGNUM_HAL_RTC_PERIOD - (clock_val & 0xFFFF); // Note: counter is only 16 bits
376 // Delay for some number of micro-seconds
378 hal_delay_us(cyg_int32 usecs)
380 cyg_uint32 ticks = 0;
381 // Divide by 1000000 in two steps to preserve precision.
382 cyg_uint32 wait_ticks = (((PCLK/100000)*usecs)/CYGNUM_HAL_ARM_SMDK2410_TIMER_PRESCALE/2/10);
383 cyg_int32 val, prev, diff;
385 // Read Timer4's current value
386 HAL_READ_UINT32(TCNTO4, prev);
389 while (ticks < wait_ticks) {
391 // Read Timer4's current value
392 HAL_READ_UINT32(TCNTO4, val);
398 diff += (CYGNUM_HAL_RTC_PERIOD+1);
400 break; // atleast 1 tick has passed
408 // -------------------------------------------------------------------------
410 // This routine is called to respond to a hardware interrupt (IRQ). It
411 // should interrogate the hardware and return the IRQ vector number.
413 hal_IRQ_handler(void)
417 HAL_READ_UINT32(INTOFFSET, ior);
421 //----------------------------------------------------------------------------
425 hal_interrupt_mask(int vector)
429 CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
430 vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
432 HAL_READ_UINT32(INTMSK, imr);
434 HAL_WRITE_UINT32(INTMSK, imr);
438 hal_interrupt_unmask(int vector)
442 CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
443 vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
445 HAL_READ_UINT32(INTMSK, imr);
447 HAL_WRITE_UINT32(INTMSK, imr);
451 hal_interrupt_acknowledge(int vector)
455 CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
456 vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
458 HAL_WRITE_UINT32(SRCPND, (1<<vector));
459 HAL_READ_UINT32(INTPND, ipr);
460 HAL_WRITE_UINT32(INTPND, ipr);
464 hal_interrupt_configure(int vector, int level, int up)
466 CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
467 vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
470 void hal_interrupt_set_level(int vector, int level)
472 CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
473 vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
477 //-----------------------------------------------------------------------------
478 // End of smdk2410_misc.c