From: lyude@redhat.com
To: Mohamed Ahmed <mohamedahmedegypt2001@gmail.com>,
linux-kernel@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org,
Danilo Krummrich <dakr@kernel.org>,
Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
Maxime Ripard <mripard@kernel.org>,
Thomas Zimmermann <tzimmermann@suse.de>,
David Airlie <airlied@gmail.com>,
Simona Vetter <simona@ffwll.ch>,
Mary Guillemard <mary@mary.zone>,
nouveau@lists.freedesktop.org
Subject: Re: [PATCH v2 04/10] drm/nouveau/disp: fix HDMI vendor infoframes on GB20x
Date: Fri, 21 Aug 2026 17:52:13 -0400 [thread overview]
Message-ID: <66c8492e4018fa32c59aaef767a975fdc8887b41.camel@redhat.com> (raw)
In-Reply-To: <20260820164929.17117-5-mohamedahmedegypt2001@gmail.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
On Thu, 2026-08-20 at 20:49 +0400, Mohamed Ahmed wrote:
> 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 <mohamedahmedegypt2001@gmail.com>
> ---
> .../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/gpu/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/gpu/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 = {
> .pci = { 0x00000001, gh100_pci_new },
> .timer = { 0x00000001, gk20a_timer_new },
> .vfn = { 0x00000001, ga100_vfn_new },
> - .disp = { 0x00000001, ga102_disp_new },
> + .disp = { 0x00000001, gb202_disp_new },
> .fifo = { 0x00000001, ga102_fifo_new },
> };
>
> @@ -2862,7 +2862,7 @@ nv1b3_chipset = {
> .pci = { 0x00000001, gh100_pci_new },
> .timer = { 0x00000001, gk20a_timer_new },
> .vfn = { 0x00000001, ga100_vfn_new },
> - .disp = { 0x00000001, ga102_disp_new },
> + .disp = { 0x00000001, gb202_disp_new },
> .fifo = { 0x00000001, ga102_fifo_new },
> };
>
> @@ -2878,7 +2878,7 @@ nv1b5_chipset = {
> .pci = { 0x00000001, gh100_pci_new },
> .timer = { 0x00000001, gk20a_timer_new },
> .vfn = { 0x00000001, ga100_vfn_new },
> - .disp = { 0x00000001, ga102_disp_new },
> + .disp = { 0x00000001, gb202_disp_new },
> .fifo = { 0x00000001, ga102_fifo_new },
> };
>
> @@ -2894,7 +2894,7 @@ nv1b6_chipset = {
> .pci = { 0x00000001, gh100_pci_new },
> .timer = { 0x00000001, gk20a_timer_new },
> .vfn = { 0x00000001, ga100_vfn_new },
> - .disp = { 0x00000001, ga102_disp_new },
> + .disp = { 0x00000001, gb202_disp_new },
> .fifo = { 0x00000001, ga102_fifo_new },
> };
>
> @@ -2910,7 +2910,7 @@ nv1b7_chipset = {
> .pci = { 0x00000001, gh100_pci_new },
> .timer = { 0x00000001, gk20a_timer_new },
> .vfn = { 0x00000001, ga100_vfn_new },
> - .disp = { 0x00000001, ga102_disp_new },
> + .disp = { 0x00000001, gb202_disp_new },
> .fifo = { 0x00000001, ga102_fifo_new },
> };
>
> 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 += nvkm/engine/disp/gp102.o
> nvkm-y += nvkm/engine/disp/gv100.o
> nvkm-y += nvkm/engine/disp/tu102.o
> nvkm-y += nvkm/engine/disp/ga102.o
> +nvkm-y += nvkm/engine/disp/gb202.o
>
> nvkm-y += nvkm/engine/disp/udisp.o
> nvkm-y += 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 <subdev/timer.h>
> +
> +/* 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, u32 size)
> +{
> + struct nvkm_device *device = ior->disp-
> >engine.subdev.device;
> + const u32 hoff = head * 0x400;
> + /* Generic infoframe unit 1, the slot NVIDIA's driver uses
> for the VSI. */
> + const u32 ctrl = 0x6f0138 + hoff;
> + u8 buf[36] = {};
> + 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 = 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 = 0; i < 36; i += 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=ALWAYS | LOC=VBLANK | OFFSET=1 |
> SIZE=0. */
> + 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 = {
> + .uevent = &gv100_disp_chan_uevent,
> + .ramht_size = 0x2000,
> + .gsp.intr = tu102_disp_intr,
> + .gsp.head_state = gv100_head_state,
> + .gsp.head_rgpos = gv100_head_rgpos,
> + .gsp.vblank_get = tu102_head_vblank_get,
> + .gsp.vblank_put = tu102_head_vblank_put,
> + .gsp.hdmi_gcp = tu102_sor_hdmi_gcp,
> + /* The legacy AVI unit is unchanged on GB20x. */
> + .gsp.hdmi_infoframe_avi = gv100_sor_hdmi_infoframe_avi,
> + .gsp.hdmi_infoframe_vsi = 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);
> +}
next prev parent reply other threads:[~2026-08-21 21:52 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-20 16:49 [PATCH v2 00/10] nouveau: assorted display fixes (GB20x, r570 DP_CONFIG_STREAM, HF-EEODB EDIDs) Mohamed Ahmed
2026-08-20 16:49 ` [PATCH v2 01/10] drm/nouveau/disp: move GSP head-timing ISR and vblank helpers to tu102.c Mohamed Ahmed
2026-08-21 19:21 ` lyude
2026-08-21 21:31 ` lyude
2026-08-20 16:49 ` [PATCH v2 02/10] drm/nouveau/disp: move the GSP HDMI GCP AVMute write to engine/disp Mohamed Ahmed
2026-08-21 19:25 ` lyude
2026-08-20 16:49 ` [PATCH v2 03/10] drm/nouveau/disp: route GSP-RM display MMIO through nvkm_disp_func hooks Mohamed Ahmed
2026-08-21 21:30 ` lyude
2026-08-20 16:49 ` [PATCH v2 04/10] drm/nouveau/disp: fix HDMI vendor infoframes on GB20x Mohamed Ahmed
2026-08-21 21:52 ` lyude [this message]
2026-08-20 16:49 ` [PATCH v2 05/10] drm/nouveau/disp: fix HDMI GCP AVMute register offsets " Mohamed Ahmed
2026-08-21 21:59 ` lyude
2026-08-20 16:49 ` [PATCH v2 06/10] drm/nouveau/gsp: use per-version DP_CONFIG_STREAM params on r570 firmware Mohamed Ahmed
2026-08-21 22:02 ` lyude
2026-08-20 16:49 ` [PATCH v2 07/10] drm/nouveau/disp: fix head state readback on GB20x Mohamed Ahmed
2026-08-21 22:06 ` lyude
2026-08-20 16:49 ` [PATCH v2 08/10] drm/nouveau/gsp: fix vblank interrupts " Mohamed Ahmed
2026-08-21 22:12 ` lyude
2026-08-21 22:36 ` Mohamed Ahmed
2026-08-20 16:49 ` [PATCH v2 09/10] drm/nouveau/dispnv50: program pixel clocks above 2.147GHz " Mohamed Ahmed
2026-08-21 22:16 ` lyude
2026-08-20 16:49 ` [PATCH v2 10/10] drm/nouveau: honor HF-EEODB EDIDs by converting to struct drm_edid Mohamed Ahmed
2026-08-21 22:19 ` lyude
2026-08-21 22:09 ` [PATCH v2 00/10] nouveau: assorted display fixes (GB20x, r570 DP_CONFIG_STREAM, HF-EEODB EDIDs) lyude
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=66c8492e4018fa32c59aaef767a975fdc8887b41.camel@redhat.com \
--to=lyude@redhat.com \
--cc=airlied@gmail.com \
--cc=dakr@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mary@mary.zone \
--cc=mohamedahmedegypt2001@gmail.com \
--cc=mripard@kernel.org \
--cc=nouveau@lists.freedesktop.org \
--cc=simona@ffwll.ch \
--cc=tzimmermann@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox