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, 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().
119 X_ARM_MMU_SECTION(SD_HI, SD_HI, 0x001, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RO_RO); /* SDRAM bank1 identity mapping */
121 X_ARM_MMU_SECTION(0xF40, 0xF40, 0x040, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* CS1 EIM control & NFC buffer */
124 static inline void set_reg(CYG_ADDRESS addr, CYG_WORD32 set, CYG_WORD32 clr)
128 HAL_READ_UINT32(addr, val);
129 val = (val & ~clr) | set;
130 HAL_WRITE_UINT32(addr, val);
133 static inline void setup_gpio(int grp, int bit)
135 CYG_ADDRESS base = MX53_GPIO_ADDR(grp);
139 set_reg(base + GPIO_DR, 0, 1 << bit);
140 set_reg(base + GPIO_GDIR, 1 << bit, 0);
144 // Platform specific initialization
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 | \
149 #define PAD_CTL_UART_IN (MUX_PAD_CTRL(PAD_CTL_HYS) | PAD_CTL_UART_OUT)
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,
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,
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,
162 static void uart_gpio_init(void)
164 mx53_iomux_setup_pads(tx53_uart_pads, CYG_NELEM(tx53_uart_pads));
167 /* GPIOs to set up for TX53/Starterkit-5:
168 Function FCT GPIO Pad IOMUXC SW_PAD SW_INP mode
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
181 FEC_RESET# 1 7,6 PATA_DA_0 0x290 0x610
182 FEC_ENABLE 1 3,20 EIM_D20 0x128 0x470
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,
198 MX53_PAD_PATA_DA_0__GPIO_7_6 | IOMUX_CONFIG_SION,
200 MX53_PAD_EIM_D20__GPIO_3_20 | IOMUX_CONFIG_SION,
203 static iomux_v3_cfg_t tx53_i2c_pads[] = {
204 MX53_PAD_EIM_D21__I2C1_SCL | MUX_PAD_CTRL(PAD_CTL_DSE_HIGH |
208 MX53_PAD_EIM_D28__I2C1_SDA | MUX_PAD_CTRL(PAD_CTL_DSE_HIGH |
214 static void fec_gpio_init(void)
216 /* setup GPIO data register to 0 and DDIR output for FEC PHY pins */
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));
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,
258 MX53_PAD_DI0_PIN2__IPU_DI0_PIN2 | PAD_CTL_LCD,
259 MX53_PAD_DI0_PIN3__IPU_DI0_PIN3 | PAD_CTL_LCD,
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),
264 /* LCD Power Enable */
265 MX53_PAD_EIM_EB3__GPIO_2_31,
267 MX53_PAD_EIM_D29__GPIO_3_29,
269 MX53_PAD_GPIO_1__GPIO_1_1,
272 void mxc_ipu_iomux_config(void)
274 /* LCD Power Enable GPIO_2_31 (active High) */
277 /* LCD Reset GPIO_3_29 (active Low) */
280 /* LCD Backlight GPIO_1_1 (PWM 0: full brightness 1: off) */
283 mx53_iomux_setup_pads(tx53_lcd_pads, CYG_NELEM(tx53_lcd_pads));
285 RedBoot_init(mxc_ipu_iomux_config, RedBoot_INIT_SECOND);
289 // Platform specific initialization
292 void plf_hardware_init(void)
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();
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);
310 #define SOC_I2C1_BASE UL(0x63fc8000)
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 */
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
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
336 #define LP3972_SLAVE_ADDR 0x34
338 static inline cyg_uint8 i2c_addr(cyg_uint8 addr, int rw)
340 return (addr << 1) | !!rw;
343 static inline cyg_uint8 tx53_i2c_read(cyg_uint8 reg)
346 HAL_READ_UINT16(SOC_I2C1_BASE + reg, val);
350 static inline void tx53_i2c_write(cyg_uint8 reg, cyg_uint8 val)
352 HAL_WRITE_UINT16(SOC_I2C1_BASE + reg, val);
355 static inline void tx53_i2c_set_reg(cyg_uint8 reg, cyg_uint8 set, cyg_uint8 clr)
357 cyg_uint8 val = tx53_i2c_read(reg);
358 val = (val & ~clr) | set;
359 tx53_i2c_write(reg, val);
362 static void tx53_i2c_disable(void)
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));
370 static int tx53_i2c_init(void)
374 /* enable I2C clock */
375 set_reg(CCM_BASE_ADDR + CLKCTL_CGPR, (1 << 4), 0);
377 /* setup I2C clock divider */
378 tx53_i2c_write(MXC_IFDR, 0x2c);
379 tx53_i2c_write(MXC_I2SR, 0);
381 /* enable I2C controller in master mode */
382 tx53_i2c_write(MXC_I2CR, MXC_I2CR_IEN);
384 ret = tx53_i2c_read(MXC_I2SR);
385 if (ret & MXC_I2SR_IBB) {
386 diag_printf("I2C bus busy\n");
393 static int tx53_i2c_wait_busy(int set)
396 const int max_loops = 100;
397 int retries = max_loops;
399 cyg_uint8 mask = set ? MXC_I2SR_IBB : 0;
401 while ((ret = mask ^ (tx53_i2c_read(MXC_I2SR) & MXC_I2SR_IBB)) && --retries > 0) {
405 diag_printf("i2c: Waiting for IBB to %s timed out\n", set ? "set" : "clear");
411 static int tx53_i2c_wait_tc(void)
414 const int max_loops = 1000;
415 int retries = max_loops;
417 while (!((ret = tx53_i2c_read(MXC_I2SR)) & MXC_I2SR_IIF) && --retries > 0) {
420 tx53_i2c_write(MXC_I2SR, 0);
421 if (!(ret & MXC_I2SR_IIF)) {
422 diag_printf("i2c: Wait for transfer completion timed out\n");
425 if (ret & MXC_I2SR_ICF) {
426 if (tx53_i2c_read(MXC_I2CR) & MXC_I2CR_MTX) {
427 if (!(ret & MXC_I2SR_RXAK)) {
430 diag_printf("i2c: No ACK received after writing data\n");
438 static int tx53_i2c_stop(void)
442 tx53_i2c_set_reg(MXC_I2CR, 0, MXC_I2CR_MSTA | MXC_I2CR_MTX);
443 ret = tx53_i2c_wait_busy(0);
447 static int tx53_i2c_start(cyg_uint8 addr, int rw)
451 ret = tx53_i2c_init();
453 diag_printf("I2C bus init failed; cannot switch fuse programming voltage\n");
456 tx53_i2c_set_reg(MXC_I2CR, MXC_I2CR_MSTA, 0);
457 ret = tx53_i2c_wait_busy(1);
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();
469 static int tx53_i2c_repeat_start(cyg_uint8 addr, int rw)
473 tx53_i2c_set_reg(MXC_I2CR, MXC_I2CR_RSTA, 0);
475 tx53_i2c_write(MXC_I2DR, i2c_addr(addr, rw));
476 ret = tx53_i2c_wait_tc();
483 static int tx53_i2c_read_byte(void)
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();
494 ret = tx53_i2c_read(MXC_I2DR);
498 static int tx53_i2c_write_byte(cyg_uint8 data, int last)
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) {
510 static int tx53_i2c_reg_read(cyg_uint8 slave_addr, cyg_uint8 reg)
514 ret = tx53_i2c_start(slave_addr, 0);
518 ret = tx53_i2c_write_byte(reg, 0);
522 ret = tx53_i2c_repeat_start(slave_addr, 1);
526 ret = tx53_i2c_read_byte();
531 static int tx53_i2c_reg_write(cyg_uint8 slave_addr, cyg_uint8 reg, cyg_uint8 val)
535 ret = tx53_i2c_start(slave_addr, 0);
539 ret = tx53_i2c_write_byte(reg, 0);
543 ret = tx53_i2c_write_byte(val, 1);
548 int tx53_mac_addr_program(unsigned char mac_addr[ETHER_ADDR_LEN])
553 for (i = 0; i < ETHER_ADDR_LEN; i++) {
554 unsigned char fuse = readl(SOC_FEC_MAC_BASE + (i << 2));
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]);
561 if (fuse != mac_addr[i]) {
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;
573 if (fuse == mac_addr[i]) {
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);
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));
592 #include CYGHWR_MEMORY_LAYOUT_H
594 typedef void code_fun(void);
596 void tx53_program_new_stack(void *func)
598 register CYG_ADDRESS stack_ptr asm("sp");
599 register CYG_ADDRESS old_stack asm("r4");
600 register code_fun *new_func asm("r0");
602 old_stack = stack_ptr;
603 stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
604 new_func = (code_fun*)func;
606 stack_ptr = old_stack;
609 #define PMIC_NAME "LT3598"
611 static int pmic_reg_read(cyg_uint8 reg)
615 ret = tx53_i2c_reg_read(LP3972_SLAVE_ADDR, reg);
617 diag_printf("Failed to read %s reg 0x%02x %d\n", PMIC_NAME,
621 diag_printf("read %02x from reg %02x\n", ret, reg);
626 static int pmic_reg_write(cyg_uint8 reg, cyg_uint8 val)
630 ret = tx53_i2c_reg_write(LP3972_SLAVE_ADDR, reg, val);
632 diag_printf("Failed to write 0x%02x to %s reg 0x%02x: %d\n",
633 val, PMIC_NAME, reg, ret);
636 diag_printf("wrote %02x to reg %02x\n", val, reg);
641 int tx53_fuse_voltage(int on)
647 ret = pmic_reg_read(0x33);
650 if ((ret & 0xe0) != 0xe0) {
651 ret = pmic_reg_write(0x33, ret | 0xe0);
655 ret = pmic_reg_read(0x33);
659 if ((ret & 0xe0) != 0xe0) {
660 diag_printf("Could not adjust LT3589 LDO4 output voltage\n");
665 ret = pmic_reg_read(0x12);
669 if (!(ret & (1 << 6))) {
670 ret = pmic_reg_write(0x12, ret | (1 << 6));
675 /* enable SW regulator control and all regulators */
676 ret = pmic_reg_write(0x10, 0xff);
681 ret = pmic_reg_read(0x13);
689 diag_printf("Waiting for LDO4 PGOOD\n");
692 if (++retries >= 1000) {
693 diag_printf("Failed to enable LDO4\n");
698 ret = pmic_reg_write(0x10, 0xbf);
702 ret = pmic_reg_read(0x12);
705 if (ret & (1 << 6)) {
706 ret = pmic_reg_write(0x12, ret & ~(1 << 6));
712 ret = pmic_reg_read(0x10);
716 if (!(ret & (1 << 6)) ^ !on) {
717 diag_printf("Could not %sable LT3589 LDO4 output\n",
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
730 int adjust_core_voltage(unsigned int clock)
737 volt = CORE_VOLTAGE_800;
738 } else if (clock <= 1000) {
739 volt = CORE_VOLTAGE_1000;
740 } else if (clock <= 1200) {
741 volt = CORE_VOLTAGE_1200;
743 diag_printf("No core voltage assigned for %u MHz core clock\n",
748 ret = pmic_reg_read(0x23);
753 ret = pmic_reg_write(0x23, volt | LT3589_SLEW_RATE(3) | LT3589_PGOOD_MASK);
758 ret = pmic_reg_read(0x20);
762 /* Select V1 reference and enable slew */
763 ret = pmic_reg_write(0x20, (ret & ~(1 << 1)) | (1 << 0));
768 ret = pmic_reg_read(0x20);
771 if (++retries >= 1000)
774 } while (ret & (1 << 0));
778 static void display_board_type(void)
780 diag_printf("\nBoard Type: Ka-Ro TX53 v3\n");
781 adjust_core_voltage(CYGNUM_HAL_ARM_TX53_CPU_CLK);
784 static void display_board_info(void)
786 display_board_type();
788 RedBoot_init(display_board_info, RedBoot_INIT_LAST);
790 void mxc_i2c_init(unsigned int module_base)
792 switch (module_base) {
794 writel(0x15, IOMUXC_BASE_ADDR + 0x12c);
795 writel(0x10c, IOMUXC_BASE_ADDR + 0x474);
796 writel(0x1, IOMUXC_BASE_ADDR + 0x814);
798 writel(0x15, IOMUXC_BASE_ADDR + 0x14c);
799 writel(0x10c, IOMUXC_BASE_ADDR + 0x494);
800 writel(0x1, IOMUXC_BASE_ADDR + 0x818);
804 writel(0x11, IOMUXC_BASE_ADDR + 0x120);
805 writel(0x1fc, IOMUXC_BASE_ADDR + 0x468);
807 writel(0x11, IOMUXC_BASE_ADDR + 0x118);
808 writel(0x1fc, IOMUXC_BASE_ADDR + 0x460);
812 diag_printf("Invalid I2C base: 0x%x\n", module_base);