From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> Currently we determine the location of the AUX registers in a confusing way. First we assume the PCH registers are used always, but then we override it for everything but HSW/BDW to use DP+0x10. Very confusing. Let's just make it straightforward and simply add a few functions to pick the right AUX_CTL based on the DP port. To deal with VLV/CHV we'll include the display_mmio_offset into the AUX register defines. Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_reg.h | 54 ++++++++--------- drivers/gpu/drm/i915/intel_dp.c | 124 ++++++++++++++++++++++++++++------------ 2 files changed, 113 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 57b9469..4e97bf2 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4182,33 +4182,33 @@ enum skl_disp_power_wells { * is 20 bytes in each direction, hence the 5 fixed * data registers */ -#define DPA_AUX_CH_CTL 0x64010 -#define DPA_AUX_CH_DATA1 0x64014 -#define DPA_AUX_CH_DATA2 0x64018 -#define DPA_AUX_CH_DATA3 0x6401c -#define DPA_AUX_CH_DATA4 0x64020 -#define DPA_AUX_CH_DATA5 0x64024 - -#define DPB_AUX_CH_CTL 0x64110 -#define DPB_AUX_CH_DATA1 0x64114 -#define DPB_AUX_CH_DATA2 0x64118 -#define DPB_AUX_CH_DATA3 0x6411c -#define DPB_AUX_CH_DATA4 0x64120 -#define DPB_AUX_CH_DATA5 0x64124 - -#define DPC_AUX_CH_CTL 0x64210 -#define DPC_AUX_CH_DATA1 0x64214 -#define DPC_AUX_CH_DATA2 0x64218 -#define DPC_AUX_CH_DATA3 0x6421c -#define DPC_AUX_CH_DATA4 0x64220 -#define DPC_AUX_CH_DATA5 0x64224 - -#define DPD_AUX_CH_CTL 0x64310 -#define DPD_AUX_CH_DATA1 0x64314 -#define DPD_AUX_CH_DATA2 0x64318 -#define DPD_AUX_CH_DATA3 0x6431c -#define DPD_AUX_CH_DATA4 0x64320 -#define DPD_AUX_CH_DATA5 0x64324 +#define DPA_AUX_CH_CTL (dev_priv->info.display_mmio_offset + 0x64010) +#define DPA_AUX_CH_DATA1 (dev_priv->info.display_mmio_offset + 0x64014) +#define DPA_AUX_CH_DATA2 (dev_priv->info.display_mmio_offset + 0x64018) +#define DPA_AUX_CH_DATA3 (dev_priv->info.display_mmio_offset + 0x6401c) +#define DPA_AUX_CH_DATA4 (dev_priv->info.display_mmio_offset + 0x64020) +#define DPA_AUX_CH_DATA5 (dev_priv->info.display_mmio_offset + 0x64024) + +#define DPB_AUX_CH_CTL (dev_priv->info.display_mmio_offset + 0x64110) +#define DPB_AUX_CH_DATA1 (dev_priv->info.display_mmio_offset + 0x64114) +#define DPB_AUX_CH_DATA2 (dev_priv->info.display_mmio_offset + 0x64118) +#define DPB_AUX_CH_DATA3 (dev_priv->info.display_mmio_offset + 0x6411c) +#define DPB_AUX_CH_DATA4 (dev_priv->info.display_mmio_offset + 0x64120) +#define DPB_AUX_CH_DATA5 (dev_priv->info.display_mmio_offset + 0x64124) + +#define DPC_AUX_CH_CTL (dev_priv->info.display_mmio_offset + 0x64210) +#define DPC_AUX_CH_DATA1 (dev_priv->info.display_mmio_offset + 0x64214) +#define DPC_AUX_CH_DATA2 (dev_priv->info.display_mmio_offset + 0x64218) +#define DPC_AUX_CH_DATA3 (dev_priv->info.display_mmio_offset + 0x6421c) +#define DPC_AUX_CH_DATA4 (dev_priv->info.display_mmio_offset + 0x64220) +#define DPC_AUX_CH_DATA5 (dev_priv->info.display_mmio_offset + 0x64224) + +#define DPD_AUX_CH_CTL (dev_priv->info.display_mmio_offset + 0x64310) +#define DPD_AUX_CH_DATA1 (dev_priv->info.display_mmio_offset + 0x64314) +#define DPD_AUX_CH_DATA2 (dev_priv->info.display_mmio_offset + 0x64318) +#define DPD_AUX_CH_DATA3 (dev_priv->info.display_mmio_offset + 0x6431c) +#define DPD_AUX_CH_DATA4 (dev_priv->info.display_mmio_offset + 0x64320) +#define DPD_AUX_CH_DATA5 (dev_priv->info.display_mmio_offset + 0x64324) #define DP_AUX_CH_CTL_SEND_BUSY (1 << 31) #define DP_AUX_CH_CTL_DONE (1 << 30) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 7e64555..bd8353f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -743,6 +743,7 @@ static uint32_t i9xx_get_aux_send_ctl(struct intel_dp *intel_dp, { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t precharge, timeout; if (IS_GEN6(dev)) @@ -1008,6 +1009,85 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) return ret; } +static uint32_t g4x_aux_ctl_reg(struct drm_i915_private *dev_priv, + enum port port) +{ + switch (port) { + case PORT_B: + return DPB_AUX_CH_CTL; + case PORT_C: + return DPC_AUX_CH_CTL; + case PORT_D: + return DPD_AUX_CH_CTL; + default: + MISSING_CASE(port); + return DPB_AUX_CH_CTL; + } +} + +static uint32_t ilk_aux_ctl_reg(struct drm_i915_private *dev_priv, + enum port port) +{ + switch (port) { + case PORT_A: + return DPA_AUX_CH_CTL; + case PORT_B: + return PCH_DPB_AUX_CH_CTL; + case PORT_C: + return PCH_DPC_AUX_CH_CTL; + case PORT_D: + return PCH_DPD_AUX_CH_CTL; + default: + MISSING_CASE(port); + return DPA_AUX_CH_CTL; + } +} + +/* + * On SKL we don't have Aux for port E so we rely + * on VBT to set a proper alternate aux channel. + */ +static enum port skl_porte_aux_port(struct drm_i915_private *dev_priv) +{ + const struct ddi_vbt_port_info *info = + &dev_priv->vbt.ddi_port_info[PORT_E]; + + switch (info->alternate_aux_channel) { + case DP_AUX_A: + return PORT_A; + case DP_AUX_B: + return PORT_B; + case DP_AUX_C: + return PORT_C; + case DP_AUX_D: + return PORT_D; + default: + MISSING_CASE(info->alternate_aux_channel); + return PORT_A; + } +} + +static uint32_t skl_aux_ctl_reg(struct drm_i915_private *dev_priv, + enum port port) +{ + if (port == PORT_E) + port = skl_porte_aux_port(dev_priv); + + switch (port) { + case PORT_A: + return DPA_AUX_CH_CTL; + case PORT_B: + return DPB_AUX_CH_CTL; + case PORT_C: + return DPC_AUX_CH_CTL; + case PORT_D: + return DPD_AUX_CH_CTL; + default: + MISSING_CASE(port); + return DPA_AUX_CH_CTL; + } +} + static void intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector) { @@ -1015,67 +1095,35 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); enum port port = intel_dig_port->port; - struct ddi_vbt_port_info *info = &dev_priv->vbt.ddi_port_info[port]; const char *name = NULL; - uint32_t porte_aux_ctl_reg = DPA_AUX_CH_CTL; int ret; - /* On SKL we don't have Aux for port E so we rely on VBT to set - * a proper alternate aux channel. - */ - if (IS_SKYLAKE(dev) && port == PORT_E) { - switch (info->alternate_aux_channel) { - case DP_AUX_B: - porte_aux_ctl_reg = DPB_AUX_CH_CTL; - break; - case DP_AUX_C: - porte_aux_ctl_reg = DPC_AUX_CH_CTL; - break; - case DP_AUX_D: - porte_aux_ctl_reg = DPD_AUX_CH_CTL; - break; - case DP_AUX_A: - default: - porte_aux_ctl_reg = DPA_AUX_CH_CTL; - } - } - switch (port) { case PORT_A: - intel_dp->aux_ch_ctl_reg = DPA_AUX_CH_CTL; name = "DPDDC-A"; break; case PORT_B: - intel_dp->aux_ch_ctl_reg = PCH_DPB_AUX_CH_CTL; name = "DPDDC-B"; break; case PORT_C: - intel_dp->aux_ch_ctl_reg = PCH_DPC_AUX_CH_CTL; name = "DPDDC-C"; break; case PORT_D: - intel_dp->aux_ch_ctl_reg = PCH_DPD_AUX_CH_CTL; name = "DPDDC-D"; break; case PORT_E: - intel_dp->aux_ch_ctl_reg = porte_aux_ctl_reg; name = "DPDDC-E"; break; default: BUG(); } - /* - * The AUX_CTL register is usually DP_CTL + 0x10. - * - * On Haswell and Broadwell though: - * - Both port A DDI_BUF_CTL and DDI_AUX_CTL are on the CPU - * - Port B/C/D AUX channels are on the PCH, DDI_BUF_CTL on the CPU - * - * Skylake moves AUX_CTL back next to DDI_BUF_CTL, on the CPU. - */ - if (!IS_HASWELL(dev) && !IS_BROADWELL(dev) && port != PORT_E) - intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10; + if (INTEL_INFO(dev_priv)->gen >= 9) + intel_dp->aux_ch_ctl_reg = skl_aux_ctl_reg(dev_priv, port); + else if (HAS_PCH_SPLIT(dev_priv)) + intel_dp->aux_ch_ctl_reg = ilk_aux_ctl_reg(dev_priv, port); + else + intel_dp->aux_ch_ctl_reg = g4x_aux_ctl_reg(dev_priv, port); intel_dp->aux.name = name; intel_dp->aux.dev = dev->dev; -- 2.4.6 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx