diff options
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) I915_READ(GEN8_PCU_IIR)); seq_printf(m, "PCU interrupt enable:\t%08x\n", I915_READ(GEN8_PCU_IER)); - } else if (IS_VALLEYVIEW(dev)) { + } else if (IS_VALLEYVIEW(dev_priv)) { seq_printf(m, "Display IER:\t%08x\n", I915_READ(VLV_IER)); seq_printf(m, "Display IIR:\t%08x\n", @@ -880,7 +864,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) seq_printf(m, "DPINVGTT:\t%08x\n", I915_READ(DPINVGTT)); |