1 //==========================================================================
5 // HAL misc board support code for the tx25
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 //========================================================================*/
45 #include <pkgconf/hal.h>
46 #include <pkgconf/system.h>
47 #include CYGBLD_HAL_PLATFORM_H
49 #include <cyg/infra/cyg_type.h> // base types
50 #include <cyg/infra/cyg_trac.h> // tracing macros
51 #include <cyg/infra/cyg_ass.h> // assertion macros
53 #include <cyg/hal/hal_io.h> // IO macros
54 #include <cyg/hal/hal_arch.h> // Register state info
55 #include <cyg/hal/hal_diag.h>
56 #include <cyg/hal/hal_intr.h> // Interrupt names
57 #include <cyg/hal/hal_cache.h>
58 #include <cyg/hal/hal_soc.h> // Hardware definitions
59 #include CYGBLD_HAL_PLF_DEFS_H // Platform specifics
61 #include <cyg/infra/diag.h> // diag_printf
63 // All the MM table layout is here:
64 #include <cyg/hal/hal_mm.h>
66 //#define EARLY_SERIAL_SETUP
68 #ifdef EARLY_SERIAL_SETUP
69 static void mxc_serial_setup(void);
71 static void uart_putc(int c)
73 while (readl(UART1_BASE_ADDR + 0xb4) & (1 << 4)) {
74 /* wait for !TX_FULL */
76 writel(c, UART1_BASE_ADDR + 0x40);
79 static void putcr(void)
85 static void printhex(unsigned int x, int len)
89 for (i = len - 1; i >= 0; i--) {
90 int c = (x >> (i * 4)) & 0xf;
100 static void dump_reg(unsigned long addr)
104 printhex(readl(addr), 8);
109 #define SD_SZ (RAM_BANK0_SIZE >> 20)
110 #ifdef RAM_BANK1_SIZE
112 #define SD_B1 (SD_B0 + SD_SZ)
113 #define SD_B2 (SD_B0 + 0x80 + SD_SZ)
114 #define SD_HI (0x900 + ((RAM_BANK1_SIZE >> 20) - 1))
117 void hal_mmu_init(void)
119 unsigned long ttb_base = RAM_BANK0_BASE + 0x4000;
123 * Set the TTB register
125 asm volatile ("mcr p15, 0, %0, c2, c0, 0" : : "r"(ttb_base));
128 * Set the Domain Access Control Register
130 i = ARM_ACCESS_DACR_DEFAULT;
131 asm volatile ("mcr p15, 0, %0, c3, c0, 0" : : "r"(i));
134 * First clear all TT entries - ie Set them to Faulting
136 memset((void *)ttb_base, 0, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE);
138 /* Phys Virt Size Attributes Function */
139 /* Base Base MB cached? buffered? access permissions */
141 X_ARM_MMU_SECTION(0x000, 0xF00, 0x001, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* Boot Rom */
142 X_ARM_MMU_SECTION(0x43f, 0x43f, 0x3c1, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* Internal Registers */
143 X_ARM_MMU_SECTION(0x800, 0x000, SD_SZ, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM */
144 X_ARM_MMU_SECTION(0x800, 0x800, SD_SZ, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM */
145 X_ARM_MMU_SECTION(0x800, 0x880, SD_SZ, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM */
146 #ifdef RAM_BANK1_SIZE
147 X_ARM_MMU_SECTION(0x900, SD_SZ, SD_SZ, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM */
148 X_ARM_MMU_SECTION(0x900, SD_B1, SD_SZ, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM */
149 X_ARM_MMU_SECTION(0x900, SD_B2, SD_SZ, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM */
150 /* make sure the last MiB in the upper bank of SDRAM (where RedBoot resides)
151 * has a unity mapping (required when switching MMU on) */
152 X_ARM_MMU_SECTION(SD_HI, SD_HI, 0x001, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RO_RO); /* SDRAM bank1 identity mapping */
154 X_ARM_MMU_SECTION(0xB20, 0xB20, 0x0E0, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* ESDCTL, WEIM, M3IF, EMI, NFC, External I/O */
155 #ifdef EARLY_SERIAL_SETUP
160 static inline void set_reg(unsigned long addr, CYG_WORD32 set, CYG_WORD32 clr)
163 HAL_READ_UINT32(addr, val);
164 val = (val & ~clr) | set;
165 HAL_WRITE_UINT32(addr, val);
169 // Platform specific initialization
171 static void fec_gpio_init(void)
173 /* GPIOs to set up for TX25/Starterkit-5:
174 Function GPIO Dir act. FCT
176 FEC_RESET PB30 OUT LOW GPIO
177 FEC_ENABLE PB27 OUT HIGH GPIO
178 OSCM26_ENABLE PB22 OUT HIGH GPIO
179 EXT_WAKEUP PB24 IN HIGH GPIO
180 FEC_TXEN PF23 OUT OUT AIN
181 FEC_TXCLK PD11 OUT IN AOUT
184 #define OCR_SHIFT(bit) (((bit) * 2) % 32)
185 #define OCR_MASK(bit) (3 << (OCR_SHIFT(bit)))
186 #define OCR_VAL(bit,val) (((val) << (OCR_SHIFT(bit))) & (OCR_MASK(bit)))
187 #define GPR_SHIFT(bit) (bit)
188 #define GPR_MASK(bit) (1 << (GPR_SHIFT(bit)))
189 #define GPR_VAL(bit,val) (((val) << (GPR_SHIFT(bit))) & (GPR_MASK(bit)))
190 #define ICONF_SHIFT(bit) (((bit) * 2) % 32)
191 #define ICONF_MASK(bit) (3 << (ICONF_SHIFT(bit)))
192 #define ICONF_VAL(bit,val) (((val) << (ICONF_SHIFT(bit))) & (ICONF_MASK(bit)))
195 * make sure the ETH PHY strap pins are pulled to the right voltage
196 * before deasserting the PHY reset GPIO
201 writel(0, IOMUXC_BASE_ADDR + 0x01E8);
202 writel(0x1C0, IOMUXC_BASE_ADDR + 0x03E0);
205 writel(0, IOMUXC_BASE_ADDR + 0x01E4);
206 writel(0x1C0, IOMUXC_BASE_ADDR + 0x03DC);
209 writel(0, IOMUXC_BASE_ADDR + 0x01DC);
210 writel(0x1C0, IOMUXC_BASE_ADDR + 0x03D4);
213 writel(0, IOMUXC_BASE_ADDR + 0x01D0);
214 writel(0x40, IOMUXC_BASE_ADDR + 0x03C8);
217 writel(0, IOMUXC_BASE_ADDR + 0x01D8);
218 writel(0x40, IOMUXC_BASE_ADDR + 0x03D0);
221 writel(0, IOMUXC_BASE_ADDR + 0x01C8);
222 writel(0x40, IOMUXC_BASE_ADDR + 0x03C0);
225 writel(0, IOMUXC_BASE_ADDR + 0x01CC);
226 writel(0x1F0, IOMUXC_BASE_ADDR + 0x03C4);
229 writel(0, IOMUXC_BASE_ADDR + 0x01E0);
230 writel(0x1C0, IOMUXC_BASE_ADDR + 0x03D8);
233 writel(0, IOMUXC_BASE_ADDR + 0x01D4);
234 writel(0x40, IOMUXC_BASE_ADDR + 0x03CC);
237 * Set up the FEC_RESET_B and FEC_ENABLE GPIO pins.
238 * Assert FEC_RESET_B, then power up the PHY by asserting
239 * FEC_ENABLE, at the same time lifting FEC_RESET_B.
241 * FEC_RESET_B: gpio4[7] is ALT 5 mode of pin D13
242 * FEC_ENABLE_B: gpio4[9] is ALT 5 mode of pin D11
244 writel(0x15, IOMUXC_BASE_ADDR + 0x0090);
245 writel(0x15, IOMUXC_BASE_ADDR + 0x0098);
247 writel(0x8, IOMUXC_BASE_ADDR + 0x0288); // open drain
248 writel(0x0, IOMUXC_BASE_ADDR + 0x0290); // cmos, no pu/pd
250 /* drop PHY power and assert reset (low) */
251 val = readl(GPIO4_BASE_ADDR + GPIO_DR) & ~((1 << 7) | (1 << 9));
252 writel(val, GPIO4_BASE_ADDR + GPIO_DR);
254 /* make the pins output */
255 val = readl(GPIO4_BASE_ADDR + GPIO_GDIR) | (1 << 7) | (1 << 9);
256 writel(val, GPIO4_BASE_ADDR + GPIO_GDIR);
260 // Platform specific initialization
263 unsigned int g_clock_src;
264 unsigned int g_board_type = BOARD_TYPE_TX25KARO;
266 static void mxc_serial_setup(void)
270 writel(0, IOMUXC_BASE_ADDR + 0x170);
271 writel(0x1E0, IOMUXC_BASE_ADDR + 0x368);
274 writel(0, IOMUXC_BASE_ADDR + 0x174);
275 writel(0x40, IOMUXC_BASE_ADDR + 0x36c);
278 writel(0, IOMUXC_BASE_ADDR + 0x178);
279 writel(0x1E0, IOMUXC_BASE_ADDR + 0x370);
282 writel(0, IOMUXC_BASE_ADDR + 0x17c);
283 writel(0x40, IOMUXC_BASE_ADDR + 0x374);
286 void plf_hardware_init(void)
288 g_clock_src = FREQ_24MHZ;
293 #define SOC_FBAC0_REG IIM_BASE_ADDR
294 #define SOC_MAC_ADDR_LOCK_BIT 2
296 extern int fuse_blow(int bank, int row, int bit);
298 int tx25_mac_addr_program(unsigned char mac_addr[ETHER_ADDR_LEN])
303 for (i = 0; i < ETHER_ADDR_LEN; i++) {
304 unsigned char fuse = readl(SOC_MAC_ADDR_BASE + (i << 2));
306 if ((fuse | mac_addr[i]) != mac_addr[i]) {
307 diag_printf("MAC address fuse cannot be programmed: fuse[%d]=0x%02x -> 0x%02x\n",
308 i, fuse, mac_addr[i]);
311 if (fuse != mac_addr[i]) {
318 if (readl(SOC_FBAC0_REG) & (1 << SOC_MAC_ADDR_LOCK_BIT)) {
319 diag_printf("MAC address is locked\n");
322 for (i = 0; i < ETHER_ADDR_LEN; i++) {
324 unsigned char fuse = readl(SOC_MAC_ADDR_BASE + (i << 2));
326 for (bit = 0; bit < 8; bit++) {
327 if (((mac_addr[i] >> bit) & 0x1) == 0)
329 if (((mac_addr[i] >> bit) & 1) == ((fuse >> bit) & 1)) {
332 if (fuse_blow(0, i + ((SOC_MAC_ADDR_BASE & 0xff) >> 2), bit)) {
333 diag_printf("Failed to blow fuse bank 0 row %d bit %d\n",
339 if ((fuse = readl(SOC_MAC_ADDR_BASE + (i << 2))) != mac_addr[i]) {
340 diag_printf("Fuse[%d] verify failed; wrote: 0x%02x read: 0x%02x\n",
341 i + 26, mac_addr[i], fuse);
346 fuse_blow(0, 0, SOC_MAC_ADDR_LOCK_BIT);
351 #include CYGHWR_MEMORY_LAYOUT_H
353 typedef void code_fun(void);
355 void tx25_program_new_stack(void *func)
357 register CYG_ADDRESS stack_ptr asm("sp");
358 register CYG_ADDRESS old_stack asm("r4");
359 register code_fun *new_func asm("r0");
360 old_stack = stack_ptr;
361 stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
362 new_func = (code_fun*)func;
364 stack_ptr = old_stack;
367 static void display_clock_src(void)
369 diag_printf("Clock input is 24 MHz\n");
372 #define WDOG_WRSR ((CYG_WORD16 *)(WDOG_BASE_ADDR + 0x4))
373 #define CRM_RCSR ((CYG_WORD32 *)(CCM_BASE_ADDR + 0x28))
375 static void display_board_type(void)
377 diag_printf("\nBoard Type: Ka-Ro TX25\n");
380 static void display_board_info(void)
382 display_board_type();
385 RedBoot_init(display_board_info, RedBoot_INIT_LAST);