1c0dcece7SHeiko Schocher /* 2c0dcece7SHeiko Schocher * Board functions for TI AM335X based pxm2 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 * Board functions for TI AM335X based boards 10c0dcece7SHeiko Schocher * 11c0dcece7SHeiko Schocher * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ 12c0dcece7SHeiko Schocher * 13c0dcece7SHeiko Schocher * SPDX-License-Identifier: GPL-2.0+ 14c0dcece7SHeiko Schocher */ 15c0dcece7SHeiko Schocher 16c0dcece7SHeiko Schocher #include <common.h> 17c0dcece7SHeiko Schocher #include <errno.h> 18c0dcece7SHeiko Schocher #include <spl.h> 19c0dcece7SHeiko Schocher #include <asm/arch/cpu.h> 20c0dcece7SHeiko Schocher #include <asm/arch/hardware.h> 21c0dcece7SHeiko Schocher #include <asm/arch/omap.h> 22c0dcece7SHeiko Schocher #include <asm/arch/ddr_defs.h> 23c0dcece7SHeiko Schocher #include <asm/arch/clock.h> 24c0dcece7SHeiko Schocher #include <asm/arch/gpio.h> 25c0dcece7SHeiko Schocher #include <asm/arch/mmc_host_def.h> 26c0dcece7SHeiko Schocher #include <asm/arch/sys_proto.h> 27c0dcece7SHeiko Schocher #include "../../../drivers/video/da8xx-fb.h" 28c0dcece7SHeiko Schocher #include <asm/io.h> 29c0dcece7SHeiko Schocher #include <asm/emif.h> 30c0dcece7SHeiko Schocher #include <asm/gpio.h> 31c0dcece7SHeiko Schocher #include <i2c.h> 32c0dcece7SHeiko Schocher #include <miiphy.h> 33c0dcece7SHeiko Schocher #include <cpsw.h> 34c0dcece7SHeiko Schocher #include <watchdog.h> 35c0dcece7SHeiko Schocher #include "board.h" 36c0dcece7SHeiko Schocher #include "../common/factoryset.h" 37c0dcece7SHeiko Schocher #include "pmic.h" 38c0dcece7SHeiko Schocher #include <nand.h> 39c0dcece7SHeiko Schocher #include <bmp_layout.h> 40c0dcece7SHeiko Schocher 41c0dcece7SHeiko Schocher DECLARE_GLOBAL_DATA_PTR; 42c0dcece7SHeiko Schocher 43c0dcece7SHeiko Schocher #ifdef CONFIG_SPL_BUILD 44c0dcece7SHeiko Schocher static void board_init_ddr(void) 45c0dcece7SHeiko Schocher { 46c0dcece7SHeiko Schocher struct emif_regs pxm2_ddr3_emif_reg_data = { 47c0dcece7SHeiko Schocher .sdram_config = 0x41805332, 48c0dcece7SHeiko Schocher .sdram_tim1 = 0x666b3c9, 49c0dcece7SHeiko Schocher .sdram_tim2 = 0x243631ca, 50c0dcece7SHeiko Schocher .sdram_tim3 = 0x33f, 51c0dcece7SHeiko Schocher .emif_ddr_phy_ctlr_1 = 0x100005, 52c0dcece7SHeiko Schocher .zq_config = 0, 53c0dcece7SHeiko Schocher .ref_ctrl = 0x81a, 54c0dcece7SHeiko Schocher }; 55c0dcece7SHeiko Schocher 56c0dcece7SHeiko Schocher struct ddr_data pxm2_ddr3_data = { 57c0dcece7SHeiko Schocher .datardsratio0 = 0x81204812, 58c0dcece7SHeiko Schocher .datawdsratio0 = 0, 59c0dcece7SHeiko Schocher .datafwsratio0 = 0x8020080, 60c0dcece7SHeiko Schocher .datawrsratio0 = 0x4010040, 61c0dcece7SHeiko Schocher }; 62c0dcece7SHeiko Schocher 63c0dcece7SHeiko Schocher struct cmd_control pxm2_ddr3_cmd_ctrl_data = { 64c0dcece7SHeiko Schocher .cmd0csratio = 0x80, 65c0dcece7SHeiko Schocher .cmd0iclkout = 0, 66c0dcece7SHeiko Schocher .cmd1csratio = 0x80, 67c0dcece7SHeiko Schocher .cmd1iclkout = 0, 68c0dcece7SHeiko Schocher .cmd2csratio = 0x80, 69c0dcece7SHeiko Schocher .cmd2iclkout = 0, 70c0dcece7SHeiko Schocher }; 71c0dcece7SHeiko Schocher 72965de8b9SLokesh Vutla const struct ctrl_ioregs ioregs = { 739fc2ed40SEgli, Samuel .cm0ioctl = DDR_IOCTRL_VAL, 749fc2ed40SEgli, Samuel .cm1ioctl = DDR_IOCTRL_VAL, 759fc2ed40SEgli, Samuel .cm2ioctl = DDR_IOCTRL_VAL, 769fc2ed40SEgli, Samuel .dt0ioctl = DDR_IOCTRL_VAL, 779fc2ed40SEgli, Samuel .dt1ioctl = DDR_IOCTRL_VAL, 78965de8b9SLokesh Vutla }; 79965de8b9SLokesh Vutla 80965de8b9SLokesh Vutla config_ddr(DDR_PLL_FREQ, &ioregs, &pxm2_ddr3_data, 81c0dcece7SHeiko Schocher &pxm2_ddr3_cmd_ctrl_data, &pxm2_ddr3_emif_reg_data, 0); 82c0dcece7SHeiko Schocher } 83c0dcece7SHeiko Schocher 84c0dcece7SHeiko Schocher /* 85c0dcece7SHeiko Schocher * voltage switching for MPU frequency switching. 86c0dcece7SHeiko Schocher * @module = mpu - 0, core - 1 87c0dcece7SHeiko Schocher * @vddx_op_vol_sel = vdd voltage to set 88c0dcece7SHeiko Schocher */ 89c0dcece7SHeiko Schocher 90c0dcece7SHeiko Schocher #define MPU 0 91c0dcece7SHeiko Schocher #define CORE 1 92c0dcece7SHeiko Schocher 93c0dcece7SHeiko Schocher int voltage_update(unsigned int module, unsigned char vddx_op_vol_sel) 94c0dcece7SHeiko Schocher { 95c0dcece7SHeiko Schocher uchar buf[4]; 96c0dcece7SHeiko Schocher unsigned int reg_offset; 97c0dcece7SHeiko Schocher 98c0dcece7SHeiko Schocher if (module == MPU) 99c0dcece7SHeiko Schocher reg_offset = PMIC_VDD1_OP_REG; 100c0dcece7SHeiko Schocher else 101c0dcece7SHeiko Schocher reg_offset = PMIC_VDD2_OP_REG; 102c0dcece7SHeiko Schocher 103c0dcece7SHeiko Schocher /* Select VDDx OP */ 104c0dcece7SHeiko Schocher if (i2c_read(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1)) 105c0dcece7SHeiko Schocher return 1; 106c0dcece7SHeiko Schocher 107c0dcece7SHeiko Schocher buf[0] &= ~PMIC_OP_REG_CMD_MASK; 108c0dcece7SHeiko Schocher 109c0dcece7SHeiko Schocher if (i2c_write(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1)) 110c0dcece7SHeiko Schocher return 1; 111c0dcece7SHeiko Schocher 112c0dcece7SHeiko Schocher /* Configure VDDx OP Voltage */ 113c0dcece7SHeiko Schocher if (i2c_read(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1)) 114c0dcece7SHeiko Schocher return 1; 115c0dcece7SHeiko Schocher 116c0dcece7SHeiko Schocher buf[0] &= ~PMIC_OP_REG_SEL_MASK; 117c0dcece7SHeiko Schocher buf[0] |= vddx_op_vol_sel; 118c0dcece7SHeiko Schocher 119c0dcece7SHeiko Schocher if (i2c_write(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1)) 120c0dcece7SHeiko Schocher return 1; 121c0dcece7SHeiko Schocher 122c0dcece7SHeiko Schocher if (i2c_read(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1)) 123c0dcece7SHeiko Schocher return 1; 124c0dcece7SHeiko Schocher 125c0dcece7SHeiko Schocher if ((buf[0] & PMIC_OP_REG_SEL_MASK) != vddx_op_vol_sel) 126c0dcece7SHeiko Schocher return 1; 127c0dcece7SHeiko Schocher 128c0dcece7SHeiko Schocher return 0; 129c0dcece7SHeiko Schocher } 130c0dcece7SHeiko Schocher 131c0dcece7SHeiko Schocher #define OSC (V_OSCK/1000000) 132c0dcece7SHeiko Schocher 133c0dcece7SHeiko Schocher const struct dpll_params dpll_mpu_pxm2 = { 134c0dcece7SHeiko Schocher 720, OSC-1, 1, -1, -1, -1, -1}; 135c0dcece7SHeiko Schocher 136c0dcece7SHeiko Schocher void spl_siemens_board_init(void) 137c0dcece7SHeiko Schocher { 138c0dcece7SHeiko Schocher uchar buf[4]; 139c0dcece7SHeiko Schocher /* 140c0dcece7SHeiko Schocher * pxm2 PMIC code. All boards currently want an MPU voltage 141c0dcece7SHeiko Schocher * of 1.2625V and CORE voltage of 1.1375V to operate at 142c0dcece7SHeiko Schocher * 720MHz. 143c0dcece7SHeiko Schocher */ 144c0dcece7SHeiko Schocher if (i2c_probe(PMIC_CTRL_I2C_ADDR)) 145c0dcece7SHeiko Schocher return; 146c0dcece7SHeiko Schocher 147c0dcece7SHeiko Schocher /* VDD1/2 voltage selection register access by control i/f */ 148c0dcece7SHeiko Schocher if (i2c_read(PMIC_CTRL_I2C_ADDR, PMIC_DEVCTRL_REG, 1, buf, 1)) 149c0dcece7SHeiko Schocher return; 150c0dcece7SHeiko Schocher 151c0dcece7SHeiko Schocher buf[0] |= PMIC_DEVCTRL_REG_SR_CTL_I2C_SEL_CTL_I2C; 152c0dcece7SHeiko Schocher 153c0dcece7SHeiko Schocher if (i2c_write(PMIC_CTRL_I2C_ADDR, PMIC_DEVCTRL_REG, 1, buf, 1)) 154c0dcece7SHeiko Schocher return; 155c0dcece7SHeiko Schocher 156c0dcece7SHeiko Schocher /* Frequency switching for OPP 120 */ 157c0dcece7SHeiko Schocher if (voltage_update(MPU, PMIC_OP_REG_SEL_1_2_6) || 158c0dcece7SHeiko Schocher voltage_update(CORE, PMIC_OP_REG_SEL_1_1_3)) { 159c0dcece7SHeiko Schocher printf("voltage update failed\n"); 160c0dcece7SHeiko Schocher } 161c0dcece7SHeiko Schocher } 162c0dcece7SHeiko Schocher #endif /* if def CONFIG_SPL_BUILD */ 163c0dcece7SHeiko Schocher 164c0dcece7SHeiko Schocher int read_eeprom(void) 165c0dcece7SHeiko Schocher { 166c0dcece7SHeiko Schocher /* nothing ToDo here for this board */ 167c0dcece7SHeiko Schocher 168c0dcece7SHeiko Schocher return 0; 169c0dcece7SHeiko Schocher } 170c0dcece7SHeiko Schocher 171c0dcece7SHeiko Schocher #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \ 172c0dcece7SHeiko Schocher (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD)) 173c0dcece7SHeiko Schocher static void cpsw_control(int enabled) 174c0dcece7SHeiko Schocher { 175c0dcece7SHeiko Schocher /* VTP can be added here */ 176c0dcece7SHeiko Schocher 177c0dcece7SHeiko Schocher return; 178c0dcece7SHeiko Schocher } 179c0dcece7SHeiko Schocher 180c0dcece7SHeiko Schocher static struct cpsw_slave_data cpsw_slaves[] = { 181c0dcece7SHeiko Schocher { 182c0dcece7SHeiko Schocher .slave_reg_ofs = 0x208, 183c0dcece7SHeiko Schocher .sliver_reg_ofs = 0xd80, 1849c653aadSMugunthan V N .phy_addr = 0, 185c0dcece7SHeiko Schocher .phy_if = PHY_INTERFACE_MODE_RMII, 186c0dcece7SHeiko Schocher }, 187c0dcece7SHeiko Schocher { 188c0dcece7SHeiko Schocher .slave_reg_ofs = 0x308, 189c0dcece7SHeiko Schocher .sliver_reg_ofs = 0xdc0, 1909c653aadSMugunthan V N .phy_addr = 1, 191c0dcece7SHeiko Schocher .phy_if = PHY_INTERFACE_MODE_RMII, 192c0dcece7SHeiko Schocher }, 193c0dcece7SHeiko Schocher }; 194c0dcece7SHeiko Schocher 195c0dcece7SHeiko Schocher static struct cpsw_platform_data cpsw_data = { 196c0dcece7SHeiko Schocher .mdio_base = CPSW_MDIO_BASE, 197c0dcece7SHeiko Schocher .cpsw_base = CPSW_BASE, 198c0dcece7SHeiko Schocher .mdio_div = 0xff, 199c0dcece7SHeiko Schocher .channels = 4, 200c0dcece7SHeiko Schocher .cpdma_reg_ofs = 0x800, 201c0dcece7SHeiko Schocher .slaves = 1, 202c0dcece7SHeiko Schocher .slave_data = cpsw_slaves, 203c0dcece7SHeiko Schocher .ale_reg_ofs = 0xd00, 204c0dcece7SHeiko Schocher .ale_entries = 1024, 205c0dcece7SHeiko Schocher .host_port_reg_ofs = 0x108, 206c0dcece7SHeiko Schocher .hw_stats_reg_ofs = 0x900, 207c0dcece7SHeiko Schocher .bd_ram_ofs = 0x2000, 208c0dcece7SHeiko Schocher .mac_control = (1 << 5), 209c0dcece7SHeiko Schocher .control = cpsw_control, 210c0dcece7SHeiko Schocher .host_port_num = 0, 211c0dcece7SHeiko Schocher .version = CPSW_CTRL_VERSION_2, 212c0dcece7SHeiko Schocher }; 213c0dcece7SHeiko Schocher #endif /* #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) */ 214c0dcece7SHeiko Schocher 215c0dcece7SHeiko Schocher #if defined(CONFIG_DRIVER_TI_CPSW) || \ 216c0dcece7SHeiko Schocher (defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET)) 217c0dcece7SHeiko Schocher int board_eth_init(bd_t *bis) 218c0dcece7SHeiko Schocher { 219c0dcece7SHeiko Schocher int n = 0; 220c0dcece7SHeiko Schocher #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \ 221c0dcece7SHeiko Schocher (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD)) 222c0dcece7SHeiko Schocher struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; 223c0dcece7SHeiko Schocher #ifdef CONFIG_FACTORYSET 224c0dcece7SHeiko Schocher int rv; 225c0dcece7SHeiko Schocher if (!is_valid_ether_addr(factory_dat.mac)) 226c0dcece7SHeiko Schocher printf("Error: no valid mac address\n"); 227c0dcece7SHeiko Schocher else 228c0dcece7SHeiko Schocher eth_setenv_enetaddr("ethaddr", factory_dat.mac); 229c0dcece7SHeiko Schocher #endif /* #ifdef CONFIG_FACTORYSET */ 230c0dcece7SHeiko Schocher 231c0dcece7SHeiko Schocher /* Set rgmii mode and enable rmii clock to be sourced from chip */ 23260ca5ad4SHeiko Schocher writel(RGMII_MODE_ENABLE | RGMII_INT_DELAY, &cdev->miisel); 233c0dcece7SHeiko Schocher 234c0dcece7SHeiko Schocher rv = cpsw_register(&cpsw_data); 235c0dcece7SHeiko Schocher if (rv < 0) 236c0dcece7SHeiko Schocher printf("Error %d registering CPSW switch\n", rv); 237c0dcece7SHeiko Schocher else 238c0dcece7SHeiko Schocher n += rv; 239c0dcece7SHeiko Schocher #endif 240c0dcece7SHeiko Schocher return n; 241c0dcece7SHeiko Schocher } 242c0dcece7SHeiko Schocher #endif /* #if defined(CONFIG_DRIVER_TI_CPSW) */ 243c0dcece7SHeiko Schocher 244c0dcece7SHeiko Schocher #if defined(CONFIG_VIDEO) && !defined(CONFIG_SPL_BUILD) 245c0dcece7SHeiko Schocher static struct da8xx_panel lcd_panels[] = { 246c0dcece7SHeiko Schocher /* AUO G156XW01 V1 */ 247c0dcece7SHeiko Schocher [0] = { 248c0dcece7SHeiko Schocher .name = "AUO_G156XW01_V1", 249c0dcece7SHeiko Schocher .width = 1376, 250c0dcece7SHeiko Schocher .height = 768, 251c0dcece7SHeiko Schocher .hfp = 14, 252c0dcece7SHeiko Schocher .hbp = 64, 253c0dcece7SHeiko Schocher .hsw = 56, 254c0dcece7SHeiko Schocher .vfp = 1, 255c0dcece7SHeiko Schocher .vbp = 28, 256c0dcece7SHeiko Schocher .vsw = 3, 257c0dcece7SHeiko Schocher .pxl_clk = 60000000, 258c0dcece7SHeiko Schocher .invert_pxl_clk = 0, 259c0dcece7SHeiko Schocher }, 260c0dcece7SHeiko Schocher /* AUO B101EVN06 V0 */ 261c0dcece7SHeiko Schocher [1] = { 262c0dcece7SHeiko Schocher .name = "AUO_B101EVN06_V0", 263c0dcece7SHeiko Schocher .width = 1280, 264c0dcece7SHeiko Schocher .height = 800, 265c0dcece7SHeiko Schocher .hfp = 52, 266c0dcece7SHeiko Schocher .hbp = 84, 267c0dcece7SHeiko Schocher .hsw = 36, 268c0dcece7SHeiko Schocher .vfp = 3, 269c0dcece7SHeiko Schocher .vbp = 14, 270c0dcece7SHeiko Schocher .vsw = 6, 271c0dcece7SHeiko Schocher .pxl_clk = 60000000, 272c0dcece7SHeiko Schocher .invert_pxl_clk = 0, 273c0dcece7SHeiko Schocher }, 274c0dcece7SHeiko Schocher /* 275c0dcece7SHeiko Schocher * Settings from factoryset 276c0dcece7SHeiko Schocher * stored in EEPROM 277c0dcece7SHeiko Schocher */ 278c0dcece7SHeiko Schocher [2] = { 279c0dcece7SHeiko Schocher .name = "factoryset", 280c0dcece7SHeiko Schocher .width = 0, 281c0dcece7SHeiko Schocher .height = 0, 282c0dcece7SHeiko Schocher .hfp = 0, 283c0dcece7SHeiko Schocher .hbp = 0, 284c0dcece7SHeiko Schocher .hsw = 0, 285c0dcece7SHeiko Schocher .vfp = 0, 286c0dcece7SHeiko Schocher .vbp = 0, 287c0dcece7SHeiko Schocher .vsw = 0, 288c0dcece7SHeiko Schocher .pxl_clk = 60000000, 289c0dcece7SHeiko Schocher .invert_pxl_clk = 0, 290c0dcece7SHeiko Schocher }, 291c0dcece7SHeiko Schocher }; 292c0dcece7SHeiko Schocher 293c0dcece7SHeiko Schocher static const struct display_panel disp_panel = { 294c0dcece7SHeiko Schocher WVGA, 295c0dcece7SHeiko Schocher 32, 296c0dcece7SHeiko Schocher 16, 297c0dcece7SHeiko Schocher COLOR_ACTIVE, 298c0dcece7SHeiko Schocher }; 299c0dcece7SHeiko Schocher 300c0dcece7SHeiko Schocher static const struct lcd_ctrl_config lcd_cfg = { 301c0dcece7SHeiko Schocher &disp_panel, 302c0dcece7SHeiko Schocher .ac_bias = 255, 303c0dcece7SHeiko Schocher .ac_bias_intrpt = 0, 304c0dcece7SHeiko Schocher .dma_burst_sz = 16, 305c0dcece7SHeiko Schocher .bpp = 32, 306c0dcece7SHeiko Schocher .fdd = 0x80, 307c0dcece7SHeiko Schocher .tft_alt_mode = 0, 308c0dcece7SHeiko Schocher .stn_565_mode = 0, 309c0dcece7SHeiko Schocher .mono_8bit_mode = 0, 310c0dcece7SHeiko Schocher .invert_line_clock = 1, 311c0dcece7SHeiko Schocher .invert_frm_clock = 1, 312c0dcece7SHeiko Schocher .sync_edge = 0, 313c0dcece7SHeiko Schocher .sync_ctrl = 1, 314c0dcece7SHeiko Schocher .raster_order = 0, 315c0dcece7SHeiko Schocher }; 316c0dcece7SHeiko Schocher 317c0dcece7SHeiko Schocher static int set_gpio(int gpio, int state) 318c0dcece7SHeiko Schocher { 319c0dcece7SHeiko Schocher gpio_request(gpio, "temp"); 320c0dcece7SHeiko Schocher gpio_direction_output(gpio, state); 321c0dcece7SHeiko Schocher gpio_set_value(gpio, state); 322c0dcece7SHeiko Schocher gpio_free(gpio); 323c0dcece7SHeiko Schocher return 0; 324c0dcece7SHeiko Schocher } 325c0dcece7SHeiko Schocher 326c0dcece7SHeiko Schocher static int enable_backlight(void) 327c0dcece7SHeiko Schocher { 328c0dcece7SHeiko Schocher set_gpio(BOARD_LCD_POWER, 1); 329c0dcece7SHeiko Schocher set_gpio(BOARD_BACK_LIGHT, 1); 330c0dcece7SHeiko Schocher set_gpio(BOARD_TOUCH_POWER, 1); 331c0dcece7SHeiko Schocher return 0; 332c0dcece7SHeiko Schocher } 333c0dcece7SHeiko Schocher 334c0dcece7SHeiko Schocher static int enable_pwm(void) 335c0dcece7SHeiko Schocher { 336c0dcece7SHeiko Schocher struct pwmss_regs *pwmss = (struct pwmss_regs *)PWMSS0_BASE; 337c0dcece7SHeiko Schocher struct pwmss_ecap_regs *ecap; 338c0dcece7SHeiko Schocher int ticks = PWM_TICKS; 339c0dcece7SHeiko Schocher int duty = PWM_DUTY; 340c0dcece7SHeiko Schocher 341c0dcece7SHeiko Schocher ecap = (struct pwmss_ecap_regs *)AM33XX_ECAP0_BASE; 342c0dcece7SHeiko Schocher /* enable clock */ 343c0dcece7SHeiko Schocher setbits_le32(&pwmss->clkconfig, ECAP_CLK_EN); 344c0dcece7SHeiko Schocher /* TimeStam Counter register */ 345c0dcece7SHeiko Schocher writel(0xdb9, &ecap->tsctr); 346c0dcece7SHeiko Schocher /* config period */ 347c0dcece7SHeiko Schocher writel(ticks - 1, &ecap->cap3); 348c0dcece7SHeiko Schocher writel(ticks - 1, &ecap->cap1); 349c0dcece7SHeiko Schocher setbits_le16(&ecap->ecctl2, 350c0dcece7SHeiko Schocher (ECTRL2_MDSL_ECAP | ECTRL2_SYNCOSEL_MASK | 0xd0)); 351c0dcece7SHeiko Schocher /* config duty */ 352c0dcece7SHeiko Schocher writel(duty, &ecap->cap2); 353c0dcece7SHeiko Schocher writel(duty, &ecap->cap4); 354c0dcece7SHeiko Schocher /* start */ 355c0dcece7SHeiko Schocher setbits_le16(&ecap->ecctl2, ECTRL2_CTRSTP_FREERUN); 356c0dcece7SHeiko Schocher return 0; 357c0dcece7SHeiko Schocher } 358c0dcece7SHeiko Schocher 359c0dcece7SHeiko Schocher static struct dpll_regs dpll_lcd_regs = { 360c0dcece7SHeiko Schocher .cm_clkmode_dpll = CM_WKUP + 0x98, 361c0dcece7SHeiko Schocher .cm_idlest_dpll = CM_WKUP + 0x48, 362c0dcece7SHeiko Schocher .cm_clksel_dpll = CM_WKUP + 0x54, 363c0dcece7SHeiko Schocher }; 364c0dcece7SHeiko Schocher 365c0dcece7SHeiko Schocher /* no console on this board */ 366c0dcece7SHeiko Schocher int board_cfb_skip(void) 367c0dcece7SHeiko Schocher { 368c0dcece7SHeiko Schocher return 1; 369c0dcece7SHeiko Schocher } 370c0dcece7SHeiko Schocher 371c0dcece7SHeiko Schocher #define PLL_GET_M(v) ((v >> 8) & 0x7ff) 372c0dcece7SHeiko Schocher #define PLL_GET_N(v) (v & 0x7f) 373c0dcece7SHeiko Schocher 374c0dcece7SHeiko Schocher static int get_clk(struct dpll_regs *dpll_regs) 375c0dcece7SHeiko Schocher { 376c0dcece7SHeiko Schocher unsigned int val; 377c0dcece7SHeiko Schocher unsigned int m, n; 378c0dcece7SHeiko Schocher int f = 0; 379c0dcece7SHeiko Schocher 380c0dcece7SHeiko Schocher val = readl(dpll_regs->cm_clksel_dpll); 381c0dcece7SHeiko Schocher m = PLL_GET_M(val); 382c0dcece7SHeiko Schocher n = PLL_GET_N(val); 383c0dcece7SHeiko Schocher f = (m * V_OSCK) / n; 384c0dcece7SHeiko Schocher 385c0dcece7SHeiko Schocher return f; 386c0dcece7SHeiko Schocher }; 387c0dcece7SHeiko Schocher 388c0dcece7SHeiko Schocher int clk_get(int clk) 389c0dcece7SHeiko Schocher { 390c0dcece7SHeiko Schocher return get_clk(&dpll_lcd_regs); 391c0dcece7SHeiko Schocher }; 392c0dcece7SHeiko Schocher 393c0dcece7SHeiko Schocher static int conf_disp_pll(int m, int n) 394c0dcece7SHeiko Schocher { 395c0dcece7SHeiko Schocher struct cm_perpll *cmper = (struct cm_perpll *)CM_PER; 396c0dcece7SHeiko Schocher struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL; 397c0dcece7SHeiko Schocher struct dpll_params dpll_lcd = {m, n, -1, -1, -1, -1, -1}; 398c0dcece7SHeiko Schocher 399c0dcece7SHeiko Schocher u32 *const clk_domains[] = { 400c0dcece7SHeiko Schocher &cmper->lcdclkctrl, 401c0dcece7SHeiko Schocher 0 402c0dcece7SHeiko Schocher }; 403c0dcece7SHeiko Schocher u32 *const clk_modules_explicit_en[] = { 404c0dcece7SHeiko Schocher &cmper->lcdclkctrl, 405c0dcece7SHeiko Schocher &cmper->lcdcclkstctrl, 406c0dcece7SHeiko Schocher &cmper->epwmss0clkctrl, 407c0dcece7SHeiko Schocher 0 408c0dcece7SHeiko Schocher }; 409c0dcece7SHeiko Schocher do_enable_clocks(clk_domains, clk_modules_explicit_en, 1); 410c0dcece7SHeiko Schocher writel(0x0, &cmdpll->clklcdcpixelclk); 411c0dcece7SHeiko Schocher 412c0dcece7SHeiko Schocher do_setup_dpll(&dpll_lcd_regs, &dpll_lcd); 413c0dcece7SHeiko Schocher 414c0dcece7SHeiko Schocher return 0; 415c0dcece7SHeiko Schocher } 416c0dcece7SHeiko Schocher 417c0dcece7SHeiko Schocher static int board_video_init(void) 418c0dcece7SHeiko Schocher { 41956eb3da4SSamuel Egli conf_disp_pll(24, 1); 420c0dcece7SHeiko Schocher if (factory_dat.pxm50) 421c0dcece7SHeiko Schocher da8xx_video_init(&lcd_panels[0], &lcd_cfg, lcd_cfg.bpp); 422c0dcece7SHeiko Schocher else 423c0dcece7SHeiko Schocher da8xx_video_init(&lcd_panels[1], &lcd_cfg, lcd_cfg.bpp); 424c0dcece7SHeiko Schocher 425c0dcece7SHeiko Schocher enable_pwm(); 426c0dcece7SHeiko Schocher enable_backlight(); 427c0dcece7SHeiko Schocher 428c0dcece7SHeiko Schocher return 0; 429c0dcece7SHeiko Schocher } 430c0dcece7SHeiko Schocher #endif 431*0c331ebcSHeiko Schocher 432*0c331ebcSHeiko Schocher #ifdef CONFIG_BOARD_LATE_INIT 433*0c331ebcSHeiko Schocher int board_late_init(void) 434*0c331ebcSHeiko Schocher { 435*0c331ebcSHeiko Schocher int ret; 436*0c331ebcSHeiko Schocher 437*0c331ebcSHeiko Schocher omap_nand_switch_ecc(1, 8); 438*0c331ebcSHeiko Schocher 439*0c331ebcSHeiko Schocher #ifdef CONFIG_FACTORYSET 440*0c331ebcSHeiko Schocher if (factory_dat.asn[0] != 0) { 441*0c331ebcSHeiko Schocher char tmp[2 * MAX_STRING_LENGTH + 2]; 442*0c331ebcSHeiko Schocher 443*0c331ebcSHeiko Schocher if (strncmp((const char *)factory_dat.asn, "PXM50", 5) == 0) 444*0c331ebcSHeiko Schocher factory_dat.pxm50 = 1; 445*0c331ebcSHeiko Schocher else 446*0c331ebcSHeiko Schocher factory_dat.pxm50 = 0; 447*0c331ebcSHeiko Schocher sprintf(tmp, "%s_%s", factory_dat.asn, 448*0c331ebcSHeiko Schocher factory_dat.comp_version); 449*0c331ebcSHeiko Schocher ret = setenv("boardid", tmp); 450*0c331ebcSHeiko Schocher if (ret) 451*0c331ebcSHeiko Schocher printf("error setting board id\n"); 452*0c331ebcSHeiko Schocher } else { 453*0c331ebcSHeiko Schocher factory_dat.pxm50 = 1; 454*0c331ebcSHeiko Schocher ret = setenv("boardid", "PXM50_1.0"); 455*0c331ebcSHeiko Schocher if (ret) 456*0c331ebcSHeiko Schocher printf("error setting board id\n"); 457*0c331ebcSHeiko Schocher } 458*0c331ebcSHeiko Schocher debug("PXM50: %d\n", factory_dat.pxm50); 459*0c331ebcSHeiko Schocher #endif 460*0c331ebcSHeiko Schocher 461*0c331ebcSHeiko Schocher return 0; 462*0c331ebcSHeiko Schocher } 463*0c331ebcSHeiko Schocher #endif 464*0c331ebcSHeiko Schocher 465c0dcece7SHeiko Schocher #include "../common/board.c" 466