Skip to content

Commit 97d7fdd

Browse files
mripardpelwell
authored andcommitted
drm/vc4: hdmi: Always try to have the highest bpc
Currently we take the max_bpc property as the bpc value and do not try anything else. However, what the other drivers seem to be doing is that they would try with the highest bpc allowed by the max_bpc property and the hardware capabilities, test if it results in an acceptable configuration, and if not decrease the bpc and try again. Let's use the same logic. Signed-off-by: Maxime Ripard <[email protected]>
1 parent 2ac18e3 commit 97d7fdd

File tree

2 files changed

+43
-5
lines changed

2 files changed

+43
-5
lines changed

drivers/gpu/drm/vc4/vc4_hdmi.c

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ vc4_hdmi_connector_duplicate_state(struct drm_connector *connector)
361361
return NULL;
362362

363363
new_state->pixel_rate = vc4_state->pixel_rate;
364+
new_state->output_bpc = vc4_state->output_bpc;
364365
__drm_atomic_helper_connector_duplicate_state(connector, &new_state->base);
365366

366367
return &new_state->base;
@@ -923,6 +924,8 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
923924
struct drm_connector_state *state,
924925
struct drm_display_mode *mode)
925926
{
927+
const struct vc4_hdmi_connector_state *vc4_state =
928+
conn_state_to_vc4_hdmi_conn_state(state);
926929
bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
927930
bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
928931
bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
@@ -970,7 +973,7 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
970973
HDMI_WRITE(HDMI_VERTB0, vertb_even);
971974
HDMI_WRITE(HDMI_VERTB1, vertb);
972975

973-
switch (state->max_bpc) {
976+
switch (vc4_state->output_bpc) {
974977
case 12:
975978
gcp = 6;
976979
gcp_en = true;
@@ -1249,9 +1252,11 @@ static void vc4_hdmi_encoder_atomic_mode_set(struct drm_encoder *encoder,
12491252
struct drm_connector_state *conn_state)
12501253
{
12511254
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);
12521257

12531258
mutex_lock(&vc4_hdmi->mutex);
1254-
vc4_hdmi->output_bpc = conn_state->max_bpc;
1259+
vc4_hdmi->output_bpc = vc4_state->output_bpc;
12551260
memcpy(&vc4_hdmi->saved_adjusted_mode,
12561261
&crtc_state->adjusted_mode,
12571262
sizeof(vc4_hdmi->saved_adjusted_mode));
@@ -1306,6 +1311,38 @@ vc4_hdmi_encoder_compute_clock(const struct vc4_hdmi *vc4_hdmi,
13061311
return 0;
13071312
}
13081313

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+
13091346
#define WIFI_2_4GHz_CH1_MIN_FREQ 2400000000ULL
13101347
#define WIFI_2_4GHz_CH1_MAX_FREQ 2422000000ULL
13111348

@@ -1340,8 +1377,7 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
13401377
pixel_rate = mode->clock * 1000;
13411378
}
13421379

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);
13451381
if (ret)
13461382
return ret;
13471383

drivers/gpu/drm/vc4/vc4_hdmi.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,8 @@ struct vc4_hdmi {
231231
bool scdc_enabled;
232232

233233
/**
234-
* @output_bpc: BPC currently being used. Protected by @mutex.
234+
* @output_bpc: Copy of @vc4_connector_state.output_bpc for use
235+
* outside of KMS hooks. Protected by @mutex.
235236
*/
236237
unsigned int output_bpc;
237238
};
@@ -253,6 +254,7 @@ encoder_to_vc4_hdmi(struct drm_encoder *encoder)
253254
struct vc4_hdmi_connector_state {
254255
struct drm_connector_state base;
255256
unsigned long long pixel_rate;
257+
unsigned int output_bpc;
256258
};
257259

258260
static inline struct vc4_hdmi_connector_state *

0 commit comments

Comments
 (0)