1235783Skib/* 2235783Skib * Copyright �� 2008 Intel Corporation 3235783Skib * 4235783Skib * Permission is hereby granted, free of charge, to any person obtaining a 5235783Skib * copy of this software and associated documentation files (the "Software"), 6235783Skib * to deal in the Software without restriction, including without limitation 7235783Skib * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8235783Skib * and/or sell copies of the Software, and to permit persons to whom the 9235783Skib * Software is furnished to do so, subject to the following conditions: 10235783Skib * 11235783Skib * The above copyright notice and this permission notice (including the next 12235783Skib * paragraph) shall be included in all copies or substantial portions of the 13235783Skib * Software. 14235783Skib * 15235783Skib * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16235783Skib * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17235783Skib * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18235783Skib * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19235783Skib * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20235783Skib * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21235783Skib * IN THE SOFTWARE. 22235783Skib * 23235783Skib * Authors: 24235783Skib * Eric Anholt <eric@anholt.net> 25235783Skib * Keith Packard <keithp@keithp.com> 26235783Skib * 27235783Skib */ 28235783Skib 29235783Skib#include <sys/cdefs.h> 30235783Skib__FBSDID("$FreeBSD$"); 31235783Skib 32235783Skib#include <dev/drm2/drmP.h> 33235783Skib#include <dev/drm2/drm.h> 34235783Skib#include <dev/drm2/i915/i915_drm.h> 35235783Skib#include <dev/drm2/i915/i915_drv.h> 36235783Skib#include <dev/drm2/i915/intel_drv.h> 37235783Skib#include <dev/drm2/i915/intel_ringbuffer.h> 38235783Skib 39235783Skib#include <sys/sysctl.h> 40235783Skib 41235783Skibenum { 42235783Skib ACTIVE_LIST, 43235783Skib FLUSHING_LIST, 44235783Skib INACTIVE_LIST, 45235783Skib PINNED_LIST, 46235783Skib}; 47235783Skib 48282199Sdumbbellstatic const char *yesno(int v) 49235783Skib{ 50282199Sdumbbell return v ? "yes" : "no"; 51235783Skib} 52235783Skib 53282199Sdumbbellstatic int i915_capabilities(struct drm_device *dev, struct sbuf *m, void *data) 54235783Skib{ 55235783Skib const struct intel_device_info *info = INTEL_INFO(dev); 56235783Skib 57235783Skib sbuf_printf(m, "gen: %d\n", info->gen); 58235783Skib if (HAS_PCH_SPLIT(dev)) 59235783Skib sbuf_printf(m, "pch: %d\n", INTEL_PCH_TYPE(dev)); 60235783Skib#define B(x) sbuf_printf(m, #x ": %s\n", yesno(info->x)) 61235783Skib B(is_mobile); 62235783Skib B(is_i85x); 63235783Skib B(is_i915g); 64235783Skib B(is_i945gm); 65235783Skib B(is_g33); 66235783Skib B(need_gfx_hws); 67235783Skib B(is_g4x); 68235783Skib B(is_pineview); 69235783Skib B(has_fbc); 70235783Skib B(has_pipe_cxsr); 71235783Skib B(has_hotplug); 72235783Skib B(cursor_needs_physical); 73235783Skib B(has_overlay); 74235783Skib B(overlay_needs_physical); 75235783Skib B(supports_tv); 76235783Skib B(has_bsd_ring); 77235783Skib B(has_blt_ring); 78235783Skib B(has_llc); 79235783Skib#undef B 80235783Skib 81282199Sdumbbell return 0; 82235783Skib} 83235783Skib 84282199Sdumbbellstatic const char *get_pin_flag(struct drm_i915_gem_object *obj) 85235783Skib{ 86235783Skib if (obj->user_pin_count > 0) 87235783Skib return "P"; 88235783Skib else if (obj->pin_count > 0) 89235783Skib return "p"; 90235783Skib else 91235783Skib return " "; 92235783Skib} 93235783Skib 94282199Sdumbbellstatic const char *get_tiling_flag(struct drm_i915_gem_object *obj) 95235783Skib{ 96235783Skib switch (obj->tiling_mode) { 97235783Skib default: 98282199Sdumbbell case I915_TILING_NONE: return " "; 99282199Sdumbbell case I915_TILING_X: return "X"; 100282199Sdumbbell case I915_TILING_Y: return "Y"; 101235783Skib } 102235783Skib} 103235783Skib 104282199Sdumbbellstatic const char *cache_level_str(int type) 105235783Skib{ 106235783Skib switch (type) { 107235783Skib case I915_CACHE_NONE: return " uncached"; 108235783Skib case I915_CACHE_LLC: return " snooped (LLC)"; 109235783Skib case I915_CACHE_LLC_MLC: return " snooped (LLC+MLC)"; 110282199Sdumbbell default: return ""; 111235783Skib } 112235783Skib} 113235783Skib 114235783Skibstatic void 115235783Skibdescribe_obj(struct sbuf *m, struct drm_i915_gem_object *obj) 116235783Skib{ 117235783Skib 118235783Skib sbuf_printf(m, "%p: %s%s %8zdKiB %04x %04x %d %d%s%s%s", 119235783Skib &obj->base, 120235783Skib get_pin_flag(obj), 121235783Skib get_tiling_flag(obj), 122235783Skib obj->base.size / 1024, 123235783Skib obj->base.read_domains, 124235783Skib obj->base.write_domain, 125235783Skib obj->last_rendering_seqno, 126235783Skib obj->last_fenced_seqno, 127235783Skib cache_level_str(obj->cache_level), 128235783Skib obj->dirty ? " dirty" : "", 129235783Skib obj->madv == I915_MADV_DONTNEED ? " purgeable" : ""); 130235783Skib if (obj->base.name) 131235783Skib sbuf_printf(m, " (name: %d)", obj->base.name); 132280369Skib if (obj->pin_display) 133280369Skib sbuf_printf(m, " (display)"); 134235783Skib if (obj->fence_reg != I915_FENCE_REG_NONE) 135235783Skib sbuf_printf(m, " (fence: %d)", obj->fence_reg); 136235783Skib if (obj->gtt_space != NULL) 137235783Skib sbuf_printf(m, " (gtt offset: %08x, size: %08x)", 138235783Skib obj->gtt_offset, (unsigned int)obj->gtt_space->size); 139235783Skib if (obj->pin_mappable || obj->fault_mappable) { 140235783Skib char s[3], *t = s; 141235783Skib if (obj->pin_mappable) 142235783Skib *t++ = 'p'; 143235783Skib if (obj->fault_mappable) 144235783Skib *t++ = 'f'; 145235783Skib *t = '\0'; 146235783Skib sbuf_printf(m, " (%s mappable)", s); 147235783Skib } 148235783Skib if (obj->ring != NULL) 149235783Skib sbuf_printf(m, " (%s)", obj->ring->name); 150235783Skib} 151235783Skib 152282199Sdumbbellstatic int i915_gem_object_list_info(struct drm_device *dev, struct sbuf *m, void *data) 153235783Skib{ 154235783Skib uintptr_t list = (uintptr_t)data; 155235783Skib struct list_head *head; 156235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 157235783Skib struct drm_i915_gem_object *obj; 158235783Skib size_t total_obj_size, total_gtt_size; 159235783Skib int count; 160235783Skib 161235783Skib if (sx_xlock_sig(&dev->dev_struct_lock)) 162282199Sdumbbell return -EINTR; 163235783Skib 164235783Skib switch (list) { 165235783Skib case ACTIVE_LIST: 166235783Skib sbuf_printf(m, "Active:\n"); 167235783Skib head = &dev_priv->mm.active_list; 168235783Skib break; 169235783Skib case INACTIVE_LIST: 170235783Skib sbuf_printf(m, "Inactive:\n"); 171235783Skib head = &dev_priv->mm.inactive_list; 172235783Skib break; 173235783Skib case FLUSHING_LIST: 174235783Skib sbuf_printf(m, "Flushing:\n"); 175235783Skib head = &dev_priv->mm.flushing_list; 176235783Skib break; 177235783Skib default: 178235783Skib DRM_UNLOCK(dev); 179282199Sdumbbell return -EINVAL; 180235783Skib } 181235783Skib 182235783Skib total_obj_size = total_gtt_size = count = 0; 183235783Skib list_for_each_entry(obj, head, mm_list) { 184235783Skib sbuf_printf(m, " "); 185235783Skib describe_obj(m, obj); 186235783Skib sbuf_printf(m, "\n"); 187235783Skib total_obj_size += obj->base.size; 188235783Skib total_gtt_size += obj->gtt_space->size; 189235783Skib count++; 190235783Skib } 191235783Skib DRM_UNLOCK(dev); 192235783Skib 193235783Skib sbuf_printf(m, "Total %d objects, %zu bytes, %zu GTT size\n", 194235783Skib count, total_obj_size, total_gtt_size); 195282199Sdumbbell return 0; 196235783Skib} 197235783Skib 198235783Skib#define count_objects(list, member) do { \ 199235783Skib list_for_each_entry(obj, list, member) { \ 200235783Skib size += obj->gtt_space->size; \ 201235783Skib ++count; \ 202235783Skib if (obj->map_and_fenceable) { \ 203235783Skib mappable_size += obj->gtt_space->size; \ 204235783Skib ++mappable_count; \ 205235783Skib } \ 206235783Skib } \ 207235783Skib} while (0) 208235783Skib 209282199Sdumbbellstatic int i915_gem_object_info(struct drm_device *dev, struct sbuf *m, void *data) 210235783Skib{ 211235783Skib struct drm_i915_private *dev_priv = dev->dev_private; 212235783Skib u32 count, mappable_count; 213235783Skib size_t size, mappable_size; 214235783Skib struct drm_i915_gem_object *obj; 215235783Skib 216235783Skib if (sx_xlock_sig(&dev->dev_struct_lock)) 217282199Sdumbbell return -EINTR; 218235783Skib sbuf_printf(m, "%u objects, %zu bytes\n", 219235783Skib dev_priv->mm.object_count, 220235783Skib dev_priv->mm.object_memory); 221235783Skib 222235783Skib size = count = mappable_size = mappable_count = 0; 223235783Skib count_objects(&dev_priv->mm.gtt_list, gtt_list); 224235783Skib sbuf_printf(m, "%u [%u] objects, %zu [%zu] bytes in gtt\n", 225235783Skib count, mappable_count, size, mappable_size); 226235783Skib 227235783Skib size = count = mappable_size = mappable_count = 0; 228235783Skib count_objects(&dev_priv->mm.active_list, mm_list); 229235783Skib count_objects(&dev_priv->mm.flushing_list, mm_list); 230235783Skib sbuf_printf(m, " %u [%u] active objects, %zu [%zu] bytes\n", 231235783Skib count, mappable_count, size, mappable_size); 232235783Skib 233235783Skib size = count = mappable_size = mappable_count = 0; 234235783Skib count_objects(&dev_priv->mm.inactive_list, mm_list); 235235783Skib sbuf_printf(m, " %u [%u] inactive objects, %zu [%zu] bytes\n", 236235783Skib count, mappable_count, size, mappable_size); 237235783Skib 238235783Skib size = count = mappable_size = mappable_count = 0; 239235783Skib list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { 240235783Skib if (obj->fault_mappable) { 241235783Skib size += obj->gtt_space->size; 242235783Skib ++count; 243235783Skib } 244235783Skib if (obj->pin_mappable) { 245235783Skib mappable_size += obj->gtt_space->size; 246235783Skib ++mappable_count; 247235783Skib } 248235783Skib } 249235783Skib sbuf_printf(m, "%u pinned mappable objects, %zu bytes\n", 250235783Skib mappable_count, mappable_size); 251235783Skib sbuf_printf(m, "%u fault mappable objects, %zu bytes\n", 252235783Skib count, size); 253235783Skib 254235783Skib sbuf_printf(m, "%zu [%zu] gtt total\n", 255235783Skib dev_priv->mm.gtt_total, dev_priv->mm.mappable_gtt_total); 256282199Sdumbbell 257235783Skib DRM_UNLOCK(dev); 258235783Skib 259282199Sdumbbell return 0; 260235783Skib} 261235783Skib 262282199Sdumbbellstatic int i915_gem_gtt_info(struct drm_device *dev, struct sbuf *m, void *data) 263235783Skib{ 264235783Skib struct drm_i915_private *dev_priv = dev->dev_private; 265280369Skib uintptr_t list = (uintptr_t)data; 266235783Skib struct drm_i915_gem_object *obj; 267235783Skib size_t total_obj_size, total_gtt_size; 268235783Skib int count; 269235783Skib 270235783Skib if (sx_xlock_sig(&dev->dev_struct_lock)) 271282199Sdumbbell return -EINTR; 272235783Skib 273235783Skib total_obj_size = total_gtt_size = count = 0; 274235783Skib list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { 275280369Skib if (list == PINNED_LIST && obj->pin_count == 0) 276280369Skib continue; 277280369Skib 278235783Skib sbuf_printf(m, " "); 279235783Skib describe_obj(m, obj); 280235783Skib sbuf_printf(m, "\n"); 281235783Skib total_obj_size += obj->base.size; 282235783Skib total_gtt_size += obj->gtt_space->size; 283235783Skib count++; 284235783Skib } 285235783Skib 286235783Skib DRM_UNLOCK(dev); 287235783Skib 288235783Skib sbuf_printf(m, "Total %d objects, %zu bytes, %zu GTT size\n", 289235783Skib count, total_obj_size, total_gtt_size); 290235783Skib 291282199Sdumbbell return 0; 292235783Skib} 293235783Skib 294282199Sdumbbellstatic int i915_gem_pageflip_info(struct drm_device *dev, struct sbuf *m, void *data) 295235783Skib{ 296235783Skib struct intel_crtc *crtc; 297235783Skib struct drm_i915_gem_object *obj; 298235783Skib struct intel_unpin_work *work; 299235783Skib char pipe; 300235783Skib char plane; 301235783Skib 302235783Skib list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) { 303235783Skib pipe = pipe_name(crtc->pipe); 304235783Skib plane = plane_name(crtc->plane); 305235783Skib 306235783Skib mtx_lock(&dev->event_lock); 307235783Skib work = crtc->unpin_work; 308235783Skib if (work == NULL) { 309235783Skib sbuf_printf(m, "No flip due on pipe %c (plane %c)\n", 310235783Skib pipe, plane); 311235783Skib } else { 312235783Skib if (!work->pending) { 313235783Skib sbuf_printf(m, "Flip queued on pipe %c (plane %c)\n", 314235783Skib pipe, plane); 315235783Skib } else { 316235783Skib sbuf_printf(m, "Flip pending (waiting for vsync) on pipe %c (plane %c)\n", 317235783Skib pipe, plane); 318235783Skib } 319235783Skib if (work->enable_stall_check) 320235783Skib sbuf_printf(m, "Stall check enabled, "); 321235783Skib else 322235783Skib sbuf_printf(m, "Stall check waiting for page flip ioctl, "); 323235783Skib sbuf_printf(m, "%d prepares\n", work->pending); 324235783Skib 325235783Skib if (work->old_fb_obj) { 326235783Skib obj = work->old_fb_obj; 327235783Skib if (obj) 328235783Skib sbuf_printf(m, "Old framebuffer gtt_offset 0x%08x\n", obj->gtt_offset); 329235783Skib } 330235783Skib if (work->pending_flip_obj) { 331235783Skib obj = work->pending_flip_obj; 332235783Skib if (obj) 333235783Skib sbuf_printf(m, "New framebuffer gtt_offset 0x%08x\n", obj->gtt_offset); 334235783Skib } 335235783Skib } 336235783Skib mtx_unlock(&dev->event_lock); 337235783Skib } 338235783Skib 339282199Sdumbbell return 0; 340235783Skib} 341235783Skib 342282199Sdumbbellstatic int i915_gem_request_info(struct drm_device *dev, struct sbuf *m, void *data) 343235783Skib{ 344235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 345235783Skib struct drm_i915_gem_request *gem_request; 346235783Skib int count; 347235783Skib 348235783Skib if (sx_xlock_sig(&dev->dev_struct_lock)) 349282199Sdumbbell return -EINTR; 350235783Skib 351235783Skib count = 0; 352235783Skib if (!list_empty(&dev_priv->rings[RCS].request_list)) { 353235783Skib sbuf_printf(m, "Render requests:\n"); 354235783Skib list_for_each_entry(gem_request, 355235783Skib &dev_priv->rings[RCS].request_list, 356235783Skib list) { 357235783Skib sbuf_printf(m, " %d @ %d\n", 358235783Skib gem_request->seqno, 359235783Skib (int) (jiffies - gem_request->emitted_jiffies)); 360235783Skib } 361235783Skib count++; 362235783Skib } 363235783Skib if (!list_empty(&dev_priv->rings[VCS].request_list)) { 364235783Skib sbuf_printf(m, "BSD requests:\n"); 365235783Skib list_for_each_entry(gem_request, 366235783Skib &dev_priv->rings[VCS].request_list, 367235783Skib list) { 368235783Skib sbuf_printf(m, " %d @ %d\n", 369235783Skib gem_request->seqno, 370235783Skib (int) (jiffies - gem_request->emitted_jiffies)); 371235783Skib } 372235783Skib count++; 373235783Skib } 374235783Skib if (!list_empty(&dev_priv->rings[BCS].request_list)) { 375235783Skib sbuf_printf(m, "BLT requests:\n"); 376235783Skib list_for_each_entry(gem_request, 377235783Skib &dev_priv->rings[BCS].request_list, 378235783Skib list) { 379235783Skib sbuf_printf(m, " %d @ %d\n", 380235783Skib gem_request->seqno, 381235783Skib (int) (jiffies - gem_request->emitted_jiffies)); 382235783Skib } 383235783Skib count++; 384235783Skib } 385235783Skib DRM_UNLOCK(dev); 386235783Skib 387235783Skib if (count == 0) 388235783Skib sbuf_printf(m, "No requests\n"); 389235783Skib 390235783Skib return 0; 391235783Skib} 392235783Skib 393282199Sdumbbellstatic void i915_ring_seqno_info(struct sbuf *m, struct intel_ring_buffer *ring) 394235783Skib{ 395235783Skib if (ring->get_seqno) { 396235783Skib sbuf_printf(m, "Current sequence (%s): %d\n", 397235783Skib ring->name, ring->get_seqno(ring)); 398235783Skib } 399235783Skib} 400235783Skib 401282199Sdumbbellstatic int i915_gem_seqno_info(struct drm_device *dev, struct sbuf *m, void *data) 402235783Skib{ 403235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 404235783Skib int i; 405235783Skib 406235783Skib if (sx_xlock_sig(&dev->dev_struct_lock)) 407282199Sdumbbell return -EINTR; 408282199Sdumbbell 409235783Skib for (i = 0; i < I915_NUM_RINGS; i++) 410235783Skib i915_ring_seqno_info(m, &dev_priv->rings[i]); 411282199Sdumbbell 412235783Skib DRM_UNLOCK(dev); 413282199Sdumbbell 414282199Sdumbbell return 0; 415235783Skib} 416235783Skib 417235783Skib 418282199Sdumbbellstatic int i915_interrupt_info(struct drm_device *dev, struct sbuf *m, void *data) 419235783Skib{ 420235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 421235783Skib int i, pipe; 422235783Skib 423235783Skib if (sx_xlock_sig(&dev->dev_struct_lock)) 424282199Sdumbbell return -EINTR; 425235783Skib 426280369Skib if (IS_VALLEYVIEW(dev)) { 427280369Skib sbuf_printf(m, "Display IER:\t%08x\n", 428280369Skib I915_READ(VLV_IER)); 429280369Skib sbuf_printf(m, "Display IIR:\t%08x\n", 430280369Skib I915_READ(VLV_IIR)); 431280369Skib sbuf_printf(m, "Display IIR_RW:\t%08x\n", 432280369Skib I915_READ(VLV_IIR_RW)); 433280369Skib sbuf_printf(m, "Display IMR:\t%08x\n", 434280369Skib I915_READ(VLV_IMR)); 435280369Skib for_each_pipe(pipe) 436280369Skib sbuf_printf(m, "Pipe %c stat:\t%08x\n", 437280369Skib pipe_name(pipe), 438280369Skib I915_READ(PIPESTAT(pipe))); 439280369Skib 440280369Skib sbuf_printf(m, "Master IER:\t%08x\n", 441280369Skib I915_READ(VLV_MASTER_IER)); 442280369Skib 443280369Skib sbuf_printf(m, "Render IER:\t%08x\n", 444280369Skib I915_READ(GTIER)); 445280369Skib sbuf_printf(m, "Render IIR:\t%08x\n", 446280369Skib I915_READ(GTIIR)); 447280369Skib sbuf_printf(m, "Render IMR:\t%08x\n", 448280369Skib I915_READ(GTIMR)); 449280369Skib 450280369Skib sbuf_printf(m, "PM IER:\t\t%08x\n", 451280369Skib I915_READ(GEN6_PMIER)); 452280369Skib sbuf_printf(m, "PM IIR:\t\t%08x\n", 453280369Skib I915_READ(GEN6_PMIIR)); 454280369Skib sbuf_printf(m, "PM IMR:\t\t%08x\n", 455280369Skib I915_READ(GEN6_PMIMR)); 456280369Skib 457280369Skib sbuf_printf(m, "Port hotplug:\t%08x\n", 458280369Skib I915_READ(PORT_HOTPLUG_EN)); 459280369Skib sbuf_printf(m, "DPFLIPSTAT:\t%08x\n", 460280369Skib I915_READ(VLV_DPFLIPSTAT)); 461280369Skib sbuf_printf(m, "DPINVGTT:\t%08x\n", 462280369Skib I915_READ(DPINVGTT)); 463280369Skib 464280369Skib } else if (!HAS_PCH_SPLIT(dev)) { 465235783Skib sbuf_printf(m, "Interrupt enable: %08x\n", 466235783Skib I915_READ(IER)); 467235783Skib sbuf_printf(m, "Interrupt identity: %08x\n", 468235783Skib I915_READ(IIR)); 469235783Skib sbuf_printf(m, "Interrupt mask: %08x\n", 470235783Skib I915_READ(IMR)); 471235783Skib for_each_pipe(pipe) 472235783Skib sbuf_printf(m, "Pipe %c stat: %08x\n", 473235783Skib pipe_name(pipe), 474235783Skib I915_READ(PIPESTAT(pipe))); 475235783Skib } else { 476235783Skib sbuf_printf(m, "North Display Interrupt enable: %08x\n", 477235783Skib I915_READ(DEIER)); 478235783Skib sbuf_printf(m, "North Display Interrupt identity: %08x\n", 479235783Skib I915_READ(DEIIR)); 480235783Skib sbuf_printf(m, "North Display Interrupt mask: %08x\n", 481235783Skib I915_READ(DEIMR)); 482235783Skib sbuf_printf(m, "South Display Interrupt enable: %08x\n", 483235783Skib I915_READ(SDEIER)); 484235783Skib sbuf_printf(m, "South Display Interrupt identity: %08x\n", 485235783Skib I915_READ(SDEIIR)); 486235783Skib sbuf_printf(m, "South Display Interrupt mask: %08x\n", 487235783Skib I915_READ(SDEIMR)); 488235783Skib sbuf_printf(m, "Graphics Interrupt enable: %08x\n", 489235783Skib I915_READ(GTIER)); 490235783Skib sbuf_printf(m, "Graphics Interrupt identity: %08x\n", 491235783Skib I915_READ(GTIIR)); 492235783Skib sbuf_printf(m, "Graphics Interrupt mask: %08x\n", 493235783Skib I915_READ(GTIMR)); 494235783Skib } 495235783Skib sbuf_printf(m, "Interrupts received: %d\n", 496235783Skib atomic_read(&dev_priv->irq_received)); 497235783Skib for (i = 0; i < I915_NUM_RINGS; i++) { 498235783Skib if (IS_GEN6(dev) || IS_GEN7(dev)) { 499235783Skib sbuf_printf(m, "Graphics Interrupt mask (%s): %08x\n", 500235783Skib dev_priv->rings[i].name, 501235783Skib I915_READ_IMR(&dev_priv->rings[i])); 502235783Skib } 503235783Skib i915_ring_seqno_info(m, &dev_priv->rings[i]); 504235783Skib } 505235783Skib DRM_UNLOCK(dev); 506235783Skib 507282199Sdumbbell return 0; 508235783Skib} 509235783Skib 510282199Sdumbbellstatic int i915_gem_fence_regs_info(struct drm_device *dev, struct sbuf *m, void *data) 511235783Skib{ 512235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 513235783Skib int i; 514235783Skib 515235783Skib if (sx_xlock_sig(&dev->dev_struct_lock)) 516282199Sdumbbell return -EINTR; 517235783Skib 518235783Skib sbuf_printf(m, "Reserved fences = %d\n", dev_priv->fence_reg_start); 519235783Skib sbuf_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs); 520235783Skib for (i = 0; i < dev_priv->num_fence_regs; i++) { 521235783Skib struct drm_i915_gem_object *obj = dev_priv->fence_regs[i].obj; 522235783Skib 523235783Skib sbuf_printf(m, "Fenced object[%2d] = ", i); 524235783Skib if (obj == NULL) 525235783Skib sbuf_printf(m, "unused"); 526235783Skib else 527235783Skib describe_obj(m, obj); 528235783Skib sbuf_printf(m, "\n"); 529235783Skib } 530235783Skib 531235783Skib DRM_UNLOCK(dev); 532282199Sdumbbell return 0; 533235783Skib} 534235783Skib 535282199Sdumbbellstatic int i915_hws_info(struct drm_device *dev, struct sbuf *m, void *data) 536235783Skib{ 537235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 538235783Skib struct intel_ring_buffer *ring; 539282199Sdumbbell const volatile u32 __iomem *hws; 540235783Skib int i; 541235783Skib 542235783Skib ring = &dev_priv->rings[(uintptr_t)data]; 543235783Skib hws = (volatile u32 *)ring->status_page.page_addr; 544235783Skib if (hws == NULL) 545282199Sdumbbell return 0; 546235783Skib 547235783Skib for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) { 548235783Skib sbuf_printf(m, "0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n", 549235783Skib i * 4, 550235783Skib hws[i], hws[i + 1], hws[i + 2], hws[i + 3]); 551235783Skib } 552282199Sdumbbell return 0; 553235783Skib} 554235783Skib 555282199Sdumbbellstatic const char *ring_str(int ring) 556235783Skib{ 557235783Skib switch (ring) { 558282199Sdumbbell case RCS: return " render"; 559282199Sdumbbell case VCS: return " bsd"; 560282199Sdumbbell case BCS: return " blt"; 561282199Sdumbbell default: return ""; 562235783Skib } 563235783Skib} 564235783Skib 565282199Sdumbbellstatic const char *pin_flag(int pinned) 566235783Skib{ 567235783Skib if (pinned > 0) 568282199Sdumbbell return " P"; 569235783Skib else if (pinned < 0) 570282199Sdumbbell return " p"; 571235783Skib else 572282199Sdumbbell return ""; 573235783Skib} 574235783Skib 575235783Skibstatic const char *tiling_flag(int tiling) 576235783Skib{ 577235783Skib switch (tiling) { 578235783Skib default: 579235783Skib case I915_TILING_NONE: return ""; 580235783Skib case I915_TILING_X: return " X"; 581235783Skib case I915_TILING_Y: return " Y"; 582235783Skib } 583235783Skib} 584235783Skib 585235783Skibstatic const char *dirty_flag(int dirty) 586235783Skib{ 587235783Skib return dirty ? " dirty" : ""; 588235783Skib} 589235783Skib 590235783Skibstatic const char *purgeable_flag(int purgeable) 591235783Skib{ 592235783Skib return purgeable ? " purgeable" : ""; 593235783Skib} 594235783Skib 595282199Sdumbbellstatic void print_error_buffers(struct sbuf *m, 596282199Sdumbbell const char *name, 597282199Sdumbbell struct drm_i915_error_buffer *err, 598282199Sdumbbell int count) 599235783Skib{ 600235783Skib 601235783Skib sbuf_printf(m, "%s [%d]:\n", name, count); 602235783Skib 603235783Skib while (count--) { 604235783Skib sbuf_printf(m, " %08x %8u %04x %04x %08x%s%s%s%s%s%s%s", 605235783Skib err->gtt_offset, 606235783Skib err->size, 607235783Skib err->read_domains, 608235783Skib err->write_domain, 609235783Skib err->seqno, 610235783Skib pin_flag(err->pinned), 611235783Skib tiling_flag(err->tiling), 612235783Skib dirty_flag(err->dirty), 613235783Skib purgeable_flag(err->purgeable), 614235783Skib err->ring != -1 ? " " : "", 615235783Skib ring_str(err->ring), 616235783Skib cache_level_str(err->cache_level)); 617235783Skib 618235783Skib if (err->name) 619235783Skib sbuf_printf(m, " (name: %d)", err->name); 620235783Skib if (err->fence_reg != I915_FENCE_REG_NONE) 621235783Skib sbuf_printf(m, " (fence: %d)", err->fence_reg); 622235783Skib 623235783Skib sbuf_printf(m, "\n"); 624235783Skib err++; 625235783Skib } 626235783Skib} 627235783Skib 628282199Sdumbbellstatic void i915_ring_error_state(struct sbuf *m, 629282199Sdumbbell struct drm_device *dev, 630282199Sdumbbell struct drm_i915_error_state *error, 631282199Sdumbbell unsigned ring) 632235783Skib{ 633235783Skib 634280369Skib MPASS((ring < I915_NUM_RINGS)); /* shut up confused gcc */ 635235783Skib sbuf_printf(m, "%s command stream:\n", ring_str(ring)); 636235783Skib sbuf_printf(m, " HEAD: 0x%08x\n", error->head[ring]); 637235783Skib sbuf_printf(m, " TAIL: 0x%08x\n", error->tail[ring]); 638235783Skib sbuf_printf(m, " ACTHD: 0x%08x\n", error->acthd[ring]); 639235783Skib sbuf_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]); 640235783Skib sbuf_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]); 641235783Skib sbuf_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]); 642235783Skib if (ring == RCS && INTEL_INFO(dev)->gen >= 4) { 643235783Skib sbuf_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); 644235783Skib sbuf_printf(m, " BBADDR: 0x%08jx\n", (uintmax_t)error->bbaddr); 645235783Skib } 646235783Skib if (INTEL_INFO(dev)->gen >= 4) 647235783Skib sbuf_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]); 648235783Skib sbuf_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); 649280369Skib sbuf_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); 650235783Skib if (INTEL_INFO(dev)->gen >= 6) { 651235783Skib sbuf_printf(m, " FAULT_REG: 0x%08x\n", error->fault_reg[ring]); 652235783Skib sbuf_printf(m, " SYNC_0: 0x%08x\n", 653235783Skib error->semaphore_mboxes[ring][0]); 654235783Skib sbuf_printf(m, " SYNC_1: 0x%08x\n", 655235783Skib error->semaphore_mboxes[ring][1]); 656235783Skib } 657235783Skib sbuf_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); 658280369Skib sbuf_printf(m, " waiting: %s\n", yesno(error->waiting[ring])); 659235783Skib sbuf_printf(m, " ring->head: 0x%08x\n", error->cpu_ring_head[ring]); 660235783Skib sbuf_printf(m, " ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]); 661235783Skib} 662235783Skib 663282199Sdumbbellstatic int i915_error_state(struct drm_device *dev, struct sbuf *m, 664235783Skib void *unused) 665235783Skib{ 666235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 667235783Skib struct drm_i915_error_state *error; 668280369Skib struct intel_ring_buffer *ring; 669235783Skib int i, j, page, offset, elt; 670235783Skib 671235783Skib mtx_lock(&dev_priv->error_lock); 672280369Skib error = dev_priv->first_error; 673280369Skib if (error != NULL) 674280369Skib refcount_acquire(&error->ref); 675280369Skib mtx_unlock(&dev_priv->error_lock); 676282199Sdumbbell if (!error) { 677235783Skib sbuf_printf(m, "no error state collected\n"); 678282199Sdumbbell return 0; 679235783Skib } 680235783Skib 681235783Skib error = dev_priv->first_error; 682235783Skib 683235783Skib sbuf_printf(m, "Time: %jd s %jd us\n", (intmax_t)error->time.tv_sec, 684235783Skib (intmax_t)error->time.tv_usec); 685235783Skib sbuf_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); 686235783Skib sbuf_printf(m, "EIR: 0x%08x\n", error->eir); 687280369Skib sbuf_printf(m, "IER: 0x%08x\n", error->ier); 688235783Skib sbuf_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); 689235783Skib 690235783Skib for (i = 0; i < dev_priv->num_fence_regs; i++) 691235783Skib sbuf_printf(m, " fence[%d] = %08jx\n", i, 692235783Skib (uintmax_t)error->fence[i]); 693235783Skib 694235783Skib if (INTEL_INFO(dev)->gen >= 6) { 695235783Skib sbuf_printf(m, "ERROR: 0x%08x\n", error->error); 696235783Skib sbuf_printf(m, "DONE_REG: 0x%08x\n", error->done_reg); 697235783Skib } 698235783Skib 699280369Skib for_each_ring(ring, dev_priv, i) 700280369Skib i915_ring_error_state(m, dev, error, i); 701235783Skib 702235783Skib if (error->active_bo) 703235783Skib print_error_buffers(m, "Active", 704235783Skib error->active_bo, 705235783Skib error->active_bo_count); 706235783Skib 707235783Skib if (error->pinned_bo) 708235783Skib print_error_buffers(m, "Pinned", 709235783Skib error->pinned_bo, 710235783Skib error->pinned_bo_count); 711235783Skib 712282199Sdumbbell for (i = 0; i < ARRAY_SIZE(error->ring); i++) { 713235783Skib struct drm_i915_error_object *obj; 714282199Sdumbbell 715235783Skib if ((obj = error->ring[i].batchbuffer)) { 716235783Skib sbuf_printf(m, "%s --- gtt_offset = 0x%08x\n", 717235783Skib dev_priv->rings[i].name, 718235783Skib obj->gtt_offset); 719235783Skib offset = 0; 720235783Skib for (page = 0; page < obj->page_count; page++) { 721235783Skib for (elt = 0; elt < PAGE_SIZE/4; elt++) { 722235783Skib sbuf_printf(m, "%08x : %08x\n", 723235783Skib offset, obj->pages[page][elt]); 724235783Skib offset += 4; 725235783Skib } 726235783Skib } 727235783Skib } 728235783Skib 729235783Skib if (error->ring[i].num_requests) { 730235783Skib sbuf_printf(m, "%s --- %d requests\n", 731235783Skib dev_priv->rings[i].name, 732235783Skib error->ring[i].num_requests); 733235783Skib for (j = 0; j < error->ring[i].num_requests; j++) { 734235783Skib sbuf_printf(m, " seqno 0x%08x, emitted %ld, tail 0x%08x\n", 735235783Skib error->ring[i].requests[j].seqno, 736235783Skib error->ring[i].requests[j].jiffies, 737235783Skib error->ring[i].requests[j].tail); 738235783Skib } 739235783Skib } 740235783Skib 741235783Skib if ((obj = error->ring[i].ringbuffer)) { 742235783Skib sbuf_printf(m, "%s --- ringbuffer = 0x%08x\n", 743235783Skib dev_priv->rings[i].name, 744235783Skib obj->gtt_offset); 745235783Skib offset = 0; 746235783Skib for (page = 0; page < obj->page_count; page++) { 747235783Skib for (elt = 0; elt < PAGE_SIZE/4; elt++) { 748235783Skib sbuf_printf(m, "%08x : %08x\n", 749235783Skib offset, 750235783Skib obj->pages[page][elt]); 751235783Skib offset += 4; 752235783Skib } 753235783Skib } 754235783Skib } 755235783Skib } 756235783Skib 757235783Skib if (error->overlay) 758235783Skib intel_overlay_print_error_state(m, error->overlay); 759235783Skib 760235783Skib if (error->display) 761235783Skib intel_display_print_error_state(m, dev, error->display); 762235783Skib 763280369Skib if (refcount_release(&error->ref)) 764280369Skib i915_error_state_free(error); 765235783Skib 766282199Sdumbbell return 0; 767235783Skib} 768235783Skib 769235783Skibstatic int 770280369Skibi915_error_state_w(struct drm_device *dev, const char *str, void *unused) 771280369Skib{ 772280369Skib drm_i915_private_t *dev_priv = dev->dev_private; 773280369Skib struct drm_i915_error_state *error; 774280369Skib 775280369Skib DRM_DEBUG_DRIVER("Resetting error state\n"); 776280369Skib mtx_lock(&dev_priv->error_lock); 777280369Skib error = dev_priv->first_error; 778280369Skib dev_priv->first_error = NULL; 779280369Skib mtx_unlock(&dev_priv->error_lock); 780280369Skib if (error != NULL && refcount_release(&error->ref)) 781280369Skib i915_error_state_free(error); 782280369Skib return (0); 783280369Skib} 784280369Skib 785280369Skibstatic int 786235783Skibi915_rstdby_delays(struct drm_device *dev, struct sbuf *m, void *unused) 787235783Skib{ 788235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 789235783Skib u16 crstanddelay; 790235783Skib 791235783Skib if (sx_xlock_sig(&dev->dev_struct_lock)) 792282199Sdumbbell return -EINTR; 793282199Sdumbbell 794235783Skib crstanddelay = I915_READ16(CRSTANDVID); 795282199Sdumbbell 796235783Skib DRM_UNLOCK(dev); 797235783Skib 798235783Skib sbuf_printf(m, "w/ctx: %d, w/o ctx: %d\n", 799235783Skib (crstanddelay >> 8) & 0x3f, (crstanddelay & 0x3f)); 800235783Skib 801235783Skib return 0; 802235783Skib} 803235783Skib 804282199Sdumbbellstatic int i915_cur_delayinfo(struct drm_device *dev, struct sbuf *m, void *unused) 805235783Skib{ 806235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 807235783Skib 808235783Skib if (IS_GEN5(dev)) { 809235783Skib u16 rgvswctl = I915_READ16(MEMSWCTL); 810235783Skib u16 rgvstat = I915_READ16(MEMSTAT_ILK); 811235783Skib 812235783Skib sbuf_printf(m, "Requested P-state: %d\n", (rgvswctl >> 8) & 0xf); 813235783Skib sbuf_printf(m, "Requested VID: %d\n", rgvswctl & 0x3f); 814235783Skib sbuf_printf(m, "Current VID: %d\n", (rgvstat & MEMSTAT_VID_MASK) >> 815235783Skib MEMSTAT_VID_SHIFT); 816235783Skib sbuf_printf(m, "Current P-state: %d\n", 817235783Skib (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT); 818235783Skib } else if (IS_GEN6(dev)) { 819235783Skib u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); 820235783Skib u32 rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS); 821235783Skib u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); 822235783Skib u32 rpstat; 823235783Skib u32 rpupei, rpcurup, rpprevup; 824235783Skib u32 rpdownei, rpcurdown, rpprevdown; 825235783Skib int max_freq; 826235783Skib 827235783Skib /* RPSTAT1 is in the GT power well */ 828235783Skib if (sx_xlock_sig(&dev->dev_struct_lock)) 829282199Sdumbbell return -EINTR; 830235783Skib gen6_gt_force_wake_get(dev_priv); 831235783Skib 832235783Skib rpstat = I915_READ(GEN6_RPSTAT1); 833235783Skib rpupei = I915_READ(GEN6_RP_CUR_UP_EI); 834235783Skib rpcurup = I915_READ(GEN6_RP_CUR_UP); 835235783Skib rpprevup = I915_READ(GEN6_RP_PREV_UP); 836235783Skib rpdownei = I915_READ(GEN6_RP_CUR_DOWN_EI); 837235783Skib rpcurdown = I915_READ(GEN6_RP_CUR_DOWN); 838235783Skib rpprevdown = I915_READ(GEN6_RP_PREV_DOWN); 839235783Skib 840235783Skib gen6_gt_force_wake_put(dev_priv); 841235783Skib DRM_UNLOCK(dev); 842235783Skib 843235783Skib sbuf_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status); 844235783Skib sbuf_printf(m, "RPSTAT1: 0x%08x\n", rpstat); 845235783Skib sbuf_printf(m, "Render p-state ratio: %d\n", 846235783Skib (gt_perf_status & 0xff00) >> 8); 847235783Skib sbuf_printf(m, "Render p-state VID: %d\n", 848235783Skib gt_perf_status & 0xff); 849235783Skib sbuf_printf(m, "Render p-state limit: %d\n", 850235783Skib rp_state_limits & 0xff); 851235783Skib sbuf_printf(m, "CAGF: %dMHz\n", ((rpstat & GEN6_CAGF_MASK) >> 852235783Skib GEN6_CAGF_SHIFT) * 50); 853235783Skib sbuf_printf(m, "RP CUR UP EI: %dus\n", rpupei & 854235783Skib GEN6_CURICONT_MASK); 855235783Skib sbuf_printf(m, "RP CUR UP: %dus\n", rpcurup & 856235783Skib GEN6_CURBSYTAVG_MASK); 857235783Skib sbuf_printf(m, "RP PREV UP: %dus\n", rpprevup & 858235783Skib GEN6_CURBSYTAVG_MASK); 859235783Skib sbuf_printf(m, "RP CUR DOWN EI: %dus\n", rpdownei & 860235783Skib GEN6_CURIAVG_MASK); 861235783Skib sbuf_printf(m, "RP CUR DOWN: %dus\n", rpcurdown & 862235783Skib GEN6_CURBSYTAVG_MASK); 863235783Skib sbuf_printf(m, "RP PREV DOWN: %dus\n", rpprevdown & 864235783Skib GEN6_CURBSYTAVG_MASK); 865235783Skib 866235783Skib max_freq = (rp_state_cap & 0xff0000) >> 16; 867235783Skib sbuf_printf(m, "Lowest (RPN) frequency: %dMHz\n", 868235783Skib max_freq * 50); 869235783Skib 870235783Skib max_freq = (rp_state_cap & 0xff00) >> 8; 871235783Skib sbuf_printf(m, "Nominal (RP1) frequency: %dMHz\n", 872235783Skib max_freq * 50); 873235783Skib 874235783Skib max_freq = rp_state_cap & 0xff; 875235783Skib sbuf_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n", 876235783Skib max_freq * 50); 877235783Skib } else { 878235783Skib sbuf_printf(m, "no P-state info available\n"); 879235783Skib } 880235783Skib 881235783Skib return 0; 882235783Skib} 883235783Skib 884282199Sdumbbellstatic int i915_delayfreq_table(struct drm_device *dev, struct sbuf *m, void *unused) 885235783Skib{ 886235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 887235783Skib u32 delayfreq; 888235783Skib int i; 889235783Skib 890235783Skib if (sx_xlock_sig(&dev->dev_struct_lock)) 891282199Sdumbbell return -EINTR; 892282199Sdumbbell 893235783Skib for (i = 0; i < 16; i++) { 894235783Skib delayfreq = I915_READ(PXVFREQ_BASE + i * 4); 895235783Skib sbuf_printf(m, "P%02dVIDFREQ: 0x%08x (VID: %d)\n", i, delayfreq, 896235783Skib (delayfreq & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT); 897235783Skib } 898282199Sdumbbell 899235783Skib DRM_UNLOCK(dev); 900282199Sdumbbell 901282199Sdumbbell return 0; 902235783Skib} 903235783Skib 904282199Sdumbbellstatic inline int MAP_TO_MV(int map) 905235783Skib{ 906235783Skib return 1250 - (map * 25); 907235783Skib} 908235783Skib 909282199Sdumbbellstatic int i915_inttoext_table(struct drm_device *dev, struct sbuf *m, void *unused) 910235783Skib{ 911235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 912235783Skib u32 inttoext; 913235783Skib int i; 914235783Skib 915235783Skib if (sx_xlock_sig(&dev->dev_struct_lock)) 916282199Sdumbbell return -EINTR; 917282199Sdumbbell 918235783Skib for (i = 1; i <= 32; i++) { 919235783Skib inttoext = I915_READ(INTTOEXT_BASE_ILK + i * 4); 920235783Skib sbuf_printf(m, "INTTOEXT%02d: 0x%08x\n", i, inttoext); 921235783Skib } 922282199Sdumbbell 923235783Skib DRM_UNLOCK(dev); 924235783Skib 925282199Sdumbbell return 0; 926235783Skib} 927235783Skib 928282199Sdumbbellstatic int ironlake_drpc_info(struct drm_device *dev, struct sbuf *m) 929235783Skib{ 930235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 931235783Skib u32 rgvmodectl; 932235783Skib u32 rstdbyctl; 933235783Skib u16 crstandvid; 934235783Skib 935235783Skib if (sx_xlock_sig(&dev->dev_struct_lock)) 936282199Sdumbbell return -EINTR; 937282199Sdumbbell 938235783Skib rgvmodectl = I915_READ(MEMMODECTL); 939235783Skib rstdbyctl = I915_READ(RSTDBYCTL); 940235783Skib crstandvid = I915_READ16(CRSTANDVID); 941282199Sdumbbell 942235783Skib DRM_UNLOCK(dev); 943235783Skib 944235783Skib sbuf_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? 945235783Skib "yes" : "no"); 946235783Skib sbuf_printf(m, "Boost freq: %d\n", 947235783Skib (rgvmodectl & MEMMODE_BOOST_FREQ_MASK) >> 948235783Skib MEMMODE_BOOST_FREQ_SHIFT); 949235783Skib sbuf_printf(m, "HW control enabled: %s\n", 950235783Skib rgvmodectl & MEMMODE_HWIDLE_EN ? "yes" : "no"); 951235783Skib sbuf_printf(m, "SW control enabled: %s\n", 952235783Skib rgvmodectl & MEMMODE_SWMODE_EN ? "yes" : "no"); 953235783Skib sbuf_printf(m, "Gated voltage change: %s\n", 954235783Skib rgvmodectl & MEMMODE_RCLK_GATE ? "yes" : "no"); 955235783Skib sbuf_printf(m, "Starting frequency: P%d\n", 956235783Skib (rgvmodectl & MEMMODE_FSTART_MASK) >> MEMMODE_FSTART_SHIFT); 957235783Skib sbuf_printf(m, "Max P-state: P%d\n", 958235783Skib (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT); 959235783Skib sbuf_printf(m, "Min P-state: P%d\n", (rgvmodectl & MEMMODE_FMIN_MASK)); 960235783Skib sbuf_printf(m, "RS1 VID: %d\n", (crstandvid & 0x3f)); 961235783Skib sbuf_printf(m, "RS2 VID: %d\n", ((crstandvid >> 8) & 0x3f)); 962235783Skib sbuf_printf(m, "Render standby enabled: %s\n", 963235783Skib (rstdbyctl & RCX_SW_EXIT) ? "no" : "yes"); 964235783Skib sbuf_printf(m, "Current RS state: "); 965235783Skib switch (rstdbyctl & RSX_STATUS_MASK) { 966235783Skib case RSX_STATUS_ON: 967235783Skib sbuf_printf(m, "on\n"); 968235783Skib break; 969235783Skib case RSX_STATUS_RC1: 970235783Skib sbuf_printf(m, "RC1\n"); 971235783Skib break; 972235783Skib case RSX_STATUS_RC1E: 973235783Skib sbuf_printf(m, "RC1E\n"); 974235783Skib break; 975235783Skib case RSX_STATUS_RS1: 976235783Skib sbuf_printf(m, "RS1\n"); 977235783Skib break; 978235783Skib case RSX_STATUS_RS2: 979235783Skib sbuf_printf(m, "RS2 (RC6)\n"); 980235783Skib break; 981235783Skib case RSX_STATUS_RS3: 982235783Skib sbuf_printf(m, "RC3 (RC6+)\n"); 983235783Skib break; 984235783Skib default: 985235783Skib sbuf_printf(m, "unknown\n"); 986235783Skib break; 987235783Skib } 988235783Skib 989235783Skib return 0; 990235783Skib} 991235783Skib 992282199Sdumbbellstatic int gen6_drpc_info(struct drm_device *dev, struct sbuf *m) 993235783Skib{ 994235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 995235783Skib u32 rpmodectl1, gt_core_status, rcctl1; 996235783Skib unsigned forcewake_count; 997235783Skib int count=0; 998235783Skib 999282199Sdumbbell 1000235783Skib if (sx_xlock_sig(&dev->dev_struct_lock)) 1001282199Sdumbbell return -EINTR; 1002235783Skib 1003235783Skib mtx_lock(&dev_priv->gt_lock); 1004235783Skib forcewake_count = dev_priv->forcewake_count; 1005235783Skib mtx_unlock(&dev_priv->gt_lock); 1006235783Skib 1007235783Skib if (forcewake_count) { 1008235783Skib sbuf_printf(m, "RC information inaccurate because userspace " 1009235783Skib "holds a reference \n"); 1010235783Skib } else { 1011235783Skib /* NB: we cannot use forcewake, else we read the wrong values */ 1012235783Skib while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1)) 1013282199Sdumbbell udelay(10); 1014235783Skib sbuf_printf(m, "RC information accurate: %s\n", yesno(count < 51)); 1015235783Skib } 1016235783Skib 1017235783Skib gt_core_status = DRM_READ32(dev_priv->mmio_map, GEN6_GT_CORE_STATUS); 1018235783Skib trace_i915_reg_rw(false, GEN6_GT_CORE_STATUS, gt_core_status, 4); 1019235783Skib 1020235783Skib rpmodectl1 = I915_READ(GEN6_RP_CONTROL); 1021235783Skib rcctl1 = I915_READ(GEN6_RC_CONTROL); 1022235783Skib DRM_UNLOCK(dev); 1023235783Skib 1024235783Skib sbuf_printf(m, "Video Turbo Mode: %s\n", 1025235783Skib yesno(rpmodectl1 & GEN6_RP_MEDIA_TURBO)); 1026235783Skib sbuf_printf(m, "HW control enabled: %s\n", 1027235783Skib yesno(rpmodectl1 & GEN6_RP_ENABLE)); 1028235783Skib sbuf_printf(m, "SW control enabled: %s\n", 1029235783Skib yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) == 1030235783Skib GEN6_RP_MEDIA_SW_MODE)); 1031235783Skib sbuf_printf(m, "RC1e Enabled: %s\n", 1032235783Skib yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE)); 1033235783Skib sbuf_printf(m, "RC6 Enabled: %s\n", 1034235783Skib yesno(rcctl1 & GEN6_RC_CTL_RC6_ENABLE)); 1035235783Skib sbuf_printf(m, "Deep RC6 Enabled: %s\n", 1036235783Skib yesno(rcctl1 & GEN6_RC_CTL_RC6p_ENABLE)); 1037235783Skib sbuf_printf(m, "Deepest RC6 Enabled: %s\n", 1038235783Skib yesno(rcctl1 & GEN6_RC_CTL_RC6pp_ENABLE)); 1039235783Skib sbuf_printf(m, "Current RC state: "); 1040235783Skib switch (gt_core_status & GEN6_RCn_MASK) { 1041235783Skib case GEN6_RC0: 1042235783Skib if (gt_core_status & GEN6_CORE_CPD_STATE_MASK) 1043235783Skib sbuf_printf(m, "Core Power Down\n"); 1044235783Skib else 1045235783Skib sbuf_printf(m, "on\n"); 1046235783Skib break; 1047235783Skib case GEN6_RC3: 1048235783Skib sbuf_printf(m, "RC3\n"); 1049235783Skib break; 1050235783Skib case GEN6_RC6: 1051235783Skib sbuf_printf(m, "RC6\n"); 1052235783Skib break; 1053235783Skib case GEN6_RC7: 1054235783Skib sbuf_printf(m, "RC7\n"); 1055235783Skib break; 1056235783Skib default: 1057235783Skib sbuf_printf(m, "Unknown\n"); 1058235783Skib break; 1059235783Skib } 1060235783Skib 1061235783Skib sbuf_printf(m, "Core Power Down: %s\n", 1062235783Skib yesno(gt_core_status & GEN6_CORE_CPD_STATE_MASK)); 1063280369Skib 1064280369Skib /* Not exactly sure what this is */ 1065280369Skib sbuf_printf(m, "RC6 \"Locked to RPn\" residency since boot: %u\n", 1066280369Skib I915_READ(GEN6_GT_GFX_RC6_LOCKED)); 1067280369Skib sbuf_printf(m, "RC6 residency since boot: %u\n", 1068280369Skib I915_READ(GEN6_GT_GFX_RC6)); 1069280369Skib sbuf_printf(m, "RC6+ residency since boot: %u\n", 1070280369Skib I915_READ(GEN6_GT_GFX_RC6p)); 1071280369Skib sbuf_printf(m, "RC6++ residency since boot: %u\n", 1072280369Skib I915_READ(GEN6_GT_GFX_RC6pp)); 1073280369Skib 1074235783Skib return 0; 1075235783Skib} 1076235783Skib 1077235783Skibstatic int i915_drpc_info(struct drm_device *dev, struct sbuf *m, void *unused) 1078235783Skib{ 1079235783Skib 1080235783Skib if (IS_GEN6(dev) || IS_GEN7(dev)) 1081282199Sdumbbell return gen6_drpc_info(dev, m); 1082235783Skib else 1083282199Sdumbbell return ironlake_drpc_info(dev, m); 1084235783Skib} 1085282199Sdumbbell 1086282199Sdumbbellstatic int i915_fbc_status(struct drm_device *dev, struct sbuf *m, void *unused) 1087235783Skib{ 1088235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 1089235783Skib 1090235783Skib if (!I915_HAS_FBC(dev)) { 1091235783Skib sbuf_printf(m, "FBC unsupported on this chipset"); 1092235783Skib return 0; 1093235783Skib } 1094235783Skib 1095235783Skib if (intel_fbc_enabled(dev)) { 1096235783Skib sbuf_printf(m, "FBC enabled"); 1097235783Skib } else { 1098235783Skib sbuf_printf(m, "FBC disabled: "); 1099235783Skib switch (dev_priv->no_fbc_reason) { 1100235783Skib case FBC_NO_OUTPUT: 1101235783Skib sbuf_printf(m, "no outputs"); 1102235783Skib break; 1103235783Skib case FBC_STOLEN_TOO_SMALL: 1104235783Skib sbuf_printf(m, "not enough stolen memory"); 1105235783Skib break; 1106235783Skib case FBC_UNSUPPORTED_MODE: 1107235783Skib sbuf_printf(m, "mode not supported"); 1108235783Skib break; 1109235783Skib case FBC_MODE_TOO_LARGE: 1110235783Skib sbuf_printf(m, "mode too large"); 1111235783Skib break; 1112235783Skib case FBC_BAD_PLANE: 1113235783Skib sbuf_printf(m, "FBC unsupported on plane"); 1114235783Skib break; 1115235783Skib case FBC_NOT_TILED: 1116235783Skib sbuf_printf(m, "scanout buffer not tiled"); 1117235783Skib break; 1118235783Skib case FBC_MULTIPLE_PIPES: 1119235783Skib sbuf_printf(m, "multiple pipes are enabled"); 1120235783Skib break; 1121235783Skib default: 1122235783Skib sbuf_printf(m, "unknown reason"); 1123235783Skib } 1124235783Skib } 1125235783Skib return 0; 1126235783Skib} 1127235783Skib 1128282199Sdumbbellstatic int i915_sr_status(struct drm_device *dev, struct sbuf *m, void *unused) 1129235783Skib{ 1130235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 1131235783Skib bool sr_enabled = false; 1132235783Skib 1133235783Skib if (HAS_PCH_SPLIT(dev)) 1134235783Skib sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN; 1135235783Skib else if (IS_CRESTLINE(dev) || IS_I945G(dev) || IS_I945GM(dev)) 1136235783Skib sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; 1137235783Skib else if (IS_I915GM(dev)) 1138235783Skib sr_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN; 1139235783Skib else if (IS_PINEVIEW(dev)) 1140235783Skib sr_enabled = I915_READ(DSPFW3) & PINEVIEW_SELF_REFRESH_EN; 1141235783Skib 1142235783Skib sbuf_printf(m, "self-refresh: %s", 1143235783Skib sr_enabled ? "enabled" : "disabled"); 1144235783Skib 1145282199Sdumbbell return 0; 1146235783Skib} 1147235783Skib 1148282199Sdumbbellstatic int i915_emon_status(struct drm_device *dev, struct sbuf *m, void *unused) 1149282199Sdumbbell{ 1150282199Sdumbbell drm_i915_private_t *dev_priv = dev->dev_private; 1151282199Sdumbbell unsigned long temp, chipset, gfx; 1152282199Sdumbbell 1153282199Sdumbbell if (!IS_GEN5(dev)) 1154282199Sdumbbell return -ENODEV; 1155282199Sdumbbell 1156282199Sdumbbell if (sx_xlock_sig(&dev->dev_struct_lock)) 1157282199Sdumbbell return -EINTR; 1158282199Sdumbbell 1159282199Sdumbbell temp = i915_mch_val(dev_priv); 1160282199Sdumbbell chipset = i915_chipset_val(dev_priv); 1161282199Sdumbbell gfx = i915_gfx_val(dev_priv); 1162282199Sdumbbell DRM_UNLOCK(dev); 1163282199Sdumbbell 1164282199Sdumbbell sbuf_printf(m, "GMCH temp: %ld\n", temp); 1165282199Sdumbbell sbuf_printf(m, "Chipset power: %ld\n", chipset); 1166282199Sdumbbell sbuf_printf(m, "GFX power: %ld\n", gfx); 1167282199Sdumbbell sbuf_printf(m, "Total power: %ld\n", chipset + gfx); 1168282199Sdumbbell 1169282199Sdumbbell return 0; 1170282199Sdumbbell} 1171282199Sdumbbell 1172235783Skibstatic int i915_ring_freq_table(struct drm_device *dev, struct sbuf *m, 1173235783Skib void *unused) 1174235783Skib{ 1175235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 1176235783Skib int gpu_freq, ia_freq; 1177235783Skib 1178235783Skib if (!(IS_GEN6(dev) || IS_GEN7(dev))) { 1179235783Skib sbuf_printf(m, "unsupported on this chipset"); 1180282199Sdumbbell return 0; 1181235783Skib } 1182235783Skib 1183235783Skib if (sx_xlock_sig(&dev->dev_struct_lock)) 1184282199Sdumbbell return -EINTR; 1185235783Skib 1186235783Skib sbuf_printf(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\n"); 1187235783Skib 1188235783Skib for (gpu_freq = dev_priv->min_delay; gpu_freq <= dev_priv->max_delay; 1189235783Skib gpu_freq++) { 1190235783Skib I915_WRITE(GEN6_PCODE_DATA, gpu_freq); 1191235783Skib I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | 1192235783Skib GEN6_PCODE_READ_MIN_FREQ_TABLE); 1193235783Skib if (_intel_wait_for(dev, 1194235783Skib (I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, 1195235783Skib 10, 1, "915frq")) { 1196235783Skib DRM_ERROR("pcode read of freq table timed out\n"); 1197235783Skib continue; 1198235783Skib } 1199235783Skib ia_freq = I915_READ(GEN6_PCODE_DATA); 1200235783Skib sbuf_printf(m, "%d\t\t%d\n", gpu_freq * 50, ia_freq * 100); 1201235783Skib } 1202235783Skib 1203235783Skib DRM_UNLOCK(dev); 1204235783Skib 1205282199Sdumbbell return 0; 1206235783Skib} 1207235783Skib 1208282199Sdumbbellstatic int i915_gfxec(struct drm_device *dev, struct sbuf *m, void *unused) 1209235783Skib{ 1210235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 1211235783Skib 1212235783Skib if (sx_xlock_sig(&dev->dev_struct_lock)) 1213282199Sdumbbell return -EINTR; 1214235783Skib 1215282199Sdumbbell sbuf_printf(m, "GFXEC: %ld\n", (unsigned long)I915_READ(0x112f4)); 1216235783Skib 1217235783Skib DRM_UNLOCK(dev); 1218235783Skib 1219282199Sdumbbell return 0; 1220235783Skib} 1221235783Skib 1222235783Skib#if 0 1223282199Sdumbbellstatic int i915_opregion(struct drm_device *dev, struct sbuf *m, void *unused) 1224235783Skib{ 1225235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 1226235783Skib struct intel_opregion *opregion = &dev_priv->opregion; 1227235783Skib 1228235783Skib if (sx_xlock_sig(&dev->dev_struct_lock)) 1229282199Sdumbbell return -EINTR; 1230282199Sdumbbell 1231235783Skib if (opregion->header) 1232235783Skib seq_write(m, opregion->header, OPREGION_SIZE); 1233282199Sdumbbell 1234235783Skib DRM_UNLOCK(dev); 1235235783Skib 1236235783Skib return 0; 1237235783Skib} 1238235783Skib#endif 1239235783Skib 1240282199Sdumbbellstatic int i915_gem_framebuffer_info(struct drm_device *dev, struct sbuf *m, void *data) 1241235783Skib{ 1242235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 1243235783Skib struct intel_fbdev *ifbdev; 1244235783Skib struct intel_framebuffer *fb; 1245235783Skib 1246235783Skib if (sx_xlock_sig(&dev->dev_struct_lock)) 1247282199Sdumbbell return -EINTR; 1248235783Skib 1249235783Skib ifbdev = dev_priv->fbdev; 1250235783Skib if (ifbdev == NULL) { 1251235783Skib DRM_UNLOCK(dev); 1252282199Sdumbbell return 0; 1253235783Skib } 1254235783Skib fb = to_intel_framebuffer(ifbdev->helper.fb); 1255235783Skib 1256235783Skib sbuf_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, obj ", 1257235783Skib fb->base.width, 1258235783Skib fb->base.height, 1259235783Skib fb->base.depth, 1260235783Skib fb->base.bits_per_pixel); 1261235783Skib describe_obj(m, fb->obj); 1262235783Skib sbuf_printf(m, "\n"); 1263235783Skib 1264235783Skib list_for_each_entry(fb, &dev->mode_config.fb_list, base.head) { 1265235783Skib if (&fb->base == ifbdev->helper.fb) 1266235783Skib continue; 1267235783Skib 1268235783Skib sbuf_printf(m, "user size: %d x %d, depth %d, %d bpp, obj ", 1269235783Skib fb->base.width, 1270235783Skib fb->base.height, 1271235783Skib fb->base.depth, 1272235783Skib fb->base.bits_per_pixel); 1273235783Skib describe_obj(m, fb->obj); 1274235783Skib sbuf_printf(m, "\n"); 1275235783Skib } 1276235783Skib 1277235783Skib DRM_UNLOCK(dev); 1278235783Skib 1279282199Sdumbbell return 0; 1280235783Skib} 1281235783Skib 1282282199Sdumbbellstatic int i915_context_status(struct drm_device *dev, struct sbuf *m, void *data) 1283235783Skib{ 1284235783Skib drm_i915_private_t *dev_priv; 1285235783Skib int ret; 1286235783Skib 1287235783Skib dev_priv = dev->dev_private; 1288235783Skib ret = sx_xlock_sig(&dev->mode_config.mutex); 1289235783Skib if (ret != 0) 1290282199Sdumbbell return -EINTR; 1291235783Skib 1292235783Skib if (dev_priv->pwrctx != NULL) { 1293235783Skib sbuf_printf(m, "power context "); 1294235783Skib describe_obj(m, dev_priv->pwrctx); 1295235783Skib sbuf_printf(m, "\n"); 1296235783Skib } 1297235783Skib 1298235783Skib if (dev_priv->renderctx != NULL) { 1299235783Skib sbuf_printf(m, "render context "); 1300235783Skib describe_obj(m, dev_priv->renderctx); 1301235783Skib sbuf_printf(m, "\n"); 1302235783Skib } 1303235783Skib 1304235783Skib sx_xunlock(&dev->mode_config.mutex); 1305235783Skib 1306282199Sdumbbell return 0; 1307235783Skib} 1308235783Skib 1309282199Sdumbbellstatic int i915_gen6_forcewake_count_info(struct drm_device *dev, struct sbuf *m, 1310235783Skib void *data) 1311235783Skib{ 1312235783Skib struct drm_i915_private *dev_priv; 1313235783Skib unsigned forcewake_count; 1314235783Skib 1315235783Skib dev_priv = dev->dev_private; 1316235783Skib mtx_lock(&dev_priv->gt_lock); 1317235783Skib forcewake_count = dev_priv->forcewake_count; 1318235783Skib mtx_unlock(&dev_priv->gt_lock); 1319235783Skib 1320235783Skib sbuf_printf(m, "forcewake count = %u\n", forcewake_count); 1321235783Skib 1322282199Sdumbbell return 0; 1323235783Skib} 1324235783Skib 1325282199Sdumbbellstatic const char *swizzle_string(unsigned swizzle) 1326235783Skib{ 1327235783Skib 1328235783Skib switch(swizzle) { 1329235783Skib case I915_BIT_6_SWIZZLE_NONE: 1330235783Skib return "none"; 1331235783Skib case I915_BIT_6_SWIZZLE_9: 1332235783Skib return "bit9"; 1333235783Skib case I915_BIT_6_SWIZZLE_9_10: 1334235783Skib return "bit9/bit10"; 1335235783Skib case I915_BIT_6_SWIZZLE_9_11: 1336235783Skib return "bit9/bit11"; 1337235783Skib case I915_BIT_6_SWIZZLE_9_10_11: 1338235783Skib return "bit9/bit10/bit11"; 1339235783Skib case I915_BIT_6_SWIZZLE_9_17: 1340235783Skib return "bit9/bit17"; 1341235783Skib case I915_BIT_6_SWIZZLE_9_10_17: 1342235783Skib return "bit9/bit10/bit17"; 1343235783Skib case I915_BIT_6_SWIZZLE_UNKNOWN: 1344235783Skib return "unknown"; 1345235783Skib } 1346235783Skib 1347235783Skib return "bug"; 1348235783Skib} 1349235783Skib 1350282199Sdumbbellstatic int i915_swizzle_info(struct drm_device *dev, struct sbuf *m, void *data) 1351235783Skib{ 1352235783Skib struct drm_i915_private *dev_priv; 1353235783Skib int ret; 1354235783Skib 1355235783Skib dev_priv = dev->dev_private; 1356235783Skib ret = sx_xlock_sig(&dev->dev_struct_lock); 1357235783Skib if (ret != 0) 1358282199Sdumbbell return -EINTR; 1359235783Skib 1360235783Skib sbuf_printf(m, "bit6 swizzle for X-tiling = %s\n", 1361235783Skib swizzle_string(dev_priv->mm.bit_6_swizzle_x)); 1362235783Skib sbuf_printf(m, "bit6 swizzle for Y-tiling = %s\n", 1363235783Skib swizzle_string(dev_priv->mm.bit_6_swizzle_y)); 1364235783Skib 1365235783Skib if (IS_GEN3(dev) || IS_GEN4(dev)) { 1366235783Skib sbuf_printf(m, "DDC = 0x%08x\n", 1367235783Skib I915_READ(DCC)); 1368235783Skib sbuf_printf(m, "C0DRB3 = 0x%04x\n", 1369235783Skib I915_READ16(C0DRB3)); 1370235783Skib sbuf_printf(m, "C1DRB3 = 0x%04x\n", 1371235783Skib I915_READ16(C1DRB3)); 1372235783Skib } else if (IS_GEN6(dev) || IS_GEN7(dev)) { 1373235783Skib sbuf_printf(m, "MAD_DIMM_C0 = 0x%08x\n", 1374235783Skib I915_READ(MAD_DIMM_C0)); 1375235783Skib sbuf_printf(m, "MAD_DIMM_C1 = 0x%08x\n", 1376235783Skib I915_READ(MAD_DIMM_C1)); 1377235783Skib sbuf_printf(m, "MAD_DIMM_C2 = 0x%08x\n", 1378235783Skib I915_READ(MAD_DIMM_C2)); 1379235783Skib sbuf_printf(m, "TILECTL = 0x%08x\n", 1380235783Skib I915_READ(TILECTL)); 1381235783Skib sbuf_printf(m, "ARB_MODE = 0x%08x\n", 1382235783Skib I915_READ(ARB_MODE)); 1383235783Skib sbuf_printf(m, "DISP_ARB_CTL = 0x%08x\n", 1384235783Skib I915_READ(DISP_ARB_CTL)); 1385282199Sdumbbell } 1386235783Skib DRM_UNLOCK(dev); 1387235783Skib 1388282199Sdumbbell return 0; 1389235783Skib} 1390235783Skib 1391282199Sdumbbellstatic int i915_ppgtt_info(struct drm_device *dev, struct sbuf *m, void *data) 1392235783Skib{ 1393235783Skib struct drm_i915_private *dev_priv; 1394235783Skib struct intel_ring_buffer *ring; 1395235783Skib int i, ret; 1396235783Skib 1397235783Skib dev_priv = dev->dev_private; 1398235783Skib 1399235783Skib ret = sx_xlock_sig(&dev->dev_struct_lock); 1400235783Skib if (ret != 0) 1401282199Sdumbbell return -EINTR; 1402235783Skib if (INTEL_INFO(dev)->gen == 6) 1403235783Skib sbuf_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE)); 1404235783Skib 1405235783Skib for (i = 0; i < I915_NUM_RINGS; i++) { 1406235783Skib ring = &dev_priv->rings[i]; 1407235783Skib 1408235783Skib sbuf_printf(m, "%s\n", ring->name); 1409235783Skib if (INTEL_INFO(dev)->gen == 7) 1410235783Skib sbuf_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(RING_MODE_GEN7(ring))); 1411235783Skib sbuf_printf(m, "PP_DIR_BASE: 0x%08x\n", I915_READ(RING_PP_DIR_BASE(ring))); 1412235783Skib sbuf_printf(m, "PP_DIR_BASE_READ: 0x%08x\n", I915_READ(RING_PP_DIR_BASE_READ(ring))); 1413235783Skib sbuf_printf(m, "PP_DIR_DCLV: 0x%08x\n", I915_READ(RING_PP_DIR_DCLV(ring))); 1414235783Skib } 1415235783Skib if (dev_priv->mm.aliasing_ppgtt) { 1416235783Skib struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; 1417235783Skib 1418235783Skib sbuf_printf(m, "aliasing PPGTT:\n"); 1419235783Skib sbuf_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset); 1420235783Skib } 1421235783Skib sbuf_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK)); 1422235783Skib DRM_UNLOCK(dev); 1423235783Skib 1424282199Sdumbbell return 0; 1425235783Skib} 1426235783Skib 1427280369Skibstatic int i915_dpio_info(struct drm_device *dev, struct sbuf *m, void *data) 1428280369Skib{ 1429280369Skib struct drm_i915_private *dev_priv; 1430280369Skib int ret; 1431280369Skib 1432280369Skib if (!IS_VALLEYVIEW(dev)) { 1433280369Skib sbuf_printf(m, "unsupported\n"); 1434280369Skib return 0; 1435280369Skib } 1436280369Skib 1437280369Skib dev_priv = dev->dev_private; 1438280369Skib 1439280369Skib ret = sx_xlock_sig(&dev->mode_config.mutex); 1440280369Skib if (ret != 0) 1441282199Sdumbbell return -EINTR; 1442280369Skib 1443280369Skib sbuf_printf(m, "DPIO_CTL: 0x%08x\n", I915_READ(DPIO_CTL)); 1444280369Skib 1445280369Skib sbuf_printf(m, "DPIO_DIV_A: 0x%08x\n", 1446280369Skib intel_dpio_read(dev_priv, _DPIO_DIV_A)); 1447280369Skib sbuf_printf(m, "DPIO_DIV_B: 0x%08x\n", 1448280369Skib intel_dpio_read(dev_priv, _DPIO_DIV_B)); 1449280369Skib 1450280369Skib sbuf_printf(m, "DPIO_REFSFR_A: 0x%08x\n", 1451280369Skib intel_dpio_read(dev_priv, _DPIO_REFSFR_A)); 1452280369Skib sbuf_printf(m, "DPIO_REFSFR_B: 0x%08x\n", 1453280369Skib intel_dpio_read(dev_priv, _DPIO_REFSFR_B)); 1454280369Skib 1455280369Skib sbuf_printf(m, "DPIO_CORE_CLK_A: 0x%08x\n", 1456280369Skib intel_dpio_read(dev_priv, _DPIO_CORE_CLK_A)); 1457280369Skib sbuf_printf(m, "DPIO_CORE_CLK_B: 0x%08x\n", 1458280369Skib intel_dpio_read(dev_priv, _DPIO_CORE_CLK_B)); 1459280369Skib 1460280369Skib sbuf_printf(m, "DPIO_LFP_COEFF_A: 0x%08x\n", 1461280369Skib intel_dpio_read(dev_priv, _DPIO_LFP_COEFF_A)); 1462280369Skib sbuf_printf(m, "DPIO_LFP_COEFF_B: 0x%08x\n", 1463280369Skib intel_dpio_read(dev_priv, _DPIO_LFP_COEFF_B)); 1464280369Skib 1465280369Skib sbuf_printf(m, "DPIO_FASTCLK_DISABLE: 0x%08x\n", 1466280369Skib intel_dpio_read(dev_priv, DPIO_FASTCLK_DISABLE)); 1467280369Skib 1468280369Skib sx_xunlock(&dev->mode_config.mutex); 1469280369Skib 1470280369Skib return 0; 1471280369Skib} 1472280369Skib 1473235783Skibstatic int 1474235783Skibi915_debug_set_wedged(SYSCTL_HANDLER_ARGS) 1475235783Skib{ 1476235783Skib struct drm_device *dev; 1477235783Skib drm_i915_private_t *dev_priv; 1478235783Skib int error, wedged; 1479235783Skib 1480235783Skib dev = arg1; 1481235783Skib dev_priv = dev->dev_private; 1482235783Skib if (dev_priv == NULL) 1483235783Skib return (EBUSY); 1484235783Skib wedged = dev_priv->mm.wedged; 1485235783Skib error = sysctl_handle_int(oidp, &wedged, 0, req); 1486235783Skib if (error || !req->newptr) 1487235783Skib return (error); 1488235783Skib DRM_INFO("Manually setting wedged to %d\n", wedged); 1489235783Skib i915_handle_error(dev, wedged); 1490235783Skib return (error); 1491235783Skib} 1492235783Skib 1493235783Skibstatic int 1494235783Skibi915_max_freq(SYSCTL_HANDLER_ARGS) 1495235783Skib{ 1496235783Skib struct drm_device *dev; 1497235783Skib drm_i915_private_t *dev_priv; 1498235783Skib int error, max_freq; 1499235783Skib 1500235783Skib dev = arg1; 1501235783Skib dev_priv = dev->dev_private; 1502235783Skib if (dev_priv == NULL) 1503235783Skib return (EBUSY); 1504235783Skib max_freq = dev_priv->max_delay * 50; 1505235783Skib error = sysctl_handle_int(oidp, &max_freq, 0, req); 1506235783Skib if (error || !req->newptr) 1507235783Skib return (error); 1508235783Skib DRM_DEBUG("Manually setting max freq to %d\n", max_freq); 1509235783Skib /* 1510235783Skib * Turbo will still be enabled, but won't go above the set value. 1511235783Skib */ 1512235783Skib dev_priv->max_delay = max_freq / 50; 1513235783Skib gen6_set_rps(dev, max_freq / 50); 1514235783Skib return (error); 1515235783Skib} 1516235783Skib 1517235783Skibstatic int 1518235783Skibi915_cache_sharing(SYSCTL_HANDLER_ARGS) 1519235783Skib{ 1520235783Skib struct drm_device *dev; 1521235783Skib drm_i915_private_t *dev_priv; 1522235783Skib int error, snpcr, cache_sharing; 1523235783Skib 1524235783Skib dev = arg1; 1525235783Skib dev_priv = dev->dev_private; 1526235783Skib if (dev_priv == NULL) 1527235783Skib return (EBUSY); 1528235783Skib DRM_LOCK(dev); 1529235783Skib snpcr = I915_READ(GEN6_MBCUNIT_SNPCR); 1530235783Skib DRM_UNLOCK(dev); 1531235783Skib cache_sharing = (snpcr & GEN6_MBC_SNPCR_MASK) >> GEN6_MBC_SNPCR_SHIFT; 1532235783Skib error = sysctl_handle_int(oidp, &cache_sharing, 0, req); 1533235783Skib if (error || !req->newptr) 1534235783Skib return (error); 1535235783Skib if (cache_sharing < 0 || cache_sharing > 3) 1536235783Skib return (EINVAL); 1537235783Skib DRM_DEBUG("Manually setting uncore sharing to %d\n", cache_sharing); 1538235783Skib 1539235783Skib DRM_LOCK(dev); 1540235783Skib /* Update the cache sharing policy here as well */ 1541235783Skib snpcr = I915_READ(GEN6_MBCUNIT_SNPCR); 1542235783Skib snpcr &= ~GEN6_MBC_SNPCR_MASK; 1543235783Skib snpcr |= (cache_sharing << GEN6_MBC_SNPCR_SHIFT); 1544235783Skib I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr); 1545235783Skib DRM_UNLOCK(dev); 1546235783Skib return (0); 1547235783Skib} 1548235783Skib 1549280369Skibstatic int 1550280369Skibi915_stop_rings(SYSCTL_HANDLER_ARGS) 1551280369Skib{ 1552280369Skib struct drm_device *dev; 1553280369Skib drm_i915_private_t *dev_priv; 1554280369Skib int error, val; 1555280369Skib 1556280369Skib dev = arg1; 1557280369Skib dev_priv = dev->dev_private; 1558280369Skib if (dev_priv == NULL) 1559280369Skib return (EBUSY); 1560280369Skib DRM_LOCK(dev); 1561280369Skib val = dev_priv->stop_rings; 1562280369Skib DRM_UNLOCK(dev); 1563280369Skib error = sysctl_handle_int(oidp, &val, 0, req); 1564280369Skib if (error || !req->newptr) 1565280369Skib return (error); 1566280369Skib DRM_DEBUG("Stopping rings 0x%08x\n", val); 1567280369Skib 1568280369Skib DRM_LOCK(dev); 1569280369Skib dev_priv->stop_rings = val; 1570280369Skib DRM_UNLOCK(dev); 1571280369Skib return (0); 1572280369Skib} 1573280369Skib 1574235783Skibstatic struct i915_info_sysctl_list { 1575235783Skib const char *name; 1576235783Skib int (*ptr)(struct drm_device *dev, struct sbuf *m, void *data); 1577280369Skib int (*ptr_w)(struct drm_device *dev, const char *str, void *data); 1578235783Skib int flags; 1579235783Skib void *data; 1580235783Skib} i915_info_sysctl_list[] = { 1581280369Skib {"i915_capabilities", i915_capabilities, NULL, 0}, 1582280369Skib {"i915_gem_objects", i915_gem_object_info, NULL, 0}, 1583280369Skib {"i915_gem_gtt", i915_gem_gtt_info, NULL, 0}, 1584280369Skib {"i915_gem_pinned", i915_gem_gtt_info, NULL, 0, (void *)PINNED_LIST}, 1585280369Skib {"i915_gem_active", i915_gem_object_list_info, NULL, 0, 1586280369Skib (void *)ACTIVE_LIST}, 1587280369Skib {"i915_gem_flushing", i915_gem_object_list_info, NULL, 0, 1588235783Skib (void *)FLUSHING_LIST}, 1589280369Skib {"i915_gem_inactive", i915_gem_object_list_info, NULL, 0, 1590235783Skib (void *)INACTIVE_LIST}, 1591280369Skib {"i915_gem_pageflip", i915_gem_pageflip_info, NULL, 0}, 1592280369Skib {"i915_gem_request", i915_gem_request_info, NULL, 0}, 1593280369Skib {"i915_gem_seqno", i915_gem_seqno_info, NULL, 0}, 1594280369Skib {"i915_gem_fence_regs", i915_gem_fence_regs_info, NULL, 0}, 1595280369Skib {"i915_gem_interrupt", i915_interrupt_info, NULL, 0}, 1596280369Skib {"i915_gem_hws", i915_hws_info, NULL, 0, (void *)RCS}, 1597280369Skib {"i915_gem_hws_blt", i915_hws_info, NULL, 0, (void *)BCS}, 1598280369Skib {"i915_gem_hws_bsd", i915_hws_info, NULL, 0, (void *)VCS}, 1599280369Skib {"i915_error_state", i915_error_state, i915_error_state_w, 0}, 1600280369Skib {"i915_rstdby_delays", i915_rstdby_delays, NULL, 0}, 1601280369Skib {"i915_cur_delayinfo", i915_cur_delayinfo, NULL, 0}, 1602280369Skib {"i915_delayfreq_table", i915_delayfreq_table, NULL, 0}, 1603280369Skib {"i915_inttoext_table", i915_inttoext_table, NULL, 0}, 1604280369Skib {"i915_drpc_info", i915_drpc_info, NULL, 0}, 1605280369Skib {"i915_emon_status", i915_emon_status, NULL, 0}, 1606280369Skib {"i915_ring_freq_table", i915_ring_freq_table, NULL, 0}, 1607280369Skib {"i915_gfxec", i915_gfxec, NULL, 0}, 1608280369Skib {"i915_fbc_status", i915_fbc_status, NULL, 0}, 1609280369Skib {"i915_sr_status", i915_sr_status, NULL, 0}, 1610235783Skib#if 0 1611280369Skib {"i915_opregion", i915_opregion, NULL, 0}, 1612235783Skib#endif 1613280369Skib {"i915_gem_framebuffer", i915_gem_framebuffer_info, NULL, 0}, 1614280369Skib {"i915_context_status", i915_context_status, NULL, 0}, 1615280369Skib {"i915_gen6_forcewake_count_info", i915_gen6_forcewake_count_info, 1616280369Skib NULL, 0}, 1617280369Skib {"i915_swizzle_info", i915_swizzle_info, NULL, 0}, 1618280369Skib {"i915_ppgtt_info", i915_ppgtt_info, NULL, 0}, 1619280369Skib {"i915_dpio", i915_dpio_info, NULL, 0}, 1620235783Skib}; 1621235783Skib 1622235783Skibstruct i915_info_sysctl_thunk { 1623235783Skib struct drm_device *dev; 1624235783Skib int idx; 1625235783Skib void *arg; 1626235783Skib}; 1627235783Skib 1628235783Skibstatic int 1629235783Skibi915_info_sysctl_handler(SYSCTL_HANDLER_ARGS) 1630235783Skib{ 1631235783Skib struct sbuf m; 1632235783Skib struct i915_info_sysctl_thunk *thunk; 1633235783Skib struct drm_device *dev; 1634235783Skib drm_i915_private_t *dev_priv; 1635280369Skib char *p; 1636235783Skib int error; 1637235783Skib 1638235783Skib thunk = arg1; 1639235783Skib dev = thunk->dev; 1640235783Skib dev_priv = dev->dev_private; 1641235783Skib if (dev_priv == NULL) 1642235783Skib return (EBUSY); 1643235783Skib error = sysctl_wire_old_buffer(req, 0); 1644235783Skib if (error != 0) 1645235783Skib return (error); 1646235783Skib sbuf_new_for_sysctl(&m, NULL, 128, req); 1647282199Sdumbbell error = -i915_info_sysctl_list[thunk->idx].ptr(dev, &m, 1648235783Skib thunk->arg); 1649235783Skib if (error == 0) 1650235783Skib error = sbuf_finish(&m); 1651235783Skib sbuf_delete(&m); 1652280369Skib if (error != 0 || req->newptr == NULL) 1653280369Skib return (error); 1654280369Skib if (req->newlen > 2048) 1655280369Skib return (E2BIG); 1656280369Skib p = malloc(req->newlen + 1, M_TEMP, M_WAITOK); 1657280369Skib error = SYSCTL_IN(req, p, req->newlen); 1658280369Skib if (error != 0) 1659280369Skib goto out; 1660280369Skib p[req->newlen] = '\0'; 1661280369Skib error = i915_info_sysctl_list[thunk->idx].ptr_w(dev, p, 1662280369Skib thunk->arg); 1663280369Skibout: 1664280369Skib free(p, M_TEMP); 1665235783Skib return (error); 1666235783Skib} 1667235783Skib 1668235783Skibextern int i915_gem_sync_exec_requests; 1669235783Skibextern int i915_fix_mi_batchbuffer_end; 1670235783Skibextern int i915_intr_pf; 1671235783Skibextern long i915_gem_wired_pages_cnt; 1672235783Skib 1673235783Skibint 1674235783Skibi915_sysctl_init(struct drm_device *dev, struct sysctl_ctx_list *ctx, 1675235783Skib struct sysctl_oid *top) 1676235783Skib{ 1677235783Skib struct sysctl_oid *oid, *info; 1678235783Skib struct i915_info_sysctl_thunk *thunks; 1679235783Skib int i, error; 1680235783Skib 1681282199Sdumbbell thunks = malloc(sizeof(*thunks) * ARRAY_SIZE(i915_info_sysctl_list), 1682235783Skib DRM_MEM_DRIVER, M_WAITOK | M_ZERO); 1683282199Sdumbbell for (i = 0; i < ARRAY_SIZE(i915_info_sysctl_list); i++) { 1684235783Skib thunks[i].dev = dev; 1685235783Skib thunks[i].idx = i; 1686235783Skib thunks[i].arg = i915_info_sysctl_list[i].data; 1687235783Skib } 1688235783Skib dev->sysctl_private = thunks; 1689235783Skib info = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(top), OID_AUTO, "info", 1690235783Skib CTLFLAG_RW, NULL, NULL); 1691235783Skib if (info == NULL) 1692282199Sdumbbell return (-ENOMEM); 1693282199Sdumbbell for (i = 0; i < ARRAY_SIZE(i915_info_sysctl_list); i++) { 1694235783Skib oid = SYSCTL_ADD_OID(ctx, SYSCTL_CHILDREN(info), OID_AUTO, 1695280369Skib i915_info_sysctl_list[i].name, CTLTYPE_STRING | 1696280369Skib (i915_info_sysctl_list[i].ptr_w != NULL ? CTLFLAG_RW : 1697280369Skib CTLFLAG_RD), 1698235783Skib &thunks[i], 0, i915_info_sysctl_handler, "A", NULL); 1699235783Skib if (oid == NULL) 1700282199Sdumbbell return (-ENOMEM); 1701235783Skib } 1702235783Skib oid = SYSCTL_ADD_LONG(ctx, SYSCTL_CHILDREN(info), OID_AUTO, 1703235783Skib "i915_gem_wired_pages", CTLFLAG_RD, &i915_gem_wired_pages_cnt, 1704235783Skib NULL); 1705235783Skib oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(top), OID_AUTO, "wedged", 1706235783Skib CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, dev, 0, 1707235783Skib i915_debug_set_wedged, "I", NULL); 1708235783Skib if (oid == NULL) 1709282199Sdumbbell return (-ENOMEM); 1710235783Skib oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(top), OID_AUTO, "max_freq", 1711235783Skib CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, dev, 0, i915_max_freq, 1712235783Skib "I", NULL); 1713235783Skib if (oid == NULL) 1714282199Sdumbbell return (-ENOMEM); 1715235783Skib oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(top), OID_AUTO, 1716235783Skib "cache_sharing", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, dev, 1717235783Skib 0, i915_cache_sharing, "I", NULL); 1718235783Skib if (oid == NULL) 1719282199Sdumbbell return (-ENOMEM); 1720280369Skib oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(top), OID_AUTO, 1721280369Skib "stop_rings", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, dev, 1722280369Skib 0, i915_stop_rings, "I", NULL); 1723280369Skib if (oid == NULL) 1724282199Sdumbbell return (-ENOMEM); 1725235783Skib oid = SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(top), OID_AUTO, "sync_exec", 1726235783Skib CTLFLAG_RW, &i915_gem_sync_exec_requests, 0, NULL); 1727235783Skib if (oid == NULL) 1728282199Sdumbbell return (-ENOMEM); 1729235783Skib oid = SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(top), OID_AUTO, "fix_mi", 1730235783Skib CTLFLAG_RW, &i915_fix_mi_batchbuffer_end, 0, NULL); 1731235783Skib if (oid == NULL) 1732282199Sdumbbell return (-ENOMEM); 1733235783Skib oid = SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(top), OID_AUTO, "intr_pf", 1734235783Skib CTLFLAG_RW, &i915_intr_pf, 0, NULL); 1735235783Skib if (oid == NULL) 1736282199Sdumbbell return (-ENOMEM); 1737235783Skib 1738235783Skib error = drm_add_busid_modesetting(dev, ctx, top); 1739235783Skib if (error != 0) 1740235783Skib return (error); 1741235783Skib 1742235783Skib return (0); 1743235783Skib} 1744235783Skib 1745235783Skibvoid 1746235783Skibi915_sysctl_cleanup(struct drm_device *dev) 1747235783Skib{ 1748235783Skib 1749235783Skib free(dev->sysctl_private, DRM_MEM_DRIVER); 1750235783Skib} 1751