From nobody Fri Oct 3 21:52:21 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 B1FF51A288 for ; Sat, 23 Aug 2025 17:26:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755969967; cv=none; b=azwg47gxuZ5pJWKvmb5/k00+FADz7TfitrtzwBnpsVJVts4IJoF1wD3ITNGi66qHOxGFBKKWCYpA4e0ouBsjwgbJ3Z/HQpmwll3TBI4wZ4eQq8/ACSkwgsbDA5qjMDN380PonHJYNzIjzt36DOGUj7UyJ8HtpDrbtvXiYmpT9ag= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755969967; c=relaxed/simple; bh=e1kmgWmlUGhFZL70rqdb+2JREf9OJYL5d+iZpZNb2vM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; b=TSIn5ek9UIHdOrbKCXAj+sdZgTio7Cx7MzFXK7auCXh1mgOYf2tt0vZpXGAONbNl7xX6iuvIHfJ34XoOY/Zy/Jge2tFh/aHdoLsKxRdWWSd1v+UmAkmXumA85+l57gtACR6itBCEKIln8U1qVJ+C8pf2rZaD54lOTI0ugi0TcOc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TTC5pZJD; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="TTC5pZJD" Received: by smtp.kernel.org (Postfix) with ESMTPS id 18379C4CEE7; Sat, 23 Aug 2025 17:26:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1755969967; bh=e1kmgWmlUGhFZL70rqdb+2JREf9OJYL5d+iZpZNb2vM=; h=From:Date:Subject:To:Cc:Reply-To:From; b=TTC5pZJDI26xgoHqxvRFFbFXr07KuV9XbPSJOEjVwjNSW30us2VRp9O5SrEWZHMoi s0rFQRZOpOtkqP9FG5aktzfttBIUgG9pUYWX21CQcpU2H8Fw5MSOOOvAAUiLlMKujv AAw7U2ywyFcDuiPPpemwooPTjV57NIFe1odfkhEwrByJUEjpHbQnp8OlrNiRjk6mO4 /diXdENdBLJO74+WDlNEfVIh1xe+TZ9jGkXMzvCI0gM4OxVMo0cxBmMqhpUz4+HCFi fNkpGAx42uBODdAfQ2PqagdEQzoaigSzwJZGZWr+Y2QR7j1GrXSXrgnLPOcyAKRCq2 Fh86NMGaz9cfg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 03EBCCA0FE1; Sat, 23 Aug 2025 17:26:07 +0000 (UTC) From: Aaron Kling via B4 Relay Date: Sat, 23 Aug 2025 12:26:05 -0500 Subject: [PATCH v2] drm/nouveau: Support reclocking on gp10b Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250823-gp10b-reclock-v2-1-90a1974a54e3@gmail.com> X-B4-Tracking: v=1; b=H4sIAKz5qWgC/3XMSw6DIBSF4a2YOy4NjyCmo+7DOEB6wZuqGGhMG 8PeS513+J/kfAdkTIQZbs0BCXfKFNca8tKAm+wakNGjNkguNe+kZGETfGQJ3RzdkxkzetVyrm3 XQv1sCT29T68fak+UXzF9Tn4Xv/WftAsmmB65QuuVUdrew2Jpvrq4wFBK+QKjMOw3qgAAAA== X-Change-ID: 20250822-gp10b-reclock-77bf36005a86 To: Lyude Paul , Danilo Krummrich , David Airlie , Simona Vetter Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, nouveau@lists.freedesktop.org, Aaron Kling X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1755969966; l=7837; i=webgeek1234@gmail.com; s=20250217; h=from:subject:message-id; bh=ORTgFAySW5YP39GAofc6irg3iux8MdjoBE9G2yJqggw=; b=p1rdWeJJgvZVq/cL66hpKKp/8N8spJmWxoJfDY06sn3iyJ/s5z8109b7Et7gJSudb5u8AuuFX pD+rjAfUN6DAhH8J+sTPV1mJudOyNbcHwttPfaJxPHKH9Z1YRAT1tP3 X-Developer-Key: i=webgeek1234@gmail.com; a=ed25519; pk=TQwd6q26txw7bkK7B8qtI/kcAohZc7bHHGSD7domdrU= X-Endpoint-Received: by B4 Relay for webgeek1234@gmail.com/20250217 with auth_id=342 X-Original-From: Aaron Kling Reply-To: webgeek1234@gmail.com From: Aaron Kling Starting with Tegra186, gpu clock handling is done by the bpmp and there is little to be done by the kernel. The only thing necessary for reclocking is to set the gpcclk to the desired rate and the bpmp handles the rest. The pstate list is based on the downstream driver generates. Signed-off-by: Aaron Kling Reviewed-by: Lyude Paul --- Changes in v2: - Fix missing static as reported by kernel ci - Link to v1: https://lore.kernel.org/r/20250822-gp10b-reclock-v1-1-5b03eaf= 3735a@gmail.com --- drivers/gpu/drm/nouveau/include/nvkm/subdev/clk.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/clk/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/clk/gp10b.c | 180 ++++++++++++++++++= ++++ drivers/gpu/drm/nouveau/nvkm/subdev/clk/gp10b.h | 16 ++ 5 files changed, 199 insertions(+) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/clk.h b/drivers/gp= u/drm/nouveau/include/nvkm/subdev/clk.h index d5d8877064a71581d8e9e92f30a3e28551dabf17..6a09d397c651aa94718aff3d193= 7162df39cc2ae 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/clk.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/clk.h @@ -134,4 +134,5 @@ int gf100_clk_new(struct nvkm_device *, enum nvkm_subde= v_type, int inst, struct int gk104_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, s= truct nvkm_clk **); int gk20a_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, s= truct nvkm_clk **); int gm20b_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, s= truct nvkm_clk **); +int gp10b_clk_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, s= truct nvkm_clk **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gp= u/drm/nouveau/nvkm/engine/device/base.c index 3375a59ebf1a4af73daf4c029605a10a7721c725..2517b65d8faad9947244707f540= eb281ad7652e4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2280,6 +2280,7 @@ nv13b_chipset =3D { .acr =3D { 0x00000001, gp10b_acr_new }, .bar =3D { 0x00000001, gm20b_bar_new }, .bus =3D { 0x00000001, gf100_bus_new }, + .clk =3D { 0x00000001, gp10b_clk_new }, .fault =3D { 0x00000001, gp10b_fault_new }, .fb =3D { 0x00000001, gp10b_fb_new }, .fuse =3D { 0x00000001, gm107_fuse_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/Kbuild b/drivers/gpu/d= rm/nouveau/nvkm/subdev/clk/Kbuild index dcecd499d8dffae3b81276ed67bb8649dfa3efd1..9fe394740f568909de71a8c420c= c8b6d8dc2235f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/Kbuild @@ -10,6 +10,7 @@ nvkm-y +=3D nvkm/subdev/clk/gf100.o nvkm-y +=3D nvkm/subdev/clk/gk104.o nvkm-y +=3D nvkm/subdev/clk/gk20a.o nvkm-y +=3D nvkm/subdev/clk/gm20b.o +nvkm-y +=3D nvkm/subdev/clk/gp10b.o =20 nvkm-y +=3D nvkm/subdev/clk/pllnv04.o nvkm-y +=3D nvkm/subdev/clk/pllgt215.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gp10b.c b/drivers/gpu/= drm/nouveau/nvkm/subdev/clk/gp10b.c new file mode 100644 index 0000000000000000000000000000000000000000..a0be53ffeb4479e4c229bd6bde8= 6bb6bdb082b56 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gp10b.c @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: MIT +#include +#include +#include +#include + +#include "priv.h" +#include "gk20a.h" +#include "gp10b.h" + +static int +gp10b_clk_init(struct nvkm_clk *base) +{ + struct gp10b_clk *clk =3D gp10b_clk(base); + struct nvkm_subdev *subdev =3D &clk->base.subdev; + int ret; + + /* Start with the highest frequency, matching the BPMP default */ + base->func->calc(base, &base->func->pstates[base->func->nr_pstates - 1].b= ase); + ret =3D base->func->prog(base); + if (ret) { + nvkm_error(subdev, "cannot initialize clock\n"); + return ret; + } + + return 0; +} + +static int +gp10b_clk_read(struct nvkm_clk *base, enum nv_clk_src src) +{ + struct gp10b_clk *clk =3D gp10b_clk(base); + struct nvkm_subdev *subdev =3D &clk->base.subdev; + + switch (src) { + case nv_clk_src_gpc: + return clk_get_rate(clk->clk) / GK20A_CLK_GPC_MDIV; + default: + nvkm_error(subdev, "invalid clock source %d\n", src); + return -EINVAL; + } +} + +static int +gp10b_clk_calc(struct nvkm_clk *base, struct nvkm_cstate *cstate) +{ + struct gp10b_clk *clk =3D gp10b_clk(base); + u32 target_rate =3D cstate->domain[nv_clk_src_gpc] * GK20A_CLK_GPC_MDIV; + + clk->new_rate =3D clk_round_rate(clk->clk, target_rate) / GK20A_CLK_GPC_M= DIV; + + return 0; +} + +static int +gp10b_clk_prog(struct nvkm_clk *base) +{ + struct gp10b_clk *clk =3D gp10b_clk(base); + int ret; + + ret =3D clk_set_rate(clk->clk, clk->new_rate * GK20A_CLK_GPC_MDIV); + if (ret < 0) + return ret; + + clk->rate =3D clk_get_rate(clk->clk) / GK20A_CLK_GPC_MDIV; + + return 0; +} + +static struct nvkm_pstate +gp10b_pstates[] =3D { + { + .base =3D { + .domain[nv_clk_src_gpc] =3D 114750, + }, + }, + { + .base =3D { + .domain[nv_clk_src_gpc] =3D 216750, + }, + }, + { + .base =3D { + .domain[nv_clk_src_gpc] =3D 318750, + }, + }, + { + .base =3D { + .domain[nv_clk_src_gpc] =3D 420750, + }, + }, + { + .base =3D { + .domain[nv_clk_src_gpc] =3D 522750, + }, + }, + { + .base =3D { + .domain[nv_clk_src_gpc] =3D 624750, + }, + }, + { + .base =3D { + .domain[nv_clk_src_gpc] =3D 726750, + }, + }, + { + .base =3D { + .domain[nv_clk_src_gpc] =3D 828750, + }, + }, + { + .base =3D { + .domain[nv_clk_src_gpc] =3D 930750, + }, + }, + { + .base =3D { + .domain[nv_clk_src_gpc] =3D 1032750, + }, + }, + { + .base =3D { + .domain[nv_clk_src_gpc] =3D 1134750, + }, + }, + { + .base =3D { + .domain[nv_clk_src_gpc] =3D 1236750, + }, + }, + { + .base =3D { + .domain[nv_clk_src_gpc] =3D 1300500, + }, + }, +}; + +static const struct nvkm_clk_func +gp10b_clk =3D { + .init =3D gp10b_clk_init, + .read =3D gp10b_clk_read, + .calc =3D gp10b_clk_calc, + .prog =3D gp10b_clk_prog, + .tidy =3D gk20a_clk_tidy, + .pstates =3D gp10b_pstates, + .nr_pstates =3D ARRAY_SIZE(gp10b_pstates), + .domains =3D { + { nv_clk_src_gpc, 0xff, 0, "core", GK20A_CLK_GPC_MDIV }, + { nv_clk_src_max } + } +}; + +int +gp10b_clk_new(struct nvkm_device *device, enum nvkm_subdev_type type, int = inst, + struct nvkm_clk **pclk) +{ + struct nvkm_device_tegra *tdev =3D device->func->tegra(device); + const struct nvkm_clk_func *func =3D &gp10b_clk; + struct gp10b_clk *clk; + int ret, i; + + clk =3D kzalloc(sizeof(*clk), GFP_KERNEL); + if (!clk) + return -ENOMEM; + *pclk =3D &clk->base; + clk->clk =3D tdev->clk; + + /* Finish initializing the pstates */ + for (i =3D 0; i < func->nr_pstates; i++) { + INIT_LIST_HEAD(&func->pstates[i].list); + func->pstates[i].pstate =3D i + 1; + } + + ret =3D nvkm_clk_ctor(func, device, type, inst, true, &clk->base); + if (ret) + return ret; + + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gp10b.h b/drivers/gpu/= drm/nouveau/nvkm/subdev/clk/gp10b.h new file mode 100644 index 0000000000000000000000000000000000000000..2f65a921a426e3f6339a31e9643= 97f6eefa50250 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gp10b.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_CLK_GP10B_H__ +#define __NVKM_CLK_GP10B_H__ + +struct gp10b_clk { + /* currently applied parameters */ + struct nvkm_clk base; + struct clk *clk; + u32 rate; + + /* new parameters to apply */ + u32 new_rate; +}; +#define gp10b_clk(p) container_of((p), struct gp10b_clk, base) + +#endif --- base-commit: c17b750b3ad9f45f2b6f7e6f7f4679844244f0b9 change-id: 20250822-gp10b-reclock-77bf36005a86 Best regards, --=20 Aaron Kling