From patchwork Tue Nov 14 09:05:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shilpasri G Bhat X-Patchwork-Id: 837752 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3ybhSv2WYNz9s9Y for ; Tue, 14 Nov 2017 20:06:23 +1100 (AEDT) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3ybhSv16l3zDr0X for ; Tue, 14 Nov 2017 20:06:23 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=linux.vnet.ibm.com (client-ip=148.163.158.5; helo=mx0a-001b2d01.pphosted.com; envelope-from=shilpa.bhat@linux.vnet.ibm.com; receiver=) Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3ybhSm1k44zDr2L for ; Tue, 14 Nov 2017 20:06:15 +1100 (AEDT) Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id vAE94FMk094465 for ; Tue, 14 Nov 2017 04:06:13 -0500 Received: from e06smtp11.uk.ibm.com (e06smtp11.uk.ibm.com [195.75.94.107]) by mx0b-001b2d01.pphosted.com with ESMTP id 2e7vjm34m3-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 14 Nov 2017 04:06:13 -0500 Received: from localhost by e06smtp11.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 14 Nov 2017 09:06:11 -0000 Received: from b06cxnps4074.portsmouth.uk.ibm.com (9.149.109.196) by e06smtp11.uk.ibm.com (192.168.101.141) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 14 Nov 2017 09:06:10 -0000 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps4074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id vAE969t644237046; Tue, 14 Nov 2017 09:06:09 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4B9F111C04A; Tue, 14 Nov 2017 09:00:59 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id BBFEC11C05B; Tue, 14 Nov 2017 09:00:58 +0000 (GMT) Received: from oc4502181600.in.ibm.com (unknown [9.124.35.159]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Tue, 14 Nov 2017 09:00:58 +0000 (GMT) From: Shilpasri G Bhat To: skiboot@lists.ozlabs.org Date: Tue, 14 Nov 2017 14:35:44 +0530 X-Mailer: git-send-email 1.8.3.1 X-TM-AS-GCONF: 00 x-cbid: 17111409-0040-0000-0000-0000040E08BF X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17111409-0041-0000-0000-000020B0BAFC Message-Id: <1510650344-7232-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-11-14_05:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1711140123 Subject: [Skiboot] [PATCH] sensors: occ: Support reading u64 sensor values X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.24 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This patch adds new OPAL call to read sensor values of type u64. It also exports energy sensors in device-tree. Signed-off-by: Shilpasri G Bhat --- core/sensor.c | 14 ++++ hw/occ-sensor.c | 210 ++++++++++++++++++++++++++++++++++++++--------------- include/opal-api.h | 3 +- include/skiboot.h | 2 +- 4 files changed, 169 insertions(+), 60 deletions(-) diff --git a/core/sensor.c b/core/sensor.c index 57b21bc..4eeed20 100644 --- a/core/sensor.c +++ b/core/sensor.c @@ -41,6 +41,19 @@ static int64_t opal_sensor_read(uint32_t sensor_hndl, int token, return OPAL_UNSUPPORTED; } +static int64_t opal_sensor_read_long(u32 sensor_hndl, int token __unused, + u64 *sensor_data) +{ + switch (sensor_get_family(sensor_hndl)) { + case SENSOR_OCC: + return occ_sensor_read(sensor_hndl, sensor_data); + default: + break; + } + + return OPAL_UNSUPPORTED; +} + static int opal_sensor_group_clear(u32 group_hndl, int token) { switch (sensor_get_family(group_hndl)) { @@ -63,4 +76,5 @@ void sensor_init(void) /* Register OPAL interface */ opal_register(OPAL_SENSOR_READ, opal_sensor_read, 3); opal_register(OPAL_SENSOR_GROUP_CLEAR, opal_sensor_group_clear, 2); + opal_register(OPAL_SENSOR_READ64, opal_sensor_read_long, 3); } diff --git a/hw/occ-sensor.c b/hw/occ-sensor.c index 1042c11..4ed0e6a 100644 --- a/hw/occ-sensor.c +++ b/hw/occ-sensor.c @@ -261,6 +261,7 @@ enum sensor_attr { SENSOR_SAMPLE_MAX, SENSOR_CSM_MIN, /* CSM's min/max */ SENSOR_CSM_MAX, + SENSOR_ACCUMULATOR, MAX_SENSOR_ATTR, }; @@ -317,22 +318,48 @@ static inline u32 sensor_handler(int occ_num, int sensor_id, int attr) return sensor_make_handler(SENSOR_OCC, occ_num, sensor_id, attr); } -int occ_sensor_read(u32 handle, u32 *data) +static u64 read_sensor(struct occ_sensor_record *sensor, int attr) +{ + switch (attr) { + case SENSOR_SAMPLE: + return sensor->sample; + case SENSOR_SAMPLE_MIN: + return sensor->sample_min; + case SENSOR_SAMPLE_MAX: + return sensor->sample_max; + case SENSOR_CSM_MIN: + return sensor->csm_min; + case SENSOR_CSM_MAX: + return sensor->csm_max; + case SENSOR_ACCUMULATOR: + return sensor->accumulator; + default: + break; + } + + return 0; +} + +static u64 read_counter(struct occ_sensor_counter *ctr, int attr) +{ + switch (attr) { + case SENSOR_SAMPLE: + return ctr->sample; + case SENSOR_ACCUMULATOR: + return ctr->accumulator; + default: + break; + } + + return 0; +} + +static int select_buffer_and_read(int occ_num, int id, int attr, u64 *val) { struct occ_sensor_data_header *hb; struct occ_sensor_name *md; - struct occ_sensor_record *sping, *spong; - struct occ_sensor_record *sensor = NULL; u8 *ping, *pong; - u16 id = sensor_get_rid(handle); - u8 occ_num = sensor_get_frc(handle); - u8 attr = sensor_get_attr(handle); - - if (occ_num > MAX_OCCS) - return OPAL_PARAMETER; - - if (attr > MAX_SENSOR_ATTR) - return OPAL_PARAMETER; + void *buffer; hb = get_sensor_header_block(occ_num); md = get_names_block(hb); @@ -345,8 +372,6 @@ int occ_sensor_read(u32 handle, u32 *data) ping = (u8 *)((u64)hb + hb->reading_ping_offset); pong = (u8 *)((u64)hb + hb->reading_pong_offset); - sping = (struct occ_sensor_record *)((u64)ping + md[id].reading_offset); - spong = (struct occ_sensor_record *)((u64)pong + md[id].reading_offset); /* Check which buffer is valid and read the data from that. * Ping Pong Action @@ -355,41 +380,73 @@ int occ_sensor_read(u32 handle, u32 *data) * 1 0 Read Ping * 1 1 Read the buffer with latest timestamp */ + if (*ping && *pong) { - if (sping->timestamp > spong->timestamp) - sensor = sping; + u64 tping, tpong; + + if (md[id].structure_type == OCC_SENSOR_READING_FULL) { + tping = ((struct occ_sensor_record *)((u64)ping + + md[id].reading_offset))->timestamp; + tpong = ((struct occ_sensor_record *)((u64)pong + + md[id].reading_offset))->timestamp; + } else { + tping = ((struct occ_sensor_counter *)((u64)ping + + md[id].reading_offset))->timestamp; + tpong = ((struct occ_sensor_counter *)((u64)pong + + md[id].reading_offset))->timestamp; + } + if (tping > tpong) + buffer = ping; else - sensor = spong; - + buffer = pong; } else if (*ping && !*pong) { - sensor = sping; + buffer = ping; } else if (!*ping && *pong) { - sensor = spong; + buffer = pong; } else if (!*ping && !*pong) { prlog(PR_DEBUG, "OCC: Both ping and pong sensor buffers are invalid\n"); return OPAL_HARDWARE; } - switch (attr) { - case SENSOR_SAMPLE: - *data = sensor->sample; - break; - case SENSOR_SAMPLE_MIN: - *data = sensor->sample_min; - break; - case SENSOR_SAMPLE_MAX: - *data = sensor->sample_max; - break; - case SENSOR_CSM_MIN: - *data = sensor->csm_min; + buffer = (void *)((u64)buffer + md[id].reading_offset); + + switch (md[id].structure_type) { + case OCC_SENSOR_READING_FULL: + *val = read_sensor(buffer, attr); break; - case SENSOR_CSM_MAX: - *data = sensor->csm_max; + case OCC_SENSOR_READING_COUNTER: + *val = read_counter(buffer, attr); break; default: - *data = 0; + return OPAL_UNSUPPORTED; } + return 0; +} + +int occ_sensor_read(u32 handle, void *data) +{ + u64 val; + u16 id = sensor_get_rid(handle); + u8 occ_num = sensor_get_frc(handle); + u8 attr = sensor_get_attr(handle); + int rc; + + if (occ_num > MAX_OCCS) + return OPAL_PARAMETER; + + if (attr > MAX_SENSOR_ATTR) + return OPAL_PARAMETER; + + rc = select_buffer_and_read(occ_num, id, attr, &val); + if (rc) + return rc; + + if (attr == SENSOR_ACCUMULATOR) + *(u64 *)data = val; + else + *(u32 *)data = val; + return OPAL_SUCCESS; } @@ -543,6 +600,41 @@ static const char *get_sensor_loc_string(enum occ_sensor_location loc) return "unknown"; } +static void add_sensor_node(const char *loc, const char *type, int i, int attr, + struct occ_sensor_name *md, u32 *phandle, u32 pir, + u32 occ_num, u32 chipid) +{ + char name[30]; + struct dt_node *node; + u32 handler; + + snprintf(name, sizeof(name), "%s-%s", loc, type); + handler = sensor_handler(occ_num, i, attr); + node = dt_new_addr(sensor_node, name, handler); + dt_add_property_string(node, "sensor-type", type); + dt_add_property_cells(node, "sensor-data", handler); + dt_add_property_string(node, "occ_label", md->name); + add_sensor_label(node, md, chipid); + + if (md->location == OCC_SENSOR_LOC_CORE) + dt_add_property_cells(node, "ibm,pir", pir); + + if (attr == SENSOR_SAMPLE) { + dt_add_property_string(node, "compatible", "ibm,opal-sensor"); + + handler = sensor_handler(occ_num, i, SENSOR_CSM_MAX); + dt_add_property_cells(node, "sensor-data-max", handler); + + handler = sensor_handler(occ_num, i, SENSOR_CSM_MIN); + dt_add_property_cells(node, "sensor-data-min", handler); + } else if (attr == SENSOR_ACCUMULATOR) { + dt_add_property_string(node, "compatible", + "ibm,opal-sensor-counter"); + } + + *phandle = node->phandle; +} + void occ_sensors_init(void) { struct proc_chip *chip; @@ -585,11 +677,9 @@ void occ_sensors_init(void) assert(phandles); for (i = 0; i < hb->nr_sensors; i++) { - char name[30]; const char *type, *loc; - struct dt_node *node; struct cpu_thread *c = NULL; - u32 handler; + int attr; if (!(md[i].type & HWMON_SENSORS_MASK)) continue; @@ -606,28 +696,32 @@ void occ_sensors_init(void) type = get_sensor_type_string(md[i].type); loc = get_sensor_loc_string(md[i].location); - snprintf(name, sizeof(name), "%s-%s", loc, type); - - handler = sensor_handler(occ_num, i, SENSOR_SAMPLE); - node = dt_new_addr(sensor_node, name, handler); - - dt_add_property_string(node, "sensor-type", type); - dt_add_property_cells(node, "sensor-data", handler); - - handler = sensor_handler(occ_num, i, SENSOR_CSM_MAX); - dt_add_property_cells(node, "sensor-data-max", handler); - handler = sensor_handler(occ_num, i, SENSOR_CSM_MIN); - dt_add_property_cells(node, "sensor-data-min", handler); - - dt_add_property_string(node, "compatible", - "ibm,opal-sensor"); - dt_add_property_string(node, "occ_label", md[i].name); - add_sensor_label(node, &md[i], chip->id); + switch (md[i].structure_type) { + case OCC_SENSOR_READING_FULL: + attr = SENSOR_SAMPLE; + break; + case OCC_SENSOR_READING_COUNTER: + attr = SENSOR_ACCUMULATOR; + break; + default: + continue; + } - if (md[i].location == OCC_SENSOR_LOC_CORE) - dt_add_property_cells(node, "ibm,pir", c->pir); - phandles[phcount++] = node->phandle; + add_sensor_node(loc, type, i, attr, &md[i], + &phandles[phcount], c->pir, occ_num, + chip->id); + phcount++; + + /* Add energy sensors */ + if (md[i].type == OCC_SENSOR_TYPE_POWER && + md[i].structure_type == OCC_SENSOR_READING_FULL) { + add_sensor_node(loc, "energy", i, + SENSOR_ACCUMULATOR, &md[i], + &phandles[phcount], c->pir, + occ_num, chip->id); + phcount++; + } } occ_num++; occ_add_sensor_groups(sg, phandles, phcount, chip->id); diff --git a/include/opal-api.h b/include/opal-api.h index 0bc036e..3f3dbff 100644 --- a/include/opal-api.h +++ b/include/opal-api.h @@ -214,7 +214,8 @@ #define OPAL_SET_POWER_SHIFT_RATIO 155 #define OPAL_SENSOR_GROUP_CLEAR 156 #define OPAL_PCI_SET_P2P 157 -#define OPAL_LAST 157 +#define OPAL_SENSOR_READ64 158 +#define OPAL_LAST 158 /* Device tree flags */ diff --git a/include/skiboot.h b/include/skiboot.h index db91325..893d673 100644 --- a/include/skiboot.h +++ b/include/skiboot.h @@ -328,7 +328,7 @@ extern int fake_nvram_write(uint32_t offset, void *src, uint32_t size); /* OCC Inband Sensors */ extern void occ_sensors_init(void); -extern int occ_sensor_read(u32 handle, u32 *data); +extern int occ_sensor_read(u32 handle, void *data); extern int occ_sensor_group_clear(u32 group_hndl, int token); extern void occ_add_sensor_groups(struct dt_node *sg, u32 *phandles, int nr_phandles, int chipid);