Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~keithp/linux
* 'drm-intel-fixes' of git://people.freedesktop.org/~keithp/linux: drm/i915: FBC off for ironlake and older, otherwise on by default drm/i915: Enable SDVO hotplug interrupts for HDMI and DVI drm/i915: Enable dither whenever display bpc < frame buffer bpc
This commit is contained in:
commit
8e8e500fca
4 changed files with 47 additions and 70 deletions
|
@ -67,11 +67,11 @@ module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600);
|
||||||
MODULE_PARM_DESC(i915_enable_rc6,
|
MODULE_PARM_DESC(i915_enable_rc6,
|
||||||
"Enable power-saving render C-state 6 (default: true)");
|
"Enable power-saving render C-state 6 (default: true)");
|
||||||
|
|
||||||
unsigned int i915_enable_fbc __read_mostly = 1;
|
unsigned int i915_enable_fbc __read_mostly = -1;
|
||||||
module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600);
|
module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600);
|
||||||
MODULE_PARM_DESC(i915_enable_fbc,
|
MODULE_PARM_DESC(i915_enable_fbc,
|
||||||
"Enable frame buffer compression for power savings "
|
"Enable frame buffer compression for power savings "
|
||||||
"(default: false)");
|
"(default: -1 (use per-chip default))");
|
||||||
|
|
||||||
unsigned int i915_lvds_downclock __read_mostly = 0;
|
unsigned int i915_lvds_downclock __read_mostly = 0;
|
||||||
module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400);
|
module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400);
|
||||||
|
|
|
@ -1799,6 +1799,7 @@ static void intel_update_fbc(struct drm_device *dev)
|
||||||
struct drm_framebuffer *fb;
|
struct drm_framebuffer *fb;
|
||||||
struct intel_framebuffer *intel_fb;
|
struct intel_framebuffer *intel_fb;
|
||||||
struct drm_i915_gem_object *obj;
|
struct drm_i915_gem_object *obj;
|
||||||
|
int enable_fbc;
|
||||||
|
|
||||||
DRM_DEBUG_KMS("\n");
|
DRM_DEBUG_KMS("\n");
|
||||||
|
|
||||||
|
@ -1839,8 +1840,15 @@ static void intel_update_fbc(struct drm_device *dev)
|
||||||
intel_fb = to_intel_framebuffer(fb);
|
intel_fb = to_intel_framebuffer(fb);
|
||||||
obj = intel_fb->obj;
|
obj = intel_fb->obj;
|
||||||
|
|
||||||
if (!i915_enable_fbc) {
|
enable_fbc = i915_enable_fbc;
|
||||||
DRM_DEBUG_KMS("fbc disabled per module param (default off)\n");
|
if (enable_fbc < 0) {
|
||||||
|
DRM_DEBUG_KMS("fbc set to per-chip default\n");
|
||||||
|
enable_fbc = 1;
|
||||||
|
if (INTEL_INFO(dev)->gen <= 5)
|
||||||
|
enable_fbc = 0;
|
||||||
|
}
|
||||||
|
if (!enable_fbc) {
|
||||||
|
DRM_DEBUG_KMS("fbc disabled per module param\n");
|
||||||
dev_priv->no_fbc_reason = FBC_MODULE_PARAM;
|
dev_priv->no_fbc_reason = FBC_MODULE_PARAM;
|
||||||
goto out_disable;
|
goto out_disable;
|
||||||
}
|
}
|
||||||
|
@ -4687,13 +4695,13 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
|
||||||
bpc = 6; /* min is 18bpp */
|
bpc = 6; /* min is 18bpp */
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
bpc = min((unsigned int)8, display_bpc);
|
bpc = 8;
|
||||||
break;
|
break;
|
||||||
case 30:
|
case 30:
|
||||||
bpc = min((unsigned int)10, display_bpc);
|
bpc = 10;
|
||||||
break;
|
break;
|
||||||
case 48:
|
case 48:
|
||||||
bpc = min((unsigned int)12, display_bpc);
|
bpc = 12;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DRM_DEBUG("unsupported depth, assuming 24 bits\n");
|
DRM_DEBUG("unsupported depth, assuming 24 bits\n");
|
||||||
|
@ -4701,10 +4709,12 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
display_bpc = min(display_bpc, bpc);
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("setting pipe bpc to %d (max display bpc %d)\n",
|
DRM_DEBUG_DRIVER("setting pipe bpc to %d (max display bpc %d)\n",
|
||||||
bpc, display_bpc);
|
bpc, display_bpc);
|
||||||
|
|
||||||
*pipe_bpp = bpc * 3;
|
*pipe_bpp = display_bpc * 3;
|
||||||
|
|
||||||
return display_bpc != bpc;
|
return display_bpc != bpc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -337,9 +337,6 @@ extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,
|
||||||
struct drm_connector *connector,
|
struct drm_connector *connector,
|
||||||
struct intel_load_detect_pipe *old);
|
struct intel_load_detect_pipe *old);
|
||||||
|
|
||||||
extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB);
|
|
||||||
extern int intel_sdvo_supports_hotplug(struct drm_connector *connector);
|
|
||||||
extern void intel_sdvo_set_hotplug(struct drm_connector *connector, int enable);
|
|
||||||
extern void intelfb_restore(void);
|
extern void intelfb_restore(void);
|
||||||
extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
|
extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
|
||||||
u16 blue, int regno);
|
u16 blue, int regno);
|
||||||
|
|
|
@ -92,6 +92,11 @@ struct intel_sdvo {
|
||||||
*/
|
*/
|
||||||
uint16_t attached_output;
|
uint16_t attached_output;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hotplug activation bits for this device
|
||||||
|
*/
|
||||||
|
uint8_t hotplug_active[2];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is used to select the color range of RBG outputs in HDMI mode.
|
* This is used to select the color range of RBG outputs in HDMI mode.
|
||||||
* It is only valid when using TMDS encoding and 8 bit per color mode.
|
* It is only valid when using TMDS encoding and 8 bit per color mode.
|
||||||
|
@ -1208,74 +1213,20 @@ static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct in
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No use! */
|
static int intel_sdvo_supports_hotplug(struct intel_sdvo *intel_sdvo)
|
||||||
#if 0
|
|
||||||
struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB)
|
|
||||||
{
|
|
||||||
struct drm_connector *connector = NULL;
|
|
||||||
struct intel_sdvo *iout = NULL;
|
|
||||||
struct intel_sdvo *sdvo;
|
|
||||||
|
|
||||||
/* find the sdvo connector */
|
|
||||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
|
||||||
iout = to_intel_sdvo(connector);
|
|
||||||
|
|
||||||
if (iout->type != INTEL_OUTPUT_SDVO)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
sdvo = iout->dev_priv;
|
|
||||||
|
|
||||||
if (sdvo->sdvo_reg == SDVOB && sdvoB)
|
|
||||||
return connector;
|
|
||||||
|
|
||||||
if (sdvo->sdvo_reg == SDVOC && !sdvoB)
|
|
||||||
return connector;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int intel_sdvo_supports_hotplug(struct drm_connector *connector)
|
|
||||||
{
|
{
|
||||||
u8 response[2];
|
u8 response[2];
|
||||||
u8 status;
|
|
||||||
struct intel_sdvo *intel_sdvo;
|
|
||||||
DRM_DEBUG_KMS("\n");
|
|
||||||
|
|
||||||
if (!connector)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
intel_sdvo = to_intel_sdvo(connector);
|
|
||||||
|
|
||||||
return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT,
|
return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT,
|
||||||
&response, 2) && response[0];
|
&response, 2) && response[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
|
static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder)
|
||||||
{
|
{
|
||||||
u8 response[2];
|
struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
|
||||||
u8 status;
|
|
||||||
struct intel_sdvo *intel_sdvo = to_intel_sdvo(connector);
|
|
||||||
|
|
||||||
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
|
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &intel_sdvo->hotplug_active, 2);
|
||||||
intel_sdvo_read_response(intel_sdvo, &response, 2);
|
|
||||||
|
|
||||||
if (on) {
|
|
||||||
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
|
|
||||||
status = intel_sdvo_read_response(intel_sdvo, &response, 2);
|
|
||||||
|
|
||||||
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
|
|
||||||
} else {
|
|
||||||
response[0] = 0;
|
|
||||||
response[1] = 0;
|
|
||||||
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
|
|
||||||
intel_sdvo_read_response(intel_sdvo, &response, 2);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo)
|
intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo)
|
||||||
|
@ -2045,6 +1996,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
|
||||||
{
|
{
|
||||||
struct drm_encoder *encoder = &intel_sdvo->base.base;
|
struct drm_encoder *encoder = &intel_sdvo->base.base;
|
||||||
struct drm_connector *connector;
|
struct drm_connector *connector;
|
||||||
|
struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
|
||||||
struct intel_connector *intel_connector;
|
struct intel_connector *intel_connector;
|
||||||
struct intel_sdvo_connector *intel_sdvo_connector;
|
struct intel_sdvo_connector *intel_sdvo_connector;
|
||||||
|
|
||||||
|
@ -2062,7 +2014,17 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
|
||||||
|
|
||||||
intel_connector = &intel_sdvo_connector->base;
|
intel_connector = &intel_sdvo_connector->base;
|
||||||
connector = &intel_connector->base;
|
connector = &intel_connector->base;
|
||||||
connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
|
if (intel_sdvo_supports_hotplug(intel_sdvo) & (1 << device)) {
|
||||||
|
connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||||
|
intel_sdvo->hotplug_active[0] |= 1 << device;
|
||||||
|
/* Some SDVO devices have one-shot hotplug interrupts.
|
||||||
|
* Ensure that they get re-enabled when an interrupt happens.
|
||||||
|
*/
|
||||||
|
intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
|
||||||
|
intel_sdvo_enable_hotplug(intel_encoder);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
|
||||||
encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
|
encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
|
||||||
connector->connector_type = DRM_MODE_CONNECTOR_DVID;
|
connector->connector_type = DRM_MODE_CONNECTOR_DVID;
|
||||||
|
|
||||||
|
@ -2569,6 +2531,14 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
|
||||||
if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))
|
if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
/* Set up hotplug command - note paranoia about contents of reply.
|
||||||
|
* We assume that the hardware is in a sane state, and only touch
|
||||||
|
* the bits we think we understand.
|
||||||
|
*/
|
||||||
|
intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG,
|
||||||
|
&intel_sdvo->hotplug_active, 2);
|
||||||
|
intel_sdvo->hotplug_active[0] &= ~0x3;
|
||||||
|
|
||||||
if (intel_sdvo_output_setup(intel_sdvo,
|
if (intel_sdvo_output_setup(intel_sdvo,
|
||||||
intel_sdvo->caps.output_flags) != true) {
|
intel_sdvo->caps.output_flags) != true) {
|
||||||
DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n",
|
DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n",
|
||||||
|
|
Loading…
Reference in a new issue