1 //==========================================================================
5 // HAL misc board support code for the TX37 board
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 //========================================================================*/
42 #include <pkgconf/hal.h>
43 #include <pkgconf/system.h>
45 #include CYGBLD_HAL_PLATFORM_H
47 #include <cyg/infra/cyg_type.h> // base types
48 #include <cyg/infra/cyg_trac.h> // tracing macros
49 #include <cyg/infra/cyg_ass.h> // assertion macros
51 #include <cyg/hal/hal_io.h> // IO macros
52 #include <cyg/hal/hal_arch.h> // Register state info
53 #include <cyg/hal/hal_diag.h>
54 #include <cyg/hal/hal_intr.h> // Interrupt names
55 #include <cyg/hal/hal_cache.h>
56 #include <cyg/hal/hal_soc.h> // Hardware definitions
57 #include <cyg/hal/karo_tx37.h> // Platform specifics
58 //#include <cyg/io/mxc_i2c.h>
59 #include <cyg/infra/diag.h> // diag_printf
61 // All the MM table layout is here:
62 #include <cyg/hal/hal_mm.h>
64 externC void* memset(void *, int, size_t);
66 volatile void *gpio_mcu1 = (volatile void *)GPIO1_BASE_ADDR;
67 volatile void *gpio_mcu2 = (volatile void *)GPIO2_BASE_ADDR;
68 volatile void *gpio_mcu3 = (volatile void *)GPIO3_BASE_ADDR;
69 volatile void *iomux = (volatile void *)IOMUXC_BASE_ADDR;
71 /* point to Data Direction Registers (DDIR) of all GPIO ports */
72 static volatile cyg_uint32 *const data_dir_reg_ptr_array[3] = {
73 (cyg_uint32 *) ((cyg_uint32) GPIO1_BASE_ADDR + 4),
74 (cyg_uint32 *) ((cyg_uint32) GPIO1_BASE_ADDR + 4),
75 (cyg_uint32 *) ((cyg_uint32) GPIO1_BASE_ADDR + 4)
78 /* point to Data Registers (DR) of all GPIO ports */
79 static volatile unsigned int *const data_reg_ptr_array[3] = {
80 (cyg_uint32 *) GPIO1_BASE_ADDR,
81 (cyg_uint32 *) GPIO2_BASE_ADDR,
82 (cyg_uint32 *) GPIO3_BASE_ADDR
85 /* point to Pad Status Registers (PSR) of all GPIO ports */
86 static volatile unsigned int *const pad_status_reg_ptr_array[3] = {
87 (cyg_uint32 *) ((cyg_uint32) GPIO1_BASE_ADDR + 4 * 2),
88 (cyg_uint32 *) ((cyg_uint32) GPIO2_BASE_ADDR + 4 * 2),
89 (cyg_uint32 *) ((cyg_uint32) GPIO3_BASE_ADDR + 4 * 2)
92 /* point to IOMUX SW MUX Control Registers*/
93 static volatile unsigned int *const iomux_sw_mux_ctrl_reg_array[3] = {
94 (cyg_uint32 *) ((cyg_uint32) IOMUXC_BASE_ADDR + 0x0008), //the offset of sw_mux_ctrl_reg_array is 0x0004
95 (cyg_uint32 *) ((cyg_uint32) IOMUXC_BASE_ADDR + 0x0230), //the offset of sw_pad_ctrl_reg_array is 0x0328
96 (cyg_uint32 *) ((cyg_uint32) IOMUXC_BASE_ADDR + 0x0508), //the offset of daisy_sel_in_reg_array is 0x07AC
100 #define UARO_URXD 0x00
101 #define UARO_UTXD 0x40
102 #define UARO_UCR1 0x80
103 #define UARO_UCR2 0x84
104 #define UARO_UCR3 0x88
105 #define UARO_UCR4 0x8c
106 #define UARO_UFCR 0x90
107 #define UARO_USR1 0x94
108 #define UARO_USR2 0x98
109 #define UARO_UESC 0x9c
110 #define UARO_UTIM 0xa0
111 #define UARO_UBIR 0xa4
112 #define UARO_UBMR 0xa8
113 #define UARO_UBRC 0xac
114 #define UARO_ONEMS 0xb0
115 #define UARO_UTS 0xb4
117 void plf_uart_init(void)
120 unsigned long UartRefFreq;
124 writel(0x0, IOMUXC_BASE_ADDR + 0x15C);
125 writel(0x4, IOMUXC_BASE_ADDR + 0x604);
126 writel(0x1C5, IOMUXC_BASE_ADDR + 0x3BC);
129 writel(0x0, IOMUXC_BASE_ADDR + 0x160);
130 writel(0x1C5, IOMUXC_BASE_ADDR + 0x3C0);
133 writel(0x0, IOMUXC_BASE_ADDR + 0x164);
134 writel(0x4, IOMUXC_BASE_ADDR + 0x600);
135 writel(0x1C4, IOMUXC_BASE_ADDR + 0x3C4);
138 writel(0x0, IOMUXC_BASE_ADDR + 0x168);
139 writel(0x1C4, IOMUXC_BASE_ADDR + 0x3C8);
141 /* Wait for UART to finish transmitting */
142 while (!(readl(UART1_BASE_ADDR + UARO_UTS) & 0x40));
145 val = readl(UART1_BASE_ADDR + UARO_UCR1);
146 writel(val & 0xfffffffe, UART1_BASE_ADDR + UARO_UCR1); /* reset UARTEN */
148 /* Set to default POR state */
149 writel(0x00000000, UART1_BASE_ADDR + UARO_UCR1);
150 writel(0x00000000, UART1_BASE_ADDR + UARO_UCR2);
152 while (!(readl(UART1_BASE_ADDR + UARO_UCR2) & 1)); /* wait for SRST = 1 */
154 writel(0x00000704, UART1_BASE_ADDR + UARO_UCR3);
155 writel(0x00008000, UART1_BASE_ADDR + UARO_UCR4);
156 writel(0x00000801, UART1_BASE_ADDR + UARO_UFCR);
157 writel(0x0000002B, UART1_BASE_ADDR + UARO_UESC);
158 writel(0x00000000, UART1_BASE_ADDR + UARO_UTIM);
159 writel(0x00000000, UART1_BASE_ADDR + UARO_UBIR);
160 writel(0x00000000, UART1_BASE_ADDR + UARO_UBMR);
161 writel(0x00000000, UART1_BASE_ADDR + UARO_ONEMS);
162 writel(0x00000000, UART1_BASE_ADDR + UARO_UTS);
164 /* Configure FIFOs */
165 writel((1 << 0) | (4 << 7) | (2 << 10), UART1_BASE_ADDR + UARO_UFCR);
166 UartRefFreq = 66500000 / 2;
168 /* Setup One MS timer */
169 writel((UartRefFreq / 1000), UART1_BASE_ADDR + UARO_ONEMS);
172 val = readl(UART1_BASE_ADDR + UARO_UCR2);
175 val |= (1 << 14); /* Ignore RTS */
177 writel(val, UART1_BASE_ADDR + UARO_UCR2);
180 val = readl(UART1_BASE_ADDR + UARO_UCR1);
181 writel(val | 1, UART1_BASE_ADDR + UARO_UCR1);
184 val = readl(UART1_BASE_ADDR + UARO_UCR2);
188 writel(val, UART1_BASE_ADDR + UARO_UCR2);
190 /* Clear status flags */
191 val = readl(UART1_BASE_ADDR + UARO_USR2);
193 writel(val, UART1_BASE_ADDR + UARO_USR2);
195 /* Clear status flags */
196 val = readl(UART1_BASE_ADDR + UARO_USR1);
198 writel(val, UART1_BASE_ADDR + UARO_USR1);
200 /* Set the numerator value minus one of the BRM ratio */
201 writel((115200 / 100) - 1, UART1_BASE_ADDR + UARO_UBIR);
203 /* Set the denominator value minus one of the BRM ratio */
204 writel((UartRefFreq / 1600) - 1, UART1_BASE_ADDR + UARO_UBMR);
206 writel('+', UART1_BASE_ADDR + UARO_UTXD);
209 void plf_send_char(unsigned char c)
211 /* Wait for UART to finish transmitting */
212 while (!(readl(UART1_BASE_ADDR + UARO_UTS) & 0x40));
214 writel(c, UART1_BASE_ADDR + UARO_UTXD);
217 void plf_send_string(const char *spt)
221 while ((achar = *(spt++)) != '\0') {
222 plf_send_char(achar);
226 void plf_printhex(unsigned long val)
230 for (i = 28; i >= 0; i -= 4) {
231 int digit = (val >> i) & 0xf;
232 plf_send_char(digit + ((digit < 10) ? '0' : ('A' - 10)));
236 void plf_dumpmem(unsigned long addr, int len)
240 for (i = 0; i < len; i += 4) {
241 unsigned long *wp = (unsigned long *)(addr + i);
245 plf_printhex(addr + i);
257 void hal_mmu_check(void)
259 unsigned long cr0, cr1;
261 asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r"(cr0) /*:*/);
262 asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r"(cr1) /*:*/);
270 #define DBG_FUNC() do { \
271 plf_send_string(__FUNCTION__); \
272 plf_send_char('\r'); \
273 plf_send_char('\n'); \
277 void hal_mmu_init(void)
279 unsigned long ttb_base = RAM_BANK0_BASE + 0x4000;
287 * Set the TTB register
289 asm volatile ("mcr p15, 0, %0, c2, c0, 0" : : "r"(ttb_base) /*:*/);
292 * Set the Domain Access Control Register
294 i = ARM_ACCESS_DACR_DEFAULT;
295 asm volatile ("mcr p15, 0, %0, c3, c0, 0" : : "r"(i) /*:*/);
298 * First clear all TT entries - ie Set them to Faulting
300 memset((void *)ttb_base, 0, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE);
302 /* Physical Virtual Size Attributes Function */
303 /* Base Base MB cached? buffered? access permissions */
304 /* xxx00000 xxx00000 */
305 X_ARM_MMU_SECTION(0x000, 0x200, 0x200, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* ROM */
306 X_ARM_MMU_SECTION(0x100, 0x100, 0x001, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* IRAM */
307 X_ARM_MMU_SECTION(0x400, 0x000, TX37_SDRAM_SIZE >> 20, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM */
308 X_ARM_MMU_SECTION(0x400, 0x400, TX37_SDRAM_SIZE >> 20, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM */
309 X_ARM_MMU_SECTION(0x7ff, 0x7ff, 0x001, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* NAND Flash buffer */
310 X_ARM_MMU_SECTION(0x800, 0x800, 0x020, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* IPUv3D */
311 X_ARM_MMU_SECTION(0xB00, 0xB00, 0x400, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* periperals */
315 plf_printhex(ttb_base);
320 plf_dumpmem(ttb_base, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE);
323 plf_dumpmem(0xc3fa8000, 0x1000);
326 plf_dumpmem(0xc3fa8000, 0x1000);
327 plf_dumpmem(0xc3fa8000, 0x1000);
328 plf_dumpmem(0xc3fa8000, 0x1000);
334 // Platform specific initialization
337 void plf_hardware_init(void)
345 v = 0x0040174A; // modified
346 writel(v, NFC_FLASH_CONFIG2_REG);
348 writel(0xFFFF0000, UNLOCK_BLK_ADD0_REG);
349 writel(0xFFFF0000, UNLOCK_BLK_ADD1_REG);
350 writel(0xFFFF0000, UNLOCK_BLK_ADD2_REG);
351 writel(0xFFFF0000, UNLOCK_BLK_ADD3_REG);
353 v = NFC_WR_PROT_CS0 | NFC_WR_PROT_BLS_UNLOCK | NFC_WR_PROT_WPC;
354 writel(v, NFC_WR_PROT_REG);
356 writel(0, NFC_IPC_REG);
359 //Enable UART transceivers also reset the Ethernet/external UART
360 temp = readw(PBC_BASE + PBC_BCTRL1);
362 writew(0x8023, PBC_BASE + PBC_BCTRL1);
364 for (i = 0; i < 100000; i++) {
367 // clear the reset, toggle the LEDs
368 writew(0xDF, PBC_BASE + PBC_BCTRL1_CLR);
370 for (i = 0; i < 100000; i++) {
373 dummy = readb(0xB4000008);
374 dummy = readb(0xB4000007);
375 dummy = readb(0xB4000008);
376 dummy = readb(0xB4000007);
380 /* Reset interrupt status reg */
381 writew(0x1F, PBC_INT_REST);
382 writew(0x00, PBC_INT_REST);
383 writew(0xFFFF, PBC_INT_MASK);
387 writel(0x0, IOMUXC_BASE_ADDR + 0x15C);
388 writel(0x4, IOMUXC_BASE_ADDR + 0x604);
389 writel(0x1C5, IOMUXC_BASE_ADDR + 0x3BC);
392 writel(0x0, IOMUXC_BASE_ADDR + 0x160);
393 writel(0x1C5, IOMUXC_BASE_ADDR + 0x3C0);
396 writel(0x0, IOMUXC_BASE_ADDR + 0x164);
397 writel(0x4, IOMUXC_BASE_ADDR + 0x600);
398 writel(0x1C4, IOMUXC_BASE_ADDR + 0x3C4);
401 writel(0x0, IOMUXC_BASE_ADDR + 0x168);
402 writel(0x1C4, IOMUXC_BASE_ADDR + 0x3C8);
406 static void configure_gpio(cyg_uint32 port, cyg_uint32 pin,
407 cyg_uint32 io_select, cyg_uint32 dir)
409 cyg_uint32 tmp, rnum, roffset, cfg_val;
411 if ((io_select & 0x200) == 0x200) {
412 rnum = (io_select >> 12) & 0xff;
413 roffset = (io_select >> 10) & 0x3;
414 cfg_val = (io_select & 0xff);
415 tmp = iomux_sw_mux_ctrl_reg_array[port][rnum];
416 tmp &= ~(0xff << (roffset * 8));
417 tmp |= (cfg_val << (roffset * 8));
418 iomux_sw_mux_ctrl_reg_array[port][rnum] = tmp;
420 if ((io_select & 0x100) == 0x100) {
421 /* Configure the direction of GPIO */
423 *data_dir_reg_ptr_array[port] |= (1 << pin);
425 *data_dir_reg_ptr_array[port] &= ~(1 << pin);
430 static void configure_pad(cyg_uint32 port, cyg_uint32 reg_index, cyg_uint32 val)
432 iomux_sw_mux_ctrl_reg_array[port][reg_index] = val;
436 #include CYGHWR_MEMORY_LAYOUT_H
438 typedef void code_fun(void);
440 void board_program_new_stack(void *func)
442 register CYG_ADDRESS stack_ptr asm("sp");
443 register CYG_ADDRESS old_stack asm("r4");
444 register code_fun *new_func asm("r0");
445 old_stack = stack_ptr;
446 stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
447 new_func = (code_fun*)func;
449 stack_ptr = old_stack;
452 #define SRC_SRSR 0x08
454 static void display_board_info(void)
456 char *reset_cause = "UNKNOWN";
460 diag_printf("\nBoard Type: Ka-Ro TX37\n");
462 HAL_READ_UINT32(SRC_BASE_ADDR + SRC_SRSR, srsr);
465 reset_cause = "POWER_ON RESET";
468 reset_cause = "EXTERNAL RESET";
471 reset_cause = "COLD RESET";
474 reset_cause = "WATCHDOG RESET";
477 reset_cause = "JTAG RESET";
480 reset_cause = "SOFT RESET";
484 diag_printf("Last RESET cause: %s\n", reset_cause);
487 RedBoot_init(display_board_info, RedBoot_INIT_LAST);