44,6 → 44,9 |
|
struct intel_crt { |
struct intel_encoder base; |
/* DPMS state is stored in the connector, which we need in the |
* encoder's enable/disable callbacks */ |
struct intel_connector *connector; |
bool force_hotplug_required; |
u32 adpa_reg; |
}; |
80,29 → 83,6 |
return true; |
} |
|
static void intel_disable_crt(struct intel_encoder *encoder) |
{ |
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
struct intel_crt *crt = intel_encoder_to_crt(encoder); |
u32 temp; |
|
temp = I915_READ(crt->adpa_reg); |
temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); |
temp &= ~ADPA_DAC_ENABLE; |
I915_WRITE(crt->adpa_reg, temp); |
} |
|
static void intel_enable_crt(struct intel_encoder *encoder) |
{ |
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
struct intel_crt *crt = intel_encoder_to_crt(encoder); |
u32 temp; |
|
temp = I915_READ(crt->adpa_reg); |
temp |= ADPA_DAC_ENABLE; |
I915_WRITE(crt->adpa_reg, temp); |
} |
|
/* Note: The caller is required to filter out dpms modes not supported by the |
* platform. */ |
static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode) |
134,6 → 114,19 |
I915_WRITE(crt->adpa_reg, temp); |
} |
|
static void intel_disable_crt(struct intel_encoder *encoder) |
{ |
intel_crt_set_dpms(encoder, DRM_MODE_DPMS_OFF); |
} |
|
static void intel_enable_crt(struct intel_encoder *encoder) |
{ |
struct intel_crt *crt = intel_encoder_to_crt(encoder); |
|
intel_crt_set_dpms(encoder, crt->connector->base.dpms); |
} |
|
|
static void intel_crt_dpms(struct drm_connector *connector, int mode) |
{ |
struct drm_device *dev = connector->dev; |
259,6 → 252,8 |
u32 adpa; |
bool ret; |
|
ENTER(); |
|
/* The first time through, trigger an explicit detection cycle */ |
if (crt->force_hotplug_required) { |
bool turn_off_dac = HAS_PCH_SPLIT(dev); |
266,7 → 261,7 |
|
crt->force_hotplug_required = 0; |
|
save_adpa = adpa = I915_READ(PCH_ADPA); |
save_adpa = adpa = I915_READ(crt->adpa_reg); |
DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa); |
|
adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER; |
273,20 → 268,20 |
if (turn_off_dac) |
adpa &= ~ADPA_DAC_ENABLE; |
|
I915_WRITE(PCH_ADPA, adpa); |
I915_WRITE(crt->adpa_reg, adpa); |
|
if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, |
if (wait_for((I915_READ(crt->adpa_reg) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, |
1000)) |
DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); |
|
if (turn_off_dac) { |
I915_WRITE(PCH_ADPA, save_adpa); |
POSTING_READ(PCH_ADPA); |
I915_WRITE(crt->adpa_reg, save_adpa); |
POSTING_READ(crt->adpa_reg); |
} |
} |
|
/* Check the status to see if both blue and green are on now */ |
adpa = I915_READ(PCH_ADPA); |
adpa = I915_READ(crt->adpa_reg); |
if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0) |
ret = true; |
else |
293,6 → 288,8 |
ret = false; |
DRM_DEBUG_KMS("ironlake hotplug adpa=0x%x, result %d\n", adpa, ret); |
|
LEAVE(); |
|
return ret; |
} |
|
299,26 → 296,29 |
static bool valleyview_crt_detect_hotplug(struct drm_connector *connector) |
{ |
struct drm_device *dev = connector->dev; |
struct intel_crt *crt = intel_attached_crt(connector); |
struct drm_i915_private *dev_priv = dev->dev_private; |
u32 adpa; |
bool ret; |
u32 save_adpa; |
|
save_adpa = adpa = I915_READ(ADPA); |
ENTER(); |
|
save_adpa = adpa = I915_READ(crt->adpa_reg); |
DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa); |
|
adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER; |
|
I915_WRITE(ADPA, adpa); |
I915_WRITE(crt->adpa_reg, adpa); |
|
if (wait_for((I915_READ(ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, |
if (wait_for((I915_READ(crt->adpa_reg) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, |
1000)) { |
DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); |
I915_WRITE(ADPA, save_adpa); |
I915_WRITE(crt->adpa_reg, save_adpa); |
} |
|
/* Check the status to see if both blue and green are on now */ |
adpa = I915_READ(ADPA); |
adpa = I915_READ(crt->adpa_reg); |
if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0) |
ret = true; |
else |
329,6 → 329,8 |
/* FIXME: debug force function and remove */ |
ret = true; |
|
LEAVE(); |
|
return ret; |
} |
|
348,6 → 350,8 |
bool ret = false; |
int i, tries = 0; |
|
ENTER(); |
|
if (HAS_PCH_SPLIT(dev)) |
return intel_ironlake_crt_detect_hotplug(connector); |
|
386,6 → 390,8 |
/* and put the bits back */ |
I915_WRITE(PORT_HOTPLUG_EN, orig); |
|
LEAVE(); |
|
return ret; |
} |
|
394,6 → 400,8 |
{ |
struct edid *edid; |
|
ENTER(); |
|
edid = drm_get_edid(connector, i2c); |
|
if (!edid && !intel_gmbus_is_forced_bit(i2c)) { |
403,6 → 411,8 |
intel_gmbus_force_bit(i2c, false); |
} |
|
LEAVE(); |
|
return edid; |
} |
|
664,11 → 674,11 |
if (HAS_PCH_SPLIT(dev)) { |
u32 adpa; |
|
adpa = I915_READ(PCH_ADPA); |
adpa = I915_READ(crt->adpa_reg); |
adpa &= ~ADPA_CRT_HOTPLUG_MASK; |
adpa |= ADPA_HOTPLUG_BITS; |
I915_WRITE(PCH_ADPA, adpa); |
POSTING_READ(PCH_ADPA); |
I915_WRITE(crt->adpa_reg, adpa); |
POSTING_READ(crt->adpa_reg); |
|
DRM_DEBUG_KMS("pch crt adpa set to 0x%x\n", adpa); |
crt->force_hotplug_required = 1; |
683,7 → 693,6 |
static const struct drm_encoder_helper_funcs crt_encoder_funcs = { |
.mode_fixup = intel_crt_mode_fixup, |
.mode_set = intel_crt_mode_set, |
.disable = intel_encoder_noop, |
}; |
|
static const struct drm_connector_funcs intel_crt_connector_funcs = { |
723,6 → 732,7 |
} |
|
connector = &intel_connector->base; |
crt->connector = intel_connector; |
drm_connector_init(dev, &intel_connector->base, |
&intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); |
|
753,7 → 763,7 |
|
crt->base.disable = intel_disable_crt; |
crt->base.enable = intel_enable_crt; |
if (IS_HASWELL(dev)) |
if (HAS_DDI(dev)) |
crt->base.get_hw_state = intel_ddi_get_hw_state; |
else |
crt->base.get_hw_state = intel_crt_get_hw_state; |
777,10 → 787,14 |
dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS; |
|
/* |
* TODO: find a proper way to discover whether we need to set the |
* polarity reversal bit or not, instead of relying on the BIOS. |
* TODO: find a proper way to discover whether we need to set the the |
* polarity and link reversal bits or not, instead of relying on the |
* BIOS. |
*/ |
if (HAS_PCH_LPT(dev)) |
dev_priv->fdi_rx_polarity_reversed = |
!!(I915_READ(_FDI_RXA_CTL) & FDI_RX_POLARITY_REVERSED_LPT); |
if (HAS_PCH_LPT(dev)) { |
u32 fdi_config = FDI_RX_POLARITY_REVERSED_LPT | |
FDI_RX_LINK_REVERSAL_OVERRIDE; |
|
dev_priv->fdi_rx_config = I915_READ(_FDI_RXA_CTL) & fdi_config; |
} |
} |