Re: [PATCH 5/7] nouveau/gsp: fix vblank interrupts on GB20x

[email protected]
Newsgroups gmane.comp.freedesktop.xorg.nouveau,gmane.linux.kernel,gmane.comp.video.dri.devel
Message-ID <[email protected]>
On Sat, 2026-08-15 at 03:57 +0400, Mohamed Ahmed wrote:
> 
> +
> +static const struct nvkm_head_func
> +gb202_head = {
> +	.state = r535_head_state,
> +	.vblank_get = gb202_head_vblank_get,
> +	.vblank_put = gb202_head_vblank_put,
> +};
> +

You should probably add these two as well:

	.state = gv100_head_state,
	.rgpos = gv100_head_rgpos,

I don't think they've actually changed in blackwell, but it's possible
maybe they do change in GB200x so you probably want to double check so
we don't lose precise vblank timestamps again.

>  static struct nvkm_conn *
>  r535_conn_new(struct nvkm_disp *disp, u32 id)
>  {
> @@ -1496,6 +1523,20 @@ r535_disp_intr(struct nvkm_inth *inth)
>  	return IRQ_HANDLED;
>  }
>  
> +static irqreturn_t
> +gb202_disp_intr(struct nvkm_inth *inth)
> +{
> +	struct nvkm_disp *disp = container_of(inth, typeof(*disp),
> engine.subdev.inth);
> +	irqreturn_t ret = r535_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;
> +}
> +
>  static void
>  r535_disp_fini(struct nvkm_disp *disp, bool suspend)
>  {
> @@ -1568,7 +1609,9 @@ r535_disp_oneinit(struct nvkm_disp *disp)
>  	struct nvkm_device *device = disp->engine.subdev.device;
>  	struct nvkm_gsp *gsp = device->gsp;
>  	const struct nvkm_rm_api *rmapi = gsp->rm->api;
> +	const struct nvkm_rm_gpu *gpu = gsp->rm->gpu;
>  	NV2080_CTRL_INTERNAL_DISPLAY_WRITE_INST_MEM_PARAMS *ctrl;
> +	nvkm_inth_func intr_func;
>  	unsigned long mask;
>  	int ret, i;
>  
> @@ -1722,7 +1765,12 @@ r535_disp_oneinit(struct nvkm_disp *disp)
>  		nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
>  
>  		for_each_set_bit(i, &disp->head.mask, disp->head.nr)
> {
> -			ret = nvkm_head_new_(&r535_head, disp, i);
> +			const struct nvkm_head_func *func =
> &r535_head;
> +
> +			if (gpu->disp.class.root >= GB202_DISP)
> +				func = &gb202_head;
> +
> +			ret = nvkm_head_new_(func, disp, i);
>  			if (ret)
>  				return ret;
>  		}
> @@ -1766,12 +1814,21 @@ r535_disp_oneinit(struct nvkm_disp *disp)
>  	if (ret)
>  		return ret;
>  
> -	ret = nvkm_gsp_intr_stall(gsp, disp->engine.subdev.type,
> disp->engine.subdev.inst);
> +	if (gpu->disp.class.root >= GB202_DISP) {
> +		/* GB20x deliver head-timing interrupts on the
> display's
> +		 * separate low-latency vector (interrupt table
> instance 1).
> +		 */
> +		ret = nvkm_gsp_intr_stall(gsp, disp-
> >engine.subdev.type, 1);
> +		intr_func = gb202_disp_intr;
> +	} else {
> +		ret = nvkm_gsp_intr_stall(gsp, disp-
> >engine.subdev.type, disp->engine.subdev.inst);
> +		intr_func = r535_disp_intr;
> +	}
>  	if (ret < 0)
>  		return ret;
>  
>  	ret = nvkm_inth_add(&device->vfn->intr, ret,
> NVKM_INTR_PRIO_NORMAL, &disp->engine.subdev,
> -			    r535_disp_intr, &disp-
> >engine.subdev.inth);
> +			    intr_func, &disp->engine.subdev.inth);
>  	if (ret)
>  		return ret;
>  
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
> b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
> index 996941c668ba..2590b22663cb 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,14 @@ r570_gsp_xlat_mc_engine_idx(u32 mc_engine_idx,
> enum nvkm_subdev_type *ptype, int
>  		*ptype = NVKM_ENGINE_DISP;
>  		*pinst = 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.
> +		 */
> +		*ptype = NVKM_ENGINE_DISP;
> +		*pinst = 1;
> +		return true;
>  	case MC_ENGINE_IDX_CE0 ... MC_ENGINE_IDX_CE19:
>  		*ptype = NVKM_ENGINE_CE;
>  		*pinst = mc_engine_idx - MC_ENGINE_IDX_CE0;
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.