From nobody Sat Sep 26 23:53:29 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=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1787060209; cv=none; d=zohomail.com; s=zohoarc; b=OB29qcYT7j4+4ZFFVFassv5LF0xKg6QaGS52IETQK6dBDHLwddqMz6rHmpC2b21ZdkGc4fT2S7ZC6y7mTySun2pfzkNfkyc3kH6Z/bfrKUgz6GlPB6RHODBdiHYKr67RrqIYL5o46YMTjbZtWJYLzGLia58540XxIjxqs4bZjws= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787060209; 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=ki+xSPvUgBrBrI8Ss6GvcQspar8xjRjj8AwaEbWah3s=; b=aynvdHoEvhxEmivfD5uygNcPvUdrEx2tgTE6XZVvSSn4a6iCPOVdFIqChLHKF/v9wI7i4f2UmKVCpAN6spD6Fe2tNPWVxnJ90RnOPLSqWE2Nh2CSEuBOi/fpPvU3KEcpqe7eP2pLCrb4t/JQ/UQXgJjmkRBD+01HxljRT4I0k5Q= 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=<0860734llx@gmail.com> (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787060209775192.5748691014611; Tue, 18 Aug 2026 06:36:49 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wwJzG-0007Cb-Md; Tue, 18 Aug 2026 09:36:18 -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 <0860734llx@gmail.com>) id 1wwJz6-00073Y-KI for qemu-devel@nongnu.org; Tue, 18 Aug 2026 09:36:08 -0400 Received: from mail-pl1-x62d.google.com ([2607:f8b0:4864:20::62d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <0860734llx@gmail.com>) id 1wwJz2-0000f4-FF for qemu-devel@nongnu.org; Tue, 18 Aug 2026 09:36:08 -0400 Received: by mail-pl1-x62d.google.com with SMTP id d9443c01a7336-2cca0c5799eso43003845ad.0 for ; Tue, 18 Aug 2026 06:36:03 -0700 (PDT) Received: from [172.17.0.5] ([42.193.175.155]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2d5d014d965sm8066845ad.35.2026.08.18.06.35.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Aug 2026 06:36:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787060163; x=1787664963; 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=ki+xSPvUgBrBrI8Ss6GvcQspar8xjRjj8AwaEbWah3s=; b=SJHyOQxySdrbm106POSZv7Vb+uYXeFA3jGrIIRgdIOwGLuxOhcMLlz6+KaUdhe6zC2 LVrrOWBdQMRw+qpg9khJL5tGpePD4BaxYabXafLBxmrv8kYo/XgUDzr5+MhUDonXnSU0 4w7uIhCm6Vepvm+3lHRHrVbr11AomqIesnoJhjNCIRCbzWhypbx6i/6CKyOC3RmISOnU raNyNqgk/nUH9qcpWLj2mAMDEzja2ppAhlnafG0pOGziE645X292DGaRmM1NRzs3udsm EIDiKMzETUEheQ+mh6fMRhB1lZRO92NnyryIVaVFRfvM1E5UUN3vnD+y3pGhcmIxcrtI qBLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787060163; x=1787664963; 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=ki+xSPvUgBrBrI8Ss6GvcQspar8xjRjj8AwaEbWah3s=; b=T5ZPHS30spPV65fPAMJ1jFnWtIdTSgNRc7byr/CG+2VGPqkCBbHVr1f6MljDrwEbTv MXrEqnVrSLYpraIyA5teK3CvZ1xclZ4X/3qYcFObm1CqZiTz3tTYiJpPM0aHkmFLlXsh rDT/Qahz6qPpIkwsGRd2CDW7hBO8pap2Xegs0BJGoVYsU6Ee50pvqefpRkfhutyiXphc nGyre8QsHv2wIyB+z74dvLBTHRWJjqK3KRaNFlaPRQCbQEmrIEuu1Iz1LbELmmhYn3Ss WwPq7NOMwiwit7f3P+ZsmsJEJl6sI7009jGwr4FUVFZz2nkCkOhCrzy/0BBBDJg9b7S+ CUPQ== X-Gm-Message-State: AOJu0YypWguGQdU3si/YY+g23aVP/RJVybz7olJFS8ryYkXAeDVM5lHA e3DpDgY/g3dKJCov+pYr4GyUgpwpxSHPs/1U36qADRhKZIZnOW6ZSr03 X-Gm-Gg: AR+sD10+FkCqaQB755q0soakDvYS6nInfcrGBEUYur2p49A4UFfvEu3DLb+jmjLv7VA vJ6LtBNuySJu0E1Iv95l1EKew1hrb6EL6eyhIE1SB5jauGc3T+zBkxgpWiJqlbQTr8IqBuIjPrK 3L0rFy2k/8z+kloXOJ0lvJdx5f7yChpj3wWo/MADmaO9wMM2TEpJbT9DokPgIYTXc7pflTrGf+2 vruCUuWzroCvdpBeq12O3bztAElkrydp1FMjSsehE8eXhF9GCJz56zxUZaYT/mROxkC7dBcrYAH dNuyEO4QWXc7I9d9j8JuApDXeQ4+kcNQ9ORCC1YjqDCq6sLJNgEppv6LvwC0a3Xqw+xxBYAXBcJ cQY4tHctBGf/9awAT9S9ZRWwzVXOxat0VsMwahxKgGIp0hVcJT+9lCedqH3TO1Tl1pUziLGT6Gt Vr2FLCDgYAPsZ/XgdyDV+AioJUBRTmGfo3K4nAGoFbxf46G3u+9jEREqCXqXr4qjOyVC7qOAWFk aQtnHR7bPu9M6Vhq7bs6Dg= X-Received: by 2002:a17:903:40d1:b0:2d5:cb05:49e0 with SMTP id d9443c01a7336-2d5cb055046mr110695555ad.12.1787060162343; Tue, 18 Aug 2026 06:36:02 -0700 (PDT) From: Simon Law <0860734llx@gmail.com> Date: Tue, 18 Aug 2026 21:35:50 +0800 Subject: [PATCH v2 1/4] hw/misc: model K230 CMU registers MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260818-feat-k230-cmu-v2-1-57eadb98f40f@gmail.com> References: <20260818-feat-k230-cmu-v2-0-57eadb98f40f@gmail.com> In-Reply-To: <20260818-feat-k230-cmu-v2-0-57eadb98f40f@gmail.com> To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Chao Liu , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , qemu-riscv@nongnu.org, Fabiano Rosas , Laurent Vivier , Pierrick Bouvier X-Mailer: b4 0.16.0 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::62d; envelope-from=0860734llx@gmail.com; helo=mail-pl1-x62d.google.com X-Spam_score_int: -13 X-Spam_score: -1.4 X-Spam_bar: - X-Spam_report: (-1.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, FROM_STARTS_WITH_NUMS=0.738, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, UPPERCASE_50_75=0.008 autolearn=no 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 @gmail.com) X-ZM-MESSAGEID: 1787060212058158500 Signed-off-by: Simon Law <0860734llx@gmail.com> --- MAINTAINERS | 3 + hw/misc/Kconfig | 3 + hw/misc/k230_cmu.c | 903 +++++++++++++++++++++++++++++++++++++++++= ++++ hw/misc/meson.build | 1 + hw/misc/trace-events | 9 + hw/riscv/Kconfig | 1 + include/hw/misc/k230_cmu.h | 58 +++ 7 files changed, 978 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 6171cc7494..2666e4d56a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1825,9 +1825,12 @@ L: qemu-riscv@nongnu.org S: Maintained F: docs/system/riscv/k230.rst F: hw/riscv/k230.c +F: hw/misc/k230_cmu.c F: hw/watchdog/k230_wdt.c +F: include/hw/misc/k230_cmu.h F: include/hw/riscv/k230.h F: include/hw/watchdog/k230_wdt.h +F: tests/qtest/k230-cmu-test.c F: tests/qtest/k230-wdt-test.c =20 RX Machines diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig index 1543ee6653..58a0421e84 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -101,6 +101,9 @@ config FSL_IMX8MP_ANALOG config FSL_IMX8MP_CCM bool =20 +config K230_CMU + bool + config STM32_RCC bool =20 diff --git a/hw/misc/k230_cmu.c b/hw/misc/k230_cmu.c new file mode 100644 index 0000000000..bbf01dd925 --- /dev/null +++ b/hw/misc/k230_cmu.c @@ -0,0 +1,903 @@ +/* + * Kendryte K230 Clock Management Unit + * + * Copyright (c) 2026 Simon Law <0860734llx@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Emulates the K230 PLL and system-clock register protocol. It models + * software-visible reset values, masks, write strobes, and PLL lock state, + * but does not provide cycle-accurate clocks or propagate QEMU Clock sign= als. + * + * K230 Technical Reference Manual V0.3.1 (2024-11-18): + * https://github.com/revyos/external-docs/blob/master/K230/en-us/K230_Tec= hnical_Reference_Manual_V0.3.1_20241118.pdf + * + * For more information, see + */ + +#include "qemu/osdep.h" +#include "hw/core/sysbus.h" +#include "hw/core/registerfields.h" +#include "migration/vmstate.h" +#include "qemu/log.h" +#include "qemu/module.h" +#include "qom/object.h" + +#include "hw/misc/k230_cmu.h" +#include "trace.h" + +REG32(CMU_CFG0, 0x00) + FIELD(CMU_CFG0, PLL_OUT_DIV, 24, 4) + FIELD(CMU_CFG0, PLL_REF_DIV, 16, 6) + FIELD(CMU_CFG0, PLL_FB_DIV, 0, 13) + +REG32(CMU_CFG1, 0x04) + FIELD(CMU_CFG1, PLL_BYPASS, 19, 1) + FIELD(CMU_CFG1, PLL_TEST, 18, 1) + FIELD(CMU_CFG1, PLL_ENSAT, 17, 1) + FIELD(CMU_CFG1, PLL_FASTEN, 16, 1) + FIELD(CMU_CFG1, PLL_BWADJ, 0, 12) + +REG32(CMU_CTL, 0x08) + FIELD(CMU_CTL, PLL_LOCK_TIM, 4, 8) + FIELD(CMU_CTL, PLL_CLK_OE, 2, 1) + FIELD(CMU_CTL, PLL_INIT, 1, 1) + FIELD(CMU_CTL, PLL_PWRDWN, 0, 1) + +REG32(CMU_STAT, 0x0c) + FIELD(CMU_STAT, PLL_FSM_STAT, 4, 2) + FIELD(CMU_STAT, PLL_RESERVED, 3, 1) + FIELD(CMU_STAT, PLL_FB_SLIP, 2, 1) + FIELD(CMU_STAT, PLL_REF_SLIP, 1, 1) + FIELD(CMU_STAT, PLL_LOCK, 0, 1) + +#define PLL_CFG0_RW_MASK (R_CMU_CFG0_PLL_OUT_DIV_MASK | \ + R_CMU_CFG0_PLL_REF_DIV_MASK | \ + R_CMU_CFG0_PLL_FB_DIV_MASK) +#define PLL_CFG1_RW_MASK (R_CMU_CFG1_PLL_BYPASS_MASK | \ + R_CMU_CFG1_PLL_TEST_MASK | \ + R_CMU_CFG1_PLL_ENSAT_MASK | \ + R_CMU_CFG1_PLL_FASTEN_MASK | \ + R_CMU_CFG1_PLL_BWADJ_MASK) +#define PLL_CTL_RW_MASK (R_CMU_CTL_PLL_LOCK_TIM_MASK | \ + R_CMU_CTL_PLL_CLK_OE_MASK) +#define PLL_CTL_W1T_MASK (R_CMU_CTL_PLL_INIT_MASK | \ + R_CMU_CTL_PLL_PWRDWN_MASK) +#define PLL_CTL_LOW_MASK (PLL_CTL_RW_MASK | PLL_CTL_W1T_MASK) +#define PLL_STAT_RO_MASK (R_CMU_STAT_PLL_FSM_STAT_MASK | \ + R_CMU_STAT_PLL_RESERVED_MASK | \ + R_CMU_STAT_PLL_FB_SLIP_MASK | \ + R_CMU_STAT_PLL_REF_SLIP_MASK | \ + R_CMU_STAT_PLL_LOCK_MASK) + +REG32(SYSCLK_CPU0_CLK_CFG, 0x000) + FIELD(SYSCLK_CPU0_CLK_CFG, CORE_CLK_ROOT_GDIV_UPD, 31, 1) + FIELD(SYSCLK_CPU0_CLK_CFG, PCLK_DIV, 15, 3) + FIELD(SYSCLK_CPU0_CLK_CFG, TDI_PCLK_EN, 14, 1) + /* FIXME: SDK get_leaf_en() reads bit 7 for this gate; */ + /* TRM says bit 13. */ + FIELD(SYSCLK_CPU0_CLK_CFG, PCLK_ENABLE, 13, 1) + FIELD(SYSCLK_CPU0_CLK_CFG, PLICLK_DIV, 10, 3) + FIELD(SYSCLK_CPU0_CLK_CFG, PLICLK_ENABLE, 9, 1) + FIELD(SYSCLK_CPU0_CLK_CFG, ACLK_DIV, 6, 3) + FIELD(SYSCLK_CPU0_CLK_CFG, CORE_CLK_ROOT_DIV, 1, 4) + FIELD(SYSCLK_CPU0_CLK_CFG, CORE_CLK_ENABLE, 0, 1) +REG32(SYSCLK_CPU1_CLK_CFG, 0x004) + FIELD(SYSCLK_CPU1_CLK_CFG, CORE_CLK_DIV_UPD, 31, 1) + FIELD(SYSCLK_CPU1_CLK_CFG, PCLK_ENABLE, 19, 1) + FIELD(SYSCLK_CPU1_CLK_CFG, PLICLK_DIV, 16, 3) + FIELD(SYSCLK_CPU1_CLK_CFG, PLICLK_ENABLE, 15, 1) + FIELD(SYSCLK_CPU1_CLK_CFG, ACLK_DIV, 12, 3) + FIELD(SYSCLK_CPU1_CLK_CFG, CORE_CLK_ROOT_DIV, 3, 3) + FIELD(SYSCLK_CPU1_CLK_CFG, CORE_CLK_SEL, 1, 2) + FIELD(SYSCLK_CPU1_CLK_CFG, CORE_CLK_ENABLE, 0, 1) +REG32(SYSCLK_AI_CLK_CFG, 0x008) + FIELD(SYSCLK_AI_CLK_CFG, CLK_DIV_UPD, 31, 1) + FIELD(SYSCLK_AI_CLK_CFG, ACLK_ENABLE, 10, 1) + FIELD(SYSCLK_AI_CLK_CFG, CLK_CDIV, 3, 3) + FIELD(SYSCLK_AI_CLK_CFG, CLK_SEL, 2, 1) + FIELD(SYSCLK_AI_CLK_CFG, CLK_ENABLE, 0, 1) +REG32(SYSCLK_VPU_CLK_CFG, 0x00c) + FIELD(SYSCLK_VPU_CLK_CFG, CLK_GDIV_UPD, 31, 1) + FIELD(SYSCLK_VPU_CLK_CFG, CFGCLK_ROOT_DIV, 11, 4) + FIELD(SYSCLK_VPU_CLK_CFG, CFGCLK_ENABLE, 10, 1) + FIELD(SYSCLK_VPU_CLK_CFG, ACLK_ROOT_DIV, 6, 4) + FIELD(SYSCLK_VPU_CLK_CFG, ACLK_ENABLE, 5, 1) + FIELD(SYSCLK_VPU_CLK_CFG, CLK_DIV, 1, 4) + FIELD(SYSCLK_VPU_CLK_CFG, CLK_EN, 0, 1) +REG32(SYSCLK_PMU_CLK_CFG, 0x010) + FIELD(SYSCLK_PMU_CLK_CFG, CLK_EN, 0, 1) +REG32(SYSCLK_HS_CLKEN_CFG, 0x018) + FIELD(SYSCLK_HS_CLKEN_CFG, SSI2_ACLK_ENABLE, 30, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SSI1_ACLK_ENABLE, 29, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, QSPI_ACLK_ENABLE, 28, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SSI0_ACLK_ENABLE, 27, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SSI2_CLK_ENABLE, 26, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SSI1_CLK_ENABLE, 25, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SSI0_CLK_ENABLE, 24, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, USB_REFCLK_SEL, 23, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, USB1_REFCLK_ENABLE, 22, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, USB0_REFCLK_ENABLE, 21, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SD1_TMCLK_ENABLE, 20, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SD1_CCLK_ENABLE, 19, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SD1_BCLK_ENABLE, 18, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SD1_ACLK_ENABLE, 17, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SD0_TMCLK_ENABLE, 16, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SD0_CCLK_ENABLE, 15, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SD0_BCLK_ENABLE, 14, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SD0_ACLK_ENABLE, 13, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SD_TMCLK_ENABLE, 12, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SD_CCLK_ENABLE, 11, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SD_BCLK_ENABLE, 10, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SD_ACLK_ENABLE, 9, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SSI2_HCLK_ENABLE, 8, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SSI1_HCLK_ENABLE, 7, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SSI0_HCLK_ENABLE, 6, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, USB1_HCLK_ENABLE, 5, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, USB0_HCLK_ENABLE, 4, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SD1_HCLK_ENABLE, 3, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, SD0_HCLK_ENABLE, 2, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, HCLK_HIGH_ENABLE, 1, 1) + FIELD(SYSCLK_HS_CLKEN_CFG, HCLK_ENABLE, 0, 1) +REG32(SYSCLK_HS_SDCLK_CFG, 0x01c) + FIELD(SYSCLK_HS_SDCLK_CFG, ACLK_ROOT_CDIV_UPD, 31, 1) + FIELD(SYSCLK_HS_SDCLK_CFG, TMCLK_DIV, 15, 5) + /* FIXME: SDK get_leaf_rate() uses ACLK_ROOT_DIV for SD CCLK, */ + /* not bits 14:12. */ + FIELD(SYSCLK_HS_SDCLK_CFG, CCLK_DIV, 12, 3) + FIELD(SYSCLK_HS_SDCLK_CFG, BCLK_DIV, 9, 3) + FIELD(SYSCLK_HS_SDCLK_CFG, ACLK_ROOT_DIV, 6, 3) + FIELD(SYSCLK_HS_SDCLK_CFG, HCLK_DIV, 3, 3) + FIELD(SYSCLK_HS_SDCLK_CFG, HCLK_HIGH_ROOT_DIV, 0, 3) +REG32(SYSCLK_HS_SPI_CFG, 0x020) + FIELD(SYSCLK_HS_SPI_CFG, SSI0_ACLK_ROOT_CDIV_UPD, 31, 1) + FIELD(SYSCLK_HS_SPI_CFG, SSI0_CLK_SEL, 18, 1) + FIELD(SYSCLK_HS_SPI_CFG, USB_REFCLK_50M_DIV, 15, 3) + FIELD(SYSCLK_HS_SPI_CFG, QSPI_ACLK_ROOT_DIV, 12, 3) + FIELD(SYSCLK_HS_SPI_CFG, SSI0_ACLK_DIV, 9, 3) + FIELD(SYSCLK_HS_SPI_CFG, SSI2_CLK_DIV, 6, 3) + FIELD(SYSCLK_HS_SPI_CFG, SSI1_CLK_DIV, 3, 3) +REG32(SYSCLK_LS_CLKEN_CFG0, 0x024) + FIELD(SYSCLK_LS_CLKEN_CFG0, PDM_CLK_ENABLE, 31, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, CODEC_MCLK_DAC_ENABLE, 30, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, CODEC_MCLK_ADC_ENABLE, 29, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, AUD_DEV_CLK_ENABLE, 28, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, GPIO_DBCLK_ENABLE, 27, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, ADC_CLK_ENABLE, 26, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, I2C4_CLK_ENABLE, 25, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, I2C3_CLK_ENABLE, 24, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, I2C2_CLK_ENABLE, 23, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, I2C1_CLK_ENABLE, 22, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, I2C0_CLK_ENABLE, 21, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, UART4_CLK_ENABLE, 20, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, UART3_CLK_ENABLE, 19, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, UART2_CLK_ENABLE, 18, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, UART1_CLK_ENABLE, 17, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, UART0_CLK_ENABLE, 16, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, ADC_PCLK_ENABLE, 15, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, CODEC_PCLK_ENABLE, 14, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, AUD_DEV_PCLK_ENABLE, 13, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, PWM_PCLK_ENABLE, 12, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, GPIO_PCLK_ENABLE, 11, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, I2C4_PCLK_ENABLE, 10, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, I2C3_PCLK_ENABLE, 9, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, I2C2_PCLK_ENABLE, 8, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, I2C1_PCLK_ENABLE, 7, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, I2C0_PCLK_ENABLE, 6, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, UART4_PCLK_ENABLE, 5, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, UART3_PCLK_ENABLE, 4, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, UART2_PCLK_ENABLE, 3, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, UART1_PCLK_ENABLE, 2, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, UART0_PCLK_ENABLE, 1, 1) + FIELD(SYSCLK_LS_CLKEN_CFG0, PCLK_ENABLE, 0, 1) +REG32(SYSCLK_LS_CLKEN_CFG1, 0x028) + FIELD(SYSCLK_LS_CLKEN_CFG1, JAMLINK3_PCLK_ENABLE, 7, 1) + FIELD(SYSCLK_LS_CLKEN_CFG1, JAMLINK2_PCLK_ENABLE, 6, 1) + FIELD(SYSCLK_LS_CLKEN_CFG1, JAMLINK1_PCLK_ENABLE, 5, 1) + FIELD(SYSCLK_LS_CLKEN_CFG1, JAMLINK0_PCLK_ENABLE, 4, 1) + FIELD(SYSCLK_LS_CLKEN_CFG1, JAMLINK3_CO_ENABLE, 3, 1) + FIELD(SYSCLK_LS_CLKEN_CFG1, JAMLINK2_CO_ENABLE, 2, 1) + FIELD(SYSCLK_LS_CLKEN_CFG1, JAMLINK1_CO_ENABLE, 1, 1) + FIELD(SYSCLK_LS_CLKEN_CFG1, JAMLINK0_CO_ENABLE, 0, 1) +REG32(SYSCLK_UART_I2C_CLKDIV_CFG, 0x02c) + FIELD(SYSCLK_UART_I2C_CLKDIV_CFG, I2C0_CLK_CDIV_UPD, 31, 1) + FIELD(SYSCLK_UART_I2C_CLKDIV_CFG, I2C4_CLK_DIV, 27, 3) + FIELD(SYSCLK_UART_I2C_CLKDIV_CFG, I2C3_CLK_DIV, 24, 3) + FIELD(SYSCLK_UART_I2C_CLKDIV_CFG, I2C2_CLK_DIV, 21, 3) + FIELD(SYSCLK_UART_I2C_CLKDIV_CFG, I2C1_CLK_DIV, 18, 3) + FIELD(SYSCLK_UART_I2C_CLKDIV_CFG, I2C0_CLK_DIV, 15, 3) + FIELD(SYSCLK_UART_I2C_CLKDIV_CFG, UART4_SCLK_DIV, 12, 3) + FIELD(SYSCLK_UART_I2C_CLKDIV_CFG, UART3_SCLK_DIV, 9, 3) + FIELD(SYSCLK_UART_I2C_CLKDIV_CFG, UART2_SCLK_DIV, 6, 3) + FIELD(SYSCLK_UART_I2C_CLKDIV_CFG, UART1_SCLK_DIV, 3, 3) + FIELD(SYSCLK_UART_I2C_CLKDIV_CFG, UART0_SCLK_DIV, 0, 3) +REG32(SYSCLK_LS_CLKDIV_CFG, 0x030) + FIELD(SYSCLK_LS_CLKDIV_CFG, JAMLINK_CO_CDIV_UPD, 31, 1) + FIELD(SYSCLK_LS_CLKDIV_CFG, JAMLINK_CO_DIV, 23, 8) + FIELD(SYSCLK_LS_CLKDIV_CFG, GPIO_DBCLK_DIV, 13, 10) + FIELD(SYSCLK_LS_CLKDIV_CFG, ADC_CLK_DIV, 3, 10) + FIELD(SYSCLK_LS_CLKDIV_CFG, PCLK_DIV, 0, 3) +/* + * SDK sysctl_clk_t marks offsets 0x034..0x044 reserved; the TRM defines + * these registers, so the TRM layout is authoritative for the v1 model. + */ +REG32(SYSCLK_AUDIO_CLKDIV_CFG, 0x034) + FIELD(SYSCLK_AUDIO_CLKDIV_CFG, AUD_DEV_CLK_FDIV_UPD, 31, 1) + FIELD(SYSCLK_AUDIO_CLKDIV_CFG, AUDIO_CLK_STEP, 16, 15) + FIELD(SYSCLK_AUDIO_CLKDIV_CFG, AUDIO_CLK_SUM, 0, 16) +REG32(SYSCLK_CODEC_ADC_MCLKDIV_CFG, 0x038) + FIELD(SYSCLK_CODEC_ADC_MCLKDIV_CFG, MCLK_ADC_FDIV_UPD, 31, 1) + FIELD(SYSCLK_CODEC_ADC_MCLKDIV_CFG, MCLK_ADC_STEP, 14, 13) + FIELD(SYSCLK_CODEC_ADC_MCLKDIV_CFG, MCLK_ADC_SUM, 0, 14) +REG32(SYSCLK_CODEC_DAC_MCLKDIV_CFG, 0x03c) + FIELD(SYSCLK_CODEC_DAC_MCLKDIV_CFG, MCLK_DAC_FDIV_UPD, 31, 1) + FIELD(SYSCLK_CODEC_DAC_MCLKDIV_CFG, MCLK_DAC_STEP, 14, 13) + FIELD(SYSCLK_CODEC_DAC_MCLKDIV_CFG, MCLK_DAC_SUM, 0, 14) +REG32(SYSCLK_PDM_CLKDIV_CFG0, 0x040) + FIELD(SYSCLK_PDM_CLKDIV_CFG0, CLK_SUM, 0, 17) +REG32(SYSCLK_PDM_CLKDIV_CFG1, 0x044) + FIELD(SYSCLK_PDM_CLKDIV_CFG1, CLK_FDIV_UPD, 31, 1) + FIELD(SYSCLK_PDM_CLKDIV_CFG1, CLK_STEP, 0, 16) +REG32(SYSCLK_SYSCTL_CLKEN_CFG, 0x050) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, HDI_CLK_ENABLE, 21, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, IOMUX_PCLK_ENABLE, 20, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, STC_CLK_EN, 19, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, TIMER5_CLK_ENABLE, 18, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, TIMER4_CLK_ENABLE, 17, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, TIMER3_CLK_ENABLE, 16, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, TIMER2_CLK_ENABLE, 15, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, TIMER1_CLK_ENABLE, 14, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, TIMER0_CLK_ENABLE, 13, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, TIMER5_CLK_SEL, 12, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, TIMER4_CLK_SEL, 11, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, TIMER3_CLK_SEL, 10, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, TIMER2_CLK_SEL, 9, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, TIMER1_CLK_SEL, 8, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, TIMER0_CLK_SEL, 7, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, WDT1_CLK_ENABLE, 6, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, WDT0_CLK_ENABLE, 5, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, MAILBOX_PCLK_ENABLE, 4, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, TIMER_PCLK_ENABLE, 3, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, WDT1_PCLK_ENABLE, 2, 1) + FIELD(SYSCLK_SYSCTL_CLKEN_CFG, WDT0_PCLK_ENABLE, 1, 1) +REG32(SYSCLK_TIMER_CLK_CFG, 0x054) + FIELD(SYSCLK_TIMER_CLK_CFG, CLK0_CDIV_UPD, 31, 1) + FIELD(SYSCLK_TIMER_CLK_CFG, CLK5_DIV, 15, 3) + FIELD(SYSCLK_TIMER_CLK_CFG, CLK4_DIV, 12, 3) + FIELD(SYSCLK_TIMER_CLK_CFG, CLK3_DIV, 9, 3) + FIELD(SYSCLK_TIMER_CLK_CFG, CLK2_DIV, 6, 3) + FIELD(SYSCLK_TIMER_CLK_CFG, CLK1_DIV, 3, 3) + FIELD(SYSCLK_TIMER_CLK_CFG, CLK0_DIV, 0, 3) +REG32(SYSCLK_SYSCTL_CLK_DIV_CFG, 0x058) + FIELD(SYSCLK_SYSCTL_CLK_DIV_CFG, PCLK_CDIV_UPD, 31, 1) + FIELD(SYSCLK_SYSCTL_CLK_DIV_CFG, HDI_CLK_DIV, 28, 3) + FIELD(SYSCLK_SYSCTL_CLK_DIV_CFG, TS_CLK_DIV, 20, 8) + FIELD(SYSCLK_SYSCTL_CLK_DIV_CFG, STC_CLK_DIV, 15, 5) + FIELD(SYSCLK_SYSCTL_CLK_DIV_CFG, WDT1_CLK_DIV, 9, 6) + FIELD(SYSCLK_SYSCTL_CLK_DIV_CFG, WDT0_CLK_DIV, 3, 6) +REG32(SYSCLK_SHRM_CLK_CFG, 0x05c) + FIELD(SYSCLK_SHRM_CLK_CFG, PCLK_ROOT_DIV_UPD, 31, 1) + FIELD(SYSCLK_SHRM_CLK_CFG, PCLK_ROOT_DIV, 18, 3) + FIELD(SYSCLK_SHRM_CLK_CFG, SRAM_CLK_SEL, 14, 1) + FIELD(SYSCLK_SHRM_CLK_CFG, AXIM_BRIDGE_CLK_EN, 13, 1) + FIELD(SYSCLK_SHRM_CLK_CFG, AXIM_CLK_EN, 12, 1) + FIELD(SYSCLK_SHRM_CLK_CFG, AXIS_CLK_EN, 11, 1) + FIELD(SYSCLK_SHRM_CLK_CFG, SRAM_ACLK_ENABLE, 10, 1) + FIELD(SYSCLK_SHRM_CLK_CFG, NONAI2D_ACLK_ENABLE, 9, 1) + FIELD(SYSCLK_SHRM_CLK_CFG, NONAI2D_PCLK_ENABLE, 8, 1) + FIELD(SYSCLK_SHRM_CLK_CFG, DECOMPRESS_ACLK_ENABLE, 7, 1) + FIELD(SYSCLK_SHRM_CLK_CFG, DECOMPRESS_PCLK_ENABLE, 6, 1) + FIELD(SYSCLK_SHRM_CLK_CFG, GSDMA_ACLK_ENABLE, 5, 1) + FIELD(SYSCLK_SHRM_CLK_CFG, GSDMA_PCLK_ENABLE, 4, 1) + FIELD(SYSCLK_SHRM_CLK_CFG, PERI_DMA_ACLK_ENABLE, 3, 1) + FIELD(SYSCLK_SHRM_CLK_CFG, PERI_DMA_PCLK_ENABLE, 2, 1) + FIELD(SYSCLK_SHRM_CLK_CFG, PCLK_ENABLE, 0, 1) +REG32(SYSCLK_DDR_CLK_CFG, 0x060) + FIELD(SYSCLK_DDR_CLK_CFG, CORE_CLK_CDIV_UPD, 31, 1) + FIELD(SYSCLK_DDR_CLK_CFG, PCLK_DIV, 14, 4) + FIELD(SYSCLK_DDR_CLK_CFG, CORE_CLK_DIV, 10, 4) + FIELD(SYSCLK_DDR_CLK_CFG, PCLK_ENABLE, 9, 1) + FIELD(SYSCLK_DDR_CLK_CFG, BYPASSPCLK_ENABLE, 8, 1) + FIELD(SYSCLK_DDR_CLK_CFG, AXI4CLK_ENABLE, 7, 1) + FIELD(SYSCLK_DDR_CLK_CFG, AXI3CLK_ENABLE, 6, 1) + FIELD(SYSCLK_DDR_CLK_CFG, AXI2CLK_ENABLE, 5, 1) + FIELD(SYSCLK_DDR_CLK_CFG, AXI1CLK_ENABLE, 4, 1) + FIELD(SYSCLK_DDR_CLK_CFG, AXI0CLK_ENABLE, 3, 1) + FIELD(SYSCLK_DDR_CLK_CFG, CLK_ENABLE, 2, 1) + FIELD(SYSCLK_DDR_CLK_CFG, CLK_SEL, 0, 2) +/* + * SDK sysctl_clk_t marks offsets 0x064..0x078 reserved; the TRM defines + * these registers, so the TRM layout is authoritative for the v1 model. + */ +REG32(SYSCLK_ISP_CLKEN_CFG, 0x064) + FIELD(SYSCLK_ISP_CLKEN_CFG, DW_ACLK_ENABLE, 19, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, DW_HCLK_ENABLE, 18, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, MCM_CLK_ENABLE, 17, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, VSE_CLK_ENABLE, 16, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, DWE_CLK_ENABLE, 15, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, ACLK_ENABLE, 14, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, HCLK_ENABLE, 13, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, CLK_ENABLE, 12, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, CSI2_PCLK_ENABLE, 11, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, CSI1_PCLK_ENABLE, 10, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, CSI0_PCLK_ENABLE, 9, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, CSI2_PIXELCLK_ENABLE, 8, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, CSI1_PIXELCLK_ENABLE, 7, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, CSI0_PIXELCLK_ENABLE, 6, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, DPHY_PCLK_ENABLE, 5, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, CFG2_CLK_ENABLE, 4, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, CFG1_CLK_ENABLE, 3, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, CFG0_CLK_ENABLE, 2, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, PCLK_ENABLE, 1, 1) + FIELD(SYSCLK_ISP_CLKEN_CFG, CSIPHY_CFGCLK_ENABLE, 0, 1) +REG32(SYSCLK_ISP_CLKDIV_CFG, 0x068) + FIELD(SYSCLK_ISP_CLKDIV_CFG, CFG_CLK_CDIV_UPD, 31, 1) + FIELD(SYSCLK_ISP_CLKDIV_CFG, CLK_SEL, 29, 1) + FIELD(SYSCLK_ISP_CLKDIV_CFG, CLK_DIV, 26, 3) + FIELD(SYSCLK_ISP_CLKDIV_CFG, PCLK_DIV, 23, 3) + FIELD(SYSCLK_ISP_CLKDIV_CFG, CSI2_PIXEL_CLK_DIV, 17, 6) + FIELD(SYSCLK_ISP_CLKDIV_CFG, CSI1_PIXEL_CLK_DIV, 11, 6) + FIELD(SYSCLK_ISP_CLKDIV_CFG, CSI0_PIXEL_CLK_DIV, 5, 6) + FIELD(SYSCLK_ISP_CLKDIV_CFG, CFG_CLK_DIV, 0, 5) +REG32(SYSCLK_MCLK_CFG, 0x06c) + FIELD(SYSCLK_MCLK_CFG, MCLK0_CDIV_UPD, 31, 1) + FIELD(SYSCLK_MCLK_CFG, MCLK2_DIV, 19, 5) + FIELD(SYSCLK_MCLK_CFG, MCLK2_SEL, 17, 2) + FIELD(SYSCLK_MCLK_CFG, MCLK1_DIV, 12, 5) + FIELD(SYSCLK_MCLK_CFG, MCLK1_SEL, 10, 2) + FIELD(SYSCLK_MCLK_CFG, MCLK0_DIV, 5, 5) + FIELD(SYSCLK_MCLK_CFG, MCLK0_SEL, 3, 2) + FIELD(SYSCLK_MCLK_CFG, MCLK2_ENABLE, 2, 1) + FIELD(SYSCLK_MCLK_CFG, MCLK1_ENABLE, 1, 1) + FIELD(SYSCLK_MCLK_CFG, MCLK0_ENABLE, 0, 1) +REG32(SYSCLK_DPU_CLK_CFG, 0x070) + FIELD(SYSCLK_DPU_CLK_CFG, CLK_DIV_UPD, 31, 1) + FIELD(SYSCLK_DPU_CLK_CFG, PCLK_DIV, 7, 3) + FIELD(SYSCLK_DPU_CLK_CFG, CLK_DIV, 3, 4) + FIELD(SYSCLK_DPU_CLK_CFG, PCLK_ENABLE, 2, 1) + FIELD(SYSCLK_DPU_CLK_CFG, ACLK_ENABLE, 1, 1) + FIELD(SYSCLK_DPU_CLK_CFG, CLK_ENABLE, 0, 1) +REG32(SYSCLK_VO_CLK_CFG, 0x074) + FIELD(SYSCLK_VO_CLK_CFG, ACLK_GPU_EN, 12, 1) + FIELD(SYSCLK_VO_CLK_CFG, ACLK_VO_EN, 11, 1) + FIELD(SYSCLK_VO_CLK_CFG, HCLK_GPU_EN, 10, 1) + FIELD(SYSCLK_VO_CLK_CFG, PCLK_DSI_PHY_EN, 9, 1) + FIELD(SYSCLK_VO_CLK_CFG, PCLK_DSI_ENABLE, 8, 1) + FIELD(SYSCLK_VO_CLK_CFG, PCLK_VO_ENABLE, 7, 1) + FIELD(SYSCLK_VO_CLK_CFG, CLK_GPU_ENABLE, 6, 1) + FIELD(SYSCLK_VO_CLK_CFG, CLKEXT_ENABLE, 5, 1) + FIELD(SYSCLK_VO_CLK_CFG, CFGCLK_ENABLE, 4, 1) + FIELD(SYSCLK_VO_CLK_CFG, REFCLK_ENABLE, 3, 1) + FIELD(SYSCLK_VO_CLK_CFG, DPIPCLK_ENABLE, 2, 1) + FIELD(SYSCLK_VO_CLK_CFG, ACLK_ENABLE, 1, 1) + FIELD(SYSCLK_VO_CLK_CFG, HCLK_ENABLE, 0, 1) +REG32(SYSCLK_DISP_CLK_DIV, 0x078) + FIELD(SYSCLK_DISP_CLK_DIV, HCLK_ROOT_CDIV_UPD, 31, 1) + FIELD(SYSCLK_DISP_CLK_DIV, CLK_GPU_DIV, 20, 4) + FIELD(SYSCLK_DISP_CLK_DIV, CLKEXT_DIV, 16, 4) + FIELD(SYSCLK_DISP_CLK_DIV, CFGCLK_DIV, 11, 5) + FIELD(SYSCLK_DISP_CLK_DIV, DPIPCLK_DIV, 3, 8) + FIELD(SYSCLK_DISP_CLK_DIV, HCLK_ROOT_DIV, 0, 3) +REG32(SYSCLK_SEC_CLK_DIV, 0x080) + FIELD(SYSCLK_SEC_CLK_DIV, PCLK_DIV_UPD, 31, 1) + FIELD(SYSCLK_SEC_CLK_DIV, ACLK_DIV, 11, 3) + FIELD(SYSCLK_SEC_CLK_DIV, FIXCLK_DIV, 6, 5) + FIELD(SYSCLK_SEC_CLK_DIV, FIXCLK_ENABLE, 5, 1) + FIELD(SYSCLK_SEC_CLK_DIV, ACLK_ENABLE, 4, 1) + FIELD(SYSCLK_SEC_CLK_DIV, PCLK_DIV, 1, 3) + FIELD(SYSCLK_SEC_CLK_DIV, PCLK_ENABLE, 0, 1) +REG32(SYSCLK_USB_TEST_CLK_DIV, 0x100) + FIELD(SYSCLK_USB_TEST_CLK_DIV, CLK480_CDIV_UPD, 31, 1) + FIELD(SYSCLK_USB_TEST_CLK_DIV, CLK100_DIV, 4, 3) + FIELD(SYSCLK_USB_TEST_CLK_DIV, CLK480_DIV, 1, 3) + FIELD(SYSCLK_USB_TEST_CLK_DIV, TEST_CLK_ENABLE, 0, 1) +REG32(SYSCLK_DPHY_TEST_CLK_DIV, 0x104) + FIELD(SYSCLK_DPHY_TEST_CLK_DIV, TEST_CLK_CDIV_UPD, 31, 1) + FIELD(SYSCLK_DPHY_TEST_CLK_DIV, TEST_CLK_DIV, 1, 4) + FIELD(SYSCLK_DPHY_TEST_CLK_DIV, TEST_CLK_ENABLE, 0, 1) +/* + * The TRM v0.3.1 sysclk summary ends at 0x104. Linux and the SDK both + * access SPI2AXI_CLK_DIV at 0x108, so v1 preserves this software ABI + * exception. + */ +REG32(SYSCLK_SPI2AXI_CLK_DIV, 0x108) + FIELD(SYSCLK_SPI2AXI_CLK_DIV, CLK_DIV_UPD, 31, 1) + FIELD(SYSCLK_SPI2AXI_CLK_DIV, CLK_DIV, 1, 3) + FIELD(SYSCLK_SPI2AXI_CLK_DIV, CLK_ENABLE, 0, 1) + +typedef struct K230PllRegDesc { + hwaddr offset; + const char *name; + uint32_t reset[K230_PLL_COUNT]; + uint32_t rw_mask; + uint32_t ro_mask; + uint32_t w1t_mask; + uint8_t write_enable_shift; + uint32_t write_enable_mask; +} K230PllRegDesc; + +typedef struct K230SysclkRegDesc { + hwaddr offset; + const char *name; + uint32_t reset; + uint32_t rw_mask; + uint32_t w1t_mask; +} K230SysclkRegDesc; + +static const K230PllRegDesc k230_pll_regs[] =3D { + { + .offset =3D A_CMU_CFG0, + .name =3D "PLLx_CFG0", + .reset =3D { + 0x0102018f, 0x00000062, 0x00070378, 0x0102018f, + }, + .rw_mask =3D PLL_CFG0_RW_MASK, + }, + { + .offset =3D A_CMU_CFG1, + .name =3D "PLLx_CFG1", + .reset =3D { + 0x000200c7, 0x00020031, 0x000201bb, 0x000200c7, + }, + .rw_mask =3D PLL_CFG1_RW_MASK, + }, + { + .offset =3D A_CMU_CTL, + .name =3D "PLLx_CTL", + .reset =3D { + 0x00000034, 0x00000034, 0x00000034, 0x00000074, + }, + .rw_mask =3D PLL_CTL_RW_MASK, + .w1t_mask =3D PLL_CTL_W1T_MASK, + .write_enable_shift =3D 16, + .write_enable_mask =3D PLL_CTL_LOW_MASK, + }, + { + .offset =3D A_CMU_STAT, + .name =3D "PLLx_STAT", + .reset =3D { + 0x00000021, 0x00000021, 0x00000021, 0x00000021, + }, + .ro_mask =3D PLL_STAT_RO_MASK, + }, +}; + +#define SYSCLK_REG(_reg, _name, _reset, _rw, _w1t) \ + { .offset =3D A_ ## _reg, .name =3D _name, .reset =3D _reset, \ + .rw_mask =3D (_rw), .w1t_mask =3D (_w1t) } + +static const K230SysclkRegDesc k230_sysclk_regs[] =3D { + SYSCLK_REG(SYSCLK_CPU0_CLK_CFG, "CPU0_CLK_CFG", 0x0000e65f, + 0x0003ffdf, R_SYSCLK_CPU0_CLK_CFG_CORE_CLK_ROOT_GDIV_UPD_MA= SK), + SYSCLK_REG(SYSCLK_CPU1_CLK_CFG, "CPU1_CLK_CFG", 0x0009900d, + 0x000f803f, R_SYSCLK_CPU1_CLK_CFG_CORE_CLK_DIV_UPD_MASK), + SYSCLK_REG(SYSCLK_AI_CLK_CFG, "AI_CLK_CFG", 0x0000043d, + 0x0000043d, R_SYSCLK_AI_CLK_CFG_CLK_DIV_UPD_MASK), + SYSCLK_REG(SYSCLK_VPU_CLK_CFG, "VPU_CLK_CFG", 0x00000c7f, + 0x00007fff, R_SYSCLK_VPU_CLK_CFG_CLK_GDIV_UPD_MASK), + SYSCLK_REG(SYSCLK_PMU_CLK_CFG, "PMU_CLK_CFG", 0x00000001, + 0x00000001, 0), + SYSCLK_REG(SYSCLK_HS_CLKEN_CFG, "HS_CLKEN_CFG", 0x7f7fffff, + 0x7fffffff, 0), + SYSCLK_REG(SYSCLK_HS_SDCLK_CFG, "HS_SDCLK_CFG", 0x000b9248, + 0x000fffff, R_SYSCLK_HS_SDCLK_CFG_ACLK_ROOT_CDIV_UPD_MASK), + SYSCLK_REG(SYSCLK_HS_SPI_CFG, "HS_SPI_CFG", 0x00039048, + 0x0007fff8, R_SYSCLK_HS_SPI_CFG_SSI0_ACLK_ROOT_CDIV_UPD_MAS= K), + SYSCLK_REG(SYSCLK_LS_CLKEN_CFG0, "LS_CLKEN_CFG0", 0xffffffff, + 0xffffffff, 0), + SYSCLK_REG(SYSCLK_LS_CLKEN_CFG1, "LS_CLKEN_CFG1", 0x000000ff, + 0x000000ff, 0), + SYSCLK_REG(SYSCLK_UART_I2C_CLKDIV_CFG, "UART_I2C_CLKDIV_CFG", + 0x1b6d9249, 0x3fffffff, + R_SYSCLK_UART_I2C_CLKDIV_CFG_I2C0_CLK_CDIV_UPD_MASK), + SYSCLK_REG(SYSCLK_LS_CLKDIV_CFG, "LS_CLKDIV_CFG", 0x01dda0c3, + 0x7fffffff, R_SYSCLK_LS_CLKDIV_CFG_JAMLINK_CO_CDIV_UPD_MASK= ), + SYSCLK_REG(SYSCLK_AUDIO_CLKDIV_CFG, "AUDIO_CLKDIV_CFG", 0x01b9f424, + 0x7fffffff, R_SYSCLK_AUDIO_CLKDIV_CFG_AUD_DEV_CLK_FDIV_UPD_= MASK), + SYSCLK_REG(SYSCLK_CODEC_ADC_MCLKDIV_CFG, "CODEC_ADC_MCLKDIV_CFG", + 0x006e7d09, 0x07ffffff, + R_SYSCLK_CODEC_ADC_MCLKDIV_CFG_MCLK_ADC_FDIV_UPD_MASK), + SYSCLK_REG(SYSCLK_CODEC_DAC_MCLKDIV_CFG, "CODEC_DAC_MCLKDIV_CFG", + 0x006e7d09, 0x07ffffff, + R_SYSCLK_CODEC_DAC_MCLKDIV_CFG_MCLK_DAC_FDIV_UPD_MASK), + SYSCLK_REG(SYSCLK_PDM_CLKDIV_CFG0, "PDM_CLKDIV_CFG0", 0x0000f424, + 0x0001ffff, 0), + SYSCLK_REG(SYSCLK_PDM_CLKDIV_CFG1, "PDM_CLKDIV_CFG1", 0x000001b9, + 0x0000ffff, R_SYSCLK_PDM_CLKDIV_CFG1_CLK_FDIV_UPD_MASK), + SYSCLK_REG(SYSCLK_SYSCTL_CLKEN_CFG, "SYSCTL_CLKEN_CFG", 0x003ffffe, + 0x003ffffe, 0), + SYSCLK_REG(SYSCLK_TIMER_CLK_CFG, "TIMER_CLK_CFG", 0x0003ffff, + 0x0003ffff, R_SYSCLK_TIMER_CLK_CFG_CLK0_CDIV_UPD_MASK), + SYSCLK_REG(SYSCLK_SYSCTL_CLK_DIV_CFG, "SYSCTL_CLK_DIV_CFG", 0x1efabef9, + 0x7ffffff8, R_SYSCLK_SYSCTL_CLK_DIV_CFG_PCLK_CDIV_UPD_MASK), + SYSCLK_REG(SYSCLK_SHRM_CLK_CFG, "SHRM_CLK_CFG", 0x000c7ffd, + 0x001c7ffd, R_SYSCLK_SHRM_CLK_CFG_PCLK_ROOT_DIV_UPD_MASK), + SYSCLK_REG(SYSCLK_DDR_CLK_CFG, "DDR_CLK_CFG", 0x000043fd, + 0x0003ffff, R_SYSCLK_DDR_CLK_CFG_CORE_CLK_CDIV_UPD_MASK), + SYSCLK_REG(SYSCLK_ISP_CLKEN_CFG, "ISP_CLKEN_CFG", 0x000fffff, + 0x000fffff, 0), + SYSCLK_REG(SYSCLK_ISP_CLKDIV_CFG, "ISP_CLKDIV_CFG", 0x00820835, + 0x3fffffff, R_SYSCLK_ISP_CLKDIV_CFG_CFG_CLK_CDIV_UPD_MASK), + SYSCLK_REG(SYSCLK_MCLK_CFG, "MCLK_CFG", 0x003a74ef, + 0x00ffffff, R_SYSCLK_MCLK_CFG_MCLK0_CDIV_UPD_MASK), + SYSCLK_REG(SYSCLK_DPU_CLK_CFG, "DPU_CLK_CFG", 0x000001ff, + 0x000003ff, R_SYSCLK_DPU_CLK_CFG_CLK_DIV_UPD_MASK), + SYSCLK_REG(SYSCLK_VO_CLK_CFG, "VO_CLK_CFG", 0x00001fff, + 0x00001fff, 0), + SYSCLK_REG(SYSCLK_DISP_CLK_DIV, "DISP_CLK_DIV", 0x0000a83b, + 0x00ffffff, R_SYSCLK_DISP_CLK_DIV_HCLK_ROOT_CDIV_UPD_MASK), + SYSCLK_REG(SYSCLK_SEC_CLK_DIV, "SEC_CLK_DIV", 0x000002f3, + 0x00003fff, R_SYSCLK_SEC_CLK_DIV_PCLK_DIV_UPD_MASK), + SYSCLK_REG(SYSCLK_USB_TEST_CLK_DIV, "USB_TEST_CLK_DIV", 0x00000039, + 0x0000007f, R_SYSCLK_USB_TEST_CLK_DIV_CLK480_CDIV_UPD_MASK), + SYSCLK_REG(SYSCLK_DPHY_TEST_CLK_DIV, "DPHY_TEST_CLK_DIV", 0x00000009, + 0x0000001f, + R_SYSCLK_DPHY_TEST_CLK_DIV_TEST_CLK_CDIV_UPD_MASK), + SYSCLK_REG(SYSCLK_SPI2AXI_CLK_DIV, "SPI2AXI_CLK_DIV", 0x00000007, + 0x0000000f, + R_SYSCLK_SPI2AXI_CLK_DIV_CLK_DIV_UPD_MASK), +}; + +#undef SYSCLK_REG + +static const K230PllRegDesc *k230_pll_desc(hwaddr addr, + unsigned *pll_index) +{ + unsigned index =3D addr / K230_PLL_STRIDE; + hwaddr offset =3D addr % K230_PLL_STRIDE; + + if (index >=3D K230_PLL_COUNT) { + return NULL; + } + + for (unsigned i =3D 0; i < ARRAY_SIZE(k230_pll_regs); i++) { + if (k230_pll_regs[i].offset =3D=3D offset) { + *pll_index =3D index; + return &k230_pll_regs[i]; + } + } + + return NULL; +} + +static uint32_t k230_pll_value(const K230PllState *pll, hwaddr offset) +{ + switch (offset) { + case A_CMU_CFG0: + return pll->cfg0; + case A_CMU_CFG1: + return pll->cfg1; + case A_CMU_CTL: + return pll->ctl & PLL_CTL_RW_MASK; + case A_CMU_STAT: + return pll->stat & PLL_STAT_RO_MASK; + default: + return 0; + } +} + +static uint32_t *k230_pll_storage(K230PllState *pll, hwaddr offset) +{ + switch (offset) { + case A_CMU_CFG0: + return &pll->cfg0; + case A_CMU_CFG1: + return &pll->cfg1; + case A_CMU_CTL: + return &pll->ctl; + default: + return NULL; + } +} + +static uint32_t k230_merge_rw(uint32_t old_value, uint32_t write_value, + uint32_t rw_mask, uint32_t w1t_mask) +{ + return ((old_value & ~rw_mask) | (write_value & rw_mask)) & ~w1t_mask; +} + +static void k230_cmu_log_undefined_access(const char *region, bool write, + hwaddr addr, uint32_t value) +{ + if (write) { + trace_k230_cmu_undefined_write(region, addr, value); + qemu_log_mask(LOG_GUEST_ERROR, + "%s: write to undefined %s offset 0x%" PRIx64 + " (value 0x%08" PRIx32 ")\n", + TYPE_K230_CMU, region, addr, value); + } else { + trace_k230_cmu_undefined_read(region, addr); + qemu_log_mask(LOG_GUEST_ERROR, + "%s: read from undefined %s offset 0x%" PRIx64 "\n", + TYPE_K230_CMU, region, addr); + } +} + +static uint64_t k230_pll_read(void *opaque, hwaddr addr, unsigned size) +{ + K230CmuState *s =3D K230_CMU(opaque); + unsigned index; + const K230PllRegDesc *desc; + uint32_t value; + + if (size !=3D sizeof(uint32_t)) { + return 0; + } + + desc =3D k230_pll_desc(addr, &index); + if (!desc) { + k230_cmu_log_undefined_access("PLL", false, addr, 0); + return 0; + } + + value =3D k230_pll_value(&s->pll[index], desc->offset); + trace_k230_cmu_pll_read(index, desc->offset, value); + return value; +} + +static void k230_pll_write(void *opaque, hwaddr addr, uint64_t value, + unsigned size) +{ + K230CmuState *s =3D K230_CMU(opaque); + unsigned index; + const K230PllRegDesc *desc; + K230PllState *pll; + uint32_t *storage; + uint32_t write_value =3D value; + uint32_t old_value; + uint32_t new_value; + + if (size !=3D sizeof(uint32_t)) { + return; + } + + desc =3D k230_pll_desc(addr, &index); + if (!desc) { + k230_cmu_log_undefined_access("PLL", true, addr, write_value); + return; + } + + pll =3D &s->pll[index]; + old_value =3D k230_pll_value(pll, desc->offset); + + if (desc->offset =3D=3D A_CMU_STAT) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: write to read-only PLL%u STAT\n", + TYPE_K230_CMU, index); + return; + } + + if (desc->offset =3D=3D A_CMU_CTL) { + uint32_t low =3D write_value & 0xffff; + uint32_t enabled =3D (write_value >> desc->write_enable_shift) & + desc->write_enable_mask; + uint32_t old_status =3D pll->stat; + uint32_t w1t =3D enabled & desc->w1t_mask & low; + bool powerdown =3D w1t & R_CMU_CTL_PLL_PWRDWN_MASK; + bool init =3D w1t & R_CMU_CTL_PLL_INIT_MASK; + + pll->ctl =3D k230_merge_rw(pll->ctl, low, + enabled & desc->rw_mask, + desc->w1t_mask); + + if (powerdown && init) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: PLL%u CTL powerdown/init conflict\n", + TYPE_K230_CMU, index); + } + + if (powerdown) { + pll->stat =3D 0; + } + if (init) { + pll->stat =3D 0x00000021; + } + if (old_status !=3D pll->stat) { + trace_k230_cmu_pll_status(index, old_status, pll->stat); + } + new_value =3D k230_pll_value(pll, desc->offset); + trace_k230_cmu_pll_write(index, desc->offset, write_value, + old_value, new_value); + return; + } + + storage =3D k230_pll_storage(pll, desc->offset); + if (!storage) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: PLL%u %s has no writable storage\n", + TYPE_K230_CMU, index, desc->name); + return; + } + *storage =3D k230_merge_rw(*storage, write_value, + desc->rw_mask, desc->w1t_mask); + new_value =3D k230_pll_value(pll, desc->offset); + trace_k230_cmu_pll_write(index, desc->offset, write_value, + old_value, new_value); +} + +static const K230SysclkRegDesc *k230_sysclk_desc(hwaddr addr, + unsigned *index) +{ + for (unsigned i =3D 0; i < ARRAY_SIZE(k230_sysclk_regs); i++) { + if (k230_sysclk_regs[i].offset =3D=3D addr) { + *index =3D i; + return &k230_sysclk_regs[i]; + } + } + + return NULL; +} + +static uint64_t k230_sysclk_read(void *opaque, hwaddr addr, unsigned size) +{ + K230CmuState *s =3D K230_CMU(opaque); + unsigned index; + uint32_t value; + + if (size !=3D sizeof(uint32_t)) { + return 0; + } + + if (!k230_sysclk_desc(addr, &index)) { + k230_cmu_log_undefined_access("sysclk", false, addr, 0); + return 0; + } + + value =3D s->sysclk[index]; + trace_k230_cmu_sysclk_read(addr, value); + return value; +} + +static void k230_sysclk_write(void *opaque, hwaddr addr, uint64_t value, + unsigned size) +{ + K230CmuState *s =3D K230_CMU(opaque); + const K230SysclkRegDesc *desc; + unsigned index; + uint32_t old_value; + uint32_t new_value; + + if (size !=3D sizeof(uint32_t)) { + return; + } + + desc =3D k230_sysclk_desc(addr, &index); + if (!desc) { + k230_cmu_log_undefined_access("sysclk", true, addr, value); + return; + } + + old_value =3D s->sysclk[index]; + new_value =3D k230_merge_rw(old_value, value, + desc->rw_mask, desc->w1t_mask); + s->sysclk[index] =3D new_value; + trace_k230_cmu_sysclk_write(addr, value, old_value, new_value); +} + +static const MemoryRegionOps k230_pll_ops =3D { + .read =3D k230_pll_read, + .write =3D k230_pll_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + .unaligned =3D false, + }, + .impl =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + .unaligned =3D false, + }, +}; + +static const MemoryRegionOps k230_sysclk_ops =3D { + .read =3D k230_sysclk_read, + .write =3D k230_sysclk_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + .unaligned =3D false, + }, + .impl =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + .unaligned =3D false, + }, +}; + +static void k230_cmu_check_reg_descs(void) +{ + for (unsigned i =3D 0; i < ARRAY_SIZE(k230_pll_regs); i++) { + const K230PllRegDesc *desc =3D &k230_pll_regs[i]; + + g_assert(!(desc->rw_mask & desc->w1t_mask)); + g_assert(!(desc->rw_mask & desc->ro_mask)); + g_assert(!(desc->w1t_mask & desc->ro_mask)); + } + + for (unsigned i =3D 0; i < ARRAY_SIZE(k230_sysclk_regs); i++) { + const K230SysclkRegDesc *desc =3D &k230_sysclk_regs[i]; + + g_assert(!(desc->rw_mask & desc->w1t_mask)); + } +} + +static void k230_cmu_reset_hold(Object *obj, ResetType type) +{ + K230CmuState *s =3D K230_CMU(obj); + + for (unsigned index =3D 0; index < K230_PLL_COUNT; index++) { + s->pll[index].cfg0 =3D k230_pll_regs[0].reset[index]; + s->pll[index].cfg1 =3D k230_pll_regs[1].reset[index]; + s->pll[index].ctl =3D k230_pll_regs[2].reset[index]; + s->pll[index].stat =3D k230_pll_regs[3].reset[index]; + } + + for (unsigned index =3D 0; index < ARRAY_SIZE(k230_sysclk_regs); index= ++) { + s->sysclk[index] =3D k230_sysclk_regs[index].reset; + } +} + +static void k230_cmu_init(Object *obj) +{ + K230CmuState *s =3D K230_CMU(obj); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(obj); + + k230_cmu_check_reg_descs(); + memory_region_init_io(&s->pll_mmio, obj, &k230_pll_ops, s, + "k230-cmu-pll", K230_CMU_SIZE); + memory_region_init_io(&s->sysclk_mmio, obj, &k230_sysclk_ops, s, + "k230-cmu-sysclk", K230_SYSCLK_SIZE); + sysbus_init_mmio(sbd, &s->pll_mmio); + sysbus_init_mmio(sbd, &s->sysclk_mmio); +} + +static const VMStateDescription vmstate_k230_pll =3D { + .name =3D "riscv.k230.cmu/pll", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32(cfg0, K230PllState), + VMSTATE_UINT32(cfg1, K230PllState), + VMSTATE_UINT32(ctl, K230PllState), + VMSTATE_UINT32(stat, K230PllState), + VMSTATE_END_OF_LIST(), + }, +}; + +static const VMStateDescription vmstate_k230_cmu =3D { + .name =3D TYPE_K230_CMU, + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (const VMStateField[]) { + VMSTATE_STRUCT_ARRAY(pll, K230CmuState, K230_PLL_COUNT, 1, + vmstate_k230_pll, K230PllState), + VMSTATE_UINT32_ARRAY(sysclk, K230CmuState, K230_SYSCLK_REG_COUNT), + VMSTATE_END_OF_LIST(), + }, +}; + +static void k230_cmu_class_init(ObjectClass *klass, const void *data) +{ + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + DeviceClass *dc =3D DEVICE_CLASS(klass); + + rc->phases.hold =3D k230_cmu_reset_hold; + dc->vmsd =3D &vmstate_k230_cmu; +} + +static const TypeInfo k230_cmu_info =3D { + .name =3D TYPE_K230_CMU, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(K230CmuState), + .instance_init =3D k230_cmu_init, + .class_init =3D k230_cmu_class_init, +}; + +static void k230_cmu_register_types(void) +{ + type_register_static(&k230_cmu_info); +} + +type_init(k230_cmu_register_types) diff --git a/hw/misc/meson.build b/hw/misc/meson.build index 23265f6035..5f1c9c439d 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -28,6 +28,7 @@ system_ss.add(when: 'CONFIG_IOSB', if_true: files('iosb.c= ')) system_ss.add(when: 'CONFIG_VIRT_CTRL', if_true: files('virt_ctrl.c')) =20 # RISC-V devices +system_ss.add(when: 'CONFIG_K230_CMU', if_true: files('k230_cmu.c')) system_ss.add(when: 'CONFIG_MCHP_PFSOC_DMC', if_true: files('mchp_pfsoc_dm= c.c')) system_ss.add(when: 'CONFIG_MCHP_PFSOC_IOSCB', if_true: files('mchp_pfsoc_= ioscb.c')) system_ss.add(when: 'CONFIG_MCHP_PFSOC_SYSREG', if_true: files('mchp_pfsoc= _sysreg.c')) diff --git a/hw/misc/trace-events b/hw/misc/trace-events index c9a868b3ef..bcedea6954 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -66,6 +66,15 @@ ecc_mem_readl_ecr1(uint32_t ret) "Read event count 2 0x%= 08x" ecc_diag_mem_writeb(uint64_t addr, uint32_t val) "Write diagnostic %"PRId6= 4" =3D 0x%02x" ecc_diag_mem_readb(uint64_t addr, uint32_t ret) "Read diagnostic %"PRId64"= =3D 0x%02x" =20 +# k230_cmu.c +k230_cmu_pll_read(unsigned int pll, uint64_t offset, uint32_t value) "PLL%= u read offset=3D0x%"PRIx64" value=3D0x%08"PRIx32 +k230_cmu_pll_write(unsigned int pll, uint64_t offset, uint32_t value, uint= 32_t old_value, uint32_t new_value) "PLL%u write offset=3D0x%"PRIx64" value= =3D0x%08"PRIx32" old=3D0x%08"PRIx32" new=3D0x%08"PRIx32 +k230_cmu_pll_status(unsigned int pll, uint32_t old_status, uint32_t new_st= atus) "PLL%u status old=3D0x%08"PRIx32" new=3D0x%08"PRIx32 +k230_cmu_sysclk_read(uint64_t offset, uint32_t value) "sysclk read offset= =3D0x%"PRIx64" value=3D0x%08"PRIx32 +k230_cmu_sysclk_write(uint64_t offset, uint32_t value, uint32_t old_value,= uint32_t new_value) "sysclk write offset=3D0x%"PRIx64" value=3D0x%08"PRIx3= 2" old=3D0x%08"PRIx32" new=3D0x%08"PRIx32 +k230_cmu_undefined_read(const char *region, uint64_t offset) "%s undefined= read offset=3D0x%"PRIx64 +k230_cmu_undefined_write(const char *region, uint64_t offset, uint32_t val= ue) "%s undefined write offset=3D0x%"PRIx64" value=3D0x%08"PRIx32 + # empty_slot.c empty_slot_write(uint64_t addr, unsigned width, uint64_t value, unsigned s= ize, const char *name) "wr addr:0x%04"PRIx64" data:0x%0*"PRIx64" size %u [%= s]" =20 diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index de37c08cae..d2e365fd70 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -161,4 +161,5 @@ config K230 select RISCV_IMSIC select SERIAL_MM select UNIMP + select K230_CMU select K230_WDT diff --git a/include/hw/misc/k230_cmu.h b/include/hw/misc/k230_cmu.h new file mode 100644 index 0000000000..e373ec0aa0 --- /dev/null +++ b/include/hw/misc/k230_cmu.h @@ -0,0 +1,58 @@ +/* + * Kendryte K230 Clock Management Unit + * + * Copyright (c) 2026 Simon Law <0860734llx@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Defines the K230 PLL and system-clock register protocol model. It keeps + * software-visible register state but does not provide cycle-accurate clo= cks + * or propagate QEMU Clock signals. + * + * K230 Technical Reference Manual V0.3.1 (2024-11-18): + * https://github.com/revyos/external-docs/blob/master/K230/en-us/K230_Tec= hnical_Reference_Manual_V0.3.1_20241118.pdf + * + * For more information, see + * + */ + +#ifndef HW_MISC_K230_CMU_H +#define HW_MISC_K230_CMU_H + +#include "hw/core/sysbus.h" +#include "qom/object.h" + +#define TYPE_K230_CMU "riscv.k230.cmu" +OBJECT_DECLARE_SIMPLE_TYPE(K230CmuState, K230_CMU) + +#define K230_PLL_COUNT 4 +#define K230_PLL_STRIDE 0x10 +#define K230_SYSCLK_REG_COUNT 32 + +#define K230_CMU_BASE_ADDR 0x91102000 +#define K230_CMU_SIZE 0x40 + +#define K230_SYSCLK_BASE_ADDR 0x91100000 +#define K230_SYSCLK_SIZE 0x1000 + +typedef struct K230PllState { + uint32_t cfg0; + uint32_t cfg1; + uint32_t ctl; + uint32_t stat; +} K230PllState; + +typedef struct K230CmuState { + /* */ + SysBusDevice parent_obj; + + /* */ + MemoryRegion pll_mmio; + MemoryRegion sysclk_mmio; + + /* Properties */ + K230PllState pll[K230_PLL_COUNT]; + uint32_t sysclk[K230_SYSCLK_REG_COUNT]; +} K230CmuState; + +#endif /* HW_MISC_K230_CMU_H */ --=20 2.43.0 From nobody Sat Sep 26 23:53:29 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=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1787060208; cv=none; d=zohomail.com; s=zohoarc; b=gZmuQAvu0z7xO7OXr6wkgxYW04qIotd0GULlnHQT5x7u+I3lxOrd65PqZ+oD5o61KTjWIQ0yG+XDaElhFHFJ5XWG4yooaHo0ujop5wZ9vumyaIE2u7eZeL5qu8qIyb214cRQ7horWKDl3BdPf1apz4MtwNijWOB/sElZ/H4nvwo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787060208; 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=XUsiX20NPZUJ5pQd/u9R/lymrgW+Q7K98qrZgTyAjqw=; b=mfP9paAy+9jEr9fnzwqA/XWSqhXIwRDTgxH4AA4lY5eSsSXshS5B8EfDcRUJfqFPcmvkUm0HQWPDKaMM2ExGq9wxdyTd/VqXsGU5rzR5Mx1Ihp924LLtCQhvyXrmSE6n3ixCEbvGZkecMJnPpMX+yAQGwJmvmPq5fCMZbZ7PwZ4= 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=<0860734llx@gmail.com> (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787060208435952.4439449632412; Tue, 18 Aug 2026 06:36:48 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wwJzG-0007Ca-OK; Tue, 18 Aug 2026 09:36:19 -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 <0860734llx@gmail.com>) id 1wwJz7-00074O-VY for qemu-devel@nongnu.org; Tue, 18 Aug 2026 09:36:10 -0400 Received: from mail-pl1-x62d.google.com ([2607:f8b0:4864:20::62d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <0860734llx@gmail.com>) id 1wwJz5-0000fd-PI for qemu-devel@nongnu.org; Tue, 18 Aug 2026 09:36:09 -0400 Received: by mail-pl1-x62d.google.com with SMTP id d9443c01a7336-2d530328efbso41814335ad.0 for ; Tue, 18 Aug 2026 06:36:07 -0700 (PDT) Received: from [172.17.0.5] ([42.193.175.155]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2d5d014d965sm8066845ad.35.2026.08.18.06.36.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Aug 2026 06:36:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787060166; x=1787664966; 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=XUsiX20NPZUJ5pQd/u9R/lymrgW+Q7K98qrZgTyAjqw=; b=NTGTc5pgZctob5NOER4+5i5VXR3iiobEz4FHOfoJSLJTawj88Qu0iy05WdfA+aO+sY oYSUkT5aDtcv+0bUYVKYrS2XnFtelPOha161HD9TXfwzqLCLe3qv2/fwXEZfLL7foScJ x+03ExNvGtgPOZA6rkARh5t33s+JaI8Zi7xbQ1WYNR5Gyp6FPSXgb0+zLXe9fBLdUI4Z YuwW0zGA1ZezoQv+kfXLATrtejdEwQO1of7OM2+Bo6YjGOvdelfwniLd1hN5sj52yTWK V5rNPTAsKxmry3nrJ6+xx8YkRd8yykuVh5KfqqTDHUHGlHFiwfUmf3ZxgAqpxlHu+hrl cmfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787060166; x=1787664966; 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=XUsiX20NPZUJ5pQd/u9R/lymrgW+Q7K98qrZgTyAjqw=; b=EbckJh3/fp+dIejbnzPhVoM1WV7K4Cng2UODjtKrov+PJcyvIIUUuWr68VnMj2W96q 8OdDgD6eUCFcUQxNEgGbwdVmIXatUt3S5YnXJTPJP4FYldS2+uOLeUbt2RYXe1JCfCen Z27vegyKuQ3s0tmR7m9mGbtWvbpBPFYOPHXuC9jRulDvfqyDEgfInZ+YYrL5IgDJtBtc Yi9FRVesu/33RLPKqH+tJkmSFlujZLEoO3o1LXv7W2ytTf3Eoq4jXMXW6hQVXb+hj++g hQa3C2SSabkg+3O7roNpMMaD7k/WNYyABRtEmNkvtO/Ya2Pt3L+sW2xIKkZY23Wf3vQa R+iA== X-Gm-Message-State: AOJu0YycgFr3awUAjOtpBlblWw9UFzbHnnkqT8/34t8Scgt3J055nE/h UYfbmXTYVmY/aPG1LBX+29DUa17Br1cJSaaLo/Kjw+DZGNHgOrKoieNR X-Gm-Gg: AR+sD10nCt1Ibctzr2nTOcq6jKMJCT1zbzWxyomfgm4XwQovrKeVi//oav4OpM3LcLe TtEIPx5PEHTt5OFqc6/cLs5CNFs8qiiIqD2dmtzOmLZ116GXP8DbqZGFdyncQwEPgEL8kRo/+kT iBiSMrICTDfLcA3U0s3zKZcCBxgqALJjO1JMWqcJuQZJrl1PeInORRlWxLi6OkmtHPgTp11o4xB Rdy2KdxNarF2od1t9Lu+Z9mT3cmRXwfHny2ZmvACQt2vhhh6ley510zZZfBIBoBgMmPEO5SfTsw KV7w5PFVTduCBVzslrLocJ/r2EpH7kBRpmYurI0XhnEIdg8lWmqoS0v+AF+Hr17K/LI+2BQ2PfR OPTvXDrM7cr5rh0xrnXUqv/Z5K2Cxok9helff90YAP9rSkg40T9yGLiyvruJt3ddXOneRuLS17h MRN6EQmIP7FBkBTr0laK3jylxT7WsPDiqCg08oUq/ggSUi3v79rO+lisS6jAxEGGdDB5OR68Aes 5CE3k/U7R1y X-Received: by 2002:a17:903:1b48:b0:2cc:864b:539 with SMTP id d9443c01a7336-2d5c4f20383mr130101765ad.6.1787060166234; Tue, 18 Aug 2026 06:36:06 -0700 (PDT) From: Simon Law <0860734llx@gmail.com> Date: Tue, 18 Aug 2026 21:35:51 +0800 Subject: [PATCH v2 2/4] hw/riscv: connect the K230 CMU MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260818-feat-k230-cmu-v2-2-57eadb98f40f@gmail.com> References: <20260818-feat-k230-cmu-v2-0-57eadb98f40f@gmail.com> In-Reply-To: <20260818-feat-k230-cmu-v2-0-57eadb98f40f@gmail.com> To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Chao Liu , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , qemu-riscv@nongnu.org, Fabiano Rosas , Laurent Vivier , Pierrick Bouvier X-Mailer: b4 0.16.0 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::62d; envelope-from=0860734llx@gmail.com; helo=mail-pl1-x62d.google.com X-Spam_score_int: -13 X-Spam_score: -1.4 X-Spam_bar: - X-Spam_report: (-1.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, FROM_STARTS_WITH_NUMS=0.738, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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 @gmail.com) X-ZM-MESSAGEID: 1787060209805158500 Signed-off-by: Simon Law <0860734llx@gmail.com> --- hw/riscv/k230.c | 14 +++++++++----- include/hw/riscv/k230.h | 2 ++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/hw/riscv/k230.c b/hw/riscv/k230.c index 656f28190c..e50062f7df 100644 --- a/hw/riscv/k230.c +++ b/hw/riscv/k230.c @@ -108,6 +108,7 @@ static void k230_soc_init(Object *obj) RISCVHartArrayState *cpu0 =3D &s->c908_cpu; =20 object_initialize_child(obj, "c908-cpu", cpu0, TYPE_RISCV_HART_ARRAY); + object_initialize_child(obj, "k230-cmu", &s->cmu, TYPE_K230_CMU); object_initialize_child(obj, "k230-wdt0", &s->wdt[0], TYPE_K230_WDT); object_initialize_child(obj, "k230-wdt1", &s->wdt[1], TYPE_K230_WDT); =20 @@ -206,6 +207,12 @@ static void k230_soc_realize(DeviceState *dev, Error *= *errp) sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt[1]), 0, qdev_get_gpio_in(DEVICE(s->c908_plic), K230_WDT1_IR= Q)); =20 + if (!sysbus_realize(SYS_BUS_DEVICE(&s->cmu), errp)) { + return; + } + sysbus_mmio_map(SYS_BUS_DEVICE(&s->cmu), 0, K230_CMU_BASE_ADDR); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->cmu), 1, K230_SYSCLK_BASE_ADDR); + /* unimplemented devices */ create_unimplemented_device("kpu.l2-cache", memmap[K230_DEV_KPU_L2_CACHE].base, @@ -265,14 +272,11 @@ static void k230_soc_realize(DeviceState *dev, Error = **errp) create_unimplemented_device("rtc", memmap[K230_DEV_RTC].base, memmap[K230_DEV_RTC].size); =20 - create_unimplemented_device("cmu", memmap[K230_DEV_CMU].base, - memmap[K230_DEV_CMU].size); - create_unimplemented_device("rmu", memmap[K230_DEV_RMU].base, memmap[K230_DEV_RMU].size); =20 - create_unimplemented_device("boot", memmap[K230_DEV_BOOT].base, - memmap[K230_DEV_BOOT].size); + create_unimplemented_device("boot", K230_CMU_BASE_ADDR + K230_CMU_SIZE, + memmap[K230_DEV_BOOT].size - K230_CMU_SIZE= ); =20 create_unimplemented_device("pwr", memmap[K230_DEV_PWR].base, memmap[K230_DEV_PWR].size); diff --git a/include/hw/riscv/k230.h b/include/hw/riscv/k230.h index 592e1c26bf..5e1579c5b3 100644 --- a/include/hw/riscv/k230.h +++ b/include/hw/riscv/k230.h @@ -16,6 +16,7 @@ #define HW_K230_H =20 #include "hw/core/boards.h" +#include "hw/misc/k230_cmu.h" #include "hw/riscv/riscv_hart.h" #include "hw/watchdog/k230_wdt.h" =20 @@ -32,6 +33,7 @@ typedef struct K230SoCState { /*< public >*/ RISCVHartArrayState c908_cpu; /* Small core */ =20 + K230CmuState cmu; K230WdtState wdt[2]; MemoryRegion sram; MemoryRegion bootrom; --=20 2.43.0 From nobody Sat Sep 26 23:53:29 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=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1787060237; cv=none; d=zohomail.com; s=zohoarc; b=AMWG3YZLh8zeB7TjJFSkW3BKUjwUZ1nrGVYbMi4bmmHpkTKabPZWXRyaV15Dh7ntRiSB2ZhwsffozkiR2niK8M6Bo5yI6NsOw0Dr2+W8NYtsNpjPNHPC1IXS71tx2pFdYjcHdgi2PXej7avmJ1f0CfDlReMxWw24qT8knTW5/1M= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787060237; 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=qGORSvOPdgCEDHlJgPj/9KH5nwJ3ohv3CXDjTRlfB8Y=; b=V0SEgFaErjtoLo+5i7QUheEiS++ZqHQN63BDcdy8dU8e37fHXYQAs/aG6Gtb5+ZagjISOyZE4H/vCkEZemQYkzy/Q6qN3gZXXlhAUa/3D05JQDMamWJQTQTc89i0f5vqwKlmC7OJl460sL5LtTk0kUXiAjsLHBfz7c1GnU72nmc= 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=<0860734llx@gmail.com> (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787060237484184.45344562355774; Tue, 18 Aug 2026 06:37:17 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wwJzR-0007QU-QP; Tue, 18 Aug 2026 09:36:30 -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 <0860734llx@gmail.com>) id 1wwJzC-00077S-9X for qemu-devel@nongnu.org; Tue, 18 Aug 2026 09:36:14 -0400 Received: from mail-pl1-x631.google.com ([2607:f8b0:4864:20::631]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <0860734llx@gmail.com>) id 1wwJzA-0000gw-4D for qemu-devel@nongnu.org; Tue, 18 Aug 2026 09:36:14 -0400 Received: by mail-pl1-x631.google.com with SMTP id d9443c01a7336-2cc891373e0so60608555ad.2 for ; Tue, 18 Aug 2026 06:36:11 -0700 (PDT) Received: from [172.17.0.5] ([42.193.175.155]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2d5d014d965sm8066845ad.35.2026.08.18.06.36.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Aug 2026 06:36:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787060171; x=1787664971; 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=qGORSvOPdgCEDHlJgPj/9KH5nwJ3ohv3CXDjTRlfB8Y=; b=OnFikBhMeAZVJ6a2Yzi7wz+rLAs0kCBHaw1s94R0gsluh6FYhRZa8NofPakB+EK2Wh gUeCC/3FMQOaE5IDlc02uYqmtUmfNH37U8nNNw0puycuOgmZtMZFOBQvsGU8YrQdhs8x F1To4OUnd6u58BwGv2UO+qph/2/u7H1PuwE2Cx6vhpgjVl3hT6GU48OnzOAMPOWRTsNn ymDu3mEdbWfh0jHwac1cbugUdp0yX4nrnLzsDsSJGS/+QmkZoKMYO4SCmXSDVYwbnvDz K2beh2d6zWnf3B6yfWvcu1rJqA9bQuqTHWDItjqqjIL3/PvM6nlkvRTBxrCtte8ZTV3i Jx3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787060171; x=1787664971; 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=qGORSvOPdgCEDHlJgPj/9KH5nwJ3ohv3CXDjTRlfB8Y=; b=m+m3rrYotcYnD5jxiZ5MU3GxkHVDBgFwqc/uK0qxXS6FWn+Xcx3/reDcixgRAsxSzW heQUGFJI8tIsM3Gxv6p/83HSG/FUrEuVrh5Qhe6UHsna5r39V8Pfc5tlIw1elBcJRcxz eHZC8Uk8idzZVx5u8h6I9664cQrteUOmyXf17AsoXCcyYnc/NNgiBPlk4ZhAhRRJxE6t nkzUI0gtseLK5fp6UUWyDLsOrpLNlAhvTd8P8hYLj1gpb96/fEnvexBrJNDeCaM8HBL4 fWAIgWc5yh+aRXiV3WplKhcbs4lacziD0mX27d6BbrCaLsnAE4wRtLFwkcS0dkIJ1i8l HtNw== X-Gm-Message-State: AOJu0YwQExQCdehxj/JwxK44WANGxGYI3uO7mCPjpAHnkAuI+j6ltIXc z+LReR8ZbmEM86HuPAj7XS7NkzM4GeNcz0d0KU+m32kNQbPTw6fjOHGh X-Gm-Gg: AR+sD10CI5sBgKZCmRGPnfx0A+Z3JlCQA/An6SRcTy7na0yKoz2M7LFsB6YfMKZ8Crd laY/x+1fc1i3bQyToYQmpllIF3wB496bTg74RQEZJFf95OWYrxhQs8GfhUgPu1VjVK/1GzIjTDk FVnMeCxRx9bJUk6rSf4WcchTW1vmxTgU9ngac3/IAZybMwtvVANt34LrEJy1cNXV/zoxc+xnVgz CpZyx3tr3Ges7RPbjp8OupnApBrh0qPkJFU3/7i2fT5ODk37/qaBSfefwd0Zbv8CnbMTgGANmte QPy0zPrldKJaITzeEBEsgefNWBGzo424n2WLD+Ghaguf0T9s6IziPoMilxpty9a0VwwYVw2K67G gSK1H7PbXeI1I4PrJy1QeNJZHms7ybE3Z/UZTUhwiuzPngfLTFJwxcwADPbgniaYo8AOW90BzZe yc21MfBgoiKbK8adcHIFR/ArMajMSI2NVh8hfr8R/z0ueVOtrnIw6F+RimRJySN1YhZccuVfhvT b1yFJATsX91 X-Received: by 2002:a17:903:3c44:b0:2d0:8b28:517c with SMTP id d9443c01a7336-2d3b0d78141mr392119605ad.3.1787060170530; Tue, 18 Aug 2026 06:36:10 -0700 (PDT) From: Simon Law <0860734llx@gmail.com> Date: Tue, 18 Aug 2026 21:35:52 +0800 Subject: [PATCH v2 3/4] tests/qtest: add K230 CMU coverage MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260818-feat-k230-cmu-v2-3-57eadb98f40f@gmail.com> References: <20260818-feat-k230-cmu-v2-0-57eadb98f40f@gmail.com> In-Reply-To: <20260818-feat-k230-cmu-v2-0-57eadb98f40f@gmail.com> To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Chao Liu , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , qemu-riscv@nongnu.org, Fabiano Rosas , Laurent Vivier , Pierrick Bouvier X-Mailer: b4 0.16.0 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::631; envelope-from=0860734llx@gmail.com; helo=mail-pl1-x631.google.com X-Spam_score_int: -13 X-Spam_score: -1.4 X-Spam_bar: - X-Spam_report: (-1.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, FROM_STARTS_WITH_NUMS=0.738, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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 @gmail.com) X-ZM-MESSAGEID: 1787060240599158500 Signed-off-by: Simon Law <0860734llx@gmail.com> --- tests/qtest/k230-cmu-test.c | 312 ++++++++++++++++++++++++++++++++++++++++= ++++ tests/qtest/meson.build | 3 +- 2 files changed, 314 insertions(+), 1 deletion(-) diff --git a/tests/qtest/k230-cmu-test.c b/tests/qtest/k230-cmu-test.c new file mode 100644 index 0000000000..ce3af909f0 --- /dev/null +++ b/tests/qtest/k230-cmu-test.c @@ -0,0 +1,312 @@ +/* + * QTest testcase for Kendryte K230 Clock Management Unit + * + * Copyright (c) 2026 Simon Law <0860734llx@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * K230 Technical Reference Manual V0.3.1 (2024-11-18), CMU chapter. + * + * The reset and mask oracle in this file is intentionally independent from + * hw/misc/k230_cmu.c, so a descriptor-table error cannot mask itself. + */ + +#include "qemu/osdep.h" +#include "qemu/bitops.h" +#include "libqtest.h" + +#define K230_PLL_BASE 0x91102000 +#define K230_SYSCLK_BASE 0x91100000 +#define K230_PLL_COUNT 4 +#define K230_PLL_STRIDE 0x10 + +#define PLL_CFG0 0x0 +#define PLL_CFG1 0x4 +#define PLL_CTL 0x8 +#define PLL_STAT 0xc + +#define PLL_CFG0_RW_MASK 0x0f3f1fff +#define PLL_CFG1_RW_MASK 0x000f0fff +#define PLL_CTL_RW_MASK 0x00000ff4 + +typedef struct K230SysclkOracle { + uint32_t offset; + uint32_t reset; + uint32_t rw_mask; + uint32_t w1t_mask; +} K230SysclkOracle; + +static const uint32_t pll_reset[K230_PLL_COUNT][4] =3D { + { 0x0102018f, 0x000200c7, 0x00000034, 0x00000021 }, + { 0x00000062, 0x00020031, 0x00000034, 0x00000021 }, + { 0x00070378, 0x000201bb, 0x00000034, 0x00000021 }, + { 0x0102018f, 0x000200c7, 0x00000074, 0x00000021 }, +}; + +static const K230SysclkOracle sysclk_oracle[] =3D { + { 0x000, 0x0000e65f, 0x0003ffdf, BIT(31) }, + { 0x004, 0x0009900d, 0x000f803f, BIT(31) }, + { 0x008, 0x0000043d, 0x0000043d, BIT(31) }, + { 0x00c, 0x00000c7f, 0x00007fff, BIT(31) }, + { 0x010, 0x00000001, 0x00000001, 0 }, + { 0x018, 0x7f7fffff, 0x7fffffff, 0 }, + { 0x01c, 0x000b9248, 0x000fffff, BIT(31) }, + { 0x020, 0x00039048, 0x0007fff8, BIT(31) }, + { 0x024, 0xffffffff, 0xffffffff, 0 }, + { 0x028, 0x000000ff, 0x000000ff, 0 }, + { 0x02c, 0x1b6d9249, 0x3fffffff, BIT(31) }, + { 0x030, 0x01dda0c3, 0x7fffffff, BIT(31) }, + { 0x034, 0x01b9f424, 0x7fffffff, BIT(31) }, + { 0x038, 0x006e7d09, 0x07ffffff, BIT(31) }, + { 0x03c, 0x006e7d09, 0x07ffffff, BIT(31) }, + { 0x040, 0x0000f424, 0x0001ffff, 0 }, + { 0x044, 0x000001b9, 0x0000ffff, BIT(31) }, + { 0x050, 0x003ffffe, 0x003ffffe, 0 }, + { 0x054, 0x0003ffff, 0x0003ffff, BIT(31) }, + { 0x058, 0x1efabef9, 0x7ffffff8, BIT(31) }, + { 0x05c, 0x000c7ffd, 0x001c7ffd, BIT(31) }, + { 0x060, 0x000043fd, 0x0003ffff, BIT(31) }, + { 0x064, 0x000fffff, 0x000fffff, 0 }, + { 0x068, 0x00820835, 0x3fffffff, BIT(31) }, + { 0x06c, 0x003a74ef, 0x00ffffff, BIT(31) }, + { 0x070, 0x000001ff, 0x000003ff, BIT(31) }, + { 0x074, 0x00001fff, 0x00001fff, 0 }, + { 0x078, 0x0000a83b, 0x00ffffff, BIT(31) }, + { 0x080, 0x000002f3, 0x00003fff, BIT(31) }, + { 0x100, 0x00000039, 0x0000007f, BIT(31) }, + { 0x104, 0x00000009, 0x0000001f, BIT(31) }, + /* TRM summary stops at 0x104; SDK/Linux ABI requires SPI2AXI at 0x108= . */ + { 0x108, 0x00000007, 0x0000000f, BIT(31) }, +}; + +static QTestState *k230_cmu_start(void) +{ + return qtest_init("-machine k230"); +} + +static uint32_t pll_addr(unsigned index, uint32_t offset) +{ + g_assert_cmpuint(index, <, K230_PLL_COUNT); + return K230_PLL_BASE + index * K230_PLL_STRIDE + offset; +} + +static uint32_t merge_rw(uint32_t old_value, uint32_t value, uint32_t mask) +{ + return (old_value & ~mask) | (value & mask); +} + +static void assert_pll_reset(QTestState *qts) +{ + static const uint32_t offsets[] =3D { PLL_CFG0, PLL_CFG1, PLL_CTL, PLL= _STAT }; + + for (unsigned pll =3D 0; pll < K230_PLL_COUNT; pll++) { + for (unsigned reg =3D 0; reg < G_N_ELEMENTS(offsets); reg++) { + g_assert_cmphex(qtest_readl(qts, pll_addr(pll, offsets[reg])),= =3D=3D, + pll_reset[pll][reg]); + } + } +} + +static void assert_sysclk_reset(QTestState *qts) +{ + for (unsigned i =3D 0; i < G_N_ELEMENTS(sysclk_oracle); i++) { + const K230SysclkOracle *reg =3D &sysclk_oracle[i]; + + g_assert_cmphex(qtest_readl(qts, K230_SYSCLK_BASE + reg->offset), = =3D=3D, + reg->reset); + } +} + +static void test_reset_pll(void) +{ + QTestState *qts =3D k230_cmu_start(); + + assert_pll_reset(qts); + qtest_quit(qts); +} + +static void test_reset_sysclk(void) +{ + QTestState *qts =3D k230_cmu_start(); + + assert_sysclk_reset(qts); + qtest_quit(qts); +} + +static void test_pll_cfg_masks(void) +{ + static const uint32_t offsets[] =3D { PLL_CFG0, PLL_CFG1 }; + static const uint32_t masks[] =3D { PLL_CFG0_RW_MASK, PLL_CFG1_RW_MASK= }; + QTestState *qts =3D k230_cmu_start(); + + for (unsigned pll =3D 0; pll < K230_PLL_COUNT; pll++) { + for (unsigned reg =3D 0; reg < G_N_ELEMENTS(offsets); reg++) { + uint32_t addr =3D pll_addr(pll, offsets[reg]); + uint32_t reset =3D pll_reset[pll][reg]; + + qtest_writel(qts, addr, 0); + g_assert_cmphex(qtest_readl(qts, addr), =3D=3D, + merge_rw(reset, 0, masks[reg])); + qtest_writel(qts, addr, UINT32_MAX); + g_assert_cmphex(qtest_readl(qts, addr), =3D=3D, + merge_rw(merge_rw(reset, 0, masks[reg]), + UINT32_MAX, masks[reg])); + + qtest_system_reset(qts); + qtest_writel(qts, addr, BIT(ctz32(masks[reg]))); + g_assert_cmphex(qtest_readl(qts, addr), =3D=3D, + merge_rw(reset, BIT(ctz32(masks[reg])), + masks[reg])); + + qtest_system_reset(qts); + qtest_writel(qts, addr, reset | BIT(ctz32(~masks[reg]))); + g_assert_cmphex(qtest_readl(qts, addr), =3D=3D, reset); + } + } + + qtest_quit(qts); +} + +static void test_pll_ctl_write_enable(void) +{ + QTestState *qts =3D k230_cmu_start(); + uint32_t addr =3D pll_addr(0, PLL_CTL); + + qtest_writel(qts, addr, 0); + g_assert_cmphex(qtest_readl(qts, addr), =3D=3D, pll_reset[0][2]); + + qtest_writel(qts, addr, BIT(16 + 2)); + g_assert_cmphex(qtest_readl(qts, addr), =3D=3D, + pll_reset[0][2] & ~BIT(2)); + + qtest_writel(qts, addr, BIT(2) | BIT(16 + 2) | BIT(16 + 4)); + g_assert_cmphex(qtest_readl(qts, addr), =3D=3D, + merge_rw(pll_reset[0][2] & ~BIT(2), + BIT(2), BIT(2) | BIT(4))); + + qtest_writel(qts, addr, UINT32_MAX); + g_assert_cmphex(qtest_readl(qts, addr), =3D=3D, PLL_CTL_RW_MASK); + qtest_quit(qts); +} + +static void test_pll_status(void) +{ + QTestState *qts =3D k230_cmu_start(); + uint32_t ctl =3D pll_addr(0, PLL_CTL); + uint32_t stat =3D pll_addr(0, PLL_STAT); + + qtest_writel(qts, stat, 0); + g_assert_cmphex(qtest_readl(qts, stat), =3D=3D, 0x00000021); + + qtest_writel(qts, ctl, BIT(0) | BIT(16)); + g_assert_cmphex(qtest_readl(qts, stat), =3D=3D, 0); + + qtest_writel(qts, ctl, BIT(1) | BIT(17)); + g_assert_cmphex(qtest_readl(qts, stat), =3D=3D, 0x00000021); + + qtest_writel(qts, ctl, BIT(0) | BIT(1) | BIT(16) | BIT(17)); + g_assert_cmphex(qtest_readl(qts, stat), =3D=3D, 0x00000021); + qtest_quit(qts); +} + +static void test_sysclk_masks(void) +{ + QTestState *qts =3D k230_cmu_start(); + + for (unsigned i =3D 0; i < G_N_ELEMENTS(sysclk_oracle); i++) { + const K230SysclkOracle *reg =3D &sysclk_oracle[i]; + uint32_t addr =3D K230_SYSCLK_BASE + reg->offset; + uint32_t after_zero =3D merge_rw(reg->reset, 0, reg->rw_mask); + + qtest_writel(qts, addr, 0); + g_assert_cmphex(qtest_readl(qts, addr), =3D=3D, after_zero); + qtest_writel(qts, addr, UINT32_MAX); + g_assert_cmphex(qtest_readl(qts, addr), =3D=3D, + merge_rw(after_zero, UINT32_MAX, reg->rw_mask)); + } + + qtest_quit(qts); +} + +static void test_sysclk_update(void) +{ + QTestState *qts =3D k230_cmu_start(); + + for (unsigned i =3D 0; i < G_N_ELEMENTS(sysclk_oracle); i++) { + const K230SysclkOracle *reg =3D &sysclk_oracle[i]; + uint32_t addr; + uint32_t flipped; + + if (!reg->w1t_mask) { + continue; + } + + addr =3D K230_SYSCLK_BASE + reg->offset; + flipped =3D merge_rw(reg->reset, ~reg->reset, reg->rw_mask); + qtest_writel(qts, addr, flipped | reg->w1t_mask); + g_assert_cmphex(qtest_readl(qts, addr), =3D=3D, flipped); + } + + qtest_quit(qts); +} + +static void test_spi2axi(void) +{ + QTestState *qts =3D k230_cmu_start(); + uint32_t addr =3D K230_SYSCLK_BASE + 0x108; + + g_assert_cmphex(qtest_readl(qts, addr), =3D=3D, 0x00000007); + qtest_writel(qts, addr, 0x00000001); + g_assert_cmphex(qtest_readl(qts, addr), =3D=3D, 0x00000001); + qtest_writel(qts, addr, 0x8000000f); + g_assert_cmphex(qtest_readl(qts, addr), =3D=3D, 0x0000000f); + qtest_quit(qts); +} + +static void test_unknown_offsets(void) +{ + QTestState *qts =3D k230_cmu_start(); + /* The 0x40 PLL window has no undefined aligned 32-bit word. */ + uint32_t addr =3D K230_SYSCLK_BASE + 0x014; + + g_assert_cmphex(qtest_readl(qts, addr), =3D=3D, 0); + qtest_writel(qts, addr, UINT32_MAX); + g_assert_cmphex(qtest_readl(qts, addr), =3D=3D, 0); + qtest_quit(qts); +} + +static void test_system_reset(void) +{ + QTestState *qts =3D k230_cmu_start(); + + qtest_writel(qts, pll_addr(0, PLL_CFG0), 0); + qtest_writel(qts, pll_addr(1, PLL_CFG1), 0); + qtest_writel(qts, pll_addr(2, PLL_CTL), BIT(16 + 2)); + qtest_writel(qts, pll_addr(3, PLL_CTL), BIT(0) | BIT(16)); + qtest_writel(qts, K230_SYSCLK_BASE + 0x000, 0); + qtest_writel(qts, K230_SYSCLK_BASE + 0x050, 0); + qtest_writel(qts, K230_SYSCLK_BASE + 0x108, 0); + + qtest_system_reset(qts); + assert_pll_reset(qts); + assert_sysclk_reset(qts); + qtest_quit(qts); +} + +int main(int argc, char *argv[]) +{ + g_test_init(&argc, &argv, NULL); + + qtest_add_func("/k230-cmu/reset/pll", test_reset_pll); + qtest_add_func("/k230-cmu/reset/sysclk", test_reset_sysclk); + qtest_add_func("/k230-cmu/pll/cfg-masks", test_pll_cfg_masks); + qtest_add_func("/k230-cmu/pll/ctl-write-enable", test_pll_ctl_write_en= able); + qtest_add_func("/k230-cmu/pll/status", test_pll_status); + qtest_add_func("/k230-cmu/sysclk/masks", test_sysclk_masks); + qtest_add_func("/k230-cmu/sysclk/update", test_sysclk_update); + qtest_add_func("/k230-cmu/sysclk/spi2axi", test_spi2axi); + qtest_add_func("/k230-cmu/unknown-offsets", test_unknown_offsets); + qtest_add_func("/k230-cmu/system-reset", test_system_reset); + + return g_test_run(); +} diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 56ff860e21..9f5c46e0bf 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -297,7 +297,8 @@ qtests_riscv64 =3D ['riscv-csr-test'] + \ (config_all_devices.has_key('CONFIG_IOMMU_TESTDEV') and config_all_devices.has_key('CONFIG_RISCV_IOMMU') ? ['iommu-riscv-test'] : []) + \ - (config_all_devices.has_key('CONFIG_K230') ? ['k230-wdt-test'] : []) + (config_all_devices.has_key('CONFIG_K230') ? + ['k230-cmu-test', 'k230-wdt-test'] : []) =20 qtests_hexagon =3D ['boot-serial-test'] =20 --=20 2.43.0 From nobody Sat Sep 26 23:53:29 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=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1787060452; cv=none; d=zohomail.com; s=zohoarc; b=XKgO82DHpqnJad3/reBGN79wSo/HE7zEO9yoozgXfWMiqw7S+mQPQQUWNCMlhFejf5vgjArC9IVeoc4mRLfan6tPwJibRrJuXvG6j/j40l3Q/W4HalFgTXGLKQ4emfqEVwo4zVSQda3tPHbssvAqywh60Q1e37QxKuJan8d4suc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787060452; 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=/D6HjVKa4QQ4IcscIfUtE4RoMhIMfrZSlP4SYUTz+h4=; b=L8khLtGfW1xoDNhZo2ewHD7jVatFc4PEiWJa5mQdpf9MU9rJd/QfVYg4ayWQShI8xEqCJpqKV/6ckCH0fSQ4vXaeV5LGHeDlWm9lRWG3g1KsJQl3a4N6u5rBT59MZ8sUe8DB2Oh5PXC/pkA0TnOI+DAj5vtu9kyXPE2cIvKOYXg= 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=<0860734llx@gmail.com> (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 178706045203733.25839852400691; Tue, 18 Aug 2026 06:40:52 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wwJzV-0007WE-V2; Tue, 18 Aug 2026 09:36:35 -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 <0860734llx@gmail.com>) id 1wwJzG-0007DD-4P for qemu-devel@nongnu.org; Tue, 18 Aug 2026 09:36:18 -0400 Received: from mail-pl1-x62d.google.com ([2607:f8b0:4864:20::62d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <0860734llx@gmail.com>) id 1wwJzE-0000hf-J8 for qemu-devel@nongnu.org; Tue, 18 Aug 2026 09:36:17 -0400 Received: by mail-pl1-x62d.google.com with SMTP id d9443c01a7336-2cc7ef7ec27so57909345ad.1 for ; Tue, 18 Aug 2026 06:36:15 -0700 (PDT) Received: from [172.17.0.5] ([42.193.175.155]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2d5d014d965sm8066845ad.35.2026.08.18.06.36.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Aug 2026 06:36:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787060175; x=1787664975; 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=/D6HjVKa4QQ4IcscIfUtE4RoMhIMfrZSlP4SYUTz+h4=; b=EX7HgWXK2txQwGpExwEjSvsQpbpo+NfoDTvvFhZm/DYVjRZSST3tr0uqj0Oxll8hs4 is0cgZi5U0dqo3GlbLl6NUT5WE7d01v1cs9AbcxRhduS2MdZjOwrtCN/zBzKWVb7bREP i3p5P+FV3qZu+3bBP/oJaPQJ3FbVCJqWUOAb7ILuFpOy/oZyhrKX4U8pPVu9GLFNngVZ KfWg54T3NUeg78ragMpAr8+RJr/noxAF5wHfWYaSyj/GH3GXYNGY68OEJ6h5FpuCdHLv sykaw1iFx5HtKkVgPpsH/AT/SzMPhUUVehIGxTEubyuHE4E+n/BqhnW7bUjpzD/cNmx1 1mBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787060175; x=1787664975; 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=/D6HjVKa4QQ4IcscIfUtE4RoMhIMfrZSlP4SYUTz+h4=; b=s2cbD9PPlwJpx7JxbYBDXRAviMK/DpbfzoPMk6YwvNhJxbFAT2zQFPYqK3DmIkO58w CtPf0MaNsPz8q6/RGmmJWhaIRH7x5PzBR/fFnuyVGTDEB8ez2GrtAGSU1JuOpb8xt2V1 pc/OSxY1npx1OJj8Gy/ARGnHKo7emx0HvkiA0kmqMrvwggwQzTcL8Z1WHL6iN3JlqLqJ ZEMS2K2seJFefXq1Uk4/UxUQQLrYg/0JB6w8UemDkRLK+iQH2wN7tmXWpsMxXCOkmUoA IVfAS1GpzttgEsrjMz4CYGQzn/5vcerko0d8NL16+XM5qh8eJpWhuddGsWhrhKrnDJKY JSzQ== X-Gm-Message-State: AOJu0YwQd9e9NTVF003HDC9ECkDDKLKLeF/2BuqZWKVjmvD2Hiusajsf h9+I7IUUG5BEbfojbN3QXlV780equpIPJfVTLMD2WNKM04qjHR1oMUX5 X-Gm-Gg: AR+sD11oCN/LJtaKnxfr6NW+3oKbSBCmaNawW2Vqx7jTl3LbjpUwljS1t/Hn0g2rnXh oWKdIXU4JfYi8atWsRlwhlL6gQMK0pq5lFKKilvsKBJeR5XgnDa20XBxMEF7UsMzN7MCqL0shz6 /vZkLVe/W606ZH0pPWWubFBxK9/o+269X3nDkS1Oqa+8pzB5sYfqiCOtYyIWtGvA5xUNTBCc60j pEZeLpGdy/gKzLkNLCLxa/jWg3rWx5mGDZ4uu6C2DnrYtGW82+N2dabO92FCf5SPdBv9dAjHGG3 QmWVsyO8iZ31YYKxayACHMTWvyID71eo7SFWw1FNOsbPCDD0BlQ04SJoHOcdGjeTpBj6tedlxSv +9JhqLd0BeJq9g64ysjhwHLLNnwSnxUD9kYJU9+KaSh7LAZB0noHlxhZ4IkVC1rNDAtUiu3TjS7 kVQ2oRvjlqJhyKVWt5i7KdT6NyFetqvn2MmJszwqOneTUeSrfjXHuQKDkQ6n52DD6cjUHeWk7KE cqofTkXIJ4f X-Received: by 2002:a17:902:e746:b0:2d0:cc92:f7c2 with SMTP id d9443c01a7336-2d3b082b6aamr374365415ad.1.1787060174984; Tue, 18 Aug 2026 06:36:14 -0700 (PDT) From: Simon Law <0860734llx@gmail.com> Date: Tue, 18 Aug 2026 21:35:53 +0800 Subject: [PATCH v2 4/4] docs/system/riscv: document K230 CMU support MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260818-feat-k230-cmu-v2-4-57eadb98f40f@gmail.com> References: <20260818-feat-k230-cmu-v2-0-57eadb98f40f@gmail.com> In-Reply-To: <20260818-feat-k230-cmu-v2-0-57eadb98f40f@gmail.com> To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Chao Liu , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , qemu-riscv@nongnu.org, Fabiano Rosas , Laurent Vivier , Pierrick Bouvier X-Mailer: b4 0.16.0 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::62d; envelope-from=0860734llx@gmail.com; helo=mail-pl1-x62d.google.com X-Spam_score_int: -13 X-Spam_score: -1.4 X-Spam_bar: - X-Spam_report: (-1.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, FROM_STARTS_WITH_NUMS=0.738, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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 @gmail.com) X-ZM-MESSAGEID: 1787060453604158500 Signed-off-by: Simon Law <0860734llx@gmail.com> --- docs/system/riscv/k230.rst | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/system/riscv/k230.rst b/docs/system/riscv/k230.rst index cea8202e55..dd50b0bd2e 100644 --- a/docs/system/riscv/k230.rst +++ b/docs/system/riscv/k230.rst @@ -18,9 +18,31 @@ The ``k230`` machine supports the following devices: * 1 c908 cores (little core) * Core Local Interruptor (CLINT) * Platform-Level Interrupt Controller (PLIC) +* Clock Management Unit (CMU) * 2 K230 Watchdog Timer * 5 UART =20 +Clock Management Unit +--------------------- + +The CMU model provides the register interface used by the K230 SDK U-Boot = and +the upstream Linux K230 clock driver. It implements the four PLL register +blocks at ``0x91102000`` through ``0x9110203f`` and the defined sysclk +registers in the ``0x91100000`` window, including the software-visible +``SPI2AXI_CLK_DIV`` register at offset ``0x108``. + +The model implements reset values, writable and reserved bits, PLL control +write-enable semantics, and write-one-to-trigger update operations. PLL lo= ck +and init completion are deterministic and immediate so that Linux clock pr= obe +does not depend on virtual time. + +The CMU does not propagate clock frequencies to QEMU devices or alter CPU +execution speed. Peripheral reset, power control, and a guest-initiated K2= 30 +system-reset backend are separate hardware blocks and are not modeled by t= he +CMU. Consequently, a guest reboot requires the future K230 reset subsystem +and matching OpenSBI reboot backend; QMP ``system_reset`` resets the CMU a= long +with the rest of the machine. + Boot options ------------ The ``k230`` machine supports K230 SDK boot through M-mode U-Boot, which t= hen --=20 2.43.0