diff options
author | Dave Airlie <airlied@redhat.com> | 2016-09-20 06:23:22 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-09-20 06:23:22 +1000 |
commit | b81a6179b6035a77d9d56d08ba1c0f81d6d4c2c5 (patch) | |
tree | 8513b3bb5d33f816f6c0a1eb96ad5071d57a54e0 /drivers/gpu | |
parent | bd4a68da1989a3735b9c183422effc177e2d5ae8 (diff) | |
parent | 6e05f3d3b9298a56d6f1acb474a75cf14a17c31e (diff) | |
download | linux-b81a6179b6035a77d9d56d08ba1c0f81d6d4c2c5.tar.gz linux-b81a6179b6035a77d9d56d08ba1c0f81d6d4c2c5.tar.bz2 linux-b81a6179b6035a77d9d56d08ba1c0f81d6d4c2c5.zip |
Merge tag 'drm-intel-next-2016-09-19' of git://anongit.freedesktop.org/drm-intel into drm-next
- refactor the sseu code (Imre)
- refine guc dmesg output (Dave Gordon)
- more vgpu work
- more skl wm fixes (Lyude)
- refactor dpll code in prep for upfront link training (Jim Bride et al)
- consolidate all platform feature checks into intel_device_info (Carlos Santa)
- refactor elsp/execlist submission as prep for re-submission after hang
recovery and eventually scheduling (Chris Wilson)
- allow synchronous gpu reset handling, to remove tricky/impossible/fragile
error recovery code (Chris Wilson)
- prep work for nonblocking (execlist) submission, using fences to track
depencies and drive elsp submission (Chris Wilson)
- partial error recover/resubmission of non-guilty batches after hangs (Chris Wilson)
- full dma-buf implicit fencing support (Chris Wilson)
- dp link training fixes (Jim, Dhinkaran, Navare, ...)
- obey dp branch device pixel rate/bpc/clock limits (Mika Kahola), needed for
many vga dongles
- bunch of small cleanups and polish all over, as usual
[airlied: printing macros collided]
* tag 'drm-intel-next-2016-09-19' of git://anongit.freedesktop.org/drm-intel: (163 commits)
drm/i915: Update DRIVER_DATE to 20160919
drm: Fix DisplayPort branch device ID kernel-doc
drm/i915: use NULL for NULL pointers
drm/i915: do not use 'false' as a NULL pointer
drm/i915: make intel_dp_compute_bpp static
drm: Add DP branch device info on debugfs
drm/i915: Update bits per component for display info
drm/i915: Check pixel rate for DP to VGA dongle
drm/i915: Read DP branch device SW revision
drm/i915: Read DP branch device HW revision
drm/i915: Cleanup DisplayPort AUX channel initialization
drm: Read DP branch device id
drm: Helper to read max bits per component
drm: Helper to read max clock rate
drm: Drop VGA from bpc definitions
drm: Add missing DP downstream port types
drm/i915: Add ddb size field to device info structure
drm/i915/guc: general tidying up (submission)
drm/i915/guc: general tidying up (loader)
drm/i915: clarify PMINTRMSK/pm_intr_keep usage
...
Diffstat (limited to 'drivers/gpu')
65 files changed, 4754 insertions, 3162 deletions
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 031c4d335b08..0ad20f1cdf69 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -439,6 +439,179 @@ int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link) } EXPORT_SYMBOL(drm_dp_link_configure); +/** + * drm_dp_downstream_max_clock() - extract branch device max + * pixel rate for legacy VGA + * converter or max TMDS clock + * rate for others + * @dpcd: DisplayPort configuration data + * @port_cap: port capabilities + * + * Returns max clock in kHz on success or 0 if max clock not defined + */ +int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], + const u8 port_cap[4]) +{ + int type = port_cap[0] & DP_DS_PORT_TYPE_MASK; + bool detailed_cap_info = dpcd[DP_DOWNSTREAMPORT_PRESENT] & + DP_DETAILED_CAP_INFO_AVAILABLE; + + if (!detailed_cap_info) + return 0; + + switch (type) { + case DP_DS_PORT_TYPE_VGA: + return port_cap[1] * 8 * 1000; + case DP_DS_PORT_TYPE_DVI: + case DP_DS_PORT_TYPE_HDMI: + case DP_DS_PORT_TYPE_DP_DUALMODE: + return port_cap[1] * 2500; + default: + return 0; + } +} +EXPORT_SYMBOL(drm_dp_downstream_max_clock); + +/** + * drm_dp_downstream_max_bpc() - extract branch device max + * bits per component + * @dpcd: DisplayPort configuration data + * @port_cap: port capabilities + * + * Returns max bpc on success or 0 if max bpc not defined + */ +int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], + const u8 port_cap[4]) +{ + int type = port_cap[0] & DP_DS_PORT_TYPE_MASK; + bool detailed_cap_info = dpcd[DP_DOWNSTREAMPORT_PRESENT] & + DP_DETAILED_CAP_INFO_AVAILABLE; + int bpc; + + if (!detailed_cap_info) + return 0; + + switch (type) { + case DP_DS_PORT_TYPE_VGA: + case DP_DS_PORT_TYPE_DVI: + case DP_DS_PORT_TYPE_HDMI: + case DP_DS_PORT_TYPE_DP_DUALMODE: + bpc = port_cap[2] & DP_DS_MAX_BPC_MASK; + + switch (bpc) { + case DP_DS_8BPC: + return 8; + case DP_DS_10BPC: + return 10; + case DP_DS_12BPC: + return 12; + case DP_DS_16BPC: + return 16; + } + default: + return 0; + } +} +EXPORT_SYMBOL(drm_dp_downstream_max_bpc); + +/** + * drm_dp_downstream_id() - identify branch device + * @aux: DisplayPort AUX channel + * @id: DisplayPort branch device id + * + * Returns branch device id on success or NULL on failure + */ +int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6]) +{ + return drm_dp_dpcd_read(aux, DP_BRANCH_ID, id, 6); +} +EXPORT_SYMBOL(drm_dp_downstream_id); + +/** + * drm_dp_downstream_debug() - debug DP branch devices + * @m: pointer for debugfs file + * @dpcd: DisplayPort configuration data + * @port_cap: port capabilities + * @aux: DisplayPort AUX channel + * + */ +void drm_dp_downstream_debug(struct seq_file *m, + const u8 dpcd[DP_RECEIVER_CAP_SIZE], + const u8 port_cap[4], struct drm_dp_aux *aux) +{ + bool detailed_cap_info = dpcd[DP_DOWNSTREAMPORT_PRESENT] & + DP_DETAILED_CAP_INFO_AVAILABLE; + int clk; + int bpc; + char id[6]; + int len; + uint8_t rev[2]; + int type = port_cap[0] & DP_DS_PORT_TYPE_MASK; + bool branch_device = dpcd[DP_DOWNSTREAMPORT_PRESENT] & + DP_DWN_STRM_PORT_PRESENT; + + seq_printf(m, "\tDP branch device present: %s\n", + branch_device ? "yes" : "no"); + + if (!branch_device) + return; + + switch (type) { + case DP_DS_PORT_TYPE_DP: + seq_puts(m, "\t\tType: DisplayPort\n"); + break; + case DP_DS_PORT_TYPE_VGA: + seq_puts(m, "\t\tType: VGA\n"); + break; + case DP_DS_PORT_TYPE_DVI: + seq_puts(m, "\t\tType: DVI\n"); + break; + case DP_DS_PORT_TYPE_HDMI: + seq_puts(m, "\t\tType: HDMI\n"); + break; + case DP_DS_PORT_TYPE_NON_EDID: + seq_puts(m, "\t\tType: others without EDID support\n"); + break; + case DP_DS_PORT_TYPE_DP_DUALMODE: + seq_puts(m, "\t\tType: DP++\n"); + break; + case DP_DS_PORT_TYPE_WIRELESS: + seq_puts(m, "\t\tType: Wireless\n"); + break; + default: + seq_puts(m, "\t\tType: N/A\n"); + } + + drm_dp_downstream_id(aux, id); + seq_printf(m, "\t\tID: %s\n", id); + + len = drm_dp_dpcd_read(aux, DP_BRANCH_HW_REV, &rev[0], 1); + if (len > 0) + seq_printf(m, "\t\tHW: %d.%d\n", + (rev[0] & 0xf0) >> 4, rev[0] & 0xf); + + len = drm_dp_dpcd_read(aux, DP_BRANCH_SW_REV, &rev, 2); + if (len > 0) + seq_printf(m, "\t\tSW: %d.%d\n", rev[0], rev[1]); + + if (detailed_cap_info) { + clk = drm_dp_downstream_max_clock(dpcd, port_cap); + + if (clk > 0) { + if (type == DP_DS_PORT_TYPE_VGA) + seq_printf(m, "\t\tMax dot clock: %d kHz\n", clk); + else + seq_printf(m, "\t\tMax TMDS clock: %d kHz\n", clk); + } + + bpc = drm_dp_downstream_max_bpc(dpcd, port_cap); + + if (bpc > 0) + seq_printf(m, "\t\tMax bpc: %d\n", bpc); + } +} +EXPORT_SYMBOL(drm_dp_downstream_debug); + /* * I2C-over-AUX implementation */ diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index a7da24640e88..a998c2bce70a 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -16,6 +16,7 @@ i915-y := i915_drv.o \ i915_params.o \ i915_pci.o \ i915_suspend.o \ + i915_sw_fence.o \ i915_sysfs.o \ intel_csr.o \ intel_device_info.o \ diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 3c72b3b103e7..70980f82a15b 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -984,7 +984,7 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, src = ERR_PTR(-ENODEV); if (src_needs_clflush && - i915_memcpy_from_wc((void *)(uintptr_t)batch_start_offset, 0, 0)) { + i915_memcpy_from_wc((void *)(uintptr_t)batch_start_offset, NULL, 0)) { src = i915_gem_object_pin_map(src_obj, I915_MAP_WC); if (!IS_ERR(src)) { i915_memcpy_from_wc(dst, diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a95d7bc81fb9..27b0e34dadec 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -40,6 +40,11 @@ #include <drm/i915_drm.h> #include "i915_drv.h" +static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node) +{ + return to_i915(node->minor->dev); +} + /* 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 @@ -57,7 +62,7 @@ drm_add_fake_info_node(struct drm_minor *minor, node->minor = minor; node->dent = ent; - node->info_ent = (void *) key; + node->info_ent = (void *)key; mutex_lock(&minor->debugfs_lock); list_add(&node->list, &minor->debugfs_list); @@ -68,12 +73,11 @@ drm_add_fake_info_node(struct drm_minor *minor, static int i915_capabilities(struct seq_file *m, void *data) { - struct drm_info_node *node = m->private; - struct drm_device *dev = node->minor->dev; - const struct intel_device_info *info = INTEL_INFO(dev); + struct drm_i915_private *dev_priv = node_to_i915(m->private); + const struct intel_device_info *info = INTEL_INFO(dev_priv); - seq_printf(m, "gen: %d\n", info->gen); - seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(dev)); + seq_printf(m, "gen: %d\n", INTEL_GEN(dev_priv)); + seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(dev_priv)); #define PRINT_FLAG(x) seq_printf(m, #x ": %s\n", yesno(info->x)) #define SEP_SEMICOLON ; DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG, SEP_SEMICOLON); @@ -155,7 +159,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) seq_printf(m, "] %x %s%s%s", i915_gem_active_get_seqno(&obj->last_write, &obj->base.dev->struct_mutex), - i915_cache_level_str(to_i915(obj->base.dev), obj->cache_level), + i915_cache_level_str(dev_priv, obj->cache_level), obj->dirty ? " dirty" : "", obj->madv == I915_MADV_DONTNEED ? " purgeable" : ""); if (obj->base.name) @@ -195,7 +199,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) } engine = i915_gem_active_get_engine(&obj->last_write, - &obj->base.dev->struct_mutex); + &dev_priv->drm.struct_mutex); if (engine) seq_printf(m, " (%s)", engine->name); @@ -221,9 +225,8 @@ static int obj_rank_by_stolen(void *priv, static int i915_gem_stolen_list_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 = to_i915(dev); + struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct drm_device *dev = &dev_priv->drm; struct drm_i915_gem_object *obj; u64 total_obj_size, total_gtt_size; LIST_HEAD(stolen); @@ -365,29 +368,29 @@ static int per_file_ctx_stats(int id, void *ptr, void *data) static void print_context_stats(struct seq_file *m, struct drm_i915_private *dev_priv) { + struct drm_device *dev = &dev_priv->drm; struct file_stats stats; struct drm_file *file; memset(&stats, 0, sizeof(stats)); - mutex_lock(&dev_priv->drm.struct_mutex); + mutex_lock(&dev->struct_mutex); if (dev_priv->kernel_context) per_file_ctx_stats(0, dev_priv->kernel_context, &stats); - list_for_each_entry(file, &dev_priv->drm.filelist, lhead) { + list_for_each_entry(file, &dev->filelist, lhead) { struct drm_i915_file_private *fpriv = file->driver_priv; idr_for_each(&fpriv->context_idr, per_file_ctx_stats, &stats); } - mutex_unlock(&dev_priv->drm.struct_mutex); + mutex_unlock(&dev->struct_mutex); print_file_stats(m, "[k]contexts", stats); } -static int i915_gem_object_info(struct seq_file *m, void* data) +static int i915_gem_object_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 = to_i915(dev); + struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct drm_device *dev = &dev_priv->drm; struct i915_ggtt *ggtt = &dev_priv->ggtt; u32 count, mapped_count, purgeable_count, dpy_count; u64 size, mapped_size, purgeable_size, dpy_size; @@ -497,9 +500,9 @@ static int i915_gem_object_info(struct seq_file *m, void* data) static int i915_gem_gtt_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 = to_i915(dev); - bool show_pin_display_only = !!data; + struct drm_i915_private *dev_priv = node_to_i915(node); + struct drm_device *dev = &dev_priv->drm; + bool show_pin_display_only = !!node->info_ent->data; struct drm_i915_gem_object *obj; u64 total_obj_size, total_gtt_size; int count, ret; @@ -531,9 +534,8 @@ static int i915_gem_gtt_info(struct seq_file *m, void *data) static int i915_gem_pageflip_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 = to_i915(dev); + struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct drm_device *dev = &dev_priv->drm; struct intel_crtc *crtc; int ret; @@ -580,7 +582,7 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data) intel_crtc_get_vblank_counter(crtc)); seq_printf(m, "%d prepares\n", atomic_read(&work->pending)); - if (INTEL_INFO(dev)->gen >= 4) + if (INTEL_GEN(dev_priv) >= 4) addr = I915_HI_DISPBASE(I915_READ(DSPSURF(crtc->plane))); else addr = I915_READ(DSPADDR(crtc->plane)); @@ -601,9 +603,8 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data) static int i915_gem_batch_pool_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 = to_i915(dev); + struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct drm_device *dev = &dev_priv->drm; struct drm_i915_gem_object *obj; struct intel_engine_cs *engine; int total = 0; @@ -646,9 +647,8 @@ static int i915_gem_batch_pool_info(struct seq_file *m, void *data) static int i915_gem_request_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 = to_i915(dev); + struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct drm_device *dev = &dev_priv->drm; struct intel_engine_cs *engine; struct drm_i915_gem_request *req; int ret, any; @@ -713,41 +713,25 @@ static void i915_ring_seqno_info(struct seq_file *m, static int i915_gem_seqno_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 = to_i915(dev); + struct drm_i915_private *dev_priv = node_to_i915(m->private); struct intel_engine_cs *engine; - int ret; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - intel_runtime_pm_get(dev_priv); for_each_engine(engine, dev_priv) i915_ring_seqno_info(m, engine); - intel_runtime_pm_put(dev_priv); - mutex_unlock(&dev->struct_mutex); - return 0; } static int i915_interrupt_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 = to_i915(dev); + struct drm_i915_private *dev_priv = node_to_i915(m->private); struct intel_engine_cs *engine; - int ret, i, pipe; + int i, pipe; - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; intel_runtime_pm_get(dev_priv); - if (IS_CHERRYVIEW(dev)) { + if (IS_CHERRYVIEW(dev_priv)) { seq_printf(m, "Master Interrupt Control:\t%08x\n", I915_READ(GEN8_MASTER_IRQ)); @@ -786,7 +770,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) I915_READ(GEN8_PCU_IIR)); seq_printf(m, "PCU interrupt enable:\t%08x\n", I915_READ(GEN8_PCU_IER)); - } else if (INTEL_INFO(dev)->gen >= 8) { + } else if (INTEL_GEN(dev_priv) >= 8) { seq_printf(m, "Master Interrupt Control:\t%08x\n", I915_READ(GEN8_MASTER_IRQ)); @@ -842,7 +826,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) |