summaryrefslogtreecommitdiff
path: root/sys/dev/pci/drm/radeon/radeon_irq_kms.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci/drm/radeon/radeon_irq_kms.c')
-rw-r--r--sys/dev/pci/drm/radeon/radeon_irq_kms.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/sys/dev/pci/drm/radeon/radeon_irq_kms.c b/sys/dev/pci/drm/radeon/radeon_irq_kms.c
index f75204ddb25..fb8f85124ce 100644
--- a/sys/dev/pci/drm/radeon/radeon_irq_kms.c
+++ b/sys/dev/pci/drm/radeon/radeon_irq_kms.c
@@ -25,13 +25,14 @@
* Alex Deucher
* Jerome Glisse
*/
-#include <dev/pci/drm/drmP.h>
-#include <dev/pci/drm/drm_crtc_helper.h>
-#include <dev/pci/drm/radeon_drm.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/radeon_drm.h>
#include "radeon_reg.h"
#include "radeon.h"
#include "atom.h"
+#include <linux/pm_runtime.h>
#define RADEON_WAIT_IDLE_TIMEOUT 200
@@ -87,10 +88,8 @@ static void radeon_hotplug_work_func(struct work_struct *work)
return;
mutex_lock(&mode_config->mutex);
- if (mode_config->num_connector) {
- list_for_each_entry(connector, &mode_config->connector_list, head)
- radeon_connector_hotplug(connector);
- }
+ list_for_each_entry(connector, &mode_config->connector_list, head)
+ radeon_connector_hotplug(connector);
mutex_unlock(&mode_config->mutex);
/* Just fire off a uevent and let userspace tell us what to do */
drm_helper_hpd_irq_event(dev);
@@ -105,10 +104,8 @@ static void radeon_dp_work_func(struct work_struct *work)
struct drm_connector *connector;
/* this should take a mutex */
- if (mode_config->num_connector) {
- list_for_each_entry(connector, &mode_config->connector_list, head)
- radeon_connector_hotplug(connector);
- }
+ list_for_each_entry(connector, &mode_config->connector_list, head)
+ radeon_connector_hotplug(connector);
}
/**
* radeon_driver_irq_preinstall_kms - drm irq preinstall callback
@@ -219,12 +216,10 @@ bool radeon_msi_ok(struct radeon_device *rdev)
* of address for "64-bit" MSIs which breaks on some platforms, notably
* IBM POWER servers, so we limit them
*/
-#ifdef notyet
if (rdev->family < CHIP_BONAIRE) {
dev_info(rdev->dev, "radeon: MSI limited to 32-bit\n");
rdev->pdev->no_64bit_msi = 1;
}
-#endif
/* force MSI on */
if (radeon_msi == 1)
@@ -291,10 +286,15 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
int r = 0;
mtx_init(&rdev->irq.lock, IPL_TTY);
+
+ /* Disable vblank irqs aggressively for power-saving */
+ rdev->ddev->vblank_disable_immediate = true;
+
r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
if (r) {
return r;
}
+
#ifdef notyet
/* enable msi */
rdev->msi_enabled = 0;
@@ -333,7 +333,6 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
*/
void radeon_irq_kms_fini(struct radeon_device *rdev)
{
- drm_vblank_cleanup(rdev->ddev);
if (rdev->irq.installed) {
drm_irq_uninstall(rdev->ddev);
rdev->irq.installed = false;
@@ -547,3 +546,38 @@ void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask)
spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
}
+/**
+ * radeon_irq_kms_update_int_n - helper for updating interrupt enable registers
+ *
+ * @rdev: radeon device pointer
+ * @reg: the register to write to enable/disable interrupts
+ * @mask: the mask that enables the interrupts
+ * @enable: whether to enable or disable the interrupt register
+ * @name: the name of the interrupt register to print to the kernel log
+ * @num: the number of the interrupt register to print to the kernel log
+ *
+ * Helper for updating the enable state of interrupt registers. Checks whether
+ * or not the interrupt matches the enable state we want. If it doesn't, then
+ * we update it and print a debugging message to the kernel log indicating the
+ * new state of the interrupt register.
+ *
+ * Used for updating sequences of interrupts registers like HPD1, HPD2, etc.
+ */
+void radeon_irq_kms_set_irq_n_enabled(struct radeon_device *rdev,
+ u32 reg, u32 mask,
+ bool enable, const char *name, unsigned n)
+{
+ u32 tmp = RREG32(reg);
+
+ /* Interrupt state didn't change */
+ if (!!(tmp & mask) == enable)
+ return;
+
+ if (enable) {
+ DRM_DEBUG("%s%d interrupts enabled\n", name, n);
+ WREG32(reg, tmp |= mask);
+ } else {
+ DRM_DEBUG("%s%d interrupts disabled\n", name, n);
+ WREG32(reg, tmp & ~mask);
+ }
+}