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