1*893c04e1SHannes Petermaier /* 2*893c04e1SHannes Petermaier * common.c 3*893c04e1SHannes Petermaier * 4*893c04e1SHannes Petermaier * common board functions for B&R boards 5*893c04e1SHannes Petermaier * 6*893c04e1SHannes Petermaier * Copyright (C) 2013 Hannes Petermaier <oe5hpm@oevsv.at> 7*893c04e1SHannes Petermaier * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com 8*893c04e1SHannes Petermaier * 9*893c04e1SHannes Petermaier * SPDX-License-Identifier: GPL-2.0+ 10*893c04e1SHannes Petermaier * 11*893c04e1SHannes Petermaier */ 12*893c04e1SHannes Petermaier 13*893c04e1SHannes Petermaier #include <common.h> 14*893c04e1SHannes Petermaier #include <errno.h> 15*893c04e1SHannes Petermaier #include <spl.h> 16*893c04e1SHannes Petermaier #include <asm/arch/cpu.h> 17*893c04e1SHannes Petermaier #include <asm/arch/hardware.h> 18*893c04e1SHannes Petermaier #include <asm/arch/omap.h> 19*893c04e1SHannes Petermaier #include <asm/arch/clock.h> 20*893c04e1SHannes Petermaier #include <asm/arch/gpio.h> 21*893c04e1SHannes Petermaier #include <asm/arch/sys_proto.h> 22*893c04e1SHannes Petermaier #include <asm/io.h> 23*893c04e1SHannes Petermaier #include <asm/gpio.h> 24*893c04e1SHannes Petermaier #include <i2c.h> 25*893c04e1SHannes Petermaier #include <miiphy.h> 26*893c04e1SHannes Petermaier #include <cpsw.h> 27*893c04e1SHannes Petermaier #include <power/tps65217.h> 28*893c04e1SHannes Petermaier #include "bur_common.h" 29*893c04e1SHannes Petermaier 30*893c04e1SHannes Petermaier static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; 31*893c04e1SHannes Petermaier /* --------------------------------------------------------------------------*/ 32*893c04e1SHannes Petermaier void blink(u32 blinks, u32 intervall, u32 pin) 33*893c04e1SHannes Petermaier { 34*893c04e1SHannes Petermaier gpio_direction_output(pin, 0); 35*893c04e1SHannes Petermaier int val = 0; 36*893c04e1SHannes Petermaier 37*893c04e1SHannes Petermaier do { 38*893c04e1SHannes Petermaier val ^= 0x01; 39*893c04e1SHannes Petermaier gpio_set_value(pin, val); 40*893c04e1SHannes Petermaier mdelay(intervall); 41*893c04e1SHannes Petermaier } while (blinks--); 42*893c04e1SHannes Petermaier 43*893c04e1SHannes Petermaier gpio_set_value(pin, 0); 44*893c04e1SHannes Petermaier } 45*893c04e1SHannes Petermaier #ifdef CONFIG_SPL_BUILD 46*893c04e1SHannes Petermaier void pmicsetup(u32 mpupll) 47*893c04e1SHannes Petermaier { 48*893c04e1SHannes Petermaier int mpu_vdd; 49*893c04e1SHannes Petermaier int usb_cur_lim; 50*893c04e1SHannes Petermaier 51*893c04e1SHannes Petermaier /* setup I2C */ 52*893c04e1SHannes Petermaier enable_i2c0_pin_mux(); 53*893c04e1SHannes Petermaier i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE); 54*893c04e1SHannes Petermaier 55*893c04e1SHannes Petermaier if (i2c_probe(TPS65217_CHIP_PM)) { 56*893c04e1SHannes Petermaier puts("PMIC (0x24) not found! skip further initalization.\n"); 57*893c04e1SHannes Petermaier return; 58*893c04e1SHannes Petermaier } 59*893c04e1SHannes Petermaier 60*893c04e1SHannes Petermaier /* Get the frequency which is defined by device fuses */ 61*893c04e1SHannes Petermaier dpll_mpu_opp100.m = am335x_get_efuse_mpu_max_freq(cdev); 62*893c04e1SHannes Petermaier printf("detected max. frequency: %d - ", dpll_mpu_opp100.m); 63*893c04e1SHannes Petermaier 64*893c04e1SHannes Petermaier if (0 != mpupll) { 65*893c04e1SHannes Petermaier dpll_mpu_opp100.m = MPUPLL_M_1000; 66*893c04e1SHannes Petermaier printf("retuning MPU-PLL to: %d MHz.\n", dpll_mpu_opp100.m); 67*893c04e1SHannes Petermaier } else { 68*893c04e1SHannes Petermaier puts("ok.\n"); 69*893c04e1SHannes Petermaier } 70*893c04e1SHannes Petermaier /* 71*893c04e1SHannes Petermaier * Increase USB current limit to 1300mA or 1800mA and set 72*893c04e1SHannes Petermaier * the MPU voltage controller as needed. 73*893c04e1SHannes Petermaier */ 74*893c04e1SHannes Petermaier if (dpll_mpu_opp100.m == MPUPLL_M_1000) { 75*893c04e1SHannes Petermaier usb_cur_lim = TPS65217_USB_INPUT_CUR_LIMIT_1800MA; 76*893c04e1SHannes Petermaier mpu_vdd = TPS65217_DCDC_VOLT_SEL_1325MV; 77*893c04e1SHannes Petermaier } else { 78*893c04e1SHannes Petermaier usb_cur_lim = TPS65217_USB_INPUT_CUR_LIMIT_1300MA; 79*893c04e1SHannes Petermaier mpu_vdd = TPS65217_DCDC_VOLT_SEL_1275MV; 80*893c04e1SHannes Petermaier } 81*893c04e1SHannes Petermaier 82*893c04e1SHannes Petermaier if (tps65217_reg_write(TPS65217_PROT_LEVEL_NONE, TPS65217_POWER_PATH, 83*893c04e1SHannes Petermaier usb_cur_lim, TPS65217_USB_INPUT_CUR_LIMIT_MASK)) 84*893c04e1SHannes Petermaier puts("tps65217_reg_write failure\n"); 85*893c04e1SHannes Petermaier 86*893c04e1SHannes Petermaier /* Set DCDC3 (CORE) voltage to 1.125V */ 87*893c04e1SHannes Petermaier if (tps65217_voltage_update(TPS65217_DEFDCDC3, 88*893c04e1SHannes Petermaier TPS65217_DCDC_VOLT_SEL_1125MV)) { 89*893c04e1SHannes Petermaier puts("tps65217_voltage_update failure\n"); 90*893c04e1SHannes Petermaier return; 91*893c04e1SHannes Petermaier } 92*893c04e1SHannes Petermaier 93*893c04e1SHannes Petermaier /* Set CORE Frequencies to OPP100 */ 94*893c04e1SHannes Petermaier do_setup_dpll(&dpll_core_regs, &dpll_core_opp100); 95*893c04e1SHannes Petermaier 96*893c04e1SHannes Petermaier /* Set DCDC2 (MPU) voltage */ 97*893c04e1SHannes Petermaier if (tps65217_voltage_update(TPS65217_DEFDCDC2, mpu_vdd)) { 98*893c04e1SHannes Petermaier puts("tps65217_voltage_update failure\n"); 99*893c04e1SHannes Petermaier return; 100*893c04e1SHannes Petermaier } 101*893c04e1SHannes Petermaier 102*893c04e1SHannes Petermaier /* Set LDO3 to 1.8V */ 103*893c04e1SHannes Petermaier if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, 104*893c04e1SHannes Petermaier TPS65217_DEFLS1, 105*893c04e1SHannes Petermaier TPS65217_LDO_VOLTAGE_OUT_1_8, 106*893c04e1SHannes Petermaier TPS65217_LDO_MASK)) 107*893c04e1SHannes Petermaier puts("tps65217_reg_write failure\n"); 108*893c04e1SHannes Petermaier /* Set LDO4 to 3.3V */ 109*893c04e1SHannes Petermaier if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, 110*893c04e1SHannes Petermaier TPS65217_DEFLS2, 111*893c04e1SHannes Petermaier TPS65217_LDO_VOLTAGE_OUT_3_3, 112*893c04e1SHannes Petermaier TPS65217_LDO_MASK)) 113*893c04e1SHannes Petermaier puts("tps65217_reg_write failure\n"); 114*893c04e1SHannes Petermaier 115*893c04e1SHannes Petermaier /* Set MPU Frequency to what we detected now that voltages are set */ 116*893c04e1SHannes Petermaier do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100); 117*893c04e1SHannes Petermaier } 118*893c04e1SHannes Petermaier 119*893c04e1SHannes Petermaier void set_uart_mux_conf(void) 120*893c04e1SHannes Petermaier { 121*893c04e1SHannes Petermaier enable_uart0_pin_mux(); 122*893c04e1SHannes Petermaier } 123*893c04e1SHannes Petermaier 124*893c04e1SHannes Petermaier void set_mux_conf_regs(void) 125*893c04e1SHannes Petermaier { 126*893c04e1SHannes Petermaier enable_board_pin_mux(); 127*893c04e1SHannes Petermaier } 128*893c04e1SHannes Petermaier 129*893c04e1SHannes Petermaier #endif /* CONFIG_SPL_BUILD */ 130*893c04e1SHannes Petermaier 131*893c04e1SHannes Petermaier #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \ 132*893c04e1SHannes Petermaier (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD)) 133*893c04e1SHannes Petermaier static void cpsw_control(int enabled) 134*893c04e1SHannes Petermaier { 135*893c04e1SHannes Petermaier /* VTP can be added here */ 136*893c04e1SHannes Petermaier return; 137*893c04e1SHannes Petermaier } 138*893c04e1SHannes Petermaier 139*893c04e1SHannes Petermaier /* describing port offsets of TI's CPSW block */ 140*893c04e1SHannes Petermaier static struct cpsw_slave_data cpsw_slaves[] = { 141*893c04e1SHannes Petermaier { 142*893c04e1SHannes Petermaier .slave_reg_ofs = 0x208, 143*893c04e1SHannes Petermaier .sliver_reg_ofs = 0xd80, 144*893c04e1SHannes Petermaier .phy_id = 0, 145*893c04e1SHannes Petermaier }, 146*893c04e1SHannes Petermaier { 147*893c04e1SHannes Petermaier .slave_reg_ofs = 0x308, 148*893c04e1SHannes Petermaier .sliver_reg_ofs = 0xdc0, 149*893c04e1SHannes Petermaier .phy_id = 1, 150*893c04e1SHannes Petermaier }, 151*893c04e1SHannes Petermaier }; 152*893c04e1SHannes Petermaier 153*893c04e1SHannes Petermaier static struct cpsw_platform_data cpsw_data = { 154*893c04e1SHannes Petermaier .mdio_base = CPSW_MDIO_BASE, 155*893c04e1SHannes Petermaier .cpsw_base = CPSW_BASE, 156*893c04e1SHannes Petermaier .mdio_div = 0xff, 157*893c04e1SHannes Petermaier .channels = 8, 158*893c04e1SHannes Petermaier .cpdma_reg_ofs = 0x800, 159*893c04e1SHannes Petermaier .slaves = 1, 160*893c04e1SHannes Petermaier .slave_data = cpsw_slaves, 161*893c04e1SHannes Petermaier .ale_reg_ofs = 0xd00, 162*893c04e1SHannes Petermaier .ale_entries = 1024, 163*893c04e1SHannes Petermaier .host_port_reg_ofs = 0x108, 164*893c04e1SHannes Petermaier .hw_stats_reg_ofs = 0x900, 165*893c04e1SHannes Petermaier .bd_ram_ofs = 0x2000, 166*893c04e1SHannes Petermaier .mac_control = (1 << 5), 167*893c04e1SHannes Petermaier .control = cpsw_control, 168*893c04e1SHannes Petermaier .host_port_num = 0, 169*893c04e1SHannes Petermaier .version = CPSW_CTRL_VERSION_2, 170*893c04e1SHannes Petermaier }; 171*893c04e1SHannes Petermaier #endif /* CONFIG_DRIVER_TI_CPSW, ... */ 172*893c04e1SHannes Petermaier 173*893c04e1SHannes Petermaier #if defined(CONFIG_DRIVER_TI_CPSW) 174*893c04e1SHannes Petermaier 175*893c04e1SHannes Petermaier int board_eth_init(bd_t *bis) 176*893c04e1SHannes Petermaier { 177*893c04e1SHannes Petermaier int rv = 0; 178*893c04e1SHannes Petermaier uint8_t mac_addr[6]; 179*893c04e1SHannes Petermaier uint32_t mac_hi, mac_lo; 180*893c04e1SHannes Petermaier 181*893c04e1SHannes Petermaier /* try reading mac address from efuse */ 182*893c04e1SHannes Petermaier mac_lo = readl(&cdev->macid0l); 183*893c04e1SHannes Petermaier mac_hi = readl(&cdev->macid0h); 184*893c04e1SHannes Petermaier mac_addr[0] = mac_hi & 0xFF; 185*893c04e1SHannes Petermaier mac_addr[1] = (mac_hi & 0xFF00) >> 8; 186*893c04e1SHannes Petermaier mac_addr[2] = (mac_hi & 0xFF0000) >> 16; 187*893c04e1SHannes Petermaier mac_addr[3] = (mac_hi & 0xFF000000) >> 24; 188*893c04e1SHannes Petermaier mac_addr[4] = mac_lo & 0xFF; 189*893c04e1SHannes Petermaier mac_addr[5] = (mac_lo & 0xFF00) >> 8; 190*893c04e1SHannes Petermaier 191*893c04e1SHannes Petermaier #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \ 192*893c04e1SHannes Petermaier (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD)) 193*893c04e1SHannes Petermaier if (!getenv("ethaddr")) { 194*893c04e1SHannes Petermaier printf("<ethaddr> not set. Validating first E-fuse MAC ... "); 195*893c04e1SHannes Petermaier 196*893c04e1SHannes Petermaier if (is_valid_ether_addr(mac_addr)) { 197*893c04e1SHannes Petermaier printf("using: %02X:%02X:%02X:%02X:%02X:%02X.\n", 198*893c04e1SHannes Petermaier mac_addr[0], mac_addr[1], mac_addr[2], 199*893c04e1SHannes Petermaier mac_addr[3], mac_addr[4], mac_addr[5] 200*893c04e1SHannes Petermaier ); 201*893c04e1SHannes Petermaier eth_setenv_enetaddr("ethaddr", mac_addr); 202*893c04e1SHannes Petermaier } 203*893c04e1SHannes Petermaier } 204*893c04e1SHannes Petermaier writel(MII_MODE_ENABLE, &cdev->miisel); 205*893c04e1SHannes Petermaier cpsw_slaves[0].phy_if = PHY_INTERFACE_MODE_MII; 206*893c04e1SHannes Petermaier cpsw_slaves[1].phy_if = PHY_INTERFACE_MODE_MII; 207*893c04e1SHannes Petermaier 208*893c04e1SHannes Petermaier rv = cpsw_register(&cpsw_data); 209*893c04e1SHannes Petermaier if (rv < 0) { 210*893c04e1SHannes Petermaier printf("Error %d registering CPSW switch\n", rv); 211*893c04e1SHannes Petermaier return 0; 212*893c04e1SHannes Petermaier } 213*893c04e1SHannes Petermaier #endif /* CONFIG_DRIVER_TI_CPSW, ... */ 214*893c04e1SHannes Petermaier return rv; 215*893c04e1SHannes Petermaier } 216*893c04e1SHannes Petermaier #endif /* CONFIG_DRIVER_TI_CPSW */ 217