From nobody Mon Sep 28 02:03:02 2026 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=oss.tenstorrent.com ARC-Seal: i=1; a=rsa-sha256; t=1785345250; cv=none; d=zohomail.com; s=zohoarc; b=ZcFf3ptNL2ynng/56B7Vwm++14weDTGfgEFtqrIAmXzyGG8omPathDUypZwyra487FA2fFyhpTBsPPZJBZpSafHuTPXeGwQ+aQ5GDu3XbL3OIlzK/kykNF7bfadisfGRxqbqdeHhaAsybL4aBhaOcFUMZPVcMFsVlc9XRod2o2k= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785345250; h=Content-Type: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=YIpPW+jQ9fhEwD83itkXvHNnk6rkY7mxSSg5uCIzBWk=; b=g13EUoCcZcHOv7P23RDK9JZ4l5j0GWbsFl/f+9C+gjRG+NX1Y9fLVk9Zrz8dDNdVG/WoY9nEokX1XHDvZ4zOB0J0t1fbZFQZ5UTuMoVopk387yHkoARpy0XGvDSQHup7MpRGAQCZ/LKNlAmw/pXFqWAkHGZaA8Q7k5xwnzIMriw= 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785345250739585.6393700183888; Wed, 29 Jul 2026 10:14:10 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wp7qf-0006E1-AL; Wed, 29 Jul 2026 13:13:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wp672-0007mB-QN for qemu-devel@nongnu.org; Wed, 29 Jul 2026 11:22:28 -0400 Received: from mail-oa1-x36.google.com ([2001:4860:4864:20::36]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wp66y-0006py-Kr for qemu-devel@nongnu.org; Wed, 29 Jul 2026 11:22:28 -0400 Received: by mail-oa1-x36.google.com with SMTP id 586e51a60fabf-4583b1703d3so415168fac.3 for ; Wed, 29 Jul 2026 08:22:24 -0700 (PDT) Received: from [10.200.56.99] ([12.55.13.134]) by smtp.gmail.com with ESMTPSA id 586e51a60fabf-458867fb651sm2476451fac.11.2026.07.29.08.22.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Jul 2026 08:22:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tenstorrent.com; s=google; t=1785338543; x=1785943343; darn=nongnu.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=YIpPW+jQ9fhEwD83itkXvHNnk6rkY7mxSSg5uCIzBWk=; b=b61/UGjhDo71/zhcriQaEHofM6kAL0SJ/L+CD05Uh2NplAybIi3VANWxf6JuPGCQ/v qPvhM07n7M1sPp1QZihTtjFPVjJI09XXZRbthiUltbw32T2bJ5K0Gc//fIZoKLX/LS16 zmykHsqxeMiulcBXfNDiCyzKy1GTta/Hu8SZqHqLkWRNqMG3QU5ebEW9ePgAw1rkoEgA Aa8oI92smLK4L04mIzWgLiQFCP3Osc8FSNh3HDMzhUtB/ji99eke2l+jRwg7yzmYjbRI 89RGKVtmWbx3a+XTs4GUcX93Pm0RTl4XemHLcqN9VUWRrgQVjK2xTCiReXpLRo4J/thp Ux7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785338543; x=1785943343; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=YIpPW+jQ9fhEwD83itkXvHNnk6rkY7mxSSg5uCIzBWk=; b=Dw2/1gA8EgBDUCzVbjc2MfLmFXDT/TzeZKEoKy0HY6ZimR0F7O5Qoovf5VTvosMiaV nPd3iskhM9L8V8wIgk8fU5t2BemWGBJsxbUdzzFdyHIdmGBI8xVZ2nNu6OUB6Fbq8LTw KddHC36vCt10BgLMFIdkRJHycThUs5mWaHxH3D9en3bY4250rUXeP3f7UmWymOua67jy BBbQFLXPKKelYTRh0hUvQtN0BaNaF8AH/uvBn+mD64QW2bkuI4a/kaM7T9pfJ84f0mKX sUB9esATvs5GCeWGolB45nEXYvnQ393P0PTdGCT2An+VDZUbK/dHDaWVTm7ssRVFF3rI SqUA== X-Gm-Message-State: AOJu0Yw6CIz1qeoigxyfSVR0eOlIP5eHmaiTIqUqNVNIJTSL/Tc0POZM PxzgY+kvQAxH3NvR8XQAOMQUK7Zstq9DxqPDGGg8o7g+4fB2dTpW53+tL75z6BM8u0Q= X-Gm-Gg: AR+sD10Zfdhvlt1d+I2hkxDPcHVHt30TBbqB9TKEuezx1gsCcD3TaoYXMqQTSr4LAaf jl/TIGynh++fMgdauy7CmB1QWR4L4hjZQ74edKg7N+KBJLN8Vbj1Qp7PrxumEgyVDPiMCRyM8r8 YMiBIdDxCGtcvS8ylqk/uz4eVnxCupM0ei6Yr9QmmsUcLpw5Wf46zx+gYlqx+Y8g1Roz3W7WlpC oA9Zt+Lmvyj7MciTV+GEDOiGWzhKgH5dpI5OTLCyiKFUEF4JP/qLWqMBlPA9Rt/BrNehcGQ2wva q05wl44KqtC9aX/0Sca+LCLTlEBye+V4WO+z98anETL+cNn1aciI2SGUlK1T8V6M0xq9yf6AODc JEAYXzZ7FWKzbkWf+8PBFsmnGruKFFGHDVXya/QeeU3yfmySP8D5HBMWNwFOliL7gxBTFc92n7l fYByYFUd31dTVHm3bFzOuF9VHdtKZtrVv3/8lwqjTsUrBpLhJnZHF2YqiKy9+6MkczMwwLiaLYw cBjmRFYHtrDXlFk7x5Z4sgmixNuHV7xSnHD2g== X-Received: by 2002:a05:6871:5220:b0:448:9e35:c3fe with SMTP id 586e51a60fabf-4586cc34955mr3990219fac.11.1785338543098; Wed, 29 Jul 2026 08:22:23 -0700 (PDT) From: Anirudh Srinivasan Date: Wed, 29 Jul 2026 10:21:34 -0500 Subject: [PATCH 1/2] hw/misc: Add Tenstorrent Atlantis PRCM model MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260729-atlantis_prcm-v1-1-502882933e51@oss.tenstorrent.com> References: <20260729-atlantis_prcm-v1-0-502882933e51@oss.tenstorrent.com> In-Reply-To: <20260729-atlantis_prcm-v1-0-502882933e51@oss.tenstorrent.com> To: qemu-devel@nongnu.org Cc: Joel Stanley , Nicholas Piggin , Michael Ellerman , Portia Stephens , qemu-riscv@nongnu.org, Pierrick Bouvier , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Chao Liu , Anirudh Srinivasan X-Mailer: b4 0.15.1 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=lists1p.gnu.org; Received-SPF: pass client-ip=2001:4860:4864:20::36; envelope-from=asrinivasan@tenstorrent.com; helo=mail-oa1-x36.google.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_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Wed, 29 Jul 2026 13:13:39 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development 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 @tenstorrent.com) X-ZM-MESSAGEID: 1785345252032158500 This device present in Tenstorrent Atlantis has registers that control clocks, reset and other misc functionality in the SoC. This commit adds models for the RCPU, HSIO, PCIE, MM and 2 DDR PRCMs. Co-developed-by: Portia Stephens Signed-off-by: Portia Stephens Signed-off-by: Anirudh Srinivasan --- MAINTAINERS | 2 + hw/misc/meson.build | 1 + hw/misc/trace-events | 4 + hw/misc/tt_atlantis_prcm.c | 436 +++++++++++++++++++++++++++++++++= ++++ include/hw/misc/tt_atlantis_prcm.h | 51 +++++ 5 files changed, 494 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index e25df9493c..49c1a5ad76 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1802,7 +1802,9 @@ R: Portia Stephens L: qemu-riscv@nongnu.org S: Supported F: docs/system/riscv/tt_*.rst +F: hw/misc/tt_*.c F: hw/riscv/tt_*.c +F: include/hw/misc/tt_*.h F: include/hw/riscv/tt_*.h F: tests/functional/riscv64/test_tt_*.py =20 diff --git a/hw/misc/meson.build b/hw/misc/meson.build index 23265f6035..26627013f3 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -36,6 +36,7 @@ system_ss.add(when: 'CONFIG_SIFIVE_E_PRCI', if_true: file= s('sifive_e_prci.c')) system_ss.add(when: 'CONFIG_SIFIVE_E_AON', if_true: files('sifive_e_aon.c'= )) system_ss.add(when: 'CONFIG_SIFIVE_U_OTP', if_true: files('sifive_u_otp.c'= )) system_ss.add(when: 'CONFIG_SIFIVE_U_PRCI', if_true: files('sifive_u_prci.= c')) +system_ss.add(when: 'CONFIG_TENSTORRENT', if_true: files('tt_atlantis_prcm= .c')) =20 subdir('macio') =20 diff --git a/hw/misc/trace-events b/hw/misc/trace-events index c9a868b3ef..9359a4e66d 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -442,3 +442,7 @@ iommu_testdev_dma_read(uint64_t gva, uint32_t len) "gva= =3D0x%" PRIx64 " len=3D%u" iommu_testdev_dma_verify(uint32_t expected, uint32_t actual) "expected=3D0= x%x actual=3D0x%x" iommu_testdev_dma_result(uint32_t result) "DMA completed result=3D0x%x" iommu_testdev_dma_armed(bool armed) "armed=3D%d" + +# tt_atlantis_prcm.c +tt_atlantis_prcm_read(uint32_t domain, uint64_t offset, uint64_t data) "do= main 0x%02x offset 0x%" PRIx64 " data 0x%" PRIx64 +tt_atlantis_prcm_write(uint32_t domain, uint64_t offset, uint64_t data) "d= omain 0x%02x offset 0x%" PRIx64 " data 0x%" PRIx64 diff --git a/hw/misc/tt_atlantis_prcm.c b/hw/misc/tt_atlantis_prcm.c new file mode 100644 index 0000000000..d341e1a8c3 --- /dev/null +++ b/hw/misc/tt_atlantis_prcm.c @@ -0,0 +1,436 @@ +/* + * PRCM (Clock and Reset Controller) in Tenstorrent Atlantis SoC + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright 2026 Tenstorrent + */ + +#include "qemu/osdep.h" +#include "qemu/bitops.h" +#include "qapi/error.h" +#include "qemu/log.h" +#include "hw/misc/tt_atlantis_prcm.h" +#include "hw/core/qdev-properties.h" +#include "hw/core/registerfields.h" +#include "hw/core/irq.h" +#include "trace.h" + +#define TO_REG(offset) ((offset) >> 2) + +#define PLL_LOCK_BIT 31 +#define PLL_FBDIV_LSB 14 +#define PLL_POSTDIV2_LSB 11 +#define PLL_POSTDIV1_LSB 8 +#define PLL_REFDIV_LSB 2 +#define PLL_BYPASS_BIT 1 + +#define PLL_RESET_VAL(BYPASS, REFDIV, POSTDIV1, POSTDIV2, FBDIV, LOCK) = \ + ((LOCK << PLL_LOCK_BIT) | (FBDIV << PLL_FBDIV_LSB) | = \ + (POSTDIV2 << PLL_POSTDIV2_LSB) | (POSTDIV1 << PLL_POSTDIV1_LSB) | = \ + (REFDIV << PLL_REFDIV_LSB) | (BYPASS << PLL_BYPASS_BIT)) + +#define RCPU_PLL_RCPU_CFG TO_REG(0) +#define RCPU_PLL_NOCC_CFG TO_REG(0x4) +#define RCPU_NOCC_CLK_CFG TO_REG(0x8) +#define RCPU_RCPU_DIV_CFG TO_REG(0xc) +#define RCPU_RCPU_BLK_CG TO_REG(0x14) +#define RCPU_LSIO_BLK_CG TO_REG(0x18) +#define RCPU_RCPU_BLK_RST TO_REG(0x1c) +#define RCPU_LSIO_BLK_RST TO_REG(0x20) +#define RCPU_PLL_RCPU_EN TO_REG(0x11c) +#define RCPU_PLL_NOCC_EN TO_REG(0x120) +#define RCPU_PLL_MM_EN TO_REG(0x0124) +#define RCPU_PLL1_MM_EN TO_REG(0x0128) +#define RCPU_PLL_HSIO_EN TO_REG(0x12c) +#define RCPU_PLL_PCIE_EN TO_REG(0x138) +#define RCPU_PLL_I2S_EN TO_REG(0x13C) +#define RCPU_PLL_MM_CFG TO_REG(0x19c) +#define RCPU_PLL_HSIO_CFG TO_REG(0x1a0) +#define RCPU_PLL_PCIE_CFG TO_REG(0x1ac) +#define RCPU_BOOT_MODE_CFG TO_REG(0x1b0) +#define RCPU_PLL_I2S_CFG TO_REG(0x1f4) +#define RCPU_I2S_DIV_CFG TO_REG(0x1f8) +#define RCPU_BUS_CFG TO_REG(0x1fc) +#define RCPU_PLL1_MM_CFG TO_REG(0x2a4) + +#define HSIO_HSIO_DIV_CFG TO_REG(0x0) +#define HSIO_HSIO_DIV_CFG1 TO_REG(0x4) +#define HSIO_HSIO_BLK_CG TO_REG(0x8) +#define HSIO_HSIO_BLK_RST TO_REG(0xc) +#define HSIO_HSIO_GMAC_DIV_CFG TO_REG(0x10) + +#define PCIE_SUBS_RST_CTL TO_REG(0x0) +#define PCIE_SUBS_CG_CTL TO_REG(0x4) +#define PCIE_SUBS_CK_CTL TO_REG(0x8) + +#define MM_MM_CLK_GATE_CFG TO_REG(0x8) +#define MM_MM_CLK_DIV_CFG TO_REG(0xC) +#define MM_MM_CLK_SEL_CFG TO_REG(0x10) +#define MM_MM_RSTN TO_REG(0x14) +#define MM_MM_CLK_DIV_CFG1 TO_REG(0x130) + +#define DDRC_STAT TO_REG(0x10014) +#define DDRC_DFISTAT TO_REG(0x10514) +#define DDRC_SWSTAT TO_REG(0x10c84) + +#define PLL_EN BIT(0) +#define RCPU_PLL_BUS_CG_EN BIT(7) +#define HSIO_PLL_BUS_CG_EN BIT(3) +#define PCIE_PLL_BUS_CG_EN BIT(1) +#define NOCC_PLL_BUS_CG_EN BIT(0) + +#define RCPU_BOOT_MODE_UART (0x0 << 4) +#define RCPU_BOOT_MODE_NOR (0x1 << 4) +#define RCPU_BOOT_MODE_SD (0x2 << 4) + +#define RCPU_DOMAIN_SIZE 0x10000 +#define HSIO_DOMAIN_SIZE 0x510 +#define PCIE_DOMAIN_SIZE 0x100 +#define MM_DOMAIN_SIZE 0x1000 +#define DDRC0_DOMAIN_SIZE 0x101000 +#define DDRC1_DOMAIN_SIZE 0x101000 + +static uint64_t tt_atlantis_prcm_read(void *opaque, hwaddr offset, + unsigned size) { + TTAtlantisPRCMState *s =3D TT_ATLANTIS_PRCM(opaque); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_GET_CLASS(s); + uint32_t data; + + if (offset >=3D c->regs_size) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "= \n", + __func__, offset); + return 0; + } + data =3D s->regs[TO_REG(offset)]; + + trace_tt_atlantis_prcm_read(c->domain, offset, data); + return data; +} + +static void tt_atlantis_prcm_write(void *opaque, hwaddr offset, + uint64_t data, unsigned size) { + TTAtlantisPRCMState *s =3D TT_ATLANTIS_PRCM(opaque); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_GET_CLASS(s); + + trace_tt_atlantis_prcm_write(c->domain, offset, data); + + if (offset >=3D c->regs_size) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx = "\n", + __func__, offset); + return; + } + + switch (TO_REG(offset)) { + default: + s->regs[TO_REG(offset)] =3D data; + break; + } +} + +static void tt_atlantis_prcm_rcpu_write(void *opaque, hwaddr offset, + uint64_t data, unsigned size) { + TTAtlantisPRCMState *s =3D TT_ATLANTIS_PRCM(opaque); + + tt_atlantis_prcm_write(opaque, offset, data, size); + + bool pll_en_written =3D false; + uint32_t pll_reg_offset; + switch TO_REG(offset) + { + case RCPU_PLL_RCPU_EN: + pll_en_written =3D true; + pll_reg_offset =3D RCPU_PLL_RCPU_CFG; + break; + case RCPU_PLL_NOCC_EN: + pll_en_written =3D true; + pll_reg_offset =3D RCPU_PLL_NOCC_CFG; + break; + case RCPU_PLL_HSIO_EN: + pll_en_written =3D true; + pll_reg_offset =3D RCPU_PLL_HSIO_CFG; + break; + case RCPU_PLL_PCIE_EN: + pll_en_written =3D true; + pll_reg_offset =3D RCPU_PLL_PCIE_CFG; + break; + case RCPU_PLL_MM_EN: + pll_en_written =3D true; + pll_reg_offset =3D RCPU_PLL_MM_CFG; + break; + case RCPU_PLL1_MM_EN: + pll_en_written =3D true; + pll_reg_offset =3D RCPU_PLL1_MM_CFG; + break; + case RCPU_PLL_I2S_EN: + pll_en_written =3D true; + pll_reg_offset =3D RCPU_PLL_I2S_CFG; + break; + } + if (pll_en_written) { + if (data & PLL_EN) { + s->regs[pll_reg_offset] |=3D BIT(PLL_LOCK_BIT); + } else { + s->regs[pll_reg_offset] &=3D ~BIT(PLL_LOCK_BIT); + } + } +} + +static const MemoryRegionOps tt_atlantis_prcm_ops =3D { + .read =3D tt_atlantis_prcm_read, + .write =3D tt_atlantis_prcm_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid.min_access_size =3D 4, + .valid.max_access_size =3D 4, +}; + +static const MemoryRegionOps tt_atlantis_prcm_rcpu_ops =3D { + .read =3D tt_atlantis_prcm_read, + .write =3D tt_atlantis_prcm_rcpu_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid.min_access_size =3D 4, + .valid.max_access_size =3D 4, +}; + +static void tt_atlantis_prcm_realize(DeviceState *dev, Error **errp) +{ + TTAtlantisPRCMState *s =3D TT_ATLANTIS_PRCM(dev); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(dev); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_GET_CLASS(s); + + if (c->domain >=3D PRCM_DOMAIN_COUNT) { + error_setg(errp, + "domain %d is larger than max number of possible domain= s %d", + c->domain, PRCM_DOMAIN_COUNT); + return; + } + s->regs =3D g_new0(uint32_t, TO_REG(c->regs_size)); + + memory_region_init_io(&s->mmio, OBJECT(s), c->ops, s, + TYPE_TT_ATLANTIS_PRCM, c->regs_size); + sysbus_init_mmio(sbd, &s->mmio); +} + +static void tt_atlantis_prcm_reset(DeviceState *dev) +{ + TTAtlantisPRCMState *s =3D TT_ATLANTIS_PRCM(dev); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_GET_CLASS(s); + + memset(s->regs, 0, c->regs_size); +} + +static void tt_atlantis_prcm_rcpu_reset(DeviceState *dev) +{ + TTAtlantisPRCMState *s =3D TT_ATLANTIS_PRCM(dev); + tt_atlantis_prcm_reset(dev); + + s->regs[RCPU_PLL_RCPU_CFG] =3D PLL_RESET_VAL(1, 0, 4, 0, 100, 1); + s->regs[RCPU_PLL_NOCC_CFG] =3D PLL_RESET_VAL(0, 2, 2, 2, 267, 1); + s->regs[RCPU_NOCC_CLK_CFG] =3D (0x25f31 << 1) | BIT(0); + s->regs[RCPU_RCPU_DIV_CFG] =3D (0xb8c2 << 1); + s->regs[RCPU_RCPU_BLK_CG] =3D 0; + s->regs[RCPU_LSIO_BLK_CG] =3D 0; + s->regs[RCPU_RCPU_BLK_RST] =3D 0xffffffff; + s->regs[RCPU_LSIO_BLK_RST] =3D 0xffffffff; + s->regs[RCPU_PLL_RCPU_EN] =3D PLL_EN; + s->regs[RCPU_PLL_NOCC_EN] =3D PLL_EN; + s->regs[RCPU_PLL_HSIO_EN] =3D 0; + s->regs[RCPU_PLL_MM_EN] =3D 0; + s->regs[RCPU_PLL1_MM_EN] =3D 0; + s->regs[RCPU_PLL_I2S_EN] =3D 0; + s->regs[RCPU_PLL_PCIE_EN] =3D 0; + s->regs[RCPU_PLL_HSIO_CFG] =3D PLL_RESET_VAL(0, 1, 2, 1, 50, 0); + s->regs[RCPU_PLL_PCIE_CFG] =3D PLL_RESET_VAL(0, 2, 3, 1, 250, 0); + s->regs[RCPU_BOOT_MODE_CFG] =3D RCPU_BOOT_MODE_SD; + s->regs[RCPU_PLL_MM_CFG] =3D PLL_RESET_VAL(0, 1, 2, 1, 50, 1); + s->regs[RCPU_PLL1_MM_CFG] =3D PLL_RESET_VAL(0, 1, 2, 1, 50, 1); + s->regs[RCPU_PLL_I2S_CFG] =3D PLL_RESET_VAL(0, 1, 6, 6, 33, 0); + s->regs[RCPU_I2S_DIV_CFG] =3D 0xde69ad31; + s->regs[RCPU_BUS_CFG] =3D NOCC_PLL_BUS_CG_EN | HSIO_PLL_BUS_CG_EN; +} + +static void tt_atlantis_prcm_ddrc_reset(DeviceState *dev) +{ + TTAtlantisPRCMState *s =3D TT_ATLANTIS_PRCM(dev); + tt_atlantis_prcm_reset(dev); + + s->regs[DDRC_STAT] =3D 0x1; + s->regs[DDRC_DFISTAT] =3D 0x1; + s->regs[DDRC_SWSTAT] =3D 0x1; +} + +static void tt_atlantis_prcm_hsio_reset(DeviceState *dev) +{ + TTAtlantisPRCMState *s =3D TT_ATLANTIS_PRCM(dev); + tt_atlantis_prcm_reset(dev); + + s->regs[HSIO_HSIO_DIV_CFG] =3D 0x20821731; + s->regs[HSIO_HSIO_DIV_CFG1] =3D 0x8; + s->regs[HSIO_HSIO_BLK_CG] =3D 0; + s->regs[HSIO_HSIO_BLK_RST] =3D 0; + s->regs[HSIO_HSIO_GMAC_DIV_CFG] =3D 0; +} + +static void tt_atlantis_prcm_pcie_reset(DeviceState *dev) +{ + TTAtlantisPRCMState *s =3D TT_ATLANTIS_PRCM(dev); + tt_atlantis_prcm_reset(dev); + + s->regs[PCIE_SUBS_RST_CTL] =3D 0; + s->regs[PCIE_SUBS_CG_CTL] =3D 0; + s->regs[PCIE_SUBS_CK_CTL] =3D 0x44908; +} + +static void tt_atlantis_prcm_mm_reset(DeviceState *dev) +{ + TTAtlantisPRCMState *s =3D TT_ATLANTIS_PRCM(dev); + tt_atlantis_prcm_reset(dev); + + s->regs[MM_MM_CLK_GATE_CFG] =3D 0; + s->regs[MM_MM_CLK_DIV_CFG] =3D 0xddc8312; + s->regs[MM_MM_CLK_SEL_CFG] =3D 0; + s->regs[MM_MM_RSTN] =3D 0; + s->regs[MM_MM_CLK_DIV_CFG1] =3D 0x333; +} + +static void tt_atlantis_prcm_unrealize(DeviceState *dev) +{ + TTAtlantisPRCMState *s =3D TT_ATLANTIS_PRCM(dev); + + g_free(s->regs); +} + +static void tt_atlantis_prcm_class_init(ObjectClass *klass, + const void *data) { + DeviceClass *dc =3D DEVICE_CLASS(klass); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_CLASS(klass); + + dc->realize =3D tt_atlantis_prcm_realize; + dc->unrealize =3D tt_atlantis_prcm_unrealize; + device_class_set_legacy_reset(dc, tt_atlantis_prcm_reset); + dc->desc =3D "Tenstorrent Atlantis PRCM Controller"; + c->ops =3D &tt_atlantis_prcm_ops; +} + +static void tt_atlantis_prcm_rcpu_class_init(ObjectClass *klass, + const void *data) { + DeviceClass *dc =3D DEVICE_CLASS(klass); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_CLASS(klass); + + dc->realize =3D tt_atlantis_prcm_realize; + device_class_set_legacy_reset(dc, tt_atlantis_prcm_rcpu_reset); + dc->desc =3D "Tenstorrent Atlantis RCPU PRCM Controller"; + c->domain =3D PRCM_DOMAIN_RCPU; + c->regs_size =3D RCPU_DOMAIN_SIZE; + c->ops =3D &tt_atlantis_prcm_rcpu_ops; +} + +static void tt_atlantis_prcm_hsio_class_init(ObjectClass *klass, + const void *data) { + DeviceClass *dc =3D DEVICE_CLASS(klass); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_CLASS(klass); + + dc->realize =3D tt_atlantis_prcm_realize; + device_class_set_legacy_reset(dc, tt_atlantis_prcm_hsio_reset); + dc->desc =3D "Tenstorrent Atlantis HSIO PRCM Controller"; + c->domain =3D PRCM_DOMAIN_HSIO; + c->regs_size =3D HSIO_DOMAIN_SIZE; + c->ops =3D &tt_atlantis_prcm_ops; +} + +static void tt_atlantis_prcm_pcie_class_init(ObjectClass *klass, + const void *data) { + DeviceClass *dc =3D DEVICE_CLASS(klass); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_CLASS(klass); + + dc->realize =3D tt_atlantis_prcm_realize; + device_class_set_legacy_reset(dc, tt_atlantis_prcm_pcie_reset); + dc->desc =3D "Tenstorrent Atlantis PCIE PRCM Controller"; + c->domain =3D PRCM_DOMAIN_PCIE; + c->regs_size =3D PCIE_DOMAIN_SIZE; + c->ops =3D &tt_atlantis_prcm_ops; +} + +static void tt_atlantis_prcm_mm_class_init(ObjectClass *klass, + const void *data) { + DeviceClass *dc =3D DEVICE_CLASS(klass); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_CLASS(klass); + + dc->realize =3D tt_atlantis_prcm_realize; + device_class_set_legacy_reset(dc, tt_atlantis_prcm_mm_reset); + dc->desc =3D "Tenstorrent Atlantis MM PRCM Controller"; + c->domain =3D PRCM_DOMAIN_MM; + c->regs_size =3D MM_DOMAIN_SIZE; + c->ops =3D &tt_atlantis_prcm_ops; +} + +static void tt_atlantis_prcm_ddrc0_class_init(ObjectClass *klass, + const void *data) { + DeviceClass *dc =3D DEVICE_CLASS(klass); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_CLASS(klass); + + dc->realize =3D tt_atlantis_prcm_realize; + device_class_set_legacy_reset(dc, tt_atlantis_prcm_ddrc_reset); + dc->desc =3D "Tenstorrent Atlantis DDR Memory Controller 0 PRCM"; + c->domain =3D PRCM_DOMAIN_DDRC0; + c->regs_size =3D DDRC0_DOMAIN_SIZE; + c->ops =3D &tt_atlantis_prcm_ops; +} + +static void tt_atlantis_prcm_ddrc1_class_init(ObjectClass *klass, + const void *data) { + DeviceClass *dc =3D DEVICE_CLASS(klass); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_CLASS(klass); + + dc->realize =3D tt_atlantis_prcm_realize; + device_class_set_legacy_reset(dc, tt_atlantis_prcm_ddrc_reset); + dc->desc =3D "Tenstorrent Atlantis DDR Memory Controller 1 PRCM"; + c->domain =3D PRCM_DOMAIN_DDRC1; + c->regs_size =3D DDRC1_DOMAIN_SIZE; + c->ops =3D &tt_atlantis_prcm_ops; +} + +static const TypeInfo tt_atlantis_prcm_types[] =3D { + { + .name =3D TYPE_TT_ATLANTIS_PRCM, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(TTAtlantisPRCMState), + .class_init =3D tt_atlantis_prcm_class_init, + .class_size =3D sizeof(TTAtlantisPRCMClass), + .abstract =3D true, + }, + { + .name =3D TYPE_TT_ATLANTIS_PRCM_RCPU, + .parent =3D TYPE_TT_ATLANTIS_PRCM, + .class_init =3D tt_atlantis_prcm_rcpu_class_init, + }, + { + .name =3D TYPE_TT_ATLANTIS_PRCM_HSIO, + .parent =3D TYPE_TT_ATLANTIS_PRCM, + .class_init =3D tt_atlantis_prcm_hsio_class_init, + }, + { + .name =3D TYPE_TT_ATLANTIS_PRCM_PCIE, + .parent =3D TYPE_TT_ATLANTIS_PRCM, + .class_init =3D tt_atlantis_prcm_pcie_class_init, + }, + { + .name =3D TYPE_TT_ATLANTIS_PRCM_MM, + .parent =3D TYPE_TT_ATLANTIS_PRCM, + .class_init =3D tt_atlantis_prcm_mm_class_init, + }, + { + .name =3D TYPE_TT_ATLANTIS_PRCM_DDRC0, + .parent =3D TYPE_TT_ATLANTIS_PRCM, + .class_init =3D tt_atlantis_prcm_ddrc0_class_init, + }, + { + .name =3D TYPE_TT_ATLANTIS_PRCM_DDRC1, + .parent =3D TYPE_TT_ATLANTIS_PRCM, + .class_init =3D tt_atlantis_prcm_ddrc1_class_init, + }, +}; + +DEFINE_TYPES(tt_atlantis_prcm_types); diff --git a/include/hw/misc/tt_atlantis_prcm.h b/include/hw/misc/tt_atlant= is_prcm.h new file mode 100644 index 0000000000..acb8a9b38b --- /dev/null +++ b/include/hw/misc/tt_atlantis_prcm.h @@ -0,0 +1,51 @@ +/* + * Clock, Reset, Pinctrl PRCM in Tenstorrent Atlantis SoC + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright 2026 Tenstorrent + */ + +#ifndef TT_ATLANTIS_PRCM_H +#define TT_ATLANTIS_PRCM_H + +#include "hw/core/sysbus.h" + +#define TYPE_TT_ATLANTIS_PRCM "tt.atlantis.prcm" +#define TYPE_TT_ATLANTIS_PRCM_RCPU "tt.atlantis.prcm.rcpu" +#define TYPE_TT_ATLANTIS_PRCM_HSIO "tt.atlantis.prcm.hsio" +#define TYPE_TT_ATLANTIS_PRCM_PCIE "tt.atlantis.prcm.pcie" +#define TYPE_TT_ATLANTIS_PRCM_MM "tt.atlantis.prcm.mm" +#define TYPE_TT_ATLANTIS_PRCM_DDRC0 "tt.atlantis.prcm.ddrc0" +#define TYPE_TT_ATLANTIS_PRCM_DDRC1 "tt.atlantis.prcm.ddrc1" +OBJECT_DECLARE_TYPE(TTAtlantisPRCMState, TTAtlantisPRCMClass, + TT_ATLANTIS_PRCM); + + +enum { + PRCM_DOMAIN_RCPU =3D 0, + PRCM_DOMAIN_HSIO =3D 1, + PRCM_DOMAIN_PCIE =3D 2, + PRCM_DOMAIN_MM =3D 3, + PRCM_DOMAIN_DDRC0 =3D 4, + PRCM_DOMAIN_DDRC1 =3D 5, + PRCM_DOMAIN_COUNT =3D 6 +}; + +struct TTAtlantisPRCMState { + SysBusDevice parent; + + MemoryRegion mmio; + + uint32_t *regs; +}; + +struct TTAtlantisPRCMClass { + SysBusDeviceClass parent_class; + + uint32_t domain; + uint32_t regs_size; + const MemoryRegionOps *ops; +}; + +#endif --=20 2.43.0 From nobody Mon Sep 28 02:03:02 2026 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=oss.tenstorrent.com ARC-Seal: i=1; a=rsa-sha256; t=1785345264; cv=none; d=zohomail.com; s=zohoarc; b=kCXo9IIVasw8NCi/BI+llluotLTrio3jKUOew5vKigk5sapKfP3Pr5I7AS0HGHCFbefh/NO/1NU5IfnzRLk0xyaf95njEzCu7U/wSe10C+9suqopihzDbvhWFDfO4imozuu5XxfsAwdDnHHE1D9ftc0gT83kaY8JvtaIQq6PLLo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785345264; h=Content-Type: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=ppq2yvLCCTSrKiVeyWJBcNiUf2UQKbqgbIV7qU6O82s=; b=GaRm4noowNt1UKNDAxfyLuIZZy9x1b+Ojg+dwKA4/khuKcShJUlaUCBGfy+8dCb3dpbfkA0df1WFhquUv0LIw8o6iup030LOQsrEkj5CaP24M2IcgJ2/3lNM73sxj7rgdj338xtKQhp1tLY9RRIjirYwyl2q/W8L4vjxx+RFMTo= 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785345264306100.69017986288372; Wed, 29 Jul 2026 10:14:24 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wp7qh-0006EX-1R; Wed, 29 Jul 2026 13:13:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wp672-0007lq-AW for qemu-devel@nongnu.org; Wed, 29 Jul 2026 11:22:28 -0400 Received: from mail-oa1-x2b.google.com ([2001:4860:4864:20::2b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wp670-0006qC-5j for qemu-devel@nongnu.org; Wed, 29 Jul 2026 11:22:28 -0400 Received: by mail-oa1-x2b.google.com with SMTP id 586e51a60fabf-44cf70de986so459256fac.0 for ; Wed, 29 Jul 2026 08:22:25 -0700 (PDT) Received: from [10.200.56.99] ([12.55.13.134]) by smtp.gmail.com with ESMTPSA id 586e51a60fabf-458867fb651sm2476451fac.11.2026.07.29.08.22.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Jul 2026 08:22:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tenstorrent.com; s=google; t=1785338544; x=1785943344; darn=nongnu.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=ppq2yvLCCTSrKiVeyWJBcNiUf2UQKbqgbIV7qU6O82s=; b=RW1xKaK8QDPzZPd7crN5VFM61iKoiaGvuA70EIykwacU2P987p059sYc2sOYTQL/FI dylLffN48+jnQJvE3hDDSOR85ov5tliAK79ulzy81baoxS4RqPUPBcy+r8xVnZ0nXb/+ 6B4Xedv7fcoh0VlpuGebi89FajTNXuN8NXh0Kmu06TYozUeWvgI75tihoMh9RGM3hyGr tpBSt6efVzIbWqKr07JACh+7uMmzo70j+56TU7927MmRH1dBB9KvOUOgWjd405vJCX0c xRPzV0CNxkyylv3bSfZLPD41+5ZOjDFUnbAJgy/4KPYGS8dsO3QPnJiftDP9KxwBtmo8 Qtcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785338544; x=1785943344; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=ppq2yvLCCTSrKiVeyWJBcNiUf2UQKbqgbIV7qU6O82s=; b=FgJSgd2K+5gLXtwPFG6DPE0zHiuFQBvhJFbNrxue81tSXxAfxi/u8OUyku7wqUkPSK c9s8PYSjahJvDBb8oM8bKS8A4PPlf6C8iSzEPOhU5yAe1BXH2zR4Dxl7fgB7HFOHZUx/ B6iTjiKMC/qpiNW2VQwxH2cISUSArKwB10LwL6qYL/t9ZLvX56Afi5A0uWktI3Ej81j8 DeNYED+OE5rRUqcQSbs99YYkAY3tFC0/32n63rL3VUj6ymXQXNkE/L8d/VKLeKvhZ1bN /3oqzOi5JKlXb5eLyPm+SnMpvSyTZvRFbJzHN1laWBkLiVJpasWqaP7+pJMMGQMBuvCm jb+g== X-Gm-Message-State: AOJu0Yzl6kGiUfvVF1400RnAtfkXVP/TPxCwQ79S5r9IsQNY+m9y3Bnq Wvn5hUJJzJ78+DEvSItHl279WEFPi4R971Hp8XfmpiR1oOxpwhDvhVjhR8x6SgBdXAk= X-Gm-Gg: AR+sD13eo44yDbj4R7Vyd/97uVQ7YLlY4/KBah8JuMeYDstlLE9wNIXjPbMXlHp+Zhw 7Rai2omJGZjp2EtxlfRpShG+ix0kRs6GFmCtlAnJ4J3nJ85iLLp0coHSJNX0vZxrSM8yumrhbp/ AqMz0NEJsvrNJ8BYH8gT7qULAjoMqK/VYth+9xNiEUbbUsxNkup1I/dkcHL03SZqahx0N+cjsNX bCL0slYo2xNooYsoq0s7NrpslZ8FO3GhkCm6pDtz9duJJ1BI5iubMAGNHKYfDePXI2SJg2Kh1VY iwzDXox2GX6KTf+RgQLFf277BtDIEIBx7Bd4f0rD6BPFPsSu+Pop0lV31tGV0PPH625iioL+ha1 s6N91oLKqE3Q8us7OlDpxym4LeckS1qVemp48gaigi4vK1Y0ch+6OZ3HxHS+8S1Oy3nXsOsrsOa q7XY9iz/6V+kutv91B1GvADqSJwQgV0Uwyjj4AugJjzvwniZ+aclRHfPR8MMfwTvDnI4ASbYJ4Z ABeIhhXrzTM3Hp2g1+dxmHLLEuNA5gaVxBcOA== X-Received: by 2002:a05:6870:f14a:b0:448:558c:d821 with SMTP id 586e51a60fabf-4586cff6fcbmr4053403fac.36.1785338544420; Wed, 29 Jul 2026 08:22:24 -0700 (PDT) From: Anirudh Srinivasan Date: Wed, 29 Jul 2026 10:21:35 -0500 Subject: [PATCH 2/2] hw/riscv/tt-atlantis: Add PRCMs to tt-atlantis model MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260729-atlantis_prcm-v1-2-502882933e51@oss.tenstorrent.com> References: <20260729-atlantis_prcm-v1-0-502882933e51@oss.tenstorrent.com> In-Reply-To: <20260729-atlantis_prcm-v1-0-502882933e51@oss.tenstorrent.com> To: qemu-devel@nongnu.org Cc: Joel Stanley , Nicholas Piggin , Michael Ellerman , Portia Stephens , qemu-riscv@nongnu.org, Pierrick Bouvier , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Chao Liu , Anirudh Srinivasan X-Mailer: b4 0.15.1 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=lists1p.gnu.org; Received-SPF: pass client-ip=2001:4860:4864:20::2b; envelope-from=asrinivasan@tenstorrent.com; helo=mail-oa1-x2b.google.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_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Wed, 29 Jul 2026 13:13:39 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development 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 @tenstorrent.com) X-ZM-MESSAGEID: 1785345266223158500 Atlantis has 4 PRCMs that are visible from S mode by the Ascalon Core (RCPU, HSIO, PCIe and MM). This commit adds these 4 PRCM blocks to the tt-atlantis model, along with necessary device tree nodes for them. Signed-off-by: Anirudh Srinivasan Reviewed-by: Chao Liu --- docs/system/riscv/tt_atlantis.rst | 1 + hw/riscv/tt_atlantis.c | 92 +++++++++++++++++++++++++++++++++++= ++++ include/hw/riscv/tt_atlantis.h | 19 ++++++++ 3 files changed, 112 insertions(+) diff --git a/docs/system/riscv/tt_atlantis.rst b/docs/system/riscv/tt_atlan= tis.rst index 1f2880d617..539c22354f 100644 --- a/docs/system/riscv/tt_atlantis.rst +++ b/docs/system/riscv/tt_atlantis.rst @@ -14,6 +14,7 @@ tt-atlantis QEMU model features * 8-core Ascalon-X CPU Cluster * RISC-V compliant Advanced Interrupt Architecture * 16550A compatible UART +* 4 PRCMs (Clock and Reset Controllers) =20 Known limitations ----------------- diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c index d808bcc11c..17cc5318b3 100644 --- a/hw/riscv/tt_atlantis.c +++ b/hw/riscv/tt_atlantis.c @@ -26,6 +26,7 @@ #include "hw/char/serial-mm.h" #include "hw/intc/riscv_aclint.h" #include "hw/misc/unimp.h" +#include "hw/misc/tt_atlantis_prcm.h" =20 #include "system/system.h" #include "system/device_tree.h" @@ -59,6 +60,10 @@ static const MemMapEntry tt_atlantis_memmap[] =3D { [TT_ATL_I2C3] =3D { 0xd4070000, 0x10000 }, [TT_ATL_I2C4] =3D { 0xd4080000, 0x10000 }, [TT_ATL_UART1] =3D { 0xd4110000, 0x10000 }, + [TT_ATL_PRCM_RCPU] =3D { 0xd0000000, 0x10000 }, + [TT_ATL_PRCM_PCIE] =3D { 0xd8000000, 0x100 }, + [TT_ATL_PRCM_MM] =3D { 0xdc000000, 0x1000 }, + [TT_ATL_PRCM_HSIO] =3D { 0xe00c0000, 0x510 }, [TT_ATL_SAPLIC] =3D { 0xe8000000, 0x4000000 }, [TT_ATL_DDR_HI] =3D { 0x100000000, 0x1000000000 }, }; @@ -328,11 +333,38 @@ static void create_fdt_i2c_device(TTAtlantisState *s,= int bus, qemu_fdt_setprop_cell(fdt, name, "reg", addr); } =20 +static char *create_fdt_prcm(void *fdt, const MemMapEntry *mem, + const char *prcm_name, uint32_t prcm_phandle) +{ + hwaddr base =3D mem->base; + hwaddr size =3D mem->size; + char *name =3D g_strdup_printf("/soc/prcm_%s@%" PRIx64, + prcm_name, mem->base); + g_autofree char *compatible =3D + g_strdup_printf("tenstorrent,atlantis-prcm-%s", prcm_name); + + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", compatible); + qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, base, 2, size); + qemu_fdt_setprop_cell(fdt, name, "#address-cells", 1); + qemu_fdt_setprop_cell(fdt, name, "#size-cells", 0); + qemu_fdt_setprop_cell(fdt, name, "#clock-cells", 1); + qemu_fdt_setprop_cell(fdt, name, "#reset-cells", 1); + qemu_fdt_setprop_cell(fdt, name, "phandle", prcm_phandle); + + return name; +} + static void finalize_fdt(TTAtlantisState *s) { uint32_t aplic_s_phandle =3D next_phandle(); uint32_t imsic_s_phandle =3D next_phandle(); uint32_t periph_clk_phandle =3D next_phandle(); + uint32_t osc_24m_phandle =3D next_phandle(); + uint32_t prcm_rcpu_phandle =3D next_phandle(); + uint32_t prcm_hsio_phandle =3D next_phandle(); + uint32_t prcm_pcie_phandle =3D next_phandle(); + uint32_t prcm_mm_phandle =3D next_phandle(); void *fdt =3D MACHINE(s)->fdt; =20 create_fdt_cpu(s, s->memmap, aplic_s_phandle, imsic_s_phandle); @@ -348,6 +380,33 @@ static void finalize_fdt(TTAtlantisState *s) aplic_s_phandle); =20 create_fdt_clk(fdt, "periph-clk", 100000000, periph_clk_phandle); + create_fdt_clk(fdt, "osc_24m", 24000000, osc_24m_phandle); + + g_autofree char *rcpu_name =3D create_fdt_prcm(fdt, + &s->memmap[TT_ATL_PRCM_RCPU], "rcpu", prcm_rcpu_phandle); + qemu_fdt_setprop_cells(fdt, rcpu_name, "clocks", osc_24m_phandle); + qemu_fdt_setprop_cells(fdt, rcpu_name, "assigned-clocks", + prcm_rcpu_phandle, TT_ATL_CLK_RCPU_ROOT, + prcm_rcpu_phandle, TT_ATL_CLK_NOCC_CLK); + qemu_fdt_setprop_cells(fdt, rcpu_name, "assigned-clock-parents", + prcm_rcpu_phandle, TT_ATL_CLK_RCPU_PLL, + prcm_rcpu_phandle, TT_ATL_CLK_NOC_PLL); + + g_autofree char *hsio_name =3D create_fdt_prcm(fdt, + &s->memmap[TT_ATL_PRCM_HSIO], "hsio", prcm_hsio_phandle); + qemu_fdt_setprop_cells(fdt, hsio_name, "clocks", osc_24m_phandle, + prcm_rcpu_phandle, TT_ATL_CLK_HSIO_PLL); + + g_autofree char *pcie_name =3D create_fdt_prcm(fdt, + &s->memmap[TT_ATL_PRCM_PCIE], "pcie", prcm_pcie_phandle); + qemu_fdt_setprop_cells(fdt, pcie_name, "clocks", osc_24m_phandle, + prcm_rcpu_phandle, TT_ATL_CLK_PCIE_PLL); + + g_autofree char *mm_name =3D create_fdt_prcm(fdt, + &s->memmap[TT_ATL_PRCM_MM], "mm", prcm_mm_phandle); + qemu_fdt_setprop_cells(fdt, mm_name, "clocks", osc_24m_phandle, + prcm_rcpu_phandle, TT_ATL_CLK_MM_PLL0, + prcm_rcpu_phandle, TT_ATL_CLK_MM_PLL1); =20 for (int i =3D 0; i < TT_ATL_NUM_I2C; i++) { create_fdt_i2c(fdt, @@ -545,6 +604,39 @@ static void tt_atlantis_machine_init(MachineState *mac= hine) serial_mm_init(system_memory, s->memmap[TT_ATL_UART1].base, 2, qdev_get_gpio_in(s->irqchip, TT_ATL_UART1_IRQ), 115200, serial_hd(0), DEVICE_LITTLE_ENDIAN); + + /* Add rcpu prcm block */ + object_initialize_child(OBJECT(s), "prcm-rcpu", &s->prcm[0], + TYPE_TT_ATLANTIS_PRCM_RCPU); + sysbus_realize(SYS_BUS_DEVICE(&s->prcm[0]), &error_fatal); + memory_region_add_subregion(system_memory, + s->memmap[TT_ATL_PRCM_RCPU].base, + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->prcm[0]), 0)); + + /* Add hsio prcm block */ + object_initialize_child(OBJECT(s), "prcm-hsio", &s->prcm[1], + TYPE_TT_ATLANTIS_PRCM_HSIO); + sysbus_realize(SYS_BUS_DEVICE(&s->prcm[1]), &error_fatal); + memory_region_add_subregion(system_memory, + s->memmap[TT_ATL_PRCM_HSIO].base, + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->prcm[1]), 0)); + + /* Add pcie prcm block */ + object_initialize_child(OBJECT(s), "prcm-pcie", &s->prcm[2], + TYPE_TT_ATLANTIS_PRCM_PCIE); + sysbus_realize(SYS_BUS_DEVICE(&s->prcm[2]), &error_fatal); + memory_region_add_subregion(system_memory, + s->memmap[TT_ATL_PRCM_PCIE].base, + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->prcm[2]), 0)); + + /* Add mm prcm block */ + object_initialize_child(OBJECT(s), "prcm-mm", &s->prcm[3], + TYPE_TT_ATLANTIS_PRCM_MM); + sysbus_realize(SYS_BUS_DEVICE(&s->prcm[3]), &error_fatal); + memory_region_add_subregion(system_memory, + s->memmap[TT_ATL_PRCM_MM].base, + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->prcm[3]), 0)); + /* * Atlantis contains a DesignWare uart while the QEMU machine * uses the serial_mm model with the base ns16550 register set. diff --git a/include/hw/riscv/tt_atlantis.h b/include/hw/riscv/tt_atlantis.h index 7f7d4a5a59..20bcdfeb52 100644 --- a/include/hw/riscv/tt_atlantis.h +++ b/include/hw/riscv/tt_atlantis.h @@ -13,12 +13,14 @@ #include "hw/core/sysbus.h" #include "hw/i2c/designware_i2c.h" #include "hw/intc/riscv_imsic.h" +#include "hw/misc/tt_atlantis_prcm.h" #include "hw/riscv/riscv_hart.h" =20 #define TYPE_TT_ATLANTIS_MACHINE MACHINE_TYPE_NAME("tt-atlantis") OBJECT_DECLARE_SIMPLE_TYPE(TTAtlantisState, TT_ATLANTIS_MACHINE) =20 #define TT_ATL_NUM_I2C 5 +#define TT_ATL_NUM_PRCM 4 =20 struct TTAtlantisState { /*< private >*/ @@ -31,6 +33,7 @@ struct TTAtlantisState { RISCVHartArrayState soc; DeviceState *irqchip; DesignWareI2CState i2c[TT_ATL_NUM_I2C]; + TTAtlantisPRCMState prcm[TT_ATL_NUM_PRCM]; =20 int fdt_size; }; @@ -59,6 +62,22 @@ enum { TT_ATL_SAPLIC, TT_ATL_SIMSIC, TT_ATL_UART1, + TT_ATL_PRCM_RCPU, + TT_ATL_PRCM_HSIO, + TT_ATL_PRCM_PCIE, + TT_ATL_PRCM_MM, +}; + +/* RCPU PRCM Clock IDs */ +enum { + TT_ATL_CLK_RCPU_PLL =3D 0, + TT_ATL_CLK_RCPU_ROOT =3D 1, + TT_ATL_CLK_NOC_PLL =3D 25, + TT_ATL_CLK_NOCC_CLK =3D 26, + TT_ATL_CLK_HSIO_PLL =3D 54, + TT_ATL_CLK_PCIE_PLL =3D 55, + TT_ATL_CLK_MM_PLL0 =3D 56, + TT_ATL_CLK_MM_PLL1 =3D 57, }; =20 #endif --=20 2.43.0