Re: [PATCH v2 09/10] drm/nouveau/dispnv50: program pixel clocks above 2.147GHz on GB20x

[email protected]
Newsgroups org.freedesktop.lists.dri-devel,org.freedesktop.lists.nouveau,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 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 <[email protected]>
> ---
>  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_head_atom *asyh)
>  {
>  	struct nvif_push *push = &head->disp->core->chan.push;
>  	struct nv50_head_mode *m = &asyh->mode;
> +	const u64 hz = (u64)m->clock * 1000;
>  	const int i = head->base.index;
>  	int ret;
>  
> -	ret = PUSH_WAIT(push, 11);
> +	ret = PUSH_WAIT(push, 14);
>  	if (ret)
>  		return ret;
>  
> @@ -245,11 +246,25 @@ headca7d_mode(struct nv50_head *head, struct
> nv50_head_atom *asyh)
>  	PUSH_MTHD(push, NVCA7D, HEAD_SET_CONTROL(i),
>  		  NVDEF(NVCA7D, HEAD_SET_CONTROL, STRUCTURE,
> PROGRESSIVE));
>  
> +	/* 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)));
>  
>  	PUSH_MTHD(push, NVCA7D,
> HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX(i),
> -		  NVVAL(NVCA7D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX,
> HERTZ, m->clock * 1000));
> +		  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_MA
> X(i),
> +		  NVVAL(NVCA7D,
> HEAD_SET_PIXEL_CLOCK_FREQUENCY_HI_MAX, HERTZ,
> +			(u32)(hz >> 31)));
>  
>  	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)
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.