From: Dave Airlie Date: Wed, 4 Mar 2015 23:41:09 +0000 (+1000) Subject: Merge tag 'drm-intel-next-2015-02-14' of git://anongit.freedesktop.org/drm-intel... X-Git-Tag: v4.1-rc1~69^2~35 X-Git-Url: https://repo.jachan.dev/linux.git/commitdiff_plain/7547af91868f0ea940abc25460accc4025c5ce0a?hp=-c Merge tag 'drm-intel-next-2015-02-14' of git://anongit.freedesktop.org/drm-intel into drm-next - use the atomic helpers for plane_upate/disable hooks (Matt Roper) - refactor the initial plane config code (Damien) - ppgtt prep patches for dynamic pagetable alloc (Ben Widawsky, reworked and rebased by a lot of other people) - framebuffer modifier support from Tvrtko Ursulin, drm core code from Rob Clark - piles of workaround patches for skl from Damien and Nick Hoath - vGPU support for xengt on the client side (Yu Zhang) - and the usual smaller things all over * tag 'drm-intel-next-2015-02-14' of git://anongit.freedesktop.org/drm-intel: (88 commits) drm/i915: Update DRIVER_DATE to 20150214 drm/i915: Remove references to previously removed UMS config option drm/i915/skl: Use a LRI for WaDisableDgMirrorFixInHalfSliceChicken5 drm/i915/skl: Fix always true comparison in a revision id check drm/i915/skl: Implement WaEnableLbsSlaRetryTimerDecrement drm/i915/skl: Implement WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken drm/i915: Add process identifier to requests drm/i915/skl: Implement WaBarrierPerformanceFixDisable drm/i915/skl: Implement WaCcsTlbPrefetchDisable:skl drm/i915/skl: Implement WaDisableChickenBitTSGBarrierAckForFFSliceCS drm/i915/skl: Implement WaDisableHDCInvalidation drm/i915/skl: Implement WaDisableLSQCROPERFforOCL drm/i915/skl: Implement WaDisablePartialResolveInVc drm/i915/skl: Introduce a SKL specific init_workarounds() drm/i915/skl: Document that we implement WaRsClearFWBitsAtReset drm/i915/skl: Implement WaSetGAPSunitClckGateDisable drm/i915/skl: Make the init clock gating function skylake specific drm/i915/skl: Provide a gen9 specific init_render_ring() drm/i915/skl: Document the WM read latency W/A with its name drm/i915/skl: Also detect eDRAM on SKL ... --- 7547af91868f0ea940abc25460accc4025c5ce0a diff --combined drivers/gpu/drm/drm_crtc.c index 4dacee645153,b15d720eda4c..29dbde5ecef7 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@@ -691,10 -691,6 +691,10 @@@ int drm_crtc_init_with_planes(struct dr if (cursor) cursor->possible_crtcs = 1 << drm_crtc_index(crtc); + if (drm_core_check_feature(dev, DRIVER_ATOMIC)) { + drm_object_attach_property(&crtc->base, config->prop_active, 0); + } + return 0; } EXPORT_SYMBOL(drm_crtc_init_with_planes); @@@ -787,7 -783,7 +787,7 @@@ int drm_display_info_set_bus_formats(st if (formats && num_formats) { fmts = kmemdup(formats, sizeof(*formats) * num_formats, GFP_KERNEL); - if (!formats) + if (!fmts) return -ENOMEM; } @@@ -1065,6 -1061,61 +1065,6 @@@ void drm_connector_unplug_all(struct dr } EXPORT_SYMBOL(drm_connector_unplug_all); -/** - * drm_bridge_init - initialize a drm transcoder/bridge - * @dev: drm device - * @bridge: transcoder/bridge to set up - * @funcs: bridge function table - * - * Initialises a preallocated bridge. Bridges should be - * subclassed as part of driver connector objects. - * - * Returns: - * Zero on success, error code on failure. - */ -int drm_bridge_init(struct drm_device *dev, struct drm_bridge *bridge, - const struct drm_bridge_funcs *funcs) -{ - int ret; - - drm_modeset_lock_all(dev); - - ret = drm_mode_object_get(dev, &bridge->base, DRM_MODE_OBJECT_BRIDGE); - if (ret) - goto out; - - bridge->dev = dev; - bridge->funcs = funcs; - - list_add_tail(&bridge->head, &dev->mode_config.bridge_list); - dev->mode_config.num_bridge++; - - out: - drm_modeset_unlock_all(dev); - return ret; -} -EXPORT_SYMBOL(drm_bridge_init); - -/** - * drm_bridge_cleanup - cleans up an initialised bridge - * @bridge: bridge to cleanup - * - * Cleans up the bridge but doesn't free the object. - */ -void drm_bridge_cleanup(struct drm_bridge *bridge) -{ - struct drm_device *dev = bridge->dev; - - drm_modeset_lock_all(dev); - drm_mode_object_put(dev, &bridge->base); - list_del(&bridge->head); - dev->mode_config.num_bridge--; - drm_modeset_unlock_all(dev); - - memset(bridge, 0, sizeof(*bridge)); -} -EXPORT_SYMBOL(drm_bridge_cleanup); - /** * drm_encoder_init - Init a preallocated encoder * @dev: drm device @@@ -1430,12 -1481,6 +1430,12 @@@ static int drm_mode_create_standard_pro return -ENOMEM; dev->mode_config.prop_crtc_id = prop; + prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC, + "ACTIVE"); + if (!prop) + return -ENOMEM; + dev->mode_config.prop_active = prop; + return 0; } @@@ -1660,6 -1705,7 +1660,6 @@@ static int drm_mode_group_init(struct d total_objects += dev->mode_config.num_crtc; total_objects += dev->mode_config.num_connector; total_objects += dev->mode_config.num_encoder; - total_objects += dev->mode_config.num_bridge; group->id_list = kcalloc(total_objects, sizeof(uint32_t), GFP_KERNEL); if (!group->id_list) @@@ -1668,6 -1714,7 +1668,6 @@@ group->num_crtcs = 0; group->num_connectors = 0; group->num_encoders = 0; - group->num_bridges = 0; return 0; } @@@ -1687,6 -1734,7 +1687,6 @@@ int drm_mode_group_init_legacy_group(st struct drm_crtc *crtc; struct drm_encoder *encoder; struct drm_connector *connector; - struct drm_bridge *bridge; int ret; ret = drm_mode_group_init(dev, group); @@@ -1704,6 -1752,11 +1704,6 @@@ group->id_list[group->num_crtcs + group->num_encoders + group->num_connectors++] = connector->base.id; - list_for_each_entry(bridge, &dev->mode_config.bridge_list, head) - group->id_list[group->num_crtcs + group->num_encoders + - group->num_connectors + group->num_bridges++] = - bridge->base.id; - return 0; } EXPORT_SYMBOL(drm_mode_group_init_legacy_group); @@@ -2009,32 -2062,21 +2009,32 @@@ int drm_mode_getcrtc(struct drm_device return -ENOENT; drm_modeset_lock_crtc(crtc, crtc->primary); - crtc_resp->x = crtc->x; - crtc_resp->y = crtc->y; crtc_resp->gamma_size = crtc->gamma_size; if (crtc->primary->fb) crtc_resp->fb_id = crtc->primary->fb->base.id; else crtc_resp->fb_id = 0; - if (crtc->enabled) { - - drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode); - crtc_resp->mode_valid = 1; + if (crtc->state) { + crtc_resp->x = crtc->primary->state->src_x >> 16; + crtc_resp->y = crtc->primary->state->src_y >> 16; + if (crtc->state->enable) { + drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->state->mode); + crtc_resp->mode_valid = 1; + } else { + crtc_resp->mode_valid = 0; + } } else { - crtc_resp->mode_valid = 0; + crtc_resp->x = crtc->x; + crtc_resp->y = crtc->y; + if (crtc->enabled) { + drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode); + crtc_resp->mode_valid = 1; + + } else { + crtc_resp->mode_valid = 0; + } } drm_modeset_unlock_crtc(crtc); @@@ -3272,6 -3314,12 +3272,12 @@@ static int framebuffer_check(const stru DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i); return -EINVAL; } + + if (r->modifier[i] && !(r->flags & DRM_MODE_FB_MODIFIERS)) { + DRM_DEBUG_KMS("bad fb modifier %llu for plane %d\n", + r->modifier[i], i); + return -EINVAL; + } } return 0; @@@ -3285,7 -3333,7 +3291,7 @@@ static struct drm_framebuffer *add_fram struct drm_framebuffer *fb; int ret; - if (r->flags & ~DRM_MODE_FB_INTERLACED) { + if (r->flags & ~(DRM_MODE_FB_INTERLACED | DRM_MODE_FB_MODIFIERS)) { DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags); return ERR_PTR(-EINVAL); } @@@ -3301,6 -3349,12 +3307,12 @@@ return ERR_PTR(-EINVAL); } + if (r->flags & DRM_MODE_FB_MODIFIERS && + !dev->mode_config.allow_fb_modifiers) { + DRM_DEBUG_KMS("driver does not support fb modifiers\n"); + return ERR_PTR(-EINVAL); + } + ret = framebuffer_check(r); if (ret) return ERR_PTR(ret); @@@ -3768,7 -3822,7 +3780,7 @@@ static struct drm_property *property_cr } /** - * drm_property_create_range - create a new ranged property type + * drm_property_create_range - create a new unsigned ranged property type * @dev: drm device * @flags: flags specifying the property type * @name: name of the property @@@ -3779,8 -3833,8 +3791,8 @@@ * object with drm_object_attach_property. The returned property object must be * freed with drm_property_destroy. * - * Userspace is allowed to set any integer value in the (min, max) range - * inclusive. + * Userspace is allowed to set any unsigned integer value in the (min, max) + * range inclusive. * * Returns: * A pointer to the newly created property on success, NULL on failure. @@@ -3794,24 -3848,6 +3806,24 @@@ struct drm_property *drm_property_creat } EXPORT_SYMBOL(drm_property_create_range); +/** + * drm_property_create_signed_range - create a new signed ranged property type + * @dev: drm device + * @flags: flags specifying the property type + * @name: name of the property + * @min: minimum value of the property + * @max: maximum value of the property + * + * This creates a new generic drm property which can then be attached to a drm + * object with drm_object_attach_property. The returned property object must be + * freed with drm_property_destroy. + * + * Userspace is allowed to set any signed integer value in the (min, max) + * range inclusive. + * + * Returns: + * A pointer to the newly created property on success, NULL on failure. + */ struct drm_property *drm_property_create_signed_range(struct drm_device *dev, int flags, const char *name, int64_t min, int64_t max) @@@ -3821,23 -3857,6 +3833,23 @@@ } EXPORT_SYMBOL(drm_property_create_signed_range); +/** + * drm_property_create_object - create a new object property type + * @dev: drm device + * @flags: flags specifying the property type + * @name: name of the property + * @type: object type from DRM_MODE_OBJECT_* defines + * + * This creates a new generic drm property which can then be attached to a drm + * object with drm_object_attach_property. The returned property object must be + * freed with drm_property_destroy. + * + * Userspace is only allowed to set this to any property value of the given + * @type. Only useful for atomic properties, which is enforced. + * + * Returns: + * A pointer to the newly created property on success, NULL on failure. + */ struct drm_property *drm_property_create_object(struct drm_device *dev, int flags, const char *name, uint32_t type) { @@@ -3845,9 -3864,6 +3857,9 @@@ flags |= DRM_MODE_PROP_OBJECT; + if (WARN_ON(!(flags & DRM_MODE_PROP_ATOMIC))) + return NULL; + property = drm_property_create(dev, flags, name, 1); if (!property) return NULL; @@@ -3858,28 -3874,6 +3870,28 @@@ } EXPORT_SYMBOL(drm_property_create_object); +/** + * drm_property_create_bool - create a new boolean property type + * @dev: drm device + * @flags: flags specifying the property type + * @name: name of the property + * + * This creates a new generic drm property which can then be attached to a drm + * object with drm_object_attach_property. The returned property object must be + * freed with drm_property_destroy. + * + * This is implemented as a ranged property with only {0, 1} as valid values. + * + * Returns: + * A pointer to the newly created property on success, NULL on failure. + */ +struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags, + const char *name) +{ + return drm_property_create_range(dev, flags, name, 0, 1); +} +EXPORT_SYMBOL(drm_property_create_bool); + /** * drm_property_add_enum - add a possible value to an enumeration property * @property: enumeration property to change @@@ -5391,6 -5385,7 +5403,6 @@@ void drm_mode_config_init(struct drm_de INIT_LIST_HEAD(&dev->mode_config.fb_list); INIT_LIST_HEAD(&dev->mode_config.crtc_list); INIT_LIST_HEAD(&dev->mode_config.connector_list); - INIT_LIST_HEAD(&dev->mode_config.bridge_list); INIT_LIST_HEAD(&dev->mode_config.encoder_list); INIT_LIST_HEAD(&dev->mode_config.property_list); INIT_LIST_HEAD(&dev->mode_config.property_blob_list); @@@ -5430,6 -5425,7 +5442,6 @@@ void drm_mode_config_cleanup(struct drm struct drm_connector *connector, *ot; struct drm_crtc *crtc, *ct; struct drm_encoder *encoder, *enct; - struct drm_bridge *bridge, *brt; struct drm_framebuffer *fb, *fbt; struct drm_property *property, *pt; struct drm_property_blob *blob, *bt; @@@ -5440,6 -5436,11 +5452,6 @@@ encoder->funcs->destroy(encoder); } - list_for_each_entry_safe(bridge, brt, - &dev->mode_config.bridge_list, head) { - bridge->funcs->destroy(bridge); - } - list_for_each_entry_safe(connector, ot, &dev->mode_config.connector_list, head) { connector->funcs->destroy(connector); diff --combined drivers/gpu/drm/i915/i915_debugfs.c index 96e811fe24ca,661527cb00ea..164fa8286fb9 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@@ -1223,11 -1223,8 +1223,11 @@@ out static int i915_hangcheck_info(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; - struct drm_i915_private *dev_priv = to_i915(node->minor->dev); + struct drm_device *dev = node->minor->dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *ring; + u64 acthd[I915_NUM_RINGS]; + u32 seqno[I915_NUM_RINGS]; int i; if (!i915.enable_hangcheck) { @@@ -1235,15 -1232,6 +1235,15 @@@ return 0; } + intel_runtime_pm_get(dev_priv); + + for_each_ring(ring, dev_priv, i) { + seqno[i] = ring->get_seqno(ring, false); + acthd[i] = intel_ring_get_active_head(ring); + } + + intel_runtime_pm_put(dev_priv); + if (delayed_work_pending(&dev_priv->gpu_error.hangcheck_work)) { seq_printf(m, "Hangcheck active, fires in %dms\n", jiffies_to_msecs(dev_priv->gpu_error.hangcheck_work.timer.expires - @@@ -1254,14 -1242,14 +1254,14 @@@ for_each_ring(ring, dev_priv, i) { seq_printf(m, "%s:\n", ring->name); seq_printf(m, "\tseqno = %x [current %x]\n", - ring->hangcheck.seqno, ring->get_seqno(ring, false)); - seq_printf(m, "\taction = %d\n", ring->hangcheck.action); - seq_printf(m, "\tscore = %d\n", ring->hangcheck.score); + ring->hangcheck.seqno, seqno[i]); seq_printf(m, "\tACTHD = 0x%08llx [current 0x%08llx]\n", (long long)ring->hangcheck.acthd, - (long long)intel_ring_get_active_head(ring)); + (long long)acthd[i]); seq_printf(m, "\tmax ACTHD = 0x%08llx\n", (long long)ring->hangcheck.max_acthd); + seq_printf(m, "\tscore = %d\n", ring->hangcheck.score); + seq_printf(m, "\taction = %d\n", ring->hangcheck.action); } return 0; @@@ -1778,11 -1766,12 +1778,12 @@@ static int i915_gem_framebuffer_info(st ifbdev = dev_priv->fbdev; fb = to_intel_framebuffer(ifbdev->helper.fb); - seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, refcount %d, obj ", + seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ", fb->base.width, fb->base.height, fb->base.depth, fb->base.bits_per_pixel, + fb->base.modifier[0], atomic_read(&fb->base.refcount.refcount)); describe_obj(m, fb->obj); seq_putc(m, '\n'); @@@ -1793,11 -1782,12 +1794,12 @@@ if (ifbdev && &fb->base == ifbdev->helper.fb) continue; - seq_printf(m, "user size: %d x %d, depth %d, %d bpp, refcount %d, obj ", + seq_printf(m, "user size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ", fb->base.width, fb->base.height, fb->base.depth, fb->base.bits_per_pixel, + fb->base.modifier[0], atomic_read(&fb->base.refcount.refcount)); describe_obj(m, fb->obj); seq_putc(m, '\n'); @@@ -4226,10 -4216,7 +4228,7 @@@ i915_max_freq_set(void *data, u64 val dev_priv->rps.max_freq_softlimit = val; - if (IS_VALLEYVIEW(dev)) - valleyview_set_rps(dev, val); - else - gen6_set_rps(dev, val); + intel_set_rps(dev, val); mutex_unlock(&dev_priv->rps.hw_lock); @@@ -4304,10 -4291,7 +4303,7 @@@ i915_min_freq_set(void *data, u64 val dev_priv->rps.min_freq_softlimit = val; - if (IS_VALLEYVIEW(dev)) - valleyview_set_rps(dev, val); - else - gen6_set_rps(dev, val); + intel_set_rps(dev, val); mutex_unlock(&dev_priv->rps.hw_lock); diff --combined drivers/gpu/drm/i915/i915_drv.c index 8039cec71fc2,ba6862f5b6b2..4badb23f2c58 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@@ -369,6 -369,19 +369,19 @@@ static const struct intel_device_info i IVB_CURSOR_OFFSETS, }; + static const struct intel_device_info intel_skylake_gt3_info = { + .is_preliminary = 1, + .is_skylake = 1, + .gen = 9, .num_pipes = 3, + .need_gfx_hws = 1, .has_hotplug = 1, + .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, + .has_llc = 1, + .has_ddi = 1, + .has_fbc = 1, + GEN_DEFAULT_PIPEOFFSETS, + IVB_CURSOR_OFFSETS, + }; + /* * Make sure any device matches here are from most specific to most * general. For example, since the Quanta match is based on the subsystem @@@ -406,7 -419,9 +419,9 @@@ INTEL_BDW_GT3M_IDS(&intel_broadwell_gt3m_info), \ INTEL_BDW_GT3D_IDS(&intel_broadwell_gt3d_info), \ INTEL_CHV_IDS(&intel_cherryview_info), \ - INTEL_SKL_IDS(&intel_skylake_info) + INTEL_SKL_GT1_IDS(&intel_skylake_info), \ + INTEL_SKL_GT2_IDS(&intel_skylake_info), \ + INTEL_SKL_GT3_IDS(&intel_skylake_gt3_info) \ static const struct pci_device_id pciidlist[] = { /* aka */ INTEL_PCI_IDS, @@@ -462,13 -477,19 +477,13 @@@ void intel_detect_pch(struct drm_devic } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) { dev_priv->pch_type = PCH_LPT; DRM_DEBUG_KMS("Found LynxPoint PCH\n"); - WARN_ON(!IS_HASWELL(dev)); - WARN_ON(IS_HSW_ULT(dev)); - } else if (IS_BROADWELL(dev)) { - dev_priv->pch_type = PCH_LPT; - dev_priv->pch_id = - INTEL_PCH_LPT_LP_DEVICE_ID_TYPE; - DRM_DEBUG_KMS("This is Broadwell, assuming " - "LynxPoint LP PCH\n"); + WARN_ON(!IS_HASWELL(dev) && !IS_BROADWELL(dev)); + WARN_ON(IS_HSW_ULT(dev) || IS_BDW_ULT(dev)); } else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { dev_priv->pch_type = PCH_LPT; DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); - WARN_ON(!IS_HASWELL(dev)); - WARN_ON(!IS_HSW_ULT(dev)); + WARN_ON(!IS_HASWELL(dev) && !IS_BROADWELL(dev)); + WARN_ON(!IS_HSW_ULT(dev) && !IS_BDW_ULT(dev)); } else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) { dev_priv->pch_type = PCH_SPT; DRM_DEBUG_KMS("Found SunrisePoint PCH\n"); @@@ -1630,11 -1651,9 +1645,9 @@@ static int __init i915_init(void if (!(driver.driver_features & DRIVER_MODESET)) { driver.get_vblank_timestamp = NULL; - #ifndef CONFIG_DRM_I915_UMS /* Silently fail loading to not upset userspace. */ DRM_DEBUG_DRIVER("KMS and UMS disabled.\n"); return 0; - #endif } /* @@@ -1650,10 -1669,8 +1663,8 @@@ static void __exit i915_exit(void) { - #ifndef CONFIG_DRM_I915_UMS if (!(driver.driver_features & DRIVER_MODESET)) return; /* Never loaded a driver. */ - #endif drm_pci_exit(&driver, &i915_pci_driver); } diff --combined drivers/gpu/drm/i915/i915_drv.h index f2a825e39646,3f210aa7652e..39f7e5676c9b --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@@ -31,6 -31,7 +31,7 @@@ #define _I915_DRV_H_ #include + #include #include "i915_reg.h" #include "intel_bios.h" @@@ -55,7 -56,7 +56,7 @@@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" - #define DRIVER_DATE "20150130" + #define DRIVER_DATE "20150214" #undef WARN_ON /* Many gcc seem to no see through this and fall over :( */ @@@ -772,10 -773,10 +773,10 @@@ struct intel_context }; struct i915_fbc { - unsigned long size; + unsigned long uncompressed_size; unsigned threshold; unsigned int fb_id; - enum plane plane; + struct intel_crtc *crtc; int y; struct drm_mm_node compressed_fb; @@@ -1640,6 -1641,10 +1641,10 @@@ struct i915_workarounds u32 count; }; + struct i915_virtual_gpu { + bool active; + }; + struct drm_i915_private { struct drm_device *dev; struct kmem_cache *slab; @@@ -1652,6 -1657,8 +1657,8 @@@ struct intel_uncore uncore; + struct i915_virtual_gpu vgpu; + struct intel_gmbus gmbus[GMBUS_NUM_PORTS]; @@@ -2153,6 -2160,9 +2160,9 @@@ struct drm_i915_gem_request /** file_priv list entry for this request */ struct list_head client_list; + /** process identifier submitting this request */ + struct pid *pid; + uint32_t uniq; /** @@@ -2339,6 -2349,7 +2349,7 @@@ struct drm_i915_cmd_table }) #define INTEL_INFO(p) (&__I915__(p)->info) #define INTEL_DEVID(p) (INTEL_INFO(p)->device_id) + #define INTEL_REVID(p) (__I915__(p)->dev->pdev->revision) #define IS_I830(dev) (INTEL_DEVID(dev) == 0x3577) #define IS_845G(dev) (INTEL_DEVID(dev) == 0x2562) @@@ -2361,9 -2372,6 +2372,6 @@@ #define IS_IVB_GT1(dev) (INTEL_DEVID(dev) == 0x0156 || \ INTEL_DEVID(dev) == 0x0152 || \ INTEL_DEVID(dev) == 0x015a) - #define IS_SNB_GT1(dev) (INTEL_DEVID(dev) == 0x0102 || \ - INTEL_DEVID(dev) == 0x0106 || \ - INTEL_DEVID(dev) == 0x010A) #define IS_VALLEYVIEW(dev) (INTEL_INFO(dev)->is_valleyview) #define IS_CHERRYVIEW(dev) (INTEL_INFO(dev)->is_valleyview && IS_GEN8(dev)) #define IS_HASWELL(dev) (INTEL_INFO(dev)->is_haswell) @@@ -2373,7 -2381,8 +2381,7 @@@ #define IS_HSW_EARLY_SDV(dev) (IS_HASWELL(dev) && \ (INTEL_DEVID(dev) & 0xFF00) == 0x0C00) #define IS_BDW_ULT(dev) (IS_BROADWELL(dev) && \ - ((INTEL_DEVID(dev) & 0xf) == 0x2 || \ - (INTEL_DEVID(dev) & 0xf) == 0x6 || \ + ((INTEL_DEVID(dev) & 0xf) == 0x6 || \ (INTEL_DEVID(dev) & 0xf) == 0xe)) #define IS_BDW_GT3(dev) (IS_BROADWELL(dev) && \ (INTEL_DEVID(dev) & 0x00F0) == 0x0020) @@@ -2386,6 -2395,12 +2394,12 @@@ INTEL_DEVID(dev) == 0x0A1E) #define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary) + #define SKL_REVID_A0 (0x0) + #define SKL_REVID_B0 (0x1) + #define SKL_REVID_C0 (0x2) + #define SKL_REVID_D0 (0x3) + #define SKL_REVID_E0 (0x4) + /* * The genX designation typically refers to the render engine, so render * capability related checks should use IS_GEN, while display and other checks @@@ -2493,8 -2508,6 +2507,6 @@@ extern int i915_max_ioctl extern int i915_suspend_legacy(struct drm_device *dev, pm_message_t state); extern int i915_resume_legacy(struct drm_device *dev); - extern int i915_master_create(struct drm_device *dev, struct drm_master *master); - extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); /* i915_params.c */ struct i915_params { @@@ -2577,6 -2590,10 +2589,10 @@@ void intel_uncore_forcewake_get(struct void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv, enum forcewake_domains domains); void assert_forcewakes_inactive(struct drm_i915_private *dev_priv); + static inline bool intel_vgpu_active(struct drm_device *dev) + { + return to_i915(dev)->vgpu.active; + } void i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, @@@ -3182,8 -3199,7 +3198,7 @@@ extern void i915_redisable_vga(struct d extern void i915_redisable_vga_power_on(struct drm_device *dev); extern bool ironlake_set_drps(struct drm_device *dev, u8 val); extern void intel_init_pch_refclk(struct drm_device *dev); - extern void gen6_set_rps(struct drm_device *dev, u8 val); - extern void valleyview_set_rps(struct drm_device *dev, u8 val); + extern void intel_set_rps(struct drm_device *dev, u8 val); extern void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable); extern void intel_detect_pch(struct drm_device *dev); @@@ -3196,8 -3212,6 +3211,6 @@@ int i915_reg_read_ioctl(struct drm_devi int i915_get_reset_stats_ioctl(struct drm_device *dev, void *data, struct drm_file *file); - void intel_notify_mmio_flip(struct intel_engine_cs *ring); - /* overlay */ extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); extern void intel_overlay_print_error_state(struct drm_i915_error_state_buf *e, diff --combined drivers/gpu/drm/i915/i915_gem.c index c26d36cc4b31,f28f0dea6c96..61134ab0be81 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@@ -29,6 -29,7 +29,7 @@@ #include #include #include "i915_drv.h" + #include "i915_vgpu.h" #include "i915_trace.h" #include "intel_drv.h" #include @@@ -2492,6 -2493,8 +2493,8 @@@ int __i915_add_request(struct intel_eng list_add_tail(&request->client_list, &file_priv->mm.request_list); spin_unlock(&file_priv->mm.lock); + + request->pid = get_pid(task_pid(current)); } trace_i915_gem_request_add(request); @@@ -2572,6 -2575,8 +2575,8 @@@ static void i915_gem_free_request(struc list_del(&request->list); i915_gem_request_remove_from_client(request); + put_pid(request->pid); + i915_gem_request_unreference(request); } @@@ -3169,13 -3174,6 +3174,13 @@@ static void i965_write_fence_reg(struc u32 size = i915_gem_obj_ggtt_size(obj); uint64_t val; + /* Adjust fence size to match tiled area */ + if (obj->tiling_mode != I915_TILING_NONE) { + uint32_t row_size = obj->stride * + (obj->tiling_mode == I915_TILING_Y ? 32 : 8); + size = (size / row_size) * row_size; + } + val = (uint64_t)((i915_gem_obj_ggtt_offset(obj) + size - 4096) & 0xfffff000) << 32; val |= i915_gem_obj_ggtt_offset(obj) & 0xfffff000; @@@ -4831,18 -4829,25 +4836,18 @@@ i915_gem_init_hw(struct drm_device *dev for (i = 0; i < NUM_L3_SLICES(dev); i++) i915_gem_l3_remap(&dev_priv->ring[RCS], i); - /* - * XXX: Contexts should only be initialized once. Doing a switch to the - * default context switch however is something we'd like to do after - * reset or thaw (the latter may not actually be necessary for HW, but - * goes with our code better). Context switching requires rings (for - * the do_switch), but before enabling PPGTT. So don't move this. - */ - ret = i915_gem_context_enable(dev_priv); + ret = i915_ppgtt_init_hw(dev); if (ret && ret != -EIO) { - DRM_ERROR("Context enable failed %d\n", ret); + DRM_ERROR("PPGTT enable failed %d\n", ret); i915_gem_cleanup_ringbuffer(dev); - - return ret; } - ret = i915_ppgtt_init_hw(dev); + ret = i915_gem_context_enable(dev_priv); if (ret && ret != -EIO) { - DRM_ERROR("PPGTT enable failed %d\n", ret); + DRM_ERROR("Context enable failed %d\n", ret); i915_gem_cleanup_ringbuffer(dev); + + return ret; } return ret; @@@ -4987,6 -4992,10 +4992,10 @@@ i915_gem_load(struct drm_device *dev else dev_priv->num_fence_regs = 8; + if (intel_vgpu_active(dev)) + dev_priv->num_fence_regs = + I915_READ(vgtif_reg(avail_rs.fence_num)); + /* Initialize fence registers to zero */ INIT_LIST_HEAD(&dev_priv->mm.fence_list); i915_gem_restore_fences(dev); diff --combined drivers/gpu/drm/i915/intel_dp.c index a74aaf9242b9,dfd94c52a4cc..868a07ba5e59 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@@ -240,7 -240,7 +240,7 @@@ uint32_t intel_dp_pack_aux(const uint8_ return v; } - void intel_dp_unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes) + static void intel_dp_unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes) { int i; if (dst_bytes > 4) @@@ -3521,6 -3521,8 +3521,6 @@@ intel_dp_link_down(struct intel_dp *int enum port port = intel_dig_port->port; struct drm_device *dev = intel_dig_port->base.base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = - to_intel_crtc(intel_dig_port->base.base.crtc); uint32_t DP = intel_dp->DP; if (WARN_ON(HAS_DDI(dev))) @@@ -3545,6 -3547,8 +3545,6 @@@ if (HAS_PCH_IBX(dev) && I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { - struct drm_crtc *crtc = intel_dig_port->base.base.crtc; - /* Hardware workaround: leaving our transcoder select * set to transcoder B while it's off will prevent the * corresponding HDMI output on transcoder A. @@@ -3555,7 -3559,18 +3555,7 @@@ */ DP &= ~DP_PIPEB_SELECT; I915_WRITE(intel_dp->output_reg, DP); - - /* Changes to enable or select take place the vblank - * after being written. - */ - if (WARN_ON(crtc == NULL)) { - /* We should never try to disable a port without a crtc - * attached. For paranoia keep the code around for a - * bit. */ - POSTING_READ(intel_dp->output_reg); - msleep(50); - } else - intel_wait_for_vblank(dev, intel_crtc->pipe); + POSTING_READ(intel_dp->output_reg); } DP &= ~DP_AUDIO_OUTPUT_ENABLE; @@@ -3803,7 -3818,7 +3803,7 @@@ go_again * 3. Use Link Training from 2.5.3.3 and 3.5.1.3 * 4. Check link status on receipt of hot-plug interrupt */ - void + static void intel_dp_check_link_status(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); @@@ -4431,7 -4446,7 +4431,7 @@@ intel_dp_hpd_pulse(struct intel_digital */ DRM_DEBUG_KMS("ignoring long hpd on eDP port %c\n", port_name(intel_dig_port->port)); - return false; + return IRQ_HANDLED; } DRM_DEBUG_KMS("got hpd irq on port %c - %s\n", diff --combined drivers/gpu/drm/i915/intel_dsi.c index 10ab68457ca8,6ce9c4592fe4..c8c8b24e300c --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@@ -360,11 -360,12 +360,11 @@@ static void intel_dsi_device_ready(stru I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_ENTER); usleep_range(2500, 3000); - val = I915_READ(MIPI_PORT_CTRL(port)); - /* Enable MIPI PHY transparent latch * Common bit for both MIPI Port A & MIPI Port C * No similar bit in MIPI Port C reg */ + val = I915_READ(MIPI_PORT_CTRL(PORT_A)); I915_WRITE(MIPI_PORT_CTRL(PORT_A), val | LP_OUTPUT_HOLD); usleep_range(1000, 1500); @@@ -542,10 -543,10 +542,10 @@@ static void intel_dsi_clear_device_read == 0x00000), 30)) DRM_ERROR("DSI LP not going Low\n"); - val = I915_READ(MIPI_PORT_CTRL(port)); /* Disable MIPI PHY transparent latch * Common bit for both MIPI Port A & MIPI Port C */ + val = I915_READ(MIPI_PORT_CTRL(PORT_A)); I915_WRITE(MIPI_PORT_CTRL(PORT_A), val & ~LP_OUTPUT_HOLD); usleep_range(1000, 1500); @@@ -854,7 -855,7 +854,7 @@@ static void intel_dsi_prepare(struct in /* recovery disables */ - I915_WRITE(MIPI_EOT_DISABLE(port), val); + I915_WRITE(MIPI_EOT_DISABLE(port), tmp); /* in terms of low power clock */ I915_WRITE(MIPI_INIT_COUNT(port), intel_dsi->init_count); diff --combined drivers/gpu/drm/i915/intel_lrc.c index 0f358c5999ec,b355da4cae88..aafcef3b6b23 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@@ -254,8 -254,10 +254,10 @@@ u32 intel_execlists_ctx_id(struct drm_i return lrca >> 12; } - static uint64_t execlists_ctx_descriptor(struct drm_i915_gem_object *ctx_obj) + static uint64_t execlists_ctx_descriptor(struct intel_engine_cs *ring, + struct drm_i915_gem_object *ctx_obj) { + struct drm_device *dev = ring->dev; uint64_t desc; uint64_t lrca = i915_gem_obj_ggtt_offset(ctx_obj); @@@ -272,6 -274,13 +274,13 @@@ * signalling between Command Streamers */ /* desc |= GEN8_CTX_FORCE_RESTORE; */ + /* WaEnableForceRestoreInCtxtDescForVCS:skl */ + if (IS_GEN9(dev) && + INTEL_REVID(dev) <= SKL_REVID_B0 && + (ring->id == BCS || ring->id == VCS || + ring->id == VECS || ring->id == VCS2)) + desc |= GEN8_CTX_FORCE_RESTORE; + return desc; } @@@ -286,13 -295,13 +295,13 @@@ static void execlists_elsp_write(struc /* XXX: You must always write both descriptors in the order below. */ if (ctx_obj1) - temp = execlists_ctx_descriptor(ctx_obj1); + temp = execlists_ctx_descriptor(ring, ctx_obj1); else temp = 0; desc[1] = (u32)(temp >> 32); desc[0] = (u32)temp; - temp = execlists_ctx_descriptor(ctx_obj0); + temp = execlists_ctx_descriptor(ring, ctx_obj0); desc[3] = (u32)(temp >> 32); desc[2] = (u32)temp; @@@ -776,7 -785,7 +785,7 @@@ int logical_ring_flush_all_caches(struc return 0; } - /** + /* * intel_logical_ring_advance_and_submit() - advance the tail and submit the workload * @ringbuf: Logical Ringbuffer to advance. * @@@ -785,9 -794,10 +794,10 @@@ * on a queue waiting for the ELSP to be ready to accept a new context submission. At that * point, the tail *inside* the context is updated and the ELSP written to. */ - void intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf, - struct intel_context *ctx, - struct drm_i915_gem_request *request) + static void + intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf, + struct intel_context *ctx, + struct drm_i915_gem_request *request) { struct intel_engine_cs *ring = ringbuf->ring; @@@ -1140,6 -1150,17 +1150,17 @@@ static int gen8_init_render_ring(struc return init_workarounds_ring(ring); } + static int gen9_init_render_ring(struct intel_engine_cs *ring) + { + int ret; + + ret = gen8_init_common_ring(ring); + if (ret) + return ret; + + return init_workarounds_ring(ring); + } + static int gen8_emit_bb_start(struct intel_ringbuffer *ringbuf, struct intel_context *ctx, u64 offset, unsigned flags) @@@ -1211,17 -1232,15 +1232,17 @@@ static int gen8_emit_flush(struct intel cmd = MI_FLUSH_DW + 1; - if (ring == &dev_priv->ring[VCS]) { - if (invalidate_domains & I915_GEM_GPU_DOMAINS) - cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD | - MI_FLUSH_DW_STORE_INDEX | - MI_FLUSH_DW_OP_STOREDW; - } else { - if (invalidate_domains & I915_GEM_DOMAIN_RENDER) - cmd |= MI_INVALIDATE_TLB | MI_FLUSH_DW_STORE_INDEX | - MI_FLUSH_DW_OP_STOREDW; + /* We always require a command barrier so that subsequent + * commands, such as breadcrumb interrupts, are strictly ordered + * wrt the contents of the write cache being flushed to memory + * (and thus being coherent from the CPU). + */ + cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW; + + if (invalidate_domains & I915_GEM_GPU_DOMAINS) { + cmd |= MI_INVALIDATE_TLB; + if (ring == &dev_priv->ring[VCS]) + cmd |= MI_INVALIDATE_BSD; } intel_logical_ring_emit(ringbuf, cmd); @@@ -1316,6 -1335,39 +1337,39 @@@ static int gen8_emit_request(struct int return 0; } + static int intel_lr_context_render_state_init(struct intel_engine_cs *ring, + struct intel_context *ctx) + { + struct intel_ringbuffer *ringbuf = ctx->engine[ring->id].ringbuf; + struct render_state so; + struct drm_i915_file_private *file_priv = ctx->file_priv; + struct drm_file *file = file_priv ? file_priv->file : NULL; + int ret; + + ret = i915_gem_render_state_prepare(ring, &so); + if (ret) + return ret; + + if (so.rodata == NULL) + return 0; + + ret = ring->emit_bb_start(ringbuf, + ctx, + so.ggtt_offset, + I915_DISPATCH_SECURE); + if (ret) + goto out; + + i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), ring); + + ret = __i915_add_request(ring, file, so.obj); + /* intel_logical_ring_add_request moves object to inactive if it + * fails */ + out: + i915_gem_render_state_fini(&so); + return ret; + } + static int gen8_init_rcs_context(struct intel_engine_cs *ring, struct intel_context *ctx) { @@@ -1399,7 -1451,10 +1453,10 @@@ static int logical_render_ring_init(str if (HAS_L3_DPF(dev)) ring->irq_keep_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT; - ring->init_hw = gen8_init_render_ring; + if (INTEL_INFO(dev)->gen >= 9) + ring->init_hw = gen9_init_render_ring; + else + ring->init_hw = gen8_init_render_ring; ring->init_context = gen8_init_rcs_context; ring->cleanup = intel_fini_pipe_control; ring->get_seqno = gen8_get_seqno; @@@ -1581,39 -1636,6 +1638,6 @@@ cleanup_render_ring return ret; } - int intel_lr_context_render_state_init(struct intel_engine_cs *ring, - struct intel_context *ctx) - { - struct intel_ringbuffer *ringbuf = ctx->engine[ring->id].ringbuf; - struct render_state so; - struct drm_i915_file_private *file_priv = ctx->file_priv; - struct drm_file *file = file_priv ? file_priv->file : NULL; - int ret; - - ret = i915_gem_render_state_prepare(ring, &so); - if (ret) - return ret; - - if (so.rodata == NULL) - return 0; - - ret = ring->emit_bb_start(ringbuf, - ctx, - so.ggtt_offset, - I915_DISPATCH_SECURE); - if (ret) - goto out; - - i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), ring); - - ret = __i915_add_request(ring, file, so.obj); - /* intel_logical_ring_add_request moves object to inactive if it - * fails */ - out: - i915_gem_render_state_fini(&so); - return ret; - } - static int populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_obj, struct intel_engine_cs *ring, struct intel_ringbuffer *ringbuf) @@@ -1659,7 -1681,8 +1683,8 @@@ reg_state[CTX_LRI_HEADER_0] |= MI_LRI_FORCE_POSTED; reg_state[CTX_CONTEXT_CONTROL] = RING_CONTEXT_CONTROL(ring); reg_state[CTX_CONTEXT_CONTROL+1] = - _MASKED_BIT_ENABLE((1<<3) | MI_RESTORE_INHIBIT); + _MASKED_BIT_ENABLE(CTX_CTRL_INHIBIT_SYN_CTX_SWITCH | + CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT); reg_state[CTX_RING_HEAD] = RING_HEAD(ring->mmio_base); reg_state[CTX_RING_HEAD+1] = 0; reg_state[CTX_RING_TAIL] = RING_TAIL(ring->mmio_base); diff --combined drivers/gpu/drm/i915/intel_pm.c index 24d77ddcc5f4,f68d12cb0246..f7c993843be8 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@@ -56,24 -56,42 +56,42 @@@ static void gen9_init_clock_gating(stru { struct drm_i915_private *dev_priv = dev->dev_private; - /* - * WaDisableSDEUnitClockGating:skl - * This seems to be a pre-production w/a. - */ - I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | - GEN8_SDEUNIT_CLOCK_GATE_DISABLE); + /* WaEnableLbsSlaRetryTimerDecrement:skl */ + I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) | + GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE); + } - /* - * WaDisableDgMirrorFixInHalfSliceChicken5:skl - * This is a pre-production w/a. - */ - I915_WRITE(GEN9_HALF_SLICE_CHICKEN5, - I915_READ(GEN9_HALF_SLICE_CHICKEN5) & - ~GEN9_DG_MIRROR_FIX_ENABLE); + static void skl_init_clock_gating(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; - /* Wa4x4STCOptimizationDisable:skl */ - I915_WRITE(CACHE_MODE_1, - _MASKED_BIT_ENABLE(GEN8_4x4_STC_OPTIMIZATION_DISABLE)); + gen9_init_clock_gating(dev); + + if (INTEL_REVID(dev) == SKL_REVID_A0) { + /* + * WaDisableSDEUnitClockGating:skl + * WaSetGAPSunitClckGateDisable:skl + */ + I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | + GEN8_GAPSUNIT_CLOCK_GATE_DISABLE | + GEN8_SDEUNIT_CLOCK_GATE_DISABLE); + } + + if (INTEL_REVID(dev) <= SKL_REVID_D0) { + /* WaDisableHDCInvalidation:skl */ + I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | + BDW_DISABLE_HDC_INVALIDATION); + + /* WaDisableChickenBitTSGBarrierAckForFFSliceCS:skl */ + I915_WRITE(FF_SLICE_CS_CHICKEN2, + I915_READ(FF_SLICE_CS_CHICKEN2) | + GEN9_TSG_BARRIER_ACK_DISABLE); + } + + if (INTEL_REVID(dev) <= SKL_REVID_E0) + /* WaDisableLSQCROPERFforOCL:skl */ + I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) | + GEN8_LQSC_RO_PERF_DIS); } static void i915_pineview_get_mem_freq(struct drm_device *dev) @@@ -1711,6 -1729,8 +1729,8 @@@ static void intel_read_wm_latency(struc GEN9_MEM_LATENCY_LEVEL_MASK; /* + * WaWmMemoryReadLatency:skl + * * punit doesn't take into account the read latency so we need * to add 2us to the various latency levels we retrieve from * the punit. @@@ -3750,7 -3770,7 +3770,7 @@@ static u32 gen6_rps_pm_mask(struct drm_ /* gen6_set_rps is called to update the frequency request, but should also be * called when the range (min_delay and max_delay) is modified so that we can * update the GEN6_RP_INTERRUPT_LIMITS register accordingly. */ - void gen6_set_rps(struct drm_device *dev, u8 val) + static void gen6_set_rps(struct drm_device *dev, u8 val) { struct drm_i915_private *dev_priv = dev->dev_private; @@@ -3786,6 -3806,27 +3806,27 @@@ trace_intel_gpu_freq_change(val * 50); } + static void valleyview_set_rps(struct drm_device *dev, u8 val) + { + struct drm_i915_private *dev_priv = dev->dev_private; + + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + WARN_ON(val > dev_priv->rps.max_freq_softlimit); + WARN_ON(val < dev_priv->rps.min_freq_softlimit); + + if (WARN_ONCE(IS_CHERRYVIEW(dev) && (val & 1), + "Odd GPU freq value\n")) + val &= ~1; + + if (val != dev_priv->rps.cur_freq) + vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); + + I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); + + dev_priv->rps.cur_freq = val; + trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val)); + } + /* vlv_set_rps_idle: Set the frequency to Rpn if Gfx clocks are down * * * If Gfx is Idle, then @@@ -3850,38 -3891,20 +3891,20 @@@ void gen6_rps_idle(struct drm_i915_priv void gen6_rps_boost(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; - mutex_lock(&dev_priv->rps.hw_lock); if (dev_priv->rps.enabled) { - if (IS_VALLEYVIEW(dev)) - valleyview_set_rps(dev_priv->dev, dev_priv->rps.max_freq_softlimit); - else - gen6_set_rps(dev_priv->dev, dev_priv->rps.max_freq_softlimit); + intel_set_rps(dev_priv->dev, dev_priv->rps.max_freq_softlimit); dev_priv->rps.last_adj = 0; } mutex_unlock(&dev_priv->rps.hw_lock); } - void valleyview_set_rps(struct drm_device *dev, u8 val) + void intel_set_rps(struct drm_device *dev, u8 val) { - struct drm_i915_private *dev_priv = dev->dev_private; - - WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); - WARN_ON(val > dev_priv->rps.max_freq_softlimit); - WARN_ON(val < dev_priv->rps.min_freq_softlimit); - - if (WARN_ONCE(IS_CHERRYVIEW(dev) && (val & 1), - "Odd GPU freq value\n")) - val &= ~1; - - if (val != dev_priv->rps.cur_freq) - vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); - - I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); - - dev_priv->rps.cur_freq = val; - trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val)); + if (IS_VALLEYVIEW(dev)) + valleyview_set_rps(dev, val); + else + gen6_set_rps(dev, val); } static void gen9_disable_rps(struct drm_device *dev) @@@ -4005,10 -4028,7 +4028,10 @@@ static void gen6_init_rps_frequencies(s &ddcc_status); if (0 == ret) dev_priv->rps.efficient_freq = - (ddcc_status >> 8) & 0xff; + clamp_t(u8, + ((ddcc_status >> 8) & 0xff), + dev_priv->rps.min_freq, + dev_priv->rps.max_freq); } /* Preserve min/max settings in case of re-init */ @@@ -5633,6 -5653,10 +5656,10 @@@ void intel_enable_gt_powersave(struct d { struct drm_i915_private *dev_priv = dev->dev_private; + /* Powersaving is controlled by the host when inside a VM */ + if (intel_vgpu_active(dev)) + return; + if (IS_IRONLAKE_M(dev)) { mutex_lock(&dev->struct_mutex); ironlake_enable_drps(dev); @@@ -6396,7 -6420,8 +6423,8 @@@ void intel_init_clock_gating(struct drm { struct drm_i915_private *dev_priv = dev->dev_private; - dev_priv->display.init_clock_gating(dev); + if (dev_priv->display.init_clock_gating) + dev_priv->display.init_clock_gating(dev); } void intel_suspend_hw(struct drm_device *dev) @@@ -6422,7 -6447,7 +6450,7 @@@ void intel_init_pm(struct drm_device *d if (INTEL_INFO(dev)->gen >= 9) { skl_setup_wm_latency(dev); - dev_priv->display.init_clock_gating = gen9_init_clock_gating; + dev_priv->display.init_clock_gating = skl_init_clock_gating; dev_priv->display.update_wm = skl_update_wm; dev_priv->display.update_sprite_wm = skl_update_sprite_wm; } else if (HAS_PCH_SPLIT(dev)) { diff --combined drivers/gpu/drm/i915/intel_ringbuffer.c index e5b3c6dbd467,e758c0592675..d17e76d32e03 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@@ -502,6 -502,68 +502,68 @@@ static void ring_setup_phys_status_page I915_WRITE(HWS_PGA, addr); } + static void intel_ring_setup_status_page(struct intel_engine_cs *ring) + { + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = ring->dev->dev_private; + u32 mmio = 0; + + /* The ring status page addresses are no longer next to the rest of + * the ring registers as of gen7. + */ + if (IS_GEN7(dev)) { + switch (ring->id) { + case RCS: + mmio = RENDER_HWS_PGA_GEN7; + break; + case BCS: + mmio = BLT_HWS_PGA_GEN7; + break; + /* + * VCS2 actually doesn't exist on Gen7. Only shut up + * gcc switch check warning + */ + case VCS2: + case VCS: + mmio = BSD_HWS_PGA_GEN7; + break; + case VECS: + mmio = VEBOX_HWS_PGA_GEN7; + break; + } + } else if (IS_GEN6(ring->dev)) { + mmio = RING_HWS_PGA_GEN6(ring->mmio_base); + } else { + /* XXX: gen8 returns to sanity */ + mmio = RING_HWS_PGA(ring->mmio_base); + } + + I915_WRITE(mmio, (u32)ring->status_page.gfx_addr); + POSTING_READ(mmio); + + /* + * Flush the TLB for this page + * + * FIXME: These two bits have disappeared on gen8, so a question + * arises: do we still need this and if so how should we go about + * invalidating the TLB? + */ + if (INTEL_INFO(dev)->gen >= 6 && INTEL_INFO(dev)->gen < 8) { + u32 reg = RING_INSTPM(ring->mmio_base); + + /* ring should be idle before issuing a sync flush*/ + WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0); + + I915_WRITE(reg, + _MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE | + INSTPM_SYNC_FLUSH)); + if (wait_for((I915_READ(reg) & INSTPM_SYNC_FLUSH) == 0, + 1000)) + DRM_ERROR("%s: wait for SyncFlush to complete for TLB invalidation timed out\n", + ring->name); + } + } + static bool stop_ring(struct intel_engine_cs *ring) { struct drm_i915_private *dev_priv = to_i915(ring->dev); @@@ -788,12 -850,14 +850,14 @@@ static int bdw_init_workarounds(struct * workaround for for a possible hang in the unlikely event a TLB * invalidation occurs during a PSD flush. */ - /* WaForceEnableNonCoherent:bdw */ - /* WaHdcDisableFetchWhenMasked:bdw */ - /* WaDisableFenceDestinationToSLM:bdw (GT3 pre-production) */ WA_SET_BIT_MASKED(HDC_CHICKEN0, + /* WaForceEnableNonCoherent:bdw */ HDC_FORCE_NON_COHERENT | + /* WaForceContextSaveRestoreNonCoherent:bdw */ + HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT | + /* WaHdcDisableFetchWhenMasked:bdw */ HDC_DONOT_FETCH_MEM_WHEN_MASKED | + /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */ (IS_BDW_GT3(dev) ? HDC_FENCE_DEST_SLM_DISABLE : 0)); /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0: @@@ -870,6 -934,78 +934,78 @@@ static int chv_init_workarounds(struct GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4); + if (INTEL_REVID(dev) == SKL_REVID_C0 || + INTEL_REVID(dev) == SKL_REVID_D0) + /* WaBarrierPerformanceFixDisable:skl */ + WA_SET_BIT_MASKED(HDC_CHICKEN0, + HDC_FENCE_DEST_SLM_DISABLE | + HDC_BARRIER_PERFORMANCE_DISABLE); + + return 0; + } + + static int gen9_init_workarounds(struct intel_engine_cs *ring) + { + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + /* WaDisablePartialInstShootdown:skl */ + WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, + PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); + + /* Syncing dependencies between camera and graphics */ + WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, + GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC); + + if (INTEL_REVID(dev) == SKL_REVID_A0 || + INTEL_REVID(dev) == SKL_REVID_B0) { + /* WaDisableDgMirrorFixInHalfSliceChicken5:skl */ + WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, + GEN9_DG_MIRROR_FIX_ENABLE); + } + + if (IS_SKYLAKE(dev) && INTEL_REVID(dev) <= SKL_REVID_B0) { + /* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:skl */ + WA_SET_BIT_MASKED(GEN7_COMMON_SLICE_CHICKEN1, + GEN9_RHWO_OPTIMIZATION_DISABLE); + WA_SET_BIT_MASKED(GEN9_SLICE_COMMON_ECO_CHICKEN0, + DISABLE_PIXEL_MASK_CAMMING); + } + + if (INTEL_REVID(dev) >= SKL_REVID_C0) { + /* WaEnableYV12BugFixInHalfSliceChicken7:skl */ + WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7, + GEN9_ENABLE_YV12_BUGFIX); + } + + if (INTEL_REVID(dev) <= SKL_REVID_D0) { + /* + *Use Force Non-Coherent whenever executing a 3D context. This + * is a workaround for a possible hang in the unlikely event + * a TLB invalidation occurs during a PSD flush. + */ + /* WaForceEnableNonCoherent:skl */ + WA_SET_BIT_MASKED(HDC_CHICKEN0, + HDC_FORCE_NON_COHERENT); + } + + /* Wa4x4STCOptimizationDisable:skl */ + WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE); + + /* WaDisablePartialResolveInVc:skl */ + WA_SET_BIT_MASKED(CACHE_MODE_1, GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE); + + /* WaCcsTlbPrefetchDisable:skl */ + WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, + GEN9_CCS_TLB_PREFETCH_ENABLE); + + return 0; + } + + static int skl_init_workarounds(struct intel_engine_cs *ring) + { + gen9_init_workarounds(ring); + return 0; } @@@ -888,6 -1024,11 +1024,11 @@@ int init_workarounds_ring(struct intel_ if (IS_CHERRYVIEW(dev)) return chv_init_workarounds(ring); + if (IS_SKYLAKE(dev)) + return skl_init_workarounds(ring); + else if (IS_GEN9(dev)) + return gen9_init_workarounds(ring); + return 0; } @@@ -1386,68 -1527,6 +1527,6 @@@ i8xx_ring_put_irq(struct intel_engine_c spin_unlock_irqrestore(&dev_priv->irq_lock, flags); } - void intel_ring_setup_status_page(struct intel_engine_cs *ring) - { - struct drm_device *dev = ring->dev; - struct drm_i915_private *dev_priv = ring->dev->dev_private; - u32 mmio = 0; - - /* The ring status page addresses are no longer next to the rest of - * the ring registers as of gen7. - */ - if (IS_GEN7(dev)) { - switch (ring->id) { - case RCS: - mmio = RENDER_HWS_PGA_GEN7; - break; - case BCS: - mmio = BLT_HWS_PGA_GEN7; - break; - /* - * VCS2 actually doesn't exist on Gen7. Only shut up - * gcc switch check warning - */ - case VCS2: - case VCS: - mmio = BSD_HWS_PGA_GEN7; - break; - case VECS: - mmio = VEBOX_HWS_PGA_GEN7; - break; - } - } else if (IS_GEN6(ring->dev)) { - mmio = RING_HWS_PGA_GEN6(ring->mmio_base); - } else { - /* XXX: gen8 returns to sanity */ - mmio = RING_HWS_PGA(ring->mmio_base); - } - - I915_WRITE(mmio, (u32)ring->status_page.gfx_addr); - POSTING_READ(mmio); - - /* - * Flush the TLB for this page - * - * FIXME: These two bits have disappeared on gen8, so a question - * arises: do we still need this and if so how should we go about - * invalidating the TLB? - */ - if (INTEL_INFO(dev)->gen >= 6 && INTEL_INFO(dev)->gen < 8) { - u32 reg = RING_INSTPM(ring->mmio_base); - - /* ring should be idle before issuing a sync flush*/ - WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0); - - I915_WRITE(reg, - _MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE | - INSTPM_SYNC_FLUSH)); - if (wait_for((I915_READ(reg) & INSTPM_SYNC_FLUSH) == 0, - 1000)) - DRM_ERROR("%s: wait for SyncFlush to complete for TLB invalidation timed out\n", - ring->name); - } - } - static int bsd_ring_flush(struct intel_engine_cs *ring, u32 invalidate_domains, @@@ -2240,14 -2319,6 +2319,14 @@@ static int gen6_bsd_ring_flush(struct i cmd = MI_FLUSH_DW; if (INTEL_INFO(ring->dev)->gen >= 8) cmd += 1; + + /* We always require a command barrier so that subsequent + * commands, such as breadcrumb interrupts, are strictly ordered + * wrt the contents of the write cache being flushed to memory + * (and thus being coherent from the CPU). + */ + cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW; + /* * Bspec vol 1c.5 - video engine command streamer: * "If ENABLED, all TLBs will be invalidated once the flush @@@ -2255,8 -2326,8 +2334,8 @@@ * Post-Sync Operation field is a value of 1h or 3h." */ if (invalidate & I915_GEM_GPU_DOMAINS) - cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD | - MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW; + cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD; + intel_ring_emit(ring, cmd); intel_ring_emit(ring, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT); if (INTEL_INFO(ring->dev)->gen >= 8) { @@@ -2352,14 -2423,6 +2431,14 @@@ static int gen6_ring_flush(struct intel cmd = MI_FLUSH_DW; if (INTEL_INFO(ring->dev)->gen >= 8) cmd += 1; + + /* We always require a command barrier so that subsequent + * commands, such as breadcrumb interrupts, are strictly ordered + * wrt the contents of the write cache being flushed to memory + * (and thus being coherent from the CPU). + */ + cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW; + /* * Bspec vol 1c.3 - blitter engine command streamer: * "If ENABLED, all TLBs will be invalidated once the flush @@@ -2367,7 -2430,8 +2446,7 @@@ * Post-Sync Operation field is a value of 1h or 3h." */ if (invalidate & I915_GEM_DOMAIN_RENDER) - cmd |= MI_INVALIDATE_TLB | MI_FLUSH_DW_STORE_INDEX | - MI_FLUSH_DW_OP_STOREDW; + cmd |= MI_INVALIDATE_TLB; intel_ring_emit(ring, cmd); intel_ring_emit(ring, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT); if (INTEL_INFO(ring->dev)->gen >= 8) { @@@ -2612,19 -2676,13 +2691,13 @@@ int intel_init_bsd_ring_buffer(struct d } /** - * Initialize the second BSD ring for Broadwell GT3. - * It is noted that this only exists on Broadwell GT3. + * Initialize the second BSD ring (eg. Broadwell GT3, Skylake GT3) */ int intel_init_bsd2_ring_buffer(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *ring = &dev_priv->ring[VCS2]; - if ((INTEL_INFO(dev)->gen != 8)) { - DRM_ERROR("No dual-BSD ring on non-BDW machine\n"); - return -EINVAL; - } - ring->name = "bsd2 ring"; ring->id = VCS2; diff --combined drivers/gpu/drm/i915/intel_uncore.c index c47a3baa53d5,27cc45849715..876e06360c36 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@@ -23,6 -23,7 +23,7 @@@ #include "i915_drv.h" #include "intel_drv.h" + #include "i915_vgpu.h" #include @@@ -166,8 -167,7 +167,8 @@@ fw_domains_reset(struct drm_i915_privat struct intel_uncore_forcewake_domain *d; enum forcewake_domain_id id; - WARN_ON(dev_priv->uncore.fw_domains == 0); + if (dev_priv->uncore.fw_domains == 0) + return; for_each_fw_domain_mask(d, fw_domains, dev_priv, id) fw_domain_reset(d); @@@ -328,8 -328,9 +329,9 @@@ static void intel_uncore_ellc_detect(st { struct drm_i915_private *dev_priv = dev->dev_private; - if ((IS_HASWELL(dev) || IS_BROADWELL(dev)) && - (__raw_i915_read32(dev_priv, HSW_EDRAM_PRESENT) == 1)) { + if ((IS_HASWELL(dev) || IS_BROADWELL(dev) || + INTEL_INFO(dev)->gen >= 9) && + (__raw_i915_read32(dev_priv, HSW_EDRAM_PRESENT) & EDRAM_ENABLED)) { /* The docs do not explain exactly how the calculation can be * made. It is somewhat guessable, but for now, it's always * 128MB. @@@ -640,6 -641,14 +642,14 @@@ static inline void __force_wake_get(str dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains); } + #define __vgpu_read(x) \ + static u##x \ + vgpu_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ + GEN6_READ_HEADER(x); \ + val = __raw_i915_read##x(dev_priv, reg); \ + GEN6_READ_FOOTER; \ + } + #define __gen6_read(x) \ static u##x \ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ @@@ -703,6 -712,10 +713,10 @@@ gen9_read##x(struct drm_i915_private *d GEN6_READ_FOOTER; \ } + __vgpu_read(8) + __vgpu_read(16) + __vgpu_read(32) + __vgpu_read(64) __gen9_read(8) __gen9_read(16) __gen9_read(32) @@@ -724,6 -737,7 +738,7 @@@ __gen6_read(64 #undef __chv_read #undef __vlv_read #undef __gen6_read + #undef __vgpu_read #undef GEN6_READ_FOOTER #undef GEN6_READ_HEADER @@@ -807,6 -821,14 +822,14 @@@ hsw_write##x(struct drm_i915_private *d GEN6_WRITE_FOOTER; \ } + #define __vgpu_write(x) \ + static void vgpu_write##x(struct drm_i915_private *dev_priv, \ + off_t reg, u##x val, bool trace) { \ + GEN6_WRITE_HEADER; \ + __raw_i915_write##x(dev_priv, reg, val); \ + GEN6_WRITE_FOOTER; \ + } + static const u32 gen8_shadowed_regs[] = { FORCEWAKE_MT, GEN6_RPNSWREQ, @@@ -924,12 -946,17 +947,17 @@@ __gen6_write(8 __gen6_write(16) __gen6_write(32) __gen6_write(64) + __vgpu_write(8) + __vgpu_write(16) + __vgpu_write(32) + __vgpu_write(64) #undef __gen9_write #undef __chv_write #undef __gen8_write #undef __hsw_write #undef __gen6_write + #undef __vgpu_write #undef GEN6_WRITE_FOOTER #undef GEN6_WRITE_HEADER @@@ -972,6 -999,7 +1000,7 @@@ static void fw_domain_init(struct drm_i d->val_set = FORCEWAKE_KERNEL; d->val_clear = 0; } else { + /* WaRsClearFWBitsAtReset:bdw,skl */ d->val_reset = _MASKED_BIT_DISABLE(0xffff); d->val_set = _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL); d->val_clear = _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL); @@@ -998,9 -1026,6 +1027,9 @@@ static void intel_uncore_fw_domains_ini { struct drm_i915_private *dev_priv = dev->dev_private; + if (INTEL_INFO(dev_priv->dev)->gen <= 5) + return; + if (IS_GEN9(dev)) { dev_priv->uncore.funcs.force_wake_get = fw_domains_get; dev_priv->uncore.funcs.force_wake_put = fw_domains_put; @@@ -1073,15 -1098,14 +1102,17 @@@ fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER, FORCEWAKE, FORCEWAKE_ACK); } + + /* All future platforms are expected to require complex power gating */ + WARN_ON(dev_priv->uncore.fw_domains == 0); } void intel_uncore_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + i915_check_vgpu(dev); + intel_uncore_ellc_detect(dev); intel_uncore_fw_domains_init(dev); __intel_uncore_early_sanitize(dev, false); @@@ -1130,6 -1154,11 +1161,11 @@@ break; } + if (intel_vgpu_active(dev)) { + ASSIGN_WRITE_MMIO_VFUNCS(vgpu); + ASSIGN_READ_MMIO_VFUNCS(vgpu); + } + i915_check_and_clear_faults(dev); } #undef ASSIGN_WRITE_MMIO_VFUNCS diff --combined include/drm/drm_crtc.h index 920e21a8f3fd,cee54c45eba9..b1465d6fbe94 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@@ -202,6 -202,7 +202,7 @@@ struct drm_framebuffer const struct drm_framebuffer_funcs *funcs; unsigned int pitches[4]; unsigned int offsets[4]; + uint64_t modifier[4]; unsigned int width; unsigned int height; /* depth can be 15 or 16 */ @@@ -253,7 -254,6 +254,7 @@@ struct drm_atomic_state * @enable: whether the CRTC should be enabled, gates all other state * @active: whether the CRTC is actively displaying (used for DPMS) * @mode_changed: for use by helpers and drivers when computing state updates + * @active_changed: for use by helpers and drivers when computing state updates * @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes * @last_vblank_count: for helpers and drivers to capture the vblank of the * update to ensure framebuffer cleanup isn't done too early @@@ -279,7 -279,6 +280,7 @@@ struct drm_crtc_state /* computed state bits used by helpers and drivers */ bool planes_changed : 1; bool mode_changed : 1; + bool active_changed : 1; /* attached planes bitmask: * WARNING: transitional helpers do not maintain plane_mask so @@@ -868,16 -867,15 +869,16 @@@ struct drm_plane /** * struct drm_bridge_funcs - drm_bridge control functions + * @attach: Called during drm_bridge_attach * @mode_fixup: Try to fixup (or reject entirely) proposed mode for this bridge * @disable: Called right before encoder prepare, disables the bridge * @post_disable: Called right after encoder prepare, for lockstepped disable * @mode_set: Set this mode to the bridge * @pre_enable: Called right before encoder commit, for lockstepped commit * @enable: Called right after encoder commit, enables the bridge - * @destroy: make object go away */ struct drm_bridge_funcs { + int (*attach)(struct drm_bridge *bridge); bool (*mode_fixup)(struct drm_bridge *bridge, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); @@@ -888,24 -886,22 +889,24 @@@ struct drm_display_mode *adjusted_mode); void (*pre_enable)(struct drm_bridge *bridge); void (*enable)(struct drm_bridge *bridge); - void (*destroy)(struct drm_bridge *bridge); }; /** * struct drm_bridge - central DRM bridge control structure * @dev: DRM device this bridge belongs to - * @head: list management + * @of_node: device node pointer to the bridge + * @list: to keep track of all added bridges * @base: base mode object * @funcs: control functions * @driver_private: pointer to the bridge driver's internal context */ struct drm_bridge { struct drm_device *dev; - struct list_head head; - - struct drm_mode_object base; + struct drm_encoder *encoder; +#ifdef CONFIG_OF + struct device_node *of_node; +#endif + struct list_head list; const struct drm_bridge_funcs *funcs; void *driver_private; @@@ -915,7 -911,6 +916,7 @@@ * struct struct drm_atomic_state - the global state object for atomic updates * @dev: parent DRM device * @allow_modeset: allow full modeset + * @legacy_cursor_update: hint to enforce legacy cursor ioctl semantics * @planes: pointer to array of plane pointers * @plane_states: pointer to array of plane states pointers * @crtcs: pointer to array of CRTC pointers @@@ -928,7 -923,6 +929,7 @@@ struct drm_atomic_state { struct drm_device *dev; bool allow_modeset : 1; + bool legacy_cursor_update : 1; struct drm_plane **planes; struct drm_plane_state **plane_states; struct drm_crtc **crtcs; @@@ -1010,6 -1004,7 +1011,6 @@@ struct drm_mode_group uint32_t num_crtcs; uint32_t num_encoders; uint32_t num_connectors; - uint32_t num_bridges; /* list of object IDs for this group */ uint32_t *id_list; @@@ -1028,6 -1023,8 +1029,6 @@@ * @fb_list: list of framebuffers available * @num_connector: number of connectors on this device * @connector_list: list of connector objects - * @num_bridge: number of bridges on this device - * @bridge_list: list of bridge objects * @num_encoder: number of encoders on this device * @encoder_list: list of encoder objects * @num_overlay_plane: number of overlay planes on this device @@@ -1072,6 -1069,8 +1073,6 @@@ struct drm_mode_config int num_connector; struct list_head connector_list; - int num_bridge; - struct list_head bridge_list; int num_encoder; struct list_head encoder_list; @@@ -1119,7 -1118,6 +1120,7 @@@ struct drm_property *prop_crtc_h; struct drm_property *prop_fb_id; struct drm_property *prop_crtc_id; + struct drm_property *prop_active; /* DVI-I properties */ struct drm_property *dvi_i_subconnector_property; @@@ -1155,6 -1153,9 +1156,9 @@@ /* whether async page flip is supported or not */ bool async_page_flip; + /* whether the driver supports fb modifiers */ + bool allow_fb_modifiers; + /* cursor size */ uint32_t cursor_width, cursor_height; }; @@@ -1220,10 -1221,9 +1224,10 @@@ extern unsigned int drm_connector_index /* helper to unplug all connectors from sysfs for device */ extern void drm_connector_unplug_all(struct drm_device *dev); -extern int drm_bridge_init(struct drm_device *dev, struct drm_bridge *bridge, - const struct drm_bridge_funcs *funcs); -extern void drm_bridge_cleanup(struct drm_bridge *bridge); +extern int drm_bridge_add(struct drm_bridge *bridge); +extern void drm_bridge_remove(struct drm_bridge *bridge); +extern struct drm_bridge *of_drm_find_bridge(struct device_node *np); +extern int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge); extern int drm_encoder_init(struct drm_device *dev, struct drm_encoder *encoder, @@@ -1353,8 -1353,6 +1357,8 @@@ struct drm_property *drm_property_creat int64_t min, int64_t max); struct drm_property *drm_property_create_object(struct drm_device *dev, int flags, const char *name, uint32_t type); +struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags, + const char *name); extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property); extern int drm_property_add_enum(struct drm_property *property, int index, uint64_t value, const char *name); diff --combined include/uapi/drm/drm_fourcc.h index a284f11a8ef5,4837c3d2319a..1a5a357d658f --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@@ -109,6 -109,9 +109,6 @@@ #define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4') /* non-subsampled Cr:Cb plane */ #define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2') /* non-subsampled Cb:Cr plane */ -/* special NV12 tiled format */ -#define DRM_FORMAT_NV12MT fourcc_code('T', 'M', '1', '2') /* 2x2 subsampled Cr:Cb plane 64x32 macroblocks */ - /* * 3 plane YCbCr * index 0: Y plane, [7:0] Y @@@ -129,4 -132,67 +129,67 @@@ #define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */ #define DRM_FORMAT_YVU444 fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */ + + /* + * Format Modifiers: + * + * Format modifiers describe, typically, a re-ordering or modification + * of the data in a plane of an FB. This can be used to express tiled/ + * swizzled formats, or compression, or a combination of the two. + * + * The upper 8 bits of the format modifier are a vendor-id as assigned + * below. The lower 56 bits are assigned as vendor sees fit. + */ + + /* Vendor Ids: */ + #define DRM_FORMAT_MOD_NONE 0 + #define DRM_FORMAT_MOD_VENDOR_INTEL 0x01 + #define DRM_FORMAT_MOD_VENDOR_AMD 0x02 + #define DRM_FORMAT_MOD_VENDOR_NV 0x03 + #define DRM_FORMAT_MOD_VENDOR_SAMSUNG 0x04 + #define DRM_FORMAT_MOD_VENDOR_QCOM 0x05 + /* add more to the end as needed */ + + #define fourcc_mod_code(vendor, val) \ + ((((u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffL)) + + /* + * Format Modifier tokens: + * + * When adding a new token please document the layout with a code comment, + * similar to the fourcc codes above. drm_fourcc.h is considered the + * authoritative source for all of these. + */ + + /* Intel framebuffer modifiers */ + + /* + * Intel X-tiling layout + * + * This is a tiled layout using 4Kb tiles (except on gen2 where the tiles 2Kb) + * in row-major layout. Within the tile bytes are laid out row-major, with + * a platform-dependent stride. On top of that the memory can apply + * platform-depending swizzling of some higher address bits into bit6. + * + * This format is highly platforms specific and not useful for cross-driver + * sharing. It exists since on a given platform it does uniquely identify the + * layout in a simple way for i915-specific userspace. + */ + #define I915_FORMAT_MOD_X_TILED fourcc_mod_code(INTEL, 1) + + /* + * Intel Y-tiling layout + * + * This is a tiled layout using 4Kb tiles (except on gen2 where the tiles 2Kb) + * in row-major layout. Within the tile bytes are laid out in OWORD (16 bytes) + * chunks column-major, with a platform-dependent height. On top of that the + * memory can apply platform-depending swizzling of some higher address bits + * into bit6. + * + * This format is highly platforms specific and not useful for cross-driver + * sharing. It exists since on a given platform it does uniquely identify the + * layout in a simple way for i915-specific userspace. + */ + #define I915_FORMAT_MOD_Y_TILED fourcc_mod_code(INTEL, 2) + #endif /* DRM_FOURCC_H */