@@ -29,6 +29,73 @@ enum dpu_perf_mode {
2929 DPU_PERF_MODE_MAX
3030};
3131
32+ /**
33+ * @_dpu_core_perf_calc_bw() - to calculate BW per crtc
34+ * @kms - pointer to the dpu_kms
35+ * @crtc - pointer to a crtc
36+ * Return: returns aggregated BW for all planes in crtc.
37+ */
38+ static u64 _dpu_core_perf_calc_bw (struct dpu_kms * kms ,
39+ struct drm_crtc * crtc )
40+ {
41+ struct drm_plane * plane ;
42+ struct dpu_plane_state * pstate ;
43+ u64 crtc_plane_bw = 0 ;
44+ u32 bw_factor ;
45+
46+ drm_atomic_crtc_for_each_plane (plane , crtc ) {
47+ pstate = to_dpu_plane_state (plane -> state );
48+
49+ if (!pstate )
50+ continue ;
51+
52+ crtc_plane_bw += pstate -> plane_fetch_bw ;
53+ }
54+
55+ bw_factor = kms -> catalog -> perf .bw_inefficiency_factor ;
56+ if (bw_factor )
57+ crtc_plane_bw = mult_frac (crtc_plane_bw , bw_factor , 100 );
58+
59+ return crtc_plane_bw ;
60+ }
61+
62+ /**
63+ * _dpu_core_perf_calc_clk() - to calculate clock per crtc
64+ * @kms - pointer to the dpu_kms
65+ * @crtc - pointer to a crtc
66+ * @state - pointer to a crtc state
67+ * Return: returns max clk for all planes in crtc.
68+ */
69+ static u64 _dpu_core_perf_calc_clk (struct dpu_kms * kms ,
70+ struct drm_crtc * crtc , struct drm_crtc_state * state )
71+ {
72+ struct drm_plane * plane ;
73+ struct dpu_plane_state * pstate ;
74+ struct drm_display_mode * mode ;
75+ u64 crtc_clk ;
76+ u32 clk_factor ;
77+
78+ mode = & state -> adjusted_mode ;
79+
80+ crtc_clk = mode -> vtotal * mode -> hdisplay * drm_mode_vrefresh (mode );
81+
82+ drm_atomic_crtc_for_each_plane (plane , crtc ) {
83+ pstate = to_dpu_plane_state (plane -> state );
84+
85+ if (!pstate )
86+ continue ;
87+
88+ crtc_clk = max (pstate -> plane_clk , crtc_clk );
89+ }
90+
91+ clk_factor = kms -> catalog -> perf .clk_inefficiency_factor ;
92+ if (clk_factor )
93+ crtc_clk = mult_frac (crtc_clk , clk_factor , 100 );
94+
95+ return crtc_clk ;
96+ }
97+
98+
3299static struct dpu_kms * _dpu_crtc_get_kms (struct drm_crtc * crtc )
33100{
34101 struct msm_drm_private * priv ;
@@ -67,19 +134,18 @@ static void _dpu_core_perf_calc_crtc(struct dpu_kms *kms,
67134 dpu_cstate = to_dpu_crtc_state (state );
68135 memset (perf , 0 , sizeof (struct dpu_core_perf_params ));
69136
70- if (!dpu_cstate -> bw_control ) {
71- perf -> bw_ctl = kms -> catalog -> perf .max_bw_high *
72- 1000ULL ;
73- perf -> max_per_pipe_ib = perf -> bw_ctl ;
74- perf -> core_clk_rate = kms -> perf .max_core_clk_rate ;
75- } else if (kms -> perf .perf_tune .mode == DPU_PERF_MODE_MINIMUM ) {
137+ if (kms -> perf .perf_tune .mode == DPU_PERF_MODE_MINIMUM ) {
76138 perf -> bw_ctl = 0 ;
77139 perf -> max_per_pipe_ib = 0 ;
78140 perf -> core_clk_rate = 0 ;
79141 } else if (kms -> perf .perf_tune .mode == DPU_PERF_MODE_FIXED ) {
80142 perf -> bw_ctl = kms -> perf .fix_core_ab_vote ;
81143 perf -> max_per_pipe_ib = kms -> perf .fix_core_ib_vote ;
82144 perf -> core_clk_rate = kms -> perf .fix_core_clk_rate ;
145+ } else {
146+ perf -> bw_ctl = _dpu_core_perf_calc_bw (kms , crtc );
147+ perf -> max_per_pipe_ib = kms -> catalog -> perf .min_dram_ib ;
148+ perf -> core_clk_rate = _dpu_core_perf_calc_clk (kms , crtc , state );
83149 }
84150
85151 DPU_DEBUG (
@@ -132,11 +198,7 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc,
132198 DPU_DEBUG ("crtc:%d bw:%llu ctrl:%d\n" ,
133199 tmp_crtc -> base .id , tmp_cstate -> new_perf .bw_ctl ,
134200 tmp_cstate -> bw_control );
135- /*
136- * For bw check only use the bw if the
137- * atomic property has been already set
138- */
139- if (tmp_cstate -> bw_control )
201+
140202 bw_sum_of_intfs += tmp_cstate -> new_perf .bw_ctl ;
141203 }
142204
@@ -152,9 +214,7 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc,
152214
153215 DPU_DEBUG ("final threshold bw limit = %d\n" , threshold );
154216
155- if (!dpu_cstate -> bw_control ) {
156- DPU_DEBUG ("bypass bandwidth check\n" );
157- } else if (!threshold ) {
217+ if (!threshold ) {
158218 DPU_ERROR ("no bandwidth limits specified\n" );
159219 return - E2BIG ;
160220 } else if (bw > threshold ) {
@@ -175,7 +235,8 @@ static int _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
175235 = dpu_crtc_get_client_type (crtc );
176236 struct drm_crtc * tmp_crtc ;
177237 struct dpu_crtc_state * dpu_cstate ;
178- int ret = 0 ;
238+ int i , ret = 0 ;
239+ u64 avg_bw ;
179240
180241 drm_for_each_crtc (tmp_crtc , crtc -> dev ) {
181242 if (tmp_crtc -> enabled &&
@@ -186,10 +247,21 @@ static int _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
186247 perf .max_per_pipe_ib = max (perf .max_per_pipe_ib ,
187248 dpu_cstate -> new_perf .max_per_pipe_ib );
188249
189- DPU_DEBUG ("crtc=%d bw=%llu\n" , tmp_crtc -> base .id ,
190- dpu_cstate -> new_perf .bw_ctl );
250+ perf .bw_ctl += dpu_cstate -> new_perf .bw_ctl ;
251+
252+ DPU_DEBUG ("crtc=%d bw=%llu paths:%d\n" ,
253+ tmp_crtc -> base .id ,
254+ dpu_cstate -> new_perf .bw_ctl , kms -> num_paths );
191255 }
192256 }
257+
258+ avg_bw = kms -> num_paths ?
259+ perf .bw_ctl / kms -> num_paths : 0 ;
260+
261+ for (i = 0 ; i < kms -> num_paths ; i ++ )
262+ icc_set_bw (kms -> path [i ],
263+ Bps_to_icc (avg_bw ), (perf .max_per_pipe_ib ));
264+
193265 return ret ;
194266}
195267
0 commit comments