From nobody Mon Sep 28 00:35:31 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=1786977838; cv=none; d=zohomail.com; s=zohoarc; b=GNdH2PnZrc4b93wVMA1D8Pjr70wBXmKkzxfL0d0lviernXCMws/NYiSQK3AsARQgyyrL1+CpmptorFz+rhxd94YVECSjGRpQ3qjFCf2qsGm+nbVgMkJtXua5WxTiEpnJkStjrYotHknkg87t7yJNEXK+h+Q7psAMaMdgL7tJtuk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786977838; 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=alJGFCIYQuRZDE7syqlJipqloG9nJw+7tRwVw6Xe5fc=; b=YQnaEffdle+HxMUBB/gpTT7tE9LGW/F3/NXbHaDmRaJ0R6gTaMbb8JelW9fBx11BsbauL1rdhzYJeDge5BCd7qGItmmjfEAVCCTshOEKxzttm17+QDsCZa+IgXXg8s5aoUeEJyvCq8NrPgl1Zme3i73ohBKnKIJiq2ZVcgQIGWM= 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 1786977838041431.229545046274; Mon, 17 Aug 2026 07:43:58 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wvyYS-0001IK-7t; Mon, 17 Aug 2026 10:43:12 -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 1wvyYG-0001Ag-UR for qemu-devel@nongnu.org; Mon, 17 Aug 2026 10:43:02 -0400 Received: from mail-yx1-xb12c.google.com ([2607:f8b0:4864:20::b12c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wvyYC-0001MH-QQ for qemu-devel@nongnu.org; Mon, 17 Aug 2026 10:43:00 -0400 Received: by mail-yx1-xb12c.google.com with SMTP id 956f58d0204a3-66c71239c48so4981031d50.2 for ; Mon, 17 Aug 2026 07:42:56 -0700 (PDT) Received: from [10.200.24.109] ([12.55.13.134]) by smtp.gmail.com with ESMTPSA id 956f58d0204a3-66cb47809d1sm904104d50.13.2026.08.17.07.42.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2026 07:42:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tenstorrent.com; s=google; t=1786977776; x=1787582576; 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=alJGFCIYQuRZDE7syqlJipqloG9nJw+7tRwVw6Xe5fc=; b=RCDgMa/lEwUZBsXAB8d5bZV6TIEq/uBBrdTCMWOqTGURfVUQE84meFFeG2Xr8dSYpn 1wn+IHB+LGcS4dVZPIrhPkPhg12JTqsecoitO8R0vy5fjoDLoJGiD0UllKedxWgUchnQ o4KmzMHnMDNrcWyTRwaU1SVg+cbpqSpBYE8uuNlcwYZ0DOiF43vAHBaxnKti1t3YsuCH mdXpvSjz1ERNW+xdal6SJjHEV1oI1are/ccsulfHa4LtlsGz34Fg6mVRoTrgcVB7ehuf z7eKUplcbjye3nXX1uzV8406f6gwtv+Hr+UffAgY9MWmJuBP/5zjRGq1RxzFj3Fn198q 37aw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786977776; x=1787582576; 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=alJGFCIYQuRZDE7syqlJipqloG9nJw+7tRwVw6Xe5fc=; b=lbZK+eMxf+M9N1+WIqItlVSGSt/XbnDsdd6ZyhV97zJTAqpHnH6TYjYBPr6CzkmIb9 qT3/UpYPoTSRNDNbMYwTwfWYxIlRJ2OJ8gQkNGITiqZCT88bpMtnGftx6IW6v5AeIxCi e73Vw0s2+XCDxMna594UGXUl3huEzrQ72jrlZi7YBd2HmfHhPM140Bh8whBnXZBLPGfR wgE2mHKe2BdFavw09VSaQ4fLmXqFWwW6gEl1x1yCK14ZYpLDg/WMfIgasGNazTsgbx7W VO0GrUQjXgR0QpNR9GUBWfP8rcS2AVme++UA3t5blOhmSuNuWEKzB/2R62lQsqi7fP+h UUBw== X-Gm-Message-State: AOJu0Yza36/WQBL9Hsa6AbRLx+AZwCan9NaKVX33DobFZGBgwzklS4Lc 5kMg7uuCRSNUPPG83vudjRYHbLzCVRt/t5CVBzVOVZ1UzWg9PcahAfQVe0bGZkHEXOw= X-Gm-Gg: AR+sD11UdNS3eCsN6ts0YH6cY7PtcFVDaiBRI/CNEXqvk/C+RuZDpVk+yuW6wJcfc05 8PBIfptwscuRybOyXmDt8/ERhuVRoJge5ftLNyT6NwDwbz9Wfchy8ALBgk7+HJR0p/DG1BJYOky tQLWTbmDgzpldtlVw+tmcm6lpF036dyqXXchEGZ3LCgL2CDQW5KvclLhh96yMdWz0Zq3RV5it9w ihDErCkfQIP6d38FaAP1vXXF0/pdD8qtwKJnSHNAtWroPUbWmUzxoE8kXtzyp5GgKNzTO3vLVHD o9TWX5gzXTI7YzGhi1vNIWP3P78CyN1I/HjEqtBDo/pZsFe6Y/9S8CLfesAifILmdZ7O4KGKZOF gC0l0CydVwAdWYuS4U/O809u2eNT8Y052eR04Ieb89SQhco3ZBdTsW9J1S93/l155HJD5F9LDeD ZXl3jPfqhMBEtv/bhfcVh1A+gjX5tzhTzRAVjjvbcFXMXXROWf9txeR+VMxNHeriDEcdiZS82jc r2X5hzsJPYDPnzh9hnmdbhhFi0R+25f1IIWuKks X-Received: by 2002:a05:690e:5c1:b0:66c:95ef:660c with SMTP id 956f58d0204a3-66cb9ee6c1emr289578d50.52.1786977775553; Mon, 17 Aug 2026 07:42:55 -0700 (PDT) From: Anirudh Srinivasan Date: Mon, 17 Aug 2026 09:42:44 -0500 Subject: [PATCH v2 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: <20260817-atlantis_prcm-v2-1-ffba0b944419@oss.tenstorrent.com> References: <20260817-atlantis_prcm-v2-0-ffba0b944419@oss.tenstorrent.com> In-Reply-To: <20260817-atlantis_prcm-v2-0-ffba0b944419@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=2607:f8b0:4864:20::b12c; envelope-from=asrinivasan@tenstorrent.com; helo=mail-yx1-xb12c.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-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: 1786977841443158500 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 | 442 +++++++++++++++++++++++++++++++++= ++++ include/hw/misc/tt_atlantis_prcm.h | 51 +++++ 5 files changed, 500 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..571f2a08fe --- /dev/null +++ b/hw/misc/tt_atlantis_prcm.c @@ -0,0 +1,442 @@ +/* + * 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); + + 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; + } + + trace_tt_atlantis_prcm_write(c->domain, offset, data); + + s->regs[TO_REG(offset)] =3D data; +} + +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); + + uint32_t pll_reg_offset; + switch (TO_REG(offset)) { + case RCPU_PLL_RCPU_EN: + pll_reg_offset =3D RCPU_PLL_RCPU_CFG; + break; + case RCPU_PLL_NOCC_EN: + pll_reg_offset =3D RCPU_PLL_NOCC_CFG; + break; + case RCPU_PLL_HSIO_EN: + pll_reg_offset =3D RCPU_PLL_HSIO_CFG; + break; + case RCPU_PLL_PCIE_EN: + pll_reg_offset =3D RCPU_PLL_PCIE_CFG; + break; + case RCPU_PLL_MM_EN: + pll_reg_offset =3D RCPU_PLL_MM_CFG; + break; + case RCPU_PLL1_MM_EN: + pll_reg_offset =3D RCPU_PLL1_MM_CFG; + break; + case RCPU_PLL_I2S_EN: + pll_reg_offset =3D RCPU_PLL_I2S_CFG; + break; + default: + return; + } + + 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_hold(Object *obj, ResetType type) +{ + TTAtlantisPRCMState *s =3D TT_ATLANTIS_PRCM(obj); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_GET_CLASS(s); + + memset(s->regs, 0, c->regs_size); +} + +static void tt_atlantis_prcm_rcpu_reset_hold(Object *obj, ResetType type) +{ + TTAtlantisPRCMState *s =3D TT_ATLANTIS_PRCM(obj); + tt_atlantis_prcm_reset_hold(obj, type); + + 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); /* Value from Datasheet */ + s->regs[RCPU_RCPU_DIV_CFG] =3D (0xb8c2 << 1); /* Value from Datasheet = */ + 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; /* Value from Datasheet */ + s->regs[RCPU_BUS_CFG] =3D NOCC_PLL_BUS_CG_EN | HSIO_PLL_BUS_CG_EN; +} + +static void tt_atlantis_prcm_ddrc_reset_hold(Object *obj, ResetType type) +{ + TTAtlantisPRCMState *s =3D TT_ATLANTIS_PRCM(obj); + tt_atlantis_prcm_reset_hold(obj, type); + + 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_hold(Object *obj, ResetType type) +{ + TTAtlantisPRCMState *s =3D TT_ATLANTIS_PRCM(obj); + tt_atlantis_prcm_reset_hold(obj, type); + + s->regs[HSIO_HSIO_DIV_CFG] =3D 0x20821731; /* Value from Datasheet */ + s->regs[HSIO_HSIO_DIV_CFG1] =3D 0x8; /* Value from Datasheet */ + 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_hold(Object *obj, ResetType type) +{ + TTAtlantisPRCMState *s =3D TT_ATLANTIS_PRCM(obj); + tt_atlantis_prcm_reset_hold(obj, type); + + s->regs[PCIE_SUBS_RST_CTL] =3D 0; + s->regs[PCIE_SUBS_CG_CTL] =3D 0; + s->regs[PCIE_SUBS_CK_CTL] =3D 0x44908; /* Value from Datasheet */ +} + +static void tt_atlantis_prcm_mm_reset_hold(Object *obj, ResetType type) +{ + TTAtlantisPRCMState *s =3D TT_ATLANTIS_PRCM(obj); + tt_atlantis_prcm_reset_hold(obj, type); + + s->regs[MM_MM_CLK_GATE_CFG] =3D 0; + s->regs[MM_MM_CLK_DIV_CFG] =3D 0xddc8312; /* Value from Datasheet */ + 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; /* Value from Datasheet */ +} + +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); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_CLASS(klass); + + dc->realize =3D tt_atlantis_prcm_realize; + dc->unrealize =3D tt_atlantis_prcm_unrealize; + dc->desc =3D "Tenstorrent Atlantis PRCM Controller"; + rc->phases.hold =3D tt_atlantis_prcm_reset_hold; + 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); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_CLASS(klass); + + dc->realize =3D tt_atlantis_prcm_realize; + dc->desc =3D "Tenstorrent Atlantis RCPU PRCM Controller"; + rc->phases.hold =3D tt_atlantis_prcm_rcpu_reset_hold; + 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); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_CLASS(klass); + + dc->realize =3D tt_atlantis_prcm_realize; + dc->desc =3D "Tenstorrent Atlantis HSIO PRCM Controller"; + rc->phases.hold =3D tt_atlantis_prcm_hsio_reset_hold; + 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); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_CLASS(klass); + + dc->realize =3D tt_atlantis_prcm_realize; + dc->desc =3D "Tenstorrent Atlantis PCIE PRCM Controller"; + rc->phases.hold =3D tt_atlantis_prcm_pcie_reset_hold; + 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); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_CLASS(klass); + + dc->realize =3D tt_atlantis_prcm_realize; + dc->desc =3D "Tenstorrent Atlantis MM PRCM Controller"; + rc->phases.hold =3D tt_atlantis_prcm_mm_reset_hold; + 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); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_CLASS(klass); + + dc->realize =3D tt_atlantis_prcm_realize; + dc->desc =3D "Tenstorrent Atlantis DDR Memory Controller 0 PRCM"; + rc->phases.hold =3D tt_atlantis_prcm_ddrc_reset_hold; + 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); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + TTAtlantisPRCMClass *c =3D TT_ATLANTIS_PRCM_CLASS(klass); + + dc->realize =3D tt_atlantis_prcm_realize; + dc->desc =3D "Tenstorrent Atlantis DDR Memory Controller 1 PRCM"; + rc->phases.hold =3D tt_atlantis_prcm_ddrc_reset_hold; + 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..dc7938433a --- /dev/null +++ b/include/hw/misc/tt_atlantis_prcm.h @@ -0,0 +1,51 @@ +/* + * PRCM (Clock and Reset Controller) 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 00:35:31 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=1786977838; cv=none; d=zohomail.com; s=zohoarc; b=joQwCoRjKKd/8zRSV9etf59xjVZsk73GZU6C35K1UfSbSJqHoBHVBR1vPuC65e8wsJ2xLAwV1XdtZUqcfTrTZM+p5FMYP1JHf1oCpz6c4kwtOYqOQJcbWam05P/XM8zu/RcdXHXEA27vVXMzVQtjsgWHhh9fE7Iw02Qb5T8lBgI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786977838; 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=lUZygXbR06TzNWyfkLlWTpBjMNElR72c8NKVbTiS+EA=; b=ZZthiriY11/9SoRt5+fJqTLmQ5Vfxf44ogl16O6pkS47XVLl4tQ+91ch8Lf7+WP6ThrVLzOudemJ1zzpNUlbB6J/4f+RL7LQi9b11E9NioT002GGfYPm0TtFWW+YB3014OkWkt19aYtE/bb507BelOp3rHg7utRiRDUcJzrH51A= 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 1786977838040333.0559866443731; Mon, 17 Aug 2026 07:43:58 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wvyYT-0001LD-0v; Mon, 17 Aug 2026 10:43:13 -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 1wvyYI-0001Bb-Pe for qemu-devel@nongnu.org; Mon, 17 Aug 2026 10:43:03 -0400 Received: from mail-yx1-xb131.google.com ([2607:f8b0:4864:20::b131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wvyYE-0001MS-SY for qemu-devel@nongnu.org; Mon, 17 Aug 2026 10:43:01 -0400 Received: by mail-yx1-xb131.google.com with SMTP id 956f58d0204a3-66c70e2904dso3735938d50.1 for ; Mon, 17 Aug 2026 07:42:57 -0700 (PDT) Received: from [10.200.24.109] ([12.55.13.134]) by smtp.gmail.com with ESMTPSA id 956f58d0204a3-66cb47809d1sm904104d50.13.2026.08.17.07.42.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2026 07:42:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tenstorrent.com; s=google; t=1786977776; x=1787582576; 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=lUZygXbR06TzNWyfkLlWTpBjMNElR72c8NKVbTiS+EA=; b=O4kPRzchHts2/QzDuIPEunZquPna4tNL66TyjF1R1okqx+ld3iwU7MsxSAFsyoTrKy 8Jn1PVIkX2hcz8mq/4nOAnHM+0qta9yXoxeQ9A48jXttJhsF6RKYlYRchLj27/PkmLFU s15mFvCMSsl0M6mIhKrBJt0JopyYu0EJqU02DJEL12t0dHAjN+Qv9meUAhDUA7t5zcUk WDeiwioWQHNNnJcteYHiVr8NV4Eog6QdWagy5a7zutCffh6+3HomVF91r0S1ktYNByCD 9jF1x++BfUYrj3QaX85tuUjwbf/KlrSFAbeP3xjAfYOQZYzmIyqSvYZtu6dRsHcItIKT HfZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786977777; x=1787582577; 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=lUZygXbR06TzNWyfkLlWTpBjMNElR72c8NKVbTiS+EA=; b=mc/wTrD6hNsU8apoF9Bvwo811FpwOzwylo8X6nIv1XBMBkFXdQv3W6Z8dDaqUXZrmX XgjxYYhNlopwZ9COToO6fnBMnbZIBFY1iMZzQ2Sw9QgkG5DAty9JZxLavTindJ8xzoeO Es3DLXNazFhwuWWr8NkeMzEfM5DqXPeD0m9bBnamjcq6iRpXjU8LHhL8C2rqRqTuEPAz /mCahka97e9vtBirCVp4dg/95Qi3Su8MdCdasdGWUihp9QvKxT0IGfgoS8nfU+odEQ3e i3L7VUkY1QgUn0GDGO9p0P3HCb0je9BBGr2aibHJ9EL08LEg0DIJL/y7KSlLmZWtCJnf QZBQ== X-Gm-Message-State: AOJu0Yz/HoQ2RoOoGPXWO/VfqEMc6g0/6bGU0+2eOSs+gf3dZ+m+0e8a 8VH6L0beCIZLld8Gy8SsluIx4omyhqdIapYqNoYQDu7utaY2X/wBmqeD1YCw779NZzU= X-Gm-Gg: AR+sD13Wh+cQfXcXrktYHxSKbrey7wruCdUO9CBI3FZf85FzAH47bAtIenCgp3bWDvV 6eWws1Dftsfq2wFUBNF2VmzcrOZCqU1wIEeB8nard6v3FHTcEpMo0cHbAfeb/51r6S8IgO2oIm9 OE+FjhAUHcmCjsvovQJHjKTp5peCfqh9XwTSt1awnO4NGZvLuJInCs3n+rTVGjOJw9/X0pHprGJ dd7P+wFXrfHG5RDu2xn0wbfHoR1lCjctww3I1MsnNKk1GlNeZjRXZChIYDkHU4C3EeXbhxWzoh7 QQmqyqIk5k21/szYE/Yce04/TbWjdMvR9w56DimDpXfXlpkPHPobUvqrxcoPOLqXrlXqXekyI1J ce8wQzJJIc6noB0VdcNwDJSEWNir28vSw+H00sjMVLsOQH6a9k53hr5KOJQkuU8GBgqq1fwQvkS cuaZnmWYqXsyZj1EBR9jXq2R7fy8I042g33gcOJj23WUOgajdrPaaHs9NHg/ojSd9Rxk5d3slYh 8oX9uvpbNcHxqI+dptWpRtxnfVrE6bp9RTe0Ic= X-Received: by 2002:a53:a68f:0:b0:668:42d:95e5 with SMTP id 956f58d0204a3-66c72b1889emr6244101d50.4.1786977776556; Mon, 17 Aug 2026 07:42:56 -0700 (PDT) From: Anirudh Srinivasan Date: Mon, 17 Aug 2026 09:42:45 -0500 Subject: [PATCH v2 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: <20260817-atlantis_prcm-v2-2-ffba0b944419@oss.tenstorrent.com> References: <20260817-atlantis_prcm-v2-0-ffba0b944419@oss.tenstorrent.com> In-Reply-To: <20260817-atlantis_prcm-v2-0-ffba0b944419@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=2607:f8b0:4864:20::b131; envelope-from=asrinivasan@tenstorrent.com; helo=mail-yx1-xb131.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-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: 1786977841383158500 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. Reviewed-by: Chao Liu Signed-off-by: Anirudh Srinivasan --- docs/system/riscv/tt_atlantis.rst | 1 + hw/riscv/tt_atlantis.c | 94 +++++++++++++++++++++++++++++++++++= ++++ include/hw/riscv/tt_atlantis.h | 19 ++++++++ 3 files changed, 114 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..9ebba07703 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,35 @@ 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) +{ + 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", next_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; void *fdt =3D MACHINE(s)->fdt; =20 create_fdt_cpu(s, s->memmap, aplic_s_phandle, imsic_s_phandle); @@ -348,6 +377,34 @@ 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 =3D qemu_fdt_get_phandle(fdt, rcpu_name); + 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"); + 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"); + 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"); + 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 +602,43 @@ 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