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