Merge tag 'drm-intel-next-2017-05-29' of git://anongit.freedesktop.org/git/drm-intel into drm-next
More stuff for 4.13: - skl+ wm fixes from Mahesh Kumar - some refactor and tests for i915_sw_fence (Chris) - tune execlist/scheduler code (Chris) - g4x,g33 gpu reset improvements (Chris, Mika) - guc code cleanup (Michal Wajdeczko, Michał Winiarski) - dp aux backlight improvements (Puthikorn Voravootivat) - buffer based guc/host communication (Michal Wajdeczko) * tag 'drm-intel-next-2017-05-29' of git://anongit.freedesktop.org/git/drm-intel: (253 commits) drm/i915: Update DRIVER_DATE to 20170529 drm/i915: Keep the forcewake timer alive for 1ms past the most recent use drm/i915/guc: capture GuC logs if FW fails to load drm/i915/guc: Introduce buffer based cmd transport drm/i915/guc: Disable send function on fini drm: Add definition for eDP backlight frequency drm/i915: Drop AUX backlight enable check for backlight control drm/i915: Consolidate #ifdef CONFIG_INTEL_IOMMU drm/i915: Only GGTT vma may be pinned and prevent shrinking drm/i915: Serialize GTT/Aperture accesses on BXT drm/i915: Convert i915_gem_object_ops->flags values to use BIT() drm/i915/selftests: Silence compiler warning in igt_ctx_exec drm/i915/guc: Skip port assign on first iteration of GuC dequeue drm/i915: Remove misleading comment in request_alloc drm/i915/g33: Improve reset reliability Revert "drm/i915: Restore lost "Initialized i915" welcome message" drm/i915/huc: Update GLK HuC version drm/i915: Check for allocation failure drm/i915/guc: Remove action status and statistics from debugfs drm/i915/g4x: Improve gpu reset reliability ...
This commit is contained in:
@@ -2482,8 +2482,6 @@ static void i915_guc_client_info(struct seq_file *m,
|
||||
client->wq_size, client->wq_offset, client->wq_tail);
|
||||
|
||||
seq_printf(m, "\tWork queue full: %u\n", client->no_wq_space);
|
||||
seq_printf(m, "\tFailed doorbell: %u\n", client->b_fail);
|
||||
seq_printf(m, "\tLast submission result: %d\n", client->retcode);
|
||||
|
||||
for_each_engine(engine, dev_priv, id) {
|
||||
u64 submissions = client->submissions[id];
|
||||
@@ -2494,42 +2492,34 @@ static void i915_guc_client_info(struct seq_file *m,
|
||||
seq_printf(m, "\tTotal: %llu\n", tot);
|
||||
}
|
||||
|
||||
static int i915_guc_info(struct seq_file *m, void *data)
|
||||
static bool check_guc_submission(struct seq_file *m)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
const struct intel_guc *guc = &dev_priv->guc;
|
||||
struct intel_engine_cs *engine;
|
||||
enum intel_engine_id id;
|
||||
u64 total;
|
||||
|
||||
if (!guc->execbuf_client) {
|
||||
seq_printf(m, "GuC submission %s\n",
|
||||
HAS_GUC_SCHED(dev_priv) ?
|
||||
"disabled" :
|
||||
"not supported");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int i915_guc_info(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
const struct intel_guc *guc = &dev_priv->guc;
|
||||
|
||||
if (!check_guc_submission(m))
|
||||
return 0;
|
||||
|
||||
seq_printf(m, "Doorbell map:\n");
|
||||
seq_printf(m, "\t%*pb\n", GUC_NUM_DOORBELLS, guc->doorbell_bitmap);
|
||||
seq_printf(m, "Doorbell next cacheline: 0x%x\n\n", guc->db_cacheline);
|
||||
|
||||
seq_printf(m, "GuC total action count: %llu\n", guc->action_count);
|
||||
seq_printf(m, "GuC action failure count: %u\n", guc->action_fail);
|
||||
seq_printf(m, "GuC last action command: 0x%x\n", guc->action_cmd);
|
||||
seq_printf(m, "GuC last action status: 0x%x\n", guc->action_status);
|
||||
seq_printf(m, "GuC last action error code: %d\n", guc->action_err);
|
||||
|
||||
total = 0;
|
||||
seq_printf(m, "\nGuC submissions:\n");
|
||||
for_each_engine(engine, dev_priv, id) {
|
||||
u64 submissions = guc->submissions[id];
|
||||
total += submissions;
|
||||
seq_printf(m, "\t%-24s: %10llu, last seqno 0x%08x\n",
|
||||
engine->name, submissions, guc->last_seqno[id]);
|
||||
}
|
||||
seq_printf(m, "\t%s: %llu\n", "Total", total);
|
||||
|
||||
seq_printf(m, "\nGuC execbuf client @ %p:\n", guc->execbuf_client);
|
||||
i915_guc_client_info(m, dev_priv, guc->execbuf_client);
|
||||
|
||||
@@ -2540,36 +2530,99 @@ static int i915_guc_info(struct seq_file *m, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i915_guc_log_dump(struct seq_file *m, void *data)
|
||||
static int i915_guc_stage_pool(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct drm_i915_gem_object *obj;
|
||||
int i = 0, pg;
|
||||
const struct intel_guc *guc = &dev_priv->guc;
|
||||
struct guc_stage_desc *desc = guc->stage_desc_pool_vaddr;
|
||||
struct i915_guc_client *client = guc->execbuf_client;
|
||||
unsigned int tmp;
|
||||
int index;
|
||||
|
||||
if (!dev_priv->guc.log.vma)
|
||||
if (!check_guc_submission(m))
|
||||
return 0;
|
||||
|
||||
obj = dev_priv->guc.log.vma->obj;
|
||||
for (pg = 0; pg < obj->base.size / PAGE_SIZE; pg++) {
|
||||
u32 *log = kmap_atomic(i915_gem_object_get_page(obj, pg));
|
||||
for (index = 0; index < GUC_MAX_STAGE_DESCRIPTORS; index++, desc++) {
|
||||
struct intel_engine_cs *engine;
|
||||
|
||||
for (i = 0; i < PAGE_SIZE / sizeof(u32); i += 4)
|
||||
seq_printf(m, "0x%08x 0x%08x 0x%08x 0x%08x\n",
|
||||
*(log + i), *(log + i + 1),
|
||||
*(log + i + 2), *(log + i + 3));
|
||||
if (!(desc->attribute & GUC_STAGE_DESC_ATTR_ACTIVE))
|
||||
continue;
|
||||
|
||||
kunmap_atomic(log);
|
||||
seq_printf(m, "GuC stage descriptor %u:\n", index);
|
||||
seq_printf(m, "\tIndex: %u\n", desc->stage_id);
|
||||
seq_printf(m, "\tAttribute: 0x%x\n", desc->attribute);
|
||||
seq_printf(m, "\tPriority: %d\n", desc->priority);
|
||||
seq_printf(m, "\tDoorbell id: %d\n", desc->db_id);
|
||||
seq_printf(m, "\tEngines used: 0x%x\n",
|
||||
desc->engines_used);
|
||||
seq_printf(m, "\tDoorbell trigger phy: 0x%llx, cpu: 0x%llx, uK: 0x%x\n",
|
||||
desc->db_trigger_phy,
|
||||
desc->db_trigger_cpu,
|
||||
desc->db_trigger_uk);
|
||||
seq_printf(m, "\tProcess descriptor: 0x%x\n",
|
||||
desc->process_desc);
|
||||
seq_printf(m, "\tWorkqueue address: 0x%x, size: 0x%x\n",
|
||||
desc->wq_addr, desc->wq_size);
|
||||
seq_putc(m, '\n');
|
||||
|
||||
for_each_engine_masked(engine, dev_priv, client->engines, tmp) {
|
||||
u32 guc_engine_id = engine->guc_id;
|
||||
struct guc_execlist_context *lrc =
|
||||
&desc->lrc[guc_engine_id];
|
||||
|
||||
seq_printf(m, "\t%s LRC:\n", engine->name);
|
||||
seq_printf(m, "\t\tContext desc: 0x%x\n",
|
||||
lrc->context_desc);
|
||||
seq_printf(m, "\t\tContext id: 0x%x\n", lrc->context_id);
|
||||
seq_printf(m, "\t\tLRCA: 0x%x\n", lrc->ring_lrca);
|
||||
seq_printf(m, "\t\tRing begin: 0x%x\n", lrc->ring_begin);
|
||||
seq_printf(m, "\t\tRing end: 0x%x\n", lrc->ring_end);
|
||||
seq_putc(m, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i915_guc_log_dump(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_info_node *node = m->private;
|
||||
struct drm_i915_private *dev_priv = node_to_i915(node);
|
||||
bool dump_load_err = !!node->info_ent->data;
|
||||
struct drm_i915_gem_object *obj = NULL;
|
||||
u32 *log;
|
||||
int i = 0;
|
||||
|
||||
if (dump_load_err)
|
||||
obj = dev_priv->guc.load_err_log;
|
||||
else if (dev_priv->guc.log.vma)
|
||||
obj = dev_priv->guc.log.vma->obj;
|
||||
|
||||
if (!obj)
|
||||
return 0;
|
||||
|
||||
log = i915_gem_object_pin_map(obj, I915_MAP_WC);
|
||||
if (IS_ERR(log)) {
|
||||
DRM_DEBUG("Failed to pin object\n");
|
||||
seq_puts(m, "(log data unaccessible)\n");
|
||||
return PTR_ERR(log);
|
||||
}
|
||||
|
||||
for (i = 0; i < obj->base.size / sizeof(u32); i += 4)
|
||||
seq_printf(m, "0x%08x 0x%08x 0x%08x 0x%08x\n",
|
||||
*(log + i), *(log + i + 1),
|
||||
*(log + i + 2), *(log + i + 3));
|
||||
|
||||
seq_putc(m, '\n');
|
||||
|
||||
i915_gem_object_unpin_map(obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i915_guc_log_control_get(void *data, u64 *val)
|
||||
{
|
||||
struct drm_device *dev = data;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct drm_i915_private *dev_priv = data;
|
||||
|
||||
if (!dev_priv->guc.log.vma)
|
||||
return -EINVAL;
|
||||
@@ -2581,14 +2634,13 @@ static int i915_guc_log_control_get(void *data, u64 *val)
|
||||
|
||||
static int i915_guc_log_control_set(void *data, u64 val)
|
||||
{
|
||||
struct drm_device *dev = data;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct drm_i915_private *dev_priv = data;
|
||||
int ret;
|
||||
|
||||
if (!dev_priv->guc.log.vma)
|
||||
return -EINVAL;
|
||||
|
||||
ret = mutex_lock_interruptible(&dev->struct_mutex);
|
||||
ret = mutex_lock_interruptible(&dev_priv->drm.struct_mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -2596,7 +2648,7 @@ static int i915_guc_log_control_set(void *data, u64 val)
|
||||
ret = i915_guc_log_control(dev_priv, val);
|
||||
intel_runtime_pm_put(dev_priv);
|
||||
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
mutex_unlock(&dev_priv->drm.struct_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2855,7 +2907,8 @@ static int i915_dmc_info(struct seq_file *m, void *unused)
|
||||
seq_printf(m, "version: %d.%d\n", CSR_VERSION_MAJOR(csr->version),
|
||||
CSR_VERSION_MINOR(csr->version));
|
||||
|
||||
if (IS_SKYLAKE(dev_priv) && csr->version >= CSR_VERSION(1, 6)) {
|
||||
if (IS_KABYLAKE(dev_priv) ||
|
||||
(IS_SKYLAKE(dev_priv) && csr->version >= CSR_VERSION(1, 6))) {
|
||||
seq_printf(m, "DC3 -> DC5 count: %d\n",
|
||||
I915_READ(SKL_CSR_DC3_DC5_COUNT));
|
||||
seq_printf(m, "DC5 -> DC6 count: %d\n",
|
||||
@@ -3043,36 +3096,6 @@ static void intel_connector_info(struct seq_file *m,
|
||||
intel_seq_print_mode(m, 2, mode);
|
||||
}
|
||||
|
||||
static bool cursor_active(struct drm_i915_private *dev_priv, int pipe)
|
||||
{
|
||||
u32 state;
|
||||
|
||||
if (IS_I845G(dev_priv) || IS_I865G(dev_priv))
|
||||
state = I915_READ(CURCNTR(PIPE_A)) & CURSOR_ENABLE;
|
||||
else
|
||||
state = I915_READ(CURCNTR(pipe)) & CURSOR_MODE;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
static bool cursor_position(struct drm_i915_private *dev_priv,
|
||||
int pipe, int *x, int *y)
|
||||
{
|
||||
u32 pos;
|
||||
|
||||
pos = I915_READ(CURPOS(pipe));
|
||||
|
||||
*x = (pos >> CURSOR_X_SHIFT) & CURSOR_POS_MASK;
|
||||
if (pos & (CURSOR_POS_SIGN << CURSOR_X_SHIFT))
|
||||
*x = -*x;
|
||||
|
||||
*y = (pos >> CURSOR_Y_SHIFT) & CURSOR_POS_MASK;
|
||||
if (pos & (CURSOR_POS_SIGN << CURSOR_Y_SHIFT))
|
||||
*y = -*y;
|
||||
|
||||
return cursor_active(dev_priv, pipe);
|
||||
}
|
||||
|
||||
static const char *plane_type(enum drm_plane_type type)
|
||||
{
|
||||
switch (type) {
|
||||
@@ -3194,9 +3217,7 @@ static int i915_display_info(struct seq_file *m, void *unused)
|
||||
seq_printf(m, "CRTC info\n");
|
||||
seq_printf(m, "---------\n");
|
||||
for_each_intel_crtc(dev, crtc) {
|
||||
bool active;
|
||||
struct intel_crtc_state *pipe_config;
|
||||
int x, y;
|
||||
|
||||
drm_modeset_lock(&crtc->base.mutex, NULL);
|
||||
pipe_config = to_intel_crtc_state(crtc->base.state);
|
||||
@@ -3208,14 +3229,18 @@ static int i915_display_info(struct seq_file *m, void *unused)
|
||||
yesno(pipe_config->dither), pipe_config->pipe_bpp);
|
||||
|
||||
if (pipe_config->base.active) {
|
||||
struct intel_plane *cursor =
|
||||
to_intel_plane(crtc->base.cursor);
|
||||
|
||||
intel_crtc_info(m, crtc);
|
||||
|
||||
active = cursor_position(dev_priv, crtc->pipe, &x, &y);
|
||||
seq_printf(m, "\tcursor visible? %s, position (%d, %d), size %dx%d, addr 0x%08x, active? %s\n",
|
||||
yesno(crtc->cursor_base),
|
||||
x, y, crtc->base.cursor->state->crtc_w,
|
||||
crtc->base.cursor->state->crtc_h,
|
||||
crtc->cursor_addr, yesno(active));
|
||||
seq_printf(m, "\tcursor visible? %s, position (%d, %d), size %dx%d, addr 0x%08x\n",
|
||||
yesno(cursor->base.state->visible),
|
||||
cursor->base.state->crtc_x,
|
||||
cursor->base.state->crtc_y,
|
||||
cursor->base.state->crtc_w,
|
||||
cursor->base.state->crtc_h,
|
||||
cursor->cursor.base);
|
||||
intel_scaler_info(m, crtc);
|
||||
intel_plane_info(m, crtc);
|
||||
}
|
||||
@@ -3316,7 +3341,7 @@ static int i915_engine_info(struct seq_file *m, void *unused)
|
||||
|
||||
if (i915.enable_execlists) {
|
||||
u32 ptr, read, write;
|
||||
struct rb_node *rb;
|
||||
unsigned int idx;
|
||||
|
||||
seq_printf(m, "\tExeclist status: 0x%08x %08x\n",
|
||||
I915_READ(RING_EXECLIST_STATUS_LO(engine)),
|
||||
@@ -3334,8 +3359,7 @@ static int i915_engine_info(struct seq_file *m, void *unused)
|
||||
if (read > write)
|
||||
write += GEN8_CSB_ENTRIES;
|
||||
while (read < write) {
|
||||
unsigned int idx = ++read % GEN8_CSB_ENTRIES;
|
||||
|
||||
idx = ++read % GEN8_CSB_ENTRIES;
|
||||
seq_printf(m, "\tExeclist CSB[%d]: 0x%08x, context: %d\n",
|
||||
idx,
|
||||
I915_READ(RING_CONTEXT_STATUS_BUF_LO(engine, idx)),
|
||||
@@ -3343,28 +3367,30 @@ static int i915_engine_info(struct seq_file *m, void *unused)
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
rq = READ_ONCE(engine->execlist_port[0].request);
|
||||
if (rq) {
|
||||
seq_printf(m, "\t\tELSP[0] count=%d, ",
|
||||
engine->execlist_port[0].count);
|
||||
print_request(m, rq, "rq: ");
|
||||
} else {
|
||||
seq_printf(m, "\t\tELSP[0] idle\n");
|
||||
}
|
||||
rq = READ_ONCE(engine->execlist_port[1].request);
|
||||
if (rq) {
|
||||
seq_printf(m, "\t\tELSP[1] count=%d, ",
|
||||
engine->execlist_port[1].count);
|
||||
print_request(m, rq, "rq: ");
|
||||
} else {
|
||||
seq_printf(m, "\t\tELSP[1] idle\n");
|
||||
for (idx = 0; idx < ARRAY_SIZE(engine->execlist_port); idx++) {
|
||||
unsigned int count;
|
||||
|
||||
rq = port_unpack(&engine->execlist_port[idx],
|
||||
&count);
|
||||
if (rq) {
|
||||
seq_printf(m, "\t\tELSP[%d] count=%d, ",
|
||||
idx, count);
|
||||
print_request(m, rq, "rq: ");
|
||||
} else {
|
||||
seq_printf(m, "\t\tELSP[%d] idle\n",
|
||||
idx);
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
spin_lock_irq(&engine->timeline->lock);
|
||||
for (rb = engine->execlist_first; rb; rb = rb_next(rb)) {
|
||||
rq = rb_entry(rb, typeof(*rq), priotree.node);
|
||||
print_request(m, rq, "\t\tQ ");
|
||||
for (rb = engine->execlist_first; rb; rb = rb_next(rb)){
|
||||
struct i915_priolist *p =
|
||||
rb_entry(rb, typeof(*p), node);
|
||||
|
||||
list_for_each_entry(rq, &p->requests,
|
||||
priotree.link)
|
||||
print_request(m, rq, "\t\tQ ");
|
||||
}
|
||||
spin_unlock_irq(&engine->timeline->lock);
|
||||
} else if (INTEL_GEN(dev_priv) > 6) {
|
||||
@@ -3704,16 +3730,10 @@ static ssize_t i915_displayport_test_active_write(struct file *file,
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
input_buffer = kmalloc(len + 1, GFP_KERNEL);
|
||||
if (!input_buffer)
|
||||
return -ENOMEM;
|
||||
input_buffer = memdup_user_nul(ubuf, len);
|
||||
if (IS_ERR(input_buffer))
|
||||
return PTR_ERR(input_buffer);
|
||||
|
||||
if (copy_from_user(input_buffer, ubuf, len)) {
|
||||
status = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
input_buffer[len] = '\0';
|
||||
DRM_DEBUG_DRIVER("Copied %d bytes from user\n", (unsigned int)len);
|
||||
|
||||
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||
@@ -3739,7 +3759,6 @@ static ssize_t i915_displayport_test_active_write(struct file *file,
|
||||
}
|
||||
}
|
||||
drm_connector_list_iter_end(&conn_iter);
|
||||
out:
|
||||
kfree(input_buffer);
|
||||
if (status < 0)
|
||||
return status;
|
||||
@@ -3900,6 +3919,8 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[8])
|
||||
num_levels = 3;
|
||||
else if (IS_VALLEYVIEW(dev_priv))
|
||||
num_levels = 1;
|
||||
else if (IS_G4X(dev_priv))
|
||||
num_levels = 3;
|
||||
else
|
||||
num_levels = ilk_wm_max_level(dev_priv) + 1;
|
||||
|
||||
@@ -3912,8 +3933,10 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[8])
|
||||
* - WM1+ latency values in 0.5us units
|
||||
* - latencies are in us on gen9/vlv/chv
|
||||
*/
|
||||
if (INTEL_GEN(dev_priv) >= 9 || IS_VALLEYVIEW(dev_priv) ||
|
||||
IS_CHERRYVIEW(dev_priv))
|
||||
if (INTEL_GEN(dev_priv) >= 9 ||
|
||||
IS_VALLEYVIEW(dev_priv) ||
|
||||
IS_CHERRYVIEW(dev_priv) ||
|
||||
IS_G4X(dev_priv))
|
||||
latency *= 10;
|
||||
else if (level > 0)
|
||||
latency *= 5;
|
||||
@@ -3974,7 +3997,7 @@ static int pri_wm_latency_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = inode->i_private;
|
||||
|
||||
if (INTEL_GEN(dev_priv) < 5)
|
||||
if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv))
|
||||
return -ENODEV;
|
||||
|
||||
return single_open(file, pri_wm_latency_show, dev_priv);
|
||||
@@ -4016,6 +4039,8 @@ static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
|
||||
num_levels = 3;
|
||||
else if (IS_VALLEYVIEW(dev_priv))
|
||||
num_levels = 1;
|
||||
else if (IS_G4X(dev_priv))
|
||||
num_levels = 3;
|
||||
else
|
||||
num_levels = ilk_wm_max_level(dev_priv) + 1;
|
||||
|
||||
@@ -4776,6 +4801,8 @@ static const struct drm_info_list i915_debugfs_list[] = {
|
||||
{"i915_guc_info", i915_guc_info, 0},
|
||||
{"i915_guc_load_status", i915_guc_load_status_info, 0},
|
||||
{"i915_guc_log_dump", i915_guc_log_dump, 0},
|
||||
{"i915_guc_load_err_log_dump", i915_guc_log_dump, 0, (void *)1},
|
||||
{"i915_guc_stage_pool", i915_guc_stage_pool, 0},
|
||||
{"i915_huc_load_status", i915_huc_load_status_info, 0},
|
||||
{"i915_frequency_info", i915_frequency_info, 0},
|
||||
{"i915_hangcheck_info", i915_hangcheck_info, 0},
|
||||
|
Reference in New Issue
Block a user