diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 99cda88819c7..04705b62d4d0 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4399,34 +4399,39 @@ #define HSW_PWR_WELL_CTL6 0x45414 /* Per-pipe DDI Function Control */ -#define PIPE_DDI_FUNC_CTL_A 0x60400 -#define PIPE_DDI_FUNC_CTL_B 0x61400 -#define PIPE_DDI_FUNC_CTL_C 0x62400 -#define PIPE_DDI_FUNC_CTL_EDP 0x6F400 -#define DDI_FUNC_CTL(pipe) _PIPE(pipe, PIPE_DDI_FUNC_CTL_A, \ - PIPE_DDI_FUNC_CTL_B) -#define PIPE_DDI_FUNC_ENABLE (1<<31) +#define TRANS_DDI_FUNC_CTL_A 0x60400 +#define TRANS_DDI_FUNC_CTL_B 0x61400 +#define TRANS_DDI_FUNC_CTL_C 0x62400 +#define TRANS_DDI_FUNC_CTL_EDP 0x6F400 +#define TRANS_DDI_FUNC_CTL(tran) _TRANSCODER(tran, TRANS_DDI_FUNC_CTL_A, \ + TRANS_DDI_FUNC_CTL_B) +#define TRANS_DDI_FUNC_ENABLE (1<<31) /* Those bits are ignored by pipe EDP since it can only connect to DDI A */ -#define PIPE_DDI_PORT_MASK (7<<28) -#define PIPE_DDI_SELECT_PORT(x) ((x)<<28) -#define PIPE_DDI_PORT_NONE (0<<28) -#define PIPE_DDI_MODE_SELECT_MASK (7<<24) -#define PIPE_DDI_MODE_SELECT_HDMI (0<<24) -#define PIPE_DDI_MODE_SELECT_DVI (1<<24) -#define PIPE_DDI_MODE_SELECT_DP_SST (2<<24) -#define PIPE_DDI_MODE_SELECT_DP_MST (3<<24) -#define PIPE_DDI_MODE_SELECT_FDI (4<<24) -#define PIPE_DDI_BPC_MASK (7<<20) -#define PIPE_DDI_BPC_8 (0<<20) -#define PIPE_DDI_BPC_10 (1<<20) -#define PIPE_DDI_BPC_6 (2<<20) -#define PIPE_DDI_BPC_12 (3<<20) -#define PIPE_DDI_PVSYNC (1<<17) -#define PIPE_DDI_PHSYNC (1<<16) -#define PIPE_DDI_BFI_ENABLE (1<<4) -#define PIPE_DDI_PORT_WIDTH_X1 (0<<1) -#define PIPE_DDI_PORT_WIDTH_X2 (1<<1) -#define PIPE_DDI_PORT_WIDTH_X4 (3<<1) +#define TRANS_DDI_PORT_MASK (7<<28) +#define TRANS_DDI_SELECT_PORT(x) ((x)<<28) +#define TRANS_DDI_PORT_NONE (0<<28) +#define TRANS_DDI_MODE_SELECT_MASK (7<<24) +#define TRANS_DDI_MODE_SELECT_HDMI (0<<24) +#define TRANS_DDI_MODE_SELECT_DVI (1<<24) +#define TRANS_DDI_MODE_SELECT_DP_SST (2<<24) +#define TRANS_DDI_MODE_SELECT_DP_MST (3<<24) +#define TRANS_DDI_MODE_SELECT_FDI (4<<24) +#define TRANS_DDI_BPC_MASK (7<<20) +#define TRANS_DDI_BPC_8 (0<<20) +#define TRANS_DDI_BPC_10 (1<<20) +#define TRANS_DDI_BPC_6 (2<<20) +#define TRANS_DDI_BPC_12 (3<<20) +#define TRANS_DDI_PVSYNC (1<<17) +#define TRANS_DDI_PHSYNC (1<<16) +#define TRANS_DDI_EDP_INPUT_MASK (7<<12) +#define TRANS_DDI_EDP_INPUT_A_ON (0<<12) +#define TRANS_DDI_EDP_INPUT_A_ONOFF (4<<12) +#define TRANS_DDI_EDP_INPUT_B_ONOFF (5<<12) +#define TRANS_DDI_EDP_INPUT_C_ONOFF (6<<12) +#define TRANS_DDI_BFI_ENABLE (1<<4) +#define TRANS_DDI_PORT_WIDTH_X1 (0<<1) +#define TRANS_DDI_PORT_WIDTH_X2 (1<<1) +#define TRANS_DDI_PORT_WIDTH_X4 (3<<1) /* DisplayPort Transport Control */ #define DP_TP_CTL_A 0x64040 diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index f568862aca57..4b5366b9b04d 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -924,68 +924,69 @@ void intel_ddi_enable_pipe_func(struct drm_crtc *crtc) struct drm_encoder *encoder = &intel_encoder->base; struct drm_i915_private *dev_priv = crtc->dev->dev_private; enum pipe pipe = intel_crtc->pipe; + enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder; int type = intel_encoder->type; uint32_t temp; - /* Enable PIPE_DDI_FUNC_CTL for the pipe to work in HDMI mode */ - temp = PIPE_DDI_FUNC_ENABLE; + /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */ + temp = TRANS_DDI_FUNC_ENABLE; switch (intel_crtc->bpp) { case 18: - temp |= PIPE_DDI_BPC_6; + temp |= TRANS_DDI_BPC_6; break; case 24: - temp |= PIPE_DDI_BPC_8; + temp |= TRANS_DDI_BPC_8; break; case 30: - temp |= PIPE_DDI_BPC_10; + temp |= TRANS_DDI_BPC_10; break; case 36: - temp |= PIPE_DDI_BPC_12; + temp |= TRANS_DDI_BPC_12; break; default: - WARN(1, "%d bpp unsupported by pipe DDI function\n", + WARN(1, "%d bpp unsupported by transcoder DDI function\n", intel_crtc->bpp); } if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC) - temp |= PIPE_DDI_PVSYNC; + temp |= TRANS_DDI_PVSYNC; if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) - temp |= PIPE_DDI_PHSYNC; + temp |= TRANS_DDI_PHSYNC; if (type == INTEL_OUTPUT_HDMI) { struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); if (intel_hdmi->has_hdmi_sink) - temp |= PIPE_DDI_MODE_SELECT_HDMI; + temp |= TRANS_DDI_MODE_SELECT_HDMI; else - temp |= PIPE_DDI_MODE_SELECT_DVI; + temp |= TRANS_DDI_MODE_SELECT_DVI; - temp |= PIPE_DDI_SELECT_PORT(intel_hdmi->ddi_port); + temp |= TRANS_DDI_SELECT_PORT(intel_hdmi->ddi_port); } else if (type == INTEL_OUTPUT_ANALOG) { - temp |= PIPE_DDI_MODE_SELECT_FDI; - temp |= PIPE_DDI_SELECT_PORT(PORT_E); + temp |= TRANS_DDI_MODE_SELECT_FDI; + temp |= TRANS_DDI_SELECT_PORT(PORT_E); } else if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - temp |= PIPE_DDI_MODE_SELECT_DP_SST; - temp |= PIPE_DDI_SELECT_PORT(intel_dp->port); + temp |= TRANS_DDI_MODE_SELECT_DP_SST; + temp |= TRANS_DDI_SELECT_PORT(intel_dp->port); switch (intel_dp->lane_count) { case 1: - temp |= PIPE_DDI_PORT_WIDTH_X1; + temp |= TRANS_DDI_PORT_WIDTH_X1; break; case 2: - temp |= PIPE_DDI_PORT_WIDTH_X2; + temp |= TRANS_DDI_PORT_WIDTH_X2; break; case 4: - temp |= PIPE_DDI_PORT_WIDTH_X4; + temp |= TRANS_DDI_PORT_WIDTH_X4; break; default: - temp |= PIPE_DDI_PORT_WIDTH_X4; + temp |= TRANS_DDI_PORT_WIDTH_X4; WARN(1, "Unsupported lane count %d\n", intel_dp->lane_count); } @@ -995,17 +996,17 @@ void intel_ddi_enable_pipe_func(struct drm_crtc *crtc) intel_encoder->type, pipe); } - I915_WRITE(DDI_FUNC_CTL(pipe), temp); + I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp); } -void intel_ddi_disable_pipe_func(struct drm_i915_private *dev_priv, - enum pipe pipe) +void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv, + enum transcoder cpu_transcoder) { - uint32_t reg = DDI_FUNC_CTL(pipe); + uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder); uint32_t val = I915_READ(reg); - val &= ~(PIPE_DDI_FUNC_ENABLE | PIPE_DDI_PORT_MASK); - val |= PIPE_DDI_PORT_NONE; + val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK); + val |= TRANS_DDI_PORT_NONE; I915_WRITE(reg, val); } @@ -1023,13 +1024,32 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder, if (!(tmp & DDI_BUF_CTL_ENABLE)) return false; - for_each_pipe(i) { - tmp = I915_READ(DDI_FUNC_CTL(i)); + if (port == PORT_A) { + tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); - if ((tmp & PIPE_DDI_PORT_MASK) - == PIPE_DDI_SELECT_PORT(port)) { - *pipe = i; - return true; + switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { + case TRANS_DDI_EDP_INPUT_A_ON: + case TRANS_DDI_EDP_INPUT_A_ONOFF: + *pipe = PIPE_A; + break; + case TRANS_DDI_EDP_INPUT_B_ONOFF: + *pipe = PIPE_B; + break; + case TRANS_DDI_EDP_INPUT_C_ONOFF: + *pipe = PIPE_C; + break; + } + + return true; + } else { + for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) { + tmp = I915_READ(TRANS_DDI_FUNC_CTL(i)); + + if ((tmp & TRANS_DDI_PORT_MASK) + == TRANS_DDI_SELECT_PORT(port)) { + *pipe = i; + return true; + } } } @@ -1043,13 +1063,20 @@ static uint32_t intel_ddi_get_crtc_pll(struct drm_i915_private *dev_priv, { uint32_t temp, ret; enum port port; + enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, + pipe); int i; - temp = I915_READ(DDI_FUNC_CTL(pipe)); - temp &= PIPE_DDI_PORT_MASK; - for (i = PORT_A; i <= PORT_E; i++) - if (temp == PIPE_DDI_SELECT_PORT(i)) - port = i; + if (cpu_transcoder == TRANSCODER_EDP) { + port = PORT_A; + } else { + temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); + temp &= TRANS_DDI_PORT_MASK; + + for (i = PORT_B; i <= PORT_E; i++) + if (temp == TRANS_DDI_SELECT_PORT(i)) + port = i; + } ret = I915_READ(PORT_CLK_SEL(port)); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 74e7625b19dc..f51b5eee30c5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1122,12 +1122,14 @@ static void assert_fdi_tx(struct drm_i915_private *dev_priv, int reg; u32 val; bool cur_state; + enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, + pipe); if (IS_HASWELL(dev_priv->dev)) { /* On Haswell, DDI is used instead of FDI_TX_CTL */ - reg = DDI_FUNC_CTL(pipe); + reg = TRANS_DDI_FUNC_CTL(cpu_transcoder); val = I915_READ(reg); - cur_state = !!(val & PIPE_DDI_FUNC_ENABLE); + cur_state = !!(val & TRANS_DDI_FUNC_ENABLE); } else { reg = FDI_TX_CTL(pipe); val = I915_READ(reg); @@ -3435,6 +3437,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) struct intel_encoder *encoder; int pipe = intel_crtc->pipe; int plane = intel_crtc->plane; + enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder; bool is_pch_port; if (!intel_crtc->active) @@ -3456,7 +3459,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) intel_disable_pipe(dev_priv, pipe); - intel_ddi_disable_pipe_func(dev_priv, pipe); + intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder); /* Disable PF */ I915_WRITE(PF_CTL(pipe), 0); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 90e706c846a4..2ad70d744232 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -610,8 +610,8 @@ extern void intel_ddi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *adjusted_mode); extern void intel_ddi_pll_init(struct drm_device *dev); extern void intel_ddi_enable_pipe_func(struct drm_crtc *crtc); -extern void intel_ddi_disable_pipe_func(struct drm_i915_private *dev_priv, - enum pipe pipe); +extern void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv, + enum transcoder cpu_transcoder); extern void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc); extern void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc); extern void intel_ddi_setup_hw_pll_state(struct drm_device *dev);