mirror of
				https://github.com/Ysurac/openmptcprouter.git
				synced 2025-03-09 15:40:20 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			127 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 30a8ce6736c11903c205b667d61e059b1510913f Mon Sep 17 00:00:00 2001
 | |
| From: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
 | |
| Date: Thu, 15 Jul 2021 01:07:30 +0200
 | |
| Subject: [PATCH] drm/vc4: Fix timings for VEC modes
 | |
| 
 | |
| This commit fixes vertical timings of the VEC (composite output) modes
 | |
| to accurately represent the 525-line ("NTSC") and 625-line ("PAL") ITU-R
 | |
| standards.
 | |
| 
 | |
| Previous timings were actually defined as 502 and 601 lines, resulting
 | |
| in non-standard 62.69 Hz and 52 Hz signals being generated,
 | |
| respectively.
 | |
| 
 | |
| Changes to vc4_crtc.c have also been made, to make the PixelValve
 | |
| vertical timings accurately correspond to the DRM modeline in interlaced
 | |
| modes. The resulting VERTA/VERTB register values have been verified
 | |
| against the reference values set by the Raspberry Pi firmware.
 | |
| 
 | |
| Signed-off-by: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
 | |
| ---
 | |
|  drivers/gpu/drm/vc4/vc4_crtc.c | 70 +++++++++++++++++++++-------------
 | |
|  1 file changed, 43 insertions(+), 27 deletions(-)
 | |
| 
 | |
| --- a/drivers/gpu/drm/vc4/vc4_crtc.c
 | |
| +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
 | |
| @@ -326,8 +326,14 @@ static void vc4_crtc_config_pv(struct dr
 | |
|  	bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
 | |
|  		       vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
 | |
|  	bool is_dsi1 = vc4_encoder->type == VC4_ENCODER_TYPE_DSI1;
 | |
| +	bool is_vec = vc4_encoder->type == VC4_ENCODER_TYPE_VEC;
 | |
|  	u32 format = is_dsi1 ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
 | |
|  	u8 ppc = pv_data->pixels_per_clock;
 | |
| +
 | |
| +	u16 vert_bp = mode->crtc_vtotal - mode->crtc_vsync_end;
 | |
| +	u16 vert_sync = mode->crtc_vsync_end - mode->crtc_vsync_start;
 | |
| +	u16 vert_fp = mode->crtc_vsync_start - mode->crtc_vdisplay;
 | |
| +
 | |
|  	bool debug_dump_regs = false;
 | |
|  	int idx;
 | |
|  
 | |
| @@ -355,49 +361,59 @@ static void vc4_crtc_config_pv(struct dr
 | |
|  		   VC4_SET_FIELD(mode->hdisplay * pixel_rep / ppc,
 | |
|  				 PV_HORZB_HACTIVE));
 | |
|  
 | |
| -	CRTC_WRITE(PV_VERTA,
 | |
| -		   VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end +
 | |
| -				 interlace,
 | |
| -				 PV_VERTA_VBP) |
 | |
| -		   VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
 | |
| -				 PV_VERTA_VSYNC));
 | |
| -	CRTC_WRITE(PV_VERTB,
 | |
| -		   VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay,
 | |
| -				 PV_VERTB_VFP) |
 | |
| -		   VC4_SET_FIELD(mode->crtc_vdisplay, PV_VERTB_VACTIVE));
 | |
| -
 | |
