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

Commit 1d98b916 authored by Rongrong Zou's avatar Rongrong Zou
Browse files

drm/hisilicon/hibmc: Add support for vblank interrupt



Add vblank interrupt.

Signed-off-by: default avatarRongrong Zou <zourongrong@gmail.com>
Reviewed-by: default avatarSean Paul <seanpaul@chromium.org>
Reviewed-by: default avatarXinliang Liu <xinliang.liu@linaro.org>
Acked-by: default avatarSean Paul <seanpaul@chromium.org>
parent 5294967f
Loading
Loading
Loading
Loading
+55 −1
Original line number Diff line number Diff line
@@ -39,16 +39,45 @@ static const struct file_operations hibmc_fops = {

static int hibmc_enable_vblank(struct drm_device *dev, unsigned int pipe)
{
	struct hibmc_drm_private *priv =
		(struct hibmc_drm_private *)dev->dev_private;

	writel(HIBMC_RAW_INTERRUPT_EN_VBLANK(1),
	       priv->mmio + HIBMC_RAW_INTERRUPT_EN);

	return 0;
}

static void hibmc_disable_vblank(struct drm_device *dev, unsigned int pipe)
{
	struct hibmc_drm_private *priv =
		(struct hibmc_drm_private *)dev->dev_private;

	writel(HIBMC_RAW_INTERRUPT_EN_VBLANK(0),
	       priv->mmio + HIBMC_RAW_INTERRUPT_EN);
}

irqreturn_t hibmc_drm_interrupt(int irq, void *arg)
{
	struct drm_device *dev = (struct drm_device *)arg;
	struct hibmc_drm_private *priv =
		(struct hibmc_drm_private *)dev->dev_private;
	u32 status;

	status = readl(priv->mmio + HIBMC_RAW_INTERRUPT);

	if (status & HIBMC_RAW_INTERRUPT_VBLANK(1)) {
		writel(HIBMC_RAW_INTERRUPT_VBLANK(1),
		       priv->mmio + HIBMC_RAW_INTERRUPT);
		drm_handle_vblank(dev, 0);
	}

	return IRQ_HANDLED;
}

static struct drm_driver hibmc_driver = {
	.driver_features	= DRIVER_GEM | DRIVER_MODESET |
				  DRIVER_ATOMIC,
				  DRIVER_ATOMIC | DRIVER_HAVE_IRQ,
	.fops			= &hibmc_fops,
	.name			= "hibmc",
	.date			= "20160828",
@@ -62,6 +91,7 @@ static struct drm_driver hibmc_driver = {
	.dumb_create            = hibmc_dumb_create,
	.dumb_map_offset        = hibmc_dumb_mmap_offset,
	.dumb_destroy           = drm_gem_dumb_destroy,
	.irq_handler		= hibmc_drm_interrupt,
};

static int hibmc_pm_suspend(struct device *dev)
@@ -268,6 +298,13 @@ static int hibmc_unload(struct drm_device *dev)
	struct hibmc_drm_private *priv = dev->dev_private;

	hibmc_fbdev_fini(priv);

	if (dev->irq_enabled)
		drm_irq_uninstall(dev);
	if (priv->msi_enabled)
		pci_disable_msi(dev->pdev);
	drm_vblank_cleanup(dev);

	hibmc_kms_fini(priv);
	hibmc_mm_fini(priv);
	dev->dev_private = NULL;
@@ -299,6 +336,23 @@ static int hibmc_load(struct drm_device *dev)
	if (ret)
		goto err;

	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
	if (ret) {
		DRM_ERROR("failed to initialize vblank: %d\n", ret);
		goto err;
	}

	priv->msi_enabled = 0;
	ret = pci_enable_msi(dev->pdev);
	if (ret) {
		DRM_WARN("enabling MSI failed: %d\n", ret);
	} else {
		priv->msi_enabled = 1;
		ret = drm_irq_install(dev, dev->pdev->irq);
		if (ret)
			DRM_WARN("install irq failed: %d\n", ret);
	}

	/* reset all the states of crtc/plane/encoder/connector */
	drm_mode_config_reset(dev);

+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ struct hibmc_drm_private {
	void __iomem   *fb_map;
	unsigned long  fb_base;
	unsigned long  fb_size;
	bool msi_enabled;

	/* drm */
	struct drm_device  *dev;