]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/mx51/karo/v1_0/src/tx51_misc.c
d835358e4c1c954d2127a7a61e5287367ef951a8
[karo-tx-redboot.git] / packages / hal / arm / mx51 / karo / v1_0 / src / tx51_misc.c
1 //==========================================================================
2 //
3 //      tx51_misc.c
4 //
5 //      HAL misc board support code for the tx51
6 //
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.
12 //
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.
16 //
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
20 // for more details.
21 //
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.
25 //
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.
32 //
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.
35 //
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
42 #include <stdlib.h>
43 #include <redboot.h>
44 #include <string.h>
45 #include <pkgconf/hal.h>
46 #include <pkgconf/system.h>
47 #include CYGBLD_HAL_PLATFORM_H
48
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
52
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 <cyg/hal/mx51_iomux.h>
60 #include <cyg/hal/karo_tx51.h>          // Platform specifics
61
62 #include <cyg/infra/diag.h>                     // diag_printf
63
64 // All the MM table layout is here:
65 #include <cyg/hal/hal_mm.h>
66
67
68 /* MMU table definitions */
69 #define SD_P0           (RAM_BANK0_BASE >> 20)                  /* physical RAM bank 0 address */
70 #define SD_C0           SD_P0                                                   /* virtual address for cached 1:1 mapping */
71 #define SD_S0           (RAM_BANK0_SIZE >> 20)                  /* RAM bank 0 size */
72 #define SD_U0           (UNCACHED_RAM_BASE_VIRT >> 20)
73 #ifdef RAM_BANK1_SIZE
74 #define SD_P1           (RAM_BANK1_BASE >> 20)                  /* physical RAM bank 1 address */
75 #define SD_C1           (SD_P0 + SD_S0)
76 #define SD_S1           (RAM_BANK1_SIZE >> 20)                  /* RAM bank 1 size */
77 #define SD_U1           (SD_U0 + SD_S0)
78 #define SD_HI           (SD_P1 + (SD_S1 - 1))
79 #endif
80
81 static unsigned long ttb_base = RAM_BANK0_BASE + 0x4000;
82
83 void hal_mmu_init(void)
84 {
85         unsigned long i;
86
87         /*
88          * Set the TTB register
89          */
90         asm volatile ("mcr  p15,0,%0,c2,c0,0" : : "r"(ttb_base));
91
92         /*
93          * Set the Domain Access Control Register
94          */
95         i = ARM_ACCESS_DACR_DEFAULT;
96         asm volatile ("mcr  p15,0,%0,c3,c0,0" : : "r"(i) /*:*/);
97
98         /*
99          * First clear all TT entries - ie Set them to Faulting
100          */
101         memset((void *)ttb_base, 0, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE);
102
103         /*                 Physical      Virtual         Size                   Attributes                                access permissions            Function */
104         /*                 Base  Base     MB                     cached?           buffered?                                                                                     */
105         /*                 xxx00000      xxx00000                                                                                */
106         X_ARM_MMU_SECTION(0x000, 0x200, 0x001, ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* Boot Rom */
107         X_ARM_MMU_SECTION(0x1FF, 0x1FF, 0x001, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* IRAM */
108         X_ARM_MMU_SECTION(0x400, 0x400, 0x200, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* IPUv3D */
109         X_ARM_MMU_SECTION(0x600, 0x600, 0x300, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* Internal Registers */
110         X_ARM_MMU_SECTION(SD_P0, 0x000, SD_S0, ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* SDRAM */
111         X_ARM_MMU_SECTION(SD_P0, SD_C0, SD_S0, ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* SDRAM */
112         X_ARM_MMU_SECTION(SD_P0, SD_U0, SD_S0, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM (uncached) */
113 #ifdef RAM_BANK1_SIZE
114         X_ARM_MMU_SECTION(SD_P1, SD_S0, SD_S1, ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* SDRAM */
115         X_ARM_MMU_SECTION(SD_P1, SD_C1, SD_S1, ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* SDRAM */
116         X_ARM_MMU_SECTION(SD_P1, SD_U1, SD_S1, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM */
117         /* make sure the last MiB in the upper bank of SDRAM (where RedBoot resides)
118          * has a unity mapping (required when switching MMU on) */
119         X_ARM_MMU_SECTION(SD_HI, SD_HI, 0x001, ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RO_RO); /* SDRAM bank1 identity mapping */
120 #endif
121         X_ARM_MMU_SECTION(0xB80, 0xB80, 0x010, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* CS1 EIM control */
122         X_ARM_MMU_SECTION(0xCC0, 0xCC0, 0x040, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* CS4/5/NAND Flash buffer */
123 }
124
125 static inline void set_reg(unsigned long addr, CYG_WORD32 set, CYG_WORD32 clr)
126 {
127         CYG_WORD32 val;
128
129         HAL_READ_UINT32(addr, val);
130         val = (val & ~clr) | set;
131         HAL_WRITE_UINT32(addr, val);
132 }
133
134 #define GPIO_BASE(grp)          (GPIO1_BASE_ADDR + (((grp) - 1) << 14))
135 static inline void setup_gpio(int grp, int bit)
136 {
137         set_reg(GPIO_BASE(grp) + GPIO_DR, 0, 1 << bit);
138         set_reg(GPIO_BASE(grp) + GPIO_GDIR, 1 << bit, 0);
139 }
140
141 //
142 // Platform specific initialization
143 //
144 static void uart_gpio_init(void)
145 {
146         writel(0, IOMUXC_SW_MUX_CTL_PAD_UART1_TXD);
147         writel(0, IOMUXC_SW_MUX_CTL_PAD_UART1_RXD);
148         /* pad_ctl: PKE | PUE | DSE_HIGH | SRE */
149         writel(0x0c5, IOMUXC_SW_PAD_CTL_PAD_UART1_TXD);
150         /* pad_ctl: HYS | PKE | PUE | DSE_HIGH | SRE */
151         writel(0x1c5, IOMUXC_SW_PAD_CTL_PAD_UART1_RXD);
152         /* pad_ctl: HYS | PKE | PUE | DSE_HIGH */
153         writel(0x1c4, IOMUXC_SW_PAD_CTL_PAD_UART1_RTS);
154         writel(0x1c4, IOMUXC_SW_PAD_CTL_PAD_UART1_CTS);
155 }
156
157 /* GPIOs to set up for TX51/Starterkit-5:
158    Function  FCT  GPIO        Pad        IOMUXC SW_PAD  SW_PAD mode
159                                          OFFSET  CTRL    MUX
160 FEC_MDC       2   GPIO3_19 NANDF_CS3     0x13c   0x524
161 FEC_MDIO      3   GPIO2_22 EIM_EB2       0x0d4   0x468  0x954  0
162 FEC_RX_CLK    1   GPIO3_11 NANDF_RB3     0x128   0x504  0x968  0
163 FEC_RX_DV     2   GPIO3_29 NANDF_D11     0x164   0x54c  0x96c  0
164 FEC_RXD0      2   GPIO3_31 NANDF_D9      0x16c   0x554  0x958  0
165 FEC_RXD1      3   GPIO2_23 EIM_EB3       0x0d8   0x64c  0x95c  0
166 FEC_RXD2      3   GPIO2_27 EIM_CS2       0x0e8   0x47c  0x960  0
167 FEC_RXD3      3   GPIO2_28 EIM_CS3       0x0ec   0x480  0x964  0
168 FEC_RX_ER     3   GPIO2_29 EIM_CS4       0x0f0   0x484  0x970  0
169 FEC_TX_CLK    1   GPIO3_24 NANDF_RDY_INT 0x150   0x538  0x974  0
170 FEC_TX_EN     1   GPIO3_23 NANDF_CS7     0x14c   0x534
171 FEC_TXD0      2   GPIO4_0  NANDF_D8      0x170   0x558
172 FEC_TXD1      2   GPIO3_20 NANDF_CS4     0x140   0x528
173 FEC_TXD2      2   GPIO3_21 NANDF_CS5     0x144   0x52c
174 FEC_TXD3      2   GPIO3_22 NANDF_CS6     0x148   0x530
175 FEC_COL       1   GPIO3_10 NANDF_RB2     0x124   0x500  0x94c  0
176 FEC_CRS       3   GPIO2_30 EIM_CS5       0x0f4   0x488  0x950  0
177 FEC_TX_ER     2   GPIO3_18 NANDF_CS2     0x138   0x520            (INT)
178
179 FEC_RESET#    1   GPIO2_14 EIM_A20       0x0ac   0x440
180 FEC_ENABLE    0   GPIO1_3  GPIO1_3       0x3d0   0x7d8
181 ---
182 OSC26M_ENABLE LP3972 GPIO2
183 */
184 static void fec_gpio_init(void)
185 {
186         /* setup GPIO data register to 0 and DDIR output for FEC PHY pins */
187         setup_gpio(3, 19);
188         setup_gpio(2, 22);
189         setup_gpio(3, 11);
190         setup_gpio(3, 29);
191         setup_gpio(3, 31);
192         setup_gpio(2, 23);
193         setup_gpio(2, 27);
194         setup_gpio(2, 28);
195         setup_gpio(2, 29);
196         setup_gpio(3, 24);
197         setup_gpio(3, 23);
198         setup_gpio(4, 0);
199         setup_gpio(3, 20);
200         setup_gpio(3, 21);
201         setup_gpio(3, 22);
202         setup_gpio(3, 10);
203         setup_gpio(2, 30);
204         setup_gpio(3, 18);
205
206         setup_gpio(2, 14);
207         setup_gpio(1, 3);
208
209         /* setup input mux for FEC pins */
210         HAL_WRITE_UINT32(IOMUXC_FEC_FEC_MDI_SELECT_INPUT, 0);
211         HAL_WRITE_UINT32(IOMUXC_FEC_FEC_RX_CLK_SELECT_INPUT, 0);
212         HAL_WRITE_UINT32(IOMUXC_FEC_FEC_RX_DV_SELECT_INPUT, 0);
213         HAL_WRITE_UINT32(IOMUXC_FEC_FEC_RDATA_0_SELECT_INPUT, 0);
214         HAL_WRITE_UINT32(IOMUXC_FEC_FEC_RDATA_1_SELECT_INPUT, 0);
215         HAL_WRITE_UINT32(IOMUXC_FEC_FEC_RDATA_2_SELECT_INPUT, 0);
216         HAL_WRITE_UINT32(IOMUXC_FEC_FEC_RDATA_3_SELECT_INPUT, 0);
217         HAL_WRITE_UINT32(IOMUXC_FEC_FEC_RX_ER_SELECT_INPUT, 0);
218         HAL_WRITE_UINT32(IOMUXC_FEC_FEC_TX_CLK_SELECT_INPUT, 0);
219         HAL_WRITE_UINT32(IOMUXC_FEC_FEC_COL_SELECT_INPUT, 0);
220         HAL_WRITE_UINT32(IOMUXC_FEC_FEC_CRS_SELECT_INPUT, 0);
221
222         /* setup FEC PHY pins for GPIO function (with SION set) */
223         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_NANDF_CS3, 2 | 0x10);
224         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_EIM_EB2, 3 | 0x10);
225         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_NANDF_RB3, 1 | 0x10);
226         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_NANDF_D11, 2 | 0x10);
227         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_NANDF_D9, 2 | 0x10);
228         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_EIM_EB3, 3 | 0x10);
229         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_EIM_CS2, 3 | 0x10);
230         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_EIM_CS3, 3 | 0x10);
231         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_EIM_CS4, 3 | 0x10);
232         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_NANDF_RDY_INT, 1 | 0x10);
233         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_NANDF_CS7, 1 | 0x10);
234         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_NANDF_D8, 2 | 0x10);
235         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_NANDF_CS4, 2 | 0x10);
236         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_NANDF_CS5, 2 | 0x10);
237         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_NANDF_CS6, 2 | 0x10);
238         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_NANDF_RB2, 1 | 0x10);
239         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_EIM_CS5, 3 | 0x10);
240         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_NANDF_CS2, 3 | 0x10);
241
242         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_EIM_A20, 1 | 0x10);
243         HAL_WRITE_UINT32(IOMUXC_SW_MUX_CTL_PAD_GPIO1_3, 0 | 0x10);
244 }
245
246 #ifdef CYGHWR_MX51_LCD_LOGO
247 void mxc_ipu_iomux_config(void)
248 {
249         // configure display data0~17 for LCD panel
250         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT0, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
251         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT0, 0x5);
252         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT1, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
253         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT1, 0x5);
254         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT2, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
255         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT2,0x5);
256         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT3, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
257         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT3, 0x5);
258         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT4, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
259         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT4, 0x5);
260         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT5, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
261         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT5, 0x5);
262         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT6, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
263         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT6, 0x5);
264         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT7, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
265         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT7, 0x5);
266         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT8, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
267         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT8, 0x5);
268         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT9, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
269         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT9, 0x5);
270         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT10, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
271         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT10, 0x5);
272         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT11, 0x5);
273         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT12, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
274         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT12, 0x5);
275         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT13, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
276         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT13, 0x5);
277         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT14, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
278         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT14, 0x5);
279         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT15, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
280         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT15, 0x5);
281         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT16, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
282         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT16, 0x5);
283         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT17, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
284         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT17, 0x5);
285
286         // DI1_PIN2 and DI1_PIN3, configured to be HSYNC and VSYNC of LCD
287         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DI1_PIN2, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
288         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DI1_PIN3, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
289
290         // PCLK - DISP_CLK
291         // No IOMUX configuration required, as there is no IOMUXing for this pin
292
293         // DRDY - PIN15
294         // No IOMUX configuration required, as there is no IOMUXing for this pin
295
296         // configure this pin to be the SER_DISP_CS
297
298         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DI1_D1_CS, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT4);
299         CONFIG_PIN(IOMUXC_SW_PAD_CTL_PAD_DI1_D1_CS, 0x85);
300
301         // configure to be DISPB1_SER_RS
302         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DI_GP1, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
303         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DI_GP1, 0x85);
304         // configure to be SER_DISP1_CLK
305         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DI_GP2, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
306         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DI_GP2, 0x85);
307         // configure to be DISPB1_SER_DIO
308         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DI_GP3, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
309         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DI_GP3, 0xC5);
310         // configure to be DISPB1_SER_DIN
311         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DI_GP4, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
312         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DI_GP4, 0xC4);
313         //CS0
314         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DI1_D0_CS, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT1);
315         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DI1_D0_CS, 0x85);
316         // WR
317         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DI1_PIN11, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT1);
318         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DI1_PIN11, 0x85);
319         // RD
320         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DI1_PIN12, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT1);
321         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DI1_PIN12, 0x85);
322         // RS
323         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_DI1_PIN13, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT1);
324         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_DI1_PIN13, 0x85);
325
326         /* LCD Power Enable GPIO4_14 (active High) */
327         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_CSI2_HSYNC, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT3);
328         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_CSI2_HSYNC, 0x04);
329         gpio_set_bit(4, 14);
330
331         /* LCD Reset GPIO4_13 (active Low) */
332         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_CSI2_VSYNC, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT3);
333         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_CSI2_VSYNC, 0x04);
334         gpio_set_bit(4, 13);
335
336         /* LCD Backlight GPIO1_2 (PWM 0: full brightness 1: off) */
337         CONFIG_PIN(IOMUXC_SW_MUX_CTL_PAD_GPIO1_2, IOMUX_PIN_SION_REGULAR | IOMUX_SW_MUX_CTL_ALT0);
338         CONFIG_PAD(IOMUXC_SW_PAD_CTL_PAD_GPIO1_2, 0x04);
339         gpio_clr_bit(1, 2);
340 }
341 RedBoot_init(mxc_ipu_iomux_config, RedBoot_INIT_SECOND);
342 #endif
343
344 //
345 // Platform specific initialization
346 //
347
348 void plf_hardware_init(void)
349 {
350 #ifdef RAM_BANK1_SIZE
351         /* destroy mapping for high area in SDRAM */
352         X_ARM_MMU_SECTION(SD_HI, 0, 0, 0, 0, ARM_ACCESS_PERM_NONE_NONE);
353 #endif
354         uart_gpio_init();
355         fec_gpio_init();
356
357         /* NFC setup */
358         writel(readl(NFC_FLASH_CONFIG3_REG) |
359                         (1 << 15) | /* assert RBB_MODE  (see Errata: ENGcm09970) */
360                         (1 << 20) | /* assert NO_SDMA */
361                         (1 << 3), /* set bus width to 8bit */
362                         NFC_FLASH_CONFIG3_REG);
363
364         /* configure MIPI-HSC legacy mode required to get data on DISP1_DAT[0..5] */
365         writel(0xf00, MIPI_HSC_BASE_ADDR);
366         /* bypass MDT and enable legacy CSI interface */
367         writel((3 << 16) | (2 << 2) | (2 << 0), MIPI_HSC_BASE_ADDR + 0x800);
368 }
369
370 static int lp3972_reg_read(cyg_uint8 reg)
371 {
372         int ret;
373         ret = -ENOSYS;
374         return ret;
375 }
376
377 static int lp3972_reg_write(cyg_uint8 reg, cyg_uint8 val)
378 {
379         int ret;
380         ret = -ENOSYS;
381         return ret;
382 }
383
384 int tx51_mac_addr_program(unsigned char mac_addr[ETHER_ADDR_LEN])
385 {
386         int ret = 0;
387         int i;
388
389         for (i = 0; i < ETHER_ADDR_LEN; i++) {
390                 unsigned char fuse = readl(SOC_FEC_MAC_BASE +
391                                                                 ETHER_ADDR_LEN * 4 - ((i + 1) << 2));
392
393                 if ((fuse | mac_addr[i]) != mac_addr[i]) {
394                         diag_printf("MAC address fuse cannot be programmed: fuse[%d]=0x%02x -> 0x%02x\n",
395                                                 i, fuse, mac_addr[i]);
396                         return -1;
397                 }
398                 if (fuse != mac_addr[i]) {
399                         ret = 1;
400                 }
401         }
402         if (ret == 0) {
403                 return ret;
404         }
405         ret = lp3972_reg_write(0x39, 0xf0);
406         if (ret < 0) {
407                 diag_printf("Failed to switch fuse programming voltage: %d\n", ret);
408                 return ret;
409         }
410         ret = lp3972_reg_read(0x39);
411         if (ret != 0xf0) {
412                 diag_printf("Failed to switch fuse programming voltage: %d\n", ret);
413                 return ret;
414         }
415         for (i = 0; i < ETHER_ADDR_LEN; i++) {
416                 int bit;
417                 unsigned char fuse = readl(SOC_FEC_MAC_BASE +
418                                                                 ETHER_ADDR_LEN * 4 - ((i + 1) << 2));
419
420                 for (bit = 0; bit < 8; bit++) {
421                         if (((mac_addr[i] >> bit) & 0x1) == 0)
422                                 continue;
423                         if (((mac_addr[i] >> bit) & 1) == ((fuse >> bit) & 1)) {
424                                 continue;
425                         }
426                         if (fuse_blow(SOC_MAC_ADDR_FUSE_BANK,
427                                                         SOC_MAC_ADDR_FUSE + ETHER_ADDR_LEN - 1 - i,
428                                                         bit)) {
429                                 diag_printf("Failed to blow fuse bank 0 row %d bit %d\n",
430                                                         i, bit);
431                                 ret = -1;
432                                 goto out;
433                         }
434                 }
435         }
436 #ifdef SOC_MAC_ADDR_LOCK_BIT
437         fuse_blow(SOC_MAC_ADDR_FUSE_BANK, SOC_MAC_ADDR_LOCK_FUSE,
438                         SOC_MAC_ADDR_LOCK_BIT);
439 #endif
440 out:
441         lp3972_reg_write(0x39, 0);
442         return ret;
443 }
444
445 #include CYGHWR_MEMORY_LAYOUT_H
446
447 typedef void code_fun(void);
448
449 void tx51_program_new_stack(void *func)
450 {
451         register CYG_ADDRESS stack_ptr asm("sp");
452         register CYG_ADDRESS old_stack asm("r4");
453         register code_fun *new_func asm("r0");
454         old_stack = stack_ptr;
455         stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
456         new_func = (code_fun*)func;
457         new_func();
458         stack_ptr = old_stack;
459 }
460
461 void increase_core_voltage(bool i)
462 {
463         int ret;
464
465         ret = lp3972_reg_read(0x23);
466         if (ret < 0) {
467                 diag_printf("Failed to read core voltage: %d\n", ret);
468         }
469
470         if (i) {
471                 /* Set core voltage to 1.175V */
472                 ret = 0x12;
473         } else {
474                 /* Set core voltage to 1.05V */
475                 ret = 0x0d;
476         }
477
478         ret = lp3972_reg_write(0x23, ret);
479         if (ret < 0) {
480                 diag_printf("Failed to write core voltage: %d\n", ret);
481         }
482 }
483
484 static unsigned long random;
485 /* provide at least _some_ sort of randomness */
486 #define MAX_LOOPS       100
487 extern int hal_timer_count(void);
488
489 static void random_init(void)
490 {
491         unsigned long timer;
492
493         int loops = MAX_LOOPS;
494
495         do {
496                 timer = hal_timer_count();
497                 srand(random + timer);
498                 random = rand();
499         } while ((timer < 5) || ((timer & (random >> (random & 0x1f))) && --loops > 0));
500 }
501 RedBoot_init(random_init, RedBoot_INIT_FIRST);
502
503 #define WDOG_WRSR       ((CYG_WORD16 *)0x10002004)
504 static void display_board_type(void)
505 {
506         CYG_WORD32 reset_cause;
507         const char *dlm = "";
508
509         diag_printf("\nBoard Type: Ka-Ro TX51\n");
510         diag_printf("Last RESET cause: ");
511         HAL_READ_UINT32(SRC_BASE_ADDR + 8, reset_cause);
512
513         if ((reset_cause & 9) == 1) {
514                 diag_printf("%sPOWER_ON RESET", dlm);
515                 dlm = " | ";
516         } else if ((reset_cause & 9) == 9) {
517                 diag_printf("%sUSER RESET", dlm);
518                 dlm = " | ";
519         }
520         if ((reset_cause & 0x11) == 0x11) {
521                 diag_printf("%sWATCHDOG RESET", dlm);
522                 dlm = " | ";
523         } else if ((reset_cause & 0x11) == 0x10) {
524                 diag_printf("%sSOFT RESET", dlm);
525                 dlm = " | ";
526         }
527         if (*dlm == '\0') {
528                 diag_printf("UNKNOWN: %08x\n", reset_cause);
529         } else {
530                 diag_printf("\n");
531         }
532 }
533
534 static void display_board_info(void)
535 {
536         display_board_type();
537 }
538 RedBoot_init(display_board_info, RedBoot_INIT_LAST);
539
540 void mxc_i2c_init(unsigned int module_base)
541 {
542         switch (module_base) {
543         case I2C_BASE_ADDR:
544                 writel(0x11, IOMUXC_BASE_ADDR + 0x210);
545                 writel(0x1ad, IOMUXC_BASE_ADDR + 0x600);
546                 writel(0x1, IOMUXC_BASE_ADDR + 0x9B4);
547
548                 writel(0x11, IOMUXC_BASE_ADDR + 0x224);
549                 writel(0x1ad, IOMUXC_BASE_ADDR + 0x614);
550                 writel(0x1, IOMUXC_BASE_ADDR + 0x9B0);
551                 break;
552         case I2C2_BASE_ADDR:
553                 writel(0x12, IOMUXC_BASE_ADDR + 0x3CC);  // i2c SCL
554                 writel(0x3, IOMUXC_BASE_ADDR + 0x9B8);
555                 writel(0x1ed, IOMUXC_BASE_ADDR + 0x7D4);
556
557                 writel(0x12, IOMUXC_BASE_ADDR + 0x3D0); // i2c SDA
558                 writel(0x3, IOMUXC_BASE_ADDR + 0x9BC);
559                 writel(0x1ed, IOMUXC_BASE_ADDR + 0x7D8);
560                 break;
561         default:
562                 diag_printf("Invalid I2C base: 0x%x\n", module_base);
563                 return;
564         }
565 }