diff options
author | Jani Nikula <jani.nikula@intel.com> | 2013-08-30 20:40:30 +0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-09-04 19:34:56 +0400 |
commit | 9c4b0a683193a646ea3b0c609a2276ae99a7cee4 (patch) | |
tree | 29bb58a9284a39546dcb02e6df2fc5e34c5cc4d6 /drivers/gpu/drm/i915/intel_opregion.c | |
parent | 20f4dbe45950e462aa7c3243f95c0d8bcc369ca0 (diff) | |
download | linux-9c4b0a683193a646ea3b0c609a2276ae99a7cee4.tar.xz |
drm/i915: add opregion function to notify bios of encoder enable/disable
The bios interface seems messy, and it's hard to tell what the bios
really wants. At first, only add support for DDI based machines (hsw+),
and see how it turns out.
The spec says to notify prior to power down and after power up. It is
unclear whether it makes a difference.
v2:
- squash notification function and callers patches together (Daniel)
- move callers to haswell_crtc_{enable,disable} (Daniel)
- rename notification function (Chris)
v3:
- separate notification function and callers again, as it's not clear
whether the display power state notification is the right thing to do
after all
v4: per Paulo's review:
- drop LVDS
- WARN on unsupported encoder types
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_opregion.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_opregion.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index c45fec5b5521..ce1c79eedcb1 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c @@ -291,6 +291,57 @@ static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out) #undef C } +#define DISPLAY_TYPE_CRT 0 +#define DISPLAY_TYPE_TV 1 +#define DISPLAY_TYPE_EXTERNAL_FLAT_PANEL 2 +#define DISPLAY_TYPE_INTERNAL_FLAT_PANEL 3 + +int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, + bool enable) +{ + struct drm_device *dev = intel_encoder->base.dev; + u32 parm = 0; + u32 type = 0; + u32 port; + + /* don't care about old stuff for now */ + if (!HAS_DDI(dev)) + return 0; + + port = intel_ddi_get_encoder_port(intel_encoder); + if (port == PORT_E) { + port = 0; + } else { + parm |= 1 << port; + port++; + } + + if (!enable) + parm |= 4 << 8; + + switch (intel_encoder->type) { + case INTEL_OUTPUT_ANALOG: + type = DISPLAY_TYPE_CRT; + break; + case INTEL_OUTPUT_UNKNOWN: + case INTEL_OUTPUT_DISPLAYPORT: + case INTEL_OUTPUT_HDMI: + type = DISPLAY_TYPE_EXTERNAL_FLAT_PANEL; + break; + case INTEL_OUTPUT_EDP: + type = DISPLAY_TYPE_INTERNAL_FLAT_PANEL; + break; + default: + WARN_ONCE(1, "unsupported intel_encoder type %d\n", + intel_encoder->type); + return -EINVAL; + } + + parm |= type << (16 + port * 3); + + return swsci(dev, SWSCI_SBCB_DISPLAY_POWER_STATE, parm, NULL); +} + static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) { struct drm_i915_private *dev_priv = dev->dev_private; |