Re: [Intel-gfx] [PATCH v2] drm/i915/bdw: BDW Software Turbo
On Thu, Jul 10, 2014 at 07:39:32PM -0700, Sun, Daisy wrote: This Software turbo will mainly take place of the hardware driven interrupt part without touching the boost/idle strategy. So gen6_rps_boost and gen6_rps_idle will still function for BDW. You still are not addressing that your function is either called at a random time, and more often than not, never. You also disabled the set_rps paths which would have disabled boost and idle. -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] startx on Fedora died today
On Thu, Jul 10, 2014 at 09:09:31PM -0400, Felix Miata wrote: F21 branched off Rawhide over recent hours. On i945G host gx62b I cloned first, then upgraded one to current F21 state and the other to Rawhide. Before today's upgrade, which moved server from 1.15.99.903 to 1.15.99.904 on both, and kernel from rc4git0.1 to rc4git2.1, booting first to multi-user, startx was working normally. Now it won't[1], though X (KDM/KDE) does work by booting to graphical instead of multi-user[2]. Is this an already known driver problem? Server? Kernel? The difference being when it crashed it tried to open the logind fd. This is a server bug - it looks like the recent non-pci platform device conflicts with the systemd integration. -Chris [1] http://fm.no-ip.com/Tmp/Linux/F/Xorg.0.log-fc21-3 [2] http://fm.no-ip.com/Tmp/Linux/F/Xorg.0.log-fc21-5 -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [RFC][PATCH] gpu:drm:i915:intel_detect_pch: back to check devfn instead of check class type
On Thu, Jul 10, 2014 at 09:08:24PM +, Tian, Kevin wrote: actually I'm curious whether it's still necessary to __detect__ PCH. Could we assume a 1:1 mapping between GPU and PCH, e.g. BDW already hard code the knowledge: } 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); Or if there is real usage on non-fixed mapping (not majority), could it be a better option to have fixed mapping as a fallback instead of leaving as PCH_NONE? Then even when Qemu doesn't provide a special tweaked PCH, the majority case just works. I guess we can do it, at least I haven't seen any strange combinations in the wild outside of Intel ... -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 1/2] drm/i915: Make the device_info structure __initconst
On Thu, Jul 10, 2014 at 10:47:21PM +0100, Damien Lespiau wrote: On Thu, Jul 10, 2014 at 10:25:27PM +0200, Daniel Vetter wrote: On Thu, Jul 10, 2014 at 02:52:42PM +0100, Damien Lespiau wrote: We don't need them past the module initialization as the correct structure is copied into dev_priv in -load(), called from drm_pci_init(), called from the module init funtion. I'm always hesitant about adding new members to struct intel_device_info because it will add 30+ * sizeof(member) bytes to the driver. However, if we can discard those table after init(), it changes everything. After this change, the driver has a new .init.rodata section contains the structures in question and .rodata has now 2848 fewer bytes. lsmod shows -5425 bytes in its size field between before and after this change. Not too sure why this (Vs the 2848 bytes lost in .rodata), but that's enough for me. Signed-off-by: Damien Lespiau damien.lesp...@intel.com You want devinintconst which is being phased out afaik ... Currently the driver gets probed synchronously but you kinda never know what the device core people are up to: - init = removed after the module is loaded. - devinit = removed after the driver is initilialized, and never for CONFIG_HOTPLUG=y. If we want to trim down the size of our driver, especially on specific platforms we imo should have a) link time optimization b) some heavy-handed macro to return a static device info c) a much more clever gcc since last time I've tried this it failed to kick out large swats of code like all the dvo crap. Despite that it was clearly unreachable :( Sigh, I followed the !DRIVER_MODESET code path, I am very sad now. I was thinking about having a Kconfig option to select a specific platform to compile the driver for and, by trying to make that work, we could end up with a nice per-platform split of the code. Would people be totally opposed to such a thing? Not opposed if we're going to sign up the compiler for the resulting dce. If it'll result in #ifdef hell then no. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH i-g-t 02/43] igt_kms: Make has_universal_planes a bitfield
On Thu, Jul 10, 2014 at 07:00:03PM +0100, Damien Lespiau wrote: Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_kms.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/igt_kms.h b/lib/igt_kms.h index a079fc2..058114a 100644 --- a/lib/igt_kms.h +++ b/lib/igt_kms.h @@ -153,7 +153,7 @@ struct igt_display { unsigned long pipes_in_use; igt_output_t *outputs; igt_pipe_t pipes[I915_MAX_PIPES]; - bool has_universal_planes; + unsigned int has_universal_planes : 1; tbh I didn't see the point of this and didn't see any follow-up patch which would explain the motivation ... -Daniel }; /* set vt into graphics mode, required to prevent fbcon from interfering */ -- 1.8.3.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH i-g-t 05/43] igt_kms: Add support for setting plane rotation
On Thu, Jul 10, 2014 at 07:00:06PM +0100, Damien Lespiau wrote: Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_kms.c | 54 ++ lib/igt_kms.h | 11 +++ 2 files changed, 65 insertions(+) diff --git a/lib/igt_kms.c b/lib/igt_kms.c index 87f5109..69f9977 100644 --- a/lib/igt_kms.c +++ b/lib/igt_kms.c @@ -537,6 +537,16 @@ get_plane_property(igt_display_t *display, uint32_t plane_id, const char *name, name, prop_id, value); } +static void +igt_plane_set_property(igt_plane_t *plane, uint32_t prop_id, uint64_t value) +{ + igt_pipe_t *pipe = plane-pipe; + igt_display_t *display = pipe-display; + + drmModeObjectSetProperty(display-drm_fd, plane-drm_plane-plane_id, + DRM_MODE_OBJECT_PLANE, prop_id, value); +} I wonder whether we shouldn't have interfaces using the property names and maybe for enum properties also the strings and let igt do it's thing. But as long as this is just an internal function it should be good enough. -Daniel + /* * Walk a plane's property list to determine its type. If we don't * find a type property, then the kernel doesn't support universal @@ -882,6 +892,10 @@ static int igt_drm_plane_commit(igt_plane_t *plane, igt_assert(plane-drm_plane); + /* it's an error to try an unsupported feature */ + igt_assert(igt_plane_supports_rotation(plane) || +!plane-rotation_changed); + fb_id = igt_plane_get_fb_id(plane); crtc_id = output-config.crtc-crtc_id; @@ -931,6 +945,14 @@ static int igt_drm_plane_commit(igt_plane_t *plane, plane-fb_changed = false; plane-position_changed = false; + + if (plane-rotation_changed) { + igt_plane_set_property(plane, plane-rotation_property, +plane-rotation); + + plane-rotation_changed = false; + } + return 0; } @@ -1013,6 +1035,9 @@ static int igt_primary_plane_commit_legacy(igt_plane_t *primary, /* Primary planes can't be windowed when using a legacy commit */ igt_assert((primary-crtc_x == 0 primary-crtc_y == 0)); + /* nor rotated */ + igt_assert(!primary-rotation_changed); + if (!primary-fb_changed !primary-position_changed !primary-panning_changed) return 0; @@ -1304,6 +1329,35 @@ void igt_plane_set_panning(igt_plane_t *plane, int x, int y) plane-panning_changed = true; } +static const char *rotation_name(igt_rotation_t rotation) +{ + switch (rotation) { + case IGT_ROTATION_0: + return 0°; + case IGT_ROTATION_90: + return 90°; + case IGT_ROTATION_180: + return 180°; + case IGT_ROTATION_270: + return 270°; + default: + igt_assert(0); + } +} + +void igt_plane_set_rotation(igt_plane_t *plane, igt_rotation_t rotation) +{ + igt_pipe_t *pipe = plane-pipe; + igt_display_t *display = pipe-display; + + LOG(display, %c.%d: plane_set_rotation(%s)\n, pipe_name(pipe-pipe), + plane-index, rotation_name(rotation)); + + plane-rotation = rotation; + + plane-rotation_changed = true; +} + void igt_wait_for_vblank(int drm_fd, enum pipe pipe) { drmVBlank wait_vbl; diff --git a/lib/igt_kms.h b/lib/igt_kms.h index 4f3474e..d34bcee 100644 --- a/lib/igt_kms.h +++ b/lib/igt_kms.h @@ -71,6 +71,14 @@ enum igt_commit_style { /* We'll add atomic here eventually. */ }; +typedef enum { + /* this maps to the kernel API */ + IGT_ROTATION_0 = 1 0, + IGT_ROTATION_90 = 1 1, + IGT_ROTATION_180 = 1 2, + IGT_ROTATION_270 = 1 3, +} igt_rotation_t; + #include igt_fb.h struct kmstest_connector_config { @@ -116,6 +124,7 @@ typedef struct { unsigned int fb_changed : 1; unsigned int position_changed : 1; unsigned int panning_changed : 1; + unsigned int rotation_changed : 1; /* * drm_plane can be NULL for primary and cursor planes (when not * using the atomic modeset API) @@ -129,6 +138,7 @@ typedef struct { int crtc_x, crtc_y; /* panning offset within the fb */ unsigned int pan_x, pan_y; + igt_rotation_t rotation; } igt_plane_t; struct igt_pipe { @@ -184,6 +194,7 @@ static inline bool igt_plane_supports_rotation(igt_plane_t *plane) void igt_plane_set_fb(igt_plane_t *plane, struct igt_fb *fb); void igt_plane_set_position(igt_plane_t *plane, int x, int y); void igt_plane_set_panning(igt_plane_t *plane, int x, int y); +void igt_plane_set_rotation(igt_plane_t *plane, igt_rotation_t rotation); void igt_wait_for_vblank(int drm_fd, enum pipe pipe); -- 1.8.3.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org
Re: [Intel-gfx] [PATCH i-g-t 05/43] igt_kms: Add support for setting plane rotation
On Thu, Jul 10, 2014 at 07:00:06PM +0100, Damien Lespiau wrote: +typedef enum { + /* this maps to the kernel API */ + IGT_ROTATION_0 = 1 0, + IGT_ROTATION_90 = 1 1, + IGT_ROTATION_180 = 1 2, + IGT_ROTATION_270 = 1 3, +} igt_rotation_t; Should we also add the flip X/Y bits, even if we currently don't support this in the kernel? -Daniel + #include igt_fb.h struct kmstest_connector_config { @@ -116,6 +124,7 @@ typedef struct { unsigned int fb_changed : 1; unsigned int position_changed : 1; unsigned int panning_changed : 1; + unsigned int rotation_changed : 1; /* * drm_plane can be NULL for primary and cursor planes (when not * using the atomic modeset API) @@ -129,6 +138,7 @@ typedef struct { int crtc_x, crtc_y; /* panning offset within the fb */ unsigned int pan_x, pan_y; + igt_rotation_t rotation; } igt_plane_t; struct igt_pipe { @@ -184,6 +194,7 @@ static inline bool igt_plane_supports_rotation(igt_plane_t *plane) void igt_plane_set_fb(igt_plane_t *plane, struct igt_fb *fb); void igt_plane_set_position(igt_plane_t *plane, int x, int y); void igt_plane_set_panning(igt_plane_t *plane, int x, int y); +void igt_plane_set_rotation(igt_plane_t *plane, igt_rotation_t rotation); void igt_wait_for_vblank(int drm_fd, enum pipe pipe); -- 1.8.3.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH i-g-t 05/43] igt_kms: Add support for setting plane rotation
On Fri, Jul 11, 2014 at 08:40:29AM +0200, Daniel Vetter wrote: On Thu, Jul 10, 2014 at 07:00:06PM +0100, Damien Lespiau wrote: +typedef enum { + /* this maps to the kernel API */ + IGT_ROTATION_0 = 1 0, + IGT_ROTATION_90 = 1 1, + IGT_ROTATION_180 = 1 2, + IGT_ROTATION_270 = 1 3, +} igt_rotation_t; Should we also add the flip X/Y bits, even if we currently don't support this in the kernel? Presumably there are tests in here to check the kernel rejects unsupported combination of rotations and unknown reflections? In which, yes. -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH i-g-t 05/43] igt_kms: Add support for setting plane rotation
On Fri, Jul 11, 2014 at 07:42:56AM +0100, Chris Wilson wrote: On Fri, Jul 11, 2014 at 08:40:29AM +0200, Daniel Vetter wrote: On Thu, Jul 10, 2014 at 07:00:06PM +0100, Damien Lespiau wrote: +typedef enum { + /* this maps to the kernel API */ + IGT_ROTATION_0 = 1 0, + IGT_ROTATION_90 = 1 1, + IGT_ROTATION_180 = 1 2, + IGT_ROTATION_270 = 1 3, +} igt_rotation_t; Should we also add the flip X/Y bits, even if we currently don't support this in the kernel? Presumably there are tests in here to check the kernel rejects unsupported combination of rotations and unknown reflections? In which, yes. I guess we should try everything and check whether it either gets rejected or works properly ... -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC] More structure for igt_kms tests
Hi all, So kms tests have rather ugly control flow compared to other tests. And the pattern is usually the same: - A subtest loops over a set of possible configurations to test and tries igt_commit. If that fails then it needs to manually reset the igt_display state and go to the next possible configuration. - A counter needs to keep track of the number of successfully applied configurations so that the test can decide to either skip (no config worked out) or succeed - failures will have bailed out earlier. The result is a lot of: - Fragile control flow code (since e.g. only few platforms have restrictions on the connector-pipe links like lvds on gen2/3 and dp on chv). - Fragile result computation logice - everyone has to duplicate the little bit of accounting to correctly skip/succeed. - Duplicated code (especially for the cleanup and try handling). I have a few ideas how we can improve: 1. We need an igt_display_reset to bring the configuration back to a known state. Imo that should be everything turned off and all properties (where known to the framework like e.g. rotation) reset to defaults. We probably need to make an igt_commit as part of this to avoid fun with strange state transitions. 2. New control flow block macros for display tests. I'm thinking of a special-cases igt_display_subtest (to make sure the special skip/succeed logic doesn't get lost) and a new igt_display_try block like this: igt_display_subtest(foo) { for_each_possible_config { /* set up the igt_display config with the igt_kms library */ /* Tries to commit the display config and skips the entire block * on failure. */ igt_display_try(display) { /* actual test code */ } /* Implicit state reset for the entire display * structure. The explicit call would be igt_display_reset(); * This is part of the igt_display_try block. */ } /* Implicit call to igt_display_result which skips/succeeds depending * whether at least one config worked. Explicit call would be igt_display_result(); * This is part of the igt_display_subtest block. */ } igt_display_try would also assert that it's called from within an igt_display_subtest block. And I guess we should disallow nesting. Comments? Cheers, Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] lib/igt_core: Don't log when listing subtests
I've noticed some spam in the userptr list ... Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- lib/igt_core.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/lib/igt_core.c b/lib/igt_core.c index bdeeb59971de..856262be34fa 100644 --- a/lib/igt_core.c +++ b/lib/igt_core.c @@ -1200,6 +1200,9 @@ void igt_log(enum igt_log_level level, const char *format, ...) assert(format); + if (list_subtests) + return; + if (igt_log_level level) return; @@ -1229,6 +1232,9 @@ void igt_vlog(enum igt_log_level level, const char *format, va_list args) { assert(format); + if (list_subtests) + return; + if (igt_log_level level) return; -- 2.0.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] startx on Fedora died today
On 2014-07-11 07:22 (GMT+0100) Chris Wilson composed: On Thu, Jul 10, 2014 at 09:09:31PM -0400, Felix Miata wrote: F21 branched off Rawhide over recent hours. On i945G host gx62b I cloned first, then upgraded one to current F21 state and the other to Rawhide. Before today's upgrade, which moved server from 1.15.99.903 to 1.15.99.904 on both, and kernel from rc4git0.1 to rc4git2.1, booting first to multi-user, startx was working normally. Now it won't[1], though X (KDM/KDE) does work by booting to graphical instead of multi-user[2]. Is this an already known driver problem? Server? Kernel? The difference being when it crashed it tried to open the logind fd. This is a server bug - it looks like the recent non-pci platform device conflicts with the systemd integration. Thanks. [1] http://fm.no-ip.com/Tmp/Linux/F/Xorg.0.log-fc21-3 [2] http://fm.no-ip.com/Tmp/Linux/F/Xorg.0.log-fc21-5 https://bugzilla.redhat.com/show_bug.cgi?id=1118540 already filed some hours before I found this, and happening with rv200 Radeon as well as Intel. I don't find anything related filed yet on bugs.freedesktop.org/ -- The wise are known for their understanding, and pleasant words are persuasive. Proverbs 16:21 (New Living Translation) Team OS/2 ** Reg. Linux User #211409 ** a11y rocks! Felix Miata *** http://fm.no-ip.com/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] startx on Fedora died today
Hi, On 07/11/2014 08:22 AM, Chris Wilson wrote: On Thu, Jul 10, 2014 at 09:09:31PM -0400, Felix Miata wrote: F21 branched off Rawhide over recent hours. On i945G host gx62b I cloned first, then upgraded one to current F21 state and the other to Rawhide. Before today's upgrade, which moved server from 1.15.99.903 to 1.15.99.904 on both, and kernel from rc4git0.1 to rc4git2.1, booting first to multi-user, startx was working normally. Now it won't[1], though X (KDM/KDE) does work by booting to graphical instead of multi-user[2]. Is this an already known driver problem? Server? Kernel? The difference being when it crashed it tried to open the logind fd. This is a server bug - it looks like the recent non-pci platform device conflicts with the systemd integration. Yes, pretty literary conflicts, they re-used an existing ODEV_ATTRIB id for a new one they used (probably an innocent rebase error). I've just send a fix to the xorg-devel list for this, and I'm starting a new Fedora rawhide / F-21 server build with this fix included. I've attached the fix here for reference. Regards, Hans From 1f822291a3db6b5f6bd5f60ba240f2ee0cbdf683 Mon Sep 17 00:00:00 2001 From: Hans de Goede hdego...@redhat.com Date: Fri, 11 Jul 2014 09:49:13 +0200 Subject: [PATCH] Fix ODEV_ATTRIB_DRIVER overlapping with ODEV_ATTRIB_FD Looks like the value of ODEV_ATTRIB_DRIVER was not updated when the patch adding it got rebased on top of a newer server version. This fixes the xserver crashing when systemd-logind integration is used. https://bugzilla.redhat.com/show_bug.cgi?id=1118540 Signed-off-by: Hans de Goede hdego...@redhat.com --- include/hotplug.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hotplug.h b/include/hotplug.h index c4268a0..b2c0d78 100644 --- a/include/hotplug.h +++ b/include/hotplug.h @@ -88,7 +88,7 @@ config_odev_free_attributes(struct OdevAttributes *attribs); /* Minor number of the device node pointed to by ODEV_ATTRIB_PATH */ #define ODEV_ATTRIB_MINOR 6 /* kernel driver name */ -#define ODEV_ATTRIB_DRIVER 4 +#define ODEV_ATTRIB_DRIVER 7 typedef void (*config_odev_probe_proc_ptr)(struct OdevAttributes *attribs); void config_odev_probe(config_odev_probe_proc_ptr probe_callback); -- 2.0.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v4 1/2] drm/i915: Set M2_N2 registers during mode set
For Gen 8, set M2_N2 registers on every mode set. This is required to make sure M2_N2 registers are set during boot, resume from sleep for cross- checking the state. The register is set only if DRRS is supported. v2: Patch rebased v3: Daniel's review comments - Removed HAS_DRRS(dev) and added bool has_drrs to pipe_config to track drrs support v4: Jesse's review comments - Made changes to set m2_n2 in intel_dp_set_m_n() Signed-off-by: Vandana Kannan vandana.kan...@intel.com Cc: Daniel Vetter daniel.vet...@ffwll.ch Cc: Jesse Barnes jbar...@virtuousgeek.org --- drivers/gpu/drm/i915/intel_display.c | 28 +--- drivers/gpu/drm/i915/intel_dp.c | 18 +++--- drivers/gpu/drm/i915/intel_drv.h | 3 ++- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a72b55f..9f651a6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -91,11 +91,11 @@ static int intel_framebuffer_init(struct drm_device *dev, struct intel_framebuffer *ifb, struct drm_mode_fb_cmd2 *mode_cmd, struct drm_i915_gem_object *obj); -static void intel_dp_set_m_n(struct intel_crtc *crtc); static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc); static void intel_set_pipe_timings(struct intel_crtc *intel_crtc); static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, -struct intel_link_m_n *m_n); +struct intel_link_m_n *m_n, +struct intel_link_m_n *m2_n2); static void ironlake_set_pipeconf(struct drm_crtc *crtc); static void haswell_set_pipeconf(struct drm_crtc *crtc); static void intel_set_pipe_csc(struct drm_crtc *crtc); @@ -4027,7 +4027,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) if (intel_crtc-config.has_pch_encoder) { intel_cpu_transcoder_set_m_n(intel_crtc, -intel_crtc-config.fdi_m_n); +intel_crtc-config.fdi_m_n, NULL); } ironlake_set_pipeconf(crtc); @@ -4137,7 +4137,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) if (intel_crtc-config.has_pch_encoder) { intel_cpu_transcoder_set_m_n(intel_crtc, -intel_crtc-config.fdi_m_n); +intel_crtc-config.fdi_m_n, NULL); } haswell_set_pipeconf(crtc); @@ -5502,7 +5502,8 @@ static void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc, } static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, -struct intel_link_m_n *m_n) +struct intel_link_m_n *m_n, +struct intel_link_m_n *m2_n2) { struct drm_device *dev = crtc-base.dev; struct drm_i915_private *dev_priv = dev-dev_private; @@ -5514,6 +5515,18 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, I915_WRITE(PIPE_DATA_N1(transcoder), m_n-gmch_n); I915_WRITE(PIPE_LINK_M1(transcoder), m_n-link_m); I915_WRITE(PIPE_LINK_N1(transcoder), m_n-link_n); + /* M2_N2 registers to be set only for gen 8 (M2_N2 available +* for gen 8) and if DRRS is supported (to make sure the +* registers are not unnecessarily accessed). +*/ + if (m2_n2 INTEL_INFO(dev)-gen 8 + crtc-config.has_drrs) { + I915_WRITE(PIPE_DATA_M2(transcoder), + TU_SIZE(m2_n2-tu) | m2_n2-gmch_m); + I915_WRITE(PIPE_DATA_N2(transcoder), m2_n2-gmch_n); + I915_WRITE(PIPE_LINK_M2(transcoder), m2_n2-link_m); + I915_WRITE(PIPE_LINK_N2(transcoder), m2_n2-link_n); + } } else { I915_WRITE(PIPE_DATA_M_G4X(pipe), TU_SIZE(m_n-tu) | m_n-gmch_m); I915_WRITE(PIPE_DATA_N_G4X(pipe), m_n-gmch_n); @@ -5522,12 +5535,13 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, } } -static void intel_dp_set_m_n(struct intel_crtc *crtc) +void intel_dp_set_m_n(struct intel_crtc *crtc) { if (crtc-config.has_pch_encoder) intel_pch_transcoder_set_m_n(crtc, crtc-config.dp_m_n); else - intel_cpu_transcoder_set_m_n(crtc, crtc-config.dp_m_n); + intel_cpu_transcoder_set_m_n(crtc, crtc-config.dp_m_n, + crtc-config.dp_m2_n2); } static void vlv_update_pll(struct intel_crtc *crtc) diff --git
[Intel-gfx] [PATCH v8 2/2] drm/i915: State readout and cross-checking for dp_m2_n2
Adding relevant read out comparison code, in check_crtc_state, for the new member of crtc_config, dp_m2_n2, which was introduced to store link_m_n values for a DP downclock mode (if available). Suggested by Daniel. v2: Changed patch title. Daniel's review comments incorporated. Added relevant state readout code for M2_N2. dp_m2_n2 comparison to be done only when high RR is not in use (This is because alternate m_n register programming will be done only when low RR is being used). v3: Modified call to get_m2_n2 which had dp_m_n as param by mistake. Compare dp_m_n and dp_m2_n2 for gen 7 and below. compare the structures based on DRRS state for gen 8 and above. Save and restore M2 N2 registers for gen 7 and below v4: For Gen=8, check M_N registers against dp_m_n and dp_m2_n2 as there is only one set of M_N registers v5: Removed the chunk which saves and restores M2_N2 registers. Modified get_m_n() to get M2_N2 registers as well. Modified the macro which compares hw.dp_m_n against sw.dp_m2_n2/sw.dp_m_n for gen 8. v6: Added check to compare dp_m2_n2 only when DRRS is enabled v7: Modified drrs check to use has_drrs v8: Add has_drrs check before reading M2_N2 registers Signed-off-by: Vandana Kannan vandana.kan...@intel.com Cc: Daniel Vetter daniel.vet...@ffwll.ch Cc: Jani Nikula jani.nik...@linux.intel.com Cc: Jesse Barnes jbar...@virtuousgeek.org --- drivers/gpu/drm/i915/intel_display.c | 75 1 file changed, 67 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9f651a6..87481f4 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7138,7 +7138,8 @@ static void intel_pch_transcoder_get_m_n(struct intel_crtc *crtc, static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc, enum transcoder transcoder, -struct intel_link_m_n *m_n) +struct intel_link_m_n *m_n, +struct intel_link_m_n *m2_n2) { struct drm_device *dev = crtc-base.dev; struct drm_i915_private *dev_priv = dev-dev_private; @@ -7152,6 +7153,20 @@ static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc, m_n-gmch_n = I915_READ(PIPE_DATA_N1(transcoder)); m_n-tu = ((I915_READ(PIPE_DATA_M1(transcoder)) TU_SIZE_MASK) TU_SIZE_SHIFT) + 1; + /* Read M2_N2 registers only for gen 8 (M2_N2 available for +* gen 8) and if DRRS is supported (to make sure the +* registers are not unnecessarily read). +*/ + if (m2_n2 INTEL_INFO(dev)-gen 8 + crtc-config.has_drrs) { + m2_n2-link_m = I915_READ(PIPE_LINK_M2(transcoder)); + m2_n2-link_n = I915_READ(PIPE_LINK_N2(transcoder)); + m2_n2-gmch_m = I915_READ(PIPE_DATA_M2(transcoder)) +~TU_SIZE_MASK; + m2_n2-gmch_n = I915_READ(PIPE_DATA_N2(transcoder)); + m2_n2-tu = ((I915_READ(PIPE_DATA_M2(transcoder)) +TU_SIZE_MASK) TU_SIZE_SHIFT) + 1; + } } else { m_n-link_m = I915_READ(PIPE_LINK_M_G4X(pipe)); m_n-link_n = I915_READ(PIPE_LINK_N_G4X(pipe)); @@ -7170,14 +7185,15 @@ void intel_dp_get_m_n(struct intel_crtc *crtc, intel_pch_transcoder_get_m_n(crtc, pipe_config-dp_m_n); else intel_cpu_transcoder_get_m_n(crtc, pipe_config-cpu_transcoder, -pipe_config-dp_m_n); +pipe_config-dp_m_n, +pipe_config-dp_m2_n2); } static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc, struct intel_crtc_config *pipe_config) { intel_cpu_transcoder_get_m_n(crtc, pipe_config-cpu_transcoder, -pipe_config-fdi_m_n); +pipe_config-fdi_m_n, NULL); } static void ironlake_get_pfit_config(struct intel_crtc *crtc, @@ -9932,6 +9948,15 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc, pipe_config-dp_m_n.gmch_m, pipe_config-dp_m_n.gmch_n, pipe_config-dp_m_n.link_m, pipe_config-dp_m_n.link_n, pipe_config-dp_m_n.tu); + + DRM_DEBUG_KMS(dp: %i, gmch_m2: %u, gmch_n2: %u, link_m2: %u, link_n2: %u, tu2: %u\n, + pipe_config-has_dp_encoder, + pipe_config-dp_m2_n2.gmch_m, + pipe_config-dp_m2_n2.gmch_n, + pipe_config-dp_m2_n2.link_m, +
[Intel-gfx] [PATCH v2 1/3] drm/i915: CHV GPU frequency to opcode functions
From: Deepak S deepa...@linux.intel.com Adding chv specific fre/encode conversion. v2: Remove generic function and platform check (Daniel) Signed-off-by: Deepak S deepa...@linux.intel.com --- drivers/gpu/drm/i915/intel_pm.c | 78 +++-- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 6892421..f673e1b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6931,7 +6931,7 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val) return 0; } -int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val) +int byt_gpu_freq(struct drm_i915_private *dev_priv, int val) { int div; @@ -6953,7 +6953,7 @@ int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val) return DIV_ROUND_CLOSEST(dev_priv-mem_freq * (val + 6 - 0xbd), 4 * div); } -int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val) +int byt_freq_opcode(struct drm_i915_private *dev_priv, int val) { int mul; @@ -6975,6 +6975,80 @@ int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val) return DIV_ROUND_CLOSEST(4 * mul * val, dev_priv-mem_freq) + 0xbd - 6; } +int chv_gpu_freq(struct drm_i915_private *dev_priv, int val) +{ + int div, freq; + + switch (dev_priv-rps.cz_freq) { + case 200: + div = 5; + break; + case 267: + div = 6; + break; + case 320: + case 333: + case 400: + div = 8; + break; + default: + return -1; + } + + freq = (DIV_ROUND_CLOSEST((dev_priv-rps.cz_freq * val), 2 * div) / 2); + + return freq; +} + +int chv_freq_opcode(struct drm_i915_private *dev_priv, int val) +{ + int mul, opcode; + + switch (dev_priv-rps.cz_freq) { + case 200: + mul = 5; + break; + case 267: + mul = 6; + break; + case 320: + case 333: + case 400: + mul = 8; + break; + default: + return -1; + } + + opcode = (DIV_ROUND_CLOSEST((val * 2 * mul), dev_priv-rps.cz_freq) * 2); + + return opcode; +} + +int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val) +{ + int ret = -1; + + if (IS_CHERRYVIEW(dev_priv-dev)) + ret = chv_gpu_freq(dev_priv, val); + else if (IS_VALLEYVIEW(dev_priv-dev)) + ret = byt_gpu_freq(dev_priv, val); + + return ret; +} + +int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val) +{ + int ret = -1; + + if (IS_CHERRYVIEW(dev_priv-dev)) + ret = chv_freq_opcode(dev_priv, val); + else if (IS_VALLEYVIEW(dev_priv-dev)) + ret = byt_freq_opcode(dev_priv, val); + + return ret; +} + void intel_pm_setup(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev-dev_private; -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/3] igt/gem_userptr_blits: Verify that userptr bo work on unshared memory
If the parent passes a userptr to some private memory, we expect to still be able to use the userptr in the child. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- tests/gem_userptr_blits.c | 52 +++ 1 file changed, 52 insertions(+) diff --git a/tests/gem_userptr_blits.c b/tests/gem_userptr_blits.c index 9cf681b..454db58 100644 --- a/tests/gem_userptr_blits.c +++ b/tests/gem_userptr_blits.c @@ -542,6 +542,55 @@ static int test_invalid_mapping(int fd) return 0; } +static void test_forked_access(int fd) +{ + uint32_t handle1, handle2; + void *ptr1, *ptr2; + int ret; + + ret = posix_memalign(ptr1, PAGE_SIZE, PAGE_SIZE); + igt_assert(ret == 0); + + ret = madvise(ptr1, PAGE_SIZE, MADV_DONTFORK); + igt_assert(ret == 0); + + ret = gem_userptr(fd, ptr1, PAGE_SIZE, 0, handle1); + igt_assert(ret == 0); + + ret = posix_memalign(ptr2, PAGE_SIZE, PAGE_SIZE); + igt_assert(ret == 0); + + ret = madvise(ptr2, PAGE_SIZE, MADV_DONTFORK); + igt_assert(ret == 0); + + ret = gem_userptr(fd, ptr2, PAGE_SIZE, 0, handle2); + igt_assert(ret == 0); + + memset(ptr1, 0x1, PAGE_SIZE); + memset(ptr2, 0x2, PAGE_SIZE); + + igt_fork(child, 1) { + copy(fd, handle1, handle2, 0); + } + igt_waitchildren(); + + gem_userptr_sync(fd, handle1); + gem_userptr_sync(fd, handle2); + + gem_close(fd, handle1); + gem_close(fd, handle2); + + igt_assert(memcmp(ptr1, ptr2, PAGE_SIZE) == 0); + + ret = madvise(ptr1, PAGE_SIZE, MADV_DOFORK); + igt_assert(ret == 0); + free(ptr1); + + ret = madvise(ptr2, PAGE_SIZE, MADV_DOFORK); + igt_assert(ret == 0); + free(ptr2); +} + static int test_forbidden_ops(int fd) { void *ptr; @@ -1108,6 +1157,9 @@ int main(int argc, char **argv) igt_subtest(invalid-mapping) test_invalid_mapping(fd); + igt_subtest(forked-access) + test_forked_access(fd); + igt_subtest(forbidden-operations) test_forbidden_ops(fd); -- 2.0.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/3] igt/gem_userptr_blits: Shared memory allocations
The forked tests allocate the bo (and thus for userptr, the memory) in the parent and pass them to all children. The difference for userptr is that we allocate system memory which the kernel then copies into each child. As the children need to access the memory for their checks, it does need to be shared - so allocate the userptr from shared memory! Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80208 Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- tests/gem_userptr_blits.c | 39 ++- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/tests/gem_userptr_blits.c b/tests/gem_userptr_blits.c index 14efdda..9cf681b 100644 --- a/tests/gem_userptr_blits.c +++ b/tests/gem_userptr_blits.c @@ -321,17 +321,32 @@ create_userptr(int fd, uint32_t val, uint32_t *ptr) } static void **handle_ptr_map; -static unsigned int num_handle_ptr_map; +static int *handle_size_map; +static unsigned int num_handle_map; -static void add_handle_ptr(uint32_t handle, void *ptr) +static void reset_handle_ptr(void) { - if (handle = num_handle_ptr_map) { + free(handle_ptr_map); + free(handle_size_map); + num_handle_map = 0; +} + +static void add_handle_ptr(uint32_t handle, void *ptr, int size) +{ + if (handle = num_handle_map) { handle_ptr_map = realloc(handle_ptr_map, (handle + 1000) * sizeof(void*)); - num_handle_ptr_map = handle + 1000; + igt_assert(handle_ptr_map); + + handle_size_map = realloc(handle_size_map, +(handle + 1000) * sizeof(int)); + igt_assert(handle_size_map); + + num_handle_map = handle + 1000; } handle_ptr_map[handle] = ptr; + handle_size_map[handle] = size; } static void *get_handle_ptr(uint32_t handle) @@ -341,10 +356,10 @@ static void *get_handle_ptr(uint32_t handle) static void free_handle_ptr(uint32_t handle) { - igt_assert(handle num_handle_ptr_map); + igt_assert(handle num_handle_map); igt_assert(handle_ptr_map[handle]); - free(handle_ptr_map[handle]); + munmap(handle_ptr_map[handle], handle_size_map[handle]); handle_ptr_map[handle] = NULL; } @@ -354,12 +369,15 @@ static uint32_t create_userptr_bo(int fd, int size) uint32_t handle; int ret; - ret = posix_memalign(ptr, PAGE_SIZE, size); - igt_assert(ret == 0); + ptr = mmap(NULL, size, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_SHARED, + -1, 0); + igt_assert(ptr != MAP_FAILED); ret = gem_userptr(fd, (uint32_t *)ptr, size, 0, handle); igt_assert(ret == 0); - add_handle_ptr(handle, ptr); + add_handle_ptr(handle, ptr, size); return handle; } @@ -641,6 +659,7 @@ static void sigbus(int sig, siginfo_t *info, void *param) MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0); if ((unsigned long)addr == ptr) { memset(addr, counter, sizeof(linear)); + munmap(addr, sizeof(linear)); return; } } @@ -708,6 +727,8 @@ static int test_dmabuf(void) close(fd1); close(fd2); + reset_handle_ptr(); + return 0; } -- 2.0.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] Updated drm-intel-testing
Hi all, New -testing cycle with cool stuff: - fbc improvements when stolen memory is tight (Ben) - cdclk handling improvements for vlv/chv (Ville) - proper fix for stuck primary planes on gmch platforms with cxsr (ImreEbgert Eich) - gen8 hw semaphore support (Ben) - more execlist prep work from Oscar Mateo - locking fixes for primary planes (Matt Roper) - code rework to support runtime pm for dpms on hsw/bdw (Paulo, Imre me), but not yet enabled because some fixes from Paulo haven't made the cut - more gpu boost tuning from Chris - as usual piles of little things all over Happy testing! Cheers, Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/2] drm/i915: Initialise userptr mmu_notifier serial to 1
During the range invalidate, we walk the list of buffers associated with the mmu_notifer and find the ones that overlap the range. An optimisation is made to speed up the iteration by assuming the previous iter is still valid whilst the tree is unmodified. This exposes a bug when a range invalidate is triggered after we have just created the mmu_notifier, but before attaching any buffers. In that case, we presume we have an unmodified list and start walking from the last iter which is NULL. Oops. The easiest fix is then to initialise the serial of the tree to 1. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: Tvrtko Ursulin tvrtko.ursu...@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_userptr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 7c38f50014db..8e9e91029aed 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -197,7 +197,7 @@ i915_mmu_notifier_get(struct drm_device *dev, struct mm_struct *mm) mmu-mm = mm; mmu-objects = RB_ROOT; mmu-count = 0; - mmu-serial = 0; + mmu-serial = 1; INIT_LIST_HEAD(mmu-linear); mmu-is_linear = false; -- 2.0.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/2] drm/i915: Abandon oom quickly if killed by a signal
Whilst waiting to obtain our locks for the last resort shrinking before an oom, we check whether or not a fatal signal was pending. If there was, we do not need to keep waiting as the oom will be aborted. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 64ec167e8921..338f80cd1bfe 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5444,8 +5444,11 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr) bool was_interruptible; bool unlock; - while (!i915_gem_shrinker_lock(dev, unlock) --timeout) + while (!i915_gem_shrinker_lock(dev, unlock) --timeout) { schedule_timeout_killable(1); + if (fatal_signal_pending(current)) + return NOTIFY_DONE; + } if (timeout == 0) { pr_err(Unable to purge GPU memory due lock contention.\n); return NOTIFY_DONE; -- 2.0.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 2/3] igt/gem_userptr_blits: Shared memory allocations
On 07/11/2014 10:40 AM, Chris Wilson wrote: The forked tests allocate the bo (and thus for userptr, the memory) in the parent and pass them to all children. The difference for userptr is that we allocate system memory which the kernel then copies into each child. As the children need to access the memory for their checks, it does need to be shared - so allocate the userptr from shared memory! Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80208 Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- tests/gem_userptr_blits.c | 39 ++- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/tests/gem_userptr_blits.c b/tests/gem_userptr_blits.c index 14efdda..9cf681b 100644 --- a/tests/gem_userptr_blits.c +++ b/tests/gem_userptr_blits.c @@ -321,17 +321,32 @@ create_userptr(int fd, uint32_t val, uint32_t *ptr) } static void **handle_ptr_map; -static unsigned int num_handle_ptr_map; +static int *handle_size_map; +static unsigned int num_handle_map; -static void add_handle_ptr(uint32_t handle, void *ptr) +static void reset_handle_ptr(void) { - if (handle = num_handle_ptr_map) { + free(handle_ptr_map); + free(handle_size_map); + num_handle_map = 0; +} + +static void add_handle_ptr(uint32_t handle, void *ptr, int size) +{ + if (handle = num_handle_map) { handle_ptr_map = realloc(handle_ptr_map, (handle + 1000) * sizeof(void*)); - num_handle_ptr_map = handle + 1000; + igt_assert(handle_ptr_map); + + handle_size_map = realloc(handle_size_map, +(handle + 1000) * sizeof(int)); + igt_assert(handle_size_map); + + num_handle_map = handle + 1000; } handle_ptr_map[handle] = ptr; + handle_size_map[handle] = size; } static void *get_handle_ptr(uint32_t handle) @@ -341,10 +356,10 @@ static void *get_handle_ptr(uint32_t handle) static void free_handle_ptr(uint32_t handle) { - igt_assert(handle num_handle_ptr_map); + igt_assert(handle num_handle_map); igt_assert(handle_ptr_map[handle]); - free(handle_ptr_map[handle]); + munmap(handle_ptr_map[handle], handle_size_map[handle]); handle_ptr_map[handle] = NULL; } @@ -354,12 +369,15 @@ static uint32_t create_userptr_bo(int fd, int size) uint32_t handle; int ret; - ret = posix_memalign(ptr, PAGE_SIZE, size); - igt_assert(ret == 0); + ptr = mmap(NULL, size, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_SHARED, + -1, 0); + igt_assert(ptr != MAP_FAILED); I wasn't sure about this straight away, but man page says ...on Linux, the mapping will be created at a nearby page boundary... so it's fine. ret = gem_userptr(fd, (uint32_t *)ptr, size, 0, handle); igt_assert(ret == 0); - add_handle_ptr(handle, ptr); + add_handle_ptr(handle, ptr, size); return handle; } @@ -641,6 +659,7 @@ static void sigbus(int sig, siginfo_t *info, void *param) MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0); if ((unsigned long)addr == ptr) { memset(addr, counter, sizeof(linear)); + munmap(addr, sizeof(linear)); return; } } @@ -708,6 +727,8 @@ static int test_dmabuf(void) close(fd1); close(fd2); + reset_handle_ptr(); + return 0; } Reviewed-by: Tvrtko Ursulin tvrtko.ursu...@intel.com ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 3/3] igt/gem_userptr_blits: Verify that userptr bo work on unshared memory
On 07/11/2014 10:40 AM, Chris Wilson wrote: If the parent passes a userptr to some private memory, we expect to still be able to use the userptr in the child. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- tests/gem_userptr_blits.c | 52 +++ 1 file changed, 52 insertions(+) diff --git a/tests/gem_userptr_blits.c b/tests/gem_userptr_blits.c index 9cf681b..454db58 100644 --- a/tests/gem_userptr_blits.c +++ b/tests/gem_userptr_blits.c @@ -542,6 +542,55 @@ static int test_invalid_mapping(int fd) return 0; } +static void test_forked_access(int fd) +{ + uint32_t handle1, handle2; + void *ptr1, *ptr2; + int ret; + + ret = posix_memalign(ptr1, PAGE_SIZE, PAGE_SIZE); + igt_assert(ret == 0); + + ret = madvise(ptr1, PAGE_SIZE, MADV_DONTFORK); + igt_assert(ret == 0); + + ret = gem_userptr(fd, ptr1, PAGE_SIZE, 0, handle1); + igt_assert(ret == 0); + + ret = posix_memalign(ptr2, PAGE_SIZE, PAGE_SIZE); + igt_assert(ret == 0); + + ret = madvise(ptr2, PAGE_SIZE, MADV_DONTFORK); + igt_assert(ret == 0); + + ret = gem_userptr(fd, ptr2, PAGE_SIZE, 0, handle2); + igt_assert(ret == 0); + + memset(ptr1, 0x1, PAGE_SIZE); + memset(ptr2, 0x2, PAGE_SIZE); + + igt_fork(child, 1) { + copy(fd, handle1, handle2, 0); + } + igt_waitchildren(); + + gem_userptr_sync(fd, handle1); + gem_userptr_sync(fd, handle2); + + gem_close(fd, handle1); + gem_close(fd, handle2); + + igt_assert(memcmp(ptr1, ptr2, PAGE_SIZE) == 0); + + ret = madvise(ptr1, PAGE_SIZE, MADV_DOFORK); + igt_assert(ret == 0); + free(ptr1); + + ret = madvise(ptr2, PAGE_SIZE, MADV_DOFORK); + igt_assert(ret == 0); + free(ptr2); +} + static int test_forbidden_ops(int fd) { void *ptr; @@ -1108,6 +1157,9 @@ int main(int argc, char **argv) igt_subtest(invalid-mapping) test_invalid_mapping(fd); + igt_subtest(forked-access) + test_forked_access(fd); + igt_subtest(forbidden-operations) test_forbidden_ops(fd); Reviewed-by: Tvrtko Ursulin tvrtko.ursu...@intel.com ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 2/2] drm/i915: Initialise userptr mmu_notifier serial to 1
On 07/11/2014 11:28 AM, Chris Wilson wrote: During the range invalidate, we walk the list of buffers associated with the mmu_notifer and find the ones that overlap the range. An optimisation is made to speed up the iteration by assuming the previous iter is still valid whilst the tree is unmodified. This exposes a bug when a range invalidate is triggered after we have just created the mmu_notifier, but before attaching any buffers. In that case, we presume we have an unmodified list and start walking from the last iter which is NULL. Oops. The easiest fix is then to initialise the serial of the tree to 1. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: Tvrtko Ursulin tvrtko.ursu...@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_userptr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 7c38f50014db..8e9e91029aed 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -197,7 +197,7 @@ i915_mmu_notifier_get(struct drm_device *dev, struct mm_struct *mm) mmu-mm = mm; mmu-objects = RB_ROOT; mmu-count = 0; - mmu-serial = 0; + mmu-serial = 1; INIT_LIST_HEAD(mmu-linear); mmu-is_linear = false; Looks good to me and I think safe to merge in any case, so: Reviewed-by: Tvrtko Ursulin tvrtko.ursu...@intel.com But it will be interesting to know what code managed to trigger this race, because as we discussed on IRC it would indicate some pretty wild userspace behaviour. Or lack of imagination on our part? Tvrtko ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] Changes to running intel-gpu-tools with Piglit
I've just updated the instructions in the intel-gpu-tools README to detail the new ways to run the tests. The most important change is that the igt symlink support has been removed from Piglit. Anyone using the symlink to tell Piglit where to locate the tests needs to update to either use piglit.conf or set the IGT_TEST_ROOT environment variable when running Piglit. There is also a new script (scripts/run-tests.sh) to help run the test suite. This takes care of setting common Piglit options and can also be used to download Piglit locally if it is not already installed. The script has the same include and exclude filters as Piglit (-t and -x) and can also immediately produce the HTML summary after the test run if used with -s. Regards, Thomas ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 2/2] drm/i915: Initialise userptr mmu_notifier serial to 1
On Fri, Jul 11, 2014 at 12:00:26PM +0100, Tvrtko Ursulin wrote: On 07/11/2014 11:28 AM, Chris Wilson wrote: During the range invalidate, we walk the list of buffers associated with the mmu_notifer and find the ones that overlap the range. An optimisation is made to speed up the iteration by assuming the previous iter is still valid whilst the tree is unmodified. This exposes a bug when a range invalidate is triggered after we have just created the mmu_notifier, but before attaching any buffers. In that case, we presume we have an unmodified list and start walking from the last iter which is NULL. Oops. The easiest fix is then to initialise the serial of the tree to 1. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: Tvrtko Ursulin tvrtko.ursu...@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_userptr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 7c38f50014db..8e9e91029aed 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -197,7 +197,7 @@ i915_mmu_notifier_get(struct drm_device *dev, struct mm_struct *mm) mmu-mm = mm; mmu-objects = RB_ROOT; mmu-count = 0; -mmu-serial = 0; +mmu-serial = 1; INIT_LIST_HEAD(mmu-linear); mmu-is_linear = false; Looks good to me and I think safe to merge in any case, so: Reviewed-by: Tvrtko Ursulin tvrtko.ursu...@intel.com But it will be interesting to know what code managed to trigger this race, because as we discussed on IRC it would indicate some pretty wild userspace behaviour. Or lack of imagination on our part? A threaded client. One thread using userptr, the other doing munmap or free. Given enough embarrassment, it will happen every time. -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 2/2] drm/i915: Initialise userptr mmu_notifier serial to 1
On 07/11/2014 12:06 PM, Chris Wilson wrote: On Fri, Jul 11, 2014 at 12:00:26PM +0100, Tvrtko Ursulin wrote: On 07/11/2014 11:28 AM, Chris Wilson wrote: During the range invalidate, we walk the list of buffers associated with the mmu_notifer and find the ones that overlap the range. An optimisation is made to speed up the iteration by assuming the previous iter is still valid whilst the tree is unmodified. This exposes a bug when a range invalidate is triggered after we have just created the mmu_notifier, but before attaching any buffers. In that case, we presume we have an unmodified list and start walking from the last iter which is NULL. Oops. The easiest fix is then to initialise the serial of the tree to 1. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: Tvrtko Ursulin tvrtko.ursu...@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_userptr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 7c38f50014db..8e9e91029aed 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -197,7 +197,7 @@ i915_mmu_notifier_get(struct drm_device *dev, struct mm_struct *mm) mmu-mm = mm; mmu-objects = RB_ROOT; mmu-count = 0; - mmu-serial = 0; + mmu-serial = 1; INIT_LIST_HEAD(mmu-linear); mmu-is_linear = false; Looks good to me and I think safe to merge in any case, so: Reviewed-by: Tvrtko Ursulin tvrtko.ursu...@intel.com But it will be interesting to know what code managed to trigger this race, because as we discussed on IRC it would indicate some pretty wild userspace behaviour. Or lack of imagination on our part? A threaded client. One thread using userptr, the other doing munmap or free. Given enough embarrassment, it will happen every time. Yes fine, but I struggle to imagine what would be the intention of such code or how did it manage to fail in such way. I hope the only difference is not that userptr upgraded the failure mode for heap corruption or memory management races in general. Tvrtko ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 2/2] drm/i915: Initialise userptr mmu_notifier serial to 1
On Fri, Jul 11, 2014 at 12:31:12PM +0100, Tvrtko Ursulin wrote: On 07/11/2014 12:06 PM, Chris Wilson wrote: On Fri, Jul 11, 2014 at 12:00:26PM +0100, Tvrtko Ursulin wrote: But it will be interesting to know what code managed to trigger this race, because as we discussed on IRC it would indicate some pretty wild userspace behaviour. Or lack of imagination on our part? A threaded client. One thread using userptr, the other doing munmap or free. Given enough embarrassment, it will happen every time. Yes fine, but I struggle to imagine what would be the intention of such code or how did it manage to fail in such way. I hope the only difference is not that userptr upgraded the failure mode for heap corruption or memory management races in general. The mmu notifier is called everytime a process sneezes. It does not imply that our object is being invalidated, just that some portion of the current-mm is being modified. -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 2/2] drm/i915: Initialise userptr mmu_notifier serial to 1
On 07/11/2014 12:35 PM, Chris Wilson wrote: On Fri, Jul 11, 2014 at 12:31:12PM +0100, Tvrtko Ursulin wrote: On 07/11/2014 12:06 PM, Chris Wilson wrote: On Fri, Jul 11, 2014 at 12:00:26PM +0100, Tvrtko Ursulin wrote: But it will be interesting to know what code managed to trigger this race, because as we discussed on IRC it would indicate some pretty wild userspace behaviour. Or lack of imagination on our part? A threaded client. One thread using userptr, the other doing munmap or free. Given enough embarrassment, it will happen every time. Yes fine, but I struggle to imagine what would be the intention of such code or how did it manage to fail in such way. I hope the only difference is not that userptr upgraded the failure mode for heap corruption or memory management races in general. The mmu notifier is called everytime a process sneezes. It does not imply that our object is being invalidated, just that some portion of the current-mm is being modified. Ah yes, I did not see the big picture. Tvrtko ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 1/3] Wait for any pid in order to reap failure quicker
On 07/11/2014 10:40 AM, Chris Wilson wrote: When waiting for the forked tests, we can respond quicker to a failure (such as oom) by waiting for any child to exit rather than waiting for each child in order. Then when we see that a test failed, we can kill all other children before aborting. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- lib/igt_core.c | 42 +++--- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/lib/igt_core.c b/lib/igt_core.c index 7ac7ebe..e5dc78b 100644 --- a/lib/igt_core.c +++ b/lib/igt_core.c @@ -915,32 +915,52 @@ bool __igt_fork(void) */ void igt_waitchildren(void) { + int err = 0; + int count; + assert(!test_child); - for (int nc = 0; nc num_test_children; nc++) { + count = 0; + while (count num_test_children) { int status = -1; - while (waitpid(test_children[nc], status, 0) == -1 - errno == EINTR) - ; + pid_t pid; + int c; - if (status != 0) { + pid = wait(status); + if (pid == -1) + continue; Not sure if it would make sense to be more defensive and maybe assert on some errors from wait(2) here (like ECHILD). But it is the same as before the patch so doesn't really matter. + + for (c = 0; c num_test_children; c++) + if (pid == test_children[c]) + break; + if (c == num_test_children) + continue; + + if (err == 0 status != 0) { if (WIFEXITED(status)) { printf(child %i failed with exit status %i\n, - nc, WEXITSTATUS(status)); - igt_fail(WEXITSTATUS(status)); + c, WEXITSTATUS(status)); + err = WEXITSTATUS(status); } else if (WIFSIGNALED(status)) { printf(child %i died with signal %i, %s\n, - nc, WTERMSIG(status), + c, WTERMSIG(status), strsignal(WTERMSIG(status))); - igt_fail(99); + err = 128 + WTERMSIG(status); } else { - printf(Unhandled failure in child %i\n, nc); - abort(); + printf(Unhandled failure [%d] in child %i\n, status, c); + err = 256; } + + for (c = 0; c num_test_children; c++) + kill(test_children[c], SIGKILL); } + + count++; } num_test_children = 0; + if (err) + igt_fail(err); } /* exit handler code */ Looks fine. Reviewed-by: Tvrtko Ursulin tvrtko.ursu...@intel.com ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t] lib: Extract gem_get_tiling() from a couple of tests.
Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/ioctl_wrappers.c | 25 + lib/ioctl_wrappers.h | 1 + tests/gem_tiled_pread.c| 16 tests/gem_tiled_pread_pwrite.c | 16 4 files changed, 26 insertions(+), 32 deletions(-) diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c index af63be3..67351af 100644 --- a/lib/ioctl_wrappers.c +++ b/lib/ioctl_wrappers.c @@ -108,6 +108,31 @@ gem_handle_to_libdrm_bo(drm_intel_bufmgr *bufmgr, int fd, const char *name, uint return bo; } +/** + * gem_get_tiling: + * @fd: open i915 drm file descriptor + * @handle: gem buffer object handle + * @tiling: (out) tiling mode of the gem buffer + * @swizzle: (out) bit 6 swizzle mode + * + * This wraps the GET_TILING ioctl. + */ +void +gem_get_tiling(int fd, uint32_t handle, uint32_t *tiling, uint32_t *swizzle) +{ + struct drm_i915_gem_get_tiling get_tiling; + int ret; + + memset(get_tiling, 0, sizeof(get_tiling)); + get_tiling.handle = handle; + + ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_TILING, get_tiling); + igt_assert(ret == 0); + + *tiling = get_tiling.tiling_mode; + *swizzle = get_tiling.swizzle_mode; +} + int __gem_set_tiling(int fd, uint32_t handle, uint32_t tiling, uint32_t stride) { struct drm_i915_gem_set_tiling st; diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h index 8ca2181..310d82e 100644 --- a/lib/ioctl_wrappers.h +++ b/lib/ioctl_wrappers.h @@ -42,6 +42,7 @@ drm_intel_bo * gem_handle_to_libdrm_bo(drm_intel_bufmgr *bufmgr, int fd, /* ioctl_wrappers.c: * * ioctl wrappers and similar stuff for bare metal testing */ +void gem_get_tiling(int fd, uint32_t handle, uint32_t *tiling, uint32_t *swizzle); void gem_set_tiling(int fd, uint32_t handle, uint32_t tiling, uint32_t stride); int __gem_set_tiling(int fd, uint32_t handle, uint32_t tiling, uint32_t stride); diff --git a/tests/gem_tiled_pread.c b/tests/gem_tiled_pread.c index 4815b72..d99b4ea 100644 --- a/tests/gem_tiled_pread.c +++ b/tests/gem_tiled_pread.c @@ -60,22 +60,6 @@ static int tile_width; static int tile_height; static int tile_size; -static void -gem_get_tiling(int fd, uint32_t handle, uint32_t *tiling, uint32_t *swizzle) -{ - struct drm_i915_gem_get_tiling get_tiling; - int ret; - - memset(get_tiling, 0, sizeof(get_tiling)); - get_tiling.handle = handle; - - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_TILING, get_tiling); - igt_assert(ret == 0); - - *tiling = get_tiling.tiling_mode; - *swizzle = get_tiling.swizzle_mode; -} - static uint32_t create_bo(int fd) { diff --git a/tests/gem_tiled_pread_pwrite.c b/tests/gem_tiled_pread_pwrite.c index b6d9d62..5ab4678 100644 --- a/tests/gem_tiled_pread_pwrite.c +++ b/tests/gem_tiled_pread_pwrite.c @@ -68,22 +68,6 @@ static uint32_t current_tiling_mode; #define PAGE_SIZE 4096 -static void -gem_get_tiling(int fd, uint32_t handle, uint32_t *tiling, uint32_t *swizzle) -{ - struct drm_i915_gem_get_tiling get_tiling; - int ret; - - memset(get_tiling, 0, sizeof(get_tiling)); - get_tiling.handle = handle; - - ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_TILING, get_tiling); - igt_assert(ret == 0); - - *tiling = get_tiling.tiling_mode; - *swizzle = get_tiling.swizzle_mode; -} - static uint32_t create_bo_and_fill(int fd) { -- 1.8.3.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2] drm/i915: Add RP1 render P state thresholds in CHV
From: Deepak S deepa...@linux.intel.com This is useful for userspace utilities to verify and micromanaging the increase/decrease frequncy. v2: Use vlv_gpu_freq to get freq (Deepak) Signed-off-by: Deepak S deepa...@linux.intel.com --- drivers/gpu/drm/i915/intel_pm.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 3fb65e9..225b6cb 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3809,6 +3809,16 @@ static int cherryview_rps_rpe_freq(struct drm_i915_private *dev_priv) return rpe; } +int cherryview_rps_guar_freq(struct drm_i915_private *dev_priv) +{ + u32 val, rp1; + + val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); + rp1 = (val PUNIT_GPU_STATUS_MAX_FREQ_SHIFT) PUNIT_GPU_STATUS_MAX_FREQ_MASK; + + return rp1; +} + int cherryview_rps_min_freq(struct drm_i915_private *dev_priv) { u32 val, rpn; @@ -4010,6 +4020,11 @@ static void cherryview_init_gt_powersave(struct drm_device *dev) vlv_gpu_freq(dev_priv, dev_priv-rps.efficient_freq), dev_priv-rps.efficient_freq); + dev_priv-rps.rp1_freq = cherryview_rps_guar_freq(dev_priv); + DRM_DEBUG_DRIVER(RP1(Guar) GPU freq: %d MHz (%u)\n, +vlv_gpu_freq(dev_priv, dev_priv-rps.rp1_freq), +dev_priv-rps.rp1_freq); + dev_priv-rps.min_freq = cherryview_rps_min_freq(dev_priv); DRM_DEBUG_DRIVER(min GPU freq: %d MHz (%u)\n, vlv_gpu_freq(dev_priv, dev_priv-rps.min_freq), -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 30/40] drm/i915: Add the WaCsStallBeforeStateCacheInvalidate:bdw workaround.
-Original Message- From: Intel-gfx [mailto:intel-gfx-boun...@lists.freedesktop.org] On Behalf Of ville.syrj...@linux.intel.com Sent: Saturday, June 28, 2014 12:04 AM To: intel-gfx@lists.freedesktop.org Subject: [Intel-gfx] [PATCH 30/40] drm/i915: Add the WaCsStallBeforeStateCacheInvalidate:bdw workaround. From: Kenneth Graunke kenn...@whitecape.org On Broadwell, any PIPE_CONTROL with the State Cache Invalidate bit set must be preceded by a PIPE_CONTROL with the CS Stall bit set. Documented on the BSpec 3D workarounds page. Signed-off-by: Kenneth Graunke kenn...@whitecape.org [vsyrjala: add chv w/a note too] Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com There is a gotcha here that this workaround name has been used for a different bug in Gen7.5 and below. The workaround name clash came from the docs rather than a mistake by the patch authors, this is the correct workaround for all gen8 based devices Reviewed-by: Rafael Barbalho rafael.barba...@intel.com --- drivers/gpu/drm/i915/intel_ringbuffer.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 97796b1..ceb1295 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -424,6 +424,14 @@ gen8_render_ring_flush(struct intel_engine_cs *ring, flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; flags |= PIPE_CONTROL_QW_WRITE; flags |= PIPE_CONTROL_GLOBAL_GTT_IVB; + + /* WaCsStallBeforeStateCacheInvalidate:bdw,chv */ + ret = gen8_emit_pipe_control(ring, + PIPE_CONTROL_CS_STALL | + PIPE_CONTROL_STALL_AT_SCOREBOARD, + 0); + if (ret) + return ret; } return gen8_emit_pipe_control(ring, flags, scratch_addr); -- 1.8.5.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 01/40] drm/i915: Try to populate mem_freq for chv
On Saturday 28 June 2014 04:33 AM, ville.syrj...@linux.intel.com wrote: From: Ville Syrjälä ville.syrj...@linux.intel.com mem_freq is needed to decode the GPU freq opcodes. FIXME: Punit reg seems to contain garbage so this isn't right Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_pm.c | 18 ++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 07c040c..ef00756 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5629,6 +5629,24 @@ static void valleyview_init_clock_gating(struct drm_device *dev) static void cherryview_init_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev-dev_private; + u32 val; + + mutex_lock(dev_priv-rps.hw_lock); + val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); + mutex_unlock(dev_priv-rps.hw_lock); + switch ((val 6) 3) { + case 0: + case 1: + dev_priv-mem_freq = 800; + break; + case 2: + dev_priv-mem_freq = 1066; + break; + case 3: + dev_priv-mem_freq = 1333; + break; + } + DRM_DEBUG_DRIVER(DDR speed: %d MHz, dev_priv-mem_freq); I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE); Added the right way of getting the mem_freq for CHV *http://lists.freedesktop.org/archives/intel-gfx/2014-July/048897.html* ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 02/40] drm/i915: Use the cached min/min/rpe values in the vlv debugfs code
On Saturday 28 June 2014 04:33 AM, ville.syrj...@linux.intel.com wrote: From: Ville Syrjälä ville.syrj...@linux.intel.com No need to re-read the hardware rps fuses when we already have all the values tucked away in dev_priv-rps. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 19 ++- drivers/gpu/drm/i915/i915_drv.h | 2 -- drivers/gpu/drm/i915/intel_pm.c | 8 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a93b3bf..415010e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1131,20 +1131,21 @@ static int i915_frequency_info(struct seq_file *m, void *unused) seq_printf(m, Max overclocked frequency: %dMHz\n, dev_priv-rps.max_freq * GT_FREQUENCY_MULTIPLIER); } else if (IS_VALLEYVIEW(dev)) { - u32 freq_sts, val; + u32 freq_sts; mutex_lock(dev_priv-rps.hw_lock); freq_sts = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); seq_printf(m, PUNIT_REG_GPU_FREQ_STS: 0x%08x\n, freq_sts); seq_printf(m, DDR freq: %d MHz\n, dev_priv-mem_freq); - val = valleyview_rps_max_freq(dev_priv); seq_printf(m, max GPU freq: %d MHz\n, - vlv_gpu_freq(dev_priv, val)); + dev_priv-rps.max_freq); - val = valleyview_rps_min_freq(dev_priv); seq_printf(m, min GPU freq: %d MHz\n, - vlv_gpu_freq(dev_priv, val)); + dev_priv-rps.min_freq); + + seq_printf(m, efficient (RPe) frequency: %d MHz\n, + dev_priv-rps.efficient_freq); seq_printf(m, current GPU freq: %d MHz\n, vlv_gpu_freq(dev_priv, (freq_sts 8) 0xff)); @@ -3565,8 +3566,8 @@ i915_max_freq_set(void *data, u64 val) if (IS_VALLEYVIEW(dev)) { val = vlv_freq_opcode(dev_priv, val); - hw_max = valleyview_rps_max_freq(dev_priv); - hw_min = valleyview_rps_min_freq(dev_priv); + hw_max = dev_priv-rps.max_freq; + hw_min = dev_priv-rps.min_freq; } else { do_div(val, GT_FREQUENCY_MULTIPLIER); @@ -3646,8 +3647,8 @@ i915_min_freq_set(void *data, u64 val) if (IS_VALLEYVIEW(dev)) { val = vlv_freq_opcode(dev_priv, val); - hw_max = valleyview_rps_max_freq(dev_priv); - hw_min = valleyview_rps_min_freq(dev_priv); + hw_max = dev_priv-rps.max_freq; + hw_min = dev_priv-rps.min_freq; } else { do_div(val, GT_FREQUENCY_MULTIPLIER); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8cea596..38859d1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2646,8 +2646,6 @@ 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 int valleyview_rps_max_freq(struct drm_i915_private *dev_priv); -extern int valleyview_rps_min_freq(struct drm_i915_private *dev_priv); extern void intel_detect_pch(struct drm_device *dev); extern int intel_trans_dp_port_sel(struct drm_crtc *crtc); extern int intel_enable_rc6(const struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index ef00756..10c9c02 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3729,7 +3729,7 @@ void gen6_update_ring_freq(struct drm_device *dev) mutex_unlock(dev_priv-rps.hw_lock); } -int cherryview_rps_max_freq(struct drm_i915_private *dev_priv) +static int cherryview_rps_max_freq(struct drm_i915_private *dev_priv) { u32 val, rp0; @@ -3749,7 +3749,7 @@ static int cherryview_rps_rpe_freq(struct drm_i915_private *dev_priv) return rpe; } -int cherryview_rps_min_freq(struct drm_i915_private *dev_priv) +static int cherryview_rps_min_freq(struct drm_i915_private *dev_priv) { u32 val, rpn; @@ -3758,7 +3758,7 @@ int cherryview_rps_min_freq(struct drm_i915_private *dev_priv) return rpn; } -int valleyview_rps_max_freq(struct drm_i915_private *dev_priv) +static int valleyview_rps_max_freq(struct drm_i915_private *dev_priv) { u32 val, rp0; @@ -3783,7 +3783,7 @@ static int valleyview_rps_rpe_freq(struct drm_i915_private *dev_priv) return rpe; } -int valleyview_rps_min_freq(struct drm_i915_private *dev_priv) +static int valleyview_rps_min_freq(struct drm_i915_private *dev_priv) { return vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM) 0xff; }
Re: [Intel-gfx] [PATCH 03/40] drm/i915: Align chv rps min/max/rpe values
On Saturday 28 June 2014 04:33 AM, ville.syrj...@linux.intel.com wrote: From: Ville Syrjälä ville.syrj...@linux.intel.com CHV wants even rps opcodes so make sure the min/max/rpe values are also even. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 8 drivers/gpu/drm/i915/intel_pm.c | 19 ++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 415010e..9b01e7c 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3566,6 +3566,10 @@ i915_max_freq_set(void *data, u64 val) if (IS_VALLEYVIEW(dev)) { val = vlv_freq_opcode(dev_priv, val); + /* CHV needs even encode values */ + if (IS_CHERRYVIEW(dev)) + val = ~1; + hw_max = dev_priv-rps.max_freq; hw_min = dev_priv-rps.min_freq; } else { @@ -3647,6 +3651,10 @@ i915_min_freq_set(void *data, u64 val) if (IS_VALLEYVIEW(dev)) { val = vlv_freq_opcode(dev_priv, val); + /* CHV needs even encode values */ + if (IS_CHERRYVIEW(dev)) + val = ALIGN(val, 2); + hw_max = dev_priv-rps.max_freq; hw_min = dev_priv-rps.min_freq; } else { diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 10c9c02..e3f23c2 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3924,21 +3924,30 @@ static void cherryview_init_gt_powersave(struct drm_device *dev) mutex_lock(dev_priv-rps.hw_lock); dev_priv-rps.max_freq = cherryview_rps_max_freq(dev_priv); + if (WARN_ON_ONCE(dev_priv-rps.max_freq 1)) + dev_priv-rps.max_freq = ~1; Cannot we use ALIGN Here? Other than this it looks fine Reviewed-by: Deepak S deepa...@linux.intel.com dev_priv-rps.rp0_freq = dev_priv-rps.max_freq; DRM_DEBUG_DRIVER(max GPU freq: %d MHz (%u)\n, vlv_gpu_freq(dev_priv, dev_priv-rps.max_freq), dev_priv-rps.max_freq); - dev_priv-rps.efficient_freq = cherryview_rps_rpe_freq(dev_priv); - DRM_DEBUG_DRIVER(RPe GPU freq: %d MHz (%u)\n, -vlv_gpu_freq(dev_priv, dev_priv-rps.efficient_freq), -dev_priv-rps.efficient_freq); - dev_priv-rps.min_freq = cherryview_rps_min_freq(dev_priv); + if (WARN_ON_ONCE(dev_priv-rps.min_freq 1)) + dev_priv-rps.min_freq = ALIGN(dev_priv-rps.min_freq, 2); DRM_DEBUG_DRIVER(min GPU freq: %d MHz (%u)\n, vlv_gpu_freq(dev_priv, dev_priv-rps.min_freq), dev_priv-rps.min_freq); + dev_priv-rps.efficient_freq = cherryview_rps_rpe_freq(dev_priv); + if (WARN_ON_ONCE(dev_priv-rps.min_freq 1)) + dev_priv-rps.efficient_freq = ~1; + dev_priv-rps.efficient_freq = clamp(dev_priv-rps.efficient_freq, +dev_priv-rps.min_freq, +dev_priv-rps.max_freq); + DRM_DEBUG_DRIVER(RPe GPU freq: %d MHz (%u)\n, +vlv_gpu_freq(dev_priv, dev_priv-rps.efficient_freq), +dev_priv-rps.efficient_freq); + /* Preserve min/max settings in case of re-init */ if (dev_priv-rps.max_freq_softlimit == 0) dev_priv-rps.max_freq_softlimit = dev_priv-rps.max_freq; ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 05/40] drm/i915: Don't disable PPGTT for CHV based in PCI rev
On Saturday 28 June 2014 04:33 AM, ville.syrj...@linux.intel.com wrote: From: Ville Syrjälä ville.syrj...@linux.intel.com In commit 62942ed7279d3e06dc15ae3d47665eff3b373327 Author: Jesse Barnes jbar...@virtuousgeek.org Date: Fri Jun 13 09:28:33 2014 -0700 drm/i915/vlv: disable PPGTT on early revs v3 we forgot about CHV. IS_VALLEYVIEW() is true for CHV, so we need to explicitly avoid disabling PPGTT on CHV. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_gtt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index a4153ee..5188936 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -64,7 +64,8 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) #endif /* Early VLV doesn't have this */ - if (IS_VALLEYVIEW(dev) dev-pdev-revision 0xb) { + if (IS_VALLEYVIEW(dev) !IS_CHERRYVIEW(dev) + dev-pdev-revision 0xb) { DRM_DEBUG_DRIVER(disabling PPGTT on pre-B3 step VLV\n); return 0; } Reviewed-by: Deepak S deepa...@linux.intel.com ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 05/40] drm/i915: Don't disable PPGTT for CHV based in PCI rev
On Sat, Jul 12, 2014 at 07:18:30PM +0530, Deepak S wrote: On Saturday 28 June 2014 04:33 AM, ville.syrj...@linux.intel.com wrote: From: Ville Syrjälä ville.syrj...@linux.intel.com In commit 62942ed7279d3e06dc15ae3d47665eff3b373327 Author: Jesse Barnes jbar...@virtuousgeek.org Date: Fri Jun 13 09:28:33 2014 -0700 drm/i915/vlv: disable PPGTT on early revs v3 we forgot about CHV. IS_VALLEYVIEW() is true for CHV, so we need to explicitly avoid disabling PPGTT on CHV. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_gtt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index a4153ee..5188936 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -64,7 +64,8 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) #endif /* Early VLV doesn't have this */ -if (IS_VALLEYVIEW(dev) dev-pdev-revision 0xb) { +if (IS_VALLEYVIEW(dev) !IS_CHERRYVIEW(dev) +dev-pdev-revision 0xb) { DRM_DEBUG_DRIVER(disabling PPGTT on pre-B3 step VLV\n); return 0; } Reviewed-by: Deepak S deepa...@linux.intel.com Queued for -next, thanks for the patch. -Daniel ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 2/2] drm/i915: Initialise userptr mmu_notifier serial to 1
On Fri, Jul 11, 2014 at 12:06:02PM +0100, Chris Wilson wrote: On Fri, Jul 11, 2014 at 12:00:26PM +0100, Tvrtko Ursulin wrote: On 07/11/2014 11:28 AM, Chris Wilson wrote: During the range invalidate, we walk the list of buffers associated with the mmu_notifer and find the ones that overlap the range. An optimisation is made to speed up the iteration by assuming the previous iter is still valid whilst the tree is unmodified. This exposes a bug when a range invalidate is triggered after we have just created the mmu_notifier, but before attaching any buffers. In that case, we presume we have an unmodified list and start walking from the last iter which is NULL. Oops. The easiest fix is then to initialise the serial of the tree to 1. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: Tvrtko Ursulin tvrtko.ursu...@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_userptr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 7c38f50014db..8e9e91029aed 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -197,7 +197,7 @@ i915_mmu_notifier_get(struct drm_device *dev, struct mm_struct *mm) mmu-mm = mm; mmu-objects = RB_ROOT; mmu-count = 0; - mmu-serial = 0; + mmu-serial = 1; INIT_LIST_HEAD(mmu-linear); mmu-is_linear = false; Looks good to me and I think safe to merge in any case, so: Reviewed-by: Tvrtko Ursulin tvrtko.ursu...@intel.com But it will be interesting to know what code managed to trigger this race, because as we discussed on IRC it would indicate some pretty wild userspace behaviour. Or lack of imagination on our part? A threaded client. One thread using userptr, the other doing munmap or free. Given enough embarrassment, it will happen every time. Can I have an igt please to confirm this and ensure it stays fixed? -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 02/40] drm/i915: Use the cached min/min/rpe values in the vlv debugfs code
On Sat, Jul 12, 2014 at 07:00:05PM +0530, Deepak S wrote: On Saturday 28 June 2014 04:33 AM, ville.syrj...@linux.intel.com wrote: From: Ville Syrjälä ville.syrj...@linux.intel.com No need to re-read the hardware rps fuses when we already have all the values tucked away in dev_priv-rps. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 19 ++- drivers/gpu/drm/i915/i915_drv.h | 2 -- drivers/gpu/drm/i915/intel_pm.c | 8 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a93b3bf..415010e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1131,20 +1131,21 @@ static int i915_frequency_info(struct seq_file *m, void *unused) seq_printf(m, Max overclocked frequency: %dMHz\n, dev_priv-rps.max_freq * GT_FREQUENCY_MULTIPLIER); } else if (IS_VALLEYVIEW(dev)) { -u32 freq_sts, val; +u32 freq_sts; mutex_lock(dev_priv-rps.hw_lock); freq_sts = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); seq_printf(m, PUNIT_REG_GPU_FREQ_STS: 0x%08x\n, freq_sts); seq_printf(m, DDR freq: %d MHz\n, dev_priv-mem_freq); -val = valleyview_rps_max_freq(dev_priv); seq_printf(m, max GPU freq: %d MHz\n, - vlv_gpu_freq(dev_priv, val)); + dev_priv-rps.max_freq); -val = valleyview_rps_min_freq(dev_priv); seq_printf(m, min GPU freq: %d MHz\n, - vlv_gpu_freq(dev_priv, val)); + dev_priv-rps.min_freq); + +seq_printf(m, efficient (RPe) frequency: %d MHz\n, + dev_priv-rps.efficient_freq); seq_printf(m, current GPU freq: %d MHz\n, vlv_gpu_freq(dev_priv, (freq_sts 8) 0xff)); @@ -3565,8 +3566,8 @@ i915_max_freq_set(void *data, u64 val) if (IS_VALLEYVIEW(dev)) { val = vlv_freq_opcode(dev_priv, val); -hw_max = valleyview_rps_max_freq(dev_priv); -hw_min = valleyview_rps_min_freq(dev_priv); +hw_max = dev_priv-rps.max_freq; +hw_min = dev_priv-rps.min_freq; } else { do_div(val, GT_FREQUENCY_MULTIPLIER); @@ -3646,8 +3647,8 @@ i915_min_freq_set(void *data, u64 val) if (IS_VALLEYVIEW(dev)) { val = vlv_freq_opcode(dev_priv, val); -hw_max = valleyview_rps_max_freq(dev_priv); -hw_min = valleyview_rps_min_freq(dev_priv); +hw_max = dev_priv-rps.max_freq; +hw_min = dev_priv-rps.min_freq; } else { do_div(val, GT_FREQUENCY_MULTIPLIER); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8cea596..38859d1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2646,8 +2646,6 @@ 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 int valleyview_rps_max_freq(struct drm_i915_private *dev_priv); -extern int valleyview_rps_min_freq(struct drm_i915_private *dev_priv); extern void intel_detect_pch(struct drm_device *dev); extern int intel_trans_dp_port_sel(struct drm_crtc *crtc); extern int intel_enable_rc6(const struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index ef00756..10c9c02 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3729,7 +3729,7 @@ void gen6_update_ring_freq(struct drm_device *dev) mutex_unlock(dev_priv-rps.hw_lock); } -int cherryview_rps_max_freq(struct drm_i915_private *dev_priv) +static int cherryview_rps_max_freq(struct drm_i915_private *dev_priv) { u32 val, rp0; @@ -3749,7 +3749,7 @@ static int cherryview_rps_rpe_freq(struct drm_i915_private *dev_priv) return rpe; } -int cherryview_rps_min_freq(struct drm_i915_private *dev_priv) +static int cherryview_rps_min_freq(struct drm_i915_private *dev_priv) { u32 val, rpn; @@ -3758,7 +3758,7 @@ int cherryview_rps_min_freq(struct drm_i915_private *dev_priv) return rpn; } -int valleyview_rps_max_freq(struct drm_i915_private *dev_priv) +static int valleyview_rps_max_freq(struct drm_i915_private *dev_priv) { u32 val, rp0; @@ -3783,7 +3783,7 @@ static int valleyview_rps_rpe_freq(struct drm_i915_private *dev_priv) return rpe; } -int valleyview_rps_min_freq(struct drm_i915_private *dev_priv) +static int valleyview_rps_min_freq(struct drm_i915_private *dev_priv) { return
Re: [Intel-gfx] [PATCH 2/2] drm/i915: Initialise userptr mmu_notifier serial to 1
On 07/11/2014 03:02 PM, Daniel Vetter wrote: On Fri, Jul 11, 2014 at 12:06:02PM +0100, Chris Wilson wrote: On Fri, Jul 11, 2014 at 12:00:26PM +0100, Tvrtko Ursulin wrote: On 07/11/2014 11:28 AM, Chris Wilson wrote: During the range invalidate, we walk the list of buffers associated with the mmu_notifer and find the ones that overlap the range. An optimisation is made to speed up the iteration by assuming the previous iter is still valid whilst the tree is unmodified. This exposes a bug when a range invalidate is triggered after we have just created the mmu_notifier, but before attaching any buffers. In that case, we presume we have an unmodified list and start walking from the last iter which is NULL. Oops. The easiest fix is then to initialise the serial of the tree to 1. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: Tvrtko Ursulin tvrtko.ursu...@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_userptr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 7c38f50014db..8e9e91029aed 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -197,7 +197,7 @@ i915_mmu_notifier_get(struct drm_device *dev, struct mm_struct *mm) mmu-mm = mm; mmu-objects = RB_ROOT; mmu-count = 0; - mmu-serial = 0; + mmu-serial = 1; INIT_LIST_HEAD(mmu-linear); mmu-is_linear = false; Looks good to me and I think safe to merge in any case, so: Reviewed-by: Tvrtko Ursulin tvrtko.ursu...@intel.com But it will be interesting to know what code managed to trigger this race, because as we discussed on IRC it would indicate some pretty wild userspace behaviour. Or lack of imagination on our part? A threaded client. One thread using userptr, the other doing munmap or free. Given enough embarrassment, it will happen every time. Can I have an igt please to confirm this and ensure it stays fixed? Sure, give me a day or two. Tvrtko ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 3/5] lib: NULLify -cairo_surface once unmapped
Just a matter of not leaving dangling pointers around. Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_fb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/igt_fb.c b/lib/igt_fb.c index 39a1f62..83f4343 100644 --- a/lib/igt_fb.c +++ b/lib/igt_fb.c @@ -521,7 +521,9 @@ static cairo_format_t drm_format_to_cairo(uint32_t drm_format) static void destroy_cairo_surface__gtt(void *arg) { struct igt_fb *fb = arg; + munmap(cairo_image_surface_get_data(fb-cairo_surface), fb-size); + fb-cairo_surface = NULL; } static void create_cairo_surface__gtt(int fd, struct igt_fb *fb) -- 1.8.3.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 4/5] lib: Don't take a reference to the surface in get_cairo_surface()
We don't need to keep a reference to the surface, the cairo context will keep a reference to it until we destroy it. Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/igt_fb.c b/lib/igt_fb.c index 83f4343..d07af0d 100644 --- a/lib/igt_fb.c +++ b/lib/igt_fb.c @@ -547,7 +547,7 @@ static cairo_surface_t *get_cairo_surface(int fd, struct igt_fb *fb) I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); igt_assert(cairo_surface_status(fb-cairo_surface) == CAIRO_STATUS_SUCCESS); - return cairo_surface_reference(fb-cairo_surface); + return fb-cairo_surface; } /** -- 1.8.3.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 5/5] testdisplay: Destroy the cairo context once the fb is painted
Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- tests/testdisplay.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/testdisplay.c b/tests/testdisplay.c index 6d8fe3a..887105d 100644 --- a/tests/testdisplay.c +++ b/tests/testdisplay.c @@ -314,6 +314,8 @@ static void paint_output_info(struct connector *c, struct igt_fb *fb) paint_image(cr, IGT_DATADIR/pass.png); igt_assert(!cairo_status(cr)); + + cairo_destroy(cr); } static void sighandler(int signo) -- 1.8.3.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 2/5] lib: Split the GTT mapping out of get_cairo_surface()
This is preparation work for when we need a different way to get a linear buffer we can use with cairo. Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_fb.c | 26 +++--- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/lib/igt_fb.c b/lib/igt_fb.c index f43af93..39a1f62 100644 --- a/lib/igt_fb.c +++ b/lib/igt_fb.c @@ -518,24 +518,28 @@ static cairo_format_t drm_format_to_cairo(uint32_t drm_format) igt_fail(101); } -static void __destroy_cairo_surface(void *arg) +static void destroy_cairo_surface__gtt(void *arg) { struct igt_fb *fb = arg; munmap(cairo_image_surface_get_data(fb-cairo_surface), fb-size); } +static void create_cairo_surface__gtt(int fd, struct igt_fb *fb) +{ + fb-cairo_surface = + cairo_image_surface_create_for_data(gem_mmap(fd, fb-gem_handle, fb-size, PROT_READ | PROT_WRITE), + drm_format_to_cairo(fb-drm_format), + fb-width, fb-height, fb-stride); + + cairo_surface_set_user_data(fb-cairo_surface, + (cairo_user_data_key_t *)create_cairo_surface__gtt, + fb, destroy_cairo_surface__gtt); +} + static cairo_surface_t *get_cairo_surface(int fd, struct igt_fb *fb) { - if (fb-cairo_surface == NULL) { - fb-cairo_surface = - cairo_image_surface_create_for_data(gem_mmap(fd, fb-gem_handle, fb-size, PROT_READ | PROT_WRITE), - drm_format_to_cairo(fb-drm_format), - fb-width, fb-height, fb-stride); - - cairo_surface_set_user_data(fb-cairo_surface, - (cairo_user_data_key_t *)get_cairo_surface, - fb, __destroy_cairo_surface); - } + if (fb-cairo_surface == NULL) + create_cairo_surface__gtt(fd, fb); gem_set_domain(fd, fb-gem_handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); -- 1.8.3.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH i-g-t 1/5] lib: Remove unused field from struct igt_fb
Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_fb.h | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/igt_fb.h b/lib/igt_fb.h index 6d030e6..f5110d4 100644 --- a/lib/igt_fb.h +++ b/lib/igt_fb.h @@ -48,7 +48,6 @@ struct igt_fb { uint32_t drm_format; int width; int height; - int depth; unsigned stride; unsigned tiling; unsigned size; -- 1.8.3.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 16/40] drm/i915: Add chv_power_wells[]
-Original Message- From: Intel-gfx [mailto:intel-gfx-boun...@lists.freedesktop.org] On Behalf Of ville.syrj...@linux.intel.com Sent: Saturday, June 28, 2014 12:04 AM To: intel-gfx@lists.freedesktop.org Subject: [Intel-gfx] [PATCH 16/40] drm/i915: Add chv_power_wells[] From: Ville Syrjälä ville.syrj...@linux.intel.com Add chv_power_wells[] so we can start to build up the power well support for chv. Just the always on well there initialy. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_pm.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 898654f..e2b956e 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6498,6 +6498,15 @@ static struct i915_power_well vlv_power_wells[] = { }, }; +static struct i915_power_well chv_power_wells[] = { + { + .name = always-on, + .always_on = 1, + .domains = VLV_ALWAYS_ON_POWER_DOMAINS, + .ops = i9xx_always_on_power_well_ops, + }, +}; + static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_priv, enum punit_power_well power_well_id) { @@ -6534,6 +6543,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) } else if (IS_BROADWELL(dev_priv-dev)) { set_power_wells(power_domains, bdw_power_wells); hsw_pwr = power_domains; + } else if (IS_CHERRYVIEW(dev_priv-dev)) { + set_power_wells(power_domains, chv_power_wells); } else if (IS_VALLEYVIEW(dev_priv-dev)) { set_power_wells(power_domains, vlv_power_wells); } else { -- 1.8.5.5 Tested-by: Rafael Barbalho rafael.barba...@intel.com ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH i-g-t 02/43] igt_kms: Make has_universal_planes a bitfield
On Fri, Jul 11, 2014 at 08:34:41AM +0200, Daniel Vetter wrote: On Thu, Jul 10, 2014 at 07:00:03PM +0100, Damien Lespiau wrote: Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_kms.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/igt_kms.h b/lib/igt_kms.h index a079fc2..058114a 100644 --- a/lib/igt_kms.h +++ b/lib/igt_kms.h @@ -153,7 +153,7 @@ struct igt_display { unsigned long pipes_in_use; igt_output_t *outputs; igt_pipe_t pipes[I915_MAX_PIPES]; - bool has_universal_planes; + unsigned int has_universal_planes : 1; tbh I didn't see the point of this and didn't see any follow-up patch which would explain the motivation ... Fair, I dropped this one for the series. -- Damien ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH i-g-t 05/43] igt_kms: Add support for setting plane rotation
On Fri, Jul 11, 2014 at 08:37:42AM +0200, Daniel Vetter wrote: On Thu, Jul 10, 2014 at 07:00:06PM +0100, Damien Lespiau wrote: Signed-off-by: Damien Lespiau damien.lesp...@intel.com --- lib/igt_kms.c | 54 ++ lib/igt_kms.h | 11 +++ 2 files changed, 65 insertions(+) diff --git a/lib/igt_kms.c b/lib/igt_kms.c index 87f5109..69f9977 100644 --- a/lib/igt_kms.c +++ b/lib/igt_kms.c @@ -537,6 +537,16 @@ get_plane_property(igt_display_t *display, uint32_t plane_id, const char *name, name, prop_id, value); } +static void +igt_plane_set_property(igt_plane_t *plane, uint32_t prop_id, uint64_t value) +{ + igt_pipe_t *pipe = plane-pipe; + igt_display_t *display = pipe-display; + + drmModeObjectSetProperty(display-drm_fd, plane-drm_plane-plane_id, +DRM_MODE_OBJECT_PLANE, prop_id, value); +} I wonder whether we shouldn't have interfaces using the property names and maybe for enum properties also the strings and let igt do it's thing. But as long as this is just an internal function it should be good enough. That'd be handy. the only issue is that you'd have to do a lookup of the property id each time or create a prop_name - prop_id map in the different objects. Also, we can provide a bit more typing than a uint64_t for the value. Trade-offs, trade-offs, ... -- Damien ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH i-g-t 00/43] Rotation test
On Thu, Jul 10, 2014 at 07:00:01PM +0100, Damien Lespiau wrote: I've taken the current rotation test to test the kernel patches and improved it a bit along the way. It's a bit like a detailed review, but with patches instead of comments. With the rotation kernel patches and an IVB machine, that test now passes. Part of the motivation has been to augment the igt_kms framework to deal with properties. Another reason include the number of lines we need to write for a test. This series brings down that number from 325 to 129, something I can live with. Whole series (but one patch after Daniel's comment) pushed to i-g-t after Chris and Daniel ack on IRC. This shouldn't blow up too hard, the test correctly skips when the kernel support is lacking. -- Damien ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] intel-gpu-tools: Dont build kms_force_connector if no cairo
From: Tim Gore tim.g...@intel.com kms_force_connector is a new test that requires cairo. I have added it to the list of tests not to build on Android unless ANDROID_HAS_CAIRO is set. Signed-off-by: Tim Gore tim.g...@intel.com --- tests/Android.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Android.mk b/tests/Android.mk index 22f12ad..00e6f1b 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -71,7 +71,8 @@ else kms_mmio_vs_cs_flip \ kms_render \ kms_universal_plane \ -kms_rotation_crc +kms_rotation_crc \ +kms_force_connector IGT_LOCAL_CFLAGS += -DANDROID_HAS_CAIRO=0 endif -- 1.9.2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 1/7] drm/i915: Read guaranteed freq for valleyview
deepa...@linux.intel.com writes: From: Deepak S deepa...@linux.intel.com Reading RP1 for valleyview to help us enable pm_rps i-g-t testcase execution. Signed-off-by: Deepak S deepa...@linux.intel.com Reviewed-by: Mika Kuoppala mika.kuopp...@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d1af641..b8e7afc 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3816,6 +3816,17 @@ int cherryview_rps_min_freq(struct drm_i915_private *dev_priv) return rpn; } +int valleyview_rps_guar_freq(struct drm_i915_private *dev_priv) +{ + u32 val, rp1; + + val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FREQ_FUSE); + + rp1 = (val FB_GFX_FGUARANTEED_FREQ_FUSE_MASK) FB_GFX_FGUARANTEED_FREQ_FUSE_SHIFT; + + return rp1; +} + int valleyview_rps_max_freq(struct drm_i915_private *dev_priv) { u32 val, rp0; @@ -3958,6 +3969,11 @@ static void valleyview_init_gt_powersave(struct drm_device *dev) vlv_gpu_freq(dev_priv, dev_priv-rps.efficient_freq), dev_priv-rps.efficient_freq); + dev_priv-rps.rp1_freq = valleyview_rps_guar_freq(dev_priv); + DRM_DEBUG_DRIVER(RP1(Guar Freq) GPU freq: %d MHz (%u)\n, + vlv_gpu_freq(dev_priv, dev_priv-rps.rp1_freq), + dev_priv-rps.rp1_freq); + dev_priv-rps.min_freq = valleyview_rps_min_freq(dev_priv); DRM_DEBUG_DRIVER(min GPU freq: %d MHz (%u)\n, vlv_gpu_freq(dev_priv, dev_priv-rps.min_freq), -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 2/7] drm/i915: Add RP0/RP1/RPn render P state thresholds in VLV sysfs
deepa...@linux.intel.com writes: From: Deepak S deepa...@linux.intel.com This is useful for userspace utilities to verify and micromanaging the increase/decrease frequncy. Signed-off-by: Deepak S deepa...@linux.intel.com Reviewed-by: Mika Kuoppala mika.kuopp...@intel.com --- drivers/gpu/drm/i915/i915_sysfs.c | 18 +++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 86ce39a..b15c8ce 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -461,11 +461,20 @@ static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr mutex_unlock(dev-struct_mutex); if (attr == dev_attr_gt_RP0_freq_mhz) { - val = ((rp_state_cap 0xff) 0) * GT_FREQUENCY_MULTIPLIER; + if (IS_VALLEYVIEW(dev)) + val = vlv_gpu_freq(dev_priv, dev_priv-rps.rp0_freq); + else + val = ((rp_state_cap 0xff) 0) * GT_FREQUENCY_MULTIPLIER; } else if (attr == dev_attr_gt_RP1_freq_mhz) { - val = ((rp_state_cap 0x00ff00) 8) * GT_FREQUENCY_MULTIPLIER; + if (IS_VALLEYVIEW(dev)) + val = vlv_gpu_freq(dev_priv, dev_priv-rps.rp1_freq); + else + val = ((rp_state_cap 0x00ff00) 8) * GT_FREQUENCY_MULTIPLIER; } else if (attr == dev_attr_gt_RPn_freq_mhz) { - val = ((rp_state_cap 0xff) 16) * GT_FREQUENCY_MULTIPLIER; + if (IS_VALLEYVIEW(dev)) + val = vlv_gpu_freq(dev_priv, dev_priv-rps.min_freq); + else + val = ((rp_state_cap 0xff) 16) * GT_FREQUENCY_MULTIPLIER; } else { BUG(); } @@ -486,6 +495,9 @@ static const struct attribute *vlv_attrs[] = { dev_attr_gt_cur_freq_mhz.attr, dev_attr_gt_max_freq_mhz.attr, dev_attr_gt_min_freq_mhz.attr, + dev_attr_gt_RP0_freq_mhz.attr, + dev_attr_gt_RP1_freq_mhz.attr, + dev_attr_gt_RPn_freq_mhz.attr, dev_attr_vlv_rpe_freq_mhz.attr, NULL, }; -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 10/40] drm/i915: Call encoder-post_disable() in intel_sanitize_encoder()
-Original Message- From: Intel-gfx [mailto:intel-gfx-boun...@lists.freedesktop.org] On Behalf Of ville.syrj...@linux.intel.com Sent: Saturday, June 28, 2014 12:04 AM To: intel-gfx@lists.freedesktop.org Subject: [Intel-gfx] [PATCH 10/40] drm/i915: Call encoder-post_disable() in intel_sanitize_encoder() From: Ville Syrjälä ville.syrj...@linux.intel.com VLV and CHV disable the DP port only in the .post_disable() hook, so we need to make intel_sanitize_encoder() call that when it's trying to disable encoders without an active pipes. My bsw actaully hits this when an external display is connected. The BIOS still likes to turn on the eDP port, but leaves the pipe disabled. Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3e4d570..a16f635 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12772,6 +12772,8 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder) encoder-base.base.id, encoder-base.name); encoder-disable(encoder); + if (encoder-post_disable) + encoder-post_disable(encoder); } encoder-base.crtc = NULL; encoder-connectors_active = false; -- 1.8.5.5 I haven't done as much DP testing on my CHT but that makes sense. Reviewed-by: Rafael Barbalho rafael.barba...@intel.com ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 4/7] drm/i915: populate mem_freq/cz_clock for chv
deepa...@linux.intel.com writes: From: Deepak S deepa...@linux.intel.com We need mem_freq or cz clock for freq/opcode conversion Signed-off-by: Deepak S deepa...@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_reg.h | 6 ++ drivers/gpu/drm/i915/intel_pm.c | 29 + 3 files changed, 36 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bce4654..568b39c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -932,6 +932,7 @@ struct intel_gen6_power_mgmt { u8 efficient_freq; /* AKA RPe. Pre-determined balanced frequency */ u8 rp1_freq;/* less than RP0 power/freqency */ u8 rp0_freq;/* Non-overclocked max frequency. */ + u32 cz_freq; u32 ei_interrupt_count; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 490f031..e533efa 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -5541,6 +5541,12 @@ enum punit_power_well { GEN6_PM_RP_DOWN_THRESHOLD | \ GEN6_PM_RP_DOWN_TIMEOUT) +#define CHV_CZ_CLOCK_FREQ_MODE_200 200 +#define CHV_CZ_CLOCK_FREQ_MODE_267 267 +#define CHV_CZ_CLOCK_FREQ_MODE_320 320 +#define CHV_CZ_CLOCK_FREQ_MODE_333 333 +#define CHV_CZ_CLOCK_FREQ_MODE_400 400 + No need to define these in my opinion as it is 1:1. Just use the numbers straight. #define GEN7_GT_SCRATCH_BASE 0x4F100 #define GEN7_GT_SCRATCH_REG_NUM 8 diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 9dfebab..6c19ce5 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5706,6 +5706,35 @@ static void valleyview_init_clock_gating(struct drm_device *dev) static void cherryview_init_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev-dev_private; + u32 val; + + mutex_lock(dev_priv-rps.hw_lock); + val = vlv_punit_read(dev_priv, CCK_FUSE_REG); s/punit/cck (?) With the changes mentioned above: Reviewed-by: Mika Kuoppala mika.kuopp...@intel.com + mutex_unlock(dev_priv-rps.hw_lock); + switch ((val 2) 0x7) { + case 0: + case 1: + dev_priv-rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_200; + dev_priv-mem_freq = 1600; + break; + case 2: + dev_priv-rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_267; + dev_priv-mem_freq = 1600; + break; + case 3: + dev_priv-rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_333; + dev_priv-mem_freq = 2000; + break; + case 4: + dev_priv-rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_320; + dev_priv-mem_freq = 1600; + break; + case 5: + dev_priv-rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_400; + dev_priv-mem_freq = 1600; + break; + } + DRM_DEBUG_DRIVER(DDR speed: %d MHz, dev_priv-mem_freq); I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 6/7] drm/i915/chv: Add basic PM interrupt support for CHV
deepa...@linux.intel.com writes: From: Deepak S deepa...@linux.intel.com Enabled PM interrupt programming for CHV. Re-using gen8 code and extending same for CHV. Signed-off-by: Deepak S deepa...@linux.intel.com Reviewed-by: Mika Kuoppala mika.kuopp...@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 2 +- drivers/gpu/drm/i915/intel_pm.c | 4 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 38e6de1..ae6246c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1403,7 +1403,7 @@ static void gen6_pm_rps_work(struct work_struct *work) spin_lock_irq(dev_priv-irq_lock); pm_iir = dev_priv-rps.pm_iir; dev_priv-rps.pm_iir = 0; - if (IS_BROADWELL(dev_priv-dev)) + if (IS_BROADWELL(dev_priv-dev) || IS_CHERRYVIEW(dev_priv-dev)) bdw_enable_pm_irq(dev_priv, dev_priv-pm_rps_events); else { /* Make sure not to corrupt PMIMR state used by ringbuffer */ diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 6abd05b..7da3719 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3398,6 +3398,8 @@ static void cherryview_disable_rps(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; I915_WRITE(GEN6_RC_CONTROL, 0); + + gen8_disable_rps_interrupts(dev); } static void valleyview_disable_rps(struct drm_device *dev) @@ -4115,6 +4117,8 @@ static void cherryview_enable_rps(struct drm_device *dev) valleyview_set_rps(dev_priv-dev, dev_priv-rps.efficient_freq); + gen8_enable_rps_interrupts(dev); + gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); } -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v4 1/2] drm/i915: Set M2_N2 registers during mode set
On Fri, 11 Jul 2014 14:32:57 +0530 Vandana Kannan vandana.kan...@intel.com wrote: For Gen 8, set M2_N2 registers on every mode set. This is required to make sure M2_N2 registers are set during boot, resume from sleep for cross- checking the state. The register is set only if DRRS is supported. v2: Patch rebased v3: Daniel's review comments - Removed HAS_DRRS(dev) and added bool has_drrs to pipe_config to track drrs support v4: Jesse's review comments - Made changes to set m2_n2 in intel_dp_set_m_n() Signed-off-by: Vandana Kannan vandana.kan...@intel.com Cc: Daniel Vetter daniel.vet...@ffwll.ch Cc: Jesse Barnes jbar...@virtuousgeek.org --- drivers/gpu/drm/i915/intel_display.c | 28 +--- drivers/gpu/drm/i915/intel_dp.c | 18 +++--- drivers/gpu/drm/i915/intel_drv.h | 3 ++- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a72b55f..9f651a6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -91,11 +91,11 @@ static int intel_framebuffer_init(struct drm_device *dev, struct intel_framebuffer *ifb, struct drm_mode_fb_cmd2 *mode_cmd, struct drm_i915_gem_object *obj); -static void intel_dp_set_m_n(struct intel_crtc *crtc); static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc); static void intel_set_pipe_timings(struct intel_crtc *intel_crtc); static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, - struct intel_link_m_n *m_n); + struct intel_link_m_n *m_n, + struct intel_link_m_n *m2_n2); static void ironlake_set_pipeconf(struct drm_crtc *crtc); static void haswell_set_pipeconf(struct drm_crtc *crtc); static void intel_set_pipe_csc(struct drm_crtc *crtc); @@ -4027,7 +4027,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) if (intel_crtc-config.has_pch_encoder) { intel_cpu_transcoder_set_m_n(intel_crtc, - intel_crtc-config.fdi_m_n); + intel_crtc-config.fdi_m_n, NULL); } ironlake_set_pipeconf(crtc); @@ -4137,7 +4137,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) if (intel_crtc-config.has_pch_encoder) { intel_cpu_transcoder_set_m_n(intel_crtc, - intel_crtc-config.fdi_m_n); + intel_crtc-config.fdi_m_n, NULL); } haswell_set_pipeconf(crtc); @@ -5502,7 +5502,8 @@ static void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc, } static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, - struct intel_link_m_n *m_n) + struct intel_link_m_n *m_n, + struct intel_link_m_n *m2_n2) { struct drm_device *dev = crtc-base.dev; struct drm_i915_private *dev_priv = dev-dev_private; @@ -5514,6 +5515,18 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, I915_WRITE(PIPE_DATA_N1(transcoder), m_n-gmch_n); I915_WRITE(PIPE_LINK_M1(transcoder), m_n-link_m); I915_WRITE(PIPE_LINK_N1(transcoder), m_n-link_n); + /* M2_N2 registers to be set only for gen 8 (M2_N2 available + * for gen 8) and if DRRS is supported (to make sure the + * registers are not unnecessarily accessed). + */ + if (m2_n2 INTEL_INFO(dev)-gen 8 + crtc-config.has_drrs) { + I915_WRITE(PIPE_DATA_M2(transcoder), + TU_SIZE(m2_n2-tu) | m2_n2-gmch_m); + I915_WRITE(PIPE_DATA_N2(transcoder), m2_n2-gmch_n); + I915_WRITE(PIPE_LINK_M2(transcoder), m2_n2-link_m); + I915_WRITE(PIPE_LINK_N2(transcoder), m2_n2-link_n); + } } else { I915_WRITE(PIPE_DATA_M_G4X(pipe), TU_SIZE(m_n-tu) | m_n-gmch_m); I915_WRITE(PIPE_DATA_N_G4X(pipe), m_n-gmch_n); @@ -5522,12 +5535,13 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, } } -static void intel_dp_set_m_n(struct intel_crtc *crtc) +void intel_dp_set_m_n(struct intel_crtc *crtc) { if (crtc-config.has_pch_encoder) intel_pch_transcoder_set_m_n(crtc, crtc-config.dp_m_n); else - intel_cpu_transcoder_set_m_n(crtc, crtc-config.dp_m_n); + intel_cpu_transcoder_set_m_n(crtc, crtc-config.dp_m_n, +crtc-config.dp_m2_n2);
[Intel-gfx] [RFC 1/1] drm/i915: Power gating display wells during i915_pm_suspend
From: Borun Fu borun...@intel.com On VLV, after i915_pm_suspend display power wells are staying power ungated. So, after initiating mem sleep echo mem /sys/power/state Display is staing D0 State. There might be better way/place to power gate these wells. Also, we need to make sure that if wells are power gated due to DPMS OFF sequence, they need not be turned off by i915_pm_suspend again. Cc: Imre Deak imre.d...@intel.com Cc: Paulo Zanoni paulo.r.zan...@intel.com Cc: Daniel Vetter daniel.vet...@ffwll.ch Cc: Jani Nikula jani.nik...@linux.intel.com Change-Id: I34c80da66aa24c423a5576c68aa1f3a8d0f43848 Signed-off-by: Sagar Kamble sagar.a.kam...@intel.com --- drivers/gpu/drm/i915/i915_drv.c | 11 +++ drivers/gpu/drm/i915/i915_drv.h | 4 drivers/gpu/drm/i915/intel_display.c | 4 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 83cb43a..a83a48e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -491,6 +491,9 @@ static int i915_drm_freeze(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; struct drm_crtc *crtc; pci_power_t opregion_target_state; + struct intel_crtc *intel_crtc; + enum intel_display_power_domain domain; + unsigned long domains; /* ignore lid events during suspend */ mutex_lock(dev_priv-modeset_restore_lock); @@ -529,6 +532,14 @@ static int i915_drm_freeze(struct drm_device *dev) drm_modeset_lock_all(dev); for_each_crtc(dev, crtc) { dev_priv-display.crtc_disable(crtc); + + intel_crtc = to_intel_crtc(crtc); + if (!HAS_DDI(dev)) { + domains = intel_crtc-enabled_power_domains; + for_each_power_domain(domain, domains) + intel_display_power_put(dev_priv, domain); + intel_crtc-enabled_power_domains = 0; + } } drm_modeset_unlock_all(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 47c8ec1..1d75007 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -179,6 +179,10 @@ enum hpd_pin { list_for_each_entry((intel_connector), (dev)-mode_config.connector_list, base.head) \ if ((intel_connector)-base.encoder == (__encoder)) +#define for_each_power_domain(domain, mask)\ + for ((domain) = 0; (domain) POWER_DOMAIN_NUM; (domain)++) \ + if ((1 (domain)) (mask)) + struct drm_i915_private; struct i915_mmu_object; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 72abc0b..b29d417 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4300,10 +4300,6 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc) I915_WRITE(BCLRPAT(crtc-pipe), 0); } -#define for_each_power_domain(domain, mask)\ - for ((domain) = 0; (domain) POWER_DOMAIN_NUM; (domain)++) \ - if ((1 (domain)) (mask)) - enum intel_display_power_domain intel_display_port_power_domain(struct intel_encoder *intel_encoder) { -- 1.8.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] lib/igt.cocci: Add stanza for for_each_pipe
Damien dodged this ... Also run the script while at it. v2: Don't just capture identifiers for pipe, but also expressions. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- lib/igt.cocci | 10 ++ tests/kms_cursor_crc.c | 2 +- tests/kms_fbc_crc.c| 2 +- tests/kms_fence_pin_leak.c | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/igt.cocci b/lib/igt.cocci index 3246924f2c38..d399496b256f 100644 --- a/lib/igt.cocci +++ b/lib/igt.cocci @@ -74,3 +74,13 @@ expression list[n] Ep; @@ -abort(); +igt_fail(1); + +@@ +iterator name for_each_pipe; +igt_display_t *display; +expression pipe; +@@ +- for (pipe = 0; pipe igt_display_get_n_pipes(display); pipe++) { ++ for_each_pipe (display, pipe) { +... +} diff --git a/tests/kms_cursor_crc.c b/tests/kms_cursor_crc.c index 82807b7bf435..bbbf053d3207 100644 --- a/tests/kms_cursor_crc.c +++ b/tests/kms_cursor_crc.c @@ -303,7 +303,7 @@ static void run_test(data_t *data, void (*testfunc)(data_t *), int cursor_w, int for_each_connected_output(display, output) { data-output = output; - for (p = 0; p igt_display_get_n_pipes(display); p++) { + for_each_pipe(display, p) { data-pipe = p; if (!prepare_crtc(data, output, cursor_w, cursor_h)) diff --git a/tests/kms_fbc_crc.c b/tests/kms_fbc_crc.c index a99bf367c528..b0108b1c4aa3 100644 --- a/tests/kms_fbc_crc.c +++ b/tests/kms_fbc_crc.c @@ -454,7 +454,7 @@ static void run_test(data_t *data, enum test_mode mode) reset_display(data); for_each_connected_output(display, data-output) { - for (data-pipe = 0; data-pipe igt_display_get_n_pipes(display); data-pipe++) { + for_each_pipe(display, data-pipe) { if (!prepare_crtc(data)) continue; diff --git a/tests/kms_fence_pin_leak.c b/tests/kms_fence_pin_leak.c index ef2e6872eb8e..6a05d977217c 100644 --- a/tests/kms_fence_pin_leak.c +++ b/tests/kms_fence_pin_leak.c @@ -196,7 +196,7 @@ static void run_test(data_t *data) enum pipe p; for_each_connected_output(display, output) { - for (p = 0; p igt_display_get_n_pipes(display); p++) { + for_each_pipe(display, p) { if (run_single_test(data, p, output)) return; /* one time ought to be enough */ } -- 2.0.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 00/19] ddi: respin of runtime PM for DPMS
On Thu, Jul 10, 2014 at 10:15:11PM +0200, Daniel Vetter wrote: On Tue, Jul 01, 2014 at 06:33:50PM -0300, Paulo Zanoni wrote: 2014-06-25 16:01 GMT-03:00 Imre Deak imre.d...@intel.com: This is a respin of the unmerged part of Daniel's runtime PM for DPMS patchset [1]. The original one also included a refactoring of the DDI PCH/CRT encoder modesetting path, I left the corresponding patches out from this series. This is because there hasn't been yet an agreement on those parts, but people would like to see the RPM DPMS support already applied. Some patches needed to be updated/rebased because of the above omission, but these weren't anywhere significant so I just marked the fact with my s-o-b line. I also added two minor change to keep the modeset sequence at its current order and collected all the reviewed-by lines. Tested on HSW DP/VGA, with basic DPMS on/off and igt/pm_rpm. For patches 2, 4, 5, 6, 7, 19: Reviewed-by: Paulo Zanoni paulo.r.zan...@intel.com However, I tested these patches on a HSW Machine with eDP+HDMI, and there are WARNs on dmesg for the dpms-non-lpsp subtest. I found at least two problems: 1 - Function hsw_ddi_pll_get_hw_state() reads registers while the device is suspended. 2 - When _intel_set_mode() calls intel_crtc_disable(), it calls assert_plane() which reads register 0x71180, which triggers an Unclaimed register error. I didn't investigate this deeply, so I don't have a suggestion for a solution. I can reproduce these errors 100% of the time. Ok, I've pulled in the series (hopefully all of it with all the right fixup and in the right order), except for the last patch. I'll do that one once your unclaimed register write fixes are in to avoid regressions. Paulo clarified on irc that the remaining patches are just to make the unclaimed register debug support more useful on bdw. So I've gone ahead and pulled in patch 19, too. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v2 1/3] drm/i915: CHV GPU frequency to opcode functions
deepa...@linux.intel.com writes: From: Deepak S deepa...@linux.intel.com Adding chv specific fre/encode conversion. v2: Remove generic function and platform check (Daniel) Signed-off-by: Deepak S deepa...@linux.intel.com Reviewed-by: Mika Kuoppala mika.kuopp...@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 78 +++-- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 6892421..f673e1b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6931,7 +6931,7 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val) return 0; } -int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val) +int byt_gpu_freq(struct drm_i915_private *dev_priv, int val) { int div; @@ -6953,7 +6953,7 @@ int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val) return DIV_ROUND_CLOSEST(dev_priv-mem_freq * (val + 6 - 0xbd), 4 * div); } -int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val) +int byt_freq_opcode(struct drm_i915_private *dev_priv, int val) { int mul; @@ -6975,6 +6975,80 @@ int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val) return DIV_ROUND_CLOSEST(4 * mul * val, dev_priv-mem_freq) + 0xbd - 6; } +int chv_gpu_freq(struct drm_i915_private *dev_priv, int val) +{ + int div, freq; + + switch (dev_priv-rps.cz_freq) { + case 200: + div = 5; + break; + case 267: + div = 6; + break; + case 320: + case 333: + case 400: + div = 8; + break; + default: + return -1; + } + + freq = (DIV_ROUND_CLOSEST((dev_priv-rps.cz_freq * val), 2 * div) / 2); + + return freq; +} + +int chv_freq_opcode(struct drm_i915_private *dev_priv, int val) +{ + int mul, opcode; + + switch (dev_priv-rps.cz_freq) { + case 200: + mul = 5; + break; + case 267: + mul = 6; + break; + case 320: + case 333: + case 400: + mul = 8; + break; + default: + return -1; + } + + opcode = (DIV_ROUND_CLOSEST((val * 2 * mul), dev_priv-rps.cz_freq) * 2); + + return opcode; +} + +int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val) +{ + int ret = -1; + + if (IS_CHERRYVIEW(dev_priv-dev)) + ret = chv_gpu_freq(dev_priv, val); + else if (IS_VALLEYVIEW(dev_priv-dev)) + ret = byt_gpu_freq(dev_priv, val); + + return ret; +} + +int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val) +{ + int ret = -1; + + if (IS_CHERRYVIEW(dev_priv-dev)) + ret = chv_freq_opcode(dev_priv, val); + else if (IS_VALLEYVIEW(dev_priv-dev)) + ret = byt_freq_opcode(dev_priv, val); + + return ret; +} + void intel_pm_setup(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev-dev_private; -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 03/42] drm/i915/bdw: Initialization for Logical Ring Contexts
From: Oscar Mateo oscar.ma...@intel.com For the moment this is just a placeholder, but it shows one of the main differences between the good ol' HW contexts and the shiny new Logical Ring Contexts: LR contexts allocate and free their own backing objects. Another difference is that the allocation is deferred (as the create function name suggests), but that does not happen in this patch yet, because for the moment we are only dealing with the default context. Early in the series we had our own gen8_gem_context_init/fini functions, but the truth is they now look almost the same as the legacy hw context init/fini functions. We can always split them later if this ceases to be the case. Also, we do not fall back to legacy ringbuffers when logical ring context initialization fails (not very likely to happen and, even if it does, hw contexts would probably fail as well). v2: Daniel says explain, do not showcase. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_gem_context.c | 29 +++-- drivers/gpu/drm/i915/intel_lrc.c| 15 +++ drivers/gpu/drm/i915/intel_lrc.h| 5 + 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index de72a28..718150e 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -182,7 +182,10 @@ void i915_gem_context_free(struct kref *ctx_ref) typeof(*ctx), ref); struct i915_hw_ppgtt *ppgtt = NULL; - if (ctx-legacy_hw_ctx.rcs_state) { + if (i915.enable_execlists) { + ppgtt = ctx_to_ppgtt(ctx); + intel_lr_context_free(ctx); + } else if (ctx-legacy_hw_ctx.rcs_state) { /* We refcount even the aliasing PPGTT to keep the code symmetric */ if (USES_PPGTT(ctx-legacy_hw_ctx.rcs_state-base.dev)) ppgtt = ctx_to_ppgtt(ctx); @@ -419,7 +422,11 @@ int i915_gem_context_init(struct drm_device *dev) if (WARN_ON(dev_priv-ring[RCS].default_context)) return 0; - if (HAS_HW_CONTEXTS(dev)) { + if (i915.enable_execlists) { + /* NB: intentionally left blank. We will allocate our own +* backing objects as we need them, thank you very much */ + dev_priv-hw_context_size = 0; + } else if (HAS_HW_CONTEXTS(dev)) { dev_priv-hw_context_size = round_up(get_context_size(dev), 4096); if (dev_priv-hw_context_size (120)) { DRM_DEBUG_DRIVER(Disabling HW Contexts; invalid size %d\n, @@ -435,11 +442,20 @@ int i915_gem_context_init(struct drm_device *dev) return PTR_ERR(ctx); } - /* NB: RCS will hold a ref for all rings */ - for (i = 0; i I915_NUM_RINGS; i++) - dev_priv-ring[i].default_context = ctx; + for (i = 0; i I915_NUM_RINGS; i++) { + struct intel_engine_cs *ring = dev_priv-ring[i]; + + /* NB: RCS will hold a ref for all rings */ + ring-default_context = ctx; + + /* FIXME: we really only want to do this for initialized rings */ + if (i915.enable_execlists) + intel_lr_context_deferred_create(ctx, ring); + } - DRM_DEBUG_DRIVER(%s context support initialized\n, dev_priv-hw_context_size ? HW : fake); + DRM_DEBUG_DRIVER(%s context support initialized\n, + i915.enable_execlists ? LR : + dev_priv-hw_context_size ? HW : fake); return 0; } @@ -781,6 +797,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, struct intel_context *ctx; int ret; + /* FIXME: allow user-created LR contexts as well */ if (!hw_context_enabled(dev)) return -ENODEV; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 21f7f1c..8cc6b55 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -51,3 +51,18 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists return 0; } + +void intel_lr_context_free(struct intel_context *ctx) +{ + /* TODO */ +} + +int intel_lr_context_deferred_create(struct intel_context *ctx, +struct intel_engine_cs *ring) +{ + BUG_ON(ctx-legacy_hw_ctx.rcs_state != NULL); + + /* TODO */ + + return 0; +} diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 75ee9c3..3b93572 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -24,6 +24,11 @@ #ifndef _INTEL_LRC_H_ #define _INTEL_LRC_H_ +/* Logical Ring Contexts */ +void intel_lr_context_free(struct intel_context *ctx); +int
[Intel-gfx] [PATCH 01/42] drm/i915/bdw: New source and header file for LRs, LRCs and Execlists
From: Oscar Mateo oscar.ma...@intel.com Some legacy HW context code assumptions don't make sense for this new submission method, so we will place this stuff in a separate file. Note for reviewers: I've carefully considered the best name for this file and this was my best option (other possibilities were intel_lr_context.c or intel_execlist.c). I am open to a certain bikeshedding on this matter, anyway. And some point in time, it would be a good idea to split intel_lrc.c/.h even further, but for the moment just shove everything together. v2: Change to intel_lrc.c v3: Squash together with the header file addition Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/Makefile| 1 + drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_lrc.c | 42 drivers/gpu/drm/i915/intel_lrc.h | 27 ++ 4 files changed, 71 insertions(+) create mode 100644 drivers/gpu/drm/i915/intel_lrc.c create mode 100644 drivers/gpu/drm/i915/intel_lrc.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index cad1683..9fee2a0 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -31,6 +31,7 @@ i915-y += i915_cmd_parser.o \ i915_gpu_error.o \ i915_irq.o \ i915_trace_points.o \ + intel_lrc.o \ intel_ringbuffer.o \ intel_uncore.o diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 47c8ec1..0a7752f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -35,6 +35,7 @@ #include i915_reg.h #include intel_bios.h #include intel_ringbuffer.h +#include intel_lrc.h #include i915_gem_gtt.h #include linux/io-mapping.h #include linux/i2c.h diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c new file mode 100644 index 000..49bb6fc --- /dev/null +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -0,0 +1,42 @@ +/* + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the Software), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + *Ben Widawsky b...@bwidawsk.net + *Michel Thierry michel.thie...@intel.com + *Thomas Daniel thomas.dan...@intel.com + *Oscar Mateo oscar.ma...@intel.com + * + */ + +/* + * GEN8 brings an expansion of the HW contexts: Logical Ring Contexts. + * These expanded contexts enable a number of new abilities, especially + * Execlists (also implemented in this file). + * + * Execlists are the new method by which, on gen8+ hardware, workloads are + * submitted for execution (as opposed to the legacy, ringbuffer-based, method). + */ + +#include drm/drmP.h +#include drm/i915_drm.h +#include i915_drv.h diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h new file mode 100644 index 000..f6830a4 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -0,0 +1,27 @@ +/* + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the Software), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + *
[Intel-gfx] [PATCH 00/42] Execlists v4
From: Oscar Mateo oscar.ma...@intel.com For a description of this patchset, please check the previous cover letters: [1], [2] and [3]. The main changes introduced in this v4 are: - Do not abstract __i915_add_request away. - Squash together the two emit request functions. - Always pass the ringbuffer along, as the struct that hold together all required information. - Integrate help into DocBook. - Early sanitize for i915.execlists (and remove lrc_enabled). - Always defer the context creation: do not special case the context create ioctl. - Do not special case the reset_ring_cleanup, do INIT_LIST_HEAD. - Add TODO to error capture code. - use_mmio_flip at driver discretion means always with Execlists. - Lock before displaying execlists info in debugfs. - Ehen populating the context, use _MASKED_BIT_ENABLE, upper/lower_32_bits, etc... - Add comment about CHV when populating the context. - Replace submit_ctx vfunc with a plain function call. - Do not change the behaviour of pipe control fini. - The BSD invalidate bit still exists in GEN8. - Squash intel_runtime_pm_get fix. - Pin rinbuffer and context backing objects only on-demand. - Reorder and rewrite to explain patches instead of showcasing them. - Reorder and rewrite to split chapters as cleanly as possible. The patches in this series can be split into chapters. They are: - Logical Ring Contexts: patches 1 to 11 - Logical Rings: patches 12 to 26 - Execlists: patches 27 to 35 - Debug, documentation and enabling: patches 36 to 40 - Last minute patches that still require more attention: patches 41 and 42 Unfortunately, in a last-minute run of the IGT testsuite, I have noticed problems in gem_evict_everything. It's still not clear I can continue working on this project come next Monday, so I have decided to send the series to the mailing list as-is, even though this potential eviction problem still needs to be chased. The last two patches (regarding on-demand pining of backing objects) also require a deep review and probably some more work, but I was running out of time. One other caveat I have noticed is that many WAs in gen8_init_clock_gating (those that affect registers that now exist per-context) can get lost in the render default context. The reason is, in Execlists, a context is saved as soon as head = tail (with MI_SET_CONTEXT, however, the context wouldn't be saved until you tried to restore a different context). As we are sending the golden state batchbuffer to the render ring as soon as the rings are initialized, we are effectively saving the default context before gen8_init_clock_gating has an opportunity to set the WAs. I haven't noticed any ill-effect from this (yet) but it would be a good idea to move the WAs somewhere else (ring init looks like a good place). I believe there is already work in progress to create a new WA architecture, so this can be tackled there. The previous IGT test [4] still applies. [1] http://lists.freedesktop.org/archives/intel-gfx/2014-March/042563.html [2] http://lists.freedesktop.org/archives/intel-gfx/2014-May/044847.html [3] http://lists.freedesktop.org/archives/intel-gfx/2014-June/047138.html [4] http://lists.freedesktop.org/archives/intel-gfx/2014-May/044846.html Ben Widawsky (2): drm/i915/bdw: Implement context switching (somewhat) drm/i915/bdw: Print context state in debugfs Michel Thierry (1): drm/i915/bdw: Two-stage execlist submit process Oscar Mateo (38): drm/i915/bdw: New source and header file for LRs, LRCs and Execlists drm/i915/bdw: Macro for LRCs and module option for Execlists drm/i915/bdw: Initialization for Logical Ring Contexts drm/i915/bdw: Introduce one context backing object per engine drm/i915/bdw: A bit more advanced LR context alloc/free drm/i915/bdw: Allocate ringbuffers for Logical Ring Contexts drm/i915/bdw: Add a context and an engine pointers to the ringbuffer drm/i915/bdw: Populate LR contexts (somewhat) drm/i915/bdw: Deferred creation of user-created LRCs drm/i915/bdw: Render moot context reset and switch with Execlists drm/i915/bdw: Don't write PDP in the legacy way when using LRCs drm/i915: Abstract the legacy workload submission mechanism away drm/i915/bdw: Skeleton for the new logical rings submission path drm/i915/bdw: Generic logical ring init and cleanup drm/i915/bdw: GEN-specific logical ring init drm/i915/bdw: GEN-specific logical ring set/get seqno drm/i915/bdw: New logical ring submission mechanism drm/i915/bdw: GEN-specific logical ring emit request drm/i915/bdw: GEN-specific logical ring emit flush drm/i915/bdw: Emission of requests with logical rings drm/i915/bdw: Ring idle and stop with logical rings drm/i915/bdw: Interrupts with logical rings drm/i915/bdw: GEN-specific logical ring emit batchbuffer start drm/i915/bdw: Workload submission mechanism for Execlists drm/i915/bdw: Always use MMIO flips with Execlists drm/i915/bdw: Render state init for Execlists drm/i915/bdw: Write the
[Intel-gfx] [PATCH 02/42] drm/i915/bdw: Macro for LRCs and module option for Execlists
From: Oscar Mateo oscar.ma...@intel.com GEN8 brings an expansion of the HW contexts: Logical Ring Contexts. These expanded contexts enable a number of new abilities, especially Execlists. The macro is defined to off until we have things in place to hope to work. v2: Rename advanced contexts to the more correct logical ring contexts. v3: Add a module parameter to enable execlists. Execlist are relatively new, and so it'd be wise to be able to switch back to ring submission to debug subtle problems that will inevitably arise. v4: Add an intel_enable_execlists function. v5: Sanitize early, as suggested by Daniel. Remove lrc_enabled. Signed-off-by: Ben Widawsky b...@bwidawsk.net (v1) Signed-off-by: Damien Lespiau damien.lesp...@intel.com (v3) Signed-off-by: Oscar Mateo oscar.ma...@intel.com (v2, v4 v5) --- drivers/gpu/drm/i915/i915_drv.h| 2 ++ drivers/gpu/drm/i915/i915_gem.c| 3 +++ drivers/gpu/drm/i915/i915_params.c | 6 ++ drivers/gpu/drm/i915/intel_lrc.c | 11 +++ drivers/gpu/drm/i915/intel_lrc.h | 3 +++ 5 files changed, 25 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0a7752f..bb7ddd1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2030,6 +2030,7 @@ struct drm_i915_cmd_table { #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)-need_gfx_hws) #define HAS_HW_CONTEXTS(dev) (INTEL_INFO(dev)-gen = 6) +#define HAS_LOGICAL_RING_CONTEXTS(dev) 0 #define HAS_ALIASING_PPGTT(dev)(INTEL_INFO(dev)-gen = 6) #define HAS_PPGTT(dev) (INTEL_INFO(dev)-gen = 7 !IS_GEN8(dev)) #define USES_PPGTT(dev)intel_enable_ppgtt(dev, false) @@ -2115,6 +2116,7 @@ struct i915_params { int enable_rc6; int enable_fbc; int enable_ppgtt; + int enable_execlists; int enable_psr; unsigned int preliminary_hw_support; int disable_power_well; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e5d4d73..d8bf4fa 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4746,6 +4746,9 @@ int i915_gem_init(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; int ret; + i915.enable_execlists = intel_sanitize_enable_execlists(dev, + i915.enable_execlists); + mutex_lock(dev-struct_mutex); if (IS_VALLEYVIEW(dev)) { diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 8145729..46d7a06 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -37,6 +37,7 @@ struct i915_params i915 __read_mostly = { .enable_fbc = -1, .enable_hangcheck = true, .enable_ppgtt = -1, + .enable_execlists = -1, .enable_psr = 0, .preliminary_hw_support = IS_ENABLED(CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT), .disable_power_well = 1, @@ -117,6 +118,11 @@ MODULE_PARM_DESC(enable_ppgtt, Override PPGTT usage. (-1=auto [default], 0=disabled, 1=aliasing, 2=full)); +module_param_named(enable_execlists, i915.enable_execlists, int, 0400); +MODULE_PARM_DESC(enable_execlists, + Override execlists usage. + (-1=auto [default], 0=disabled, 1=enabled)); + module_param_named(enable_psr, i915.enable_psr, int, 0600); MODULE_PARM_DESC(enable_psr, Enable PSR (default: false)); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 49bb6fc..21f7f1c 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -40,3 +40,14 @@ #include drm/drmP.h #include drm/i915_drm.h #include i915_drv.h + +int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists) +{ + if (enable_execlists == 0) + return 0; + + if (HAS_LOGICAL_RING_CONTEXTS(dev) USES_PPGTT(dev)) + return 1; + + return 0; +} diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index f6830a4..75ee9c3 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -24,4 +24,7 @@ #ifndef _INTEL_LRC_H_ #define _INTEL_LRC_H_ +/* Execlists */ +int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists); + #endif /* _INTEL_LRC_H_ */ -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 32/42] drm/i915/bdw: Help out the ctx switch interrupt handler
From: Oscar Mateo oscar.ma...@intel.com If we receive a storm of requests for the same context (see gem_storedw_loop_*) we might end up iterating over too many elements in interrupt time, looking for contexts to squash together. Instead, share the burden by giving more intelligence to the queue function. At most, the interrupt will iterate over three elements. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 26 ++ 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index d3e961e..6beab26 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -384,9 +384,10 @@ static int execlists_context_queue(struct intel_engine_cs *ring, struct intel_context *to, u32 tail) { - struct intel_ctx_submit_request *req = NULL; + struct drm_i915_private *dev_priv = ring-dev-dev_private; + struct intel_ctx_submit_request *req = NULL, *cursor; unsigned long flags; - bool was_empty; + int num_elements = 0; req = kzalloc(sizeof(*req), GFP_KERNEL); if (req == NULL) @@ -400,9 +401,26 @@ static int execlists_context_queue(struct intel_engine_cs *ring, spin_lock_irqsave(ring-execlist_lock, flags); - was_empty = list_empty(ring-execlist_queue); + list_for_each_entry(cursor, ring-execlist_queue, execlist_link) + if (++num_elements 2) + break; + + if (num_elements 2) { + struct intel_ctx_submit_request *tail_req; + + tail_req = list_last_entry(ring-execlist_queue, + struct intel_ctx_submit_request, + execlist_link); + if (to == tail_req-ctx) { + WARN(tail_req-elsp_submitted != 0, + More than 2 already-submitted reqs queued\n); + list_del(tail_req-execlist_link); + queue_work(dev_priv-wq, tail_req-work); + } + } + list_add_tail(req-execlist_link, ring-execlist_queue); - if (was_empty) + if (num_elements == 0) execlists_context_unqueue(ring); spin_unlock_irqrestore(ring-execlist_lock, flags); -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 20/42] drm/i915/bdw: Emission of requests with logical rings
From: Oscar Mateo oscar.ma...@intel.com On a previous iteration of this patch, I created an Execlists version of __i915_add_request and asbtracted it away as a vfunc. Daniel Vetter wondered then why that was needed: with the clean split in command submission I expect every function to know wether it'll submit to an lrc (everything in intel_lrc.c) or wether it'll submit to a legacy ring (existing code), so I don't see a need for an add_request vfunc. The honest, hairy truth is that this patch is the glue keeping the whole logical ring puzzle together: - i915_add_request is used by intel_ring_idle, which in turn is used by i915_gpu_idle, which in turn is used in several places inside the eviction and gtt codes. - Also, it is used by i915_gem_check_olr, which is littered all over i915_gem.c - ... If I were to duplicate all the code that directly or indirectly uses __i915_add_request, I'll end up creating a separate driver. To show the differences between the existing legacy version and the new Execlists one, this time I have special-cased __i915_add_request instead of adding an add_request vfunc. I hope this helps to untangle this Gordian knot. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_gem.c | 72 +--- drivers/gpu/drm/i915/intel_lrc.c | 30 ++--- drivers/gpu/drm/i915/intel_lrc.h | 1 + 3 files changed, 80 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 9560b40..1c83b9c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2327,10 +2327,21 @@ int __i915_add_request(struct intel_engine_cs *ring, { struct drm_i915_private *dev_priv = ring-dev-dev_private; struct drm_i915_gem_request *request; + struct intel_ringbuffer *ringbuf; u32 request_ring_position, request_start; int ret; - request_start = intel_ring_get_tail(ring-buffer); + request = ring-preallocated_lazy_request; + if (WARN_ON(request == NULL)) + return -ENOMEM; + + if (i915.enable_execlists) { + struct intel_context *ctx = request-ctx; + ringbuf = ctx-engine[ring-id].ringbuf; + } else + ringbuf = ring-buffer; + + request_start = intel_ring_get_tail(ringbuf); /* * Emit any outstanding flushes - execbuf can fail to emit the flush * after having emitted the batchbuffer command. Hence we need to fix @@ -2338,24 +2349,32 @@ int __i915_add_request(struct intel_engine_cs *ring, * is that the flush _must_ happen before the next request, no matter * what. */ - ret = intel_ring_flush_all_caches(ring); - if (ret) - return ret; - - request = ring-preallocated_lazy_request; - if (WARN_ON(request == NULL)) - return -ENOMEM; + if (i915.enable_execlists) { + ret = logical_ring_flush_all_caches(ringbuf); + if (ret) + return ret; + } else { + ret = intel_ring_flush_all_caches(ring); + if (ret) + return ret; + } /* Record the position of the start of the request so that * should we detect the updated seqno part-way through the * GPU processing the request, we never over-estimate the * position of the head. */ - request_ring_position = intel_ring_get_tail(ring-buffer); + request_ring_position = intel_ring_get_tail(ringbuf); - ret = ring-add_request(ring); - if (ret) - return ret; + if (i915.enable_execlists) { + ret = ring-emit_request(ringbuf); + if (ret) + return ret; + } else { + ret = ring-add_request(ring); + if (ret) + return ret; + } request-seqno = intel_ring_get_seqno(ring); request-ring = ring; @@ -2370,12 +2389,14 @@ int __i915_add_request(struct intel_engine_cs *ring, */ request-batch_obj = obj; - /* Hold a reference to the current context so that we can inspect -* it later in case a hangcheck error event fires. -*/ - request-ctx = ring-last_context; - if (request-ctx) - i915_gem_context_reference(request-ctx); + if (!i915.enable_execlists) { + /* Hold a reference to the current context so that we can inspect +* it later in case a hangcheck error event fires. +*/ + request-ctx = ring-last_context; + if (request-ctx) + i915_gem_context_reference(request-ctx); + } request-emitted_jiffies = jiffies; list_add_tail(request-list, ring-request_list); @@ -2630,6 +2651,7 @@ i915_gem_retire_requests_ring(struct
[Intel-gfx] [PATCH 27/42] drm/i915/bdw: Implement context switching (somewhat)
From: Ben Widawsky benjamin.widaw...@intel.com A context switch occurs by submitting a context descriptor to the ExecList Submission Port. Given that we can now initialize a context, it's possible to begin implementing the context switch by creating the descriptor and submitting it to ELSP (actually two, since the ELSP has two ports). The context object must be mapped in the GGTT, which means it must exist in the 0-4GB graphics VA range. Signed-off-by: Ben Widawsky b...@bwidawsk.net v2: This code has changed quite a lot in various rebases. Of particular importance is that now we use the globally unique Submission ID to send to the hardware. Also, context pages are now pinned unconditionally to GGTT, so there is no need to bind them. v3: Use LRCA[31:12] as hwCtxId[19:0]. This guarantees that the HW context ID we submit to the ELSP is globally unique and != 0 (Bspec requirements of the software use-only bits of the Context ID in the Context Descriptor Format) without the hassle of the previous submission Id construction. Also, re-add the ELSP porting read (it was dropped somewhere during the rebases). v4: - Squash with drm/i915/bdw: Add forcewake lock around ELSP writes (BSPEC says: SW must set Force Wakeup bit to prevent GT from entering C6 while ELSP writes are in progress) as noted by Thomas Daniel (thomas.dan...@intel.com). - Rename functions and use an execlists/intel_execlists_ namespace. - The BUG_ON only checked that the LRCA was 32 bits, but it didn't make sure that it was properly aligned. Spotted by Alistair Mcaulay alistair.mcau...@intel.com. v5: - Improved source code comments as suggested by Chris Wilson. - No need to abstract submit_ctx away, as pointed by Brad Volkin. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 116 ++- drivers/gpu/drm/i915/intel_lrc.h | 1 + 2 files changed, 115 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 27466df..db5f27b 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -47,6 +47,7 @@ #define GEN8_LR_CONTEXT_ALIGN 4096 #define RING_ELSP(ring)((ring)-mmio_base+0x230) +#define RING_EXECLIST_STATUS(ring) ((ring)-mmio_base+0x234) #define RING_CONTEXT_CONTROL(ring) ((ring)-mmio_base+0x244) #define CTX_LRI_HEADER_0 0x01 @@ -78,6 +79,26 @@ #define CTX_R_PWR_CLK_STATE0x42 #define CTX_GPGPU_CSR_BASE_ADDRESS 0x44 +#define GEN8_CTX_VALID (10) +#define GEN8_CTX_FORCE_PD_RESTORE (11) +#define GEN8_CTX_FORCE_RESTORE (12) +#define GEN8_CTX_L3LLC_COHERENT (15) +#define GEN8_CTX_PRIVILEGE (18) +enum { + ADVANCED_CONTEXT=0, + LEGACY_CONTEXT, + ADVANCED_AD_CONTEXT, + LEGACY_64B_CONTEXT +}; +#define GEN8_CTX_MODE_SHIFT 3 +enum { + FAULT_AND_HANG=0, + FAULT_AND_HALT, /* Debug only */ + FAULT_AND_STREAM, + FAULT_AND_CONTINUE /* Unsupported */ +}; +#define GEN8_CTX_ID_SHIFT 32 + int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists) { if (enable_execlists == 0) @@ -90,6 +111,93 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists return 0; } +u32 intel_execlists_ctx_id(struct drm_i915_gem_object *ctx_obj) +{ + u32 lrca = i915_gem_obj_ggtt_offset(ctx_obj); + + /* LRCA is required to be 4K aligned so the more significant 20 bits +* are globally unique */ + return lrca 12; +} + +static uint64_t execlists_ctx_descriptor(struct drm_i915_gem_object *ctx_obj) +{ + uint64_t desc; + uint64_t lrca = i915_gem_obj_ggtt_offset(ctx_obj); + BUG_ON(lrca 0x0FFFULL); + + desc = GEN8_CTX_VALID; + desc |= LEGACY_CONTEXT GEN8_CTX_MODE_SHIFT; + desc |= GEN8_CTX_L3LLC_COHERENT; + desc |= GEN8_CTX_PRIVILEGE; + desc |= lrca; + desc |= (u64)intel_execlists_ctx_id(ctx_obj) GEN8_CTX_ID_SHIFT; + + /* TODO: WaDisableLiteRestore when we start using semaphore +* signalling between Command Streamers */ + /* desc |= GEN8_CTX_FORCE_RESTORE; */ + + return desc; +} + +static void execlists_elsp_write(struct intel_engine_cs *ring, +struct drm_i915_gem_object *ctx_obj0, +struct drm_i915_gem_object *ctx_obj1) +{ + struct drm_i915_private *dev_priv = ring-dev-dev_private; + uint64_t temp = 0; + uint32_t desc[4]; + + /* XXX: You must always write both descriptors in the order below. */ + if (ctx_obj1) + temp = execlists_ctx_descriptor(ctx_obj1); + else + temp = 0; + desc[1] = (u32)(temp 32); + desc[0] = (u32)temp; + + temp = execlists_ctx_descriptor(ctx_obj0); + desc[3] = (u32)(temp 32); + desc[2] = (u32)temp; + + /* Set Force Wakeup bit to
[Intel-gfx] [PATCH 35/42] drm/i915/bdw: Disable semaphores for Execlists
From: Oscar Mateo oscar.ma...@intel.com Up until recently, semaphores weren't enabled in BDW so we didn't care about them. But then Rodrigo came and enabled them: commit 521e62e49a42661a4ee0102644517dbe2f100a23 Author: Rodrigo Vivi rodrigo.v...@intel.com drm/i915: Enable semaphores on BDW So now we have to explicitly disable them for Execlists until both features play nicely. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_drv.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 83cb43a..ce345df 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -477,6 +477,10 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) if (i915.semaphores = 0) return i915.semaphores; + /* TODO: make semaphores and Execlists play nicely together */ + if (i915.enable_execlists) + return false; + #ifdef CONFIG_INTEL_IOMMU /* Enable semaphores on SNB when IO remapping is off */ if (INTEL_INFO(dev)-gen == 6 intel_iommu_gfx_mapped) -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 38/42] drm/i915/bdw: Print context state in debugfs
From: Ben Widawsky b...@bwidawsk.net This has turned out to be really handy in debug so far. Update: Since writing this patch, I've gotten similar code upstream for error state. I've used it quite a bit in debugfs however, and I'd like to keep it here at least until preemption is working. Signed-off-by: Ben Widawsky b...@bwidawsk.net This patch was accidentally dropped in the first Execlists version, and it has been very useful indeed. Put it back again, but as a standalone debugfs file. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 52 + 1 file changed, 52 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4c62900..34ddabc 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1694,6 +1694,57 @@ static int i915_context_status(struct seq_file *m, void *unused) return 0; } +static int i915_dump_lrc(struct seq_file *m, void *unused) +{ + struct drm_info_node *node = (struct drm_info_node *) m-private; + struct drm_device *dev = node-minor-dev; + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_engine_cs *ring; + struct intel_context *ctx; + int ret, i; + + if (!i915.enable_execlists) { + seq_printf(m, Logical Ring Contexts are disabled\n); + return 0; + } + + ret = mutex_lock_interruptible(dev-mode_config.mutex); + if (ret) + return ret; + + list_for_each_entry(ctx, dev_priv-context_list, link) { + for_each_ring(ring, dev_priv, i) { + struct drm_i915_gem_object *ctx_obj = ctx-engine[i].state; + + if (ring-default_context == ctx) + continue; + + if (ctx_obj) { + struct page *page = i915_gem_object_get_page(ctx_obj, 1); + uint32_t *reg_state = kmap_atomic(page); + int j; + + seq_printf(m, CONTEXT: %s %u\n, ring-name, + intel_execlists_ctx_id(ctx_obj)); + + for (j = 0; j 0x600 / sizeof(u32) / 4; j += 4) { + seq_printf(m, \t[0x%08lx] 0x%08x 0x%08x 0x%08x 0x%08x\n, + i915_gem_obj_ggtt_offset(ctx_obj) + 4096 + (j * 4), + reg_state[j], reg_state[j + 1], + reg_state[j + 2], reg_state[j + 3]); + } + kunmap_atomic(reg_state); + + seq_putc(m, '\n'); + } + } + } + + mutex_unlock(dev-mode_config.mutex); + + return 0; +} + static int i915_execlists(struct seq_file *m, void *data) { struct drm_info_node *node = (struct drm_info_node *) m-private; @@ -3985,6 +4036,7 @@ static const struct drm_info_list i915_debugfs_list[] = { {i915_opregion, i915_opregion, 0}, {i915_gem_framebuffer, i915_gem_framebuffer_info, 0}, {i915_context_status, i915_context_status, 0}, + {i915_dump_lrc, i915_dump_lrc, 0}, {i915_execlists, i915_execlists, 0}, {i915_gen6_forcewake_count, i915_gen6_forcewake_count_info, 0}, {i915_swizzle_info, i915_swizzle_info, 0}, -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 14/42] drm/i915/bdw: Generic logical ring init and cleanup
From: Oscar Mateo oscar.ma...@intel.com Allocate and populate the default LRC for every ring, call gen-specific init/cleanup, init/fini the command parser and set the status page (now inside the LRC object). These are things all engines/rings have in common. Stopping the ring before cleanup and initializing the seqnos is left as a TODO task (we need more infrastructure in place before we can achieve this). v2: Check the ringbuffer backing obj for ring_is_initialized, instead of the context backing obj (similar, but not exactly the same). Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_gem_context.c | 4 --- drivers/gpu/drm/i915/intel_lrc.c| 54 +++-- drivers/gpu/drm/i915/intel_ringbuffer.c | 17 +++ drivers/gpu/drm/i915/intel_ringbuffer.h | 6 +--- 4 files changed, 70 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 288f5de..9085ff1 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -450,10 +450,6 @@ int i915_gem_context_init(struct drm_device *dev) /* NB: RCS will hold a ref for all rings */ ring-default_context = ctx; - - /* FIXME: we really only want to do this for initialized rings */ - if (i915.enable_execlists) - intel_lr_context_deferred_create(ctx, ring); } DRM_DEBUG_DRIVER(%s context support initialized\n, diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index cb56bb8..05b7069 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -108,12 +108,60 @@ void intel_logical_ring_stop(struct intel_engine_cs *ring) void intel_logical_ring_cleanup(struct intel_engine_cs *ring) { - /* TODO */ + if (!intel_ring_initialized(ring)) + return; + + /* TODO: make sure the ring is stopped */ + ring-preallocated_lazy_request = NULL; + ring-outstanding_lazy_seqno = 0; + + if (ring-cleanup) + ring-cleanup(ring); + + i915_cmd_parser_fini_ring(ring); + + if (ring-status_page.obj) { + kunmap(sg_page(ring-status_page.obj-pages-sgl)); + ring-status_page.obj = NULL; + } } static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *ring) { - /* TODO */ + int ret; + struct intel_context *dctx = ring-default_context; + struct drm_i915_gem_object *dctx_obj; + + /* Intentionally left blank. */ + ring-buffer = NULL; + + ring-dev = dev; + INIT_LIST_HEAD(ring-active_list); + INIT_LIST_HEAD(ring-request_list); + init_waitqueue_head(ring-irq_queue); + + ret = intel_lr_context_deferred_create(dctx, ring); + if (ret) + return ret; + + /* The status page is offset 0 from the context object in LRCs. */ + dctx_obj = dctx-engine[ring-id].state; + ring-status_page.gfx_addr = i915_gem_obj_ggtt_offset(dctx_obj); + ring-status_page.page_addr = kmap(sg_page(dctx_obj-pages-sgl)); + if (ring-status_page.page_addr == NULL) + return -ENOMEM; + ring-status_page.obj = dctx_obj; + + ret = i915_cmd_parser_init_ring(ring); + if (ret) + return ret; + + if (ring-init) { + ret = ring-init(ring); + if (ret) + return ret; + } + return 0; } @@ -397,6 +445,8 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, int ret; BUG_ON(ctx-legacy_hw_ctx.rcs_state != NULL); + if (ctx-engine[ring-id].state) + return 0; context_size = round_up(get_lr_context_size(ring), 4096); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 279dda4..20eb1a4 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -40,6 +40,23 @@ */ #define CACHELINE_BYTES 64 +bool +intel_ring_initialized(struct intel_engine_cs *ring) +{ + struct drm_device *dev = ring-dev; + + if (!dev) + return false; + + if (i915.enable_execlists) { + struct intel_context *dctx = ring-default_context; + struct intel_ringbuffer *ringbuf = dctx-engine[ring-id].ringbuf; + + return ringbuf-obj; + } else + return ring-buffer ring-buffer-obj; +} + static inline int __ring_space(int head, int tail, int size) { int space = head - (tail + I915_RING_FREE_SPACE); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index be40788..7203ee2 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -288,11 +288,7 @@ struct
[Intel-gfx] [PATCH 16/42] drm/i915/bdw: GEN-specific logical ring set/get seqno
From: Oscar Mateo oscar.ma...@intel.com No mistery here: the seqno is still retrieved from the engine's HW status page (the one in the default context. For the moment, I see no reason to worry about other context's HWS page). Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 7c8b75e..f171fd5 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -149,6 +149,16 @@ static int gen8_init_render_ring(struct intel_engine_cs *ring) return ret; } +static u32 gen8_get_seqno(struct intel_engine_cs *ring, bool lazy_coherency) +{ + return intel_read_status_page(ring, I915_GEM_HWS_INDEX); +} + +static void gen8_set_seqno(struct intel_engine_cs *ring, u32 seqno) +{ + intel_write_status_page(ring, I915_GEM_HWS_INDEX, seqno); +} + void intel_logical_ring_cleanup(struct intel_engine_cs *ring) { if (!intel_ring_initialized(ring)) @@ -221,6 +231,8 @@ static int logical_render_ring_init(struct drm_device *dev) ring-init = gen8_init_render_ring; ring-cleanup = intel_fini_pipe_control; + ring-get_seqno = gen8_get_seqno; + ring-set_seqno = gen8_set_seqno; return logical_ring_init(dev, ring); } @@ -237,6 +249,8 @@ static int logical_bsd_ring_init(struct drm_device *dev) GT_RENDER_USER_INTERRUPT GEN8_VCS1_IRQ_SHIFT; ring-init = gen8_init_common_ring; + ring-get_seqno = gen8_get_seqno; + ring-set_seqno = gen8_set_seqno; return logical_ring_init(dev, ring); } @@ -253,6 +267,8 @@ static int logical_bsd2_ring_init(struct drm_device *dev) GT_RENDER_USER_INTERRUPT GEN8_VCS2_IRQ_SHIFT; ring-init = gen8_init_common_ring; + ring-get_seqno = gen8_get_seqno; + ring-set_seqno = gen8_set_seqno; return logical_ring_init(dev, ring); } @@ -269,6 +285,8 @@ static int logical_blt_ring_init(struct drm_device *dev) GT_RENDER_USER_INTERRUPT GEN8_BCS_IRQ_SHIFT; ring-init = gen8_init_common_ring; + ring-get_seqno = gen8_get_seqno; + ring-set_seqno = gen8_set_seqno; return logical_ring_init(dev, ring); } @@ -285,6 +303,8 @@ static int logical_vebox_ring_init(struct drm_device *dev) GT_RENDER_USER_INTERRUPT GEN8_VECS_IRQ_SHIFT; ring-init = gen8_init_common_ring; + ring-get_seqno = gen8_get_seqno; + ring-set_seqno = gen8_set_seqno; return logical_ring_init(dev, ring); } -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 10/42] drm/i915/bdw: Render moot context reset and switch with Execlists
From: Oscar Mateo oscar.ma...@intel.com These two functions make no sense in an Logical Ring Context Execlists world. v2: We got rid of lrc_enabled and centralized everything in the sanitized i915.enbale_execlists instead. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_gem_context.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index fbe7278..288f5de 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -380,6 +380,9 @@ void i915_gem_context_reset(struct drm_device *dev) struct drm_i915_private *dev_priv = dev-dev_private; int i; + if (i915.enable_execlists) + return; + /* Prevent the hardware from restoring the last context (which hung) on * the next switch */ for (i = 0; i I915_NUM_RINGS; i++) { @@ -514,6 +517,9 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv) ppgtt-enable(ppgtt); } + if (i915.enable_execlists) + return 0; + /* FIXME: We should make this work, even in reset */ if (i915_reset_in_progress(dev_priv-gpu_error)) return 0; @@ -769,6 +775,9 @@ int i915_switch_context(struct intel_engine_cs *ring, { struct drm_i915_private *dev_priv = ring-dev-dev_private; + if (i915.enable_execlists) + return 0; + WARN_ON(!mutex_is_locked(dev_priv-dev-struct_mutex)); if (to-legacy_hw_ctx.rcs_state == NULL) { /* We have the fake context */ -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 12/42] drm/i915: Abstract the legacy workload submission mechanism away
From: Oscar Mateo oscar.ma...@intel.com As suggested by Daniel Vetter. The idea, in subsequent patches, is to provide an alternative to these vfuncs for the Execlists submission mechanism. v2: Splitted into two and reordered to illustrate our intentions, instead of showing it off. Also, remove the add_request vfunc and added the stop_ring one. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_drv.h| 24 drivers/gpu/drm/i915/i915_gem.c| 15 +++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 20 ++-- 3 files changed, 45 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ca1a0cc..24faec3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1610,6 +1610,21 @@ struct drm_i915_private { /* Old ums support infrastructure, same warning applies. */ struct i915_ums_state ums; + /* Abstract the submission mechanism (legacy ringbuffer or execlists) away */ + struct { + int (*do_execbuf) (struct drm_device *dev, struct drm_file *file, + struct intel_engine_cs *ring, + struct intel_context *ctx, + struct drm_i915_gem_execbuffer2 *args, + struct list_head *vmas, + struct drm_i915_gem_object *batch_obj, + u64 exec_start, u32 flags); + int (*init_rings) (struct drm_device *dev); + void (*cleanup_ring) (struct intel_engine_cs *ring); + void (*stop_ring) (struct intel_engine_cs *ring); + bool (*is_ring_initialized) (struct intel_engine_cs *ring); + } gt; + /* * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch * will be rejected. Instead look for a better place. @@ -2217,6 +2232,14 @@ int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +int i915_gem_ringbuffer_submission(struct drm_device *dev, + struct drm_file *file, + struct intel_engine_cs *ring, + struct intel_context *ctx, + struct drm_i915_gem_execbuffer2 *args, + struct list_head *vmas, + struct drm_i915_gem_object *batch_obj, + u64 exec_start, u32 flags); int i915_gem_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_execbuffer2(struct drm_device *dev, void *data, @@ -2369,6 +2392,7 @@ void i915_gem_reset(struct drm_device *dev); bool i915_gem_clflush_object(struct drm_i915_gem_object *obj, bool force); int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); int __must_check i915_gem_init(struct drm_device *dev); +int i915_gem_init_rings(struct drm_device *dev); int __must_check i915_gem_init_hw(struct drm_device *dev); int i915_gem_l3_remap(struct intel_engine_cs *ring, int slice); void i915_gem_init_swizzling(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d8bf4fa..6544286 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4518,7 +4518,7 @@ i915_gem_stop_ringbuffers(struct drm_device *dev) int i; for_each_ring(ring, dev_priv, i) - intel_stop_ring_buffer(ring); + dev_priv-gt.stop_ring(ring); } int @@ -4635,7 +4635,7 @@ intel_enable_blt(struct drm_device *dev) return true; } -static int i915_gem_init_rings(struct drm_device *dev) +int i915_gem_init_rings(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev-dev_private; int ret; @@ -4718,7 +4718,7 @@ i915_gem_init_hw(struct drm_device *dev) i915_gem_init_swizzling(dev); - ret = i915_gem_init_rings(dev); + ret = dev_priv-gt.init_rings(dev); if (ret) return ret; @@ -4759,6 +4759,13 @@ int i915_gem_init(struct drm_device *dev) DRM_DEBUG_DRIVER(allow wake ack timed out\n); } + if (!i915.enable_execlists) { + dev_priv-gt.do_execbuf = i915_gem_ringbuffer_submission; + dev_priv-gt.init_rings = i915_gem_init_rings; + dev_priv-gt.cleanup_ring = intel_cleanup_ring_buffer; + dev_priv-gt.stop_ring = intel_stop_ring_buffer; + } + i915_gem_init_userptr(dev); i915_gem_init_global_gtt(dev); @@ -4794,7 +4801,7 @@
[Intel-gfx] [PATCH 21/42] drm/i915/bdw: Ring idle and stop with logical rings
From: Oscar Mateo oscar.ma...@intel.com This is a hard one, since there is no direct hardware ring to control when in Execlists. We reuse intel_ring_idle here, but it should be fine as long as i915_add_request does the ring thing. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 24 ++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index c89e0be..39ac8b1 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -103,7 +103,24 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file, void intel_logical_ring_stop(struct intel_engine_cs *ring) { - /* TODO */ + struct drm_i915_private *dev_priv = ring-dev-dev_private; + int ret; + + if (!intel_ring_initialized(ring)) + return; + + ret = intel_ring_idle(ring); + if (ret !i915_reset_in_progress(to_i915(ring-dev)-gpu_error)) + DRM_ERROR(failed to quiesce %s whilst cleaning up: %d\n, + ring-name, ret); + + /* TODO: Is this correct with Execlists enabled? */ + I915_WRITE_MODE(ring, _MASKED_BIT_ENABLE(STOP_RING)); + if (wait_for_atomic((I915_READ_MODE(ring) MODE_IDLE) != 0, 1000)) { + DRM_ERROR(%s :timed out trying to stop ring\n, ring-name); + return; + } + I915_WRITE_MODE(ring, _MASKED_BIT_DISABLE(STOP_RING)); } int logical_ring_flush_all_caches(struct intel_ringbuffer *ringbuf) @@ -475,10 +492,13 @@ static int gen8_emit_request(struct intel_ringbuffer *ringbuf) void intel_logical_ring_cleanup(struct intel_engine_cs *ring) { + struct drm_i915_private *dev_priv = ring-dev-dev_private; + if (!intel_ring_initialized(ring)) return; - /* TODO: make sure the ring is stopped */ + intel_logical_ring_stop(ring); + WARN_ON((I915_READ_MODE(ring) MODE_IDLE) == 0); ring-preallocated_lazy_request = NULL; ring-outstanding_lazy_seqno = 0; -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 30/42] drm/i915/bdw: Handle context switch events
From: Thomas Daniel thomas.dan...@intel.com Handle all context status events in the context status buffer on every context switch interrupt. We only remove work from the execlist queue after a context status buffer reports that it has completed and we only attempt to schedule new contexts on interrupt when a previously submitted context completes (unless no contexts are queued, which means the GPU is free). We canot call intel_runtime_pm_get() in an interrupt (or with a spinlock grabbed, FWIW), because it might sleep, which is not a nice thing to do. Instead, do the runtime_pm get/put together with the create/destroy request, and handle the forcewake get/put directly. Signed-off-by: Thomas Daniel thomas.dan...@intel.com v2: Unreferencing the context when we are freeing the request might free the backing bo, which requires the struct_mutex to be grabbed, so defer unreferencing and freeing to a bottom half. v3: - Ack the interrupt inmediately, before trying to handle it (fix for missing interrupts by Bob Beckett robert.beck...@intel.com). - Update the Context Status Buffer Read Pointer, just in case (spotted by Damien Lespiau). v4: New namespace and multiple rebase changes. v5: Squash with drm/i915/bdw: Do not call intel_runtime_pm_get() in an interrupt, as suggested by Daniel. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 35 ++--- drivers/gpu/drm/i915/intel_lrc.c| 129 ++-- drivers/gpu/drm/i915/intel_lrc.h| 3 + drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + 4 files changed, 151 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 7bd44e2..ae748db 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1628,6 +1628,7 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, struct drm_i915_private *dev_priv, u32 master_ctl) { + struct intel_engine_cs *ring; u32 rcs, bcs, vcs; uint32_t tmp = 0; irqreturn_t ret = IRQ_NONE; @@ -1637,14 +1638,20 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, if (tmp) { I915_WRITE(GEN8_GT_IIR(0), tmp); ret = IRQ_HANDLED; + rcs = tmp GEN8_RCS_IRQ_SHIFT; - bcs = tmp GEN8_BCS_IRQ_SHIFT; + ring = dev_priv-ring[RCS]; if (rcs GT_RENDER_USER_INTERRUPT) - notify_ring(dev, dev_priv-ring[RCS]); + notify_ring(dev, ring); + if (rcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + intel_execlists_handle_ctx_events(ring); + + bcs = tmp GEN8_BCS_IRQ_SHIFT; + ring = dev_priv-ring[BCS]; if (bcs GT_RENDER_USER_INTERRUPT) - notify_ring(dev, dev_priv-ring[BCS]); - if ((rcs | bcs) GEN8_GT_CONTEXT_SWITCH_INTERRUPT) - DRM_DEBUG_DRIVER(TODO: Context switch\n); + notify_ring(dev, ring); + if (bcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + intel_execlists_handle_ctx_events(ring); } else DRM_ERROR(The master control interrupt lied (GT0)!\n); } @@ -1654,16 +1661,20 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, if (tmp) { I915_WRITE(GEN8_GT_IIR(1), tmp); ret = IRQ_HANDLED; + vcs = tmp GEN8_VCS1_IRQ_SHIFT; + ring = dev_priv-ring[VCS]; if (vcs GT_RENDER_USER_INTERRUPT) - notify_ring(dev, dev_priv-ring[VCS]); + notify_ring(dev, ring); if (vcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) - DRM_DEBUG_DRIVER(TODO: Context switch\n); + intel_execlists_handle_ctx_events(ring); + vcs = tmp GEN8_VCS2_IRQ_SHIFT; + ring = dev_priv-ring[VCS2]; if (vcs GT_RENDER_USER_INTERRUPT) - notify_ring(dev, dev_priv-ring[VCS2]); + notify_ring(dev, ring); if (vcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) - DRM_DEBUG_DRIVER(TODO: Context switch\n); + intel_execlists_handle_ctx_events(ring); } else DRM_ERROR(The master control interrupt lied (GT1)!\n); } @@ -1684,11 +1695,13 @@ static irqreturn_t gen8_gt_irq_handler(struct
[Intel-gfx] [PATCH 15/42] drm/i915/bdw: GEN-specific logical ring init
From: Oscar Mateo oscar.ma...@intel.com Logical rings do not need most of the initialization their legacy ringbuffer counterparts do: we just need the pipe control object for the render ring, enable Execlists on the hardware and a few workarounds. v2: Squash with: drm/i915: Extract pipe control fini make init outside accesible. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/intel_lrc.c| 54 + drivers/gpu/drm/i915/intel_ringbuffer.c | 34 + drivers/gpu/drm/i915/intel_ringbuffer.h | 3 ++ 3 files changed, 78 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 05b7069..7c8b75e 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -106,6 +106,49 @@ void intel_logical_ring_stop(struct intel_engine_cs *ring) /* TODO */ } +static int gen8_init_common_ring(struct intel_engine_cs *ring) +{ + struct drm_device *dev = ring-dev; + struct drm_i915_private *dev_priv = dev-dev_private; + + I915_WRITE(RING_MODE_GEN7(ring), + _MASKED_BIT_DISABLE(GFX_REPLAY_MODE) | + _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE)); + POSTING_READ(RING_MODE_GEN7(ring)); + DRM_DEBUG_DRIVER(Execlists enabled for %s\n, ring-name); + + memset(ring-hangcheck, 0, sizeof(ring-hangcheck)); + + return 0; +} + +static int gen8_init_render_ring(struct intel_engine_cs *ring) +{ + struct drm_device *dev = ring-dev; + struct drm_i915_private *dev_priv = dev-dev_private; + int ret; + + ret = gen8_init_common_ring(ring); + if (ret) + return ret; + + /* We need to disable the AsyncFlip performance optimisations in order +* to use MI_WAIT_FOR_EVENT within the CS. It should already be +* programmed to '1' on all products. +* +* WaDisableAsyncFlipPerfMode:snb,ivb,hsw,vlv,bdw,chv +*/ + I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE)); + + ret = intel_init_pipe_control(ring); + if (ret) + return ret; + + I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING)); + + return ret; +} + void intel_logical_ring_cleanup(struct intel_engine_cs *ring) { if (!intel_ring_initialized(ring)) @@ -176,6 +219,9 @@ static int logical_render_ring_init(struct drm_device *dev) ring-irq_enable_mask = GT_RENDER_USER_INTERRUPT GEN8_RCS_IRQ_SHIFT; + ring-init = gen8_init_render_ring; + ring-cleanup = intel_fini_pipe_control; + return logical_ring_init(dev, ring); } @@ -190,6 +236,8 @@ static int logical_bsd_ring_init(struct drm_device *dev) ring-irq_enable_mask = GT_RENDER_USER_INTERRUPT GEN8_VCS1_IRQ_SHIFT; + ring-init = gen8_init_common_ring; + return logical_ring_init(dev, ring); } @@ -204,6 +252,8 @@ static int logical_bsd2_ring_init(struct drm_device *dev) ring-irq_enable_mask = GT_RENDER_USER_INTERRUPT GEN8_VCS2_IRQ_SHIFT; + ring-init = gen8_init_common_ring; + return logical_ring_init(dev, ring); } @@ -218,6 +268,8 @@ static int logical_blt_ring_init(struct drm_device *dev) ring-irq_enable_mask = GT_RENDER_USER_INTERRUPT GEN8_BCS_IRQ_SHIFT; + ring-init = gen8_init_common_ring; + return logical_ring_init(dev, ring); } @@ -232,6 +284,8 @@ static int logical_vebox_ring_init(struct drm_device *dev) ring-irq_enable_mask = GT_RENDER_USER_INTERRUPT GEN8_VECS_IRQ_SHIFT; + ring-init = gen8_init_common_ring; + return logical_ring_init(dev, ring); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 20eb1a4..ca45c58 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -573,8 +573,25 @@ out: return ret; } -static int -init_pipe_control(struct intel_engine_cs *ring) +void +intel_fini_pipe_control(struct intel_engine_cs *ring) +{ + struct drm_device *dev = ring-dev; + + if (ring-scratch.obj == NULL) + return; + + if (INTEL_INFO(dev)-gen = 5) { + kunmap(sg_page(ring-scratch.obj-pages-sgl)); + i915_gem_object_ggtt_unpin(ring-scratch.obj); + } + + drm_gem_object_unreference(ring-scratch.obj-base); + ring-scratch.obj = NULL; +} + +int +intel_init_pipe_control(struct intel_engine_cs *ring) { int ret; @@ -649,7 +666,7 @@ static int init_render_ring(struct intel_engine_cs *ring) _MASKED_BIT_ENABLE(GFX_REPLAY_MODE)); if (INTEL_INFO(dev)-gen = 5) { - ret = init_pipe_control(ring); + ret = intel_init_pipe_control(ring); if (ret) return ret; } @@
[Intel-gfx] [PATCH 25/42] drm/i915/bdw: Always use MMIO flips with Execlists
From: Oscar Mateo oscar.ma...@intel.com The normal flip function places things in the ring in the legacy way, so we either fix that or force MMIO flips always as we do in this patch. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/intel_display.c | 2 ++ drivers/gpu/drm/i915/intel_lrc.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 72abc0b..f3ca991 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9487,6 +9487,8 @@ static bool use_mmio_flip(struct intel_engine_cs *ring, return false; else if (i915.use_mmio_flip 0) return true; + else if (i915.enable_execlists) + return true; else return ring != obj-ring; } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 40fc671..332dac2 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -83,7 +83,8 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists if (enable_execlists == 0) return 0; - if (HAS_LOGICAL_RING_CONTEXTS(dev) USES_PPGTT(dev)) + if (HAS_LOGICAL_RING_CONTEXTS(dev) USES_PPGTT(dev) + i915.use_mmio_flip = 0) return 1; return 0; -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 31/42] drm/i915/bdw: Avoid non-lite-restore preemptions
From: Oscar Mateo oscar.ma...@intel.com In the current Execlists feeding mechanism, full preemption is not supported yet: only lite-restores are allowed (this is: the GPU simply samples a new tail pointer for the context currently in execution). But we have identified an scenario in which a full preemption occurs: 1) We submit two contexts for execution (A B). 2) The GPU finishes with the first one (A), switches to the second one (B) and informs us. 3) We submit B again (hoping to cause a lite restore) together with C, but in the time we spend writing to the ELSP, the GPU finishes B. 4) The GPU start executing B again (since we told it so). 5) We receive a B finished interrupt and, mistakenly, we submit C (again) and D, causing a full preemption of B. The race is avoided by keeping track of how many times a context has been submitted to the hardware and by better discriminating the received context switch interrupts: in the example, when we have submitted B twice, we won´t submit C and D as soon as we receive the notification that B is completed because we were expecting to get a LITE_RESTORE and we didn´t, so we know a second completion will be received shortly. Without this explicit checking, somehow, the batch buffer execution order gets messed with. This can be verified with the IGT test I sent together with the series. I don´t know the exact mechanism by which the pre-emption messes with the execution order but, since other people is working on the Scheduler + Preemption on Execlists, I didn´t try to fix it. In these series, only Lite Restores are supported (other kind of preemptions WARN). v2: elsp_submitted belongs in the new intel_ctx_submit_request. Several rebase changes. v3: Clarify how the race is avoided, as requested by Daniel. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 28 drivers/gpu/drm/i915/intel_lrc.h | 2 ++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 9d320fa..d3e961e 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -264,6 +264,7 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring) else if (req0-ctx == cursor-ctx) { /* Same ctx: ignore first request, as second request * will update tail past first request's workload */ + cursor-elsp_submitted = req0-elsp_submitted; list_del(req0-execlist_link); queue_work(dev_priv-wq, req0-work); req0 = cursor; @@ -273,8 +274,14 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring) } } + WARN_ON(req1 req1-elsp_submitted); + BUG_ON(execlists_submit_context(ring, req0-ctx, req0-tail, req1? req1-ctx : NULL, req1? req1-tail : 0)); + + req0-elsp_submitted++; + if (req1) + req1-elsp_submitted++; } static bool execlists_check_remove_request(struct intel_engine_cs *ring, @@ -291,9 +298,13 @@ static bool execlists_check_remove_request(struct intel_engine_cs *ring, struct drm_i915_gem_object *ctx_obj = head_req-ctx-engine[ring-id].state; if (intel_execlists_ctx_id(ctx_obj) == request_id) { - list_del(head_req-execlist_link); - queue_work(dev_priv-wq, head_req-work); - return true; + WARN(head_req-elsp_submitted == 0, + Never submitted head request\n); + if (--head_req-elsp_submitted = 0) { + list_del(head_req-execlist_link); + queue_work(dev_priv-wq, head_req-work); + return true; + } } } @@ -326,7 +337,16 @@ void intel_execlists_handle_ctx_events(struct intel_engine_cs *ring) status_id = I915_READ(RING_CONTEXT_STATUS_BUF(ring) + (read_pointer % 6) * 8 + 4); - if (status GEN8_CTX_STATUS_COMPLETE) { + if (status GEN8_CTX_STATUS_PREEMPTED) { + if (status GEN8_CTX_STATUS_LITE_RESTORE) { + if (execlists_check_remove_request(ring, status_id)) + WARN(1, Lite Restored request removed from queue\n); + } else + WARN(1, Preemption without Lite Restore\n); + } + +if ((status GEN8_CTX_STATUS_ACTIVE_IDLE) || +(status GEN8_CTX_STATUS_ELEMENT_SWITCH)) { if (execlists_check_remove_request(ring, status_id))
[Intel-gfx] [PATCH 23/42] drm/i915/bdw: GEN-specific logical ring emit batchbuffer start
From: Oscar Mateo oscar.ma...@intel.com Dispatch_execbuffer's evil twin. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/intel_lrc.c| 28 drivers/gpu/drm/i915/intel_ringbuffer.h | 2 ++ 2 files changed, 30 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 9f45043..f4b3834 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -384,6 +384,29 @@ static int gen8_init_render_ring(struct intel_engine_cs *ring) return ret; } +static int gen8_emit_bb_start(struct intel_ringbuffer *ringbuf, + u64 offset, unsigned flags) +{ + struct intel_engine_cs *ring = ringbuf-ring; + struct drm_i915_private *dev_priv = ring-dev-dev_private; + bool ppgtt = dev_priv-mm.aliasing_ppgtt != NULL + !(flags I915_DISPATCH_SECURE); + int ret; + + ret = intel_logical_ring_begin(ringbuf, 4); + if (ret) + return ret; + + /* FIXME(BDW): Address space and security selectors. */ + intel_logical_ring_emit(ringbuf, MI_BATCH_BUFFER_START_GEN8 | (ppgtt8)); + intel_logical_ring_emit(ringbuf, lower_32_bits(offset)); + intel_logical_ring_emit(ringbuf, upper_32_bits(offset)); + intel_logical_ring_emit(ringbuf, MI_NOOP); + intel_logical_ring_advance(ringbuf); + + return 0; +} + static bool gen8_logical_ring_get_irq(struct intel_engine_cs *ring) { struct drm_device *dev = ring-dev; @@ -611,6 +634,7 @@ static int logical_render_ring_init(struct drm_device *dev) ring-emit_flush = gen8_emit_flush_render; ring-irq_get = gen8_logical_ring_get_irq; ring-irq_put = gen8_logical_ring_put_irq; + ring-emit_bb_start = gen8_emit_bb_start; return logical_ring_init(dev, ring); } @@ -635,6 +659,7 @@ static int logical_bsd_ring_init(struct drm_device *dev) ring-emit_flush = gen8_emit_flush; ring-irq_get = gen8_logical_ring_get_irq; ring-irq_put = gen8_logical_ring_put_irq; + ring-emit_bb_start = gen8_emit_bb_start; return logical_ring_init(dev, ring); } @@ -659,6 +684,7 @@ static int logical_bsd2_ring_init(struct drm_device *dev) ring-emit_flush = gen8_emit_flush; ring-irq_get = gen8_logical_ring_get_irq; ring-irq_put = gen8_logical_ring_put_irq; + ring-emit_bb_start = gen8_emit_bb_start; return logical_ring_init(dev, ring); } @@ -683,6 +709,7 @@ static int logical_blt_ring_init(struct drm_device *dev) ring-emit_flush = gen8_emit_flush; ring-irq_get = gen8_logical_ring_get_irq; ring-irq_put = gen8_logical_ring_put_irq; + ring-emit_bb_start = gen8_emit_bb_start; return logical_ring_init(dev, ring); } @@ -707,6 +734,7 @@ static int logical_vebox_ring_init(struct drm_device *dev) ring-emit_flush = gen8_emit_flush; ring-irq_get = gen8_logical_ring_get_irq; ring-irq_put = gen8_logical_ring_put_irq; + ring-emit_bb_start = gen8_emit_bb_start; return logical_ring_init(dev, ring); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 09102b2..c885d5c 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -228,6 +228,8 @@ struct intel_engine_cs { int (*emit_flush)(struct intel_ringbuffer *ringbuf, u32 invalidate_domains, u32 flush_domains); + int (*emit_bb_start)(struct intel_ringbuffer *ringbuf, +u64 offset, unsigned flags); /** * List of objects currently involved in rendering from the -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 08/42] drm/i915/bdw: Populate LR contexts (somewhat)
From: Oscar Mateo oscar.ma...@intel.com For the most part, logical ring context objects are similar to hardware contexts in that the backing object is meant to be opaque. There are some exceptions where we need to poke certain offsets of the object for initialization, updating the tail pointer or updating the PDPs. For our basic execlist implementation we'll only need our PPGTT PDs, and ringbuffer addresses in order to set up the context. With previous patches, we have both, so start prepping the context to be load. Before running a context for the first time you must populate some fields in the context object. These fields begin 1 PAGE + LRCA, ie. the first page (in 0 based counting) of the context image. These same fields will be read and written to as contexts are saved and restored once the system is up and running. Many of these fields are completely reused from previous global registers: ringbuffer head/tail/control, context control matches some previous MI_SET_CONTEXT flags, and page directories. There are other fields which we don't touch which we may want in the future. v2: CTX_LRI_HEADER_0 is MI_LOAD_REGISTER_IMM(14) for render and (11) for other engines. v3: Several rebases and general changes to the code. v4: Squash with Extract LR context object populating Also, Damien's review comments: - Set the Force Posted bit on the LRI header, as the BSpec suggest we do. - Prevent warning when compiling a 32-bits kernel without HIGHMEM64. - Add a clarifying comment to the context population code. v5: Damien's review comments: - The third MI_LOAD_REGISTER_IMM in the context does not set Force Posted. - Remove dead code. v6: Add a note about the (presumed) differences between BDW and CHV state contexts. Also, Brad's review comments: - Use the _MASKED_BIT_ENABLE, upper_32_bits and lower_32_bits macros. - Be less magical about how we set the ring size in the context. Signed-off-by: Ben Widawsky b...@bwidawsk.net (v1) Signed-off-by: Rafael Barbalho rafael.barba...@intel.com (v2) Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_lrc.c | 159 ++- 2 files changed, 156 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 45f447a..6c0811b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -282,6 +282,7 @@ * address/value pairs. Don't overdue it, though, x = 2^4 must hold! */ #define MI_LOAD_REGISTER_IMM(x)MI_INSTR(0x22, 2*(x)-1) +#define MI_LRI_FORCE_POSTED (112) #define MI_STORE_REGISTER_MEM(x) MI_INSTR(0x24, 2*(x)-1) #define MI_STORE_REGISTER_MEM_GEN8(x) MI_INSTR(0x24, 3*(x)-1) #define MI_SRM_LRM_GLOBAL_GTT(122) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 2eb7db6..cf322ec 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -46,6 +46,38 @@ #define GEN8_LR_CONTEXT_ALIGN 4096 +#define RING_ELSP(ring)((ring)-mmio_base+0x230) +#define RING_CONTEXT_CONTROL(ring) ((ring)-mmio_base+0x244) + +#define CTX_LRI_HEADER_0 0x01 +#define CTX_CONTEXT_CONTROL0x02 +#define CTX_RING_HEAD 0x04 +#define CTX_RING_TAIL 0x06 +#define CTX_RING_BUFFER_START 0x08 +#define CTX_RING_BUFFER_CONTROL0x0a +#define CTX_BB_HEAD_U 0x0c +#define CTX_BB_HEAD_L 0x0e +#define CTX_BB_STATE 0x10 +#define CTX_SECOND_BB_HEAD_U 0x12 +#define CTX_SECOND_BB_HEAD_L 0x14 +#define CTX_SECOND_BB_STATE0x16 +#define CTX_BB_PER_CTX_PTR 0x18 +#define CTX_RCS_INDIRECT_CTX 0x1a +#define CTX_RCS_INDIRECT_CTX_OFFSET0x1c +#define CTX_LRI_HEADER_1 0x21 +#define CTX_CTX_TIMESTAMP 0x22 +#define CTX_PDP3_UDW 0x24 +#define CTX_PDP3_LDW 0x26 +#define CTX_PDP2_UDW 0x28 +#define CTX_PDP2_LDW 0x2a +#define CTX_PDP1_UDW 0x2c +#define CTX_PDP1_LDW 0x2e +#define CTX_PDP0_UDW 0x30 +#define CTX_PDP0_LDW 0x32 +#define CTX_LRI_HEADER_2 0x41 +#define CTX_R_PWR_CLK_STATE0x42 +#define CTX_GPGPU_CSR_BASE_ADDRESS 0x44 + int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists) { if (enable_execlists == 0) @@ -57,6 +89,115 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists return 0; } +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) +{ + struct drm_i915_gem_object *ring_obj = ringbuf-obj; + struct i915_hw_ppgtt
[Intel-gfx] [PATCH 11/42] drm/i915/bdw: Don't write PDP in the legacy way when using LRCs
From: Oscar Mateo oscar.ma...@intel.com This is mostly for correctness so that we know we are running the LR context correctly (this is, the PDPs are contained inside the context object). v2: Move the check to inside the enable PPGTT function. The switch happens in two places: the legacy context switch (that we won't hit when Execlists are enabled) and the PPGTT enable, which unfortunately we need. This would look much nicer if the ppgtt-enable was part of the ring init, where it logically belongs. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_gem_gtt.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index a4153ee..3b956e7 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -851,6 +851,11 @@ static int gen8_ppgtt_enable(struct i915_hw_ppgtt *ppgtt) if (USES_FULL_PPGTT(dev)) continue; + /* In the case of Execlists, we don't want to write the PDPs +* in the legacy way (they live inside the context now) */ + if (i915.enable_execlists) + return 0; + ret = ppgtt-switch_mm(ppgtt, ring, true); if (ret) goto err_out; -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 39/42] drm/i915/bdw: Document Logical Rings, LR contexts and Execlists
From: Oscar Mateo oscar.ma...@intel.com Add theory of operation notes to intel_lrc.c and comments to externally visible functions. v2: Add notes on logical ring context creation. v3: Use kerneldoc. v4: Integrate it in the DocBook template. Signed-off-by: Thomas Daniel thomas.dan...@intel.com (v1) Signed-off-by: Oscar Mateo oscar.ma...@intel.com (v2, v3) --- Documentation/DocBook/drm.tmpl | 5 + drivers/gpu/drm/i915/intel_lrc.c | 215 ++- drivers/gpu/drm/i915/intel_lrc.h | 30 ++ 3 files changed, 249 insertions(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 4890d94..cd981f2 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -3945,6 +3945,11 @@ int num_ioctls;/synopsis !Pdrivers/gpu/drm/i915/i915_cmd_parser.c batch buffer command parser !Idrivers/gpu/drm/i915/i915_cmd_parser.c /sect2 + sect2 +titleLogical Rings, Logical Ring Contexts and Execlists/title +!Pdrivers/gpu/drm/i915/intel_lrc.c Logical Rings, Logical Ring Contexts and Execlists +!Idrivers/gpu/drm/i915/intel_lrc.c + /sect2 /sect1 /chapter /part diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 8ce9698..3c3fa69 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -28,13 +28,108 @@ * */ -/* +/** + * DOC: Logical Rings, Logical Ring Contexts and Execlists + * + * Motivation: * GEN8 brings an expansion of the HW contexts: Logical Ring Contexts. * These expanded contexts enable a number of new abilities, especially * Execlists (also implemented in this file). * + * One of the main differences with the legacy HW contexts is that logical + * ring contexts incorporate many more things to the context's state, like + * PDPs or ringbuffer control registers: + * + * The reason why PDPs are included in the context is straightforward: as + * PPGTTs (per-process GTTs) are actually per-context, having the PDPs + * contained there mean you don't need to do a ppgtt-switch_mm yourself, + * instead, the GPU will do it for you on the context switch. + * + * But, what about the ringbuffer control registers (head, tail, etc..)? + * shouldn't we just need a set of those per engine command streamer? This is + * where the name Logical Rings starts to make sense: by virtualizing the + * rings, the engine cs shifts to a new ring buffer with every context + * switch. When you want to submit a workload to the GPU you: A) choose your + * context, B) find its appropriate virtualized ring, C) write commands to it + * and then, finally, D) tell the GPU to switch to that context. + * + * Instead of the legacy MI_SET_CONTEXT, the way you tell the GPU to switch + * to a contexts is via a context execution list, ergo Execlists. + * + * LRC implementation: + * Regarding the creation of contexts, we have: + * + * - One global default context. + * - One local default context for each opened fd. + * - One local extra context for each context create ioctl call. + * + * Now that ringbuffers belong per-context (and not per-engine, like before) + * and that contexts are uniquely tied to a given engine (and not reusable, + * like before) we need: + * + * - One ringbuffer per-engine inside each context. + * - One backing object per-engine inside each context. + * + * The global default context starts its life with these new objects fully + * allocated and populated. The local default context for each opened fd is + * more complex, because we don't know at creation time which engine is going + * to use them. To handle this, we have implemented a deferred creation of LR + * contexts: + * + * The local context starts its life as a hollow or blank holder, that only + * gets populated for a given engine once we receive an execbuffer. If later + * on we receive another execbuffer ioctl for the same context but a different + * engine, we allocate/populate a new ringbuffer and context backing object and + * so on. + * + * Finally, regarding local contexts created using the ioctl call: as they are + * only allowed with the render ring, we can allocate populate them right + * away (no need to defer anything, at least for now). + * + * Execlists implementation: * Execlists are the new method by which, on gen8+ hardware, workloads are * submitted for execution (as opposed to the legacy, ringbuffer-based, method). + * This method works as follows: + * + * When a request is committed, its commands (the BB start and any leading or + * trailing commands, like the seqno breadcrumbs) are placed in the ringbuffer + * for the appropriate context. The tail pointer in the hardware context is not + * updated at this time, but instead, kept by the driver in the ringbuffer + * structure. A structure representing this request is added to a request queue + * for the appropriate engine: this structure contains a copy of the context's + * tail after the
[Intel-gfx] [PATCH 33/42] drm/i915/bdw: Make sure gpu reset still works with Execlists
From: Oscar Mateo oscar.ma...@intel.com If we reset a ring after a hang, we have to make sure that we clear out all queued Execlists requests. v2: The ring is, at this point, already being correctly re-programmed for Execlists, and the hangcheck counters cleared. v3: Daniel suggests to drop the if (execlists) because the Execlists queue should be empty in legacy mode (which is true, if we do the INIT_LIST_HEAD). Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_gem.c | 11 +++ drivers/gpu/drm/i915/intel_ringbuffer.c | 1 + 2 files changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1c83b9c..b5ea3b0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2567,6 +2567,17 @@ static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv, i915_gem_free_request(request); } + while (!list_empty(ring-execlist_queue)) { + struct intel_ctx_submit_request *submit_req; + + submit_req = list_first_entry(ring-execlist_queue, + struct intel_ctx_submit_request, + execlist_link); + list_del(submit_req-execlist_link); + i915_gem_context_unreference(submit_req-ctx); + kfree(submit_req); + } + /* These may not have been flush before the reset, do so now */ kfree(ring-preallocated_lazy_request); ring-preallocated_lazy_request = NULL; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 3188403..6e604c9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1587,6 +1587,7 @@ static int intel_init_ring_buffer(struct drm_device *dev, ring-dev = dev; INIT_LIST_HEAD(ring-active_list); INIT_LIST_HEAD(ring-request_list); + INIT_LIST_HEAD(ring-execlist_queue); ringbuf-size = 32 * PAGE_SIZE; ringbuf-ring = ring; ringbuf-ctx = ring-default_context; -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 06/42] drm/i915/bdw: Allocate ringbuffers for Logical Ring Contexts
From: Oscar Mateo oscar.ma...@intel.com As we have said a couple of times by now, logical ring contexts have their own ringbuffers: not only the backing pages, but the whole management struct. In a previous version of the series, this was achieved with two separate patches: drm/i915/bdw: Allocate ringbuffer backing objects for default global LRC drm/i915/bdw: Allocate ringbuffer for user-created LRCs Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_lrc.c| 38 + drivers/gpu/drm/i915/intel_ringbuffer.c | 6 +++--- drivers/gpu/drm/i915/intel_ringbuffer.h | 4 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0638356..ca1a0cc 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -621,6 +621,7 @@ struct intel_context { /* Execlists */ struct { struct drm_i915_gem_object *state; + struct intel_ringbuffer *ringbuf; } engine[I915_NUM_RINGS]; struct list_head link; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index a3fc6fc..0a12b8c 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -63,7 +63,11 @@ void intel_lr_context_free(struct intel_context *ctx) for (i = 0; i I915_NUM_RINGS; i++) { struct drm_i915_gem_object *ctx_obj = ctx-engine[i].state; + struct intel_ringbuffer *ringbuf = ctx-engine[i].ringbuf; + if (ctx_obj) { + intel_destroy_ringbuffer_obj(ringbuf); + kfree(ringbuf); i915_gem_object_ggtt_unpin(ctx_obj); drm_gem_object_unreference(ctx_obj-base); } @@ -97,6 +101,7 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, struct drm_device *dev = ring-dev; struct drm_i915_gem_object *ctx_obj; uint32_t context_size; + struct intel_ringbuffer *ringbuf; int ret; BUG_ON(ctx-legacy_hw_ctx.rcs_state != NULL); @@ -117,6 +122,39 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, return ret; } + ringbuf = kzalloc(sizeof(*ringbuf), GFP_KERNEL); + if (!ringbuf) { + DRM_DEBUG_DRIVER(Failed to allocate ringbuffer %s\n, + ring-name); + i915_gem_object_ggtt_unpin(ctx_obj); + drm_gem_object_unreference(ctx_obj-base); + ret = -ENOMEM; + return ret; + } + + ringbuf-size = 32 * PAGE_SIZE; + ringbuf-effective_size = ringbuf-size; + ringbuf-head = 0; + ringbuf-tail = 0; + ringbuf-space = ringbuf-size; + ringbuf-last_retired_head = -1; + + /* TODO: For now we put this in the mappable region so that we can reuse +* the existing ringbuffer code which ioremaps it. When we start +* creating many contexts, this will no longer work and we must switch +* to a kmapish interface. +*/ + ret = intel_alloc_ringbuffer_obj(dev, ringbuf); + if (ret) { + DRM_DEBUG_DRIVER(Failed to allocate ringbuffer obj %s: %d\n, + ring-name, ret); + kfree(ringbuf); + i915_gem_object_ggtt_unpin(ctx_obj); + drm_gem_object_unreference(ctx_obj-base); + return ret; + } + + ctx-engine[ring-id].ringbuf = ringbuf; ctx-engine[ring-id].state = ctx_obj; return 0; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 599709e..01e9840 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1495,7 +1495,7 @@ static int init_phys_status_page(struct intel_engine_cs *ring) return 0; } -static void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf) +void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf) { if (!ringbuf-obj) return; @@ -1506,8 +1506,8 @@ static void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf) ringbuf-obj = NULL; } -static int intel_alloc_ringbuffer_obj(struct drm_device *dev, - struct intel_ringbuffer *ringbuf) +int intel_alloc_ringbuffer_obj(struct drm_device *dev, + struct intel_ringbuffer *ringbuf) { struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_object *obj; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index ed59410..053d004 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -353,6 +353,10 @@
[Intel-gfx] [PATCH 28/42] drm/i915/bdw: Write the tail pointer, LRC style
From: Oscar Mateo oscar.ma...@intel.com Each logical ring context has the tail pointer in the context object, so update it before submission. v2: New namespace. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index db5f27b..ceee121 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -176,6 +176,21 @@ static void execlists_elsp_write(struct intel_engine_cs *ring, gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); } +static int execlists_ctx_write_tail(struct drm_i915_gem_object *ctx_obj, u32 tail) +{ + struct page *page; + uint32_t *reg_state; + + page = i915_gem_object_get_page(ctx_obj, 1); + reg_state = kmap_atomic(page); + + reg_state[CTX_RING_TAIL+1] = tail; + + kunmap_atomic(reg_state); + + return 0; +} + static int execlists_submit_context(struct intel_engine_cs *ring, struct intel_context *to0, u32 tail0, struct intel_context *to1, u32 tail1) @@ -187,10 +202,14 @@ static int execlists_submit_context(struct intel_engine_cs *ring, BUG_ON(!ctx_obj0); BUG_ON(!i915_gem_obj_is_pinned(ctx_obj0)); + execlists_ctx_write_tail(ctx_obj0, tail0); + if (to1) { ctx_obj1 = to1-engine[ring-id].state; BUG_ON(!ctx_obj1); BUG_ON(!i915_gem_obj_is_pinned(ctx_obj1)); + + execlists_ctx_write_tail(ctx_obj1, tail1); } execlists_elsp_write(ring, ctx_obj0, ctx_obj1); -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 24/42] drm/i915/bdw: Workload submission mechanism for Execlists
From: Oscar Mateo oscar.ma...@intel.com This is what i915_gem_do_execbuffer calls when it wants to execute some worload in an Execlists world. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_drv.h| 6 ++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 4 +- drivers/gpu/drm/i915/intel_lrc.c | 128 - 3 files changed, 135 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 24faec3..9a3adff 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2232,6 +2232,12 @@ int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +void i915_gem_execbuffer_move_to_active(struct list_head *vmas, + struct intel_engine_cs *ring); +void i915_gem_execbuffer_retire_commands(struct drm_device *dev, +struct drm_file *file, +struct intel_engine_cs *ring, +struct drm_i915_gem_object *obj); int i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file, struct intel_engine_cs *ring, diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 491ef7e..41e6467 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -962,7 +962,7 @@ i915_gem_validate_context(struct drm_device *dev, struct drm_file *file, return ctx; } -static void +void i915_gem_execbuffer_move_to_active(struct list_head *vmas, struct intel_engine_cs *ring) { @@ -994,7 +994,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas, } } -static void +void i915_gem_execbuffer_retire_commands(struct drm_device *dev, struct drm_file *file, struct intel_engine_cs *ring, diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index f4b3834..40fc671 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -89,6 +89,57 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists return 0; } +static int logical_ring_invalidate_all_caches(struct intel_ringbuffer *ringbuf) +{ + struct intel_engine_cs *ring = ringbuf-ring; + uint32_t flush_domains; + int ret; + + flush_domains = 0; + if (ring-gpu_caches_dirty) + flush_domains = I915_GEM_GPU_DOMAINS; + + ret = ring-emit_flush(ringbuf, I915_GEM_GPU_DOMAINS, flush_domains); + if (ret) + return ret; + + ring-gpu_caches_dirty = false; + return 0; +} + +static int execlists_move_to_gpu(struct intel_ringbuffer *ringbuf, +struct list_head *vmas) +{ + struct intel_engine_cs *ring = ringbuf-ring; + struct i915_vma *vma; + uint32_t flush_domains = 0; + bool flush_chipset = false; + int ret; + + list_for_each_entry(vma, vmas, exec_list) { + struct drm_i915_gem_object *obj = vma-obj; + ret = i915_gem_object_sync(obj, ring); + if (ret) + return ret; + + if (obj-base.write_domain I915_GEM_DOMAIN_CPU) + flush_chipset |= i915_gem_clflush_object(obj, false); + + flush_domains |= obj-base.write_domain; + } + + if (flush_chipset) + i915_gem_chipset_flush(ring-dev); + + if (flush_domains I915_GEM_DOMAIN_GTT) + wmb(); + + /* Unconditionally invalidate gpu caches and ensure that we do flush +* any residual writes from the previous batch. +*/ + return logical_ring_invalidate_all_caches(ringbuf); +} + int intel_execlists_submission(struct drm_device *dev, struct drm_file *file, struct intel_engine_cs *ring, struct intel_context *ctx, @@ -97,7 +148,82 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file, struct drm_i915_gem_object *batch_obj, u64 exec_start, u32 flags) { - /* TODO */ + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_ringbuffer *ringbuf = ctx-engine[ring-id].ringbuf; + int instp_mode; + u32 instp_mask; + int ret; + + if (args-num_cliprects != 0) { + DRM_DEBUG(clip rectangles are only valid on pre-gen5\n); + return -EINVAL; + }
[Intel-gfx] [PATCH 37/42] drm/i915/bdw: Display context backing obj ringbuffer info in debugfs
From: Oscar Mateo oscar.ma...@intel.com Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 25 +++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 66e9244..4c62900 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1628,6 +1628,12 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) return 0; } +static void describe_ctx_ringbuf(struct seq_file *m, struct intel_ringbuffer *ringbuf) +{ + seq_printf(m, (ringbuffer, space: %d, head: %u, tail: %u, last head: %d), + ringbuf-space, ringbuf-head, ringbuf-tail, + ringbuf-last_retired_head); +} static int i915_context_status(struct seq_file *m, void *unused) { @@ -1655,7 +1661,7 @@ static int i915_context_status(struct seq_file *m, void *unused) } list_for_each_entry(ctx, dev_priv-context_list, link) { - if (ctx-legacy_hw_ctx.rcs_state == NULL) + if (!i915.enable_execlists ctx-legacy_hw_ctx.rcs_state == NULL) continue; seq_puts(m, HW context ); @@ -1664,7 +1670,22 @@ static int i915_context_status(struct seq_file *m, void *unused) if (ring-default_context == ctx) seq_printf(m, (default context %s) , ring-name); - describe_obj(m, ctx-legacy_hw_ctx.rcs_state); + if (i915.enable_execlists) { + seq_putc(m, '\n'); + for_each_ring(ring, dev_priv, i) { + struct drm_i915_gem_object *ctx_obj = ctx-engine[i].state; + struct intel_ringbuffer *ringbuf = ctx-engine[i].ringbuf; + + seq_printf(m, %s: , ring-name); + if (ctx_obj) + describe_obj(m, ctx_obj); + if (ringbuf) + describe_ctx_ringbuf(m, ringbuf); + seq_putc(m, '\n'); + } + } else + describe_obj(m, ctx-legacy_hw_ctx.rcs_state); + seq_putc(m, '\n'); } -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 13/42] drm/i915/bdw: Skeleton for the new logical rings submission path
From: Oscar Mateo oscar.ma...@intel.com Execlists are indeed a brave new world with respect to workload submission to the GPU. In previous version of these series, I have tried to impact the legacy ringbuffer submission path as little as possible (mostly, passing the context around and using the correct ringbuffer when I needed one) but Daniel is afraid (probably with a reason) that these changes and, especially, future ones, will end up breaking older gens. This commit and some others coming next will try to limit the damage by creating an alternative path for workload submission. The first step is here: laying out a new ring init/fini. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_gem.c | 5 ++ drivers/gpu/drm/i915/intel_lrc.c | 151 +++ drivers/gpu/drm/i915/intel_lrc.h | 12 3 files changed, 168 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6544286..9560b40 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4764,6 +4764,11 @@ int i915_gem_init(struct drm_device *dev) dev_priv-gt.init_rings = i915_gem_init_rings; dev_priv-gt.cleanup_ring = intel_cleanup_ring_buffer; dev_priv-gt.stop_ring = intel_stop_ring_buffer; + } else { + dev_priv-gt.do_execbuf = intel_execlists_submission; + dev_priv-gt.init_rings = intel_logical_rings_init; + dev_priv-gt.cleanup_ring = intel_logical_ring_cleanup; + dev_priv-gt.stop_ring = intel_logical_ring_stop; } i915_gem_init_userptr(dev); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index cf322ec..cb56bb8 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -89,6 +89,157 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists return 0; } +int intel_execlists_submission(struct drm_device *dev, struct drm_file *file, + struct intel_engine_cs *ring, + struct intel_context *ctx, + struct drm_i915_gem_execbuffer2 *args, + struct list_head *vmas, + struct drm_i915_gem_object *batch_obj, + u64 exec_start, u32 flags) +{ + /* TODO */ + return 0; +} + +void intel_logical_ring_stop(struct intel_engine_cs *ring) +{ + /* TODO */ +} + +void intel_logical_ring_cleanup(struct intel_engine_cs *ring) +{ + /* TODO */ +} + +static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *ring) +{ + /* TODO */ + return 0; +} + +static int logical_render_ring_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_engine_cs *ring = dev_priv-ring[RCS]; + + ring-name = render ring; + ring-id = RCS; + ring-mmio_base = RENDER_RING_BASE; + ring-irq_enable_mask = + GT_RENDER_USER_INTERRUPT GEN8_RCS_IRQ_SHIFT; + + return logical_ring_init(dev, ring); +} + +static int logical_bsd_ring_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_engine_cs *ring = dev_priv-ring[VCS]; + + ring-name = bsd ring; + ring-id = VCS; + ring-mmio_base = GEN6_BSD_RING_BASE; + ring-irq_enable_mask = + GT_RENDER_USER_INTERRUPT GEN8_VCS1_IRQ_SHIFT; + + return logical_ring_init(dev, ring); +} + +static int logical_bsd2_ring_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_engine_cs *ring = dev_priv-ring[VCS2]; + + ring-name = bds2 ring; + ring-id = VCS2; + ring-mmio_base = GEN8_BSD2_RING_BASE; + ring-irq_enable_mask = + GT_RENDER_USER_INTERRUPT GEN8_VCS2_IRQ_SHIFT; + + return logical_ring_init(dev, ring); +} + +static int logical_blt_ring_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_engine_cs *ring = dev_priv-ring[BCS]; + + ring-name = blitter ring; + ring-id = BCS; + ring-mmio_base = BLT_RING_BASE; + ring-irq_enable_mask = + GT_RENDER_USER_INTERRUPT GEN8_BCS_IRQ_SHIFT; + + return logical_ring_init(dev, ring); +} + +static int logical_vebox_ring_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_engine_cs *ring = dev_priv-ring[VECS]; + + ring-name = video enhancement ring; + ring-id = VECS; + ring-mmio_base = VEBOX_RING_BASE; + ring-irq_enable_mask = + GT_RENDER_USER_INTERRUPT GEN8_VECS_IRQ_SHIFT; + + return logical_ring_init(dev, ring); +} + +int
[Intel-gfx] [PATCH 09/42] drm/i915/bdw: Deferred creation of user-created LRCs
From: Oscar Mateo oscar.ma...@intel.com The backing objects and ringbuffers for contexts created via open fd are actually empty until the user starts sending execbuffers to them. At that point, we allocate populate them. We do this because, at create time, we really don't know which engine is going to be used with the context later on (and we don't want to waste memory on objects that we might never use). v2: As contexts created via ioctl can only be used with the render ring, we have enough information to allocate populate them right away. v3: Defer the creation always, even with ioctl-created contexts, as requested by Daniel Vetter. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_gem_context.c| 7 +++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 8 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 48d7476..fbe7278 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -784,9 +784,9 @@ int i915_switch_context(struct intel_engine_cs *ring, return do_switch(ring, to); } -static bool hw_context_enabled(struct drm_device *dev) +static bool contexts_enabled(struct drm_device *dev) { - return to_i915(dev)-hw_context_size; + return i915.enable_execlists || to_i915(dev)-hw_context_size; } int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, @@ -797,8 +797,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, struct intel_context *ctx; int ret; - /* FIXME: allow user-created LR contexts as well */ - if (!hw_context_enabled(dev)) + if (!contexts_enabled(dev)) return -ENODEV; ret = i915_mutex_lock_interruptible(dev); diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 60998fc..a006404 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -951,6 +951,14 @@ i915_gem_validate_context(struct drm_device *dev, struct drm_file *file, return ERR_PTR(-EIO); } + if (i915.enable_execlists !ctx-engine[ring-id].state) { + int ret = intel_lr_context_deferred_create(ctx, ring); + if (ret) { + DRM_DEBUG(Could not create LRC %u: %d\n, ctx_id, ret); + return ERR_PTR(ret); + } + } + return ctx; } -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 41/42] drm/i915/bdw: Pin the context backing objects to GGTT on-demand
From: Oscar Mateo oscar.ma...@intel.com Up until now, we have pinned every logical ring context backing object during creation, and left it pinned until destruction. This made my life easier, but it's a harmful thing to do, because we cause fragmentation of the GGTT (and, eventually, we would run out of space). This patch makes the pinning on-demand: the backing objects of the two contexts that are written to the ELSP are pinned right before submission and unpinned once the hardware is done with them. The only context that is still pinned regardless is the global default one, so that the HWS can still be accessed in the same way (ring-status_page). There are several TODO left in this patch, so it's probably not ready for merging yet: - execlists_submit_context has increased chances of failing now, so we cannot simply BUG_ON if it does. I outlined here a possible recovery mechanism, but maybe it's a bit too naive. - The debugfs entries that access the context backing object need to be checked and modified to pin the object accordingly. - A recovery from reset probably needs to unpin some objects as well. - Something is not right during module re-loading (occasional failure in tests/drv_module_reload). - Lots of testing!! Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 74 +--- 1 file changed, 54 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 3c3fa69..244269b 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -333,24 +333,41 @@ static int execlists_ctx_write_tail(struct drm_i915_gem_object *ctx_obj, u32 tai } static int execlists_submit_context(struct intel_engine_cs *ring, - struct intel_context *to0, u32 tail0, - struct intel_context *to1, u32 tail1) + struct intel_ctx_submit_request *req0, + struct intel_ctx_submit_request *req1) { - struct drm_i915_gem_object *ctx_obj0; + struct intel_context *to0 = req0-ctx; + struct drm_i915_gem_object *ctx_obj0 = to0-engine[ring-id].state; struct drm_i915_gem_object *ctx_obj1 = NULL; + bool ctx0_pinned = false; + int ret; - ctx_obj0 = to0-engine[ring-id].state; BUG_ON(!ctx_obj0); - BUG_ON(!i915_gem_obj_is_pinned(ctx_obj0)); + if (to0 != ring-default_context !req0-elsp_submitted) { + ret = i915_gem_obj_ggtt_pin(ctx_obj0, GEN8_LR_CONTEXT_ALIGN, 0); + if (ret) + return ret; + ctx0_pinned = true; + } + + execlists_ctx_write_tail(ctx_obj0, req0-tail); - execlists_ctx_write_tail(ctx_obj0, tail0); + if (req1) { + struct intel_context *to1 = req1-ctx; - if (to1) { ctx_obj1 = to1-engine[ring-id].state; + BUG_ON(!ctx_obj1); - BUG_ON(!i915_gem_obj_is_pinned(ctx_obj1)); + if (to1 != ring-default_context) { + ret = i915_gem_obj_ggtt_pin(ctx_obj1, GEN8_LR_CONTEXT_ALIGN, 0); + if (ret) { + if (ctx0_pinned) + i915_gem_object_ggtt_unpin(ctx_obj0); + return ret; + } + } - execlists_ctx_write_tail(ctx_obj1, tail1); + execlists_ctx_write_tail(ctx_obj1, req1-tail); } execlists_elsp_write(ring, ctx_obj0, ctx_obj1); @@ -388,8 +405,15 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring) WARN_ON(req1 req1-elsp_submitted); - BUG_ON(execlists_submit_context(ring, req0-ctx, req0-tail, - req1? req1-ctx : NULL, req1? req1-tail : 0)); + if (WARN_ON(execlists_submit_context(ring, req0, req1))) { + list_del(req0-execlist_link); + queue_work(dev_priv-wq, req0-work); + if (req1) { + list_del(req1-execlist_link); + queue_work(dev_priv-wq, req1-work); + } + return; + } req0-elsp_submitted++; if (req1) @@ -413,6 +437,8 @@ static bool execlists_check_remove_request(struct intel_engine_cs *ring, WARN(head_req-elsp_submitted == 0, Never submitted head request\n); if (--head_req-elsp_submitted = 0) { + if (head_req-ctx != ring-default_context) + i915_gem_object_ggtt_unpin(ctx_obj); list_del(head_req-execlist_link); queue_work(dev_priv-wq, head_req-work); return true; @@
[Intel-gfx] [PATCH 18/42] drm/i915/bdw: GEN-specific logical ring emit request
From: Oscar Mateo oscar.ma...@intel.com Very similar to the legacy add_request, only modified to account for logical ringbuffer. v2: Use MI_GLOBAL_GTT, as suggested by Brad Volkin. v3: Unify render and non-render in the same function, as noticed by Brad Volkin. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_lrc.c| 31 +++ drivers/gpu/drm/i915/intel_ringbuffer.h | 3 +++ 3 files changed, 35 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 6c0811b..4df121b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -272,6 +272,7 @@ #define MI_SEMAPHORE_POLL(115) #define MI_SEMAPHORE_SAD_GTE_SDD (112) #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) +#define MI_STORE_DWORD_IMM_GEN8MI_INSTR(0x20, 2) #define MI_MEM_VIRTUAL (1 22) /* 965+ only */ #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) #define MI_STORE_DWORD_INDEX_SHIFT 2 diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index bd37d51..64bda7a 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -352,6 +352,32 @@ static void gen8_set_seqno(struct intel_engine_cs *ring, u32 seqno) intel_write_status_page(ring, I915_GEM_HWS_INDEX, seqno); } +static int gen8_emit_request(struct intel_ringbuffer *ringbuf) +{ + struct intel_engine_cs *ring = ringbuf-ring; + u32 cmd; + int ret; + + ret = intel_logical_ring_begin(ringbuf, 6); + if (ret) + return ret; + + cmd = MI_STORE_DWORD_IMM_GEN8; + cmd |= MI_GLOBAL_GTT; + + intel_logical_ring_emit(ringbuf, cmd); + intel_logical_ring_emit(ringbuf, + (ring-status_page.gfx_addr + + (I915_GEM_HWS_INDEX MI_STORE_DWORD_INDEX_SHIFT))); + intel_logical_ring_emit(ringbuf, 0); + intel_logical_ring_emit(ringbuf, ring-outstanding_lazy_seqno); + intel_logical_ring_emit(ringbuf, MI_USER_INTERRUPT); + intel_logical_ring_emit(ringbuf, MI_NOOP); + intel_logical_ring_advance_and_submit(ringbuf); + + return 0; +} + void intel_logical_ring_cleanup(struct intel_engine_cs *ring) { if (!intel_ring_initialized(ring)) @@ -426,6 +452,7 @@ static int logical_render_ring_init(struct drm_device *dev) ring-cleanup = intel_fini_pipe_control; ring-get_seqno = gen8_get_seqno; ring-set_seqno = gen8_set_seqno; + ring-emit_request = gen8_emit_request; return logical_ring_init(dev, ring); } @@ -444,6 +471,7 @@ static int logical_bsd_ring_init(struct drm_device *dev) ring-init = gen8_init_common_ring; ring-get_seqno = gen8_get_seqno; ring-set_seqno = gen8_set_seqno; + ring-emit_request = gen8_emit_request; return logical_ring_init(dev, ring); } @@ -462,6 +490,7 @@ static int logical_bsd2_ring_init(struct drm_device *dev) ring-init = gen8_init_common_ring; ring-get_seqno = gen8_get_seqno; ring-set_seqno = gen8_set_seqno; + ring-emit_request = gen8_emit_request; return logical_ring_init(dev, ring); } @@ -480,6 +509,7 @@ static int logical_blt_ring_init(struct drm_device *dev) ring-init = gen8_init_common_ring; ring-get_seqno = gen8_get_seqno; ring-set_seqno = gen8_set_seqno; + ring-emit_request = gen8_emit_request; return logical_ring_init(dev, ring); } @@ -498,6 +528,7 @@ static int logical_vebox_ring_init(struct drm_device *dev) ring-init = gen8_init_common_ring; ring-get_seqno = gen8_get_seqno; ring-set_seqno = gen8_set_seqno; + ring-emit_request = gen8_emit_request; return logical_ring_init(dev, ring); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index c305df0..176ee6a 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -215,6 +215,9 @@ struct intel_engine_cs { unsigned int num_dwords); } semaphore; + /* Execlists */ + int (*emit_request)(struct intel_ringbuffer *ringbuf); + /** * List of objects currently involved in rendering from the * ringbuffer. -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 22/42] drm/i915/bdw: Interrupts with logical rings
From: Oscar Mateo oscar.ma...@intel.com We need to attend context switch interrupts from all rings. Also, fixed writing IMR/IER and added HWSTAM at ring init time. Notice that, if added to irq_enable_mask, the context switch interrupts would be incorrectly masked out when the user interrupts are due to no users waiting on a sequence number. Therefore, this commit adds a bitmask of interrupts to be kept unmasked at all times. v2: Disable HWSTAM, as suggested by Damien (nobody listens to these interrupts, anyway). v3: Add new get/put_irq functions. Signed-off-by: Thomas Daniel thomas.dan...@intel.com (v1) Signed-off-by: Oscar Mateo oscar.ma...@intel.com (v2 v3) --- drivers/gpu/drm/i915/i915_irq.c | 19 +-- drivers/gpu/drm/i915/i915_reg.h | 3 ++ drivers/gpu/drm/i915/intel_lrc.c| 58 + drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 026f0a3..7bd44e2 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1643,6 +1643,8 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, notify_ring(dev, dev_priv-ring[RCS]); if (bcs GT_RENDER_USER_INTERRUPT) notify_ring(dev, dev_priv-ring[BCS]); + if ((rcs | bcs) GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER(TODO: Context switch\n); } else DRM_ERROR(The master control interrupt lied (GT0)!\n); } @@ -1655,9 +1657,13 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, vcs = tmp GEN8_VCS1_IRQ_SHIFT; if (vcs GT_RENDER_USER_INTERRUPT) notify_ring(dev, dev_priv-ring[VCS]); + if (vcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER(TODO: Context switch\n); vcs = tmp GEN8_VCS2_IRQ_SHIFT; if (vcs GT_RENDER_USER_INTERRUPT) notify_ring(dev, dev_priv-ring[VCS2]); + if (vcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER(TODO: Context switch\n); } else DRM_ERROR(The master control interrupt lied (GT1)!\n); } @@ -1681,6 +1687,8 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, vcs = tmp GEN8_VECS_IRQ_SHIFT; if (vcs GT_RENDER_USER_INTERRUPT) notify_ring(dev, dev_priv-ring[VECS]); + if (vcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER(TODO: Context switch\n); } else DRM_ERROR(The master control interrupt lied (GT3)!\n); } @@ -3768,12 +3776,17 @@ static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv) /* These are interrupts we'll toggle with the ring mask register */ uint32_t gt_interrupts[] = { GT_RENDER_USER_INTERRUPT GEN8_RCS_IRQ_SHIFT | + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_RCS_IRQ_SHIFT | GT_RENDER_L3_PARITY_ERROR_INTERRUPT | - GT_RENDER_USER_INTERRUPT GEN8_BCS_IRQ_SHIFT, + GT_RENDER_USER_INTERRUPT GEN8_BCS_IRQ_SHIFT | + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_BCS_IRQ_SHIFT, GT_RENDER_USER_INTERRUPT GEN8_VCS1_IRQ_SHIFT | - GT_RENDER_USER_INTERRUPT GEN8_VCS2_IRQ_SHIFT, + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_VCS1_IRQ_SHIFT | + GT_RENDER_USER_INTERRUPT GEN8_VCS2_IRQ_SHIFT | + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_VCS2_IRQ_SHIFT, 0, - GT_RENDER_USER_INTERRUPT GEN8_VECS_IRQ_SHIFT + GT_RENDER_USER_INTERRUPT GEN8_VECS_IRQ_SHIFT | + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_VECS_IRQ_SHIFT }; for (i = 0; i ARRAY_SIZE(gt_interrupts); i++) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 4df121b..1138b46 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1062,6 +1062,7 @@ enum punit_power_well { #define RING_ACTHD_UDW(base) ((base)+0x5c) #define RING_NOPID(base) ((base)+0x94) #define RING_IMR(base) ((base)+0xa8) +#define RING_HWSTAM(base) ((base)+0x98) #define RING_TIMESTAMP(base) ((base)+0x358) #define TAIL_ADDR0x0018 #define HEAD_WRAP_COUNT 0xFFE0 @@ -4590,6 +4591,8 @@ enum punit_power_well { #define GEN8_GT_IIR(which)
[Intel-gfx] [PATCH 40/42] drm/i915/bdw: Enable Logical Ring Contexts (hence, Execlists)
From: Oscar Mateo oscar.ma...@intel.com The time has come, the Walrus said, to talk of many things. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9e3e38e..426ef0c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2054,7 +2054,7 @@ struct drm_i915_cmd_table { #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)-need_gfx_hws) #define HAS_HW_CONTEXTS(dev) (INTEL_INFO(dev)-gen = 6) -#define HAS_LOGICAL_RING_CONTEXTS(dev) 0 +#define HAS_LOGICAL_RING_CONTEXTS(dev) (INTEL_INFO(dev)-gen = 8) #define HAS_ALIASING_PPGTT(dev)(INTEL_INFO(dev)-gen = 6) #define HAS_PPGTT(dev) (INTEL_INFO(dev)-gen = 7 !IS_GEN8(dev)) #define USES_PPGTT(dev)intel_enable_ppgtt(dev, false) -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 26/42] drm/i915/bdw: Render state init for Execlists
From: Oscar Mateo oscar.ma...@intel.com The batchbuffer that sets the render context state is submitted in a different way, and from different places. We needed to make both the render state preparation and free functions outside accesible, and namespace accordingly. This mess is so that all LR, LRC and Execlists functionality can go together in intel_lrc.c: we can fix all of this later on, once the interfaces are clear. v2: Create a separate ctx-rcs_initialized for the Execlists case, as suggested by Chris Wilson. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 4 +-- drivers/gpu/drm/i915/i915_gem_context.c | 17 +- drivers/gpu/drm/i915/i915_gem_render_state.c | 40 ++- drivers/gpu/drm/i915/i915_gem_render_state.h | 47 drivers/gpu/drm/i915/intel_lrc.c | 46 +++ drivers/gpu/drm/i915/intel_lrc.h | 2 ++ drivers/gpu/drm/i915/intel_renderstate.h | 8 + 7 files changed, 139 insertions(+), 25 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_gem_render_state.h diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9a3adff..9e3e38e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -37,6 +37,7 @@ #include intel_ringbuffer.h #include intel_lrc.h #include i915_gem_gtt.h +#include i915_gem_render_state.h #include linux/io-mapping.h #include linux/i2c.h #include linux/i2c-algo-bit.h @@ -619,6 +620,7 @@ struct intel_context { } legacy_hw_ctx; /* Execlists */ + bool rcs_initialized; struct { struct drm_i915_gem_object *state; struct intel_ringbuffer *ringbuf; @@ -2546,8 +2548,6 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file *file); -/* i915_gem_render_state.c */ -int i915_gem_render_state_init(struct intel_engine_cs *ring); /* i915_gem_evict.c */ int __must_check i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm, diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 9085ff1..0dc6992 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -513,8 +513,23 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv) ppgtt-enable(ppgtt); } - if (i915.enable_execlists) + if (i915.enable_execlists) { + struct intel_context *dctx; + + ring = dev_priv-ring[RCS]; + dctx = ring-default_context; + + if (!dctx-rcs_initialized) { + ret = intel_lr_context_render_state_init(ring, dctx); + if (ret) { + DRM_ERROR(Init render state failed: %d\n, ret); + return ret; + } + dctx-rcs_initialized = true; + } + return 0; + } /* FIXME: We should make this work, even in reset */ if (i915_reset_in_progress(dev_priv-gpu_error)) diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c index e60be3f..a9a62d7 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.c +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c @@ -28,13 +28,6 @@ #include i915_drv.h #include intel_renderstate.h -struct render_state { - const struct intel_renderstate_rodata *rodata; - struct drm_i915_gem_object *obj; - u64 ggtt_offset; - int gen; -}; - static const struct intel_renderstate_rodata * render_state_get_rodata(struct drm_device *dev, const int gen) { @@ -127,30 +120,47 @@ static int render_state_setup(struct render_state *so) return 0; } -static void render_state_fini(struct render_state *so) +void i915_gem_render_state_fini(struct render_state *so) { i915_gem_object_ggtt_unpin(so-obj); drm_gem_object_unreference(so-obj-base); } -int i915_gem_render_state_init(struct intel_engine_cs *ring) +int i915_gem_render_state_prepare(struct intel_engine_cs *ring, + struct render_state *so) { - struct render_state so; int ret; if (WARN_ON(ring-id != RCS)) return -ENOENT; - ret = render_state_init(so, ring-dev); + ret = render_state_init(so, ring-dev); if (ret) return ret; - if (so.rodata == NULL) + if (so-rodata == NULL) return 0; - ret = render_state_setup(so); + ret = render_state_setup(so); + if (ret) { + i915_gem_render_state_fini(so); + return ret; +
Re: [Intel-gfx] [PATCH 1/7] drm/i915: Read guaranteed freq for valleyview
On Fri, Jul 11, 2014 at 05:42:48PM +0300, Mika Kuoppala wrote: deepa...@linux.intel.com writes: From: Deepak S deepa...@linux.intel.com Reading RP1 for valleyview to help us enable pm_rps i-g-t testcase execution. Signed-off-by: Deepak S deepa...@linux.intel.com Reviewed-by: Mika Kuoppala mika.kuopp...@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d1af641..b8e7afc 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3816,6 +3816,17 @@ int cherryview_rps_min_freq(struct drm_i915_private *dev_priv) return rpn; } +int valleyview_rps_guar_freq(struct drm_i915_private *dev_priv) Missing static here. Fixed and queued for -next, thanks for the patch. -Daniel +{ + u32 val, rp1; + + val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FREQ_FUSE); + + rp1 = (val FB_GFX_FGUARANTEED_FREQ_FUSE_MASK) FB_GFX_FGUARANTEED_FREQ_FUSE_SHIFT; + + return rp1; +} + int valleyview_rps_max_freq(struct drm_i915_private *dev_priv) { u32 val, rp0; @@ -3958,6 +3969,11 @@ static void valleyview_init_gt_powersave(struct drm_device *dev) vlv_gpu_freq(dev_priv, dev_priv-rps.efficient_freq), dev_priv-rps.efficient_freq); + dev_priv-rps.rp1_freq = valleyview_rps_guar_freq(dev_priv); + DRM_DEBUG_DRIVER(RP1(Guar Freq) GPU freq: %d MHz (%u)\n, +vlv_gpu_freq(dev_priv, dev_priv-rps.rp1_freq), +dev_priv-rps.rp1_freq); + dev_priv-rps.min_freq = valleyview_rps_min_freq(dev_priv); DRM_DEBUG_DRIVER(min GPU freq: %d MHz (%u)\n, vlv_gpu_freq(dev_priv, dev_priv-rps.min_freq), -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v2 1/3] drm/i915: CHV GPU frequency to opcode functions
On Sat, Jul 12, 2014 at 02:54:33PM +0530, deepa...@linux.intel.com wrote: From: Deepak S deepa...@linux.intel.com Adding chv specific fre/encode conversion. v2: Remove generic function and platform check (Daniel) Signed-off-by: Deepak S deepa...@linux.intel.com When resubmitting patches into an existing patchbomb thread please use --in-reply-to the old patch this new one here replaces. Otherwise I'll have a good chance to pick up patches out of order or the wrong ones. Thanks, Daniel --- drivers/gpu/drm/i915/intel_pm.c | 78 +++-- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 6892421..f673e1b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6931,7 +6931,7 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val) return 0; } -int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val) +int byt_gpu_freq(struct drm_i915_private *dev_priv, int val) { int div; @@ -6953,7 +6953,7 @@ int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val) return DIV_ROUND_CLOSEST(dev_priv-mem_freq * (val + 6 - 0xbd), 4 * div); } -int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val) +int byt_freq_opcode(struct drm_i915_private *dev_priv, int val) { int mul; @@ -6975,6 +6975,80 @@ int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val) return DIV_ROUND_CLOSEST(4 * mul * val, dev_priv-mem_freq) + 0xbd - 6; } +int chv_gpu_freq(struct drm_i915_private *dev_priv, int val) +{ + int div, freq; + + switch (dev_priv-rps.cz_freq) { + case 200: + div = 5; + break; + case 267: + div = 6; + break; + case 320: + case 333: + case 400: + div = 8; + break; + default: + return -1; + } + + freq = (DIV_ROUND_CLOSEST((dev_priv-rps.cz_freq * val), 2 * div) / 2); + + return freq; +} + +int chv_freq_opcode(struct drm_i915_private *dev_priv, int val) +{ + int mul, opcode; + + switch (dev_priv-rps.cz_freq) { + case 200: + mul = 5; + break; + case 267: + mul = 6; + break; + case 320: + case 333: + case 400: + mul = 8; + break; + default: + return -1; + } + + opcode = (DIV_ROUND_CLOSEST((val * 2 * mul), dev_priv-rps.cz_freq) * 2); + + return opcode; +} + +int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val) +{ + int ret = -1; + + if (IS_CHERRYVIEW(dev_priv-dev)) + ret = chv_gpu_freq(dev_priv, val); + else if (IS_VALLEYVIEW(dev_priv-dev)) + ret = byt_gpu_freq(dev_priv, val); + + return ret; +} + +int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val) +{ + int ret = -1; + + if (IS_CHERRYVIEW(dev_priv-dev)) + ret = chv_freq_opcode(dev_priv, val); + else if (IS_VALLEYVIEW(dev_priv-dev)) + ret = byt_freq_opcode(dev_priv, val); + + return ret; +} + void intel_pm_setup(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev-dev_private; -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 2/7] drm/i915: Add RP0/RP1/RPn render P state thresholds in VLV sysfs
On Thu, Jul 10, 2014 at 01:16:22PM +0530, deepa...@linux.intel.com wrote: From: Deepak S deepa...@linux.intel.com This is useful for userspace utilities to verify and micromanaging the increase/decrease frequncy. Signed-off-by: Deepak S deepa...@linux.intel.com --- drivers/gpu/drm/i915/i915_sysfs.c | 18 +++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 86ce39a..b15c8ce 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -461,11 +461,20 @@ static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr mutex_unlock(dev-struct_mutex); if (attr == dev_attr_gt_RP0_freq_mhz) { - val = ((rp_state_cap 0xff) 0) * GT_FREQUENCY_MULTIPLIER; + if (IS_VALLEYVIEW(dev)) + val = vlv_gpu_freq(dev_priv, dev_priv-rps.rp0_freq); + else + val = ((rp_state_cap 0xff) 0) * GT_FREQUENCY_MULTIPLIER; } else if (attr == dev_attr_gt_RP1_freq_mhz) { - val = ((rp_state_cap 0x00ff00) 8) * GT_FREQUENCY_MULTIPLIER; + if (IS_VALLEYVIEW(dev)) + val = vlv_gpu_freq(dev_priv, dev_priv-rps.rp1_freq); + else + val = ((rp_state_cap 0x00ff00) 8) * GT_FREQUENCY_MULTIPLIER; } else if (attr == dev_attr_gt_RPn_freq_mhz) { - val = ((rp_state_cap 0xff) 16) * GT_FREQUENCY_MULTIPLIER; + if (IS_VALLEYVIEW(dev)) + val = vlv_gpu_freq(dev_priv, dev_priv-rps.min_freq); + else + val = ((rp_state_cap 0xff) 16) * GT_FREQUENCY_MULTIPLIER; } else { BUG(); } @@ -486,6 +495,9 @@ static const struct attribute *vlv_attrs[] = { dev_attr_gt_cur_freq_mhz.attr, dev_attr_gt_max_freq_mhz.attr, dev_attr_gt_min_freq_mhz.attr, + dev_attr_gt_RP0_freq_mhz.attr, + dev_attr_gt_RP1_freq_mhz.attr, + dev_attr_gt_RPn_freq_mhz.attr, dev_attr_vlv_rpe_freq_mhz.attr, NULL, }; This now exactly matches gen6_attrs, so I've killed it while applying. -Daniel -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/sysfs: Merge vlv_attrs with gen6_attrs
They match now. Cc: Deepak S deepa...@linux.intel.com Cc: Mika Kuoppala mika.kuopp...@intel.com Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_sysfs.c | 20 ++-- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index b15c8cee103b..32e4302a4608 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -491,17 +491,6 @@ static const struct attribute *gen6_attrs[] = { NULL, }; -static const struct attribute *vlv_attrs[] = { - dev_attr_gt_cur_freq_mhz.attr, - dev_attr_gt_max_freq_mhz.attr, - dev_attr_gt_min_freq_mhz.attr, - dev_attr_gt_RP0_freq_mhz.attr, - dev_attr_gt_RP1_freq_mhz.attr, - dev_attr_gt_RPn_freq_mhz.attr, - dev_attr_vlv_rpe_freq_mhz.attr, - NULL, -}; - static ssize_t error_state_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) @@ -593,9 +582,7 @@ void i915_setup_sysfs(struct drm_device *dev) } ret = 0; - if (IS_VALLEYVIEW(dev)) - ret = sysfs_create_files(dev-primary-kdev-kobj, vlv_attrs); - else if (INTEL_INFO(dev)-gen = 6) + if (INTEL_INFO(dev)-gen = 6) ret = sysfs_create_files(dev-primary-kdev-kobj, gen6_attrs); if (ret) DRM_ERROR(RPS sysfs setup failed\n); @@ -609,10 +596,7 @@ void i915_setup_sysfs(struct drm_device *dev) void i915_teardown_sysfs(struct drm_device *dev) { sysfs_remove_bin_file(dev-primary-kdev-kobj, error_state_attr); - if (IS_VALLEYVIEW(dev)) - sysfs_remove_files(dev-primary-kdev-kobj, vlv_attrs); - else - sysfs_remove_files(dev-primary-kdev-kobj, gen6_attrs); + sysfs_remove_files(dev-primary-kdev-kobj, gen6_attrs); device_remove_bin_file(dev-primary-kdev, dpf_attrs_1); device_remove_bin_file(dev-primary-kdev, dpf_attrs); #ifdef CONFIG_PM -- 2.0.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 04/42] drm/i915/bdw: Introduce one context backing object per engine
From: Oscar Mateo oscar.ma...@intel.com A context backing object only makes sense for a given engine (because it holds state data specific to that engine). In legacy ringbuffer sumission mode, the only MI_SET_CONTEXT we really perform is for the render engine, so one backing object is all we nee. With Execlists, however, we need backing objects for every engine, as contexts become the only way to submit workloads to the GPU. To tackle this problem, we multiplex the context struct to contain no-of-engines objects. Originally, I colored this code by instantiating one new context for every engine I wanted to use, but this change suggested by Brad Volkin makes it more elegant. v2: Leave the old backing object pointer behind. Daniel Vetter suggested using a union, but it makes more sense to keep rcs_state as a NULL pointer behind, to make sure no one uses it incorrectly when Execlists are enabled, similar to what he suggested for ring-buffer (Rusty's API level 5). v3: Use the name state instead of the too-generic obj, so that it mirrors the name choice for the legacy rcs_state. Signed-off-by: Oscar Mateo oscar.ma...@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bb7ddd1..0ebf41b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -612,11 +612,17 @@ struct intel_context { struct i915_ctx_hang_stats hang_stats; struct i915_address_space *vm; + /* Legacy ring buffer submission */ struct { struct drm_i915_gem_object *rcs_state; bool initialized; } legacy_hw_ctx; + /* Execlists */ + struct { + struct drm_i915_gem_object *state; + } engine[I915_NUM_RINGS]; + struct list_head link; }; -- 1.9.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx