]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/mx53/karo/v1_0/src/tx53_misc.c
TX53 Release 2011-12-20
[karo-tx-redboot.git] / packages / hal / arm / mx53 / karo / v1_0 / src / tx53_misc.c
1 //==========================================================================
2 //
3 //      tx53_misc.c
4 //
5 //      HAL misc board support code for the tx53
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 CYGBLD_HAL_PLF_DEFS_H          // Platform specifics
60
61 #include <cyg/infra/diag.h>                     // diag_printf
62
63 // All the MM table layout is here:
64 #include <cyg/hal/hal_mm.h>
65
66 /* MMU table definitions */
67 #define SD_P0           (RAM_BANK0_BASE >> 20)                  /* physical RAM bank 0 address */
68 #define SD_C0           SD_P0                                                   /* virtual address for cached 1:1 mapping */
69 #define SD_S0           (RAM_BANK0_SIZE >> 20)                  /* RAM bank 0 size */
70 #define SD_U0           (UNCACHED_RAM_BASE_VIRT >> 20)
71 #ifdef RAM_BANK1_SIZE
72 #define SD_P1           (RAM_BANK1_BASE >> 20)                  /* physical RAM bank 1 address */
73 #define SD_C1           (SD_P0 + SD_S0)
74 #define SD_S1           (RAM_BANK1_SIZE >> 20)                  /* RAM bank 1 size */
75 #define SD_U1           (SD_U0 + SD_S0)
76 #define SD_HI           (SD_P1 + (SD_S1 - 1))
77 #endif
78
79 static unsigned long ttb_base = RAM_BANK0_BASE + 0x4000;
80
81 void hal_mmu_init(void)
82 {
83         unsigned long i;
84         /*
85          * Set the TTB register
86          */
87         asm volatile ("mcr  p15,0,%0,c2,c0,0" : : "r"(ttb_base));
88
89         /*
90          * Set the Domain Access Control Register
91          */
92         i = ARM_ACCESS_DACR_DEFAULT;
93         asm volatile ("mcr  p15,0,%0,c3,c0,0" : : "r"(i) /*:*/);
94
95         /*
96          * First clear all TT entries - ie Set them to Faulting
97          */
98         memset((void *)ttb_base, 0, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE);
99
100         /*                 Physical      Virtual         Size                   Attributes                                access permissions            Function */
101         /*                 Base  Base     MB                     cached?           buffered?                                                                                     */
102         /*                 xxx00000      xxx00000                                                                                */
103         X_ARM_MMU_SECTION(0x000, 0x200, 0x001, ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* Boot Rom */
104 //      X_ARM_MMU_SECTION(0x1FF, 0x1FF, 0x001, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* IRAM */
105         X_ARM_MMU_SECTION(0x180, 0x180, 0x080, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* IPUv3D */
106         X_ARM_MMU_SECTION(0x500, 0x500, 0x200, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* Internal Registers */
107         X_ARM_MMU_SECTION(SD_P0, 0x000, SD_S0, ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* SDRAM */
108         X_ARM_MMU_SECTION(SD_P0, SD_C0, SD_S0, ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* SDRAM */
109         X_ARM_MMU_SECTION(SD_P0, SD_U0, SD_S0, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM (uncached) */
110 #ifdef RAM_BANK1_SIZE
111         X_ARM_MMU_SECTION(SD_P1, SD_S0, SD_S1, ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* SDRAM */
112         X_ARM_MMU_SECTION(SD_P1, SD_C1, SD_S1, ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* SDRAM */
113         X_ARM_MMU_SECTION(SD_P1, SD_U1, SD_S1, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM */
114         /* make sure the last MiB in the upper bank of SDRAM (where RedBoot resides)
115          * has a unity mapping (required when switching MMU on) */
116         X_ARM_MMU_SECTION(SD_HI, SD_HI, 0x001, ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RO_RO); /* SDRAM bank1 identity mapping */
117 #endif
118         X_ARM_MMU_SECTION(0xF40, 0xF40, 0x040, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* CS1 EIM control & NFC buffer */
119 }
120
121 static inline void set_reg(CYG_ADDRESS addr, CYG_WORD32 set, CYG_WORD32 clr)
122 {
123         CYG_WORD32 val;
124
125         HAL_READ_UINT32(addr, val);
126         val = (val & ~clr) | set;
127         HAL_WRITE_UINT32(addr, val);
128 }
129
130 static inline void setup_gpio(int grp, int bit)
131 {
132         CYG_ADDRESS base = MX53_GPIO_ADDR(grp);
133
134         if (base == 0)
135                 return;
136         set_reg(base + GPIO_DR, 0, 1 << bit);
137         set_reg(base + GPIO_GDIR, 1 << bit, 0);
138 }
139
140 //
141 // Platform specific initialization
142 //
143 #define PAD_CTL_UART_OUT                MUX_PAD_CTRL(PAD_CTL_PKE | PAD_CTL_PUE | \
144                                                         PAD_CTL_PUS_100K_DOWN | PAD_CTL_DSE_HIGH | \
145                                                         PAD_CTL_SRE_FAST)
146 #define PAD_CTL_UART_IN         (MUX_PAD_CTRL(PAD_CTL_HYS) | PAD_CTL_UART_OUT)
147
148 static iomux_v3_cfg_t tx53_uart_pads[] = {
149         MX53_PAD_PATA_DIOW__UART1_TXD_MUX | PAD_CTL_UART_OUT,
150         MX53_PAD_PATA_DMACK__UART1_RXD_MUX | PAD_CTL_UART_IN,
151
152         MX53_PAD_PATA_DMARQ__UART2_TXD_MUX | PAD_CTL_UART_OUT,
153         MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX | PAD_CTL_UART_IN,
154
155         MX53_PAD_PATA_CS_0__UART3_TXD_MUX | PAD_CTL_UART_OUT,
156         MX53_PAD_PATA_CS_1__UART3_RXD_MUX | PAD_CTL_UART_IN,
157 };
158
159 static void uart_gpio_init(void)
160 {
161         mx53_iomux_setup_pads(tx53_uart_pads, CYG_NELEM(tx53_uart_pads));
162 }
163
164 /* GPIOs to set up for TX53/Starterkit-5:
165    Function  FCT  GPIO        Pad    IOMUXC SW_PAD  SW_INP mode
166                                      OFFSET  CTRL    SEL
167 FEC_REF_CLK   0   1,23 FEC_REF_CLK   0x24c   0x5c8
168 FEC_MDC       0   1,31 FEC_MDC       0x26c   0x5e8
169 FEC_MDIO      0   1,22 FEC_MDIO      0x248   0x5c4  0x804  1
170 FEC_RXD0      0   1,27 FEC_RXD0      0x25c   0x5d8
171 FEC_RXD1      0   1,26 FEC_RXD1      0x258   0x5d4
172 FEC_RX_ER     0   1,24 FEC_RX_ER     0x250   0x5cc
173 FEC_TX_EN     0   1,28 FEC_TX_EN     0x260   0x5dc
174 FEC_TXD0      0   1,30 FEC_TXD0      0x268   0x5e4
175 FEC_TXD1      0   1,29 FEC_TXD1      0x264   0x5e0
176 FEC_CRS_DV    0   1,25 FEC_CRS_DV    0x254   0x5d0
177
178 FEC_RESET#    1   7,6  PATA_DA_0     0x290   0x610
179 FEC_ENABLE    1   3,20 EIM_D20       0x128   0x470
180 */
181 static iomux_v3_cfg_t tx53_fec_pads[] = {
182         /* setup FEC PHY pins for GPIO function (with SION set) */
183         MX53_PAD_FEC_REF_CLK__GPIO_1_23 | IOMUX_CONFIG_SION,
184         MX53_PAD_FEC_MDC__GPIO_1_31 | IOMUX_CONFIG_SION,
185         MX53_PAD_FEC_MDIO__GPIO_1_22 | IOMUX_CONFIG_SION,
186         MX53_PAD_FEC_RXD0__GPIO_1_27 | IOMUX_CONFIG_SION,
187         MX53_PAD_FEC_RXD1__GPIO_1_26 | IOMUX_CONFIG_SION,
188         MX53_PAD_FEC_RX_ER__GPIO_1_24 | IOMUX_CONFIG_SION,
189         MX53_PAD_FEC_TX_EN__GPIO_1_28 | IOMUX_CONFIG_SION,
190         MX53_PAD_FEC_TXD0__GPIO_1_30 | IOMUX_CONFIG_SION,
191         MX53_PAD_FEC_TXD1__GPIO_1_29 | IOMUX_CONFIG_SION,
192         MX53_PAD_FEC_CRS_DV__GPIO_1_25 | IOMUX_CONFIG_SION,
193
194         /* PHY reset */
195         MX53_PAD_PATA_DA_0__GPIO_7_6 | IOMUX_CONFIG_SION,
196         /* PHY power */
197         MX53_PAD_EIM_D20__GPIO_3_20 | IOMUX_CONFIG_SION,
198 };
199
200 static iomux_v3_cfg_t tx53_i2c_pads[] = {
201         MX53_PAD_EIM_D21__I2C1_SCL | MUX_PAD_CTRL(PAD_CTL_DSE_HIGH |
202                                                                                         PAD_CTL_HYS |
203                                                                                         PAD_CTL_ODE) |
204                                                                 IOMUX_CONFIG_SION,
205         MX53_PAD_EIM_D28__I2C1_SDA | MUX_PAD_CTRL(PAD_CTL_DSE_HIGH |
206                                                                                         PAD_CTL_HYS |
207                                                                                         PAD_CTL_ODE) |
208                                                                 IOMUX_CONFIG_SION,
209 };
210
211 static void fec_gpio_init(void)
212 {
213         /* setup GPIO data register to 0 and DDIR output for FEC PHY pins */
214         setup_gpio(1, 23);
215         setup_gpio(1, 31);
216         setup_gpio(1, 22);
217         setup_gpio(1, 25);
218         setup_gpio(1, 27);
219         setup_gpio(1, 26);
220         setup_gpio(1, 24);
221         setup_gpio(1, 28);
222         setup_gpio(1, 30);
223         setup_gpio(1, 29);
224
225         setup_gpio(7, 6);
226         setup_gpio(3, 20);
227
228         /* setup input mux for FEC pins */
229         mx53_iomux_setup_pads(tx53_fec_pads, CYG_NELEM(tx53_fec_pads));
230         mx53_iomux_setup_pads(tx53_i2c_pads, CYG_NELEM(tx53_i2c_pads));
231 }
232
233 #ifdef CYGHWR_MX53_LCD_LOGO
234 static iomux_v3_cfg_t tx53_lcd_pads[] = {
235 #define PAD_CTL_LCD             MUX_PAD_CTRL(PAD_CTL_DSE_HIGH | PAD_CTL_DSE_HIGH)
236         MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0 | PAD_CTL_LCD,
237         MX53_PAD_DISP0_DAT1, | PAD_CTL_LCD,
238         MX53_PAD_DISP0_DAT2, | PAD_CTL_LCD,
239         MX53_PAD_DISP0_DAT3, | PAD_CTL_LCD,
240         MX53_PAD_DISP0_DAT4, | PAD_CTL_LCD,
241         MX53_PAD_DISP0_DAT5, | PAD_CTL_LCD,
242         MX53_PAD_DISP0_DAT6, | PAD_CTL_LCD,
243         MX53_PAD_DISP0_DAT7, | PAD_CTL_LCD,
244         MX53_PAD_DISP0_DAT8, | PAD_CTL_LCD,
245         MX53_PAD_DISP0_DAT9, | PAD_CTL_LCD,
246         MX53_PAD_DISP0_DAT10, | PAD_CTL_LCD,
247         MX53_PAD_DISP0_DAT12, | PAD_CTL_LCD,
248         MX53_PAD_DISP0_DAT13, | PAD_CTL_LCD,
249         MX53_PAD_DISP0_DAT14, | PAD_CTL_LCD,
250         MX53_PAD_DISP0_DAT15, | PAD_CTL_LCD,
251         MX53_PAD_DISP0_DAT16, | PAD_CTL_LCD,
252         MX53_PAD_DISP0_DAT17, | PAD_CTL_LCD,
253
254         /* HSYNC, VSYNC */
255         MX53_PAD_DI0_PIN2__IPU_DI0_PIN2 | PAD_CTL_LCD,
256         MX53_PAD_DI0_PIN3__IPU_DI0_PIN3 | PAD_CTL_LCD,
257         /* OE_ACD */
258         MX53_PAD_DI0_PIN15__IPU_DI0_PIN15 | MUX_PAD_CRTL(PAD_CTL_LCD | PAD_CTL_PKE),
259         MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK | MUX_PAD_CTRL(PAD_CTL_LCD),
260
261         /* LCD Power Enable */
262         MX53_PAD_EIM_EB3__GPIO_2_31,
263         /* LCD Reset */
264         MX53_PAD_EIM_D29__GPIO_3_29,
265         /* LCD backlight */
266         MX53_PAD_GPIO_1__GPIO_1_1,
267 };
268
269 void mxc_ipu_iomux_config(void)
270 {
271         /* LCD Power Enable GPIO_2_31 (active High) */
272         gpio_clr_bit(2, 31);
273
274         /* LCD Reset GPIO_3_29 (active Low) */
275         gpio_clr_bit(3, 29);
276
277         /* LCD Backlight GPIO_1_1 (PWM 0: full brightness 1: off) */
278         gpio_set_bit(1, 1);
279
280         mx53_iomux_setup_pads(tx53_lcd_pads, CYG_NELEM(tx53_lcd_pads));
281 }
282 RedBoot_init(mxc_ipu_iomux_config, RedBoot_INIT_SECOND);
283 #endif
284
285 //
286 // Platform specific initialization
287 //
288
289 void plf_hardware_init(void)
290 {
291 #ifdef RAM_BANK1_SIZE
292         /* destroy mapping for high area in SDRAM */
293         X_ARM_MMU_SECTION(SD_HI, 0, 0, 0, 0, ARM_ACCESS_PERM_NONE_NONE);
294 #endif
295         uart_gpio_init();
296         fec_gpio_init();
297
298         /* NFC setup */
299         writel(readl(NFC_FLASH_CONFIG3_REG) |
300                         (1 << 15) | /* assert RBB_MODE  (see Errata: ENGcm09970) */
301                         (1 << 20) | /* assert NO_SDMA */
302                         (1 << 3), /* set bus width to 8bit */
303                         NFC_FLASH_CONFIG3_REG);
304 }
305
306 #define SOC_I2C1_BASE           UL(0x63fc8000)
307
308 /* Address offsets of the I2C registers */
309 #define MXC_IADR                                0x00    /* Address Register */
310 #define MXC_IFDR                                0x04    /* Freq div register */
311 #define MXC_I2CR                                0x08    /* Control regsiter */
312 #define MXC_I2SR                                0x0C    /* Status register */
313 #define MXC_I2DR                                0x10    /* Data I/O register */
314
315 /* Bit definitions of I2CR */
316 #define MXC_I2CR_IEN                    0x0080
317 #define MXC_I2CR_IIEN                   0x0040
318 #define MXC_I2CR_MSTA                   0x0020
319 #define MXC_I2CR_MTX                    0x0010
320 #define MXC_I2CR_TXAK                   0x0008
321 #define MXC_I2CR_RSTA                   0x0004
322
323 /* Bit definitions of I2SR */
324 #define MXC_I2SR_ICF                    0x0080
325 #define MXC_I2SR_IAAS                   0x0040
326 #define MXC_I2SR_IBB                    0x0020
327 #define MXC_I2SR_IAL                    0x0010
328 #define MXC_I2SR_SRW                    0x0004
329 #define MXC_I2SR_IIF                    0x0002
330 #define MXC_I2SR_RXAK                   0x0001
331
332 #define LP3972_SLAVE_ADDR       0x34
333
334 static inline cyg_uint8 i2c_addr(cyg_uint8 addr, int rw)
335 {
336         return (addr << 1) | !!rw;
337 }
338
339 static inline cyg_uint8 tx53_i2c_read(cyg_uint8 reg)
340 {
341         cyg_uint16 val;
342         HAL_READ_UINT16(SOC_I2C1_BASE + reg, val);
343         return val;
344 }
345
346 static inline void tx53_i2c_write(cyg_uint8 reg, cyg_uint8 val)
347 {
348         HAL_WRITE_UINT16(SOC_I2C1_BASE + reg, val);
349 }
350
351 static inline void tx53_i2c_set_reg(cyg_uint8 reg, cyg_uint8 set, cyg_uint8 clr)
352 {
353         cyg_uint8 val = tx53_i2c_read(reg);
354         val = (val & ~clr) | set;
355         tx53_i2c_write(reg, val);
356 }
357
358 static void tx53_i2c_disable(void)
359 {
360         /* disable I2C controller */
361         tx53_i2c_set_reg(MXC_I2CR, 0, MXC_I2CR_IEN);
362         /* disable I2C clock */
363         set_reg(CCM_BASE_ADDR + CLKCTL_CGPR, 0, (1 << 4));
364 }
365
366 static int tx53_i2c_init(void)
367 {
368         int ret;
369
370         /* enable I2C clock */
371         set_reg(CCM_BASE_ADDR + CLKCTL_CGPR, (1 << 4), 0);
372
373         /* setup I2C clock divider */
374         tx53_i2c_write(MXC_IFDR, 0x2c);
375         tx53_i2c_write(MXC_I2SR, 0);
376
377         /* enable I2C controller in master mode */
378         tx53_i2c_write(MXC_I2CR, MXC_I2CR_IEN);
379
380         ret = tx53_i2c_read(MXC_I2SR);
381         if (ret & MXC_I2SR_IBB) {
382                 diag_printf("I2C bus busy\n");
383                 tx53_i2c_disable();
384                 return -EIO;
385         }
386         return 0;
387 }
388
389 static int tx53_i2c_wait_busy(int set)
390 {
391         int ret;
392         const int max_loops = 100;
393         int retries = max_loops;
394
395         cyg_uint8 mask = set ? MXC_I2SR_IBB : 0;
396
397         while ((ret = mask ^ (tx53_i2c_read(MXC_I2SR) & MXC_I2SR_IBB)) && --retries > 0) {
398                 HAL_DELAY_US(3);
399         }
400         if (ret != 0) {
401                 diag_printf("i2c: Waiting for IBB to %s timed out\n", set ? "set" : "clear");
402                 return -ETIMEDOUT;
403         }
404         return ret;
405 }
406
407 static int tx53_i2c_wait_tc(void)
408 {
409         int ret;
410         const int max_loops = 1000;
411         int retries = max_loops;
412
413         while (!((ret = tx53_i2c_read(MXC_I2SR)) & MXC_I2SR_IIF) && --retries > 0) {
414                 HAL_DELAY_US(3);
415         }
416         tx53_i2c_write(MXC_I2SR, 0);
417         if (!(ret & MXC_I2SR_IIF)) {
418                 diag_printf("i2c: Wait for transfer completion timed out\n");
419                 return -ETIMEDOUT;
420         }
421         if (ret & MXC_I2SR_ICF) {
422                 if (tx53_i2c_read(MXC_I2CR) & MXC_I2CR_MTX) {
423                         if (!(ret & MXC_I2SR_RXAK)) {
424                                 ret = 0;
425                         } else {
426                                 diag_printf("i2c: No ACK received after writing data\n");
427                                 return -ENXIO;
428                         }
429                 }
430         }
431         return ret;
432 }
433
434 static int tx53_i2c_stop(void)
435 {
436         int ret;
437
438         tx53_i2c_set_reg(MXC_I2CR, 0, MXC_I2CR_MSTA | MXC_I2CR_MTX);
439         ret = tx53_i2c_wait_busy(0);
440         return ret;
441 }
442
443 static int tx53_i2c_start(cyg_uint8 addr, int rw)
444 {
445         int ret;
446
447         ret = tx53_i2c_init();
448         if (ret < 0) {
449                 diag_printf("I2C bus init failed; cannot switch fuse programming voltage\n");
450                 return ret;
451         }
452         tx53_i2c_set_reg(MXC_I2CR, MXC_I2CR_MSTA, 0);
453         ret = tx53_i2c_wait_busy(1);
454         if (ret == 0) {
455                 tx53_i2c_set_reg(MXC_I2CR, MXC_I2CR_MTX, 0);
456                 tx53_i2c_write(MXC_I2DR, i2c_addr(addr, rw));
457                 ret = tx53_i2c_wait_tc();
458                 if (ret < 0) {
459                         tx53_i2c_stop();
460                 }
461         }
462         return ret;
463 }
464
465 static int tx53_i2c_repeat_start(cyg_uint8 addr, int rw)
466 {
467         int ret;
468
469         tx53_i2c_set_reg(MXC_I2CR, MXC_I2CR_RSTA, 0);
470         HAL_DELAY_US(3);
471         tx53_i2c_write(MXC_I2DR, i2c_addr(addr, rw));
472         ret = tx53_i2c_wait_tc();
473         if (ret < 0) {
474                 tx53_i2c_stop();
475         }
476         return ret;
477 }
478
479 static int tx53_i2c_read_byte(void)
480 {
481         int ret;
482
483         tx53_i2c_set_reg(MXC_I2CR, MXC_I2CR_TXAK, MXC_I2CR_MTX);
484         (void)tx53_i2c_read(MXC_I2DR); /* dummy read after address cycle */
485         ret = tx53_i2c_wait_tc();
486         tx53_i2c_stop();
487         if (ret < 0) {
488                 return ret;
489         }
490         ret = tx53_i2c_read(MXC_I2DR);
491         return ret;
492 }
493
494 static int tx53_i2c_write_byte(cyg_uint8 data, int last)
495 {
496         int ret;
497
498         tx53_i2c_set_reg(MXC_I2CR, MXC_I2CR_MTX, 0);
499         tx53_i2c_write(MXC_I2DR, data);
500         if ((ret = tx53_i2c_wait_tc()) < 0 || last) {
501                 tx53_i2c_stop();
502         }
503         return ret;
504 }
505
506 static int tx53_i2c_reg_read(cyg_uint8 slave_addr, cyg_uint8 reg)
507 {
508         int ret;
509
510         ret = tx53_i2c_start(slave_addr, 0);
511         if (ret < 0) {
512                 return ret;
513         }
514         ret = tx53_i2c_write_byte(reg, 0);
515         if (ret < 0) {
516                 return ret;
517         }
518         ret = tx53_i2c_repeat_start(slave_addr, 1);
519         if (ret < 0) {
520                 return ret;
521         }
522         ret = tx53_i2c_read_byte();
523         tx53_i2c_disable();
524         return ret;
525 }
526
527 static int tx53_i2c_reg_write(cyg_uint8 slave_addr, cyg_uint8 reg, cyg_uint8 val)
528 {
529         int ret;
530
531         ret = tx53_i2c_start(slave_addr, 0);
532         if (ret < 0) {
533                 return ret;
534         }
535         ret = tx53_i2c_write_byte(reg, 0);
536         if (ret < 0) {
537                 return ret;
538         }
539         ret = tx53_i2c_write_byte(val, 1);
540         tx53_i2c_disable();
541         return ret;
542 }
543
544 int tx53_mac_addr_program(unsigned char mac_addr[ETHER_ADDR_LEN])
545 {
546         int ret = 0;
547         int i;
548
549         for (i = 0; i < ETHER_ADDR_LEN; i++) {
550                 unsigned char fuse = readl(SOC_FEC_MAC_BASE + (i << 2));
551
552                 if ((fuse | mac_addr[i]) != mac_addr[i]) {
553                         diag_printf("MAC address fuse cannot be programmed: fuse[%d]=0x%02x -> 0x%02x\n",
554                                                 i, fuse, mac_addr[i]);
555                         return -1;
556                 }
557                 if (fuse != mac_addr[i]) {
558                         ret = 1;
559                 }
560         }
561         if (ret == 0) {
562                 return ret;
563         }
564
565         for (i = 0; i < ETHER_ADDR_LEN; i++) {
566                 unsigned char fuse = readl(SOC_FEC_MAC_BASE + (i << 2));
567                 int row = SOC_MAC_ADDR_FUSE + i;
568
569                 if (fuse == mac_addr[i]) {
570                         continue;
571                 }
572                 fuse_blow_row(SOC_MAC_ADDR_FUSE_BANK, row, mac_addr[i]);
573                 ret = sense_fuse(SOC_MAC_ADDR_FUSE_BANK, row, 0);
574                 if (ret != mac_addr[i]) {
575                         diag_printf("Failed to verify fuse bank %d row %d; expected %02x got %02x\n",
576                                                 SOC_MAC_ADDR_FUSE_BANK, row, mac_addr[i], ret);
577                         goto out;
578                 }
579         }
580 #ifdef SOC_MAC_ADDR_LOCK_BIT
581         fuse_blow_row(SOC_MAC_ADDR_FUSE_BANK, SOC_MAC_ADDR_LOCK_FUSE,
582                                 (1 << SOC_MAC_ADDR_LOCK_BIT));
583 #endif
584 out:
585         return ret;
586 }
587
588 #include CYGHWR_MEMORY_LAYOUT_H
589
590 typedef void code_fun(void);
591
592 void tx53_program_new_stack(void *func)
593 {
594         register CYG_ADDRESS stack_ptr asm("sp");
595         register CYG_ADDRESS old_stack asm("r4");
596         register code_fun *new_func asm("r0");
597
598         old_stack = stack_ptr;
599         stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
600         new_func = (code_fun*)func;
601         new_func();
602         stack_ptr = old_stack;
603 }
604
605 #if CYGNUM_HAL_ARM_TX53_SDRAM_TYPE == 2
606 #define PMIC_NAME                       "LP3972"
607 #elif CYGNUM_HAL_ARM_TX53_SDRAM_TYPE == 3
608 #define PMIC_NAME                       "LT3598"
609 #else
610 #error Bad CYGNUM_HAL_ARM_TX53_SDRAM_TYPE
611 #endif
612
613 static int pmic_reg_read(cyg_uint8 reg)
614 {
615         int ret;
616
617         ret = tx53_i2c_reg_read(LP3972_SLAVE_ADDR, reg);
618         if (ret < 0)
619                 diag_printf("Failed to read %s reg 0x%02x %d\n", PMIC_NAME,
620                                         reg, ret);
621         return ret;
622 }
623
624 static int pmic_reg_write(cyg_uint8 reg, cyg_uint8 val)
625 {
626         int ret;
627
628         ret = tx53_i2c_reg_write(LP3972_SLAVE_ADDR, reg, val);
629         if (ret)
630                 diag_printf("Failed to write 0x%02x to %s reg 0x%02x: %d\n",
631                                         val, PMIC_NAME, reg, ret);
632         return ret;
633 }
634
635 #if CYGNUM_HAL_ARM_TX53_SDRAM_TYPE == 2
636 int tx53_fuse_voltage(int on)
637 {
638         int ret;
639
640         ret = pmic_reg_read(0x81);
641         if (ret < 0)
642                 return ret;
643
644         /* Try to enable FUSE_VDD by asserting LP3972 GPIO1 */
645         ret = (ret & ~0x3) | (on ? 1 : 3);
646         ret = pmic_reg_write(0x81, ret);
647         if (ret) {
648                 return ret;
649         }
650         ret = pmic_reg_read(0x81);
651         if ((ret & 0x3) != (on ? 0x1 : 0x3)) {
652                 return -EIO;
653         }
654         return 0;
655 }
656
657 #define CORE_VOLTAGE_HIGH               0x1b
658 #define CORE_VOLTAGE_LOW                0x03
659 #if CYGNUM_HAL_ARM_TX53_SDRAM_SIZE == SZ_512M
660 #define SDRAM_SIZE_STR                  '0'
661 #else
662 #if CYGNUM_HAL_ARM_TX53_CPU_CLK == 1000
663 #define SDRAM_SIZE_STR                  '2'
664 #else
665 #define SDRAM_SIZE_STR                  '1'
666 #endif /* CYGNUM_HAL_ARM_TX53_CPU_CLK == 1000 */
667 #endif /* CYGNUM_HAL_ARM_TX53_SDRAM_SIZE == SZ512M */
668
669 #elif CYGNUM_HAL_ARM_TX53_SDRAM_TYPE == 3
670 int tx53_fuse_voltage(int on)
671 {
672         int ret;
673
674         if (on) {
675                 ret = pmic_reg_read(0x33);
676                 if (ret < 0)
677                         return ret;
678                 if ((ret & 0xe0) != 0xe0) {
679                         ret = pmic_reg_write(0x33, ret | 0xe0);
680                         if (ret)
681                                 return ret;
682
683                         ret = pmic_reg_read(0x33);
684                         if (ret < 0)
685                                 return ret;
686
687                         if ((ret & 0xe0) != 0xe0) {
688                                 diag_printf("Could not adjust LT3589 LDO4 output voltage\n");
689                                 return -EIO;
690                         }
691                 }
692
693                 ret = pmic_reg_read(0x12);
694                 if (ret < 0)
695                         return ret;
696
697                 if (!(ret & (1 << 6))) {
698                         ret |= 1 << 6; /* LDO4 Startup: don't wait for output < 300mV */
699                         ret = pmic_reg_write(0x12, ret);
700                         if (ret)
701                                 return -EIO;
702                         ret = pmic_reg_read(0x12);
703                         if (!(ret & (1 << 6))) {
704                                 diag_printf("Could not set LT3589 LDO4 Startup control\n");
705                                 return -EIO;
706                         }
707                 }
708         }
709         /* enable SW regulator control and all regulators (except LDO4, if !on) */
710         ret = pmic_reg_write(0x10, 0xbf | (!!on << 6));
711         if (ret)
712                 return ret;
713
714         ret = pmic_reg_read(0x10);
715         if (ret < 0)
716                 return ret;
717
718         if (!(ret & (1 << 6)) ^ !on) {
719                 diag_printf("Could not enable LT3589 LDO4 output\n");
720                 return -EIO;
721         }
722         return 0;
723 }
724
725 #define CORE_VOLTAGE_HIGH               0x1c
726 #define CORE_VOLTAGE_LOW                0x17
727 #if CYGNUM_HAL_ARM_TX53_SDRAM_SIZE == SZ_512M
728 #define SDRAM_SIZE_STR                  '0'
729 #else
730 #define SDRAM_SIZE_STR                  '1'
731 #endif
732 #endif
733
734 void increase_core_voltage(bool high)
735 {
736         int ret;
737         const int volt = high ? CORE_VOLTAGE_HIGH : CORE_VOLTAGE_LOW;
738
739         ret = pmic_reg_read(0x23);
740         if (ret < 0) {
741                 diag_printf("Failed to read core voltage: %d\n", ret);
742                 return;
743         }
744
745         ret = pmic_reg_write(0x23, volt);
746         if (ret < 0) {
747                 diag_printf("Failed to write core voltage: %d\n", ret);
748         }
749 }
750
751 static void display_board_type(void)
752 {
753         char cpu_freq;
754         const char *ddr_type = _stringify(CYGNUM_HAL_ARM_TX53_SDRAM_TYPE);
755
756         switch (CYGNUM_HAL_ARM_TX53_CPU_CLK) {
757         case 800:
758                 cpu_freq = '8';
759                 break;
760
761         case 1000:
762                 cpu_freq = '1';
763                 break;
764
765         default:
766                 cpu_freq = '?';
767         }
768
769         diag_printf("\nBoard Type: Ka-Ro TX53-%c%c%s%c\n",
770                                 cpu_freq, CYGNUM_HAL_ARM_TX53_SDRAM_TYPE == 2 ? '0' : 'x',
771                                 ddr_type, SDRAM_SIZE_STR);
772 }
773
774 static void display_board_info(void)
775 {
776         display_board_type();
777 }
778 RedBoot_init(display_board_info, RedBoot_INIT_LAST);
779
780 void mxc_i2c_init(unsigned int module_base)
781 {
782         switch (module_base) {
783         case I2C1_BASE_ADDR:
784                 writel(0x15, IOMUXC_BASE_ADDR + 0x12c);
785                 writel(0x10c, IOMUXC_BASE_ADDR + 0x474);
786                 writel(0x1, IOMUXC_BASE_ADDR + 0x814);
787
788                 writel(0x15, IOMUXC_BASE_ADDR + 0x14c);
789                 writel(0x10c, IOMUXC_BASE_ADDR + 0x494);
790                 writel(0x1, IOMUXC_BASE_ADDR + 0x818);
791                 break;
792
793         case I2C3_BASE_ADDR:
794                 writel(0x11, IOMUXC_BASE_ADDR + 0x120);
795                 writel(0x1fc, IOMUXC_BASE_ADDR + 0x468);
796
797                 writel(0x11, IOMUXC_BASE_ADDR + 0x118);
798                 writel(0x1fc, IOMUXC_BASE_ADDR + 0x460);
799                 break;
800
801         default:
802                 diag_printf("Invalid I2C base: 0x%x\n", module_base);
803         }
804 }