From patchwork Thu Jul 23 17:00:29 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhenyu Wang X-Patchwork-Id: 36949 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n6N91bqs009943 for ; Thu, 23 Jul 2009 09:01:37 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 756579F68D; Thu, 23 Jul 2009 02:01:37 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from fmsmga101.fm.intel.com (mga05.intel.com [192.55.52.89]) by gabe.freedesktop.org (Postfix) with ESMTP id 74C019E774 for ; Thu, 23 Jul 2009 02:01:33 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP; 23 Jul 2009 02:00:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.43,253,1246863600"; d="scan'208";a="477305450" Received: from debian-ilk.sh.intel.com (HELO localhost.localdomain) ([10.239.36.10]) by fmsmga002.fm.intel.com with ESMTP; 23 Jul 2009 01:54:45 -0700 From: Zhenyu Wang To: intel-gfx@lists.freedesktop.org Date: Fri, 24 Jul 2009 01:00:29 +0800 Message-Id: <1248368433-3734-3-git-send-email-zhenyuw@linux.intel.com> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <1248368433-3734-2-git-send-email-zhenyuw@linux.intel.com> References: <1248368433-3734-1-git-send-email-zhenyuw@linux.intel.com> <1248368433-3734-2-git-send-email-zhenyuw@linux.intel.com> Subject: [Intel-gfx] [PATCH 2/6] drm/i915: fix issue in display pipe setup on IGDNG X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.9 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org During pipe DPMS off, instead of busy waiting pipe off, insert delays during wait and don't loop after enough tries which matches spec requirement. Also try to match DPMS on path by disable FDI TX PLL in DPMS off. Disable PF by writing PF_WIN_SZ which really trigger the update. Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/i915_reg.h | 2 + drivers/gpu/drm/i915/intel_display.c | 56 ++++++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 897a116..7c77c4c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1848,6 +1848,8 @@ #define PFA_CTL_1 0x68080 #define PFB_CTL_1 0x68880 #define PF_ENABLE (1<<31) +#define PFA_WIN_SZ 0x68074 +#define PFB_WIN_SZ 0x68874 /* legacy palette */ #define LGC_PALETTE_A 0x4a000 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b06364e..15a8c39 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1038,6 +1038,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF; int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1; + int pf_win_size = (pipe == 0) ? PFA_WIN_SZ : PFB_WIN_SZ; int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; @@ -1051,7 +1052,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) int trans_vblank_reg = (pipe == 0) ? TRANS_VBLANK_A : TRANS_VBLANK_B; int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; u32 temp; - int tries = 5, j; + int tries = 5, j, n; /* XXX: When our outputs are all unaware of DPMS modes other than off * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. @@ -1239,19 +1240,21 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) if ((temp & PIPEACONF_ENABLE) != 0) { I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); I915_READ(pipeconf_reg); + n = 0; /* wait for cpu pipe off, pipe state */ - while ((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) != 0) - ; + while ((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) != 0) { + n++; + if (n < 60) { + udelay(500); + continue; + } else { + DRM_DEBUG("pipe %d off delay\n", pipe); + break; + } + } } else DRM_DEBUG("crtc %d is disabled\n", pipe); - /* IGDNG-A : disable cpu panel fitter ? */ - temp = I915_READ(pf_ctl_reg); - if ((temp & PF_ENABLE) != 0) { - I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); - I915_READ(pf_ctl_reg); - } - /* disable CPU FDI tx and PCH FDI rx */ temp = I915_READ(fdi_tx_reg); I915_WRITE(fdi_tx_reg, temp & ~FDI_TX_ENABLE); @@ -1261,6 +1264,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) I915_WRITE(fdi_rx_reg, temp & ~FDI_RX_ENABLE); I915_READ(fdi_rx_reg); + udelay(100); + /* still set train pattern 1 */ temp = I915_READ(fdi_tx_reg); temp &= ~FDI_LINK_TRAIN_NONE; @@ -1272,14 +1277,25 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) temp |= FDI_LINK_TRAIN_PATTERN_1; I915_WRITE(fdi_rx_reg, temp); + udelay(100); + /* disable PCH transcoder */ temp = I915_READ(transconf_reg); if ((temp & TRANS_ENABLE) != 0) { I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); I915_READ(transconf_reg); + n = 0; /* wait for PCH transcoder off, transcoder state */ - while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) != 0) - ; + while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) != 0) { + n++; + if (n < 60) { + udelay(500); + continue; + } else { + DRM_DEBUG("transcoder %d off delay\n", pipe); + break; + } + } } /* disable PCH DPLL */ @@ -1297,6 +1313,22 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) I915_READ(fdi_rx_reg); } + /* Disable CPU FDI TX PLL */ + temp = I915_READ(fdi_tx_reg); + if ((temp & FDI_TX_PLL_ENABLE) != 0) { + I915_WRITE(fdi_tx_reg, temp & ~FDI_TX_PLL_ENABLE); + I915_READ(fdi_tx_reg); + udelay(100); + } + + /* Disable PF */ + temp = I915_READ(pf_ctl_reg); + if ((temp & PF_ENABLE) != 0) { + I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); + I915_READ(pf_ctl_reg); + } + I915_WRITE(pf_win_size, 0); + /* Wait for the clocks to turn off. */ udelay(150); break;