From nobody Mon Sep 28 14:47:59 2026 Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7EE7325C6EE for ; Thu, 20 Aug 2026 16:50:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244616; cv=none; b=EyGiQl9FESxxfhJOoFtaFJtAmexBYuwfPR35YblBv6ZxOPVR4rGcL9WDPW8d2zNOhRi7tDH+Njf1VqT+U2+ztbcj+oDUjDf34km5iJMwb4NmtYY6n68GUgWVLYTF2nWHuVHTDWJy9S5JVTGnHtAnlaqOLh/PwzOvRIVRaA4Wods= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244616; c=relaxed/simple; bh=N4dJ/VQfPDh6+1SQ15donlxRwGPwC7fnrB91uT7IBXQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LfEkc4AyxQp/Eg07Ju6oif35RgL1T8315xdTvj77sz4ZvByLJUma/2lPJyrPS95s8RFqwQbkSS/AJxCk/kAepQ3hgYyzE4yVHXaHZV8QEaK5uBmPJssha1wxF6trZQO6Zl9O4ifMuW+AZ8zgH69cKbDCsmRKsk5VoXy78gjrhAU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=gw18BOyt; arc=none smtp.client-ip=209.85.128.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="gw18BOyt" Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-496bb7cdf51so294405e9.2 for ; Thu, 20 Aug 2026 09:50:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787244613; x=1787849413; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=nZ6u9Bl+UeuSLChNk/rtttClrX+K1Z0lpt5z16O5QEc=; b=gw18BOytjnRrwh7vdtFGGM0aZ5H5j5LaCTwPsi2PJyRCaARBVdxCnMyimUKZC2SuwL r3YmE+rTWzRI+JwVJSXmmXMHdq12Avz3z8HU8zaSc0khhA96imE5TLf3RfGQQmmWGfd3 V0hUlEykDZoFB4Hw80Qtv3JxBG/UwIBniMTGLOaGE5V7z5PIdg9DfgYdrb7lW1xmYojQ kWDOgE37pgHYDRFMc4ww8Yen/f2NWmcFks9Pfp9hl1K1xdRQ4VmA2orMRXe2Gr5INzVu qIRB6BPzoEzUhdKssYrFE5x3KPmToruoeuI0SGjsKKx2MP049MJtciD0jcdTfNwOV13c ZDdg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787244613; x=1787849413; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=nZ6u9Bl+UeuSLChNk/rtttClrX+K1Z0lpt5z16O5QEc=; b=Advtm+kDgVrvhza0V3wIHBxHC+h0bpMtvZya3ATBptxY58md8unXpumgGOHwTyfJ64 aEzfR98B/suu2gDDKGf50ohfpxzpL7DHqM0FJgKcaVX2GNY8KLFONxqgV+MR859JO/Zr kMct93mARMHzMBLLKxkaRXvtpmKK+qxE15GmwRKEwQxGWDbcEXqkoNb3ov0JOKw6dh0q 7GhaP7yFR0IgF52yBQVOSlg/AQpL6Y+rTYVci2VawHWFzovdoG4L8ZYvJkN1CPnzf7cx 6GQj8J9kLOL9HMs6G0T7Sj9jHXvfXx/x3EkPU+q3DT22pLlZtoc+Iq/NVc8UJleLi58L LMqQ== X-Gm-Message-State: AOJu0Yx+/U7vUc+Y67zJBksHEdggVzwLxZ+rVJY9StCxbLxjEu9urKyB 2Lf8FMK7abvKNkDCt4c6lynUIqh2nagZ7cKSUz82xb4MHPq08o0tTbnbhs7eg0KE X-Gm-Gg: AR+sD13hkhuT0a/H9yKF1/DyCYATVmbmlVPItJmvf9jJScZCkuddKVssl6YXGGpxX06 u3wtGx/YzU/OxAtCiBV+LLbQGMJhuPeI0+jzTsR+OmUo4PUyp+7XQGjX/PDjAM6GJO5QXyaXEup bqJj/99S/7QjuIC2Fs9UrckOIZC+SSn/KxoJiSQYkMa9AuY94mE2FcqF0v6LZSo/gQ/o3FEhrJ2 PNBB5BjxkkU+1Jq0rY3vehlEHqd49PKvteQSQw6PcEkHKek2BTThFP4AjAuTitdj82JXqQSox7R Zytn2kqDzN1jjK/preGqC93Nu60Te1Hd8zohoM/RPi8oOf8QhVYsGPYSisCHv+b7G9vbssKYykx C7xMxnppkNstgZc63DzVY+VI/Gei0dTJTBOx3dAs2FEYAHmVaQV0dpaTtmrbdX55B0fMxVz6hJm a6/spXoAVDfE6PAt97RXJgeTE9f5ZPwKQFyAFa14k+SbqNo6TzuRQmWluke2xjUYlhHY8= X-Received: by 2002:a05:600c:3544:b0:493:f140:c3fb with SMTP id 5b1f17b1804b1-499b8301874mr4103855e9.7.1787244612602; Thu, 20 Aug 2026 09:50:12 -0700 (PDT) Received: from fedora ([5.31.134.170]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-499aa1111b2sm205307545e9.5.2026.08.20.09.50.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 09:50:11 -0700 (PDT) From: Mohamed Ahmed To: linux-kernel@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, Lyude Paul , Danilo Krummrich , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Mary Guillemard , nouveau@lists.freedesktop.org, Mohamed Ahmed Subject: [PATCH v2 01/10] drm/nouveau/disp: move GSP head-timing ISR and vblank helpers to tu102.c Date: Thu, 20 Aug 2026 20:49:20 +0400 Message-ID: <20260820164929.17117-2-mohamedahmedegypt2001@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> References: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The GSP-RM display code in rm/r535/disp.c owns a handful of direct MMIO routines: the head-timing (vblank) interrupt handler and the per-head vblank enable/disable. They program display registers, not RM, so they belong with the rest of the per-chip register code in engine/disp/. Move them to tu102.c (Turing is the first GSP-capable generation) as tu102_disp_intr() and tu102_head_vblank_get()/put(), exported for rm/r535/disp.c, which keeps calling them by name for now. No functional change. Signed-off-by: Mohamed Ahmed Reviewed-by: Lyude Paul --- .../gpu/drm/nouveau/nvkm/engine/disp/head.h | 3 ++ .../gpu/drm/nouveau/nvkm/engine/disp/priv.h | 1 + .../gpu/drm/nouveau/nvkm/engine/disp/tu102.c | 50 ++++++++++++++++++ .../nouveau/nvkm/subdev/gsp/rm/r535/disp.c | 52 ++----------------- 4 files changed, 57 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h b/drivers/gpu/= drm/nouveau/nvkm/engine/disp/head.h index b642729c254f..986043e87554 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h @@ -56,6 +56,9 @@ int gv100_head_new(struct nvkm_disp *, int id); void gv100_head_state(struct nvkm_head *head, struct nvkm_head_state *stat= e); void gv100_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline); =20 +void tu102_head_vblank_get(struct nvkm_head *); +void tu102_head_vblank_put(struct nvkm_head *); + #define HEAD_MSG(h,l,f,a...) do { = \ struct nvkm_head *_h =3D (h); \ nvkm_##l(&_h->disp->engine.subdev, "head-%d: "f"\n", _h->id, ##a); \ diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h b/drivers/gpu/= drm/nouveau/nvkm/engine/disp/priv.h index a3fd7cb7c488..722ec340e12a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h @@ -72,6 +72,7 @@ int gv100_disp_wndw_cnt(struct nvkm_disp *, unsigned long= *); int gv100_disp_caps_new(const struct nvkm_oclass *, void *, u32, struct nv= km_object **); =20 int tu102_disp_init(struct nvkm_disp *); +irqreturn_t tu102_disp_intr(struct nvkm_inth *); =20 void nv50_disp_dptmds_war_2(struct nvkm_disp *, struct dcb_output *); void nv50_disp_dptmds_war_3(struct nvkm_disp *, struct dcb_output *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/tu102.c b/drivers/gpu= /drm/nouveau/nvkm/engine/disp/tu102.c index dcb9f8ba374c..7b70b466fa36 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/tu102.c @@ -104,6 +104,56 @@ tu102_sor_new(struct nvkm_disp *disp, int id) return nvkm_ior_new_(&tu102_sor, disp, SOR, id, hda & BIT(id)); } =20 +/* The GSP-RM display path leaves head-timing (vblank) interrupts and their + * enables to us. These program the RM head-timing line (bit 1 of the + * per-head enable, not the bit nvkm's own gv100 path uses). + */ +void +tu102_head_vblank_put(struct nvkm_head *head) +{ + struct nvkm_device *device =3D head->disp->engine.subdev.device; + + nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000002, 0x00000000); +} + +void +tu102_head_vblank_get(struct nvkm_head *head) +{ + struct nvkm_device *device =3D head->disp->engine.subdev.device; + + nvkm_wr32(device, 0x611800 + (head->id * 4), 0x00000002); + nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000002, 0x00000002); +} + +static void +tu102_disp_intr_head_timing(struct nvkm_disp *disp, int head) +{ + struct nvkm_subdev *subdev =3D &disp->engine.subdev; + struct nvkm_device *device =3D subdev->device; + u32 stat =3D nvkm_rd32(device, 0x611c00 + (head * 0x04)); + + if (stat & 0x00000002) { + nvkm_disp_vblank(disp, head); + + nvkm_wr32(device, 0x611800 + (head * 0x04), 0x00000002); + } +} + +irqreturn_t +tu102_disp_intr(struct nvkm_inth *inth) +{ + struct nvkm_disp *disp =3D container_of(inth, typeof(*disp), engine.subde= v.inth); + struct nvkm_subdev *subdev =3D &disp->engine.subdev; + struct nvkm_device *device =3D subdev->device; + unsigned long mask =3D nvkm_rd32(device, 0x611ec0) & 0x000000ff; + int head; + + for_each_set_bit(head, &mask, 8) + tu102_disp_intr_head_timing(disp, head); + + return IRQ_HANDLED; +} + int tu102_disp_init(struct nvkm_disp *disp) { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c b/drive= rs/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c index e77733a5d9c3..8e57bb6519e5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c @@ -608,29 +608,12 @@ r535_sor_cnt(struct nvkm_disp *disp, unsigned long *p= mask) return 4; } =20 -static void -r535_head_vblank_put(struct nvkm_head *head) -{ - struct nvkm_device *device =3D head->disp->engine.subdev.device; - - nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000002, 0x00000000); -} - -static void -r535_head_vblank_get(struct nvkm_head *head) -{ - struct nvkm_device *device =3D head->disp->engine.subdev.device; - - nvkm_wr32(device, 0x611800 + (head->id * 4), 0x00000002); - nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000002, 0x00000002); -} - static const struct nvkm_head_func r535_head =3D { .state =3D gv100_head_state, .rgpos =3D gv100_head_rgpos, - .vblank_get =3D r535_head_vblank_get, - .vblank_put =3D r535_head_vblank_put, + .vblank_get =3D tu102_head_vblank_get, + .vblank_put =3D tu102_head_vblank_put, }; =20 static struct nvkm_conn * @@ -1404,35 +1387,6 @@ static const struct nvkm_event_func r535_disp_event =3D { }; =20 -static void -r535_disp_intr_head_timing(struct nvkm_disp *disp, int head) -{ - struct nvkm_subdev *subdev =3D &disp->engine.subdev; - struct nvkm_device *device =3D subdev->device; - u32 stat =3D nvkm_rd32(device, 0x611c00 + (head * 0x04)); - - if (stat & 0x00000002) { - nvkm_disp_vblank(disp, head); - - nvkm_wr32(device, 0x611800 + (head * 0x04), 0x00000002); - } -} - -static irqreturn_t -r535_disp_intr(struct nvkm_inth *inth) -{ - struct nvkm_disp *disp =3D container_of(inth, typeof(*disp), engine.subde= v.inth); - struct nvkm_subdev *subdev =3D &disp->engine.subdev; - struct nvkm_device *device =3D subdev->device; - unsigned long mask =3D nvkm_rd32(device, 0x611ec0) & 0x000000ff; - int head; - - for_each_set_bit(head, &mask, 8) - r535_disp_intr_head_timing(disp, head); - - return IRQ_HANDLED; -} - static void r535_disp_fini(struct nvkm_disp *disp, bool suspend) { @@ -1708,7 +1662,7 @@ r535_disp_oneinit(struct nvkm_disp *disp) return ret; =20 ret =3D nvkm_inth_add(&device->vfn->intr, ret, NVKM_INTR_PRIO_NORMAL, &di= sp->engine.subdev, - r535_disp_intr, &disp->engine.subdev.inth); + tu102_disp_intr, &disp->engine.subdev.inth); if (ret) return ret; =20 --=20 2.55.0 From nobody Mon Sep 28 14:47:59 2026 Received: from mail-wm1-f47.google.com (mail-wm1-f47.google.com [209.85.128.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 235E147D935 for ; Thu, 20 Aug 2026 16:50:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244622; cv=none; b=QLWx0req7+NH31HM1Dh+vHgY5/VS3uO72gMFfyudQOnWqyK1fiNDr7XgySS1O5bi3SvC1CX6r98zNaAUIQe/EX9OD8Qlbj4aIsHDNrA/yz0f0eko1Voo0a/HMFbsBQbChoowI3+gylFIbtzw8cdxq8yqEwTQiOz6JNNx9OHteRE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244622; c=relaxed/simple; bh=bLV0QyrRJ3XiBOpEeaayQWuOh4CXhmxxheZ9I7HNJcw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kiS5ndwxe78ANxsVHDnKZvn48U4Ypy8R6Lr8RYQZ9zFseoOlwfOuWgEvoX3Y70AkZaLLHFjfezET8kPf4XW3QB4FiWofzp+S5IFhttDuiEK5Ypjo56wLLfW8t9Cm3E8eX7CpacQiGDkiq8VvfkLNT5o07/MWZt+IqnOFtCck/9s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=N/iTHaVa; arc=none smtp.client-ip=209.85.128.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="N/iTHaVa" Received: by mail-wm1-f47.google.com with SMTP id 5b1f17b1804b1-490cf322ed0so461145e9.1 for ; Thu, 20 Aug 2026 09:50:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787244619; x=1787849419; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=rT8aU54Ao2Sd1OnFQ2SWEU+B+UCoOzmBSCO9Ey1DwWE=; b=N/iTHaVakMJ+VB0YhUlLTt8Q2qlFsjgGWOP0sG3s6JWAxz6YrXsjTMj4OeN1UqI1fC sDqmDlw6i5oNQ5NVVvR6moIROtUnQ5jsI8Iobk2xuD8kSXX73cukSEHbiGOGfCAlxetO n2OTjUrOtXG36833lUWcRRTYWu9gzS6p7In1uJNW7QSR2Ljz5GJ3mAFbybPebpSbreMw QhrnaKtVUHDIY/OpUTo97b4puUyZWH8MfQd0dbq8Jj+jUFescMQMqxw4EE7qJRDHt7M1 9VIUpux4+INz9iiOeE8eiUsmCnVrG6MezlN4/n7vWZxIXhgPg9NnfC8SnPHGXKXRYZqB ZqRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787244619; x=1787849419; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=rT8aU54Ao2Sd1OnFQ2SWEU+B+UCoOzmBSCO9Ey1DwWE=; b=pT/ZboCbLB9Je7pSTuWB78+JKOAiQkFbOk1uJpWMKJ5EYhG5QkFOcfwftskuzOnKhf ZdHed7mApBTFW/8NO5cR0hn2xtdfSX2Kuj3m8ql+GKacaI6VYME20VZwcoVG7kqLu+Dz 5ctGbqUZslmgqUXJmoiHT2zOUR+NOnjrtKkGQaEt/KTvvuVx7oQXpac9if4F4pEIWxeo hmaBQgwR/kLYgInHf1w45ki1hjRxEZu+UbHMZQFiJlUd5b9y6kdnZWQhyPcqrXqn9LMV DctCH3n4o4QpX55SsIWlJ0lzU8csFHvTDhG8fagWf4uar6a/xeo2wpijvBL3rEAxuDhT 0lNw== X-Gm-Message-State: AOJu0YwjkLLynsh7QesPnIn75M7+9QaGeLgQzV040pNPm6RAVfArXPXv 7aI3xTs3PaV27X7kt3e7jjBShUhLklyA+oY7OnDJ9xopRT3esX4fZPDQuGCQGV8R X-Gm-Gg: AR+sD11x+T+wPILGLLS3pdE+pn9vJBQ9Utz/785mzNbh/hJYyCFYIFhxBK7NgHspCgZ ubPHZWYm1YJx4zxME2KpygPS41GYfaE38l5m1VoShNySUxOH+a3EdPBRTDq3Ugh1I2hmjxHxvLe WUIbZLybavomZqynXNSLVnZHuSfVOpa2KjsioYQa4YbNskeRmFC36YjJvyiIxZt/kKW1QMdrsJq VYMFTJgSqgYNseZFD7DS+FjRUXkRns+2ihxZxxSbdVXigi0qfk9Z6l8aOGsSFKdRaNgtdoHZXm2 dlYp/44myNjWg1/yB8frILnmnbo19t+bjQhld9jnjRDreqJ/bMqcJoR6xMMddoRTNlp3d7vXYmA 0FxolnZS1HaY6BASyKcYbyjuQbJHdMUYsPPGmG85XjgZDYgk4QScdAXlUn9mIANPKUZe5W5Fnei m4AQP+TN1DwysxN2olRzWLFe1vWMLUnb5ADHgVkQM5ut+Q560hZcmc7p42OFI8/uXPgtI= X-Received: by 2002:a05:600c:a087:b0:499:a760:722f with SMTP id 5b1f17b1804b1-499b8461acfmr3397515e9.13.1787244619109; Thu, 20 Aug 2026 09:50:19 -0700 (PDT) Received: from fedora ([5.31.134.170]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-499aa1111b2sm205307545e9.5.2026.08.20.09.50.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 09:50:17 -0700 (PDT) From: Mohamed Ahmed To: linux-kernel@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, Lyude Paul , Danilo Krummrich , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Mary Guillemard , nouveau@lists.freedesktop.org, Mohamed Ahmed Subject: [PATCH v2 02/10] drm/nouveau/disp: move the GSP HDMI GCP AVMute write to engine/disp Date: Thu, 20 Aug 2026 20:49:21 +0400 Message-ID: <20260820164929.17117-3-mohamedahmedegypt2001@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> References: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" r535_sor_hdmi_audio() pairs two RM controls (a SET_OD_PACKET carrying the same General Control Packet, and the audio mute-stream toggle) with a direct write of the GCP AVMute bit through the SF GCP unit. The controls are RM and stay, but the direct write is register programming and moves next to the other per-chip display code as tu102_sor_hdmi_gcp(). No functional change. Signed-off-by: Mohamed Ahmed Reviewed-by: Lyude Paul --- drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/disp/tu102.c | 15 +++++++++++++++ .../drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c | 9 +-------- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h b/drivers/gpu/d= rm/nouveau/nvkm/engine/disp/ior.h index 3ba04bead2f9..5d682a774f2d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h @@ -194,6 +194,7 @@ void gv100_sor_dp_audio_sym(struct nvkm_ior *, int, u16= , u32); void gv100_sor_dp_watermark(struct nvkm_ior *, int, u8); extern const struct nvkm_ior_func_hda gv100_sor_hda; =20 +void tu102_sor_hdmi_gcp(struct nvkm_ior *, int, bool); void tu102_sor_dp_vcpi(struct nvkm_ior *, int, u8, u8, u16, u16); =20 int nv50_pior_cnt(struct nvkm_disp *, unsigned long *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/tu102.c b/drivers/gpu= /drm/nouveau/nvkm/engine/disp/tu102.c index 7b70b466fa36..6cfd52c9056f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/tu102.c @@ -30,6 +30,21 @@ =20 #include =20 +/* General Control Packet: bracket an audio enable/disable with AVMute + * through the legacy GCP SF unit. Used by the GSP-RM path, which sends the + * equivalent packet via RM as well but keeps the direct write in sync. + */ +void +tu102_sor_hdmi_gcp(struct nvkm_ior *sor, int head, bool enable) +{ + struct nvkm_device *device =3D sor->disp->engine.subdev.device; + const u32 hdmi =3D head * 0x400; + + nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000000); + nvkm_wr32(device, 0x6f00cc + hdmi, !enable ? 0x00000001 : 0x00000010); + nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000001); +} + void tu102_sor_dp_vcpi(struct nvkm_ior *sor, int head, u8 slot, u8 slot_nr, u16= pbn, u16 aligned) { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c b/drive= rs/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c index 8e57bb6519e5..cd4451e62512 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c @@ -545,16 +545,9 @@ r535_sor_hdmi_ctrl_audio(struct nvkm_outp *outp, bool = enable) static void r535_sor_hdmi_audio(struct nvkm_ior *sor, int head, bool enable) { - struct nvkm_device *device =3D sor->disp->engine.subdev.device; - const u32 hdmi =3D head * 0x400; - r535_sor_hdmi_ctrl_audio(sor->asy.outp, enable); r535_sor_hdmi_ctrl_audio_mute(sor->asy.outp, !enable); - - /* General Control (GCP). */ - nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000000); - nvkm_wr32(device, 0x6f00cc + hdmi, !enable ? 0x00000001 : 0x00000010); - nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000001); + tu102_sor_hdmi_gcp(sor, head, enable); } =20 static void --=20 2.55.0 From nobody Mon Sep 28 14:47:59 2026 Received: from mail-wm1-f41.google.com (mail-wm1-f41.google.com [209.85.128.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7896647D935 for ; Thu, 20 Aug 2026 16:50:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244629; cv=none; b=eG8V+CL3GDTTcIX7S+Esa1+rPs/tPvVfrYvIuAdUo2cHv4qp/H9FpyhQzYO/ZXlIfHC3MC5XfscrRjIEhq1KoUizYgBkWPhxJ4DtIOeaIdZfW6lDCM/Y8kgNoGB3/uzYicajmhS+0nVGV2PNwZhiMRv8AMiXqFINKb7C80c5mMM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244629; c=relaxed/simple; bh=XZqwrkVdoORwSTP1RHva7vdp29OX/3XDtwh9D4Qj2RE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QU1ISlq9MzN2SrZ0/VaT+o04iZ4TUptaktcGudbyLehS+VKZfYOhogzPvrJ+zqYgGbPYQxh+YUcKZqu1pL9gtviEskSdSpbddxHaVUh4mJ4S+RZnCJvx2xFAZ04DIxELd2KcHyDnjYMOT1ILOtZA6UhVfiN55AVooMeXWclJAo0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Rtp54oYN; arc=none smtp.client-ip=209.85.128.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Rtp54oYN" Received: by mail-wm1-f41.google.com with SMTP id 5b1f17b1804b1-49557167508so362595e9.1 for ; Thu, 20 Aug 2026 09:50:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787244626; x=1787849426; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=uA+ttixfTL8eQL/cabSDvzDeSAF53vHarfWSrokRJJI=; b=Rtp54oYNlmTpKumwbZ4MybQsbnINbUS7COR2qHhTIzfwb8A6dOL1yWyD8nInwSzVFK ZP1L/G4nhEDdg94xCso2BJ++Crp4F6rcE4HBmZ+1jjBgYdY7N+R28cqg6KZj6hII/32U yE7A44HSEVfDpWUlU1RdSOQx2m+AyggwRjES+AG3GvM67YfFS3Ah4oUkLVNZQ9KmDOWU rj6jyFO5INgmik9YeUYjZAlUT4+IErLpNYc+0ckDmUOg7KqwFzDR3y7QzPJf9wfDArFg MXALnn3IVnevNBy3K682nriVCJZ1R1uVFLIVQmKj6MCoafvtsTDPftWtoeRQ5vaa8vcQ AVkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787244626; x=1787849426; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=uA+ttixfTL8eQL/cabSDvzDeSAF53vHarfWSrokRJJI=; b=MnHlY9q6zkdAhtXRnjwPnzv0mlW/9qbHVl5qB+JsPElRSuLtgLisAUXR2Aaw3GCPpH U9aKMEd4LHUX5qSdy2/0beOFad7dDynItS+FzlRdvVN6jsIDWuotgOFBdVBPZjbE40z9 mia9aK1byt5gd/wHTH7ovAaDcK6vPJHFLidEmYNb4m378JlLszb3G6kC/1xRqrXPiqmn qOZiE7oA6Th917+iI8HV712vOvB9WxRb1o6GkpRTl5C7WtKLPK/k5xntt3AjhxWhBPIX XhaSJabk4/m3dk5Pef+hUlOY286K3E/g2EJtp/Yb+OK6pi388pZShGS6C3y+6tdwZUUD Z5sg== X-Gm-Message-State: AOJu0YxyRwmO5x4PWafOIab6NqWn1iIc2vKJNoHPlWLj17MxMu3UH9Jl 5D8ElMlHEXYi7h9QafBEvvvlppgeWyaDADcwsj6pFIs7o/H8bmLaQJK+1p2kJ0Hk X-Gm-Gg: AR+sD114A2YcAvIN8BlH09KEgXe824mAuCj3aMEgCTfhBEyf7PvmvmGgVlQImAB4zSB 3KYlgWLwA9gBVGKlNyYCbNBReK6JFDEogFR1XnFEH6pQa9ukqBEU567JaNQZmr+3a09MowDWn1o o7W2Ub6doo03bob4EhDV9QWXOZUUF/3pmKVr8D1QBFblmEGC+elFL1opwWkzqC+ifW7i1moE9Vp D2JnzP1pH6vaD/QIwwTPyJOuqz4JPo33EjbYWGObFaru9aYW3xX4msiLCYRg2t9IXddMRt9tQRb AQy5W5xlNJUVi5PH0PcoTr2piaumdKSVTBwyJeclaemAd/dKz4qm0RRjQK+WuY3en36aqBrjvoD ACq+UlAbgOKqtMzbNni5hnNMgVBJkndp57ehhoPPeVhsR7xX3eD7c7PJzXb1snCxuLU9AajgmuP heegxQsYKIJEml7Iu2cCqr885kjvzCbLOEh9LaoH7OQACSq2JdLON5+WB4ipFehekCxuA= X-Received: by 2002:a05:600c:4e91:b0:499:7a15:fcec with SMTP id 5b1f17b1804b1-499b83547e9mr2734665e9.13.1787244625397; Thu, 20 Aug 2026 09:50:25 -0700 (PDT) Received: from fedora ([5.31.134.170]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-499aa1111b2sm205307545e9.5.2026.08.20.09.50.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 09:50:23 -0700 (PDT) From: Mohamed Ahmed To: linux-kernel@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, Lyude Paul , Danilo Krummrich , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Mary Guillemard , nouveau@lists.freedesktop.org, Mohamed Ahmed Subject: [PATCH v2 03/10] drm/nouveau/disp: route GSP-RM display MMIO through nvkm_disp_func hooks Date: Thu, 20 Aug 2026 20:49:22 +0400 Message-ID: <20260820164929.17117-4-mohamedahmedegypt2001@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> References: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The GSP-RM display code in rm/r535/disp.c borrows a few register-programming routines from engine/disp (the head-timing interrupt handler, vblank enables, armed head state and scanout position readback, the AVI/VSI infoframe writers and the GCP AVMute write) and so far picked them by name, which means it has to know which chip it runs on the moment a generation changes any of them. Give nvkm_disp_func a .gsp table that each chip fills with exactly those hooks, add tu102_gsp_disp (TU1xx) and ga102_gsp_disp (GA10x onwards) carrying the current functions, hand them to r535_disp_new() instead of the full hardware tables, and make rm/r535/disp.c call through the hooks. r535_head becomes four forwarders, r535_sor_hdmi gets infoframe forwarders, r535_sor_hdmi_audio() calls the GCP hook, and the interrupt handler and its vector come from the table (intr_low_latency selects the second DISP interrupt instance for chips that raise head timing on a separate vector). The tables are per chip even though the two currently coincide, so a generation that changes a hook only touches its own file. rm/r535/disp.c no longer contains chip-specific register code, and a new display generation only has to provide its own table. No functional change. Signed-off-by: Mohamed Ahmed --- .../gpu/drm/nouveau/nvkm/engine/disp/ga102.c | 16 ++++- .../gpu/drm/nouveau/nvkm/engine/disp/priv.h | 19 ++++++ .../gpu/drm/nouveau/nvkm/engine/disp/tu102.c | 16 ++++- .../nouveau/nvkm/subdev/gsp/rm/r535/disp.c | 60 ++++++++++++++++--- 4 files changed, 100 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ga102.c b/drivers/gpu= /drm/nouveau/nvkm/engine/disp/ga102.c index ab0a85c92430..b48ed7146396 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ga102.c @@ -144,12 +144,26 @@ ga102_disp =3D { }, }; =20 +static const struct nvkm_disp_func +ga102_gsp_disp =3D { + .uevent =3D &gv100_disp_chan_uevent, + .ramht_size =3D 0x2000, + .gsp.intr =3D tu102_disp_intr, + .gsp.head_state =3D gv100_head_state, + .gsp.head_rgpos =3D gv100_head_rgpos, + .gsp.vblank_get =3D tu102_head_vblank_get, + .gsp.vblank_put =3D tu102_head_vblank_put, + .gsp.hdmi_gcp =3D tu102_sor_hdmi_gcp, + .gsp.hdmi_infoframe_avi =3D gv100_sor_hdmi_infoframe_avi, + .gsp.hdmi_infoframe_vsi =3D gv100_sor_hdmi_infoframe_vsi, +}; + int ga102_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int= inst, struct nvkm_disp **pdisp) { if (nvkm_gsp_rm(device->gsp)) - return r535_disp_new(&ga102_disp, device, type, inst, pdisp); + return r535_disp_new(&ga102_gsp_disp, device, type, inst, pdisp); =20 return nvkm_disp_new_(&ga102_disp, device, type, inst, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h b/drivers/gpu/= drm/nouveau/nvkm/engine/disp/priv.h index 722ec340e12a..3cb903741fb8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h @@ -5,6 +5,8 @@ #include #include struct nvkm_head; +struct nvkm_head_state; +struct nvkm_ior; struct nvkm_outp; struct dcb_output; =20 @@ -34,6 +36,23 @@ struct nvkm_disp_func { int (*new)(struct nvkm_disp *, int id); } wndw, head, dac, sor, pior; =20 + /* Register programming that the GSP-RM display path (rm/r535) needs from + * the chip, everything else on that path goes through RM. Every hook + * is called unconditionally. + */ + struct { + irqreturn_t (*intr)(struct nvkm_inth *); + /* Head-timing interrupts arrive on a second DISP vector. */ + bool intr_low_latency; + void (*head_state)(struct nvkm_head *, struct nvkm_head_state *); + void (*head_rgpos)(struct nvkm_head *, u16 *hline, u16 *vline); + void (*vblank_get)(struct nvkm_head *); + void (*vblank_put)(struct nvkm_head *); + void (*hdmi_gcp)(struct nvkm_ior *, int head, bool enable); + void (*hdmi_infoframe_avi)(struct nvkm_ior *, int head, void *data, u32 = size); + void (*hdmi_infoframe_vsi)(struct nvkm_ior *, int head, void *data, u32 = size); + } gsp; + u16 ramht_size; =20 struct nvkm_sclass root; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/tu102.c b/drivers/gpu= /drm/nouveau/nvkm/engine/disp/tu102.c index 6cfd52c9056f..9db3cac487e3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/tu102.c @@ -295,12 +295,26 @@ tu102_disp =3D { }, }; =20 +static const struct nvkm_disp_func +tu102_gsp_disp =3D { + .uevent =3D &gv100_disp_chan_uevent, + .ramht_size =3D 0x2000, + .gsp.intr =3D tu102_disp_intr, + .gsp.head_state =3D gv100_head_state, + .gsp.head_rgpos =3D gv100_head_rgpos, + .gsp.vblank_get =3D tu102_head_vblank_get, + .gsp.vblank_put =3D tu102_head_vblank_put, + .gsp.hdmi_gcp =3D tu102_sor_hdmi_gcp, + .gsp.hdmi_infoframe_avi =3D gv100_sor_hdmi_infoframe_avi, + .gsp.hdmi_infoframe_vsi =3D gv100_sor_hdmi_infoframe_vsi, +}; + int tu102_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int= inst, struct nvkm_disp **pdisp) { if (nvkm_gsp_rm(device->gsp)) - return r535_disp_new(&tu102_disp, device, type, inst, pdisp); + return r535_disp_new(&tu102_gsp_disp, device, type, inst, pdisp); =20 return nvkm_disp_new_(&tu102_disp, device, type, inst, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c b/drive= rs/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c index cd4451e62512..f3e55253bcbc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c @@ -547,7 +547,19 @@ r535_sor_hdmi_audio(struct nvkm_ior *sor, int head, bo= ol enable) { r535_sor_hdmi_ctrl_audio(sor->asy.outp, enable); r535_sor_hdmi_ctrl_audio_mute(sor->asy.outp, !enable); - tu102_sor_hdmi_gcp(sor, head, enable); + sor->disp->func->gsp.hdmi_gcp(sor, head, enable); +} + +static void +r535_sor_hdmi_infoframe_avi(struct nvkm_ior *sor, int head, void *data, u3= 2 size) +{ + sor->disp->func->gsp.hdmi_infoframe_avi(sor, head, data, size); +} + +static void +r535_sor_hdmi_infoframe_vsi(struct nvkm_ior *sor, int head, void *data, u3= 2 size) +{ + sor->disp->func->gsp.hdmi_infoframe_vsi(sor, head, data, size); } =20 static void @@ -575,8 +587,8 @@ r535_sor_hdmi =3D { .ctrl =3D r535_sor_hdmi_ctrl, .scdc =3D r535_sor_hdmi_scdc, /*TODO: SF_USER -> KMS. */ - .infoframe_avi =3D gv100_sor_hdmi_infoframe_avi, - .infoframe_vsi =3D gv100_sor_hdmi_infoframe_vsi, + .infoframe_avi =3D r535_sor_hdmi_infoframe_avi, + .infoframe_vsi =3D r535_sor_hdmi_infoframe_vsi, .audio =3D r535_sor_hdmi_audio, }; =20 @@ -601,12 +613,36 @@ r535_sor_cnt(struct nvkm_disp *disp, unsigned long *p= mask) return 4; } =20 +static void +r535_head_state(struct nvkm_head *head, struct nvkm_head_state *state) +{ + head->disp->func->gsp.head_state(head, state); +} + +static void +r535_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline) +{ + head->disp->func->gsp.head_rgpos(head, hline, vline); +} + +static void +r535_head_vblank_get(struct nvkm_head *head) +{ + head->disp->func->gsp.vblank_get(head); +} + +static void +r535_head_vblank_put(struct nvkm_head *head) +{ + head->disp->func->gsp.vblank_put(head); +} + static const struct nvkm_head_func r535_head =3D { - .state =3D gv100_head_state, - .rgpos =3D gv100_head_rgpos, - .vblank_get =3D tu102_head_vblank_get, - .vblank_put =3D tu102_head_vblank_put, + .state =3D r535_head_state, + .rgpos =3D r535_head_rgpos, + .vblank_get =3D r535_head_vblank_get, + .vblank_put =3D r535_head_vblank_put, }; =20 static struct nvkm_conn * @@ -1650,12 +1686,17 @@ r535_disp_oneinit(struct nvkm_disp *disp) if (ret) return ret; =20 - ret =3D nvkm_gsp_intr_stall(gsp, disp->engine.subdev.type, disp->engine.s= ubdev.inst); + /* Chips that raise head-timing interrupts on a separate low-latency + * vector report it as a second DISP interrupt table entry, exposed + * as instance 1 by the RM engine-index translation. + */ + ret =3D nvkm_gsp_intr_stall(gsp, disp->engine.subdev.type, + disp->func->gsp.intr_low_latency ? 1 : disp->engine.subdev.inst); if (ret < 0) return ret; =20 ret =3D nvkm_inth_add(&device->vfn->intr, ret, NVKM_INTR_PRIO_NORMAL, &di= sp->engine.subdev, - tu102_disp_intr, &disp->engine.subdev.inth); + disp->func->gsp.intr, &disp->engine.subdev.inth); if (ret) return ret; =20 @@ -1688,6 +1729,7 @@ r535_disp_new(const struct nvkm_disp_func *hw, struct= nvkm_device *device, rm->uevent =3D hw->uevent; rm->sor.cnt =3D r535_sor_cnt; rm->sor.new =3D r535_sor_new; + rm->gsp =3D hw->gsp; rm->ramht_size =3D hw->ramht_size; =20 rm->root.oclass =3D gpu->disp.class.root; --=20 2.55.0 From nobody Mon Sep 28 14:47:59 2026 Received: from mail-wm1-f47.google.com (mail-wm1-f47.google.com [209.85.128.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 379E025C6EE for ; Thu, 20 Aug 2026 16:50:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244636; cv=none; b=AgIQJzFRLfi1t+Lx/GUbN1+5n05bM7KIxmRQHa88qxPDxDzqaPSAC40CPDYwvWniK/FSQkv7tllsi4UhrFr2UvIe/vY7nvf7EMUsHYL/q6H+2UchMQlH7teueHL2Jx/dAho8MpNjAMYSUsWGtvPZSO3WKF50N2N4VpIkI0Fj7FQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244636; c=relaxed/simple; bh=mdZw3YYD76M+QjVpGGWi2Jman+wvmRenqipa27mvmUM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mdnMF/0aiF/5tVjdrkJ1H5+UJpWa3hmZNPgr4+yM3OG9L0BmCrD81Y3MZ6DV8DReX19gPMqOCc5SoPRaVWM2EkT5CbLC9zilbr1gRiKFE4HvcK7amhyc2J44SLmIi19k6Bqhpeglh7ArUHtiW98g4bKXS2IKvCHXRKXm8kza2zs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=OdO8TJAK; arc=none smtp.client-ip=209.85.128.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="OdO8TJAK" Received: by mail-wm1-f47.google.com with SMTP id 5b1f17b1804b1-49954b88fffso486325e9.0 for ; Thu, 20 Aug 2026 09:50:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787244632; x=1787849432; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Ycg+tBlFzf10BcsIAnsRc1Aa1/nfomdKMEdD+fHIfbQ=; b=OdO8TJAKgfma5PGefGzEB6QYJIAOE5bI13INYm6pADnrPoE579V6EUaOBRMhrnaDPk 8iy3innR6S3Sjb9eVfNkT6gY3niESr62BR1VifpjXBlrTVrig3c0jrhw0BrgAiJaDl3O vSsKXdZC8+AxzplBUkqK9J/N0ac8VeH/ZtDYGxsEmmq257p0HQliFl9IyWlQWBGfpg0R enXgvwCZXHW990sr++Rw3H5Cokv96hS0LvN4MJt0VPl0kdlWPD6Zq94Rm9TEx6o0yUq/ 7l6gHLemmgJGWQVxEa6S2nE56A7jdwF5KYC0WSBfRrfxL9Gfj2JfFY4T2QDI2Row9wVB jpjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787244632; x=1787849432; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Ycg+tBlFzf10BcsIAnsRc1Aa1/nfomdKMEdD+fHIfbQ=; b=WtANiaRbWvFXz7VUgWY/E7x5A+Vyz5eOuwmyqcqyxO9wFAT6yejY9QB8cZPzPXpIxF IwaH5aTYEJPqWURZODzhyqpGBfS8+zOeVA+I5aEC651D4/ZH5Yit0FlcjtljSs2w2Vqr K04pnDjnbjud8lvxWVoStrBszJRwwqEZmZyPOHK0gCZV+tWG4cHnSLcqNZRohGKLqK41 mnWqxJo5Jnec0V799KuaAInnOiaGoQLDGRO7DmLC8uiRWbR9dqLajgokXKPAve+kHpRJ vvchbOXhDG7gSn6mfV3uhku4i34/CeIkyM1jtvUInaQFlni2r6M79Tz1/f2KM2uc2zHl DWbA== X-Gm-Message-State: AOJu0Yzvsh0qfCUh9KCnm8FhXhNBSd1vC/eWdlSq+vIegv1TK7WueYfh 8cMmk3/Wl6PcIgJL3AMcYk+NQsil2JQ9SlVk/jG8CUAwu9MAgQY4FQUgur+uH4il X-Gm-Gg: AR+sD10BummFN46XtuAEg2StzTmoUNmkcUED2W4YgvvHVp9SdE2GS/FiHrlWYjjXk1s lXTPCpAT5ViOuffNqfN9sjIAJBGqVIJiTYRiQi4UwNiq8n9y6RYWMam4WF5HwdIbH0ATAM7nCgZ sMEMIxqjKNcuLL+VC7lLWgly+tPcNwweMMPD2vreIuksuCu9nH/GL6bCzU7EsXgAm/gRvy9Ae9b NjMgoWaaMtH2JcEmrRjlCBgj6uV6GgbSU4l+dUIcRosoyHP1cpNN9u1Qn6sCLePptqI6fM366BX qvmgbFmwPM0kXMiD7ORWa+TjbXM12JOcMK5ZutV2ahjpCcpD0Qgz4ysWmCMACJeeaGzRTmy/L5a Yvt7dsKwLjkPZkxNN48dbUb5t7qb7i40cfA/YzC3QQTD2zMnHDNmDVDHEJNDUHdgMrFAlbdr+n9 GSqX8UgcMYP9j42OGgZv73IkapOQgD9o4Mt/hoNMyiXyDDyQuz8dLhkKa2iY3U8xHJGxQF91scC AzdxQ== X-Received: by 2002:a05:600c:8108:b0:493:a966:d5b5 with SMTP id 5b1f17b1804b1-499b82f40b6mr5097465e9.2.1787244632248; Thu, 20 Aug 2026 09:50:32 -0700 (PDT) Received: from fedora ([5.31.134.170]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-499aa1111b2sm205307545e9.5.2026.08.20.09.50.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 09:50:29 -0700 (PDT) From: Mohamed Ahmed To: linux-kernel@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, Lyude Paul , Danilo Krummrich , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Mary Guillemard , nouveau@lists.freedesktop.org, Mohamed Ahmed Subject: [PATCH v2 04/10] drm/nouveau/disp: fix HDMI vendor infoframes on GB20x Date: Thu, 20 Aug 2026 20:49:23 +0400 Message-ID: <20260820164929.17117-5-mohamedahmedegypt2001@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> References: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The GSP path reuses the GV100 direct-MMIO infoframe writers on every chip. On GB20x that is only half right as while the legacy SF AVI unit is unchanged, the legacy VSI unit at 0x6f0100 was removed, so gv100_sor_hdmi_infoframe_vsi() writes into a reserved area and no vendor infoframe ever reaches the HW. This affects HDMI-VIC signalling which can impact some 4K modes for legacy HDMI 1.4 sinks. GB20x (NVDisplay 5.0+) reorganised the SF HDMI packet units. Per NVIDIA's published C971/CA71 DISP_SF_USER class headers, only three legacy units remain (AVI at +0x000, GCP at +0x040, ACR at +0x080), and vendor infoframes must instead be sent through the shared generic infoframe units at +0x130, whose 9-dword packet slots are loaded through the shared data port at +0x3f0/+0x3f4. Add a VSI writer using the same programming sequence OpenRM uses on these chips (nvhdmipkt_C971.c, programAdvancedInfoframeC971()): disable the unit and wait for it to idle, clear the SENT status, write the packet through the data port with a zero inserted in HB3 after the three header bytes, then enable the unit for every-frame transmission during vblank. Generic unit 1 is used for the VSI, matching the slot assignment in NVIDIA's nvkms (NVHDMIPKT_TYPE_SHARED_GENERIC2, unit 0 is reserved for extended metadata packets and unit 2 for the HDR DRM infoframe, if those are wired up later). GB20x so far shared GA10x's display entry point. Give it its own, gb202_disp_new(), with a gb202_gsp_disp table that supplies the VSI writer to the GSP path and otherwise carries the same hooks as GA10x. The following fixes fill in the rest of the GB20x differences there. Signed-off-by: Mohamed Ahmed Reviewed-by: Lyude Paul --- .../drm/nouveau/include/nvkm/engine/disp.h | 1 + .../gpu/drm/nouveau/nvkm/engine/device/base.c | 10 +- .../gpu/drm/nouveau/nvkm/engine/disp/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/engine/disp/gb202.c | 91 +++++++++++++++++++ 4 files changed, 98 insertions(+), 5 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/gb202.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h b/drivers/g= pu/drm/nouveau/include/nvkm/engine/disp.h index 7903d7470d19..01145db32c53 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h @@ -87,4 +87,5 @@ int gp102_disp_new(struct nvkm_device *, enum nvkm_subdev= _type, int inst, struct int gv100_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, = struct nvkm_disp **); int tu102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, = struct nvkm_disp **); int ga102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, = struct nvkm_disp **); +int gb202_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, = struct nvkm_disp **); #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 ea62dc97f118..96c8a5b29999 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2846,7 +2846,7 @@ nv1b2_chipset =3D { .pci =3D { 0x00000001, gh100_pci_new }, .timer =3D { 0x00000001, gk20a_timer_new }, .vfn =3D { 0x00000001, ga100_vfn_new }, - .disp =3D { 0x00000001, ga102_disp_new }, + .disp =3D { 0x00000001, gb202_disp_new }, .fifo =3D { 0x00000001, ga102_fifo_new }, }; =20 @@ -2862,7 +2862,7 @@ nv1b3_chipset =3D { .pci =3D { 0x00000001, gh100_pci_new }, .timer =3D { 0x00000001, gk20a_timer_new }, .vfn =3D { 0x00000001, ga100_vfn_new }, - .disp =3D { 0x00000001, ga102_disp_new }, + .disp =3D { 0x00000001, gb202_disp_new }, .fifo =3D { 0x00000001, ga102_fifo_new }, }; =20 @@ -2878,7 +2878,7 @@ nv1b5_chipset =3D { .pci =3D { 0x00000001, gh100_pci_new }, .timer =3D { 0x00000001, gk20a_timer_new }, .vfn =3D { 0x00000001, ga100_vfn_new }, - .disp =3D { 0x00000001, ga102_disp_new }, + .disp =3D { 0x00000001, gb202_disp_new }, .fifo =3D { 0x00000001, ga102_fifo_new }, }; =20 @@ -2894,7 +2894,7 @@ nv1b6_chipset =3D { .pci =3D { 0x00000001, gh100_pci_new }, .timer =3D { 0x00000001, gk20a_timer_new }, .vfn =3D { 0x00000001, ga100_vfn_new }, - .disp =3D { 0x00000001, ga102_disp_new }, + .disp =3D { 0x00000001, gb202_disp_new }, .fifo =3D { 0x00000001, ga102_fifo_new }, }; =20 @@ -2910,7 +2910,7 @@ nv1b7_chipset =3D { .pci =3D { 0x00000001, gh100_pci_new }, .timer =3D { 0x00000001, gk20a_timer_new }, .vfn =3D { 0x00000001, ga100_vfn_new }, - .disp =3D { 0x00000001, ga102_disp_new }, + .disp =3D { 0x00000001, gb202_disp_new }, .fifo =3D { 0x00000001, ga102_fifo_new }, }; =20 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/= drm/nouveau/nvkm/engine/disp/Kbuild index e1aecd3fe96c..98d6ca5ac311 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild @@ -27,6 +27,7 @@ nvkm-y +=3D nvkm/engine/disp/gp102.o nvkm-y +=3D nvkm/engine/disp/gv100.o nvkm-y +=3D nvkm/engine/disp/tu102.o nvkm-y +=3D nvkm/engine/disp/ga102.o +nvkm-y +=3D nvkm/engine/disp/gb202.o =20 nvkm-y +=3D nvkm/engine/disp/udisp.o nvkm-y +=3D nvkm/engine/disp/uconn.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gb202.c b/drivers/gpu= /drm/nouveau/nvkm/engine/disp/gb202.c new file mode 100644 index 000000000000..fa83aee35ae7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gb202.c @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright 2026 Valve Corp. + */ +#include "priv.h" +#include "head.h" +#include "ior.h" + +#include + +/* GB20x (NVD5.0) reorganised the SF HDMI packet units. The AVI unit is + * unchanged from GV100, but the legacy VSI unit is gone. Vendor infoframes + * are sent through the shared generic infoframe units instead. Register + * layout per NVIDIA's clc971.h/clca71.h, programming sequence per + * nvhdmipkt_C971.c:programAdvancedInfoframeC971(). + */ +static void +gb202_sor_hdmi_infoframe_vsi(struct nvkm_ior *ior, int head, void *data, u= 32 size) +{ + struct nvkm_device *device =3D ior->disp->engine.subdev.device; + const u32 hoff =3D head * 0x400; + /* Generic infoframe unit 1, the slot NVIDIA's driver uses for the VSI. */ + const u32 ctrl =3D 0x6f0138 + hoff; + u8 buf[36] =3D {}; + int i; + + /* Disable the unit and wait for it to go idle. */ + nvkm_mask(device, ctrl, 0x00000001, 0x00000000); + if (nvkm_msec(device, 2000, + if (!(nvkm_rd32(device, ctrl) & 0x00400000)) + break; + ) < 0) + return; + + if (!size) + return; + + /* Clear SENT status, and point the data port at unit 1's slot. */ + nvkm_mask(device, ctrl, 0x00800000, 0x00800000); + nvkm_wr32(device, 0x6f03f0 + hoff, 0x00000001); + + /* The data port takes the raw packet, except that a zero is inserted + * in HB3 after the three header bytes. A slot is 9 dwords (HB0-3 plus + * up to 32 payload bytes). An HDMI infoframe carries at most PB0-27, + * so the tail stays zero, and we always write the whole slot. + */ + size =3D min_t(u32, size, 31); + memcpy(buf, data, min_t(u32, size, 3)); + if (size > 3) + memcpy(&buf[4], (u8 *)data + 3, size - 3); + + for (i =3D 0; i < 36; i +=3D 4) { + nvkm_wr32(device, 0x6f03f4 + hoff, buf[i + 0] | buf[i + 1] << 8 | + buf[i + 2] << 16 | + (u32)buf[i + 3] << 24); + } + + /* No flip ID or scanline matching. */ + nvkm_wr32(device, 0x6f013c + hoff, 0x00000000); + + /* ENABLE | RUN_MODE=3DALWAYS | LOC=3DVBLANK | OFFSET=3D1 | SIZE=3D0. */ + nvkm_wr32(device, ctrl, 0x00000041); + + /* Audio priority low (the init value). */ + nvkm_wr32(device, 0x6f03f8 + hoff, 0x00000002); +} + +/* GB20x is GSP-only. This table supplies the register programming the + * GSP-RM display path needs from the chip. + */ +static const struct nvkm_disp_func +gb202_gsp_disp =3D { + .uevent =3D &gv100_disp_chan_uevent, + .ramht_size =3D 0x2000, + .gsp.intr =3D tu102_disp_intr, + .gsp.head_state =3D gv100_head_state, + .gsp.head_rgpos =3D gv100_head_rgpos, + .gsp.vblank_get =3D tu102_head_vblank_get, + .gsp.vblank_put =3D tu102_head_vblank_put, + .gsp.hdmi_gcp =3D tu102_sor_hdmi_gcp, + /* The legacy AVI unit is unchanged on GB20x. */ + .gsp.hdmi_infoframe_avi =3D gv100_sor_hdmi_infoframe_avi, + .gsp.hdmi_infoframe_vsi =3D gb202_sor_hdmi_infoframe_vsi, +}; + +int +gb202_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int= inst, + struct nvkm_disp **pdisp) +{ + return r535_disp_new(&gb202_gsp_disp, device, type, inst, pdisp); +} --=20 2.55.0 From nobody Mon Sep 28 14:47:59 2026 Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DF73547DD43 for ; Thu, 20 Aug 2026 16:50:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244642; cv=none; b=fgizy3tVcqFTg/SY2eW0Vygs9ZfV1f3ZcMDNWPuixJvhiNylseQ/wMltGlUdbHqKc9gOeXvzku5ZhOK5541tir1Q4ZVXbjBBeamglswCQJIwTVAYr8clsmIeQlqJJ9s/Uyt6kTUs4fukD56nZwiNHiMn66jOYu+79bVOlrM5mE8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244642; c=relaxed/simple; bh=TRBaZvXX7eRHCbqJWWdhfRNiMX0uvZkkKVs+NLBS694=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HeBkgjOgB9woYCy0Jm7HxPwU3xRW/LxNKa2BYw25Z0bM874rDZiTxIksH/aaOf2pC6XTxgAqWwbkPb4nWNEZ5JRhrci7BBNEaMc53NR0d+MLwnkFEAFImPcblPIs+tRUGyuif1oSgoseCZLN50ZZKSEwNKQbmyI2F2aF9ylDoN4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=KoUXta8l; arc=none smtp.client-ip=209.85.128.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KoUXta8l" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-4980dc26022so392425e9.1 for ; Thu, 20 Aug 2026 09:50:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787244639; x=1787849439; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Y+Y9y81hA9Cad/KoflpAlEdybDJIGHGo0qSz9MnRnh8=; b=KoUXta8li4b4B52Sueu4lvaquNJsmzHjau5wZNEYZUsi8/YhtK3KfACtD/TXzdRBjU SsDc71iSymXSocrsXcvAT6/tHLL59O11+KbJ11UHbGQRVOKc87bmZTManWQELn/FmhwA BU6NHvevUsPWk8SJtbpIapdgUvFL76OynjyOiQXiL2j69+sUViZG5itu0hfLzg+4QvRl XOWifSNeC/FKAIGy+DQPGv73sBL9lNf3hs1Cxg1an1kFH5SHBGsqS1d+l8zqiQTc5nQv UlFipqO8i89YGu+zO8tZW9oYwkeE0FP6ApbsVw0u+hMbbaXvoIUPx3WoCaUs/gFBm+hf rFmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787244639; x=1787849439; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Y+Y9y81hA9Cad/KoflpAlEdybDJIGHGo0qSz9MnRnh8=; b=pF+TSBai53ueM9H9YsaHdVsSATFvGFWZg6gxhzxf35eTlLV5gbCvapllN9kiGSaX8g F9TeDyEEPIxQtmgLwULuWyXZ+dcJpU/wLgadaZPQaKpQPLuYGNIKl9DPASN1MWcLUUiQ Yl/ssai/emEhH9usLulxNhxCA3n6pLa5eOqFo21izAlKwSOVLAQ855o9uwiPrYl8ANGS wgdYU52jYT1p2CpHgSKngm8+sze7BOlMBP3oBXdt71CbeDFwUTJAx25EXubUq9PG/C83 HBH5Nu6QQEG/JYE6agzJSPHyttFja98VTkyuGozmhKY8V74loGnxlc7aaQEofzD2rQz6 JoZA== X-Gm-Message-State: AOJu0YxIeyl7+DFRsauunntwnECtwzuCtBMOnqsTck+paEyAWLbkRQG0 zIH7jHDJMAjTXrZ4DC3V0Gn4bp7FISah9hIL6RVr5hjGK7Aa2BM7acdCvyS8QNjR X-Gm-Gg: AR+sD12XgSVlR8XqCjNu1ddahe/8uusPRc5J2GMgmJo2iYK38OmETePqNfO6GEMAVid lfDDBLfu1SFrPGEC9yXJSzA3JFuG3wceUSw/5iKakm3eVcqZwwdXA+378zEck8JbDZiSJHZiava XJ6wEx9YD5U03FeYeEVc50A9MoZzO9jqKO4fGwFYUb8z/kp23aaMuxRuUUdRT2bvZtDTd80tRFh xP+TDOJw4Di7mDjIdVGAWMgUs2YEt2qvyHlwh7Txyt2XZ5BmgmClTJW3B4nXW9PIKxJfwKRKZbY 4bEi4S8lhkldV5+72bjqQ5xKTnRtAqhRpJk4TTAyudPp38s/UZ+m736aipGo9XIxacbDOJwpbuA 53MGShP1TWiBd11WUffuhlIqImwsPujpADeKKvdy0MIuoFl1sTJgLAas3wUQzFvrXeiuMGgXyQ2 w8jOa/k4vs2Wiwc/Qlje9GVPioaJdUrrZJ2AifAHlbP14BkrXLhuRqYd5usC/6zV07rgQ= X-Received: by 2002:a05:600c:19c7:b0:499:484a:81d0 with SMTP id 5b1f17b1804b1-499b82e84aemr4300455e9.9.1787244639062; Thu, 20 Aug 2026 09:50:39 -0700 (PDT) Received: from fedora ([5.31.134.170]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-499aa1111b2sm205307545e9.5.2026.08.20.09.50.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 09:50:36 -0700 (PDT) From: Mohamed Ahmed To: linux-kernel@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, Lyude Paul , Danilo Krummrich , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Mary Guillemard , nouveau@lists.freedesktop.org, Mohamed Ahmed Subject: [PATCH v2 05/10] drm/nouveau/disp: fix HDMI GCP AVMute register offsets on GB20x Date: Thu, 20 Aug 2026 20:49:24 +0400 Message-ID: <20260820164929.17117-6-mohamedahmedegypt2001@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> References: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The GSP path brackets audio enablement with a General Control Packet AVMute toggle. r535_sor_hdmi_audio() calls the gsp.hdmi_gcp hook, which every chip so far serves with tu102_sor_hdmi_gcp() and the legacy GCP unit at 0x6f00c0/0x6f00cc. On GB20x the SF packet units were compacted and the old generic and VSI units are gone (ACR keeps slot 2) and the GCP unit moved from slot 3 to slot 1 (control 0x6f0040 and subpack 0x6f004c from NVIDIA's published clc971.h. The same offsets are also used by OpenRM's hdmiWriteGeneralCtrlPacketC871() on these chips). The old addresses are reserved on GB20x, so the AVMute writes were silent no-ops and mitigated only by the equivalent GCP r535_sor_hdmi_audio() already sends through the SET_OD_PACKET RM control. Add a GB20x GCP writer using the new offsets and hook it into gb202_gsp_disp, keeping the direct MMIO path in sync with the hardware as on earlier chips. Only SB0 (the AVMute bit) is written. On NVD5.0 the subpack register also carries SB1_CTRL (bit 24), which selects where the deep-color CD/PP fields are generated (hardware or from the driver, with the default being HW). hdmiWriteGeneralCtrlPacketC871() likewise writes only SB0-SB2. Signed-off-by: Mohamed Ahmed --- .../gpu/drm/nouveau/nvkm/engine/disp/gb202.c | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gb202.c b/drivers/gpu= /drm/nouveau/nvkm/engine/disp/gb202.c index fa83aee35ae7..4863b2b36db0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gb202.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gb202.c @@ -65,6 +65,24 @@ gb202_sor_hdmi_infoframe_vsi(struct nvkm_ior *ior, int h= ead, void *data, u32 siz nvkm_wr32(device, 0x6f03f8 + hoff, 0x00000002); } =20 +/* General Control Packet AVMute bracket. The GCP unit moved to slot 1 on + * NVD5.0. Only SB0 (the AVMute bit) is ours to write so we must not do a + * full write here: SB1 carries the deep-color CD/PP fields, and SB1_CTRL + * (bit 24, new with clc871.h) controls where their generation happens (HW + * or driver) on these chips, with the default being HW. + */ +static void +gb202_sor_hdmi_gcp(struct nvkm_ior *sor, int head, bool enable) +{ + struct nvkm_device *device =3D sor->disp->engine.subdev.device; + const u32 hdmi =3D head * 0x400; + + nvkm_mask(device, 0x6f0040 + hdmi, 0x00000001, 0x00000000); + nvkm_mask(device, 0x6f004c + hdmi, 0x000000ff, !enable ? 0x00000001 : + 0x00000010); + nvkm_mask(device, 0x6f0040 + hdmi, 0x00000001, 0x00000001); +} + /* GB20x is GSP-only. This table supplies the register programming the * GSP-RM display path needs from the chip. */ @@ -77,7 +95,7 @@ gb202_gsp_disp =3D { .gsp.head_rgpos =3D gv100_head_rgpos, .gsp.vblank_get =3D tu102_head_vblank_get, .gsp.vblank_put =3D tu102_head_vblank_put, - .gsp.hdmi_gcp =3D tu102_sor_hdmi_gcp, + .gsp.hdmi_gcp =3D gb202_sor_hdmi_gcp, /* The legacy AVI unit is unchanged on GB20x. */ .gsp.hdmi_infoframe_avi =3D gv100_sor_hdmi_infoframe_avi, .gsp.hdmi_infoframe_vsi =3D gb202_sor_hdmi_infoframe_vsi, --=20 2.55.0 From nobody Mon Sep 28 14:47:59 2026 Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 467CD47F2FA for ; Thu, 20 Aug 2026 16:50:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244649; cv=none; b=kZGRGEoBHp+o1bRAvW5+N666QtE3YOajtYrhwjQ+5AbPQ+fUTc82M9RWV9FhPRUCGUUL4gMXFKqKLzifp38tYB/OJBl+14/nUqwyrbHGkSO4zqhvpuZpqlsNJ+UH/Y+HB2mdQKGSmFv71coPcF81+l5IxkQY3m0KKKHfORm+KMY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244649; c=relaxed/simple; bh=HL9eNfTKpWlVqoM/GY4Y0HCRGf37CSp/d9xDFss5Pb0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=S1brQPjSpkghmgozRoK9eCOCSO8pHLRicXMiCDQRvK0vxdHVzRYvTYzRcCjVsS5Y15f44Z0AXWmFX8eIKbeL1N9J+UQLOW5+9s0hf/iRF5oKf0o4oT1C0rfqPTxcnKvtP1TIDVXvlmiD7lXQE/S8wrIgobVuHqILNDgi4FwXw1I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=pWl4q1jg; arc=none smtp.client-ip=209.85.128.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="pWl4q1jg" Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-4955aa106b1so561285e9.0 for ; Thu, 20 Aug 2026 09:50:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787244645; x=1787849445; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=vnOb/9NeU+aY27k+bEV+VJd7crL2q/W32VHlWjgPnxc=; b=pWl4q1jg1TLTOR5uQEduvAGl5uVjVHMwhwREkErp1uV1oXTyyi4lQ1X0R7UcBPTVyZ Fip8pkbrgadhtMAd3l6MMFVd2NGQOnBBRWauhohPdCVjAMImHKluUGk0/AVAQhocWrB8 YTt9ddgNC1JpnZgywXdD2kvCN3o6CTukc2P07hI7r9NDAHkVgVRdVYRRm4mE8f5wwvsi otk/ME47cb+yLS3yIykdG4M7haslEm2ve2GDZijm4Km3vmnIAZLDBBUEBnZe5vachgjY Njg9v5uZxTNiS/KVqYsAPQuw0wWdjXJQTJx5EG6QmsgTm1nQHuYLYs81SDiE8mUirX1h RPiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787244645; x=1787849445; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=vnOb/9NeU+aY27k+bEV+VJd7crL2q/W32VHlWjgPnxc=; b=D4z4ay/vrAWDFpvvPIfhADA+vrcqHr3g7puuSsEm1vVxtPGM2bxHGquoWTMXFj/zIB FxuPy+f7n4eBQxmhL3CSRIWcFl/KzSEJn5VKnHT67a1+5wPo+tvdx/TLlAhC5nRX3r0B YUDQtJBXheR2HgtrS4aHBFQKiiESrCJtlrhsmZ0R5WyAo38lm4RKbs0Z3SmtwKwzM44r uJ1JIHE8iHDQCIILEQMyZvpKsxu0NilvKxulRNdtf5nE7iZoWwHnwgYxnkO/CQILPlij OBBcxcZ4uKDSd5L9cY0pA5xw9R/8/NRQfze+BqRUEUKyplr33Vckpe9czd8ljDces1PL A5wA== X-Gm-Message-State: AOJu0YyiooazibwAK6igCFaqrKmba48dP/zSGsnQfhEplIhmt7VQI5+A m/EgfJuerJxbjijqeTlw+yu7Ixg5E8SzWhKlIj9WK4BBaqmVnAcMKx9nfvat+hcH X-Gm-Gg: AR+sD10+3GPBY//tV8qS//t3Pp0/u7JlBP2CbsdOrdeH9oyuAKrJCWCMJjB0xBwSAPx UoIJZZlMxlGwELWqkYatJaAT7UrBlGMxsKX/Fhep0A2qAbzgpucfP5XihVCtJxEzXQLUKoUiEcA lhR7p6UlykVDGqjPrZuKSC7G4ev2iXC65vZfvUYkMcoRCmJyTFTUu3n0E3atpqq+Z3Rr3nz1CXm eQya9T0zKxl8owxgOmzHyVfhWNJmUO3BbAxKu+ptvVGOq+BMA9rEpeKeTbHx00ce9gsT+aN2ekr U5gE51sVOXnokNdCZ6CNB37MJ273p970f/DCbMWj7VHcmQtkaQenaQXEqrqyIF/89ae3gpJLVKL QEMBlHc5sB5Mv0JED2mr0OBUQvPSsQyBiWQ9/aTZvFt/V6XSk2RKfxPzlGuCpjeP64XtA6y8fhW xW9BOtYAYa+KUrZfejYCGSp3sAbhfS0yxMvy8nGCMooG+AXdcgm9DwGVWPLgjVxqzN1tU= X-Received: by 2002:a05:600c:6211:b0:499:621a:2ec2 with SMTP id 5b1f17b1804b1-499b82e8e9dmr5345035e9.3.1787244645217; Thu, 20 Aug 2026 09:50:45 -0700 (PDT) Received: from fedora ([5.31.134.170]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-499aa1111b2sm205307545e9.5.2026.08.20.09.50.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 09:50:43 -0700 (PDT) From: Mohamed Ahmed To: linux-kernel@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, Lyude Paul , Danilo Krummrich , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Mary Guillemard , nouveau@lists.freedesktop.org, Mohamed Ahmed Subject: [PATCH v2 06/10] drm/nouveau/gsp: use per-version DP_CONFIG_STREAM params on r570 firmware Date: Thu, 20 Aug 2026 20:49:25 +0400 Message-ID: <20260820164929.17117-7-mohamedahmedegypt2001@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> References: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" NVIDIA removed the deprecated actualPclkHz/linkClkFreqHz fields and the whole Legacy{activeCnt, activeFrac, activePolarity, mvidWarEnabled, MvidWarParams} block from the SST sub-struct of NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS between the 535 and 570 releases (compared in OpenRM tags 535.113.01 vs 570.144), shrinking the struct. Everything nouveau writes sits at identical offsets in both layouts except the trailing SST.bEnableAudioOverRightPanel (written as zero), but the size is wrong on r570, which means r535_sor_dp_sst() and r535_sor_dp_vcpi() are sent with an incorrect size. Route the .sst/.vcpi IOR functions through nvkm_rm_api_disp the same way bl_ctrl and dp.get_caps/set_indexed_link_rates already are. Keep the existing implementation for r535 and add an r570 implementation built against the 570.144 layout, which already exists in r570/nvrm/disp.h but was unused until now. Also add the NV0073_CTRL_CMD_DP_CONFIG_STREAM define that was missing from the layout. Other DP controls sent through shared r535 code did not change layout between the tags. Signed-off-by: Mohamed Ahmed Reviewed-by: Lyude Paul --- .../nouveau/nvkm/subdev/gsp/rm/r535/disp.c | 33 ++++++++-- .../nouveau/nvkm/subdev/gsp/rm/r570/disp.c | 64 +++++++++++++++++++ .../nvkm/subdev/gsp/rm/r570/nvrm/disp.h | 2 + .../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 5 ++ 4 files changed, 97 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c b/drive= rs/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c index f3e55253bcbc..3a8ff621ed62 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c @@ -400,16 +400,16 @@ r535_sor_dp_audio(struct nvkm_ior *sor, int head, boo= l enable) r535_sor_dp_audio_mute(sor, false); } =20 -static void -r535_sor_dp_vcpi(struct nvkm_ior *sor, int head, u8 slot, u8 slot_nr, u16 = pbn, u16 aligned_pbn) +static int +r535_dp_vcpi(struct nvkm_ior *sor, int head, u8 slot, u8 slot_nr, u16 pbn,= u16 aligned_pbn) { struct nvkm_disp *disp =3D sor->disp; struct NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS *ctrl; =20 ctrl =3D nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, NV0073_CTRL_CMD_DP_CONFIG_STREAM, sizeof(*ctrl)); - if (WARN_ON(IS_ERR(ctrl))) - return; + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); =20 ctrl->subDeviceInstance =3D 0; ctrl->head =3D head; @@ -429,12 +429,20 @@ r535_sor_dp_vcpi(struct nvkm_ior *sor, int head, u8 s= lot, u8 slot_nr, u16 pbn, u ctrl->MST.sendACT =3D 0; ctrl->MST.singleHeadMSTPipeline =3D 0; ctrl->MST.bEnableAudioOverRightPanel =3D 0; - WARN_ON(nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl)); + return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl); +} + +static void +r535_sor_dp_vcpi(struct nvkm_ior *sor, int head, u8 slot, u8 slot_nr, u16 = pbn, u16 aligned_pbn) +{ + const struct nvkm_rm_api *rmapi =3D sor->disp->engine.subdev.device->gsp-= >rm->api; + + WARN_ON(rmapi->disp->dp.vcpi(sor, head, slot, slot_nr, pbn, aligned_pbn)); } =20 static int -r535_sor_dp_sst(struct nvkm_ior *sor, int head, bool ef, - u32 watermark, u32 hblanksym, u32 vblanksym) +r535_dp_sst(struct nvkm_ior *sor, int head, bool ef, + u32 watermark, u32 hblanksym, u32 vblanksym) { struct nvkm_disp *disp =3D sor->disp; struct NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS *ctrl; @@ -461,6 +469,15 @@ r535_sor_dp_sst(struct nvkm_ior *sor, int head, bool e= f, return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl); } =20 +static int +r535_sor_dp_sst(struct nvkm_ior *sor, int head, bool ef, + u32 watermark, u32 hblanksym, u32 vblanksym) +{ + const struct nvkm_rm_api *rmapi =3D sor->disp->engine.subdev.device->gsp-= >rm->api; + + return rmapi->disp->dp.sst(sor, head, ef, watermark, hblanksym, vblanksym= ); +} + static const struct nvkm_ior_func_dp r535_sor_dp =3D { .sst =3D r535_sor_dp_sst, @@ -1771,6 +1788,8 @@ r535_disp =3D { .dp =3D { .get_caps =3D r535_dp_get_caps, .set_indexed_link_rates =3D r535_dp_set_indexed_link_rates, + .sst =3D r535_dp_sst, + .vcpi =3D r535_dp_vcpi, }, .chan =3D { .set_pushbuf =3D r535_disp_chan_set_pushbuf, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/disp.c b/drive= rs/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/disp.c index a96e31c2d80b..8a23837f356e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/disp.c @@ -5,6 +5,7 @@ #include =20 #include +#include #include =20 #include "nvhw/drf.h" @@ -74,6 +75,67 @@ r570_disp_chan_set_pushbuf(struct nvkm_disp *disp, s32 o= class, int inst, struct return nvkm_gsp_rm_ctrl_wr(&gsp->internal.device.subdevice, ctrl); } =20 +static int +r570_dp_vcpi(struct nvkm_ior *sor, int head, u8 slot, u8 slot_nr, u16 pbn,= u16 aligned_pbn) +{ + struct nvkm_disp *disp =3D sor->disp; + NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS *ctrl; + + ctrl =3D nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, + NV0073_CTRL_CMD_DP_CONFIG_STREAM, sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + ctrl->subDeviceInstance =3D 0; + ctrl->head =3D head; + ctrl->sorIndex =3D sor->id; + ctrl->dpLink =3D sor->asy.link =3D=3D 2; + ctrl->bEnableOverride =3D 1; + ctrl->bMST =3D 1; + ctrl->hBlankSym =3D 0; + ctrl->vBlankSym =3D 0; + ctrl->colorFormat =3D 0; + ctrl->bEnableTwoHeadOneOr =3D 0; + ctrl->singleHeadMultistreamMode =3D 0; + ctrl->MST.slotStart =3D slot; + ctrl->MST.slotEnd =3D slot + slot_nr - 1; + ctrl->MST.PBN =3D pbn; + ctrl->MST.Timeslice =3D aligned_pbn; + ctrl->MST.sendACT =3D 0; + ctrl->MST.singleHeadMSTPipeline =3D 0; + ctrl->MST.bEnableAudioOverRightPanel =3D 0; + return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl); +} + +static int +r570_dp_sst(struct nvkm_ior *sor, int head, bool ef, + u32 watermark, u32 hblanksym, u32 vblanksym) +{ + struct nvkm_disp *disp =3D sor->disp; + NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS *ctrl; + + ctrl =3D nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, + NV0073_CTRL_CMD_DP_CONFIG_STREAM, sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + ctrl->subDeviceInstance =3D 0; + ctrl->head =3D head; + ctrl->sorIndex =3D sor->id; + ctrl->dpLink =3D sor->asy.link =3D=3D 2; + ctrl->bEnableOverride =3D 1; + ctrl->bMST =3D 0; + ctrl->hBlankSym =3D hblanksym; + ctrl->vBlankSym =3D vblanksym; + ctrl->colorFormat =3D 0; + ctrl->bEnableTwoHeadOneOr =3D 0; + ctrl->SST.bEnhancedFraming =3D ef; + ctrl->SST.tuSize =3D 64; + ctrl->SST.waterMark =3D watermark; + ctrl->SST.bEnableAudioOverRightPanel =3D 0; + return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl); +} + static int r570_dp_set_indexed_link_rates(struct nvkm_outp *outp) { @@ -255,6 +317,8 @@ r570_disp =3D { .dp =3D { .get_caps =3D r570_dp_get_caps, .set_indexed_link_rates =3D r570_dp_set_indexed_link_rates, + .sst =3D r570_dp_sst, + .vcpi =3D r570_dp_vcpi, }, .chan =3D { .set_pushbuf =3D r570_disp_chan_set_pushbuf, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/disp.h b/= drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/disp.h index 06e972835d77..742b25a2a12d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/disp.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/disp.h @@ -256,6 +256,8 @@ typedef struct NV0073_CTRL_DP_CTRL_PARAMS { NvU32 eightLaneDpcdBaseAddr; } NV0073_CTRL_DP_CTRL_PARAMS; =20 +#define NV0073_CTRL_CMD_DP_CONFIG_STREAM (0x731362U) /* = finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0= 073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS_MESSAGE_ID" */ + typedef struct NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS { NvU32 subDeviceInstance; NvU32 head; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/= drm/nouveau/nvkm/subdev/gsp/rm/rm.h index 0fb0e67406c6..e9ac47d86b69 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -6,6 +6,7 @@ #ifndef __NVKM_RM_H__ #define __NVKM_RM_H__ #include "handles.h" +struct nvkm_ior; struct nvkm_outp; struct r535_gr; =20 @@ -93,6 +94,10 @@ struct nvkm_rm_api { struct { int (*get_caps)(struct nvkm_disp *, int *link_bw, bool *mst, bool *wm); int (*set_indexed_link_rates)(struct nvkm_outp *); + int (*sst)(struct nvkm_ior *, int head, bool ef, + u32 watermark, u32 hblanksym, u32 vblanksym); + int (*vcpi)(struct nvkm_ior *, int head, + u8 slot, u8 slot_nr, u16 pbn, u16 aligned_pbn); } dp; =20 struct { --=20 2.55.0 From nobody Mon Sep 28 14:47:59 2026 Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C569647F2FA for ; Thu, 20 Aug 2026 16:50:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244655; cv=none; b=Dmsed8Imw2airB1jNWyEStgTfJWMnOnY196B1xVJN73fU6QAhlYcWz20EK03MpfU/kieE4cBPBh0Gcx3m8QqKOrkNw/gctG95KN15p4WsR1gb/96xnuOraFby9H2erwOLaczexx6ub/3DDsUlRISExTkKD0DKkfiNvHdRqtUevc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244655; c=relaxed/simple; bh=FMgLQ0hOfOtoOAnn2oc0dZBzACXsfR9c7qzfwitYVTM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=V86WJGHpUWVVKiNC8/S3SXeGk0soMgvJZchpLaUvPkaKPaeZsUO3XtWga2whZy7hTrL8OyXaJDQVf9U9DXPRj+5x8kqa8h/UMOFXlTBuvSiA8CS41wdmdkJyM4gzVWPEH4uc0OhHNxPYh2JoUZBpN6UObBB0uZMkebpJb4D5n7M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=FCRjbcUA; arc=none smtp.client-ip=209.85.128.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="FCRjbcUA" Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-4980dc26022so394735e9.1 for ; Thu, 20 Aug 2026 09:50:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787244652; x=1787849452; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=YE7qcApQ+Obk30eKV1C+kC93MwiUbUNOYm/DV2i4pE0=; b=FCRjbcUAnS9Zm6XijFCOPR9hkEucqM+7J2VshIO8XY6O/y5q7jZkNWbNkCyXDYB8lW JkAkgnVL+IP9Gss3hBhdbJgMHDcqlru4nZB5Immw0HABHcVYubDXQo+sFAdeF9278tfw 0j+iVoX+DpzkE3Bvi/FB2IbIvhEAEPlYowfCurzaeDkT2q6xY2A41uASDLFR+PaumQnD sFsRzdySObwJInFRpPQ9bkBLfS6K0T7DNAk3fWhBsuDO8bBXDkZIZFG/9xD7vMjwXqjD UKv6dQ41Ajkfzf2r9vu9D9/lTIshXj9LKwk+huq0O3vKha9CEImyaqyRMLzyWjyxhjiX DIUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787244652; x=1787849452; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=YE7qcApQ+Obk30eKV1C+kC93MwiUbUNOYm/DV2i4pE0=; b=CCRt7V8OKJAutGM3MD2Ibmjzz/OLuTN4H9kz0tCDD583eFZsNJqAOwSEdsK4geZWab uVnRj4klz9BTho9W+XoIMXa3qUubYDP+uyXC4jnCmDX9WyML2XUPCorOPcvfr+OQkGnZ bx425F/GDChTOarm7Ta7mFPNX17ldYP4AaYeetvwOdteFZX9il6MOn4oT3tlsXYHAqxk nGjlUF+otKvKilJO8on0kcHVY+GdYu8mGRbMGu4yzG1CHYGpY266XSsujXFF74U1KPL1 NgoDQ4ThvBra4ldzbKlWfw4olJ1+esL0Xcp/4UVRmRwe52lpmjLdwXN4uLG6ETQu7y/t Qx3g== X-Gm-Message-State: AOJu0YxU9sXYsjRBz+6XqUvIeVpI1yW09+UMXvL5o7v28puUUjLqVqvh Or1MmYCL+oudR5jqtwx3MUbjWIs0XFU7nP1isGfmUAarYmYRKwghNT1ZtxsyWk+k X-Gm-Gg: AR+sD1026f51j11qz/kcOrJI8wxMpA3di8g9up9QsZ2cuLgQ4IcT6o7HUGR11v91yXE 9C3sKWCcizNM1NO2jMoGid3G92HBi2BiT1Q7TNxv+FX1UQrNDjTF7bM5V7ojqQQdbm/hs/10iKY bXx1cGQ77EGpCdcdHsdIbtSIWabA3fZ45tI9H1pJP+atuu+/cDPhZh9Yt9FdSibiDvEsQzpDaZ9 8FOkzzIKIsp2FMJ/b0QVIcuYEBACReSCQ+wM21lZ3Gtu4xsXRB4xAnPCrvHYPt5dCX5BySJNWmZ gBE5/skoGbaFIlsqeHWne0eHHpjYYYP+0CeDlUYAA5H5WOuAotx+Tj8mIcBWmset0LzADNnBAJE VPdoi8T0uB779sRbe1iw5VUlaNt+aVGc+6FhRbV5wF/qjnxN89ci1I75KlrdPJ6WSau+rFlFb2R s9jPPz7vU+xtjv4hE0J/UH4BicNORbM8JmD5H9aun2XDEuUDplNtLfdnYUcGpebgIjAy8= X-Received: by 2002:a05:600c:4e8b:b0:499:872b:abd4 with SMTP id 5b1f17b1804b1-499b829ef81mr4294175e9.6.1787244651755; Thu, 20 Aug 2026 09:50:51 -0700 (PDT) Received: from fedora ([5.31.134.170]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-499aa1111b2sm205307545e9.5.2026.08.20.09.50.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 09:50:49 -0700 (PDT) From: Mohamed Ahmed To: linux-kernel@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, Lyude Paul , Danilo Krummrich , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Mary Guillemard , nouveau@lists.freedesktop.org, Mohamed Ahmed Subject: [PATCH v2 07/10] drm/nouveau/disp: fix head state readback on GB20x Date: Thu, 20 Aug 2026 20:49:26 +0400 Message-ID: <20260820164929.17117-8-mohamedahmedegypt2001@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> References: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The GSP path reads armed head state and the RG scanout position through gv100_head_state() and gv100_head_rgpos() on every generation. gv100_head_state() reads the core channel's state mirror at a 0x400 per-head stride, which NVD5.0 (GB20x) doubled. Per NVIDIA's published CA7D class header every HEAD_SET method sits at 0x2000 + head * 0x800, while the mirror bases are unchanged (assembly at 0x680000, armed at +0x8000, per OpenRM's v03_00 channel-user-base HAL which is still used on DISPv0502). Add gb202_head_state(), the same readback at the 0x800 stride, and supply it through gb202_gsp_disp. gv100_head_rgpos() is kept. The RG registers keep their per-head 0x800 stride on NVD5.0, and OpenRM's kdispReadRgLineCountAndFrameCount_v03_00 still reads NV_PDISP_RG_DPCA on DISPv0502. Signed-off-by: Mohamed Ahmed Reviewed-by: Lyude Paul --- .../gpu/drm/nouveau/nvkm/engine/disp/gb202.c | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gb202.c b/drivers/gpu= /drm/nouveau/nvkm/engine/disp/gb202.c index 4863b2b36db0..a66c820be9fe 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gb202.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gb202.c @@ -83,6 +83,53 @@ gb202_sor_hdmi_gcp(struct nvkm_ior *sor, int head, bool = enable) nvkm_mask(device, 0x6f0040 + hdmi, 0x00000001, 0x00000001); } =20 +/* Same core-channel state mirror as gv100_head_state() (assembly at 0x680= 000, + * armed at +0x8000, per-head method offsets unchanged), but NVD5.0 spaces + * heads 0x800 apart (see NVCA7D_HEAD_SET_*(a) in clca7d.h). + */ +static void +gb202_head_state(struct nvkm_head *head, struct nvkm_head_state *state) +{ + struct nvkm_device *device =3D head->disp->engine.subdev.device; + const u32 hoff =3D (state =3D=3D &head->arm) * 0x8000 + head->id * 0x800; + u32 data; + + data =3D nvkm_rd32(device, 0x682064 + hoff); + state->vtotal =3D (data & 0xffff0000) >> 16; + state->htotal =3D (data & 0x0000ffff); + data =3D nvkm_rd32(device, 0x682068 + hoff); + state->vsynce =3D (data & 0xffff0000) >> 16; + state->hsynce =3D (data & 0x0000ffff); + data =3D nvkm_rd32(device, 0x68206c + hoff); + state->vblanke =3D (data & 0xffff0000) >> 16; + state->hblanke =3D (data & 0x0000ffff); + data =3D nvkm_rd32(device, 0x682070 + hoff); + state->vblanks =3D (data & 0xffff0000) >> 16; + state->hblanks =3D (data & 0x0000ffff); + /* Bit 31 is ADJ1000DIV1001, not a HERTZ bit. We don't have enough bits + * to add the full clock in hz on Blackwell (35 bits), but state->hz + * is unused and obsolete under GSP so this is fine. + */ + state->hz =3D nvkm_rd32(device, 0x68200c + hoff) & 0x7fffffff; + + data =3D nvkm_rd32(device, 0x682004 + hoff); + switch ((data & 0x000000f0) >> 4) { + case 5: + state->or.depth =3D 30; + break; + case 4: + state->or.depth =3D 24; + break; + case 1: + state->or.depth =3D 18; + break; + default: + state->or.depth =3D 18; + WARN_ON(1); + break; + } +} + /* GB20x is GSP-only. This table supplies the register programming the * GSP-RM display path needs from the chip. */ @@ -91,7 +138,7 @@ gb202_gsp_disp =3D { .uevent =3D &gv100_disp_chan_uevent, .ramht_size =3D 0x2000, .gsp.intr =3D tu102_disp_intr, - .gsp.head_state =3D gv100_head_state, + .gsp.head_state =3D gb202_head_state, .gsp.head_rgpos =3D gv100_head_rgpos, .gsp.vblank_get =3D tu102_head_vblank_get, .gsp.vblank_put =3D tu102_head_vblank_put, --=20 2.55.0 From nobody Mon Sep 28 14:47:59 2026 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DC8C346D544 for ; Thu, 20 Aug 2026 16:50:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244661; cv=none; b=VKwBwQhP9SEpDtq8GlAqcb/nNdY4UViiSnHRkH7yfUJdrd/d+McHtCehxVW80uqqCe+PiPdCJldOptR3HX/ETIOi9zK6qGWH9qYH7BrEHKDJ25VyccPIM0GWGGWr1mqoizCDDxbg4eai1ZfGljIFlojanyi4hfsz8vjtgZDkNOo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244661; c=relaxed/simple; bh=g2uBihBp8oLRoZGfgfncFNXCNLuLA35uLC/eV8naD68=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=b1+HCbnYDkceyK0qei0r9Cz73ZimjHrIMf4xIBwKCvL8HNXDx2geCgLp7PYA5YkO2LLH17iNBp9ljqEHIv8c/2KCGccEFpRNE/Htxukk1cPhS2MVxmZqqvEUktxLRBlPoDflGXhTQkgI5tyJf/d7hgpqLZZZw2HKIHYJIul+r1o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=QGr0U28R; arc=none smtp.client-ip=209.85.128.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="QGr0U28R" Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-498028b3d5eso442125e9.1 for ; Thu, 20 Aug 2026 09:50:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787244658; x=1787849458; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=PblTzKwEMx0jDI4oVKpj3IJS/TAZT0OEcT+54p3qrbc=; b=QGr0U28RwbVxxXObp0hm0xcbc/DNRKeebjwDj2AWNsBH/P79G1lDQLxnGSRwfZnFhj T+hAXE3P4JQXC1RpgjXd7fG8HA2nRGbklcs5A2+f6VTyqOeAyzzsVe26aqAUIDHXU/PE fyKdPKJPtfKAliqpBvpdYAn7ftDJZD+hWP1su7skpxJDz/fq+gIOQ4VO8MFbuyQ28+jT ARye5+5aoT0N+3EouukrCXVnkOMMn2yEBicf6Q+wNi/fbwXx8MBJSI2R2m1A3IDK9ofg /ttu0DKWW23be+jxF1XgWCwmWFCSEGEDcFJux0c0J9MP3OTUOc75SDvZtkZWPmjU1qak ZK7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787244658; x=1787849458; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=PblTzKwEMx0jDI4oVKpj3IJS/TAZT0OEcT+54p3qrbc=; b=o/uisdrX/w2zF2/ZOPVogfpvdujR3A0KBymPWtbvBI52vjeShFho4wTEE3R6/nYPPF vURIz4adwYSzrbHqLw/1CCKrPokWYiEP6tEQzHTNsZHwBBEYnelOHTCe+I9lJR3ucCUG 3BYcdH1jllGzRCVMGtJYGPSMkZNk9GTMY3JQ2TYeJsbfXRaumPGFAHDD6yip4OWs2jQz /C4a3uqTHHrU/WfK4I6A/K3cU9z56EdKUWXFc3O8PBCynZBJ0rCLgqaalzCvOh5mQnul GS6HR+oK7qTTpwgJSXPiA7UvV9/ClZ/jdKlVMHPFzf5+56KUGRv9KbjYg7MYd+ZQBPXG zHqA== X-Gm-Message-State: AOJu0YyBdE+l8UktQ2Lf4DkNvEALPDAYfF1qyQp4jilPdtwyWJJSXjg1 /mzqNpvDIxmpPdAGOtJilvzdUxqyCEyXGJHqxaD5ZS64Fo2+q7lxjA8LNKhbjARP X-Gm-Gg: AR+sD10Dij35JOALTAoZf1QUntgnqZqrHGJskR2W9NzsiW3ZX/kmW9yi80sdZeMYXyu bUQYzAy1CRq9nSpeZodPUA3/GuSo+e0tdO2rK9f3s5460+0sw3VhWLpOHfL7WDi+4jrdbjKt7Us On3L5Wg2KfTqdO3DVq1z0mw1TXl3M7LwQprGpUmJx3azUsdfHytYJEAQwdxAumPCjaJzmS+bA2O roAUkovQy5vd2CpvrzkT/VjpsGVs+OIpF4pXstWhCX1UHHCKTu/vCJybX14Eu6jkWfzMJdokpYk Iof20XE7jVug4bw9bXl8nlqWLAuihFctWqqi+wodlZvcmNGxra2RfdxNgol5/oAg2taJPhtcNaJ t0Jsl0eqMsYTB2Pus/0EHcWCll+gHJD6ch5gflgKyWXOthP6u79xEEbbpX1t5FdSi29Nx8poLxs Z/Bxl8RdkOfPrYCbrGJcIiH9CRP11+aa/qHHDBOcA8TCyoetH4wtVv30QD97zLfUNhAGo= X-Received: by 2002:a05:600c:1910:b0:499:5f7a:7ea2 with SMTP id 5b1f17b1804b1-499b845c7d9mr2645455e9.12.1787244657983; Thu, 20 Aug 2026 09:50:57 -0700 (PDT) Received: from fedora ([5.31.134.170]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-499aa1111b2sm205307545e9.5.2026.08.20.09.50.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 09:50:56 -0700 (PDT) From: Mohamed Ahmed To: linux-kernel@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, Lyude Paul , Danilo Krummrich , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Mary Guillemard , nouveau@lists.freedesktop.org, Mohamed Ahmed Subject: [PATCH v2 08/10] drm/nouveau/gsp: fix vblank interrupts on GB20x Date: Thu, 20 Aug 2026 20:49:27 +0400 Message-ID: <20260820164929.17117-9-mohamedahmedegypt2001@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> References: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The GSP path programs per-head timing (vblank) interrupts the same way on every generation. NVD5.0 (GB20x) reworked the FE interrupt frontend around four message-based kernel vectors (high latency, low latency, PMU, and GSP) and moved RM head-timing interrupts to the dedicated low-latency vector: - The enable is NV_PDISP_FE_RM_INTR_EN1_HEAD_TIMING, 0x611ef0 + head*4 (570.144 kernel_head_0501.c, renamed kernel_head_0502.c from 575.51.02 on, and v05_01 dev_disp.h). - The vector is reported as a separate interrupt table entry, MC_ENGINE_IDX_DISP_LOW (intr_gb202.c, intrCacheDispIntrVectors). - The vector must be re-armed through NV_PDISP_FE_INTR_RETRIGGER(1) at 0x611f34 after servicing (kdispServiceInterrupt -> kdispIntrRetrigger_v05_01). The event latch (0x611800), per-head status (0x611c00), and dispatch summary (0x611ec0) the interrupt handler uses are unchanged on GB20x (kheadReadPendingVblank_v03_00 and kheadResetPendingLastData_v03_00 remain for DISPv0502+). On GB20x the old code enables head timing onto the legacy vector, leaves its handler there, and never re-arms the message-based vectors. Page flips still complete (nv50 sends those events from the commit path), so the desktop looks fine while DRM vblank waits and vblank sequence queries are affected. Supply GB20x vblank enables and an interrupt handler that re-arms the vector after servicing through gb202_gsp_disp, translate the low-latency interrupt table entry as a second NVKM_ENGINE_DISP instance, and flag the table so r535_disp_oneinit() attaches the handler to that instance. Signed-off-by: Mohamed Ahmed Reviewed-by: Lyude Paul --- .../gpu/drm/nouveau/nvkm/engine/disp/gb202.c | 42 +++++++++++++++++-- .../nouveau/nvkm/subdev/gsp/rm/r535/disp.c | 5 ++- .../drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c | 9 ++++ 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gb202.c b/drivers/gpu= /drm/nouveau/nvkm/engine/disp/gb202.c index a66c820be9fe..f78669bafd64 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gb202.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gb202.c @@ -130,6 +130,40 @@ gb202_head_state(struct nvkm_head *head, struct nvkm_h= ead_state *state) } } =20 +/* NVD5.0 (GB20x and later) moved the RM head-timing interrupt enable to + * the low-latency vector's EN1 block. The event latch is unchanged. + */ +static void +gb202_head_vblank_put(struct nvkm_head *head) +{ + struct nvkm_device *device =3D head->disp->engine.subdev.device; + + nvkm_mask(device, 0x611ef0 + (head->id * 4), 0x00000002, 0x00000000); +} + +static void +gb202_head_vblank_get(struct nvkm_head *head) +{ + struct nvkm_device *device =3D head->disp->engine.subdev.device; + + nvkm_wr32(device, 0x611800 + (head->id * 4), 0x00000002); + nvkm_mask(device, 0x611ef0 + (head->id * 4), 0x00000002, 0x00000002); +} + +static irqreturn_t +gb202_disp_intr(struct nvkm_inth *inth) +{ + struct nvkm_disp *disp =3D container_of(inth, typeof(*disp), engine.subde= v.inth); + irqreturn_t ret =3D tu102_disp_intr(inth); + + /* The FE interrupt vectors are message-based on NVD5.0. Re-arm the + * low-latency vector so it fires again for any event that latched + * while we were servicing. + */ + nvkm_wr32(disp->engine.subdev.device, 0x611f34, 0x00000001); + return ret; +} + /* GB20x is GSP-only. This table supplies the register programming the * GSP-RM display path needs from the chip. */ @@ -137,11 +171,13 @@ static const struct nvkm_disp_func gb202_gsp_disp =3D { .uevent =3D &gv100_disp_chan_uevent, .ramht_size =3D 0x2000, - .gsp.intr =3D tu102_disp_intr, + /* Head timing arrives on the dedicated low-latency vector. */ + .gsp.intr =3D gb202_disp_intr, + .gsp.intr_low_latency =3D true, .gsp.head_state =3D gb202_head_state, .gsp.head_rgpos =3D gv100_head_rgpos, - .gsp.vblank_get =3D tu102_head_vblank_get, - .gsp.vblank_put =3D tu102_head_vblank_put, + .gsp.vblank_get =3D gb202_head_vblank_get, + .gsp.vblank_put =3D gb202_head_vblank_put, .gsp.hdmi_gcp =3D gb202_sor_hdmi_gcp, /* The legacy AVI unit is unchanged on GB20x. */ .gsp.hdmi_infoframe_avi =3D gv100_sor_hdmi_infoframe_avi, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c b/drive= rs/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c index 3a8ff621ed62..a95f78c4502f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c @@ -1705,7 +1705,10 @@ r535_disp_oneinit(struct nvkm_disp *disp) =20 /* Chips that raise head-timing interrupts on a separate low-latency * vector report it as a second DISP interrupt table entry, exposed - * as instance 1 by the RM engine-index translation. + * as instance 1 by the RM engine-index translation (see + * r570_gsp_xlat_mc_engine_idx()). Their high-latency vector + * (instance 0) is left unhandled as no event nouveau enables is + * routed to it, and without a handler it stays masked. */ ret =3D nvkm_gsp_intr_stall(gsp, disp->engine.subdev.type, disp->func->gsp.intr_low_latency ? 1 : disp->engine.subdev.inst); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c b/driver= s/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c index 3e391646d8f7..b45781cd0dfd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c @@ -44,6 +44,15 @@ r570_gsp_xlat_mc_engine_idx(u32 mc_engine_idx, enum nvkm= _subdev_type *ptype, int *ptype =3D NVKM_ENGINE_DISP; *pinst =3D 0; return true; + case MC_ENGINE_IDX_DISP_LOW: + /* GB20x+ report a separate low-latency display vector, used + * for head-timing interrupts. Expose it as a second DISP + * interrupt instance. r535_disp_oneinit() attaches the + * handler to it when the chip's gsp.intr_low_latency is set. + */ + *ptype =3D NVKM_ENGINE_DISP; + *pinst =3D 1; + return true; case MC_ENGINE_IDX_CE0 ... MC_ENGINE_IDX_CE19: *ptype =3D NVKM_ENGINE_CE; *pinst =3D mc_engine_idx - MC_ENGINE_IDX_CE0; --=20 2.55.0 From nobody Mon Sep 28 14:47:59 2026 Received: from mail-wr1-f41.google.com (mail-wr1-f41.google.com [209.85.221.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 46D5946D544 for ; Thu, 20 Aug 2026 16:51:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244667; cv=none; b=L4mdblgrxfQmnteBf07RJLjqBhR4GsDRo7x9qfhThB45PvpbgX+wKs8H3U7VvAURE/qb4teDyma8dG3vWuzK0IqyV2YgKZFM5wtqCA7dGdoEfLnZ/WoZfy+pYfOvHIPlR3gMRKq0gnvPn1GPxTP4HiYSNxAd1e1uMKPpGwBdOlc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244667; c=relaxed/simple; bh=BSaN1jVK1y1WFwL3wZPNexZO8YTn1LFCEPZ2Mz6n9lE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Y1OlTTBj6dnJv86OD2fzpduadSobTldIQ6ESq4JCDAvVAkpCCvUf/zGh/TVTO+JHxWsI9/nAQMiBVIFFI9bRXvw9JunUsf+jl1LtF7E7nws4PZ4qwh5MO7OZY5Mg1mQBoMDSK2vsKHcT1WZuVpyty34fVt1tm6y6zT64RmrRHJk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lGR5NnbV; arc=none smtp.client-ip=209.85.221.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lGR5NnbV" Received: by mail-wr1-f41.google.com with SMTP id ffacd0b85a97d-47f633e6058so128757f8f.0 for ; Thu, 20 Aug 2026 09:51:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787244664; x=1787849464; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=xoij1rKhFdJD5+LmFn+9RDZC5MZ7psm+4aCRvb4W/Ds=; b=lGR5NnbV/8eCjp1takh5HpaY2ciAGePMSvUKtfzSSjzlGdGi5mCYuXm3ZZFFmkqq6d acDNq97mGzXDvI/qh7xNItHp8oZR2nYG2osiP9DXqEbfRwxG9TCfgRuctOgoJ3PFzQbU jfhbSV7dWlMPkUmc1U1N8O7k3rvcG76ItdPDPZr3fqnBcXo+79ZjJF0Ty9oWHXNr/SJ3 +bia6tJwfG42rkzN1hQcRaad+W0cBkwbqiJkgbdgRhEdJCXSbrhHnKRCYYusMjeb07JZ cfu8OnhGHqbZWSvKVz3JFdghPKsZ+h68kXGPa7AGu4evLz7Dy1RJHE7Kq9J0Y63ryIs2 mwKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787244664; x=1787849464; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=xoij1rKhFdJD5+LmFn+9RDZC5MZ7psm+4aCRvb4W/Ds=; b=Ro7TRfDow7TTk0NBB8uVnkZ65eyM55iJJz55/nR4903b9/yc3K5InEV/oj3eA5NEkw ntAOThFmUUOmA+ERQZhozAwfpUt0r7E4l+5T+49SFqU4EVEODkpZfKFlQTfNkypsNoe8 lnGIKocbJCmBR7th2JsriLA8TY6YY7gASN3NCPdIGxGEGED1lBMIb3Dv1zFI4ka9lCw4 ju7bWWF3mH+NG6zInFqqTacPeqpqrKyCuuZjgLL7kQcdZcmjkIXf+Uky9vXaZORAvnFN XCt17FFQugRmHX0pqntu6UMfS5O/zfWTLvAVDbTmT/Kp/L0NK79TOJPOMhxiycHLUfGZ QRcQ== X-Gm-Message-State: AOJu0Yx4MvM8wW3ZWIOZdd65WVltFEeKNSMOGTK8yFmOiJD/hWwzlNKO r+ojqfF9KSOUWRwmAE6l/R29S0kv+dBRU0mGZZYpBRqzx3/QLM9x1hlm27EOurlh X-Gm-Gg: AR+sD12veXt0iMmW4kq6tkD0pPEMX2YJ95zvsbHy8wOjncQ9WywtdOOn/alw8OxC75C /Xgbdw57VE8K3ihjm67hVCNOwfs4H41DRom6XYLrrnU+pIwFa2uB2IBlbx0vMsdOlEHkyEmto1i mnYkSVr8SvPBbUFa85dZA6v6Xs6xV7+UczQxuS73SGtAKAo1GObrcLOk7hFEgY/ev3/SCwUeMg8 rm3p4xGhDFWVdaPH/d+Iy6BdnFjTN2xstrCHjvnGeuOght4WtnQDQMzTTsl2GSIfSR/a3fsYRN1 ZeYlUwtF2hYMQgC1LRXPZ3RQrQLKE9Ewg93v0Zkmaht6GdV3F9BZUlG4qL0+KN3pz8IOcCBYtzA zKo/tHQq8aaz8inwAYerK7xnsTcjHp8tZQ753CW7kiBIBSwViZQFdAEoeMYfm8515qvrxOhSuDU lvbgoTDCmDGHmii28R0RnTEP3LW9NCtWPJYf587HtsU7QlABvSnEB9bfh24Yl+xR/t6dM= X-Received: by 2002:a05:600c:c8c:b0:499:af7d:b759 with SMTP id 5b1f17b1804b1-499b845c91cmr3249335e9.13.1787244664550; Thu, 20 Aug 2026 09:51:04 -0700 (PDT) Received: from fedora ([5.31.134.170]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-499aa1111b2sm205307545e9.5.2026.08.20.09.50.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 09:51:02 -0700 (PDT) From: Mohamed Ahmed To: linux-kernel@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, Lyude Paul , Danilo Krummrich , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Mary Guillemard , nouveau@lists.freedesktop.org, Mohamed Ahmed Subject: [PATCH v2 09/10] drm/nouveau/dispnv50: program pixel clocks above 2.147GHz on GB20x Date: Thu, 20 Aug 2026 20:49:28 +0400 Message-ID: <20260820164929.17117-10-mohamedahmedegypt2001@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> References: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The HEAD_SET_PIXEL_CLOCK_FREQUENCY(_MAX) methods carry only 31 HERTZ bits. Starting with C97D the upper bits live in separate HEAD_SET_PIXEL_CLOCK_FREQUENCY_HI(_MAX) methods, which nouveau never programmed and headca7d_mode() computed m->clock * 1000 into the 31-bit field. NVVAL's mask then silently truncates anything past 2^31 Hz, which means that every mode scanned out at pclk modulo 2^31. No mode nouveau can currently commit crosses the boundary (an uncompressed HDMI FRL mode tops out around 1.78GHz at 8bpc), but this is a prerequisite for the upcoming DSC work, which makes 2.147GHz+ modes reachable. Program the full value split across the low and HI methods, exactly as OpenRM's EvoSetRasterParams9() does (nvkms-evo4.c, 31-bit low word plus the 4 HI HERTZ bits, giving 35 bits of range). Signed-off-by: Mohamed Ahmed Reviewed-by: Lyude Paul --- drivers/gpu/drm/nouveau/dispnv50/headca7d.c | 21 ++++++++++++++++--- .../drm/nouveau/include/nvhw/class/clca7d.h | 4 ++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/headca7d.c b/drivers/gpu/drm/= nouveau/dispnv50/headca7d.c index eeaeb15aa664..678cbc78ca9f 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/headca7d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/headca7d.c @@ -219,10 +219,11 @@ headca7d_mode(struct nv50_head *head, struct nv50_hea= d_atom *asyh) { struct nvif_push *push =3D &head->disp->core->chan.push; struct nv50_head_mode *m =3D &asyh->mode; + const u64 hz =3D (u64)m->clock * 1000; const int i =3D head->base.index; int ret; =20 - ret =3D PUSH_WAIT(push, 11); + ret =3D PUSH_WAIT(push, 14); if (ret) return ret; =20 @@ -245,11 +246,25 @@ headca7d_mode(struct nv50_head *head, struct nv50_hea= d_atom *asyh) PUSH_MTHD(push, NVCA7D, HEAD_SET_CONTROL(i), NVDEF(NVCA7D, HEAD_SET_CONTROL, STRUCTURE, PROGRESSIVE)); =20 + /* The FREQUENCY methods carry only 31 HERTZ bits; the upper bits + * of anything past 2.147GHz live in the HI methods + * (EvoSetRasterParams9()). Truncating would scan out at pclk modulo 2^31. + */ PUSH_MTHD(push, NVCA7D, HEAD_SET_PIXEL_CLOCK_FREQUENCY(i), - NVVAL(NVCA7D, HEAD_SET_PIXEL_CLOCK_FREQUENCY, HERTZ, m->clock * 1000)); + NVVAL(NVCA7D, HEAD_SET_PIXEL_CLOCK_FREQUENCY, HERTZ, + (u32)(hz & 0x7fffffff))); =20 PUSH_MTHD(push, NVCA7D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX(i), - NVVAL(NVCA7D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX, HERTZ, m->clock * 10= 00)); + NVVAL(NVCA7D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX, HERTZ, + (u32)(hz & 0x7fffffff))); + + PUSH_MTHD(push, NVCA7D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_HI(i), + NVVAL(NVCA7D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_HI, HERTZ, + (u32)(hz >> 31)), + + HEAD_SET_PIXEL_CLOCK_FREQUENCY_HI_MAX(i), + NVVAL(NVCA7D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_HI_MAX, HERTZ, + (u32)(hz >> 31))); =20 return 0; } diff --git a/drivers/gpu/drm/nouveau/include/nvhw/class/clca7d.h b/drivers/= gpu/drm/nouveau/include/nvhw/class/clca7d.h index 0fec6fc21d44..5754878ddc69 100644 --- a/drivers/gpu/drm/nouveau/include/nvhw/class/clca7d.h +++ b/drivers/gpu/drm/nouveau/include/nvhw/class/clca7d.h @@ -734,6 +734,10 @@ #define NVCA7D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_BYPASS = 20:20 #define NVCA7D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_BYPASS_DISABLE = (0x00000000) #define NVCA7D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_BYPASS_ENABLE = (0x00000001) +#define NVCA7D_HEAD_SET_PIXEL_CLOCK_FREQUENCY_HI(a) = (0x000020C0 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_PIXEL_CLOCK_FREQUENCY_HI_HERTZ = 3:0 +#define NVCA7D_HEAD_SET_PIXEL_CLOCK_FREQUENCY_HI_MAX(a) = (0x000020C4 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_PIXEL_CLOCK_FREQUENCY_HI_MAX_HERTZ = 3:0 #define NVCA7D_HEAD_SET_SURFACE_ADDRESS_HI_CRC(a) = (0x00002150 + (a)*0x00000800) #define NVCA7D_HEAD_SET_SURFACE_ADDRESS_HI_CRC_ADDRESS_HI = 31:0 #define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CRC(a) = (0x00002154 + (a)*0x00000800) --=20 2.55.0 From nobody Mon Sep 28 14:47:59 2026 Received: from mail-wm1-f46.google.com (mail-wm1-f46.google.com [209.85.128.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 20C7A3793CE for ; Thu, 20 Aug 2026 16:51:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244695; cv=none; b=XB3C46LZzph2FoSMwbegRZdqwWQxnzC2new1zYl1EMpCUkF3J3PJAkhNhMUUcYvymfpQa/UhwOuPkmqKH/FnmAclfl31h3jMzF/TjRBDyipyC4fqVNJYd4LiKlD0nyL4eytzCMrMyDb56Vox7gZy/PPHc4gWUvvU7d21gg5v1yk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787244695; c=relaxed/simple; bh=nrqP+CK+Cvw/3R0m+02Z5ZUhhbFY9GXPJ2m2GBDeBbg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UUSFP/6DMU+WamQwRTerlt+uviRsqQ9ruaH+Q5hxNZn1c5G+RNUWvIG0l6Vk6u4ejnRQGuFV1FdoL+fXtCf7VE+vlSoqwEQQxnudA8xzpGdEH3lFtCAZvTFHJYJ5EjbN6W1UgWdLyZ7lmCsm3lb2BHka3Ipuk+gOpj5DnGYNHPY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=r3tEtoFB; arc=none smtp.client-ip=209.85.128.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="r3tEtoFB" Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-4995b0343c1so243905e9.3 for ; Thu, 20 Aug 2026 09:51:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787244672; x=1787849472; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Rrx+hjGGRBi6QEFoHXTNw/rycuz8rCyp2ooSpQ0sJ88=; b=r3tEtoFBd0ZAN3zzd3jB2npnYXaf0bL4eUPVOp4DMrrn5qP5Mf65h0RJuI+rz59Pcg mi/1QT4/92FWfZfhh15Z/gCzayb8PUAIQsHtjZxMzoXUHFFfIMns8cY0/fXCv5vnmUHz 7xB+6SPSlyEFUYm2F1KWO/Za0GKAPJ3UjS15zwrFINtmAahLFHd8dQpSrw9fO8fpyfYp TG+TDM242kepFxL6aFeQryxLlWQzZv2ZSwEpXzoRi2op6k0pK1Brmw+btUJ5QDka3v1d DCphNJVjhH86mrlDKsMRfh2/WcB0YTaubo6GoZTba81LaJDmCeu7JdkP0DlEZUasRfw2 aLRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787244672; x=1787849472; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Rrx+hjGGRBi6QEFoHXTNw/rycuz8rCyp2ooSpQ0sJ88=; b=WoDd+97SCnfh9s3yXwG9KvVN3sfqccoxVrjQeUxdk1biZsqxTUuHNZp4iH7XPoeOJu /Mr6uSJGatRwRvcdmQsOWUYgcVNjmM7AIPQ5sJpFd7YTsve8BKbmcvudAOJ8nQCeJBoV ZC07zGsmNrrfsc6yoVQ/CobQCdqNuPdd6BlVViwRUlEycAKWeu4ra86TMYgRzvDJ4ckH 2w6KqA3d0SKclpmePsGO088hj8Dd7Oxi5brSzETK5Gf7IvPh6/EiGFR2xCwjevfR3/0m fQgLyN4elHah4/gEyGyjHcqZfxbrIcOHkmshUqWr1JXCo6qe8ARcpCtsgXhn3EDZG+Ao Wgrg== X-Gm-Message-State: AOJu0Yzoe9zqpTAlA+u9Nv7S40cM/8yj1hSppVRRXIuAGe3LP/wYiFaG VMedk0nzJbZhkOnSDa0yJuoi9z/aQaaVHzwx8nAxVk7orI9y/HWQVnupjCKI5ej/ X-Gm-Gg: AR+sD12uIyS8YFx8dWO7YfsSH0x0PcSK+CbNifItRMNV0ltLiXfGUhcfo7dKG267daO mT0Ll1jRHLGU8mekiOGOfcduuPvHbixX2dfRbz7jIXPzLspNPt7ps7hduf3S/IeAvfB3eaoDMKJ jGwpf5HQGxDshBLvQLgOdU0MblznoN7YXDwsTDlYenp0QTkPT6rxvQprfz9mtQXq6q2tJlWvJjQ K1FkBTsrDb8nlO6ln717Ac/4Bpah8fdv/EJF7nkl/LWRlFz/bxeY+W5CA0IPct0JITYGzs0WbVq FMYxNEKzaSZpPlvlbPnljC6Wp/BCKH5yfx7tcQdWNA+FN22EOOJ0L067IQkYdSOZVYtk6kr5X38 g1zwNzscS8PyH+csFtPdgbkgRH9P6Gm4GjOS2w5MF18WnrMnrbAZeDyl+JytLttdrKbScdp/BZy S3KKwWuGSPn+Tx8ZO5Ku6z807V0x46lBZP97ba8Aw+h2Q/eArIgWPF9jzgZo+I3zDt/hlI8+QsF OFirg== X-Received: by 2002:a05:600c:46d1:b0:492:4e09:9fc1 with SMTP id 5b1f17b1804b1-499b8469f20mr2469975e9.15.1787244671464; Thu, 20 Aug 2026 09:51:11 -0700 (PDT) Received: from fedora ([5.31.134.170]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-499aa1111b2sm205307545e9.5.2026.08.20.09.51.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 09:51:09 -0700 (PDT) From: Mohamed Ahmed To: linux-kernel@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, Lyude Paul , Danilo Krummrich , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Mary Guillemard , nouveau@lists.freedesktop.org, Mohamed Ahmed Subject: [PATCH v2 10/10] drm/nouveau: honor HF-EEODB EDIDs by converting to struct drm_edid Date: Thu, 20 Aug 2026 20:49:29 +0400 Message-ID: <20260820164929.17117-11-mohamedahmedegypt2001@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> References: <20260820164929.17117-1-mohamedahmedegypt2001@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" HDMI 2.1 sinks ship HF-EEODB EDIDs. Byte 126 deliberately claims one extension block for legacy sources, and the true count lives in the CTA block's first data block. Their high-refresh timings sit in DisplayID extension blocks 2+. The kernel already reads these EDIDs whole, and on GSP boards RM returns the full EDID with its true size. However, nouveau then hands the buffer to the legacy API which sizes the EDID from byte 126 so the DisplayID blocks are not parsed/exposed and the sysfs blob truncates to 256 bytes. The mode list then tops out at the CTA VICs. Convert to the struct drm_edid API, which carries the real size. Read via drm_edid_read_ddc()/drm_edid_read_switcheroo() where an adapter exists, and serve RM's buffer through drm_edid_read_custom() with a block-reading callback where not, which also routes the GSP path through drm's block validation and the debugfs EDID override. A failed RM read now takes the same "no EDID" path as an empty DDC read which stops it from leaking the runtime-PM reference detect() holds. The property, display_info, and mode list go through drm_edid_connector_update()/_add_modes() and every EDID source is funneled through nouveau_connector_set_edid() so all of them reach the property that drm_edid_connector_add_modes() reads from. nouveau_acpi_edid() now returns a drm_edid sized from the EDID's extension count but never past the length _DDC actually returned, so padded buffers pass and truncated ones are rejected, and every firmware-provided EDID (OF, ACPI, VBIOS-embedded) is validated with drm_edid_valid(). An invalid one is treated as no EDID. get_modes() re-syncs the property from the connector's copy when the probe helper has cleared it for a forced-off connector, before adding modes. The few raw EDID readers are converted along with it, so no raw struct edid pointer is kept. Ownership and freeing move to the drm_edid. MST connectors keep their separate legacy path. Signed-off-by: Mohamed Ahmed Reviewed-by: Lyude Paul --- drivers/gpu/drm/nouveau/dispnv04/dfp.c | 5 +- drivers/gpu/drm/nouveau/dispnv50/disp.c | 4 +- drivers/gpu/drm/nouveau/nouveau_acpi.c | 21 ++- drivers/gpu/drm/nouveau/nouveau_acpi.h | 10 +- drivers/gpu/drm/nouveau/nouveau_connector.c | 147 +++++++++++++++----- drivers/gpu/drm/nouveau/nouveau_connector.h | 12 +- 6 files changed, 151 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv04/dfp.c b/drivers/gpu/drm/nouve= au/dispnv04/dfp.c index c9f96ec8455d..00eb2aacbe93 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/dfp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/dfp.c @@ -344,9 +344,8 @@ static void nv04_dfp_mode_set(struct drm_encoder *encod= er, regp->fp_control |=3D (2 << 24); if (nv_encoder->dcb->type =3D=3D DCB_OUTPUT_LVDS) { bool duallink =3D false, dummy; - if (nv_connector->edid && - nv_connector->type =3D=3D DCB_CONNECTOR_LVDS_SPWG) { - duallink =3D (((u8 *)nv_connector->edid)[121] =3D=3D 2); + if (nv_connector->spwg_links) { + duallink =3D nv_connector->spwg_links =3D=3D 2; } else { nouveau_bios_parse_lvds_table(dev, output_mode->clock, &duallink, &dummy); diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouv= eau/dispnv50/disp.c index 2c66e480b511..add19d479ebe 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1803,8 +1803,8 @@ nv50_sor_atomic_enable(struct drm_encoder *encoder, s= truct drm_atomic_commit *st lvds_dual =3D bios->fp.dual_link; lvds_8bpc =3D bios->fp.if_is_24bit; } else { - if (nv_connector->type =3D=3D DCB_CONNECTOR_LVDS_SPWG) { - if (((u8 *)nv_connector->edid)[121] =3D=3D 2) + if (nv_connector->spwg_links) { + if (nv_connector->spwg_links =3D=3D 2) lvds_dual =3D true; } else if (mode->clock >=3D bios->fp.duallink_transition_clk) { diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouve= au/nouveau_acpi.c index 21b56cc7605c..ab2868edd42b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -360,9 +360,10 @@ void nouveau_unregister_dsm_handler(void) {} void nouveau_switcheroo_optimus_dsm(void) {} #endif =20 -void * +const struct drm_edid * nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { + const struct drm_edid *drm_edid; struct acpi_device *acpidev; int type, ret; void *edid; @@ -384,7 +385,23 @@ nouveau_acpi_edid(struct drm_device *dev, struct drm_c= onnector *connector) if (ret < 0) return NULL; =20 - return edid; + /* Never let the EDID's own extension count reach past what _DDC + * actually returned. Drop the padding some firmware appends so the + * container is exactly the EDID, then validate it like the DDC + * readers would. + */ + if (ret >=3D EDID_LENGTH) + ret =3D min_t(int, ret, EDID_LENGTH * + (1 + ((const struct edid *)edid)->extensions)); + drm_edid =3D drm_edid_alloc(edid, ret); + kfree(edid); + + if (drm_edid && !drm_edid_valid(drm_edid)) { + drm_dbg_kms(dev, "Invalid EDID from ACPI _DDC\n"); + drm_edid_free(drm_edid); + drm_edid =3D NULL; + } + return drm_edid; } =20 bool nouveau_acpi_video_backlight_use_native(void) diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.h b/drivers/gpu/drm/nouve= au/nouveau_acpi.h index e39dd8b94b8b..bc3ccca7b338 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.h +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.h @@ -4,13 +4,15 @@ =20 #define ROM_BIOS_PAGE 4096 =20 +struct drm_edid; + #if defined(CONFIG_ACPI) && defined(CONFIG_X86) bool nouveau_is_optimus(void); bool nouveau_is_v1_dsm(void); void nouveau_register_dsm_handler(void); void nouveau_unregister_dsm_handler(void); void nouveau_switcheroo_optimus_dsm(void); -void *nouveau_acpi_edid(struct drm_device *, struct drm_connector *); +const struct drm_edid *nouveau_acpi_edid(struct drm_device *, struct drm_c= onnector *); bool nouveau_acpi_video_backlight_use_native(void); void nouveau_acpi_video_register_backlight(void); #else @@ -19,7 +21,11 @@ static inline bool nouveau_is_v1_dsm(void) { return fals= e; }; static inline void nouveau_register_dsm_handler(void) {} static inline void nouveau_unregister_dsm_handler(void) {} static inline void nouveau_switcheroo_optimus_dsm(void) {} -static inline void *nouveau_acpi_edid(struct drm_device *dev, struct drm_c= onnector *connector) { return NULL; } +static inline const struct drm_edid * +nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) +{ + return NULL; +} static inline bool nouveau_acpi_video_backlight_use_native(void) { return = true; } static inline void nouveau_acpi_video_register_backlight(void) {} #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/= nouveau/nouveau_connector.c index b0b0ad9a0c24..55912da83cd0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -397,7 +397,7 @@ nouveau_connector_destroy(struct drm_connector *connect= or) struct nouveau_connector *nv_connector =3D nouveau_connector(connector); nvif_event_dtor(&nv_connector->irq); nvif_event_dtor(&nv_connector->hpd); - kfree(nv_connector->edid); + drm_edid_free(nv_connector->drm_edid); drm_connector_unregister(connector); drm_connector_cleanup(connector); if (nv_connector->aux.transfer) @@ -469,6 +469,36 @@ nouveau_connector_ddc_detect(struct drm_connector *con= nector) return found; } =20 +static void +nouveau_connector_set_edid(struct nouveau_connector *nv_connector, + const struct drm_edid *drm_edid) +{ + if (nv_connector->drm_edid =3D=3D drm_edid) + return; + + /* Updates the EDID property and display_info with HF-EEODB-aware + * sizing. The legacy helpers truncate both to what EDID byte 126 + * admits, hiding the DisplayID extension blocks that carry the + * high-refresh timings. + */ + drm_edid_connector_update(&nv_connector->base, drm_edid); + + drm_edid_free(nv_connector->drm_edid); + nv_connector->drm_edid =3D drm_edid; + + /* The SPWG link-count byte lives in a vendor descriptor drm has no + * accessor for. Peek at it once here so nothing else needs the raw + * EDID. + */ + nv_connector->spwg_links =3D 0; + if (nv_connector->type =3D=3D DCB_CONNECTOR_LVDS_SPWG) { + const u8 *raw =3D (const u8 *)drm_edid_raw(drm_edid); + + if (raw) + nv_connector->spwg_links =3D raw[121] =3D=3D 2 ? 2 : 1; + } +} + static struct nouveau_encoder * nouveau_connector_of_detect(struct drm_connector *connector) { @@ -490,8 +520,17 @@ nouveau_connector_of_detect(struct drm_connector *conn= ector) int idx =3D name ? name[strlen(name) - 1] - 'A' : 0; =20 if (nv_encoder->dcb->i2c_index =3D=3D idx && edid) { - nv_connector->edid =3D - kmemdup(edid, EDID_LENGTH, GFP_KERNEL); + const struct drm_edid *drm_edid =3D + drm_edid_alloc(edid, EDID_LENGTH); + + /* Firmware-provided, so validate it like the DDC + * readers would. + */ + if (drm_edid && !drm_edid_valid(drm_edid)) { + drm_edid_free(drm_edid); + drm_edid =3D NULL; + } + nouveau_connector_set_edid(nv_connector, drm_edid); return nv_encoder; } } @@ -546,17 +585,23 @@ nouveau_connector_set_encoder(struct drm_connector *c= onnector, } } =20 -static void -nouveau_connector_set_edid(struct nouveau_connector *nv_connector, - struct edid *edid) +struct nouveau_rm_edid { + u8 *data; + size_t size; +}; + +static int +nouveau_connector_rm_edid_block(void *context, u8 *buf, unsigned int block, + size_t len) { - if (nv_connector->edid !=3D edid) { - struct edid *old_edid =3D nv_connector->edid; + struct nouveau_rm_edid *rm =3D context; + size_t offset =3D (size_t)block * EDID_LENGTH; =20 - drm_connector_update_edid_property(&nv_connector->base, edid); - kfree(old_edid); - nv_connector->edid =3D edid; - } + if (offset + len > rm->size) + return -EINVAL; + + memcpy(buf, rm->data + offset, len); + return 0; } =20 static enum drm_connector_status @@ -590,22 +635,37 @@ nouveau_connector_detect(struct drm_connector *connec= tor, bool force) =20 nv_encoder =3D nouveau_connector_ddc_detect(connector); if (nv_encoder) { - struct edid *new_edid =3D NULL; + const struct drm_edid *new_edid =3D NULL; =20 if (nv_encoder->i2c) { if ((vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC) && nv_connector->type =3D=3D DCB_CONNECTOR_LVDS) - new_edid =3D drm_get_edid_switcheroo(connector, nv_encoder->i2c); + new_edid =3D drm_edid_read_switcheroo(connector, nv_encoder->i2c); else - new_edid =3D drm_get_edid(connector, nv_encoder->i2c); + new_edid =3D drm_edid_read_ddc(connector, nv_encoder->i2c); } else { - ret =3D nvif_outp_edid_get(&nv_encoder->outp, (u8 **)&new_edid); - if (ret < 0) - return connector_status_disconnected; + struct nouveau_rm_edid rm =3D {}; + + /* RM (which owns the DDC pads on GSP boards) reads the + * EDID whole and returns its true size, which for an + * HF-EEODB EDID exceeds what byte 126 admits. Serve it + * through drm's block reader so EEODB sizing, block + * validation, and the debugfs EDID override all apply. + * A failed read is treated like an empty DDC read, + * which releases the runtime-PM reference. + */ + ret =3D nvif_outp_edid_get(&nv_encoder->outp, &rm.data); + if (ret >=3D 0) { + rm.size =3D ret; + new_edid =3D drm_edid_read_custom(connector, + nouveau_connector_rm_edid_block, + &rm); + kfree(rm.data); + } } =20 nouveau_connector_set_edid(nv_connector, new_edid); - if (!nv_connector->edid) { + if (!nv_connector->drm_edid) { NV_ERROR(drm, "DDC responded, but no EDID for %s\n", connector->name); goto detect_analog; @@ -626,7 +686,7 @@ nouveau_connector_detect(struct drm_connector *connecto= r, bool force) nv_partner->dcb->type =3D=3D DCB_OUTPUT_TMDS) || (nv_encoder->dcb->type =3D=3D DCB_OUTPUT_TMDS && nv_partner->dcb->type =3D=3D DCB_OUTPUT_ANALOG))) { - if (nv_connector->edid->input & DRM_EDID_INPUT_DIGITAL) + if (drm_edid_is_digital(nv_connector->drm_edid)) type =3D DCB_OUTPUT_TMDS; else type =3D DCB_OUTPUT_ANALOG; @@ -638,7 +698,8 @@ nouveau_connector_detect(struct drm_connector *connecto= r, bool force) conn_status =3D connector_status_connected; =20 if (nv_encoder->dcb->type =3D=3D DCB_OUTPUT_DP) - drm_dp_cec_set_edid(&nv_connector->aux, nv_connector->edid); + drm_dp_cec_attach(&nv_connector->aux, + connector->display_info.source_physical_address); =20 goto out; } else { @@ -670,7 +731,7 @@ nouveau_connector_detect(struct drm_connector *connecto= r, bool force) } =20 out: - if (!nv_connector->edid) + if (!nv_connector->drm_edid) drm_dp_cec_unset_edid(&nv_connector->aux); =20 pm_runtime_mark_last_busy(dev->dev); @@ -686,7 +747,7 @@ nouveau_connector_detect_lvds(struct drm_connector *con= nector, bool force) struct nouveau_drm *drm =3D nouveau_drm(dev); struct nouveau_connector *nv_connector =3D nouveau_connector(connector); struct nouveau_encoder *nv_encoder =3D NULL; - struct edid *edid =3D NULL; + const struct drm_edid *edid =3D NULL; enum drm_connector_status status =3D connector_status_disconnected; =20 nv_encoder =3D find_encoder(connector, DCB_OUTPUT_LVDS); @@ -697,7 +758,7 @@ nouveau_connector_detect_lvds(struct drm_connector *con= nector, bool force) if (!drm->vbios.fp_no_ddc) { status =3D nouveau_connector_detect(connector, force); if (status =3D=3D connector_status_connected) { - edid =3D nv_connector->edid; + edid =3D nv_connector->drm_edid; goto out; } } @@ -733,9 +794,17 @@ nouveau_connector_detect_lvds(struct drm_connector *co= nnector, bool force) * stored for the panel stored in them. */ if (!drm->vbios.fp_no_ddc) { - edid =3D (struct edid *)nouveau_bios_embedded_edid(dev); - if (edid) { - edid =3D kmemdup(edid, EDID_LENGTH, GFP_KERNEL); + const void *embedded =3D nouveau_bios_embedded_edid(dev); + + if (embedded) { + edid =3D drm_edid_alloc(embedded, EDID_LENGTH); + /* Firmware-provided, so validate it like the DDC + * readers would. + */ + if (edid && !drm_edid_valid(edid)) { + drm_edid_free(edid); + edid =3D NULL; + } if (edid) status =3D connector_status_connected; } @@ -886,7 +955,7 @@ nouveau_connector_detect_depth(struct drm_connector *co= nnector) bool duallink; =20 /* if the edid is feeling nice enough to provide this info, use it */ - if (nv_connector->edid && connector->display_info.bpc) + if (nv_connector->drm_edid && connector->display_info.bpc) return; =20 /* EDID 1.4 is *supposed* to be supported on eDP, but, Apple... */ @@ -913,9 +982,8 @@ nouveau_connector_detect_depth(struct drm_connector *co= nnector) /* LVDS: DDC panel, need to first determine the number of links to * know which if_is_24bit flag to check... */ - if (nv_connector->edid && - nv_connector->type =3D=3D DCB_CONNECTOR_LVDS_SPWG) - duallink =3D ((u8 *)nv_connector->edid)[121] =3D=3D 2; + if (nv_connector->spwg_links) + duallink =3D nv_connector->spwg_links =3D=3D 2; else duallink =3D mode->clock >=3D bios->fp.duallink_transition_clk; =20 @@ -973,12 +1041,17 @@ nouveau_connector_get_modes(struct drm_connector *co= nnector) nv_connector->native_mode =3D NULL; } =20 - if (nv_connector->edid) - ret =3D drm_add_edid_modes(connector, nv_connector->edid); - else - if (nv_encoder->dcb->type =3D=3D DCB_OUTPUT_LVDS && - (nv_encoder->dcb->lvdsconf.use_straps_for_mode || - drm->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) { + if (nv_connector->drm_edid) { + /* The probe helper clears the property and display_info for + * a forced-off connector without calling detect(). Re-sync + * from our copy then, since add_modes() reads the property. + */ + if (!connector->edid_blob_ptr) + drm_edid_connector_update(connector, nv_connector->drm_edid); + ret =3D drm_edid_connector_add_modes(connector); + } else if (nv_encoder->dcb->type =3D=3D DCB_OUTPUT_LVDS && + (nv_encoder->dcb->lvdsconf.use_straps_for_mode || + drm->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) { struct drm_display_mode mode; =20 nouveau_bios_fp_mode(dev, &mode); diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/= nouveau/nouveau_connector.h index 0608cabed058..eb292d2ba4bc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.h +++ b/drivers/gpu/drm/nouveau/nouveau_connector.h @@ -43,7 +43,7 @@ =20 struct nvkm_i2c_port; struct dcb_output; -struct edid; +struct drm_edid; =20 #ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT struct nouveau_backlight { @@ -121,6 +121,13 @@ struct nouveau_connector { struct drm_connector base; enum dcb_connector_type type; u8 index; + /* LVDS_SPWG panels state their link count in EDID descriptor 4 (SPWG + * byte 0x79), cached by nouveau_connector_set_edid() so nothing else + * needs the raw EDID. 0 =3D unknown (not an SPWG panel, or no EDID) and + * callers fall back to their transition-clock/VBIOS heuristics; + * 1 =3D single link; 2 =3D dual link. + */ + u8 spwg_links; =20 struct nvif_conn conn; u64 hpd_pending; @@ -137,7 +144,8 @@ struct nouveau_connector { int scaling_mode; =20 struct nouveau_encoder *detected_encoder; - struct edid *edid; + /* Owner of the sink's EDID, HF-EEODB-complete. */ + const struct drm_edid *drm_edid; struct drm_display_mode *native_mode; #ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT struct nouveau_backlight *backlight; --=20 2.55.0