[PATCH 4/4] drm: bridge: dw-hdmi: Take input format from plat_data
Neil Armstrong
narmstrong at baylibre.com
Mon Jan 30 03:05:18 PST 2017
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 at baylibre.com>
---
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
More information about the linux-amlogic
mailing list