1 //==========================================================================
5 // HAL misc board support code for the tx53
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //========================================================================*/
45 #include <pkgconf/hal.h>
46 #include <pkgconf/system.h>
47 #include CYGBLD_HAL_PLATFORM_H
49 #include <cyg/infra/cyg_type.h> // base types
50 #include <cyg/infra/cyg_trac.h> // tracing macros
51 #include <cyg/infra/cyg_ass.h> // assertion macros
53 #include <cyg/hal/hal_io.h> // IO macros
54 #include <cyg/hal/hal_arch.h> // Register state info
55 #include <cyg/hal/hal_diag.h>
56 #include <cyg/hal/hal_intr.h> // Interrupt names
57 #include <cyg/hal/hal_cache.h>
58 #include <cyg/hal/hal_soc.h> // Hardware definitions
59 #include CYGBLD_HAL_PLF_DEFS_H // Platform specifics
61 #include <cyg/infra/diag.h> // diag_printf
63 // All the MM table layout is here:
64 #include <cyg/hal/hal_mm.h>
66 /* 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)
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))
79 static unsigned long ttb_base = RAM_BANK0_BASE + 0x4000;
81 void hal_mmu_init(void)
85 * Set the TTB register
87 asm volatile ("mcr p15,0,%0,c2,c0,0" : : "r"(ttb_base));
90 * Set the Domain Access Control Register
92 i = ARM_ACCESS_DACR_DEFAULT;
93 asm volatile ("mcr p15,0,%0,c3,c0,0" : : "r"(i) /*:*/);
96 * First clear all TT entries - ie Set them to Faulting
98 memset((void *)ttb_base, 0, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE);
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 */
118 X_ARM_MMU_SECTION(0xF40, 0xF40, 0x040, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* CS1 EIM control & NFC buffer */
121 static inline void set_reg(CYG_ADDRESS addr, CYG_WORD32 set, CYG_WORD32 clr)
125 HAL_READ_UINT32(addr, val);
126 val = (val & ~clr) | set;
127 HAL_WRITE_UINT32(addr, val);
130 static inline void setup_gpio(int grp, int bit)
132 CYG_ADDRESS base = MX53_GPIO_ADDR(grp);
136 set_reg(base + GPIO_DR, 0, 1 << bit);
137 set_reg(base + GPIO_GDIR, 1 << bit, 0);
141 // Platform specific initialization
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 | \
146 #define PAD_CTL_UART_IN (MUX_PAD_CTRL(PAD_CTL_HYS) | PAD_CTL_UART_OUT)
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,
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,
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,
159 static void uart_gpio_init(void)
161 mx53_iomux_setup_pads(tx53_uart_pads, CYG_NELEM(tx53_uart_pads));
164 /* GPIOs to set up for TX53/Starterkit-5:
165 Function FCT GPIO Pad IOMUXC SW_PAD SW_INP mode
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
178 FEC_RESET# 1 7,6 PATA_DA_0 0x290 0x610
179 FEC_ENABLE 1 3,20 EIM_D20 0x128 0x470
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,
195 MX53_PAD_PATA_DA_0__GPIO_7_6 | IOMUX_CONFIG_SION,
197 MX53_PAD_EIM_D20__GPIO_3_20 | IOMUX_CONFIG_SION,
200 static iomux_v3_cfg_t tx53_i2c_pads[] = {
201 MX53_PAD_EIM_D21__I2C1_SCL | MUX_PAD_CTRL(PAD_CTL_DSE_HIGH |
205 MX53_PAD_EIM_D28__I2C1_SDA | MUX_PAD_CTRL(PAD_CTL_DSE_HIGH |
211 static void fec_gpio_init(void)
213 /* setup GPIO data register to 0 and DDIR output for FEC PHY pins */
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));
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,
255 MX53_PAD_DI0_PIN2__IPU_DI0_PIN2 | PAD_CTL_LCD,
256 MX53_PAD_DI0_PIN3__IPU_DI0_PIN3 | PAD_CTL_LCD,
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),
261 /* LCD Power Enable */
262 MX53_PAD_EIM_EB3__GPIO_2_31,
264 MX53_PAD_EIM_D29__GPIO_3_29,
266 MX53_PAD_GPIO_1__GPIO_1_1,
269 void mxc_ipu_iomux_config(void)
271 /* LCD Power Enable GPIO_2_31 (active High) */
274 /* LCD Reset GPIO_3_29 (active Low) */
277 /* LCD Backlight GPIO_1_1 (PWM 0: full brightness 1: off) */
280 mx53_iomux_setup_pads(tx53_lcd_pads, CYG_NELEM(tx53_lcd_pads));
282 RedBoot_init(mxc_ipu_iomux_config, RedBoot_INIT_SECOND);
286 // Platform specific initialization
289 void plf_hardware_init(void)
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);
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);
306 #define SOC_I2C1_BASE UL(0x63fc8000)
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 */
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
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
332 #define LP3972_SLAVE_ADDR 0x34
334 static inline cyg_uint8 i2c_addr(cyg_uint8 addr, int rw)
336 return (addr << 1) | !!rw;
339 static inline cyg_uint8 tx53_i2c_read(cyg_uint8 reg)
342 HAL_READ_UINT16(SOC_I2C1_BASE + reg, val);
346 static inline void tx53_i2c_write(cyg_uint8 reg, cyg_uint8 val)
348 HAL_WRITE_UINT16(SOC_I2C1_BASE + reg, val);
351 static inline void tx53_i2c_set_reg(cyg_uint8 reg, cyg_uint8 set, cyg_uint8 clr)
353 cyg_uint8 val = tx53_i2c_read(reg);
354 val = (val & ~clr) | set;
355 tx53_i2c_write(reg, val);
358 static void tx53_i2c_disable(void)
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));
366 static int tx53_i2c_init(void)
370 /* enable I2C clock */
371 set_reg(CCM_BASE_ADDR + CLKCTL_CGPR, (1 << 4), 0);
373 /* setup I2C clock divider */
374 tx53_i2c_write(MXC_IFDR, 0x2c);
375 tx53_i2c_write(MXC_I2SR, 0);
377 /* enable I2C controller in master mode */
378 tx53_i2c_write(MXC_I2CR, MXC_I2CR_IEN);
380 ret = tx53_i2c_read(MXC_I2SR);
381 if (ret & MXC_I2SR_IBB) {
382 diag_printf("I2C bus busy\n");
389 static int tx53_i2c_wait_busy(int set)
392 const int max_loops = 100;
393 int retries = max_loops;
395 cyg_uint8 mask = set ? MXC_I2SR_IBB : 0;
397 while ((ret = mask ^ (tx53_i2c_read(MXC_I2SR) & MXC_I2SR_IBB)) && --retries > 0) {
401 diag_printf("i2c: Waiting for IBB to %s timed out\n", set ? "set" : "clear");
407 static int tx53_i2c_wait_tc(void)
410 const int max_loops = 1000;
411 int retries = max_loops;
413 while (!((ret = tx53_i2c_read(MXC_I2SR)) & MXC_I2SR_IIF) && --retries > 0) {
416 tx53_i2c_write(MXC_I2SR, 0);
417 if (!(ret & MXC_I2SR_IIF)) {
418 diag_printf("i2c: Wait for transfer completion timed out\n");
421 if (ret & MXC_I2SR_ICF) {
422 if (tx53_i2c_read(MXC_I2CR) & MXC_I2CR_MTX) {
423 if (!(ret & MXC_I2SR_RXAK)) {
426 diag_printf("i2c: No ACK received after writing data\n");
434 static int tx53_i2c_stop(void)
438 tx53_i2c_set_reg(MXC_I2CR, 0, MXC_I2CR_MSTA | MXC_I2CR_MTX);
439 ret = tx53_i2c_wait_busy(0);
443 static int tx53_i2c_start(cyg_uint8 addr, int rw)
447 ret = tx53_i2c_init();
449 diag_printf("I2C bus init failed; cannot switch fuse programming voltage\n");
452 tx53_i2c_set_reg(MXC_I2CR, MXC_I2CR_MSTA, 0);
453 ret = tx53_i2c_wait_busy(1);
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();
465 static int tx53_i2c_repeat_start(cyg_uint8 addr, int rw)
469 tx53_i2c_set_reg(MXC_I2CR, MXC_I2CR_RSTA, 0);
471 tx53_i2c_write(MXC_I2DR, i2c_addr(addr, rw));
472 ret = tx53_i2c_wait_tc();
479 static int tx53_i2c_read_byte(void)
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();
490 ret = tx53_i2c_read(MXC_I2DR);
494 static int tx53_i2c_write_byte(cyg_uint8 data, int last)
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) {
506 static int tx53_i2c_reg_read(cyg_uint8 slave_addr, cyg_uint8 reg)
510 ret = tx53_i2c_start(slave_addr, 0);
514 ret = tx53_i2c_write_byte(reg, 0);
518 ret = tx53_i2c_repeat_start(slave_addr, 1);
522 ret = tx53_i2c_read_byte();
527 static int tx53_i2c_reg_write(cyg_uint8 slave_addr, cyg_uint8 reg, cyg_uint8 val)
531 ret = tx53_i2c_start(slave_addr, 0);
535 ret = tx53_i2c_write_byte(reg, 0);
539 ret = tx53_i2c_write_byte(val, 1);
544 int tx53_mac_addr_program(unsigned char mac_addr[ETHER_ADDR_LEN])
549 for (i = 0; i < ETHER_ADDR_LEN; i++) {
550 unsigned char fuse = readl(SOC_FEC_MAC_BASE + (i << 2));
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]);
557 if (fuse != mac_addr[i]) {
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;
569 if (fuse == mac_addr[i]) {
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);
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));
588 #include CYGHWR_MEMORY_LAYOUT_H
590 typedef void code_fun(void);
592 void tx53_program_new_stack(void *func)
594 register CYG_ADDRESS stack_ptr asm("sp");
595 register CYG_ADDRESS old_stack asm("r4");
596 register code_fun *new_func asm("r0");
598 old_stack = stack_ptr;
599 stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
600 new_func = (code_fun*)func;
602 stack_ptr = old_stack;
605 #define PMIC_NAME "LT3598"
607 static int pmic_reg_read(cyg_uint8 reg)
611 ret = tx53_i2c_reg_read(LP3972_SLAVE_ADDR, reg);
613 diag_printf("Failed to read %s reg 0x%02x %d\n", PMIC_NAME,
617 diag_printf("read %02x from reg %02x\n", ret, reg);
622 static int pmic_reg_write(cyg_uint8 reg, cyg_uint8 val)
626 ret = tx53_i2c_reg_write(LP3972_SLAVE_ADDR, reg, val);
628 diag_printf("Failed to write 0x%02x to %s reg 0x%02x: %d\n",
629 val, PMIC_NAME, reg, ret);
632 diag_printf("wrote %02x to reg %02x\n", val, reg);
637 int tx53_fuse_voltage(int on)
643 ret = pmic_reg_read(0x33);
646 if ((ret & 0xe0) != 0xe0) {
647 ret = pmic_reg_write(0x33, ret | 0xe0);
651 ret = pmic_reg_read(0x33);
655 if ((ret & 0xe0) != 0xe0) {
656 diag_printf("Could not adjust LT3589 LDO4 output voltage\n");
661 ret = pmic_reg_read(0x12);
665 if (!(ret & (1 << 6))) {
666 ret = pmic_reg_write(0x12, ret | (1 << 6));
671 /* enable SW regulator control and all regulators */
672 ret = pmic_reg_write(0x10, 0xff);
677 ret = pmic_reg_read(0x13);
685 diag_printf("Waiting for LDO4 PGOOD\n");
688 if (++retries >= 1000) {
689 diag_printf("Failed to enable LDO4\n");
694 ret = pmic_reg_write(0x10, 0xbf);
698 ret = pmic_reg_read(0x12);
701 if (ret & (1 << 6)) {
702 ret = pmic_reg_write(0x12, ret & ~(1 << 6));
708 ret = pmic_reg_read(0x10);
712 if (!(ret & (1 << 6)) ^ !on) {
713 diag_printf("Could not %sable LT3589 LDO4 output\n",
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
726 int adjust_core_voltage(unsigned int clock)
734 volt = CORE_VOLTAGE_1200;
738 volt = CORE_VOLTAGE_1000;
742 volt = CORE_VOLTAGE_800;
747 diag_printf("No core voltage assigned for %u MHz core clock\n",
751 volt = CORE_VOLTAGE_800;
754 ret = pmic_reg_read(0x23);
759 ret = pmic_reg_write(0x23, volt | LT3589_SLEW_RATE(3) | LT3589_PGOOD_MASK);
764 ret = pmic_reg_read(0x20);
768 /* Select V1 reference and enable slew */
769 ret = pmic_reg_write(0x20, (ret & ~(1 << 1)) | (1 << 0));
774 ret = pmic_reg_read(0x20);
777 if (++retries >= 1000)
780 } while (ret & (1 << 0));
784 static void display_board_type(void)
786 diag_printf("\nBoard Type: Ka-Ro TX53 v3\n");
789 static void display_board_info(void)
791 display_board_type();
793 RedBoot_init(display_board_info, RedBoot_INIT_LAST);
795 void mxc_i2c_init(unsigned int module_base)
797 switch (module_base) {
799 writel(0x15, IOMUXC_BASE_ADDR + 0x12c);
800 writel(0x10c, IOMUXC_BASE_ADDR + 0x474);
801 writel(0x1, IOMUXC_BASE_ADDR + 0x814);
803 writel(0x15, IOMUXC_BASE_ADDR + 0x14c);
804 writel(0x10c, IOMUXC_BASE_ADDR + 0x494);
805 writel(0x1, IOMUXC_BASE_ADDR + 0x818);
809 writel(0x11, IOMUXC_BASE_ADDR + 0x120);
810 writel(0x1fc, IOMUXC_BASE_ADDR + 0x468);
812 writel(0x11, IOMUXC_BASE_ADDR + 0x118);
813 writel(0x1fc, IOMUXC_BASE_ADDR + 0x460);
817 diag_printf("Invalid I2C base: 0x%x\n", module_base);