From patchwork Mon Sep 10 04:31:55 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Airlie X-Patchwork-Id: 1429761 Return-Path: X-Original-To: patchwork-dri-devel@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 0D957DF28C for ; Mon, 10 Sep 2012 04:40:48 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 04D179EB3C for ; Sun, 9 Sep 2012 21:40:48 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by gabe.freedesktop.org (Postfix) with ESMTP id 598FF9E8D0 for ; Sun, 9 Sep 2012 21:32:05 -0700 (PDT) Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q8A4W4Eo026476 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 10 Sep 2012 00:32:05 -0400 Received: from prime.bne.redhat.com (dhcp-40-183.bne.redhat.com [10.64.40.183]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q8A4VvW2023447 for ; Mon, 10 Sep 2012 00:32:04 -0400 From: Dave Airlie To: dri-devel@lists.freedesktop.org Subject: [PATCH 5/5] radeon: add dynamic power off support Date: Mon, 10 Sep 2012 14:31:55 +1000 Message-Id: <1347251515-10136-6-git-send-email-airlied@gmail.com> In-Reply-To: <1347251515-10136-1-git-send-email-airlied@gmail.com> References: <1347251515-10136-1-git-send-email-airlied@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org From: Dave Airlie This adds the start of dynamic power off support to radeon, it probably turns off way to many GPUs but is an initial implementation I've tested on an gm45/rv635 combination laptop. Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon.h | 3 +++ drivers/gpu/drm/radeon/radeon_device.c | 2 +- drivers/gpu/drm/radeon/radeon_drv.c | 6 ++++++ drivers/gpu/drm/radeon/radeon_pm.c | 37 +++++++++++++++++++++++++++++++++- 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 59a1531..0abad51 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1839,6 +1839,9 @@ extern int radeon_acpi_init(struct radeon_device *rdev); static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; } #endif +extern bool radeon_dynamic_power_check(struct drm_device *dev); +extern int radeon_dynamic_power_set_state(struct drm_device *dev, int state); + #include "radeon_object.h" #endif diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 857cf5b..c58849c 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -1093,7 +1093,7 @@ int radeon_device_init(struct radeon_device *rdev, /* this will fail for cards that aren't VGA class devices, just * ignore it */ vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); - vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, false); + vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, true); r = radeon_init(rdev); if (r) diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 8c593ea..b0a7211 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -118,6 +118,9 @@ struct dma_buf *radeon_gem_prime_export(struct drm_device *dev, struct drm_gem_object *radeon_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf); +bool radeon_dynamic_power_check(struct drm_device *dev); +int radeon_dynamic_power_set_state(struct drm_device *dev, int state); + #if defined(CONFIG_DEBUG_FS) int radeon_debugfs_init(struct drm_minor *minor); void radeon_debugfs_cleanup(struct drm_minor *minor); @@ -385,6 +388,9 @@ static struct drm_driver kms_driver = { .gem_prime_export = radeon_gem_prime_export, .gem_prime_import = radeon_gem_prime_import, + .dynamic_off_check = radeon_dynamic_power_check, + .dynamic_set_state = radeon_dynamic_power_set_state, + .name = DRIVER_NAME, .desc = DRIVER_DESC, .date = DRIVER_DATE, diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 7ae6066..2763ff1 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -30,7 +30,7 @@ #include #include #include - +#include #define RADEON_IDLE_LOOP_MS 100 #define RADEON_RECLOCK_DELAY_MS 200 #define RADEON_WAIT_VBLANK_TIMEOUT 200 @@ -643,6 +643,8 @@ int radeon_pm_init(struct radeon_device *rdev) DRM_INFO("radeon: power management initialized\n"); } + drm_dynamic_power_init(rdev->ddev); + return 0; } @@ -877,3 +879,36 @@ static int radeon_debugfs_pm_init(struct radeon_device *rdev) return 0; #endif } + +bool radeon_dynamic_power_check(struct drm_device *dev) +{ + struct drm_crtc *crtc; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + if (crtc->enabled) { + DRM_DEBUG_DRIVER("failing to power off - crtc active\n"); + return false; + } + } + return true; +} + +int radeon_dynamic_power_set_state(struct drm_device *dev, int state) +{ + pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; + + if (state == DRM_SWITCH_POWER_DYNAMIC_OFF) { + dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; + vga_switcheroo_set_dynamic_switch(dev->pdev, VGA_SWITCHEROO_OFF, false); + drm_kms_helper_poll_disable(dev); + radeon_suspend_kms(dev, pmm); + vga_switcheroo_set_dynamic_switch(dev->pdev, VGA_SWITCHEROO_OFF, true); + } else { + vga_switcheroo_set_dynamic_switch(dev->pdev, VGA_SWITCHEROO_ON, true); + radeon_resume_kms(dev); + vga_switcheroo_set_dynamic_switch(dev->pdev, VGA_SWITCHEROO_ON, false); + drm_kms_helper_poll_enable(dev); + dev->switch_power_state = DRM_SWITCH_POWER_ON; + } + return 0; +}