The Linux Kernel Mailing List
 help / color / mirror / Atom feed
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);
> +}


  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