From 803095077a4804aa4291cb90e2f5b85096472b51 Mon Sep 17 00:00:00 2001 From: Tobias Powalowski Date: Thu, 2 Jun 2016 13:51:16 +0000 Subject: [PATCH] fix flicker problem and rtlwifi atomic bug --- 0001-linux-4.6-drm-i915-psr.patch | 115 ++++++++++++++++++++++++ 0001-linux-4.6-rtlwifi-fix-atomic.patch | 70 +++++++++++++++ PKGBUILD | 18 +++- 3 files changed, 200 insertions(+), 3 deletions(-) create mode 100644 0001-linux-4.6-drm-i915-psr.patch create mode 100644 0001-linux-4.6-rtlwifi-fix-atomic.patch diff --git a/0001-linux-4.6-drm-i915-psr.patch b/0001-linux-4.6-drm-i915-psr.patch new file mode 100644 index 0000000..29ba7ea --- /dev/null +++ b/0001-linux-4.6-drm-i915-psr.patch @@ -0,0 +1,115 @@ +From 03b7b5f983091bca17e9c163832fcde56971d7d1 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 18 May 2016 18:47:11 +0200 +Subject: drm/i915/psr: Try to program link training times correctly +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The default of 0 is 500us of link training, but that's not enough for +some platforms. Decoding this correctly means we're using 2.5ms of +link training on these platforms, which fixes flickering issues +associated with enabling PSR. + +v2: Unbotch the math a bit. + +v3: Drop debug hunk. + +v4: Improve commit message. + +Tested-by: Lyude +Cc: Lyude +Cc: stable@vger.kernel.org +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=95176 +Cc: Rodrigo Vivi +Cc: Sonika Jindal +Cc: Durgadoss R +Cc: "Pandiyan, Dhinakaran" +Tested-by: Ville Syrjälä +Reviewed-by: Ville Syrjälä +Tested-by: fritsch@kodi.tv +Signed-off-by: Daniel Vetter +Link: http://patchwork.freedesktop.org/patch/msgid/1463590036-17824-2-git-send-email-daniel.vetter@ffwll.ch +(cherry picked from commit 50db139018f9c94376d5f4db94a3bae65fdfac14) +Signed-off-by: Jani Nikula +--- + drivers/gpu/drm/i915/intel_psr.c | 55 ++++++++++++++++++++++++++++++++++------ + 1 file changed, 47 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c +index c3abae4..a788d1e 100644 +--- a/drivers/gpu/drm/i915/intel_psr.c ++++ b/drivers/gpu/drm/i915/intel_psr.c +@@ -280,7 +280,10 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp) + * with the 5 or 6 idle patterns. + */ + uint32_t idle_frames = max(6, dev_priv->vbt.psr.idle_frames); +- uint32_t val = 0x0; ++ uint32_t val = EDP_PSR_ENABLE; ++ ++ val |= max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT; ++ val |= idle_frames << EDP_PSR_IDLE_FRAME_SHIFT; + + if (IS_HASWELL(dev)) + val |= EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES; +@@ -288,14 +291,50 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp) + if (dev_priv->psr.link_standby) + val |= EDP_PSR_LINK_STANDBY; + +- I915_WRITE(EDP_PSR_CTL, val | +- max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | +- idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | +- EDP_PSR_ENABLE); ++ if (dev_priv->vbt.psr.tp1_wakeup_time > 5) ++ val |= EDP_PSR_TP1_TIME_2500us; ++ else if (dev_priv->vbt.psr.tp1_wakeup_time > 1) ++ val |= EDP_PSR_TP1_TIME_500us; ++ else if (dev_priv->vbt.psr.tp1_wakeup_time > 0) ++ val |= EDP_PSR_TP1_TIME_100us; ++ else ++ val |= EDP_PSR_TP1_TIME_0us; ++ ++ if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 5) ++ val |= EDP_PSR_TP2_TP3_TIME_2500us; ++ else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 1) ++ val |= EDP_PSR_TP2_TP3_TIME_500us; ++ else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 0) ++ val |= EDP_PSR_TP2_TP3_TIME_100us; ++ else ++ val |= EDP_PSR_TP2_TP3_TIME_0us; ++ ++ if (intel_dp_source_supports_hbr2(intel_dp) && ++ drm_dp_tps3_supported(intel_dp->dpcd)) ++ val |= EDP_PSR_TP1_TP3_SEL; ++ else ++ val |= EDP_PSR_TP1_TP2_SEL; ++ ++ I915_WRITE(EDP_PSR_CTL, val); ++ ++ if (!dev_priv->psr.psr2_support) ++ return; ++ ++ /* FIXME: selective update is probably totally broken because it doesn't ++ * mesh at all with our frontbuffer tracking. And the hw alone isn't ++ * good enough. */ ++ val = EDP_PSR2_ENABLE | EDP_SU_TRACK_ENABLE; ++ ++ if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 5) ++ val |= EDP_PSR2_TP2_TIME_2500; ++ else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 1) ++ val |= EDP_PSR2_TP2_TIME_500; ++ else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 0) ++ val |= EDP_PSR2_TP2_TIME_100; ++ else ++ val |= EDP_PSR2_TP2_TIME_50; + +- if (dev_priv->psr.psr2_support) +- I915_WRITE(EDP_PSR2_CTL, EDP_PSR2_ENABLE | +- EDP_SU_TRACK_ENABLE | EDP_PSR2_TP2_TIME_100); ++ I915_WRITE(EDP_PSR2_CTL, val); + } + + static bool intel_psr_match_conditions(struct intel_dp *intel_dp) +-- +cgit v0.12 + diff --git a/0001-linux-4.6-rtlwifi-fix-atomic.patch b/0001-linux-4.6-rtlwifi-fix-atomic.patch new file mode 100644 index 0000000..e514ec8 --- /dev/null +++ b/0001-linux-4.6-rtlwifi-fix-atomic.patch @@ -0,0 +1,70 @@ +From de26859dcf363d520cc44e59f6dcaf20ebe0aadf Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Sat, 21 May 2016 11:50:35 -0500 +Subject: rtlwifi: Fix scheduling while atomic error from commit 49f86ec21c01 + +Commit 49f86ec21c01 ("rtlwifi: Change long delays to sleeps") was correct +for most cases; however, driver rtl8192ce calls the affected routines while +in atomic context. The kernel bug output is as follows: + +BUG: scheduling while atomic: wpa_supplicant/627/0x00000002 +[...] + [] __schedule+0x899/0xad0 + [] schedule+0x3c/0x90 + [] schedule_hrtimeout_range_clock+0xa2/0x120 + [] ? hrtimer_init+0x120/0x120 + [] ? schedule_hrtimeout_range_clock+0x96/0x120 + [] schedule_hrtimeout_range+0x13/0x20 + [] usleep_range+0x4f/0x70 + [] rtl_rfreg_delay+0x38/0x50 [rtlwifi] + [] rtl92c_phy_config_rf_with_headerfile+0xc7/0xe0 [rtl8192ce] + +To fix this bug, three of the changes from delay to sleep are reverted. +Unfortunately, one of the changes involves a delay of 50 msec. The calling +code will be modified so that this long delay can be avoided; however, +this change is being pushed now to fix the problem in kernel 4.6.0. + +Fixes: 49f86ec21c01 ("rtlwifi: Change long delays to sleeps") +Reported-by: James Feeney +Signed-off-by: Larry Finger +Cc: James Feeney +Cc: Stable [4.6+] +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/realtek/rtlwifi/core.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c +index 0f48048..3a0faa8 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/core.c ++++ b/drivers/net/wireless/realtek/rtlwifi/core.c +@@ -54,7 +54,7 @@ EXPORT_SYMBOL(channel5g_80m); + void rtl_addr_delay(u32 addr) + { + if (addr == 0xfe) +- msleep(50); ++ mdelay(50); + else if (addr == 0xfd) + msleep(5); + else if (addr == 0xfc) +@@ -75,7 +75,7 @@ void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr, + rtl_addr_delay(addr); + } else { + rtl_set_rfreg(hw, rfpath, addr, mask, data); +- usleep_range(1, 2); ++ udelay(1); + } + } + EXPORT_SYMBOL(rtl_rfreg_delay); +@@ -86,7 +86,7 @@ void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data) + rtl_addr_delay(addr); + } else { + rtl_set_bbreg(hw, addr, MASKDWORD, data); +- usleep_range(1, 2); ++ udelay(1); + } + } + EXPORT_SYMBOL(rtl_bb_delay); +-- +cgit v0.12 + diff --git a/PKGBUILD b/PKGBUILD index 26cd9f8..cb939c0 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -5,7 +5,7 @@ pkgbase=linux # Build stock -ARCH kernel #pkgbase=linux-custom # Build kernel with a different name _srcname=linux-4.6 pkgver=4.6.1 -pkgrel=1 +pkgrel=2 arch=('i686' 'x86_64') url="http://www.kernel.org/" license=('GPL2') @@ -19,7 +19,9 @@ source=("https://www.kernel.org/pub/linux/kernel/v4.x/${_srcname}.tar.xz" 'config' 'config.x86_64' # standard config files for mkinitcpio ramdisk 'linux.preset' - 'change-default-console-loglevel.patch') + 'change-default-console-loglevel.patch' + '0001-linux-4.6-drm-i915-psr.patch' + '0001-linux-4.6-rtlwifi-fix-atomic.patch') sha256sums=('a93771cd5a8ad27798f22e9240538dfea48d3a2bf2a6a6ab415de3f02d25d866' 'SKIP' @@ -28,7 +30,9 @@ sha256sums=('a93771cd5a8ad27798f22e9240538dfea48d3a2bf2a6a6ab415de3f02d25d866' '02e8b02e8cd10aa059917a489a9663e7f66bdf12c5ae8a1e0369bb2862da6b68' 'd59014b8f887c6aa9488ef5ff9bc5d4357850a979f3ff90a2999bbe24e5c6e15' 'f0d90e756f14533ee67afda280500511a62465b4f76adcc5effa95a40045179c' - '1256b241cd477b265a3c2d64bdc19ffe3c9bbcee82ea3994c590c2c76e767d99') + '1256b241cd477b265a3c2d64bdc19ffe3c9bbcee82ea3994c590c2c76e767d99' + 'b719c3bd58d71a9e0d76b3674e854419ebec4a3fa9f8a4823f23639720527e83' + 'ae0d16e81a915fae130125ba9d0b6fd2427e06f50b8b9514abc4029efe61ee98') validpgpkeys=( 'ABAF11C65A2970B130ABE3C479BE3E4300411886' # Linus Torvalds '647F28654894E3BD457199BE38DBBDC86092693E' # Greg Kroah-Hartman @@ -50,6 +54,14 @@ prepare() { # (relevant patch sent upstream: https://lkml.org/lkml/2011/7/26/227) patch -p1 -i "${srcdir}/change-default-console-loglevel.patch" + # fix flickering on 4.6 + # reported from brain0 and heftig on IRC + patch -p1 -i "${srcdir}/0001-linux-4.6-drm-i915-psr.patch" + + # fix rtlwifi atomic + # https://bugs.archlinux.org/task/49401 + patch -p1 -i "${srcdir}/0001-linux-4.6-rtlwifi-fix-atomic.patch" + if [ "${CARCH}" = "x86_64" ]; then cat "${srcdir}/config.x86_64" > ./.config else