From nobody Mon Nov 25 13:47:23 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=1715795010; cv=none; d=zohomail.com; s=zohoarc; b=KoCmQDGune3AMnPpRTKYqgrNX8da557Da+r5lYy5K4fa9hZ5sR7pgHzZPO64oJxgHIYSfDzpgJMHQfvXEQ7jHC5Z9OWj7jsyhMbvghB2RKnZLgEBZFAiN2ug4yFsx/v7UjcDSygMY4HBxTdboHFf3viyaFhP8DoKN/0yJECSbrY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1715795010; 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=fDdEqKsebMY4IH8RYCXUBnrZSxSEEs+/CxArXdXZMk4=; b=CQBjulG/xzCtEnHE49K/i25LsnPlfudUnRdFkhzaIYYzILII5XCCHreh/caL87QTVYgdJshS4NUBaTignIs0ZmmddPRvNjZBs51d3hmCbQs7pbTsPKMlcmN8/yfeQHh5GRrXBbCT6uBevyeFxl/B17wjOYDQ9FflLEu38I0W1eM= 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 1715795010232644.6485136031346; Wed, 15 May 2024 10:43:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1s7IeE-00011j-QZ; Wed, 15 May 2024 13:42:38 -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 1s7Ie2-00010p-3S; Wed, 15 May 2024 13:42:26 -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 1s7Idy-0006X3-Bd; Wed, 15 May 2024 13:42:24 -0400 Received: from pps.filterd (m0360072.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 44FF6J1J025038; Wed, 15 May 2024 17:42:12 GMT Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3y4w9r8rc4-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 15 May 2024 17:42:12 +0000 Received: from m0360072.ppops.net (m0360072.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 44FHgBfI009810; Wed, 15 May 2024 17:42:11 GMT Received: from ppma11.dal12v.mail.ibm.com (db.9e.1632.ip4.static.sl-reverse.com [50.22.158.219]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3y4w9r8rc3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 15 May 2024 17:42:11 +0000 Received: from pps.filterd (ppma11.dal12v.mail.ibm.com [127.0.0.1]) by ppma11.dal12v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 44FH2HnV005721; Wed, 15 May 2024 17:42:11 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 3y2nq2vh1b-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 15 May 2024 17:42:11 +0000 Received: from smtpav02.fra02v.mail.ibm.com (smtpav02.fra02v.mail.ibm.com [10.20.54.101]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 44FHg5mX51380674 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 15 May 2024 17:42:07 GMT Received: from smtpav02.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1EEAA2004F; Wed, 15 May 2024 17:42:05 +0000 (GMT) Received: from smtpav02.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2F50520040; Wed, 15 May 2024 17:42:03 +0000 (GMT) Received: from gfwr515.rchland.ibm.com (unknown [9.10.239.103]) by smtpav02.fra02v.mail.ibm.com (Postfix) with ESMTP; Wed, 15 May 2024 17:42:03 +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=fDdEqKsebMY4IH8RYCXUBnrZSxSEEs+/CxArXdXZMk4=; b=rEFLqE141cmWu3zeaQjpZrUOPBZyBpsud43LYyuETdcgcVfgImQ0fw1uz1I9vqzyq7Fv D4F/fgP7wpMpQghPcfoaSLtFwHps+5QBNY0Ofs/CKdk2E671K6LS33q8aJ0DGnAtNUAf M8q13iuE0A09KR/xiEJt20V3fLWuTfvgVus92cKRRYOiDI+fqKF21AAPB3Hok+mqf7rG G1+tj6yeAOpPGL77KQkibapwcV3lBac2j66LjeLCE3ynUDL23ubF2WkK5OsW40nk9JFU YOZa3e5FguTv13vcol+s9IlCidBZZLj3HZD7wNRh/PkwbBT9x6PPUSJ+togfV2JV9NQh Rg== 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.vnet.ibm.com, dantan@us.ibm.com, milesg@linux.vnet.ibm.com Subject: [PATCH v3 1/5] ppc/pnv: Add SPI controller model Date: Wed, 15 May 2024 12:41:45 -0500 Message-Id: <20240515174149.17713-2-chalapathi.v@linux.ibm.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20240515174149.17713-1-chalapathi.v@linux.ibm.com> References: <20240515174149.17713-1-chalapathi.v@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: hXTaVKr0JVoY2OtumuRW6t217XNxYa9X X-Proofpoint-GUID: V75ND5DFghV-Xyzoz1kGWEWH3Sf444qD X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.650,FMLib:17.11.176.26 definitions=2024-05-15_10,2024-05-15_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 adultscore=0 impostorscore=0 spamscore=0 priorityscore=1501 lowpriorityscore=0 malwarescore=0 mlxscore=0 suspectscore=0 phishscore=0 clxscore=1015 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2405010000 definitions=main-2405150125 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 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: 1715795012334100003 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 | 3 + include/hw/ssi/pnv_spi.h | 44 +++++++ include/hw/ssi/pnv_spi_regs.h | 114 +++++++++++++++++ hw/ppc/pnv_spi_controller.c | 228 ++++++++++++++++++++++++++++++++++ hw/ppc/Kconfig | 1 + hw/ppc/meson.build | 1 + hw/ppc/trace-events | 6 + 7 files changed, 397 insertions(+) create mode 100644 include/hw/ssi/pnv_spi.h create mode 100644 include/hw/ssi/pnv_spi_regs.h create mode 100644 hw/ppc/pnv_spi_controller.c diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h index 6209e18492..a77b97f9b1 100644 --- a/include/hw/ppc/pnv_xscom.h +++ b/include/hw/ppc/pnv_xscom.h @@ -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..244ee1cfc0 --- /dev/null +++ b/include/hw/ssi/pnv_spi.h @@ -0,0 +1,44 @@ +/* + * QEMU PowerPC SPI Controller 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" + +#ifndef PPC_PNV_SPI_CONTROLLER_H +#define PPC_PNV_SPI_CONTROLLER_H + +#define TYPE_PNV_SPI_CONTROLLER "pnv-spi-controller" +#define PNV_SPICONTROLLER(obj) \ + OBJECT_CHECK(PnvSpiController, (obj), TYPE_PNV_SPI_CONTROLLER) + +#define SPI_CONTROLLER_REG_SIZE 8 + +#define TYPE_PNV_SPI_BUS "pnv-spi-bus" +typedef struct PnvSpiController { + SysBusDevice parent_obj; + + SSIBus *ssi_bus; + qemu_irq *cs_line; + MemoryRegion xscom_spic_regs; + /* SPI controller object number */ + uint32_t spic_num; + + /* SPI Controller registers */ + uint64_t error_reg; + uint64_t counter_config_reg; + uint64_t config_reg1; + uint64_t clock_config_reset_control; + uint64_t memory_mapping_reg; + uint64_t transmit_data_reg; + uint64_t receive_data_reg; + uint8_t sequencer_operation_reg[SPI_CONTROLLER_REG_SIZE]; + uint64_t status_reg; +} PnvSpiController; +#endif /* PPC_PNV_SPI_CONTROLLER_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..6f613aca5e --- /dev/null +++ b/include/hw/ssi/pnv_spi_regs.h @@ -0,0 +1,114 @@ +/* + * QEMU PowerPC SPI Controller model + * + * Copyright (c) 2023, IBM Corporation. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef SPI_CONTROLLER_REGS_H +#define SPI_CONTROLLER_REGS_H + +/* Error Register */ +#define ERROR_REG 0x00 + +/* counter_config_reg */ +#define COUNTER_CONFIG_REG 0x01 +#define COUNTER_CONFIG_REG_SHIFT_COUNT_N1 PPC_BITMASK(0, 7) +#define COUNTER_CONFIG_REG_SHIFT_COUNT_N2 PPC_BITMASK(8, 15) +#define COUNTER_CONFIG_REG_COUNT_COMPARE1 PPC_BITMASK(24, 31) +#define COUNTER_CONFIG_REG_COUNT_COMPARE2 PPC_BITMASK(32, 39) +#define COUNTER_CONFIG_REG_N1_COUNT_CONTROL PPC_BITMASK(48, 51) +#define COUNTER_CONFIG_REG_N2_COUNT_CONTROL PPC_BITMASK(52, 55) + +/* config_reg */ +#define CONFIG_REG1 0x02 + +/* clock_config_reset_control_ecc_enable_reg */ +#define CLOCK_CONFIG_REG 0x03 +#define CLOCK_CONFIG_RESET_CONTROL_HARD_RESET 0x0084000000000000; +#define CLOCK_CONFIG_REG_RESET_CONTROL PPC_BITMASK(24, 27) +#define CLOCK_CONFIG_REG_ECC_CONTROL PPC_BITMASK(28, 30) + +/* memory_mapping_reg */ +#define MEMORY_MAPPING_REG 0x04 +#define MEMORY_MAPPING_REG_MMSPISM_BASE_ADDR PPC_BITMASK(0, 15) +#define MEMORY_MAPPING_REG_MMSPISM_ADDR_MASK PPC_BITMASK(16, 31) +#define MEMORY_MAPPING_REG_RDR_MATCH_VAL PPC_BITMASK(32, 47) +#define MEMORY_MAPPING_REG_RDR_MATCH_MASK PPC_BITMASK(48, 63) + +/* transmit_data_reg */ +#define TRANSMIT_DATA_REG 0x05 + +/* receive_data_reg */ +#define RECEIVE_DATA_REG 0x06 + +/* sequencer_operation_reg */ +#define SEQUENCER_OPERATION_REG 0x07 + +/* status_reg */ +#define STATUS_REG 0x08 +#define STATUS_REG_RDR_FULL PPC_BIT(0) +#define STATUS_REG_RDR_OVERRUN PPC_BIT(1) +#define STATUS_REG_RDR_UNDERRUN PPC_BIT(2) +#define STATUS_REG_TDR_FULL PPC_BIT(4) +#define STATUS_REG_TDR_OVERRUN PPC_BIT(5) +#define STATUS_REG_TDR_UNDERRUN PPC_BIT(6) +#define STATUS_REG_SEQUENCER_FSM PPC_BITMASK(8, 15) +#define STATUS_REG_SHIFTER_FSM PPC_BITMASK(16, 27) +#define STATUS_REG_SEQUENCER_INDEX PPC_BITMASK(28, 31) +#define STATUS_REG_GENERAL_SPI_STATUS PPC_BITMASK(32, 63) +#define STATUS_REG_RDR PPC_BITMASK(1, 3) +#define STATUS_REG_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/ppc/pnv_spi_controller.c b/hw/ppc/pnv_spi_controller.c new file mode 100644 index 0000000000..11b119cf0f --- /dev/null +++ b/hw/ppc/pnv_spi_controller.c @@ -0,0 +1,228 @@ +/* + * QEMU PowerPC SPI Controller 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 "hw/ppc/fdt.h" +#include +#include +#include "hw/irq.h" +#include "trace.h" + +static uint64_t pnv_spi_controller_read(void *opaque, hwaddr addr, + unsigned size) +{ + PnvSpiController *s =3D PNV_SPICONTROLLER(opaque); + uint32_t reg =3D addr >> 3; + uint64_t val =3D ~0ull; + + switch (reg) { + case ERROR_REG: + val =3D s->error_reg; + break; + case COUNTER_CONFIG_REG: + val =3D s->counter_config_reg; + break; + case CONFIG_REG1: + val =3D s->config_reg1; + break; + case CLOCK_CONFIG_REG: + val =3D s->clock_config_reset_control; + break; + case MEMORY_MAPPING_REG: + val =3D s->memory_mapping_reg; + break; + case TRANSMIT_DATA_REG: + val =3D s->transmit_data_reg; + break; + case RECEIVE_DATA_REG: + val =3D s->receive_data_reg; + trace_pnv_spi_read_RDR(val); + s->status_reg =3D SETFIELD(STATUS_REG_RDR_FULL, s->status_reg, 0); + break; + case SEQUENCER_OPERATION_REG: + val =3D 0; + for (int i =3D 0; i < SPI_CONTROLLER_REG_SIZE; i++) { + val =3D (val << 8) | s->sequencer_operation_reg[i]; + } + break; + case STATUS_REG: + val =3D s->status_reg; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "spi_controller_regs: Invalid xscom= " + "read at 0x%08x\n", reg); + } + + trace_pnv_spi_read(addr, val); + return val; +} + +static void pnv_spi_controller_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) +{ + PnvSpiController *s =3D PNV_SPICONTROLLER(opaque); + uint32_t reg =3D addr >> 3; + + trace_pnv_spi_write(addr, val); + + switch (reg) { + case ERROR_REG: + s->error_reg =3D val; + break; + case COUNTER_CONFIG_REG: + s->counter_config_reg =3D val; + break; + case CONFIG_REG1: + s->config_reg1 =3D val; + break; + case CLOCK_CONFIG_REG: + /* + * To reset the SPI controller write the sequence 0x5 0xA to + * reset_control field + */ + if (GETFIELD(CLOCK_CONFIG_REG_RESET_CONTROL, + s->clock_config_reset_control) =3D=3D 0x5)= { + if (GETFIELD(CLOCK_CONFIG_REG_RESET_CONTROL, val) =3D=3D 0xA) { + /* SPI controller reset sequence completed, resetting */ + s->clock_config_reset_control =3D + CLOCK_CONFIG_RESET_CONTROL_HARD_RESET; + } else { + s->clock_config_reset_control =3D val; + } + } else { + s->clock_config_reset_control =3D val; + } + break; + case MEMORY_MAPPING_REG: + s->memory_mapping_reg =3D val; + break; + case TRANSMIT_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->transmit_data_reg =3D val; + trace_pnv_spi_write_TDR(val); + s->status_reg =3D SETFIELD(STATUS_REG_TDR_FULL, s->status_reg, 1); + s->status_reg =3D SETFIELD(STATUS_REG_TDR_UNDERRUN, s->status_reg,= 0); + break; + case RECEIVE_DATA_REG: + s->receive_data_reg =3D val; + break; + case SEQUENCER_OPERATION_REG: + for (int i =3D 0; i < SPI_CONTROLLER_REG_SIZE; i++) { + s->sequencer_operation_reg[i] =3D (val >> (56 - i * 8)) & 0xFF; + } + break; + case STATUS_REG: + /* other fields are ignore_write */ + s->status_reg =3D SETFIELD(STATUS_REG_RDR_OVERRUN, s->status_reg, + GETFIELD(STATUS_REG_RDR, val)); + s->status_reg =3D SETFIELD(STATUS_REG_TDR_OVERRUN, s->status_reg, + GETFIELD(STATUS_REG_TDR, val)); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "spi_controller_regs: Invalid xscom= " + "write at 0x%08x\n", reg); + } + return; +} + +static const MemoryRegionOps pnv_spi_controller_xscom_ops =3D { + .read =3D pnv_spi_controller_read, + .write =3D pnv_spi_controller_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_controller_properties[] =3D { + DEFINE_PROP_UINT32("spic_num", PnvSpiController, spic_num, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void pnv_spi_controller_realize(DeviceState *dev, Error **errp) +{ + PnvSpiController *s =3D PNV_SPICONTROLLER(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 controller scoms */ + pnv_xscom_region_init(&s->xscom_spic_regs, OBJECT(s), + &pnv_spi_controller_xscom_ops, s, + "xscom-spi-controller-regs", + PNV10_XSCOM_PIB_SPIC_SIZE); +} + +static int pnv_spi_controller_dt_xscom(PnvXScomInterface *dev, void *fdt, + int offset) +{ + PnvSpiController *s =3D PNV_SPICONTROLLER(dev); + g_autofree char *name; + int s_offset; + const char compat[] =3D "ibm,power10-spi_controller"; + 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("spi_controller@%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_controller_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_controller_dt_xscom; + + dc->desc =3D "PowerNV SPI Controller"; + dc->realize =3D pnv_spi_controller_realize; + device_class_set_props(dc, pnv_spi_controller_properties); +} + +static const TypeInfo pnv_spi_controller_info =3D { + .name =3D TYPE_PNV_SPI_CONTROLLER, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(PnvSpiController), + .class_init =3D pnv_spi_controller_class_init, + .interfaces =3D (InterfaceInfo[]) { + { TYPE_PNV_XSCOM_INTERFACE }, + { } + } +}; + +static void pnv_spi_controller_register_types(void) +{ + type_register_static(&pnv_spi_controller_info); +} + +type_init(pnv_spi_controller_register_types); diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index 78f83e78ce..6f9670b377 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -39,6 +39,7 @@ config POWERNV select PCI_POWERNV select PCA9552 select PCA9554 + select SSI =20 config PPC405 bool diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build index d096636ee7..68fadbae7b 100644 --- a/hw/ppc/meson.build +++ b/hw/ppc/meson.build @@ -56,6 +56,7 @@ ppc_ss.add(when: 'CONFIG_POWERNV', if_true: files( 'pnv_pnor.c', 'pnv_nest_pervasive.c', 'pnv_n1_chiplet.c', + 'pnv_spi_controller.c', )) # PowerPC 4xx boards ppc_ss.add(when: 'CONFIG_PPC405', if_true: files( diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events index bf29bbfd4b..b8e494ffc5 100644 --- a/hw/ppc/trace-events +++ b/hw/ppc/trace-events @@ -110,6 +110,12 @@ pnv_sbe_cmd_timer_stop(void) "" pnv_sbe_cmd_timer_expired(void) "" pnv_sbe_msg_recv(uint16_t cmd, uint16_t seq, uint16_t ctrl_flags) "cmd 0x%= " PRIx16 " seq %"PRIu16 " ctrl_flags 0x%" PRIx16 =20 +#pnv_spi_controller.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 + # ppc.c ppc_tb_adjust(uint64_t offs1, uint64_t offs2, int64_t diff, int64_t second= s) "adjusted from 0x%"PRIx64" to 0x%"PRIx64", diff %"PRId64" (%"PRId64"s)" ppc_tb_load(uint64_t tb) "tb 0x%016" PRIx64 --=20 2.39.3