Skip to content

Commit

Permalink
Merge tag 'drm-intel-next-2014-02-14' of ssh://git.freedesktop.org/gi…
Browse files Browse the repository at this point in the history
…t/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
  ...
  • Loading branch information
Dave Airlie committed Mar 3, 2014
2 parents 4d538b7 + 4c0e552 commit 4d33f3a
Show file tree
Hide file tree
Showing 32 changed files with 1,124 additions and 522 deletions.
23 changes: 23 additions & 0 deletions drivers/gpu/drm/drm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,16 @@ static const struct drm_prop_enum_list drm_encoder_enum_list[] =
{ 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)
{
int i;
Expand Down Expand Up @@ -264,6 +274,19 @@ const char *drm_get_connector_status_name(enum drm_connector_status status)
}
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)
{
return isascii(c) && isprint(c) ? c : '?';
Expand Down
6 changes: 4 additions & 2 deletions drivers/gpu/drm/drm_fb_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,7 @@ static int drm_fb_helper_probe_connector_modes(struct drm_fb_helper *fb_helper,
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;

Expand All @@ -1149,6 +1149,7 @@ static struct drm_display_mode *drm_has_preferred_mode(struct drm_fb_helper_conn
}
return NULL;
}
EXPORT_SYMBOL(drm_has_preferred_mode);

static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector)
{
Expand All @@ -1157,7 +1158,7 @@ static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector)
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)
{
struct drm_cmdline_mode *cmdline_mode;
Expand Down Expand Up @@ -1197,6 +1198,7 @@ static struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_conne
list_add(&mode->head, &fb_helper_conn->connector->modes);
return mode;
}
EXPORT_SYMBOL(drm_pick_cmdline_mode);

static bool drm_connector_enabled(struct drm_connector *connector, bool strict)
{
Expand Down
162 changes: 162 additions & 0 deletions drivers/gpu/drm/i915/i915_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1937,6 +1937,9 @@ static int i915_sink_crc(struct seq_file *m, void *data)
if (connector->base.dpms != DRM_MODE_DPMS_ON)
continue;

if (!connector->base.encoder)
continue;

encoder = to_intel_encoder(connector->base.encoder);
if (encoder->type != INTEL_OUTPUT_EDP)
continue;
Expand Down Expand Up @@ -2074,6 +2077,164 @@ static int i915_power_domain_info(struct seq_file *m, void *unused)
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 {
const char *name;
struct drm_device *dev;
Expand Down Expand Up @@ -3519,6 +3680,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_energy_uJ", i915_energy_uJ, 0},
{"i915_pc8_status", i915_pc8_status, 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)

Expand Down
81 changes: 69 additions & 12 deletions drivers/gpu/drm/i915/i915_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,16 +626,18 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
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;
drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
master_priv->sarea_priv;
struct drm_i915_master_private *master_priv;
drm_i915_sarea_t *sarea_priv;
drm_i915_batchbuffer_t *batch = data;
int ret;
struct drm_clip_rect *cliprects = NULL;

if (drm_core_check_feature(dev, DRIVER_MODESET))
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) {
DRM_ERROR("Batchbuffer ioctl disabled\n");
return -EINVAL;
Expand Down Expand Up @@ -682,9 +684,8 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
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;
drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
master_priv->sarea_priv;
struct drm_i915_master_private *master_priv;
drm_i915_sarea_t *sarea_priv;
drm_i915_cmdbuffer_t *cmdbuf = data;
struct drm_clip_rect *cliprects = NULL;
void *batch_data;
Expand All @@ -696,6 +697,9 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
if (drm_core_check_feature(dev, DRIVER_MODESET))
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);

if (cmdbuf->num_cliprects < 0)
Expand Down Expand Up @@ -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)
{
const struct intel_device_info *info = dev_priv->info;
const struct intel_device_info *info = &dev_priv->info;

#define PRINT_S(name) "%s"
#define SEP_EMPTY
Expand All @@ -1459,6 +1463,58 @@ static void i915_dump_device_info(struct drm_i915_private *dev_priv)
#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
* @dev: DRM device
Expand All @@ -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)
{
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;
uint32_t aperture_size;

Expand All @@ -1496,7 +1552,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)

dev->dev_private = (void *)dev_priv;
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->gpu_error.lock);
Expand Down Expand Up @@ -1635,9 +1694,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
if (!IS_I945G(dev) && !IS_I945GM(dev))
pci_enable_msi(dev->pdev);

dev_priv->num_plane = 1;
if (IS_VALLEYVIEW(dev))
dev_priv->num_plane = 2;
intel_device_info_runtime_init(dev);

if (INTEL_INFO(dev)->num_pipes) {
ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes);
Expand Down
Loading

0 comments on commit 4d33f3a

Please sign in to comment.