From nobody Mon Nov 25 03:00:40 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1718643402; cv=none; d=zohomail.com; s=zohoarc; b=oEH93/lSCppBN6aPCeR/2Z8fXnbN6OnBLDHO2styiaCy6d1aGMyVeNJRCCA96NYlSDdfzPU3BlqXe4w3lBez9MxpyARsKuu4iN7PCx5LJQ9eCWvfyloWHvHhU8SlZRZvLdnu2/Ep+Is0MHQ6OuXiCaWqdOgho2hN/I0wSe5pb1g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1718643402; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=NQyc0+hImRbgb42clxjNTXvcHVNWBlIjiQln3nxG6EI=; b=hhK0HX0Oi72oxHKGmUSL/Nml7gaPqmJIzB2DrCCAn5Yb67QK2Rg5R6nZ3V8m1YNJD6niDq6rDdyI+qRJkpPSE9QkX8mOq7JGjRpmKfDW8HJiphf0l2ZtcctfRluQUa8vXHgQagz3oXYbpaeUBc50zNfFGR6/y8T067GUM1FlxbM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1718643402618136.59057644009408; Mon, 17 Jun 2024 09:56:42 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sJFdE-00082P-PN; Mon, 17 Jun 2024 12:55:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sJFd7-000809-9I; Mon, 17 Jun 2024 12:54:53 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sJFd3-0000bP-M9; Mon, 17 Jun 2024 12:54:53 -0400 Received: from pps.filterd (m0356516.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 45HGa1mc001642; Mon, 17 Jun 2024 16:54:44 GMT Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3ytrpyg2mp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 17 Jun 2024 16:54:44 +0000 (GMT) Received: from m0356516.ppops.net (m0356516.ppops.net [127.0.0.1]) by pps.reinject (8.18.0.8/8.18.0.8) with ESMTP id 45HGshhM001283; Mon, 17 Jun 2024 16:54:43 GMT Received: from ppma13.dal12v.mail.ibm.com (dd.9e.1632.ip4.static.sl-reverse.com [50.22.158.221]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3ytrpyg2mm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 17 Jun 2024 16:54:43 +0000 (GMT) Received: from pps.filterd (ppma13.dal12v.mail.ibm.com [127.0.0.1]) by ppma13.dal12v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 45HGVCn6009457; Mon, 17 Jun 2024 16:54:43 GMT Received: from smtprelay05.fra02v.mail.ibm.com ([9.218.2.225]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 3ysqgmbkby-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 17 Jun 2024 16:54:43 +0000 Received: from smtpav06.fra02v.mail.ibm.com (smtpav06.fra02v.mail.ibm.com [10.20.54.105]) by smtprelay05.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 45HGsbST48169240 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 17 Jun 2024 16:54:39 GMT Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4C7152004B; Mon, 17 Jun 2024 16:54:37 +0000 (GMT) Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6A55420063; Mon, 17 Jun 2024 16:54:35 +0000 (GMT) Received: from gfwr527.rchland.ibm.com (unknown [9.10.239.127]) by smtpav06.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 17 Jun 2024 16:54:35 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=pp1; bh=NQyc0+hImRbgb 42clxjNTXvcHVNWBlIjiQln3nxG6EI=; b=rUj1nCUZNWEzGZJpDOPSO60urOL8i 763alOTeRMBSG8+vgBXze4IoQycZEl93hQLdpvxLfgBpX/oOoNmA/p1ilAMkUlM/ yFY6MxEmbnioWPTVd0z8mnatm7Y2bKwkh6aDbKMDfIu3kaUjgZkZTOsosuVoT4tF Uc9OtoRklL7eiWT8+TS7+nCrdGIdHiXjpDcGsFt8RADlrP0nyUeYNGGmRgscxzC1 rTDF2asKUurllBtoHDmRVivX2SS/BGOtKlrj0PfuJc+oD/HQ52YbFAbFx9BE9DTw NwfUkhOMMkDd1bMeCXLwbCNCGTQj2e9ML8VSSz6aL0G7NnaBJ6/jYlnvw== From: Chalapathi V To: qemu-devel@nongnu.org Cc: qemu-ppc@nongnu.org, fbarrat@linux.ibm.com, npiggin@gmail.com, clg@kaod.org, calebs@us.ibm.com, chalapathi.v@ibm.com, chalapathi.v@linux.ibm.com, saif.abrar@linux.ibm.com, dantan@us.ibm.com, milesg@linux.ibm.com Subject: [PATCH v4 1/5] ppc/pnv: Add SPI model Date: Mon, 17 Jun 2024 11:54:15 -0500 Message-Id: <20240617165419.8388-2-chalapathi.v@linux.ibm.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20240617165419.8388-1-chalapathi.v@linux.ibm.com> References: <20240617165419.8388-1-chalapathi.v@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: TxJKJpBWCrtxAuA8IoNRX46TyOz1mHnQ X-Proofpoint-GUID: ZtaeoWt9hG_DX-K0HxWTqMnDzI15JgIV X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-06-17_14,2024-06-17_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 bulkscore=0 clxscore=1015 mlxlogscore=999 spamscore=0 impostorscore=0 phishscore=0 priorityscore=1501 adultscore=0 mlxscore=0 suspectscore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2405170001 definitions=main-2406170131 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=148.163.158.5; envelope-from=chalapathi.v@linux.ibm.com; helo=mx0b-001b2d01.pphosted.com X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1718643403739100001 Content-Type: text/plain; charset="utf-8" SPI controller device model supports a connection to a single SPI responder. This provide access to SPI seeproms, TPM, flash device and an ADC controlle= r. All SPI function control is mapped into the SPI register space to enable fu= ll control by firmware. In this commit SPI configuration component is modelled which contains all SPI configuration and status registers as well as the ho= ld registers for data to be sent or having been received. An existing QEMU SSI framework is used and SSI_BUS is created. Signed-off-by: Chalapathi V --- include/hw/ppc/pnv_xscom.h | 5 +- include/hw/ssi/pnv_spi.h | 59 ++++++++++ include/hw/ssi/pnv_spi_regs.h | 114 +++++++++++++++++++ hw/ssi/pnv_spi.c | 202 ++++++++++++++++++++++++++++++++++ hw/ppc/Kconfig | 3 + hw/ssi/Kconfig | 4 + hw/ssi/meson.build | 1 + hw/ssi/trace-events | 6 + 8 files changed, 393 insertions(+), 1 deletion(-) create mode 100644 include/hw/ssi/pnv_spi.h create mode 100644 include/hw/ssi/pnv_spi_regs.h create mode 100644 hw/ssi/pnv_spi.c diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h index 6209e18492..0020dd172f 100644 --- a/include/hw/ppc/pnv_xscom.h +++ b/include/hw/ppc/pnv_xscom.h @@ -21,9 +21,9 @@ #define PPC_PNV_XSCOM_H =20 #include "exec/memory.h" -#include "hw/ppc/pnv.h" =20 typedef struct PnvXScomInterface PnvXScomInterface; +typedef struct PnvChip PnvChip; =20 #define TYPE_PNV_XSCOM_INTERFACE "pnv-xscom-interface" #define PNV_XSCOM_INTERFACE(obj) \ @@ -194,6 +194,9 @@ struct PnvXScomInterfaceClass { #define PNV10_XSCOM_PEC_PCI_BASE 0x8010800 /* index goes upwards ... */ #define PNV10_XSCOM_PEC_PCI_SIZE 0x200 =20 +#define PNV10_XSCOM_PIB_SPIC_BASE 0xc0000 +#define PNV10_XSCOM_PIB_SPIC_SIZE 0x20 + void pnv_xscom_init(PnvChip *chip, uint64_t size, hwaddr addr); int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset, uint64_t xscom_base, uint64_t xscom_size, diff --git a/include/hw/ssi/pnv_spi.h b/include/hw/ssi/pnv_spi.h new file mode 100644 index 0000000000..71c53d4a17 --- /dev/null +++ b/include/hw/ssi/pnv_spi.h @@ -0,0 +1,59 @@ +/* + * QEMU PowerPC SPI model + * + * Copyright (c) 2024, IBM Corporation. + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * This model Supports a connection to a single SPI responder. + * Introduced for P10 to provide access to SPI seeproms, TPM, flash device + * and an ADC controller. + */ +#include "hw/ssi/ssi.h" +#include "hw/sysbus.h" + +#ifndef PPC_PNV_SPI_H +#define PPC_PNV_SPI_H + +/* Userful macros */ +#define PPC_BIT(bit) (0x8000000000000000ULL >> (bit)) +#define PPC_BIT8(bit) (0x80 >> (bit)) +#define PPC_BITMASK(bs, be) ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs)) +#define PPC_BITMASK8(bs, be) ((PPC_BIT8(bs) - PPC_BIT8(be)) | PPC_BIT8(= bs)) +#define MASK_TO_LSH(m) (__builtin_ffsll(m) - 1) +#define GETFIELD(m, v) (((v) & (m)) >> MASK_TO_LSH(m)) +#define SETFIELD(m, v, val) \ + (((v) & ~(m)) | ((((typeof(v))(val)) << MASK_TO_LSH(m)) & (m))) + +#define _FDT(exp) \ + do { \ + int _ret =3D (exp); \ + if (_ret < 0) { \ + error_report("error creating device tree: %s: %s", \ + #exp, fdt_strerror(_ret)); \ + exit(1); \ + } \ + } while (0) + +#define TYPE_PNV_SPI "pnv-spi" +OBJECT_DECLARE_SIMPLE_TYPE(PnvSpi, PNV_SPI) + +#define PNV_SPI_REG_SIZE 8 +#define PNV_SPI_REGS 7 + +#define TYPE_PNV_SPI_BUS "pnv-spi-bus" +typedef struct PnvSpi { + SysBusDevice parent_obj; + + SSIBus *ssi_bus; + qemu_irq *cs_line; + MemoryRegion xscom_spic_regs; + /* SPI object number */ + uint32_t spic_num; + + /* SPI registers */ + uint64_t regs[PNV_SPI_REGS]; + uint8_t seq_op[PNV_SPI_REG_SIZE]; + uint64_t status; +} PnvSpi; +#endif /* PPC_PNV_SPI_H */ diff --git a/include/hw/ssi/pnv_spi_regs.h b/include/hw/ssi/pnv_spi_regs.h new file mode 100644 index 0000000000..a0b5f3973d --- /dev/null +++ b/include/hw/ssi/pnv_spi_regs.h @@ -0,0 +1,114 @@ +/* + * QEMU PowerPC SPI model + * + * Copyright (c) 2024, IBM Corporation. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef PNV_SPI_CONTROLLER_REGS_H +#define PNV_SPI_CONTROLLER_REGS_H + +/* Error Register */ +#define ERROR_REG 0x00 + +/* counter_config_reg */ +#define SPI_CTR_CFG_REG 0x01 +#define SPI_CTR_CFG_N1 PPC_BITMASK(0, 7) +#define SPI_CTR_CFG_N2 PPC_BITMASK(8, 15) +#define SPI_CTR_CFG_CMP1 PPC_BITMASK(24, 31) +#define SPI_CTR_CFG_CMP2 PPC_BITMASK(32, 39) +#define SPI_CTR_CFG_N1_CTRL PPC_BITMASK(48, 51) +#define SPI_CTR_CFG_N2_CTRL PPC_BITMASK(52, 55) + +/* config_reg */ +#define CONFIG_REG1 0x02 + +/* clock_config_reset_control_ecc_enable_reg */ +#define SPI_CLK_CFG_REG 0x03 +#define SPI_CLK_CFG_HARD_RST 0x0084000000000000; +#define SPI_CLK_CFG_RST_CTRL PPC_BITMASK(24, 27) +#define SPI_CLK_CFG_ECC_CTRL PPC_BITMASK(28, 30) + +/* memory_mapping_reg */ +#define SPI_MM_REG 0x04 +#define SPI_MM_BASE_ADDR PPC_BITMASK(0, 15) +#define SPI_MM_ADDR_MASK PPC_BITMASK(16, 31) +#define SPI_MM_RDR_MATCH_VAL PPC_BITMASK(32, 47) +#define SPI_MM_RDR_MATCH_MASK PPC_BITMASK(48, 63) + +/* transmit_data_reg */ +#define SPI_XMIT_DATA_REG 0x05 + +/* receive_data_reg */ +#define SPI_RCV_DATA_REG 0x06 + +/* sequencer_operation_reg */ +#define SPI_SEQ_OP_REG 0x07 + +/* status_reg */ +#define SPI_STS_REG 0x08 +#define SPI_STS_RDR_FULL PPC_BIT(0) +#define SPI_STS_RDR_OVERRUN PPC_BIT(1) +#define SPI_STS_RDR_UNDERRUN PPC_BIT(2) +#define SPI_STS_TDR_FULL PPC_BIT(4) +#define SPI_STS_TDR_OVERRUN PPC_BIT(5) +#define SPI_STS_TDR_UNDERRUN PPC_BIT(6) +#define SPI_STS_SEQ_FSM PPC_BITMASK(8, 15) +#define SPI_STS_SHIFTER_FSM PPC_BITMASK(16, 27) +#define SPI_STS_SEQ_INDEX PPC_BITMASK(28, 31) +#define SPI_STS_GEN_STATUS PPC_BITMASK(32, 63) +#define SPI_STS_RDR PPC_BITMASK(1, 3) +#define SPI_STS_TDR PPC_BITMASK(5, 7) + +/* + * Shifter states + * + * These are the same values defined for the Shifter FSM field of the + * status register. It's a 12 bit field so we will represent it as three + * nibbles in the constants. + * + * These are shifter_fsm values + * + * Status reg bits 16-27 -> field bits 0-11 + * bits 0,1,2,5 unused/reserved + * bit 4 crc shift in (unused) + * bit 8 crc shift out (unused) + */ + +#define FSM_DONE 0x100 /* bit 3 */ +#define FSM_SHIFT_N2 0x020 /* bit 6 */ +#define FSM_WAIT 0x010 /* bit 7 */ +#define FSM_SHIFT_N1 0x004 /* bit 9 */ +#define FSM_START 0x002 /* bit 10 */ +#define FSM_IDLE 0x001 /* bit 11 */ + +/* + * Sequencer states + * + * These are sequencer_fsm values + * + * Status reg bits 8-15 -> field bits 0-7 + * bits 0-3 unused/reserved + * + */ +#define SEQ_STATE_INDEX_INCREMENT 0x08 /* bit 4 */ +#define SEQ_STATE_EXECUTE 0x04 /* bit 5 */ +#define SEQ_STATE_DECODE 0x02 /* bit 6 */ +#define SEQ_STATE_IDLE 0x01 /* bit 7 */ + +/* + * These are the supported sequencer operations. + * Only the upper nibble is significant because for many operations + * the lower nibble is a variable specific to the operation. + */ +#define SEQ_OP_STOP 0x00 +#define SEQ_OP_SELECT_SLAVE 0x10 +#define SEQ_OP_SHIFT_N1 0x30 +#define SEQ_OP_SHIFT_N2 0x40 +#define SEQ_OP_BRANCH_IFNEQ_RDR 0x60 +#define SEQ_OP_TRANSFER_TDR 0xC0 +#define SEQ_OP_BRANCH_IFNEQ_INC_1 0xE0 +#define SEQ_OP_BRANCH_IFNEQ_INC_2 0xF0 + +#endif diff --git a/hw/ssi/pnv_spi.c b/hw/ssi/pnv_spi.c new file mode 100644 index 0000000000..da9e3925dd --- /dev/null +++ b/hw/ssi/pnv_spi.c @@ -0,0 +1,202 @@ +/* + * QEMU PowerPC SPI model + * + * Copyright (c) 2024, IBM Corporation. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "hw/qdev-properties.h" +#include "hw/ppc/pnv_xscom.h" +#include "hw/ssi/pnv_spi.h" +#include "hw/ssi/pnv_spi_regs.h" +#include "hw/ssi/ssi.h" +#include +#include "hw/irq.h" +#include "trace.h" + +static uint64_t pnv_spi_xscom_read(void *opaque, hwaddr addr, unsigned siz= e) +{ + PnvSpi *s =3D PNV_SPI(opaque); + uint32_t reg =3D addr >> 3; + uint64_t val =3D ~0ull; + + switch (reg) { + case ERROR_REG: + case SPI_CTR_CFG_REG: + case CONFIG_REG1: + case SPI_CLK_CFG_REG: + case SPI_MM_REG: + case SPI_XMIT_DATA_REG: + val =3D s->regs[reg]; + break; + case SPI_RCV_DATA_REG: + val =3D s->regs[reg]; + trace_pnv_spi_read_RDR(val); + s->status =3D SETFIELD(SPI_STS_RDR_FULL, s->status, 0); + break; + case SPI_SEQ_OP_REG: + val =3D 0; + for (int i =3D 0; i < PNV_SPI_REG_SIZE; i++) { + val =3D (val << 8) | s->seq_op[i]; + } + break; + case SPI_STS_REG: + val =3D s->status; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi_regs: Invalid xscom " + "read at 0x%" PRIx32 "\n", reg); + } + + trace_pnv_spi_read(addr, val); + return val; +} + +static void pnv_spi_xscom_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) +{ + PnvSpi *s =3D PNV_SPI(opaque); + uint32_t reg =3D addr >> 3; + + trace_pnv_spi_write(addr, val); + + switch (reg) { + case ERROR_REG: + case SPI_CTR_CFG_REG: + case CONFIG_REG1: + case SPI_MM_REG: + case SPI_RCV_DATA_REG: + s->regs[reg] =3D val; + break; + case SPI_CLK_CFG_REG: + /* + * To reset the SPI controller write the sequence 0x5 0xA to + * reset_control field + */ + if ((GETFIELD(SPI_CLK_CFG_RST_CTRL, s->regs[SPI_CLK_CFG_REG]) =3D= =3D 0x5) + && (GETFIELD(SPI_CLK_CFG_RST_CTRL, val) =3D=3D 0xA)) { + /* SPI controller reset sequence completed, resetting */ + s->regs[reg] =3D SPI_CLK_CFG_HARD_RST; + } else { + s->regs[reg] =3D val; + } + break; + case SPI_XMIT_DATA_REG: + /* + * Writing to the transmit data register causes the transmit data + * register full status bit in the status register to be set. Wri= ting + * when the transmit data register full status bit is already set + * causes a "Resource Not Available" condition. This is not possi= ble + * in the model since writes to this register are not asynchronous= to + * the operation sequence like it would be in hardware. + */ + s->regs[reg] =3D val; + trace_pnv_spi_write_TDR(val); + s->status =3D SETFIELD(SPI_STS_TDR_FULL, s->status, 1); + s->status =3D SETFIELD(SPI_STS_TDR_UNDERRUN, s->status, 0); + break; + case SPI_SEQ_OP_REG: + for (int i =3D 0; i < PNV_SPI_REG_SIZE; i++) { + s->seq_op[i] =3D (val >> (56 - i * 8)) & 0xFF; + } + break; + case SPI_STS_REG: + /* other fields are ignore_write */ + s->status =3D SETFIELD(SPI_STS_RDR_OVERRUN, s->status, + GETFIELD(SPI_STS_RDR, val)); + s->status =3D SETFIELD(SPI_STS_TDR_OVERRUN, s->status, + GETFIELD(SPI_STS_TDR, val)); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi_regs: Invalid xscom " + "write at 0x%" PRIx32 "\n", reg); + } + return; +} + +static const MemoryRegionOps pnv_spi_xscom_ops =3D { + .read =3D pnv_spi_xscom_read, + .write =3D pnv_spi_xscom_write, + .valid.min_access_size =3D 8, + .valid.max_access_size =3D 8, + .impl.min_access_size =3D 8, + .impl.max_access_size =3D 8, + .endianness =3D DEVICE_BIG_ENDIAN, +}; + +static Property pnv_spi_properties[] =3D { + DEFINE_PROP_UINT32("spic_num", PnvSpi, spic_num, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void pnv_spi_realize(DeviceState *dev, Error **errp) +{ + PnvSpi *s =3D PNV_SPI(dev); + g_autofree char *name =3D g_strdup_printf(TYPE_PNV_SPI_BUS ".%d", + s->spic_num); + s->ssi_bus =3D ssi_create_bus(dev, name); + s->cs_line =3D g_new0(qemu_irq, 1); + qdev_init_gpio_out_named(DEVICE(s), s->cs_line, "cs", 1); + + /* spi scoms */ + pnv_xscom_region_init(&s->xscom_spic_regs, OBJECT(s), + &pnv_spi_xscom_ops, s, + "xscom-spi-regs", + PNV10_XSCOM_PIB_SPIC_SIZE); +} + +static int pnv_spi_dt_xscom(PnvXScomInterface *dev, void *fdt, + int offset) +{ + PnvSpi *s =3D PNV_SPI(dev); + g_autofree char *name; + int s_offset; + const char compat[] =3D "ibm,power10-spi"; + uint32_t spic_pcba =3D PNV10_XSCOM_PIB_SPIC_BASE + + s->spic_num * PNV10_XSCOM_PIB_SPIC_SIZE; + uint32_t reg[] =3D { + cpu_to_be32(spic_pcba), + cpu_to_be32(PNV10_XSCOM_PIB_SPIC_SIZE) + }; + name =3D g_strdup_printf("pnv_spi@%x", spic_pcba); + s_offset =3D fdt_add_subnode(fdt, offset, name); + _FDT(s_offset); + + _FDT(fdt_setprop(fdt, s_offset, "reg", reg, sizeof(reg))); + _FDT(fdt_setprop(fdt, s_offset, "compatible", compat, sizeof(compat))); + _FDT((fdt_setprop_cell(fdt, s_offset, "spic_num#", s->spic_num))); + return 0; +} + +static void pnv_spi_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + PnvXScomInterfaceClass *xscomc =3D PNV_XSCOM_INTERFACE_CLASS(klass); + + xscomc->dt_xscom =3D pnv_spi_dt_xscom; + + dc->desc =3D "PowerNV SPI"; + dc->realize =3D pnv_spi_realize; + device_class_set_props(dc, pnv_spi_properties); +} + +static const TypeInfo pnv_spi_info =3D { + .name =3D TYPE_PNV_SPI, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(PnvSpi), + .class_init =3D pnv_spi_class_init, + .interfaces =3D (InterfaceInfo[]) { + { TYPE_PNV_XSCOM_INTERFACE }, + { } + } +}; + +static void pnv_spi_register_types(void) +{ + type_register_static(&pnv_spi_info); +} + +type_init(pnv_spi_register_types); diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index 78f83e78ce..4668d59eab 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -39,6 +39,9 @@ config POWERNV select PCI_POWERNV select PCA9552 select PCA9554 + select SSI + select SSI_M25P80 + select PNV_SPI =20 config PPC405 bool diff --git a/hw/ssi/Kconfig b/hw/ssi/Kconfig index 83ee53c1d0..8d180de7cf 100644 --- a/hw/ssi/Kconfig +++ b/hw/ssi/Kconfig @@ -24,3 +24,7 @@ config STM32F2XX_SPI config BCM2835_SPI bool select SSI + +config PNV_SPI + bool + select SSI diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build index b999aeb027..b7ad7fca3b 100644 --- a/hw/ssi/meson.build +++ b/hw/ssi/meson.build @@ -12,3 +12,4 @@ system_ss.add(when: 'CONFIG_IMX', if_true: files('imx_spi= .c')) system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_spi.c')) system_ss.add(when: 'CONFIG_IBEX', if_true: files('ibex_spi_host.c')) system_ss.add(when: 'CONFIG_BCM2835_SPI', if_true: files('bcm2835_spi.c')) +system_ss.add(when: 'CONFIG_PNV_SPI', if_true: files('pnv_spi.c')) diff --git a/hw/ssi/trace-events b/hw/ssi/trace-events index 2d5bd2b83d..4388024a05 100644 --- a/hw/ssi/trace-events +++ b/hw/ssi/trace-events @@ -32,3 +32,9 @@ ibex_spi_host_reset(const char *msg) "%s" ibex_spi_host_transfer(uint32_t tx_data, uint32_t rx_data) "tx_data: 0x%" = PRIx32 " rx_data: @0x%" PRIx32 ibex_spi_host_write(uint64_t addr, uint32_t size, uint64_t data) "@0x%" PR= Ix64 " size %u: 0x%" PRIx64 ibex_spi_host_read(uint64_t addr, uint32_t size) "@0x%" PRIx64 " size %u:" + +#pnv_spi.c +pnv_spi_read(uint64_t addr, uint64_t val) "addr 0x%" PRIx64 " val 0x%" PRI= x64 +pnv_spi_write(uint64_t addr, uint64_t val) "addr 0x%" PRIx64 " val 0x%" PR= Ix64 +pnv_spi_read_RDR(uint64_t val) "data extracted =3D 0x%" PRIx64 +pnv_spi_write_TDR(uint64_t val) "being written, data written =3D 0x%" PRIx= 64 --=20 2.39.3