hdmi_mode_set_vswing(state);
}
+#define YUV_MODE BIT(0)
+
+bool hdmi_mode_fixup_t28hpc(state_struct *state,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct imx_hdp *hdp = container_of(state, struct imx_hdp, state);
+ int vic = drm_match_cea_mode(mode);
+ struct drm_display_info *di = &hdp->connector.display_info;
+
+ hdp->bpc = 8;
+ hdp->format = PXL_RGB;
+
+ if ((vic == VIC_MODE_97_60Hz || vic == VIC_MODE_96_50Hz)) {
+ if (di->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)
+ hdp->bpc = 12;
+ else if (di->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
+ hdp->bpc = 10;
+
+ if (drm_mode_is_420_only(di, mode) ||
+ (drm_mode_is_420_also(di, mode) && hdp->bpc > 8)) {
+ hdp->format = YCBCR_4_2_0;
+
+ adjusted_mode->private_flags = YUV_MODE;
+ } else {
+ hdp->bpc = 8;
+ }
+
+ return true;
+ }
+
+ if (di->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_36)
+ hdp->bpc = 12;
+ else if (di->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30)
+ hdp->bpc = 10;
+
+ /* 10-bit color depth for the following modes is not supported */
+ if ((vic == VIC_MODE_95_30Hz || vic == VIC_MODE_94_25Hz ||
+ vic == VIC_MODE_93_24Hz) && hdp->bpc == 10)
+ hdp->bpc = 8;
+
+ return true;
+}
+
int hdmi_get_edid_block(void *data, u8 *buf, u32 block, size_t len)
{
HDMITX_TRANS_DATA edidResp;
struct drm_display_mode *mode, int format, int color_depth);
void hdmi_mode_set_t28hpc(state_struct *state,
struct drm_display_mode *mode, int format, int color_depth, int temp);
+bool hdmi_mode_fixup_t28hpc(state_struct *state,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
int hdmi_get_edid_block(void *data, u8 *buf, u32 block, size_t len);
int hdmi_get_hpd_state(state_struct *state, u8 *hpd);
int hdmi_write_hdr_metadata(state_struct *state,
struct drm_display_mode *adjusted_mode)
{
struct imx_hdp *hdp = bridge->driver_private;
- struct drm_display_info *di = &hdp->connector.display_info;
int vic = drm_match_cea_mode(mode);
if (vic < 0)
return false;
- /* force output 10bit YUV420 if HDMI sink support HDR10 */
- if (vic == VIC_MODE_97_60Hz && cpu_is_imx8mq() &&
- (di->color_formats & DRM_COLOR_FORMAT_YCRCB420) &&
- (di->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)) {
- hdp->bpc = 10;
- hdp->format = YCBCR_4_2_0;
- return true;
- }
-
- hdp->bpc = 8;
- hdp->format = PXL_RGB;
+ if (hdp && hdp->ops && hdp->ops->mode_fixup)
+ return hdp->ops->mode_fixup(&hdp->state, mode, adjusted_mode);
return true;
}
static struct hdp_ops imx8mq_ops = {
.phy_init = hdmi_phy_init_t28hpc,
.mode_set = hdmi_mode_set_t28hpc,
+ .mode_fixup = hdmi_mode_fixup_t28hpc,
.get_edid_block = hdmi_get_edid_block,
.get_hpd_state = hdmi_get_hpd_state,
.write_hdr_metadata = hdmi_write_hdr_metadata,
#define HOTPLUG_DEBOUNCE_MS 200
-#define VIC_MODE_96_50Hz 96
#define VIC_MODE_97_60Hz 97
+#define VIC_MODE_96_50Hz 96
+#define VIC_MODE_95_30Hz 95
+#define VIC_MODE_94_25Hz 94
+#define VIC_MODE_93_24Hz 93
+
/**
* imx_hdp_call - Calls a struct imx hdp_operations operation on
* an entity
int format, int color_depth);
void (*mode_set)(state_struct *state, struct drm_display_mode *mode,
int format, int color_depth, int max_link);
+ bool (*mode_fixup)(state_struct *state,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
int (*get_edid_block)(void *data, u8 *buf, u32 block, size_t len);
int (*get_hpd_state)(state_struct *state, u8 *hpd);
int (*write_hdr_metadata)(state_struct *state,