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