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>
This commit is contained in:
parent
20f4dbe459
commit
9c4b0a6831
@ -2189,15 +2189,23 @@ static inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter)
|
|||||||
extern void intel_i2c_reset(struct drm_device *dev);
|
extern void intel_i2c_reset(struct drm_device *dev);
|
||||||
|
|
||||||
/* intel_opregion.c */
|
/* intel_opregion.c */
|
||||||
|
struct intel_encoder;
|
||||||
extern int intel_opregion_setup(struct drm_device *dev);
|
extern int intel_opregion_setup(struct drm_device *dev);
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
extern void intel_opregion_init(struct drm_device *dev);
|
extern void intel_opregion_init(struct drm_device *dev);
|
||||||
extern void intel_opregion_fini(struct drm_device *dev);
|
extern void intel_opregion_fini(struct drm_device *dev);
|
||||||
extern void intel_opregion_asle_intr(struct drm_device *dev);
|
extern void intel_opregion_asle_intr(struct drm_device *dev);
|
||||||
|
extern int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
|
||||||
|
bool enable);
|
||||||
#else
|
#else
|
||||||
static inline void intel_opregion_init(struct drm_device *dev) { return; }
|
static inline void intel_opregion_init(struct drm_device *dev) { return; }
|
||||||
static inline void intel_opregion_fini(struct drm_device *dev) { return; }
|
static inline void intel_opregion_fini(struct drm_device *dev) { return; }
|
||||||
static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; }
|
static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; }
|
||||||
|
static inline int
|
||||||
|
intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, bool enable)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* intel_acpi.c */
|
/* intel_acpi.c */
|
||||||
|
@ -291,6 +291,57 @@ static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out)
|
|||||||
#undef C
|
#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)
|
static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user