+// SPDX-License-Identifier: GPL-2.0+
/*
* board.c
*
* Board functions for TI AM335X based boards
*
* Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
+#include <env.h>
#include <errno.h>
+#include <init.h>
#include <spl.h>
#include <serial.h>
#include <asm/arch/cpu.h>
#include <cpsw.h>
#include <power/tps65217.h>
#include <power/tps65910.h>
-#include <environment.h>
+#include <env_internal.h>
#include <watchdog.h>
-#include <environment.h>
#include "../common/board_detect.h"
#include "board.h"
void do_board_detect(void)
{
enable_i2c0_pin_mux();
+#ifndef CONFIG_DM_I2C
i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
-
+#endif
if (ti_i2c_eeprom_am_get(CONFIG_EEPROM_BUS_ADDRESS,
CONFIG_EEPROM_CHIP_ADDRESS))
printf("ti_i2c_eeprom_init failed\n");
#ifdef CONFIG_SPL_OS_BOOT
int spl_start_uboot(void)
{
+#ifdef CONFIG_SPL_SERIAL_SUPPORT
/* break into full u-boot on 'c' */
if (serial_tstc() && serial_getc() == 'c')
return 1;
+#endif
#ifdef CONFIG_SPL_ENV_SUPPORT
env_init();
if (board_is_evm_sk())
return &dpll_ddr3_303MHz[ind];
- else if (board_is_bone_lt() || board_is_icev2())
+ else if (board_is_pb() || board_is_bone_lt() || board_is_icev2())
return &dpll_ddr3_400MHz[ind];
else if (board_is_evm_15_or_later())
return &dpll_ddr3_303MHz[ind];
if (bone_not_connected_to_ac_power())
freq = MPUPLL_M_600;
- if (board_is_bone_lt())
+ if (board_is_pb() || board_is_bone_lt())
freq = MPUPLL_M_1000;
switch (freq) {
if (board_is_bone() && !strncmp(board_ti_get_rev(), "00A1", 4))
return;
+#ifndef CONFIG_DM_I2C
if (i2c_probe(TPS65217_CHIP_PM))
return;
+#else
+ if (power_tps65217_init(0))
+ return;
+#endif
+
/*
* On Beaglebone White we need to ensure we have AC power
* Override what we have detected since we know if we have
* a Beaglebone Black it supports 1GHz.
*/
- if (board_is_bone_lt())
+ if (board_is_pb() || board_is_bone_lt())
freq = MPUPLL_M_1000;
switch (freq) {
* 1.10V. For MPU voltage we need to switch based on
* the frequency we are running at.
*/
+#ifndef CONFIG_DM_I2C
if (i2c_probe(TPS65910_CTRL_I2C_ADDR))
return;
-
+#else
+ if (power_tps65910_init(0))
+ return;
+#endif
/*
* Depending on MPU clock and PG we will need a different
* VDD to drive at that speed.
if (first_time) {
enable_i2c0_pin_mux();
+#ifndef CONFIG_DM_I2C
i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED,
CONFIG_SYS_OMAP24_I2C_SLAVE);
+#endif
first_time = false;
}
}
if (board_is_evm_sk())
config_ddr(303, &ioregs_evmsk, &ddr3_data,
&ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0);
- else if (board_is_bone_lt())
+ else if (board_is_pb() || board_is_bone_lt())
config_ddr(400, &ioregs_bonelt,
&ddr3_beagleblack_data,
&ddr3_beagleblack_cmd_ctrl_data,
}
#endif
-#if !defined(CONFIG_SPL_BUILD) || \
- (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
+#if defined(CONFIG_CLOCK_SYNTHESIZER) && (!defined(CONFIG_SPL_BUILD) || \
+ (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD)))
static void request_and_set_gpio(int gpio, char *name, int val)
{
int ret;
};
#endif
+#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_CONTROL) && \
+ defined(CONFIG_DM_ETH) && defined(CONFIG_DRIVER_TI_CPSW)
+
+#define MAX_CPSW_SLAVES 2
+
+/* At the moment, we do not want to stop booting for any failures here */
+int ft_board_setup(void *fdt, bd_t *bd)
+{
+ const char *slave_path, *enet_name;
+ int enetnode, slavenode, phynode;
+ struct udevice *ethdev;
+ char alias[16];
+ u32 phy_id[2];
+ int phy_addr;
+ int i, ret;
+
+ /* phy address fixup needed only on beagle bone family */
+ if (!board_is_beaglebonex())
+ goto done;
+
+ for (i = 0; i < MAX_CPSW_SLAVES; i++) {
+ sprintf(alias, "ethernet%d", i);
+
+ slave_path = fdt_get_alias(fdt, alias);
+ if (!slave_path)
+ continue;
+
+ slavenode = fdt_path_offset(fdt, slave_path);
+ if (slavenode < 0)
+ continue;
+
+ enetnode = fdt_parent_offset(fdt, slavenode);
+ enet_name = fdt_get_name(fdt, enetnode, NULL);
+
+ ethdev = eth_get_dev_by_name(enet_name);
+ if (!ethdev)
+ continue;
+
+ phy_addr = cpsw_get_slave_phy_addr(ethdev, i);
+
+ /* check for phy_id as well as phy-handle properties */
+ ret = fdtdec_get_int_array_count(fdt, slavenode, "phy_id",
+ phy_id, 2);
+ if (ret == 2) {
+ if (phy_id[1] != phy_addr) {
+ printf("fixing up phy_id for %s, old: %d, new: %d\n",
+ alias, phy_id[1], phy_addr);
+
+ phy_id[0] = cpu_to_fdt32(phy_id[0]);
+ phy_id[1] = cpu_to_fdt32(phy_addr);
+ do_fixup_by_path(fdt, slave_path, "phy_id",
+ phy_id, sizeof(phy_id), 0);
+ }
+ } else {
+ phynode = fdtdec_lookup_phandle(fdt, slavenode,
+ "phy-handle");
+ if (phynode < 0)
+ continue;
+
+ ret = fdtdec_get_int(fdt, phynode, "reg", -ENOENT);
+ if (ret < 0)
+ continue;
+
+ if (ret != phy_addr) {
+ printf("fixing up phy-handle for %s, old: %d, new: %d\n",
+ alias, ret, phy_addr);
+
+ fdt_setprop_u32(fdt, phynode, "reg",
+ cpu_to_fdt32(phy_addr));
+ }
+ }
+ }
+
+done:
+ return 0;
+}
+#endif
+
/*
* Basic board specific setup. Pinmux has been handled already.
*/
#endif
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
-#if defined(CONFIG_NOR) || defined(CONFIG_NAND)
+#if defined(CONFIG_NOR) || defined(CONFIG_MTD_RAW_NAND)
gpmc_init();
#endif
-#if !defined(CONFIG_SPL_BUILD) || \
- (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
+#if defined(CONFIG_CLOCK_SYNTHESIZER) && (!defined(CONFIG_SPL_BUILD) || \
+ (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD)))
if (board_is_icev2()) {
int rv;
u32 reg;
#ifdef CONFIG_BOARD_LATE_INIT
int board_late_init(void)
{
+ struct udevice *dev;
#if !defined(CONFIG_SPL_BUILD)
uint8_t mac_addr[6];
uint32_t mac_hi, mac_lo;
if (board_is_bbg1())
name = "BBG1";
+ if (board_is_bben())
+ name = "BBEN";
set_board_info_env(name);
/*
env_set("serial#", board_serial);
}
+ /* Just probe the potentially supported cdce913 device */
+ uclass_get_device(UCLASS_CLK, 0, &dev);
+
return 0;
}
#endif
-#ifndef CONFIG_DM_ETH
-
-#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
- (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
-static void cpsw_control(int enabled)
-{
- /* VTP can be added here */
-
- return;
-}
-
-static struct cpsw_slave_data cpsw_slaves[] = {
+/* CPSW platdata */
+#if !CONFIG_IS_ENABLED(OF_CONTROL)
+struct cpsw_slave_data slave_data[] = {
{
- .slave_reg_ofs = 0x208,
- .sliver_reg_ofs = 0xd80,
- .phy_addr = 0,
+ .slave_reg_ofs = CPSW_SLAVE0_OFFSET,
+ .sliver_reg_ofs = CPSW_SLIVER0_OFFSET,
+ .phy_addr = 0,
},
{
- .slave_reg_ofs = 0x308,
- .sliver_reg_ofs = 0xdc0,
- .phy_addr = 1,
+ .slave_reg_ofs = CPSW_SLAVE1_OFFSET,
+ .sliver_reg_ofs = CPSW_SLIVER1_OFFSET,
+ .phy_addr = 1,
},
};
-static struct cpsw_platform_data cpsw_data = {
- .mdio_base = CPSW_MDIO_BASE,
+struct cpsw_platform_data am335_eth_data = {
.cpsw_base = CPSW_BASE,
- .mdio_div = 0xff,
+ .version = CPSW_CTRL_VERSION_2,
+ .bd_ram_ofs = CPSW_BD_OFFSET,
+ .ale_reg_ofs = CPSW_ALE_OFFSET,
+ .cpdma_reg_ofs = CPSW_CPDMA_OFFSET,
+ .mdio_div = CPSW_MDIO_DIV,
+ .host_port_reg_ofs = CPSW_HOST_PORT_OFFSET,
.channels = 8,
- .cpdma_reg_ofs = 0x800,
- .slaves = 1,
- .slave_data = cpsw_slaves,
- .ale_reg_ofs = 0xd00,
+ .slaves = 2,
+ .slave_data = slave_data,
.ale_entries = 1024,
- .host_port_reg_ofs = 0x108,
- .hw_stats_reg_ofs = 0x900,
.bd_ram_ofs = 0x2000,
- .mac_control = (1 << 5),
- .control = cpsw_control,
- .host_port_num = 0,
- .version = CPSW_CTRL_VERSION_2,
+ .mac_control = 0x20,
+ .active_slave = 0,
+ .mdio_base = 0x4a101000,
+ .gmii_sel = 0x44e10650,
+ .phy_sel_compat = "ti,am3352-cpsw-phy-sel",
+ .syscon_addr = 0x44e10630,
+ .macid_sel_compat = "cpsw,am33xx",
};
-#endif
-#if ((defined(CONFIG_SPL_ETH_SUPPORT) || defined(CONFIG_SPL_USB_ETHER)) &&\
- defined(CONFIG_SPL_BUILD)) || \
- ((defined(CONFIG_DRIVER_TI_CPSW) || \
- defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET)) && \
- !defined(CONFIG_SPL_BUILD))
-
-/*
- * This function will:
- * Read the eFuse for MAC addresses, and set ethaddr/eth1addr/usbnet_devaddr
- * in the environment
- * Perform fixups to the PHY present on certain boards. We only need this
- * function in:
- * - SPL with either CPSW or USB ethernet support
- * - Full U-Boot, with either CPSW or USB ethernet
- * Build in only these cases to avoid warnings about unused variables
- * when we build an SPL that has neither option but full U-Boot will.
- */
-int board_eth_init(bd_t *bis)
-{
- int rv, n = 0;
-#if defined(CONFIG_USB_ETHER) && \
- (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_USB_ETHER))
- uint8_t mac_addr[6];
- uint32_t mac_hi, mac_lo;
-
- /*
- * use efuse mac address for USB ethernet as we know that
- * both CPSW and USB ethernet will never be active at the same time
- */
- mac_lo = readl(&cdev->macid0l);
- mac_hi = readl(&cdev->macid0h);
- mac_addr[0] = mac_hi & 0xFF;
- mac_addr[1] = (mac_hi & 0xFF00) >> 8;
- mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
- mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
- mac_addr[4] = mac_lo & 0xFF;
- mac_addr[5] = (mac_lo & 0xFF00) >> 8;
-#endif
-
-
-#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
- (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
-
-#ifdef CONFIG_DRIVER_TI_CPSW
- if (board_is_bone() || board_is_bone_lt() ||
- board_is_idk()) {
- writel(MII_MODE_ENABLE, &cdev->miisel);
- cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if =
- PHY_INTERFACE_MODE_MII;
- } else if (board_is_icev2()) {
- writel(RMII_MODE_ENABLE | RMII_CHIPCKL_ENABLE, &cdev->miisel);
- cpsw_slaves[0].phy_if = PHY_INTERFACE_MODE_RMII;
- cpsw_slaves[1].phy_if = PHY_INTERFACE_MODE_RMII;
- cpsw_slaves[0].phy_addr = 1;
- cpsw_slaves[1].phy_addr = 3;
- } else {
- writel((RGMII_MODE_ENABLE | RGMII_INT_DELAY), &cdev->miisel);
- cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if =
- PHY_INTERFACE_MODE_RGMII;
- }
-
- rv = cpsw_register(&cpsw_data);
- if (rv < 0)
- printf("Error %d registering CPSW switch\n", rv);
- else
- n += rv;
-#endif
+struct eth_pdata cpsw_pdata = {
+ .iobase = 0x4a100000,
+ .phy_interface = 0,
+ .priv_pdata = &am335_eth_data,
+};
- /*
- *
- * CPSW RGMII Internal Delay Mode is not supported in all PVT
- * operating points. So we must set the TX clock delay feature
- * in the AR8051 PHY. Since we only support a single ethernet
- * device in U-Boot, we only do this for the first instance.
- */
-#define AR8051_PHY_DEBUG_ADDR_REG 0x1d
-#define AR8051_PHY_DEBUG_DATA_REG 0x1e
-#define AR8051_DEBUG_RGMII_CLK_DLY_REG 0x5
-#define AR8051_RGMII_TX_CLK_DLY 0x100
-
- if (board_is_evm_sk() || board_is_gp_evm()) {
- const char *devname;
- devname = miiphy_get_current_dev();
-
- miiphy_write(devname, 0x0, AR8051_PHY_DEBUG_ADDR_REG,
- AR8051_DEBUG_RGMII_CLK_DLY_REG);
- miiphy_write(devname, 0x0, AR8051_PHY_DEBUG_DATA_REG,
- AR8051_RGMII_TX_CLK_DLY);
- }
-#endif
-#if defined(CONFIG_USB_ETHER) && \
- (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_USB_ETHER))
- if (is_valid_ethaddr(mac_addr))
- eth_env_set_enetaddr("usbnet_devaddr", mac_addr);
-
- rv = usb_eth_initialize(bis);
- if (rv < 0)
- printf("Error %d registering USB_ETHER\n", rv);
- else
- n += rv;
-#endif
- return n;
-}
+U_BOOT_DEVICE(am335x_eth) = {
+ .name = "eth_cpsw",
+ .platdata = &cpsw_pdata,
+};
#endif
-#endif /* CONFIG_DM_ETH */
-
#ifdef CONFIG_SPL_LOAD_FIT
int board_fit_config_name_match(const char *name)
{
return 0;
else if (board_is_bone_lt() && !strcmp(name, "am335x-boneblack"))
return 0;
+ else if (board_is_pb() && !strcmp(name, "am335x-pocketbeagle"))
+ return 0;
else if (board_is_evm_sk() && !strcmp(name, "am335x-evmsk"))
return 0;
else if (board_is_bbg1() && !strcmp(name, "am335x-bonegreen"))