@@ -66,6 +66,83 @@ static void dpu_crtc_destroy(struct drm_crtc *crtc)
6666 kfree (dpu_crtc );
6767}
6868
69+ static struct drm_encoder * get_encoder_from_crtc (struct drm_crtc * crtc )
70+ {
71+ struct drm_device * dev = crtc -> dev ;
72+ struct drm_encoder * encoder ;
73+
74+ drm_for_each_encoder (encoder , dev )
75+ if (encoder -> crtc == crtc )
76+ return encoder ;
77+
78+ return NULL ;
79+ }
80+
81+ static u32 dpu_crtc_get_vblank_counter (struct drm_crtc * crtc )
82+ {
83+ struct drm_encoder * encoder ;
84+
85+ encoder = get_encoder_from_crtc (crtc );
86+ if (!encoder ) {
87+ DRM_ERROR ("no encoder found for crtc %d\n" , crtc -> index );
88+ return false;
89+ }
90+
91+ return dpu_encoder_get_frame_count (encoder );
92+ }
93+
94+ static bool dpu_crtc_get_scanout_position (struct drm_crtc * crtc ,
95+ bool in_vblank_irq ,
96+ int * vpos , int * hpos ,
97+ ktime_t * stime , ktime_t * etime ,
98+ const struct drm_display_mode * mode )
99+ {
100+ unsigned int pipe = crtc -> index ;
101+ struct drm_encoder * encoder ;
102+ int line , vsw , vbp , vactive_start , vactive_end , vfp_end ;
103+
104+ encoder = get_encoder_from_crtc (crtc );
105+ if (!encoder ) {
106+ DRM_ERROR ("no encoder found for crtc %d\n" , pipe );
107+ return false;
108+ }
109+
110+ vsw = mode -> crtc_vsync_end - mode -> crtc_vsync_start ;
111+ vbp = mode -> crtc_vtotal - mode -> crtc_vsync_end ;
112+
113+ /*
114+ * the line counter is 1 at the start of the VSYNC pulse and VTOTAL at
115+ * the end of VFP. Translate the porch values relative to the line
116+ * counter positions.
117+ */
118+
119+ vactive_start = vsw + vbp + 1 ;
120+ vactive_end = vactive_start + mode -> crtc_vdisplay ;
121+
122+ /* last scan line before VSYNC */
123+ vfp_end = mode -> crtc_vtotal ;
124+
125+ if (stime )
126+ * stime = ktime_get ();
127+
128+ line = dpu_encoder_get_linecount (encoder );
129+
130+ if (line < vactive_start )
131+ line -= vactive_start ;
132+ else if (line > vactive_end )
133+ line = line - vfp_end - vactive_start ;
134+ else
135+ line -= vactive_start ;
136+
137+ * vpos = line ;
138+ * hpos = 0 ;
139+
140+ if (etime )
141+ * etime = ktime_get ();
142+
143+ return true;
144+ }
145+
69146static void _dpu_crtc_setup_blend_cfg (struct dpu_crtc_mixer * mixer ,
70147 struct dpu_plane_state * pstate , struct dpu_format * format )
71148{
@@ -130,7 +207,9 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
130207 uint32_t stage_idx , lm_idx ;
131208 int zpos_cnt [DPU_STAGE_MAX + 1 ] = { 0 };
132209 bool bg_alpha_enable = false;
210+ DECLARE_BITMAP (fetch_active , SSPP_MAX );
133211
212+ memset (fetch_active , 0 , sizeof (fetch_active ));
134213 drm_atomic_crtc_for_each_plane (plane , crtc ) {
135214 state = plane -> state ;
136215 if (!state )
@@ -140,7 +219,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
140219 fb = state -> fb ;
141220
142221 dpu_plane_get_ctl_flush (plane , ctl , & flush_mask );
143-
222+ set_bit ( dpu_plane_pipe ( plane ), fetch_active );
144223 DPU_DEBUG ("crtc %d stage:%d - plane %d sspp %d fb %d\n" ,
145224 crtc -> base .id ,
146225 pstate -> stage ,
@@ -180,6 +259,9 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
180259 }
181260 }
182261
262+ if (ctl -> ops .set_active_pipes )
263+ ctl -> ops .set_active_pipes (ctl , fetch_active );
264+
183265 _dpu_crtc_program_lm_output_roi (crtc );
184266}
185267
@@ -839,6 +921,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
839921 DPU_DEBUG ("crtc%d -> enable %d, active %d, skip atomic_check\n" ,
840922 crtc -> base .id , crtc_state -> enable ,
841923 crtc_state -> active );
924+ memset (& cstate -> new_perf , 0 , sizeof (cstate -> new_perf ));
842925 goto end ;
843926 }
844927
@@ -1247,6 +1330,8 @@ static const struct drm_crtc_funcs dpu_crtc_funcs = {
12471330 .early_unregister = dpu_crtc_early_unregister ,
12481331 .enable_vblank = msm_crtc_enable_vblank ,
12491332 .disable_vblank = msm_crtc_disable_vblank ,
1333+ .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp ,
1334+ .get_vblank_counter = dpu_crtc_get_vblank_counter ,
12501335};
12511336
12521337static const struct drm_crtc_helper_funcs dpu_crtc_helper_funcs = {
@@ -1255,6 +1340,7 @@ static const struct drm_crtc_helper_funcs dpu_crtc_helper_funcs = {
12551340 .atomic_check = dpu_crtc_atomic_check ,
12561341 .atomic_begin = dpu_crtc_atomic_begin ,
12571342 .atomic_flush = dpu_crtc_atomic_flush ,
1343+ .get_scanout_position = dpu_crtc_get_scanout_position ,
12581344};
12591345
12601346/* initialize crtc */
0 commit comments