{"id":799391,"url":"http://patchwork.ozlabs.org/api/1.2/patches/799391/?format=json","web_url":"http://patchwork.ozlabs.org/project/skiboot/patch/1502217156-31878-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com/","project":{"id":44,"url":"http://patchwork.ozlabs.org/api/1.2/projects/44/?format=json","name":"skiboot firmware development","link_name":"skiboot","list_id":"skiboot.lists.ozlabs.org","list_email":"skiboot@lists.ozlabs.org","web_url":"http://github.com/open-power/skiboot","scm_url":"http://github.com/open-power/skiboot","webscm_url":"","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<1502217156-31878-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com>","list_archive_url":null,"date":"2017-08-08T18:32:36","name":"sensors: dts: Assert special wakeup on idle cores while reading temperature","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"33a54bd72c7824df5400eff531f63b1d6d0e8f8c","submitter":{"id":64639,"url":"http://patchwork.ozlabs.org/api/1.2/people/64639/?format=json","name":"Shilpasri G Bhat","email":"shilpa.bhat@linux.vnet.ibm.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/skiboot/patch/1502217156-31878-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com/mbox/","series":[],"comments":"http://patchwork.ozlabs.org/api/patches/799391/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/799391/checks/","tags":{},"related":[],"headers":{"Return-Path":"<skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org>","X-Original-To":["incoming@patchwork.ozlabs.org","skiboot@lists.ozlabs.org"],"Delivered-To":["patchwork-incoming@bilbo.ozlabs.org","skiboot@lists.ozlabs.org"],"Received":["from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68])\n\t(using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xRjh43VzJz9s7g\n\tfor <incoming@patchwork.ozlabs.org>;\n\tWed,  9 Aug 2017 04:33:08 +1000 (AEST)","from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 3xRjh40JsqzDqsT\n\tfor <incoming@patchwork.ozlabs.org>;\n\tWed,  9 Aug 2017 04:33:08 +1000 (AEST)","from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com\n\t[148.163.156.1])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 3xRjgn6DkczDqpt\n\tfor <skiboot@lists.ozlabs.org>; Wed,  9 Aug 2017 04:32:53 +1000 (AEST)","from pps.filterd (m0098394.ppops.net [127.0.0.1])\n\tby mx0a-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id\n\tv78IWbjj133132\n\tfor <skiboot@lists.ozlabs.org>; Tue, 8 Aug 2017 14:32:50 -0400","from e23smtp04.au.ibm.com (e23smtp04.au.ibm.com [202.81.31.146])\n\tby mx0a-001b2d01.pphosted.com with ESMTP id 2c7j5t1t33-1\n\t(version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT)\n\tfor <skiboot@lists.ozlabs.org>; Tue, 08 Aug 2017 14:32:50 -0400","from localhost\n\tby e23smtp04.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use\n\tOnly! Violators will be prosecuted\n\tfor <skiboot@lists.ozlabs.org> from <shilpa.bhat@linux.vnet.ibm.com>; \n\tWed, 9 Aug 2017 04:32:47 +1000","from d23relay09.au.ibm.com (202.81.31.228)\n\tby e23smtp04.au.ibm.com (202.81.31.210) with IBM ESMTP SMTP Gateway:\n\tAuthorized Use Only! Violators will be prosecuted; \n\tWed, 9 Aug 2017 04:32:45 +1000","from d23av01.au.ibm.com (d23av01.au.ibm.com [9.190.234.96])\n\tby d23relay09.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id\n\tv78IWiFG33620006\n\tfor <skiboot@lists.ozlabs.org>; Wed, 9 Aug 2017 04:32:44 +1000","from d23av01.au.ibm.com (localhost [127.0.0.1])\n\tby d23av01.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id\n\tv78IWil8002281\n\tfor <skiboot@lists.ozlabs.org>; Wed, 9 Aug 2017 04:32:44 +1000","from oc4502181600.ibm.com ([9.79.205.212])\n\tby d23av01.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id\n\tv78IWeaI002241; Wed, 9 Aug 2017 04:32:41 +1000"],"From":"Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>","To":"skiboot@lists.ozlabs.org","Date":"Wed,  9 Aug 2017 00:02:36 +0530","X-Mailer":"git-send-email 1.8.3.1","X-TM-AS-MML":"disable","x-cbid":"17080818-0012-0000-0000-00000258C83A","X-IBM-AV-DETECTION":"SAVI=unused REMOTE=unused XFE=unused","x-cbparentid":"17080818-0013-0000-0000-00000773DAC0","Message-Id":"<1502217156-31878-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com>","X-Proofpoint-Virus-Version":"vendor=fsecure engine=2.50.10432:, ,\n\tdefinitions=2017-08-08_09:, , signatures=0","X-Proofpoint-Spam-Details":"rule=outbound_notspam policy=outbound score=0\n\tspamscore=0 suspectscore=1\n\tmalwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam\n\tadjust=0 reason=mlx scancount=1 engine=8.0.1-1706020000\n\tdefinitions=main-1708080302","Subject":"[Skiboot] [PATCH] sensors: dts: Assert special wakeup on idle cores\n\twhile reading temperature","X-BeenThere":"skiboot@lists.ozlabs.org","X-Mailman-Version":"2.1.23","Precedence":"list","List-Id":"Mailing list for skiboot development <skiboot.lists.ozlabs.org>","List-Unsubscribe":"<https://lists.ozlabs.org/options/skiboot>,\n\t<mailto:skiboot-request@lists.ozlabs.org?subject=unsubscribe>","List-Archive":"<http://lists.ozlabs.org/pipermail/skiboot/>","List-Post":"<mailto:skiboot@lists.ozlabs.org>","List-Help":"<mailto:skiboot-request@lists.ozlabs.org?subject=help>","List-Subscribe":"<https://lists.ozlabs.org/listinfo/skiboot>,\n\t<mailto:skiboot-request@lists.ozlabs.org?subject=subscribe>","Cc":"ego@linux.vnet.ibm.com","MIME-Version":"1.0","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"base64","Errors-To":"skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org","Sender":"\"Skiboot\"\n\t<skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org>"},"content":"In P9, when a core enters a stop state, its clocks will be stopped\nto save power and hence we will not be able to perform a scom\noperation to read the DTS temperature sensor.  Hence, assert\na special wakeup on cores that have entered a stop state in order to\nsuccessfully complete the scom operation.\n\nSigned-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>\n---\nTODO:\n- Make the dts_read_core_temp_p9() call async\n\n core/hostservices.c    | 79 +++++++++++++++++++++++++++++++-------------------\n hw/dts.c               | 32 ++++++++++++++++++--\n hw/slw.c               | 20 +++++++++++++\n include/hostservices.h |  4 +++\n include/skiboot.h      |  3 ++\n include/xscom.h        | 12 ++++++++\n 6 files changed, 118 insertions(+), 32 deletions(-)","diff":"diff --git a/core/hostservices.c b/core/hostservices.c\nindex d1f6fda..345c8c0 100644\n--- a/core/hostservices.c\n+++ b/core/hostservices.c\n@@ -545,9 +545,10 @@ static void hservice_nanosleep(uint64_t i_seconds, uint64_t i_nano_seconds)\n \tnanosleep_nopoll(&ts, NULL);\n }\n \n-static int hservice_set_special_wakeup(struct cpu_thread *cpu)\n+int hservice_set_special_wakeup(struct cpu_thread *cpu)\n {\n \tuint64_t val, core_id, poll_target, stamp;\n+\tu64 wkup_addr, wkup_mask, pm_reg, idle_hist_reg;\n \tint rc;\n \n \t/*\n@@ -558,20 +559,36 @@ static int hservice_set_special_wakeup(struct cpu_thread *cpu)\n \t/* Grab core ID once */\n \tcore_id = pir_to_core_id(cpu->pir);\n \n+\tswitch (proc_gen) {\n+\tcase proc_gen_p8:\n+\t\twkup_addr = XSCOM_ADDR_P8_EX_SLAVE(core_id,\n+\t\t\t\t\t\t   EX_PM_SPECIAL_WAKEUP_PHYP);\n+\t\twkup_mask = EX_PM_GP0_SPECIAL_WAKEUP_DONE;\n+\t\tpm_reg = XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_GP0);\n+\t\tidle_hist_reg = XSCOM_ADDR_P8_EX_SLAVE(core_id,\n+\t\t\t\t\tEX_PM_IDLE_STATE_HISTORY_PHYP);\n+\t\tbreak;\n+\tcase proc_gen_p9:\n+\t\twkup_addr = XSCOM_ADDR_P9_EC_SLAVE(core_id,\n+\t\t\t\t\t\t   EC_PPM_SPECIAL_WKUP_HYP);\n+\t\twkup_mask = EC_PPM_GPPMR_SPECIAL_WAKEUP_DONE;\n+\t\tpm_reg = XSCOM_ADDR_P9_EC_SLAVE(core_id, EC_PPM_GPPMR_SCOM);\n+\t\tidle_hist_reg = XSCOM_ADDR_P9_EC_SLAVE(core_id,\n+\t\t\t\t\t\tEC_PM_IDLE_STATE_HISTORY_PHYP);\n+\t\tbreak;\n+\tdefault:\n+\t\treturn OPAL_UNSUPPORTED;\n+\t}\n+\n \t/*\n \t * The original HWp reads the XSCOM first but ignores the result\n \t * and error, let's do the same until I know for sure that is\n \t * not necessary\n \t */\n-\txscom_read(cpu->chip_id,\n-\t\t   XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_SPECIAL_WAKEUP_PHYP),\n-\t\t   &val);\n+\txscom_read(cpu->chip_id, wkup_addr, &val);\n \n \t/* Then we write special wakeup */\n-\trc = xscom_write(cpu->chip_id,\n-\t\t\t XSCOM_ADDR_P8_EX_SLAVE(core_id,\n-\t\t\t\t\t\tEX_PM_SPECIAL_WAKEUP_PHYP),\n-\t\t\t PPC_BIT(0));\n+\trc = xscom_write(cpu->chip_id, wkup_addr, PPC_BIT(0));\n \tif (rc) {\n \t\tprerror(\"HBRT: XSCOM error %d asserting special\"\n \t\t\t\" wakeup on 0x%x\\n\", rc, cpu->pir);\n@@ -602,14 +619,13 @@ static int hservice_set_special_wakeup(struct cpu_thread *cpu)\n \tstamp = mftb();\n \tpoll_target = stamp + msecs_to_tb(200);\n \tval = 0;\n-\twhile (!(val & EX_PM_GP0_SPECIAL_WAKEUP_DONE)) {\n+\n+\twhile (!(val & wkup_mask)) {\n \t\t/* Wait 1 us */\n \t\thservice_nanosleep(0, 1000);\n \n \t\t/* Read PM state */\n-\t\trc = xscom_read(cpu->chip_id,\n-\t\t\t\tXSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_GP0),\n-\t\t\t\t&val);\n+\t\trc = xscom_read(cpu->chip_id, pm_reg, &val);\n \t\tif (rc) {\n \t\t\tprerror(\"HBRT: XSCOM error %d reading PM state on\"\n \t\t\t\t\" 0x%x\\n\", rc, cpu->pir);\n@@ -621,7 +637,7 @@ static int hservice_set_special_wakeup(struct cpu_thread *cpu)\n \t}\n \n \t/* Success ? */\n-\tif (val & EX_PM_GP0_SPECIAL_WAKEUP_DONE) {\n+\tif (val & wkup_mask) {\n \t\tuint64_t now = mftb();\n \t\tprlog(PR_TRACE, \"HBRT: Special wakeup complete after %ld us\\n\",\n \t\t      tb_to_usecs(now - stamp));\n@@ -639,23 +655,19 @@ static int hservice_set_special_wakeup(struct cpu_thread *cpu)\n \tprerror(\"HBRT: Timeout on special wakeup of 0x%0x\\n\", cpu->pir);\n \tprerror(\"HBRT:      PM0 = 0x%016llx\\n\", val);\n \tval = -1;\n-\txscom_read(cpu->chip_id,\n-\t\t   XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_SPECIAL_WAKEUP_PHYP),\n-\t\t   &val);\n+\txscom_read(cpu->chip_id, wkup_addr, &val);\n \tprerror(\"HBRT: SPC_WKUP = 0x%016llx\\n\", val);\n \tval = -1;\n-\txscom_read(cpu->chip_id,\n-\t\t   XSCOM_ADDR_P8_EX_SLAVE(core_id,\n-\t\t\t\t\t  EX_PM_IDLE_STATE_HISTORY_PHYP),\n-\t\t   &val);\n+\txscom_read(cpu->chip_id, idle_hist_reg, &val);\n \tprerror(\"HBRT:  HISTORY = 0x%016llx\\n\", val);\n \n \treturn OPAL_HARDWARE;\n }\n \n-static int hservice_clr_special_wakeup(struct cpu_thread *cpu)\n+int hservice_clr_special_wakeup(struct cpu_thread *cpu)\n {\n \tuint64_t val, core_id;\n+\tu64 addr;\n \tint rc;\n \n \t/*\n@@ -671,14 +683,23 @@ static int hservice_clr_special_wakeup(struct cpu_thread *cpu)\n \t * and error, let's do the same until I know for sure that is\n \t * not necessary\n \t */\n-\txscom_read(cpu->chip_id,\n-\t\t   XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_SPECIAL_WAKEUP_PHYP),\n-\t\t   &val);\n+\tswitch (proc_gen) {\n+\tcase proc_gen_p8:\n+\t\taddr = XSCOM_ADDR_P8_EX_SLAVE(core_id,\n+\t\t\t\t\t      EX_PM_SPECIAL_WAKEUP_PHYP);\n+\t\tbreak;\n+\tcase proc_gen_p9:\n+\t\taddr = XSCOM_ADDR_P9_EC_SLAVE(core_id,\n+\t\t\t\t\t      EC_PPM_SPECIAL_WKUP_HYP);\n+\t\tbreak;\n+\tdefault:\n+\t\treturn OPAL_UNSUPPORTED;\n+\t}\n+\n+\txscom_read(cpu->chip_id, addr, &val);\n \n \t/* Then we write special wakeup */\n-\trc = xscom_write(cpu->chip_id,\n-\t\t\t XSCOM_ADDR_P8_EX_SLAVE(core_id,\n-\t\t\t\t\t\tEX_PM_SPECIAL_WAKEUP_PHYP), 0);\n+\trc = xscom_write(cpu->chip_id, addr, 0);\n \tif (rc) {\n \t\tprerror(\"HBRT: XSCOM error %d deasserting\"\n \t\t\t\" special wakeup on 0x%x\\n\", rc, cpu->pir);\n@@ -690,9 +711,7 @@ static int hservice_clr_special_wakeup(struct cpu_thread *cpu)\n \t * \"This puts an inherent delay in the propagation of the reset\n \t * transition\"\n \t */\n-\txscom_read(cpu->chip_id,\n-\t\t   XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_SPECIAL_WAKEUP_PHYP),\n-\t\t   &val);\n+\txscom_read(cpu->chip_id, addr, &val);\n \n \treturn 0;\n }\ndiff --git a/hw/dts.c b/hw/dts.c\nindex a10df58..a19f7d3 100644\n--- a/hw/dts.c\n+++ b/hw/dts.c\n@@ -20,6 +20,7 @@\n #include <dts.h>\n #include <skiboot.h>\n #include <opal-api.h>\n+#include <hostservices.h>\n \n struct dts {\n \tuint8_t\t\tvalid;\n@@ -198,16 +199,32 @@ static int dts_read_core_temp_p8(uint32_t pir, struct dts *dts)\n  */\n static int dts_read_core_temp_p9(uint32_t pir, struct dts *dts)\n {\n+\tstruct cpu_thread *cpu = find_cpu_by_pir(pir);\n \tint32_t chip_id = pir_to_chip_id(pir);\n \tint32_t core = pir_to_core_id(pir);\n \tuint64_t dts0;\n \tstruct dts temps[P9_CORE_ZONES];\n \tint rc;\n+\tbool stopped;\n+\n+\t/* Check if CPU is idle */\n+\tstopped = check_core_stopped(pir);\n+\n+\t/* Assert special wakeup */\n+\tif (stopped) {\n+\t\trc = hservice_set_special_wakeup(cpu);\n+\t\tif (rc) {\n+\t\t\tprerror(\"Failed to set special wakeup on %d (%d)\\n\",\n+\t\t\t\tcore, rc);\n+\t\t\treturn rc;\n+\t\t}\n+\t}\n \n+\t/* Read temperature */\n \trc = xscom_read(chip_id, XSCOM_ADDR_P9_EC(core, EC_THERM_P9_DTS_RESULT0),\n \t\t\t&dts0);\n \tif (rc)\n-\t\treturn rc;\n+\t\tgoto clr;\n \n \tdts_decode_one_dts(dts0 >> 48, &temps[P9_CORE_DTS0]);\n \tdts_decode_one_dts(dts0 >> 32, &temps[P9_CORE_DTS1]);\n@@ -222,7 +239,18 @@ static int dts_read_core_temp_p9(uint32_t pir, struct dts *dts)\n \t * them for the moment until we understand why.\n \t */\n \tdts->trip = 0;\n-\treturn 0;\n+clr:\n+\t/* Release special wakeup */\n+\tif (stopped) {\n+\t\trc = hservice_clr_special_wakeup(cpu);\n+\t\tif (rc) {\n+\t\t\tprerror(\"Failed to clear special wakeup on %d (%d)\\n\",\n+\t\t\t\tcore, rc);\n+\t\t\treturn rc;\n+\t\t}\n+\t}\n+\n+\treturn rc;\n }\n \n static int dts_read_core_temp(uint32_t pir, struct dts *dts)\ndiff --git a/hw/slw.c b/hw/slw.c\nindex c0ab9de..32fc6d4 100644\n--- a/hw/slw.c\n+++ b/hw/slw.c\n@@ -1521,3 +1521,23 @@ void slw_init(void)\n \t\t\tslw_init_chip_p9(chip);\n \t}\n }\n+\n+bool check_core_stopped(u32 pir)\n+{\n+\tu64 val;\n+\tu32 chip_id = pir_to_chip_id(pir);\n+\tu32 core = pir_to_core_id(pir);\n+\tint rc;\n+\n+\trc = xscom_read(chip_id, XSCOM_ADDR_P9_EX(core, EX_PM_SISR), &val);\n+\tif (rc) {\n+\t\tprerror(\"Failed to read Stop Interface Status Register %d\\n\",\n+\t\t\trc);\n+\t\treturn true;\n+\t}\n+\n+\tif (pir & 0x4)\n+\t\treturn (!(val & EX_PM_SISR_INST_C1));\n+\telse\n+\t\treturn (!(val & EX_PM_SISR_INST_C0));\n+}\ndiff --git a/include/hostservices.h b/include/hostservices.h\nindex d6bb3e3..82303b8 100644\n--- a/include/hostservices.h\n+++ b/include/hostservices.h\n@@ -17,6 +17,8 @@\n #ifndef __HOSTSERVICES_H\n #define __HOSTSERVICES_H\n \n+#include <cpu.h>\n+\n bool hservices_init(void);\n void hservices_lid_preload(void);\n bool hservices_lid_preload_complete(void);\n@@ -39,4 +41,6 @@ void host_services_occ_base_setup(void);\n int find_master_and_slave_occ(uint64_t **master, uint64_t **slave,\n \t\t\t      int *nr_masters, int *nr_slaves);\n \n+int hservice_clr_special_wakeup(struct cpu_thread *cpu);\n+int hservice_set_special_wakeup(struct cpu_thread *cpu);\n #endif /* __HOSTSERVICES_H */\ndiff --git a/include/skiboot.h b/include/skiboot.h\nindex 4b7d519..c1e2aa3 100644\n--- a/include/skiboot.h\n+++ b/include/skiboot.h\n@@ -317,4 +317,7 @@ extern int occ_sensor_group_clear(u32 group_hndl, int token);\n extern void occ_add_sensor_groups(struct dt_node *sg, u32  *phandles,\n \t\t\t\t  int nr_phandles, int chipid);\n \n+/* Check if a core has entered a stop state */\n+bool check_core_stopped(u32 pir);\n+\n #endif /* __SKIBOOT_H */\ndiff --git a/include/xscom.h b/include/xscom.h\nindex 5a5d0b9..da72dd5 100644\n--- a/include/xscom.h\n+++ b/include/xscom.h\n@@ -148,6 +148,18 @@\n #define EC_PPM_SPECIAL_WKUP_FSP\t\t0x010B\n #define EC_PPM_SPECIAL_WKUP_OCC\t\t0x010C\n #define EC_PPM_SPECIAL_WKUP_HYP\t\t0x010D\n+#define EC_PM_IDLE_STATE_HISTORY_PHYP\t0x0114\n+#define EC_PPM_GPPMR_SCOM\t\t0x0100\n+#define EC_PPM_GPPMR_SCOM1\t\t0x0101\n+#define EC_PPM_GPPMR_SCOM2\t\t0x0102\n+\n+#define EC_PPM_GPPMR_SPECIAL_WAKEUP_DONE\tPPC_BIT(0)\n+\n+/* P9 CME Local Stop Interface Status Register */\n+#define EX_PM_SISR\t\t\t0x1204C\n+#define EX_PM_SISR_INST_C0\t\tPPC_BIT(46)\n+#define EX_PM_SISR_INST_C1\t\tPPC_BIT(47)\n+\n \n /************* XXXX Move these P8 only registers elswhere !!! ****************/\n \n","prefixes":[]}