@@ -3853,9 +3853,36 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
3853
3853
return true;
3854
3854
}
3855
3855
3856
+ static bool tgl_crtc_can_enable_sagv (const struct intel_crtc_state * crtc_state )
3857
+ {
3858
+ struct intel_crtc * crtc = to_intel_crtc (crtc_state -> uapi .crtc );
3859
+ enum plane_id plane_id ;
3860
+
3861
+ if (!crtc_state -> hw .active )
3862
+ return true;
3863
+
3864
+ for_each_plane_id_on_crtc (crtc , plane_id ) {
3865
+ const struct skl_ddb_entry * plane_alloc =
3866
+ & crtc_state -> wm .skl .plane_ddb_y [plane_id ];
3867
+ const struct skl_plane_wm * wm =
3868
+ & crtc_state -> wm .skl .optimal .planes [plane_id ];
3869
+
3870
+ if (skl_ddb_entry_size (plane_alloc ) < wm -> sagv_wm0 .min_ddb_alloc )
3871
+ return false;
3872
+ }
3873
+
3874
+ return true;
3875
+ }
3876
+
3856
3877
static bool intel_crtc_can_enable_sagv (const struct intel_crtc_state * crtc_state )
3857
3878
{
3858
- return skl_crtc_can_enable_sagv (crtc_state );
3879
+ struct intel_crtc * crtc = to_intel_crtc (crtc_state -> uapi .crtc );
3880
+ struct drm_i915_private * dev_priv = to_i915 (crtc -> base .dev );
3881
+
3882
+ if (INTEL_GEN (dev_priv ) >= 12 )
3883
+ return tgl_crtc_can_enable_sagv (crtc_state );
3884
+ else
3885
+ return skl_crtc_can_enable_sagv (crtc_state );
3859
3886
}
3860
3887
3861
3888
bool intel_can_enable_sagv (struct drm_i915_private * dev_priv ,
@@ -3873,7 +3900,7 @@ static int intel_compute_sagv_mask(struct intel_atomic_state *state)
3873
3900
struct drm_i915_private * dev_priv = to_i915 (state -> base .dev );
3874
3901
int ret ;
3875
3902
struct intel_crtc * crtc ;
3876
- const struct intel_crtc_state * new_crtc_state ;
3903
+ struct intel_crtc_state * new_crtc_state ;
3877
3904
struct intel_bw_state * new_bw_state = NULL ;
3878
3905
const struct intel_bw_state * old_bw_state = NULL ;
3879
3906
int i ;
@@ -3904,6 +3931,20 @@ static int intel_compute_sagv_mask(struct intel_atomic_state *state)
3904
3931
return ret ;
3905
3932
}
3906
3933
3934
+ for_each_new_intel_crtc_in_state (state , crtc ,
3935
+ new_crtc_state , i ) {
3936
+ struct skl_pipe_wm * pipe_wm = & new_crtc_state -> wm .skl .optimal ;
3937
+
3938
+ /*
3939
+ * We store use_sagv_wm in the crtc state rather than relying on
3940
+ * that bw state since we have no convenient way to get at the
3941
+ * latter from the plane commit hooks (especially in the legacy
3942
+ * cursor case)
3943
+ */
3944
+ pipe_wm -> use_sagv_wm = INTEL_GEN (dev_priv ) >= 12 &&
3945
+ intel_can_enable_sagv (dev_priv , new_bw_state );
3946
+ }
3947
+
3907
3948
if (intel_can_enable_sagv (dev_priv , new_bw_state ) !=
3908
3949
intel_can_enable_sagv (dev_priv , old_bw_state )) {
3909
3950
ret = intel_atomic_serialize_global_state (& new_bw_state -> base );
@@ -4647,8 +4688,11 @@ skl_plane_wm_level(const struct intel_crtc_state *crtc_state,
4647
4688
enum plane_id plane_id ,
4648
4689
int level )
4649
4690
{
4650
- const struct skl_plane_wm * wm =
4651
- & crtc_state -> wm .skl .optimal .planes [plane_id ];
4691
+ const struct skl_pipe_wm * pipe_wm = & crtc_state -> wm .skl .optimal ;
4692
+ const struct skl_plane_wm * wm = & pipe_wm -> planes [plane_id ];
4693
+
4694
+ if (level == 0 && pipe_wm -> use_sagv_wm )
4695
+ return & wm -> sagv_wm0 ;
4652
4696
4653
4697
return & wm -> wm [level ];
4654
4698
}
@@ -4689,7 +4733,6 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state)
4689
4733
plane_data_rate ,
4690
4734
uv_plane_data_rate );
4691
4735
4692
-
4693
4736
skl_ddb_get_pipe_allocation_limits (dev_priv , crtc_state , total_data_rate ,
4694
4737
alloc , & num_active );
4695
4738
alloc_size = skl_ddb_entry_size (alloc );
@@ -5225,6 +5268,20 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
5225
5268
}
5226
5269
}
5227
5270
5271
+ static void tgl_compute_sagv_wm (const struct intel_crtc_state * crtc_state ,
5272
+ const struct skl_wm_params * wm_params ,
5273
+ struct skl_plane_wm * plane_wm )
5274
+ {
5275
+ struct drm_i915_private * dev_priv = to_i915 (crtc_state -> uapi .crtc -> dev );
5276
+ struct skl_wm_level * sagv_wm = & plane_wm -> sagv_wm0 ;
5277
+ struct skl_wm_level * levels = plane_wm -> wm ;
5278
+ unsigned int latency = dev_priv -> wm .skl_latency [0 ] + dev_priv -> sagv_block_time_us ;
5279
+
5280
+ skl_compute_plane_wm (crtc_state , 0 , latency ,
5281
+ wm_params , & levels [0 ],
5282
+ sagv_wm );
5283
+ }
5284
+
5228
5285
static void skl_compute_transition_wm (const struct intel_crtc_state * crtc_state ,
5229
5286
const struct skl_wm_params * wp ,
5230
5287
struct skl_plane_wm * wm )
@@ -5292,6 +5349,8 @@ static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state,
5292
5349
const struct intel_plane_state * plane_state ,
5293
5350
enum plane_id plane_id , int color_plane )
5294
5351
{
5352
+ struct intel_crtc * crtc = to_intel_crtc (crtc_state -> uapi .crtc );
5353
+ struct drm_i915_private * dev_priv = to_i915 (crtc -> base .dev );
5295
5354
struct skl_plane_wm * wm = & crtc_state -> wm .skl .optimal .planes [plane_id ];
5296
5355
struct skl_wm_params wm_params ;
5297
5356
int ret ;
@@ -5302,6 +5361,10 @@ static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state,
5302
5361
return ret ;
5303
5362
5304
5363
skl_compute_wm_levels (crtc_state , & wm_params , wm -> wm );
5364
+
5365
+ if (INTEL_GEN (dev_priv ) >= 12 )
5366
+ tgl_compute_sagv_wm (crtc_state , & wm_params , wm );
5367
+
5305
5368
skl_compute_transition_wm (crtc_state , & wm_params , wm );
5306
5369
5307
5370
return 0 ;
@@ -5668,23 +5731,25 @@ skl_print_wm_changes(struct intel_atomic_state *state)
5668
5731
continue ;
5669
5732
5670
5733
drm_dbg_kms (& dev_priv -> drm ,
5671
- "[PLANE:%d:%s] level %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm"
5672
- " -> %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm\n" ,
5734
+ "[PLANE:%d:%s] level %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm "
5735
+ " -> %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm \n" ,
5673
5736
plane -> base .base .id , plane -> base .name ,
5674
5737
enast (old_wm -> wm [0 ].plane_en ), enast (old_wm -> wm [1 ].plane_en ),
5675
5738
enast (old_wm -> wm [2 ].plane_en ), enast (old_wm -> wm [3 ].plane_en ),
5676
5739
enast (old_wm -> wm [4 ].plane_en ), enast (old_wm -> wm [5 ].plane_en ),
5677
5740
enast (old_wm -> wm [6 ].plane_en ), enast (old_wm -> wm [7 ].plane_en ),
5678
5741
enast (old_wm -> trans_wm .plane_en ),
5742
+ enast (old_wm -> sagv_wm0 .plane_en ),
5679
5743
enast (new_wm -> wm [0 ].plane_en ), enast (new_wm -> wm [1 ].plane_en ),
5680
5744
enast (new_wm -> wm [2 ].plane_en ), enast (new_wm -> wm [3 ].plane_en ),
5681
5745
enast (new_wm -> wm [4 ].plane_en ), enast (new_wm -> wm [5 ].plane_en ),
5682
5746
enast (new_wm -> wm [6 ].plane_en ), enast (new_wm -> wm [7 ].plane_en ),
5683
- enast (new_wm -> trans_wm .plane_en ));
5747
+ enast (new_wm -> trans_wm .plane_en ),
5748
+ enast (new_wm -> sagv_wm0 .plane_en ));
5684
5749
5685
5750
drm_dbg_kms (& dev_priv -> drm ,
5686
- "[PLANE:%d:%s] lines %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d"
5687
- " -> %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d\n" ,
5751
+ "[PLANE:%d:%s] lines %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d "
5752
+ " -> %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d \n" ,
5688
5753
plane -> base .base .id , plane -> base .name ,
5689
5754
enast (old_wm -> wm [0 ].ignore_lines ), old_wm -> wm [0 ].plane_res_l ,
5690
5755
enast (old_wm -> wm [1 ].ignore_lines ), old_wm -> wm [1 ].plane_res_l ,
@@ -5695,6 +5760,7 @@ skl_print_wm_changes(struct intel_atomic_state *state)
5695
5760
enast (old_wm -> wm [6 ].ignore_lines ), old_wm -> wm [6 ].plane_res_l ,
5696
5761
enast (old_wm -> wm [7 ].ignore_lines ), old_wm -> wm [7 ].plane_res_l ,
5697
5762
enast (old_wm -> trans_wm .ignore_lines ), old_wm -> trans_wm .plane_res_l ,
5763
+ enast (old_wm -> sagv_wm0 .ignore_lines ), old_wm -> sagv_wm0 .plane_res_l ,
5698
5764
5699
5765
enast (new_wm -> wm [0 ].ignore_lines ), new_wm -> wm [0 ].plane_res_l ,
5700
5766
enast (new_wm -> wm [1 ].ignore_lines ), new_wm -> wm [1 ].plane_res_l ,
@@ -5704,37 +5770,42 @@ skl_print_wm_changes(struct intel_atomic_state *state)
5704
5770
enast (new_wm -> wm [5 ].ignore_lines ), new_wm -> wm [5 ].plane_res_l ,
5705
5771
enast (new_wm -> wm [6 ].ignore_lines ), new_wm -> wm [6 ].plane_res_l ,
5706
5772
enast (new_wm -> wm [7 ].ignore_lines ), new_wm -> wm [7 ].plane_res_l ,
5707
- enast (new_wm -> trans_wm .ignore_lines ), new_wm -> trans_wm .plane_res_l );
5773
+ enast (new_wm -> trans_wm .ignore_lines ), new_wm -> trans_wm .plane_res_l ,
5774
+ enast (new_wm -> sagv_wm0 .ignore_lines ), new_wm -> sagv_wm0 .plane_res_l );
5708
5775
5709
5776
drm_dbg_kms (& dev_priv -> drm ,
5710
- "[PLANE:%d:%s] blocks %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d"
5711
- " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d\n" ,
5777
+ "[PLANE:%d:%s] blocks %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d "
5778
+ " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d \n" ,
5712
5779
plane -> base .base .id , plane -> base .name ,
5713
5780
old_wm -> wm [0 ].plane_res_b , old_wm -> wm [1 ].plane_res_b ,
5714
5781
old_wm -> wm [2 ].plane_res_b , old_wm -> wm [3 ].plane_res_b ,
5715
5782
old_wm -> wm [4 ].plane_res_b , old_wm -> wm [5 ].plane_res_b ,
5716
5783
old_wm -> wm [6 ].plane_res_b , old_wm -> wm [7 ].plane_res_b ,
5717
5784
old_wm -> trans_wm .plane_res_b ,
5785
+ old_wm -> sagv_wm0 .plane_res_b ,
5718
5786
new_wm -> wm [0 ].plane_res_b , new_wm -> wm [1 ].plane_res_b ,
5719
5787
new_wm -> wm [2 ].plane_res_b , new_wm -> wm [3 ].plane_res_b ,
5720
5788
new_wm -> wm [4 ].plane_res_b , new_wm -> wm [5 ].plane_res_b ,
5721
5789
new_wm -> wm [6 ].plane_res_b , new_wm -> wm [7 ].plane_res_b ,
5722
- new_wm -> trans_wm .plane_res_b );
5790
+ new_wm -> trans_wm .plane_res_b ,
5791
+ new_wm -> sagv_wm0 .plane_res_b );
5723
5792
5724
5793
drm_dbg_kms (& dev_priv -> drm ,
5725
- "[PLANE:%d:%s] min_ddb %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d"
5726
- " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d\n" ,
5794
+ "[PLANE:%d:%s] min_ddb %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d "
5795
+ " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d \n" ,
5727
5796
plane -> base .base .id , plane -> base .name ,
5728
5797
old_wm -> wm [0 ].min_ddb_alloc , old_wm -> wm [1 ].min_ddb_alloc ,
5729
5798
old_wm -> wm [2 ].min_ddb_alloc , old_wm -> wm [3 ].min_ddb_alloc ,
5730
5799
old_wm -> wm [4 ].min_ddb_alloc , old_wm -> wm [5 ].min_ddb_alloc ,
5731
5800
old_wm -> wm [6 ].min_ddb_alloc , old_wm -> wm [7 ].min_ddb_alloc ,
5732
5801
old_wm -> trans_wm .min_ddb_alloc ,
5802
+ old_wm -> sagv_wm0 .min_ddb_alloc ,
5733
5803
new_wm -> wm [0 ].min_ddb_alloc , new_wm -> wm [1 ].min_ddb_alloc ,
5734
5804
new_wm -> wm [2 ].min_ddb_alloc , new_wm -> wm [3 ].min_ddb_alloc ,
5735
5805
new_wm -> wm [4 ].min_ddb_alloc , new_wm -> wm [5 ].min_ddb_alloc ,
5736
5806
new_wm -> wm [6 ].min_ddb_alloc , new_wm -> wm [7 ].min_ddb_alloc ,
5737
- new_wm -> trans_wm .min_ddb_alloc );
5807
+ new_wm -> trans_wm .min_ddb_alloc ,
5808
+ new_wm -> sagv_wm0 .min_ddb_alloc );
5738
5809
}
5739
5810
}
5740
5811
}
@@ -6027,6 +6098,9 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
6027
6098
skl_wm_level_from_reg_val (val , & wm -> wm [level ]);
6028
6099
}
6029
6100
6101
+ if (INTEL_GEN (dev_priv ) >= 12 )
6102
+ wm -> sagv_wm0 = wm -> wm [0 ];
6103
+
6030
6104
if (plane_id != PLANE_CURSOR )
6031
6105
val = I915_READ (PLANE_WM_TRANS (pipe , plane_id ));
6032
6106
else
0 commit comments