Merge tag 'topic/drm-misc-2015-10-08' of git://anongit.freedesktop.org/drm-intel...
[linux-drm-fsl-dcu.git] / drivers / gpu / drm / i915 / i915_debugfs.c
index 40e77fdbf03deeabd7b80e8caf88597c44c4cab8..84c7b6b294ee5318128a7ffd0423dca09c09b6dd 100644 (file)
@@ -46,11 +46,6 @@ enum {
        PINNED_LIST,
 };
 
-static const char *yesno(int v)
-{
-       return v ? "yes" : "no";
-}
-
 /* As the drm_debugfs_init() routines are called before dev->dev_private is
  * allocated we need to hook into the minor for release. */
 static int
@@ -1386,17 +1381,16 @@ static int ironlake_drpc_info(struct seq_file *m)
        intel_runtime_pm_put(dev_priv);
        mutex_unlock(&dev->struct_mutex);
 
-       seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ?
-                  "yes" : "no");
+       seq_printf(m, "HD boost: %s\n", yesno(rgvmodectl & MEMMODE_BOOST_EN));
        seq_printf(m, "Boost freq: %d\n",
                   (rgvmodectl & MEMMODE_BOOST_FREQ_MASK) >>
                   MEMMODE_BOOST_FREQ_SHIFT);
        seq_printf(m, "HW control enabled: %s\n",
-                  rgvmodectl & MEMMODE_HWIDLE_EN ? "yes" : "no");
+                  yesno(rgvmodectl & MEMMODE_HWIDLE_EN));
        seq_printf(m, "SW control enabled: %s\n",
-                  rgvmodectl & MEMMODE_SWMODE_EN ? "yes" : "no");
+                  yesno(rgvmodectl & MEMMODE_SWMODE_EN));
        seq_printf(m, "Gated voltage change: %s\n",
-                  rgvmodectl & MEMMODE_RCLK_GATE ? "yes" : "no");
+                  yesno(rgvmodectl & MEMMODE_RCLK_GATE));
        seq_printf(m, "Starting frequency: P%d\n",
                   (rgvmodectl & MEMMODE_FSTART_MASK) >> MEMMODE_FSTART_SHIFT);
        seq_printf(m, "Max P-state: P%d\n",
@@ -1405,7 +1399,7 @@ static int ironlake_drpc_info(struct seq_file *m)
        seq_printf(m, "RS1 VID: %d\n", (crstandvid & 0x3f));
        seq_printf(m, "RS2 VID: %d\n", ((crstandvid >> 8) & 0x3f));
        seq_printf(m, "Render standby enabled: %s\n",
-                  (rstdbyctl & RCX_SW_EXIT) ? "no" : "yes");
+                  yesno(!(rstdbyctl & RCX_SW_EXIT)));
        seq_puts(m, "Current RS state: ");
        switch (rstdbyctl & RSX_STATUS_MASK) {
        case RSX_STATUS_ON:
@@ -1994,7 +1988,7 @@ static void i915_dump_lrc_obj(struct seq_file *m,
                return;
        }
 
-       page = i915_gem_object_get_page(ctx_obj, 1);
+       page = i915_gem_object_get_page(ctx_obj, LRC_STATE_PN);
        if (!WARN_ON(page == NULL)) {
                reg_state = kmap_atomic(page);
 
@@ -2074,8 +2068,8 @@ static int i915_execlists(struct seq_file *m, void *data)
 
                seq_printf(m, "%s\n", ring->name);
 
-               status = I915_READ(RING_EXECLIST_STATUS(ring));
-               ctx_id = I915_READ(RING_EXECLIST_STATUS(ring) + 4);
+               status = I915_READ(RING_EXECLIST_STATUS_LO(ring));
+               ctx_id = I915_READ(RING_EXECLIST_STATUS_HI(ring));
                seq_printf(m, "\tExeclist status: 0x%08X, context: %u\n",
                           status, ctx_id);
 
@@ -2090,8 +2084,8 @@ static int i915_execlists(struct seq_file *m, void *data)
                           read_pointer, write_pointer);
 
                for (i = 0; i < 6; i++) {
-                       status = I915_READ(RING_CONTEXT_STATUS_BUF(ring) + 8*i);
-                       ctx_id = I915_READ(RING_CONTEXT_STATUS_BUF(ring) + 8*i + 4);
+                       status = I915_READ(RING_CONTEXT_STATUS_BUF_LO(ring, i));
+                       ctx_id = I915_READ(RING_CONTEXT_STATUS_BUF_HI(ring, i));
 
                        seq_printf(m, "\tStatus buffer %d: 0x%08X, context: %u\n",
                                   i, status, ctx_id);
@@ -2249,7 +2243,6 @@ static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_engine_cs *ring;
-       struct drm_file *file;
        int i;
 
        if (INTEL_INFO(dev)->gen == 6)
@@ -2272,13 +2265,6 @@ static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev)
                ppgtt->debug_dump(ppgtt, m);
        }
 
