drm/i915: add port power domains
Parts that poke port specific HW blocks like the encoder HW state readout or connector hotplug detect code need a way to check whether required power domains are on or enable/disable these. For this purpose add a set of power domains that refer to the port HW blocks. Get the proper port power domains during modeset. For now when requesting the power domain for a DDI port get it for a 4 lane configuration. This can be optimized later to request only the 2 lane power domain, when proper support is added on the VLV PHY side for this. Atm, the PHY setup code assumes a 4 lane config in all cases. Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
a45f4466e4
commit
319be8ae8a
|
@ -2048,6 +2048,28 @@ static const char *power_domain_str(enum intel_display_power_domain domain)
|
||||||
return "TRANSCODER_C";
|
return "TRANSCODER_C";
|
||||||
case POWER_DOMAIN_TRANSCODER_EDP:
|
case POWER_DOMAIN_TRANSCODER_EDP:
|
||||||
return "TRANSCODER_EDP";
|
return "TRANSCODER_EDP";
|
||||||
|
case POWER_DOMAIN_PORT_DDI_A_2_LANES:
|
||||||
|
return "PORT_DDI_A_2_LANES";
|
||||||
|
case POWER_DOMAIN_PORT_DDI_A_4_LANES:
|
||||||
|
return "PORT_DDI_A_4_LANES";
|
||||||
|
case POWER_DOMAIN_PORT_DDI_B_2_LANES:
|
||||||
|
return "PORT_DDI_B_2_LANES";
|
||||||
|
case POWER_DOMAIN_PORT_DDI_B_4_LANES:
|
||||||
|
return "PORT_DDI_B_4_LANES";
|
||||||
|
case POWER_DOMAIN_PORT_DDI_C_2_LANES:
|
||||||
|
return "PORT_DDI_C_2_LANES";
|
||||||
|
case POWER_DOMAIN_PORT_DDI_C_4_LANES:
|
||||||
|
return "PORT_DDI_C_4_LANES";
|
||||||
|
case POWER_DOMAIN_PORT_DDI_D_2_LANES:
|
||||||
|
return "PORT_DDI_D_2_LANES";
|
||||||
|
case POWER_DOMAIN_PORT_DDI_D_4_LANES:
|
||||||
|
return "PORT_DDI_D_4_LANES";
|
||||||
|
case POWER_DOMAIN_PORT_DSI:
|
||||||
|
return "PORT_DSI";
|
||||||
|
case POWER_DOMAIN_PORT_CRT:
|
||||||
|
return "PORT_CRT";
|
||||||
|
case POWER_DOMAIN_PORT_OTHER:
|
||||||
|
return "PORT_OTHER";
|
||||||
case POWER_DOMAIN_VGA:
|
case POWER_DOMAIN_VGA:
|
||||||
return "VGA";
|
return "VGA";
|
||||||
case POWER_DOMAIN_AUDIO:
|
case POWER_DOMAIN_AUDIO:
|
||||||
|
|
|
@ -114,6 +114,17 @@ enum intel_display_power_domain {
|
||||||
POWER_DOMAIN_TRANSCODER_B,
|
POWER_DOMAIN_TRANSCODER_B,
|
||||||
POWER_DOMAIN_TRANSCODER_C,
|
POWER_DOMAIN_TRANSCODER_C,
|
||||||
POWER_DOMAIN_TRANSCODER_EDP,
|
POWER_DOMAIN_TRANSCODER_EDP,
|
||||||
|
POWER_DOMAIN_PORT_DDI_A_2_LANES,
|
||||||
|
POWER_DOMAIN_PORT_DDI_A_4_LANES,
|
||||||
|
POWER_DOMAIN_PORT_DDI_B_2_LANES,
|
||||||
|
POWER_DOMAIN_PORT_DDI_B_4_LANES,
|
||||||
|
POWER_DOMAIN_PORT_DDI_C_2_LANES,
|
||||||
|
POWER_DOMAIN_PORT_DDI_C_4_LANES,
|
||||||
|
POWER_DOMAIN_PORT_DDI_D_2_LANES,
|
||||||
|
POWER_DOMAIN_PORT_DDI_D_4_LANES,
|
||||||
|
POWER_DOMAIN_PORT_DSI,
|
||||||
|
POWER_DOMAIN_PORT_CRT,
|
||||||
|
POWER_DOMAIN_PORT_OTHER,
|
||||||
POWER_DOMAIN_VGA,
|
POWER_DOMAIN_VGA,
|
||||||
POWER_DOMAIN_AUDIO,
|
POWER_DOMAIN_AUDIO,
|
||||||
POWER_DOMAIN_INIT,
|
POWER_DOMAIN_INIT,
|
||||||
|
|
|
@ -3962,9 +3962,49 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc)
|
||||||
for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \
|
for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \
|
||||||
if ((1 << (domain)) & (mask))
|
if ((1 << (domain)) & (mask))
|
||||||
|
|
||||||
static unsigned long get_pipe_power_domains(struct drm_device *dev,
|
enum intel_display_power_domain
|
||||||
enum pipe pipe, bool pfit_enabled)
|
intel_display_port_power_domain(struct intel_encoder *intel_encoder)
|
||||||
{
|
{
|
||||||
|
struct drm_device *dev = intel_encoder->base.dev;
|
||||||
|
struct intel_digital_port *intel_dig_port;
|
||||||
|
|
||||||
|
switch (intel_encoder->type) {
|
||||||
|
case INTEL_OUTPUT_UNKNOWN:
|
||||||
|
/* Only DDI platforms should ever use this output type */
|
||||||
|
WARN_ON_ONCE(!HAS_DDI(dev));
|
||||||
|
case INTEL_OUTPUT_DISPLAYPORT:
|
||||||
|
case INTEL_OUTPUT_HDMI:
|
||||||
|
case INTEL_OUTPUT_EDP:
|
||||||
|
intel_dig_port = enc_to_dig_port(&intel_encoder->base);
|
||||||
|
switch (intel_dig_port->port) {
|
||||||
|
case PORT_A:
|
||||||
|
return POWER_DOMAIN_PORT_DDI_A_4_LANES;
|
||||||
|
case PORT_B:
|
||||||
|
return POWER_DOMAIN_PORT_DDI_B_4_LANES;
|
||||||
|
case PORT_C:
|
||||||
|
return POWER_DOMAIN_PORT_DDI_C_4_LANES;
|
||||||
|
case PORT_D:
|
||||||
|
return POWER_DOMAIN_PORT_DDI_D_4_LANES;
|
||||||
|
default:
|
||||||
|
WARN_ON_ONCE(1);
|
||||||
|
return POWER_DOMAIN_PORT_OTHER;
|
||||||
|
}
|
||||||
|
case INTEL_OUTPUT_ANALOG:
|
||||||
|
return POWER_DOMAIN_PORT_CRT;
|
||||||
|
case INTEL_OUTPUT_DSI:
|
||||||
|
return POWER_DOMAIN_PORT_DSI;
|
||||||
|
default:
|
||||||
|
return POWER_DOMAIN_PORT_OTHER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
|
||||||
|
{
|
||||||
|
struct drm_device *dev = crtc->dev;
|
||||||
|
struct intel_encoder *intel_encoder;
|
||||||
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||||
|
enum pipe pipe = intel_crtc->pipe;
|
||||||
|
bool pfit_enabled = intel_crtc->config.pch_pfit.enabled;
|
||||||
unsigned long mask;
|
unsigned long mask;
|
||||||
enum transcoder transcoder;
|
enum transcoder transcoder;
|
||||||
|
|
||||||
|
@ -3975,6 +4015,9 @@ static unsigned long get_pipe_power_domains(struct drm_device *dev,
|
||||||
if (pfit_enabled)
|
if (pfit_enabled)
|
||||||
mask |= BIT(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
|
mask |= BIT(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
|
||||||
|
|
||||||
|
for_each_encoder_on_crtc(dev, crtc, intel_encoder)
|
||||||
|
mask |= BIT(intel_display_port_power_domain(intel_encoder));
|
||||||
|
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4008,9 +4051,7 @@ static void modeset_update_crtc_power_domains(struct drm_device *dev)
|
||||||
if (!crtc->base.enabled)
|
if (!crtc->base.enabled)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pipe_domains[crtc->pipe] = get_pipe_power_domains(dev,
|
pipe_domains[crtc->pipe] = get_crtc_power_domains(&crtc->base);
|
||||||
crtc->pipe,
|
|
||||||
crtc->config.pch_pfit.enabled);
|
|
||||||
|
|
||||||
for_each_power_domain(domain, pipe_domains[crtc->pipe])
|
for_each_power_domain(domain, pipe_domains[crtc->pipe])
|
||||||
intel_display_power_get(dev_priv, domain);
|
intel_display_power_get(dev_priv, domain);
|
||||||
|
|
|
@ -733,6 +733,8 @@ bool intel_crtc_active(struct drm_crtc *crtc);
|
||||||
void hsw_enable_ips(struct intel_crtc *crtc);
|
void hsw_enable_ips(struct intel_crtc *crtc);
|
||||||
void hsw_disable_ips(struct intel_crtc *crtc);
|
void hsw_disable_ips(struct intel_crtc *crtc);
|
||||||
void intel_display_set_init_power(struct drm_i915_private *dev, bool enable);
|
void intel_display_set_init_power(struct drm_i915_private *dev, bool enable);
|
||||||
|
enum intel_display_power_domain
|
||||||
|
intel_display_port_power_domain(struct intel_encoder *intel_encoder);
|
||||||
int valleyview_get_vco(struct drm_i915_private *dev_priv);
|
int valleyview_get_vco(struct drm_i915_private *dev_priv);
|
||||||
void intel_mode_from_pipe_config(struct drm_display_mode *mode,
|
void intel_mode_from_pipe_config(struct drm_display_mode *mode,
|
||||||
struct intel_crtc_config *pipe_config);
|
struct intel_crtc_config *pipe_config);
|
||||||
|
|
|
@ -5483,6 +5483,15 @@ EXPORT_SYMBOL_GPL(i915_release_power_well);
|
||||||
#define HSW_ALWAYS_ON_POWER_DOMAINS ( \
|
#define HSW_ALWAYS_ON_POWER_DOMAINS ( \
|
||||||
BIT(POWER_DOMAIN_PIPE_A) | \
|
BIT(POWER_DOMAIN_PIPE_A) | \
|
||||||
BIT(POWER_DOMAIN_TRANSCODER_EDP) | \
|
BIT(POWER_DOMAIN_TRANSCODER_EDP) | \
|
||||||
|
BIT(POWER_DOMAIN_PORT_DDI_A_2_LANES) | \
|
||||||
|
BIT(POWER_DOMAIN_PORT_DDI_A_4_LANES) | \
|
||||||
|
BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \
|
||||||
|
BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
|
||||||
|
BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \
|
||||||
|
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_CRT) | \
|
||||||
BIT(POWER_DOMAIN_INIT))
|
BIT(POWER_DOMAIN_INIT))
|
||||||
#define HSW_DISPLAY_POWER_DOMAINS ( \
|
#define HSW_DISPLAY_POWER_DOMAINS ( \
|
||||||
(POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS) | \
|
(POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS) | \
|
||||||
|
|
Loading…
Reference in New Issue