summaryrefslogtreecommitdiff
path: root/sys/dev/pci/drm/radeon/radeon_irq_kms.c
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2019-04-14 10:14:55 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2019-04-14 10:14:55 +0000
commit9f7b0921603520095dd22535e96859917ee7ed2a (patch)
tree97b1df96a36c7959c2dd1bd53d7769ac0b604927 /sys/dev/pci/drm/radeon/radeon_irq_kms.c
parent1385ee84a74b2316b691d76fe5282b8aa4568a0a (diff)
Update shared drm code, inteldrm(4) and radeondrm(4) from linux 4.4 to
linux 4.19.34. Adds support for more Intel hardware: Broxton/Apollo Lake (was is_preliminary in 4.4) Amber Lake (another Kaby Lake refresh) Gemini Lake Coffee Lake Whiskey Lake Cannon Lake (though no hardware with Intel graphics ever shipped) Ice Lake (alpha support, hardware not released) This does not add support for new radeon hardware on the AMD side as newer radeons have a different kernel driver (amdgpu). Thanks to the OpenBSD Foundation for sponsoring this work, kettenis@ for helping and a bunch of other developers for testing.
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);
+ }
+}