1 /* 2 * Board functions for TI AM335X based rut board 3 * (C) Copyright 2013 Siemens Schweiz AG 4 * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de. 5 * 6 * Based on: 7 * u-boot:/board/ti/am335x/board.c 8 * 9 * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ 10 * 11 * SPDX-License-Identifier: GPL-2.0+ 12 */ 13 14 #include <common.h> 15 #include <errno.h> 16 #include <spi.h> 17 #include <spl.h> 18 #include <asm/arch/cpu.h> 19 #include <asm/arch/hardware.h> 20 #include <asm/arch/omap.h> 21 #include <asm/arch/ddr_defs.h> 22 #include <asm/arch/clock.h> 23 #include <asm/arch/gpio.h> 24 #include <asm/arch/mmc_host_def.h> 25 #include <asm/arch/sys_proto.h> 26 #include <asm/io.h> 27 #include <asm/emif.h> 28 #include <asm/gpio.h> 29 #include <i2c.h> 30 #include <miiphy.h> 31 #include <cpsw.h> 32 #include <video.h> 33 #include <watchdog.h> 34 #include "board.h" 35 #include "../common/factoryset.h" 36 #include "../../../drivers/video/da8xx-fb.h" 37 38 /* 39 * Read header information from EEPROM into global structure. 40 */ 41 static int read_eeprom(void) 42 { 43 return 0; 44 } 45 46 #ifdef CONFIG_SPL_BUILD 47 static void board_init_ddr(void) 48 { 49 struct emif_regs rut_ddr3_emif_reg_data = { 50 .sdram_config = 0x61C04AB2, 51 .sdram_tim1 = 0x0888A39B, 52 .sdram_tim2 = 0x26337FDA, 53 .sdram_tim3 = 0x501F830F, 54 .emif_ddr_phy_ctlr_1 = 0x6, 55 .zq_config = 0x50074BE4, 56 .ref_ctrl = 0x93B, 57 }; 58 59 struct ddr_data rut_ddr3_data = { 60 .datardsratio0 = 0x3b, 61 .datawdsratio0 = 0x85, 62 .datafwsratio0 = 0x100, 63 .datawrsratio0 = 0xc1, 64 }; 65 66 struct cmd_control rut_ddr3_cmd_ctrl_data = { 67 .cmd0csratio = 0x40, 68 .cmd0iclkout = 1, 69 .cmd1csratio = 0x40, 70 .cmd1iclkout = 1, 71 .cmd2csratio = 0x40, 72 .cmd2iclkout = 1, 73 }; 74 75 const struct ctrl_ioregs ioregs = { 76 .cm0ioctl = RUT_IOCTRL_VAL, 77 .cm1ioctl = RUT_IOCTRL_VAL, 78 .cm2ioctl = RUT_IOCTRL_VAL, 79 .dt0ioctl = RUT_IOCTRL_VAL, 80 .dt1ioctl = RUT_IOCTRL_VAL, 81 }; 82 83 config_ddr(DDR_PLL_FREQ, &ioregs, &rut_ddr3_data, 84 &rut_ddr3_cmd_ctrl_data, &rut_ddr3_emif_reg_data, 0); 85 } 86 87 static int request_and_pulse_reset(int gpio, const char *name) 88 { 89 int ret; 90 const int delay_us = 2000; /* 2ms */ 91 92 ret = gpio_request(gpio, name); 93 if (ret < 0) { 94 printf("%s: Unable to request %s\n", __func__, name); 95 goto err; 96 } 97 98 ret = gpio_direction_output(gpio, 0); 99 if (ret < 0) { 100 printf("%s: Unable to set %s as output\n", __func__, name); 101 goto err_free_gpio; 102 } 103 104 udelay(delay_us); 105 106 gpio_set_value(gpio, 1); 107 108 return 0; 109 110 err_free_gpio: 111 gpio_free(gpio); 112 err: 113 return ret; 114 } 115 116 #define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio)) 117 #define ETH_PHY_RESET_GPIO GPIO_TO_PIN(2, 18) 118 #define MAXTOUCH_RESET_GPIO GPIO_TO_PIN(3, 18) 119 #define DISPLAY_RESET_GPIO GPIO_TO_PIN(3, 19) 120 121 #define REQUEST_AND_PULSE_RESET(N) \ 122 request_and_pulse_reset(N, #N); 123 124 static void spl_siemens_board_init(void) 125 { 126 REQUEST_AND_PULSE_RESET(ETH_PHY_RESET_GPIO); 127 REQUEST_AND_PULSE_RESET(MAXTOUCH_RESET_GPIO); 128 REQUEST_AND_PULSE_RESET(DISPLAY_RESET_GPIO); 129 } 130 #endif /* if def CONFIG_SPL_BUILD */ 131 132 #if defined(CONFIG_DRIVER_TI_CPSW) 133 static void cpsw_control(int enabled) 134 { 135 /* VTP can be added here */ 136 137 return; 138 } 139 140 static struct cpsw_slave_data cpsw_slaves[] = { 141 { 142 .slave_reg_ofs = 0x208, 143 .sliver_reg_ofs = 0xd80, 144 .phy_addr = 1, 145 .phy_if = PHY_INTERFACE_MODE_RMII, 146 }, 147 { 148 .slave_reg_ofs = 0x308, 149 .sliver_reg_ofs = 0xdc0, 150 .phy_addr = 0, 151 .phy_if = PHY_INTERFACE_MODE_RMII, 152 }, 153 }; 154 155 static struct cpsw_platform_data cpsw_data = { 156 .mdio_base = CPSW_MDIO_BASE, 157 .cpsw_base = CPSW_BASE, 158 .mdio_div = 0xff, 159 .channels = 8, 160 .cpdma_reg_ofs = 0x800, 161 .slaves = 1, 162 .slave_data = cpsw_slaves, 163 .ale_reg_ofs = 0xd00, 164 .ale_entries = 1024, 165 .host_port_reg_ofs = 0x108, 166 .hw_stats_reg_ofs = 0x900, 167 .bd_ram_ofs = 0x2000, 168 .mac_control = (1 << 5), 169 .control = cpsw_control, 170 .host_port_num = 0, 171 .version = CPSW_CTRL_VERSION_2, 172 }; 173 174 #if defined(CONFIG_DRIVER_TI_CPSW) || \ 175 (defined(CONFIG_USB_ETHER) && defined(CONFIG_USB_MUSB_GADGET)) 176 int board_eth_init(bd_t *bis) 177 { 178 struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; 179 int n = 0; 180 int rv; 181 182 #ifndef CONFIG_SPL_BUILD 183 factoryset_env_set(); 184 #endif 185 186 /* Set rgmii mode and enable rmii clock to be sourced from chip */ 187 writel((RMII_MODE_ENABLE | RMII_CHIPCKL_ENABLE), &cdev->miisel); 188 189 rv = cpsw_register(&cpsw_data); 190 if (rv < 0) 191 printf("Error %d registering CPSW switch\n", rv); 192 else 193 n += rv; 194 return n; 195 } 196 #endif /* #if defined(CONFIG_DRIVER_TI_CPSW) */ 197 #endif /* #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) */ 198 199 #if defined(CONFIG_HW_WATCHDOG) 200 static bool hw_watchdog_init_done; 201 static int hw_watchdog_trigger_level; 202 203 void hw_watchdog_reset(void) 204 { 205 if (!hw_watchdog_init_done) 206 return; 207 208 hw_watchdog_trigger_level = hw_watchdog_trigger_level ? 0 : 1; 209 gpio_set_value(WATCHDOG_TRIGGER_GPIO, hw_watchdog_trigger_level); 210 } 211 212 void hw_watchdog_init(void) 213 { 214 gpio_request(WATCHDOG_TRIGGER_GPIO, "watchdog_trigger"); 215 gpio_direction_output(WATCHDOG_TRIGGER_GPIO, hw_watchdog_trigger_level); 216 217 hw_watchdog_reset(); 218 219 hw_watchdog_init_done = 1; 220 } 221 #endif /* defined(CONFIG_HW_WATCHDOG) */ 222 223 #if defined(CONFIG_VIDEO) && !defined(CONFIG_SPL_BUILD) 224 static struct da8xx_panel lcd_panels[] = { 225 /* FORMIKE, 4.3", 480x800, KWH043MC17-F01 */ 226 [0] = { 227 .name = "KWH043MC17-F01", 228 .width = 480, 229 .height = 800, 230 .hfp = 50, /* no spec, "don't care" values */ 231 .hbp = 50, 232 .hsw = 50, 233 .vfp = 50, 234 .vbp = 50, 235 .vsw = 50, 236 .pxl_clk = 35910000, /* tCYCD=20ns, max 50MHz, 60fps */ 237 .invert_pxl_clk = 1, 238 }, 239 /* FORMIKE, 4.3", 480x800, KWH043ST20-F01 */ 240 [1] = { 241 .name = "KWH043ST20-F01", 242 .width = 480, 243 .height = 800, 244 .hfp = 50, /* no spec, "don't care" values */ 245 .hbp = 50, 246 .hsw = 50, 247 .vfp = 50, 248 .vbp = 50, 249 .vsw = 50, 250 .pxl_clk = 35910000, /* tCYCD=20ns, max 50MHz, 60fps */ 251 .invert_pxl_clk = 1, 252 }, 253 /* Multi-Inno, 4.3", 480x800, MI0430VT-1 */ 254 [2] = { 255 .name = "MI0430VT-1", 256 .width = 480, 257 .height = 800, 258 .hfp = 50, /* no spec, "don't care" values */ 259 .hbp = 50, 260 .hsw = 50, 261 .vfp = 50, 262 .vbp = 50, 263 .vsw = 50, 264 .pxl_clk = 35910000, /* tCYCD=20ns, max 50MHz, 60fps */ 265 .invert_pxl_clk = 1, 266 }, 267 }; 268 269 static const struct display_panel disp_panels[] = { 270 [0] = { 271 WVGA, 272 16, /* RGB 888 */ 273 16, 274 COLOR_ACTIVE, 275 }, 276 [1] = { 277 WVGA, 278 16, /* RGB 888 */ 279 16, 280 COLOR_ACTIVE, 281 }, 282 [2] = { 283 WVGA, 284 24, /* RGB 888 */ 285 16, 286 COLOR_ACTIVE, 287 }, 288 }; 289 290 static const struct lcd_ctrl_config lcd_cfgs[] = { 291 [0] = { 292 &disp_panels[0], 293 .ac_bias = 255, 294 .ac_bias_intrpt = 0, 295 .dma_burst_sz = 16, 296 .bpp = 16, 297 .fdd = 0x80, 298 .tft_alt_mode = 0, 299 .stn_565_mode = 0, 300 .mono_8bit_mode = 0, 301 .invert_line_clock = 1, 302 .invert_frm_clock = 1, 303 .sync_edge = 0, 304 .sync_ctrl = 1, 305 .raster_order = 0, 306 }, 307 [1] = { 308 &disp_panels[1], 309 .ac_bias = 255, 310 .ac_bias_intrpt = 0, 311 .dma_burst_sz = 16, 312 .bpp = 16, 313 .fdd = 0x80, 314 .tft_alt_mode = 0, 315 .stn_565_mode = 0, 316 .mono_8bit_mode = 0, 317 .invert_line_clock = 1, 318 .invert_frm_clock = 1, 319 .sync_edge = 0, 320 .sync_ctrl = 1, 321 .raster_order = 0, 322 }, 323 [2] = { 324 &disp_panels[2], 325 .ac_bias = 255, 326 .ac_bias_intrpt = 0, 327 .dma_burst_sz = 16, 328 .bpp = 24, 329 .fdd = 0x80, 330 .tft_alt_mode = 0, 331 .stn_565_mode = 0, 332 .mono_8bit_mode = 0, 333 .invert_line_clock = 1, 334 .invert_frm_clock = 1, 335 .sync_edge = 0, 336 .sync_ctrl = 1, 337 .raster_order = 0, 338 }, 339 340 }; 341 342 /* no console on this board */ 343 int board_cfb_skip(void) 344 { 345 return 1; 346 } 347 348 #define PLL_GET_M(v) ((v >> 8) & 0x7ff) 349 #define PLL_GET_N(v) (v & 0x7f) 350 351 static struct dpll_regs dpll_lcd_regs = { 352 .cm_clkmode_dpll = CM_WKUP + 0x98, 353 .cm_idlest_dpll = CM_WKUP + 0x48, 354 .cm_clksel_dpll = CM_WKUP + 0x54, 355 }; 356 357 static int get_clk(struct dpll_regs *dpll_regs) 358 { 359 unsigned int val; 360 unsigned int m, n; 361 int f = 0; 362 363 val = readl(dpll_regs->cm_clksel_dpll); 364 m = PLL_GET_M(val); 365 n = PLL_GET_N(val); 366 f = (m * V_OSCK) / n; 367 368 return f; 369 }; 370 371 int clk_get(int clk) 372 { 373 return get_clk(&dpll_lcd_regs); 374 }; 375 376 static int conf_disp_pll(int m, int n) 377 { 378 struct cm_perpll *cmper = (struct cm_perpll *)CM_PER; 379 struct dpll_params dpll_lcd = {m, n, -1, -1, -1, -1, -1}; 380 #if defined(DISPL_PLL_SPREAD_SPECTRUM) 381 struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP; 382 #endif 383 384 u32 *const clk_domains[] = { 385 &cmper->lcdclkctrl, 386 0 387 }; 388 u32 *const clk_modules_explicit_en[] = { 389 &cmper->lcdclkctrl, 390 &cmper->lcdcclkstctrl, 391 &cmper->spi1clkctrl, 392 0 393 }; 394 do_enable_clocks(clk_domains, clk_modules_explicit_en, 1); 395 396 do_setup_dpll(&dpll_lcd_regs, &dpll_lcd); 397 398 #if defined(DISPL_PLL_SPREAD_SPECTRUM) 399 writel(0x64, &cmwkup->resv6[3]); /* 0x50 */ 400 writel(0x800, &cmwkup->resv6[2]); /* 0x4c */ 401 writel(readl(&cmwkup->clkmoddplldisp) | CM_CLKMODE_DPLL_SSC_EN_MASK, 402 &cmwkup->clkmoddplldisp); /* 0x98 */ 403 #endif 404 return 0; 405 } 406 407 static int set_gpio(int gpio, int state) 408 { 409 gpio_request(gpio, "temp"); 410 gpio_direction_output(gpio, state); 411 gpio_set_value(gpio, state); 412 gpio_free(gpio); 413 return 0; 414 } 415 416 static int enable_lcd(void) 417 { 418 unsigned char buf[1]; 419 420 set_gpio(BOARD_LCD_RESET, 0); 421 mdelay(1); 422 set_gpio(BOARD_LCD_RESET, 1); 423 mdelay(1); 424 425 /* spi lcd init */ 426 kwh043st20_f01_spi_startup(1, 0, 5000000, SPI_MODE_0); 427 428 /* backlight on */ 429 buf[0] = 0xf; 430 i2c_write(0x24, 0x7, 1, buf, 1); 431 buf[0] = 0x3f; 432 i2c_write(0x24, 0x8, 1, buf, 1); 433 return 0; 434 } 435 436 int arch_early_init_r(void) 437 { 438 enable_lcd(); 439 return 0; 440 } 441 442 static int board_video_init(void) 443 { 444 int i; 445 int anzdisp = ARRAY_SIZE(lcd_panels); 446 int display = 1; 447 448 for (i = 0; i < anzdisp; i++) { 449 if (strncmp((const char *)factory_dat.disp_name, 450 lcd_panels[i].name, 451 strlen((const char *)factory_dat.disp_name)) == 0) { 452 printf("DISPLAY: %s\n", factory_dat.disp_name); 453 break; 454 } 455 } 456 if (i == anzdisp) { 457 i = 1; 458 printf("%s: %s not found, using default %s\n", __func__, 459 factory_dat.disp_name, lcd_panels[i].name); 460 } 461 conf_disp_pll(24, 1); 462 da8xx_video_init(&lcd_panels[display], &lcd_cfgs[display], 463 lcd_cfgs[display].bpp); 464 465 return 0; 466 } 467 #endif /* ifdef CONFIG_VIDEO */ 468 469 #ifdef CONFIG_BOARD_LATE_INIT 470 int board_late_init(void) 471 { 472 int ret; 473 char tmp[2 * MAX_STRING_LENGTH + 2]; 474 475 omap_nand_switch_ecc(1, 8); 476 477 if (factory_dat.asn[0] != 0) 478 sprintf(tmp, "%s_%s", factory_dat.asn, 479 factory_dat.comp_version); 480 else 481 strcpy(tmp, "QMX7.E38_4.0"); 482 483 ret = env_set("boardid", tmp); 484 if (ret) 485 printf("error setting board id\n"); 486 487 return 0; 488 } 489 #endif 490 491 #include "../common/board.c" 492