summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/cpu/armv7/am33xx/sys_info.c57
-rw-r--r--arch/arm/include/asm/arch-am33xx/clocks_am33xx.h10
-rw-r--r--arch/arm/include/asm/arch-am33xx/sys_proto.h3
-rw-r--r--board/ti/am335x/board.c134
-rw-r--r--include/configs/am335x_evm.h5
5 files changed, 208 insertions, 1 deletions
diff --git a/arch/arm/cpu/armv7/am33xx/sys_info.c b/arch/arm/cpu/armv7/am33xx/sys_info.c
index 63afaaa328..50eb598ff2 100644
--- a/arch/arm/cpu/armv7/am33xx/sys_info.c
+++ b/arch/arm/cpu/armv7/am33xx/sys_info.c
@@ -17,6 +17,7 @@
#include <asm/arch/sys_proto.h>
#include <asm/arch/cpu.h>
#include <asm/arch/clock.h>
+#include <power/tps65910.h>
struct ctrl_stat *cstat = (struct ctrl_stat *)CTRL_BASE;
@@ -119,3 +120,59 @@ int print_cpuinfo(void)
return 0;
}
#endif /* CONFIG_DISPLAY_CPUINFO */
+
+#ifdef CONFIG_AM33XX
+int am335x_get_efuse_mpu_max_freq(struct ctrl_dev *cdev)
+{
+ int sil_rev;
+
+ sil_rev = readl(&cdev->deviceid) >> 28;
+
+ if (sil_rev == 1)
+ /* PG 2.0, efuse may not be set. */
+ return MPUPLL_M_800;
+ else if (sil_rev >= 2) {
+ /* Check what the efuse says our max speed is. */
+ int efuse_arm_mpu_max_freq;
+ efuse_arm_mpu_max_freq = readl(&cdev->efuse_sma);
+ switch ((efuse_arm_mpu_max_freq & DEVICE_ID_MASK)) {
+ case AM335X_ZCZ_1000:
+ return MPUPLL_M_1000;
+ case AM335X_ZCZ_800:
+ return MPUPLL_M_800;
+ case AM335X_ZCZ_720:
+ return MPUPLL_M_720;
+ case AM335X_ZCZ_600:
+ case AM335X_ZCE_600:
+ return MPUPLL_M_600;
+ case AM335X_ZCZ_300:
+ case AM335X_ZCE_300:
+ return MPUPLL_M_300;
+ }
+ }
+
+ /* PG 1.0 or otherwise unknown, use the PG1.0 max */
+ return MPUPLL_M_720;
+}
+
+int am335x_get_tps65910_mpu_vdd(int sil_rev, int frequency)
+{
+ /* For PG2.1 and later, we have one set of values. */
+ if (sil_rev >= 2) {
+ switch (frequency) {
+ case MPUPLL_M_1000:
+ return TPS65910_OP_REG_SEL_1_3_2_5;
+ case MPUPLL_M_800:
+ return TPS65910_OP_REG_SEL_1_2_6;
+ case MPUPLL_M_720:
+ return TPS65910_OP_REG_SEL_1_2_0;
+ case MPUPLL_M_600:
+ case MPUPLL_M_300:
+ return TPS65910_OP_REG_SEL_1_1_3;
+ }
+ }
+
+ /* Default to PG1.0/PG2.0 values. */
+ return TPS65910_OP_REG_SEL_1_1_3;
+}
+#endif
diff --git a/arch/arm/include/asm/arch-am33xx/clocks_am33xx.h b/arch/arm/include/asm/arch-am33xx/clocks_am33xx.h
index 140379fb38..aad698ddfe 100644
--- a/arch/arm/include/asm/arch-am33xx/clocks_am33xx.h
+++ b/arch/arm/include/asm/arch-am33xx/clocks_am33xx.h
@@ -11,9 +11,17 @@
#ifndef _CLOCKS_AM33XX_H_
#define _CLOCKS_AM33XX_H_
+/* MAIN PLL Fdll supported frequencies */
+#define MPUPLL_M_1000 1000
+#define MPUPLL_M_800 800
+#define MPUPLL_M_720 720
+#define MPUPLL_M_600 600
+#define MPUPLL_M_550 550
+#define MPUPLL_M_300 300
+
/* MAIN PLL Fdll = 550 MHz, by default */
#ifndef CONFIG_SYS_MPUCLK
-#define CONFIG_SYS_MPUCLK 550
+#define CONFIG_SYS_MPUCLK MPUPLL_M_550
#endif
#define UART_RESET (0x1 << 1)
diff --git a/arch/arm/include/asm/arch-am33xx/sys_proto.h b/arch/arm/include/asm/arch-am33xx/sys_proto.h
index 55f57ac9be..87b7d367b9 100644
--- a/arch/arm/include/asm/arch-am33xx/sys_proto.h
+++ b/arch/arm/include/asm/arch-am33xx/sys_proto.h
@@ -10,6 +10,7 @@
#ifndef _SYS_PROTO_H_
#define _SYS_PROTO_H_
+#include <asm/arch/cpu.h>
#define BOARD_REV_ID 0x0
@@ -43,4 +44,6 @@ u32 wait_on_value(u32, u32, void *, u32);
void enable_norboot_pin_mux(void);
#endif
void am33xx_spl_board_init(void);
+int am335x_get_efuse_mpu_max_freq(struct ctrl_dev *cdev);
+int am335x_get_tps65910_mpu_vdd(int sil_rev, int frequency);
#endif
diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c
index cc0442612f..6135f07a41 100644
--- a/board/ti/am335x/board.c
+++ b/board/ti/am335x/board.c
@@ -26,6 +26,8 @@
#include <i2c.h>
#include <miiphy.h>
#include <cpsw.h>
+#include <power/tps65217.h>
+#include <power/tps65910.h>
#include "board.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -244,6 +246,138 @@ const struct dpll_params dpll_ddr_evm_sk = {
const struct dpll_params dpll_ddr_bone_black = {
400, OSC-1, 1, -1, -1, -1, -1};
+void am33xx_spl_board_init(void)
+{
+ struct am335x_baseboard_id header;
+ struct dpll_params dpll_mpu = {0, OSC-1, 1, -1, -1, -1, -1};
+ int mpu_vdd;
+
+ if (read_eeprom(&header) < 0)
+ puts("Could not get board ID.\n");
+
+ /* Get the frequency */
+ dpll_mpu.m = am335x_get_efuse_mpu_max_freq(cdev);
+
+ if (board_is_bone(&header) || board_is_bone_lt(&header)) {
+ /* BeagleBone PMIC Code */
+ int usb_cur_lim;
+
+ /*
+ * Only perform PMIC configurations if board rev > A1
+ * on Beaglebone White
+ */
+ if (board_is_bone(&header) && !strncmp(header.version,
+ "00A1", 4))
+ return;
+
+ if (i2c_probe(TPS65217_CHIP_PM))
+ return;
+
+ /*
+ * On Beaglebone White we need to ensure we have AC power
+ * before increasing the frequency.
+ */
+ if (board_is_bone(&header)) {
+ uchar pmic_status_reg;
+ if (tps65217_reg_read(TPS65217_STATUS,
+ &pmic_status_reg))
+ return;
+ if (!(pmic_status_reg & TPS65217_PWR_SRC_AC_BITMASK)) {
+ puts("No AC power, disabling frequency switch\n");
+ return;
+ }
+ }
+
+ /*
+ * Override what we have detected since we know if we have
+ * a Beaglebone Black it supports 1GHz.
+ */
+ if (board_is_bone_lt(&header))
+ dpll_mpu.m = MPUPLL_M_1000;
+
+ /*
+ * Increase USB current limit to 1300mA or 1800mA and set
+ * the MPU voltage controller as needed.
+ */
+ if (dpll_mpu.m == MPUPLL_M_1000) {
+ usb_cur_lim = TPS65217_USB_INPUT_CUR_LIMIT_1800MA;
+ mpu_vdd = TPS65217_DCDC_VOLT_SEL_1325MV;
+ } else {
+ usb_cur_lim = TPS65217_USB_INPUT_CUR_LIMIT_1300MA;
+ mpu_vdd = TPS65217_DCDC_VOLT_SEL_1275MV;
+ }
+
+ if (tps65217_reg_write(TPS65217_PROT_LEVEL_NONE,
+ TPS65217_POWER_PATH,
+ usb_cur_lim,
+ TPS65217_USB_INPUT_CUR_LIMIT_MASK))
+ puts("tps65217_reg_write failure\n");
+
+
+ /* Set DCDC2 (MPU) voltage */
+ if (tps65217_voltage_update(TPS65217_DEFDCDC2, mpu_vdd)) {
+ puts("tps65217_voltage_update failure\n");
+ return;
+ }
+
+ /*
+ * Set LDO3, LDO4 output voltage to 3.3V for Beaglebone.
+ * Set LDO3 to 1.8V and LDO4 to 3.3V for Beaglebone Black.
+ */
+ if (board_is_bone(&header)) {
+ if (tps65217_reg_write(TPS65217_PROT_LEVEL_2,
+ TPS65217_DEFLS1,
+ TPS65217_LDO_VOLTAGE_OUT_3_3,
+ TPS65217_LDO_MASK))
+ puts("tps65217_reg_write failure\n");
+ } else {
+ if (tps65217_reg_write(TPS65217_PROT_LEVEL_2,
+ TPS65217_DEFLS1,
+ TPS65217_LDO_VOLTAGE_OUT_1_8,
+ TPS65217_LDO_MASK))
+ puts("tps65217_reg_write failure\n");
+ }
+
+ if (tps65217_reg_write(TPS65217_PROT_LEVEL_2,
+ TPS65217_DEFLS2,
+ TPS65217_LDO_VOLTAGE_OUT_3_3,
+ TPS65217_LDO_MASK))
+ puts("tps65217_reg_write failure\n");
+ } else {
+ int sil_rev;
+
+ /*
+ * The GP EVM, IDK and EVM SK use a TPS65910 PMIC. For all
+ * MPU frequencies we support we use a CORE voltage of
+ * 1.1375V. For MPU voltage we need to switch based on
+ * the frequency we are running at.
+ */
+ if (i2c_probe(TPS65910_CTRL_I2C_ADDR))
+ return;
+
+ /*
+ * Depending on MPU clock and PG we will need a different
+ * VDD to drive at that speed.
+ */
+ sil_rev = readl(&cdev->deviceid) >> 28;
+ mpu_vdd = am335x_get_tps65910_mpu_vdd(sil_rev, dpll_mpu.m);
+
+ /* Tell the TPS65910 to use i2c */
+ tps65910_set_i2c_control();
+
+ /* First update MPU voltage. */
+ if (tps65910_voltage_update(MPU, mpu_vdd))
+ return;
+
+ /* Second, update the CORE voltage. */
+ if (tps65910_voltage_update(CORE, TPS65910_OP_REG_SEL_1_1_3))
+ return;
+ }
+
+ /* Set MPU Frequency to what we detected now that voltages are set */
+ do_setup_dpll(&dpll_mpu_regs, &dpll_mpu);
+}
+
const struct dpll_params *get_dpll_ddr_params(void)
{
struct am335x_baseboard_id header;
diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
index 3de30fc280..0c3384cc4a 100644
--- a/include/configs/am335x_evm.h
+++ b/include/configs/am335x_evm.h
@@ -189,8 +189,13 @@
#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
#define CONFIG_SYS_I2C_MULTI_EEPROMS
+/* PMIC support */
+#define CONFIG_POWER_TPS65217
+#define CONFIG_POWER_TPS65910
+
/* SPL */
#ifndef CONFIG_NOR_BOOT
+#define CONFIG_SPL_POWER_SUPPORT
#define CONFIG_SPL_YMODEM_SUPPORT
/* CPSW support */
OpenPOWER on IntegriCloud