Commit 412665b4 authored by Albert ARIBAUD's avatar Albert ARIBAUD
Browse files

Merge branch 'u-boot-samsung/master' into 'u-boot-arm/master'

parents b6379e15 ce0c1bc1
......@@ -914,6 +914,10 @@ Matt Sealey <matt@genesi-usa.com>
Bo Shen <voice.shen@atmel.com>
at91sam9x5ek ARM926EJS (AT91SAM9G15,G25,G35,X25,X35 SoC)
Rajeshwari Shinde <rajeshwari.s@samsung.com>
snow ARM ARMV7 (EXYNOS5250 SoC)
Michal Simek <monstr@monstr.eu>
zynq ARM ARMV7 (Zynq SoC)
......
......@@ -95,3 +95,48 @@ void set_dp_phy_ctrl(unsigned int enable)
if (cpu_is_exynos5())
exynos5_dp_phy_control(enable);
}
static void exynos5_set_ps_hold_ctrl(void)
{
struct exynos5_power *power =
(struct exynos5_power *)samsung_get_base_power();
/* Set PS-Hold high */
setbits_le32(&power->ps_hold_control,
EXYNOS_PS_HOLD_CONTROL_DATA_HIGH);
}
void set_ps_hold_ctrl(void)
{
if (cpu_is_exynos5())
exynos5_set_ps_hold_ctrl();
}
static void exynos5_set_xclkout(void)
{
struct exynos5_power *power =
(struct exynos5_power *)samsung_get_base_power();
/* use xxti for xclk out */
clrsetbits_le32(&power->pmu_debug, PMU_DEBUG_CLKOUT_SEL_MASK,
PMU_DEBUG_XXTI);
}
void set_xclkout(void)
{
if (cpu_is_exynos5())
exynos5_set_xclkout();
}
/* Enables hardware tripping to power off the system when TMU fails */
void set_hw_thermal_trip(void)
{
if (cpu_is_exynos5()) {
struct exynos5_power *power =
(struct exynos5_power *)samsung_get_base_power();
/* PS_HOLD_CONTROL register ENABLE_HW_TRIP bit*/
setbits_le32(&power->ps_hold_control, POWER_ENABLE_HW_TRIP);
}
}
......@@ -151,4 +151,9 @@
};
};
tmu@10060000 {
compatible = "samsung,exynos-tmu";
reg = <0x10060000 0x10000>;
};
};
......@@ -857,6 +857,9 @@ void set_mipi_phy_ctrl(unsigned int dev_index, unsigned int enable);
void set_usbhost_phy_ctrl(unsigned int enable);
/* Enables hardware tripping to power off the system when TMU fails */
void set_hw_thermal_trip(void);
#define POWER_USB_HOST_PHY_CTRL_EN (1 << 0)
#define POWER_USB_HOST_PHY_CTRL_DISABLE (0 << 0)
......@@ -864,4 +867,25 @@ void set_dp_phy_ctrl(unsigned int enable);
#define EXYNOS_DP_PHY_ENABLE (1 << 0)
#define EXYNOS_PS_HOLD_CONTROL_DATA_HIGH (1 << 8)
#define POWER_ENABLE_HW_TRIP (1UL << 31)
/*
* Set ps_hold data driving value high
* This enables the machine to stay powered on
* after the initial power-on condition goes away
* (e.g. power button).
*/
void set_ps_hold_ctrl(void);
/* PMU_DEBUG bits [12:8] = 0x1000 selects XXTI clock source */
#define PMU_DEBUG_XXTI 0x1000
/* Mask bit[12:8] for xxti clock selection */
#define PMU_DEBUG_CLKOUT_SEL_MASK 0x1f00
/*
* Pmu debug is used for xclkout, enable xclkout with
* source as XXTI
*/
void set_xclkout(void);
#endif
......@@ -78,11 +78,12 @@ struct spl_machine_param {
*/
u32 uboot_size;
enum boot_mode boot_source; /* Boot device */
enum mem_manuf mem_manuf; /* Memory Manufacturer */
unsigned frequency_mhz; /* Frequency of memory in MHz */
unsigned arm_freq_mhz; /* ARM Frequency in MHz */
u32 serial_base; /* Serial base address */
u32 i2c_base; /* i2c base address */
u32 board_rev_gpios; /* Board revision GPIOs */
enum mem_manuf mem_manuf; /* Memory Manufacturer */
} __attribute__((__packed__));
#endif
......
/*
* Copyright (c) 2012 Samsung Electronics Co., Ltd.
* http://www.samsung.com
* Akshay Saraswat <akshay.s@samsung.com>
*
* EXYNOS - Thermal Management Unit
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef __ASM_ARCH_TMU_H
#define __ASM_ARCH_TMU_H
struct exynos5_tmu_reg {
unsigned triminfo;
unsigned rsvd1;
unsigned rsvd2;
unsigned rsvd3;
unsigned rsvd4;
unsigned triminfo_control;
unsigned rsvd5;
unsigned rsvd6;
unsigned tmu_control;
unsigned rsvd7;
unsigned tmu_status;
unsigned sampling_internal;
unsigned counter_value0;
unsigned counter_value1;
unsigned rsvd8;
unsigned rsvd9;
unsigned current_temp;
unsigned rsvd10;
unsigned rsvd11;
unsigned rsvd12;
unsigned threshold_temp_rise;
unsigned threshold_temp_fall;
unsigned rsvd13;
unsigned rsvd14;
unsigned past_temp3_0;
unsigned past_temp7_4;
unsigned past_temp11_8;
unsigned past_temp15_12;
unsigned inten;
unsigned intstat;
unsigned intclear;
unsigned rsvd15;
unsigned emul_con;
};
#endif /* __ASM_ARCH_TMU_H */
......@@ -66,4 +66,17 @@
compatible = "maxim,max77686_pmic";
};
};
tmu@10060000 {
samsung,min-temp = <25>;
samsung,max-temp = <125>;
samsung,start-warning = <95>;
samsung,start-tripping = <105>;
samsung,hw-tripping = <110>;
samsung,efuse-min-value = <40>;
samsung,efuse-value = <55>;
samsung,efuse-max-value = <100>;
samsung,slope = <274761730>;
samsung,dc-value = <25>;
};
};
/*
* SAMSUNG Snow board device tree source
*
* Copyright (c) 2012 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/dts-v1/;
/include/ ARCH_CPU_DTS
/ {
model = "Google Snow";
compatible = "google,snow", "samsung,exynos5250";
aliases {
i2c0 = "/i2c@12c60000";
i2c1 = "/i2c@12c70000";
i2c2 = "/i2c@12c80000";
i2c3 = "/i2c@12c90000";
i2c4 = "/i2c@12ca0000";
i2c5 = "/i2c@12cb0000";
i2c6 = "/i2c@12cc0000";
i2c7 = "/i2c@12cd0000";
spi0 = "/spi@12d20000";
spi1 = "/spi@12d30000";
spi2 = "/spi@12d40000";
spi3 = "/spi@131a0000";
spi4 = "/spi@131b0000";
};
sound@12d60000 {
samsung,i2s-epll-clock-frequency = <192000000>;
samsung,i2s-sampling-rate = <48000>;
samsung,i2s-bits-per-sample = <16>;
samsung,i2s-channels = <2>;
samsung,i2s-lr-clk-framesize = <256>;
samsung,i2s-bit-clk-framesize = <32>;
samsung,codec-type = "max98095";
};
i2c@12cd0000 {
soundcodec@22 {
reg = <0x22>;
compatible = "maxim,max98095-codec";
};
};
i2c@12c60000 {
pmic@9 {
reg = <0x9>;
compatible = "maxim,max77686_pmic";
};
};
};
......@@ -23,6 +23,7 @@
#include <common.h>
#include <fdtdec.h>
#include <asm/io.h>
#include <errno.h>
#include <i2c.h>
#include <lcd.h>
#include <netdev.h>
......@@ -35,9 +36,40 @@
#include <asm/arch/sromc.h>
#include <asm/arch/dp_info.h>
#include <power/pmic.h>
#include <power/max77686_pmic.h>
#include <tmu.h>
DECLARE_GLOBAL_DATA_PTR;
#if defined CONFIG_EXYNOS_TMU
/*
* Boot Time Thermal Analysis for SoC temperature threshold breach
*/
static void boot_temp_check(void)
{
int temp;
switch (tmu_monitor(&temp)) {
/* Status TRIPPED ans WARNING means corresponding threshold breach */
case TMU_STATUS_TRIPPED:
puts("EXYNOS_TMU: TRIPPING! Device power going down ...\n");
set_ps_hold_ctrl();
hang();
break;
case TMU_STATUS_WARNING:
puts("EXYNOS_TMU: WARNING! Temperature very high\n");
break;
/*
* TMU_STATUS_INIT means something is wrong with temperature sensing
* and TMU status was changed back from NORMAL to INIT.
*/
case TMU_STATUS_INIT:
default:
debug("EXYNOS_TMU: Unknown TMU state\n");
}
}
#endif
#ifdef CONFIG_USB_EHCI_EXYNOS
int board_usb_vbus_init(void)
{
......@@ -54,14 +86,38 @@ int board_usb_vbus_init(void)
}
#endif
#ifdef CONFIG_SOUND_MAX98095
static void board_enable_audio_codec(void)
{
struct exynos5_gpio_part1 *gpio1 = (struct exynos5_gpio_part1 *)
samsung_get_base_gpio_part1();
/* Enable MAX98095 Codec */
s5p_gpio_direction_output(&gpio1->x1, 7, 1);
s5p_gpio_set_pull(&gpio1->x1, 7, GPIO_PULL_NONE);
}
#endif
int board_init(void)
{
gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);
#if defined CONFIG_EXYNOS_TMU
if (tmu_init(gd->fdt_blob) != TMU_STATUS_NORMAL) {
debug("%s: Failed to init TMU\n", __func__);
return -1;
}
boot_temp_check();
#endif
#ifdef CONFIG_EXYNOS_SPI
spi_init();
#endif
#ifdef CONFIG_USB_EHCI_EXYNOS
board_usb_vbus_init();
#endif
#ifdef CONFIG_SOUND_MAX98095
board_enable_audio_codec();
#endif
return 0;
}
......@@ -80,12 +136,119 @@ int dram_init(void)
}
#if defined(CONFIG_POWER)
static int pmic_reg_update(struct pmic *p, int reg, uint regval)
{
u32 val;
int ret = 0;
ret = pmic_reg_read(p, reg, &val);
if (ret) {
debug("%s: PMIC %d register read failed\n", __func__, reg);
return -1;
}
val |= regval;
ret = pmic_reg_write(p, reg, val);
if (ret) {
debug("%s: PMIC %d register write failed\n", __func__, reg);
return -1;
}
return 0;
}
int power_init_board(void)
{
struct pmic *p;
set_ps_hold_ctrl();
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
if (pmic_init(I2C_PMIC))
return -1;
else
return 0;
p = pmic_get("MAX77686_PMIC");
if (!p)
return -ENODEV;
if (pmic_probe(p))
return -1;
if (pmic_reg_update(p, MAX77686_REG_PMIC_32KHZ, MAX77686_32KHCP_EN))
return -1;
if (pmic_reg_update(p, MAX77686_REG_PMIC_BBAT,
MAX77686_BBCHOSTEN | MAX77686_BBCVS_3_5V))
return -1;
/* VDD_MIF */
if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK1OUT,
MAX77686_BUCK1OUT_1V)) {
debug("%s: PMIC %d register write failed\n", __func__,
MAX77686_REG_PMIC_BUCK1OUT);
return -1;
}
if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK1CRTL,
MAX77686_BUCK1CTRL_EN))
return -1;
/* VDD_ARM */
if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK2DVS1,
MAX77686_BUCK2DVS1_1_3V)) {
debug("%s: PMIC %d register write failed\n", __func__,
MAX77686_REG_PMIC_BUCK2DVS1);
return -1;
}
if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK2CTRL1,
MAX77686_BUCK2CTRL_ON))
return -1;
/* VDD_INT */
if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK3DVS1,
MAX77686_BUCK3DVS1_1_0125V)) {
debug("%s: PMIC %d register write failed\n", __func__,
MAX77686_REG_PMIC_BUCK3DVS1);
return -1;
}
if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK3CTRL,
MAX77686_BUCK3CTRL_ON))
return -1;
/* VDD_G3D */
if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK4DVS1,
MAX77686_BUCK4DVS1_1_2V)) {
debug("%s: PMIC %d register write failed\n", __func__,
MAX77686_REG_PMIC_BUCK4DVS1);
return -1;
}
if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK4CTRL1,
MAX77686_BUCK3CTRL_ON))
return -1;
/* VDD_LDO2 */
if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO2CTRL1,
MAX77686_LD02CTRL1_1_5V | EN_LDO))
return -1;
/* VDD_LDO3 */
if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO3CTRL1,
MAX77686_LD03CTRL1_1_8V | EN_LDO))
return -1;
/* VDD_LDO5 */
if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO5CTRL1,
MAX77686_LD05CTRL1_1_8V | EN_LDO))
return -1;
/* VDD_LDO10 */
if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO10CTRL1,
MAX77686_LD10CTRL1_1_8V | EN_LDO))
return -1;
return 0;
}
#endif
......@@ -212,8 +375,17 @@ int board_eth_init(bd_t *bis)
#ifdef CONFIG_DISPLAY_BOARDINFO
int checkboard(void)
{
printf("\nBoard: SMDK5250\n");
#ifdef CONFIG_OF_CONTROL
const char *board_name;
board_name = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
if (board_name == NULL)
printf("\nUnknown Board\n");
else
printf("\nBoard: %s\n", board_name);
#else
printf("\nBoard: SMDK5250\n");
#endif
return 0;
}
#endif
......
......@@ -298,6 +298,7 @@ s5p_goni arm armv7 goni samsung
smdkc100 arm armv7 smdkc100 samsung s5pc1xx
origen arm armv7 origen samsung exynos
s5pc210_universal arm armv7 universal_c210 samsung exynos
snow arm armv7 smdk5250 samsung exynos
smdk5250 arm armv7 smdk5250 samsung exynos
smdkv310 arm armv7 smdkv310 samsung exynos
trats arm armv7 trats samsung exynos
......
......@@ -27,7 +27,9 @@
#include <dtt.h>
#include <i2c.h>
#include <tmu.h>
#if defined CONFIG_DTT_SENSORS
static unsigned long sensor_initialized;
static void _initialize_dtt(void)
......@@ -59,9 +61,11 @@ void dtt_init(void)
/* switch back to original I2C bus */
I2C_SET_BUS(old_bus);
}
#endif
int do_dtt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
int dtt_i2c(void)
{
#if defined CONFIG_DTT_SENSORS
int i;
unsigned char sensors[] = CONFIG_DTT_SENSORS;
int old_bus;
......@@ -83,8 +87,34 @@ int do_dtt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
/* switch back to original I2C bus */
I2C_SET_BUS(old_bus);
#endif
return 0;
}
int dtt_tmu(void)
{
#if defined CONFIG_TMU_CMD_DTT
int cur_temp;
/* Sense and return latest thermal info */
if (tmu_monitor(&cur_temp) == TMU_STATUS_INIT) {
puts("TMU is in unknown state, temperature is invalid\n");
return -1;
}
printf("Current temperature: %u degrees Celsius\n", cur_temp);
#endif
return 0;
}
int do_dtt(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
int err = 0;
err |= dtt_i2c();
err |= dtt_tmu();
return err;
} /* do_dtt() */
/***************************************************/
......
Exynos Thermal management Unit
Required properties:
- compatible : Should be "samsung,exynos-tmu" for TMU
- samsung,min-temp : Minimum temperature value (25 degree celsius)
- Current temperature of SoC should be more than this value.
- samsung,max-temp : Maximum temperature value (125 degree celsius)
- Current temperature of SoC should be less than this value.
- samsung,start-warning : Temperature at which TMU starts giving warning (degree celsius)
- samsung,start-tripping : Temperature at which TMU shuts down the system (degree celsius)
- samsung,hw-tripping : Temperature at which hardware tripping should happen
in case TMU fails to power off (degree celsius)
- samsung,efuse-min-value : SOC efuse min value (Constant 40)
- efuse-value should be more than this value.
- samsung,efuse-value : SOC actual efuse value (Literal value)
- This is the data trimming info.
- This value is used to calculate measuring error.
- samsung,efuse-max-value : SoC max efuse value (Constant 100)
- efuse-value should be less than this value.
- samsung,slope : Default value 274761730 (Constant 0x1060_8802).
- This is the default value for TMU_CONTROL register.
- It sets the gain of amplifier to the positive-tc generator block.
- It selects thermal tripping mode and enables thermal tripping.
- samsung,dc-value : Measured data calibration value (Constant 25)
- Used for tempearture calculation.
- This is 25 because temperature measured is always above 25 degrees.
Example:
tmu@10060000 {
compatible = "samsung,exynos-tmu"
samsung,min-temp = <25>;
samsung,max-temp = <125>;
samsung,start-warning = <95>;
samsung,start-tripping = <105>;
samsung,hw-tripping = <110>;
samsung,efuse-min-value = <40>;
samsung,efuse-value = <55>;
samsung,efuse-max-value = <100>;
samsung,slope = <274761730>;
samsung,dc-value = <25>;
};
......@@ -412,9 +412,11 @@ int sdhci_init(struct mmc *mmc)
status = sdhci_readl(host, SDHCI_PRESENT_STATE);
}
/* Eable all state */
sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_ENABLE);
sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_SIGNAL_ENABLE);
/* Enable only interrupts served by the SD controller */
sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK
, SDHCI_INT_ENABLE);
/* Mask all sdhci interrupt sources */
sdhci_writel(host, 0x0, SDHCI_SIGNAL_ENABLE);
return 0;
}
......
......@@ -25,6 +25,7 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libpower.o
COBJS-$(CONFIG_EXYNOS_TMU) += exynos-tmu.o