-       list_for_each_entry_reverse(file, &dev->filelist, lhead) {
-               struct drm_i915_file_private *file_priv = file->driver_priv;
-
-               seq_printf(m, "proc: %s\n",
-                          get_pid_task(file->pid, PIDTYPE_PID)->comm);
-               idr_for_each(&file_priv->context_idr, per_file_ctx, m);
-       }
        seq_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK));
 }
 
@@ -2287,6 +2273,7 @@ static int i915_ppgtt_info(struct seq_file *m, void *data)
        struct drm_info_node *node = m->private;
        struct drm_device *dev = node->minor->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_file *file;
 
        int ret = mutex_lock_interruptible(&dev->struct_mutex);
        if (ret)
@@ -2298,6 +2285,19 @@ static int i915_ppgtt_info(struct seq_file *m, void *data)
        else if (INTEL_INFO(dev)->gen >= 6)
                gen6_ppgtt_info(m, dev);
 
+       list_for_each_entry_reverse(file, &dev->filelist, lhead) {
+               struct drm_i915_file_private *file_priv = file->driver_priv;
+               struct task_struct *task;
+
+               task = get_pid_task(file->pid, PIDTYPE_PID);
+               if (!task)
+                       return -ESRCH;
+               seq_printf(m, "\nproc: %s\n", task->comm);
+               put_task_struct(task);
+               idr_for_each(&file_priv->context_idr, per_file_ctx,
+                            (void *)(unsigned long)m);
+       }
+
        intel_runtime_pm_put(dev_priv);
        mutex_unlock(&dev->struct_mutex);
 
@@ -2371,6 +2371,147 @@ static int i915_llc(struct seq_file *m, void *data)
        return 0;
 }
 
+static int i915_guc_load_status_info(struct seq_file *m, void *data)
+{
+       struct drm_info_node *node = m->private;
+       struct drm_i915_private *dev_priv = node->minor->dev->dev_private;
+       struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
+       u32 tmp, i;
+
+       if (!HAS_GUC_UCODE(dev_priv->dev))
+               return 0;
+
+       seq_printf(m, "GuC firmware status:\n");
+       seq_printf(m, "\tpath: %s\n",
+               guc_fw->guc_fw_path);
+       seq_printf(m, "\tfetch: %s\n",
+               intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status));
+       seq_printf(m, "\tload: %s\n",
+               intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
+       seq_printf(m, "\tversion wanted: %d.%d\n",
+               guc_fw->guc_fw_major_wanted, guc_fw->guc_fw_minor_wanted);
+       seq_printf(m, "\tversion found: %d.%d\n",
+               guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found);
+
+       tmp = I915_READ(GUC_STATUS);
+
+       seq_printf(m, "\nGuC status 0x%08x:\n", tmp);
+       seq_printf(m, "\tBootrom status = 0x%x\n",
+               (tmp & GS_BOOTROM_MASK) >> GS_BOOTROM_SHIFT);
+       seq_printf(m, "\tuKernel status = 0x%x\n",
+               (tmp & GS_UKERNEL_MASK) >> GS_UKERNEL_SHIFT);
+       seq_printf(m, "\tMIA Core status = 0x%x\n",
+               (tmp & GS_MIA_MASK) >> GS_MIA_SHIFT);
+       seq_puts(m, "\nScratch registers:\n");
+       for (i = 0; i < 16; i++)
+               seq_printf(m, "\t%2d: \t0x%x\n", i, I915_READ(SOFT_SCRATCH(i)));
+
+       return 0;
+}
+
+static void i915_guc_client_info(struct seq_file *m,
+                                struct drm_i915_private *dev_priv,
+                                struct i915_guc_client *client)
+{
+       struct intel_engine_cs *ring;
+       uint64_t tot = 0;
+       uint32_t i;
+
+       seq_printf(m, "\tPriority %d, GuC ctx index: %u, PD offset 0x%x\n",
+               client->priority, client->ctx_index, client->proc_desc_offset);
+       seq_printf(m, "\tDoorbell id %d, offset: 0x%x, cookie 0x%x\n",
+               client->doorbell_id, client->doorbell_offset, client->cookie);
+       seq_printf(m, "\tWQ size %d, offset: 0x%x, tail %d\n",
+               client->wq_size, client->wq_offset, client->wq_tail);
+
+       seq_printf(m, "\tFailed to queue: %u\n", client->q_fail);
+       seq_printf(m, "\tFailed doorbell: %u\n", client->b_fail);
+       seq_printf(m, "\tLast submission result: %d\n", client->retcode);
+
+       for_each_ring(ring, dev_priv, i) {
+               seq_printf(m, "\tSubmissions: %llu %s\n",
+                               client->submissions[i],
+                               ring->name);
+               tot += client->submissions[i];
+       }
+       seq_printf(m, "\tTotal: %llu\n", tot);
+}
+
+static int i915_guc_info(struct seq_file *m, void *data)
+{
+       struct drm_info_node *node = m->private;
+       struct drm_device *dev = node->minor->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_guc guc;
+       struct i915_guc_client client = {};
+       struct intel_engine_cs *ring;
+       enum intel_ring_id i;
+       u64 total = 0;
+
+       if (!HAS_GUC_SCHED(dev_priv->dev))
+               return 0;
+
+       /* Take a local copy of the GuC data, so we can dump it at leisure */
+       spin_lock(&dev_priv->guc.host2guc_lock);
+       guc = dev_priv->guc;
+       if (guc.execbuf_client) {
+               spin_lock(&guc.execbuf_client->wq_lock);
+               client = *guc.execbuf_client;
+               spin_unlock(&guc.execbuf_client->wq_lock);
+       }
+       spin_unlock(&dev_priv->guc.host2guc_lock);
+
+       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);
+
+       seq_printf(m, "\nGuC submissions:\n");
+       for_each_ring(ring, dev_priv, i) {
+               seq_printf(m, "\t%-24s: %10llu, last seqno 0x%08x %9d\n",
+                       ring->name, guc.submissions[i],
+                       guc.last_seqno[i], guc.last_seqno[i]);
+               total += guc.submissions[i];
+       }
+       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, &client);
+
+       /* Add more as required ... */
+
+       return 0;
+}
+
+static int i915_guc_log_dump(struct seq_file *m, void *data)
+{
+       struct drm_info_node *node = m->private;
+       struct drm_device *dev = node->minor->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_gem_object *log_obj = dev_priv->guc.log_obj;
+       u32 *log;
+       int i = 0, pg;
+
+       if (!log_obj)
+               return 0;
+
+       for (pg = 0; pg < log_obj->base.size / PAGE_SIZE; pg++) {
+               log = kmap_atomic(i915_gem_object_get_page(log_obj, pg));
+
+               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));
+
+               kunmap_atomic(log);
+       }
+
+       seq_putc(m, '\n');
+
+       return 0;
+}
+
 static int i915_edp_psr_status(struct seq_file *m, void *data)
 {
        struct drm_info_node *node = m->private;
@@ -2679,11 +2820,13 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *intel_crtc)
        struct drm_device *dev = node->minor->dev;
        struct drm_crtc *crtc = &intel_crtc->base;
        struct intel_encoder *intel_encoder;
