[Intel-gfx] [PATCH] drm/i915: Program the correct frequencies into the interrupt thresholds
The only question is the units for the interrupt thresholds. Everywhere we treat the min/max frequencies in units of 50MHz. However, indications seem to be that we expect the thresholds in units of 100MHz - though currently we program them using the 50MHz values. Cc: Jesse Barnes jbar...@virtuousgeek.org --- drivers/gpu/drm/i915/intel_pm.c | 28 +++- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 73cf311..bb10582 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2187,7 +2187,6 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); u32 pcu_mbox, rc6_mask = 0; u32 gtfifodbg; - int cur_freq, min_freq, max_freq; int rc6_mode; int i; @@ -2208,6 +2207,14 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) gen6_gt_force_wake_get(dev_priv); + rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); + gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); + + /* In units of 100MHz */ + dev_priv-max_delay = rp_state_cap 0xff; + dev_priv-min_delay = (rp_state_cap 0xff) 16; + dev_priv-cur_delay = (gt_perf_status 0xff00) 8; + /* disable the counters and set deterministic thresholds */ I915_WRITE(GEN6_RC_CONTROL, 0); @@ -2255,8 +2262,8 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 100); I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, - 18 24 | - 6 16); + dev_priv-max_delay 24 | + dev_priv-min_delay 16); I915_WRITE(GEN6_RP_UP_THRESHOLD, 1); I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 100); I915_WRITE(GEN6_RP_UP_EI, 10); @@ -2282,10 +2289,6 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) 500)) DRM_ERROR(timeout waiting for pcode mailbox to finish\n); - min_freq = (rp_state_cap 0xff) 16; - max_freq = rp_state_cap 0xff; - cur_freq = (gt_perf_status 0xff00) 8; - /* Check for overclock support */ if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) GEN6_PCODE_READY) == 0, 500)) @@ -2296,14 +2299,13 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) 500)) DRM_ERROR(timeout waiting for pcode mailbox to finish\n); if (pcu_mbox (131)) { /* OC supported */ - max_freq = pcu_mbox 0xff; + dev_priv-max_delay = pcu_mbox 0xff; DRM_DEBUG_DRIVER(overclocking supported, adjusting frequency max to %dMHz\n, pcu_mbox * 50); - } - /* In units of 100MHz */ - dev_priv-max_delay = max_freq; - dev_priv-min_delay = min_freq; - dev_priv-cur_delay = cur_freq; + I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, + dev_priv-max_delay 24 | + dev_priv-min_delay 16); + } /* requires MSI enabled */ I915_WRITE(GEN6_PMIER, -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Periodically sanity check power management
Every time we use the device after a period of idleness, check that the power management setup is still sane. This is to workaround a bug whereby it seems that we begin suppressing power management interrupts, preventing SandyBridge+ from going into turbo mode. This patch does have a side-effect. It removes the mark-busy for just moving the cursor - we don't want to increase the render clock just for the sprite, though we may want to bump the display frequency. I'd argue that we do not, and certainly don't want to take the struct_mutex here due to the large latencies that introduces. References: https://bugs.freedesktop.org/show_bug.cgi?id=44006 Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h |1 + drivers/gpu/drm/i915/intel_display.c |8 +++- drivers/gpu/drm/i915/intel_drv.h |2 ++ drivers/gpu/drm/i915/intel_pm.c | 37 ++ 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6b6eb49..bf34316 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -240,6 +240,7 @@ struct drm_i915_display_funcs { void (*update_wm)(struct drm_device *dev); void (*update_sprite_wm)(struct drm_device *dev, int pipe, uint32_t sprite_width, int pixel_size); + void (*sanitize_pm)(struct drm_device *dev); int (*crtc_mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 05c6e66..40fac16 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4982,9 +4982,6 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc, else i9xx_update_cursor(crtc, base); } - - if (visible) - intel_mark_busy(dev, to_intel_framebuffer(crtc-fb)-obj); } static int intel_crtc_cursor_set(struct drm_crtc *crtc, @@ -5697,9 +5694,10 @@ void intel_mark_busy(struct drm_device *dev, struct drm_i915_gem_object *obj) if (!drm_core_check_feature(dev, DRIVER_MODESET)) return; - if (!dev_priv-busy) + if (!dev_priv-busy) { + intel_sanitize_pm(dev); dev_priv-busy = true; - else + } else mod_timer(dev_priv-idle_timer, jiffies + msecs_to_jiffies(GPU_IDLE_TIMEOUT)); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b4d39f2..a57f0fb 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -351,6 +351,8 @@ void intel_plane_cleanup(struct intel_plane *plane); extern void intel_flush_display_plane(struct drm_i915_private *dev_priv, enum plane plane); +void intel_sanitize_pm(struct drm_device *dev); + /* intel_panel.c */ extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, struct drm_display_mode *adjusted_mode); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 3b05ba3..1b7cc51 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2938,6 +2938,41 @@ void intel_init_clock_gating(struct drm_device *dev) dev_priv-display.init_pch_clock_gating(dev); } +static void gen6_sanitize_pm(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + u32 limits, delay, old; + + gen6_gt_force_wake_get(dev_priv); + + old = limits = I915_READ(GEN6_RP_INTERRUPT_LIMITS); + /* Make sure we continue to get interrupts +* until we hit the minimum or maximum frequencies. +*/ + limits = ~(0x3f 16 | 0x3f 24); + delay = dev_priv-cur_delay; + if (delay dev_priv-max_delay) + limits |= (dev_priv-max_delay 0x3f) 24; + if (delay dev_priv-min_delay) + limits |= (dev_priv-min_delay 0x3f) 16; + + if (old != limits) { + DRM_ERROR(Power management discrepancy: GEN6_RP_INTERRUPT_LIMITS expected %08x, was %08x\n, + limits, old); + I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits); + } + + gen6_gt_force_wake_put(dev_priv); +} + +void intel_sanitize_pm(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + + if (dev_priv-display.sanitize_pm) + dev_priv-display.sanitize_pm(dev); +} + /* Set up chip specific power management-related functions */ void intel_init_pm(struct drm_device *dev) { @@ -3014,6 +3049,7 @@ void intel_init_pm(struct drm_device *dev)
[Intel-gfx] [pull] drm-intel-fixes for 3.4
Hi Dave, Nothing major here and imo can wait a bit if you don't have anything important in drm-fixes yet: - VGA load-detect fix. This bug seems to be as old as the load-detect code (2.6.30), but needs stupid userspace (upowerd trying to detect connectors on dpms-off outputs) to actually kill the machine. And obviously a machine without VGA-hotplug, otherwise we don't do load detect. - 2 interger overflow fixes for unpriviledged ioctls from Xi Wang. Yours, Daniel The following changes since commit 66f75a5d028beaf67c931435fdc3e7823125730c: Linux 3.4-rc4 (2012-04-21 14:47:52 -0700) are available in the git repository at: git://people.freedesktop.org/~danvet/drm-intel drm-intel-fixes for you to fetch changes up to 44afb3a04391a74309d16180d1e4f8386fdfa745: drm/i915: fix integer overflow in i915_gem_do_execbuffer() (2012-04-23 22:32:15 +0200) Daniel Vetter (1): drm/i915: fixup load-detect on enabled, but not active pipe Xi Wang (2): drm/i915: fix integer overflow in i915_gem_execbuffer2() drm/i915: fix integer overflow in i915_gem_do_execbuffer() drivers/gpu/drm/i915/i915_gem_execbuffer.c |8 +++- drivers/gpu/drm/i915/intel_crt.c | 29 +++- 2 files changed, 18 insertions(+), 19 deletions(-) -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: use the new masked bit macro some more
I've missed this one. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_reg.h |1 - drivers/gpu/drm/i915/intel_pm.c |3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f1f4d8f..529e0c9 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -635,7 +635,6 @@ #define MI_ARB_DISPLAY_PRIORITY_B_A (1 0)/* display B display A */ #define CACHE_MODE_0 0x02120 /* 915+ only */ -#define CM0_MASK_SHIFT 16 #define CM0_IZ_OPT_DISABLE (16) #define CM0_ZR_OPT_DISABLE (15) #define CM0_STC_EVICT_DISABLE_LRA_SNB (15) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0552058..e66330c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2663,9 +2663,8 @@ static void gen6_init_clock_gating(struct drm_device *dev) I915_WRITE(WM2_LP_ILK, 0); I915_WRITE(WM1_LP_ILK, 0); - /* clear masked bit */ I915_WRITE(CACHE_MODE_0, - CM0_STC_EVICT_DISABLE_LRA_SNB CM0_MASK_SHIFT); + _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB)); I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) | -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [pull] drm-intel-fixes for 3.4
On Thu, Apr 26, 2012 at 05:35:01PM +0200, Daniel Vetter wrote: Hi Dave, Nothing major here and imo can wait a bit if you don't have anything important in drm-fixes yet: - VGA load-detect fix. This bug seems to be as old as the load-detect code (2.6.30), but needs stupid userspace (upowerd trying to detect connectors on dpms-off outputs) to actually kill the machine. And obviously a machine without VGA-hotplug, otherwise we don't do load detect. - 2 interger overflow fixes for unpriviledged ioctls from Xi Wang. A tested-by for a regression fix just arrived, so I've thrown that in, too: - Fix SDVO regression for low-res (pixelclock 100MHz) digital outputs, introduce in 2.6.36. Cheers, Daniel The following changes since commit 66f75a5d028beaf67c931435fdc3e7823125730c: Linux 3.4-rc4 (2012-04-21 14:47:52 -0700) are available in the git repository at: git://people.freedesktop.org/~danvet/drm-intel drm-intel-fixes for you to fetch changes up to 6651819b4b4fc3caa6964c5d825eb4bb996f3905: drm/i915: handle input/output sdvo timings separately in mode_set (2012-04-26 18:56:26 +0200) Daniel Vetter (2): drm/i915: fixup load-detect on enabled, but not active pipe drm/i915: handle input/output sdvo timings separately in mode_set Xi Wang (2): drm/i915: fix integer overflow in i915_gem_execbuffer2() drm/i915: fix integer overflow in i915_gem_do_execbuffer() drivers/gpu/drm/i915/i915_gem_execbuffer.c |8 ++- drivers/gpu/drm/i915/intel_crt.c | 29 +--- drivers/gpu/drm/i915/intel_sdvo.c | 34 +++- 3 files changed, 36 insertions(+), 35 deletions(-) -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/4] drm/i915: clear up backlight inversion confusion on gen4
There's a bit in the docs for gen4 only that says whether the backlight control is inverted. And both the quirk we have and all bugs only concern i965gm and gm45 (and mostly Acer) afaics. So lets drop the quirk and use the bit instead. Also clean up the BLC register definitions a bit by correctly grouping the CTL and CTL2 definitions together. This quirk was originally added in commit 5a15ab5b93e4a3ebcd4fa6c76cf646a45e9cf806 Author: Carsten Emde c.e...@osadl.org Date: Thu Mar 15 15:56:27 2012 +0100 drm/i915: panel: invert brightness acer aspire 5734z References: https://bugzilla.kernel.org/show_bug.cgi?id=31522 References: https://bugs.freedesktop.org/show_bug.cgi?id=37986 References: https://bugs.freedesktop.org/show_bug.cgi?id=40455 Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Signed-off-by: Carsten Emde c.e...@osadl.org --- drivers/gpu/drm/i915/i915_reg.h |7 --- drivers/gpu/drm/i915/intel_display.c |3 --- drivers/gpu/drm/i915/intel_panel.c |4 3 files changed, 8 insertions(+), 6 deletions(-) Index: linux-tip/drivers/gpu/drm/i915/i915_reg.h === --- linux-tip.orig/drivers/gpu/drm/i915/i915_reg.h +++ linux-tip/drivers/gpu/drm/i915/i915_reg.h @@ -1683,16 +1683,17 @@ #define PFIT_AUTO_RATIOS 0x61238 /* Backlight control */ -#define BLC_PWM_CTL0x61254 -#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) #define BLC_PWM_CTL2 0x61250 /* 965+ only */ -#define BLM_COMBINATION_MODE (1 30) +#define BLM_COMBINATION_MODE (1 30) +#define BLM_POLARITY_I965(1 28) /* gen4 only */ +#define BLC_PWM_CTL0x61254 /* * This is the most significant 15 bits of the number of backlight cycles in a * complete cycle of the modulated backlight control. * * The actual value is this field multiplied by two. */ +#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) #define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff 17) #define BLM_LEGACY_MODE (1 16) /* Index: linux-tip/drivers/gpu/drm/i915/intel_display.c === --- linux-tip.orig/drivers/gpu/drm/i915/intel_display.c +++ linux-tip/drivers/gpu/drm/i915/intel_display.c @@ -9143,9 +9143,6 @@ struct intel_quirk intel_quirks[] = { /* Sony Vaio Y cannot use SSC on LVDS */ { 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable }, - - /* Acer Aspire 5734Z must invert backlight brightness */ - { 0x2a42, 0x1025, 0x0459, quirk_invert_brightness }, }; static void intel_init_quirks(struct drm_device *dev) Index: linux-tip/drivers/gpu/drm/i915/intel_panel.c === --- linux-tip.orig/drivers/gpu/drm/i915/intel_panel.c +++ linux-tip/drivers/gpu/drm/i915/intel_panel.c @@ -208,6 +208,10 @@ static u32 intel_panel_compute_brightnes dev_priv-quirks QUIRK_INVERT_BRIGHTNESS) return intel_panel_get_max_backlight(dev) - val; + /* gen4 has a polarity bit */ + if (IS_GEN4(dev) (I915_READ(BLC_PWM_CTL2) BLM_POLARITY_I965)) + return intel_panel_get_max_backlight(dev) - val; + return val; } ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 0/4] drm/i915: Re: clear up backlight inversion confusion on gen4
On 04/23/2012 06:55 PM, Carsten Emde wrote: On 04/23/2012 05:56 PM, Daniel Vetter wrote: On Mon, Apr 23, 2012 at 05:38:27PM +0200, Carsten Emde wrote: On 04/23/2012 05:22 PM, Daniel Vetter wrote: Ok, so the polarity bit does work as advertised. But I still don't understand how your machine works, Let's go ahead and summarize what we have up to now. 1. With KMS enabled, the backlight panel of the Acer Aspire 5734Z remains dark. 2. Further evaluation showed that the brightness is inverted on this machine, i.e. while setting the Legacy Backlight Brightness (LBB) register to 0x0 normally causes the backlight to be turned off, and 0xFF causes the backlight to be set to 100% intensity, the Acer Aspire 5734Z turns the backlight off at 0xFF and sets it to maximum intensity at 0. 3. In a first step, a quirk was introduced to cope with this particular oddity. 4. Daniel Vetter found out there is a bit in the 2nd backlight control register (BLC_PWM_CTL2) that indicates panel backlight brightness is inverted. 5. On the Acer Aspire 5734Z, however, this bit is not set. 6. Chris Wilson found out that Daniel's bit #28 sometimes could be bit #29. 7. On the Aspire 5734Z, bit #29 is set. As a conclusion, I have prepared a patch series that - uses Danieĺ's patch to invert brightness, if required, - reverts the quirk to invert backlight brightness, - introduces a new quirk to indicate bit #29 instead of #28 is used, - marks the Acer Aspire 5734Z to use the quirked bit. With these patches applied, the Acer Aspire 5734Z works. -Carsten. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/4] drm/i915: completely revert the invert brightness quirk
The quirk to indicate that the panel backlight brightness is inverted is not longer needed. Remove it. Signed-off-by: Carsten Emde c.e...@osadl.org --- drivers/gpu/drm/i915/i915_drv.h |1 - drivers/gpu/drm/i915/intel_display.c | 10 -- 2 files changed, 11 deletions(-) Index: linux-tip/drivers/gpu/drm/i915/i915_drv.h === --- linux-tip.orig/drivers/gpu/drm/i915/i915_drv.h +++ linux-tip/drivers/gpu/drm/i915/i915_drv.h @@ -295,7 +295,6 @@ enum intel_pch { #define QUIRK_PIPEA_FORCE (10) #define QUIRK_LVDS_SSC_DISABLE (11) -#define QUIRK_INVERT_BRIGHTNESS (12) struct intel_fbdev; struct intel_fbc_work; Index: linux-tip/drivers/gpu/drm/i915/intel_display.c === --- linux-tip.orig/drivers/gpu/drm/i915/intel_display.c +++ linux-tip/drivers/gpu/drm/i915/intel_display.c @@ -9101,16 +9101,6 @@ static void quirk_ssc_force_disable(stru dev_priv-quirks |= QUIRK_LVDS_SSC_DISABLE; } -/* - * A machine (e.g. Acer Aspire 5734Z) may need to invert the panel backlight - * brightness value - */ -static void quirk_invert_brightness(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev-dev_private; - dev_priv-quirks |= QUIRK_INVERT_BRIGHTNESS; -} - struct intel_quirk { int device; int subsystem_vendor; ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 4/4] drm/i915: assign the brightness inversion quirk to Acer Aspire 5734Z
The Acer Aspire 5734Z uses bit #29 instead of bit #28 to indicate that the panel backlight brightness is inverted. Assign it to the related quirk. Signed-off-by: Carsten Emde c.e...@osadl.org --- drivers/gpu/drm/i915/intel_display.c |6 ++ 1 file changed, 6 insertions(+) Index: linux-tip/drivers/gpu/drm/i915/intel_display.c === --- linux-tip.orig/drivers/gpu/drm/i915/intel_display.c +++ linux-tip/drivers/gpu/drm/i915/intel_display.c @@ -9143,6 +9143,12 @@ struct intel_quirk intel_quirks[] = { /* Sony Vaio Y cannot use SSC on LVDS */ { 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable }, + + /* +* Acer Aspire 5734Z uses an alternate bit to indicate +* panel backlight brightness inversion +*/ + { 0x2a42, 0x1025, 0x0459, quirk_alt_bit_for_brightness_inversion }, }; static void intel_init_quirks(struct drm_device *dev) ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/4] drm/i915: add quirk to indicate that an alt bit is used for brightness inversion
Bit #28 of the backlight control BLC_PWM_CTL2 is normally used to indicate whether the brightness of the panel backlight is inverted. Sometimes, however, bit #29 is used for this purpose. Add a quirk to mark machines that do so. Signed-off-by: Carsten Emde c.e...@osadl.org --- drivers/gpu/drm/i915/i915_drv.h |1 + drivers/gpu/drm/i915/i915_reg.h |1 + drivers/gpu/drm/i915/intel_display.c | 10 ++ drivers/gpu/drm/i915/intel_panel.c | 12 ++-- 4 files changed, 22 insertions(+), 2 deletions(-) Index: linux-tip/drivers/gpu/drm/i915/i915_drv.h === --- linux-tip.orig/drivers/gpu/drm/i915/i915_drv.h +++ linux-tip/drivers/gpu/drm/i915/i915_drv.h @@ -295,6 +295,7 @@ enum intel_pch { #define QUIRK_PIPEA_FORCE (10) #define QUIRK_LVDS_SSC_DISABLE (11) +#define QUIRK_ALT_BIT_FOR_BRIGHTNESS_INVERSION (21) struct intel_fbdev; struct intel_fbc_work; Index: linux-tip/drivers/gpu/drm/i915/i915_reg.h === --- linux-tip.orig/drivers/gpu/drm/i915/i915_reg.h +++ linux-tip/drivers/gpu/drm/i915/i915_reg.h @@ -1685,6 +1685,7 @@ /* Backlight control */ #define BLC_PWM_CTL2 0x61250 /* 965+ only */ #define BLM_COMBINATION_MODE (1 30) +#define BLM_ALT_POLARITY_I965(1 29) /* quirk only */ #define BLM_POLARITY_I965(1 28) /* gen4 only */ #define BLC_PWM_CTL0x61254 /* Index: linux-tip/drivers/gpu/drm/i915/intel_display.c === --- linux-tip.orig/drivers/gpu/drm/i915/intel_display.c +++ linux-tip/drivers/gpu/drm/i915/intel_display.c @@ -9101,6 +9101,16 @@ static void quirk_ssc_force_disable(stru dev_priv-quirks |= QUIRK_LVDS_SSC_DISABLE; } +/* + * A machine may use an alternate bit to indicate panel backlight brightness + * inversion + */ +static void quirk_alt_bit_for_brightness_inversion(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + dev_priv-quirks |= QUIRK_ALT_BIT_FOR_BRIGHTNESS_INVERSION; +} + struct intel_quirk { int device; int subsystem_vendor; Index: linux-tip/drivers/gpu/drm/i915/intel_panel.c === --- linux-tip.orig/drivers/gpu/drm/i915/intel_panel.c +++ linux-tip/drivers/gpu/drm/i915/intel_panel.c @@ -208,9 +208,17 @@ static u32 intel_panel_compute_brightnes dev_priv-quirks QUIRK_INVERT_BRIGHTNESS) return intel_panel_get_max_backlight(dev) - val; - /* gen4 has a polarity bit */ - if (IS_GEN4(dev) (I915_READ(BLC_PWM_CTL2) BLM_POLARITY_I965)) + if (IS_GEN4(dev)) { + /* gen4 has a - possibly quirked - polarity bit */ + int mask; + + if (dev_priv-quirks QUIRK_ALT_BIT_FOR_BRIGHTNESS_INVERSION) + mask = BLM_ALT_POLARITY_I965; + else + mask = BLM_POLARITY_I965; + if (I915_READ(BLC_PWM_CTL2) mask) return intel_panel_get_max_backlight(dev) - val; + } return val; } ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 3/4] drm/i915: add quirk to indicate that an alt bit is used for brightness inversion
On Thu, Apr 26, 2012 at 06:48:36PM +0200, Carsten Emde wrote: Bit #28 of the backlight control BLC_PWM_CTL2 is normally used to indicate whether the brightness of the panel backlight is inverted. Sometimes, however, bit #29 is used for this purpose. Add a quirk to mark machines that do so. Signed-off-by: Carsten Emde c.e...@osadl.org --- drivers/gpu/drm/i915/i915_drv.h |1 + drivers/gpu/drm/i915/i915_reg.h |1 + drivers/gpu/drm/i915/intel_display.c | 10 ++ drivers/gpu/drm/i915/intel_panel.c | 12 ++-- 4 files changed, 22 insertions(+), 2 deletions(-) Index: linux-tip/drivers/gpu/drm/i915/i915_drv.h === --- linux-tip.orig/drivers/gpu/drm/i915/i915_drv.h +++ linux-tip/drivers/gpu/drm/i915/i915_drv.h @@ -295,6 +295,7 @@ enum intel_pch { #define QUIRK_PIPEA_FORCE (10) #define QUIRK_LVDS_SSC_DISABLE (11) +#define QUIRK_ALT_BIT_FOR_BRIGHTNESS_INVERSION (21) struct intel_fbdev; struct intel_fbc_work; Index: linux-tip/drivers/gpu/drm/i915/i915_reg.h === --- linux-tip.orig/drivers/gpu/drm/i915/i915_reg.h +++ linux-tip/drivers/gpu/drm/i915/i915_reg.h @@ -1685,6 +1685,7 @@ /* Backlight control */ #define BLC_PWM_CTL2 0x61250 /* 965+ only */ #define BLM_COMBINATION_MODE (1 30) +#define BLM_ALT_POLARITY_I965 (1 29) /* quirk only */ bit29 is the pipe select bit, i.e. the backlight controller uses the pixel clock from this pipe as the signal to module the backlight. I need to look some more into this. -Daniel #define BLM_POLARITY_I965 (1 28) /* gen4 only */ #define BLC_PWM_CTL 0x61254 /* Index: linux-tip/drivers/gpu/drm/i915/intel_display.c === --- linux-tip.orig/drivers/gpu/drm/i915/intel_display.c +++ linux-tip/drivers/gpu/drm/i915/intel_display.c @@ -9101,6 +9101,16 @@ static void quirk_ssc_force_disable(stru dev_priv-quirks |= QUIRK_LVDS_SSC_DISABLE; } +/* + * A machine may use an alternate bit to indicate panel backlight brightness + * inversion + */ +static void quirk_alt_bit_for_brightness_inversion(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + dev_priv-quirks |= QUIRK_ALT_BIT_FOR_BRIGHTNESS_INVERSION; +} + struct intel_quirk { int device; int subsystem_vendor; Index: linux-tip/drivers/gpu/drm/i915/intel_panel.c === --- linux-tip.orig/drivers/gpu/drm/i915/intel_panel.c +++ linux-tip/drivers/gpu/drm/i915/intel_panel.c @@ -208,9 +208,17 @@ static u32 intel_panel_compute_brightnes dev_priv-quirks QUIRK_INVERT_BRIGHTNESS) return intel_panel_get_max_backlight(dev) - val; - /* gen4 has a polarity bit */ - if (IS_GEN4(dev) (I915_READ(BLC_PWM_CTL2) BLM_POLARITY_I965)) + if (IS_GEN4(dev)) { + /* gen4 has a - possibly quirked - polarity bit */ + int mask; + + if (dev_priv-quirks QUIRK_ALT_BIT_FOR_BRIGHTNESS_INVERSION) + mask = BLM_ALT_POLARITY_I965; + else + mask = BLM_POLARITY_I965; + if (I915_READ(BLC_PWM_CTL2) mask) return intel_panel_get_max_backlight(dev) - val; + } return val; } -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] properly enable the blc controller on the right pipe
Depending upon how things are set up, this might help. If not, please install intel-gpu-tools and grab the output of intel_reg_dumper both when booting with nomodeset and when booting with kms. Thanks, Daniel --- drivers/gpu/drm/i915/intel_drv.h |3 ++- drivers/gpu/drm/i915/intel_lvds.c |3 ++- drivers/gpu/drm/i915/intel_panel.c | 15 ++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 715afa1..5a021ce 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -323,7 +323,8 @@ extern u32 intel_panel_get_max_backlight(struct drm_device *dev); extern u32 intel_panel_get_backlight(struct drm_device *dev); extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); extern int intel_panel_setup_backlight(struct drm_device *dev); -extern void intel_panel_enable_backlight(struct drm_device *dev); +extern void intel_panel_enable_backlight(struct drm_device *dev, +enum pipe pipe); extern void intel_panel_disable_backlight(struct drm_device *dev); extern void intel_panel_destroy_backlight(struct drm_device *dev); extern enum drm_connector_status intel_panel_detect(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 30e2c82..3e71b86 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -71,6 +71,7 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector) static void intel_lvds_enable(struct intel_lvds *intel_lvds) { struct drm_device *dev = intel_lvds-base.base.dev; + struct intel_crtc *intel_crtc = to_intel_crtc(intel_lvds-base.base.crtc); struct drm_i915_private *dev_priv = dev-dev_private; u32 ctl_reg, lvds_reg, stat_reg; @@ -107,7 +108,7 @@ static void intel_lvds_enable(struct intel_lvds *intel_lvds) if (wait_for((I915_READ(stat_reg) PP_ON) != 0, 1000)) DRM_ERROR(timed out waiting for panel to power on\n); - intel_panel_enable_backlight(dev); + intel_panel_enable_backlight(dev, intel_crtc-pipe); } static void intel_lvds_disable(struct intel_lvds *intel_lvds) diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 48177ec..486cf92 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -261,17 +261,30 @@ void intel_panel_disable_backlight(struct drm_device *dev) dev_priv-backlight_enabled = false; intel_panel_actually_set_backlight(dev, 0); + + /*disable the blc*/ + I915_WRITE(BLC_PWM_CTL2, + I915_READ(BLC_PWM_CTL2) ~(131)); } -void intel_panel_enable_backlight(struct drm_device *dev) +void intel_panel_enable_backlight(struct drm_device *dev, + enum pipe pipe) { struct drm_i915_private *dev_priv = dev-dev_private; + u32 tmp; if (dev_priv-backlight_level == 0) dev_priv-backlight_level = intel_panel_get_max_backlight(dev); dev_priv-backlight_enabled = true; intel_panel_actually_set_backlight(dev, dev_priv-backlight_level); + + /*enable the blc on the right pipe*/ + tmp = I915_READ(BLC_PWM_CTL2); + tmp = ~(129); /* pipe select */ + tmp |= pipe == PIPE_A ? 0 : 1; + I915_WRITE(BLC_PWM_CTL2, + I915_READ(BLC_PWM_CTL2) ~(131)); } static void intel_panel_init_backlight(struct drm_device *dev) -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] properly enable the blc controller on the right pipe
On Thu, Apr 26, 2012 at 07:25:32PM +0200, Daniel Vetter wrote: Depending upon how things are set up, this might help. If not, please install intel-gpu-tools and grab the output of intel_reg_dumper both when booting with nomodeset and when booting with kms. Thanks, Daniel btw, all these stuff is in the public documentation at http://intellinuxgraphics.org/documentation.html The backlight stuff is in volume three: display registers. -Daniel --- drivers/gpu/drm/i915/intel_drv.h |3 ++- drivers/gpu/drm/i915/intel_lvds.c |3 ++- drivers/gpu/drm/i915/intel_panel.c | 15 ++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 715afa1..5a021ce 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -323,7 +323,8 @@ extern u32 intel_panel_get_max_backlight(struct drm_device *dev); extern u32 intel_panel_get_backlight(struct drm_device *dev); extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); extern int intel_panel_setup_backlight(struct drm_device *dev); -extern void intel_panel_enable_backlight(struct drm_device *dev); +extern void intel_panel_enable_backlight(struct drm_device *dev, + enum pipe pipe); extern void intel_panel_disable_backlight(struct drm_device *dev); extern void intel_panel_destroy_backlight(struct drm_device *dev); extern enum drm_connector_status intel_panel_detect(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 30e2c82..3e71b86 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -71,6 +71,7 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector) static void intel_lvds_enable(struct intel_lvds *intel_lvds) { struct drm_device *dev = intel_lvds-base.base.dev; + struct intel_crtc *intel_crtc = to_intel_crtc(intel_lvds-base.base.crtc); struct drm_i915_private *dev_priv = dev-dev_private; u32 ctl_reg, lvds_reg, stat_reg; @@ -107,7 +108,7 @@ static void intel_lvds_enable(struct intel_lvds *intel_lvds) if (wait_for((I915_READ(stat_reg) PP_ON) != 0, 1000)) DRM_ERROR(timed out waiting for panel to power on\n); - intel_panel_enable_backlight(dev); + intel_panel_enable_backlight(dev, intel_crtc-pipe); } static void intel_lvds_disable(struct intel_lvds *intel_lvds) diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 48177ec..486cf92 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -261,17 +261,30 @@ void intel_panel_disable_backlight(struct drm_device *dev) dev_priv-backlight_enabled = false; intel_panel_actually_set_backlight(dev, 0); + + /*disable the blc*/ + I915_WRITE(BLC_PWM_CTL2, +I915_READ(BLC_PWM_CTL2) ~(131)); } -void intel_panel_enable_backlight(struct drm_device *dev) +void intel_panel_enable_backlight(struct drm_device *dev, + enum pipe pipe) { struct drm_i915_private *dev_priv = dev-dev_private; + u32 tmp; if (dev_priv-backlight_level == 0) dev_priv-backlight_level = intel_panel_get_max_backlight(dev); dev_priv-backlight_enabled = true; intel_panel_actually_set_backlight(dev, dev_priv-backlight_level); + + /*enable the blc on the right pipe*/ + tmp = I915_READ(BLC_PWM_CTL2); + tmp = ~(129); /* pipe select */ + tmp |= pipe == PIPE_A ? 0 : 1; + I915_WRITE(BLC_PWM_CTL2, +I915_READ(BLC_PWM_CTL2) ~(131)); } static void intel_panel_init_backlight(struct drm_device *dev) -- 1.7.10 -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 00/24] Haswell v4
Hi, This patch aims at addressing all the bikesheds I had for the past ones, and re-structure the patches in a more logical way. The major changes are the introduction of the intel_ddi.c module, cleanup of the debugging patches, and addition of functions to simplify digital outputs handling for DDI connections. As major areas that will still receive attention in the next patches are: the iCLKIP / WRPLL table rework into a function, proper Haswell DIP support, DP support and digital outputs detection on hotplug (e.g., detection of DP and HDMI according to what's on the other end of the DDI port). But as most of those features are being worked in parallel, I thought on sending this patch bomb so it could be used as base for others. So please, bikeshed and comment :). Eugeni Dodonov (24): drm/i915: add Haswell DIP controls registers drm/i915: support infoframes on Haswell drm/i915: add support for SBI ops drm/i915: calculate same watermarks on Haswell as on Ivy Bridge drm/i915: reuse Ivybridge interrupts code for Haswell drm/i915: properly check for pipe count drm/i915: show unknown sdvox registers on hdmi init drm/i915: do not use fdi_normal_train on haswell drm/i915: detect PCH encoders on Haswell drm/i915: enable power wells on haswell init drm/i915: program WM_LINETIME on Haswell drm/i915: add LPT PCH checks drm/i915: handle DDI-related assertions drm/i915: account for only one PCH receiver on Haswell drm/i915: initialize DDI buffer translations drm/i915: support DDI training in FDI mode drm/i915: disable pipe DDI function when disabling pipe drm/i915: program iCLKIP on Lynx Point drm/i915: detect digital outputs on Haswell drm/i915: add support for DDI-controlled digital outputs drm/i915: add WR PLL programming table drm/i915: move HDMI structs to shared location drm/i915: prepare HDMI link for Haswell drm/i915: hook Haswell devices in place drivers/char/agp/intel-agp.c |4 + drivers/gpu/drm/i915/Makefile|1 + drivers/gpu/drm/i915/i915_drv.c |7 + drivers/gpu/drm/i915/i915_irq.c |7 +- drivers/gpu/drm/i915/i915_reg.h | 16 + drivers/gpu/drm/i915/intel_ddi.c | 765 ++ drivers/gpu/drm/i915/intel_display.c | 524 +-- drivers/gpu/drm/i915/intel_drv.h | 26 +- drivers/gpu/drm/i915/intel_hdmi.c| 85 +++- drivers/gpu/drm/i915/intel_pm.c | 50 ++- 10 files changed, 1432 insertions(+), 53 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_ddi.c -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 01/24] drm/i915: add Haswell DIP controls registers
Haswell has different DIP control registers and offsets. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 16 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f1f4d8f..4f17b74 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3518,6 +3518,22 @@ #define VLV_TVIDEO_DIP_GCP(pipe) \ _PIPE(pipe, VLV_VIDEO_DIP_GDCP_PAYLOAD_A, VLV_VIDEO_DIP_GDCP_PAYLOAD_B) +/* Haswell DIP controls */ +#define HSW_VIDEO_DIP_CTL_A0x60200 +#define HSW_VIDEO_DIP_AVI_DATA_A 0x60220 +#define HSW_VIDEO_DIP_GCP_A0x60210 + +#define HSW_VIDEO_DIP_CTL_B0x61200 +#define HSW_VIDEO_DIP_AVI_DATA_B 0x61220 +#define HSW_VIDEO_DIP_GCP_B0x61210 + +#define HSW_TVIDEO_DIP_CTL(pipe) \ +_PIPE(pipe, HSW_VIDEO_DIP_CTL_A, HSW_VIDEO_DIP_CTL_B) +#define HSW_TVIDEO_DIP_AVI_DATA(pipe) \ +_PIPE(pipe, HSW_VIDEO_DIP_AVI_DATA_A, HSW_VIDEO_DIP_AVI_DATA_B) +#define HSW_TVIDEO_DIP_GCP(pipe) \ + _PIPE(pipe, HSW_VIDEO_DIP_GCP_A, HSW_VIDEO_DIP_GCP_B) + #define _TRANS_HTOTAL_B 0xe1000 #define _TRANS_HBLANK_B 0xe1004 #define _TRANS_HSYNC_B 0xe1008 -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 02/24] drm/i915: support infoframes on Haswell
Haswell has different DIP registers which we need to use for infoframes, so add proper infrastructure to address that. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_hdmi.c | 34 ++ 1 file changed, 34 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 7de2d3b..f6a9b83 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -208,6 +208,36 @@ static void vlv_write_infoframe(struct drm_encoder *encoder, I915_WRITE(reg, VIDEO_DIP_ENABLE | val | flags); } +static void hsw_write_infoframe(struct drm_encoder *encoder, +struct dip_infoframe *frame) +{ + uint32_t *data = (uint32_t *)frame; + struct drm_device *dev = encoder-dev; + struct drm_i915_private *dev_priv = dev-dev_private; + struct drm_crtc *crtc = encoder-crtc; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int reg = HSW_TVIDEO_DIP_CTL(intel_crtc-pipe); + unsigned i, len = DIP_HEADER_SIZE + frame-len; + u32 flags, val = I915_READ(reg); + + intel_wait_for_vblank(dev, intel_crtc-pipe); + + flags = intel_infoframe_index(frame); + + val = ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ + + I915_WRITE(reg, VIDEO_DIP_ENABLE | val | flags); + + for (i = 0; i len; i += 4) { + I915_WRITE(HSW_TVIDEO_DIP_AVI_DATA(intel_crtc-pipe), *data); + data++; + } + + flags |= intel_infoframe_flags(frame); + + I915_WRITE(reg, VIDEO_DIP_ENABLE | val | flags); +} + static void intel_set_infoframe(struct drm_encoder *encoder, struct dip_infoframe *frame) { @@ -587,6 +617,10 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) intel_hdmi-write_infoframe = vlv_write_infoframe; for_each_pipe(i) I915_WRITE(VLV_TVIDEO_DIP_CTL(i), 0); + } else if (IS_HASWELL(dev)) { + intel_hdmi-write_infoframe = hsw_write_infoframe; + for_each_pipe(i) + I915_WRITE(HSW_TVIDEO_DIP_CTL(i), 0); } else { intel_hdmi-write_infoframe = ironlake_write_infoframe; for_each_pipe(i) -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 03/24] drm/i915: add support for SBI ops
With Lynx Point, we need to use SBI to communicate with the display clock control. This commit adds helper functions to access the registers via SBI. v2: de-inline the function and address changes in bits names v3: protect operations with dpio_lock, increase timeout to 100 for paranoia sake. v4: decrease paranoia a bit, as noticed by Chris Wilson v1 Reviewed-by: Rodrigo Vivi rodrigo.v...@gmail.com Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_display.c | 63 ++ 1 file changed, 63 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e1716be..8262ec6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1300,6 +1300,69 @@ static void intel_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) POSTING_READ(reg); } +/* SBI access */ +static void +intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value) +{ + unsigned long flags; + + spin_lock_irqsave(dev_priv-dpio_lock, flags); + if (wait_for((I915_READ(SBI_CTL_STAT) SBI_READY) == 0, + 100)) { + DRM_ERROR(timeout waiting for SBI to become ready\n); + goto out_unlock; + } + + I915_WRITE(SBI_ADDR, + (reg 16)); + I915_WRITE(SBI_DATA, + value); + I915_WRITE(SBI_CTL_STAT, + SBI_BUSY | + SBI_CTL_OP_CRWR); + + if (wait_for((I915_READ(SBI_CTL_STAT) (SBI_READY | SBI_RESPONSE_SUCCESS)) == 0, + 100)) { + DRM_ERROR(timeout waiting for SBI to complete write transaction\n); + goto out_unlock; + } + +out_unlock: + spin_unlock_irqrestore(dev_priv-dpio_lock, flags); +} + +static u32 +intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg) +{ + unsigned long flags; + u32 value; + + spin_lock_irqsave(dev_priv-dpio_lock, flags); + if (wait_for((I915_READ(SBI_CTL_STAT) SBI_READY) == 0, + 100)) { + DRM_ERROR(timeout waiting for SBI to become ready\n); + goto out_unlock; + } + + I915_WRITE(SBI_ADDR, + (reg 16)); + I915_WRITE(SBI_CTL_STAT, + SBI_BUSY | + SBI_CTL_OP_CRRD); + + if (wait_for((I915_READ(SBI_CTL_STAT) (SBI_READY | SBI_RESPONSE_SUCCESS)) == 0, + 100)) { + DRM_ERROR(timeout waiting for SBI to complete read transaction\n); + goto out_unlock; + } + + value = I915_READ(SBI_DATA); + +out_unlock: + spin_unlock_irqrestore(dev_priv-dpio_lock, flags); + return value; +} + /** * intel_enable_pch_pll - enable PCH PLL * @dev_priv: i915 private structure -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 04/24] drm/i915: calculate same watermarks on Haswell as on Ivy Bridge
Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_pm.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0552058..06f38ec 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1694,8 +1694,8 @@ static void sandybridge_update_wm(struct drm_device *dev) enabled |= 2; } - /* IVB has 3 pipes */ - if (IS_IVYBRIDGE(dev) + /* Only IVB and Haswell has 3 pipes support so far */ + if ((IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) g4x_compute_wm0(dev, 2, sandybridge_display_wm_info, latency, sandybridge_cursor_wm_info, latency, -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 05/24] drm/i915: reuse Ivybridge interrupts code for Haswell
v2: prevent possible conflicts with VLV. v3: simplify IRQ handling for Gen5+ onwards. v1 Reviewed-by: Rodrigo Vivi rodrigo.v...@gmail.com Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/i915_irq.c |7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 0211263..bc8b80c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2006,7 +2006,7 @@ static void ironlake_irq_preinstall(struct drm_device *dev) INIT_WORK(dev_priv-hotplug_work, i915_hotplug_work_func); INIT_WORK(dev_priv-error_work, i915_error_work_func); - if (IS_GEN6(dev) || IS_IVYBRIDGE(dev)) + if (IS_GEN6(dev) || IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) INIT_WORK(dev_priv-rps_work, gen6_pm_rps_work); I915_WRITE(HWSTAM, 0xeffe); @@ -2627,8 +2627,7 @@ void intel_irq_init(struct drm_device *dev) { dev-driver-get_vblank_counter = i915_get_vblank_counter; dev-max_vblank_count = 0xff; /* only 24 bits of frame count */ - if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev) || - IS_VALLEYVIEW(dev)) { + if (IS_G4X(dev) || INTEL_INFO(dev)-gen = 5) { dev-max_vblank_count = 0x; /* full 32 bit counter */ dev-driver-get_vblank_counter = gm45_get_vblank_counter; } @@ -2646,7 +2645,7 @@ void intel_irq_init(struct drm_device *dev) dev-driver-irq_uninstall = valleyview_irq_uninstall; dev-driver-enable_vblank = valleyview_enable_vblank; dev-driver-disable_vblank = valleyview_disable_vblank; - } else if (IS_IVYBRIDGE(dev)) { + } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { /* Share pre uninstall handlers with ILK/SNB */ dev-driver-irq_handler = ivybridge_irq_handler; dev-driver-irq_preinstall = ironlake_irq_preinstall; -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 08/24] drm/i915: do not use fdi_normal_train on haswell
This should be already configured when FDI auto-negotiation is done. Reviewed-by: Rodrigo Vivi rodrigo.v...@gmail.com Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_display.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 27f384d..758173d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2700,7 +2700,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) I915_WRITE(TRANS_VSYNC(pipe), I915_READ(VSYNC(pipe))); I915_WRITE(TRANS_VSYNCSHIFT(pipe), I915_READ(VSYNCSHIFT(pipe))); - intel_fdi_normal_train(crtc); + if (!IS_HASWELL(dev)) + intel_fdi_normal_train(crtc); /* For PCH DP, enable TRANS_DP_CTL */ if (HAS_PCH_CPT(dev) -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 09/24] drm/i915: detect PCH encoders on Haswell
On Haswell, the recommended PCH-connected output is the one driven by DDI E in FDI mode, used for VGA connection. All the others are handled by the CPU. Note that this does not accounts for Haswell/PPT combination yet. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_display.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 758173d..ea1ac15 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2631,6 +2631,18 @@ static bool intel_crtc_driving_pch(struct drm_crtc *crtc) if (encoder-base.crtc != crtc) continue; + /* On Haswell, LPT PCH handles the VGA connection via FDI, and Haswell +* CPU handles all others */ + if (IS_HASWELL(dev)) { + if (HAS_PCH_LPT(dev) (encoder-type == DRM_MODE_ENCODER_DAC)) + return true; + else { + DRM_DEBUG_KMS(Haswell detected encoder %d, assuming is CPU\n, + encoder-type); + return false; + } + } + switch (encoder-type) { case INTEL_OUTPUT_EDP: if (!intel_encoder_is_pch_edp(encoder-base)) -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 10/24] drm/i915: enable power wells on haswell init
This attempts to enable all the available power wells during the initialization. Those power wells can be enabled in parallel or on-demand, and disabled when no longer needed, but this is out of scope of this initial enablement. Proper tracking of who uses which power well will require a considerable rework of our display handling, so we just leave them all enabled when the driver is loaded for now. v2: use more generic and future-proof code Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 36 1 file changed, 36 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 06f38ec..f87768d 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2937,6 +2937,37 @@ void intel_init_clock_gating(struct drm_device *dev) dev_priv-display.init_pch_clock_gating(dev); } +/* Starting with Haswell, we have different power wells for + * different parts of the GPU. This attempts to enable them all. + */ +void intel_init_power_wells(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + unsigned long power_wells[] = { + HSW_PWR_WELL_CTL1, + HSW_PWR_WELL_CTL2, + HSW_PWR_WELL_CTL4 + }; + int i; + + if (!IS_HASWELL(dev)) + return; + + mutex_lock(dev-struct_mutex); + + for (i = 0; i ARRAY_SIZE(power_wells); i++) { + int well = I915_READ(power_wells[i]); + + if ((well HSW_PWR_WELL_STATE) == 0) { + I915_WRITE(power_wells[i], well HSW_PWR_WELL_ENABLE); + if (wait_for(I915_READ(power_wells[i] HSW_PWR_WELL_STATE), 20)) + DRM_ERROR(Error enabling power well %lx\n, power_wells[i]); + } + } + + mutex_unlock(dev-struct_mutex); +} + /* Set up chip specific power management-related functions */ void intel_init_pm(struct drm_device *dev) { @@ -3077,5 +3108,10 @@ void intel_init_pm(struct drm_device *dev) else dev_priv-display.get_fifo_size = i830_get_fifo_size; } + + /* We attempt to init the necessary power wells early in the initialization +* time, so the subsystems that expect power to be enabled can work. +*/ + intel_init_power_wells(dev); } -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 11/24] drm/i915: program WM_LINETIME on Haswell
The line time can be programmed according to the number of horizontal pixels vs effective pixel rate ratio. v2: improve comment as per Chris Wilson suggestion v3: incorporate latest changes in specs. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_display.c | 13 + 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ea1ac15..8308da0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4555,6 +4555,19 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, (adjusted_mode-crtc_vsync_start - 1) | ((adjusted_mode-crtc_vsync_end - 1) 16)); + if (IS_HASWELL(dev)) { + temp = I915_READ(PIPE_WM_LINETIME(pipe)); + temp = ~PIPE_WM_LINETIME_MASK; + + /* The WM are computed with base on how long it takes to fill a single +* row at the given clock rate, multiplied by 8. +* */ + temp |= PIPE_WM_LINETIME_TIME( + ((adjusted_mode-crtc_hdisplay * 1000) / adjusted_mode-clock) * 8); + + I915_WRITE(PIPE_WM_LINETIME(pipe), temp); + } + /* pipesrc controls the size that is scaled from, which should * always be the user's requested size. */ -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 12/24] drm/i915: add LPT PCH checks
Avoid bogus asserts on Lynx Point. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_display.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8308da0..ca0edbf 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -917,6 +917,11 @@ static void assert_pch_pll(struct drm_i915_private *dev_priv, u32 val; bool cur_state; + if (HAS_PCH_LPT(dev_priv-dev)) { + DRM_DEBUG_DRIVER(LPT detected: skipping PCH PLL test\n); + return; + } + if (!intel_crtc-pch_pll) { WARN(1, asserting PCH PLL enabled with no PLL\n); return; @@ -1102,6 +1107,11 @@ static void assert_pch_refclk_enabled(struct drm_i915_private *dev_priv) u32 val; bool enabled; + if (HAS_PCH_LPT(dev_priv-dev)) { + DRM_DEBUG_DRIVER(LPT does not has PCH refclk, skipping check\n); + return; + } + val = I915_READ(PCH_DREF_CONTROL); enabled = !!(val (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK | DREF_SUPERSPREAD_SOURCE_MASK)); -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 13/24] drm/i915: handle DDI-related assertions
Prevent bogus asserts on DDI-related paths. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_display.c | 35 -- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ca0edbf..b2d3dc1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -954,9 +954,16 @@ static void assert_fdi_tx(struct drm_i915_private *dev_priv, u32 val; bool cur_state; - reg = FDI_TX_CTL(pipe); - val = I915_READ(reg); - cur_state = !!(val FDI_TX_ENABLE); + if (IS_HASWELL(dev_priv-dev)) { + /* On Haswell, DDI is used instead of FDI_TX_CTL */ + reg = DDI_FUNC_CTL(pipe); + val = I915_READ(reg); + cur_state = !!(val PIPE_DDI_FUNC_ENABLE); + } else { + reg = FDI_TX_CTL(pipe); + val = I915_READ(reg); + cur_state = !!(val FDI_TX_ENABLE); + } WARN(cur_state != state, FDI TX state assertion failure (expected %s, current %s)\n, state_string(state), state_string(cur_state)); @@ -991,6 +998,10 @@ static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv, if (dev_priv-info-gen == 5) return; + /* On Haswell, DDI ports are responsible for the FDI PLL setup */ + if (IS_HASWELL(dev_priv-dev)) + return; + reg = FDI_TX_CTL(pipe); val = I915_READ(reg); WARN(!(val FDI_TX_PLL_ENABLE), FDI TX PLL assertion failure, should be active but is disabled\n); @@ -2515,14 +2526,18 @@ static void ironlake_fdi_pll_enable(struct drm_crtc *crtc) POSTING_READ(reg); udelay(200); - /* Enable CPU FDI TX PLL, always on for Ironlake */ - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - if ((temp FDI_TX_PLL_ENABLE) == 0) { - I915_WRITE(reg, temp | FDI_TX_PLL_ENABLE); + /* On Haswell, the PLL configuration for ports and pipes is handled +* separately, as part of DDI setup */ + if (!IS_HASWELL(dev)) { + /* Enable CPU FDI TX PLL, always on for Ironlake */ + reg = FDI_TX_CTL(pipe); + temp = I915_READ(reg); + if ((temp FDI_TX_PLL_ENABLE) == 0) { + I915_WRITE(reg, temp | FDI_TX_PLL_ENABLE); - POSTING_READ(reg); - udelay(100); + POSTING_READ(reg); + udelay(100); + } } } -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 14/24] drm/i915: account for only one PCH receiver on Haswell
On Haswell, only one pipe can work in FDI mode, so this patch prevents messing with wrong registers when FDI is being used by non-first pipe. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_display.c | 19 --- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b2d3dc1..6509402 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -978,9 +978,14 @@ static void assert_fdi_rx(struct drm_i915_private *dev_priv, u32 val; bool cur_state; - reg = FDI_RX_CTL(pipe); - val = I915_READ(reg); - cur_state = !!(val FDI_RX_ENABLE); + if (IS_HASWELL(dev_priv-dev) pipe 0) { + DRM_ERROR(Attempting to enable FDI_RX on Haswell pipe 0\n); + return; + } else { + reg = FDI_RX_CTL(pipe); + val = I915_READ(reg); + cur_state = !!(val FDI_RX_ENABLE); + } WARN(cur_state != state, FDI RX state assertion failure (expected %s, current %s)\n, state_string(state), state_string(cur_state)); @@ -1013,6 +1018,10 @@ static void assert_fdi_rx_pll_enabled(struct drm_i915_private *dev_priv, int reg; u32 val; + if (IS_HASWELL(dev_priv-dev) pipe 0) { + DRM_ERROR(Attempting to enable FDI on Haswell with pipe 0\n); + return; + } reg = FDI_RX_CTL(pipe); val = I915_READ(reg); WARN(!(val FDI_RX_PLL_ENABLE), FDI RX PLL assertion failure, should be active but is disabled\n); @@ -1484,6 +1493,10 @@ static void intel_enable_transcoder(struct drm_i915_private *dev_priv, assert_fdi_tx_enabled(dev_priv, pipe); assert_fdi_rx_enabled(dev_priv, pipe); + if (IS_HASWELL(dev_priv-dev) pipe 0) { + DRM_ERROR(Attempting to enable transcoder on Haswell with pipe 0\n); + return; + } reg = TRANSCONF(pipe); val = I915_READ(reg); pipeconf_val = I915_READ(PIPECONF(pipe)); -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 16/24] drm/i915: support DDI training in FDI mode
Starting with Haswell, DDI ports can work in FDI mode to support connectivity with the outputs located on the PCH. This commit adds support for such connections in the intel_ddi module, and provides Haswell-specific functionality to make it work. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 121 ++ drivers/gpu/drm/i915/intel_display.c |3 + drivers/gpu/drm/i915/intel_drv.h |1 + drivers/gpu/drm/i915/intel_pm.c | 10 +++ 4 files changed, 135 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 32594a8..93436caa 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -109,3 +109,124 @@ void intel_prepare_ddi(struct drm_device *dev) intel_prepare_ddi_buffers(dev, PORT_E, true); } } + +static const long hsw_ddi_buf_ctl_values[] = { + DDI_BUF_EMP_400MV_0DB_HSW, + DDI_BUF_EMP_400MV_3_5DB_HSW, + DDI_BUF_EMP_400MV_6DB_HSW, + DDI_BUF_EMP_400MV_9_5DB_HSW, + DDI_BUF_EMP_600MV_0DB_HSW, + DDI_BUF_EMP_600MV_3_5DB_HSW, + DDI_BUF_EMP_600MV_6DB_HSW, + DDI_BUF_EMP_800MV_0DB_HSW, + DDI_BUF_EMP_800MV_3_5DB_HSW +}; + + +/* Link training for Haswell DDI port to work in FDI mode */ +static void hsw_fdi_link_train(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc-dev; + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc-pipe; + u32 reg, temp, i; + + /* Configure CPU PLL, wait for warmup */ + I915_WRITE(SPLL_CTL, + SPLL_PLL_ENABLE | + SPLL_PLL_FREQ_1350MHz | + SPLL_PLL_SCC); + + /* Use SPLL to drive the output when in FDI mode */ + I915_WRITE(PORT_CLK_SEL(PORT_E), + PORT_CLK_SEL_SPLL); + I915_WRITE(PIPE_CLK_SEL(pipe), + PIPE_CLK_SEL_PORT(PORT_E)); + + udelay(20); + + /* Start the training iterating through available voltages and emphasis */ + for (i=0; i ARRAY_SIZE(hsw_ddi_buf_ctl_values); i++) { + /* Configure DP_TP_CTL with auto-training */ + I915_WRITE(DP_TP_CTL(PORT_E), + DP_TP_CTL_FDI_AUTOTRAIN | + DP_TP_CTL_ENHANCED_FRAME_ENABLE | + DP_TP_CTL_LINK_TRAIN_PAT1 | + DP_TP_CTL_ENABLE); + + /* Configure and enable DDI_BUF_CTL for DDI E with next voltage */ + temp = I915_READ(DDI_BUF_CTL(PORT_E)); + temp = (temp ~DDI_BUF_EMP_MASK); + I915_WRITE(DDI_BUF_CTL(PORT_E), + temp | + DDI_BUF_CTL_ENABLE | + DDI_PORT_WIDTH_X2 | + hsw_ddi_buf_ctl_values[i]); + + udelay(600); + + /* Enable CPU FDI Receiver with auto-training */ + reg = FDI_RX_CTL(pipe); + I915_WRITE(reg, + I915_READ(reg) | + FDI_LINK_TRAIN_AUTO | + FDI_RX_ENABLE | + FDI_LINK_TRAIN_PATTERN_1_CPT | + FDI_RX_ENHANCE_FRAME_ENABLE | + FDI_PORT_WIDTH_2X_LPT | + FDI_RX_PLL_ENABLE); + POSTING_READ(reg); + udelay(100); + + temp = I915_READ(DP_TP_STATUS(PORT_E)); + if (temp DP_TP_STATUS_AUTOTRAIN_DONE) { + DRM_DEBUG_DRIVER(BUF_CTL training done on %d step\n, i); + + /* Enable normal pixel sending for FDI */ + I915_WRITE(DP_TP_CTL(PORT_E), + DP_TP_CTL_FDI_AUTOTRAIN | + DP_TP_CTL_LINK_TRAIN_NORMAL | + DP_TP_CTL_ENHANCED_FRAME_ENABLE | + DP_TP_CTL_ENABLE); + + /* Enable PIPE_DDI_FUNC_CTL for the pipe to work in FDI mode */ + temp = I915_READ(DDI_FUNC_CTL(pipe)); + temp = ~PIPE_DDI_PORT_MASK; + temp |= PIPE_DDI_SELECT_PORT(PORT_E) | + PIPE_DDI_MODE_SELECT_FDI | + PIPE_DDI_FUNC_ENABLE | + PIPE_DDI_PORT_WIDTH_X2; + I915_WRITE(DDI_FUNC_CTL(pipe), + temp); + break; + } else { +
[Intel-gfx] [PATCH 17/24] drm/i915: disable pipe DDI function when disabling pipe
Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_display.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5be2ff1..b7e50af 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1627,6 +1627,16 @@ static void intel_disable_pipe(struct drm_i915_private *dev_priv, I915_WRITE(reg, val ~PIPECONF_ENABLE); intel_wait_for_pipe_off(dev_priv-dev, pipe); + + /* On HSW, disable pipe DDI function the pipe */ + if (IS_HASWELL(dev_priv-dev)) { + val = I915_READ(DDI_FUNC_CTL(pipe)); + val = ~PIPE_DDI_PORT_MASK; + val = ~PIPE_DDI_FUNC_ENABLE; + I915_WRITE(DDI_FUNC_CTL(pipe), + val); + } + } /* -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 15/24] drm/i915: initialize DDI buffer translations
DDI is introduced starting with Haswell GPU generation. So to simplify its management in the future, we also add intel_ddi.c to hold all the DDI-related items. Buffer translations for DDI links must be initialized prior to enablement. For FDI and DP, first 9 pairs of values are used to select the connection parameters. HDMI uses the last pair of values and ignores the first 9 pairs. So we program HDMI values in both cases, which allows HDMI to work over both FDI and DP-friendly buffers. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/Makefile|1 + drivers/gpu/drm/i915/intel_ddi.c | 111 ++ drivers/gpu/drm/i915/intel_display.c |2 + drivers/gpu/drm/i915/intel_drv.h |1 + 4 files changed, 115 insertions(+) create mode 100644 drivers/gpu/drm/i915/intel_ddi.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 8b8bbc7..0ca7f76 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -19,6 +19,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \ intel_crt.o \ intel_lvds.o \ intel_bios.o \ + intel_ddi.o \ intel_dp.o \ intel_hdmi.o \ intel_sdvo.o \ diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c new file mode 100644 index 000..32594a8 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -0,0 +1,111 @@ +/* + * Copyright © 2012 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: + *Eugeni Dodonov eugeni.dodo...@intel.com + * + */ + +#include i915_drv.h +#include intel_drv.h + +/* HDMI/DVI modes ignore everything but the last 2 items. So we share + * them for both DP and FDI transports, allowing those ports to + * automatically adapt to HDMI connections as well + */ +static const long hsw_ddi_translations_dp[] = { + 0x00FF, 0x0006000E, + 0x00D75FFF, 0x0005000A, + 0x00C30FFF, 0x00040006, + 0x80AAAFFF, 0x000B, + 0x00FF, 0x0005000A, + 0x00D75FFF, 0x000C0004, + 0x80C30FFF, 0x000B, + 0x00FF, 0x00040006, + 0x80D75FFF, 0x000B, + 0x00FF, 0x00040006 +}; + +static const long hsw_ddi_translations_fdi[] = { + 0x00FF, 0x0007000E, + 0x00D75FFF, 0x000F000A, + 0x00C30FFF, 0x00060006, + 0x00AAAFFF, 0x001E, + 0x00FF, 0x000F000A, + 0x00D75FFF, 0x00160004, + 0x00C30FFF, 0x001E, + 0x00FF, 0x00060006, + 0x00D75FFF, 0x001E, + 0x00FF, 0x00040006 +}; + +/* On Haswell, DDI port buffers must be programmed with correct values + * in advance. The buffer values are different for FDI and DP modes, + * but the HDMI/DVI fields are shared among those. So we program the DDI + * in either FDI or DP modes only, as HDMI connections will work with both + * of those + */ +void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, bool use_fdi_mode) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + u32 reg; + int i, j; + + DRM_DEBUG_DRIVER(Initializing DDI buffers for port %c in %s mode\n, + port_name(port), + use_fdi_mode ? FDI : DP); + + WARN((use_fdi_mode (port != PORT_E)), + Programming port %c in FDI mode, this probably will not work.\n, + port_name(port)); + + /* Those registers seem to be double-buffered, so write them twice */ + for (j=0; j 2; j++) { + for (i=0, reg=DDI_BUF_TRANS(port); i ARRAY_SIZE(hsw_ddi_translations_fdi); i++) { + I915_WRITE(reg, + (use_fdi_mode) ? + hsw_ddi_translations_fdi[i] : + hsw_ddi_translations_dp[i]);
[Intel-gfx] [PATCH 20/24] drm/i915: add support for DDI-controlled digital outputs
Those are driven by DDIs on Haswell architecture, so we need to keep track of which DDI is being used on each output. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_hdmi.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index d73a16c..06ff2d8 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -41,6 +41,7 @@ struct intel_hdmi { struct intel_encoder base; u32 sdvox_reg; int ddc_bus; + int ddi_port; uint32_t color_range; bool has_hdmi_sink; bool has_audio; @@ -606,6 +607,24 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) intel_encoder-clone_mask = (1 INTEL_HDMIF_CLONE_BIT); intel_hdmi-ddc_bus = GMBUS_PORT_DPD; dev_priv-hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS; + } else if (sdvox_reg == DDI_BUF_CTL(PORT_B)) { + DRM_DEBUG_DRIVER(LPT: detected output on DDI B\n); + intel_encoder-clone_mask = (1 INTEL_HDMIB_CLONE_BIT); + intel_hdmi-ddc_bus = GMBUS_PORT_DPB; + intel_hdmi-ddi_port = PORT_B; + dev_priv-hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; + } else if (sdvox_reg == DDI_BUF_CTL(PORT_C)) { + DRM_DEBUG_DRIVER(LPT: detected output on DDI C\n); + intel_encoder-clone_mask = (1 INTEL_HDMIC_CLONE_BIT); + intel_hdmi-ddc_bus = GMBUS_PORT_DPC; + intel_hdmi-ddi_port = PORT_C; + dev_priv-hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; + } else if (sdvox_reg == DDI_BUF_CTL(PORT_D)) { + DRM_DEBUG_DRIVER(LPT: detected output on DDI D\n); + intel_encoder-clone_mask = (1 INTEL_HDMID_CLONE_BIT); + intel_hdmi-ddc_bus = GMBUS_PORT_DPD; + intel_hdmi-ddi_port = PORT_D; + dev_priv-hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS; } else { DRM_ERROR(Unknown sdvox register on HDMI init: %x\n, sdvox_reg); } -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 19/24] drm/i915: detect digital outputs on Haswell
Digital port detection on Haswell is indicated by the presence of a bit in DDI_BUF_CTL for port A, and by a different register for ports B, C and D. So we check for those bits during the initialization time and let the hdmi function know about those. Note that this bit does not indicates whether the output is DP or HDMI. However, the DDI buffers can be programmed in a way that is shared between DP/HDMI and FDI/HDMI except for PORT E. So for now, we detect those digital outputs as being HDMI, but proper DP support is still pending. Note that DDI A can only drive eDP, so we do not handle it here for hdmi initialization. v2: simplify Haswell handling logic v3: use generic function for handling digital outputs. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 29 + drivers/gpu/drm/i915/intel_display.c | 21 - drivers/gpu/drm/i915/intel_drv.h |1 + 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 93436caa..cd6fbaa 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -230,3 +230,32 @@ void ddi_fdi_link_train(struct drm_crtc *crtc) if (IS_HASWELL(dev)) hsw_fdi_link_train(crtc); } + +/* For DDI connections, it is possible to support different outputs over the + * same DDI port, such as HDMI or DP or even VGA via FDI. So we don't know by + * the time the output is detected what exactly is on the other end of it. This + * function aims at providing support for this detection and proper output + * configuration. + */ +void intel_ddi_init(struct drm_device *dev, enum port port) +{ + /* For now, we don't do any proper output detection and assume that we +* handle HDMI only */ + + switch(port){ + case PORT_A: + /* We don't handle eDP and DP yet */ + DRM_DEBUG_DRIVER(Found digital output on DDI port A\n); + break; + /* Assume that the ports B, C and D are working in HDMI mode for now */ + case PORT_B: + case PORT_C: + case PORT_D: + intel_hdmi_init(dev, DDI_BUF_CTL(port)); + break; + default: + DRM_DEBUG_DRIVER(No handlers defined for port %d, skipping DDI initialization\n, + port); + break; + } +} diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bc7c255..b1d5bfc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6707,7 +6707,26 @@ static void intel_setup_outputs(struct drm_device *dev) intel_crt_init(dev); - if (HAS_PCH_SPLIT(dev)) { + if (IS_HASWELL(dev)) { + int found; + + /* Haswell uses DDI functions to detect digital outputs */ + found = I915_READ(DDI_BUF_CTL_A) DDI_INIT_DISPLAY_DETECTED; + /* DDI A only supports eDP */ + if (found) + intel_ddi_init(dev, PORT_A); + + /* DDI B, C and D detection is indicated by the SFUSE_STRAP +* register */ + found = I915_READ(SFUSE_STRAP); + + if (found SFUSE_STRAP_DDIB_DETECTED) + intel_ddi_init(dev, PORT_B); + if (found SFUSE_STRAP_DDIC_DETECTED) + intel_ddi_init(dev, PORT_C); + if (found SFUSE_STRAP_DDID_DETECTED) + intel_ddi_init(dev, PORT_D); + } else if (HAS_PCH_SPLIT(dev)) { int found; if (I915_READ(HDMIB) PORT_DETECTED) { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index df3536f..6543720 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -444,6 +444,7 @@ extern void intel_write_eld(struct drm_encoder *encoder, extern void intel_cpt_verify_modeset(struct drm_device *dev, int pipe); extern void intel_prepare_ddi(struct drm_device *dev); extern void ddi_fdi_link_train(struct drm_crtc *crtc); +extern void intel_ddi_init(struct drm_device *dev, enum port port); /* For use by IVB LP watermark workaround in intel_sprite.c */ extern void intel_update_watermarks(struct drm_device *dev); -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 21/24] drm/i915: add WR PLL programming table
This table is used for programming WR PLL clocks, used by HDMI and DVI outputs. I split it into a separate patch to simplify the HDMI enabling patch which was getting huge. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 388 ++ 1 file changed, 388 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index cd6fbaa..85ebe8e 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -259,3 +259,391 @@ void intel_ddi_init(struct drm_device *dev, enum port port) break; } } + +/* WRPLL clock dividers */ +struct wrpll_tmds_clock { + u32 clock; + u16 p; /* Post divider */ + u16 n2; /* Feedback divider */ + u16 r2; /* Reference divider */ +}; + +/* Table of matching values for WRPLL clocks programming for each frequency */ +static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = { + {19750, 38, 25, 18}, + {2, 48, 32, 18}, + {21000, 36, 21, 15}, + {21912, 42, 29, 17}, + {22000, 36, 22, 15}, + {23000, 36, 23, 15}, + {23500, 40, 40, 23}, + {23750, 26, 16, 14}, + {23750, 26, 16, 14}, + {24000, 36, 24, 15}, + {25000, 36, 25, 15}, + {25175, 26, 40, 33}, + {25200, 30, 21, 15}, + {26000, 36, 26, 15}, + {27000, 30, 21, 14}, + {27027, 18, 100,111}, + {27500, 30, 29, 19}, + {28000, 34, 30, 17}, + {28320, 26, 30, 22}, + {28322, 32, 42, 25}, + {28750, 24, 23, 18}, + {29000, 30, 29, 18}, + {29750, 32, 30, 17}, + {3, 30, 25, 15}, + {30750, 30, 41, 24}, + {31000, 30, 31, 18}, + {31500, 30, 28, 16}, + {32000, 30, 32, 18}, + {32500, 28, 32, 19}, + {33000, 24, 22, 15}, + {34000, 28, 30, 17}, + {35000, 26, 32, 19}, + {35500, 24, 30, 19}, + {36000, 26, 26, 15}, + {36750, 26, 46, 26}, + {37000, 24, 23, 14}, + {37762, 22, 40, 26}, + {37800, 20, 21, 15}, + {38000, 24, 27, 16}, + {38250, 24, 34, 20}, + {39000, 24, 26, 15}, + {4, 24, 32, 18}, + {40500, 20, 21, 14}, + {40541, 22, 147,89}, + {40750, 18, 19, 14}, + {41000, 16, 17, 14}, + {41500, 22, 44, 26}, + {41540, 22, 44, 26}, + {42000, 18, 21, 15}, + {42500, 22, 45, 26}, + {43000, 20, 43, 27}, + {43163, 20, 24, 15}, + {44000, 18, 22, 15}, + {44900, 20, 108,65}, + {45000, 20, 25, 15}, + {45250, 20, 52, 31}, + {46000, 18, 23, 15}, + {46750, 20, 45, 26}, + {47000, 20, 40, 23}, + {48000, 18, 24, 15}, + {49000, 18, 49, 30}, + {49500, 16, 22, 15}, + {5, 18, 25, 15}, + {50500, 18, 32, 19}, + {51000, 18, 34, 20}, + {52000, 18, 26, 15}, + {52406, 14, 34, 25}, + {53000, 16, 22, 14}, + {54000, 16, 24, 15}, + {54054, 16, 173,108}, + {54500, 14, 24, 17}, + {55000, 12, 22, 18}, + {56000, 14, 45, 31}, + {56250, 16, 25, 15}, + {56750, 14, 25, 17}, + {57000, 16, 27, 16}, + {58000, 16, 43, 25}, + {58250, 16, 38, 22}, + {58750, 16, 40, 23}, + {59000, 14, 26, 17}, + {59341, 14, 40, 26}, + {59400, 16, 44, 25}, + {6, 16, 32, 18}, + {60500, 12, 39, 29}, + {61000, 14, 49, 31}, + {62000, 14, 37, 23}, + {62250, 14, 42, 26}, + {63000, 12, 21, 15}, + {63500, 14, 28, 17}, + {64000, 12, 27, 19}, + {65000, 14, 32, 19}, + {65250, 12, 29, 20}, + {65500, 12, 32, 22}, + {66000, 12, 22, 15}, + {7, 14, 38, 22}, + {66750, 10, 21, 17}, + {67000, 14, 33, 19}, + {67750, 14, 58, 33}, + {68000, 14, 30, 17}, + {68179, 14, 46, 26}, + {68250, 14, 46, 26}, + {69000, 12, 23, 15}, + {7, 12, 28, 18}, + {71000, 12, 30, 19}, + {72000, 12, 24, 15}, + {73000, 10, 23, 17}, + {74000, 12, 23, 14}, +
[Intel-gfx] [PATCH 23/24] drm/i915: prepare HDMI link for Haswell
On Haswell, we need to properly train the DDI buffers prior to enabling HDMI, and enable the required clocks with correct dividers for the desired frequency. Also, we cannot simple reuse HDMI routines from previous generations of GPU, as most of HDMI-specific stuff is being done via the DDI port programming instead of HDMI-specific registers. This commit take advantage of the WR PLL clock table which is in a separate (previous) commit to select the right divisors for each mode. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 116 + drivers/gpu/drm/i915/intel_drv.h |5 ++ drivers/gpu/drm/i915/intel_hdmi.c | 13 - 3 files changed, 133 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 85ebe8e..a6c5376 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -647,3 +647,119 @@ static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = { {297000,2, 22, 20}, {298000,2, 21, 19}, }; + +void intel_ddi_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_device *dev = encoder-dev; + struct drm_i915_private *dev_priv = dev-dev_private; + struct drm_crtc *crtc = encoder-crtc; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); + int port = intel_hdmi-ddi_port; + int pipe = intel_crtc-pipe; + int p, n2, r2, valid=0; + u32 temp, i; + + /* On Haswell, we need to enable the clocks and prepare DDI function to +* work in HDMI mode for this pipe. +*/ + DRM_DEBUG_KMS(Preparing HDMI DDI mode for Haswell on port %c, pipe %c\n, port_name(port), pipe_name(pipe)); + + for (i=0; i ARRAY_SIZE(wrpll_tmds_clock_table); i++) { + if (crtc-mode.clock == wrpll_tmds_clock_table[i].clock) { + p = wrpll_tmds_clock_table[i].p; + n2 = wrpll_tmds_clock_table[i].n2; + r2 = wrpll_tmds_clock_table[i].r2; + + DRM_DEBUG_KMS(WR PLL clock: found settings for %dKHz refresh rate: p=%d, n2=%d, r2=%d\n, + crtc-mode.clock, + p, n2, r2); + + valid = 1; + break; + } + } + + if (!valid) { + DRM_ERROR(Unable to find WR PLL clock settings for %dKHz refresh rate\n, + crtc-mode.clock); + return; + } + + /* Enable LCPLL if disabled */ + temp = I915_READ(LCPLL_CTL); + if (temp LCPLL_PLL_DISABLE) + I915_WRITE(LCPLL_CTL, + temp ~LCPLL_PLL_DISABLE); + + /* Configure WR PLL 1, program the correct divider values for +* the desired frequency and wait for warmup */ + I915_WRITE(WRPLL_CTL1, + WRPLL_PLL_ENABLE | + WRPLL_PLL_SELECT_LCPLL_2700 | + WRPLL_DIVIDER_REFERENCE(r2) | + WRPLL_DIVIDER_FEEDBACK(n2) | + WRPLL_DIVIDER_POST(p)); + + udelay(20); + + /* Use WRPLL1 clock to drive the output to the port, and tell the pipe to use +* this port for connection. +*/ + I915_WRITE(PORT_CLK_SEL(port), + PORT_CLK_SEL_WRPLL1); + I915_WRITE(PIPE_CLK_SEL(pipe), + PIPE_CLK_SEL_PORT(port)); + + udelay(20); + + if (intel_hdmi-has_audio) { + /* Proper support for digital audio needs a new logic and a new set +* of registers, so we leave it for future patch bombing. +*/ + DRM_DEBUG_DRIVER(HDMI audio on pipe %c not yet supported on DDI\n, +pipe_name(intel_crtc-pipe)); + } + + /* Enable PIPE_DDI_FUNC_CTL for the pipe to work in HDMI mode */ + temp = I915_READ(DDI_FUNC_CTL(pipe)); + temp = ~PIPE_DDI_PORT_MASK; + temp = ~PIPE_DDI_BPC_12; + temp |= PIPE_DDI_SELECT_PORT(port) | + PIPE_DDI_MODE_SELECT_HDMI | + ((intel_crtc-bpp 24) ? + PIPE_DDI_BPC_12 : + PIPE_DDI_BPC_8) | + PIPE_DDI_FUNC_ENABLE; + + I915_WRITE(DDI_FUNC_CTL(pipe), temp); + + intel_hdmi_set_avi_infoframe(encoder); + intel_hdmi_set_spd_infoframe(encoder); +} + +void intel_ddi_dpms(struct drm_encoder *encoder, int mode) +{ + struct drm_device *dev = encoder-dev; + struct drm_i915_private *dev_priv = dev-dev_private; +
Re: [Intel-gfx] [PATCH 04/24] drm/i915: calculate same watermarks on Haswell as on Ivy Bridge
On Thu, 26 Apr 2012 15:20:59 -0300 Eugeni Dodonov eugeni.dodo...@intel.com wrote: Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_pm.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0552058..06f38ec 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1694,8 +1694,8 @@ static void sandybridge_update_wm(struct drm_device *dev) enabled |= 2; } - /* IVB has 3 pipes */ - if (IS_IVYBRIDGE(dev) + /* Only IVB and Haswell has 3 pipes support so far */ + if ((IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) g4x_compute_wm0(dev, 2, sandybridge_display_wm_info, latency, sandybridge_cursor_wm_info, latency, This could probably just check num_pipes instead. Jesse ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: use the new masked bit macro some more
On Thu, 26 Apr 2012 18:24:54 +0200, Daniel Vetter daniel.vet...@ffwll.ch wrote: I've missed this one. And MI_ARB_STATE. -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
[Intel-gfx] [PATCH 04/24] drm/i915: calculate same watermarks on Haswell as on Ivy Bridge
v2: check for num_pipe instead, as suggested by Jesse CC: Jesse Barnes jbar...@virtuousgeek.org Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_pm.c |3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0552058..4e0af68 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1694,8 +1694,7 @@ static void sandybridge_update_wm(struct drm_device *dev) enabled |= 2; } - /* IVB has 3 pipes */ - if (IS_IVYBRIDGE(dev) + if ((dev_priv-num_pipe == 2) g4x_compute_wm0(dev, 2, sandybridge_display_wm_info, latency, sandybridge_cursor_wm_info, latency, -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] properly enable the blc controller on the right pipe
Daniel, Depending upon how things are set up, this might help. Yeah, thanks a lot, works great now! I removed patch 3/4 and 4/4 and pushed this one; so currently applied are: [PATCH 1/4] drm/i915: clear up backlight inversion confusion on gen4 [PATCH 2/4] drm/i915: completely revert the invert brightness quirk [PATCH] properly enable the blc controller on the right pipe Can you pick these three patches? Thanks, -Carsten. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 15/24] drm/i915: initialize DDI buffer translations
DDI is introduced starting with Haswell GPU generation. So to simplify its management in the future, we also add intel_ddi.c to hold all the DDI-related items. Buffer translations for DDI links must be initialized prior to enablement. For FDI and DP, first 9 pairs of values are used to select the connection parameters. HDMI uses the last pair of values and ignores the first 9 pairs. So we program HDMI values in both cases, which allows HDMI to work over both FDI and DP-friendly buffers. v2: simplify the loop as suggested by Chris Wilson. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/Makefile|1 + drivers/gpu/drm/i915/intel_ddi.c | 111 ++ drivers/gpu/drm/i915/intel_display.c |2 + drivers/gpu/drm/i915/intel_drv.h |1 + 4 files changed, 115 insertions(+) create mode 100644 drivers/gpu/drm/i915/intel_ddi.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 8b8bbc7..0ca7f76 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -19,6 +19,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \ intel_crt.o \ intel_lvds.o \ intel_bios.o \ + intel_ddi.o \ intel_dp.o \ intel_hdmi.o \ intel_sdvo.o \ diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c new file mode 100644 index 000..b1c98e7 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -0,0 +1,111 @@ +/* + * Copyright © 2012 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: + *Eugeni Dodonov eugeni.dodo...@intel.com + * + */ + +#include i915_drv.h +#include intel_drv.h + +/* HDMI/DVI modes ignore everything but the last 2 items. So we share + * them for both DP and FDI transports, allowing those ports to + * automatically adapt to HDMI connections as well + */ +static const u32 hsw_ddi_translations_dp[] = { + 0x00FF, 0x0006000E, + 0x00D75FFF, 0x0005000A, + 0x00C30FFF, 0x00040006, + 0x80AAAFFF, 0x000B, + 0x00FF, 0x0005000A, + 0x00D75FFF, 0x000C0004, + 0x80C30FFF, 0x000B, + 0x00FF, 0x00040006, + 0x80D75FFF, 0x000B, + 0x00FF, 0x00040006 +}; + +static const u32 hsw_ddi_translations_fdi[] = { + 0x00FF, 0x0007000E, + 0x00D75FFF, 0x000F000A, + 0x00C30FFF, 0x00060006, + 0x00AAAFFF, 0x001E, + 0x00FF, 0x000F000A, + 0x00D75FFF, 0x00160004, + 0x00C30FFF, 0x001E, + 0x00FF, 0x00060006, + 0x00D75FFF, 0x001E, + 0x00FF, 0x00040006 +}; + +/* On Haswell, DDI port buffers must be programmed with correct values + * in advance. The buffer values are different for FDI and DP modes, + * but the HDMI/DVI fields are shared among those. So we program the DDI + * in either FDI or DP modes only, as HDMI connections will work with both + * of those + */ +void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, bool use_fdi_mode) +{ + struct drm_i915_private *dev_priv = dev-dev_private; + u32 reg; + int i, j; + const u32 *ddi_translations = ((use_fdi_mode) ? + hsw_ddi_translations_fdi : + hsw_ddi_translations_dp); + + DRM_DEBUG_DRIVER(Initializing DDI buffers for port %c in %s mode\n, + port_name(port), + use_fdi_mode ? FDI : DP); + + WARN((use_fdi_mode (port != PORT_E)), + Programming port %c in FDI mode, this probably will not work.\n, + port_name(port)); + + /* Those registers seem to be double-buffered, so write them twice */ + for (j=0; j 2; j++) { + for (i=0, reg=DDI_BUF_TRANS(port); i ARRAY_SIZE(hsw_ddi_translations_fdi); i++) { + I915_WRITE(reg,
Re: [Intel-gfx] [PATCH 01/24] drm/i915: add Haswell DIP controls registers
On Thu, Apr 26, 2012 at 03:20:56PM -0300, Eugeni Dodonov wrote: Haswell has different DIP control registers and offsets. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com Afaict hsw has a dip reg for every type of info frame, whereas older machines have one dip reg and a switch in the control reg. Can you please the definitions for the other regs here, too, and a big yelling FIXME comment in the second patch saying that this is a hack and Paulo needs to fix things up? -Daniel --- drivers/gpu/drm/i915/i915_reg.h | 16 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f1f4d8f..4f17b74 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3518,6 +3518,22 @@ #define VLV_TVIDEO_DIP_GCP(pipe) \ _PIPE(pipe, VLV_VIDEO_DIP_GDCP_PAYLOAD_A, VLV_VIDEO_DIP_GDCP_PAYLOAD_B) +/* Haswell DIP controls */ +#define HSW_VIDEO_DIP_CTL_A 0x60200 +#define HSW_VIDEO_DIP_AVI_DATA_A 0x60220 +#define HSW_VIDEO_DIP_GCP_A 0x60210 + +#define HSW_VIDEO_DIP_CTL_B 0x61200 +#define HSW_VIDEO_DIP_AVI_DATA_B 0x61220 +#define HSW_VIDEO_DIP_GCP_B 0x61210 + +#define HSW_TVIDEO_DIP_CTL(pipe) \ + _PIPE(pipe, HSW_VIDEO_DIP_CTL_A, HSW_VIDEO_DIP_CTL_B) +#define HSW_TVIDEO_DIP_AVI_DATA(pipe) \ + _PIPE(pipe, HSW_VIDEO_DIP_AVI_DATA_A, HSW_VIDEO_DIP_AVI_DATA_B) +#define HSW_TVIDEO_DIP_GCP(pipe) \ + _PIPE(pipe, HSW_VIDEO_DIP_GCP_A, HSW_VIDEO_DIP_GCP_B) + #define _TRANS_HTOTAL_B 0xe1000 #define _TRANS_HBLANK_B 0xe1004 #define _TRANS_HSYNC_B 0xe1008 -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] properly enable the blc controller on the right pipe
On Thu, Apr 26, 2012 at 09:12:16PM +0200, Carsten Emde wrote: Daniel, Depending upon how things are set up, this might help. Yeah, thanks a lot, works great now! I removed patch 3/4 and 4/4 and pushed this one; so currently applied are: [PATCH 1/4] drm/i915: clear up backlight inversion confusion on gen4 [PATCH 2/4] drm/i915: completely revert the invert brightness quirk [PATCH] properly enable the blc controller on the right pipe Can you pick these three patches? Hey, that was just a quick hack to check things ;-) Can you please also check what happens when you drop the first patch clear up backlight inversion confusion? Hopefully that still works ... -Daniel -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: use the new masked bit macro some more
I've missed this one. v2: Chris Wilson noticed another register. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_gem.c |6 ++ drivers/gpu/drm/i915/i915_reg.h |2 -- drivers/gpu/drm/i915/intel_pm.c |3 +-- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0d53eac..220f481 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3721,10 +3721,8 @@ i915_gem_load(struct drm_device *dev) /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ if (IS_GEN3(dev)) { - u32 tmp = I915_READ(MI_ARB_STATE); - if (!(tmp MI_ARB_C3_LP_WRITE_ENABLE)) { - /* arb state is a masked write, so set bit + bit in mask */ - tmp = MI_ARB_C3_LP_WRITE_ENABLE | (MI_ARB_C3_LP_WRITE_ENABLE MI_ARB_MASK_SHIFT); + if (!(I915_READ(MI_ARB_STATE) MI_ARB_C3_LP_WRITE_ENABLE)) { + u32 tmp = _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE); I915_WRITE(MI_ARB_STATE, tmp); } } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f1f4d8f..7bc407a 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -570,7 +570,6 @@ #define LM_BURST_LENGTH 0x0700 #define LM_FIFO_WATERMARK 0x001F #define MI_ARB_STATE 0x020e4 /* 915+ only */ -#define MI_ARB_MASK_SHIFT 16/* shift for enable bits */ /* Make render/texture TLB fetches lower priorty than associated data * fetches. This is not turned on by default @@ -635,7 +634,6 @@ #define MI_ARB_DISPLAY_PRIORITY_B_A (1 0)/* display B display A */ #define CACHE_MODE_0 0x02120 /* 915+ only */ -#define CM0_MASK_SHIFT 16 #define CM0_IZ_OPT_DISABLE (16) #define CM0_ZR_OPT_DISABLE (15) #define CM0_STC_EVICT_DISABLE_LRA_SNB (15) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0552058..e66330c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2663,9 +2663,8 @@ static void gen6_init_clock_gating(struct drm_device *dev) I915_WRITE(WM2_LP_ILK, 0); I915_WRITE(WM1_LP_ILK, 0); - /* clear masked bit */ I915_WRITE(CACHE_MODE_0, - CM0_STC_EVICT_DISABLE_LRA_SNB CM0_MASK_SHIFT); + _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB)); I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) | -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 01/24] drm/i915: add Haswell DIP controls registers
Haswell has different DIP control registers and offsets. v2: also add the new DIP frame registers, as suggested by Daniel Vetter. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 34 ++ 1 file changed, 34 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f1f4d8f..bdb1771 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3518,6 +3518,40 @@ #define VLV_TVIDEO_DIP_GCP(pipe) \ _PIPE(pipe, VLV_VIDEO_DIP_GDCP_PAYLOAD_A, VLV_VIDEO_DIP_GDCP_PAYLOAD_B) +/* Haswell DIP controls */ +#define HSW_VIDEO_DIP_CTL_A0x60200 +#define HSW_VIDEO_DIP_AVI_DATA_A 0x60220 +#define HSW_VIDEO_DIP_VS_DATA_A0x60260 +#define HSW_VIDEO_DIP_SPD_DATA_A 0x602A0 +#define HSW_VIDEO_DIP_GMP_DATA_A 0x602E0 +#define HSW_VIDEO_DIP_VSC_DATA_A 0x60320 +#define HSW_VIDEO_DIP_AVI_ECC_A0x60240 +#define HSW_VIDEO_DIP_VS_ECC_A 0x60280 +#define HSW_VIDEO_DIP_SPD_ECC_A0x602C0 +#define HSW_VIDEO_DIP_GMP_ECC_A0x60300 +#define HSW_VIDEO_DIP_VSC_ECC_A0x60344 +#define HSW_VIDEO_DIP_GCP_A0x60210 + +#define HSW_VIDEO_DIP_CTL_B0x61200 +#define HSW_VIDEO_DIP_AVI_DATA_B 0x61220 +#define HSW_VIDEO_DIP_VS_DATA_A0x61260 +#define HSW_VIDEO_DIP_SPD_DATA_B 0x612A0 +#define HSW_VIDEO_DIP_GMP_DATA_B 0x612E0 +#define HSW_VIDEO_DIP_VSC_DATA_B 0x61320 +#define HSW_VIDEO_DIP_BVI_ECC_B0x61240 +#define HSW_VIDEO_DIP_VS_ECC_B 0x61280 +#define HSW_VIDEO_DIP_SPD_ECC_B0x612C0 +#define HSW_VIDEO_DIP_GMP_ECC_B0x61300 +#define HSW_VIDEO_DIP_VSC_ECC_B0x61344 +#define HSW_VIDEO_DIP_GCP_B0x61210 + +#define HSW_TVIDEO_DIP_CTL(pipe) \ +_PIPE(pipe, HSW_VIDEO_DIP_CTL_A, HSW_VIDEO_DIP_CTL_B) +#define HSW_TVIDEO_DIP_AVI_DATA(pipe) \ +_PIPE(pipe, HSW_VIDEO_DIP_AVI_DATA_A, HSW_VIDEO_DIP_AVI_DATA_B) +#define HSW_TVIDEO_DIP_GCP(pipe) \ + _PIPE(pipe, HSW_VIDEO_DIP_GCP_A, HSW_VIDEO_DIP_GCP_B) + #define _TRANS_HTOTAL_B 0xe1000 #define _TRANS_HBLANK_B 0xe1004 #define _TRANS_HSYNC_B 0xe1008 -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 02/24] drm/i915: support infoframes on Haswell
Haswell has different DIP registers which we need to use for infoframes, so add proper infrastructure to address that. v2: add a comment to indicate that full DIP frames support is still not there, as suggested by Daniel Vetter. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_hdmi.c | 37 + 1 file changed, 37 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 7de2d3b..a215ae7 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -208,6 +208,36 @@ static void vlv_write_infoframe(struct drm_encoder *encoder, I915_WRITE(reg, VIDEO_DIP_ENABLE | val | flags); } +static void hsw_write_infoframe(struct drm_encoder *encoder, +struct dip_infoframe *frame) +{ + uint32_t *data = (uint32_t *)frame; + struct drm_device *dev = encoder-dev; + struct drm_i915_private *dev_priv = dev-dev_private; + struct drm_crtc *crtc = encoder-crtc; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int reg = HSW_TVIDEO_DIP_CTL(intel_crtc-pipe); + unsigned i, len = DIP_HEADER_SIZE + frame-len; + u32 flags, val = I915_READ(reg); + + intel_wait_for_vblank(dev, intel_crtc-pipe); + + flags = intel_infoframe_index(frame); + + val = ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ + + I915_WRITE(reg, VIDEO_DIP_ENABLE | val | flags); + + for (i = 0; i len; i += 4) { + I915_WRITE(HSW_TVIDEO_DIP_AVI_DATA(intel_crtc-pipe), *data); + data++; + } + + flags |= intel_infoframe_flags(frame); + + I915_WRITE(reg, VIDEO_DIP_ENABLE | val | flags); +} + static void intel_set_infoframe(struct drm_encoder *encoder, struct dip_infoframe *frame) { @@ -587,6 +617,13 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) intel_hdmi-write_infoframe = vlv_write_infoframe; for_each_pipe(i) I915_WRITE(VLV_TVIDEO_DIP_CTL(i), 0); + } else if (IS_HASWELL(dev)) { +/* FIXME: Haswell has a new set of DIP frame registers, but we are + * just doing the minimal required for HDMI to work at this stage. + */ + intel_hdmi-write_infoframe = hsw_write_infoframe; + for_each_pipe(i) + I915_WRITE(HSW_TVIDEO_DIP_CTL(i), 0); } else { intel_hdmi-write_infoframe = ironlake_write_infoframe; for_each_pipe(i) -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: use the new masked bit macro some more
On Thu, 26 Apr 2012 21:33:02 +0200, Daniel Vetter daniel.vet...@ffwll.ch wrote: /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ if (IS_GEN3(dev)) { - u32 tmp = I915_READ(MI_ARB_STATE); - if (!(tmp MI_ARB_C3_LP_WRITE_ENABLE)) { - /* arb state is a masked write, so set bit + bit in mask */ - tmp = MI_ARB_C3_LP_WRITE_ENABLE | (MI_ARB_C3_LP_WRITE_ENABLE MI_ARB_MASK_SHIFT); + if (!(I915_READ(MI_ARB_STATE) MI_ARB_C3_LP_WRITE_ENABLE)) { + u32 tmp = _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE); I915_WRITE(MI_ARB_STATE, tmp); Just write the masked bit, the state before is irrelevant. I can't spot any other shifts that look to be being used as a mask, so whatever the outcome of the above bikeshedding: Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk -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 16/24] drm/i915: support DDI training in FDI mode
On Thu, Apr 26, 2012 at 03:21:11PM -0300, Eugeni Dodonov wrote: Starting with Haswell, DDI ports can work in FDI mode to support connectivity with the outputs located on the PCH. This commit adds support for such connections in the intel_ddi module, and provides Haswell-specific functionality to make it work. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 121 ++ drivers/gpu/drm/i915/intel_display.c |3 + drivers/gpu/drm/i915/intel_drv.h |1 + drivers/gpu/drm/i915/intel_pm.c | 10 +++ 4 files changed, 135 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 32594a8..93436caa 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -109,3 +109,124 @@ void intel_prepare_ddi(struct drm_device *dev) intel_prepare_ddi_buffers(dev, PORT_E, true); } } + +static const long hsw_ddi_buf_ctl_values[] = { + DDI_BUF_EMP_400MV_0DB_HSW, + DDI_BUF_EMP_400MV_3_5DB_HSW, + DDI_BUF_EMP_400MV_6DB_HSW, + DDI_BUF_EMP_400MV_9_5DB_HSW, + DDI_BUF_EMP_600MV_0DB_HSW, + DDI_BUF_EMP_600MV_3_5DB_HSW, + DDI_BUF_EMP_600MV_6DB_HSW, + DDI_BUF_EMP_800MV_0DB_HSW, + DDI_BUF_EMP_800MV_3_5DB_HSW +}; + + +/* Link training for Haswell DDI port to work in FDI mode */ +static void hsw_fdi_link_train(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc-dev; + struct drm_i915_private *dev_priv = dev-dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc-pipe; + u32 reg, temp, i; + + /* Configure CPU PLL, wait for warmup */ + I915_WRITE(SPLL_CTL, + SPLL_PLL_ENABLE | + SPLL_PLL_FREQ_1350MHz | + SPLL_PLL_SCC); + + /* Use SPLL to drive the output when in FDI mode */ + I915_WRITE(PORT_CLK_SEL(PORT_E), + PORT_CLK_SEL_SPLL); + I915_WRITE(PIPE_CLK_SEL(pipe), + PIPE_CLK_SEL_PORT(PORT_E)); + + udelay(20); + + /* Start the training iterating through available voltages and emphasis */ + for (i=0; i ARRAY_SIZE(hsw_ddi_buf_ctl_values); i++) { + /* Configure DP_TP_CTL with auto-training */ + I915_WRITE(DP_TP_CTL(PORT_E), + DP_TP_CTL_FDI_AUTOTRAIN | + DP_TP_CTL_ENHANCED_FRAME_ENABLE | + DP_TP_CTL_LINK_TRAIN_PAT1 | + DP_TP_CTL_ENABLE); + + /* Configure and enable DDI_BUF_CTL for DDI E with next voltage */ + temp = I915_READ(DDI_BUF_CTL(PORT_E)); + temp = (temp ~DDI_BUF_EMP_MASK); + I915_WRITE(DDI_BUF_CTL(PORT_E), + temp | + DDI_BUF_CTL_ENABLE | + DDI_PORT_WIDTH_X2 | + hsw_ddi_buf_ctl_values[i]); + + udelay(600); + + /* Enable CPU FDI Receiver with auto-training */ + reg = FDI_RX_CTL(pipe); + I915_WRITE(reg, + I915_READ(reg) | + FDI_LINK_TRAIN_AUTO | + FDI_RX_ENABLE | + FDI_LINK_TRAIN_PATTERN_1_CPT | + FDI_RX_ENHANCE_FRAME_ENABLE | + FDI_PORT_WIDTH_2X_LPT | + FDI_RX_PLL_ENABLE); + POSTING_READ(reg); + udelay(100); + + temp = I915_READ(DP_TP_STATUS(PORT_E)); + if (temp DP_TP_STATUS_AUTOTRAIN_DONE) { + DRM_DEBUG_DRIVER(BUF_CTL training done on %d step\n, i); + + /* Enable normal pixel sending for FDI */ + I915_WRITE(DP_TP_CTL(PORT_E), + DP_TP_CTL_FDI_AUTOTRAIN | + DP_TP_CTL_LINK_TRAIN_NORMAL | + DP_TP_CTL_ENHANCED_FRAME_ENABLE | + DP_TP_CTL_ENABLE); + + /* Enable PIPE_DDI_FUNC_CTL for the pipe to work in FDI mode */ + temp = I915_READ(DDI_FUNC_CTL(pipe)); + temp = ~PIPE_DDI_PORT_MASK; + temp |= PIPE_DDI_SELECT_PORT(PORT_E) | + PIPE_DDI_MODE_SELECT_FDI | + PIPE_DDI_FUNC_ENABLE | + PIPE_DDI_PORT_WIDTH_X2; + I915_WRITE(DDI_FUNC_CTL(pipe), + temp); + break; +
Re: [Intel-gfx] [PATCH] drm/i915: Prefer to pageflip on the active ring on IvyBridge
On Mon, 16 Apr 2012 15:29:41 +0100, Chris Wilson ch...@chris-wilson.co.uk wrote: IvyBridge has the ability to pageflip from either the Render or Blitter rings. Scheduling the pageflip on the active ring (if the new scanout is being rendered on either pipeline) saves inserting a semaphore (if available) and forcing a stall on both pipelines. We presume that the current scanout is inactive. As a follow-up to my own suggestion; don't even think of pageflipping from the render ring, it is full of disappointment. -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
[Intel-gfx] [PATCH 01/24] drm/i915: add Haswell DIP controls registers
Haswell has different DIP control registers and offsets. v2: also add the new DIP frame registers, as suggested by Daniel Vetter. v2.1: fix a typo in HSW_VIDEO_DIP_VS_DATA name for 2nd register. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 34 ++ 1 file changed, 34 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f1f4d8f..76e2233 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3518,6 +3518,40 @@ #define VLV_TVIDEO_DIP_GCP(pipe) \ _PIPE(pipe, VLV_VIDEO_DIP_GDCP_PAYLOAD_A, VLV_VIDEO_DIP_GDCP_PAYLOAD_B) +/* Haswell DIP controls */ +#define HSW_VIDEO_DIP_CTL_A0x60200 +#define HSW_VIDEO_DIP_AVI_DATA_A 0x60220 +#define HSW_VIDEO_DIP_VS_DATA_A0x60260 +#define HSW_VIDEO_DIP_SPD_DATA_A 0x602A0 +#define HSW_VIDEO_DIP_GMP_DATA_A 0x602E0 +#define HSW_VIDEO_DIP_VSC_DATA_A 0x60320 +#define HSW_VIDEO_DIP_AVI_ECC_A0x60240 +#define HSW_VIDEO_DIP_VS_ECC_A 0x60280 +#define HSW_VIDEO_DIP_SPD_ECC_A0x602C0 +#define HSW_VIDEO_DIP_GMP_ECC_A0x60300 +#define HSW_VIDEO_DIP_VSC_ECC_A0x60344 +#define HSW_VIDEO_DIP_GCP_A0x60210 + +#define HSW_VIDEO_DIP_CTL_B0x61200 +#define HSW_VIDEO_DIP_AVI_DATA_B 0x61220 +#define HSW_VIDEO_DIP_VS_DATA_B0x61260 +#define HSW_VIDEO_DIP_SPD_DATA_B 0x612A0 +#define HSW_VIDEO_DIP_GMP_DATA_B 0x612E0 +#define HSW_VIDEO_DIP_VSC_DATA_B 0x61320 +#define HSW_VIDEO_DIP_BVI_ECC_B0x61240 +#define HSW_VIDEO_DIP_VS_ECC_B 0x61280 +#define HSW_VIDEO_DIP_SPD_ECC_B0x612C0 +#define HSW_VIDEO_DIP_GMP_ECC_B0x61300 +#define HSW_VIDEO_DIP_VSC_ECC_B0x61344 +#define HSW_VIDEO_DIP_GCP_B0x61210 + +#define HSW_TVIDEO_DIP_CTL(pipe) \ +_PIPE(pipe, HSW_VIDEO_DIP_CTL_A, HSW_VIDEO_DIP_CTL_B) +#define HSW_TVIDEO_DIP_AVI_DATA(pipe) \ +_PIPE(pipe, HSW_VIDEO_DIP_AVI_DATA_A, HSW_VIDEO_DIP_AVI_DATA_B) +#define HSW_TVIDEO_DIP_GCP(pipe) \ + _PIPE(pipe, HSW_VIDEO_DIP_GCP_A, HSW_VIDEO_DIP_GCP_B) + #define _TRANS_HTOTAL_B 0xe1000 #define _TRANS_HBLANK_B 0xe1004 #define _TRANS_HSYNC_B 0xe1008 -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 14/24] drm/i915: account for only one PCH receiver on Haswell
On Thu, Apr 26, 2012 at 03:21:09PM -0300, Eugeni Dodonov wrote: On Haswell, only one pipe can work in FDI mode, so this patch prevents messing with wrong registers when FDI is being used by non-first pipe. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com I think we need to restrict the vga encoder to pipe 0 with possible_crtcs, otherwise userspace won't figure out why vga just won't work. Can you please add this to this patch? Also, please add a small note to the commit message that fdi should work on any pipe, we're just making our lifes easier for now ... -Daniel --- drivers/gpu/drm/i915/intel_display.c | 19 --- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b2d3dc1..6509402 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -978,9 +978,14 @@ static void assert_fdi_rx(struct drm_i915_private *dev_priv, u32 val; bool cur_state; - reg = FDI_RX_CTL(pipe); - val = I915_READ(reg); - cur_state = !!(val FDI_RX_ENABLE); + if (IS_HASWELL(dev_priv-dev) pipe 0) { + DRM_ERROR(Attempting to enable FDI_RX on Haswell pipe 0\n); + return; + } else { + reg = FDI_RX_CTL(pipe); + val = I915_READ(reg); + cur_state = !!(val FDI_RX_ENABLE); + } WARN(cur_state != state, FDI RX state assertion failure (expected %s, current %s)\n, state_string(state), state_string(cur_state)); @@ -1013,6 +1018,10 @@ static void assert_fdi_rx_pll_enabled(struct drm_i915_private *dev_priv, int reg; u32 val; + if (IS_HASWELL(dev_priv-dev) pipe 0) { + DRM_ERROR(Attempting to enable FDI on Haswell with pipe 0\n); + return; + } reg = FDI_RX_CTL(pipe); val = I915_READ(reg); WARN(!(val FDI_RX_PLL_ENABLE), FDI RX PLL assertion failure, should be active but is disabled\n); @@ -1484,6 +1493,10 @@ static void intel_enable_transcoder(struct drm_i915_private *dev_priv, assert_fdi_tx_enabled(dev_priv, pipe); assert_fdi_rx_enabled(dev_priv, pipe); + if (IS_HASWELL(dev_priv-dev) pipe 0) { + DRM_ERROR(Attempting to enable transcoder on Haswell with pipe 0\n); + return; + } reg = TRANSCONF(pipe); val = I915_READ(reg); pipeconf_val = I915_READ(PIPECONF(pipe)); -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: use the new masked bit macro some more
I've missed this one. v2: Chris Wilson noticed another register. v3: Color choice improvements. Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_gem.c |8 ++-- drivers/gpu/drm/i915/i915_reg.h |2 -- drivers/gpu/drm/i915/intel_pm.c |3 +-- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0d53eac..b46a3fd 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3721,12 +3721,8 @@ i915_gem_load(struct drm_device *dev) /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ if (IS_GEN3(dev)) { - u32 tmp = I915_READ(MI_ARB_STATE); - if (!(tmp MI_ARB_C3_LP_WRITE_ENABLE)) { - /* arb state is a masked write, so set bit + bit in mask */ - tmp = MI_ARB_C3_LP_WRITE_ENABLE | (MI_ARB_C3_LP_WRITE_ENABLE MI_ARB_MASK_SHIFT); - I915_WRITE(MI_ARB_STATE, tmp); - } + I915_WRITE(MI_ARB_STATE, + _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE)); } dev_priv-relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f1f4d8f..7bc407a 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -570,7 +570,6 @@ #define LM_BURST_LENGTH 0x0700 #define LM_FIFO_WATERMARK 0x001F #define MI_ARB_STATE 0x020e4 /* 915+ only */ -#define MI_ARB_MASK_SHIFT 16/* shift for enable bits */ /* Make render/texture TLB fetches lower priorty than associated data * fetches. This is not turned on by default @@ -635,7 +634,6 @@ #define MI_ARB_DISPLAY_PRIORITY_B_A (1 0)/* display B display A */ #define CACHE_MODE_0 0x02120 /* 915+ only */ -#define CM0_MASK_SHIFT 16 #define CM0_IZ_OPT_DISABLE (16) #define CM0_ZR_OPT_DISABLE (15) #define CM0_STC_EVICT_DISABLE_LRA_SNB (15) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0552058..e66330c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2663,9 +2663,8 @@ static void gen6_init_clock_gating(struct drm_device *dev) I915_WRITE(WM2_LP_ILK, 0); I915_WRITE(WM1_LP_ILK, 0); - /* clear masked bit */ I915_WRITE(CACHE_MODE_0, - CM0_STC_EVICT_DISABLE_LRA_SNB CM0_MASK_SHIFT); + _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB)); I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) | -- 1.7.10 ___ 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: i915.enable_backlight=0 disables intel_backlight
On Wed, Apr 25, 2012 at 10:28:41AM -0700, Kamal Mostafa wrote: i915.enable_backlight=0 can be used to disable i915 backlight control and the /sys/class/backlight/intel_backlight interface -- useful for systems where intel_backight conflicts with BIOS backlight control. BugLink: https://launchpad.net/bugs/954661 Signed-off-by: Kamal Mostafa ka...@canonical.com Ok, I've just gone through the fun of merging a set of backlight quirks a few weeks back. Then noticed that an awful lot of machines seem to be affected and later on read about a few interesting bits in the documentation. Turns out the hw is all good, it's just the driver totally mishandling the backlight. To cut things short: This time around I want more justification for the quirk than just this makes this one machine work somehow. -Daniel --- drivers/gpu/drm/i915/i915_drv.c|6 ++ drivers/gpu/drm/i915/i915_drv.h|1 + drivers/gpu/drm/i915/intel_panel.c | 12 3 files changed, 19 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ae8a64f..ddb947b 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -112,6 +112,12 @@ module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, int, 0600); MODULE_PARM_DESC(i915_enable_ppgtt, Enable PPGTT (default: true)); +int i915_enable_backlight __read_mostly = -1; +module_param_named(enable_backlight, i915_enable_backlight, int, 0644); +MODULE_PARM_DESC(enable_backlight, + Enable backlight control and the intel_backlight interface. + (default: -1 (auto))); + static struct drm_driver driver; extern int intel_agp_enabled; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5fabc6c..6e52a42 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1087,6 +1087,7 @@ extern int i915_enable_rc6 __read_mostly; extern int i915_enable_fbc __read_mostly; extern bool i915_enable_hangcheck __read_mostly; extern int i915_enable_ppgtt __read_mostly; +extern int i915_enable_backlight __read_mostly; extern int i915_suspend(struct drm_device *dev, pm_message_t state); extern int i915_resume(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 48177ec..fcecbd2 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -259,6 +259,9 @@ void intel_panel_disable_backlight(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev-dev_private; + if (!i915_enable_backlight) + return; + dev_priv-backlight_enabled = false; intel_panel_actually_set_backlight(dev, 0); } @@ -267,6 +270,9 @@ void intel_panel_enable_backlight(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev-dev_private; + if (!i915_enable_backlight) + return; + if (dev_priv-backlight_level == 0) dev_priv-backlight_level = intel_panel_get_max_backlight(dev); @@ -333,6 +339,9 @@ int intel_panel_setup_backlight(struct drm_device *dev) struct backlight_properties props; struct drm_connector *connector; + if (!i915_enable_backlight) + return 0; + intel_panel_init_backlight(dev); if (dev_priv-int_lvds_connector) @@ -368,6 +377,9 @@ void intel_panel_destroy_backlight(struct drm_device *dev) #else int intel_panel_setup_backlight(struct drm_device *dev) { + if (!i915_enable_backlight) + return; + intel_panel_init_backlight(dev); return 0; } -- 1.7.5.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 12/12] drm/i915: Remove unused and unloved vblank macros
On Wed, Apr 25, 2012 at 01:55:24PM -0700, Jesse Barnes wrote: On Tue, 24 Apr 2012 22:59:52 +0100 Chris Wilson ch...@chris-wilson.co.uk wrote: Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_irq.c | 11 --- 1 file changed, 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a1150b7..d3500c7 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -37,17 +37,6 @@ #include i915_trace.h #include intel_drv.h -#define MAX_NOPID ((u32)~0) - -#define I915_PIPE_VBLANK_STATUS(PIPE_START_VBLANK_INTERRUPT_STATUS |\ -PIPE_VBLANK_INTERRUPT_STATUS) - -#define I915_PIPE_VBLANK_ENABLE(PIPE_START_VBLANK_INTERRUPT_ENABLE |\ -PIPE_VBLANK_INTERRUPT_ENABLE) - -#define DRM_I915_VBLANK_PIPE_ALL (DRM_I915_VBLANK_PIPE_A | \ -DRM_I915_VBLANK_PIPE_B) - /* For display hotplug interrupt */ static void ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) Yay. Reviewed-by: Jesse Barnes jbar...@virtuousgeek.org I've slurped in the entire series for -next, thanks for the patches and review. -Daniel -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 00/17] dri1 dragon slaughtering, v2
Hi all, Essentially just rebased on top of latest dinq. Happy bikeshedding! Cheers, Daniel Daniel Vetter (17): drm/i915: move dri1 vblank stubs to i915_dma.c drm/i915: create dev_priv-dri1 dragon dungeon^W^W sub-struct drm/i915 disallow physical batchbuffers for KMS drm/i915: rip out dev_priv-tex_lru_log_granularity drm/i915: remove LP_RINGfriends from modeset code drm/i915: kill intel_clear_scanline_wait drm/i915: rip out dri1 breadcrumb updates from gen5+ irq handlers drm/i915: move dri1 irq ioctl code to i915_dma.c drm/i915: extract dri1 breadcrumb update from irq handler drm/i915: move LP_RINGfriends to i915_dma.c drm/i915: disallow clip rects on gen5+ drm/i915: move the ips code to intel_pm.c drm/i915: move rps/emon function declarations drm/i915: kill pointless clearing of dev_priv-hws_map drm/i915: rework legacy GFX HWS handling drm/i915: fixup __iomem mixups in ringbuffer.c drm/i915: move pnv|ilk_gem_mem_freq to intel_pm.c drivers/gpu/drm/i915/i915_dma.c| 815 drivers/gpu/drm/i915/i915_drv.h| 48 +-- drivers/gpu/drm/i915/i915_gem.c|5 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c |5 + drivers/gpu/drm/i915/i915_irq.c| 211 +--- drivers/gpu/drm/i915/intel_display.c | 100 ++-- drivers/gpu/drm/i915/intel_drv.h | 12 +- drivers/gpu/drm/i915/intel_overlay.c | 58 ++- drivers/gpu/drm/i915/intel_pm.c| 618 +- drivers/gpu/drm/i915/intel_ringbuffer.c| 44 +-- drivers/gpu/drm/i915/intel_ringbuffer.h|8 +- 11 files changed, 937 insertions(+), 987 deletions(-) -- 1.7.7.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 00/17] dri1 dragon slaughtering, v2
Hi all, Essentially just rebased on top of latest dinq. Happy bikeshedding! Cheers, Daniel Daniel Vetter (17): drm/i915: move dri1 vblank stubs to i915_dma.c drm/i915: create dev_priv-dri1 dragon dungeon^W^W sub-struct drm/i915 disallow physical batchbuffers for KMS drm/i915: rip out dev_priv-tex_lru_log_granularity drm/i915: remove LP_RINGfriends from modeset code drm/i915: kill intel_clear_scanline_wait drm/i915: rip out dri1 breadcrumb updates from gen5+ irq handlers drm/i915: move dri1 irq ioctl code to i915_dma.c drm/i915: extract dri1 breadcrumb update from irq handler drm/i915: move LP_RINGfriends to i915_dma.c drm/i915: disallow clip rects on gen5+ drm/i915: move the ips code to intel_pm.c drm/i915: move rps/emon function declarations drm/i915: kill pointless clearing of dev_priv-hws_map drm/i915: rework legacy GFX HWS handling drm/i915: fixup __iomem mixups in ringbuffer.c drm/i915: move pnv|ilk_gem_mem_freq to intel_pm.c drivers/gpu/drm/i915/i915_dma.c| 815 drivers/gpu/drm/i915/i915_drv.h| 48 +-- drivers/gpu/drm/i915/i915_gem.c|5 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c |5 + drivers/gpu/drm/i915/i915_irq.c| 211 +--- drivers/gpu/drm/i915/intel_display.c | 100 ++-- drivers/gpu/drm/i915/intel_drv.h | 12 +- drivers/gpu/drm/i915/intel_overlay.c | 58 ++- drivers/gpu/drm/i915/intel_pm.c| 618 +- drivers/gpu/drm/i915/intel_ringbuffer.c| 44 +-- drivers/gpu/drm/i915/intel_ringbuffer.h|8 +- 11 files changed, 937 insertions(+), 987 deletions(-) -- 1.7.7.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 01/17] drm/i915: move dri1 vblank stubs to i915_dma.c
i915_dma.c contains most of the old dri1 horror-show, so move the remaining bits there, too. The code has been removed and the only thing left are some stubs to ensure that userspace doesn't try to use this stuff. vblank_pipe_set only returns 0 without any side-effects, so we can even stub it out with the canonical drm_noop. v2: Rebase against ENODEV changes. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_dma.c | 44 +++- drivers/gpu/drm/i915/i915_drv.h |7 drivers/gpu/drm/i915/i915_irq.c | 61 --- 3 files changed, 43 insertions(+), 69 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 7a55abb..653fc86 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -721,6 +721,48 @@ fail_batch_free: return ret; } +static int i915_vblank_pipe_get(struct drm_device *dev, void *data, +struct drm_file *file_priv) +{ + drm_i915_private_t *dev_priv = dev-dev_private; + drm_i915_vblank_pipe_t *pipe = data; + + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return -ENODEV; + + if (!dev_priv) { + DRM_ERROR(called with no initialization\n); + return -EINVAL; + } + + pipe-pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; + + return 0; +} + +/** + * Schedule buffer swap at given vertical blank. + */ +static int i915_vblank_swap(struct drm_device *dev, void *data, +struct drm_file *file_priv) +{ + /* The delayed swap mechanism was fundamentally racy, and has been +* removed. The model was that the client requested a delayed flip/swap +* from the kernel, then waited for vblank before continuing to perform +* rendering. The problem was that the kernel might wake the client +* up before it dispatched the vblank swap (since the lock has to be +* held while touching the ringbuffer), in which case the client would +* clear and start the next frame before the swap occurred, and +* flicker would occur in addition to likely missing the vblank. +* +* In the absence of this ioctl, userland falls back to a correct path +* of waiting for a vblank, then dispatching the swap on its own. +* Context switching to userland and back is plenty fast enough for +* meeting the requirements of vblank swapping. +*/ + return -EINVAL; +} + static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -2156,7 +2198,7 @@ struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH), DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0095c8d..d60b573 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1155,13 +1155,6 @@ extern int i915_irq_wait(struct drm_device *dev, void *data, extern void intel_irq_init(struct drm_device *dev); -extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int i915_vblank_swap(struct drm_device *dev, void *data, - struct drm_file *file_priv); - void i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5c360ee..874956c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1628,67 +1628,6 @@ static void valleyview_disable_vblank(struct drm_device *dev, int pipe) spin_unlock_irqrestore(dev_priv-irq_lock, irqflags); } - -/* Set the vblank monitor pipe - */ -int i915_vblank_pipe_set(struct drm_device *dev, void *data, -struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev-dev_private; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -ENODEV; - - if (!dev_priv) { - DRM_ERROR(called with no
[Intel-gfx] [PATCH 02/17] drm/i915: create dev_priv-dri1 dragon dungeon^W^W sub-struct
... and shove allow_batchbuffer in there. More dragons will follow suit. There's the curious case that we allow this for KMS ... Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_dma.c |8 drivers/gpu/drm/i915/i915_drv.h | 11 ++- drivers/gpu/drm/i915/i915_gem.c |2 +- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 653fc86..0da8f12 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -198,7 +198,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) /* Allow hardware batchbuffers unless told otherwise. */ - dev_priv-allow_batchbuffer = 1; + dev_priv-dri1.allow_batchbuffer = 1; return 0; } @@ -610,7 +610,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, if (drm_core_check_feature(dev, DRIVER_MODESET)) return -ENODEV; - if (!dev_priv-allow_batchbuffer) { + if (!dev_priv-dri1.allow_batchbuffer) { DRM_ERROR(Batchbuffer ioctl disabled\n); return -EINVAL; } @@ -799,7 +799,7 @@ static int i915_getparam(struct drm_device *dev, void *data, value = dev-pdev-irq ? 1 : 0; break; case I915_PARAM_ALLOW_BATCHBUFFER: - value = dev_priv-allow_batchbuffer ? 1 : 0; + value = dev_priv-dri1.allow_batchbuffer ? 1 : 0; break; case I915_PARAM_LAST_DISPATCH: value = READ_BREADCRUMB(dev_priv); @@ -882,7 +882,7 @@ static int i915_setparam(struct drm_device *dev, void *data, dev_priv-tex_lru_log_granularity = param-value; break; case I915_SETPARAM_ALLOW_BATCHBUFFER: - dev_priv-allow_batchbuffer = param-value; + dev_priv-dri1.allow_batchbuffer = param-value ? 1 : 0; break; case I915_SETPARAM_NUM_USED_FENCES: if (param-value dev_priv-num_fence_regs || diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d60b573..aaa038a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -397,7 +397,6 @@ typedef struct drm_i915_private { struct work_struct hotplug_work; int tex_lru_log_granularity; - int allow_batchbuffer; unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; int vblank_pipe; int num_pipe; @@ -630,6 +629,7 @@ typedef struct drm_i915_private { u32 saveMCHBAR_RENDER_STANDBY; u32 savePCH_PORT_HOTPLUG; + struct { /** Bridge to intel-gtt-ko */ const struct intel_gtt *gtt; @@ -739,6 +739,15 @@ typedef struct drm_i915_private { size_t object_memory; u32 object_count; } mm; + + /* Old dri1 support infrastructure, beware the dragons ya fools entering +* here! */ + struct { + unsigned allow_batchbuffer : 1; + } dri1; + + /* Kernel Modesetting */ + struct sdvo_device_mapping sdvo_mappings[2]; /* indicate whether the LVDS_BORDER should be enabled or not */ unsigned int lvds_border_bits; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0d53eac..f06316f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3606,7 +3606,7 @@ int i915_gem_init(struct drm_device *dev) } /* Allow hardware batchbuffers unless told otherwise. */ - dev_priv-allow_batchbuffer = 1; + dev_priv-dri1.allow_batchbuffer = 1; return 0; } -- 1.7.7.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 03/17] drm/i915 disallow physical batchbuffers for KMS
Even the horrible gen3 XvMC code has learned to do this right by the time xf86-video-intel releases learned to do kernel modesetting. So we can just disallow this. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_gem.c |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f06316f..97d2276 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3605,8 +3605,9 @@ int i915_gem_init(struct drm_device *dev) return ret; } - /* Allow hardware batchbuffers unless told otherwise. */ - dev_priv-dri1.allow_batchbuffer = 1; + /* Allow hardware batchbuffers unless told otherwise, but not for KMS. */ + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + dev_priv-dri1.allow_batchbuffer = 1; return 0; } -- 1.7.7.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 04/17] drm/i915: rip out dev_priv-tex_lru_log_granularity
Assigned in setparam, used never. I didn't bother to dig through the archives to figure out what this was supposed to do. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_dma.c |1 - drivers/gpu/drm/i915/i915_drv.h |1 - 2 files changed, 0 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 0da8f12..7db7eab 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -879,7 +879,6 @@ static int i915_setparam(struct drm_device *dev, void *data, case I915_SETPARAM_USE_MI_BATCHBUFFER_START: break; case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: - dev_priv-tex_lru_log_granularity = param-value; break; case I915_SETPARAM_ALLOW_BATCHBUFFER: dev_priv-dri1.allow_batchbuffer = param-value ? 1 : 0; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index aaa038a..894a551 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -396,7 +396,6 @@ typedef struct drm_i915_private { u32 hotplug_supported_mask; struct work_struct hotplug_work; - int tex_lru_log_granularity; unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; int vblank_pipe; int num_pipe; -- 1.7.7.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 05/17] drm/i915: remove LP_RINGfriends from modeset code
The LP refers to 'low priority' as opposed to the high priority ring on gen2/3. So lets constrain its use to the code of that era. Unfortunately we can't yet completely remove the associated macros from common headers and shove them into i915_dma.c to the other dri1 legacy support code, a few cleanups are still missing for that. Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/intel_display.c | 78 ++ drivers/gpu/drm/i915/intel_overlay.c | 58 ++--- drivers/gpu/drm/i915/intel_pm.c | 27 ++-- 3 files changed, 87 insertions(+), 76 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e1716be..278c0f0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5749,16 +5749,17 @@ static int intel_gen2_queue_flip(struct drm_device *dev, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); unsigned long offset; u32 flip_mask; + struct intel_ring_buffer *ring = dev_priv-ring[RCS]; int ret; - ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); + ret = intel_pin_and_fence_fb_obj(dev, obj, ring); if (ret) goto err; /* Offset into the new buffer for cases of shared fbs between CRTCs */ offset = crtc-y * fb-pitches[0] + crtc-x * fb-bits_per_pixel/8; - ret = BEGIN_LP_RING(6); + ret = intel_ring_begin(ring, 6); if (ret) goto err_unpin; @@ -5769,14 +5770,14 @@ static int intel_gen2_queue_flip(struct drm_device *dev, flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; else flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; - OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); - OUT_RING(MI_NOOP); - OUT_RING(MI_DISPLAY_FLIP | -MI_DISPLAY_FLIP_PLANE(intel_crtc-plane)); - OUT_RING(fb-pitches[0]); - OUT_RING(obj-gtt_offset + offset); - OUT_RING(0); /* aux display base address, unused */ - ADVANCE_LP_RING(); + intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask); + intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(ring, MI_DISPLAY_FLIP | + MI_DISPLAY_FLIP_PLANE(intel_crtc-plane)); + intel_ring_emit(ring, fb-pitches[0]); + intel_ring_emit(ring, obj-gtt_offset + offset); + intel_ring_emit(ring, 0); /* aux display base address, unused */ + intel_ring_advance(ring); return 0; err_unpin: @@ -5794,16 +5795,17 @@ static int intel_gen3_queue_flip(struct drm_device *dev, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); unsigned long offset; u32 flip_mask; + struct intel_ring_buffer *ring = dev_priv-ring[RCS]; int ret; - ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); + ret = intel_pin_and_fence_fb_obj(dev, obj, ring); if (ret) goto err; /* Offset into the new buffer for cases of shared fbs between CRTCs */ offset = crtc-y * fb-pitches[0] + crtc-x * fb-bits_per_pixel/8; - ret = BEGIN_LP_RING(6); + ret = intel_ring_begin(ring, 6); if (ret) goto err_unpin; @@ -5811,15 +5813,15 @@ static int intel_gen3_queue_flip(struct drm_device *dev, flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; else flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; - OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); - OUT_RING(MI_NOOP); - OUT_RING(MI_DISPLAY_FLIP_I915 | -MI_DISPLAY_FLIP_PLANE(intel_crtc-plane)); - OUT_RING(fb-pitches[0]); - OUT_RING(obj-gtt_offset + offset); - OUT_RING(MI_NOOP); - - ADVANCE_LP_RING(); + intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask); + intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | + MI_DISPLAY_FLIP_PLANE(intel_crtc-plane)); + intel_ring_emit(ring, fb-pitches[0]); + intel_ring_emit(ring, obj-gtt_offset + offset); + intel_ring_emit(ring, MI_NOOP); + + intel_ring_advance(ring); return 0; err_unpin: @@ -5836,13 +5838,14 @@ static int intel_gen4_queue_flip(struct drm_device *dev, struct drm_i915_private *dev_priv = dev-dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); uint32_t pf, pipesrc; + struct intel_ring_buffer *ring = dev_priv-ring[RCS]; int ret; - ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); + ret = intel_pin_and_fence_fb_obj(dev, obj, ring); if (ret) goto err; - ret = BEGIN_LP_RING(4); + ret = intel_ring_begin(ring, 4); if (ret) goto err_unpin; @@ -5850,10 +5853,10 @@ static int intel_gen4_queue_flip(struct drm_device *dev, *
[Intel-gfx] [PATCH 06/17] drm/i915: kill intel_clear_scanline_wait
This is a pretty racy way to close these races, and we have much better means to cope with these races meanwhile: For non-broken userspace we correctly wait for any outstanding rendering, for broken userspace the hangcheck will save the day. Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/intel_display.c | 22 -- 1 files changed, 0 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 278c0f0..2617ab5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2528,26 +2528,6 @@ static void ironlake_fdi_disable(struct drm_crtc *crtc) udelay(100); } -/* - * When we disable a pipe, we need to clear any pending scanline wait events - * to avoid hanging the ring, which we assume we are waiting on. - */ -static void intel_clear_scanline_wait(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev-dev_private; - struct intel_ring_buffer *ring; - u32 tmp; - - if (IS_GEN2(dev)) - /* Can't break the hang on i8xx */ - return; - - ring = LP_RING(dev_priv); - tmp = I915_READ_CTL(ring); - if (tmp RING_WAIT) - I915_WRITE_CTL(ring, tmp); -} - static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) { struct drm_device *dev = crtc-dev; @@ -2931,7 +2911,6 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) mutex_lock(dev-struct_mutex); intel_update_fbc(dev); - intel_clear_scanline_wait(dev); mutex_unlock(dev-struct_mutex); } @@ -3036,7 +3015,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) intel_crtc-active = false; intel_update_fbc(dev); intel_update_watermarks(dev); - intel_clear_scanline_wait(dev); } static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) -- 1.7.7.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 07/17] drm/i915: rip out dri1 breadcrumb updates from gen5+ irq handlers
We never supported dri1 on gen5+. VLV never had that code, so no need to remove it. Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_irq.c | 16 1 files changed, 0 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 874956c..37f945d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -585,7 +585,6 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev-dev_private; int ret = IRQ_NONE; u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir; - struct drm_i915_master_private *master_priv; atomic_inc(dev_priv-irq_received); @@ -604,13 +603,6 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) ret = IRQ_HANDLED; - if (dev-primary-master) { - master_priv = dev-primary-master-driver_priv; - if (master_priv-sarea_priv) - master_priv-sarea_priv-last_dispatch = - READ_BREADCRUMB(dev_priv); - } - snb_gt_irq_handler(dev, dev_priv, gt_iir); if (de_iir DE_GSE_IVB) @@ -672,7 +664,6 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) int ret = IRQ_NONE; u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir; u32 hotplug_mask; - struct drm_i915_master_private *master_priv; atomic_inc(dev_priv-irq_received); @@ -697,13 +688,6 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) ret = IRQ_HANDLED; - if (dev-primary-master) { - master_priv = dev-primary-master-driver_priv; - if (master_priv-sarea_priv) - master_priv-sarea_priv-last_dispatch = - READ_BREADCRUMB(dev_priv); - } - if (IS_GEN5(dev)) ilk_gt_irq_handler(dev, dev_priv, gt_iir); else -- 1.7.7.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 08/17] drm/i915: move dri1 irq ioctl code to i915_dma.c
Let's just get this out of the way. v2: Rebase against ENODEV changes. Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_dma.c | 110 +++ drivers/gpu/drm/i915/i915_drv.h |4 -- drivers/gpu/drm/i915/i915_irq.c | 110 --- 3 files changed, 110 insertions(+), 114 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 7db7eab..142a1c9 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -721,6 +721,116 @@ fail_batch_free: return ret; } +static int i915_emit_irq(struct drm_device * dev) +{ + drm_i915_private_t *dev_priv = dev-dev_private; + struct drm_i915_master_private *master_priv = dev-primary-master-driver_priv; + + i915_kernel_lost_context(dev); + + DRM_DEBUG_DRIVER(\n); + + dev_priv-counter++; + if (dev_priv-counter 0x7FFFUL) + dev_priv-counter = 1; + if (master_priv-sarea_priv) + master_priv-sarea_priv-last_enqueue = dev_priv-counter; + + if (BEGIN_LP_RING(4) == 0) { + OUT_RING(MI_STORE_DWORD_INDEX); + OUT_RING(I915_BREADCRUMB_INDEX MI_STORE_DWORD_INDEX_SHIFT); + OUT_RING(dev_priv-counter); + OUT_RING(MI_USER_INTERRUPT); + ADVANCE_LP_RING(); + } + + return dev_priv-counter; +} + +static int i915_wait_irq(struct drm_device * dev, int irq_nr) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev-dev_private; + struct drm_i915_master_private *master_priv = dev-primary-master-driver_priv; + int ret = 0; + struct intel_ring_buffer *ring = LP_RING(dev_priv); + + DRM_DEBUG_DRIVER(irq_nr=%d breadcrumb=%d\n, irq_nr, + READ_BREADCRUMB(dev_priv)); + + if (READ_BREADCRUMB(dev_priv) = irq_nr) { + if (master_priv-sarea_priv) + master_priv-sarea_priv-last_dispatch = READ_BREADCRUMB(dev_priv); + return 0; + } + + if (master_priv-sarea_priv) + master_priv-sarea_priv-perf_boxes |= I915_BOX_WAIT; + + if (ring-irq_get(ring)) { + DRM_WAIT_ON(ret, ring-irq_queue, 3 * DRM_HZ, + READ_BREADCRUMB(dev_priv) = irq_nr); + ring-irq_put(ring); + } else if (wait_for(READ_BREADCRUMB(dev_priv) = irq_nr, 3000)) + ret = -EBUSY; + + if (ret == -EBUSY) { + DRM_ERROR(EBUSY -- rec: %d emitted: %d\n, + READ_BREADCRUMB(dev_priv), (int)dev_priv-counter); + } + + return ret; +} + +/* Needs the lock as it touches the ring. + */ +static int i915_irq_emit(struct drm_device *dev, void *data, +struct drm_file *file_priv) +{ + drm_i915_private_t *dev_priv = dev-dev_private; + drm_i915_irq_emit_t *emit = data; + int result; + + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return -ENODEV; + + if (!dev_priv || !LP_RING(dev_priv)-virtual_start) { + DRM_ERROR(called with no initialization\n); + return -EINVAL; + } + + RING_LOCK_TEST_WITH_RETURN(dev, file_priv); + + mutex_lock(dev-struct_mutex); + result = i915_emit_irq(dev); + mutex_unlock(dev-struct_mutex); + + if (DRM_COPY_TO_USER(emit-irq_seq, result, sizeof(int))) { + DRM_ERROR(copy_to_user\n); + return -EFAULT; + } + + return 0; +} + +/* Doesn't need the hardware lock. + */ +static int i915_irq_wait(struct drm_device *dev, void *data, +struct drm_file *file_priv) +{ + drm_i915_private_t *dev_priv = dev-dev_private; + drm_i915_irq_wait_t *irqwait = data; + + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return -ENODEV; + + if (!dev_priv) { + DRM_ERROR(called with no initialization\n); + return -EINVAL; + } + + return i915_wait_irq(dev, irqwait-irq_seq); +} + static int i915_vblank_pipe_get(struct drm_device *dev, void *data, struct drm_file *file_priv) { diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 894a551..96c517e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1156,10 +1156,6 @@ extern void i915_update_gfx_val(struct drm_i915_private *dev_priv); /* i915_irq.c */ void i915_hangcheck_elapsed(unsigned long data); void i915_handle_error(struct drm_device *dev, bool wedged); -extern int i915_irq_emit(struct drm_device *dev, void *data, -struct drm_file *file_priv); -extern int i915_irq_wait(struct drm_device *dev, void *data, -struct drm_file *file_priv); extern void intel_irq_init(struct
[Intel-gfx] [PATCH 09/17] drm/i915: extract dri1 breadcrumb update from irq handler
... and hide it in i915_dma.c. This way all the legacy stuff dealing with READ_BREADCRUMB and LP_RING and friends is in i915_dma.c. v2: Rebase on top of Chris Wilson's rework irq handling code. Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_dma.c | 13 + drivers/gpu/drm/i915/i915_drv.h |1 + drivers/gpu/drm/i915/i915_irq.c | 24 +++- 3 files changed, 17 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 142a1c9..aa69da2 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -47,6 +47,19 @@ #include acpi/video.h #include asm/pat.h +void i915_update_dri1_breadcrumb(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev-dev_private; + struct drm_i915_master_private *master_priv; + + if (dev-primary-master) { + master_priv = dev-primary-master-driver_priv; + if (master_priv-sarea_priv) + master_priv-sarea_priv-last_dispatch = + READ_BREADCRUMB(dev_priv); + } +} + static void i915_write_hws_pga(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev-dev_private; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 96c517e..9cb3ae8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1129,6 +1129,7 @@ extern int i915_master_create(struct drm_device *dev, struct drm_master *master) extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); /* i915_dma.c */ +void i915_update_dri1_breadcrumb(struct drm_device *dev); extern void i915_kernel_lost_context(struct drm_device * dev); extern int i915_driver_load(struct drm_device *, unsigned long flags); extern int i915_driver_unload(struct drm_device *); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 7cbaa65..f91dd02 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2014,7 +2014,6 @@ static irqreturn_t i8xx_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev-dev_private; - struct drm_i915_master_private *master_priv; u16 iir, new_iir; u32 pipe_stats[2]; unsigned long irqflags; @@ -2060,12 +2059,7 @@ static irqreturn_t i8xx_irq_handler(DRM_IRQ_ARGS) I915_WRITE16(IIR, iir ~flip_mask); new_iir = I915_READ16(IIR); /* Flush posted writes */ - if (dev-primary-master) { - master_priv = dev-primary-master-driver_priv; - if (master_priv-sarea_priv) - master_priv-sarea_priv-last_dispatch = - READ_BREADCRUMB(dev_priv); - } + i915_update_dri1_breadcrumb(dev); if (iir I915_USER_INTERRUPT) notify_ring(dev, dev_priv-ring[RCS]); @@ -2202,7 +2196,6 @@ static irqreturn_t i915_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev-dev_private; - struct drm_i915_master_private *master_priv; u32 iir, new_iir, pipe_stats[I915_MAX_PIPES]; unsigned long irqflags; u32 flip_mask = @@ -2308,12 +2301,7 @@ static irqreturn_t i915_irq_handler(DRM_IRQ_ARGS) iir = new_iir; } while (iir ~flip_mask); - if (dev-primary-master) { - master_priv = dev-primary-master-driver_priv; - if (master_priv-sarea_priv) - master_priv-sarea_priv-last_dispatch = - READ_BREADCRUMB(dev_priv); - } + i915_update_dri1_breadcrumb(dev); return ret; } @@ -2453,7 +2441,6 @@ static irqreturn_t i965_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev-dev_private; - struct drm_i915_master_private *master_priv; u32 iir, new_iir; u32 pipe_stats[I915_MAX_PIPES]; unsigned long irqflags; @@ -2562,12 +2549,7 @@ static irqreturn_t i965_irq_handler(DRM_IRQ_ARGS) iir = new_iir; } - if (dev-primary-master) { - master_priv = dev-primary-master-driver_priv; - if (master_priv-sarea_priv) - master_priv-sarea_priv-last_dispatch = - READ_BREADCRUMB(dev_priv); - } + i915_update_dri1_breadcrumb(dev); return ret; } -- 1.7.7.6 ___ Intel-gfx mailing list
[Intel-gfx] [PATCH 10/17] drm/i915: move LP_RINGfriends to i915_dma.c
Wohoo! Now we only need to move all the gem/kms stuff that accidentally landed in i915_dma.c out of it, and this will be our legacy dri1 grave-yard. Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_dma.c | 26 ++ drivers/gpu/drm/i915/i915_drv.h | 22 -- drivers/gpu/drm/i915/intel_ringbuffer.h |3 --- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index aa69da2..ed6a603 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -47,6 +47,32 @@ #include acpi/video.h #include asm/pat.h +#define LP_RING(d) (((struct drm_i915_private *)(d))-ring[RCS]) + +#define BEGIN_LP_RING(n) \ + intel_ring_begin(LP_RING(dev_priv), (n)) + +#define OUT_RING(x) \ + intel_ring_emit(LP_RING(dev_priv), x) + +#define ADVANCE_LP_RING() \ + intel_ring_advance(LP_RING(dev_priv)) + +/** + * Lock test for when it's just for synchronization of ring access. + * + * In that case, we don't need to do it when GEM is initialized as nobody else + * has access to the ring. + */ +#define RING_LOCK_TEST_WITH_RETURN(dev, file) do { \ + if (LP_RING(dev-dev_private)-obj == NULL) \ + LOCK_TEST_WITH_RETURN(dev, file); \ +} while (0) + +#define READ_HWSP(dev_priv, reg) intel_read_status_page(LP_RING(dev_priv), reg) +#define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX) +#define I915_BREADCRUMB_INDEX 0x21 + void i915_update_dri1_breadcrumb(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev-dev_private; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9cb3ae8..b6567a6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1472,28 +1472,6 @@ extern void intel_display_print_error_state(struct seq_file *m, struct intel_display_error_state *error); #endif -#define LP_RING(d) (((struct drm_i915_private *)(d))-ring[RCS]) - -#define BEGIN_LP_RING(n) \ - intel_ring_begin(LP_RING(dev_priv), (n)) - -#define OUT_RING(x) \ - intel_ring_emit(LP_RING(dev_priv), x) - -#define ADVANCE_LP_RING() \ - intel_ring_advance(LP_RING(dev_priv)) - -/** - * Lock test for when it's just for synchronization of ring access. - * - * In that case, we don't need to do it when GEM is initialized as nobody else - * has access to the ring. - */ -#define RING_LOCK_TEST_WITH_RETURN(dev, file) do { \ - if (LP_RING(dev-dev_private)-obj == NULL) \ - LOCK_TEST_WITH_RETURN(dev, file); \ -} while (0) - /* On SNB platform, before reading ring registers forcewake bit * must be set to prevent GT core from power down and stale values being * returned. diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index e0b25bb..fb35922 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -169,10 +169,7 @@ intel_read_status_page(struct intel_ring_buffer *ring, * * The area from dword 0x20 to 0x3ff is available for driver usage. */ -#define READ_HWSP(dev_priv, reg) intel_read_status_page(LP_RING(dev_priv), reg) -#define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX) #define I915_GEM_HWS_INDEX 0x20 -#define I915_BREADCRUMB_INDEX 0x21 void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring); -- 1.7.7.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 11/17] drm/i915: disallow clip rects on gen5+
Unfortunately there has been dri1 userspace that used gem to manage the gtt and hence also needed cliprects in the execbuf ioctl. So we can't ever remove that code without breaking the ioctl abi. But at least we can disable it on gen5+, because these horrible versions of mesa have not supported these chips. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_gem_execbuffer.c |5 + 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 68ec013..fc69391 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1116,6 +1116,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, return -EINVAL; } + if (INTEL_INFO(dev)-gen = 5) { + DRM_DEBUG(clip rectangles are only valid on pre-gen5\n); + return -EINVAL; + } + cliprects = kmalloc(args-num_cliprects * sizeof(*cliprects), GFP_KERNEL); if (cliprects == NULL) { -- 1.7.7.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 12/17] drm/i915: move the ips code to intel_pm.c
We now have a nice home for power management code, so let's use it! Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_dma.c | 472 +- drivers/gpu/drm/i915/intel_drv.h |3 + drivers/gpu/drm/i915/intel_pm.c | 478 ++ 3 files changed, 483 insertions(+), 470 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index ed6a603..ffe6014 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -36,14 +36,12 @@ #include i915_drm.h #include i915_drv.h #include i915_trace.h -#include ../../../platform/x86/intel_ips.h #include linux/pci.h #include linux/vgaarb.h #include linux/acpi.h #include linux/pnp.h #include linux/vga_switcheroo.h #include linux/slab.h -#include linux/module.h #include acpi/video.h #include asm/pat.h @@ -1481,465 +1479,6 @@ static void i915_ironlake_get_mem_freq(struct drm_device *dev) } } -static const struct cparams { - u16 i; - u16 t; - u16 m; - u16 c; -} cparams[] = { - { 1, 1333, 301, 28664 }, - { 1, 1066, 294, 24460 }, - { 1, 800, 294, 25192 }, - { 0, 1333, 276, 27605 }, - { 0, 1066, 276, 27605 }, - { 0, 800, 231, 23784 }, -}; - -unsigned long i915_chipset_val(struct drm_i915_private *dev_priv) -{ - u64 total_count, diff, ret; - u32 count1, count2, count3, m = 0, c = 0; - unsigned long now = jiffies_to_msecs(jiffies), diff1; - int i; - - diff1 = now - dev_priv-last_time1; - - /* Prevent division-by-zero if we are asking too fast. -* Also, we don't get interesting results if we are polling -* faster than once in 10ms, so just return the saved value -* in such cases. -*/ - if (diff1 = 10) - return dev_priv-chipset_power; - - count1 = I915_READ(DMIEC); - count2 = I915_READ(DDREC); - count3 = I915_READ(CSIEC); - - total_count = count1 + count2 + count3; - - /* FIXME: handle per-counter overflow */ - if (total_count dev_priv-last_count1) { - diff = ~0UL - dev_priv-last_count1; - diff += total_count; - } else { - diff = total_count - dev_priv-last_count1; - } - - for (i = 0; i ARRAY_SIZE(cparams); i++) { - if (cparams[i].i == dev_priv-c_m - cparams[i].t == dev_priv-r_t) { - m = cparams[i].m; - c = cparams[i].c; - break; - } - } - - diff = div_u64(diff, diff1); - ret = ((m * diff) + c); - ret = div_u64(ret, 10); - - dev_priv-last_count1 = total_count; - dev_priv-last_time1 = now; - - dev_priv-chipset_power = ret; - - return ret; -} - -unsigned long i915_mch_val(struct drm_i915_private *dev_priv) -{ - unsigned long m, x, b; - u32 tsfs; - - tsfs = I915_READ(TSFS); - - m = ((tsfs TSFS_SLOPE_MASK) TSFS_SLOPE_SHIFT); - x = I915_READ8(TR1); - - b = tsfs TSFS_INTR_MASK; - - return ((m * x) / 127) - b; -} - -static u16 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid) -{ - static const struct v_table { - u16 vd; /* in .1 mil */ - u16 vm; /* in .1 mil */ - } v_table[] = { - { 0, 0, }, - { 375, 0, }, - { 500, 0, }, - { 625, 0, }, - { 750, 0, }, - { 875, 0, }, - { 1000, 0, }, - { 1125, 0, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4250, 3125, }, - { 4375, 3250, }, - { 4500, 3375, }, - { 4625, 3500, }, - { 4750, 3625, }, - { 4875, 3750, }, - { 5000, 3875, }, - { 5125, 4000, }, - { 5250, 4125, }, - { 5375, 4250, }, - { 5500, 4375, }, - { 5625, 4500, }, - { 5750, 4625, }, - { 5875, 4750, }, - { 6000, 4875, }, - { 6125, 5000, }, -
[Intel-gfx] [PATCH 13/17] drm/i915: move rps/emon function declarations
They're now in intel_pm.c, so group them a bit better. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/intel_drv.h |9 + 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f4f1e8b..7c323c5 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -401,10 +401,6 @@ extern void intel_enable_clock_gating(struct drm_device *dev); extern void ironlake_disable_rc6(struct drm_device *dev); extern void ironlake_enable_drps(struct drm_device *dev); extern void ironlake_disable_drps(struct drm_device *dev); -extern void gen6_enable_rps(struct drm_i915_private *dev_priv); -extern void gen6_update_ring_freq(struct drm_i915_private *dev_priv); -extern void gen6_disable_rps(struct drm_device *dev); -extern void intel_init_emon(struct drm_device *dev); extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_i915_gem_object *obj, @@ -466,4 +462,9 @@ extern void intel_update_fbc(struct drm_device *dev); extern void intel_gpu_ips_init(struct drm_i915_private *dev_priv); extern void intel_gpu_ips_teardown(void); +extern void gen6_enable_rps(struct drm_i915_private *dev_priv); +extern void gen6_update_ring_freq(struct drm_i915_private *dev_priv); +extern void gen6_disable_rps(struct drm_device *dev); +extern void intel_init_emon(struct drm_device *dev); + #endif /* __INTEL_DRV_H__ */ -- 1.7.7.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 14/17] drm/i915: kill pointless clearing of dev_priv-hws_map
We kzalloc dev_priv, and we never use hws_map in intel_ringbuffer.c. Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/intel_ringbuffer.c |5 - 1 files changed, 0 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 427b7c5..efec21a 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -890,7 +890,6 @@ i915_dispatch_execbuffer(struct intel_ring_buffer *ring, static void cleanup_status_page(struct intel_ring_buffer *ring) { - drm_i915_private_t *dev_priv = ring-dev-dev_private; struct drm_i915_gem_object *obj; obj = ring-status_page.obj; @@ -901,14 +900,11 @@ static void cleanup_status_page(struct intel_ring_buffer *ring) i915_gem_object_unpin(obj); drm_gem_object_unreference(obj-base); ring-status_page.obj = NULL; - - memset(dev_priv-hws_map, 0, sizeof(dev_priv-hws_map)); } static int init_status_page(struct intel_ring_buffer *ring) { struct drm_device *dev = ring-dev; - drm_i915_private_t *dev_priv = dev-dev_private; struct drm_i915_gem_object *obj; int ret; @@ -929,7 +925,6 @@ static int init_status_page(struct intel_ring_buffer *ring) ring-status_page.gfx_addr = obj-gtt_offset; ring-status_page.page_addr = kmap(obj-pages[0]); if (ring-status_page.page_addr == NULL) { - memset(dev_priv-hws_map, 0, sizeof(dev_priv-hws_map)); goto err_unpin; } ring-status_page.obj = obj; -- 1.7.7.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 15/17] drm/i915: rework legacy GFX HWS handling
To get the fun stuff out of the way, the legacy hws is allocated by userspace when the gpu needs a gfx hws. And there's no reference-counting going on, so userspace can simply screw everyone over. At least it's not as horrible as i810, where the ringbuffer is allocated by userspace ... We can't fix this disaster, but we can at least clean up the code a bit to clean things up: - Drop the drm ioremap indirection. - Add a new new read_legacy_status_page to paper over the differences between the legacy gfx hws and the physical hws shared with the new ringbuffer code. - Add a pointer in dev_priv-dri1 for the cpu addresss - that one is an iomem remapping as opposed to all other hw status pages. This is just prep work to make sparse happy. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_dma.c | 29 - drivers/gpu/drm/i915/i915_drv.h |2 +- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index ffe6014..f4ae172 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -67,7 +67,16 @@ LOCK_TEST_WITH_RETURN(dev, file); \ } while (0) -#define READ_HWSP(dev_priv, reg) intel_read_status_page(LP_RING(dev_priv), reg) +static inline u32 +intel_read_legacy_status_page(struct drm_i915_private *dev_priv, int reg) +{ + if (I915_NEED_GFX_HWS(dev_priv-dev)) + return ioread32(dev_priv-dri1.gfx_hws_cpu_addr + reg); + else + return intel_read_status_page(LP_RING(dev_priv), reg); +} + +#define READ_HWSP(dev_priv, reg) intel_read_legacy_status_page(dev_priv, reg) #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX) #define I915_BREADCRUMB_INDEX 0x21 @@ -137,7 +146,7 @@ static void i915_free_hws(struct drm_device *dev) if (ring-status_page.gfx_addr) { ring-status_page.gfx_addr = 0; - drm_core_ioremapfree(dev_priv-hws_map, dev); + iounmap(dev_priv-dri1.gfx_hws_cpu_addr); } /* Need to rewrite hardware status page */ @@ -1073,23 +1082,17 @@ static int i915_set_status_page(struct drm_device *dev, void *data, ring-status_page.gfx_addr = hws-addr (0x112); - dev_priv-hws_map.offset = dev-agp-base + hws-addr; - dev_priv-hws_map.size = 4*1024; - dev_priv-hws_map.type = 0; - dev_priv-hws_map.flags = 0; - dev_priv-hws_map.mtrr = 0; - - drm_core_ioremap_wc(dev_priv-hws_map, dev); - if (dev_priv-hws_map.handle == NULL) { + dev_priv-dri1.gfx_hws_cpu_addr = ioremap_wc(dev-agp-base + hws-addr, +4096); + if (dev_priv-dri1.gfx_hws_cpu_addr == NULL) { i915_dma_cleanup(dev); ring-status_page.gfx_addr = 0; DRM_ERROR(can not ioremap virtual address for G33 hw status page\n); return -ENOMEM; } - ring-status_page.page_addr = - (void __force __iomem *)dev_priv-hws_map.handle; - memset_io(ring-status_page.page_addr, 0, PAGE_SIZE); + + memset_io(dev_priv-dri1.gfx_hws_cpu_addr, 0, PAGE_SIZE); I915_WRITE(HWS_PGA, ring-status_page.gfx_addr); DRM_DEBUG_DRIVER(load hws HWS_PGA with gfx mem 0x%x\n, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b6567a6..dd0517b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -367,7 +367,6 @@ typedef struct drm_i915_private { drm_dma_handle_t *status_page_dmah; uint32_t counter; - drm_local_map_t hws_map; struct drm_i915_gem_object *pwrctx; struct drm_i915_gem_object *renderctx; @@ -743,6 +742,7 @@ typedef struct drm_i915_private { * here! */ struct { unsigned allow_batchbuffer : 1; + u32 __iomem *gfx_hws_cpu_addr; } dri1; /* Kernel Modesetting */ -- 1.7.7.6 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 16/17] drm/i915: fixup __iomem mixups in ringbuffer.c
Two things: - ring-virtual start is an __iomem pointer, treat it accordingly. - dev_priv-status_page.page_addr is now always a cpu addr, no pointer casting needed for that. Take the opportunity to remove the unnecessary drm indirection when setting up the ringbuffer iomapping. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_dma.c |2 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 39 +- drivers/gpu/drm/i915/intel_ringbuffer.h |5 +-- 3 files changed, 15 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index f4ae172..dfaa0b5 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -256,7 +256,7 @@ static int i915_dma_resume(struct drm_device * dev) DRM_DEBUG_DRIVER(%s\n, __func__); - if (ring-map.handle == NULL) { + if (ring-virtual_start == NULL) { DRM_ERROR(can not ioremap virtual address for ring buffer\n); return -ENOMEM; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index efec21a..ee8dabf 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -977,20 +977,14 @@ static int intel_init_ring_buffer(struct drm_device *dev, if (ret) goto err_unref; - ring-map.size = ring-size; - ring-map.offset = dev-agp-base + obj-gtt_offset; - ring-map.type = 0; - ring-map.flags = 0; - ring-map.mtrr = 0; - - drm_core_ioremap_wc(ring-map, dev); - if (ring-map.handle == NULL) { + ring-virtual_start = ioremap_wc(dev-agp-base + obj-gtt_offset, +ring-size); + if (ring-virtual_start == NULL) { DRM_ERROR(Failed to map ringbuffer.\n); ret = -EINVAL; goto err_unpin; } - ring-virtual_start = ring-map.handle; ret = ring-init(ring); if (ret) goto err_unmap; @@ -1006,7 +1000,7 @@ static int intel_init_ring_buffer(struct drm_device *dev, return 0; err_unmap: - drm_core_ioremapfree(ring-map, dev); + iounmap(ring-virtual_start); err_unpin: i915_gem_object_unpin(obj); err_unref: @@ -1034,7 +1028,7 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring) I915_WRITE_CTL(ring, 0); - drm_core_ioremapfree(ring-map, ring-dev); + iounmap(ring-virtual_start); i915_gem_object_unpin(ring-obj); drm_gem_object_unreference(ring-obj-base); @@ -1048,7 +1042,7 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring) static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring) { - unsigned int *virt; + uint32_t __iomem *virt; int rem = ring-size - ring-tail; if (ring-space rem) { @@ -1057,12 +1051,10 @@ static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring) return ret; } - virt = (unsigned int *)(ring-virtual_start + ring-tail); - rem /= 8; - while (rem--) { - *virt++ = MI_NOOP; - *virt++ = MI_NOOP; - } + virt = ring-virtual_start + ring-tail; + rem /= 4; + while (rem--) + iowrite32(MI_NOOP, virt++); ring-tail = 0; ring-space = ring_space(ring); @@ -1425,20 +1417,13 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) if (IS_I830(ring-dev)) ring-effective_size -= 128; - ring-map.offset = start; - ring-map.size = size; - ring-map.type = 0; - ring-map.flags = 0; - ring-map.mtrr = 0; - - drm_core_ioremap_wc(ring-map, dev); - if (ring-map.handle == NULL) { + ring-virtual_start = ioremap_wc(start, size); + if (ring-virtual_start == NULL) { DRM_ERROR(can not ioremap virtual address for ring buffer\n); return -ENOMEM; } - ring-virtual_start = (void __force __iomem *)ring-map.handle; return 0; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index fb35922..893742d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -2,7 +2,7 @@ #define _INTEL_RINGBUFFER_H_ struct intel_hw_status_page { - u32 __iomem *page_addr; + u32 *page_addr; unsigned intgfx_addr; struct drm_i915_gem_object *obj; }; @@ -117,7 +117,6 @@ struct intel_ring_buffer { u32 outstanding_lazy_request; wait_queue_head_t irq_queue; - drm_local_map_t map; void *private; }; @@ -151,7 +150,7 @@ static inline u32 intel_read_status_page(struct intel_ring_buffer *ring,
[Intel-gfx] [PATCH 17/17] drm/i915: move pnv|ilk_gem_mem_freq to intel_pm.c
Because this is the place where we actually use the results of them. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_dma.c | 112 -- drivers/gpu/drm/i915/intel_pm.c | 113 +++ 2 files changed, 113 insertions(+), 112 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index dfaa0b5..1ba3fa0 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1375,113 +1375,6 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master) master-driver_priv = NULL; } -static void i915_pineview_get_mem_freq(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev-dev_private; - u32 tmp; - - tmp = I915_READ(CLKCFG); - - switch (tmp CLKCFG_FSB_MASK) { - case CLKCFG_FSB_533: - dev_priv-fsb_freq = 533; /* 133*4 */ - break; - case CLKCFG_FSB_800: - dev_priv-fsb_freq = 800; /* 200*4 */ - break; - case CLKCFG_FSB_667: - dev_priv-fsb_freq = 667; /* 167*4 */ - break; - case CLKCFG_FSB_400: - dev_priv-fsb_freq = 400; /* 100*4 */ - break; - } - - switch (tmp CLKCFG_MEM_MASK) { - case CLKCFG_MEM_533: - dev_priv-mem_freq = 533; - break; - case CLKCFG_MEM_667: - dev_priv-mem_freq = 667; - break; - case CLKCFG_MEM_800: - dev_priv-mem_freq = 800; - break; - } - - /* detect pineview DDR3 setting */ - tmp = I915_READ(CSHRDDR3CTL); - dev_priv-is_ddr3 = (tmp CSHRDDR3CTL_DDR3) ? 1 : 0; -} - -static void i915_ironlake_get_mem_freq(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev-dev_private; - u16 ddrpll, csipll; - - ddrpll = I915_READ16(DDRMPLL1); - csipll = I915_READ16(CSIPLL0); - - switch (ddrpll 0xff) { - case 0xc: - dev_priv-mem_freq = 800; - break; - case 0x10: - dev_priv-mem_freq = 1066; - break; - case 0x14: - dev_priv-mem_freq = 1333; - break; - case 0x18: - dev_priv-mem_freq = 1600; - break; - default: - DRM_DEBUG_DRIVER(unknown memory frequency 0x%02x\n, -ddrpll 0xff); - dev_priv-mem_freq = 0; - break; - } - - dev_priv-r_t = dev_priv-mem_freq; - - switch (csipll 0x3ff) { - case 0x00c: - dev_priv-fsb_freq = 3200; - break; - case 0x00e: - dev_priv-fsb_freq = 3733; - break; - case 0x010: - dev_priv-fsb_freq = 4266; - break; - case 0x012: - dev_priv-fsb_freq = 4800; - break; - case 0x014: - dev_priv-fsb_freq = 5333; - break; - case 0x016: - dev_priv-fsb_freq = 5866; - break; - case 0x018: - dev_priv-fsb_freq = 6400; - break; - default: - DRM_DEBUG_DRIVER(unknown fsb frequency 0x%04x\n, -csipll 0x3ff); - dev_priv-fsb_freq = 0; - break; - } - - if (dev_priv-fsb_freq == 3200) { - dev_priv-c_m = 0; - } else if (dev_priv-fsb_freq 3200 dev_priv-fsb_freq = 4800) { - dev_priv-c_m = 1; - } else { - dev_priv-c_m = 2; - } -} - static void i915_mtrr_setup(struct drm_i915_private *dev_priv, unsigned long base, unsigned long size) @@ -1634,11 +1527,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto out_gem_unload; } - if (IS_PINEVIEW(dev)) - i915_pineview_get_mem_freq(dev); - else if (IS_GEN5(dev)) - i915_ironlake_get_mem_freq(dev); - /* On the 945G/GM, the chipset reports the MSI capability on the * integrated graphics even though the support isn't actually there * according to the published specs. It doesn't appear to function diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index bf77c83..cf5b1db 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -526,6 +526,113 @@ out_disable: } } +static void i915_pineview_get_mem_freq(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev-dev_private; + u32 tmp; + + tmp = I915_READ(CLKCFG); + + switch (tmp CLKCFG_FSB_MASK) { + case CLKCFG_FSB_533: + dev_priv-fsb_freq = 533; /* 133*4 */ + break; + case CLKCFG_FSB_800: + dev_priv-fsb_freq
Re: [Intel-gfx] [PATCH 01/17] drm/i915: move dri1 vblank stubs to i915_dma.c
On Thu, Apr 26, 2012 at 11:19:08PM +0200, Daniel Vetter wrote: i915_dma.c contains most of the old dri1 horror-show, so move the remaining bits there, too. The code has been removed and the only thing left are some stubs to ensure that userspace doesn't try to use this stuff. vblank_pipe_set only returns 0 without any side-effects, so we can even stub it out with the canonical drm_noop. v2: Rebase against ENODEV changes. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Ignore this patchbomb, gmail crapped out :( -Daniel -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 00/12 v2] wait for BO with timeout
Hopefully addressed all the comments from the first series. Tests and sample libdrm remain in the same place. Much thanks to Chris Wilson on helping me smash this into shape. Ben Widawsky (12): drm/i915: remove do_retire from i915_wait_request drm/i915: remove some extra retiring drm/i915: move vbetool invoked ier stuff drm/i915: kill waiting_seqno drm/i915: drop polled waits from i915_wait_request drm/i915: extract __wait_seqno from i915_wait_request drm/i915: remove polled wait from throttle drm/i915: use __wait_seqno for ring throttle drm/i915: timeout parameter for seqno wait drm/i915: extract some common olr+wedge code drm/i915: wait render timeout ioctl drm/i915: s/i915_wait_reqest/i915_wait_seqno/g drivers/gpu/drm/i915/i915_debugfs.c|4 +- drivers/gpu/drm/i915/i915_dma.c|3 +- drivers/gpu/drm/i915/i915_drv.h| 11 +- drivers/gpu/drm/i915/i915_gem.c| 295 +--- drivers/gpu/drm/i915/i915_gem_evict.c | 15 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c |2 +- drivers/gpu/drm/i915/i915_gem_gtt.c|2 +- drivers/gpu/drm/i915/i915_irq.c| 21 +- drivers/gpu/drm/i915/intel_overlay.c |6 +- drivers/gpu/drm/i915/intel_ringbuffer.c|4 +- drivers/gpu/drm/i915/intel_ringbuffer.h|1 - include/drm/i915_drm.h |8 + 12 files changed, 230 insertions(+), 142 deletions(-) -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 01/12 v2] drm/i915: remove do_retire from i915_wait_request
This originates from a hack by me to quickly fix a bug in an earlier patch where we needed control over whether or not waiting on a seqno actually did any retire list processing. Since the two operations aren't clearly related, we should pull the parameter out of the wait function, and make the caller responsible for retiring if the action is desired. The only function call site which did not get an explicit retire_request call (on purpose) is i915_gem_inactive_shrink(). That code was already calling retire_request a second time. v2: don't modify any behavior excepit i915_gem_inactive_shrink(Daniel) Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_dma.c|3 ++- drivers/gpu/drm/i915/i915_drv.h|5 ++--- drivers/gpu/drm/i915/i915_gem.c| 33 ++-- drivers/gpu/drm/i915/i915_gem_evict.c | 15 ++--- drivers/gpu/drm/i915/i915_gem_execbuffer.c |3 ++- drivers/gpu/drm/i915/i915_gem_gtt.c|2 +- drivers/gpu/drm/i915/intel_overlay.c |8 +++ drivers/gpu/drm/i915/intel_ringbuffer.c|4 +++- 8 files changed, 37 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index e2983a9..36c8d5f 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -2013,9 +2013,10 @@ int i915_driver_unload(struct drm_device *dev) unregister_shrinker(dev_priv-mm.inactive_shrinker); mutex_lock(dev-struct_mutex); - ret = i915_gpu_idle(dev, true); + ret = i915_gpu_idle(dev); if (ret) DRM_ERROR(failed to idle hardware: %d\n, ret); + i915_gem_retire_requests(dev); mutex_unlock(dev-struct_mutex); /* Cancel the retire work handler, which should be idle now. */ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index cf2c896..34d7041 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1298,14 +1298,13 @@ int __must_check i915_gem_init_hw(struct drm_device *dev); void i915_gem_init_swizzling(struct drm_device *dev); void i915_gem_init_ppgtt(struct drm_device *dev); void i915_gem_cleanup_ringbuffer(struct drm_device *dev); -int __must_check i915_gpu_idle(struct drm_device *dev, bool do_retire); +int __must_check i915_gpu_idle(struct drm_device *dev); int __must_check i915_gem_idle(struct drm_device *dev); int __must_check i915_add_request(struct intel_ring_buffer *ring, struct drm_file *file, struct drm_i915_gem_request *request); int __must_check i915_wait_request(struct intel_ring_buffer *ring, - uint32_t seqno, - bool do_retire); + uint32_t seqno); int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); int __must_check i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0d53eac..25be0e0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1825,8 +1825,7 @@ i915_gem_retire_work_handler(struct work_struct *work) */ int i915_wait_request(struct intel_ring_buffer *ring, - uint32_t seqno, - bool do_retire) + uint32_t seqno) { drm_i915_private_t *dev_priv = ring-dev-dev_private; u32 ier; @@ -1902,14 +1901,6 @@ i915_wait_request(struct intel_ring_buffer *ring, if (atomic_read(dev_priv-mm.wedged)) ret = -EAGAIN; - /* Directly dispatch request retiring. While we have the work queue -* to handle this, the waiter on a request often wants an associated -* buffer to have made it to the inactive list, and we would need -* a separate wait queue to handle that. -*/ - if (ret == 0 do_retire) - i915_gem_retire_requests_ring(ring); - return ret; } @@ -1931,10 +1922,10 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj) * it. */ if (obj-active) { - ret = i915_wait_request(obj-ring, obj-last_rendering_seqno, - true); + ret = i915_wait_request(obj-ring, obj-last_rendering_seqno); if (ret) return ret; + i915_gem_retire_requests_ring(obj-ring); } return 0; @@ -2117,7 +2108,7 @@ i915_gem_flush_ring(struct intel_ring_buffer *ring, return 0; } -static int i915_ring_idle(struct intel_ring_buffer *ring, bool do_retire) +static int i915_ring_idle(struct intel_ring_buffer *ring) { int ret; @@ -2131,18 +2122,17 @@ static int i915_ring_idle(struct intel_ring_buffer *ring, bool do_retire) return ret;
[Intel-gfx] [PATCH 02/12] drm/i915: remove some extra retiring
Not every caller of gpu_idle needs to retire requests. Try to pick only the callers that need it. This was originally combined with the previous patch in the first series on the mailing list. Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_dma.c|1 - drivers/gpu/drm/i915/i915_gem.c|1 - drivers/gpu/drm/i915/i915_gem_execbuffer.c |1 - drivers/gpu/drm/i915/intel_overlay.c |2 -- 4 files changed, 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 36c8d5f..e73389d 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -2016,7 +2016,6 @@ int i915_driver_unload(struct drm_device *dev) ret = i915_gpu_idle(dev); if (ret) DRM_ERROR(failed to idle hardware: %d\n, ret); - i915_gem_retire_requests(dev); mutex_unlock(dev-struct_mutex); /* Cancel the retire work handler, which should be idle now. */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 25be0e0..3b731ef 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3387,7 +3387,6 @@ i915_gem_idle(struct drm_device *dev) mutex_unlock(dev-struct_mutex); return ret; } - i915_gem_retire_requests(dev); /* Under UMS, be paranoid and evict. */ if (!drm_core_check_feature(dev, DRIVER_MODESET)) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index cbba0aa..582f6c4 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1223,7 +1223,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, ret = i915_gpu_idle(dev); if (ret) goto err; - i915_gem_retire_requests(dev); BUG_ON(ring-sync_seqno[i]); } diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index e06e46a..07a5cad 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -228,7 +228,6 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay, ret = i915_wait_request(LP_RING(dev_priv), overlay-last_flip_req); if (ret) return ret; - i915_gem_retire_requests(dev); overlay-last_flip_req = 0; return 0; @@ -450,7 +449,6 @@ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay) ret = i915_wait_request(LP_RING(dev_priv), overlay-last_flip_req); if (ret) return ret; - i915_gem_retire_requests(dev); if (overlay-flip_tail) overlay-flip_tail(overlay); -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 03/12 v2] drm/i915: move vbetool invoked ier stuff
This extra bit of interrupt enabling code doesn't belong in the wait seqno function. If anything we should pull it out to a helper so the throttle code can also use it. The history is a bit vague, but I am going to attempt to just dump it, unless someone can argue otherwise. Removing this allows for a shared lock free wait seqno function. To keep tabs on this issue though, the IER value is stored on error capture (recommended by Chris Wilson) v2: fixed typo EIR-IER (Ben) Fix some white space (Ben) Move IER capture to globally instead of per ring (Ben) Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_debugfs.c |1 + drivers/gpu/drm/i915/i915_drv.h |1 + drivers/gpu/drm/i915/i915_gem.c | 14 -- drivers/gpu/drm/i915/i915_irq.c |8 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 120db46..8ed0342 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -712,6 +712,7 @@ static int i915_error_state(struct seq_file *m, void *unused) error-time.tv_usec); seq_printf(m, PCI ID: 0x%04x\n, dev-pci_device); seq_printf(m, EIR: 0x%08x\n, error-eir); + seq_printf(m, IER: 0x%08x\n, error-ier); seq_printf(m, PGTBL_ER: 0x%08x\n, error-pgtbl_er); for (i = 0; i dev_priv-num_fence_regs; i++) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 34d7041..d0eeb28 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -173,6 +173,7 @@ struct intel_display_error_state; struct drm_i915_error_state { u32 eir; u32 pgtbl_er; + u32 ier; u32 pipestat[I915_MAX_PIPES]; u32 tail[I915_NUM_RINGS]; u32 head[I915_NUM_RINGS]; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3b731ef..5938b9b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1828,7 +1828,6 @@ i915_wait_request(struct intel_ring_buffer *ring, uint32_t seqno) { drm_i915_private_t *dev_priv = ring-dev-dev_private; - u32 ier; int ret = 0; BUG_ON(seqno == 0); @@ -1863,19 +1862,6 @@ i915_wait_request(struct intel_ring_buffer *ring, } if (!i915_seqno_passed(ring-get_seqno(ring), seqno)) { - if (HAS_PCH_SPLIT(ring-dev)) - ier = I915_READ(DEIER) | I915_READ(GTIER); - else if (IS_VALLEYVIEW(ring-dev)) - ier = I915_READ(GTIER) | I915_READ(VLV_IER); - else - ier = I915_READ(IER); - if (!ier) { - DRM_ERROR(something (likely vbetool) disabled - interrupts, re-enabling\n); - ring-dev-driver-irq_preinstall(ring-dev); - ring-dev-driver-irq_postinstall(ring-dev); - } - trace_i915_gem_request_wait_begin(ring, seqno); ring-waiting_seqno = seqno; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 0211263..5e9d05d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1155,6 +1155,14 @@ static void i915_capture_error_state(struct drm_device *dev) error-eir = I915_READ(EIR); error-pgtbl_er = I915_READ(PGTBL_ER); + + if (HAS_PCH_SPLIT(dev)) + error-ier = I915_READ(DEIER) | I915_READ(GTIER); + else if (IS_VALLEYVIEW(dev)) + error-ier = I915_READ(GTIER) | I915_READ(VLV_IER); + else + error-ier = I915_READ(IER); + for_each_pipe(pipe) error-pipestat[pipe] = I915_READ(PIPESTAT(pipe)); -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 04/12 v2] drm/i915: kill waiting_seqno
The waiting_seqno is not terribly useful, and as such we can remove it so that we'll be able to extract lockless code. v2: Keep the information for error_state (Chris) Check if ring is initialized in hangcheck (Chris) Capture the waiting ring (Chris) Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_debugfs.c |3 +-- drivers/gpu/drm/i915/i915_drv.h |1 + drivers/gpu/drm/i915/i915_gem.c |2 -- drivers/gpu/drm/i915/i915_irq.c | 13 - drivers/gpu/drm/i915/intel_ringbuffer.h |1 - 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 8ed0342..9d4bf6b 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -414,8 +414,6 @@ static void i915_ring_seqno_info(struct seq_file *m, if (ring-get_seqno) { seq_printf(m, Current sequence (%s): %d\n, ring-name, ring-get_seqno(ring)); - seq_printf(m, Waiter sequence (%s): %d\n, - ring-name, ring-waiting_seqno); seq_printf(m, IRQ sequence (%s): %d\n, ring-name, ring-irq_seqno); } @@ -687,6 +685,7 @@ static void i915_ring_error_state(struct seq_file *m, error-semaphore_mboxes[ring][1]); } seq_printf(m, seqno: 0x%08x\n, error-seqno[ring]); + seq_printf(m, waiting: %s\n, yesno(error-waiting[ring])); seq_printf(m, ring-head: 0x%08x\n, error-cpu_ring_head[ring]); seq_printf(m, ring-tail: 0x%08x\n, error-cpu_ring_tail[ring]); } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d0eeb28..d260762 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -174,6 +174,7 @@ struct drm_i915_error_state { u32 eir; u32 pgtbl_er; u32 ier; + bool waiting[I915_NUM_RINGS]; u32 pipestat[I915_MAX_PIPES]; u32 tail[I915_NUM_RINGS]; u32 head[I915_NUM_RINGS]; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5938b9b..c29c758 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1864,7 +1864,6 @@ i915_wait_request(struct intel_ring_buffer *ring, if (!i915_seqno_passed(ring-get_seqno(ring), seqno)) { trace_i915_gem_request_wait_begin(ring, seqno); - ring-waiting_seqno = seqno; if (ring-irq_get(ring)) { if (dev_priv-mm.interruptible) ret = wait_event_interruptible(ring-irq_queue, @@ -1880,7 +1879,6 @@ i915_wait_request(struct intel_ring_buffer *ring, seqno) || atomic_read(dev_priv-mm.wedged), 3000)) ret = -EBUSY; - ring-waiting_seqno = 0; trace_i915_gem_request_wait_end(ring, seqno); } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5e9d05d..98494ba 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1064,6 +1064,7 @@ static void i915_record_ring_state(struct drm_device *dev, error-instdone[ring-id] = I915_READ(INSTDONE); } + error-waiting[ring-id] = waitqueue_active(ring-irq_queue); error-instpm[ring-id] = I915_READ(RING_INSTPM(ring-mmio_base)); error-seqno[ring-id] = ring-get_seqno(ring); error-acthd[ring-id] = intel_ring_get_active_head(ring); @@ -1877,14 +1878,16 @@ ring_last_seqno(struct intel_ring_buffer *ring) static bool i915_hangcheck_ring_idle(struct intel_ring_buffer *ring, bool *err) { + /* Hanghceck may trigger before ring is initialized */ + if (ring-obj == NULL) + return true; + if (list_empty(ring-request_list) || i915_seqno_passed(ring-get_seqno(ring), ring_last_seqno(ring))) { /* Issue a wake-up to catch stuck h/w. */ - if (ring-waiting_seqno waitqueue_active(ring-irq_queue)) { - DRM_ERROR(Hangcheck timer elapsed... %s idle [waiting on %d, at %d], missed IRQ?\n, - ring-name, - ring-waiting_seqno, - ring-get_seqno(ring)); + if (waitqueue_active(ring-irq_queue)) { + DRM_ERROR(Hangcheck timer elapsed... %s idle\n, + ring-name); wake_up_all(ring-irq_queue); *err = true; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index e0b25bb..d3bf259 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++
[Intel-gfx] [PATCH 05/12 v2] drm/i915: drop polled waits from i915_wait_request
The only time irq_get should fail is during unload or suspend. Both of these points should try to quiesce the GPU before disabling interrupts and so the atomic polling should never occur. This was recommended by Chris Wilson as a way of reducing added complexity to the polled wait which I introduced in an RFC patch. 09:57 ickle_ it's only there as a fudge for waiting after irqs after uninstalled during sr, we aren't actually meant to hit it 09:57 ickle_ so maybe we should just kill the code there and fix the breakage v2: return -ENODEV instead of -EBUSY when irq_get fails Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_gem.c | 25 +++-- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c29c758..c5f0b03 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1864,22 +1864,19 @@ i915_wait_request(struct intel_ring_buffer *ring, if (!i915_seqno_passed(ring-get_seqno(ring), seqno)) { trace_i915_gem_request_wait_begin(ring, seqno); - if (ring-irq_get(ring)) { - if (dev_priv-mm.interruptible) - ret = wait_event_interruptible(ring-irq_queue, - i915_seqno_passed(ring-get_seqno(ring), seqno) - || atomic_read(dev_priv-mm.wedged)); - else - wait_event(ring-irq_queue, - i915_seqno_passed(ring-get_seqno(ring), seqno) - || atomic_read(dev_priv-mm.wedged)); + if (WARN_ON(!ring-irq_get(ring))) + return -ENODEV; - ring-irq_put(ring); - } else if (wait_for_atomic(i915_seqno_passed(ring-get_seqno(ring), -seqno) || - atomic_read(dev_priv-mm.wedged), 3000)) - ret = -EBUSY; + if (dev_priv-mm.interruptible) + ret = wait_event_interruptible(ring-irq_queue, + i915_seqno_passed(ring-get_seqno(ring), seqno) + || atomic_read(dev_priv-mm.wedged)); + else + wait_event(ring-irq_queue, + i915_seqno_passed(ring-get_seqno(ring), seqno) + || atomic_read(dev_priv-mm.wedged)); + ring-irq_put(ring); trace_i915_gem_request_wait_end(ring, seqno); } if (atomic_read(dev_priv-mm.wedged)) -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 06/12 v2] drm/i915: extract __wait_seqno from i915_wait_request
i915_wait_request is actually a fairly large function encapsulating quite a few different operations. Because being able to wait on seqnos in various conditions is useful, extracting that bit of code to a helper function seems useful v2: pull the irq_get/put as well (Ben) Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_gem.c | 49 +-- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c5f0b03..06668eb 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1819,6 +1819,36 @@ i915_gem_retire_work_handler(struct work_struct *work) mutex_unlock(dev-struct_mutex); } +static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, + bool interruptible) +{ + drm_i915_private_t *dev_priv = ring-dev-dev_private; + int ret = 0; + + if (i915_seqno_passed(ring-get_seqno(ring), seqno)) + return 0; + + trace_i915_gem_request_wait_begin(ring, seqno); + if (WARN_ON(!ring-irq_get(ring))) + return -ENODEV; + +#define EXIT_COND \ + (i915_seqno_passed(ring-get_seqno(ring), seqno) || \ + atomic_read(dev_priv-mm.wedged)) + + if (interruptible) + ret = wait_event_interruptible(ring-irq_queue, + EXIT_COND); + else + wait_event(ring-irq_queue, EXIT_COND); + + ring-irq_put(ring); + trace_i915_gem_request_wait_end(ring, seqno); +#undef EXIT_COND + + return ret; +} + /** * Waits for a sequence number to be signaled, and cleans up the * request and object lists appropriately for that event. @@ -1861,24 +1891,7 @@ i915_wait_request(struct intel_ring_buffer *ring, seqno = request-seqno; } - if (!i915_seqno_passed(ring-get_seqno(ring), seqno)) { - trace_i915_gem_request_wait_begin(ring, seqno); - - if (WARN_ON(!ring-irq_get(ring))) - return -ENODEV; - - if (dev_priv-mm.interruptible) - ret = wait_event_interruptible(ring-irq_queue, - i915_seqno_passed(ring-get_seqno(ring), seqno) - || atomic_read(dev_priv-mm.wedged)); - else - wait_event(ring-irq_queue, - i915_seqno_passed(ring-get_seqno(ring), seqno) - || atomic_read(dev_priv-mm.wedged)); - - ring-irq_put(ring); - trace_i915_gem_request_wait_end(ring, seqno); - } + ret = __wait_seqno(ring, seqno, dev_priv-mm.interruptible); if (atomic_read(dev_priv-mm.wedged)) ret = -EAGAIN; -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 07/12] drm/i915: remove polled wait from throttle
It's about to go away anyway. Just here to help bisection. Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_gem.c |5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 06668eb..4de0515 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2996,11 +2996,8 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) if (ret == 0 atomic_read(dev_priv-mm.wedged)) ret = -EIO; - } else if (wait_for_atomic(i915_seqno_passed(ring-get_seqno(ring), -seqno) || - atomic_read(dev_priv-mm.wedged), 3000)) { + } else ret = -EBUSY; - } } if (ret == 0) -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 08/12 v2] drm/i915: use __wait_seqno for ring throttle
It turns out throttle had an almost identical bit of code to do the wait. Now we can call the new helper directly. This is just a bonus, and not needed for the overall series. v2: remove irq_get/put which is now in __wait_seqno (Ben) Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_gem.c | 20 +--- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4de0515..0ae1a73 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2981,25 +2981,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) if (seqno == 0) return 0; - ret = 0; - if (!i915_seqno_passed(ring-get_seqno(ring), seqno)) { - /* And wait for the seqno passing without holding any locks and -* causing extra latency for others. This is safe as the irq -* generation is designed to be run atomically and so is -* lockless. -*/ - if (ring-irq_get(ring)) { - ret = wait_event_interruptible(ring-irq_queue, - i915_seqno_passed(ring-get_seqno(ring), seqno) - || atomic_read(dev_priv-mm.wedged)); - ring-irq_put(ring); - - if (ret == 0 atomic_read(dev_priv-mm.wedged)) - ret = -EIO; - } else - ret = -EBUSY; - } - + ret = __wait_seqno(ring, seqno, true); if (ret == 0) queue_delayed_work(dev_priv-wq, dev_priv-mm.retire_work, 0); -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 09/12] drm/i915: timeout parameter for seqno wait
Insert a wait parameter in the code so we can possibly timeout on a seqno wait if need be. The code should be functionally the same as before because all the callers will continue to retry if an arbitrary timeout elapses. We'd like to have nanosecond granularity, but the only way to do this is with hrtimer, and that doesn't fit well with the needs of this code. Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_gem.c | 58 +++ 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0ae1a73..f054439 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1820,10 +1820,23 @@ i915_gem_retire_work_handler(struct work_struct *work) } static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, - bool interruptible) + bool interruptible, long *usecs) { drm_i915_private_t *dev_priv = ring-dev-dev_private; - int ret = 0; + bool wait_forever = false; + long timeout, end; + + if (usecs == NULL || ((*usecs) 0)) { + wait_forever = true; + timeout = msecs_to_jiffies(100); + } else + timeout = usecs_to_jiffies(*usecs); + + if (i915_seqno_passed(ring-get_seqno(ring), seqno)) + return 0; + + if (WARN_ON(!ring-irq_get(ring))) + return -ENODEV; if (i915_seqno_passed(ring-get_seqno(ring), seqno)) return 0; @@ -1836,17 +1849,40 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, (i915_seqno_passed(ring-get_seqno(ring), seqno) || \ atomic_read(dev_priv-mm.wedged)) + trace_i915_gem_request_wait_begin(ring, seqno); +again: if (interruptible) - ret = wait_event_interruptible(ring-irq_queue, - EXIT_COND); + end = wait_event_interruptible_timeout(ring-irq_queue, + EXIT_COND, + timeout); else - wait_event(ring-irq_queue, EXIT_COND); + end = wait_event_timeout(ring-irq_queue, EXIT_COND, timeout); +#undef EXIT_COND + + if (atomic_read(dev_priv-mm.wedged)) + end = -EAGAIN; + + if (end == 0 wait_forever) + goto again; - ring-irq_put(ring); trace_i915_gem_request_wait_end(ring, seqno); -#undef EXIT_COND + ring-irq_put(ring); - return ret; + if (!wait_forever) { + BUG_ON(end == 0); + *usecs = jiffies_to_usecs(timeout - end); + } + + switch (end) { + case -EAGAIN: /* Wedged */ + case -ERESTARTSYS: /* Signal */ + return (int)end; + case 0: /* Tiemout */ + return -ETIME; + default: /* Completed */ + WARN_ON(end 0); /* We're not aware of other errors */ + return 0; + } } /** @@ -1891,9 +1927,7 @@ i915_wait_request(struct intel_ring_buffer *ring, seqno = request-seqno; } - ret = __wait_seqno(ring, seqno, dev_priv-mm.interruptible); - if (atomic_read(dev_priv-mm.wedged)) - ret = -EAGAIN; + ret = __wait_seqno(ring, seqno, dev_priv-mm.interruptible, NULL); return ret; } @@ -2981,7 +3015,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) if (seqno == 0) return 0; - ret = __wait_seqno(ring, seqno, true); + ret = __wait_seqno(ring, seqno, true, NULL); if (ret == 0) queue_delayed_work(dev_priv-wq, dev_priv-mm.retire_work, 0); -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 10/12] drm/i915: extract some common olr+wedge code
Refactor. Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_gem.c | 122 +-- 1 file changed, 65 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f054439..63eda79 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1819,6 +1819,59 @@ i915_gem_retire_work_handler(struct work_struct *work) mutex_unlock(dev-struct_mutex); } + +static int +i915_gem_check_wedge(struct drm_i915_private *dev_priv) +{ + BUG_ON(!mutex_is_locked(dev_priv-dev-struct_mutex)); + + if (atomic_read(dev_priv-mm.wedged)) { + struct completion *x = dev_priv-error_completion; + bool recovery_complete; + unsigned long flags; + + /* Give the error handler a chance to run. */ + spin_lock_irqsave(x-wait.lock, flags); + recovery_complete = x-done 0; + spin_unlock_irqrestore(x-wait.lock, flags); + + return recovery_complete ? -EIO : -EAGAIN; + } + + return 0; +} + +/* + * Compare seqno against outstanding lazy request. Emit a request if they are + * equal. Seqno is updated with the new value if a request was emitted. + */ +static int +i915_gem_check_olr(struct intel_ring_buffer *ring, u32 *seqno) +{ + int ret = 0; + + BUG_ON(!mutex_is_locked(ring-dev-struct_mutex)); + + if (*seqno == ring-outstanding_lazy_request) { + struct drm_i915_gem_request *request; + + request = kzalloc(sizeof(*request), GFP_KERNEL); + if (request == NULL) + return -ENOMEM; + + ret = i915_add_request(ring, NULL, request); + if (ret) { + kfree(request); + return ret; + } + + *seqno = request-seqno; + } + + return ret; +} + + static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, bool interruptible, long *usecs) { @@ -1898,34 +1951,13 @@ i915_wait_request(struct intel_ring_buffer *ring, BUG_ON(seqno == 0); - if (atomic_read(dev_priv-mm.wedged)) { - struct completion *x = dev_priv-error_completion; - bool recovery_complete; - unsigned long flags; - - /* Give the error handler a chance to run. */ - spin_lock_irqsave(x-wait.lock, flags); - recovery_complete = x-done 0; - spin_unlock_irqrestore(x-wait.lock, flags); - - return recovery_complete ? -EIO : -EAGAIN; - } - - if (seqno == ring-outstanding_lazy_request) { - struct drm_i915_gem_request *request; - - request = kzalloc(sizeof(*request), GFP_KERNEL); - if (request == NULL) - return -ENOMEM; - - ret = i915_add_request(ring, NULL, request); - if (ret) { - kfree(request); - return ret; - } + ret = i915_gem_check_wedge(dev_priv); + if (ret) + return ret; - seqno = request-seqno; - } + ret = i915_gem_check_olr(ring, seqno); + if (ret) + return ret; ret = __wait_seqno(ring, seqno, dev_priv-mm.interruptible, NULL); @@ -1991,22 +2023,9 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj, if (seqno = from-sync_seqno[idx]) return 0; - if (seqno == from-outstanding_lazy_request) { - struct drm_i915_gem_request *request; - - request = kzalloc(sizeof(*request), GFP_KERNEL); - if (request == NULL) - return -ENOMEM; - - ret = i915_add_request(from, NULL, request); - if (ret) { - kfree(request); - return ret; - } - - seqno = request-seqno; - } - + ret = i915_gem_check_olr(obj-ring, seqno); + if (ret) + return ret; ret = to-sync_to(to, from, seqno); if (!ret) @@ -3194,20 +3213,9 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, if (obj-base.write_domain I915_GEM_GPU_DOMAINS) { ret = i915_gem_flush_ring(obj-ring, 0, obj-base.write_domain); - } else if (obj-ring-outstanding_lazy_request == - obj-last_rendering_seqno) { - struct drm_i915_gem_request *request; - - /* This ring is not being cleared by active usage, -* so emit a request to do so. -*/ - request = kzalloc(sizeof(*request), GFP_KERNEL); - if (request) { -
[Intel-gfx] [PATCH 11/12 v2] drm/i915: wait render timeout ioctl
This helps implement glClientWaitSync. Finally we can use the new timed seqno waiting function to allow userspace to wait on a request with a timeout. This implements that interface. The new ioctl is very straight forward, there is a flags field which I envision may be useful for various flush permutations of the command. On 32bit systems, the timeout is restricted to 2^32 - 1 microseconds. v2: ETIME/ERESTARTSYS instead of changing to EBUSY, and EGAIN (Chris) Flush the object from the gpu write domain (Chris + Daniel) Fix leaked refcount in good case (Chris) Naturally align ioctl struct (Chris) Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_dma.c |1 + drivers/gpu/drm/i915/i915_drv.h |2 ++ drivers/gpu/drm/i915/i915_gem.c | 55 +++ include/drm/i915_drm.h |8 ++ 4 files changed, 66 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index e73389d..ed0ccb7 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -2189,6 +2189,7 @@ struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, intel_sprite_get_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_UNLOCKED), }; int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d260762..d415f0f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1221,6 +1221,8 @@ int i915_gem_get_tiling(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +int i915_gem_wait_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); void i915_gem_load(struct drm_device *dev); int i915_gem_init_object(struct drm_gem_object *obj); int __must_check i915_gem_flush_ring(struct intel_ring_buffer *ring, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 63eda79..0dee6bc 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1991,6 +1991,61 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj) return 0; } +int +i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) +{ + struct drm_i915_gem_wait *args = data; + struct drm_i915_gem_object *obj; + struct intel_ring_buffer *ring = NULL; + long timeout; + u32 seqno = 0; + int ret = 0; + + /* For now timeout is microseconds only */ + timeout = (long)DIV_ROUND_UP_ULL(args-timeout_ns, NSEC_PER_USEC); + + ret = i915_mutex_lock_interruptible(dev); + if (ret) + return ret; + + obj = to_intel_bo(drm_gem_object_lookup(dev, file, args-bo_handle)); + if (obj-base == NULL) { + mutex_unlock(dev-struct_mutex); + return -ENOENT; + } + + /* Need to make sure the object is flushed first. This non-obvious +* flush is required to enforce that (active !olr) == no wait +* necessary. +*/ + ret = i915_gem_object_flush_gpu_write_domain(obj); + if (ret) + goto out; + + if (obj-active) { + seqno = obj-last_rendering_seqno; + ring = obj-ring; + } + + if (seqno == 0) +goto out; + + ret = i915_gem_check_olr(ring, seqno); + if (ret) + goto out; + + mutex_unlock(dev-struct_mutex); + ret = __wait_seqno(ring, seqno, true, timeout); + drm_gem_object_unreference_unlocked(obj-base); + args-timeout_ns = timeout * NSEC_PER_USEC; + return ret; + +out: + drm_gem_object_unreference(obj-base); + mutex_unlock(dev-struct_mutex); + return ret; +} + /** * i915_gem_object_sync - sync an object to a ring. * diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index f3f8224..8f818f8 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -200,6 +200,7 @@ typedef struct _drm_i915_sarea { #define DRM_I915_GEM_EXECBUFFER2 0x29 #define DRM_I915_GET_SPRITE_COLORKEY 0x2a #define DRM_I915_SET_SPRITE_COLORKEY 0x2b +#define DRM_I915_GEM_WAIT 0x2c #define DRM_IOCTL_I915_INITDRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) @@ -243,6 +244,7 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_OVERLAY_ATTRS
[Intel-gfx] [PATCH 12/12] drm/i915: s/i915_wait_reqest/i915_wait_seqno/g
Wait request is poorly named IMO. After working with these functions for some time, I feel it's much clearer to name the functions more appropriately. Of course we must update the callers to use the new name as well. This leaves room within our namespace for a *real* wait request function at some point. Note to maintainer: this patch is optional. Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_drv.h |4 ++-- drivers/gpu/drm/i915/i915_gem.c |9 - drivers/gpu/drm/i915/intel_overlay.c|4 ++-- drivers/gpu/drm/i915/intel_ringbuffer.c |2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d415f0f..f961cc8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1307,8 +1307,8 @@ int __must_check i915_gem_idle(struct drm_device *dev); int __must_check i915_add_request(struct intel_ring_buffer *ring, struct drm_file *file, struct drm_i915_gem_request *request); -int __must_check i915_wait_request(struct intel_ring_buffer *ring, - uint32_t seqno); +int __must_check i915_wait_seqno(struct intel_ring_buffer *ring, +uint32_t seqno); int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); int __must_check i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0dee6bc..3ae21d4 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1943,8 +1943,7 @@ again: * request and object lists appropriately for that event. */ int -i915_wait_request(struct intel_ring_buffer *ring, - uint32_t seqno) +i915_wait_seqno(struct intel_ring_buffer *ring, uint32_t seqno) { drm_i915_private_t *dev_priv = ring-dev-dev_private; int ret = 0; @@ -1982,7 +1981,7 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj) * it. */ if (obj-active) { - ret = i915_wait_request(obj-ring, obj-last_rendering_seqno); + ret = i915_wait_seqno(obj-ring, obj-last_rendering_seqno); if (ret) return ret; i915_gem_retire_requests_ring(obj-ring); @@ -2224,7 +2223,7 @@ static int i915_ring_idle(struct intel_ring_buffer *ring) return ret; } - return i915_wait_request(ring, i915_gem_next_request_seqno(ring)); + return i915_wait_seqno(ring, i915_gem_next_request_seqno(ring)); } int i915_gpu_idle(struct drm_device *dev) @@ -2423,7 +2422,7 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj) } if (obj-last_fenced_seqno) { - ret = i915_wait_request(obj-ring, obj-last_fenced_seqno); + ret = i915_wait_seqno(obj-ring, obj-last_fenced_seqno); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 07a5cad..7a05a34 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -225,7 +225,7 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay, } overlay-last_flip_req = request-seqno; overlay-flip_tail = tail; - ret = i915_wait_request(LP_RING(dev_priv), overlay-last_flip_req); + ret = i915_wait_seqno(LP_RING(dev_priv), overlay-last_flip_req); if (ret) return ret; @@ -446,7 +446,7 @@ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay) if (overlay-last_flip_req == 0) return 0; - ret = i915_wait_request(LP_RING(dev_priv), overlay-last_flip_req); + ret = i915_wait_seqno(LP_RING(dev_priv), overlay-last_flip_req); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index a7d97d1..9bc9e12 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1088,7 +1088,7 @@ static int intel_ring_wait_seqno(struct intel_ring_buffer *ring, u32 seqno) was_interruptible = dev_priv-mm.interruptible; dev_priv-mm.interruptible = false; - ret = i915_wait_request(ring, seqno); + ret = i915_wait_seqno(ring, seqno); dev_priv-mm.interruptible = was_interruptible; if (!ret) -- 1.7.10 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 0/6] gpu hangman support
On Wed, 25 Apr 2012 13:57:07 +0200 Daniel Vetter daniel.vet...@ffwll.ch wrote: Hi all, In the light of the recent oops in the error state code I've resurrected my gpu hangman and brushed it up a bit. Together with the hangman check in i-g-t (which now also works a bit more reliable) we'll have a basic test of our hangcheck, reset and error state infrastructure. Comments, flames and excessively-painted bikesheds highly welcome. Cheers, Daniel Would you mind separating out the reset patches? I really want those regardless of the fate of hangman. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx