Received: by 2002:a05:7412:8d11:b0:fa:4934:9f with SMTP id bj17csp434415rdb; Mon, 15 Jan 2024 01:59:06 -0800 (PST) X-Google-Smtp-Source: AGHT+IHVRdtd+O5hloVKXeSd+z35KU9r72Vv00MpBwVtytKMkmiULp739J2K0LQUEGnq0DMy0ZIg X-Received: by 2002:a05:6214:230f:b0:681:2640:3c17 with SMTP id gc15-20020a056214230f00b0068126403c17mr8257628qvb.55.1705312745904; Mon, 15 Jan 2024 01:59:05 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1705312745; cv=none; d=google.com; s=arc-20160816; b=Bql2xzR9lMOvB0y1i81dtWBBrJ7SdgOKZekt10YfyHhFIegejU4j3GDsW1WtFTPWzC CZ55d7e49lGnBf7ygQ6fGiGxGrZBhcn/WjhukMI3rH8GW2QhuQZjwJGhzpqbJLenJ7Hs ReLpU8SimcdGvYVP5dVvEunElMzdxoNnteX9GFSOFJVx5mcCBzyMLvkMC9aCN2cSqJEZ 1WlW81MQCsB6Wy510Lc5XP+Y34pDqthuRUYx/htO8tMRu8khPzVlfVkGt1VjEhSx+hyO jVKTW+dIedeqnXa3vRuBnNxa2PmWoNU/y0+2ELy5V4ZZTtuVqJZId5EFcTTraRsbe1s4 7uqw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:subject:message-id:date:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:from :dkim-signature; bh=Un0coVhtWSEOIOADUBKABiubu38hV2vKs0T4BYd1GBo=; fh=I8DfF3Mdni5EGDfdItZlMHWtNZZhwbhtK6zdcgpiXz4=; b=cgsLH2o+oqKmMhUdMVUuHlwja12u3d9Td6oRlvrsYZkMnWRnFbS232Al+TsKrSFhMH 6Qys3DBIe87NXL/He5w7eZddu7Wi7L8zVyJRSyMP6EV0872aTdfH1akgR3I67rHJ/jtm lRRU2Xpa5x7jjQ8XvaO73Op2yGyLz+ULDyfw7ODFAENbmiVvY7Fdv91POcGpheH6NESr bcYjrjn+4Thss3wmLZcmajocduTG7rWB/afvwvUa5AysoUReb1UTd0wwfRN//AP5DTK4 lXelJSZoUOsoB17Qzviv/OSjGhaeObNXBLjutYuLfd1ZDKhs9KAtI7wflZzeh1jjcMsl IQ6w== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@canonical.com header.s=20210705 header.b="EEdfps8/"; spf=pass (google.com: domain of linux-kernel+bounces-25836-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-25836-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=canonical.com Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id s7-20020a0cb307000000b0067f74a8de8esi7494636qve.501.2024.01.15.01.59.05 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Jan 2024 01:59:05 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-25836-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@canonical.com header.s=20210705 header.b="EEdfps8/"; spf=pass (google.com: domain of linux-kernel+bounces-25836-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-25836-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=canonical.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 469DF1C21674 for ; Mon, 15 Jan 2024 09:59:05 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 595A3F9E5; Mon, 15 Jan 2024 09:58:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b="EEdfps8/" Received: from smtp-relay-internal-0.canonical.com (smtp-relay-internal-0.canonical.com [185.125.188.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0E602F9C7 for ; Mon, 15 Jan 2024 09:58:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=canonical.com Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 3FED23F694 for ; Mon, 15 Jan 2024 09:52:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1705312330; bh=jI+5qM0nAtwQLs5qbWPIA0JCeb2TgRx9NNnpwhxsqJI=; h=From:In-Reply-To:References:Mime-Version:Date:Message-ID:Subject: To:Cc:Content-Type; b=EEdfps8/yFcDR1DZ4FnrgMgxoABrzMjXGlIyeEK+JKMcaY7xJ60aIZ+PJCR2hv4WR dzvH3SppR2H1tcpfXYR/3VVA1VVnTpTpg1DyhlxmLgAOClFgnSdO9TEj8XpnCU052w M0vvwBTrcyZX2jYgtkoprU5sprQsKqS/wWRXiku37RWIUgrzcVYs+k/AIpgK36oE0j pXtVnR7SJn47SsnECfltA+3sk6BktY5pW99YC5gyt8f1gTETnWSJrvjtGj+SIT5JPK VaTTWYLZlTxiEoNPfPR3EobWUoj21qasRxNK6G2NoMlTVO02oHAiyrd0r5RoIoO/68 si6OC3Lbbr6/w== Received: by mail-qt1-f198.google.com with SMTP id d75a77b69052e-429abac743fso89431581cf.2 for ; Mon, 15 Jan 2024 01:52:10 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1705312329; x=1705917129; h=cc:to:subject:message-id:date:mime-version:references:in-reply-to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=jI+5qM0nAtwQLs5qbWPIA0JCeb2TgRx9NNnpwhxsqJI=; b=IX+uPlQHV8pegI/h0f8JsHr0n9xifstI26h1+ScuPIb9IGEkqgmjwxPLd3bYTBqxB6 is1g9LYheU7f9rjCiWytMSX2RDOaTs/5ZXTMMMhR6GOg8N8TreIimFoy+w4wZ/yrM2gl XeMw2lA8jALMpsi5fPcnTsValzbTqvZigv2NBYHpuAqjrbhelaI4mCFoEB4LRHbtrdeM 5/NjkR57LLzOG0uYpPXoLZhv3240hk6WDyFiQTHxYTwtrkCjoNQ5vawLcf3CJndLGSS3 raS7cYkIEKc37RkNjfnYOZ6kggCYlJKBT+QNPsVnnM+nwCuakkRHhvFFHGXI+Wos20qx mmmw== X-Gm-Message-State: AOJu0YyDl4yQQnq+4vNWEqbo7sTkNkfZJC8HGZI01J1vTz8gDOG2aABf WC0LIKnMitoAvhF31DFvTIxYdsKmiTg98ztIgJYRy2s8biexkgXUdJ1B76w3dBV5/9OZ1dk504+ AOCDs9Fe7XZO+R62B9WDcBOeyagV0h5DcY1YpKKEv7OErTfT9CzYhKEpyTgaYFykB X-Received: by 2002:a05:622a:4:b0:429:92b7:cba8 with SMTP id x4-20020a05622a000400b0042992b7cba8mr6911262qtw.126.1705312329278; Mon, 15 Jan 2024 01:52:09 -0800 (PST) X-Received: by 2002:a05:622a:4:b0:429:92b7:cba8 with SMTP id x4-20020a05622a000400b0042992b7cba8mr6911258qtw.126.1705312328988; Mon, 15 Jan 2024 01:52:08 -0800 (PST) Received: from 348282803490 named unknown by gmailapi.google.com with HTTPREST; Mon, 15 Jan 2024 04:52:08 -0500 From: Emil Renner Berthing In-Reply-To: <20240110-clk-th1520-v1-3-8b0682567984@tenstorrent.com> References: <20240110-clk-th1520-v1-0-8b0682567984@tenstorrent.com> <20240110-clk-th1520-v1-3-8b0682567984@tenstorrent.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 Date: Mon, 15 Jan 2024 04:52:08 -0500 Message-ID: Subject: Re: [PATCH RFC 3/3] clk: thead: add support for T-HEAD TH1520 AP clocks To: Drew Fustini , Jisheng Zhang , Guo Ren , Fu Wei , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Yangtao Li Cc: linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, Emil Renner Berthing , Han Gao , Xi Ruoyao , Robert Nelson , Jason Kridner , Drew Fustini Content-Type: text/plain; charset="UTF-8" Drew Fustini wrote: > From: Jisheng Zhang > > Add support for the AP sub system clock controller in the T-HEAD TH1520. > This include CPU, DPU, GMAC and TEE PLLs. > > Link: https://openbeagle.org/beaglev-ahead/beaglev-ahead/-/blob/main/docs/TH1520%20System%20User%20Manual.pdf > Co-developed-by: Yangtao Li > Signed-off-by: Yangtao Li > Signed-off-by: Jisheng Zhang > [rebased on linux-next-20240110] > [fixed checkpatch warnings] > [corrected npu_clk enable bit and c910_i0_clk reg] > [revised commit description] > Signed-off-by: Drew Fustini > --- > MAINTAINERS | 1 + > drivers/clk/Kconfig | 1 + > drivers/clk/Makefile | 1 + > drivers/clk/thead/Kconfig | 12 + > drivers/clk/thead/Makefile | 2 + > drivers/clk/thead/clk-th1520-ap.c | 1018 +++++++++++++++++++++++++++++++++++++ > 6 files changed, 1035 insertions(+) > .. > --- /dev/null > +++ b/drivers/clk/thead/clk-th1520-ap.c > @@ -0,0 +1,1018 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2023 Jisheng Zhang > + * Copyright (C) 2023 Vivo Communication Technology Co. Ltd. > + * Authors: Yangtao Li > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +struct ccu_internal { > + u8 shift; > + u8 width; > +}; > + > +struct ccu_div_internal { > + u8 shift; > + u8 width; > + u32 flags; > +}; > + > +struct ccu_common { > + struct regmap *map; > + u16 reg; > + struct clk_hw hw; > +}; > + > +struct ccu_mux { > + struct ccu_internal mux; > + struct ccu_common common; > +}; > + > +struct ccu_gate { > + u32 enable; > + struct ccu_common common; > +}; > + > +struct ccu_div { > + u32 enable; > + struct ccu_div_internal div; > + struct ccu_internal mux; > + struct ccu_common common; > +}; > + > +/* > + * struct ccu_mdiv - Definition of an M-D-I-V clock > + * > + * Clocks based on the formula (parent * M) / (D * I * V) > + */ > +struct ccu_mdiv { > + struct ccu_internal m; > + struct ccu_internal d; > + struct ccu_internal i; > + struct ccu_internal v; > + struct ccu_common common; > +}; > [...] > +static unsigned long ccu_mdiv_recalc_rate(struct clk_hw *hw, > + unsigned long parent_rate) > +{ > + struct ccu_mdiv *mdiv = hw_to_ccu_mdiv(hw); > + unsigned long div, rate = parent_rate; > + unsigned int m, d, i, v, val; > + > + regmap_read(mdiv->common.map, mdiv->common.reg, &val); > + > + m = val >> mdiv->m.shift; > + m &= GENMASK(mdiv->m.width - 1, 0); > + > + d = val >> mdiv->d.shift; > + d &= GENMASK(mdiv->d.width - 1, 0); > + > + i = val >> mdiv->i.shift; > + i &= GENMASK(mdiv->i.width - 1, 0); > + > + v = val >> mdiv->v.shift; > + v &= GENMASK(mdiv->v.width - 1, 0); > + > + rate = parent_rate * m; > + div = d * i * v; > + do_div(rate, div); > + > + return rate; > +} Hi Drew, I don't think this is right. There is an input predivider that's not handled here, and then the PLL multiplies the input frequency and outputs "Foutvco". Then this is followed by a post divider to produce "Foutpostdiv". Some clocks derive directly from the "Foutvco" so this should really be modelled as two different clocks. Also what's called D and I are the postdivider but V is an optional fractional divider. All in all I think it should be something like this: #define TH1520_PLL_CFG0 0x0 #define TH1520_PLL_POSTDIV2 GENMASK(26, 24) #define TH1520_PLL_POSTDIV1 GENMASK(22, 20) #define TH1520_PLL_FBDIV GENMASK(19, 8) #define TH1520_PLL_REFDIV GENMASK(5, 0) #define TH1520_PLL_CFG1 0x4 #define TH1520_PLL_BYPASS BIT(30) #define TH1520_PLL_RST BIT(29) #define TH1520_PLL_POSTDIVPD BIT(28) #define TH1520_PLL_4PHASEPD BIT(27) #define TH1520_PLL_DACPD BIT(25) #define TH1520_PLL_DSMPD BIT(24) #define TH1520_PLL_FRAC GENMASK(23, 0) #define TH1520_PLL_FRAC_BITS 24 #define TH1520_PLL_CFG2 0x8 #define TH1520_PLL_CFG3 0xc static unsigned long th1520_pll_vco_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct th1520_pll *pll = th1520_pll_from_vco(hw); void __iomem *cfg0reg = pll->base + TH1520_PLL_CFG0; void __iomem *cfg1reg = pll->base + TH1520_PLL_CFG1; unsigned long rate, mul; u32 cfg0, cfg1, div; scoped_guard(spinlock_irqsave, pll->lock) { cfg0 = readl_relaxed(cfg0reg); cfg1 = readl_relaxed(cfg1reg); } mul = FIELD_GET(TH1520_PLL_FBDIV, cfg0); div = FIELD_GET(TH1520_PLL_REFDIV, cfg0); if (!(cfg1 & TH1520_PLL_DSMPD)) { mul <<= TH1520_PLL_FRAC_BITS; mul += FIELD_GET(TH1520_PLL_FRAC, cfg1); div <<= TH1520_PLL_FRAC_BITS; } rate = parent_rate * mul; do_div(rate, div); return rate; } static unsigned long th1520_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct th1520_pll *pll = th1520_pll_from_postdiv(hw); void __iomem *cfg0reg = pll->base + TH1520_PLL_CFG0; void __iomem *cfg1reg = pll->base + TH1520_PLL_CFG1; unsigned long rate = parent_rate; u32 cfg0, cfg1; scoped_guard(spinlock_irqsave, pll->lock) { cfg0 = readl_relaxed(cfg0reg); cfg1 = readl_relaxed(cfg1reg); } if (cfg1 & TH1520_PLL_BYPASS) return rate; do_div(rate, FIELD_GET(TH1520_PLL_POSTDIV1, cfg0) * FIELD_GET(TH1520_PLL_POSTDIV2, cfg0)); return rate; } (Here D = POSTDIV1, I = POSTDIV2 and V = FRAC) However, have a look at Chen Wang's series at https://lore.kernel.org/linux-riscv/cdb7aed766aa6411e61ec25a6f1cb22a1aef4a21.1704694903.git.unicorn_wang@outlook.com/ The PLL implementation there is very similar to the TH1520. At first I thought it was exactly the same, but on closer inspection it seems like the bitfields are arranged a little different unfortunately. The rest of the clocks in this driver seem to be generic gate and mux implementations that should probably be replaced by the versions in Linux already. Eg. devm_clk_hw_register_gate*() and devm_clk_hw_register_mux*(). Lastly this only implements the clocks in the AP_SUBSYS memory range, but there are also AON_SUBSYS, DDR_SUBSYS, MISC_SUBSYS, VI_SUBSYS, VO_SUBSYS, VP_SUBSYS, DSP_SUBSYS and AUDIO_SUBSYS. Upstreaming one of them first in fine, but make sure to consider how the others should be added. /Emil