+       struct drm_plane_state *plane_state = crtc->primary->state;
+       struct drm_framebuffer *fb = plane_state->fb;
 
-       if (crtc->primary->fb)
+       if (fb)
                seq_printf(m, "\tfb: %d, pos: %dx%d, size: %dx%d\n",
-                          crtc->primary->fb->base.id, crtc->x, crtc->y,
-                          crtc->primary->fb->width, crtc->primary->fb->height);
+                          fb->base.id, plane_state->src_x >> 16,
+                          plane_state->src_y >> 16, fb->width, fb->height);
        else
                seq_puts(m, "\tprimary plane disabled\n");
        for_each_encoder_on_crtc(dev, crtc, intel_encoder)
@@ -2705,8 +2848,7 @@ static void intel_dp_info(struct seq_file *m,
        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");
+       seq_printf(m, "\taudio support: %s\n", yesno(intel_dp->has_audio));
        if (intel_encoder->type == INTEL_OUTPUT_EDP)
                intel_panel_info(m, &intel_connector->panel);
 }
@@ -2717,8 +2859,7 @@ static void intel_hdmi_info(struct seq_file *m,
        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");
+       seq_printf(m, "\taudio support: %s\n", yesno(intel_hdmi->has_audio));
 }
 
 static void intel_lvds_info(struct seq_file *m,
@@ -4806,7 +4947,7 @@ static void cherryview_sseu_device_status(struct drm_device *dev,
                                          struct sseu_dev_status *stat)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       const int ss_max = 2;
+       int ss_max = 2;
        int ss;
        u32 sig1[ss_max], sig2[ss_max];
 
@@ -5032,6 +5173,9 @@ static const struct drm_info_list i915_debugfs_list[] = {
        {"i915_gem_hws_bsd", i915_hws_info, 0, (void *)VCS},
        {"i915_gem_hws_vebox", i915_hws_info, 0, (void *)VECS},
        {"i915_gem_batch_pool", i915_gem_batch_pool_info, 0},
+       {"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_frequency_info", i915_frequency_info, 0},
        {"i915_hangcheck_info", i915_hangcheck_info, 0},
        {"i915_drpc_info", i915_drpc_info, 0},