Some display pipelines can only provide non-RBG input pixels to the HDMI TX Controller, this patch takes the pixel format from the plat_data if provided. Signed-off-by: Neil Armstrong <narmstrong@xxxxxxxxxxxx> --- drivers/gpu/drm/bridge/dw-hdmi.c | 55 ++++++++++++++++++++-------------------- include/drm/bridge/dw_hdmi.h | 14 ++++++++-- 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c index f75e5f9..f4ba019 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/dw-hdmi.c @@ -35,12 +35,6 @@ #define HDMI_EDID_LEN 512 -#define RGB 0 -#define YCBCR444 1 -#define YCBCR422_16BITS 2 -#define YCBCR422_8BITS 3 -#define XVYCC444 4 - enum hdmi_datamap { RGB444_8B = 0x01, RGB444_10B = 0x03, @@ -548,7 +542,7 @@ static void hdmi_video_sample(struct dw_hdmi *hdmi) int color_format = 0; u8 val; - if (hdmi->hdmi_data.enc_in_format == RGB) { + if (hdmi->hdmi_data.enc_in_format == DW_HDMI_ENC_FMT_RGB) { if (hdmi->hdmi_data.enc_color_depth == 8) color_format = 0x01; else if (hdmi->hdmi_data.enc_color_depth == 10) @@ -559,7 +553,7 @@ static void hdmi_video_sample(struct dw_hdmi *hdmi) color_format = 0x07; else return; - } else if (hdmi->hdmi_data.enc_in_format == YCBCR444) { + } else if (hdmi->hdmi_data.enc_in_format == DW_HDMI_ENC_FMT_YCBCR444) { if (hdmi->hdmi_data.enc_color_depth == 8) color_format = 0x09; else if (hdmi->hdmi_data.enc_color_depth == 10) @@ -570,7 +564,8 @@ static void hdmi_video_sample(struct dw_hdmi *hdmi) color_format = 0x0F; else return; - } else if (hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) { + } else if (hdmi->hdmi_data.enc_in_format == + DW_HDMI_ENC_FMT_YCBCR422_8BITS) { if (hdmi->hdmi_data.enc_color_depth == 8) color_format = 0x16; else if (hdmi->hdmi_data.enc_color_depth == 10) @@ -606,20 +601,20 @@ static int is_color_space_conversion(struct dw_hdmi *hdmi) static int is_color_space_decimation(struct dw_hdmi *hdmi) { - if (hdmi->hdmi_data.enc_out_format != YCBCR422_8BITS) + if (hdmi->hdmi_data.enc_out_format != DW_HDMI_ENC_FMT_YCBCR422_8BITS) return 0; - if (hdmi->hdmi_data.enc_in_format == RGB || - hdmi->hdmi_data.enc_in_format == YCBCR444) + if (hdmi->hdmi_data.enc_in_format == DW_HDMI_ENC_FMT_RGB || + hdmi->hdmi_data.enc_in_format == DW_HDMI_ENC_FMT_YCBCR444) return 1; return 0; } static int is_color_space_interpolation(struct dw_hdmi *hdmi) { - if (hdmi->hdmi_data.enc_in_format != YCBCR422_8BITS) + if (hdmi->hdmi_data.enc_in_format != DW_HDMI_ENC_FMT_YCBCR422_8BITS) return 0; - if (hdmi->hdmi_data.enc_out_format == RGB || - hdmi->hdmi_data.enc_out_format == YCBCR444) + if (hdmi->hdmi_data.enc_out_format == DW_HDMI_ENC_FMT_RGB || + hdmi->hdmi_data.enc_out_format == DW_HDMI_ENC_FMT_YCBCR444) return 1; return 0; } @@ -631,13 +626,14 @@ static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi) u32 csc_scale = 1; if (is_color_space_conversion(hdmi)) { - if (hdmi->hdmi_data.enc_out_format == RGB) { + if (hdmi->hdmi_data.enc_out_format == DW_HDMI_ENC_FMT_RGB) { if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601) csc_coeff = &csc_coeff_rgb_out_eitu601; else csc_coeff = &csc_coeff_rgb_out_eitu709; - } else if (hdmi->hdmi_data.enc_in_format == RGB) { + } else if (hdmi->hdmi_data.enc_in_format == + DW_HDMI_ENC_FMT_RGB) { if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601) csc_coeff = &csc_coeff_rgb_in_eitu601; @@ -709,8 +705,8 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi) struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data; u8 val, vp_conf; - if (hdmi_data->enc_out_format == RGB || - hdmi_data->enc_out_format == YCBCR444) { + if (hdmi_data->enc_out_format == DW_HDMI_ENC_FMT_RGB || + hdmi_data->enc_out_format == DW_HDMI_ENC_FMT_YCBCR444) { if (!hdmi_data->enc_color_depth) { output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; } else if (hdmi_data->enc_color_depth == 8) { @@ -725,7 +721,8 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi) } else { return; } - } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) { + } else if (hdmi_data->enc_out_format == + DW_HDMI_ENC_FMT_YCBCR422_8BITS) { if (!hdmi_data->enc_color_depth || hdmi_data->enc_color_depth == 8) remap_size = HDMI_VP_REMAP_YCC422_16bit; @@ -1101,15 +1098,16 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) /* Initialise info frame from DRM mode */ drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); - if (hdmi->hdmi_data.enc_out_format == YCBCR444) + if (hdmi->hdmi_data.enc_out_format == DW_HDMI_ENC_FMT_YCBCR444) frame.colorspace = HDMI_COLORSPACE_YUV444; - else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) + else if (hdmi->hdmi_data.enc_out_format == + DW_HDMI_ENC_FMT_YCBCR422_8BITS) frame.colorspace = HDMI_COLORSPACE_YUV422; else frame.colorspace = HDMI_COLORSPACE_RGB; /* Set up colorimetry */ - if (hdmi->hdmi_data.enc_out_format == XVYCC444) { + if (hdmi->hdmi_data.enc_out_format == DW_HDMI_ENC_FMT_XVYCC444) { frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601) frame.extended_colorimetry = @@ -1117,7 +1115,7 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/ frame.extended_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_709; - } else if (hdmi->hdmi_data.enc_out_format != RGB) { + } else if (hdmi->hdmi_data.enc_out_format != DW_HDMI_ENC_FMT_RGB) { frame.colorimetry = hdmi->hdmi_data.colorimetry; frame.extended_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; } else { /* Carries no data */ @@ -1406,10 +1404,13 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0; hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0; - /* TODO: Get input format from IPU (via FB driver interface) */ - hdmi->hdmi_data.enc_in_format = RGB; + /* Get input format from plat data or fallback to RGB */ + if (hdmi->plat_data->input_fmt >= 0) + hdmi->hdmi_data.enc_in_format = hdmi->plat_data->input_fmt; + else + hdmi->hdmi_data.enc_in_format = DW_HDMI_ENC_FMT_RGB; - hdmi->hdmi_data.enc_out_format = RGB; + hdmi->hdmi_data.enc_out_format = DW_HDMI_ENC_FMT_RGB; hdmi->hdmi_data.enc_color_depth = 8; hdmi->hdmi_data.pix_repet_factor = 0; diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index 5b5dfb6..a4caf8b 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -22,6 +22,14 @@ enum { DW_HDMI_RES_MAX, }; +enum dw_hdmi_color_enc_format { + DW_HDMI_ENC_FMT_RGB = 0, + DW_HDMI_ENC_FMT_YCBCR444, + DW_HDMI_ENC_FMT_YCBCR422_16BITS, + DW_HDMI_ENC_FMT_YCBCR422_8BITS, + DW_HDMI_ENC_FMT_XVYCC444, +}; + enum dw_hdmi_phy_type { DW_HDMI_PHY_DWC_HDMI_TX_PHY = 0x00, DW_HDMI_PHY_DWC_MHL_PHY_HEAC = 0xb2, @@ -61,8 +69,8 @@ struct hdmi_vmode { }; struct hdmi_data_info { - unsigned int enc_in_format; - unsigned int enc_out_format; + enum dw_hdmi_color_enc_format enc_in_format; + enum dw_hdmi_color_enc_format enc_out_format; unsigned int enc_color_depth; unsigned int colorimetry; unsigned int pix_repet_factor; @@ -95,6 +103,8 @@ struct dw_hdmi_plat_data { enum drm_mode_status (*mode_valid)(struct drm_connector *connector, struct drm_display_mode *mode); struct regmap *regm; + + int input_fmt; }; int dw_hdmi_probe(struct platform_device *pdev, -- 1.9.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel