1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * board.c 4 * 5 * Board functions for B&R BRXRE1 Board 6 * 7 * Copyright (C) 2013 Hannes Schmelzer <oe5hpm@oevsv.at> 8 * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com 9 * 10 */ 11 #include <common.h> 12 #include <errno.h> 13 #include <spl.h> 14 #include <asm/arch/cpu.h> 15 #include <asm/arch/hardware.h> 16 #include <asm/arch/omap.h> 17 #include <asm/arch/ddr_defs.h> 18 #include <asm/arch/clock.h> 19 #include <asm/arch/gpio.h> 20 #include <asm/arch/sys_proto.h> 21 #include <asm/arch/mem.h> 22 #include <asm/io.h> 23 #include <asm/emif.h> 24 #include <asm/gpio.h> 25 #include <dm.h> 26 #include <i2c.h> 27 #include <power/tps65217.h> 28 #include "../common/bur_common.h" 29 #include <lcd.h> 30 31 /* -------------------------------------------------------------------------*/ 32 /* -- defines for used GPIO Hardware -- */ 33 #define ESC_KEY (0+19) 34 #define LCD_PWR (0+5) 35 #define PUSH_KEY (0+31) 36 /* -------------------------------------------------------------------------*/ 37 /* -- PSOC Resetcontroller Register defines -- */ 38 39 /* I2C Address of controller */ 40 #define RSTCTRL_ADDR 0x75 41 /* Register for CTRL-word */ 42 #define RSTCTRL_CTRLREG 0x01 43 /* Register for giving some information to VxWorks OS */ 44 #define RSTCTRL_SCRATCHREG 0x04 45 46 /* -- defines for RSTCTRL_CTRLREG -- */ 47 #define RSTCTRL_FORCE_PWR_NEN 0x0404 48 #define RSTCTRL_CAN_STB 0x4040 49 50 DECLARE_GLOBAL_DATA_PTR; 51 52 static int rstctrl_rw(u8 reg, unsigned char rnw, void *pdat, int size) 53 { 54 struct udevice *i2cdev; 55 int rc; 56 57 rc = i2c_get_chip_for_busnum(0, RSTCTRL_ADDR, 1, &i2cdev); 58 if (rc >= 0) { 59 if (rnw) 60 rc = dm_i2c_read(i2cdev, reg, pdat, size); 61 else 62 rc = dm_i2c_write(i2cdev, reg, pdat, size); 63 } else { 64 printf("%s: cannot get udevice for chip 0x%02x!\n", 65 __func__, RSTCTRL_ADDR); 66 } 67 68 return rc; 69 } 70 71 #if defined(CONFIG_SPL_BUILD) 72 /* TODO: check ram-timing ! */ 73 static const struct ddr_data ddr3_data = { 74 .datardsratio0 = MT41K256M16HA125E_RD_DQS, 75 .datawdsratio0 = MT41K256M16HA125E_WR_DQS, 76 .datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE, 77 .datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA, 78 }; 79 static const struct cmd_control ddr3_cmd_ctrl_data = { 80 .cmd0csratio = MT41K256M16HA125E_RATIO, 81 .cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT, 82 83 .cmd1csratio = MT41K256M16HA125E_RATIO, 84 .cmd1iclkout = MT41K256M16HA125E_INVERT_CLKOUT, 85 86 .cmd2csratio = MT41K256M16HA125E_RATIO, 87 .cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT, 88 }; 89 static struct emif_regs ddr3_emif_reg_data = { 90 .sdram_config = MT41K256M16HA125E_EMIF_SDCFG, 91 .ref_ctrl = MT41K256M16HA125E_EMIF_SDREF, 92 .sdram_tim1 = MT41K256M16HA125E_EMIF_TIM1, 93 .sdram_tim2 = MT41K256M16HA125E_EMIF_TIM2, 94 .sdram_tim3 = MT41K256M16HA125E_EMIF_TIM3, 95 .zq_config = MT41K256M16HA125E_ZQ_CFG, 96 .emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY, 97 }; 98 99 static const struct ctrl_ioregs ddr3_ioregs = { 100 .cm0ioctl = MT41K256M16HA125E_IOCTRL_VALUE, 101 .cm1ioctl = MT41K256M16HA125E_IOCTRL_VALUE, 102 .cm2ioctl = MT41K256M16HA125E_IOCTRL_VALUE, 103 .dt0ioctl = MT41K256M16HA125E_IOCTRL_VALUE, 104 .dt1ioctl = MT41K256M16HA125E_IOCTRL_VALUE, 105 }; 106 107 #define OSC (V_OSCK/1000000) 108 const struct dpll_params dpll_ddr3 = { 400, OSC-1, 1, -1, -1, -1, -1}; 109 110 void am33xx_spl_board_init(void) 111 { 112 unsigned short buf; 113 int rc; 114 115 struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER; 116 struct cm_wkuppll *const cmwkup = (struct cm_wkuppll *)CM_WKUP; 117 /* 118 * enable additional clocks of modules which are accessed later from 119 * VxWorks OS 120 */ 121 u32 *const clk_domains[] = { 0 }; 122 123 u32 *const clk_modules_xre1specific[] = { 124 &cmwkup->wkup_adctscctrl, 125 &cmper->spi1clkctrl, 126 &cmper->dcan0clkctrl, 127 &cmper->dcan1clkctrl, 128 &cmper->epwmss0clkctrl, 129 &cmper->epwmss1clkctrl, 130 &cmper->epwmss2clkctrl, 131 &cmper->lcdclkctrl, 132 &cmper->lcdcclkstctrl, 133 0 134 }; 135 do_enable_clocks(clk_domains, clk_modules_xre1specific, 1); 136 /* power-OFF LCD-Display */ 137 if (gpio_request(LCD_PWR, "LCD_PWR") != 0) 138 printf("cannot request gpio for LCD_PWR!\n"); 139 else if (gpio_direction_output(LCD_PWR, 0) != 0) 140 printf("cannot set direction output on LCD_PWR!\n"); 141 142 /* setup I2C */ 143 enable_i2c_pin_mux(); 144 145 /* power-ON 3V3 via Resetcontroller */ 146 buf = RSTCTRL_FORCE_PWR_NEN | RSTCTRL_CAN_STB; 147 rc = rstctrl_rw(RSTCTRL_CTRLREG, 0, (uint8_t *)&buf, sizeof(buf)); 148 if (rc != 0) 149 printf("ERROR: cannot write to resetc (turn on PWR_nEN)\n"); 150 151 pmicsetup(0, 0); 152 } 153 154 const struct dpll_params *get_dpll_ddr_params(void) 155 { 156 return &dpll_ddr3; 157 } 158 159 void sdram_init(void) 160 { 161 config_ddr(400, &ddr3_ioregs, 162 &ddr3_data, 163 &ddr3_cmd_ctrl_data, 164 &ddr3_emif_reg_data, 0); 165 } 166 #endif /* CONFIG_SPL_BUILD */ 167 /* 168 * Basic board specific setup. Pinmux has been handled already. 169 */ 170 int board_init(void) 171 { 172 if (power_tps65217_init(0)) 173 printf("WARN: cannot setup PMIC 0x24 @ bus #0, not found!.\n"); 174 175 return 0; 176 } 177 178 #ifdef CONFIG_BOARD_LATE_INIT 179 int board_late_init(void) 180 { 181 const unsigned int toff = 1000; 182 unsigned int cnt = 3; 183 unsigned short buf = 0xAAAA; 184 unsigned char scratchreg = 0; 185 int rc; 186 187 /* try to read out some boot-instruction from resetcontroller */ 188 rc = rstctrl_rw(RSTCTRL_SCRATCHREG, 1, &scratchreg, sizeof(scratchreg)); 189 if (rc != 0) 190 printf("ERROR: read scratchregister (resetc) failed!\n"); 191 192 if (gpio_request(ESC_KEY, "boot-key") != 0) { 193 printf("cannot request boot-key!\n"); 194 } else if (gpio_get_value(ESC_KEY)) { 195 do { 196 lcd_position_cursor(1, 8); 197 switch (cnt) { 198 case 3: 199 lcd_puts( 200 "release ESC-KEY to enter SERVICE-mode."); 201 break; 202 case 2: 203 lcd_puts( 204 "release ESC-KEY to enter DIAGNOSE-mode."); 205 break; 206 case 1: 207 lcd_puts( 208 "release ESC-KEY to enter BOOT-mode. "); 209 break; 210 } 211 mdelay(toff); 212 cnt--; 213 if (!gpio_get_value(ESC_KEY) && 214 gpio_get_value(PUSH_KEY) && 2 == cnt) { 215 lcd_position_cursor(1, 8); 216 lcd_puts( 217 "switching to network-console ... "); 218 env_set("bootcmd", "run netconsole"); 219 cnt = 4; 220 break; 221 } else if (!gpio_get_value(ESC_KEY) && 222 gpio_get_value(PUSH_KEY) && 1 == cnt) { 223 lcd_position_cursor(1, 8); 224 lcd_puts( 225 "starting u-boot script from USB ... "); 226 env_set("bootcmd", "run usbscript"); 227 cnt = 4; 228 break; 229 } else if ((!gpio_get_value(ESC_KEY) && 230 gpio_get_value(PUSH_KEY) && cnt == 0) || 231 (gpio_get_value(ESC_KEY) && 232 gpio_get_value(PUSH_KEY) && cnt == 0)) { 233 lcd_position_cursor(1, 8); 234 lcd_puts( 235 "starting script from network ... "); 236 env_set("bootcmd", "run netscript"); 237 cnt = 4; 238 break; 239 } else if (!gpio_get_value(ESC_KEY)) { 240 break; 241 } 242 } while (cnt); 243 } else if (scratchreg == 0xCC) { 244 lcd_position_cursor(1, 8); 245 lcd_puts( 246 "starting vxworks from network ... "); 247 env_set("bootcmd", "run netboot"); 248 cnt = 4; 249 } else if (scratchreg == 0xCD) { 250 lcd_position_cursor(1, 8); 251 lcd_puts( 252 "starting script from network ... "); 253 env_set("bootcmd", "run netscript"); 254 cnt = 4; 255 } else if (scratchreg == 0xCE) { 256 lcd_position_cursor(1, 8); 257 lcd_puts( 258 "starting AR from eMMC ... "); 259 env_set("bootcmd", "run mmcboot"); 260 cnt = 4; 261 } 262 263 lcd_position_cursor(1, 8); 264 switch (cnt) { 265 case 0: 266 lcd_puts("entering BOOT-mode. "); 267 env_set("bootcmd", "run defaultAR"); 268 buf = 0x0000; 269 break; 270 case 1: 271 lcd_puts("entering DIAGNOSE-mode. "); 272 buf = 0x0F0F; 273 break; 274 case 2: 275 lcd_puts("entering SERVICE mode. "); 276 buf = 0xB4B4; 277 break; 278 case 3: 279 lcd_puts("loading OS... "); 280 buf = 0x0404; 281 break; 282 } 283 /* write bootinfo into scratchregister of resetcontroller */ 284 rc = rstctrl_rw(RSTCTRL_SCRATCHREG, 0, (uint8_t *)&buf, sizeof(buf)); 285 if (rc != 0) 286 printf("ERROR: write scratchregister (resetc) failed!\n"); 287 288 /* setup othbootargs for bootvx-command (vxWorks bootline) */ 289 char othbootargs[128]; 290 snprintf(othbootargs, sizeof(othbootargs), 291 "u=vxWorksFTP pw=vxWorks o=0x%08x;0x%08x;0x%08x;0x%08x", 292 (unsigned int) gd->fb_base-0x20, 293 (u32)env_get_ulong("vx_memtop", 16, gd->fb_base-0x20), 294 (u32)env_get_ulong("vx_romfsbase", 16, 0), 295 (u32)env_get_ulong("vx_romfssize", 16, 0)); 296 env_set("othbootargs", othbootargs); 297 /* 298 * reset VBAR registers to its reset location, VxWorks 6.9.3.2 does 299 * expect that vectors are there, original u-boot moves them to _start 300 */ 301 __asm__("ldr r0,=0x20000"); 302 __asm__("mcr p15, 0, r0, c12, c0, 0"); /* Set VBAR */ 303 304 return 0; 305 } 306 #endif /* CONFIG_BOARD_LATE_INIT */ 307