Skip to content

Commit 5ba39f5

Browse files
6by9pelwell
authored andcommitted
drm/vc4: hdmi: Add property to allow manual config of RGB or YCbCr
Add a custom property "Output format" that allows the overriding of the default colourspace choice in the way that the old firmware hdmi_pixel_encoding property did. If the chosen format is not supported, then it will still drop back to the older behaviour. This won't be acceptable to upstream, but it adds back the missing functionality of hdmi_pixel_encoding. Signed-off-by: Dave Stevenson <[email protected]>
1 parent 2862884 commit 5ba39f5

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

drivers/gpu/drm/vc4/vc4_hdmi.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector,
599599

600600
if (old_state->colorspace != new_state->colorspace ||
601601
old_vc4_state->broadcast_rgb != new_vc4_state->broadcast_rgb ||
602+
old_vc4_state->requested_output_format != new_vc4_state->requested_output_format ||
602603
!drm_connector_atomic_hdr_metadata_equal(old_state, new_state)) {
603604
struct drm_crtc_state *crtc_state;
604605

@@ -625,6 +626,8 @@ static int vc4_hdmi_connector_get_property(struct drm_connector *connector,
625626

626627
if (property == vc4_hdmi->broadcast_rgb_property) {
627628
*val = vc4_conn_state->broadcast_rgb;
629+
} else if (property == vc4_hdmi->output_format_property) {
630+
*val = vc4_conn_state->requested_output_format;
628631
} else {
629632
drm_dbg(drm, "Unknown property [PROP:%d:%s]\n",
630633
property->base.id, property->name);
@@ -648,6 +651,9 @@ static int vc4_hdmi_connector_set_property(struct drm_connector *connector,
648651
if (property == vc4_hdmi->broadcast_rgb_property) {
649652
vc4_conn_state->broadcast_rgb = val;
650653
return 0;
654+
} else if (property == vc4_hdmi->output_format_property) {
655+
vc4_conn_state->requested_output_format = val;
656+
return 0;
651657
}
652658

653659
drm_dbg(drm, "Unknown property [PROP:%d:%s]\n",
@@ -692,6 +698,7 @@ vc4_hdmi_connector_duplicate_state(struct drm_connector *connector)
692698
new_state->tmds_char_rate = vc4_state->tmds_char_rate;
693699
new_state->output_bpc = vc4_state->output_bpc;
694700
new_state->output_format = vc4_state->output_format;
701+
new_state->requested_output_format = vc4_state->requested_output_format;
695702
new_state->broadcast_rgb = vc4_state->broadcast_rgb;
696703
__drm_atomic_helper_connector_duplicate_state(connector, &new_state->base);
697704

@@ -740,6 +747,33 @@ vc4_hdmi_attach_broadcast_rgb_property(struct drm_device *dev,
740747
VC4_HDMI_BROADCAST_RGB_AUTO);
741748
}
742749

750+
static const struct drm_prop_enum_list output_format_names[] = {
751+
{ VC4_HDMI_OUTPUT_AUTO, "Automatic" },
752+
{ VC4_HDMI_OUTPUT_RGB, "RGB" },
753+
{ VC4_HDMI_OUTPUT_YUV422, "YCbCr 4:2:2" },
754+
{ VC4_HDMI_OUTPUT_YUV444, "YCbCr 4:4:4" },
755+
};
756+
757+
static void
758+
vc4_hdmi_attach_output_format_property(struct drm_device *dev,
759+
struct vc4_hdmi *vc4_hdmi)
760+
{
761+
struct drm_property *prop = vc4_hdmi->output_format_property;
762+
763+
if (!prop) {
764+
prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM,
765+
"Output format",
766+
output_format_names,
767+
ARRAY_SIZE(output_format_names));
768+
if (!prop)
769+
return;
770+
771+
vc4_hdmi->output_format_property = prop;
772+
}
773+
774+
drm_object_attach_property(&vc4_hdmi->connector.base, prop, 0);
775+
}
776+
743777
static int vc4_hdmi_connector_init(struct drm_device *dev,
744778
struct vc4_hdmi *vc4_hdmi)
745779
{
@@ -790,6 +824,7 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
790824
}
791825

792826
vc4_hdmi_attach_broadcast_rgb_property(dev, vc4_hdmi);
827+
vc4_hdmi_attach_output_format_property(dev, vc4_hdmi);
793828

794829
drm_connector_attach_encoder(connector, encoder);
795830

@@ -1960,6 +1995,10 @@ static void vc4_hdmi_encoder_atomic_mode_set(struct drm_encoder *encoder,
19601995
&crtc_state->adjusted_mode);
19611996
vc4_hdmi->output_bpc = vc4_state->output_bpc;
19621997
vc4_hdmi->output_format = vc4_state->output_format;
1998+
vc4_hdmi->requested_output_format = vc4_state->requested_output_format;
1999+
memcpy(&vc4_hdmi->saved_adjusted_mode,
2000+
&crtc_state->adjusted_mode,
2001+
sizeof(vc4_hdmi->saved_adjusted_mode));
19632002
mutex_unlock(&vc4_hdmi->mutex);
19642003
}
19652004

@@ -2118,6 +2157,26 @@ vc4_hdmi_encoder_compute_format(const struct vc4_hdmi *vc4_hdmi,
21182157
const struct drm_display_info *info = &connector->display_info;
21192158
unsigned int format;
21202159

2160+
if (vc4_state->requested_output_format != VC4_HDMI_OUTPUT_AUTO) {
2161+
drm_dbg(dev, "Trying with user requested output %u\n",
2162+
vc4_state->requested_output_format);
2163+
2164+
format = vc4_state->requested_output_format;
2165+
if (vc4_hdmi_sink_supports_format_bpc(vc4_hdmi, info, mode,
2166+
format, bpc)) {
2167+
int ret;
2168+
2169+
ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state,
2170+
mode, bpc, format);
2171+
if (!ret) {
2172+
vc4_state->output_format = format;
2173+
return 0;
2174+
}
2175+
}
2176+
2177+
return -EINVAL;
2178+
}
2179+
21212180
drm_dbg(dev, "Trying with an RGB output\n");
21222181

21232182
format = VC4_HDMI_OUTPUT_RGB;

drivers/gpu/drm/vc4/vc4_hdmi.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ struct vc4_hdmi_audio {
113113
};
114114

115115
enum vc4_hdmi_output_format {
116+
VC4_HDMI_OUTPUT_AUTO,
116117
VC4_HDMI_OUTPUT_RGB,
117118
VC4_HDMI_OUTPUT_YUV422,
118119
VC4_HDMI_OUTPUT_YUV444,
@@ -138,6 +139,7 @@ struct vc4_hdmi {
138139
struct delayed_work scrambling_work;
139140

140141
struct drm_property *broadcast_rgb_property;
142+
struct drm_property *output_format_property;
141143

142144
struct i2c_adapter *ddc;
143145
void __iomem *hdmicore_regs;
@@ -230,6 +232,11 @@ struct vc4_hdmi {
230232
* for use outside of KMS hooks. Protected by @mutex.
231233
*/
232234
enum vc4_hdmi_output_format output_format;
235+
/**
236+
* @requested_output_format: Copy of @vc4_connector_state.requested_output_format
237+
* for use outside of KMS hooks. Protected by @mutex.
238+
*/
239+
enum vc4_hdmi_output_format requested_output_format;
233240

234241
/**
235242
* @plugged_cb: Callback provided by hdmi-codec to indicate that an
@@ -273,6 +280,7 @@ struct vc4_hdmi_connector_state {
273280
unsigned int output_bpc;
274281
enum vc4_hdmi_output_format output_format;
275282
enum vc4_hdmi_broadcast_rgb broadcast_rgb;
283+
enum vc4_hdmi_output_format requested_output_format;
276284
};
277285

278286
#define conn_state_to_vc4_hdmi_conn_state(_state) \

0 commit comments

Comments
 (0)