From patchwork Mon Oct 18 12:37:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frederic Barrat X-Patchwork-Id: 1542586 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=Xyzzdbfn; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org (client-ip=112.213.38.117; helo=lists.ozlabs.org; envelope-from=skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org; receiver=) Received: from lists.ozlabs.org (lists.ozlabs.org [112.213.38.117]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HXxJ33xbYz9sPf for ; Mon, 18 Oct 2021 23:38:43 +1100 (AEDT) Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4HXxJ32qTvz2yg2 for ; Mon, 18 Oct 2021 23:38:43 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=Xyzzdbfn; dkim-atps=neutral X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=linux.ibm.com (client-ip=148.163.158.5; helo=mx0b-001b2d01.pphosted.com; envelope-from=fbarrat@linux.ibm.com; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=Xyzzdbfn; dkim-atps=neutral Received: from mx0b-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 4HXxHF1Psjz2yp1 for ; Mon, 18 Oct 2021 23:38:00 +1100 (AEDT) Received: from pps.filterd (m0127361.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 19IBKa3p022776 for ; Mon, 18 Oct 2021 08:37:57 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=2rBPuMuTlV7yUtzZFdudUnay9Bi6RvV3AxTebgHfR64=; b=XyzzdbfnFiIa5fw7ftobBcMPjDbWZadgaGuWsjtC85ZhsrTA3qqGMurwavcnccYGmqYA dYNgre8u4bthu5dQetmS4PdGqNFoZquOTMg5Z+g7W+aM61XI1RVbFhnyQpSOFaKCyh2T DlwFk8BGfrtGVnSJsbbG4WOuNA0mX99B9zAhxqu3/8Lj3K2EiCRMVQbNq0fJ5iSEP2mL GmOoGasPWtFdp1mb8d+ylohykbdDwN6l0guG1gsWSktIvwkUPt72UcbtjCi4D5KJrAkR FK504YZjRiN5M67sn9TUYsZ5tvDKocqIHZDg/KBId+rMmjCZ07eLlkFivp5wgM/6bIcO og== Received: from ppma03ams.nl.ibm.com (62.31.33a9.ip4.static.sl-reverse.com [169.51.49.98]) by mx0a-001b2d01.pphosted.com with ESMTP id 3bs59b56np-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 18 Oct 2021 08:37:57 -0400 Received: from pps.filterd (ppma03ams.nl.ibm.com [127.0.0.1]) by ppma03ams.nl.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 19ICbksC022584 for ; Mon, 18 Oct 2021 12:37:55 GMT Received: from b06avi18878370.portsmouth.uk.ibm.com (b06avi18878370.portsmouth.uk.ibm.com [9.149.26.194]) by ppma03ams.nl.ibm.com with ESMTP id 3bqpc9e5s8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 18 Oct 2021 12:37:55 +0000 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06avi18878370.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 19ICW3XR64618992 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Mon, 18 Oct 2021 12:32:03 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 05E1E4C046 for ; Mon, 18 Oct 2021 12:37:53 +0000 (GMT) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E48044C059 for ; Mon, 18 Oct 2021 12:37:52 +0000 (GMT) Received: from localhost.localdomain.com (unknown [9.145.170.57]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP for ; Mon, 18 Oct 2021 12:37:52 +0000 (GMT) From: Frederic Barrat To: skiboot@lists.ozlabs.org Date: Mon, 18 Oct 2021 14:37:50 +0200 Message-Id: <20211018123751.72794-6-fbarrat@linux.ibm.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211018123751.72794-1-fbarrat@linux.ibm.com> References: <20211018123751.72794-1-fbarrat@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: Pi1P2wtUwgwZ99idFy83Hw0fcQRD0SbJ X-Proofpoint-GUID: Pi1P2wtUwgwZ99idFy83Hw0fcQRD0SbJ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.182.1,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.0.607.475 definitions=2021-10-18_05,2021-10-14_02,2020-04-07_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=999 mlxscore=0 phishscore=0 adultscore=0 clxscore=1015 priorityscore=1501 suspectscore=0 malwarescore=0 spamscore=0 bulkscore=0 lowpriorityscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2109230001 definitions=main-2110180077 Subject: [Skiboot] [PATCH 5/6] zz: Rework PCI slots definition and hotplug control X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" The ZZ platform reuses most of the P8, fsp-based system infrastructure for PCI slot definitions (firenze-pci, lxvpd). However the PCI hotplug controller hardware is different. We got lucky as the i2c bus definitions used on firenze were invalid on ZZ, so PCI hotplug control errors out nicely, as opposed to sending random i2c requests to an unsuspecting device. This patch defines an interface to the hotplug controller used on ZZ. It also provides the updated i2c information for each PCI slot. Signed-off-by: Frederic Barrat --- platforms/ibm-fsp/firenze-pci.c | 5 +- platforms/ibm-fsp/ibm-fsp.h | 1 + platforms/ibm-fsp/zz.c | 189 ++++++++++++++++++++++++++++++++ 3 files changed, 194 insertions(+), 1 deletion(-) diff --git a/platforms/ibm-fsp/firenze-pci.c b/platforms/ibm-fsp/firenze-pci.c index 5fbbc2ff..08467632 100644 --- a/platforms/ibm-fsp/firenze-pci.c +++ b/platforms/ibm-fsp/firenze-pci.c @@ -969,7 +969,10 @@ void firenze_pci_get_slot_info(struct phb *phb, struct pci_device *pd) s = lxvpd_get_slot(slot); if (s) { lxvpd_extract_info(slot, s); - firenze_pci_slot_init(slot); + if (proc_gen == proc_gen_p9) + zz_pci_slot_init(slot); + else + firenze_pci_slot_init(slot); } } diff --git a/platforms/ibm-fsp/ibm-fsp.h b/platforms/ibm-fsp/ibm-fsp.h index bb191645..b5b61b56 100644 --- a/platforms/ibm-fsp/ibm-fsp.h +++ b/platforms/ibm-fsp/ibm-fsp.h @@ -31,6 +31,7 @@ extern void firenze_pci_get_slot_info(struct phb *phb, struct pci_device *pd); extern void firenze_pci_add_loc_code(struct dt_node *np, struct pci_device *pd); +void zz_pci_slot_init(struct pci_slot *slot); /* VPD support */ void vpd_iohub_load(struct dt_node *hub_node); diff --git a/platforms/ibm-fsp/zz.c b/platforms/ibm-fsp/zz.c index 493d6030..8ce3e936 100644 --- a/platforms/ibm-fsp/zz.c +++ b/platforms/ibm-fsp/zz.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -141,6 +142,193 @@ static void add_opencapi_dt_nodes(void) } } +#define UCD_GPIO_SELECT 0xFA +#define UCD_GPIO_CONFIG 0xFB + +struct hp_controller { + struct lock lock; + struct i2c_request req; +}; + +struct hp_controller ucd; + +struct zz_pci_slot_info { + uint8_t index; + const char *label; + uint8_t slave_addr; + uint8_t enable_port; + uint8_t pgood_port; +}; + +static struct zz_pci_slot_info zz_pci_slots[] = { + /* UCD 9090-0 */ + { 0x06, "C2", 0xC8, 0, 18 }, + { 0x07, "C3", 0xC8, 4, 22 }, + { 0x08, "C4", 0xC8, 5, 15 }, + { 0x09, "C5", 0xC8, 6, 16 }, + { 0x0A, "C6", 0xC8, 7, 17 }, + /* UCD 90120A-0 */ + { 0x0B, "C7", 0xD0, 0, 18 }, + { 0x0C, "C8", 0xD0, 1, 19 }, + { 0x0D, "C9", 0xD0, 4, 20 }, + { 0x0E, "C10", 0xD0, 5, 21 }, + { 0x0F, "C11", 0xD0, 6, 24 }, + { 0x10, "C12", 0xD0, 7, 25 }, +}; + +static struct zz_pci_slot_info *zz_get_slot_info(struct lxvpd_pci_slot *s) +{ + for (int i = 0; i < ARRAY_SIZE(zz_pci_slots); i++) { + if (zz_pci_slots[i].index == s->slot_index && + !strcmp(zz_pci_slots[i].label, s->label)) { + return &zz_pci_slots[i]; + } + } + return NULL; +} + +static void hp_controller_init(struct hp_controller *hpc) +{ + init_lock(&hpc->lock); + hpc->req.offset = 0; + hpc->req.offset_bytes = 1; + hpc->req.rw_len = 1; + hpc->req.timeout = 100; + hpc->req.bus = p8_i2c_find_bus_by_port(0, 2, 1); + if (!hpc->req.bus) { + prerror("PLAT: Unable to find PCI power controller I2C bus\n"); + return; + } +} + +static int64_t __ucd_op(struct hp_controller *hpc, enum i2c_operation op, + uint32_t addr, uint8_t port, uint8_t *state) +{ + int64_t rc; + + if (!hpc->req.bus) + return OPAL_HARDWARE; + + hpc->req.op = SMBUS_WRITE; + hpc->req.dev_addr = addr >> 1; + hpc->req.offset = UCD_GPIO_SELECT; + hpc->req.rw_buf = &port; + rc = i2c_request_sync(&hpc->req); + if (rc) + return rc; + + hpc->req.op = op; + hpc->req.dev_addr = addr >> 1; + hpc->req.offset = UCD_GPIO_CONFIG; + hpc->req.rw_buf = state; + return i2c_request_sync(&hpc->req); +} + +static int64_t ucd_read(struct hp_controller *hpc, uint32_t addr, + uint8_t port, uint8_t *state) +{ + return __ucd_op(hpc, SMBUS_READ, addr, port, state); +} + +static int64_t ucd_write(struct hp_controller *hpc, uint32_t addr, + uint8_t port, uint8_t state) +{ + return __ucd_op(hpc, SMBUS_WRITE, addr, port, &state); +} + +static int64_t hp_controller_read_state(struct hp_controller *hpc, + struct zz_pci_slot_info *info, + uint8_t *val) +{ + uint8_t enable, pgood; + int64_t rc; + + lock(&hpc->lock); + + rc = ucd_read(hpc, info->slave_addr, info->pgood_port, &pgood); + if (rc) + goto unlock_err; + + rc = ucd_read(hpc, info->slave_addr, info->enable_port, &enable); + if (rc) + goto unlock_err; + + unlock(&hpc->lock); + + *val = ((enable & 0xE) == 0xE) && ((pgood & 0xE) == 0x8); + return OPAL_SUCCESS; + +unlock_err: + unlock(&hpc->lock); + prerror("PLAT: Can't read the state of PCI slot %s, rc=%lld\n", + info->label, rc); + return rc; +} + +static int64_t hp_controller_write_state(struct hp_controller *hpc, + struct zz_pci_slot_info *info, + uint8_t val) +{ + uint8_t enable; + int64_t rc; + + if (val == PCI_SLOT_POWER_ON) + enable = 0x7; + else + enable = 0x3; + + lock(&hpc->lock); + rc = ucd_write(hpc, info->slave_addr, info->enable_port, enable); + unlock(&hpc->lock); + return rc; +} + +static int64_t zz_pci_slot_get_power_state(struct pci_slot *slot, uint8_t *val) +{ + struct lxvpd_pci_slot *s = slot->data; + struct zz_pci_slot_info *info = NULL; + + info = zz_get_slot_info(s); + if (!info) + return OPAL_PARAMETER; + + return hp_controller_read_state(&ucd, info, val); +} + +static int64_t zz_pci_slot_set_power_state(struct pci_slot *slot, + uint8_t val) +{ + struct lxvpd_pci_slot *s = slot->data; + struct zz_pci_slot_info *info = NULL; + + if (val != PCI_SLOT_POWER_OFF && val != PCI_SLOT_POWER_ON) + return OPAL_PARAMETER; + + info = zz_get_slot_info(s); + if (!info) + return OPAL_PARAMETER; + + slot->power_state = val; + return hp_controller_write_state(&ucd, info, val); +} + +void zz_pci_slot_init(struct pci_slot *slot) +{ + struct lxvpd_pci_slot *s = slot->data; + struct zz_pci_slot_info *info; + + slot->ops.add_properties = lxvpd_add_slot_properties; + + info = zz_get_slot_info(s); + if (!info) + return; /* Slot doesn't support power management */ + + prlog(PR_INFO, "PLAT: PCI slot %s supports power management\n", + info->label); + slot->ops.get_power_state = zz_pci_slot_get_power_state; + slot->ops.set_power_state = zz_pci_slot_set_power_state; +} + static bool zz_probe(void) { /* FIXME: make this neater when the dust settles */ @@ -179,6 +367,7 @@ static void zz_init(void) { ibm_fsp_init(); hservice_fsp_init(); + hp_controller_init(&ucd); } DECLARE_PLATFORM(zz) = {