diff --git a/src/cpu/samsung/exynos5-common/Makefile.inc b/src/cpu/samsung/exynos5-common/Makefile.inc index 6911b70765..6331863440 100644 --- a/src/cpu/samsung/exynos5-common/Makefile.inc +++ b/src/cpu/samsung/exynos5-common/Makefile.inc @@ -21,3 +21,4 @@ ramstage-y += gpio.c ramstage-y += i2c.c ramstage-y += s5p-dp-reg.c ramstage-y += exynos-fb.c +ramstage-y += exynos-tmu.c diff --git a/src/cpu/samsung/exynos5-common/exynos-tmu.c b/src/cpu/samsung/exynos5-common/exynos-tmu.c index f908076a85..26777fca23 100644 --- a/src/cpu/samsung/exynos5-common/exynos-tmu.c +++ b/src/cpu/samsung/exynos5-common/exynos-tmu.c @@ -2,11 +2,12 @@ * Copyright (c) 2012 Samsung Electronics Co., Ltd. * http://www.samsung.com * Akshay Saraswat + * Copyright (c) 2013 Google Inc. * * EXYNOS - Thermal Management Unit * - * See file CREDITS for list of people who contributed to this - * project. + * This file was originally imported from Das U-Boot and then re-factored + * for coreboot. * * 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 @@ -17,11 +18,11 @@ * MA 02111-1307 USA */ -#include -#include -#include -#include -#include +#include +#include +#include + +#include #define TRIMINFO_RELOAD 1 #define CORE_EN 1 @@ -46,55 +47,6 @@ INTCLEAR_RISE2 | INTCLEAR_FALL0 | \ INTCLEAR_FALL1 | INTCLEAR_FALL2) -/* Tmeperature threshold values for various thermal events */ -struct temperature_params { - /* minimum value in temperature code range */ - unsigned int min_val; - /* maximum value in temperature code range */ - unsigned int max_val; - /* temperature threshold to start warning */ - unsigned int start_warning; - /* temperature threshold CPU tripping */ - unsigned int start_tripping; - /* temperature threshold for HW tripping */ - unsigned int hardware_tripping; -}; - -/* Pre-defined values and thresholds for calibration of current temperature */ -struct tmu_data { - /* pre-defined temperature thresholds */ - struct temperature_params ts; - /* pre-defined efuse range minimum value */ - unsigned int efuse_min_value; - /* pre-defined efuse value for temperature calibration */ - unsigned int efuse_value; - /* pre-defined efuse range maximum value */ - unsigned int efuse_max_value; - /* current temperature sensing slope */ - unsigned int slope; -}; - -/* TMU device specific details and status */ -struct tmu_info { - /* base Address for the TMU */ - unsigned tmu_base; - /* mux Address for the TMU */ - int tmu_mux; - /* pre-defined values for calibration and thresholds */ - struct tmu_data data; - /* value required for triminfo_25 calibration */ - unsigned int te1; - /* value required for triminfo_85 calibration */ - unsigned int te2; - /* TMU DC value for threshold calculation */ - int dc_value; - /* enum value indicating status of the TMU */ - int tmu_state; -}; - -/* Global struct tmu_info variable to store init values */ -static struct tmu_info gbl_info; - /* * After reading temperature code from register, compensating * its value and calculating celsius temperatue, @@ -102,7 +54,7 @@ static struct tmu_info gbl_info; * * @return current temperature of the chip as sensed by TMU */ -int get_cur_temp(struct tmu_info *info) +static int get_cur_temp(struct tmu_info *info) { int cur_temp; struct tmu_reg *reg = (struct tmu_reg *)info->tmu_base; @@ -120,19 +72,20 @@ int get_cur_temp(struct tmu_info *info) /* * Monitors status of the TMU device and exynos temperature * - * @param temp pointer to the current temperature value + * @info TMU info + * @temp pointer to the current temperature value * @return enum tmu_status_t value, code indicating event to execute */ -enum tmu_status_t tmu_monitor(int *temp) +enum tmu_status_t tmu_monitor(struct tmu_info *info, int *temp) { - if (gbl_info.tmu_state == TMU_STATUS_INIT) + if (info->tmu_state == TMU_STATUS_INIT) return -1; int cur_temp; - struct tmu_data *data = &gbl_info.data; + struct tmu_data *data = &info->data; /* Read current temperature of the SOC */ - cur_temp = get_cur_temp(&gbl_info); + cur_temp = get_cur_temp(info); *temp = cur_temp; /* Temperature code lies between min 25 and max 125 */ @@ -146,93 +99,20 @@ enum tmu_status_t tmu_monitor(int *temp) return TMU_STATUS_NORMAL; /* Temperature code does not lie between min 25 and max 125 */ else { - gbl_info.tmu_state = TMU_STATUS_INIT; - debug("EXYNOS_TMU: Thermal reading failed\n"); + info->tmu_state = TMU_STATUS_INIT; + printk(BIOS_DEBUG, "EXYNOS_TMU: Thermal reading failed\n"); return -1; } return 0; } -/* - * Get TMU specific pre-defined values from FDT - * - * @param info pointer to the tmu_info struct - * @param blob FDT blob - * @return int value, 0 for success - */ -int get_tmu_fdt_values(struct tmu_info *info, const void *blob) -{ - int node; - int error = 0; - - /* Get the node from FDT for TMU */ - node = fdtdec_next_compatible(blob, 0, - COMPAT_SAMSUNG_EXYNOS_TMU); - if (node < 0) { - debug("EXYNOS_TMU: No node for tmu in device tree\n"); - return -1; - } - - /* - * Get the pre-defined TMU specific values from FDT. - * All of these are expected to be correct otherwise - * miscalculation of register values in tmu_setup_parameters - * may result in misleading current temperature. - */ - info->tmu_base = fdtdec_get_addr(blob, node, "reg"); - if (info->tmu_base == FDT_ADDR_T_NONE) { - debug("%s: Missing tmu-base\n", __func__); - return -1; - } - info->tmu_mux = fdtdec_get_int(blob, - node, "samsung,mux", -1); - error |= info->tmu_mux; - info->data.ts.min_val = fdtdec_get_int(blob, - node, "samsung,min-temp", -1); - error |= info->data.ts.min_val; - info->data.ts.max_val = fdtdec_get_int(blob, - node, "samsung,max-temp", -1); - error |= info->data.ts.max_val; - info->data.ts.start_warning = fdtdec_get_int(blob, - node, "samsung,start-warning", -1); - error |= info->data.ts.start_warning; - info->data.ts.start_tripping = fdtdec_get_int(blob, - node, "samsung,start-tripping", -1); - error |= info->data.ts.start_tripping; - info->data.ts.hardware_tripping = fdtdec_get_int(blob, - node, "samsung,hw-tripping", -1); - error |= info->data.ts.hardware_tripping; - info->data.efuse_min_value = fdtdec_get_int(blob, - node, "samsung,efuse-min-value", -1); - error |= info->data.efuse_min_value; - info->data.efuse_value = fdtdec_get_int(blob, - node, "samsung,efuse-value", -1); - error |= info->data.efuse_value; - info->data.efuse_max_value = fdtdec_get_int(blob, - node, "samsung,efuse-max-value", -1); - error |= info->data.efuse_max_value; - info->data.slope = fdtdec_get_int(blob, - node, "samsung,slope", -1); - error |= info->data.slope; - info->dc_value = fdtdec_get_int(blob, - node, "samsung,dc-value", -1); - error |= info->dc_value; - - if (error == -1) { - debug("fail to get tmu node properties\n"); - return -1; - } - - return 0; -} - /* * Calibrate and calculate threshold values and * enable interrupt levels * * @param info pointer to the tmu_info struct */ -void tmu_setup_parameters(struct tmu_info *info) +static void tmu_setup_parameters(struct tmu_info *info) { unsigned int te_temp, con; unsigned int warning_code, trip_code, hwtrip_code; @@ -302,17 +182,14 @@ void tmu_setup_parameters(struct tmu_info *info) /* * Initialize TMU device * - * @param blob FDT blob * @return int value, 0 for success */ -int tmu_init(const void *blob) +int tmu_init(struct tmu_info *info) { - gbl_info.tmu_state = TMU_STATUS_INIT; - if (get_tmu_fdt_values(&gbl_info, blob) < 0) - return -1; + info->tmu_state = TMU_STATUS_INIT; - tmu_setup_parameters(&gbl_info); - gbl_info.tmu_state = TMU_STATUS_NORMAL; + tmu_setup_parameters(info); + info->tmu_state = TMU_STATUS_NORMAL; return 0; } diff --git a/src/cpu/samsung/exynos5-common/exynos-tmu.h b/src/cpu/samsung/exynos5-common/exynos-tmu.h new file mode 100644 index 0000000000..40eda5626e --- /dev/null +++ b/src/cpu/samsung/exynos5-common/exynos-tmu.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * Akshay Saraswat + * + * 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 __EXYNOS_TMU_H +#define __EXYNOS_TMU_H + +struct 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; +}; + +enum tmu_status_t { + TMU_STATUS_INIT = 0, + TMU_STATUS_NORMAL, + TMU_STATUS_WARNING, + TMU_STATUS_TRIPPED, +}; + +/* Tmeperature threshold values for various thermal events */ +struct temperature_params { + /* minimum value in temperature code range */ + unsigned int min_val; + /* maximum value in temperature code range */ + unsigned int max_val; + /* temperature threshold to start warning */ + unsigned int start_warning; + /* temperature threshold CPU tripping */ + unsigned int start_tripping; + /* temperature threshold for HW tripping */ + unsigned int hardware_tripping; +}; + +/* Pre-defined values and thresholds for calibration of current temperature */ +struct tmu_data { + /* pre-defined temperature thresholds */ + struct temperature_params ts; + /* pre-defined efuse range minimum value */ + unsigned int efuse_min_value; + /* pre-defined efuse value for temperature calibration */ + unsigned int efuse_value; + /* pre-defined efuse range maximum value */ + unsigned int efuse_max_value; + /* current temperature sensing slope */ + unsigned int slope; +}; + +/* TMU device specific details and status */ +struct tmu_info { + /* base Address for the TMU */ + unsigned tmu_base; + /* mux Address for the TMU */ + int tmu_mux; + /* pre-defined values for calibration and thresholds */ + struct tmu_data data; + /* value required for triminfo_25 calibration */ + unsigned int te1; + /* value required for triminfo_85 calibration */ + unsigned int te2; + /* TMU DC value for threshold calculation */ + int dc_value; + /* enum value indicating status of the TMU */ + int tmu_state; +}; + +extern struct tmu_info *tmu_info; + +/* + * Monitors status of the TMU device and exynos temperature + * + * @info pointer to TMU info struct + * @temp pointer to the current temperature value + * @return enum tmu_status_t value, code indicating event to execute + * and -1 on error + */ +enum tmu_status_t tmu_monitor(struct tmu_info *info, int *temp); + +/* + * Initialize TMU device + * + * @info pointer to TMU info struct + * @return int value, 0 for success + */ +int tmu_init(struct tmu_info *info); + +#endif /* EXYNOS_TMU_H */ diff --git a/src/cpu/samsung/exynos5250/Makefile.inc b/src/cpu/samsung/exynos5250/Makefile.inc index 1046b8bc0b..8788a6c88e 100644 --- a/src/cpu/samsung/exynos5250/Makefile.inc +++ b/src/cpu/samsung/exynos5250/Makefile.inc @@ -28,6 +28,7 @@ ramstage-y += power.c ramstage-y += soc.c ramstage-$(CONFIG_CONSOLE_SERIAL_UART) += uart.c ramstage-y += cpu.c +ramstage-y += exynos5250-tmu.c ramstage-y += mct.c #ramstage-$(CONFIG_SATA_AHCI) += sata.c diff --git a/src/cpu/samsung/exynos5250/cpu.h b/src/cpu/samsung/exynos5250/cpu.h index a356e19990..cff966ee98 100644 --- a/src/cpu/samsung/exynos5250/cpu.h +++ b/src/cpu/samsung/exynos5250/cpu.h @@ -120,4 +120,6 @@ enum periph_id exynos5_get_periph_id(unsigned base_addr); void exynos5250_config_l2_cache(void); +extern struct tmu_info exynos5250_tmu_info; + #endif /* _EXYNOS5250_CPU_H */ diff --git a/src/cpu/samsung/exynos5250/exynos-tmu.h b/src/cpu/samsung/exynos5250/exynos-tmu.h deleted file mode 100644 index ad9e394456..0000000000 --- a/src/cpu/samsung/exynos5250/exynos-tmu.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * Akshay Saraswat - * - * 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_THERMAL_H -#define __ASM_ARCH_THERMAL_H - -struct 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; -}; - -enum tmu_status_t { - TMU_STATUS_INIT = 0, - TMU_STATUS_NORMAL, - TMU_STATUS_WARNING, - TMU_STATUS_TRIPPED, -}; - -/* - * Monitors status of the TMU device and exynos temperature - * - * @param temp pointer to the current temperature value - * @return enum tmu_status_t value, code indicating event to execute - * and -1 on error - */ -enum tmu_status_t tmu_monitor(int *temp); - -/* - * Initialize TMU device - * - * @param blob FDT blob - * @return int value, 0 for success - */ -int tmu_init(const void *blob); -#endif diff --git a/src/cpu/samsung/exynos5250/exynos5250-tmu.c b/src/cpu/samsung/exynos5250/exynos5250-tmu.c new file mode 100644 index 0000000000..7d8397c568 --- /dev/null +++ b/src/cpu/samsung/exynos5250/exynos5250-tmu.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2013 Google Inc. + * + * 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 as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 + * + * This file contains Exynos5250-specific TMU information. + */ + +#include +#include + +struct tmu_info exynos5250_tmu_info = { + .tmu_base = 0x10060000, + .tmu_mux = 6, + .data = { + .ts = { + .min_val = 25, + .max_val = 125, + .start_warning = 95, + .start_tripping = 105, + .hardware_tripping = 110, + }, + .efuse_min_value = 40, + .efuse_value = 55, + .efuse_max_value = 100, + .slope = 0x10008802, + }, + .dc_value = 25, +};