Merge tag 'drm-intel-next-2014-02-14' of ssh://git.freedesktop.org/git/drm-intel into drm-next
- Fix the execbuf rebind performance regression due to topic/ppgtt (Chris). - Fix up the connector cleanup ordering for sdvod i2c and dp aux devices (Imre). - Try to preserve the firmware modeset config on driver load. And a bit of prep work for smooth takeover of the fb contents (Jesse). - Prep cleanup for larger gtt address spaces on bdw (Ben). - Improve our vblank_wait code to make hsw modesets faster (Paulo). - Display debugfs file (Jesse). - DRRS prep work from Vandana Kannan. - pipestat interrupt handler to fix a few races around vblank/pageflip handling on byt (Imre). - Improve display fuse handling for display-less SKUs (Damien). - Drop locks while stalling for the gpu when serving pagefaults to improve interactivity (Chris). - And as usual piles of other improvements and small fixes all over. * tag 'drm-intel-next-2014-02-14' of ssh://git.freedesktop.org/git/drm-intel: (65 commits) drm/i915: fix NULL deref in the load detect code drm/i915: Only bind each object rather than for every execbuffer drm/i915: Directly return the vma from bind_to_vm drm/i915: Simplify i915_gem_object_ggtt_unpin drm/i915: Allow blocking in the PDE alloc when running low on gtt space drm/i915: Don't allocate context pages as mappable drm/i915: Handle set_cache_level errors in the status page setup drm/i915: Don't pin the status page as mappable drm/i915: Don't set PIN_MAPPABLE for legacy ringbuffers drm/i915: Handle set_cache_level errors in the pipe control scratch setup drm/i915: split PIN_GLOBAL out from PIN_MAPPABLE drm/i915: Consolidate binding parameters into flags drm/i915: sdvo: add i2c sysfs symlink to the connector's directory drm/i915: sdvo: fix error path in sdvo_connector_init drm/i915: dp: fix order of dp aux i2c device cleanup drm/i915: add unregister callback to connector drm/i915: don't reference null pointer at i915_sink_crc drm/i915/lvds: Remove dead code from failing case drm/i915: don't preserve inherited configs with nothing on v2 drm/i915/bdw: Split up PPGTT cleanup ...
This commit is contained in:
@@ -215,6 +215,16 @@ static const struct drm_prop_enum_list drm_encoder_enum_list[] =
|
|||||||
{ DRM_MODE_ENCODER_DSI, "DSI" },
|
{ DRM_MODE_ENCODER_DSI, "DSI" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct drm_prop_enum_list drm_subpixel_enum_list[] =
|
||||||
|
{
|
||||||
|
{ SubPixelUnknown, "Unknown" },
|
||||||
|
{ SubPixelHorizontalRGB, "Horizontal RGB" },
|
||||||
|
{ SubPixelHorizontalBGR, "Horizontal BGR" },
|
||||||
|
{ SubPixelVerticalRGB, "Vertical RGB" },
|
||||||
|
{ SubPixelVerticalBGR, "Vertical BGR" },
|
||||||
|
{ SubPixelNone, "None" },
|
||||||
|
};
|
||||||
|
|
||||||
void drm_connector_ida_init(void)
|
void drm_connector_ida_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -264,6 +274,19 @@ const char *drm_get_connector_status_name(enum drm_connector_status status)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_get_connector_status_name);
|
EXPORT_SYMBOL(drm_get_connector_status_name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_get_subpixel_order_name - return a string for a given subpixel enum
|
||||||
|
* @order: enum of subpixel_order
|
||||||
|
*
|
||||||
|
* Note you could abuse this and return something out of bounds, but that
|
||||||
|
* would be a caller error. No unscrubbed user data should make it here.
|
||||||
|
*/
|
||||||
|
const char *drm_get_subpixel_order_name(enum subpixel_order order)
|
||||||
|
{
|
||||||
|
return drm_subpixel_enum_list[order].name;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(drm_get_subpixel_order_name);
|
||||||
|
|
||||||
static char printable_char(int c)
|
static char printable_char(int c)
|
||||||
{
|
{
|
||||||
return isascii(c) && isprint(c) ? c : '?';
|
return isascii(c) && isprint(c) ? c : '?';
|
||||||
|
|||||||
@@ -1136,7 +1136,7 @@ static int drm_fb_helper_probe_connector_modes(struct drm_fb_helper *fb_helper,
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct drm_display_mode *drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector, int width, int height)
|
struct drm_display_mode *drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector, int width, int height)
|
||||||
{
|
{
|
||||||
struct drm_display_mode *mode;
|
struct drm_display_mode *mode;
|
||||||
|
|
||||||
@@ -1149,6 +1149,7 @@ static struct drm_display_mode *drm_has_preferred_mode(struct drm_fb_helper_conn
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(drm_has_preferred_mode);
|
||||||
|
|
||||||
static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector)
|
static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector)
|
||||||
{
|
{
|
||||||
@@ -1157,7 +1158,7 @@ static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector)
|
|||||||
return cmdline_mode->specified;
|
return cmdline_mode->specified;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
|
struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
|
||||||
int width, int height)
|
int width, int height)
|
||||||
{
|
{
|
||||||
struct drm_cmdline_mode *cmdline_mode;
|
struct drm_cmdline_mode *cmdline_mode;
|
||||||
@@ -1197,6 +1198,7 @@ create_mode:
|
|||||||
list_add(&mode->head, &fb_helper_conn->connector->modes);
|
list_add(&mode->head, &fb_helper_conn->connector->modes);
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(drm_pick_cmdline_mode);
|
||||||
|
|
||||||
static bool drm_connector_enabled(struct drm_connector *connector, bool strict)
|
static bool drm_connector_enabled(struct drm_connector *connector, bool strict)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1937,6 +1937,9 @@ static int i915_sink_crc(struct seq_file *m, void *data)
|
|||||||
if (connector->base.dpms != DRM_MODE_DPMS_ON)
|
if (connector->base.dpms != DRM_MODE_DPMS_ON)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!connector->base.encoder)
|
||||||
|
continue;
|
||||||
|
|
||||||
encoder = to_intel_encoder(connector->base.encoder);
|
encoder = to_intel_encoder(connector->base.encoder);
|
||||||
if (encoder->type != INTEL_OUTPUT_EDP)
|
if (encoder->type != INTEL_OUTPUT_EDP)
|
||||||
continue;
|
continue;
|
||||||
@@ -2074,6 +2077,164 @@ static int i915_power_domain_info(struct seq_file *m, void *unused)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void intel_seq_print_mode(struct seq_file *m, int tabs,
|
||||||
|
struct drm_display_mode *mode)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < tabs; i++)
|
||||||
|
seq_putc(m, '\t');
|
||||||
|
|
||||||
|
seq_printf(m, "id %d:\"%s\" freq %d clock %d hdisp %d hss %d hse %d htot %d vdisp %d vss %d vse %d vtot %d type 0x%x flags 0x%x\n",
|
||||||
|
mode->base.id, mode->name,
|
||||||
|
mode->vrefresh, mode->clock,
|
||||||
|
mode->hdisplay, mode->hsync_start,
|
||||||
|
mode->hsync_end, mode->htotal,
|
||||||
|
mode->vdisplay, mode->vsync_start,
|
||||||
|
mode->vsync_end, mode->vtotal,
|
||||||
|
mode->type, mode->flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void intel_encoder_info(struct seq_file *m,
|
||||||
|
struct intel_crtc *intel_crtc,
|
||||||
|
struct intel_encoder *intel_encoder)
|
||||||
|
{
|
||||||
|
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||||
|
struct drm_device *dev = node->minor->dev;
|
||||||
|
struct drm_crtc *crtc = &intel_crtc->base;
|
||||||
|
struct intel_connector *intel_connector;
|
||||||
|
struct drm_encoder *encoder;
|
||||||
|
|
||||||
|
encoder = &intel_encoder->base;
|
||||||
|
seq_printf(m, "\tencoder %d: type: %s, connectors:\n",
|
||||||
|
encoder->base.id, drm_get_encoder_name(encoder));
|
||||||
|
for_each_connector_on_encoder(dev, encoder, intel_connector) {
|
||||||
|
struct drm_connector *connector = &intel_connector->base;
|
||||||
|
seq_printf(m, "\t\tconnector %d: type: %s, status: %s",
|
||||||
|
connector->base.id,
|
||||||
|
drm_get_connector_name(connector),
|
||||||
|
drm_get_connector_status_name(connector->status));
|
||||||
|
if (connector->status == connector_status_connected) {
|
||||||
|
struct drm_display_mode *mode = &crtc->mode;
|
||||||
|
seq_printf(m, ", mode:\n");
|
||||||
|
intel_seq_print_mode(m, 2, mode);
|
||||||
|
} else {
|
||||||
|
seq_putc(m, '\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void intel_crtc_info(struct seq_file *m, struct intel_crtc *intel_crtc)
|
||||||
|
{
|
||||||
|
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||||
|
struct drm_device *dev = node->minor->dev;
|
||||||
|
struct drm_crtc *crtc = &intel_crtc->base;
|
||||||
|
struct intel_encoder *intel_encoder;
|
||||||
|
|
||||||
|
seq_printf(m, "\tfb: %d, pos: %dx%d, size: %dx%d\n",
|
||||||
|
crtc->fb->base.id, crtc->x, crtc->y,
|
||||||
|
crtc->fb->width, crtc->fb->height);
|
||||||
|
for_each_encoder_on_crtc(dev, crtc, intel_encoder)
|
||||||
|
intel_encoder_info(m, intel_crtc, intel_encoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void intel_panel_info(struct seq_file *m, struct intel_panel *panel)
|
||||||
|
{
|
||||||
|
struct drm_display_mode *mode = panel->fixed_mode;
|
||||||
|
|
||||||
|
seq_printf(m, "\tfixed mode:\n");
|
||||||
|
intel_seq_print_mode(m, 2, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void intel_dp_info(struct seq_file *m,
|
||||||
|
struct intel_connector *intel_connector)
|
||||||
|
{
|
||||||
|
struct intel_encoder *intel_encoder = intel_connector->encoder;
|
||||||
|
struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
|
||||||
|
|
||||||
|
seq_printf(m, "\tDPCD rev: %x\n", intel_dp->dpcd[DP_DPCD_REV]);
|
||||||
|
seq_printf(m, "\taudio support: %s\n", intel_dp->has_audio ? "yes" :
|
||||||
|
"no");
|
||||||
|
if (intel_encoder->type == INTEL_OUTPUT_EDP)
|
||||||
|
intel_panel_info(m, &intel_connector->panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void intel_hdmi_info(struct seq_file *m,
|
||||||
|
struct intel_connector *intel_connector)
|
||||||
|
{
|
||||||
|
struct intel_encoder *intel_encoder = intel_connector->encoder;
|
||||||
|
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&intel_encoder->base);
|
||||||
|
|
||||||
|
seq_printf(m, "\taudio support: %s\n", intel_hdmi->has_audio ? "yes" :
|
||||||
|
"no");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void intel_lvds_info(struct seq_file *m,
|
||||||
|
struct intel_connector *intel_connector)
|
||||||
|
{
|
||||||
|
intel_panel_info(m, &intel_connector->panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void intel_connector_info(struct seq_file *m,
|
||||||
|
struct drm_connector *connector)
|
||||||
|
{
|
||||||
|
struct intel_connector *intel_connector = to_intel_connector(connector);
|
||||||
|
struct intel_encoder *intel_encoder = intel_connector->encoder;
|
||||||
|
|
||||||
|
seq_printf(m, "connector %d: type %s, status: %s\n",
|
||||||
|
connector->base.id, drm_get_connector_name(connector),
|
||||||
|
drm_get_connector_status_name(connector->status));
|
||||||
|
if (connector->status == connector_status_connected) {
|
||||||
|
seq_printf(m, "\tname: %s\n", connector->display_info.name);
|
||||||
|
seq_printf(m, "\tphysical dimensions: %dx%dmm\n",
|
||||||
|
connector->display_info.width_mm,
|
||||||
|
connector->display_info.height_mm);
|
||||||
|
seq_printf(m, "\tsubpixel order: %s\n",
|
||||||
|
drm_get_subpixel_order_name(connector->display_info.subpixel_order));
|
||||||
|
seq_printf(m, "\tCEA rev: %d\n",
|
||||||
|
connector->display_info.cea_rev);
|
||||||
|
}
|
||||||
|
if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
|
||||||
|
intel_encoder->type == INTEL_OUTPUT_EDP)
|
||||||
|
intel_dp_info(m, intel_connector);
|
||||||
|
else if (intel_encoder->type == INTEL_OUTPUT_HDMI)
|
||||||
|
intel_hdmi_info(m, intel_connector);
|
||||||
|
else if (intel_encoder->type == INTEL_OUTPUT_LVDS)
|
||||||
|
intel_lvds_info(m, intel_connector);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int i915_display_info(struct seq_file *m, void *unused)
|
||||||
|
{
|
||||||
|
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||||
|
struct drm_device *dev = node->minor->dev;
|
||||||
|
struct drm_crtc *crtc;
|
||||||
|
struct drm_connector *connector;
|
||||||
|
|
||||||
|
drm_modeset_lock_all(dev);
|
||||||
|
seq_printf(m, "CRTC info\n");
|
||||||
|
seq_printf(m, "---------\n");
|
||||||
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||||
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||||
|
|
||||||
|
seq_printf(m, "CRTC %d: pipe: %c, active: %s\n",
|
||||||
|
crtc->base.id, pipe_name(intel_crtc->pipe),
|
||||||
|
intel_crtc->active ? "yes" : "no");
|
||||||
|
if (intel_crtc->active)
|
||||||
|
intel_crtc_info(m, intel_crtc);
|
||||||
|
}
|
||||||
|
|
||||||
|
seq_printf(m, "\n");
|
||||||
|
seq_printf(m, "Connector info\n");
|
||||||
|
seq_printf(m, "--------------\n");
|
||||||
|
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||||
|
intel_connector_info(m, connector);
|
||||||
|
}
|
||||||
|
drm_modeset_unlock_all(dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct pipe_crc_info {
|
struct pipe_crc_info {
|
||||||
const char *name;
|
const char *name;
|
||||||
struct drm_device *dev;
|
struct drm_device *dev;
|
||||||
@@ -3519,6 +3680,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
|
|||||||
{"i915_energy_uJ", i915_energy_uJ, 0},
|
{"i915_energy_uJ", i915_energy_uJ, 0},
|
||||||
{"i915_pc8_status", i915_pc8_status, 0},
|
{"i915_pc8_status", i915_pc8_status, 0},
|
||||||
{"i915_power_domain_info", i915_power_domain_info, 0},
|
{"i915_power_domain_info", i915_power_domain_info, 0},
|
||||||
|
{"i915_display_info", i915_display_info, 0},
|
||||||
};
|
};
|
||||||
#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
|
#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
|
||||||
|
|
||||||
|
|||||||
@@ -626,9 +626,8 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
|
|||||||
struct drm_file *file_priv)
|
struct drm_file *file_priv)
|
||||||
{
|
{
|
||||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||||
struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
|
struct drm_i915_master_private *master_priv;
|
||||||
drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
|
drm_i915_sarea_t *sarea_priv;
|
||||||
master_priv->sarea_priv;
|
|
||||||
drm_i915_batchbuffer_t *batch = data;
|
drm_i915_batchbuffer_t *batch = data;
|
||||||
int ret;
|
int ret;
|
||||||
struct drm_clip_rect *cliprects = NULL;
|
struct drm_clip_rect *cliprects = NULL;
|
||||||
@@ -636,6 +635,9 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
|
|||||||
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
master_priv = dev->primary->master->driver_priv;
|
||||||
|
sarea_priv = (drm_i915_sarea_t *) master_priv->sarea_priv;
|
||||||
|
|
||||||
if (!dev_priv->dri1.allow_batchbuffer) {
|
if (!dev_priv->dri1.allow_batchbuffer) {
|
||||||
DRM_ERROR("Batchbuffer ioctl disabled\n");
|
DRM_ERROR("Batchbuffer ioctl disabled\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -682,9 +684,8 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
|
|||||||
struct drm_file *file_priv)
|
struct drm_file *file_priv)
|
||||||
{
|
{
|
||||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||||
struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
|
struct drm_i915_master_private *master_priv;
|
||||||
drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
|
drm_i915_sarea_t *sarea_priv;
|
||||||
master_priv->sarea_priv;
|
|
||||||
drm_i915_cmdbuffer_t *cmdbuf = data;
|
drm_i915_cmdbuffer_t *cmdbuf = data;
|
||||||
struct drm_clip_rect *cliprects = NULL;
|
struct drm_clip_rect *cliprects = NULL;
|
||||||
void *batch_data;
|
void *batch_data;
|
||||||
@@ -696,6 +697,9 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
|
|||||||
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
master_priv = dev->primary->master->driver_priv;
|
||||||
|
sarea_priv = (drm_i915_sarea_t *) master_priv->sarea_priv;
|
||||||
|
|
||||||
RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
|
RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
|
||||||
|
|
||||||
if (cmdbuf->num_cliprects < 0)
|
if (cmdbuf->num_cliprects < 0)
|
||||||
@@ -1442,7 +1446,7 @@ static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
|
|||||||
|
|
||||||
static void i915_dump_device_info(struct drm_i915_private *dev_priv)
|
static void i915_dump_device_info(struct drm_i915_private *dev_priv)
|
||||||
{
|
{
|
||||||
const struct intel_device_info *info = dev_priv->info;
|
const struct intel_device_info *info = &dev_priv->info;
|
||||||
|
|
||||||
#define PRINT_S(name) "%s"
|
#define PRINT_S(name) "%s"
|
||||||
#define SEP_EMPTY
|
#define SEP_EMPTY
|
||||||
@@ -1459,6 +1463,58 @@ static void i915_dump_device_info(struct drm_i915_private *dev_priv)
|
|||||||
#undef SEP_COMMA
|
#undef SEP_COMMA
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine various intel_device_info fields at runtime.
|
||||||
|
*
|
||||||
|
* Use it when either:
|
||||||
|
* - it's judged too laborious to fill n static structures with the limit
|
||||||
|
* when a simple if statement does the job,
|
||||||
|
* - run-time checks (eg read fuse/strap registers) are needed.
|
||||||
|
*
|
||||||
|
* This function needs to be called:
|
||||||
|
* - after the MMIO has been setup as we are reading registers,
|
||||||
|
* - after the PCH has been detected,
|
||||||
|
* - before the first usage of the fields it can tweak.
|
||||||
|
*/
|
||||||
|
static void intel_device_info_runtime_init(struct drm_device *dev)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
struct intel_device_info *info;
|
||||||
|
|
||||||
|
info = (struct intel_device_info *)&dev_priv->info;
|
||||||
|
|
||||||
|
info->num_sprites = 1;
|
||||||
|
if (IS_VALLEYVIEW(dev))
|
||||||
|
info->num_sprites = 2;
|
||||||
|
|
||||||
|
if (i915.disable_display) {
|
||||||
|
DRM_INFO("Display disabled (module parameter)\n");
|
||||||
|
info->num_pipes = 0;
|
||||||
|
} else if (info->num_pipes > 0 &&
|
||||||
|
(INTEL_INFO(dev)->gen == 7 || INTEL_INFO(dev)->gen == 8) &&
|
||||||
|
!IS_VALLEYVIEW(dev)) {
|
||||||
|
u32 fuse_strap = I915_READ(FUSE_STRAP);
|
||||||
|
u32 sfuse_strap = I915_READ(SFUSE_STRAP);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SFUSE_STRAP is supposed to have a bit signalling the display
|
||||||
|
* is fused off. Unfortunately it seems that, at least in
|
||||||
|
* certain cases, fused off display means that PCH display
|
||||||
|
* reads don't land anywhere. In that case, we read 0s.
|
||||||
|
*
|
||||||
|
* On CPT/PPT, we can detect this case as SFUSE_STRAP_FUSE_LOCK
|
||||||
|
* should be set when taking over after the firmware.
|
||||||
|
*/
|
||||||
|
if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE ||
|
||||||
|
sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED ||
|
||||||
|
(dev_priv->pch_type == PCH_CPT &&
|
||||||
|
!(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) {
|
||||||
|
DRM_INFO("Display fused off, disabling\n");
|
||||||
|
info->num_pipes = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* i915_driver_load - setup chip and create an initial config
|
* i915_driver_load - setup chip and create an initial config
|
||||||
* @dev: DRM device
|
* @dev: DRM device
|
||||||
@@ -1473,7 +1529,7 @@ static void i915_dump_device_info(struct drm_i915_private *dev_priv)
|
|||||||
int i915_driver_load(struct drm_device *dev, unsigned long flags)
|
int i915_driver_load(struct drm_device *dev, unsigned long flags)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv;
|
struct drm_i915_private *dev_priv;
|
||||||
struct intel_device_info *info;
|
struct intel_device_info *info, *device_info;
|
||||||
int ret = 0, mmio_bar, mmio_size;
|
int ret = 0, mmio_bar, mmio_size;
|
||||||
uint32_t aperture_size;
|
uint32_t aperture_size;
|
||||||
|
|
||||||
@@ -1496,7 +1552,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
|
|||||||
|
|
||||||
dev->dev_private = (void *)dev_priv;
|
dev->dev_private = (void *)dev_priv;
|
||||||
dev_priv->dev = dev;
|
dev_priv->dev = dev;
|
||||||
dev_priv->info = info;
|
|
||||||
|
/* copy initial configuration to dev_priv->info */
|
||||||
|
device_info = (struct intel_device_info *)&dev_priv->info;
|
||||||
|
*device_info = *info;
|
||||||
|
|
||||||
spin_lock_init(&dev_priv->irq_lock);
|
spin_lock_init(&dev_priv->irq_lock);
|
||||||
spin_lock_init(&dev_priv->gpu_error.lock);
|
spin_lock_init(&dev_priv->gpu_error.lock);
|
||||||
@@ -1635,9 +1694,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
|
|||||||
if (!IS_I945G(dev) && !IS_I945GM(dev))
|
if (!IS_I945G(dev) && !IS_I945GM(dev))
|
||||||
pci_enable_msi(dev->pdev);
|
pci_enable_msi(dev->pdev);
|
||||||
|
|
||||||
dev_priv->num_plane = 1;
|
intel_device_info_runtime_init(dev);
|
||||||
if (IS_VALLEYVIEW(dev))
|
|
||||||
dev_priv->num_plane = 2;
|
|
||||||
|
|
||||||
if (INTEL_INFO(dev)->num_pipes) {
|
if (INTEL_INFO(dev)->num_pipes) {
|
||||||
ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes);
|
ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes);
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ enum plane {
|
|||||||
};
|
};
|
||||||
#define plane_name(p) ((p) + 'A')
|
#define plane_name(p) ((p) + 'A')
|
||||||
|
|
||||||
#define sprite_name(p, s) ((p) * dev_priv->num_plane + (s) + 'A')
|
#define sprite_name(p, s) ((p) * INTEL_INFO(dev)->num_sprites + (s) + 'A')
|
||||||
|
|
||||||
enum port {
|
enum port {
|
||||||
PORT_A = 0,
|
PORT_A = 0,
|
||||||
@@ -164,6 +164,10 @@ enum hpd_pin {
|
|||||||
list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \
|
list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \
|
||||||
if ((intel_encoder)->base.crtc == (__crtc))
|
if ((intel_encoder)->base.crtc == (__crtc))
|
||||||
|
|
||||||
|
#define for_each_connector_on_encoder(dev, __encoder, intel_connector) \
|
||||||
|
list_for_each_entry((intel_connector), &(dev)->mode_config.connector_list, base.head) \
|
||||||
|
if ((intel_connector)->base.encoder == (__encoder))
|
||||||
|
|
||||||
struct drm_i915_private;
|
struct drm_i915_private;
|
||||||
|
|
||||||
enum intel_dpll_id {
|
enum intel_dpll_id {
|
||||||
@@ -530,6 +534,7 @@ struct intel_uncore {
|
|||||||
struct intel_device_info {
|
struct intel_device_info {
|
||||||
u32 display_mmio_offset;
|
u32 display_mmio_offset;
|
||||||
u8 num_pipes:3;
|
u8 num_pipes:3;
|
||||||
|
u8 num_sprites:2;
|
||||||
u8 gen;
|
u8 gen;
|
||||||
u8 ring_mask; /* Rings supported by the HW */
|
u8 ring_mask; /* Rings supported by the HW */
|
||||||
DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG, SEP_SEMICOLON);
|
DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG, SEP_SEMICOLON);
|
||||||
@@ -1390,7 +1395,7 @@ typedef struct drm_i915_private {
|
|||||||
struct drm_device *dev;
|
struct drm_device *dev;
|
||||||
struct kmem_cache *slab;
|
struct kmem_cache *slab;
|
||||||
|
|
||||||
const struct intel_device_info *info;
|
const struct intel_device_info info;
|
||||||
|
|
||||||
int relative_constants_mode;
|
int relative_constants_mode;
|
||||||
|
|
||||||
@@ -1435,6 +1440,7 @@ typedef struct drm_i915_private {
|
|||||||
};
|
};
|
||||||
u32 gt_irq_mask;
|
u32 gt_irq_mask;
|
||||||
u32 pm_irq_mask;
|
u32 pm_irq_mask;
|
||||||
|
u32 pipestat_irq_mask[I915_MAX_PIPES];
|
||||||
|
|
||||||
struct work_struct hotplug_work;
|
struct work_struct hotplug_work;
|
||||||
bool enable_hotplug_processing;
|
bool enable_hotplug_processing;
|
||||||
@@ -1450,8 +1456,6 @@ typedef struct drm_i915_private {
|
|||||||
u32 hpd_event_bits;
|
u32 hpd_event_bits;
|
||||||
struct timer_list hotplug_reenable_timer;
|
struct timer_list hotplug_reenable_timer;
|
||||||
|
|
||||||
int num_plane;
|
|
||||||
|
|
||||||
struct i915_fbc fbc;
|
struct i915_fbc fbc;
|
||||||
struct intel_opregion opregion;
|
struct intel_opregion opregion;
|
||||||
struct intel_vbt_data vbt;
|
struct intel_vbt_data vbt;
|
||||||
@@ -1501,8 +1505,8 @@ typedef struct drm_i915_private {
|
|||||||
|
|
||||||
struct sdvo_device_mapping sdvo_mappings[2];
|
struct sdvo_device_mapping sdvo_mappings[2];
|
||||||
|
|
||||||
struct drm_crtc *plane_to_crtc_mapping[3];
|
struct drm_crtc *plane_to_crtc_mapping[I915_MAX_PIPES];
|
||||||
struct drm_crtc *pipe_to_crtc_mapping[3];
|
struct drm_crtc *pipe_to_crtc_mapping[I915_MAX_PIPES];
|
||||||
wait_queue_head_t pending_flip_queue;
|
wait_queue_head_t pending_flip_queue;
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
@@ -1799,7 +1803,7 @@ struct drm_i915_file_private {
|
|||||||
atomic_t rps_wait_boost;
|
atomic_t rps_wait_boost;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INTEL_INFO(dev) (to_i915(dev)->info)
|
#define INTEL_INFO(dev) (&to_i915(dev)->info)
|
||||||
|
|
||||||
#define IS_I830(dev) ((dev)->pdev->device == 0x3577)
|
#define IS_I830(dev) ((dev)->pdev->device == 0x3577)
|
||||||
#define IS_845G(dev) ((dev)->pdev->device == 0x2562)
|
#define IS_845G(dev) ((dev)->pdev->device == 0x2562)
|
||||||
@@ -1953,18 +1957,20 @@ struct i915_params {
|
|||||||
int vbt_sdvo_panel_type;
|
int vbt_sdvo_panel_type;
|
||||||
int enable_rc6;
|
int enable_rc6;
|
||||||
int enable_fbc;
|
int enable_fbc;
|
||||||
bool enable_hangcheck;
|
|
||||||
int enable_ppgtt;
|
int enable_ppgtt;
|
||||||
int enable_psr;
|
int enable_psr;
|
||||||
unsigned int preliminary_hw_support;
|
unsigned int preliminary_hw_support;
|
||||||
int disable_power_well;
|
int disable_power_well;
|
||||||
int enable_ips;
|
int enable_ips;
|
||||||
bool fastboot;
|
|
||||||
int enable_pc8;
|
int enable_pc8;
|
||||||
int pc8_timeout;
|
int pc8_timeout;
|
||||||
|
int invert_brightness;
|
||||||
|
/* leave bools at the end to not create holes */
|
||||||
|
bool enable_hangcheck;
|
||||||
|
bool fastboot;
|
||||||
bool prefault_disable;
|
bool prefault_disable;
|
||||||
bool reset;
|
bool reset;
|
||||||
int invert_brightness;
|
bool disable_display;
|
||||||
};
|
};
|
||||||
extern struct i915_params i915 __read_mostly;
|
extern struct i915_params i915 __read_mostly;
|
||||||
|
|
||||||
@@ -2012,10 +2018,12 @@ extern void intel_uncore_check_errors(struct drm_device *dev);
|
|||||||
extern void intel_uncore_fini(struct drm_device *dev);
|
extern void intel_uncore_fini(struct drm_device *dev);
|
||||||
|
|
||||||
void
|
void
|
||||||
i915_enable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe, u32 mask);
|
i915_enable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe,
|
||||||
|
u32 status_mask);
|
||||||
|
|
||||||
void
|
void
|
||||||
i915_disable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe, u32 mask);
|
i915_disable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe,
|
||||||
|
u32 status_mask);
|
||||||
|
|
||||||
/* i915_gem.c */
|
/* i915_gem.c */
|
||||||
int i915_gem_init_ioctl(struct drm_device *dev, void *data,
|
int i915_gem_init_ioctl(struct drm_device *dev, void *data,
|
||||||
@@ -2076,14 +2084,14 @@ void i915_init_vm(struct drm_i915_private *dev_priv,
|
|||||||
void i915_gem_free_object(struct drm_gem_object *obj);
|
void i915_gem_free_object(struct drm_gem_object *obj);
|
||||||
void i915_gem_vma_destroy(struct i915_vma *vma);
|
void i915_gem_vma_destroy(struct i915_vma *vma);
|
||||||
|
|
||||||
|
#define PIN_MAPPABLE 0x1
|
||||||
|
#define PIN_NONBLOCK 0x2
|
||||||
|
#define PIN_GLOBAL 0x4
|
||||||
int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,
|
int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,
|
||||||
struct i915_address_space *vm,
|
struct i915_address_space *vm,
|
||||||
uint32_t alignment,
|
uint32_t alignment,
|
||||||
bool map_and_fenceable,
|
unsigned flags);
|
||||||
bool nonblocking);
|
|
||||||
void i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj);
|
|
||||||
int __must_check i915_vma_unbind(struct i915_vma *vma);
|
int __must_check i915_vma_unbind(struct i915_vma *vma);
|
||||||
int __must_check i915_gem_object_ggtt_unbind(struct drm_i915_gem_object *obj);
|
|
||||||
int i915_gem_object_put_pages(struct drm_i915_gem_object *obj);
|
int i915_gem_object_put_pages(struct drm_i915_gem_object *obj);
|
||||||
void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv);
|
void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv);
|
||||||
void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
|
void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
|
||||||
@@ -2283,13 +2291,19 @@ i915_gem_obj_ggtt_size(struct drm_i915_gem_object *obj)
|
|||||||
static inline int __must_check
|
static inline int __must_check
|
||||||
i915_gem_obj_ggtt_pin(struct drm_i915_gem_object *obj,
|
i915_gem_obj_ggtt_pin(struct drm_i915_gem_object *obj,
|
||||||
uint32_t alignment,
|
uint32_t alignment,
|
||||||
bool map_and_fenceable,
|
unsigned flags)
|
||||||
bool nonblocking)
|
|
||||||
{
|
{
|
||||||
return i915_gem_object_pin(obj, obj_to_ggtt(obj), alignment,
|
return i915_gem_object_pin(obj, obj_to_ggtt(obj), alignment, flags | PIN_GLOBAL);
|
||||||
map_and_fenceable, nonblocking);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
i915_gem_object_ggtt_unbind(struct drm_i915_gem_object *obj)
|
||||||
|
{
|
||||||
|
return i915_vma_unbind(i915_gem_obj_to_ggtt(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
void i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj);
|
||||||
|
|
||||||
/* i915_gem_context.c */
|
/* i915_gem_context.c */
|
||||||
#define ctx_to_ppgtt(ctx) container_of((ctx)->vm, struct i915_hw_ppgtt, base)
|
#define ctx_to_ppgtt(ctx) container_of((ctx)->vm, struct i915_hw_ppgtt, base)
|
||||||
int __must_check i915_gem_context_init(struct drm_device *dev);
|
int __must_check i915_gem_context_init(struct drm_device *dev);
|
||||||
@@ -2331,8 +2345,7 @@ int __must_check i915_gem_evict_something(struct drm_device *dev,
|
|||||||
int min_size,
|
int min_size,
|
||||||
unsigned alignment,
|
unsigned alignment,
|
||||||
unsigned cache_level,
|
unsigned cache_level,
|
||||||
bool mappable,
|
unsigned flags);
|
||||||
bool nonblock);
|
|
||||||
int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle);
|
int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle);
|
||||||
int i915_gem_evict_everything(struct drm_device *dev);
|
int i915_gem_evict_everything(struct drm_device *dev);
|
||||||
|
|
||||||
@@ -2547,6 +2560,7 @@ extern void intel_modeset_suspend_hw(struct drm_device *dev);
|
|||||||
extern void intel_modeset_init(struct drm_device *dev);
|
extern void intel_modeset_init(struct drm_device *dev);
|
||||||
extern void intel_modeset_gem_init(struct drm_device *dev);
|
extern void intel_modeset_gem_init(struct drm_device *dev);
|
||||||
extern void intel_modeset_cleanup(struct drm_device *dev);
|
extern void intel_modeset_cleanup(struct drm_device *dev);
|
||||||
|
extern void intel_connector_unregister(struct intel_connector *);
|
||||||
extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
|
extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
|
||||||
extern void intel_modeset_setup_hw_state(struct drm_device *dev,
|
extern void intel_modeset_setup_hw_state(struct drm_device *dev,
|
||||||
bool force_restore);
|
bool force_restore);
|
||||||
|
|||||||
@@ -43,12 +43,6 @@ static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *o
|
|||||||
static __must_check int
|
static __must_check int
|
||||||
i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
|
i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
|
||||||
bool readonly);
|
bool readonly);
|
||||||
static __must_check int
|
|
||||||
i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
|
|
||||||
struct i915_address_space *vm,
|
|
||||||
unsigned alignment,
|
|
||||||
bool map_and_fenceable,
|
|
||||||
bool nonblocking);
|
|
||||||
static int i915_gem_phys_pwrite(struct drm_device *dev,
|
static int i915_gem_phys_pwrite(struct drm_device *dev,
|
||||||
struct drm_i915_gem_object *obj,
|
struct drm_i915_gem_object *obj,
|
||||||
struct drm_i915_gem_pwrite *args,
|
struct drm_i915_gem_pwrite *args,
|
||||||
@@ -605,7 +599,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev,
|
|||||||
char __user *user_data;
|
char __user *user_data;
|
||||||
int page_offset, page_length, ret;
|
int page_offset, page_length, ret;
|
||||||
|
|
||||||
ret = i915_gem_obj_ggtt_pin(obj, 0, true, true);
|
ret = i915_gem_obj_ggtt_pin(obj, 0, PIN_MAPPABLE | PIN_NONBLOCK);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@@ -1014,7 +1008,8 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
|
|||||||
struct timespec *timeout,
|
struct timespec *timeout,
|
||||||
struct drm_i915_file_private *file_priv)
|
struct drm_i915_file_private *file_priv)
|
||||||
{
|
{
|
||||||
drm_i915_private_t *dev_priv = ring->dev->dev_private;
|
struct drm_device *dev = ring->dev;
|
||||||
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||||
const bool irq_test_in_progress =
|
const bool irq_test_in_progress =
|
||||||
ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_ring_flag(ring);
|
ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_ring_flag(ring);
|
||||||
struct timespec before, now;
|
struct timespec before, now;
|
||||||
@@ -1029,7 +1024,7 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
|
|||||||
|
|
||||||
timeout_expire = timeout ? jiffies + timespec_to_jiffies_timeout(timeout) : 0;
|
timeout_expire = timeout ? jiffies + timespec_to_jiffies_timeout(timeout) : 0;
|
||||||
|
|
||||||
if (dev_priv->info->gen >= 6 && can_wait_boost(file_priv)) {
|
if (INTEL_INFO(dev)->gen >= 6 && can_wait_boost(file_priv)) {
|
||||||
gen6_rps_boost(dev_priv);
|
gen6_rps_boost(dev_priv);
|
||||||
if (file_priv)
|
if (file_priv)
|
||||||
mod_delayed_work(dev_priv->wq,
|
mod_delayed_work(dev_priv->wq,
|
||||||
@@ -1184,7 +1179,7 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
|
|||||||
*/
|
*/
|
||||||
static __must_check int
|
static __must_check int
|
||||||
i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
|
i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
|
||||||
struct drm_file *file,
|
struct drm_i915_file_private *file_priv,
|
||||||
bool readonly)
|
bool readonly)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = obj->base.dev;
|
struct drm_device *dev = obj->base.dev;
|
||||||
@@ -1211,7 +1206,7 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
|
|||||||
|
|
||||||
reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
|
reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
|
||||||
mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
ret = __wait_seqno(ring, seqno, reset_counter, true, NULL, file->driver_priv);
|
ret = __wait_seqno(ring, seqno, reset_counter, true, NULL, file_priv);
|
||||||
mutex_lock(&dev->struct_mutex);
|
mutex_lock(&dev->struct_mutex);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@@ -1260,7 +1255,9 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
|
|||||||
* We will repeat the flush holding the lock in the normal manner
|
* We will repeat the flush holding the lock in the normal manner
|
||||||
* to catch cases where we are gazumped.
|
* to catch cases where we are gazumped.
|
||||||
*/
|
*/
|
||||||
ret = i915_gem_object_wait_rendering__nonblocking(obj, file, !write_domain);
|
ret = i915_gem_object_wait_rendering__nonblocking(obj,
|
||||||
|
file->driver_priv,
|
||||||
|
!write_domain);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto unref;
|
goto unref;
|
||||||
|
|
||||||
@@ -1392,6 +1389,15 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|||||||
|
|
||||||
trace_i915_gem_object_fault(obj, page_offset, true, write);
|
trace_i915_gem_object_fault(obj, page_offset, true, write);
|
||||||
|
|
||||||
|
/* Try to flush the object off the GPU first without holding the lock.
|
||||||
|
* Upon reacquiring the lock, we will perform our sanity checks and then
|
||||||
|
* repeat the flush holding the lock in the normal manner to catch cases
|
||||||
|
* where we are gazumped.
|
||||||
|
*/
|
||||||
|
ret = i915_gem_object_wait_rendering__nonblocking(obj, NULL, !write);
|
||||||
|
if (ret)
|
||||||
|
goto unlock;
|
||||||
|
|
||||||
/* Access to snoopable pages through the GTT is incoherent. */
|
/* Access to snoopable pages through the GTT is incoherent. */
|
||||||
if (obj->cache_level != I915_CACHE_NONE && !HAS_LLC(dev)) {
|
if (obj->cache_level != I915_CACHE_NONE && !HAS_LLC(dev)) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
@@ -1399,7 +1405,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Now bind it into the GTT if needed */
|
/* Now bind it into the GTT if needed */
|
||||||
ret = i915_gem_obj_ggtt_pin(obj, 0, true, false);
|
ret = i915_gem_obj_ggtt_pin(obj, 0, PIN_MAPPABLE);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
@@ -1618,7 +1624,7 @@ i915_gem_mmap_gtt(struct drm_file *file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (obj->madv != I915_MADV_WILLNEED) {
|
if (obj->madv != I915_MADV_WILLNEED) {
|
||||||
DRM_ERROR("Attempting to mmap a purgeable buffer\n");
|
DRM_DEBUG("Attempting to mmap a purgeable buffer\n");
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -1972,7 +1978,7 @@ i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (obj->madv != I915_MADV_WILLNEED) {
|
if (obj->madv != I915_MADV_WILLNEED) {
|
||||||
DRM_ERROR("Attempting to obtain a purgeable object\n");
|
DRM_DEBUG("Attempting to obtain a purgeable object\n");
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2709,7 +2715,6 @@ int i915_vma_unbind(struct i915_vma *vma)
|
|||||||
|
|
||||||
if (!drm_mm_node_allocated(&vma->node)) {
|
if (!drm_mm_node_allocated(&vma->node)) {
|
||||||
i915_gem_vma_destroy(vma);
|
i915_gem_vma_destroy(vma);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2761,26 +2766,6 @@ int i915_vma_unbind(struct i915_vma *vma)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Unbinds an object from the global GTT aperture.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
i915_gem_object_ggtt_unbind(struct drm_i915_gem_object *obj)
|
|
||||||
{
|
|
||||||
struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
|
|
||||||
struct i915_address_space *ggtt = &dev_priv->gtt.base;
|
|
||||||
|
|
||||||
if (!i915_gem_obj_ggtt_bound(obj))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (i915_gem_obj_to_ggtt(obj)->pin_count)
|
|
||||||
return -EBUSY;
|
|
||||||
|
|
||||||
BUG_ON(obj->pages == NULL);
|
|
||||||
|
|
||||||
return i915_vma_unbind(i915_gem_obj_to_vma(obj, ggtt));
|
|
||||||
}
|
|
||||||
|
|
||||||
int i915_gpu_idle(struct drm_device *dev)
|
int i915_gpu_idle(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||||
@@ -3203,18 +3188,17 @@ static void i915_gem_verify_gtt(struct drm_device *dev)
|
|||||||
/**
|
/**
|
||||||
* Finds free space in the GTT aperture and binds the object there.
|
* Finds free space in the GTT aperture and binds the object there.
|
||||||
*/
|
*/
|
||||||
static int
|
static struct i915_vma *
|
||||||
i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
|
i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
|
||||||
struct i915_address_space *vm,
|
struct i915_address_space *vm,
|
||||||
unsigned alignment,
|
unsigned alignment,
|
||||||
bool map_and_fenceable,
|
unsigned flags)
|
||||||
bool nonblocking)
|
|
||||||
{
|
{
|
||||||
struct drm_device *dev = obj->base.dev;
|
struct drm_device *dev = obj->base.dev;
|
||||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||||
u32 size, fence_size, fence_alignment, unfenced_alignment;
|
u32 size, fence_size, fence_alignment, unfenced_alignment;
|
||||||
size_t gtt_max =
|
size_t gtt_max =
|
||||||
map_and_fenceable ? dev_priv->gtt.mappable_end : vm->total;
|
flags & PIN_MAPPABLE ? dev_priv->gtt.mappable_end : vm->total;
|
||||||
struct i915_vma *vma;
|
struct i915_vma *vma;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -3230,37 +3214,35 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
|
|||||||
obj->tiling_mode, false);
|
obj->tiling_mode, false);
|
||||||
|
|
||||||
if (alignment == 0)
|
if (alignment == 0)
|
||||||
alignment = map_and_fenceable ? fence_alignment :
|
alignment = flags & PIN_MAPPABLE ? fence_alignment :
|
||||||
unfenced_alignment;
|
unfenced_alignment;
|
||||||
if (map_and_fenceable && alignment & (fence_alignment - 1)) {
|
if (flags & PIN_MAPPABLE && alignment & (fence_alignment - 1)) {
|
||||||
DRM_ERROR("Invalid object alignment requested %u\n", alignment);
|
DRM_DEBUG("Invalid object alignment requested %u\n", alignment);
|
||||||
return -EINVAL;
|
return ERR_PTR(-EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
size = map_and_fenceable ? fence_size : obj->base.size;
|
size = flags & PIN_MAPPABLE ? fence_size : obj->base.size;
|
||||||
|
|
||||||
/* If the object is bigger than the entire aperture, reject it early
|
/* If the object is bigger than the entire aperture, reject it early
|
||||||
* before evicting everything in a vain attempt to find space.
|
* before evicting everything in a vain attempt to find space.
|
||||||
*/
|
*/
|
||||||
if (obj->base.size > gtt_max) {
|
if (obj->base.size > gtt_max) {
|
||||||
DRM_ERROR("Attempting to bind an object larger than the aperture: object=%zd > %s aperture=%zu\n",
|
DRM_DEBUG("Attempting to bind an object larger than the aperture: object=%zd > %s aperture=%zu\n",
|
||||||
obj->base.size,
|
obj->base.size,
|
||||||
map_and_fenceable ? "mappable" : "total",
|
flags & PIN_MAPPABLE ? "mappable" : "total",
|
||||||
gtt_max);
|
gtt_max);
|
||||||
return -E2BIG;
|
return ERR_PTR(-E2BIG);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = i915_gem_object_get_pages(obj);
|
ret = i915_gem_object_get_pages(obj);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ERR_PTR(ret);
|
||||||
|
|
||||||
i915_gem_object_pin_pages(obj);
|
i915_gem_object_pin_pages(obj);
|
||||||
|
|
||||||
vma = i915_gem_obj_lookup_or_create_vma(obj, vm);
|
vma = i915_gem_obj_lookup_or_create_vma(obj, vm);
|
||||||
if (IS_ERR(vma)) {
|
if (IS_ERR(vma))
|
||||||
ret = PTR_ERR(vma);
|
|
||||||
goto err_unpin;
|
goto err_unpin;
|
||||||
}
|
|
||||||
|
|
||||||
search_free:
|
search_free:
|
||||||
ret = drm_mm_insert_node_in_range_generic(&vm->mm, &vma->node,
|
ret = drm_mm_insert_node_in_range_generic(&vm->mm, &vma->node,
|
||||||
@@ -3269,9 +3251,7 @@ search_free:
|
|||||||
DRM_MM_SEARCH_DEFAULT);
|
DRM_MM_SEARCH_DEFAULT);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret = i915_gem_evict_something(dev, vm, size, alignment,
|
ret = i915_gem_evict_something(dev, vm, size, alignment,
|
||||||
obj->cache_level,
|
obj->cache_level, flags);
|
||||||
map_and_fenceable,
|
|
||||||
nonblocking);
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto search_free;
|
goto search_free;
|
||||||
|
|
||||||
@@ -3302,19 +3282,23 @@ search_free:
|
|||||||
obj->map_and_fenceable = mappable && fenceable;
|
obj->map_and_fenceable = mappable && fenceable;
|
||||||
}
|
}
|
||||||
|
|
||||||
WARN_ON(map_and_fenceable && !obj->map_and_fenceable);
|
WARN_ON(flags & PIN_MAPPABLE && !obj->map_and_fenceable);
|
||||||
|
|
||||||
|
trace_i915_vma_bind(vma, flags);
|
||||||
|
vma->bind_vma(vma, obj->cache_level,
|
||||||
|
flags & (PIN_MAPPABLE | PIN_GLOBAL) ? GLOBAL_BIND : 0);
|
||||||
|
|
||||||
trace_i915_vma_bind(vma, map_and_fenceable);
|
|
||||||
i915_gem_verify_gtt(dev);
|
i915_gem_verify_gtt(dev);
|
||||||
return 0;
|
return vma;
|
||||||
|
|
||||||
err_remove_node:
|
err_remove_node:
|
||||||
drm_mm_remove_node(&vma->node);
|
drm_mm_remove_node(&vma->node);
|
||||||
err_free_vma:
|
err_free_vma:
|
||||||
i915_gem_vma_destroy(vma);
|
i915_gem_vma_destroy(vma);
|
||||||
|
vma = ERR_PTR(ret);
|
||||||
err_unpin:
|
err_unpin:
|
||||||
i915_gem_object_unpin_pages(obj);
|
i915_gem_object_unpin_pages(obj);
|
||||||
return ret;
|
return vma;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -3506,7 +3490,9 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
|
|||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry(vma, &obj->vma_list, vma_link)
|
list_for_each_entry(vma, &obj->vma_list, vma_link)
|
||||||
vma->bind_vma(vma, cache_level, 0);
|
if (drm_mm_node_allocated(&vma->node))
|
||||||
|
vma->bind_vma(vma, cache_level,
|
||||||
|
obj->has_global_gtt_mapping ? GLOBAL_BIND : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry(vma, &obj->vma_list, vma_link)
|
list_for_each_entry(vma, &obj->vma_list, vma_link)
|
||||||
@@ -3675,7 +3661,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
|
|||||||
* (e.g. libkms for the bootup splash), we have to ensure that we
|
* (e.g. libkms for the bootup splash), we have to ensure that we
|
||||||
* always use map_and_fenceable for all scanout buffers.
|
* always use map_and_fenceable for all scanout buffers.
|
||||||
*/
|
*/
|
||||||
ret = i915_gem_obj_ggtt_pin(obj, alignment, true, false);
|
ret = i915_gem_obj_ggtt_pin(obj, alignment, PIN_MAPPABLE);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_unpin_display;
|
goto err_unpin_display;
|
||||||
|
|
||||||
@@ -3831,52 +3817,49 @@ int
|
|||||||
i915_gem_object_pin(struct drm_i915_gem_object *obj,
|
i915_gem_object_pin(struct drm_i915_gem_object *obj,
|
||||||
struct i915_address_space *vm,
|
struct i915_address_space *vm,
|
||||||
uint32_t alignment,
|
uint32_t alignment,
|
||||||
bool map_and_fenceable,
|
unsigned flags)
|
||||||
bool nonblocking)
|
|
||||||
{
|
{
|
||||||
const u32 flags = map_and_fenceable ? GLOBAL_BIND : 0;
|
|
||||||
struct i915_vma *vma;
|
struct i915_vma *vma;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
WARN_ON(map_and_fenceable && !i915_is_ggtt(vm));
|
if (WARN_ON(flags & (PIN_GLOBAL | PIN_MAPPABLE) && !i915_is_ggtt(vm)))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
vma = i915_gem_obj_to_vma(obj, vm);
|
vma = i915_gem_obj_to_vma(obj, vm);
|
||||||
|
|
||||||
if (vma) {
|
if (vma) {
|
||||||
if (WARN_ON(vma->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT))
|
if (WARN_ON(vma->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
if ((alignment &&
|
if ((alignment &&
|
||||||
vma->node.start & (alignment - 1)) ||
|
vma->node.start & (alignment - 1)) ||
|
||||||
(map_and_fenceable && !obj->map_and_fenceable)) {
|
(flags & PIN_MAPPABLE && !obj->map_and_fenceable)) {
|
||||||
WARN(vma->pin_count,
|
WARN(vma->pin_count,
|
||||||
"bo is already pinned with incorrect alignment:"
|
"bo is already pinned with incorrect alignment:"
|
||||||
" offset=%lx, req.alignment=%x, req.map_and_fenceable=%d,"
|
" offset=%lx, req.alignment=%x, req.map_and_fenceable=%d,"
|
||||||
" obj->map_and_fenceable=%d\n",
|
" obj->map_and_fenceable=%d\n",
|
||||||
i915_gem_obj_offset(obj, vm), alignment,
|
i915_gem_obj_offset(obj, vm), alignment,
|
||||||
map_and_fenceable,
|
flags & PIN_MAPPABLE,
|
||||||
obj->map_and_fenceable);
|
obj->map_and_fenceable);
|
||||||
ret = i915_vma_unbind(vma);
|
ret = i915_vma_unbind(vma);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
vma = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!i915_gem_obj_bound(obj, vm)) {
|
if (vma == NULL || !drm_mm_node_allocated(&vma->node)) {
|
||||||
ret = i915_gem_object_bind_to_vm(obj, vm, alignment,
|
vma = i915_gem_object_bind_to_vm(obj, vm, alignment, flags);
|
||||||
map_and_fenceable,
|
if (IS_ERR(vma))
|
||||||
nonblocking);
|
return PTR_ERR(vma);
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vma = i915_gem_obj_to_vma(obj, vm);
|
if (flags & PIN_GLOBAL && !obj->has_global_gtt_mapping)
|
||||||
|
vma->bind_vma(vma, obj->cache_level, GLOBAL_BIND);
|
||||||
|
|
||||||
vma->bind_vma(vma, obj->cache_level, flags);
|
vma->pin_count++;
|
||||||
|
if (flags & PIN_MAPPABLE)
|
||||||
i915_gem_obj_to_vma(obj, vm)->pin_count++;
|
obj->pin_mappable |= true;
|
||||||
obj->pin_mappable |= map_and_fenceable;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -3916,13 +3899,13 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (obj->madv != I915_MADV_WILLNEED) {
|
if (obj->madv != I915_MADV_WILLNEED) {
|
||||||
DRM_ERROR("Attempting to pin a purgeable buffer\n");
|
DRM_DEBUG("Attempting to pin a purgeable buffer\n");
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj->pin_filp != NULL && obj->pin_filp != file) {
|
if (obj->pin_filp != NULL && obj->pin_filp != file) {
|
||||||
DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n",
|
DRM_DEBUG("Already pinned in i915_gem_pin_ioctl(): %d\n",
|
||||||
args->handle);
|
args->handle);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -3934,7 +3917,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (obj->user_pin_count == 0) {
|
if (obj->user_pin_count == 0) {
|
||||||
ret = i915_gem_obj_ggtt_pin(obj, args->alignment, true, false);
|
ret = i915_gem_obj_ggtt_pin(obj, args->alignment, PIN_MAPPABLE);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -3969,7 +3952,7 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (obj->pin_filp != file) {
|
if (obj->pin_filp != file) {
|
||||||
DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n",
|
DRM_DEBUG("Not pinned by caller in i915_gem_pin_ioctl(): %d\n",
|
||||||
args->handle);
|
args->handle);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
|
|||||||
@@ -258,8 +258,7 @@ i915_gem_create_context(struct drm_device *dev,
|
|||||||
* context.
|
* context.
|
||||||
*/
|
*/
|
||||||
ret = i915_gem_obj_ggtt_pin(ctx->obj,
|
ret = i915_gem_obj_ggtt_pin(ctx->obj,
|
||||||
get_context_alignment(dev),
|
get_context_alignment(dev), 0);
|
||||||
false, false);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret);
|
DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret);
|
||||||
goto err_destroy;
|
goto err_destroy;
|
||||||
@@ -335,8 +334,7 @@ void i915_gem_context_reset(struct drm_device *dev)
|
|||||||
|
|
||||||
if (i == RCS) {
|
if (i == RCS) {
|
||||||
WARN_ON(i915_gem_obj_ggtt_pin(dctx->obj,
|
WARN_ON(i915_gem_obj_ggtt_pin(dctx->obj,
|
||||||
get_context_alignment(dev),
|
get_context_alignment(dev), 0));
|
||||||
false, false));
|
|
||||||
/* Fake a finish/inactive */
|
/* Fake a finish/inactive */
|
||||||
dctx->obj->base.write_domain = 0;
|
dctx->obj->base.write_domain = 0;
|
||||||
dctx->obj->active = 0;
|
dctx->obj->active = 0;
|
||||||
@@ -612,8 +610,7 @@ static int do_switch(struct intel_ring_buffer *ring,
|
|||||||
/* Trying to pin first makes error handling easier. */
|
/* Trying to pin first makes error handling easier. */
|
||||||
if (ring == &dev_priv->ring[RCS]) {
|
if (ring == &dev_priv->ring[RCS]) {
|
||||||
ret = i915_gem_obj_ggtt_pin(to->obj,
|
ret = i915_gem_obj_ggtt_pin(to->obj,
|
||||||
get_context_alignment(ring->dev),
|
get_context_alignment(ring->dev), 0);
|
||||||
false, false);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ mark_free(struct i915_vma *vma, struct list_head *unwind)
|
|||||||
int
|
int
|
||||||
i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm,
|
i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm,
|
||||||
int min_size, unsigned alignment, unsigned cache_level,
|
int min_size, unsigned alignment, unsigned cache_level,
|
||||||
bool mappable, bool nonblocking)
|
unsigned flags)
|
||||||
{
|
{
|
||||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||||
struct list_head eviction_list, unwind_list;
|
struct list_head eviction_list, unwind_list;
|
||||||
@@ -76,7 +76,7 @@ i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm,
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
int pass = 0;
|
int pass = 0;
|
||||||
|
|
||||||
trace_i915_gem_evict(dev, min_size, alignment, mappable);
|
trace_i915_gem_evict(dev, min_size, alignment, flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The goal is to evict objects and amalgamate space in LRU order.
|
* The goal is to evict objects and amalgamate space in LRU order.
|
||||||
@@ -102,7 +102,7 @@ i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
INIT_LIST_HEAD(&unwind_list);
|
INIT_LIST_HEAD(&unwind_list);
|
||||||
if (mappable) {
|
if (flags & PIN_MAPPABLE) {
|
||||||
BUG_ON(!i915_is_ggtt(vm));
|
BUG_ON(!i915_is_ggtt(vm));
|
||||||
drm_mm_init_scan_with_range(&vm->mm, min_size,
|
drm_mm_init_scan_with_range(&vm->mm, min_size,
|
||||||
alignment, cache_level, 0,
|
alignment, cache_level, 0,
|
||||||
@@ -117,7 +117,7 @@ search_again:
|
|||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nonblocking)
|
if (flags & PIN_NONBLOCK)
|
||||||
goto none;
|
goto none;
|
||||||
|
|
||||||
/* Now merge in the soon-to-be-expired objects... */
|
/* Now merge in the soon-to-be-expired objects... */
|
||||||
@@ -141,7 +141,7 @@ none:
|
|||||||
/* Can we unpin some objects such as idle hw contents,
|
/* Can we unpin some objects such as idle hw contents,
|
||||||
* or pending flips?
|
* or pending flips?
|
||||||
*/
|
*/
|
||||||
if (nonblocking)
|
if (flags & PIN_NONBLOCK)
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
/* Only idle the GPU and repeat the search once */
|
/* Only idle the GPU and repeat the search once */
|
||||||
|
|||||||
@@ -544,19 +544,23 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma,
|
|||||||
struct drm_i915_gem_object *obj = vma->obj;
|
struct drm_i915_gem_object *obj = vma->obj;
|
||||||
struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
|
struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
|
||||||
bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
|
bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
|
||||||
bool need_fence, need_mappable;
|
bool need_fence;
|
||||||
u32 flags = (entry->flags & EXEC_OBJECT_NEEDS_GTT) &&
|
unsigned flags;
|
||||||
!vma->obj->has_global_gtt_mapping ? GLOBAL_BIND : 0;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
flags = 0;
|
||||||
|
|
||||||
need_fence =
|
need_fence =
|
||||||
has_fenced_gpu_access &&
|
has_fenced_gpu_access &&
|
||||||
entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
|
entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
|
||||||
obj->tiling_mode != I915_TILING_NONE;
|
obj->tiling_mode != I915_TILING_NONE;
|
||||||
need_mappable = need_fence || need_reloc_mappable(vma);
|
if (need_fence || need_reloc_mappable(vma))
|
||||||
|
flags |= PIN_MAPPABLE;
|
||||||
|
|
||||||
ret = i915_gem_object_pin(obj, vma->vm, entry->alignment, need_mappable,
|
if (entry->flags & EXEC_OBJECT_NEEDS_GTT)
|
||||||
false);
|
flags |= PIN_GLOBAL;
|
||||||
|
|
||||||
|
ret = i915_gem_object_pin(obj, vma->vm, entry->alignment, flags);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -585,8 +589,6 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma,
|
|||||||
obj->base.pending_write_domain = I915_GEM_DOMAIN_RENDER;
|
obj->base.pending_write_domain = I915_GEM_DOMAIN_RENDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
vma->bind_vma(vma, obj->cache_level, flags);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -319,17 +319,27 @@ static void gen8_ppgtt_insert_entries(struct i915_address_space *vm,
|
|||||||
kunmap_atomic(pt_vaddr);
|
kunmap_atomic(pt_vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
|
static void gen8_ppgtt_free(struct i915_hw_ppgtt *ppgtt)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ppgtt->num_pd_pages ; i++)
|
||||||
|
kfree(ppgtt->gen8_pt_dma_addr[i]);
|
||||||
|
|
||||||
|
__free_pages(ppgtt->gen8_pt_pages, get_order(ppgtt->num_pt_pages << PAGE_SHIFT));
|
||||||
|
__free_pages(ppgtt->pd_pages, get_order(ppgtt->num_pd_pages << PAGE_SHIFT));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gen8_ppgtt_unmap_pages(struct i915_hw_ppgtt *ppgtt)
|
||||||
{
|
{
|
||||||
struct i915_hw_ppgtt *ppgtt =
|
|
||||||
container_of(vm, struct i915_hw_ppgtt, base);
|
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
list_del(&vm->global_link);
|
|
||||||
drm_mm_takedown(&vm->mm);
|
|
||||||
|
|
||||||
for (i = 0; i < ppgtt->num_pd_pages; i++) {
|
for (i = 0; i < ppgtt->num_pd_pages; i++) {
|
||||||
if (ppgtt->pd_dma_addr[i]) {
|
/* TODO: In the future we'll support sparse mappings, so this
|
||||||
|
* will have to change. */
|
||||||
|
if (!ppgtt->pd_dma_addr[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
pci_unmap_page(ppgtt->base.dev->pdev,
|
pci_unmap_page(ppgtt->base.dev->pdev,
|
||||||
ppgtt->pd_dma_addr[i],
|
ppgtt->pd_dma_addr[i],
|
||||||
PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
|
PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
|
||||||
@@ -344,11 +354,18 @@ static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kfree(ppgtt->gen8_pt_dma_addr[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__free_pages(ppgtt->gen8_pt_pages, get_order(ppgtt->num_pt_pages << PAGE_SHIFT));
|
static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
|
||||||
__free_pages(ppgtt->pd_pages, get_order(ppgtt->num_pd_pages << PAGE_SHIFT));
|
{
|
||||||
|
struct i915_hw_ppgtt *ppgtt =
|
||||||
|
container_of(vm, struct i915_hw_ppgtt, base);
|
||||||
|
|
||||||
|
list_del(&vm->global_link);
|
||||||
|
drm_mm_takedown(&vm->mm);
|
||||||
|
|
||||||
|
gen8_ppgtt_unmap_pages(ppgtt);
|
||||||
|
gen8_ppgtt_free(ppgtt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -868,7 +885,7 @@ alloc:
|
|||||||
if (ret == -ENOSPC && !retried) {
|
if (ret == -ENOSPC && !retried) {
|
||||||
ret = i915_gem_evict_something(dev, &dev_priv->gtt.base,
|
ret = i915_gem_evict_something(dev, &dev_priv->gtt.base,
|
||||||
GEN6_PD_SIZE, GEN6_PD_ALIGN,
|
GEN6_PD_SIZE, GEN6_PD_ALIGN,
|
||||||
I915_CACHE_NONE, false, true);
|
I915_CACHE_NONE, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|||||||
@@ -419,6 +419,16 @@ done:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool __cpu_fifo_underrun_reporting_enabled(struct drm_device *dev,
|
||||||
|
enum pipe pipe)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
|
||||||
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||||
|
|
||||||
|
return !intel_crtc->cpu_fifo_underrun_disabled;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* intel_set_pch_fifo_underrun_reporting - enable/disable FIFO underrun messages
|
* intel_set_pch_fifo_underrun_reporting - enable/disable FIFO underrun messages
|
||||||
* @dev: drm device
|
* @dev: drm device
|
||||||
@@ -473,38 +483,102 @@ done:
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
i915_enable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe, u32 mask)
|
__i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
|
||||||
|
u32 enable_mask, u32 status_mask)
|
||||||
{
|
{
|
||||||
u32 reg = PIPESTAT(pipe);
|
u32 reg = PIPESTAT(pipe);
|
||||||
u32 pipestat = I915_READ(reg) & 0x7fff0000;
|
u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK;
|
||||||
|
|
||||||
assert_spin_locked(&dev_priv->irq_lock);
|
assert_spin_locked(&dev_priv->irq_lock);
|
||||||
|
|
||||||
if ((pipestat & mask) == mask)
|
if (WARN_ON_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK ||
|
||||||
|
status_mask & ~PIPESTAT_INT_STATUS_MASK))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if ((pipestat & enable_mask) == enable_mask)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dev_priv->pipestat_irq_mask[pipe] |= status_mask;
|
||||||
|
|
||||||
/* Enable the interrupt, clear any pending status */
|
/* Enable the interrupt, clear any pending status */
|
||||||
pipestat |= mask | (mask >> 16);
|
pipestat |= enable_mask | status_mask;
|
||||||
I915_WRITE(reg, pipestat);
|
I915_WRITE(reg, pipestat);
|
||||||
POSTING_READ(reg);
|
POSTING_READ(reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
i915_disable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe, u32 mask)
|
__i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
|
||||||
|
u32 enable_mask, u32 status_mask)
|
||||||
{
|
{
|
||||||
u32 reg = PIPESTAT(pipe);
|
u32 reg = PIPESTAT(pipe);
|
||||||
u32 pipestat = I915_READ(reg) & 0x7fff0000;
|
u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK;
|
||||||
|
|
||||||
assert_spin_locked(&dev_priv->irq_lock);
|
assert_spin_locked(&dev_priv->irq_lock);
|
||||||
|
|
||||||
if ((pipestat & mask) == 0)
|
if (WARN_ON_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK ||
|
||||||
|
status_mask & ~PIPESTAT_INT_STATUS_MASK))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pipestat &= ~mask;
|
if ((pipestat & enable_mask) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dev_priv->pipestat_irq_mask[pipe] &= ~status_mask;
|
||||||
|
|
||||||
|
pipestat &= ~enable_mask;
|
||||||
I915_WRITE(reg, pipestat);
|
I915_WRITE(reg, pipestat);
|
||||||
POSTING_READ(reg);
|
POSTING_READ(reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 vlv_get_pipestat_enable_mask(struct drm_device *dev, u32 status_mask)
|
||||||
|
{
|
||||||
|
u32 enable_mask = status_mask << 16;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On pipe A we don't support the PSR interrupt yet, on pipe B the
|
||||||
|
* same bit MBZ.
|
||||||
|
*/
|
||||||
|
if (WARN_ON_ONCE(status_mask & PIPE_A_PSR_STATUS_VLV))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
enable_mask &= ~(PIPE_FIFO_UNDERRUN_STATUS |
|
||||||
|
SPRITE0_FLIP_DONE_INT_EN_VLV |
|
||||||
|
SPRITE1_FLIP_DONE_INT_EN_VLV);
|
||||||
|
if (status_mask & SPRITE0_FLIP_DONE_INT_STATUS_VLV)
|
||||||
|
enable_mask |= SPRITE0_FLIP_DONE_INT_EN_VLV;
|
||||||
|
if (status_mask & SPRITE1_FLIP_DONE_INT_STATUS_VLV)
|
||||||
|
enable_mask |= SPRITE1_FLIP_DONE_INT_EN_VLV;
|
||||||
|
|
||||||
|
return enable_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
|
||||||
|
u32 status_mask)
|
||||||
|
{
|
||||||
|
u32 enable_mask;
|
||||||
|
|
||||||
|
if (IS_VALLEYVIEW(dev_priv->dev))
|
||||||
|
enable_mask = vlv_get_pipestat_enable_mask(dev_priv->dev,
|
||||||
|
status_mask);
|
||||||
|
else
|
||||||
|
enable_mask = status_mask << 16;
|
||||||
|
__i915_enable_pipestat(dev_priv, pipe, enable_mask, status_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
|
||||||
|
u32 status_mask)
|
||||||
|
{
|
||||||
|
u32 enable_mask;
|
||||||
|
|
||||||
|
if (IS_VALLEYVIEW(dev_priv->dev))
|
||||||
|
enable_mask = vlv_get_pipestat_enable_mask(dev_priv->dev,
|
||||||
|
status_mask);
|
||||||
|
else
|
||||||
|
enable_mask = status_mask << 16;
|
||||||
|
__i915_disable_pipestat(dev_priv, pipe, enable_mask, status_mask);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* i915_enable_asle_pipestat - enable ASLE pipestat for OpRegion
|
* i915_enable_asle_pipestat - enable ASLE pipestat for OpRegion
|
||||||
*/
|
*/
|
||||||
@@ -518,10 +592,10 @@ static void i915_enable_asle_pipestat(struct drm_device *dev)
|
|||||||
|
|
||||||
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
||||||
|
|
||||||
i915_enable_pipestat(dev_priv, PIPE_B, PIPE_LEGACY_BLC_EVENT_ENABLE);
|
i915_enable_pipestat(dev_priv, PIPE_B, PIPE_LEGACY_BLC_EVENT_STATUS);
|
||||||
if (INTEL_INFO(dev)->gen >= 4)
|
if (INTEL_INFO(dev)->gen >= 4)
|
||||||
i915_enable_pipestat(dev_priv, PIPE_A,
|
i915_enable_pipestat(dev_priv, PIPE_A,
|
||||||
PIPE_LEGACY_BLC_EVENT_ENABLE);
|
PIPE_LEGACY_BLC_EVENT_STATUS);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
||||||
}
|
}
|
||||||
@@ -1479,18 +1553,48 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
|
|||||||
static void valleyview_pipestat_irq_handler(struct drm_device *dev, u32 iir)
|
static void valleyview_pipestat_irq_handler(struct drm_device *dev, u32 iir)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
u32 pipe_stats[I915_MAX_PIPES];
|
u32 pipe_stats[I915_MAX_PIPES] = { };
|
||||||
int pipe;
|
int pipe;
|
||||||
|
|
||||||
spin_lock(&dev_priv->irq_lock);
|
spin_lock(&dev_priv->irq_lock);
|
||||||
for_each_pipe(pipe) {
|
for_each_pipe(pipe) {
|
||||||
int reg = PIPESTAT(pipe);
|
int reg;
|
||||||
pipe_stats[pipe] = I915_READ(reg);
|
u32 mask, iir_bit = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PIPESTAT bits get signalled even when the interrupt is
|
||||||
|
* disabled with the mask bits, and some of the status bits do
|
||||||
|
* not generate interrupts at all (like the underrun bit). Hence
|
||||||
|
* we need to be careful that we only handle what we want to
|
||||||
|
* handle.
|
||||||
|
*/
|
||||||
|
mask = 0;
|
||||||
|
if (__cpu_fifo_underrun_reporting_enabled(dev, pipe))
|
||||||
|
mask |= PIPE_FIFO_UNDERRUN_STATUS;
|
||||||
|
|
||||||
|
switch (pipe) {
|
||||||
|
case PIPE_A:
|
||||||
|
iir_bit = I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
|
||||||
|
break;
|
||||||
|
case PIPE_B:
|
||||||
|
iir_bit = I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (iir & iir_bit)
|
||||||
|
mask |= dev_priv->pipestat_irq_mask[pipe];
|
||||||
|
|
||||||
|
if (!mask)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
reg = PIPESTAT(pipe);
|
||||||
|
mask |= PIPESTAT_INT_ENABLE_MASK;
|
||||||
|
pipe_stats[pipe] = I915_READ(reg) & mask;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear the PIPE*STAT regs before the IIR
|
* Clear the PIPE*STAT regs before the IIR
|
||||||
*/
|
*/
|
||||||
if (pipe_stats[pipe] & 0x8000ffff)
|
if (pipe_stats[pipe] & (PIPE_FIFO_UNDERRUN_STATUS |
|
||||||
|
PIPESTAT_INT_STATUS_MASK))
|
||||||
I915_WRITE(reg, pipe_stats[pipe]);
|
I915_WRITE(reg, pipe_stats[pipe]);
|
||||||
}
|
}
|
||||||
spin_unlock(&dev_priv->irq_lock);
|
spin_unlock(&dev_priv->irq_lock);
|
||||||
@@ -2269,13 +2373,13 @@ static int i915_enable_vblank(struct drm_device *dev, int pipe)
|
|||||||
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
||||||
if (INTEL_INFO(dev)->gen >= 4)
|
if (INTEL_INFO(dev)->gen >= 4)
|
||||||
i915_enable_pipestat(dev_priv, pipe,
|
i915_enable_pipestat(dev_priv, pipe,
|
||||||
PIPE_START_VBLANK_INTERRUPT_ENABLE);
|
PIPE_START_VBLANK_INTERRUPT_STATUS);
|
||||||
else
|
else
|
||||||
i915_enable_pipestat(dev_priv, pipe,
|
i915_enable_pipestat(dev_priv, pipe,
|
||||||
PIPE_VBLANK_INTERRUPT_ENABLE);
|
PIPE_VBLANK_INTERRUPT_STATUS);
|
||||||
|
|
||||||
/* maintain vblank delivery even in deep C-states */
|
/* maintain vblank delivery even in deep C-states */
|
||||||
if (dev_priv->info->gen == 3)
|
if (INTEL_INFO(dev)->gen == 3)
|
||||||
I915_WRITE(INSTPM, _MASKED_BIT_DISABLE(INSTPM_AGPBUSY_DIS));
|
I915_WRITE(INSTPM, _MASKED_BIT_DISABLE(INSTPM_AGPBUSY_DIS));
|
||||||
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
||||||
|
|
||||||
@@ -2309,7 +2413,7 @@ static int valleyview_enable_vblank(struct drm_device *dev, int pipe)
|
|||||||
|
|
||||||
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
||||||
i915_enable_pipestat(dev_priv, pipe,
|
i915_enable_pipestat(dev_priv, pipe,
|
||||||
PIPE_START_VBLANK_INTERRUPT_ENABLE);
|
PIPE_START_VBLANK_INTERRUPT_STATUS);
|
||||||
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2340,12 +2444,12 @@ static void i915_disable_vblank(struct drm_device *dev, int pipe)
|
|||||||
unsigned long irqflags;
|
unsigned long irqflags;
|
||||||
|
|
||||||
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
||||||
if (dev_priv->info->gen == 3)
|
if (INTEL_INFO(dev)->gen == 3)
|
||||||
I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_AGPBUSY_DIS));
|
I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_AGPBUSY_DIS));
|
||||||
|
|
||||||
i915_disable_pipestat(dev_priv, pipe,
|
i915_disable_pipestat(dev_priv, pipe,
|
||||||
PIPE_VBLANK_INTERRUPT_ENABLE |
|
PIPE_VBLANK_INTERRUPT_STATUS |
|
||||||
PIPE_START_VBLANK_INTERRUPT_ENABLE);
|
PIPE_START_VBLANK_INTERRUPT_STATUS);
|
||||||
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2368,7 +2472,7 @@ static void valleyview_disable_vblank(struct drm_device *dev, int pipe)
|
|||||||
|
|
||||||
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
||||||
i915_disable_pipestat(dev_priv, pipe,
|
i915_disable_pipestat(dev_priv, pipe,
|
||||||
PIPE_START_VBLANK_INTERRUPT_ENABLE);
|
PIPE_START_VBLANK_INTERRUPT_STATUS);
|
||||||
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2916,8 +3020,8 @@ static int valleyview_irq_postinstall(struct drm_device *dev)
|
|||||||
{
|
{
|
||||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||||
u32 enable_mask;
|
u32 enable_mask;
|
||||||
u32 pipestat_enable = PLANE_FLIP_DONE_INT_EN_VLV |
|
u32 pipestat_enable = PLANE_FLIP_DONE_INT_STATUS_VLV |
|
||||||
PIPE_CRC_DONE_ENABLE;
|
PIPE_CRC_DONE_INTERRUPT_STATUS;
|
||||||
unsigned long irqflags;
|
unsigned long irqflags;
|
||||||
|
|
||||||
enable_mask = I915_DISPLAY_PORT_INTERRUPT;
|
enable_mask = I915_DISPLAY_PORT_INTERRUPT;
|
||||||
@@ -2948,7 +3052,7 @@ static int valleyview_irq_postinstall(struct drm_device *dev)
|
|||||||
* just to make the assert_spin_locked check happy. */
|
* just to make the assert_spin_locked check happy. */
|
||||||
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
||||||
i915_enable_pipestat(dev_priv, PIPE_A, pipestat_enable);
|
i915_enable_pipestat(dev_priv, PIPE_A, pipestat_enable);
|
||||||
i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_EVENT_ENABLE);
|
i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS);
|
||||||
i915_enable_pipestat(dev_priv, PIPE_B, pipestat_enable);
|
i915_enable_pipestat(dev_priv, PIPE_B, pipestat_enable);
|
||||||
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
||||||
|
|
||||||
@@ -3171,8 +3275,8 @@ static int i8xx_irq_postinstall(struct drm_device *dev)
|
|||||||
/* Interrupt setup is already guaranteed to be single-threaded, this is
|
/* Interrupt setup is already guaranteed to be single-threaded, this is
|
||||||
* just to make the assert_spin_locked check happy. */
|
* just to make the assert_spin_locked check happy. */
|
||||||
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
||||||
i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_ENABLE);
|
i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS);
|
||||||
i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_ENABLE);
|
i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS);
|
||||||
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3354,8 +3458,8 @@ static int i915_irq_postinstall(struct drm_device *dev)
|
|||||||
/* Interrupt setup is already guaranteed to be single-threaded, this is
|
/* Interrupt setup is already guaranteed to be single-threaded, this is
|
||||||
* just to make the assert_spin_locked check happy. */
|
* just to make the assert_spin_locked check happy. */
|
||||||
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
||||||
i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_ENABLE);
|
i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS);
|
||||||
i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_ENABLE);
|
i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS);
|
||||||
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3564,9 +3668,9 @@ static int i965_irq_postinstall(struct drm_device *dev)
|
|||||||
/* Interrupt setup is already guaranteed to be single-threaded, this is
|
/* Interrupt setup is already guaranteed to be single-threaded, this is
|
||||||
* just to make the assert_spin_locked check happy. */
|
* just to make the assert_spin_locked check happy. */
|
||||||
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
||||||
i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_EVENT_ENABLE);
|
i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS);
|
||||||
i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_ENABLE);
|
i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS);
|
||||||
i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_ENABLE);
|
i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS);
|
||||||
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ struct i915_params i915 __read_mostly = {
|
|||||||
.prefault_disable = 0,
|
.prefault_disable = 0,
|
||||||
.reset = true,
|
.reset = true,
|
||||||
.invert_brightness = 0,
|
.invert_brightness = 0,
|
||||||
|
.disable_display = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
module_param_named(modeset, i915.modeset, int, 0400);
|
module_param_named(modeset, i915.modeset, int, 0400);
|
||||||
@@ -153,3 +154,6 @@ MODULE_PARM_DESC(invert_brightness,
|
|||||||
"report PCI device ID, subsystem vendor and subsystem device ID "
|
"report PCI device ID, subsystem vendor and subsystem device ID "
|
||||||
"to dri-devel@lists.freedesktop.org, if your machine needs it. "
|
"to dri-devel@lists.freedesktop.org, if your machine needs it. "
|
||||||
"It will then be included in an upcoming module version.");
|
"It will then be included in an upcoming module version.");
|
||||||
|
|
||||||
|
module_param_named(disable_display, i915.disable_display, bool, 0600);
|
||||||
|
MODULE_PARM_DESC(disable_display, "Disable display (default: false)");
|
||||||
|
|||||||
@@ -789,7 +789,8 @@
|
|||||||
#define _3D_CHICKEN3 0x02090
|
#define _3D_CHICKEN3 0x02090
|
||||||
#define _3D_CHICKEN_SF_DISABLE_OBJEND_CULL (1 << 10)
|
#define _3D_CHICKEN_SF_DISABLE_OBJEND_CULL (1 << 10)
|
||||||
#define _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL (1 << 5)
|
#define _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL (1 << 5)
|
||||||
#define _3D_CHICKEN_SDE_LIMIT_FIFO_POLY_DEPTH(x) ((x)<<1)
|
#define _3D_CHICKEN_SDE_LIMIT_FIFO_POLY_DEPTH(x) ((x)<<1) /* gen8+ */
|
||||||
|
#define _3D_CHICKEN3_SF_DISABLE_PIPELINED_ATTR_FETCH (1 << 1) /* gen6 */
|
||||||
|
|
||||||
#define MI_MODE 0x0209c
|
#define MI_MODE 0x0209c
|
||||||
# define VS_TIMER_DISPATCH (1 << 6)
|
# define VS_TIMER_DISPATCH (1 << 6)
|
||||||
@@ -1204,8 +1205,8 @@
|
|||||||
*/
|
*/
|
||||||
#define DPLL_A_OFFSET 0x6014
|
#define DPLL_A_OFFSET 0x6014
|
||||||
#define DPLL_B_OFFSET 0x6018
|
#define DPLL_B_OFFSET 0x6018
|
||||||
#define DPLL(pipe) (dev_priv->info->dpll_offsets[pipe] + \
|
#define DPLL(pipe) (dev_priv->info.dpll_offsets[pipe] + \
|
||||||
dev_priv->info->display_mmio_offset)
|
dev_priv->info.display_mmio_offset)
|
||||||
|
|
||||||
#define VGA0 0x6000
|
#define VGA0 0x6000
|
||||||
#define VGA1 0x6004
|
#define VGA1 0x6004
|
||||||
@@ -1282,8 +1283,8 @@
|
|||||||
|
|
||||||
#define DPLL_A_MD_OFFSET 0x601c /* 965+ only */
|
#define DPLL_A_MD_OFFSET 0x601c /* 965+ only */
|
||||||
#define DPLL_B_MD_OFFSET 0x6020 /* 965+ only */
|
#define DPLL_B_MD_OFFSET 0x6020 /* 965+ only */
|
||||||
#define DPLL_MD(pipe) (dev_priv->info->dpll_md_offsets[pipe] + \
|
#define DPLL_MD(pipe) (dev_priv->info.dpll_md_offsets[pipe] + \
|
||||||
dev_priv->info->display_mmio_offset)
|
dev_priv->info.display_mmio_offset)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UDI pixel divider, controlling how many pixels are stuffed into a packet.
|
* UDI pixel divider, controlling how many pixels are stuffed into a packet.
|
||||||
@@ -1352,7 +1353,7 @@
|
|||||||
#define DSTATE_PLL_D3_OFF (1<<3)
|
#define DSTATE_PLL_D3_OFF (1<<3)
|
||||||
#define DSTATE_GFX_CLOCK_GATING (1<<1)
|
#define DSTATE_GFX_CLOCK_GATING (1<<1)
|
||||||
#define DSTATE_DOT_CLOCK_GATING (1<<0)
|
#define DSTATE_DOT_CLOCK_GATING (1<<0)
|
||||||
#define DSPCLK_GATE_D (dev_priv->info->display_mmio_offset + 0x6200)
|
#define DSPCLK_GATE_D (dev_priv->info.display_mmio_offset + 0x6200)
|
||||||
# define DPUNIT_B_CLOCK_GATE_DISABLE (1 << 30) /* 965 */
|
# define DPUNIT_B_CLOCK_GATE_DISABLE (1 << 30) /* 965 */
|
||||||
# define VSUNIT_CLOCK_GATE_DISABLE (1 << 29) /* 965 */
|
# define VSUNIT_CLOCK_GATE_DISABLE (1 << 29) /* 965 */
|
||||||
# define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* 965 */
|
# define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* 965 */
|
||||||
@@ -1478,8 +1479,8 @@
|
|||||||
*/
|
*/
|
||||||
#define PALETTE_A_OFFSET 0xa000
|
#define PALETTE_A_OFFSET 0xa000
|
||||||
#define PALETTE_B_OFFSET 0xa800
|
#define PALETTE_B_OFFSET 0xa800
|
||||||
#define PALETTE(pipe) (dev_priv->info->palette_offsets[pipe] + \
|
#define PALETTE(pipe) (dev_priv->info.palette_offsets[pipe] + \
|
||||||
dev_priv->info->display_mmio_offset)
|
dev_priv->info.display_mmio_offset)
|
||||||
|
|
||||||
/* MCH MMIO space */
|
/* MCH MMIO space */
|
||||||
|
|
||||||
@@ -1969,9 +1970,9 @@
|
|||||||
#define TRANSCODER_C_OFFSET 0x62000
|
#define TRANSCODER_C_OFFSET 0x62000
|
||||||
#define TRANSCODER_EDP_OFFSET 0x6f000
|
#define TRANSCODER_EDP_OFFSET 0x6f000
|
||||||
|
|
||||||
#define _TRANSCODER2(pipe, reg) (dev_priv->info->trans_offsets[(pipe)] - \
|
#define _TRANSCODER2(pipe, reg) (dev_priv->info.trans_offsets[(pipe)] - \
|
||||||
dev_priv->info->trans_offsets[TRANSCODER_A] + (reg) + \
|
dev_priv->info.trans_offsets[TRANSCODER_A] + (reg) + \
|
||||||
dev_priv->info->display_mmio_offset)
|
dev_priv->info.display_mmio_offset)
|
||||||
|
|
||||||
#define HTOTAL(trans) _TRANSCODER2(trans, _HTOTAL_A)
|
#define HTOTAL(trans) _TRANSCODER2(trans, _HTOTAL_A)
|
||||||
#define HBLANK(trans) _TRANSCODER2(trans, _HBLANK_A)
|
#define HBLANK(trans) _TRANSCODER2(trans, _HBLANK_A)
|
||||||
@@ -2098,7 +2099,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Hotplug control (945+ only) */
|
/* Hotplug control (945+ only) */
|
||||||
#define PORT_HOTPLUG_EN (dev_priv->info->display_mmio_offset + 0x61110)
|
#define PORT_HOTPLUG_EN (dev_priv->info.display_mmio_offset + 0x61110)
|
||||||
#define PORTB_HOTPLUG_INT_EN (1 << 29)
|
#define PORTB_HOTPLUG_INT_EN (1 << 29)
|
||||||
#define PORTC_HOTPLUG_INT_EN (1 << 28)
|
#define PORTC_HOTPLUG_INT_EN (1 << 28)
|
||||||
#define PORTD_HOTPLUG_INT_EN (1 << 27)
|
#define PORTD_HOTPLUG_INT_EN (1 << 27)
|
||||||
@@ -2128,7 +2129,7 @@
|
|||||||
#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2)
|
#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2)
|
||||||
#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2)
|
#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2)
|
||||||
|
|
||||||
#define PORT_HOTPLUG_STAT (dev_priv->info->display_mmio_offset + 0x61114)
|
#define PORT_HOTPLUG_STAT (dev_priv->info.display_mmio_offset + 0x61114)
|
||||||
/*
|
/*
|
||||||
* HDMI/DP bits are gen4+
|
* HDMI/DP bits are gen4+
|
||||||
*
|
*
|
||||||
@@ -2346,9 +2347,7 @@
|
|||||||
#define VIDEO_DIP_CTL 0x61170
|
#define VIDEO_DIP_CTL 0x61170
|
||||||
/* Pre HSW: */
|
/* Pre HSW: */
|
||||||
#define VIDEO_DIP_ENABLE (1 << 31)
|
#define VIDEO_DIP_ENABLE (1 << 31)
|
||||||
#define VIDEO_DIP_PORT_B (1 << 29)
|
#define VIDEO_DIP_PORT(port) ((port) << 29)
|
||||||
#define VIDEO_DIP_PORT_C (2 << 29)
|
|
||||||
#define VIDEO_DIP_PORT_D (3 << 29)
|
|
||||||
#define VIDEO_DIP_PORT_MASK (3 << 29)
|
#define VIDEO_DIP_PORT_MASK (3 << 29)
|
||||||
#define VIDEO_DIP_ENABLE_GCP (1 << 25)
|
#define VIDEO_DIP_ENABLE_GCP (1 << 25)
|
||||||
#define VIDEO_DIP_ENABLE_AVI (1 << 21)
|
#define VIDEO_DIP_ENABLE_AVI (1 << 21)
|
||||||
@@ -2405,7 +2404,7 @@
|
|||||||
#define PP_DIVISOR 0x61210
|
#define PP_DIVISOR 0x61210
|
||||||
|
|
||||||
/* Panel fitting */
|
/* Panel fitting */
|
||||||
#define PFIT_CONTROL (dev_priv->info->display_mmio_offset + 0x61230)
|
#define PFIT_CONTROL (dev_priv->info.display_mmio_offset + 0x61230)
|
||||||
#define PFIT_ENABLE (1 << 31)
|
#define PFIT_ENABLE (1 << 31)
|
||||||
#define PFIT_PIPE_MASK (3 << 29)
|
#define PFIT_PIPE_MASK (3 << 29)
|
||||||
#define PFIT_PIPE_SHIFT 29
|
#define PFIT_PIPE_SHIFT 29
|
||||||
@@ -2423,7 +2422,7 @@
|
|||||||
#define PFIT_SCALING_PROGRAMMED (1 << 26)
|
#define PFIT_SCALING_PROGRAMMED (1 << 26)
|
||||||
#define PFIT_SCALING_PILLAR (2 << 26)
|
#define PFIT_SCALING_PILLAR (2 << 26)
|
||||||
#define PFIT_SCALING_LETTER (3 << 26)
|
#define PFIT_SCALING_LETTER (3 << 26)
|
||||||
#define PFIT_PGM_RATIOS (dev_priv->info->display_mmio_offset + 0x61234)
|
#define PFIT_PGM_RATIOS (dev_priv->info.display_mmio_offset + 0x61234)
|
||||||
/* Pre-965 */
|
/* Pre-965 */
|
||||||
#define PFIT_VERT_SCALE_SHIFT 20
|
#define PFIT_VERT_SCALE_SHIFT 20
|
||||||
#define PFIT_VERT_SCALE_MASK 0xfff00000
|
#define PFIT_VERT_SCALE_MASK 0xfff00000
|
||||||
@@ -2435,25 +2434,25 @@
|
|||||||
#define PFIT_HORIZ_SCALE_SHIFT_965 0
|
#define PFIT_HORIZ_SCALE_SHIFT_965 0
|
||||||
#define PFIT_HORIZ_SCALE_MASK_965 0x00001fff
|
#define PFIT_HORIZ_SCALE_MASK_965 0x00001fff
|
||||||
|
|
||||||
#define PFIT_AUTO_RATIOS (dev_priv->info->display_mmio_offset + 0x61238)
|
#define PFIT_AUTO_RATIOS (dev_priv->info.display_mmio_offset + 0x61238)
|
||||||
|
|
||||||
#define _VLV_BLC_PWM_CTL2_A (dev_priv->info->display_mmio_offset + 0x61250)
|
#define _VLV_BLC_PWM_CTL2_A (dev_priv->info.display_mmio_offset + 0x61250)
|
||||||
#define _VLV_BLC_PWM_CTL2_B (dev_priv->info->display_mmio_offset + 0x61350)
|
#define _VLV_BLC_PWM_CTL2_B (dev_priv->info.display_mmio_offset + 0x61350)
|
||||||
#define VLV_BLC_PWM_CTL2(pipe) _PIPE(pipe, _VLV_BLC_PWM_CTL2_A, \
|
#define VLV_BLC_PWM_CTL2(pipe) _PIPE(pipe, _VLV_BLC_PWM_CTL2_A, \
|
||||||
_VLV_BLC_PWM_CTL2_B)
|
_VLV_BLC_PWM_CTL2_B)
|
||||||
|
|
||||||
#define _VLV_BLC_PWM_CTL_A (dev_priv->info->display_mmio_offset + 0x61254)
|
#define _VLV_BLC_PWM_CTL_A (dev_priv->info.display_mmio_offset + 0x61254)
|
||||||
#define _VLV_BLC_PWM_CTL_B (dev_priv->info->display_mmio_offset + 0x61354)
|
#define _VLV_BLC_PWM_CTL_B (dev_priv->info.display_mmio_offset + 0x61354)
|
||||||
#define VLV_BLC_PWM_CTL(pipe) _PIPE(pipe, _VLV_BLC_PWM_CTL_A, \
|
#define VLV_BLC_PWM_CTL(pipe) _PIPE(pipe, _VLV_BLC_PWM_CTL_A, \
|
||||||
_VLV_BLC_PWM_CTL_B)
|
_VLV_BLC_PWM_CTL_B)
|
||||||
|
|
||||||
#define _VLV_BLC_HIST_CTL_A (dev_priv->info->display_mmio_offset + 0x61260)
|
#define _VLV_BLC_HIST_CTL_A (dev_priv->info.display_mmio_offset + 0x61260)
|
||||||
#define _VLV_BLC_HIST_CTL_B (dev_priv->info->display_mmio_offset + 0x61360)
|
#define _VLV_BLC_HIST_CTL_B (dev_priv->info.display_mmio_offset + 0x61360)
|
||||||
#define VLV_BLC_HIST_CTL(pipe) _PIPE(pipe, _VLV_BLC_HIST_CTL_A, \
|
#define VLV_BLC_HIST_CTL(pipe) _PIPE(pipe, _VLV_BLC_HIST_CTL_A, \
|
||||||
_VLV_BLC_HIST_CTL_B)
|
_VLV_BLC_HIST_CTL_B)
|
||||||
|
|
||||||
/* Backlight control */
|
/* Backlight control */
|
||||||
#define BLC_PWM_CTL2 (dev_priv->info->display_mmio_offset + 0x61250) /* 965+ only */
|
#define BLC_PWM_CTL2 (dev_priv->info.display_mmio_offset + 0x61250) /* 965+ only */
|
||||||
#define BLM_PWM_ENABLE (1 << 31)
|
#define BLM_PWM_ENABLE (1 << 31)
|
||||||
#define BLM_COMBINATION_MODE (1 << 30) /* gen4 only */
|
#define BLM_COMBINATION_MODE (1 << 30) /* gen4 only */
|
||||||
#define BLM_PIPE_SELECT (1 << 29)
|
#define BLM_PIPE_SELECT (1 << 29)
|
||||||
@@ -2476,7 +2475,7 @@
|
|||||||
#define BLM_PHASE_IN_COUNT_MASK (0xff << 8)
|
#define BLM_PHASE_IN_COUNT_MASK (0xff << 8)
|
||||||
#define BLM_PHASE_IN_INCR_SHIFT (0)
|
#define BLM_PHASE_IN_INCR_SHIFT (0)
|
||||||
#define BLM_PHASE_IN_INCR_MASK (0xff << 0)
|
#define BLM_PHASE_IN_INCR_MASK (0xff << 0)
|
||||||
#define BLC_PWM_CTL (dev_priv->info->display_mmio_offset + 0x61254)
|
#define BLC_PWM_CTL (dev_priv->info.display_mmio_offset + 0x61254)
|
||||||
/*
|
/*
|
||||||
* This is the most significant 15 bits of the number of backlight cycles in a
|
* This is the most significant 15 bits of the number of backlight cycles in a
|
||||||
* complete cycle of the modulated backlight control.
|
* complete cycle of the modulated backlight control.
|
||||||
@@ -2498,7 +2497,7 @@
|
|||||||
#define BACKLIGHT_DUTY_CYCLE_MASK_PNV (0xfffe)
|
#define BACKLIGHT_DUTY_CYCLE_MASK_PNV (0xfffe)
|
||||||
#define BLM_POLARITY_PNV (1 << 0) /* pnv only */
|
#define BLM_POLARITY_PNV (1 << 0) /* pnv only */
|
||||||
|
|
||||||
#define BLC_HIST_CTL (dev_priv->info->display_mmio_offset + 0x61260)
|
#define BLC_HIST_CTL (dev_priv->info.display_mmio_offset + 0x61260)
|
||||||
|
|
||||||
/* New registers for PCH-split platforms. Safe where new bits show up, the
|
/* New registers for PCH-split platforms. Safe where new bits show up, the
|
||||||
* register layout machtes with gen4 BLC_PWM_CTL[12]. */
|
* register layout machtes with gen4 BLC_PWM_CTL[12]. */
|
||||||
@@ -3253,6 +3252,7 @@
|
|||||||
#define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
|
#define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
|
||||||
#define PIPE_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
|
#define PIPE_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
|
||||||
#define PIPE_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
|
#define PIPE_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
|
||||||
|
#define PIPE_B_PSR_INTERRUPT_ENABLE_VLV (1UL<<19)
|
||||||
#define PIPE_HOTPLUG_TV_INTERRUPT_ENABLE (1UL<<18) /* pre-965 */
|
#define PIPE_HOTPLUG_TV_INTERRUPT_ENABLE (1UL<<18) /* pre-965 */
|
||||||
#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
|
#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
|
||||||
#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17)
|
#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17)
|
||||||
@@ -3269,13 +3269,18 @@
|
|||||||
#define PIPE_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
|
#define PIPE_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
|
||||||
#define PIPE_DPST_EVENT_STATUS (1UL<<7)
|
#define PIPE_DPST_EVENT_STATUS (1UL<<7)
|
||||||
#define PIPE_LEGACY_BLC_EVENT_STATUS (1UL<<6)
|
#define PIPE_LEGACY_BLC_EVENT_STATUS (1UL<<6)
|
||||||
|
#define PIPE_A_PSR_STATUS_VLV (1UL<<6)
|
||||||
#define PIPE_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
|
#define PIPE_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
|
||||||
#define PIPE_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
|
#define PIPE_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
|
||||||
|
#define PIPE_B_PSR_STATUS_VLV (1UL<<3)
|
||||||
#define PIPE_HOTPLUG_TV_INTERRUPT_STATUS (1UL<<2) /* pre-965 */
|
#define PIPE_HOTPLUG_TV_INTERRUPT_STATUS (1UL<<2) /* pre-965 */
|
||||||
#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
|
#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
|
||||||
#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1)
|
#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1)
|
||||||
#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0)
|
#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0)
|
||||||
|
|
||||||
|
#define PIPESTAT_INT_ENABLE_MASK 0x7fff0000
|
||||||
|
#define PIPESTAT_INT_STATUS_MASK 0x0000ffff
|
||||||
|
|
||||||
#define PIPE_A_OFFSET 0x70000
|
#define PIPE_A_OFFSET 0x70000
|
||||||
#define PIPE_B_OFFSET 0x71000
|
#define PIPE_B_OFFSET 0x71000
|
||||||
#define PIPE_C_OFFSET 0x72000
|
#define PIPE_C_OFFSET 0x72000
|
||||||
@@ -3287,9 +3292,9 @@
|
|||||||
*/
|
*/
|
||||||
#define PIPE_EDP_OFFSET 0x7f000
|
#define PIPE_EDP_OFFSET 0x7f000
|
||||||
|
|
||||||
#define _PIPE2(pipe, reg) (dev_priv->info->pipe_offsets[pipe] - \
|
#define _PIPE2(pipe, reg) (dev_priv->info.pipe_offsets[pipe] - \
|
||||||
dev_priv->info->pipe_offsets[PIPE_A] + (reg) + \
|
dev_priv->info.pipe_offsets[PIPE_A] + (reg) + \
|
||||||
dev_priv->info->display_mmio_offset)
|
dev_priv->info.display_mmio_offset)
|
||||||
|
|
||||||
#define PIPECONF(pipe) _PIPE2(pipe, _PIPEACONF)
|
#define PIPECONF(pipe) _PIPE2(pipe, _PIPEACONF)
|
||||||
#define PIPEDSL(pipe) _PIPE2(pipe, _PIPEADSL)
|
#define PIPEDSL(pipe) _PIPE2(pipe, _PIPEADSL)
|
||||||
@@ -3351,7 +3356,7 @@
|
|||||||
#define DSPARB_BEND_SHIFT 9 /* on 855 */
|
#define DSPARB_BEND_SHIFT 9 /* on 855 */
|
||||||
#define DSPARB_AEND_SHIFT 0
|
#define DSPARB_AEND_SHIFT 0
|
||||||
|
|
||||||
#define DSPFW1 (dev_priv->info->display_mmio_offset + 0x70034)
|
#define DSPFW1 (dev_priv->info.display_mmio_offset + 0x70034)
|
||||||
#define DSPFW_SR_SHIFT 23
|
#define DSPFW_SR_SHIFT 23
|
||||||
#define DSPFW_SR_MASK (0x1ff<<23)
|
#define DSPFW_SR_MASK (0x1ff<<23)
|
||||||
#define DSPFW_CURSORB_SHIFT 16
|
#define DSPFW_CURSORB_SHIFT 16
|
||||||
@@ -3359,11 +3364,11 @@
|
|||||||
#define DSPFW_PLANEB_SHIFT 8
|
#define DSPFW_PLANEB_SHIFT 8
|
||||||
#define DSPFW_PLANEB_MASK (0x7f<<8)
|
#define DSPFW_PLANEB_MASK (0x7f<<8)
|
||||||
#define DSPFW_PLANEA_MASK (0x7f)
|
#define DSPFW_PLANEA_MASK (0x7f)
|
||||||
#define DSPFW2 (dev_priv->info->display_mmio_offset + 0x70038)
|
#define DSPFW2 (dev_priv->info.display_mmio_offset + 0x70038)
|
||||||
#define DSPFW_CURSORA_MASK 0x00003f00
|
#define DSPFW_CURSORA_MASK 0x00003f00
|
||||||
#define DSPFW_CURSORA_SHIFT 8
|
#define DSPFW_CURSORA_SHIFT 8
|
||||||
#define DSPFW_PLANEC_MASK (0x7f)
|
#define DSPFW_PLANEC_MASK (0x7f)
|
||||||
#define DSPFW3 (dev_priv->info->display_mmio_offset + 0x7003c)
|
#define DSPFW3 (dev_priv->info.display_mmio_offset + 0x7003c)
|
||||||
#define DSPFW_HPLL_SR_EN (1<<31)
|
#define DSPFW_HPLL_SR_EN (1<<31)
|
||||||
#define DSPFW_CURSOR_SR_SHIFT 24
|
#define DSPFW_CURSOR_SR_SHIFT 24
|
||||||
#define PINEVIEW_SELF_REFRESH_EN (1<<30)
|
#define PINEVIEW_SELF_REFRESH_EN (1<<30)
|
||||||
@@ -3371,8 +3376,8 @@
|
|||||||
#define DSPFW_HPLL_CURSOR_SHIFT 16
|
#define DSPFW_HPLL_CURSOR_SHIFT 16
|
||||||
#define DSPFW_HPLL_CURSOR_MASK (0x3f<<16)
|
#define DSPFW_HPLL_CURSOR_MASK (0x3f<<16)
|
||||||
#define DSPFW_HPLL_SR_MASK (0x1ff)
|
#define DSPFW_HPLL_SR_MASK (0x1ff)
|
||||||
#define DSPFW4 (dev_priv->info->display_mmio_offset + 0x70070)
|
#define DSPFW4 (dev_priv->info.display_mmio_offset + 0x70070)
|
||||||
#define DSPFW7 (dev_priv->info->display_mmio_offset + 0x7007c)
|
#define DSPFW7 (dev_priv->info.display_mmio_offset + 0x7007c)
|
||||||
|
|
||||||
/* drain latency register values*/
|
/* drain latency register values*/
|
||||||
#define DRAIN_LATENCY_PRECISION_32 32
|
#define DRAIN_LATENCY_PRECISION_32 32
|
||||||
@@ -3496,12 +3501,12 @@
|
|||||||
#define PIPE_PIXEL_MASK 0x00ffffff
|
#define PIPE_PIXEL_MASK 0x00ffffff
|
||||||
#define PIPE_PIXEL_SHIFT 0
|
#define PIPE_PIXEL_SHIFT 0
|
||||||
/* GM45+ just has to be different */
|
/* GM45+ just has to be different */
|
||||||
#define _PIPEA_FRMCOUNT_GM45 (dev_priv->info->display_mmio_offset + 0x70040)
|
#define _PIPEA_FRMCOUNT_GM45 (dev_priv->info.display_mmio_offset + 0x70040)
|
||||||
#define _PIPEA_FLIPCOUNT_GM45 (dev_priv->info->display_mmio_offset + 0x70044)
|
#define _PIPEA_FLIPCOUNT_GM45 (dev_priv->info.display_mmio_offset + 0x70044)
|
||||||
#define PIPE_FRMCOUNT_GM45(pipe) _PIPE(pipe, _PIPEA_FRMCOUNT_GM45, _PIPEB_FRMCOUNT_GM45)
|
#define PIPE_FRMCOUNT_GM45(pipe) _PIPE(pipe, _PIPEA_FRMCOUNT_GM45, _PIPEB_FRMCOUNT_GM45)
|
||||||
|
|
||||||
/* Cursor A & B regs */
|
/* Cursor A & B regs */
|
||||||
#define _CURACNTR (dev_priv->info->display_mmio_offset + 0x70080)
|
#define _CURACNTR (dev_priv->info.display_mmio_offset + 0x70080)
|
||||||
/* Old style CUR*CNTR flags (desktop 8xx) */
|
/* Old style CUR*CNTR flags (desktop 8xx) */
|
||||||
#define CURSOR_ENABLE 0x80000000
|
#define CURSOR_ENABLE 0x80000000
|
||||||
#define CURSOR_GAMMA_ENABLE 0x40000000
|
#define CURSOR_GAMMA_ENABLE 0x40000000
|
||||||
@@ -3524,16 +3529,16 @@
|
|||||||
#define MCURSOR_PIPE_B (1 << 28)
|
#define MCURSOR_PIPE_B (1 << 28)
|
||||||
#define MCURSOR_GAMMA_ENABLE (1 << 26)
|
#define MCURSOR_GAMMA_ENABLE (1 << 26)
|
||||||
#define CURSOR_TRICKLE_FEED_DISABLE (1 << 14)
|
#define CURSOR_TRICKLE_FEED_DISABLE (1 << 14)
|
||||||
#define _CURABASE (dev_priv->info->display_mmio_offset + 0x70084)
|
#define _CURABASE (dev_priv->info.display_mmio_offset + 0x70084)
|
||||||
#define _CURAPOS (dev_priv->info->display_mmio_offset + 0x70088)
|
#define _CURAPOS (dev_priv->info.display_mmio_offset + 0x70088)
|
||||||
#define CURSOR_POS_MASK 0x007FF
|
#define CURSOR_POS_MASK 0x007FF
|
||||||
#define CURSOR_POS_SIGN 0x8000
|
#define CURSOR_POS_SIGN 0x8000
|
||||||
#define CURSOR_X_SHIFT 0
|
#define CURSOR_X_SHIFT 0
|
||||||
#define CURSOR_Y_SHIFT 16
|
#define CURSOR_Y_SHIFT 16
|
||||||
#define CURSIZE 0x700a0
|
#define CURSIZE 0x700a0
|
||||||
#define _CURBCNTR (dev_priv->info->display_mmio_offset + 0x700c0)
|
#define _CURBCNTR (dev_priv->info.display_mmio_offset + 0x700c0)
|
||||||
#define _CURBBASE (dev_priv->info->display_mmio_offset + 0x700c4)
|
#define _CURBBASE (dev_priv->info.display_mmio_offset + 0x700c4)
|
||||||
#define _CURBPOS (dev_priv->info->display_mmio_offset + 0x700c8)
|
#define _CURBPOS (dev_priv->info.display_mmio_offset + 0x700c8)
|
||||||
|
|
||||||
#define _CURBCNTR_IVB 0x71080
|
#define _CURBCNTR_IVB 0x71080
|
||||||
#define _CURBBASE_IVB 0x71084
|
#define _CURBBASE_IVB 0x71084
|
||||||
@@ -3608,44 +3613,44 @@
|
|||||||
#define I915_HI_DISPBASE(val) (val & DISP_BASEADDR_MASK)
|
#define I915_HI_DISPBASE(val) (val & DISP_BASEADDR_MASK)
|
||||||
|
|
||||||
/* VBIOS flags */
|
/* VBIOS flags */
|
||||||
#define SWF00 (dev_priv->info->display_mmio_offset + 0x71410)
|
#define SWF00 (dev_priv->info.display_mmio_offset + 0x71410)
|
||||||
#define SWF01 (dev_priv->info->display_mmio_offset + 0x71414)
|
#define SWF01 (dev_priv->info.display_mmio_offset + 0x71414)
|
||||||
#define SWF02 (dev_priv->info->display_mmio_offset + 0x71418)
|
#define SWF02 (dev_priv->info.display_mmio_offset + 0x71418)
|
||||||
#define SWF03 (dev_priv->info->display_mmio_offset + 0x7141c)
|
#define SWF03 (dev_priv->info.display_mmio_offset + 0x7141c)
|
||||||
#define SWF04 (dev_priv->info->display_mmio_offset + 0x71420)
|
#define SWF04 (dev_priv->info.display_mmio_offset + 0x71420)
|
||||||
#define SWF05 (dev_priv->info->display_mmio_offset + 0x71424)
|
#define SWF05 (dev_priv->info.display_mmio_offset + 0x71424)
|
||||||
#define SWF06 (dev_priv->info->display_mmio_offset + 0x71428)
|
#define SWF06 (dev_priv->info.display_mmio_offset + 0x71428)
|
||||||
#define SWF10 (dev_priv->info->display_mmio_offset + 0x70410)
|
#define SWF10 (dev_priv->info.display_mmio_offset + 0x70410)
|
||||||
#define SWF11 (dev_priv->info->display_mmio_offset + 0x70414)
|
#define SWF11 (dev_priv->info.display_mmio_offset + 0x70414)
|
||||||
#define SWF14 (dev_priv->info->display_mmio_offset + 0x71420)
|
#define SWF14 (dev_priv->info.display_mmio_offset + 0x71420)
|
||||||
#define SWF30 (dev_priv->info->display_mmio_offset + 0x72414)
|
#define SWF30 (dev_priv->info.display_mmio_offset + 0x72414)
|
||||||
#define SWF31 (dev_priv->info->display_mmio_offset + 0x72418)
|
#define SWF31 (dev_priv->info.display_mmio_offset + 0x72418)
|
||||||
#define SWF32 (dev_priv->info->display_mmio_offset + 0x7241c)
|
#define SWF32 (dev_priv->info.display_mmio_offset + 0x7241c)
|
||||||
|
|
||||||
/* Pipe B */
|
/* Pipe B */
|
||||||
#define _PIPEBDSL (dev_priv->info->display_mmio_offset + 0x71000)
|
#define _PIPEBDSL (dev_priv->info.display_mmio_offset + 0x71000)
|
||||||
#define _PIPEBCONF (dev_priv->info->display_mmio_offset + 0x71008)
|
#define _PIPEBCONF (dev_priv->info.display_mmio_offset + 0x71008)
|
||||||
#define _PIPEBSTAT (dev_priv->info->display_mmio_offset + 0x71024)
|
#define _PIPEBSTAT (dev_priv->info.display_mmio_offset + 0x71024)
|
||||||
#define _PIPEBFRAMEHIGH 0x71040
|
#define _PIPEBFRAMEHIGH 0x71040
|
||||||
#define _PIPEBFRAMEPIXEL 0x71044
|
#define _PIPEBFRAMEPIXEL 0x71044
|
||||||
#define _PIPEB_FRMCOUNT_GM45 (dev_priv->info->display_mmio_offset + 0x71040)
|
#define _PIPEB_FRMCOUNT_GM45 (dev_priv->info.display_mmio_offset + 0x71040)
|
||||||
#define _PIPEB_FLIPCOUNT_GM45 (dev_priv->info->display_mmio_offset + 0x71044)
|
#define _PIPEB_FLIPCOUNT_GM45 (dev_priv->info.display_mmio_offset + 0x71044)
|
||||||
|
|
||||||
|
|
||||||
/* Display B control */
|
/* Display B control */
|
||||||
#define _DSPBCNTR (dev_priv->info->display_mmio_offset + 0x71180)
|
#define _DSPBCNTR (dev_priv->info.display_mmio_offset + 0x71180)
|
||||||
#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
|
#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
|
||||||
#define DISPPLANE_ALPHA_TRANS_DISABLE 0
|
#define DISPPLANE_ALPHA_TRANS_DISABLE 0
|
||||||
#define DISPPLANE_SPRITE_ABOVE_DISPLAY 0
|
#define DISPPLANE_SPRITE_ABOVE_DISPLAY 0
|
||||||
#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
|
#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
|
||||||
#define _DSPBADDR (dev_priv->info->display_mmio_offset + 0x71184)
|
#define _DSPBADDR (dev_priv->info.display_mmio_offset + 0x71184)
|
||||||
#define _DSPBSTRIDE (dev_priv->info->display_mmio_offset + 0x71188)
|
#define _DSPBSTRIDE (dev_priv->info.display_mmio_offset + 0x71188)
|
||||||
#define _DSPBPOS (dev_priv->info->display_mmio_offset + 0x7118C)
|
#define _DSPBPOS (dev_priv->info.display_mmio_offset + 0x7118C)
|
||||||
#define _DSPBSIZE (dev_priv->info->display_mmio_offset + 0x71190)
|
#define _DSPBSIZE (dev_priv->info.display_mmio_offset + 0x71190)
|
||||||
#define _DSPBSURF (dev_priv->info->display_mmio_offset + 0x7119C)
|
#define _DSPBSURF (dev_priv->info.display_mmio_offset + 0x7119C)
|
||||||
#define _DSPBTILEOFF (dev_priv->info->display_mmio_offset + 0x711A4)
|
#define _DSPBTILEOFF (dev_priv->info.display_mmio_offset + 0x711A4)
|
||||||
#define _DSPBOFFSET (dev_priv->info->display_mmio_offset + 0x711A4)
|
#define _DSPBOFFSET (dev_priv->info.display_mmio_offset + 0x711A4)
|
||||||
#define _DSPBSURFLIVE (dev_priv->info->display_mmio_offset + 0x711AC)
|
#define _DSPBSURFLIVE (dev_priv->info.display_mmio_offset + 0x711AC)
|
||||||
|
|
||||||
/* Sprite A control */
|
/* Sprite A control */
|
||||||
#define _DVSACNTR 0x72180
|
#define _DVSACNTR 0x72180
|
||||||
@@ -4109,12 +4114,13 @@
|
|||||||
#define ILK_ELPIN_409_SELECT (1 << 25)
|
#define ILK_ELPIN_409_SELECT (1 << 25)
|
||||||
#define ILK_DPARB_GATE (1<<22)
|
#define ILK_DPARB_GATE (1<<22)
|
||||||
#define ILK_VSDPFD_FULL (1<<21)
|
#define ILK_VSDPFD_FULL (1<<21)
|
||||||
#define ILK_DISPLAY_CHICKEN_FUSES 0x42014
|
#define FUSE_STRAP 0x42014
|
||||||
#define ILK_INTERNAL_GRAPHICS_DISABLE (1 << 31)
|
#define ILK_INTERNAL_GRAPHICS_DISABLE (1 << 31)
|
||||||
#define ILK_INTERNAL_DISPLAY_DISABLE (1 << 30)
|
#define ILK_INTERNAL_DISPLAY_DISABLE (1 << 30)
|
||||||
#define ILK_DISPLAY_DEBUG_DISABLE (1 << 29)
|
#define ILK_DISPLAY_DEBUG_DISABLE (1 << 29)
|
||||||
#define ILK_HDCP_DISABLE (1 << 25)
|
#define ILK_HDCP_DISABLE (1 << 25)
|
||||||
#define ILK_eDP_A_DISABLE (1 << 24)
|
#define ILK_eDP_A_DISABLE (1 << 24)
|
||||||
|
#define HSW_CDCLK_LIMIT (1 << 24)
|
||||||
#define ILK_DESKTOP (1 << 23)
|
#define ILK_DESKTOP (1 << 23)
|
||||||
|
|
||||||
#define ILK_DSPCLK_GATE_D 0x42020
|
#define ILK_DSPCLK_GATE_D 0x42020
|
||||||
@@ -4178,9 +4184,6 @@
|
|||||||
#define HSW_SCRATCH1 0xb038
|
#define HSW_SCRATCH1 0xb038
|
||||||
#define HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE (1<<27)
|
#define HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE (1<<27)
|
||||||
|
|
||||||
#define HSW_FUSE_STRAP 0x42014
|
|
||||||
#define HSW_CDCLK_LIMIT (1 << 24)
|
|
||||||
|
|
||||||
/* PCH */
|
/* PCH */
|
||||||
|
|
||||||
/* south display engine interrupt: IBX */
|
/* south display engine interrupt: IBX */
|
||||||
@@ -5051,7 +5054,7 @@
|
|||||||
#define GEN8_CENTROID_PIXEL_OPT_DIS (1<<8)
|
#define GEN8_CENTROID_PIXEL_OPT_DIS (1<<8)
|
||||||
#define GEN8_SAMPLER_POWER_BYPASS_DIS (1<<1)
|
#define GEN8_SAMPLER_POWER_BYPASS_DIS (1<<1)
|
||||||
|
|
||||||
#define G4X_AUD_VID_DID (dev_priv->info->display_mmio_offset + 0x62020)
|
#define G4X_AUD_VID_DID (dev_priv->info.display_mmio_offset + 0x62020)
|
||||||
#define INTEL_AUDIO_DEVCL 0x808629FB
|
#define INTEL_AUDIO_DEVCL 0x808629FB
|
||||||
#define INTEL_AUDIO_DEVBLC 0x80862801
|
#define INTEL_AUDIO_DEVBLC 0x80862801
|
||||||
#define INTEL_AUDIO_DEVCTG 0x80862802
|
#define INTEL_AUDIO_DEVCTG 0x80862802
|
||||||
@@ -5435,6 +5438,8 @@
|
|||||||
|
|
||||||
/* SFUSE_STRAP */
|
/* SFUSE_STRAP */
|
||||||
#define SFUSE_STRAP 0xc2014
|
#define SFUSE_STRAP 0xc2014
|
||||||
|
#define SFUSE_STRAP_FUSE_LOCK (1<<13)
|
||||||
|
#define SFUSE_STRAP_DISPLAY_DISABLED (1<<7)
|
||||||
#define SFUSE_STRAP_DDIB_DETECTED (1<<2)
|
#define SFUSE_STRAP_DDIB_DETECTED (1<<2)
|
||||||
#define SFUSE_STRAP_DDIC_DETECTED (1<<1)
|
#define SFUSE_STRAP_DDIC_DETECTED (1<<1)
|
||||||
#define SFUSE_STRAP_DDID_DETECTED (1<<0)
|
#define SFUSE_STRAP_DDID_DETECTED (1<<0)
|
||||||
@@ -5904,11 +5909,11 @@
|
|||||||
#define READ_DATA_VALID(n) (1 << (n))
|
#define READ_DATA_VALID(n) (1 << (n))
|
||||||
|
|
||||||
/* For UMS only (deprecated): */
|
/* For UMS only (deprecated): */
|
||||||
#define _PALETTE_A (dev_priv->info->display_mmio_offset + 0xa000)
|
#define _PALETTE_A (dev_priv->info.display_mmio_offset + 0xa000)
|
||||||
#define _PALETTE_B (dev_priv->info->display_mmio_offset + 0xa800)
|
#define _PALETTE_B (dev_priv->info.display_mmio_offset + 0xa800)
|
||||||
#define _DPLL_A (dev_priv->info->display_mmio_offset + 0x6014)
|
#define _DPLL_A (dev_priv->info.display_mmio_offset + 0x6014)
|
||||||
#define _DPLL_B (dev_priv->info->display_mmio_offset + 0x6018)
|
#define _DPLL_B (dev_priv->info.display_mmio_offset + 0x6018)
|
||||||
#define _DPLL_A_MD (dev_priv->info->display_mmio_offset + 0x601c)
|
#define _DPLL_A_MD (dev_priv->info.display_mmio_offset + 0x601c)
|
||||||
#define _DPLL_B_MD (dev_priv->info->display_mmio_offset + 0x6020)
|
#define _DPLL_B_MD (dev_priv->info.display_mmio_offset + 0x6020)
|
||||||
|
|
||||||
#endif /* _I915_REG_H_ */
|
#endif /* _I915_REG_H_ */
|
||||||
|
|||||||
@@ -34,15 +34,15 @@ TRACE_EVENT(i915_gem_object_create,
|
|||||||
);
|
);
|
||||||
|
|
||||||
TRACE_EVENT(i915_vma_bind,
|
TRACE_EVENT(i915_vma_bind,
|
||||||
TP_PROTO(struct i915_vma *vma, bool mappable),
|
TP_PROTO(struct i915_vma *vma, unsigned flags),
|
||||||
TP_ARGS(vma, mappable),
|
TP_ARGS(vma, flags),
|
||||||
|
|
||||||
TP_STRUCT__entry(
|
TP_STRUCT__entry(
|
||||||
__field(struct drm_i915_gem_object *, obj)
|
__field(struct drm_i915_gem_object *, obj)
|
||||||
__field(struct i915_address_space *, vm)
|
__field(struct i915_address_space *, vm)
|
||||||
__field(u32, offset)
|
__field(u32, offset)
|
||||||
__field(u32, size)
|
__field(u32, size)
|
||||||
__field(bool, mappable)
|
__field(unsigned, flags)
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
@@ -50,12 +50,12 @@ TRACE_EVENT(i915_vma_bind,
|
|||||||
__entry->vm = vma->vm;
|
__entry->vm = vma->vm;
|
||||||
__entry->offset = vma->node.start;
|
__entry->offset = vma->node.start;
|
||||||
__entry->size = vma->node.size;
|
__entry->size = vma->node.size;
|
||||||
__entry->mappable = mappable;
|
__entry->flags = flags;
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_printk("obj=%p, offset=%08x size=%x%s vm=%p",
|
TP_printk("obj=%p, offset=%08x size=%x%s vm=%p",
|
||||||
__entry->obj, __entry->offset, __entry->size,
|
__entry->obj, __entry->offset, __entry->size,
|
||||||
__entry->mappable ? ", mappable" : "",
|
__entry->flags & PIN_MAPPABLE ? ", mappable" : "",
|
||||||
__entry->vm)
|
__entry->vm)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -196,26 +196,26 @@ DEFINE_EVENT(i915_gem_object, i915_gem_object_destroy,
|
|||||||
);
|
);
|
||||||
|
|
||||||
TRACE_EVENT(i915_gem_evict,
|
TRACE_EVENT(i915_gem_evict,
|
||||||
TP_PROTO(struct drm_device *dev, u32 size, u32 align, bool mappable),
|
TP_PROTO(struct drm_device *dev, u32 size, u32 align, unsigned flags),
|
||||||
TP_ARGS(dev, size, align, mappable),
|
TP_ARGS(dev, size, align, flags),
|
||||||
|
|
||||||
TP_STRUCT__entry(
|
TP_STRUCT__entry(
|
||||||
__field(u32, dev)
|
__field(u32, dev)
|
||||||
__field(u32, size)
|
__field(u32, size)
|
||||||
__field(u32, align)
|
__field(u32, align)
|
||||||
__field(bool, mappable)
|
__field(unsigned, flags)
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
__entry->dev = dev->primary->index;
|
__entry->dev = dev->primary->index;
|
||||||
__entry->size = size;
|
__entry->size = size;
|
||||||
__entry->align = align;
|
__entry->align = align;
|
||||||
__entry->mappable = mappable;
|
__entry->flags = flags;
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_printk("dev=%d, size=%d, align=%d %s",
|
TP_printk("dev=%d, size=%d, align=%d %s",
|
||||||
__entry->dev, __entry->size, __entry->align,
|
__entry->dev, __entry->size, __entry->align,
|
||||||
__entry->mappable ? ", mappable" : "")
|
__entry->flags & PIN_MAPPABLE ? ", mappable" : "")
|
||||||
);
|
);
|
||||||
|
|
||||||
TRACE_EVENT(i915_gem_evict_everything,
|
TRACE_EVENT(i915_gem_evict_everything,
|
||||||
|
|||||||
@@ -833,6 +833,7 @@ void intel_crt_init(struct drm_device *dev)
|
|||||||
crt->base.get_hw_state = intel_crt_get_hw_state;
|
crt->base.get_hw_state = intel_crt_get_hw_state;
|
||||||
}
|
}
|
||||||
intel_connector->get_hw_state = intel_connector_get_hw_state;
|
intel_connector->get_hw_state = intel_connector_get_hw_state;
|
||||||
|
intel_connector->unregister = intel_connector_unregister;
|
||||||
|
|
||||||
drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
|
drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
|
||||||
|
|
||||||
|
|||||||
@@ -1415,7 +1415,7 @@ int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
|
|||||||
|
|
||||||
if (lcpll & LCPLL_CD_SOURCE_FCLK) {
|
if (lcpll & LCPLL_CD_SOURCE_FCLK) {
|
||||||
return 800000;
|
return 800000;
|
||||||
} else if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT) {
|
} else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT) {
|
||||||
return 450000;
|
return 450000;
|
||||||
} else if (freq == LCPLL_CLK_FREQ_450) {
|
} else if (freq == LCPLL_CLK_FREQ_450) {
|
||||||
return 450000;
|
return 450000;
|
||||||
|
|||||||
@@ -51,7 +51,10 @@ static void ironlake_pch_clock_get(struct intel_crtc *crtc,
|
|||||||
|
|
||||||
static int intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
|
static int intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
|
||||||
int x, int y, struct drm_framebuffer *old_fb);
|
int x, int y, struct drm_framebuffer *old_fb);
|
||||||
|
static int intel_framebuffer_init(struct drm_device *dev,
|
||||||
|
struct intel_framebuffer *ifb,
|
||||||
|
struct drm_mode_fb_cmd2 *mode_cmd,
|
||||||
|
struct drm_i915_gem_object *obj);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int min, max;
|
int min, max;
|
||||||
@@ -1030,7 +1033,7 @@ static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv,
|
|||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
/* ILK FDI PLL is always enabled */
|
/* ILK FDI PLL is always enabled */
|
||||||
if (dev_priv->info->gen == 5)
|
if (INTEL_INFO(dev_priv->dev)->gen == 5)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* On Haswell, DDI ports are responsible for the FDI PLL setup */
|
/* On Haswell, DDI ports are responsible for the FDI PLL setup */
|
||||||
@@ -1189,7 +1192,7 @@ static void assert_sprites_disabled(struct drm_i915_private *dev_priv,
|
|||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
if (IS_VALLEYVIEW(dev)) {
|
if (IS_VALLEYVIEW(dev)) {
|
||||||
for (i = 0; i < dev_priv->num_plane; i++) {
|
for (i = 0; i < INTEL_INFO(dev)->num_sprites; i++) {
|
||||||
reg = SPCNTR(pipe, i);
|
reg = SPCNTR(pipe, i);
|
||||||
val = I915_READ(reg);
|
val = I915_READ(reg);
|
||||||
WARN((val & SP_ENABLE),
|
WARN((val & SP_ENABLE),
|
||||||
@@ -1443,7 +1446,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc)
|
|||||||
assert_pipe_disabled(dev_priv, crtc->pipe);
|
assert_pipe_disabled(dev_priv, crtc->pipe);
|
||||||
|
|
||||||
/* No really, not for ILK+ */
|
/* No really, not for ILK+ */
|
||||||
BUG_ON(dev_priv->info->gen >= 5);
|
BUG_ON(INTEL_INFO(dev)->gen >= 5);
|
||||||
|
|
||||||
/* PLL is protected by panel, make sure we can write it */
|
/* PLL is protected by panel, make sure we can write it */
|
||||||
if (IS_MOBILE(dev) && !IS_I830(dev))
|
if (IS_MOBILE(dev) && !IS_I830(dev))
|
||||||
@@ -1549,11 +1552,12 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
|
|||||||
*/
|
*/
|
||||||
static void ironlake_enable_shared_dpll(struct intel_crtc *crtc)
|
static void ironlake_enable_shared_dpll(struct intel_crtc *crtc)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
|
struct drm_device *dev = crtc->base.dev;
|
||||||
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
|
struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
|
||||||
|
|
||||||
/* PCH PLLs only available on ILK, SNB and IVB */
|
/* PCH PLLs only available on ILK, SNB and IVB */
|
||||||
BUG_ON(dev_priv->info->gen < 5);
|
BUG_ON(INTEL_INFO(dev)->gen < 5);
|
||||||
if (WARN_ON(pll == NULL))
|
if (WARN_ON(pll == NULL))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1578,11 +1582,12 @@ static void ironlake_enable_shared_dpll(struct intel_crtc *crtc)
|
|||||||
|
|
||||||
static void intel_disable_shared_dpll(struct intel_crtc *crtc)
|
static void intel_disable_shared_dpll(struct intel_crtc *crtc)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
|
struct drm_device *dev = crtc->base.dev;
|
||||||
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
|
struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
|
||||||
|
|
||||||
/* PCH only available on ILK+ */
|
/* PCH only available on ILK+ */
|
||||||
BUG_ON(dev_priv->info->gen < 5);
|
BUG_ON(INTEL_INFO(dev)->gen < 5);
|
||||||
if (WARN_ON(pll == NULL))
|
if (WARN_ON(pll == NULL))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1617,7 +1622,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
|
|||||||
uint32_t reg, val, pipeconf_val;
|
uint32_t reg, val, pipeconf_val;
|
||||||
|
|
||||||
/* PCH only available on ILK+ */
|
/* PCH only available on ILK+ */
|
||||||
BUG_ON(dev_priv->info->gen < 5);
|
BUG_ON(INTEL_INFO(dev)->gen < 5);
|
||||||
|
|
||||||
/* Make sure PCH DPLL is enabled */
|
/* Make sure PCH DPLL is enabled */
|
||||||
assert_shared_dpll_enabled(dev_priv,
|
assert_shared_dpll_enabled(dev_priv,
|
||||||
@@ -1670,7 +1675,7 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv,
|
|||||||
u32 val, pipeconf_val;
|
u32 val, pipeconf_val;
|
||||||
|
|
||||||
/* PCH only available on ILK+ */
|
/* PCH only available on ILK+ */
|
||||||
BUG_ON(dev_priv->info->gen < 5);
|
BUG_ON(INTEL_INFO(dev_priv->dev)->gen < 5);
|
||||||
|
|
||||||
/* FDI must be feeding us bits for PCH ports */
|
/* FDI must be feeding us bits for PCH ports */
|
||||||
assert_fdi_tx_enabled(dev_priv, (enum pipe) cpu_transcoder);
|
assert_fdi_tx_enabled(dev_priv, (enum pipe) cpu_transcoder);
|
||||||
@@ -1744,21 +1749,16 @@ static void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* intel_enable_pipe - enable a pipe, asserting requirements
|
* intel_enable_pipe - enable a pipe, asserting requirements
|
||||||
* @dev_priv: i915 private structure
|
* @crtc: crtc responsible for the pipe
|
||||||
* @pipe: pipe to enable
|
|
||||||
* @pch_port: on ILK+, is this pipe driving a PCH port or not
|
|
||||||
*
|
*
|
||||||
* Enable @pipe, making sure that various hardware specific requirements
|
* Enable @crtc's pipe, making sure that various hardware specific requirements
|
||||||
* are met, if applicable, e.g. PLL enabled, LVDS pairs enabled, etc.
|
* are met, if applicable, e.g. PLL enabled, LVDS pairs enabled, etc.
|
||||||
*
|
|
||||||
* @pipe should be %PIPE_A or %PIPE_B.
|
|
||||||
*
|
|
||||||
* Will wait until the pipe is actually running (i.e. first vblank) before
|
|
||||||
* returning.
|
|
||||||
*/
|
*/
|
||||||
static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
|
static void intel_enable_pipe(struct intel_crtc *crtc)
|
||||||
bool pch_port, bool dsi)
|
|
||||||
{
|
{
|
||||||
|
struct drm_device *dev = crtc->base.dev;
|
||||||
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
enum pipe pipe = crtc->pipe;
|
||||||
enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
|
enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
|
||||||
pipe);
|
pipe);
|
||||||
enum pipe pch_transcoder;
|
enum pipe pch_transcoder;
|
||||||
@@ -1780,12 +1780,12 @@ static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
|
|||||||
* need the check.
|
* need the check.
|
||||||
*/
|
*/
|
||||||
if (!HAS_PCH_SPLIT(dev_priv->dev))
|
if (!HAS_PCH_SPLIT(dev_priv->dev))
|
||||||
if (dsi)
|
if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DSI))
|
||||||
assert_dsi_pll_enabled(dev_priv);
|
assert_dsi_pll_enabled(dev_priv);
|
||||||
else
|
else
|
||||||
assert_pll_enabled(dev_priv, pipe);
|
assert_pll_enabled(dev_priv, pipe);
|
||||||
else {
|
else {
|
||||||
if (pch_port) {
|
if (crtc->config.has_pch_encoder) {
|
||||||
/* if driving the PCH, we need FDI enabled */
|
/* if driving the PCH, we need FDI enabled */
|
||||||
assert_fdi_rx_pll_enabled(dev_priv, pch_transcoder);
|
assert_fdi_rx_pll_enabled(dev_priv, pch_transcoder);
|
||||||
assert_fdi_tx_pll_enabled(dev_priv,
|
assert_fdi_tx_pll_enabled(dev_priv,
|
||||||
@@ -1796,10 +1796,23 @@ static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
|
|||||||
|
|
||||||
reg = PIPECONF(cpu_transcoder);
|
reg = PIPECONF(cpu_transcoder);
|
||||||
val = I915_READ(reg);
|
val = I915_READ(reg);
|
||||||
if (val & PIPECONF_ENABLE)
|
if (val & PIPECONF_ENABLE) {
|
||||||
|
WARN_ON(!(pipe == PIPE_A &&
|
||||||
|
dev_priv->quirks & QUIRK_PIPEA_FORCE));
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
I915_WRITE(reg, val | PIPECONF_ENABLE);
|
I915_WRITE(reg, val | PIPECONF_ENABLE);
|
||||||
|
POSTING_READ(reg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There's no guarantee the pipe will really start running now. It
|
||||||
|
* depends on the Gen, the output type and the relative order between
|
||||||
|
* pipe and plane enabling. Avoid waiting on HSW+ since it's not
|
||||||
|
* necessary.
|
||||||
|
* TODO: audit the previous gens.
|
||||||
|
*/
|
||||||
|
if (INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev))
|
||||||
intel_wait_for_vblank(dev_priv->dev, pipe);
|
intel_wait_for_vblank(dev_priv->dev, pipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1851,7 +1864,8 @@ static void intel_disable_pipe(struct drm_i915_private *dev_priv,
|
|||||||
void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
|
void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
|
||||||
enum plane plane)
|
enum plane plane)
|
||||||
{
|
{
|
||||||
u32 reg = dev_priv->info->gen >= 4 ? DSPSURF(plane) : DSPADDR(plane);
|
struct drm_device *dev = dev_priv->dev;
|
||||||
|
u32 reg = INTEL_INFO(dev)->gen >= 4 ? DSPSURF(plane) : DSPADDR(plane);
|
||||||
|
|
||||||
I915_WRITE(reg, I915_READ(reg));
|
I915_WRITE(reg, I915_READ(reg));
|
||||||
POSTING_READ(reg);
|
POSTING_READ(reg);
|
||||||
@@ -1929,6 +1943,14 @@ static bool need_vtd_wa(struct drm_device *dev)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int intel_align_height(struct drm_device *dev, int height, bool tiled)
|
||||||
|
{
|
||||||
|
int tile_height;
|
||||||
|
|
||||||
|
tile_height = tiled ? (IS_GEN2(dev) ? 16 : 8) : 1;
|
||||||
|
return ALIGN(height, tile_height);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
intel_pin_and_fence_fb_obj(struct drm_device *dev,
|
intel_pin_and_fence_fb_obj(struct drm_device *dev,
|
||||||
struct drm_i915_gem_object *obj,
|
struct drm_i915_gem_object *obj,
|
||||||
@@ -2299,33 +2321,6 @@ intel_finish_fb(struct drm_framebuffer *old_fb)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void intel_crtc_update_sarea_pos(struct drm_crtc *crtc, int x, int y)
|
|
||||||
{
|
|
||||||
struct drm_device *dev = crtc->dev;
|
|
||||||
struct drm_i915_master_private *master_priv;
|
|
||||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
||||||
|
|
||||||
if (!dev->primary->master)
|
|
||||||
return;
|
|
||||||
|
|
||||||
master_priv = dev->primary->master->driver_priv;
|
|
||||||
if (!master_priv->sarea_priv)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (intel_crtc->pipe) {
|
|
||||||
case 0:
|
|
||||||
master_priv->sarea_priv->pipeA_x = x;
|
|
||||||
master_priv->sarea_priv->pipeA_y = y;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
master_priv->sarea_priv->pipeB_x = x;
|
|
||||||
master_priv->sarea_priv->pipeB_y = y;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
|
intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
|
||||||
struct drm_framebuffer *fb)
|
struct drm_framebuffer *fb)
|
||||||
@@ -2413,8 +2408,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
|
|||||||
intel_edp_psr_update(dev);
|
intel_edp_psr_update(dev);
|
||||||
mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
|
|
||||||
intel_crtc_update_sarea_pos(crtc, x, y);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3587,8 +3580,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
|
|||||||
intel_crtc_load_lut(crtc);
|
intel_crtc_load_lut(crtc);
|
||||||
|
|
||||||
intel_update_watermarks(crtc);
|
intel_update_watermarks(crtc);
|
||||||
intel_enable_pipe(dev_priv, pipe,
|
intel_enable_pipe(intel_crtc);
|
||||||
intel_crtc->config.has_pch_encoder, false);
|
|
||||||
intel_enable_primary_plane(dev_priv, plane, pipe);
|
intel_enable_primary_plane(dev_priv, plane, pipe);
|
||||||
intel_enable_planes(crtc);
|
intel_enable_planes(crtc);
|
||||||
intel_crtc_update_cursor(crtc, true);
|
intel_crtc_update_cursor(crtc, true);
|
||||||
@@ -3733,8 +3725,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
|
|||||||
intel_ddi_enable_transcoder_func(crtc);
|
intel_ddi_enable_transcoder_func(crtc);
|
||||||
|
|
||||||
intel_update_watermarks(crtc);
|
intel_update_watermarks(crtc);
|
||||||
intel_enable_pipe(dev_priv, pipe,
|
intel_enable_pipe(intel_crtc);
|
||||||
intel_crtc->config.has_pch_encoder, false);
|
|
||||||
|
|
||||||
if (intel_crtc->config.has_pch_encoder)
|
if (intel_crtc->config.has_pch_encoder)
|
||||||
lpt_pch_enable(crtc);
|
lpt_pch_enable(crtc);
|
||||||
@@ -3748,16 +3739,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
|
|||||||
* to change the workaround. */
|
* to change the workaround. */
|
||||||
haswell_mode_set_planes_workaround(intel_crtc);
|
haswell_mode_set_planes_workaround(intel_crtc);
|
||||||
haswell_crtc_enable_planes(crtc);
|
haswell_crtc_enable_planes(crtc);
|
||||||
|
|
||||||
/*
|
|
||||||
* There seems to be a race in PCH platform hw (at least on some
|
|
||||||
* outputs) where an enabled pipe still completes any pageflip right
|
|
||||||
* away (as if the pipe is off) instead of waiting for vblank. As soon
|
|
||||||
* as the first vblank happend, everything works as expected. Hence just
|
|
||||||
* wait for one vblank before returning to avoid strange things
|
|
||||||
* happening.
|
|
||||||
*/
|
|
||||||
intel_wait_for_vblank(dev, intel_crtc->pipe);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ironlake_pfit_disable(struct intel_crtc *crtc)
|
static void ironlake_pfit_disable(struct intel_crtc *crtc)
|
||||||
@@ -4169,7 +4150,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
|
|||||||
intel_crtc_load_lut(crtc);
|
intel_crtc_load_lut(crtc);
|
||||||
|
|
||||||
intel_update_watermarks(crtc);
|
intel_update_watermarks(crtc);
|
||||||
intel_enable_pipe(dev_priv, pipe, false, is_dsi);
|
intel_enable_pipe(intel_crtc);
|
||||||
intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
|
intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
|
||||||
intel_enable_primary_plane(dev_priv, plane, pipe);
|
intel_enable_primary_plane(dev_priv, plane, pipe);
|
||||||
intel_enable_planes(crtc);
|
intel_enable_planes(crtc);
|
||||||
@@ -4208,7 +4189,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
|
|||||||
intel_crtc_load_lut(crtc);
|
intel_crtc_load_lut(crtc);
|
||||||
|
|
||||||
intel_update_watermarks(crtc);
|
intel_update_watermarks(crtc);
|
||||||
intel_enable_pipe(dev_priv, pipe, false, false);
|
intel_enable_pipe(intel_crtc);
|
||||||
intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
|
intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
|
||||||
intel_enable_primary_plane(dev_priv, plane, pipe);
|
intel_enable_primary_plane(dev_priv, plane, pipe);
|
||||||
intel_enable_planes(crtc);
|
intel_enable_planes(crtc);
|
||||||
@@ -5256,25 +5237,23 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc,
|
|||||||
pipe_config->requested_mode.hdisplay = pipe_config->pipe_src_w;
|
pipe_config->requested_mode.hdisplay = pipe_config->pipe_src_w;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void intel_crtc_mode_from_pipe_config(struct intel_crtc *intel_crtc,
|
void intel_mode_from_pipe_config(struct drm_display_mode *mode,
|
||||||
struct intel_crtc_config *pipe_config)
|
struct intel_crtc_config *pipe_config)
|
||||||
{
|
{
|
||||||
struct drm_crtc *crtc = &intel_crtc->base;
|
mode->hdisplay = pipe_config->adjusted_mode.crtc_hdisplay;
|
||||||
|
mode->htotal = pipe_config->adjusted_mode.crtc_htotal;
|
||||||
|
mode->hsync_start = pipe_config->adjusted_mode.crtc_hsync_start;
|
||||||
|
mode->hsync_end = pipe_config->adjusted_mode.crtc_hsync_end;
|
||||||
|
|
||||||
crtc->mode.hdisplay = pipe_config->adjusted_mode.crtc_hdisplay;
|
mode->vdisplay = pipe_config->adjusted_mode.crtc_vdisplay;
|
||||||
crtc->mode.htotal = pipe_config->adjusted_mode.crtc_htotal;
|
mode->vtotal = pipe_config->adjusted_mode.crtc_vtotal;
|
||||||
crtc->mode.hsync_start = pipe_config->adjusted_mode.crtc_hsync_start;
|
mode->vsync_start = pipe_config->adjusted_mode.crtc_vsync_start;
|
||||||
crtc->mode.hsync_end = pipe_config->adjusted_mode.crtc_hsync_end;
|
mode->vsync_end = pipe_config->adjusted_mode.crtc_vsync_end;
|
||||||
|
|
||||||
crtc->mode.vdisplay = pipe_config->adjusted_mode.crtc_vdisplay;
|
mode->flags = pipe_config->adjusted_mode.flags;
|
||||||
crtc->mode.vtotal = pipe_config->adjusted_mode.crtc_vtotal;
|
|
||||||
crtc->mode.vsync_start = pipe_config->adjusted_mode.crtc_vsync_start;
|
|
||||||
crtc->mode.vsync_end = pipe_config->adjusted_mode.crtc_vsync_end;
|
|
||||||
|
|
||||||
crtc->mode.flags = pipe_config->adjusted_mode.flags;
|
mode->clock = pipe_config->adjusted_mode.crtc_clock;
|
||||||
|
mode->flags |= pipe_config->adjusted_mode.flags;
|
||||||
crtc->mode.clock = pipe_config->adjusted_mode.crtc_clock;
|
|
||||||
crtc->mode.flags |= pipe_config->adjusted_mode.flags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
|
static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
|
||||||
@@ -7577,7 +7556,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
|
|||||||
|
|
||||||
/* we only need to pin inside GTT if cursor is non-phy */
|
/* we only need to pin inside GTT if cursor is non-phy */
|
||||||
mutex_lock(&dev->struct_mutex);
|
mutex_lock(&dev->struct_mutex);
|
||||||
if (!dev_priv->info->cursor_needs_physical) {
|
if (!INTEL_INFO(dev)->cursor_needs_physical) {
|
||||||
unsigned alignment;
|
unsigned alignment;
|
||||||
|
|
||||||
if (obj->tiling_mode) {
|
if (obj->tiling_mode) {
|
||||||
@@ -7625,7 +7604,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
|
|||||||
|
|
||||||
finish:
|
finish:
|
||||||
if (intel_crtc->cursor_bo) {
|
if (intel_crtc->cursor_bo) {
|
||||||
if (dev_priv->info->cursor_needs_physical) {
|
if (INTEL_INFO(dev)->cursor_needs_physical) {
|
||||||
if (intel_crtc->cursor_bo != obj)
|
if (intel_crtc->cursor_bo != obj)
|
||||||
i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo);
|
i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo);
|
||||||
} else
|
} else
|
||||||
@@ -7687,8 +7666,8 @@ static struct drm_display_mode load_detect_mode = {
|
|||||||
704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
|
704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct drm_framebuffer *
|
struct drm_framebuffer *
|
||||||
intel_framebuffer_create(struct drm_device *dev,
|
__intel_framebuffer_create(struct drm_device *dev,
|
||||||
struct drm_mode_fb_cmd2 *mode_cmd,
|
struct drm_mode_fb_cmd2 *mode_cmd,
|
||||||
struct drm_i915_gem_object *obj)
|
struct drm_i915_gem_object *obj)
|
||||||
{
|
{
|
||||||
@@ -7701,12 +7680,7 @@ intel_framebuffer_create(struct drm_device *dev,
|
|||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = i915_mutex_lock_interruptible(dev);
|
|
||||||
if (ret)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj);
|
ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj);
|
||||||
mutex_unlock(&dev->struct_mutex);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
@@ -7718,6 +7692,23 @@ err:
|
|||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct drm_framebuffer *
|
||||||
|
intel_framebuffer_create(struct drm_device *dev,
|
||||||
|
struct drm_mode_fb_cmd2 *mode_cmd,
|
||||||
|
struct drm_i915_gem_object *obj)
|
||||||
|
{
|
||||||
|
struct drm_framebuffer *fb;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = i915_mutex_lock_interruptible(dev);
|
||||||
|
if (ret)
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
fb = __intel_framebuffer_create(dev, mode_cmd, obj);
|
||||||
|
mutex_unlock(&dev->struct_mutex);
|
||||||
|
|
||||||
|
return fb;
|
||||||
|
}
|
||||||
|
|
||||||
static u32
|
static u32
|
||||||
intel_framebuffer_pitch_for_width(int width, int bpp)
|
intel_framebuffer_pitch_for_width(int width, int bpp)
|
||||||
{
|
{
|
||||||
@@ -7763,14 +7754,16 @@ mode_fits_in_fbdev(struct drm_device *dev,
|
|||||||
struct drm_i915_gem_object *obj;
|
struct drm_i915_gem_object *obj;
|
||||||
struct drm_framebuffer *fb;
|
struct drm_framebuffer *fb;
|
||||||
|
|
||||||
if (dev_priv->fbdev == NULL)
|
if (!dev_priv->fbdev)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
obj = dev_priv->fbdev->ifb.obj;
|
if (!dev_priv->fbdev->fb)
|
||||||
if (obj == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
fb = &dev_priv->fbdev->ifb.base;
|
obj = dev_priv->fbdev->fb->obj;
|
||||||
|
BUG_ON(!obj);
|
||||||
|
|
||||||
|
fb = &dev_priv->fbdev->fb->base;
|
||||||
if (fb->pitches[0] < intel_framebuffer_pitch_for_width(mode->hdisplay,
|
if (fb->pitches[0] < intel_framebuffer_pitch_for_width(mode->hdisplay,
|
||||||
fb->bits_per_pixel))
|
fb->bits_per_pixel))
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -8220,7 +8213,7 @@ void intel_mark_idle(struct drm_device *dev)
|
|||||||
intel_decrease_pllclock(crtc);
|
intel_decrease_pllclock(crtc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev_priv->info->gen >= 6)
|
if (INTEL_INFO(dev)->gen >= 6)
|
||||||
gen6_rps_idle(dev->dev_private);
|
gen6_rps_idle(dev->dev_private);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10384,8 +10377,7 @@ static bool has_edp_a(struct drm_device *dev)
|
|||||||
if ((I915_READ(DP_A) & DP_DETECTED) == 0)
|
if ((I915_READ(DP_A) & DP_DETECTED) == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (IS_GEN5(dev) &&
|
if (IS_GEN5(dev) && (I915_READ(FUSE_STRAP) & ILK_eDP_A_DISABLE))
|
||||||
(I915_READ(ILK_DISPLAY_CHICKEN_FUSES) & ILK_eDP_A_DISABLE))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -10538,18 +10530,13 @@ static void intel_setup_outputs(struct drm_device *dev)
|
|||||||
drm_helper_move_panel_connectors_to_head(dev);
|
drm_helper_move_panel_connectors_to_head(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void intel_framebuffer_fini(struct intel_framebuffer *fb)
|
|
||||||
{
|
|
||||||
drm_framebuffer_cleanup(&fb->base);
|
|
||||||
WARN_ON(!fb->obj->framebuffer_references--);
|
|
||||||
drm_gem_object_unreference_unlocked(&fb->obj->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
|
static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
|
||||||
{
|
{
|
||||||
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
|
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
|
||||||
|
|
||||||
intel_framebuffer_fini(intel_fb);
|
drm_framebuffer_cleanup(fb);
|
||||||
|
WARN_ON(!intel_fb->obj->framebuffer_references--);
|
||||||
|
drm_gem_object_unreference_unlocked(&intel_fb->obj->base);
|
||||||
kfree(intel_fb);
|
kfree(intel_fb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10573,7 +10560,7 @@ int intel_framebuffer_init(struct drm_device *dev,
|
|||||||
struct drm_mode_fb_cmd2 *mode_cmd,
|
struct drm_mode_fb_cmd2 *mode_cmd,
|
||||||
struct drm_i915_gem_object *obj)
|
struct drm_i915_gem_object *obj)
|
||||||
{
|
{
|
||||||
int aligned_height, tile_height;
|
int aligned_height;
|
||||||
int pitch_limit;
|
int pitch_limit;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -10667,9 +10654,8 @@ int intel_framebuffer_init(struct drm_device *dev,
|
|||||||
if (mode_cmd->offsets[0] != 0)
|
if (mode_cmd->offsets[0] != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
tile_height = IS_GEN2(dev) ? 16 : 8;
|
aligned_height = intel_align_height(dev, mode_cmd->height,
|
||||||
aligned_height = ALIGN(mode_cmd->height,
|
obj->tiling_mode);
|
||||||
obj->tiling_mode ? tile_height : 1);
|
|
||||||
/* FIXME drm helper for size checks (especially planar formats)? */
|
/* FIXME drm helper for size checks (especially planar formats)? */
|
||||||
if (obj->base.size < aligned_height * mode_cmd->pitches[0])
|
if (obj->base.size < aligned_height * mode_cmd->pitches[0])
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -11049,7 +11035,7 @@ void intel_modeset_init(struct drm_device *dev)
|
|||||||
|
|
||||||
for_each_pipe(i) {
|
for_each_pipe(i) {
|
||||||
intel_crtc_init(dev, i);
|
intel_crtc_init(dev, i);
|
||||||
for (j = 0; j < dev_priv->num_plane; j++) {
|
for (j = 0; j < INTEL_INFO(dev)->num_sprites; j++) {
|
||||||
ret = intel_plane_init(dev, i, j);
|
ret = intel_plane_init(dev, i, j);
|
||||||
if (ret)
|
if (ret)
|
||||||
DRM_DEBUG_KMS("pipe %c sprite %c init failed: %d\n",
|
DRM_DEBUG_KMS("pipe %c sprite %c init failed: %d\n",
|
||||||
@@ -11069,6 +11055,8 @@ void intel_modeset_init(struct drm_device *dev)
|
|||||||
|
|
||||||
/* Just in case the BIOS is doing something questionable. */
|
/* Just in case the BIOS is doing something questionable. */
|
||||||
intel_disable_fbc(dev);
|
intel_disable_fbc(dev);
|
||||||
|
|
||||||
|
intel_modeset_setup_hw_state(dev, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -11375,8 +11363,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
|
|||||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list,
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list,
|
||||||
base.head) {
|
base.head) {
|
||||||
if (crtc->active && i915.fastboot) {
|
if (crtc->active && i915.fastboot) {
|
||||||
intel_crtc_mode_from_pipe_config(crtc, &crtc->config);
|
intel_mode_from_pipe_config(&crtc->base.mode, &crtc->config);
|
||||||
|
|
||||||
DRM_DEBUG_KMS("[CRTC:%d] found active mode: ",
|
DRM_DEBUG_KMS("[CRTC:%d] found active mode: ",
|
||||||
crtc->base.base.id);
|
crtc->base.base.id);
|
||||||
drm_mode_debug_printmodeline(&crtc->base.mode);
|
drm_mode_debug_printmodeline(&crtc->base.mode);
|
||||||
@@ -11436,10 +11423,14 @@ void intel_modeset_gem_init(struct drm_device *dev)
|
|||||||
intel_modeset_init_hw(dev);
|
intel_modeset_init_hw(dev);
|
||||||
|
|
||||||
intel_setup_overlay(dev);
|
intel_setup_overlay(dev);
|
||||||
|
}
|
||||||
|
|
||||||
mutex_lock(&dev->mode_config.mutex);
|
void intel_connector_unregister(struct intel_connector *intel_connector)
|
||||||
intel_modeset_setup_hw_state(dev, false);
|
{
|
||||||
mutex_unlock(&dev->mode_config.mutex);
|
struct drm_connector *connector = &intel_connector->base;
|
||||||
|
|
||||||
|
intel_panel_destroy_backlight(connector);
|
||||||
|
drm_sysfs_connector_remove(connector);
|
||||||
}
|
}
|
||||||
|
|
||||||
void intel_modeset_cleanup(struct drm_device *dev)
|
void intel_modeset_cleanup(struct drm_device *dev)
|
||||||
@@ -11486,8 +11477,10 @@ void intel_modeset_cleanup(struct drm_device *dev)
|
|||||||
|
|
||||||
/* destroy the backlight and sysfs files before encoders/connectors */
|
/* destroy the backlight and sysfs files before encoders/connectors */
|
||||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||||
intel_panel_destroy_backlight(connector);
|
struct intel_connector *intel_connector;
|
||||||
drm_sysfs_connector_remove(connector);
|
|
||||||
|
intel_connector = to_intel_connector(connector);
|
||||||
|
intel_connector->unregister(intel_connector);
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_mode_config_cleanup(dev);
|
drm_mode_config_cleanup(dev);
|
||||||
@@ -11520,12 +11513,24 @@ int intel_modeset_vga_set_state(struct drm_device *dev, bool state)
|
|||||||
unsigned reg = INTEL_INFO(dev)->gen >= 6 ? SNB_GMCH_CTRL : INTEL_GMCH_CTRL;
|
unsigned reg = INTEL_INFO(dev)->gen >= 6 ? SNB_GMCH_CTRL : INTEL_GMCH_CTRL;
|
||||||
u16 gmch_ctrl;
|
u16 gmch_ctrl;
|
||||||
|
|
||||||
pci_read_config_word(dev_priv->bridge_dev, reg, &gmch_ctrl);
|
if (pci_read_config_word(dev_priv->bridge_dev, reg, &gmch_ctrl)) {
|
||||||
|
DRM_ERROR("failed to read control word\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!!(gmch_ctrl & INTEL_GMCH_VGA_DISABLE) == !state)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (state)
|
if (state)
|
||||||
gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE;
|
gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE;
|
||||||
else
|
else
|
||||||
gmch_ctrl |= INTEL_GMCH_VGA_DISABLE;
|
gmch_ctrl |= INTEL_GMCH_VGA_DISABLE;
|
||||||
pci_write_config_word(dev_priv->bridge_dev, reg, gmch_ctrl);
|
|
||||||
|
if (pci_write_config_word(dev_priv->bridge_dev, reg, gmch_ctrl)) {
|
||||||
|
DRM_ERROR("failed to write control word\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -784,6 +784,16 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
intel_dp_connector_unregister(struct intel_connector *intel_connector)
|
||||||
|
{
|
||||||
|
struct intel_dp *intel_dp = intel_attached_dp(&intel_connector->base);
|
||||||
|
|
||||||
|
sysfs_remove_link(&intel_connector->base.kdev->kobj,
|
||||||
|
intel_dp->adapter.dev.kobj.name);
|
||||||
|
intel_connector_unregister(intel_connector);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
intel_dp_i2c_init(struct intel_dp *intel_dp,
|
intel_dp_i2c_init(struct intel_dp *intel_dp,
|
||||||
struct intel_connector *intel_connector, const char *name)
|
struct intel_connector *intel_connector, const char *name)
|
||||||
@@ -801,9 +811,19 @@ intel_dp_i2c_init(struct intel_dp *intel_dp,
|
|||||||
strncpy(intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1);
|
strncpy(intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1);
|
||||||
intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0';
|
intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0';
|
||||||
intel_dp->adapter.algo_data = &intel_dp->algo;
|
intel_dp->adapter.algo_data = &intel_dp->algo;
|
||||||
intel_dp->adapter.dev.parent = intel_connector->base.kdev;
|
intel_dp->adapter.dev.parent = intel_connector->base.dev->dev;
|
||||||
|
|
||||||
ret = i2c_dp_aux_add_bus(&intel_dp->adapter);
|
ret = i2c_dp_aux_add_bus(&intel_dp->adapter);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = sysfs_create_link(&intel_connector->base.kdev->kobj,
|
||||||
|
&intel_dp->adapter.dev.kobj,
|
||||||
|
intel_dp->adapter.dev.kobj.name);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
i2c_del_adapter(&intel_dp->adapter);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3739,7 +3759,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
|
|||||||
fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
|
fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
|
||||||
}
|
}
|
||||||
|
|
||||||
intel_panel_init(&intel_connector->panel, fixed_mode);
|
intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
|
||||||
intel_panel_setup_backlight(connector);
|
intel_panel_setup_backlight(connector);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -3808,6 +3828,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
|
|||||||
intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
|
intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
|
||||||
else
|
else
|
||||||
intel_connector->get_hw_state = intel_connector_get_hw_state;
|
intel_connector->get_hw_state = intel_connector_get_hw_state;
|
||||||
|
intel_connector->unregister = intel_dp_connector_unregister;
|
||||||
|
|
||||||
intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10;
|
intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10;
|
||||||
if (HAS_DDI(dev)) {
|
if (HAS_DDI(dev)) {
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ struct intel_framebuffer {
|
|||||||
|
|
||||||
struct intel_fbdev {
|
struct intel_fbdev {
|
||||||
struct drm_fb_helper helper;
|
struct drm_fb_helper helper;
|
||||||
struct intel_framebuffer ifb;
|
struct intel_framebuffer *fb;
|
||||||
struct list_head fbdev_list;
|
struct list_head fbdev_list;
|
||||||
struct drm_display_mode *our_mode;
|
struct drm_display_mode *our_mode;
|
||||||
};
|
};
|
||||||
@@ -187,6 +187,14 @@ struct intel_connector {
|
|||||||
* and active (i.e. dpms ON state). */
|
* and active (i.e. dpms ON state). */
|
||||||
bool (*get_hw_state)(struct intel_connector *);
|
bool (*get_hw_state)(struct intel_connector *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Removes all interfaces through which the connector is accessible
|
||||||
|
* - like sysfs, debugfs entries -, so that no new operations can be
|
||||||
|
* started on the connector. Also makes sure all currently pending
|
||||||
|
* operations finish before returing.
|
||||||
|
*/
|
||||||
|
void (*unregister)(struct intel_connector *);
|
||||||
|
|
||||||
/* Panel info for eDP and LVDS */
|
/* Panel info for eDP and LVDS */
|
||||||
struct intel_panel panel;
|
struct intel_panel panel;
|
||||||
|
|
||||||
@@ -681,11 +689,10 @@ int intel_pin_and_fence_fb_obj(struct drm_device *dev,
|
|||||||
struct drm_i915_gem_object *obj,
|
struct drm_i915_gem_object *obj,
|
||||||
struct intel_ring_buffer *pipelined);
|
struct intel_ring_buffer *pipelined);
|
||||||
void intel_unpin_fb_obj(struct drm_i915_gem_object *obj);
|
void intel_unpin_fb_obj(struct drm_i915_gem_object *obj);
|
||||||
int intel_framebuffer_init(struct drm_device *dev,
|
struct drm_framebuffer *
|
||||||
struct intel_framebuffer *ifb,
|
__intel_framebuffer_create(struct drm_device *dev,
|
||||||
struct drm_mode_fb_cmd2 *mode_cmd,
|
struct drm_mode_fb_cmd2 *mode_cmd,
|
||||||
struct drm_i915_gem_object *obj);
|
struct drm_i915_gem_object *obj);
|
||||||
void intel_framebuffer_fini(struct intel_framebuffer *fb);
|
|
||||||
void intel_prepare_page_flip(struct drm_device *dev, int plane);
|
void intel_prepare_page_flip(struct drm_device *dev, int plane);
|
||||||
void intel_finish_page_flip(struct drm_device *dev, int pipe);
|
void intel_finish_page_flip(struct drm_device *dev, int pipe);
|
||||||
void intel_finish_page_flip_plane(struct drm_device *dev, int plane);
|
void intel_finish_page_flip_plane(struct drm_device *dev, int plane);
|
||||||
@@ -727,6 +734,8 @@ 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_device *dev, bool enable);
|
void intel_display_set_init_power(struct drm_device *dev, bool enable);
|
||||||
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,
|
||||||
|
struct intel_crtc_config *pipe_config);
|
||||||
|
|
||||||
/* intel_dp.c */
|
/* intel_dp.c */
|
||||||
void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
|
void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
|
||||||
@@ -824,7 +833,8 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
|
|||||||
|
|
||||||
/* intel_panel.c */
|
/* intel_panel.c */
|
||||||
int intel_panel_init(struct intel_panel *panel,
|
int intel_panel_init(struct intel_panel *panel,
|
||||||
struct drm_display_mode *fixed_mode);
|
struct drm_display_mode *fixed_mode,
|
||||||
|
struct drm_display_mode *downclock_mode);
|
||||||
void intel_panel_fini(struct intel_panel *panel);
|
void intel_panel_fini(struct intel_panel *panel);
|
||||||
void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
|
void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
|
||||||
struct drm_display_mode *adjusted_mode);
|
struct drm_display_mode *adjusted_mode);
|
||||||
|
|||||||
@@ -586,6 +586,7 @@ bool intel_dsi_init(struct drm_device *dev)
|
|||||||
intel_encoder->get_config = intel_dsi_get_config;
|
intel_encoder->get_config = intel_dsi_get_config;
|
||||||
|
|
||||||
intel_connector->get_hw_state = intel_connector_get_hw_state;
|
intel_connector->get_hw_state = intel_connector_get_hw_state;
|
||||||
|
intel_connector->unregister = intel_connector_unregister;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(intel_dsi_devices); i++) {
|
for (i = 0; i < ARRAY_SIZE(intel_dsi_devices); i++) {
|
||||||
dsi = &intel_dsi_devices[i];
|
dsi = &intel_dsi_devices[i];
|
||||||
@@ -624,7 +625,7 @@ bool intel_dsi_init(struct drm_device *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
|
fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
|
||||||
intel_panel_init(&intel_connector->panel, fixed_mode);
|
intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|||||||
@@ -477,6 +477,7 @@ void intel_dvo_init(struct drm_device *dev)
|
|||||||
intel_encoder->compute_config = intel_dvo_compute_config;
|
intel_encoder->compute_config = intel_dvo_compute_config;
|
||||||
intel_encoder->mode_set = intel_dvo_mode_set;
|
intel_encoder->mode_set = intel_dvo_mode_set;
|
||||||
intel_connector->get_hw_state = intel_dvo_connector_get_hw_state;
|
intel_connector->get_hw_state = intel_dvo_connector_get_hw_state;
|
||||||
|
intel_connector->unregister = intel_connector_unregister;
|
||||||
|
|
||||||
/* Now, try to find a controller */
|
/* Now, try to find a controller */
|
||||||
for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
|
for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
|
|||||||
{
|
{
|
||||||
struct intel_fbdev *ifbdev =
|
struct intel_fbdev *ifbdev =
|
||||||
container_of(helper, struct intel_fbdev, helper);
|
container_of(helper, struct intel_fbdev, helper);
|
||||||
|
struct drm_framebuffer *fb;
|
||||||
struct drm_device *dev = helper->dev;
|
struct drm_device *dev = helper->dev;
|
||||||
struct drm_mode_fb_cmd2 mode_cmd = {};
|
struct drm_mode_fb_cmd2 mode_cmd = {};
|
||||||
struct drm_i915_gem_object *obj;
|
struct drm_i915_gem_object *obj;
|
||||||
@@ -93,13 +94,17 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
|
|||||||
/* Flush everything out, we'll be doing GTT only from now on */
|
/* Flush everything out, we'll be doing GTT only from now on */
|
||||||
ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
|
ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
DRM_ERROR("failed to pin fb: %d\n", ret);
|
DRM_ERROR("failed to pin obj: %d\n", ret);
|
||||||
goto out_unref;
|
goto out_unref;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj);
|
fb = __intel_framebuffer_create(dev, &mode_cmd, obj);
|
||||||
if (ret)
|
if (IS_ERR(fb)) {
|
||||||
|
ret = PTR_ERR(fb);
|
||||||
goto out_unpin;
|
goto out_unpin;
|
||||||
|
}
|
||||||
|
|
||||||
|
ifbdev->fb = to_intel_framebuffer(fb);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -116,7 +121,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
|
|||||||
{
|
{
|
||||||
struct intel_fbdev *ifbdev =
|
struct intel_fbdev *ifbdev =
|
||||||
container_of(helper, struct intel_fbdev, helper);
|
container_of(helper, struct intel_fbdev, helper);
|
||||||
struct intel_framebuffer *intel_fb = &ifbdev->ifb;
|
struct intel_framebuffer *intel_fb = ifbdev->fb;
|
||||||
struct drm_device *dev = helper->dev;
|
struct drm_device *dev = helper->dev;
|
||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
struct fb_info *info;
|
struct fb_info *info;
|
||||||
@@ -126,11 +131,12 @@ static int intelfb_create(struct drm_fb_helper *helper,
|
|||||||
|
|
||||||
mutex_lock(&dev->struct_mutex);
|
mutex_lock(&dev->struct_mutex);
|
||||||
|
|
||||||
if (!intel_fb->obj) {
|
if (!intel_fb || WARN_ON(!intel_fb->obj)) {
|
||||||
DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n");
|
DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n");
|
||||||
ret = intelfb_alloc(helper, sizes);
|
ret = intelfb_alloc(helper, sizes);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
intel_fb = ifbdev->fb;
|
||||||
} else {
|
} else {
|
||||||
DRM_DEBUG_KMS("re-using BIOS fb\n");
|
DRM_DEBUG_KMS("re-using BIOS fb\n");
|
||||||
sizes->fb_width = intel_fb->base.width;
|
sizes->fb_width = intel_fb->base.width;
|
||||||
@@ -148,7 +154,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
|
|||||||
|
|
||||||
info->par = helper;
|
info->par = helper;
|
||||||
|
|
||||||
fb = &ifbdev->ifb.base;
|
fb = &ifbdev->fb->base;
|
||||||
|
|
||||||
ifbdev->helper.fb = fb;
|
ifbdev->helper.fb = fb;
|
||||||
ifbdev->helper.fbdev = info;
|
ifbdev->helper.fbdev = info;
|
||||||
@@ -194,7 +200,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
|
|||||||
* If the object is stolen however, it will be full of whatever
|
* If the object is stolen however, it will be full of whatever
|
||||||
* garbage was left in there.
|
* garbage was left in there.
|
||||||
*/
|
*/
|
||||||
if (ifbdev->ifb.obj->stolen)
|
if (ifbdev->fb->obj->stolen)
|
||||||
memset_io(info->screen_base, 0, info->screen_size);
|
memset_io(info->screen_base, 0, info->screen_size);
|
||||||
|
|
||||||
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
|
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
|
||||||
@@ -236,7 +242,152 @@ static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
|
|||||||
*blue = intel_crtc->lut_b[regno] << 8;
|
*blue = intel_crtc->lut_b[regno] << 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct drm_fb_helper_crtc *
|
||||||
|
intel_fb_helper_crtc(struct drm_fb_helper *fb_helper, struct drm_crtc *crtc)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < fb_helper->crtc_count; i++)
|
||||||
|
if (fb_helper->crtc_info[i].mode_set.crtc == crtc)
|
||||||
|
return &fb_helper->crtc_info[i];
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to read the BIOS display configuration and use it for the initial
|
||||||
|
* fb configuration.
|
||||||
|
*
|
||||||
|
* The BIOS or boot loader will generally create an initial display
|
||||||
|
* configuration for us that includes some set of active pipes and displays.
|
||||||
|
* This routine tries to figure out which pipes and connectors are active
|
||||||
|
* and stuffs them into the crtcs and modes array given to us by the
|
||||||
|
* drm_fb_helper code.
|
||||||
|
*
|
||||||
|
* The overall sequence is:
|
||||||
|
* intel_fbdev_init - from driver load
|
||||||
|
* intel_fbdev_init_bios - initialize the intel_fbdev using BIOS data
|
||||||
|
* drm_fb_helper_init - build fb helper structs
|
||||||
|
* drm_fb_helper_single_add_all_connectors - more fb helper structs
|
||||||
|
* intel_fbdev_initial_config - apply the config
|
||||||
|
* drm_fb_helper_initial_config - call ->probe then register_framebuffer()
|
||||||
|
* drm_setup_crtcs - build crtc config for fbdev
|
||||||
|
* intel_fb_initial_config - find active connectors etc
|
||||||
|
* drm_fb_helper_single_fb_probe - set up fbdev
|
||||||
|
* intelfb_create - re-use or alloc fb, build out fbdev structs
|
||||||
|
*
|
||||||
|
* Note that we don't make special consideration whether we could actually
|
||||||
|
* switch to the selected modes without a full modeset. E.g. when the display
|
||||||
|
* is in VGA mode we need to recalculate watermarks and set a new high-res
|
||||||
|
* framebuffer anyway.
|
||||||
|
*/
|
||||||
|
static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
|
||||||
|
struct drm_fb_helper_crtc **crtcs,
|
||||||
|
struct drm_display_mode **modes,
|
||||||
|
bool *enabled, int width, int height)
|
||||||
|
{
|
||||||
|
struct drm_device *dev = fb_helper->dev;
|
||||||
|
int i, j;
|
||||||
|
bool *save_enabled;
|
||||||
|
bool any_enabled = false;
|
||||||
|
|
||||||
|
save_enabled = kcalloc(dev->mode_config.num_connector, sizeof(bool),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!save_enabled)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
memcpy(save_enabled, enabled, dev->mode_config.num_connector);
|
||||||
|
|
||||||
|
for (i = 0; i < fb_helper->connector_count; i++) {
|
||||||
|
struct drm_fb_helper_connector *fb_conn;
|
||||||
|
struct drm_connector *connector;
|
||||||
|
struct drm_encoder *encoder;
|
||||||
|
struct drm_fb_helper_crtc *new_crtc;
|
||||||
|
|
||||||
|
fb_conn = fb_helper->connector_info[i];
|
||||||
|
connector = fb_conn->connector;
|
||||||
|
if (!enabled[i]) {
|
||||||
|
DRM_DEBUG_KMS("connector %d not enabled, skipping\n",
|
||||||
|
connector->base.id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
encoder = connector->encoder;
|
||||||
|
if (!encoder || WARN_ON(!encoder->crtc)) {
|
||||||
|
DRM_DEBUG_KMS("connector %d has no encoder or crtc, skipping\n",
|
||||||
|
connector->base.id);
|
||||||
|
enabled[i] = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_crtc = intel_fb_helper_crtc(fb_helper, encoder->crtc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure we're not trying to drive multiple connectors
|
||||||
|
* with a single CRTC, since our cloning support may not
|
||||||
|
* match the BIOS.
|
||||||
|
*/
|
||||||
|
for (j = 0; j < fb_helper->connector_count; j++) {
|
||||||
|
if (crtcs[j] == new_crtc) {
|
||||||
|
any_enabled = false;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n",
|
||||||
|
fb_conn->connector->base.id);
|
||||||
|
|
||||||
|
/* go for command line mode first */
|
||||||
|
modes[i] = drm_pick_cmdline_mode(fb_conn, width, height);
|
||||||
|
|
||||||
|
/* try for preferred next */
|
||||||
|
if (!modes[i]) {
|
||||||
|
DRM_DEBUG_KMS("looking for preferred mode on connector %d\n",
|
||||||
|
fb_conn->connector->base.id);
|
||||||
|
modes[i] = drm_has_preferred_mode(fb_conn, width,
|
||||||
|
height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* last resort: use current mode */
|
||||||
|
if (!modes[i]) {
|
||||||
|
/*
|
||||||
|
* IMPORTANT: We want to use the adjusted mode (i.e.
|
||||||
|
* after the panel fitter upscaling) as the initial
|
||||||
|
* config, not the input mode, which is what crtc->mode
|
||||||
|
* usually contains. But since our current fastboot
|
||||||
|
* code puts a mode derived from the post-pfit timings
|
||||||
|
* into crtc->mode this works out correctly. We don't
|
||||||
|
* use hwmode anywhere right now, so use it for this
|
||||||
|
* since the fb helper layer wants a pointer to
|
||||||
|
* something we own.
|
||||||
|
*/
|
||||||
|
intel_mode_from_pipe_config(&encoder->crtc->hwmode,
|
||||||
|
&to_intel_crtc(encoder->crtc)->config);
|
||||||
|
modes[i] = &encoder->crtc->hwmode;
|
||||||
|
}
|
||||||
|
crtcs[i] = new_crtc;
|
||||||
|
|
||||||
|
DRM_DEBUG_KMS("connector %s on crtc %d: %s\n",
|
||||||
|
drm_get_connector_name(connector),
|
||||||
|
encoder->crtc->base.id,
|
||||||
|
modes[i]->name);
|
||||||
|
|
||||||
|
any_enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (!any_enabled) {
|
||||||
|
memcpy(enabled, save_enabled, dev->mode_config.num_connector);
|
||||||
|
kfree(save_enabled);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(save_enabled);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
|
static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
|
||||||
|
.initial_config = intel_fb_initial_config,
|
||||||
.gamma_set = intel_crtc_fb_gamma_set,
|
.gamma_set = intel_crtc_fb_gamma_set,
|
||||||
.gamma_get = intel_crtc_fb_gamma_get,
|
.gamma_get = intel_crtc_fb_gamma_get,
|
||||||
.fb_probe = intelfb_create,
|
.fb_probe = intelfb_create,
|
||||||
@@ -258,8 +409,8 @@ static void intel_fbdev_destroy(struct drm_device *dev,
|
|||||||
|
|
||||||
drm_fb_helper_fini(&ifbdev->helper);
|
drm_fb_helper_fini(&ifbdev->helper);
|
||||||
|
|
||||||
drm_framebuffer_unregister_private(&ifbdev->ifb.base);
|
drm_framebuffer_unregister_private(&ifbdev->fb->base);
|
||||||
intel_framebuffer_fini(&ifbdev->ifb);
|
drm_framebuffer_remove(&ifbdev->fb->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
int intel_fbdev_init(struct drm_device *dev)
|
int intel_fbdev_init(struct drm_device *dev)
|
||||||
@@ -322,7 +473,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state)
|
|||||||
* been restored from swap. If the object is stolen however, it will be
|
* been restored from swap. If the object is stolen however, it will be
|
||||||
* full of whatever garbage was left in there.
|
* full of whatever garbage was left in there.
|
||||||
*/
|
*/
|
||||||
if (state == FBINFO_STATE_RUNNING && ifbdev->ifb.obj->stolen)
|
if (state == FBINFO_STATE_RUNNING && ifbdev->fb->obj->stolen)
|
||||||
memset_io(info->screen_base, 0, info->screen_size);
|
memset_io(info->screen_base, 0, info->screen_size);
|
||||||
|
|
||||||
fb_set_suspend(info, state);
|
fb_set_suspend(info, state);
|
||||||
|
|||||||
@@ -425,7 +425,7 @@ static void g4x_set_infoframes(struct drm_encoder *encoder,
|
|||||||
struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
|
struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
|
||||||
u32 reg = VIDEO_DIP_CTL;
|
u32 reg = VIDEO_DIP_CTL;
|
||||||
u32 val = I915_READ(reg);
|
u32 val = I915_READ(reg);
|
||||||
u32 port;
|
u32 port = VIDEO_DIP_PORT(intel_dig_port->port);
|
||||||
|
|
||||||
assert_hdmi_port_disabled(intel_hdmi);
|
assert_hdmi_port_disabled(intel_hdmi);
|
||||||
|
|
||||||
@@ -449,18 +449,6 @@ static void g4x_set_infoframes(struct drm_encoder *encoder,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (intel_dig_port->port) {
|
|
||||||
case PORT_B:
|
|
||||||
port = VIDEO_DIP_PORT_B;
|
|
||||||
break;
|
|
||||||
case PORT_C:
|
|
||||||
port = VIDEO_DIP_PORT_C;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
BUG();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (port != (val & VIDEO_DIP_PORT_MASK)) {
|
if (port != (val & VIDEO_DIP_PORT_MASK)) {
|
||||||
if (val & VIDEO_DIP_ENABLE) {
|
if (val & VIDEO_DIP_ENABLE) {
|
||||||
val &= ~VIDEO_DIP_ENABLE;
|
val &= ~VIDEO_DIP_ENABLE;
|
||||||
@@ -491,7 +479,7 @@ static void ibx_set_infoframes(struct drm_encoder *encoder,
|
|||||||
struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
|
struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
|
||||||
u32 reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
|
u32 reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
|
||||||
u32 val = I915_READ(reg);
|
u32 val = I915_READ(reg);
|
||||||
u32 port;
|
u32 port = VIDEO_DIP_PORT(intel_dig_port->port);
|
||||||
|
|
||||||
assert_hdmi_port_disabled(intel_hdmi);
|
assert_hdmi_port_disabled(intel_hdmi);
|
||||||
|
|
||||||
@@ -507,21 +495,6 @@ static void ibx_set_infoframes(struct drm_encoder *encoder,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (intel_dig_port->port) {
|
|
||||||
case PORT_B:
|
|
||||||
port = VIDEO_DIP_PORT_B;
|
|
||||||
break;
|
|
||||||
case PORT_C:
|
|
||||||
port = VIDEO_DIP_PORT_C;
|
|
||||||
break;
|
|
||||||
case PORT_D:
|
|
||||||
port = VIDEO_DIP_PORT_D;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
BUG();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (port != (val & VIDEO_DIP_PORT_MASK)) {
|
if (port != (val & VIDEO_DIP_PORT_MASK)) {
|
||||||
if (val & VIDEO_DIP_ENABLE) {
|
if (val & VIDEO_DIP_ENABLE) {
|
||||||
val &= ~VIDEO_DIP_ENABLE;
|
val &= ~VIDEO_DIP_ENABLE;
|
||||||
@@ -1263,6 +1236,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
|
|||||||
intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
|
intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
|
||||||
else
|
else
|
||||||
intel_connector->get_hw_state = intel_connector_get_hw_state;
|
intel_connector->get_hw_state = intel_connector_get_hw_state;
|
||||||
|
intel_connector->unregister = intel_connector_unregister;
|
||||||
|
|
||||||
intel_hdmi_add_properties(intel_hdmi, connector);
|
intel_hdmi_add_properties(intel_hdmi, connector);
|
||||||
|
|
||||||
|
|||||||
@@ -899,6 +899,7 @@ void intel_lvds_init(struct drm_device *dev)
|
|||||||
struct drm_encoder *encoder;
|
struct drm_encoder *encoder;
|
||||||
struct drm_display_mode *scan; /* *modes, *bios_mode; */
|
struct drm_display_mode *scan; /* *modes, *bios_mode; */
|
||||||
struct drm_display_mode *fixed_mode = NULL;
|
struct drm_display_mode *fixed_mode = NULL;
|
||||||
|
struct drm_display_mode *downclock_mode = NULL;
|
||||||
struct edid *edid;
|
struct edid *edid;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
u32 lvds;
|
u32 lvds;
|
||||||
@@ -957,6 +958,7 @@ void intel_lvds_init(struct drm_device *dev)
|
|||||||
intel_encoder->get_hw_state = intel_lvds_get_hw_state;
|
intel_encoder->get_hw_state = intel_lvds_get_hw_state;
|
||||||
intel_encoder->get_config = intel_lvds_get_config;
|
intel_encoder->get_config = intel_lvds_get_config;
|
||||||
intel_connector->get_hw_state = intel_connector_get_hw_state;
|
intel_connector->get_hw_state = intel_connector_get_hw_state;
|
||||||
|
intel_connector->unregister = intel_connector_unregister;
|
||||||
|
|
||||||
intel_connector_attach_encoder(intel_connector, intel_encoder);
|
intel_connector_attach_encoder(intel_connector, intel_encoder);
|
||||||
intel_encoder->type = INTEL_OUTPUT_LVDS;
|
intel_encoder->type = INTEL_OUTPUT_LVDS;
|
||||||
@@ -1032,15 +1034,14 @@ void intel_lvds_init(struct drm_device *dev)
|
|||||||
|
|
||||||
fixed_mode = drm_mode_duplicate(dev, scan);
|
fixed_mode = drm_mode_duplicate(dev, scan);
|
||||||
if (fixed_mode) {
|
if (fixed_mode) {
|
||||||
intel_connector->panel.downclock_mode =
|
downclock_mode =
|
||||||
intel_find_panel_downclock(dev,
|
intel_find_panel_downclock(dev,
|
||||||
fixed_mode, connector);
|
fixed_mode, connector);
|
||||||
if (intel_connector->panel.downclock_mode !=
|
if (downclock_mode != NULL &&
|
||||||
NULL && i915.lvds_downclock) {
|
i915.lvds_downclock) {
|
||||||
/* We found the downclock for LVDS. */
|
/* We found the downclock for LVDS. */
|
||||||
dev_priv->lvds_downclock_avail = true;
|
dev_priv->lvds_downclock_avail = true;
|
||||||
dev_priv->lvds_downclock =
|
dev_priv->lvds_downclock =
|
||||||
intel_connector->panel.
|
|
||||||
downclock_mode->clock;
|
downclock_mode->clock;
|
||||||
DRM_DEBUG_KMS("LVDS downclock is found"
|
DRM_DEBUG_KMS("LVDS downclock is found"
|
||||||
" in EDID. Normal clock %dKhz, "
|
" in EDID. Normal clock %dKhz, "
|
||||||
@@ -1116,7 +1117,7 @@ out:
|
|||||||
}
|
}
|
||||||
drm_sysfs_connector_add(connector);
|
drm_sysfs_connector_add(connector);
|
||||||
|
|
||||||
intel_panel_init(&intel_connector->panel, fixed_mode);
|
intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
|
||||||
intel_panel_setup_backlight(connector);
|
intel_panel_setup_backlight(connector);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -1125,8 +1126,6 @@ failed:
|
|||||||
DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
|
DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
|
||||||
drm_connector_cleanup(connector);
|
drm_connector_cleanup(connector);
|
||||||
drm_encoder_cleanup(encoder);
|
drm_encoder_cleanup(encoder);
|
||||||
if (fixed_mode)
|
|
||||||
drm_mode_destroy(dev, fixed_mode);
|
|
||||||
kfree(lvds_encoder);
|
kfree(lvds_encoder);
|
||||||
kfree(lvds_connector);
|
kfree(lvds_connector);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1349,7 +1349,7 @@ void intel_setup_overlay(struct drm_device *dev)
|
|||||||
}
|
}
|
||||||
overlay->flip_addr = reg_bo->phys_obj->handle->busaddr;
|
overlay->flip_addr = reg_bo->phys_obj->handle->busaddr;
|
||||||
} else {
|
} else {
|
||||||
ret = i915_gem_obj_ggtt_pin(reg_bo, PAGE_SIZE, true, false);
|
ret = i915_gem_obj_ggtt_pin(reg_bo, PAGE_SIZE, PIN_MAPPABLE);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
DRM_ERROR("failed to pin overlay register bo\n");
|
DRM_ERROR("failed to pin overlay register bo\n");
|
||||||
goto out_free_bo;
|
goto out_free_bo;
|
||||||
|
|||||||
@@ -1190,9 +1190,11 @@ void intel_panel_init_backlight_funcs(struct drm_device *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int intel_panel_init(struct intel_panel *panel,
|
int intel_panel_init(struct intel_panel *panel,
|
||||||
struct drm_display_mode *fixed_mode)
|
struct drm_display_mode *fixed_mode,
|
||||||
|
struct drm_display_mode *downclock_mode)
|
||||||
{
|
{
|
||||||
panel->fixed_mode = fixed_mode;
|
panel->fixed_mode = fixed_mode;
|
||||||
|
panel->downclock_mode = downclock_mode;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2741,7 +2741,7 @@ intel_alloc_context_page(struct drm_device *dev)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = i915_gem_obj_ggtt_pin(ctx, 4096, true, false);
|
ret = i915_gem_obj_ggtt_pin(ctx, 4096, 0);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
DRM_ERROR("failed to pin power context: %d\n", ret);
|
DRM_ERROR("failed to pin power context: %d\n", ret);
|
||||||
goto err_unref;
|
goto err_unref;
|
||||||
@@ -3196,12 +3196,6 @@ static void valleyview_disable_rps(struct drm_device *dev)
|
|||||||
|
|
||||||
static void intel_print_rc6_info(struct drm_device *dev, u32 mode)
|
static void intel_print_rc6_info(struct drm_device *dev, u32 mode)
|
||||||
{
|
{
|
||||||
if (IS_GEN6(dev))
|
|
||||||
DRM_DEBUG_DRIVER("Sandybridge: deep RC6 disabled\n");
|
|
||||||
|
|
||||||
if (IS_HASWELL(dev))
|
|
||||||
DRM_DEBUG_DRIVER("Haswell: only RC6 available\n");
|
|
||||||
|
|
||||||
DRM_INFO("Enabling RC6 states: RC6 %s, RC6p %s, RC6pp %s\n",
|
DRM_INFO("Enabling RC6 states: RC6 %s, RC6p %s, RC6pp %s\n",
|
||||||
(mode & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off",
|
(mode & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off",
|
||||||
(mode & GEN6_RC_CTL_RC6p_ENABLE) ? "on" : "off",
|
(mode & GEN6_RC_CTL_RC6p_ENABLE) ? "on" : "off",
|
||||||
@@ -3222,14 +3216,10 @@ int intel_enable_rc6(const struct drm_device *dev)
|
|||||||
if (INTEL_INFO(dev)->gen == 5)
|
if (INTEL_INFO(dev)->gen == 5)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (IS_HASWELL(dev))
|
if (IS_IVYBRIDGE(dev))
|
||||||
return INTEL_RC6_ENABLE;
|
|
||||||
|
|
||||||
/* snb/ivb have more than one rc6 state. */
|
|
||||||
if (INTEL_INFO(dev)->gen == 6)
|
|
||||||
return INTEL_RC6_ENABLE;
|
|
||||||
|
|
||||||
return (INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE);
|
return (INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE);
|
||||||
|
|
||||||
|
return INTEL_RC6_ENABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen6_enable_rps_interrupts(struct drm_device *dev)
|
static void gen6_enable_rps_interrupts(struct drm_device *dev)
|
||||||
@@ -3286,7 +3276,7 @@ static void gen8_enable_rps(struct drm_device *dev)
|
|||||||
/* 3: Enable RC6 */
|
/* 3: Enable RC6 */
|
||||||
if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
|
if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
|
||||||
rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
|
rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
|
||||||
DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off");
|
intel_print_rc6_info(dev, rc6_mask);
|
||||||
I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
|
I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
|
||||||
GEN6_RC_CTL_EI_MODE(1) |
|
GEN6_RC_CTL_EI_MODE(1) |
|
||||||
rc6_mask);
|
rc6_mask);
|
||||||
@@ -3903,9 +3893,10 @@ static unsigned long __i915_chipset_val(struct drm_i915_private *dev_priv)
|
|||||||
|
|
||||||
unsigned long i915_chipset_val(struct drm_i915_private *dev_priv)
|
unsigned long i915_chipset_val(struct drm_i915_private *dev_priv)
|
||||||
{
|
{
|
||||||
|
struct drm_device *dev = dev_priv->dev;
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
|
|
||||||
if (dev_priv->info->gen != 5)
|
if (INTEL_INFO(dev)->gen != 5)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
spin_lock_irq(&mchdev_lock);
|
spin_lock_irq(&mchdev_lock);
|
||||||
@@ -3934,6 +3925,7 @@ unsigned long i915_mch_val(struct drm_i915_private *dev_priv)
|
|||||||
|
|
||||||
static u16 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid)
|
static u16 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid)
|
||||||
{
|
{
|
||||||
|
struct drm_device *dev = dev_priv->dev;
|
||||||
static const struct v_table {
|
static const struct v_table {
|
||||||
u16 vd; /* in .1 mil */
|
u16 vd; /* in .1 mil */
|
||||||
u16 vm; /* in .1 mil */
|
u16 vm; /* in .1 mil */
|
||||||
@@ -4067,7 +4059,7 @@ static u16 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid)
|
|||||||
{ 16000, 14875, },
|
{ 16000, 14875, },
|
||||||
{ 16125, 15000, },
|
{ 16125, 15000, },
|
||||||
};
|
};
|
||||||
if (dev_priv->info->is_mobile)
|
if (INTEL_INFO(dev)->is_mobile)
|
||||||
return v_table[pxvid].vm;
|
return v_table[pxvid].vm;
|
||||||
else
|
else
|
||||||
return v_table[pxvid].vd;
|
return v_table[pxvid].vd;
|
||||||
@@ -4110,7 +4102,9 @@ static void __i915_update_gfx_val(struct drm_i915_private *dev_priv)
|
|||||||
|
|
||||||
void i915_update_gfx_val(struct drm_i915_private *dev_priv)
|
void i915_update_gfx_val(struct drm_i915_private *dev_priv)
|
||||||
{
|
{
|
||||||
if (dev_priv->info->gen != 5)
|
struct drm_device *dev = dev_priv->dev;
|
||||||
|
|
||||||
|
if (INTEL_INFO(dev)->gen != 5)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
spin_lock_irq(&mchdev_lock);
|
spin_lock_irq(&mchdev_lock);
|
||||||
@@ -4159,9 +4153,10 @@ static unsigned long __i915_gfx_val(struct drm_i915_private *dev_priv)
|
|||||||
|
|
||||||
unsigned long i915_gfx_val(struct drm_i915_private *dev_priv)
|
unsigned long i915_gfx_val(struct drm_i915_private *dev_priv)
|
||||||
{
|
{
|
||||||
|
struct drm_device *dev = dev_priv->dev;
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
|
|
||||||
if (dev_priv->info->gen != 5)
|
if (INTEL_INFO(dev)->gen != 5)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
spin_lock_irq(&mchdev_lock);
|
spin_lock_irq(&mchdev_lock);
|
||||||
@@ -4697,6 +4692,14 @@ static void gen6_init_clock_gating(struct drm_device *dev)
|
|||||||
I915_WRITE(_3D_CHICKEN3, (0xFFFF << 16) |
|
I915_WRITE(_3D_CHICKEN3, (0xFFFF << 16) |
|
||||||
_3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL);
|
_3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bspec says:
|
||||||
|
* "This bit must be set if 3DSTATE_CLIP clip mode is set to normal and
|
||||||
|
* 3DSTATE_SF number of SF output attributes is more than 16."
|
||||||
|
*/
|
||||||
|
I915_WRITE(_3D_CHICKEN3,
|
||||||
|
_MASKED_BIT_ENABLE(_3D_CHICKEN3_SF_DISABLE_PIPELINED_ATTR_FETCH));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* According to the spec the following bits should be
|
* According to the spec the following bits should be
|
||||||
* set in order to enable memory self-refresh and fbc:
|
* set in order to enable memory self-refresh and fbc:
|
||||||
|
|||||||
@@ -531,9 +531,11 @@ init_pipe_control(struct intel_ring_buffer *ring)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
i915_gem_object_set_cache_level(ring->scratch.obj, I915_CACHE_LLC);
|
ret = i915_gem_object_set_cache_level(ring->scratch.obj, I915_CACHE_LLC);
|
||||||
|
if (ret)
|
||||||
|
goto err_unref;
|
||||||
|
|
||||||
ret = i915_gem_obj_ggtt_pin(ring->scratch.obj, 4096, true, false);
|
ret = i915_gem_obj_ggtt_pin(ring->scratch.obj, 4096, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_unref;
|
goto err_unref;
|
||||||
|
|
||||||
@@ -1271,12 +1273,13 @@ static int init_status_page(struct intel_ring_buffer *ring)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
|
ret = i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
|
||||||
|
if (ret)
|
||||||
ret = i915_gem_obj_ggtt_pin(obj, 4096, true, false);
|
goto err_unref;
|
||||||
if (ret != 0) {
|
|
||||||
|
ret = i915_gem_obj_ggtt_pin(obj, 4096, 0);
|
||||||
|
if (ret)
|
||||||
goto err_unref;
|
goto err_unref;
|
||||||
}
|
|
||||||
|
|
||||||
ring->status_page.gfx_addr = i915_gem_obj_ggtt_offset(obj);
|
ring->status_page.gfx_addr = i915_gem_obj_ggtt_offset(obj);
|
||||||
ring->status_page.page_addr = kmap(sg_page(obj->pages->sgl));
|
ring->status_page.page_addr = kmap(sg_page(obj->pages->sgl));
|
||||||
@@ -1356,7 +1359,7 @@ static int intel_init_ring_buffer(struct drm_device *dev,
|
|||||||
|
|
||||||
ring->obj = obj;
|
ring->obj = obj;
|
||||||
|
|
||||||
ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, true, false);
|
ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, PIN_MAPPABLE);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_unref;
|
goto err_unref;
|
||||||
|
|
||||||
@@ -1513,7 +1516,8 @@ static int ring_wait_for_space(struct intel_ring_buffer *ring, int n)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->primary->master) {
|
if (!drm_core_check_feature(dev, DRIVER_MODESET) &&
|
||||||
|
dev->primary->master) {
|
||||||
struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
|
struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
|
||||||
if (master_priv->sarea_priv)
|
if (master_priv->sarea_priv)
|
||||||
master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
|
master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
|
||||||
@@ -1939,7 +1943,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = i915_gem_obj_ggtt_pin(obj, 0, true, false);
|
ret = i915_gem_obj_ggtt_pin(obj, 0, 0);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
drm_gem_object_unreference(&obj->base);
|
drm_gem_object_unreference(&obj->base);
|
||||||
DRM_ERROR("Failed to ping batch bo\n");
|
DRM_ERROR("Failed to ping batch bo\n");
|
||||||
|
|||||||
@@ -2382,24 +2382,62 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, struct intel_sdvo *sdvo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
intel_sdvo_connector_unregister(struct intel_connector *intel_connector)
|
||||||
|
{
|
||||||
|
struct drm_connector *drm_connector;
|
||||||
|
struct intel_sdvo *sdvo_encoder;
|
||||||
|
|
||||||
|
drm_connector = &intel_connector->base;
|
||||||
|
sdvo_encoder = intel_attached_sdvo(&intel_connector->base);
|
||||||
|
|
||||||
|
sysfs_remove_link(&drm_connector->kdev->kobj,
|
||||||
|
sdvo_encoder->ddc.dev.kobj.name);
|
||||||
|
intel_connector_unregister(intel_connector);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
intel_sdvo_connector_init(struct intel_sdvo_connector *connector,
|
intel_sdvo_connector_init(struct intel_sdvo_connector *connector,
|
||||||
struct intel_sdvo *encoder)
|
struct intel_sdvo *encoder)
|
||||||
{
|
{
|
||||||
drm_connector_init(encoder->base.base.dev,
|
struct drm_connector *drm_connector;
|
||||||
&connector->base.base,
|
int ret;
|
||||||
|
|
||||||
|
drm_connector = &connector->base.base;
|
||||||
|
ret = drm_connector_init(encoder->base.base.dev,
|
||||||
|
drm_connector,
|
||||||
&intel_sdvo_connector_funcs,
|
&intel_sdvo_connector_funcs,
|
||||||
connector->base.base.connector_type);
|
connector->base.base.connector_type);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
drm_connector_helper_add(&connector->base.base,
|
drm_connector_helper_add(drm_connector,
|
||||||
&intel_sdvo_connector_helper_funcs);
|
&intel_sdvo_connector_helper_funcs);
|
||||||
|
|
||||||
connector->base.base.interlace_allowed = 1;
|
connector->base.base.interlace_allowed = 1;
|
||||||
connector->base.base.doublescan_allowed = 0;
|
connector->base.base.doublescan_allowed = 0;
|
||||||
connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB;
|
connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB;
|
||||||
connector->base.get_hw_state = intel_sdvo_connector_get_hw_state;
|
connector->base.get_hw_state = intel_sdvo_connector_get_hw_state;
|
||||||
|
connector->base.unregister = intel_sdvo_connector_unregister;
|
||||||
|
|
||||||
intel_connector_attach_encoder(&connector->base, &encoder->base);
|
intel_connector_attach_encoder(&connector->base, &encoder->base);
|
||||||
drm_sysfs_connector_add(&connector->base.base);
|
ret = drm_sysfs_connector_add(drm_connector);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err1;
|
||||||
|
|
||||||
|
ret = sysfs_create_link(&encoder->ddc.dev.kobj,
|
||||||
|
&drm_connector->kdev->kobj,
|
||||||
|
encoder->ddc.dev.kobj.name);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err2;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err2:
|
||||||
|
drm_sysfs_connector_remove(drm_connector);
|
||||||
|
err1:
|
||||||
|
drm_connector_cleanup(drm_connector);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -2459,7 +2497,11 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
|
|||||||
intel_sdvo->is_hdmi = true;
|
intel_sdvo->is_hdmi = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
|
if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
|
||||||
|
kfree(intel_sdvo_connector);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (intel_sdvo->is_hdmi)
|
if (intel_sdvo->is_hdmi)
|
||||||
intel_sdvo_add_hdmi_properties(intel_sdvo, intel_sdvo_connector);
|
intel_sdvo_add_hdmi_properties(intel_sdvo, intel_sdvo_connector);
|
||||||
|
|
||||||
@@ -2490,7 +2532,10 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
|
|||||||
|
|
||||||
intel_sdvo->is_tv = true;
|
intel_sdvo->is_tv = true;
|
||||||
|
|
||||||
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
|
if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
|
||||||
|
kfree(intel_sdvo_connector);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!intel_sdvo_tv_create_property(intel_sdvo, intel_sdvo_connector, type))
|
if (!intel_sdvo_tv_create_property(intel_sdvo, intel_sdvo_connector, type))
|
||||||
goto err;
|
goto err;
|
||||||
@@ -2534,8 +2579,11 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
|
|||||||
intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
|
intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
|
||||||
}
|
}
|
||||||
|
|
||||||
intel_sdvo_connector_init(intel_sdvo_connector,
|
if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
|
||||||
intel_sdvo);
|
kfree(intel_sdvo_connector);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2566,7 +2614,11 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
|
|||||||
intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
|
intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
|
||||||
}
|
}
|
||||||
|
|
||||||
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
|
if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
|
||||||
|
kfree(intel_sdvo_connector);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
|
if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
|||||||
@@ -1189,8 +1189,8 @@ intel_tv_detect_type(struct intel_tv *intel_tv,
|
|||||||
if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
|
if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
|
||||||
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
||||||
i915_disable_pipestat(dev_priv, 0,
|
i915_disable_pipestat(dev_priv, 0,
|
||||||
PIPE_HOTPLUG_INTERRUPT_ENABLE |
|
PIPE_HOTPLUG_INTERRUPT_STATUS |
|
||||||
PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
|
PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
|
||||||
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1266,8 +1266,8 @@ intel_tv_detect_type(struct intel_tv *intel_tv,
|
|||||||
if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
|
if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
|
||||||
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
||||||
i915_enable_pipestat(dev_priv, 0,
|
i915_enable_pipestat(dev_priv, 0,
|
||||||
PIPE_HOTPLUG_INTERRUPT_ENABLE |
|
PIPE_HOTPLUG_INTERRUPT_STATUS |
|
||||||
PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
|
PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
|
||||||
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1634,6 +1634,7 @@ intel_tv_init(struct drm_device *dev)
|
|||||||
intel_encoder->disable = intel_disable_tv;
|
intel_encoder->disable = intel_disable_tv;
|
||||||
intel_encoder->get_hw_state = intel_tv_get_hw_state;
|
intel_encoder->get_hw_state = intel_tv_get_hw_state;
|
||||||
intel_connector->get_hw_state = intel_connector_get_hw_state;
|
intel_connector->get_hw_state = intel_connector_get_hw_state;
|
||||||
|
intel_connector->unregister = intel_connector_unregister;
|
||||||
|
|
||||||
intel_connector_attach_encoder(intel_connector, intel_encoder);
|
intel_connector_attach_encoder(intel_connector, intel_encoder);
|
||||||
intel_encoder->type = INTEL_OUTPUT_TVOUT;
|
intel_encoder->type = INTEL_OUTPUT_TVOUT;
|
||||||
|
|||||||
@@ -994,6 +994,7 @@ extern void drm_encoder_cleanup(struct drm_encoder *encoder);
|
|||||||
|
|
||||||
extern const char *drm_get_connector_name(const struct drm_connector *connector);
|
extern const char *drm_get_connector_name(const struct drm_connector *connector);
|
||||||
extern const char *drm_get_connector_status_name(enum drm_connector_status status);
|
extern const char *drm_get_connector_status_name(enum drm_connector_status status);
|
||||||
|
extern const char *drm_get_subpixel_order_name(enum subpixel_order order);
|
||||||
extern const char *drm_get_dpms_name(int val);
|
extern const char *drm_get_dpms_name(int val);
|
||||||
extern const char *drm_get_dvi_i_subconnector_name(int val);
|
extern const char *drm_get_dvi_i_subconnector_name(int val);
|
||||||
extern const char *drm_get_dvi_i_select_name(int val);
|
extern const char *drm_get_dvi_i_select_name(int val);
|
||||||
|
|||||||
@@ -121,5 +121,11 @@ bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel);
|
|||||||
int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper);
|
int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper);
|
||||||
int drm_fb_helper_debug_enter(struct fb_info *info);
|
int drm_fb_helper_debug_enter(struct fb_info *info);
|
||||||
int drm_fb_helper_debug_leave(struct fb_info *info);
|
int drm_fb_helper_debug_leave(struct fb_info *info);
|
||||||
|
struct drm_display_mode *
|
||||||
|
drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector,
|
||||||
|
int width, int height);
|
||||||
|
struct drm_display_mode *
|
||||||
|
drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
|
||||||
|
int width, int height);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user