Hi
Is there an easy way to check this is on?
I have radeon.dynpm=1 in grub but usually when I use switcheroo I see messages saying the card if now off at the moment I can old see messages saying when the card gets powered up
Is it possible to have the on and off messages appearing?
Cheers
Mike
On 20 September 2013 18:18, Alex Deucher alexdeucher@gmail.com wrote:
From: Dave Airlie airlied@redhat.com
This hooks radeon up to the runtime PM system to enable dynamic power management for secondary GPUs in switchable and powerxpress laptops.
v2: agd5f: clean up, add module parameter
Signed-off-by: Dave Airlie airlied@redhat.com Signed-off-by: Alex Deucher alexander.deucher@amd.com
drivers/gpu/drm/radeon/radeon.h | 8 +- drivers/gpu/drm/radeon/radeon_atpx_handler.c | 4 + drivers/gpu/drm/radeon/radeon_connectors.c | 63 ++++++++++++-- drivers/gpu/drm/radeon/radeon_device.c | 52 +++++++++--- drivers/gpu/drm/radeon/radeon_display.c | 47 ++++++++++- drivers/gpu/drm/radeon/radeon_drv.c | 122 +++++++++++++++++++++++++-- drivers/gpu/drm/radeon/radeon_drv.h | 3 + drivers/gpu/drm/radeon/radeon_ioc32.c | 2 +- drivers/gpu/drm/radeon/radeon_irq_kms.c | 8 +- drivers/gpu/drm/radeon/radeon_kms.c | 26 +++++- 10 files changed, 299 insertions(+), 36 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 986100a..ad54525 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -98,6 +98,7 @@ extern int radeon_lockup_timeout; extern int radeon_fastfb; extern int radeon_dpm; extern int radeon_aspm; +extern int radeon_runtime_pm;
/*
- Copy from radeon_drv.h so we don't have to include both and have
conflicting @@ -2212,6 +2213,9 @@ struct radeon_device { /* clock, powergating flags */ u32 cg_flags; u32 pg_flags;
struct dev_pm_domain vga_pm_domain;
bool have_disp_power_ref;
};
int radeon_device_init(struct radeon_device *rdev, @@ -2673,8 +2677,8 @@ extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain); extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo); extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base); extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); -extern int radeon_resume_kms(struct drm_device *dev, bool resume); -extern int radeon_suspend_kms(struct drm_device *dev, bool suspend); +extern int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); +extern int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon); extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size); extern void radeon_program_register_sequence(struct radeon_device *rdev, const u32 *registers, diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index d96070b..6153ec1 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -59,6 +59,10 @@ struct atpx_mux { u16 mux; } __packed;
+bool radeon_is_px(void) {
return radeon_atpx_priv.atpx_detected;
+}
/**
- radeon_atpx_call - call an ATPX method
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 79159b5..5855b5b 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -31,6 +31,8 @@ #include "radeon.h" #include "atom.h"
+#include <linux/pm_runtime.h>
extern void radeon_combios_connected_scratch_regs(struct drm_connector *connector, struct drm_encoder *encoder, @@ -626,6 +628,11 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct drm_encoder *encoder = radeon_best_single_encoder(connector); enum drm_connector_status ret = connector_status_disconnected;
int r;
r = pm_runtime_get_sync(connector->dev->dev);
if (r < 0)
return connector_status_disconnected; if (encoder) { struct radeon_encoder *radeon_encoder =
to_radeon_encoder(encoder); @@ -651,6 +658,8 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) /* check acpi lid status ??? */
radeon_connector_update_scratch_regs(connector, ret);
pm_runtime_mark_last_busy(connector->dev->dev);
pm_runtime_put_autosuspend(connector->dev->dev); return ret;
}
@@ -750,6 +759,11 @@ radeon_vga_detect(struct drm_connector *connector, bool force) struct drm_encoder_helper_funcs *encoder_funcs; bool dret = false; enum drm_connector_status ret = connector_status_disconnected;
int r;
r = pm_runtime_get_sync(connector->dev->dev);
if (r < 0)
return connector_status_disconnected; encoder = radeon_best_single_encoder(connector); if (!encoder)
@@ -790,9 +804,8 @@ radeon_vga_detect(struct drm_connector *connector, bool force) * detected a monitor via load. */ if (radeon_connector->detected_by_load)
return connector->status;
else
return ret;
ret = connector->status;
goto out; } if (radeon_connector->dac_load_detect && encoder) {
@@ -817,6 +830,11 @@ radeon_vga_detect(struct drm_connector *connector, bool force) }
radeon_connector_update_scratch_regs(connector, ret);
+out:
pm_runtime_mark_last_busy(connector->dev->dev);
pm_runtime_put_autosuspend(connector->dev->dev);
return ret;
}
@@ -873,10 +891,15 @@ radeon_tv_detect(struct drm_connector *connector, bool force) struct drm_encoder_helper_funcs *encoder_funcs; struct radeon_connector *radeon_connector = to_radeon_connector(connector); enum drm_connector_status ret = connector_status_disconnected;
int r; if (!radeon_connector->dac_load_detect) return ret;
r = pm_runtime_get_sync(connector->dev->dev);
if (r < 0)
return connector_status_disconnected;
encoder = radeon_best_single_encoder(connector); if (!encoder) ret = connector_status_disconnected;
@@ -887,6 +910,8 @@ radeon_tv_detect(struct drm_connector *connector, bool force) if (ret == connector_status_connected) ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false); radeon_connector_update_scratch_regs(connector, ret);
pm_runtime_mark_last_busy(connector->dev->dev);
pm_runtime_put_autosuspend(connector->dev->dev); return ret;
}
@@ -954,12 +979,18 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) struct drm_encoder *encoder = NULL; struct drm_encoder_helper_funcs *encoder_funcs; struct drm_mode_object *obj;
int i;
int i, r; enum drm_connector_status ret = connector_status_disconnected; bool dret = false, broken_edid = false;
if (!force && radeon_check_hpd_status_unchanged(connector))
return connector->status;
r = pm_runtime_get_sync(connector->dev->dev);
if (r < 0)
return connector_status_disconnected;
if (!force && radeon_check_hpd_status_unchanged(connector)) {
ret = connector->status;
goto exit;
} if (radeon_connector->ddc_bus) dret = radeon_ddc_probe(radeon_connector, false);
@@ -1110,6 +1141,11 @@ out:
/* updated in get modes as well since we need to know if it's
analog or digital */ radeon_connector_update_scratch_regs(connector, ret);
+exit:
pm_runtime_mark_last_busy(connector->dev->dev);
pm_runtime_put_autosuspend(connector->dev->dev);
return ret;
}
@@ -1377,9 +1413,16 @@ radeon_dp_detect(struct drm_connector *connector, bool force) enum drm_connector_status ret = connector_status_disconnected; struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; struct drm_encoder *encoder = radeon_best_single_encoder(connector);
int r;
if (!force && radeon_check_hpd_status_unchanged(connector))
return connector->status;
r = pm_runtime_get_sync(connector->dev->dev);
if (r < 0)
return connector_status_disconnected;
if (!force && radeon_check_hpd_status_unchanged(connector)) {
ret = connector->status;
goto out;
} if (radeon_connector->edid) { kfree(radeon_connector->edid);
@@ -1443,6 +1486,10 @@ radeon_dp_detect(struct drm_connector *connector, bool force) }
radeon_connector_update_scratch_regs(connector, ret);
+out:
pm_runtime_mark_last_busy(connector->dev->dev);
pm_runtime_put_autosuspend(connector->dev->dev);
return ret;
}
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 37cfcee..b9b9dfd 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -101,6 +101,12 @@ static const char radeon_family_name[][16] = { "LAST", };
+#if defined(CONFIG_VGA_SWITCHEROO) +bool radeon_is_px(void); +#else +static inline bool radeon_is_px(void) { return false; } +#endif
/**
- radeon_program_register_sequence - program an array of registers.
@@ -1076,6 +1082,10 @@ static bool radeon_switcheroo_quirk_long_wakeup(struct pci_dev *pdev) static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) { struct drm_device *dev = pci_get_drvdata(pdev);
if (radeon_is_px() && state == VGA_SWITCHEROO_OFF)
return;
if (state == VGA_SWITCHEROO_ON) { unsigned d3_delay = dev->pdev->d3_delay;
@@ -1086,7 +1096,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero if (d3_delay < 20 && radeon_switcheroo_quirk_long_wakeup(pdev)) dev->pdev->d3_delay = 20;
radeon_resume_kms(dev, 1);
radeon_resume_kms(dev, true, true); dev->pdev->d3_delay = d3_delay;
@@ -1096,7 +1106,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero printk(KERN_INFO "radeon: switched off\n"); drm_kms_helper_poll_disable(dev); dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
radeon_suspend_kms(dev, 1);
radeon_suspend_kms(dev, true, true); dev->switch_power_state = DRM_SWITCH_POWER_OFF; }
} @@ -1146,6 +1156,7 @@ int radeon_device_init(struct radeon_device *rdev, { int r, i; int dma_bits;
bool runtime = false; rdev->shutdown = false; rdev->dev = &pdev->dev;
@@ -1292,7 +1303,14 @@ 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);
if (radeon_runtime_pm == 1)
runtime = true;
if ((radeon_runtime_pm == -1) && radeon_is_px())
runtime = true;
vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops,
runtime);
if (runtime)
vga_switcheroo_init_domain_pm_ops(rdev->dev,
&rdev->vga_pm_domain);
r = radeon_init(rdev); if (r)
@@ -1373,7 +1391,7 @@ void radeon_device_fini(struct radeon_device *rdev)
- Returns 0 for success or an error on failure.
- Called at driver suspend.
*/ -int radeon_suspend_kms(struct drm_device *dev, bool suspend) +int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon) { struct radeon_device *rdev; struct drm_crtc *crtc; @@ -1448,9 +1466,12 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend) pci_disable_device(dev->pdev); pci_set_power_state(dev->pdev, PCI_D3hot); }
console_lock();
radeon_fbdev_set_suspend(rdev, 1);
console_unlock();
if (fbcon) {
console_lock();
radeon_fbdev_set_suspend(rdev, 1);
console_unlock();
} return 0;
}
@@ -1463,7 +1484,7 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend)
- Returns 0 for success or an error on failure.
- Called at driver resume.
*/ -int radeon_resume_kms(struct drm_device *dev, bool resume) +int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon) { struct drm_connector *connector; struct radeon_device *rdev = dev->dev_private; @@ -1472,12 +1493,15 @@ int radeon_resume_kms(struct drm_device *dev, bool resume) if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0;
console_lock();
if (fbcon) {
console_lock();
} if (resume) { pci_set_power_state(dev->pdev, PCI_D0); pci_restore_state(dev->pdev); if (pci_enable_device(dev->pdev)) {
console_unlock();
if (fbcon)
console_unlock(); return -1; } }
@@ -1492,9 +1516,11 @@ int radeon_resume_kms(struct drm_device *dev, bool resume) radeon_pm_resume(rdev); radeon_restore_bios_scratch_regs(rdev);
radeon_fbdev_set_suspend(rdev, 0);
console_unlock();
if (fbcon) {
radeon_fbdev_set_suspend(rdev, 0);
console_unlock();
}
/* init dig PHYs, disp eng pll */ if (rdev->is_atom_bios) { radeon_atom_encoder_init(rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 0d1aa05..bc37e33 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -30,6 +30,7 @@ #include "atom.h" #include <asm/div64.h>
+#include <linux/pm_runtime.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_edid.h>
@@ -494,11 +495,55 @@ unlock_free: return r; }
+static int +radeon_crtc_set_config(struct drm_mode_set *set) +{
struct drm_device *dev;
struct radeon_device *rdev;
struct drm_crtc *crtc;
bool active = false;
int ret;
if (!set || !set->crtc)
return -EINVAL;
dev = set->crtc->dev;
ret = pm_runtime_get_sync(dev->dev);
if (ret < 0)
return ret;
ret = drm_crtc_helper_set_config(set);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
if (crtc->enabled)
active = true;
pm_runtime_mark_last_busy(dev->dev);
rdev = dev->dev_private;
/* if we have active crtcs and we don't have a power ref,
take the current one */
if (active && !rdev->have_disp_power_ref) {
rdev->have_disp_power_ref = true;
return ret;
}
/* if we have no active crtcs, then drop the power ref
we got before */
if (!active && rdev->have_disp_power_ref) {
pm_runtime_put_autosuspend(dev->dev);
rdev->have_disp_power_ref = false;
}
/* drop the power reference we got coming in here */
pm_runtime_put_autosuspend(dev->dev);
return ret;
+} static const struct drm_crtc_funcs radeon_crtc_funcs = { .cursor_set = radeon_crtc_cursor_set, .cursor_move = radeon_crtc_cursor_move, .gamma_set = radeon_crtc_gamma_set,
.set_config = drm_crtc_helper_set_config,
.set_config = radeon_crtc_set_config, .destroy = radeon_crtc_destroy, .page_flip = radeon_crtc_page_flip,
}; diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 788bfb0..427c64f 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -36,8 +36,9 @@ #include <drm/drm_pciids.h> #include <linux/console.h> #include <linux/module.h>
+#include <linux/pm_runtime.h> +#include <linux/vga_switcheroo.h> +#include "drm_crtc_helper.h" /*
- KMS wrapper.
- 2.0.0 - initial interface
@@ -87,8 +88,8 @@ void radeon_driver_postclose_kms(struct drm_device *dev, struct drm_file *file_priv); void radeon_driver_preclose_kms(struct drm_device *dev, struct drm_file *file_priv); -int radeon_suspend_kms(struct drm_device *dev, bool suspend); -int radeon_resume_kms(struct drm_device *dev, bool resume); +int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon); +int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc); int radeon_enable_vblank_kms(struct drm_device *dev, int crtc); void radeon_disable_vblank_kms(struct drm_device *dev, int crtc); @@ -137,9 +138,11 @@ void radeon_debugfs_cleanup(struct drm_minor *minor); #if defined(CONFIG_VGA_SWITCHEROO) void radeon_register_atpx_handler(void); void radeon_unregister_atpx_handler(void); +bool radeon_is_px(void); #else static inline void radeon_register_atpx_handler(void) {} static inline void radeon_unregister_atpx_handler(void) {} +static inline bool radeon_is_px(void) { return false; } #endif
int radeon_no_wb; @@ -162,6 +165,7 @@ int radeon_lockup_timeout = 10000; int radeon_fastfb = 0; int radeon_dpm = -1; int radeon_aspm = -1; +int radeon_runtime_pm = -1;
MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); module_param_named(no_wb, radeon_no_wb, int, 0444); @@ -223,6 +227,9 @@ module_param_named(dpm, radeon_dpm, int, 0444); MODULE_PARM_DESC(aspm, "ASPM support (1 = enable, 0 = disable, -1 = auto)"); module_param_named(aspm, radeon_aspm, int, 0444);
+MODULE_PARM_DESC(runpm, "PX runtime pm (1 = force enable, 0 = disable, -1 = PX only default)"); +module_param_named(runpm, radeon_runtime_pm, int, 0444);
static struct pci_device_id pciidlist[] = { radeon_PCI_IDS }; @@ -259,6 +266,7 @@ static int radeon_resume(struct drm_device *dev) return 0; }
static const struct file_operations radeon_driver_old_fops = { .owner = THIS_MODULE, .open = drm_open, @@ -357,28 +365,121 @@ static int radeon_pmops_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev);
return radeon_suspend_kms(drm_dev, 1);
return radeon_suspend_kms(drm_dev, true, true);
}
static int radeon_pmops_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev);
return radeon_resume_kms(drm_dev, 1);
return radeon_resume_kms(drm_dev, true, true);
}
static int radeon_pmops_freeze(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev);
return radeon_suspend_kms(drm_dev, 0);
return radeon_suspend_kms(drm_dev, false, true);
}
static int radeon_pmops_thaw(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev);
return radeon_resume_kms(drm_dev, 0);
return radeon_resume_kms(drm_dev, false, true);
+}
+static int radeon_pmops_runtime_suspend(struct device *dev) +{
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev);
int ret;
if (radeon_runtime_pm == 0)
return -EINVAL;
drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
drm_kms_helper_poll_disable(drm_dev);
vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF);
ret = radeon_suspend_kms(drm_dev, false, false);
pci_save_state(pdev);
pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3cold);
drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF;
return 0;
+}
+static int radeon_pmops_runtime_resume(struct device *dev) +{
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev);
int ret;
if (radeon_runtime_pm == 0)
return -EINVAL;
drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
ret = pci_enable_device(pdev);
if (ret)
return ret;
pci_set_master(pdev);
ret = radeon_resume_kms(drm_dev, false, false);
drm_kms_helper_poll_enable(drm_dev);
vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON);
drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
return 0;
+}
+static int radeon_pmops_runtime_idle(struct device *dev) +{
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev);
struct drm_crtc *crtc;
if (radeon_runtime_pm == 0)
return -EBUSY;
/* are we PX enabled? */
if (radeon_runtime_pm == -1 && !radeon_is_px()) {
DRM_DEBUG_DRIVER("failing to power off - not px\n");
return -EBUSY;
}
list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) {
if (crtc->enabled) {
DRM_DEBUG_DRIVER("failing to power off - crtc
active\n");
return -EBUSY;
}
}
pm_runtime_mark_last_busy(dev);
pm_runtime_autosuspend(dev);
/* we don't want the main rpm_idle to call suspend - we want to
autosuspend */
return 1;
+}
+long radeon_drm_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg)
+{
struct drm_file *file_priv = filp->private_data;
struct drm_device *dev;
long ret;
dev = file_priv->minor->dev;
ret = pm_runtime_get_sync(dev->dev);
if (ret < 0)
return ret;
ret = drm_ioctl(filp, cmd, arg);
pm_runtime_mark_last_busy(dev->dev);
pm_runtime_put_autosuspend(dev->dev);
return ret;
}
static const struct dev_pm_ops radeon_pm_ops = { @@ -388,13 +489,16 @@ static const struct dev_pm_ops radeon_pm_ops = { .thaw = radeon_pmops_thaw, .poweroff = radeon_pmops_freeze, .restore = radeon_pmops_resume,
.runtime_suspend = radeon_pmops_runtime_suspend,
.runtime_resume = radeon_pmops_runtime_resume,
.runtime_idle = radeon_pmops_runtime_idle,
};
static const struct file_operations radeon_driver_kms_fops = { .owner = THIS_MODULE, .open = drm_open, .release = drm_release,
.unlocked_ioctl = drm_ioctl,
.unlocked_ioctl = radeon_drm_ioctl, .mmap = radeon_mmap, .poll = drm_poll, .read = drm_read,
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index b369d42..543dcfa 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h @@ -113,6 +113,9 @@ #define DRIVER_MINOR 33 #define DRIVER_PATCHLEVEL 0
+long radeon_drm_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg);
/* The rest of the file is DEPRECATED! */ #ifdef CONFIG_DRM_RADEON_UMS
diff --git a/drivers/gpu/drm/radeon/radeon_ioc32.c b/drivers/gpu/drm/radeon/radeon_ioc32.c index c180df8..bdb0f93 100644 --- a/drivers/gpu/drm/radeon/radeon_ioc32.c +++ b/drivers/gpu/drm/radeon/radeon_ioc32.c @@ -418,7 +418,7 @@ long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long if (nr < DRM_COMMAND_BASE) return drm_compat_ioctl(filp, cmd, arg);
ret = drm_ioctl(filp, cmd, arg);
ret = radeon_drm_ioctl(filp, cmd, arg); return ret;
} diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index cc9e848..ec6240b 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -32,6 +32,8 @@ #include "radeon.h" #include "atom.h"
+#include <linux/pm_runtime.h>
#define RADEON_WAIT_IDLE_TIMEOUT 200
/** @@ -47,8 +49,12 @@ irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; struct radeon_device *rdev = dev->dev_private;
irqreturn_t ret;
return radeon_irq_process(rdev);
ret = radeon_irq_process(rdev);
if (ret == IRQ_HANDLED)
pm_runtime_mark_last_busy(dev->dev);
return ret;
}
/* diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 61580dd..bffff51 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -32,7 +32,7 @@
#include <linux/vga_switcheroo.h> #include <linux/slab.h>
+#include <linux/pm_runtime.h> /**
- radeon_driver_unload_kms - Main unload function for KMS.
@@ -50,9 +50,14 @@ int radeon_driver_unload_kms(struct drm_device *dev)
if (rdev == NULL) return 0;
if (rdev->rmmio == NULL) goto done_free;
pm_runtime_get_sync(dev->dev);
radeon_acpi_fini(rdev);
radeon_modeset_fini(rdev); radeon_device_fini(rdev);
@@ -125,9 +130,20 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) "Error during ACPI methods call\n"); }
if (radeon_runtime_pm != 0) {
pm_runtime_use_autosuspend(dev->dev);
pm_runtime_set_autosuspend_delay(dev->dev, 5000);
pm_runtime_set_active(dev->dev);
pm_runtime_allow(dev->dev);
pm_runtime_mark_last_busy(dev->dev);
pm_runtime_put_autosuspend(dev->dev);
}
out: if (r) radeon_driver_unload_kms(dev);
return r;
}
@@ -475,9 +491,14 @@ void radeon_driver_lastclose_kms(struct drm_device *dev) int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) { struct radeon_device *rdev = dev->dev_private;
int r; file_priv->driver_priv = NULL;
r = pm_runtime_get_sync(dev->dev);
if (r < 0)
return r;
/* new gpu have virtual address space support */ if (rdev->family >= CHIP_CAYMAN) { struct radeon_fpriv *fpriv;
@@ -506,6 +527,9 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
file_priv->driver_priv = fpriv; }
pm_runtime_mark_last_busy(dev->dev);
pm_runtime_put_autosuspend(dev->dev); return 0;
}
-- 1.8.3.1
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel