@@ -361,6 +361,7 @@ vc4_hdmi_connector_duplicate_state(struct drm_connector *connector)
361
361
return NULL ;
362
362
363
363
new_state -> pixel_rate = vc4_state -> pixel_rate ;
364
+ new_state -> output_bpc = vc4_state -> output_bpc ;
364
365
__drm_atomic_helper_connector_duplicate_state (connector , & new_state -> base );
365
366
366
367
return & new_state -> base ;
@@ -923,6 +924,8 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
923
924
struct drm_connector_state * state ,
924
925
struct drm_display_mode * mode )
925
926
{
927
+ const struct vc4_hdmi_connector_state * vc4_state =
928
+ conn_state_to_vc4_hdmi_conn_state (state );
926
929
bool hsync_pos = mode -> flags & DRM_MODE_FLAG_PHSYNC ;
927
930
bool vsync_pos = mode -> flags & DRM_MODE_FLAG_PVSYNC ;
928
931
bool interlaced = mode -> flags & DRM_MODE_FLAG_INTERLACE ;
@@ -970,7 +973,7 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
970
973
HDMI_WRITE (HDMI_VERTB0 , vertb_even );
971
974
HDMI_WRITE (HDMI_VERTB1 , vertb );
972
975
973
- switch (state -> max_bpc ) {
976
+ switch (vc4_state -> output_bpc ) {
974
977
case 12 :
975
978
gcp = 6 ;
976
979
gcp_en = true;
@@ -1249,9 +1252,11 @@ static void vc4_hdmi_encoder_atomic_mode_set(struct drm_encoder *encoder,
1249
1252
struct drm_connector_state * conn_state )
1250
1253
{
1251
1254
struct vc4_hdmi * vc4_hdmi = encoder_to_vc4_hdmi (encoder );
1255
+ struct vc4_hdmi_connector_state * vc4_state =
1256
+ conn_state_to_vc4_hdmi_conn_state (conn_state );
1252
1257
1253
1258
mutex_lock (& vc4_hdmi -> mutex );
1254
- vc4_hdmi -> output_bpc = conn_state -> max_bpc ;
1259
+ vc4_hdmi -> output_bpc = vc4_state -> output_bpc ;
1255
1260
memcpy (& vc4_hdmi -> saved_adjusted_mode ,
1256
1261
& crtc_state -> adjusted_mode ,
1257
1262
sizeof (vc4_hdmi -> saved_adjusted_mode ));
@@ -1306,6 +1311,38 @@ vc4_hdmi_encoder_compute_clock(const struct vc4_hdmi *vc4_hdmi,
1306
1311
return 0 ;
1307
1312
}
1308
1313
1314
+ static int
1315
+ vc4_hdmi_encoder_compute_config (const struct vc4_hdmi * vc4_hdmi ,
1316
+ struct vc4_hdmi_connector_state * vc4_state ,
1317
+ const struct drm_display_mode * mode )
1318
+ {
1319
+ struct drm_connector_state * conn_state = & vc4_state -> base ;
1320
+ unsigned int max_bpc = clamp_t (unsigned int , conn_state -> max_bpc , 8 , 12 );
1321
+ unsigned int bpc ;
1322
+ int ret ;
1323
+
1324
+ for (bpc = max_bpc ; bpc >= 8 ; bpc -= 2 ) {
1325
+ drm_dbg (dev , "Trying with a %d bpc output\n" , bpc );
1326
+
1327
+ ret = vc4_hdmi_encoder_compute_clock (vc4_hdmi , vc4_state ,
1328
+ mode , bpc );
1329
+ if (ret )
1330
+ continue ;
1331
+
1332
+ vc4_state -> output_bpc = bpc ;
1333
+
1334
+ drm_dbg (dev ,
1335
+ "Mode %ux%u @ %uHz: Found configuration: bpc: %u, clock: %llu\n" ,
1336
+ mode -> hdisplay , mode -> vdisplay , drm_mode_vrefresh (mode ),
1337
+ vc4_state -> output_bpc ,
1338
+ vc4_state -> pixel_rate );
1339
+
1340
+ break ;
1341
+ }
1342
+
1343
+ return ret ;
1344
+ }
1345
+
1309
1346
#define WIFI_2_4GHz_CH1_MIN_FREQ 2400000000ULL
1310
1347
#define WIFI_2_4GHz_CH1_MAX_FREQ 2422000000ULL
1311
1348
@@ -1340,8 +1377,7 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
1340
1377
pixel_rate = mode -> clock * 1000 ;
1341
1378
}
1342
1379
1343
- ret = vc4_hdmi_encoder_compute_clock (vc4_hdmi , vc4_state , mode ,
1344
- conn_state -> max_bpc );
1380
+ ret = vc4_hdmi_encoder_compute_config (vc4_hdmi , vc4_state , mode );
1345
1381
if (ret )
1346
1382
return ret ;
1347
1383
0 commit comments