From 96e35598cead98de897038c0b4813396e694cb72 Mon Sep 17 00:00:00 2001 From: Shashank Sharma Date: Fri, 12 Oct 2018 11:53:10 +0530 Subject: drm/i915: Check LSPCON vendor OUI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Intel LSPCON chip is provided by 2 vendors: - Megachips America (MCA) - Parade technologies (Parade tech) Its important to know the vendor of this chip, as the address to write AVI infoframes is different for those two. This patch reads the vendor OUI signature, and marks into LSPCON encoder structure for future usages. This patch also does a small re-arrangement of the code, by moving lspcon mode change into probe function. V2: Use dp->desc for OUI detection, dont add a helper for this (Ville) V3: Rebase, Added r-b from Maarten V4: Rebase V5: Rebase V6: Rebase V7: Rebase V8: Rebase V9: Rebase V10: Rebase Cc: Imre Deak Cc: Ville Syrjälä Cc: Maarten Lankhorst Reviewed-by: Lankhorst Signed-off-by: Shashank Sharma Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1539325394-20788-4-git-send-email-shashank.sharma@intel.com --- drivers/gpu/drm/i915/intel_lspcon.c | 69 +++++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 14 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_lspcon.c') diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c index 3e085c5f2b81..56f80b74690d 100644 --- a/drivers/gpu/drm/i915/intel_lspcon.c +++ b/drivers/gpu/drm/i915/intel_lspcon.c @@ -27,6 +27,10 @@ #include #include "intel_drv.h" +/* LSPCON OUI Vendor ID(signatures) */ +#define LSPCON_VENDOR_PARADE_OUI 0x001CF8 +#define LSPCON_VENDOR_MCA_OUI 0x0060AD + static struct intel_dp *lspcon_to_intel_dp(struct intel_lspcon *lspcon) { struct intel_digital_port *dig_port = @@ -50,6 +54,40 @@ static const char *lspcon_mode_name(enum drm_lspcon_mode mode) } } +static bool lspcon_detect_vendor(struct intel_lspcon *lspcon) +{ + struct intel_dp *dp = lspcon_to_intel_dp(lspcon); + struct drm_dp_dpcd_ident *ident; + u32 vendor_oui; + + if (drm_dp_read_desc(&dp->aux, &dp->desc, drm_dp_is_branch(dp->dpcd))) { + DRM_ERROR("Can't read description\n"); + return false; + } + + ident = &dp->desc.ident; + vendor_oui = (ident->oui[0] << 16) | (ident->oui[1] << 8) | + ident->oui[2]; + + switch (vendor_oui) { + case LSPCON_VENDOR_MCA_OUI: + lspcon->vendor = LSPCON_VENDOR_MCA; + DRM_DEBUG_KMS("Vendor: Mega Chips\n"); + break; + + case LSPCON_VENDOR_PARADE_OUI: + lspcon->vendor = LSPCON_VENDOR_PARADE; + DRM_DEBUG_KMS("Vendor: Parade Tech\n"); + break; + + default: + DRM_ERROR("Invalid/Unknown vendor OUI\n"); + return false; + } + + return true; +} + static enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon) { enum drm_lspcon_mode current_mode; @@ -159,7 +197,18 @@ static bool lspcon_probe(struct intel_lspcon *lspcon) /* Yay ... got a LSPCON device */ DRM_DEBUG_KMS("LSPCON detected\n"); lspcon->mode = lspcon_wait_mode(lspcon, expected_mode); - lspcon->active = true; + + /* + * In the SW state machine, lets Put LSPCON in PCON mode only. + * In this way, it will work with both HDMI 1.4 sinks as well as HDMI + * 2.0 sinks. + */ + if (lspcon->active && lspcon->mode != DRM_LSPCON_MODE_PCON) { + if (lspcon_change_mode(lspcon, DRM_LSPCON_MODE_PCON) < 0) { + DRM_ERROR("LSPCON mode change to PCON failed\n"); + return false; + } + } return true; } @@ -230,25 +279,17 @@ bool lspcon_init(struct intel_digital_port *intel_dig_port) return false; } - /* - * In the SW state machine, lets Put LSPCON in PCON mode only. - * In this way, it will work with both HDMI 1.4 sinks as well as HDMI - * 2.0 sinks. - */ - if (lspcon->active && lspcon->mode != DRM_LSPCON_MODE_PCON) { - if (lspcon_change_mode(lspcon, DRM_LSPCON_MODE_PCON) < 0) { - DRM_ERROR("LSPCON mode change to PCON failed\n"); - return false; - } - } - if (!intel_dp_read_dpcd(dp)) { DRM_ERROR("LSPCON DPCD read failed\n"); return false; } - drm_dp_read_desc(&dp->aux, &dp->desc, drm_dp_is_branch(dp->dpcd)); + if (!lspcon_detect_vendor(lspcon)) { + DRM_ERROR("LSPCON vendor detection failed\n"); + return false; + } + lspcon->active = true; DRM_DEBUG_KMS("Success: LSPCON init\n"); return true; } -- cgit From 06c812d7c591906e5f159cecfc8e561a2f59d848 Mon Sep 17 00:00:00 2001 From: Shashank Sharma Date: Fri, 12 Oct 2018 11:53:11 +0530 Subject: drm/i915: Add AVI infoframe support for LSPCON In order to pass AVI infoframes to LSPCON devices, a source has to write them in a vendor recommended method and location. This patch series: - adds generic LSPCON infoframe setup functions. - registers these functions into existing AVI infoframe framework. - triggers these functions from modeset sequence. Next patches in the series will add vendor specific code. V2: Added new parameter to align with new definition of drm_hdmi_avi_infoframe_quant_range V3: Added r-b from Maarten (for V2) Added new parameter output_format in struct lspcon to accommodate Ville's review comments on last patch of the series V4: Addressed Ville's review comment - Do not add output_format in LSPCON state, as its non-atomic. Add this into CRTC state (added in a later patch). V5: Rebase V6: Rebase V7: Rebase V8: Rebase V9: Rebase V10: Rebase V11: Accommodated rebasing changes in intel_git_port fptrs (set_infoframes and infoframe_enabled) Cc: Ville Syrjala Cc: Imre Deak Cc: Maarten Lankhorst Reviewed-by: Maarten Lankhorst Signed-off-by: Shashank Sharma Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1539325394-20788-5-git-send-email-shashank.sharma@intel.com --- drivers/gpu/drm/i915/intel_lspcon.c | 49 +++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_lspcon.c') diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c index 56f80b74690d..8d497279ee9c 100644 --- a/drivers/gpu/drm/i915/intel_lspcon.c +++ b/drivers/gpu/drm/i915/intel_lspcon.c @@ -234,6 +234,55 @@ static void lspcon_resume_in_pcon_wa(struct intel_lspcon *lspcon) DRM_DEBUG_KMS("LSPCON DP descriptor mismatch after resume\n"); } +void lspcon_set_infoframes(struct intel_encoder *encoder, + bool enable, + const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) +{ + ssize_t ret; + union hdmi_infoframe frame; + uint8_t buf[VIDEO_DIP_DATA_SIZE]; + struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); + struct intel_lspcon *lspcon = &dig_port->lspcon; + struct intel_dp *intel_dp = &dig_port->dp; + struct drm_connector *connector = &intel_dp->attached_connector->base; + const struct drm_display_mode *mode = &crtc_state->base.adjusted_mode; + bool is_hdmi2_sink = connector->display_info.hdmi.scdc.supported; + + if (!lspcon->active) { + DRM_ERROR("Writing infoframes while LSPCON disabled ?\n"); + return; + } + + ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, + mode, is_hdmi2_sink); + if (ret < 0) { + DRM_ERROR("couldn't fill AVI infoframe\n"); + return; + } + + drm_hdmi_avi_infoframe_quant_range(&frame.avi, mode, + crtc_state->limited_color_range ? + HDMI_QUANTIZATION_RANGE_LIMITED : + HDMI_QUANTIZATION_RANGE_FULL, + false, is_hdmi2_sink); + + ret = hdmi_infoframe_pack(&frame, buf, sizeof(buf)); + if (ret < 0) { + DRM_ERROR("Failed to pack AVI IF\n"); + return; + } + + dig_port->write_infoframe(encoder, crtc_state, HDMI_INFOFRAME_TYPE_AVI, + buf, ret); +} + +bool lspcon_infoframe_enabled(struct intel_encoder *encoder, + const struct intel_crtc_state *pipe_config) +{ + return enc_to_intel_lspcon(&encoder->base)->active; +} + void lspcon_resume(struct intel_lspcon *lspcon) { enum drm_lspcon_mode expected_mode; -- cgit From 7cbf19fd54ffef01a8a7af554b8447bef7c17ce7 Mon Sep 17 00:00:00 2001 From: Shashank Sharma Date: Fri, 12 Oct 2018 11:53:12 +0530 Subject: drm/i915: Write AVI infoframes for MCA LSPCON MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LSPCON is a DP branch device, so LSPCON vendors define specific methods to pass AVI infoframes to the the chip. This patch adds: - a generic wrapper function for writing AVI infoframes for all LSPCON devices. - a vendor specific function to wrire AVI infoframes into MCA LSPCON devices. V2: Rebase V3: Added r-b from Maarten V4: Rebase V5: Rebase V6: Rebase V7: Fixed checkpatch warnings for alignment V8: Rebase V9: Added the retry logic, with 50ms incremental delays while writing AVI IF V10: Changed the return value check V11: Fixed checkpatch warning V12: Rebase Cc: Imre Deak Cc: Ville Syrjälä Cc: Maarten Lankhorst Reviewed-by: Maarten Lankhorst Signed-off-by: Shashank Sharma Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1539325394-20788-6-git-send-email-shashank.sharma@intel.com --- drivers/gpu/drm/i915/intel_lspcon.c | 88 +++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_lspcon.c') diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c index 8d497279ee9c..b806803238d4 100644 --- a/drivers/gpu/drm/i915/intel_lspcon.c +++ b/drivers/gpu/drm/i915/intel_lspcon.c @@ -31,6 +31,12 @@ #define LSPCON_VENDOR_PARADE_OUI 0x001CF8 #define LSPCON_VENDOR_MCA_OUI 0x0060AD +/* AUX addresses to write MCA AVI IF */ +#define LSPCON_MCA_AVI_IF_WRITE_OFFSET 0x5C0 +#define LSPCON_MCA_AVI_IF_CTRL 0x5DF +#define LSPCON_MCA_AVI_IF_KICKOFF (1 << 0) +#define LSPCON_MCA_AVI_IF_HANDLED (1 << 1) + static struct intel_dp *lspcon_to_intel_dp(struct intel_lspcon *lspcon) { struct intel_digital_port *dig_port = @@ -234,6 +240,88 @@ static void lspcon_resume_in_pcon_wa(struct intel_lspcon *lspcon) DRM_DEBUG_KMS("LSPCON DP descriptor mismatch after resume\n"); } +static bool _lspcon_write_avi_infoframe_mca(struct drm_dp_aux *aux, + const uint8_t *buffer, ssize_t len) +{ + int ret; + uint32_t val = 0; + uint32_t retry; + uint16_t reg; + const uint8_t *data = buffer; + + reg = LSPCON_MCA_AVI_IF_WRITE_OFFSET; + while (val < len) { + /* DPCD write for AVI IF can fail on a slow FW day, so retry */ + for (retry = 0; retry < 5; retry++) { + ret = drm_dp_dpcd_write(aux, reg, (void *)data, 1); + if (ret == 1) { + break; + } else if (retry < 4) { + mdelay(50); + continue; + } else { + DRM_ERROR("DPCD write failed at:0x%x\n", reg); + return false; + } + } + val++; reg++; data++; + } + + val = 0; + reg = LSPCON_MCA_AVI_IF_CTRL; + ret = drm_dp_dpcd_read(aux, reg, &val, 1); + if (ret < 0) { + DRM_ERROR("DPCD read failed, address 0x%x\n", reg); + return false; + } + + /* Indicate LSPCON chip about infoframe, clear bit 1 and set bit 0 */ + val &= ~LSPCON_MCA_AVI_IF_HANDLED; + val |= LSPCON_MCA_AVI_IF_KICKOFF; + + ret = drm_dp_dpcd_write(aux, reg, &val, 1); + if (ret < 0) { + DRM_ERROR("DPCD read failed, address 0x%x\n", reg); + return false; + } + + val = 0; + ret = drm_dp_dpcd_read(aux, reg, &val, 1); + if (ret < 0) { + DRM_ERROR("DPCD read failed, address 0x%x\n", reg); + return false; + } + + if (val == LSPCON_MCA_AVI_IF_HANDLED) + DRM_DEBUG_KMS("AVI IF handled by FW\n"); + + return true; +} + +void lspcon_write_infoframe(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + unsigned int type, + const void *frame, ssize_t len) +{ + bool ret = true; + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + struct intel_lspcon *lspcon = enc_to_intel_lspcon(&encoder->base); + + /* LSPCON only needs AVI IF */ + if (type != HDMI_INFOFRAME_TYPE_AVI) + return; + + if (lspcon->vendor == LSPCON_VENDOR_MCA) + ret = _lspcon_write_avi_infoframe_mca(&intel_dp->aux, + frame, len); + if (!ret) { + DRM_ERROR("Failed to write AVI infoframes\n"); + return; + } + + DRM_DEBUG_DRIVER("AVI infoframes updated successfully\n"); +} + void lspcon_set_infoframes(struct intel_encoder *encoder, bool enable, const struct intel_crtc_state *crtc_state, -- cgit From 799a964ffe0b536e4c9f36991a6002c05c3140ae Mon Sep 17 00:00:00 2001 From: Shashank Sharma Date: Fri, 12 Oct 2018 11:53:13 +0530 Subject: drm/i915: Write AVI infoframes for Parade LSPCON MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Different LSPCON vendors specify their custom methods to pass AVI infoframes to the LSPCON chip, so does Parade tech. This patch adds functions to arrange and write AVI infoframes into Parade LSPCON chips. V2: rebase V3: Added r-b from Maarten V4: rebase V5: rebase V6: rebase V7: Fixed checkpatch warnings for alignment V8: Rebase V9: Rebase V10: Rebase Cc: Imre Deak Cc: Ville Syrjälä Cc: Maarten Lankhorst Reviewed-by: Maarten Lankhorst Signed-off-by: Shashank Sharma Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1539325394-20788-7-git-send-email-shashank.sharma@intel.com --- drivers/gpu/drm/i915/intel_lspcon.c | 117 +++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/intel_lspcon.c') diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c index b806803238d4..829c40abbde1 100644 --- a/drivers/gpu/drm/i915/intel_lspcon.c +++ b/drivers/gpu/drm/i915/intel_lspcon.c @@ -37,6 +37,12 @@ #define LSPCON_MCA_AVI_IF_KICKOFF (1 << 0) #define LSPCON_MCA_AVI_IF_HANDLED (1 << 1) +/* AUX addresses to write Parade AVI IF */ +#define LSPCON_PARADE_AVI_IF_WRITE_OFFSET 0x516 +#define LSPCON_PARADE_AVI_IF_CTRL 0x51E +#define LSPCON_PARADE_AVI_IF_KICKOFF (1 << 7) +#define LSPCON_PARADE_AVI_IF_DATA_SIZE 32 + static struct intel_dp *lspcon_to_intel_dp(struct intel_lspcon *lspcon) { struct intel_digital_port *dig_port = @@ -240,6 +246,111 @@ static void lspcon_resume_in_pcon_wa(struct intel_lspcon *lspcon) DRM_DEBUG_KMS("LSPCON DP descriptor mismatch after resume\n"); } +static bool lspcon_parade_fw_ready(struct drm_dp_aux *aux) +{ + u8 avi_if_ctrl; + u8 retry; + ssize_t ret; + + /* Check if LSPCON FW is ready for data */ + for (retry = 0; retry < 5; retry++) { + if (retry) + usleep_range(200, 300); + + ret = drm_dp_dpcd_read(aux, LSPCON_PARADE_AVI_IF_CTRL, + &avi_if_ctrl, 1); + if (ret < 0) { + DRM_ERROR("Failed to read AVI IF control\n"); + return false; + } + + if ((avi_if_ctrl & LSPCON_PARADE_AVI_IF_KICKOFF) == 0) + return true; + } + + DRM_ERROR("Parade FW not ready to accept AVI IF\n"); + return false; +} + +static bool _lspcon_parade_write_infoframe_blocks(struct drm_dp_aux *aux, + uint8_t *avi_buf) +{ + u8 avi_if_ctrl; + u8 block_count = 0; + u8 *data; + uint16_t reg; + ssize_t ret; + + while (block_count < 4) { + if (!lspcon_parade_fw_ready(aux)) { + DRM_DEBUG_KMS("LSPCON FW not ready, block %d\n", + block_count); + return false; + } + + reg = LSPCON_PARADE_AVI_IF_WRITE_OFFSET; + data = avi_buf + block_count * 8; + ret = drm_dp_dpcd_write(aux, reg, data, 8); + if (ret < 0) { + DRM_ERROR("Failed to write AVI IF block %d\n", + block_count); + return false; + } + + /* + * Once a block of data is written, we have to inform the FW + * about this by writing into avi infoframe control register: + * - set the kickoff bit[7] to 1 + * - write the block no. to bits[1:0] + */ + reg = LSPCON_PARADE_AVI_IF_CTRL; + avi_if_ctrl = LSPCON_PARADE_AVI_IF_KICKOFF | block_count; + ret = drm_dp_dpcd_write(aux, reg, &avi_if_ctrl, 1); + if (ret < 0) { + DRM_ERROR("Failed to update (0x%x), block %d\n", + reg, block_count); + return false; + } + + block_count++; + } + + DRM_DEBUG_KMS("Wrote AVI IF blocks successfully\n"); + return true; +} + +static bool _lspcon_write_avi_infoframe_parade(struct drm_dp_aux *aux, + const uint8_t *frame, + ssize_t len) +{ + uint8_t avi_if[LSPCON_PARADE_AVI_IF_DATA_SIZE] = {1, }; + + /* + * Parade's frames contains 32 bytes of data, divided + * into 4 frames: + * Token byte (first byte of first frame, must be non-zero) + * HB0 to HB2 from AVI IF (3 bytes header) + * PB0 to PB27 from AVI IF (28 bytes data) + * So it should look like this + * first block: | | + * next 3 blocks: |||| + */ + + if (len > LSPCON_PARADE_AVI_IF_DATA_SIZE - 1) { + DRM_ERROR("Invalid length of infoframes\n"); + return false; + } + + memcpy(&avi_if[1], frame, len); + + if (!_lspcon_parade_write_infoframe_blocks(aux, avi_if)) { + DRM_DEBUG_KMS("Failed to write infoframe blocks\n"); + return false; + } + + return true; +} + static bool _lspcon_write_avi_infoframe_mca(struct drm_dp_aux *aux, const uint8_t *buffer, ssize_t len) { @@ -303,7 +414,7 @@ void lspcon_write_infoframe(struct intel_encoder *encoder, unsigned int type, const void *frame, ssize_t len) { - bool ret = true; + bool ret; struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); struct intel_lspcon *lspcon = enc_to_intel_lspcon(&encoder->base); @@ -314,6 +425,10 @@ void lspcon_write_infoframe(struct intel_encoder *encoder, if (lspcon->vendor == LSPCON_VENDOR_MCA) ret = _lspcon_write_avi_infoframe_mca(&intel_dp->aux, frame, len); + else + ret = _lspcon_write_avi_infoframe_parade(&intel_dp->aux, + frame, len); + if (!ret) { DRM_ERROR("Failed to write AVI infoframes\n"); return; -- cgit From 668b6c176c33f443a50afd981cc9c0939e411b3b Mon Sep 17 00:00:00 2001 From: Shashank Sharma Date: Fri, 12 Oct 2018 11:53:14 +0530 Subject: drm/i915: Add YCBCR 4:2:0/4:4:4 support for LSPCON LSPCON chips can generate YCBCR outputs, if asked nicely :). In order to generate YCBCR 4:2:0 outputs, a source must: - send YCBCR 4:4:4 signals to LSPCON - program color space as 4:2:0 in AVI infoframes Whereas for YCBCR 4:4:4 outputs, the source must: - send YCBCR 4:4:4 signals to LSPCON - program color space as 4:4:4 in AVI infoframes So for both 4:2:0 as well as 4:4:4 outputs, we are driving the pipe for YCBCR 4:4:4 output, but AVI infoframe's color space information indicates LSPCON FW to start scaling down from YCBCR 4:4:4 and generate YCBCR 4:2:0 output. As the scaling is done by LSPCON device, we need not to reserve a scaler for 4:2:0 outputs. V2: rebase V3: Addressed review comments from Ville - add enum crtc_output_format instead of bool ycbcr420 - use crtc_output_format=4:4:4 for modeset of LSPCON 4:2:0 output cases in this way we will have YCBCR 4:4:4 framework ready (except the ABI part) V4: Added r-b from Maarten (for v3) Addressed review comments from Ville: - Do not add a non-atomic state variable to determine lspcon output. Instead add bool in CRTC state to indicate lspcon based scaling. V5: Addressed review comments from Ville: - Change the state bool name from external scaling to something more relavent. - Keep the info and adjusted_mode structures const. - use crtc_state instead of pipe_config. - Push all the config change into lspcon_ycbcr420_config function. V6: Rebase, small changes to accommodate changes in patch 2. V7: Fixed checkpatch warnings for alignment V8: Rebase PS: Ignored following warnings to match the current formatting: drm/i915: Add YCBCR 4:2:0/4:4:4 support for LSPCON -:53: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV) #53: FILE: drivers/gpu/drm/i915/i915_reg.h:8721: +#define TRANS_MSA_SAMPLING_444 (2<<1) ^ -:54: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV) #54: FILE: drivers/gpu/drm/i915/i915_reg.h:8722: +#define TRANS_MSA_CLRSP_YCBCR (2<<3) V9: Rebase V10: Rebase V11: Rebase Cc: Ville Syrjala Cc: Maarten Lankhorst Reviewed-by: Maarten Lankhorst Signed-off-by: Shashank Sharma Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1539325394-20788-8-git-send-email-shashank.sharma@intel.com --- drivers/gpu/drm/i915/intel_lspcon.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_lspcon.c') diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c index 829c40abbde1..fff32b31c7df 100644 --- a/drivers/gpu/drm/i915/intel_lspcon.c +++ b/drivers/gpu/drm/i915/intel_lspcon.c @@ -180,6 +180,21 @@ static bool lspcon_wake_native_aux_ch(struct intel_lspcon *lspcon) return true; } +void lspcon_ycbcr420_config(struct drm_connector *connector, + struct intel_crtc_state *crtc_state) +{ + const struct drm_display_info *info = &connector->display_info; + const struct drm_display_mode *adjusted_mode = + &crtc_state->base.adjusted_mode; + + if (drm_mode_is_420_only(info, adjusted_mode) && + connector->ycbcr_420_allowed) { + crtc_state->port_clock /= 2; + crtc_state->output_format = INTEL_OUTPUT_FORMAT_YCBCR444; + crtc_state->lspcon_downsampling = true; + } +} + static bool lspcon_probe(struct intel_lspcon *lspcon) { int retry; @@ -464,6 +479,15 @@ void lspcon_set_infoframes(struct intel_encoder *encoder, return; } + if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444) { + if (crtc_state->lspcon_downsampling) + frame.avi.colorspace = HDMI_COLORSPACE_YUV420; + else + frame.avi.colorspace = HDMI_COLORSPACE_YUV444; + } else { + frame.avi.colorspace = HDMI_COLORSPACE_RGB; + } + drm_hdmi_avi_infoframe_quant_range(&frame.avi, mode, crtc_state->limited_color_range ? HDMI_QUANTIZATION_RANGE_LIMITED : @@ -517,6 +541,7 @@ bool lspcon_init(struct intel_digital_port *intel_dig_port) struct intel_lspcon *lspcon = &intel_dig_port->lspcon; struct drm_device *dev = intel_dig_port->base.base.dev; struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_connector *connector = &dp->attached_connector->base; if (!HAS_LSPCON(dev_priv)) { DRM_ERROR("LSPCON is not supported on this platform\n"); @@ -541,6 +566,7 @@ bool lspcon_init(struct intel_digital_port *intel_dig_port) return false; } + connector->ycbcr_420_allowed = true; lspcon->active = true; DRM_DEBUG_KMS("Success: LSPCON init\n"); return true; -- cgit From 6bd36e0822ca841bbb21d050e80cd690209bd322 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 7 Nov 2018 19:18:21 +0200 Subject: drm/i915: Switch LSPCON to PCON mode if it's in LS mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We no longer change LSPCON into PCON mode if it boots up in LS mode. This was broken by some code shuffling in commit 96e35598cead ("drm/i915: Check LSPCON vendor OUI"). I actually can't see a reason why that code shuffling had to be done. The commit msg notes it but doesn't justify it in any way. But I guess we'll keep the code in its current place anyway and just make the "switch to PCON mode" part effective once again. Cc: Shashank Sharma Cc: Maarten Lankhorst Cc: Tvrtko Ursulin Tested-by: Tvrtko Ursulin Fixes: 96e35598cead ("drm/i915: Check LSPCON vendor OUI") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20181107171821.27862-1-ville.syrjala@linux.intel.com Reviewed-by: Shashank Sharma --- drivers/gpu/drm/i915/intel_lspcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/intel_lspcon.c') diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c index fff32b31c7df..96a8d9524b0c 100644 --- a/drivers/gpu/drm/i915/intel_lspcon.c +++ b/drivers/gpu/drm/i915/intel_lspcon.c @@ -230,7 +230,7 @@ static bool lspcon_probe(struct intel_lspcon *lspcon) * In this way, it will work with both HDMI 1.4 sinks as well as HDMI * 2.0 sinks. */ - if (lspcon->active && lspcon->mode != DRM_LSPCON_MODE_PCON) { + if (lspcon->mode != DRM_LSPCON_MODE_PCON) { if (lspcon_change_mode(lspcon, DRM_LSPCON_MODE_PCON) < 0) { DRM_ERROR("LSPCON mode change to PCON failed\n"); return false; -- cgit