]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/mx53/karo/v1_0/src/tx53_misc.c
d3d03b7ba4869cd69b315eaf83612e1843c4f52c
[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 #define PMIC_NAME                       "LT3598"
606
607 static int pmic_reg_read(cyg_uint8 reg)
608 {
609         int ret;
610
611         ret = tx53_i2c_reg_read(LP3972_SLAVE_ADDR, reg);
612         if (ret < 0)
613                 diag_printf("Failed to read %s reg 0x%02x %d\n", PMIC_NAME,
614                                         reg, ret);
615 #ifdef DEBUG
616         else
617                 diag_printf("read %02x from reg %02x\n", ret, reg);
618 #endif
619         return ret;
620 }
621
622 static int pmic_reg_write(cyg_uint8 reg, cyg_uint8 val)
623 {
624         int ret;
625
626         ret = tx53_i2c_reg_write(LP3972_SLAVE_ADDR, reg, val);
627         if (ret)
628                 diag_printf("Failed to write 0x%02x to %s reg 0x%02x: %d\n",
629                                         val, PMIC_NAME, reg, ret);
630 #ifdef DEBUG
631         else
632                 diag_printf("wrote %02x to reg %02x\n", val, reg);
633 #endif
634         return ret;
635 }
636
637 int tx53_fuse_voltage(int on)
638 {
639         int ret;
640         int retries = 0;
641
642         if (on) {
643                 ret = pmic_reg_read(0x33);
644                 if (ret < 0)
645                         return ret;
646                 if ((ret & 0xe0) != 0xe0) {
647                         ret = pmic_reg_write(0x33, ret | 0xe0);
648                         if (ret)
649                                 return ret;
650
651                         ret = pmic_reg_read(0x33);
652                         if (ret < 0)
653                                 return ret;
654
655                         if ((ret & 0xe0) != 0xe0) {
656                                 diag_printf("Could not adjust LT3589 LDO4 output voltage\n");
657                                 return -EIO;
658                         }
659                 }
660
661                 ret = pmic_reg_read(0x12);
662                 if (ret < 0)
663                         return ret;
664
665                 if (!(ret & (1 << 6))) {
666                         ret = pmic_reg_write(0x12, ret | (1 << 6));
667                         if (ret)
668                                 return ret;
669                 }
670
671                 /* enable SW regulator control and all regulators */
672                 ret = pmic_reg_write(0x10, 0xff);
673                 if (ret)
674                         return ret;
675
676                 for (;;) {
677                         ret = pmic_reg_read(0x13);
678                         if (ret < 0)
679                                 return ret;
680                         if (ret & (1 << 7))
681                                 break;
682
683 #ifdef DEBUG
684                         if (retries == 0)
685                                 diag_printf("Waiting for LDO4 PGOOD\n");
686 #endif
687                         HAL_DELAY_US(100);
688                         if (++retries >= 1000) {
689                                 diag_printf("Failed to enable LDO4\n");
690                                 return -ETIMEDOUT;
691                         }
692                 }
693         } else {
694                 ret = pmic_reg_write(0x10, 0xbf);
695                 if (ret)
696                         return ret;
697
698                 ret = pmic_reg_read(0x12);
699                 if (ret < 0)
700                         return ret;
701                 if (ret & (1 << 6)) {
702                         ret = pmic_reg_write(0x12, ret & ~(1 << 6));
703                         if (ret)
704                                 return ret;
705                 }
706         }
707
708         ret = pmic_reg_read(0x10);
709         if (ret < 0)
710                 return ret;
711
712         if (!(ret & (1 << 6)) ^ !on) {
713                 diag_printf("Could not %sable LT3589 LDO4 output\n",
714                                         on ? "en" : "dis");
715                 return -EIO;
716         }
717         return 0;
718 }
719
720 #define LT3589_PGOOD_MASK               (1 << 5)
721 #define LT3589_SLEW_RATE(n)             (((n) & 3) << 6)
722 #define CORE_VOLTAGE_1200               0x1e
723 #define CORE_VOLTAGE_1000               0x19
724 #define CORE_VOLTAGE_800                0x13
725
726 int adjust_core_voltage(unsigned int clock)
727 {
728         int ret;
729         int volt;
730         int retries = 0;
731
732         switch (clock) {
733         case 1200:
734                 volt = CORE_VOLTAGE_1200;
735                 break;
736
737         case 1000:
738                 volt = CORE_VOLTAGE_1000;
739                 break;
740
741         case 800:
742                 volt = CORE_VOLTAGE_800;
743                 break;
744
745         default:
746                 if (clock > 1200) {
747                         diag_printf("No core voltage assigned for %u MHz core clock\n",
748                                                 clock);
749                         return -EINVAL;
750                 }
751                 volt = CORE_VOLTAGE_800;
752         }
753
754         ret = pmic_reg_read(0x23);
755         if (ret < 0) {
756                 return ret;
757         }
758
759         ret = pmic_reg_write(0x23, volt | LT3589_SLEW_RATE(3) | LT3589_PGOOD_MASK);
760         if (ret < 0) {
761                 return ret;
762         }
763
764         ret = pmic_reg_read(0x20);
765         if (ret < 0)
766                 return ret;
767
768         /* Select V1 reference and enable slew */
769         ret = pmic_reg_write(0x20, (ret & ~(1 << 1)) | (1 << 0));
770         if (ret)
771                 return ret;
772
773         do {
774                 ret = pmic_reg_read(0x20);
775                 if (ret < 0)
776                         return ret;
777                 if (++retries >= 1000)
778                         return -ETIMEDOUT;
779                 HAL_DELAY_US(100);
780         } while (ret & (1 << 0));
781         return ret;
782 }
783
784 static void display_board_type(void)
785 {
786         diag_printf("\nBoard Type: Ka-Ro TX53 v3\n");
787 }
788
789 static void display_board_info(void)
790 {
791         display_board_type();
792 }
793 RedBoot_init(display_board_info, RedBoot_INIT_LAST);
794
795 void mxc_i2c_init(unsigned int module_base)
796 {
797         switch (module_base) {
798         case I2C1_BASE_ADDR:
799                 writel(0x15, IOMUXC_BASE_ADDR + 0x12c);
800                 writel(0x10c, IOMUXC_BASE_ADDR + 0x474);
801                 writel(0x1, IOMUXC_BASE_ADDR + 0x814);
802
803                 writel(0x15, IOMUXC_BASE_ADDR + 0x14c);
804                 writel(0x10c, IOMUXC_BASE_ADDR + 0x494);
805                 writel(0x1, IOMUXC_BASE_ADDR + 0x818);
806                 break;
807
808         case I2C3_BASE_ADDR:
809                 writel(0x11, IOMUXC_BASE_ADDR + 0x120);
810                 writel(0x1fc, IOMUXC_BASE_ADDR + 0x468);
811
812                 writel(0x11, IOMUXC_BASE_ADDR + 0x118);
813                 writel(0x1fc, IOMUXC_BASE_ADDR + 0x460);
814                 break;
815
816         default:
817                 diag_printf("Invalid I2C base: 0x%x\n", module_base);
818         }
819 }