Re: [PATCH v2 01/10] drm/nouveau/disp: move GSP head-timing ISR and vblank helpers to tu102.c

[email protected]
Newsgroups org.freedesktop.lists.nouveau,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Reviewed-by: Lyude Paul <[email protected]>

On Thu, 2026-08-20 at 20:49 +0400, Mohamed Ahmed wrote:
> 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 <[email protected]>
> ---
>  .../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
> *state);
>  void gv100_head_rgpos(struct nvkm_head *head, u16 *hline, u16
> *vline);
>  
> +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 =
> (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 nvkm_object **);
>  
>  int tu102_disp_init(struct nvkm_disp *);
> +irqreturn_t tu102_disp_intr(struct nvkm_inth *);
>  
>  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));
>  }
>  
> +/* 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 = 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 = 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 = &disp->engine.subdev;
> +	struct nvkm_device *device = subdev->device;
> +	u32 stat = 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 = container_of(inth, typeof(*disp),
> engine.subdev.inth);
> +	struct nvkm_subdev *subdev = &disp->engine.subdev;
> +	struct nvkm_device *device = subdev->device;
> +	unsigned long mask = 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/drivers/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 *pmask)
>  	return 4;
>  }
>  
> -static void
> -r535_head_vblank_put(struct nvkm_head *head)
> -{
> -	struct nvkm_device *device = 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 = 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 = {
>  	.state = gv100_head_state,
>  	.rgpos = gv100_head_rgpos,
> -	.vblank_get = r535_head_vblank_get,
> -	.vblank_put = r535_head_vblank_put,
> +	.vblank_get = tu102_head_vblank_get,
> +	.vblank_put = tu102_head_vblank_put,
>  };
>  
>  static struct nvkm_conn *
> @@ -1404,35 +1387,6 @@ static const struct nvkm_event_func
>  r535_disp_event = {
>  };
>  
> -static void
> -r535_disp_intr_head_timing(struct nvkm_disp *disp, int head)
> -{
> -	struct nvkm_subdev *subdev = &disp->engine.subdev;
> -	struct nvkm_device *device = subdev->device;
> -	u32 stat = 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 = container_of(inth, typeof(*disp),
> engine.subdev.inth);
> -	struct nvkm_subdev *subdev = &disp->engine.subdev;
> -	struct nvkm_device *device = subdev->device;
> -	unsigned long mask = 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;
>  
>  	ret = nvkm_inth_add(&device->vfn->intr, ret,
> NVKM_INTR_PRIO_NORMAL, &disp->engine.subdev,
> -			    r535_disp_intr, &disp-
> >engine.subdev.inth);
> +			    tu102_disp_intr, &disp-
> >engine.subdev.inth);
>  	if (ret)
>  		return ret;
>  
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.