diff options
author | Cédric Le Goater <clg@fr.ibm.com> | 2015-03-09 21:56:19 +0100 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-03-24 18:22:55 +1100 |
commit | 3c0627cb13b40f76a2339c021ed7581fa6293fdf (patch) | |
tree | a8e94d08540dccd77fa8d0450de3e492e17343b9 | |
parent | a5413878280a0cccd58d76802beffcce95f15c89 (diff) | |
download | skiboot-3c0627cb13b40f76a2339c021ed7581fa6293fdf.zip skiboot-3c0627cb13b40f76a2339c021ed7581fa6293fdf.tar.gz skiboot-3c0627cb13b40f76a2339c021ed7581fa6293fdf.tar.bz2 |
dts: add memory buffers temperature sensors
The memory buffer chips (Centaur) have DTS very similar to the
ones we find on the cores.
Only available on open power machines for the moment.
Signed-off-by: Cédric Le Goater <clg@fr.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r-- | doc/device-tree/ibm,opal/sensors.txt | 26 | ||||
-rw-r--r-- | hw/dts.c | 96 |
2 files changed, 122 insertions, 0 deletions
diff --git a/doc/device-tree/ibm,opal/sensors.txt b/doc/device-tree/ibm,opal/sensors.txt index 81aeff8..80a6d81 100644 --- a/doc/device-tree/ibm,opal/sensors.txt +++ b/doc/device-tree/ibm,opal/sensors.txt @@ -64,4 +64,30 @@ ibm,opal/sensors/ { ibm,pir = <0x20>; label = "Core"; }; + + /* + * Centaur temperatures (DTS) nodes. Open Power only. + * + * We use the PIR of the core as a resource identifier. + */ + mem-temp@1 { + compatible = "ibm,opal-sensor"; + name = "mem-temp"; + sensor-type = "temp"; + + /* Status bits : + * + * 0x0003 FATAL + * 0x0002 CRITICAL + * 0x0001 WARNING + */ + sensor-data = <0x00810001>; + + /* + * These are extra properties to help Linux output. + */ + ibm,chip-id = <0x80000001>; + label = "Centaur"; + }; + }; @@ -30,6 +30,14 @@ #define EX_THERM_CONTROL_REG 0x10050012 #define EX_THERM_ERR_STATUS_REG 0x10050013 +/* Per memory controller Digital Thermal Sensors */ +#define THERM_MEM_DTS_RESULT0 0x2050000 + +/* Per memory controller Digital Thermal Sensors control registers */ +#define THERM_MEM_MODE_REG 0x205000F +#define THERM_MEM_CONTROL_REG 0x2050012 +#define THERM_MEM_ERR_STATUS_REG 0x2050013 + struct dts { uint8_t valid; uint8_t trip; @@ -123,12 +131,58 @@ static int dts_read_core_temp(uint32_t pir, struct dts *dts) return 0; } + +/* Different sensor locations */ +#define P8_MEM_DTS0 0 +#define P8_MEM_DTS1 1 +#define P8_MEM_ZONES 2 + +static int dts_read_mem_temp(uint32_t chip_id, struct dts *dts) +{ + uint64_t dts0; + struct dts temps[P8_MEM_ZONES]; + int i; + int rc; + + rc = xscom_read(chip_id, THERM_MEM_DTS_RESULT0, &dts0); + if (rc) + return rc; + + dts_decode_one_dts(dts0 >> 48, &temps[P8_MEM_DTS0]); + dts_decode_one_dts(dts0 >> 32, &temps[P8_MEM_DTS1]); + + for (i = 0; i < P8_MEM_ZONES; i++) { + int16_t t = temps[i].temp; + + if (!temps[i].valid) + continue; + + /* keep the max temperature of all 4 sensors */ + if (t > dts->temp) + dts->temp = t; + + dts->valid++; + dts->trip |= temps[i].trip; + } + + prlog(PR_TRACE, "DTS: Chip %x temp:%dC trip:%x\n", + chip_id, dts->temp, dts->trip); + + /* + * FIXME: The trip bits are always set ?! Just discard + * them for the moment until we understand why. + */ + dts->trip = 0; + return 0; +} + /* * DTS sensor class ids. Only one for the moment: the core * temperature. */ enum sensor_dts_class { SENSOR_DTS_CORE_TEMP, + SENSOR_DTS_MEM_TEMP, /* To be continued */ }; @@ -156,6 +210,14 @@ int64_t dts_sensor_read(uint32_t sensor_hndl, uint32_t *sensor_data) case SENSOR_DTS_CORE_TEMP: rc = dts_read_core_temp(rid, &dts); break; + case SENSOR_DTS_MEM_TEMP: + /* + * restore centaur chip id which was truncated to fit + * in the sensor handler + */ + rid |= 0x80000000; + rc = dts_read_mem_temp(rid, &dts); + break; default: rc = OPAL_PARAMETER; break; @@ -176,6 +238,7 @@ bool dts_sensor_create_nodes(struct dt_node *sensors) uint8_t sensor_class = SENSOR_DTS_CORE_TEMP|SENSOR_DTS; struct proc_chip *chip; + struct dt_node *cn; char name[64]; /* build the device tree nodes : @@ -209,5 +272,38 @@ bool dts_sensor_create_nodes(struct dt_node *sensors) } } + sensor_class = SENSOR_DTS_MEM_TEMP|SENSOR_DTS; + + /* + * sensors/mem-temp@chip for Centaurs + */ + dt_for_each_compatible(dt_root, cn, "ibm,centaur") { + uint32_t chip_id; + struct dt_node *node; + uint32_t handler; + + chip_id = dt_prop_get_u32(cn, "ibm,chip-id"); + + snprintf(name, sizeof(name), "mem-temp@%x", chip_id); + + /* + * We only have two bytes for the resource + * identifier. Let's trunctate the centaur chip id + */ + handler = sensor_make_handler(sensor_class, + chip_id & 0xffff, SENSOR_DTS_ATTR_TEMP_MAX); + node = dt_new(sensors, name); + dt_add_property_string(node, "compatible", + "ibm,opal-sensor"); + dt_add_property_cells(node, "sensor-data", handler); + + handler = sensor_make_handler(sensor_class, + chip_id, SENSOR_DTS_ATTR_TEMP_TRIP); + dt_add_property_cells(node, "sensor-status", handler); + dt_add_property_string(node, "sensor-type", "temp"); + dt_add_property_cells(node, "ibm,chip-id", chip_id); + dt_add_property_string(node, "label", "Centaur"); + } + return true; } |