Skip to content

Commit 58329f9

Browse files
authored
Merge pull request torvalds#145 from vamrs-feng/pr_limit_hdmi
Radxa ROCK 3C has one HDMI port supporting CEC and HDMI 2.0 with resolutions up to 1080P@60fps. Signed-off-by: Stephen Chen <[email protected]>
2 parents 76bd764 + 7dc3930 commit 58329f9

File tree

4 files changed

+42
-0
lines changed

4 files changed

+42
-0
lines changed

arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@
243243

244244
&hdmi {
245245
status = "okay";
246+
preset_max_hdisplay = <1920>;
247+
preset_max_vdisplay = <1080>;
246248
};
247249

248250
&hdmi_in_vp0 {

drivers/gpu/drm/bridge/synopsys/dw-hdmi.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,9 @@ struct dw_hdmi {
330330
bool logo_plug_out; /* hdmi is plug out when kernel logo */
331331
bool update;
332332
bool hdr2sdr; /* from hdr to sdr */
333+
334+
unsigned int preset_max_hdisplay;
335+
unsigned int preset_max_vdisplay;
333336
};
334337

335338
#define HDMI_IH_PHY_STAT0_RX_SENSE \
@@ -3080,6 +3083,14 @@ dw_hdmi_update_hdr_property(struct drm_connector *connector)
30803083
return ret;
30813084
}
30823085

3086+
bool dw_hdmi_resolution_within_custom_limit(struct dw_hdmi *dw_hdmi,
3087+
unsigned int hdisplay, unsigned int vdisplay)
3088+
{
3089+
return !dw_hdmi->preset_max_hdisplay ||
3090+
!dw_hdmi->preset_max_vdisplay ||
3091+
hdisplay * vdisplay <= dw_hdmi->preset_max_hdisplay * dw_hdmi->preset_max_vdisplay;
3092+
}
3093+
30833094
static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
30843095
{
30853096
struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
@@ -3091,6 +3102,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
30913102
struct drm_display_info *info = &connector->display_info;
30923103
void *data = hdmi->plat_data->phy_data;
30933104
int i, ret = 0;
3105+
struct drm_display_mode *preferred_mode = NULL;
30943106

30953107
memset(metedata, 0, sizeof(*metedata));
30963108
edid = dw_hdmi_get_edid(hdmi, connector);
@@ -3143,6 +3155,26 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
31433155
dw_hdmi_update_hdr_property(connector);
31443156
dw_hdmi_check_output_type_changed(hdmi);
31453157

3158+
if ((hdmi->preset_max_hdisplay) && (hdmi->preset_max_vdisplay)) {
3159+
list_for_each_entry(mode, &connector->probed_modes, head) {
3160+
if (mode->hdisplay == hdmi->preset_max_hdisplay &&
3161+
mode->vdisplay == hdmi->preset_max_vdisplay) {
3162+
preferred_mode?:(preferred_mode = mode);
3163+
if(!(mode->flags & DRM_MODE_FLAG_INTERLACE)) {
3164+
if((preferred_mode->flags & DRM_MODE_FLAG_INTERLACE) || (
3165+
drm_mode_vrefresh(mode) >
3166+
drm_mode_vrefresh(preferred_mode) &&
3167+
drm_mode_vrefresh(mode) <= 60)) {
3168+
preferred_mode = mode;
3169+
}
3170+
}
3171+
}
3172+
}
3173+
3174+
if (preferred_mode)
3175+
preferred_mode->type |= DRM_MODE_TYPE_PREFERRED;
3176+
}
3177+
31463178
return ret;
31473179
}
31483180

@@ -4748,6 +4780,9 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
47484780
mutex_init(&hdmi->cec_notifier_mutex);
47494781
spin_lock_init(&hdmi->audio_lock);
47504782

4783+
of_property_read_u32(np, "preset_max_hdisplay", &hdmi->preset_max_hdisplay);
4784+
of_property_read_u32(np, "preset_max_vdisplay", &hdmi->preset_max_vdisplay);
4785+
47514786
ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
47524787
if (ddc_node) {
47534788
hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node);

drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,6 +1613,9 @@ dw_hdmi_rockchip_mode_valid(struct dw_hdmi *dw_hdmi, void *data,
16131613

16141614
hdmi = to_rockchip_hdmi(encoder);
16151615

1616+
if (!dw_hdmi_resolution_within_custom_limit(dw_hdmi, mode->hdisplay, mode->vdisplay))
1617+
return MODE_BAD;
1618+
16161619
/*
16171620
* If sink max TMDS clock < 340MHz, we should check the mode pixel
16181621
* clock > 340MHz is YCbCr420 or not and whether the platform supports

include/drm/bridge/dw_hdmi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,5 +340,7 @@ int dw_hdmi_qp_get_output_type_cap(struct dw_hdmi_qp *hdmi);
340340
void dw_hdmi_set_hpd_wake(struct dw_hdmi *hdmi);
341341
void dw_hdmi_cec_wake_ops_register(struct dw_hdmi *hdmi,
342342
const struct dw_hdmi_cec_wake_ops *cec_ops);
343+
bool dw_hdmi_resolution_within_custom_limit(struct dw_hdmi *dw_hdmi,
344+
unsigned int hdisplay, unsigned int vdisplay);
343345

344346
#endif /* __IMX_HDMI_H__ */

0 commit comments

Comments
 (0)