From patchwork Tue Dec 4 16:48:55 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Zanoni X-Patchwork-Id: 1839161 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id AAA1EDF230 for ; Tue, 4 Dec 2012 16:49:58 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 88B0BE6392 for ; Tue, 4 Dec 2012 08:49:58 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ob0-f177.google.com (mail-ob0-f177.google.com [209.85.214.177]) by gabe.freedesktop.org (Postfix) with ESMTP id C3B6AE63D9 for ; Tue, 4 Dec 2012 08:49:19 -0800 (PST) Received: by mail-ob0-f177.google.com with SMTP id uo13so3897485obb.36 for ; Tue, 04 Dec 2012 08:49:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=x3SWA0A2eq6hQ/q2IxegdHLOLez94Q0qpLAtLg9b1nk=; b=i25pY2ECAYEFuX99I6y8BUxzCW0s2bQPz+/QXdqWydPpN3Ft+AxwbrYLD8HTeSUbrF U/7SgdSMoi+VAW2Mq6uIJZqawRcU3K1pIQKN3v3/G8qmtqpbiGH+j4kz49LdPvu0HSn3 4prPf7WVn7JVOqYYcuHYjFDnB6AbxK6v+UpvKrUF3EoDdFWP/SkJI65I7fvwgFVHeQs3 NAAN0PyssG5D5hbzxdire53YfKc/oreK7DiTPzMOql4FcsEBasP4FxUYXzFgaoO+2W+R hMrHIAX4ZmzN1kPMcK2E4Q3yThP74cpZ2H0wKCegXASvl9g7vk2yPPwwpHYKfr2W2zJn CmGw== Received: by 10.182.134.66 with SMTP id pi2mr8287227obb.42.1354639759243; Tue, 04 Dec 2012 08:49:19 -0800 (PST) Received: from vicky.domain.invalid ([177.96.10.127]) by mx.google.com with ESMTPS id zz6sm1191290oeb.1.2012.12.04.08.49.17 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 04 Dec 2012 08:49:18 -0800 (PST) From: Paulo Zanoni To: intel-gfx@lists.freedesktop.org Date: Tue, 4 Dec 2012 14:48:55 -0200 Message-Id: <1354639737-3727-2-git-send-email-przanoni@gmail.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1354639737-3727-1-git-send-email-przanoni@gmail.com> References: <1354639737-3727-1-git-send-email-przanoni@gmail.com> Cc: Paulo Zanoni Subject: [Intel-gfx] [PATCH 1/2] drm/i915: fix intel_init_power_wells X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 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+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org From: Paulo Zanoni The current code was wrong in many different ways, so this is a full rewrite. We don't have "different power wells for different parts of the GPU", we have a single power well, but we have multiple registers that can be used to request enabling/disabling the power well. So let's be a good citizen and only use the register we're suppose to use, except when we're loading the driver, where we clear the request made by the BIOS. If any of the registers is requesting the power well to be enabled, it will be enabled. If none of the registers is requesting the power well to be enabled, it will be disabled. For now we're just forcing the power well to be enabled, but in the next commits we'll change this. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/i915_reg.h | 8 ++--- drivers/gpu/drm/i915/intel_display.c | 5 +-- drivers/gpu/drm/i915/intel_drv.h | 2 +- drivers/gpu/drm/i915/intel_pm.c | 70 +++++++++++++++++++++++++++--------- 4 files changed, 59 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 462b50a..04b5d32 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4414,10 +4414,10 @@ #define AUDIO_CP_READY_C (1<<9) /* HSW Power Wells */ -#define HSW_PWR_WELL_CTL1 0x45400 /* BIOS */ -#define HSW_PWR_WELL_CTL2 0x45404 /* Driver */ -#define HSW_PWR_WELL_CTL3 0x45408 /* KVMR */ -#define HSW_PWR_WELL_CTL4 0x4540C /* Debug */ +#define HSW_PWR_WELL_BIOS 0x45400 /* CTL1 */ +#define HSW_PWR_WELL_DRIVER 0x45404 /* CTL2 */ +#define HSW_PWR_WELL_KVMR 0x45408 /* CTL3 */ +#define HSW_PWR_WELL_DEBUG 0x4540C /* CTL4 */ #define HSW_PWR_WELL_ENABLE (1<<31) #define HSW_PWR_WELL_STATE (1<<30) #define HSW_PWR_WELL_CTL5 0x45410 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 093a163..1864b4f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8593,10 +8593,7 @@ static void i915_disable_vga(struct drm_device *dev) void intel_modeset_init_hw(struct drm_device *dev) { - /* 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); + intel_init_power_well(dev); intel_prepare_ddi(dev); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 7ca7772..6bafe26 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -646,7 +646,7 @@ 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 intel_init_power_wells(struct drm_device *dev); +extern void intel_init_power_well(struct drm_device *dev); extern void intel_enable_gt_powersave(struct drm_device *dev); extern void intel_disable_gt_powersave(struct drm_device *dev); extern void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index abfff29..53a44e0 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3919,33 +3919,69 @@ void intel_init_clock_gating(struct drm_device *dev) dev_priv->display.init_clock_gating(dev); } -/* Starting with Haswell, we have different power wells for - * different parts of the GPU. This attempts to enable them all. +static void intel_set_power_well(struct drm_device *dev, bool enable) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + bool is_enabled, enable_requested; + uint32_t tmp; + + tmp = I915_READ(HSW_PWR_WELL_DRIVER); + is_enabled = !!(tmp & HSW_PWR_WELL_STATE); + enable_requested = !!(tmp & HSW_PWR_WELL_ENABLE); + + if (enable) { + if (!enable_requested) + I915_WRITE(HSW_PWR_WELL_DRIVER, HSW_PWR_WELL_ENABLE); + + if (!is_enabled) { + DRM_DEBUG_KMS("Enabling power well\n"); + if (wait_for((I915_READ(HSW_PWR_WELL_DRIVER) & + HSW_PWR_WELL_STATE), 20)) + DRM_ERROR("Timeout enabling power well\n"); + } + } else { + if (enable_requested) + I915_WRITE(HSW_PWR_WELL_DRIVER, 0); + + if (is_enabled) { + if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE) + DRM_DEBUG_KMS("Not disabling power well: requested by BIOS\n"); + else if (I915_READ(HSW_PWR_WELL_KVMR) & HSW_PWR_WELL_ENABLE) + DRM_DEBUG_KMS("Not disabling power well: requested by KVMR\n"); + else if (I915_READ(HSW_PWR_WELL_DEBUG) & HSW_PWR_WELL_ENABLE) + DRM_DEBUG_KMS("Not disabling power well: requested by DEBUG\n"); + else { + DRM_DEBUG_KMS("Disabling power well\n"); + if (wait_for((I915_READ(HSW_PWR_WELL_DRIVER) & + HSW_PWR_WELL_STATE) == 0, 20)) + DRM_ERROR("Timeout disabling power well\n"); + } + } + } +} + +/* + * Starting with Haswell, we have a "Power Down Well" that can be turned off + * when not needed anymore. We have 4 registers that can request the power well + * to be enabled, and it will only be disabled if none of the registers is + * requesting it to be enabled. */ -void intel_init_power_wells(struct drm_device *dev) +void intel_init_power_well(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]); + /* For now, we need the power well to be always enabled. */ + intel_set_power_well(dev, true); - 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]); - } - } + /* We're taking over the BIOS, so clear any requests made by it since + * the driver is in charge now. */ + if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE) + I915_WRITE(HSW_PWR_WELL_BIOS, 0); mutex_unlock(&dev->struct_mutex); }