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