Merge tag 'drm-intel-next-fixes-2015-09-02' of git://anongit.freedesktop.org/drm-intel into drm-next
i915 display fixes headed for v4.3. Mostly SKL, but some regression fixes too. * tag 'drm-intel-next-fixes-2015-09-02' of git://anongit.freedesktop.org/drm-intel: i915: Set ddi_pll_sel in DP MST path drm/i915: Don't use link_bw for PLL setup drm/i915: Preserve SSC earlier drm/i915/skl: Adding DDI_E power well domain drm/i915: eDP can be present on DDI-E drm/i915/skl: Enable DDI-E drm/i915: Enable HDMI on DDI-E drm/i915: apply the PCI_D0/D3 hibernation workaround everywhere on pre GEN6 drm/i915: Check DP link status on long hpd too drm/i915: set CDCLK if DPLL0 enabled during resuming from S3
This commit is contained in:
commit
5b78cb6687
|
@ -2562,6 +2562,8 @@ static const char *power_domain_str(enum intel_display_power_domain domain)
|
|||
return "PORT_DDI_D_2_LANES";
|
||||
case POWER_DOMAIN_PORT_DDI_D_4_LANES:
|
||||
return "PORT_DDI_D_4_LANES";
|
||||
case POWER_DOMAIN_PORT_DDI_E_2_LANES:
|
||||
return "PORT_DDI_E_2_LANES";
|
||||
case POWER_DOMAIN_PORT_DSI:
|
||||
return "PORT_DSI";
|
||||
case POWER_DOMAIN_PORT_CRT:
|
||||
|
|
|
@ -662,15 +662,18 @@ static int i915_drm_suspend_late(struct drm_device *drm_dev, bool hibernation)
|
|||
|
||||
pci_disable_device(drm_dev->pdev);
|
||||
/*
|
||||
* During hibernation on some GEN4 platforms the BIOS may try to access
|
||||
* During hibernation on some platforms the BIOS may try to access
|
||||
* the device even though it's already in D3 and hang the machine. So
|
||||
* leave the device in D0 on those platforms and hope the BIOS will
|
||||
* power down the device properly. Platforms where this was seen:
|
||||
* Lenovo Thinkpad X301, X61s
|
||||
* power down the device properly. The issue was seen on multiple old
|
||||
* GENs with different BIOS vendors, so having an explicit blacklist
|
||||
* is inpractical; apply the workaround on everything pre GEN6. The
|
||||
* platforms where the issue was seen:
|
||||
* Lenovo Thinkpad X301, X61s, X60, T60, X41
|
||||
* Fujitsu FSC S7110
|
||||
* Acer Aspire 1830T
|
||||
*/
|
||||
if (!(hibernation &&
|
||||
drm_dev->pdev->subsystem_vendor == PCI_VENDOR_ID_LENOVO &&
|
||||
INTEL_INFO(dev_priv)->gen == 4))
|
||||
if (!(hibernation && INTEL_INFO(dev_priv)->gen < 6))
|
||||
pci_set_power_state(drm_dev->pdev, PCI_D3hot);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -182,6 +182,7 @@ enum intel_display_power_domain {
|
|||
POWER_DOMAIN_PORT_DDI_C_4_LANES,
|
||||
POWER_DOMAIN_PORT_DDI_D_2_LANES,
|
||||
POWER_DOMAIN_PORT_DDI_D_4_LANES,
|
||||
POWER_DOMAIN_PORT_DDI_E_2_LANES,
|
||||
POWER_DOMAIN_PORT_DSI,
|
||||
POWER_DOMAIN_PORT_CRT,
|
||||
POWER_DOMAIN_PORT_OTHER,
|
||||
|
@ -1416,6 +1417,10 @@ enum modeset_restore {
|
|||
#define DP_AUX_C 0x20
|
||||
#define DP_AUX_D 0x30
|
||||
|
||||
#define DDC_PIN_B 0x05
|
||||
#define DDC_PIN_C 0x04
|
||||
#define DDC_PIN_D 0x06
|
||||
|
||||
struct ddi_vbt_port_info {
|
||||
/*
|
||||
* This is an index in the HDMI/DVI DDI buffer translation table.
|
||||
|
@ -1430,6 +1435,7 @@ struct ddi_vbt_port_info {
|
|||
uint8_t supports_dp:1;
|
||||
|
||||
uint8_t alternate_aux_channel;
|
||||
uint8_t alternate_ddc_pin;
|
||||
|
||||
uint8_t dp_boost_level;
|
||||
uint8_t hdmi_boost_level;
|
||||
|
|
|
@ -905,23 +905,23 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
|
|||
uint8_t hdmi_level_shift;
|
||||
int i, j;
|
||||
bool is_dvi, is_hdmi, is_dp, is_edp, is_crt;
|
||||
uint8_t aux_channel;
|
||||
uint8_t aux_channel, ddc_pin;
|
||||
/* Each DDI port can have more than one value on the "DVO Port" field,
|
||||
* so look for all the possible values for each port and abort if more
|
||||
* than one is found. */
|
||||
int dvo_ports[][2] = {
|
||||
{DVO_PORT_HDMIA, DVO_PORT_DPA},
|
||||
{DVO_PORT_HDMIB, DVO_PORT_DPB},
|
||||
{DVO_PORT_HDMIC, DVO_PORT_DPC},
|
||||
{DVO_PORT_HDMID, DVO_PORT_DPD},
|
||||
{DVO_PORT_CRT, -1 /* Port E can only be DVO_PORT_CRT */ },
|
||||
int dvo_ports[][3] = {
|
||||
{DVO_PORT_HDMIA, DVO_PORT_DPA, -1},
|
||||
{DVO_PORT_HDMIB, DVO_PORT_DPB, -1},
|
||||
{DVO_PORT_HDMIC, DVO_PORT_DPC, -1},
|
||||
{DVO_PORT_HDMID, DVO_PORT_DPD, -1},
|
||||
{DVO_PORT_CRT, DVO_PORT_HDMIE, DVO_PORT_DPE},
|
||||
};
|
||||
|
||||
/* Find the child device to use, abort if more than one found. */
|
||||
for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
|
||||
it = dev_priv->vbt.child_dev + i;
|
||||
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
if (dvo_ports[port][j] == -1)
|
||||
break;
|
||||
|
||||
|
@ -939,6 +939,7 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
|
|||
return;
|
||||
|
||||
aux_channel = child->raw[25];
|
||||
ddc_pin = child->common.ddc_pin;
|
||||
|
||||
is_dvi = child->common.device_type & DEVICE_TYPE_TMDS_DVI_SIGNALING;
|
||||
is_dp = child->common.device_type & DEVICE_TYPE_DISPLAYPORT_OUTPUT;
|
||||
|
@ -970,11 +971,27 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
|
|||
DRM_DEBUG_KMS("Port %c is internal DP\n", port_name(port));
|
||||
|
||||
if (is_dvi) {
|
||||
if (child->common.ddc_pin == 0x05 && port != PORT_B)
|
||||
if (port == PORT_E) {
|
||||
info->alternate_ddc_pin = ddc_pin;
|
||||
/* if DDIE share ddc pin with other port, then
|
||||
* dvi/hdmi couldn't exist on the shared port.
|
||||
* Otherwise they share the same ddc bin and system
|
||||
* couldn't communicate with them seperately. */
|
||||
if (ddc_pin == DDC_PIN_B) {
|
||||
dev_priv->vbt.ddi_port_info[PORT_B].supports_dvi = 0;
|
||||
dev_priv->vbt.ddi_port_info[PORT_B].supports_hdmi = 0;
|
||||
} else if (ddc_pin == DDC_PIN_C) {
|
||||
dev_priv->vbt.ddi_port_info[PORT_C].supports_dvi = 0;
|
||||
dev_priv->vbt.ddi_port_info[PORT_C].supports_hdmi = 0;
|
||||
} else if (ddc_pin == DDC_PIN_D) {
|
||||
dev_priv->vbt.ddi_port_info[PORT_D].supports_dvi = 0;
|
||||
dev_priv->vbt.ddi_port_info[PORT_D].supports_hdmi = 0;
|
||||
}
|
||||
} else if (ddc_pin == DDC_PIN_B && port != PORT_B)
|
||||
DRM_DEBUG_KMS("Unexpected DDC pin for port B\n");
|
||||
if (child->common.ddc_pin == 0x04 && port != PORT_C)
|
||||
else if (ddc_pin == DDC_PIN_C && port != PORT_C)
|
||||
DRM_DEBUG_KMS("Unexpected DDC pin for port C\n");
|
||||
if (child->common.ddc_pin == 0x06 && port != PORT_D)
|
||||
else if (ddc_pin == DDC_PIN_D && port != PORT_D)
|
||||
DRM_DEBUG_KMS("Unexpected DDC pin for port D\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -758,11 +758,6 @@ int intel_parse_bios(struct drm_device *dev);
|
|||
#define DVO_C 2
|
||||
#define DVO_D 3
|
||||
|
||||
/* define the PORT for DP output type */
|
||||
#define PORT_IDPB 7
|
||||
#define PORT_IDPC 8
|
||||
#define PORT_IDPD 9
|
||||
|
||||
/* Possible values for the "DVO Port" field for versions >= 155: */
|
||||
#define DVO_PORT_HDMIA 0
|
||||
#define DVO_PORT_HDMIB 1
|
||||
|
@ -775,6 +770,8 @@ int intel_parse_bios(struct drm_device *dev);
|
|||
#define DVO_PORT_DPC 8
|
||||
#define DVO_PORT_DPD 9
|
||||
#define DVO_PORT_DPA 10
|
||||
#define DVO_PORT_DPE 11
|
||||
#define DVO_PORT_HDMIE 12
|
||||
#define DVO_PORT_MIPIA 21
|
||||
#define DVO_PORT_MIPIB 22
|
||||
#define DVO_PORT_MIPIC 23
|
||||
|
|
|
@ -1554,17 +1554,14 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc,
|
|||
DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
|
||||
wrpll_params.central_freq;
|
||||
} else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
|
||||
struct drm_encoder *encoder = &intel_encoder->base;
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
|
||||
switch (intel_dp->link_bw) {
|
||||
case DP_LINK_BW_1_62:
|
||||
switch (crtc_state->port_clock / 2) {
|
||||
case 81000:
|
||||
ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
|
||||
break;
|
||||
case DP_LINK_BW_2_7:
|
||||
case 135000:
|
||||
ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
|
||||
break;
|
||||
case DP_LINK_BW_5_4:
|
||||
case 270000:
|
||||
ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -5150,7 +5150,6 @@ static enum intel_display_power_domain port_to_power_domain(enum port port)
|
|||
{
|
||||
switch (port) {
|
||||
case PORT_A:
|
||||
case PORT_E:
|
||||
return POWER_DOMAIN_PORT_DDI_A_4_LANES;
|
||||
case PORT_B:
|
||||
return POWER_DOMAIN_PORT_DDI_B_4_LANES;
|
||||
|
@ -5158,6 +5157,8 @@ static enum intel_display_power_domain port_to_power_domain(enum port port)
|
|||
return POWER_DOMAIN_PORT_DDI_C_4_LANES;
|
||||
case PORT_D:
|
||||
return POWER_DOMAIN_PORT_DDI_D_4_LANES;
|
||||
case PORT_E:
|
||||
return POWER_DOMAIN_PORT_DDI_E_2_LANES;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
return POWER_DOMAIN_PORT_OTHER;
|
||||
|
@ -5712,16 +5713,13 @@ void skl_init_cdclk(struct drm_i915_private *dev_priv)
|
|||
/* enable PG1 and Misc I/O */
|
||||
intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
|
||||
|
||||
/* DPLL0 already enabed !? */
|
||||
if (I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE) {
|
||||
DRM_DEBUG_DRIVER("DPLL0 already running\n");
|
||||
return;
|
||||
/* DPLL0 not enabled (happens on early BIOS versions) */
|
||||
if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE)) {
|
||||
/* enable DPLL0 */
|
||||
required_vco = skl_cdclk_get_vco(dev_priv->skl_boot_cdclk);
|
||||
skl_dpll0_enable(dev_priv, required_vco);
|
||||
}
|
||||
|
||||
/* enable DPLL0 */
|
||||
required_vco = skl_cdclk_get_vco(dev_priv->skl_boot_cdclk);
|
||||
skl_dpll0_enable(dev_priv, required_vco);
|
||||
|
||||
/* set CDCLK to the frequency the BIOS chose */
|
||||
skl_set_cdclk(dev_priv, dev_priv->skl_boot_cdclk);
|
||||
|
||||
|
@ -13963,6 +13961,15 @@ static void intel_setup_outputs(struct drm_device *dev)
|
|||
intel_ddi_init(dev, PORT_C);
|
||||
if (found & SFUSE_STRAP_DDID_DETECTED)
|
||||
intel_ddi_init(dev, PORT_D);
|
||||
/*
|
||||
* On SKL we don't have a way to detect DDI-E so we rely on VBT.
|
||||
*/
|
||||
if (IS_SKYLAKE(dev) &&
|
||||
(dev_priv->vbt.ddi_port_info[PORT_E].supports_dp ||
|
||||
dev_priv->vbt.ddi_port_info[PORT_E].supports_dvi ||
|
||||
dev_priv->vbt.ddi_port_info[PORT_E].supports_hdmi))
|
||||
intel_ddi_init(dev, PORT_E);
|
||||
|
||||
} else if (HAS_PCH_SPLIT(dev)) {
|
||||
int found;
|
||||
dpd_is_edp = intel_dp_is_edp(dev, PORT_D);
|
||||
|
@ -14733,6 +14740,24 @@ void intel_modeset_init(struct drm_device *dev)
|
|||
if (INTEL_INFO(dev)->num_pipes == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* There may be no VBT; and if the BIOS enabled SSC we can
|
||||
* just keep using it to avoid unnecessary flicker. Whereas if the
|
||||
* BIOS isn't using it, don't assume it will work even if the VBT
|
||||
* indicates as much.
|
||||
*/
|
||||
if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
|
||||
bool bios_lvds_use_ssc = !!(I915_READ(PCH_DREF_CONTROL) &
|
||||
DREF_SSC1_ENABLE);
|
||||
|
||||
if (dev_priv->vbt.lvds_use_ssc != bios_lvds_use_ssc) {
|
||||
DRM_DEBUG_KMS("SSC %sabled by BIOS, overriding VBT which says %sabled\n",
|
||||
bios_lvds_use_ssc ? "en" : "dis",
|
||||
dev_priv->vbt.lvds_use_ssc ? "en" : "dis");
|
||||
dev_priv->vbt.lvds_use_ssc = bios_lvds_use_ssc;
|
||||
}
|
||||
}
|
||||
|
||||
intel_init_display(dev);
|
||||
intel_init_audio(dev);
|
||||
|
||||
|
@ -15292,7 +15317,6 @@ void intel_display_resume(struct drm_device *dev)
|
|||
|
||||
void intel_modeset_gem_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct drm_crtc *c;
|
||||
struct drm_i915_gem_object *obj;
|
||||
int ret;
|
||||
|
@ -15301,16 +15325,6 @@ void intel_modeset_gem_init(struct drm_device *dev)
|
|||
intel_init_gt_powersave(dev);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
/*
|
||||
* There may be no VBT; and if the BIOS enabled SSC we can
|
||||
* just keep using it to avoid unnecessary flicker. Whereas if the
|
||||
* BIOS isn't using it, don't assume it will work even if the VBT
|
||||
* indicates as much.
|
||||
*/
|
||||
if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
|
||||
dev_priv->vbt.lvds_use_ssc = !!(I915_READ(PCH_DREF_CONTROL) &
|
||||
DREF_SSC1_ENABLE);
|
||||
|
||||
intel_modeset_init_hw(dev);
|
||||
|
||||
intel_setup_overlay(dev);
|
||||
|
|
|
@ -48,28 +48,28 @@
|
|||
#define INTEL_DP_RESOLUTION_FAILSAFE (3 << INTEL_DP_RESOLUTION_SHIFT_MASK)
|
||||
|
||||
struct dp_link_dpll {
|
||||
int link_bw;
|
||||
int clock;
|
||||
struct dpll dpll;
|
||||
};
|
||||
|
||||
static const struct dp_link_dpll gen4_dpll[] = {
|
||||
{ DP_LINK_BW_1_62,
|
||||
{ 162000,
|
||||
{ .p1 = 2, .p2 = 10, .n = 2, .m1 = 23, .m2 = 8 } },
|
||||
{ DP_LINK_BW_2_7,
|
||||
{ 270000,
|
||||
{ .p1 = 1, .p2 = 10, .n = 1, .m1 = 14, .m2 = 2 } }
|
||||
};
|
||||
|
||||
static const struct dp_link_dpll pch_dpll[] = {
|
||||
{ DP_LINK_BW_1_62,
|
||||
{ 162000,
|
||||
{ .p1 = 2, .p2 = 10, .n = 1, .m1 = 12, .m2 = 9 } },
|
||||
{ DP_LINK_BW_2_7,
|
||||
{ 270000,
|
||||
{ .p1 = 1, .p2 = 10, .n = 2, .m1 = 14, .m2 = 8 } }
|
||||
};
|
||||
|
||||
static const struct dp_link_dpll vlv_dpll[] = {
|
||||
{ DP_LINK_BW_1_62,
|
||||
{ 162000,
|
||||
{ .p1 = 3, .p2 = 2, .n = 5, .m1 = 3, .m2 = 81 } },
|
||||
{ DP_LINK_BW_2_7,
|
||||
{ 270000,
|
||||
{ .p1 = 2, .p2 = 2, .n = 1, .m1 = 2, .m2 = 27 } }
|
||||
};
|
||||
|
||||
|
@ -83,11 +83,11 @@ static const struct dp_link_dpll chv_dpll[] = {
|
|||
* m2 is stored in fixed point format using formula below
|
||||
* (m2_int << 22) | m2_fraction
|
||||
*/
|
||||
{ DP_LINK_BW_1_62, /* m2_int = 32, m2_fraction = 1677722 */
|
||||
{ 162000, /* m2_int = 32, m2_fraction = 1677722 */
|
||||
{ .p1 = 4, .p2 = 2, .n = 1, .m1 = 2, .m2 = 0x819999a } },
|
||||
{ DP_LINK_BW_2_7, /* m2_int = 27, m2_fraction = 0 */
|
||||
{ 270000, /* m2_int = 27, m2_fraction = 0 */
|
||||
{ .p1 = 4, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c00000 } },
|
||||
{ DP_LINK_BW_5_4, /* m2_int = 27, m2_fraction = 0 */
|
||||
{ 540000, /* m2_int = 27, m2_fraction = 0 */
|
||||
{ .p1 = 2, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c00000 } }
|
||||
};
|
||||
|
||||
|
@ -1130,7 +1130,7 @@ intel_dp_connector_unregister(struct intel_connector *intel_connector)
|
|||
}
|
||||
|
||||
static void
|
||||
skl_edp_set_pll_config(struct intel_crtc_state *pipe_config, int link_clock)
|
||||
skl_edp_set_pll_config(struct intel_crtc_state *pipe_config)
|
||||
{
|
||||
u32 ctrl1;
|
||||
|
||||
|
@ -1142,7 +1142,7 @@ skl_edp_set_pll_config(struct intel_crtc_state *pipe_config, int link_clock)
|
|||
pipe_config->dpll_hw_state.cfgcr2 = 0;
|
||||
|
||||
ctrl1 = DPLL_CTRL1_OVERRIDE(SKL_DPLL0);
|
||||
switch (link_clock / 2) {
|
||||
switch (pipe_config->port_clock / 2) {
|
||||
case 81000:
|
||||
ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810,
|
||||
SKL_DPLL0);
|
||||
|
@ -1175,20 +1175,20 @@ skl_edp_set_pll_config(struct intel_crtc_state *pipe_config, int link_clock)
|
|||
pipe_config->dpll_hw_state.ctrl1 = ctrl1;
|
||||
}
|
||||
|
||||
static void
|
||||
hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config, int link_bw)
|
||||
void
|
||||
hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config)
|
||||
{
|
||||
memset(&pipe_config->dpll_hw_state, 0,
|
||||
sizeof(pipe_config->dpll_hw_state));
|
||||
|
||||
switch (link_bw) {
|
||||
case DP_LINK_BW_1_62:
|
||||
switch (pipe_config->port_clock / 2) {
|
||||
case 81000:
|
||||
pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_810;
|
||||
break;
|
||||
case DP_LINK_BW_2_7:
|
||||
case 135000:
|
||||
pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_1350;
|
||||
break;
|
||||
case DP_LINK_BW_5_4:
|
||||
case 270000:
|
||||
pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_2700;
|
||||
break;
|
||||
}
|
||||
|
@ -1245,7 +1245,7 @@ intel_dp_source_rates(struct drm_device *dev, const int **source_rates)
|
|||
|
||||
static void
|
||||
intel_dp_set_clock(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config, int link_bw)
|
||||
struct intel_crtc_state *pipe_config)
|
||||
{
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
const struct dp_link_dpll *divisor = NULL;
|
||||
|
@ -1267,7 +1267,7 @@ intel_dp_set_clock(struct intel_encoder *encoder,
|
|||
|
||||
if (divisor && count) {
|
||||
for (i = 0; i < count; i++) {
|
||||
if (link_bw == divisor[i].link_bw) {
|
||||
if (pipe_config->port_clock == divisor[i].clock) {
|
||||
pipe_config->dpll = divisor[i].dpll;
|
||||
pipe_config->clock_set = true;
|
||||
break;
|
||||
|
@ -1544,13 +1544,13 @@ intel_dp_compute_config(struct intel_encoder *encoder,
|
|||
}
|
||||
|
||||
if (IS_SKYLAKE(dev) && is_edp(intel_dp))
|
||||
skl_edp_set_pll_config(pipe_config, common_rates[clock]);
|
||||
skl_edp_set_pll_config(pipe_config);
|
||||
else if (IS_BROXTON(dev))
|
||||
/* handled in ddi */;
|
||||
else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
|
||||
hsw_dp_set_ddi_pll_sel(pipe_config, intel_dp->link_bw);
|
||||
hsw_dp_set_ddi_pll_sel(pipe_config);
|
||||
else
|
||||
intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
|
||||
intel_dp_set_clock(encoder, pipe_config);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -4961,9 +4961,12 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
|
|||
|
||||
intel_dp_probe_oui(intel_dp);
|
||||
|
||||
if (!intel_dp_probe_mst(intel_dp))
|
||||
if (!intel_dp_probe_mst(intel_dp)) {
|
||||
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
|
||||
intel_dp_check_link_status(intel_dp);
|
||||
drm_modeset_unlock(&dev->mode_config.connection_mutex);
|
||||
goto mst_fail;
|
||||
|
||||
}
|
||||
} else {
|
||||
if (intel_dp->is_mst) {
|
||||
if (intel_dp_check_mst_status(intel_dp) == -EINVAL)
|
||||
|
@ -4971,10 +4974,6 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
|
|||
}
|
||||
|
||||
if (!intel_dp->is_mst) {
|
||||
/*
|
||||
* we'll check the link status via the normal hot plug path later -
|
||||
* but for short hpds we should check it now
|
||||
*/
|
||||
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
|
||||
intel_dp_check_link_status(intel_dp);
|
||||
drm_modeset_unlock(&dev->mode_config.connection_mutex);
|
||||
|
@ -5016,16 +5015,17 @@ intel_trans_dp_port_sel(struct drm_crtc *crtc)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* check the VBT to see whether the eDP is on DP-D port */
|
||||
/* check the VBT to see whether the eDP is on another port */
|
||||
bool intel_dp_is_edp(struct drm_device *dev, enum port port)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
union child_device_config *p_child;
|
||||
int i;
|
||||
static const short port_mapping[] = {
|
||||
[PORT_B] = PORT_IDPB,
|
||||
[PORT_C] = PORT_IDPC,
|
||||
[PORT_D] = PORT_IDPD,
|
||||
[PORT_B] = DVO_PORT_DPB,
|
||||
[PORT_C] = DVO_PORT_DPC,
|
||||
[PORT_D] = DVO_PORT_DPD,
|
||||
[PORT_E] = DVO_PORT_DPE,
|
||||
};
|
||||
|
||||
if (port == PORT_A)
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config)
|
||||
{
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
|
||||
struct intel_digital_port *intel_dig_port = intel_mst->primary;
|
||||
struct intel_dp *intel_dp = &intel_dig_port->dp;
|
||||
|
@ -97,6 +98,10 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
|
|||
&pipe_config->dp_m_n);
|
||||
|
||||
pipe_config->dp_m_n.tu = slots;
|
||||
|
||||
if (IS_HASWELL(dev) || IS_BROADWELL(dev))
|
||||
hsw_dp_set_ddi_pll_sel(pipe_config);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
|
|
@ -1185,6 +1185,7 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp);
|
|||
void intel_edp_drrs_invalidate(struct drm_device *dev,
|
||||
unsigned frontbuffer_bits);
|
||||
void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits);
|
||||
void hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config);
|
||||
|
||||
/* intel_dp_mst.c */
|
||||
int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
|
||||
|
|
|
@ -1958,6 +1958,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
|
|||
struct drm_device *dev = intel_encoder->base.dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
enum port port = intel_dig_port->port;
|
||||
uint8_t alternate_ddc_pin;
|
||||
|
||||
drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_HDMIA);
|
||||
|
@ -1991,6 +1992,26 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
|
|||
intel_hdmi->ddc_bus = GMBUS_PIN_DPD;
|
||||
intel_encoder->hpd_pin = HPD_PORT_D;
|
||||
break;
|
||||
case PORT_E:
|
||||
/* On SKL PORT E doesn't have seperate GMBUS pin
|
||||
* We rely on VBT to set a proper alternate GMBUS pin. */
|
||||
alternate_ddc_pin =
|
||||
dev_priv->vbt.ddi_port_info[PORT_E].alternate_ddc_pin;
|
||||
switch (alternate_ddc_pin) {
|
||||
case DDC_PIN_B:
|
||||
intel_hdmi->ddc_bus = GMBUS_PIN_DPB;
|
||||
break;
|
||||
case DDC_PIN_C:
|
||||
intel_hdmi->ddc_bus = GMBUS_PIN_DPC;
|
||||
break;
|
||||
case DDC_PIN_D:
|
||||
intel_hdmi->ddc_bus = GMBUS_PIN_DPD;
|
||||
break;
|
||||
default:
|
||||
MISSING_CASE(alternate_ddc_pin);
|
||||
}
|
||||
intel_encoder->hpd_pin = HPD_PORT_E;
|
||||
break;
|
||||
case PORT_A:
|
||||
intel_encoder->hpd_pin = HPD_PORT_A;
|
||||
/* Internal port only for eDP. */
|
||||
|
|
|
@ -297,6 +297,7 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
|
|||
BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
|
||||
BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) | \
|
||||
BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \
|
||||
BIT(POWER_DOMAIN_PORT_DDI_E_2_LANES) | \
|
||||
BIT(POWER_DOMAIN_AUX_B) | \
|
||||
BIT(POWER_DOMAIN_AUX_C) | \
|
||||
BIT(POWER_DOMAIN_AUX_D) | \
|
||||
|
@ -316,6 +317,7 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
|
|||
#define SKL_DISPLAY_DDI_A_E_POWER_DOMAINS ( \
|
||||
BIT(POWER_DOMAIN_PORT_DDI_A_2_LANES) | \
|
||||
BIT(POWER_DOMAIN_PORT_DDI_A_4_LANES) | \
|
||||
BIT(POWER_DOMAIN_PORT_DDI_E_2_LANES) | \
|
||||
BIT(POWER_DOMAIN_INIT))
|
||||
#define SKL_DISPLAY_DDI_B_POWER_DOMAINS ( \
|
||||
BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \
|
||||
|
|
Loading…
Reference in New Issue