Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fbf81762 authored by Dave Airlie's avatar Dave Airlie
Browse files

drm/kms: disable/enable poll around switcheroo on/off



Because we aren't in a suspend state the poll will still run when we have switcherooed a card off.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent fc5ea29d
Loading
Loading
Loading
Loading
+22 −6
Original line number Original line Diff line number Diff line
@@ -860,19 +860,24 @@ static void output_poll_execute(struct slow_work *work)
	}
	}
}
}


void drm_kms_helper_poll_init(struct drm_device *dev)
void drm_kms_helper_poll_disable(struct drm_device *dev)
{
	if (!dev->mode_config.poll_enabled)
		return;
	delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work);
}
EXPORT_SYMBOL(drm_kms_helper_poll_disable);

void drm_kms_helper_poll_enable(struct drm_device *dev)
{
{
	struct drm_connector *connector;
	bool poll = false;
	bool poll = false;
	struct drm_connector *connector;
	int ret;
	int ret;


	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
		if (connector->polled)
		if (connector->polled)
			poll = true;
			poll = true;
	}
	}
	slow_work_register_user(THIS_MODULE);
	delayed_slow_work_init(&dev->mode_config.output_poll_slow_work,
			       &output_poll_ops);


	if (poll) {
	if (poll) {
		ret = delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, DRM_OUTPUT_POLL_PERIOD);
		ret = delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, DRM_OUTPUT_POLL_PERIOD);
@@ -880,11 +885,22 @@ void drm_kms_helper_poll_init(struct drm_device *dev)
			DRM_ERROR("delayed enqueue failed %d\n", ret);
			DRM_ERROR("delayed enqueue failed %d\n", ret);
	}
	}
}
}
EXPORT_SYMBOL(drm_kms_helper_poll_enable);

void drm_kms_helper_poll_init(struct drm_device *dev)
{
	slow_work_register_user(THIS_MODULE);
	delayed_slow_work_init(&dev->mode_config.output_poll_slow_work,
			       &output_poll_ops);
	dev->mode_config.poll_enabled = true;

	drm_kms_helper_poll_enable(dev);
}
EXPORT_SYMBOL(drm_kms_helper_poll_init);
EXPORT_SYMBOL(drm_kms_helper_poll_init);


void drm_kms_helper_poll_fini(struct drm_device *dev)
void drm_kms_helper_poll_fini(struct drm_device *dev)
{
{
	delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work);
	drm_kms_helper_poll_disable(dev);
	slow_work_unregister_user(THIS_MODULE);
	slow_work_unregister_user(THIS_MODULE);
}
}
EXPORT_SYMBOL(drm_kms_helper_poll_fini);
EXPORT_SYMBOL(drm_kms_helper_poll_fini);
+3 −1
Original line number Original line Diff line number Diff line
@@ -1399,12 +1399,14 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_
	struct drm_device *dev = pci_get_drvdata(pdev);
	struct drm_device *dev = pci_get_drvdata(pdev);
	pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
	pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
	if (state == VGA_SWITCHEROO_ON) {
	if (state == VGA_SWITCHEROO_ON) {
		printk(KERN_INFO "i915: switched off\n");
		printk(KERN_INFO "i915: switched on\n");
		/* i915 resume handler doesn't set to D0 */
		/* i915 resume handler doesn't set to D0 */
		pci_set_power_state(dev->pdev, PCI_D0);
		pci_set_power_state(dev->pdev, PCI_D0);
		i915_resume(dev);
		i915_resume(dev);
		drm_kms_helper_poll_enable(dev);
	} else {
	} else {
		printk(KERN_ERR "i915: switched off\n");
		printk(KERN_ERR "i915: switched off\n");
		drm_kms_helper_poll_disable(dev);
		i915_suspend(dev, pmm);
		i915_suspend(dev, pmm);
	}
	}
}
}
+3 −0
Original line number Original line Diff line number Diff line
@@ -376,12 +376,15 @@ nouveau_card_init_channel(struct drm_device *dev)
static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
					 enum vga_switcheroo_state state)
					 enum vga_switcheroo_state state)
{
{
	struct drm_device *dev = pci_get_drvdata(pdev);
	pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
	pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
	if (state == VGA_SWITCHEROO_ON) {
	if (state == VGA_SWITCHEROO_ON) {
		printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
		printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
		nouveau_pci_resume(pdev);
		nouveau_pci_resume(pdev);
		drm_kms_helper_poll_enable(dev);
	} else {
	} else {
		printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
		printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
		drm_kms_helper_poll_disable(dev);
		nouveau_pci_suspend(pdev, pmm);
		nouveau_pci_suspend(pdev, pmm);
	}
	}
}
}
+2 −0
Original line number Original line Diff line number Diff line
@@ -546,8 +546,10 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero
		/* don't suspend or resume card normally */
		/* don't suspend or resume card normally */
		rdev->powered_down = false;
		rdev->powered_down = false;
		radeon_resume_kms(dev);
		radeon_resume_kms(dev);
		drm_kms_helper_poll_enable(dev);
	} else {
	} else {
		printk(KERN_INFO "radeon: switched off\n");
		printk(KERN_INFO "radeon: switched off\n");
		drm_kms_helper_poll_disable(dev);
		radeon_suspend_kms(dev, pmm);
		radeon_suspend_kms(dev, pmm);
		/* don't suspend or resume card normally */
		/* don't suspend or resume card normally */
		rdev->powered_down = true;
		rdev->powered_down = true;
+3 −0
Original line number Original line Diff line number Diff line
@@ -130,4 +130,7 @@ extern int drm_helper_resume_force_mode(struct drm_device *dev);
extern void drm_kms_helper_poll_init(struct drm_device *dev);
extern void drm_kms_helper_poll_init(struct drm_device *dev);
extern void drm_kms_helper_poll_fini(struct drm_device *dev);
extern void drm_kms_helper_poll_fini(struct drm_device *dev);
extern void drm_helper_hpd_irq_event(struct drm_device *dev);
extern void drm_helper_hpd_irq_event(struct drm_device *dev);

extern void drm_kms_helper_poll_disable(struct drm_device *dev);
extern void drm_kms_helper_poll_enable(struct drm_device *dev);
#endif
#endif