|  	if (interlace) {
 | |
| +		bool odd_field_first = false;
 | |
| +		u32 field_delay = mode->htotal * pixel_rep / (2 * ppc);
 | |
| +		u16 vert_bp_even = vert_bp;
 | |
| +		u16 vert_fp_even = vert_fp;
 | |
| +
 | |
| +		if (is_vec) {
 | |
| +			/* VEC (composite output) */
 | |
| +			++field_delay;
 | |
| +			if (mode->htotal == 858) {
 | |
| +				/* 525-line mode (NTSC or PAL-M) */
 | |
| +				odd_field_first = true;
 | |
| +			}
 | |
| +		}
 | |
| +
 | |
| +		if (odd_field_first)
 | |
| +			++vert_fp_even;
 | |
| +		else
 | |
| +			++vert_bp;
 | |
| +
 | |
|  		CRTC_WRITE(PV_VERTA_EVEN,
 | |
| -			   VC4_SET_FIELD(mode->crtc_vtotal -
 | |
| -					 mode->crtc_vsync_end,
 | |
| -					 PV_VERTA_VBP) |
 | |
| -			   VC4_SET_FIELD(mode->crtc_vsync_end -
 | |
| -					 mode->crtc_vsync_start,
 | |
| -					 PV_VERTA_VSYNC));
 | |
| +			   VC4_SET_FIELD(vert_bp_even, PV_VERTA_VBP) |
 | |
| +			   VC4_SET_FIELD(vert_sync, PV_VERTA_VSYNC));
 | |
|  		CRTC_WRITE(PV_VERTB_EVEN,
 | |
| -			   VC4_SET_FIELD(mode->crtc_vsync_start -
 | |
| -					 mode->crtc_vdisplay,
 | |
| -					 PV_VERTB_VFP) |
 | |
| +			   VC4_SET_FIELD(vert_fp_even, PV_VERTB_VFP) |
 | |
|  			   VC4_SET_FIELD(mode->crtc_vdisplay, PV_VERTB_VACTIVE));
 | |
|  
 | |
| -		/* We set up first field even mode for HDMI.  VEC's
 | |
| -		 * NTSC mode would want first field odd instead, once
 | |
| -		 * we support it (to do so, set ODD_FIRST and put the
 | |
| -		 * delay in VSYNCD_EVEN instead).
 | |
| +		/* We set up first field even mode for HDMI and VEC's PAL.
 | |
| +		 * For NTSC, we need first field odd.
 | |
|  		 */
 | |
|  		CRTC_WRITE(PV_V_CONTROL,
 | |
|  			   PV_VCONTROL_CONTINUOUS |
 | |
|  			   (is_dsi ? PV_VCONTROL_DSI : 0) |
 | |
|  			   PV_VCONTROL_INTERLACE |
 | |
| -			   VC4_SET_FIELD(mode->htotal * pixel_rep / (2 * ppc),
 | |
| -					 PV_VCONTROL_ODD_DELAY));
 | |
| -		CRTC_WRITE(PV_VSYNCD_EVEN, 0);
 | |
| +			   (odd_field_first
 | |
| +				   ? PV_VCONTROL_ODD_FIRST
 | |
| +				   : VC4_SET_FIELD(field_delay,
 | |
| +						   PV_VCONTROL_ODD_DELAY)));
 | |
| +		CRTC_WRITE(PV_VSYNCD_EVEN,
 | |
| +			   (odd_field_first ? field_delay : 0));
 | |
|  	} else {
 | |
|  		CRTC_WRITE(PV_V_CONTROL,
 | |
|  			   PV_VCONTROL_CONTINUOUS |
 | |
|  			   (is_dsi ? PV_VCONTROL_DSI : 0));
 | |
|  	}
 | |
|  
 | |
| +	CRTC_WRITE(PV_VERTA,
 | |
| +		   VC4_SET_FIELD(vert_bp, PV_VERTA_VBP) |
 | |
| +		   VC4_SET_FIELD(vert_sync, PV_VERTA_VSYNC));
 | |
| +	CRTC_WRITE(PV_VERTB,
 | |
| +		   VC4_SET_FIELD(vert_fp, PV_VERTB_VFP) |
 | |
| +		   VC4_SET_FIELD(mode->crtc_vdisplay, PV_VERTB_VACTIVE));
 | |
| +
 | |
|  	if (is_dsi)
 | |
|  		CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
 | |
|  
 |