All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dan Carpenter <dan.carpenter@oracle.com>
To: lichenyang <lichenyang@loongson.cn>
Cc: David Airlie <airlied@linux.ie>,
	Huacai Chen <chenhuacai@kernel.org>,
	linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org,
	devel@linuxdriverproject.org,
	Tiezhu Yang <yangtiezhu@loongson.cn>
Subject: Re: [PATCH v2 3/3] drm/loongson: Add interrupt driver for LS7A
Date: Mon, 19 Jul 2021 12:58:19 +0300	[thread overview]
Message-ID: <20210719095819.GS1931@kadam> (raw)
In-Reply-To: <20210715015809.107821-3-lichenyang@loongson.cn>

On Thu, Jul 15, 2021 at 09:58:09AM +0800, lichenyang wrote:
> Add LS7A DC vsync interrupt enable and close function, and
> register irq_handler function interface.
> Add vbrank event processing flow.
> 
> V2:
> - Remove the useless flags parameter.

Do this in a separate patch.  It is an unrelated cleanup.

> - Added error handling in the loongson_drm_load function.
> 
> Signed-off-by: lichenyang <lichenyang@loongson.cn>
> ---
>  drivers/gpu/drm/loongson/Makefile        |   3 +-
>  drivers/gpu/drm/loongson/loongson_crtc.c |  43 +++++++++-
>  drivers/gpu/drm/loongson/loongson_drv.c  |  22 +++--
>  drivers/gpu/drm/loongson/loongson_drv.h  |  17 +++-
>  drivers/gpu/drm/loongson/loongson_irq.c  | 105 +++++++++++++++++++++++
>  5 files changed, 179 insertions(+), 11 deletions(-)
>  create mode 100644 drivers/gpu/drm/loongson/loongson_irq.c
> 
> diff --git a/drivers/gpu/drm/loongson/Makefile b/drivers/gpu/drm/loongson/Makefile
> index 773b806e99a2..cc50b65c7e03 100644
> --- a/drivers/gpu/drm/loongson/Makefile
> +++ b/drivers/gpu/drm/loongson/Makefile
> @@ -11,5 +11,6 @@ loongson-y := loongson_drv.o \
>  	loongson_device.o \
>  	loongson_connector.o \
>  	loongson_encoder.o \
> -	loongson_i2c.o
> +	loongson_i2c.o \
> +	loongson_irq.o
>  obj-$(CONFIG_DRM_LOONGSON) += loongson.o
> diff --git a/drivers/gpu/drm/loongson/loongson_crtc.c b/drivers/gpu/drm/loongson/loongson_crtc.c
> index 4cb65fa08778..4c62d5b2bd56 100644
> --- a/drivers/gpu/drm/loongson/loongson_crtc.c
> +++ b/drivers/gpu/drm/loongson/loongson_crtc.c
> @@ -154,19 +154,25 @@ static void loongson_crtc_mode_set_nofb(struct drm_crtc *crtc)
>  }
>  
>  static void loongson_crtc_atomic_enable(struct drm_crtc *crtc,
> -					struct drm_atomic_state *old_state)
> +					struct drm_atomic_state *old_crtc_state)
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct loongson_device *ldev = dev->dev_private;
>  	struct loongson_crtc *lcrtc = to_loongson_crtc(crtc);
>  	u32 reg_offset = lcrtc->reg_offset;
>  
> +	if (lcrtc->cfg_reg & CFG_ENABLE)
> +		goto vblank_on;
> +
>  	lcrtc->cfg_reg |= CFG_ENABLE;
>  	ls7a_mm_wreg(ldev, FB_CFG_REG + reg_offset, lcrtc->cfg_reg);
> +
> +vblank_on:
> +	drm_crtc_vblank_on(crtc);
>  }
>  
>  static void loongson_crtc_atomic_disable(struct drm_crtc *crtc,
> -					 struct drm_atomic_state *old_state)
> +					 struct drm_atomic_state *old_crtc_state)
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct loongson_device *ldev = dev->dev_private;
> @@ -175,10 +181,36 @@ static void loongson_crtc_atomic_disable(struct drm_crtc *crtc,
>  
>  	lcrtc->cfg_reg &= ~CFG_ENABLE;
>  	ls7a_mm_wreg(ldev, FB_CFG_REG + reg_offset, lcrtc->cfg_reg);
> +
> +	spin_lock_irq(&crtc->dev->event_lock);
> +	if (crtc->state->event) {
> +		drm_crtc_send_vblank_event(crtc, crtc->state->event);
> +		crtc->state->event = NULL;
> +	}
> +	spin_unlock_irq(&crtc->dev->event_lock);
> +
> +	drm_crtc_vblank_off(crtc);
> +}
> +
> +static void loongson_crtc_atomic_flush(struct drm_crtc *crtc,
> +				       struct drm_crtc_state *old_crtc_state)
> +{
> +	struct drm_pending_vblank_event *event = crtc->state->event;
> +
> +	if (event) {

Flip this around:

	if (!event)
		return;


> +		crtc->state->event = NULL;
> +
> +		spin_lock_irq(&crtc->dev->event_lock);
> +		if (drm_crtc_vblank_get(crtc) == 0)
> +			drm_crtc_arm_vblank_event(crtc, event);
> +		else
> +			drm_crtc_send_vblank_event(crtc, event);
> +		spin_unlock_irq(&crtc->dev->event_lock);
> +	}
>  }
>  
>  static enum drm_mode_status loongson_mode_valid(struct drm_crtc *crtc,
> -						const struct drm_display_mode *mode)
> +		const struct drm_display_mode *mode)
>  {
>  	if (mode->hdisplay > 1920)
>  		return MODE_BAD;
> @@ -194,9 +226,10 @@ static enum drm_mode_status loongson_mode_valid(struct drm_crtc *crtc,
>  
>  static const struct drm_crtc_helper_funcs loongson_crtc_helper_funcs = {
>  	.mode_valid = loongson_mode_valid,
> +	.mode_set_nofb = loongson_crtc_mode_set_nofb,
> +	.atomic_flush = loongson_crtc_atomic_flush,
>  	.atomic_enable = loongson_crtc_atomic_enable,
>  	.atomic_disable = loongson_crtc_atomic_disable,
> -	.mode_set_nofb = loongson_crtc_mode_set_nofb,
>  };
>  
>  static const struct drm_crtc_funcs loongson_crtc_funcs = {
> @@ -206,6 +239,8 @@ static const struct drm_crtc_funcs loongson_crtc_funcs = {
>  	.destroy = drm_crtc_cleanup,
>  	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
>  	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
> +	.enable_vblank = loongson_crtc_enable_vblank,
> +	.disable_vblank = loongson_crtc_disable_vblank,
>  };
>  
>  int loongson_crtc_init(struct loongson_device *ldev, int index)
> diff --git a/drivers/gpu/drm/loongson/loongson_drv.c b/drivers/gpu/drm/loongson/loongson_drv.c
> index 252be9e25aff..13003f6ae062 100644
> --- a/drivers/gpu/drm/loongson/loongson_drv.c
> +++ b/drivers/gpu/drm/loongson/loongson_drv.c
> @@ -24,7 +24,7 @@ static const struct drm_mode_config_funcs loongson_mode_funcs = {
>  	.mode_valid = drm_vram_helper_mode_valid
>  };
>  
> -static int loongson_device_init(struct drm_device *dev, uint32_t flags)
> +static int loongson_device_init(struct drm_device *dev)
>  {
>  	struct loongson_device *ldev = dev->dev_private;
>  	struct pci_dev *gpu_pdev;
> @@ -131,7 +131,7 @@ int loongson_modeset_init(struct loongson_device *ldev)
>  	return 0;
>  }
>  
> -static int loongson_drm_load(struct drm_device *dev, unsigned long flags)
> +static int loongson_drm_load(struct drm_device *dev)
>  {
>  	struct loongson_device *ldev;
>  	int ret;
> @@ -143,7 +143,7 @@ static int loongson_drm_load(struct drm_device *dev, unsigned long flags)
>  	dev->dev_private = ldev;
>  	ldev->dev = dev;
>  
> -	ret = loongson_device_init(dev, flags);
> +	ret = loongson_device_init(dev);
>  	if (ret)
>  		goto err;
>  
> @@ -164,8 +164,16 @@ static int loongson_drm_load(struct drm_device *dev, unsigned long flags)
>  	pci_set_drvdata(dev->pdev, dev);
>  
>  	ret = loongson_modeset_init(ldev);
> -	if (ret)
> +	if (ret) {
>  		dev_err(dev->dev, "Fatal error during modeset init: %d\n", ret);
> +		goto err;
> +	}
> +
> +	ret = loongson_irq_init(ldev);
> +	if (ret) {
> +		dev_err(dev->dev, "Fatal error during irq init: %d\n", ret);
> +		goto err;
> +	}
>  
>  	drm_kms_helper_poll_init(dev);
>  	drm_mode_config_reset(dev);
> @@ -192,6 +200,10 @@ static struct drm_driver loongson_drm_driver = {
>  	.fops = &fops,
>  	DRM_GEM_VRAM_DRIVER,
>  
> +	.irq_handler = loongson_irq_handler,
> +	.irq_preinstall = loongson_irq_preinstall,
> +	.irq_uninstall = loongson_irq_uninstall,
> +
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
>  	.date = DRIVER_DATE,
> @@ -221,7 +233,7 @@ static int loongson_pci_probe(struct pci_dev *pdev,
>  		goto err_free;
>  	}
>  
> -	ret = loongson_drm_load(dev, 0x0);
> +	ret = loongson_drm_load(dev);
>  	if (ret) {
>  		drm_err(dev, "failed to load loongson: %d\n", ret);
>  		goto err_pdev;
> diff --git a/drivers/gpu/drm/loongson/loongson_drv.h b/drivers/gpu/drm/loongson/loongson_drv.h
> index 24a534c3c79c..60f5bd48f7f2 100644
> --- a/drivers/gpu/drm/loongson/loongson_drv.h
> +++ b/drivers/gpu/drm/loongson/loongson_drv.h
> @@ -4,9 +4,11 @@
>  #define __LOONGSON_DRV_H__
>  
>  #include <drm/drm_drv.h>
> +#include <drm/drm_fourcc.h>
> +#include <drm/drm_vblank.h>
>  #include <drm/drm_gem.h>
> +#include <drm/drm_irq.h>
>  #include <drm/drm_fb_helper.h>
> -#include <drm/drm_fourcc.h>
>  #include <drm/drm_probe_helper.h>
>  #include <drm/drm_atomic.h>
>  #include <drm/drm_atomic_helper.h>
> @@ -49,6 +51,7 @@
>  #define FB_HSYNC_REG (0x1420)
>  #define FB_VDISPLAY_REG (0x1480)
>  #define FB_VSYNC_REG (0x14a0)
> +#define FB_INT_REG (0x1570)
>  
>  #define CFG_FMT GENMASK(2, 0)
>  #define CFG_FBSWITCH BIT(7)
> @@ -60,6 +63,10 @@
>  #define FB_PANCFG_DEF 0x80001311
>  #define FB_HSYNC_PULSE (1 << 30)
>  #define FB_VSYNC_PULSE (1 << 30)
> +#define FB_VSYNC1_ENABLE (1 << 16)
> +#define FB_VSYNC0_ENABLE (1 << 18)
> +#define FB_VSYNC1_INT (1 << 0)
> +#define FB_VSYNC0_INT (1 << 2)
>  
>  /* PIX PLL */
>  #define LOOPC_MIN 24
> @@ -136,6 +143,14 @@ int loongson_encoder_init(struct loongson_device *ldev, int index);
>  /* plane */
>  int loongson_plane_init(struct loongson_crtc *lcrtc);
>  
> +/* irq */
> +int loongson_irq_init(struct loongson_device *ldev);
> +int loongson_crtc_enable_vblank(struct drm_crtc *crtc);
> +void loongson_crtc_disable_vblank(struct drm_crtc *crtc);
> +irqreturn_t loongson_irq_handler(int irq, void *arg);
> +void loongson_irq_preinstall(struct drm_device *dev);
> +void loongson_irq_uninstall(struct drm_device *dev);
> +
>  /* i2c */
>  int loongson_dc_gpio_init(struct loongson_device *ldev);
>  
> diff --git a/drivers/gpu/drm/loongson/loongson_irq.c b/drivers/gpu/drm/loongson/loongson_irq.c
> new file mode 100644
> index 000000000000..d212e16f3c00
> --- /dev/null
> +++ b/drivers/gpu/drm/loongson/loongson_irq.c
> @@ -0,0 +1,105 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +
> +#include "loongson_drv.h"
> +#include <linux/pci.h>
> +
> +int loongson_irq_init(struct loongson_device *ldev)
> +{
> +	struct drm_device *dev;
> +	int ret, irq;
> +
> +	dev = ldev->dev;
> +	irq = dev->pdev->irq;
> +
> +	ret = drm_vblank_init(dev, ldev->num_crtc);
> +	if (ret) {
> +		dev_err(dev->dev, "Fatal error during vblank init: %d\n", ret);
> +		return ret;
> +	}
> +	DRM_INFO("drm vblank init finished\n");
> +
> +	ret = drm_irq_install(dev, irq);
> +	if (ret) {
> +		dev_err(dev->dev, "Fatal error during irq install: %d\n", ret);
> +		return ret;
> +	}
> +	DRM_INFO("loongson irq initialized\n");
> +
> +	return 0;
> +}
> +
> +int loongson_crtc_enable_vblank(struct drm_crtc *crtc)
> +{
> +	struct loongson_crtc *lcrtc = to_loongson_crtc(crtc);
> +	struct loongson_device *ldev = lcrtc->ldev;
> +	u32 reg_val;
> +
> +	if (lcrtc->crtc_id) {
> +		reg_val = ls7a_mm_rreg(ldev, FB_INT_REG);
> +		reg_val |= FB_VSYNC1_ENABLE;
> +		ls7a_mm_wreg(ldev, FB_INT_REG, reg_val);
> +	} else {
> +		reg_val = ls7a_mm_rreg(ldev, FB_INT_REG);
> +		reg_val |= FB_VSYNC0_ENABLE;
> +		ls7a_mm_wreg(ldev, FB_INT_REG, reg_val);
> +	}
> +
> +	return 0;
> +}
> +
> +void loongson_crtc_disable_vblank(struct drm_crtc *crtc)
> +{
> +	struct loongson_crtc *lcrtc = to_loongson_crtc(crtc);
> +	struct loongson_device *ldev = lcrtc->ldev;
> +	u32 reg_val;
> +
> +	if (lcrtc->crtc_id) {
> +		reg_val = ls7a_mm_rreg(ldev, FB_INT_REG);
> +		reg_val &= ~FB_VSYNC1_ENABLE;
> +		ls7a_mm_wreg(ldev, FB_INT_REG, reg_val);
> +	} else {
> +		reg_val = ls7a_mm_rreg(ldev, FB_INT_REG);
> +		reg_val &= ~FB_VSYNC0_ENABLE;
> +		ls7a_mm_wreg(ldev, FB_INT_REG, reg_val);
> +	}

More readable to pull the common code in one place:

	reg_val = ls7a_mm_rreg(ldev, FB_INT_REG);

	if (lcrtc->crtc_id)
		reg_val &= ~FB_VSYNC1_ENABLE;
	else
		reg_val &= ~FB_VSYNC0_ENABLE;

	ls7a_mm_wreg(ldev, FB_INT_REG, reg_val);


> +}
> +

regards,
dan carpenter


WARNING: multiple messages have this Message-ID (diff)
From: Dan Carpenter <dan.carpenter@oracle.com>
To: lichenyang <lichenyang@loongson.cn>
Cc: David Airlie <airlied@linux.ie>, Daniel Vetter <daniel@ffwll.ch>,
	linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org,
	devel@linuxdriverproject.org, Huacai Chen <chenhuacai@kernel.org>,
	Tiezhu Yang <yangtiezhu@loongson.cn>
Subject: Re: [PATCH v2 3/3] drm/loongson: Add interrupt driver for LS7A
Date: Mon, 19 Jul 2021 12:58:19 +0300	[thread overview]
Message-ID: <20210719095819.GS1931@kadam> (raw)
In-Reply-To: <20210715015809.107821-3-lichenyang@loongson.cn>

On Thu, Jul 15, 2021 at 09:58:09AM +0800, lichenyang wrote:
> Add LS7A DC vsync interrupt enable and close function, and
> register irq_handler function interface.
> Add vbrank event processing flow.
> 
> V2:
> - Remove the useless flags parameter.

Do this in a separate patch.  It is an unrelated cleanup.

> - Added error handling in the loongson_drm_load function.
> 
> Signed-off-by: lichenyang <lichenyang@loongson.cn>
> ---
>  drivers/gpu/drm/loongson/Makefile        |   3 +-
>  drivers/gpu/drm/loongson/loongson_crtc.c |  43 +++++++++-
>  drivers/gpu/drm/loongson/loongson_drv.c  |  22 +++--
>  drivers/gpu/drm/loongson/loongson_drv.h  |  17 +++-
>  drivers/gpu/drm/loongson/loongson_irq.c  | 105 +++++++++++++++++++++++
>  5 files changed, 179 insertions(+), 11 deletions(-)
>  create mode 100644 drivers/gpu/drm/loongson/loongson_irq.c
> 
> diff --git a/drivers/gpu/drm/loongson/Makefile b/drivers/gpu/drm/loongson/Makefile
> index 773b806e99a2..cc50b65c7e03 100644
> --- a/drivers/gpu/drm/loongson/Makefile
> +++ b/drivers/gpu/drm/loongson/Makefile
> @@ -11,5 +11,6 @@ loongson-y := loongson_drv.o \
>  	loongson_device.o \
>  	loongson_connector.o \
>  	loongson_encoder.o \
> -	loongson_i2c.o
> +	loongson_i2c.o \
> +	loongson_irq.o
>  obj-$(CONFIG_DRM_LOONGSON) += loongson.o
> diff --git a/drivers/gpu/drm/loongson/loongson_crtc.c b/drivers/gpu/drm/loongson/loongson_crtc.c
> index 4cb65fa08778..4c62d5b2bd56 100644
> --- a/drivers/gpu/drm/loongson/loongson_crtc.c
> +++ b/drivers/gpu/drm/loongson/loongson_crtc.c
> @@ -154,19 +154,25 @@ static void loongson_crtc_mode_set_nofb(struct drm_crtc *crtc)
>  }
>  
>  static void loongson_crtc_atomic_enable(struct drm_crtc *crtc,
> -					struct drm_atomic_state *old_state)
> +					struct drm_atomic_state *old_crtc_state)
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct loongson_device *ldev = dev->dev_private;
>  	struct loongson_crtc *lcrtc = to_loongson_crtc(crtc);
>  	u32 reg_offset = lcrtc->reg_offset;
>  
> +	if (lcrtc->cfg_reg & CFG_ENABLE)
> +		goto vblank_on;
> +
>  	lcrtc->cfg_reg |= CFG_ENABLE;
>  	ls7a_mm_wreg(ldev, FB_CFG_REG + reg_offset, lcrtc->cfg_reg);
> +
> +vblank_on:
> +	drm_crtc_vblank_on(crtc);
>  }
>  
>  static void loongson_crtc_atomic_disable(struct drm_crtc *crtc,
> -					 struct drm_atomic_state *old_state)
> +					 struct drm_atomic_state *old_crtc_state)
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct loongson_device *ldev = dev->dev_private;
> @@ -175,10 +181,36 @@ static void loongson_crtc_atomic_disable(struct drm_crtc *crtc,
>  
>  	lcrtc->cfg_reg &= ~CFG_ENABLE;
>  	ls7a_mm_wreg(ldev, FB_CFG_REG + reg_offset, lcrtc->cfg_reg);
> +
> +	spin_lock_irq(&crtc->dev->event_lock);
> +	if (crtc->state->event) {
> +		drm_crtc_send_vblank_event(crtc, crtc->state->event);
> +		crtc->state->event = NULL;
> +	}
> +	spin_unlock_irq(&crtc->dev->event_lock);
> +
> +	drm_crtc_vblank_off(crtc);
> +}
> +
> +static void loongson_crtc_atomic_flush(struct drm_crtc *crtc,
> +				       struct drm_crtc_state *old_crtc_state)
> +{
> +	struct drm_pending_vblank_event *event = crtc->state->event;
> +
> +	if (event) {

Flip this around:

	if (!event)
		return;


> +		crtc->state->event = NULL;
> +
> +		spin_lock_irq(&crtc->dev->event_lock);
> +		if (drm_crtc_vblank_get(crtc) == 0)
> +			drm_crtc_arm_vblank_event(crtc, event);
> +		else
> +			drm_crtc_send_vblank_event(crtc, event);
> +		spin_unlock_irq(&crtc->dev->event_lock);
> +	}
>  }
>  
>  static enum drm_mode_status loongson_mode_valid(struct drm_crtc *crtc,
> -						const struct drm_display_mode *mode)
> +		const struct drm_display_mode *mode)
>  {
>  	if (mode->hdisplay > 1920)
>  		return MODE_BAD;
> @@ -194,9 +226,10 @@ static enum drm_mode_status loongson_mode_valid(struct drm_crtc *crtc,
>  
>  static const struct drm_crtc_helper_funcs loongson_crtc_helper_funcs = {
>  	.mode_valid = loongson_mode_valid,
> +	.mode_set_nofb = loongson_crtc_mode_set_nofb,
> +	.atomic_flush = loongson_crtc_atomic_flush,
>  	.atomic_enable = loongson_crtc_atomic_enable,
>  	.atomic_disable = loongson_crtc_atomic_disable,
> -	.mode_set_nofb = loongson_crtc_mode_set_nofb,
>  };
>  
>  static const struct drm_crtc_funcs loongson_crtc_funcs = {
> @@ -206,6 +239,8 @@ static const struct drm_crtc_funcs loongson_crtc_funcs = {
>  	.destroy = drm_crtc_cleanup,
>  	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
>  	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
> +	.enable_vblank = loongson_crtc_enable_vblank,
> +	.disable_vblank = loongson_crtc_disable_vblank,
>  };
>  
>  int loongson_crtc_init(struct loongson_device *ldev, int index)
> diff --git a/drivers/gpu/drm/loongson/loongson_drv.c b/drivers/gpu/drm/loongson/loongson_drv.c
> index 252be9e25aff..13003f6ae062 100644
> --- a/drivers/gpu/drm/loongson/loongson_drv.c
> +++ b/drivers/gpu/drm/loongson/loongson_drv.c
> @@ -24,7 +24,7 @@ static const struct drm_mode_config_funcs loongson_mode_funcs = {
>  	.mode_valid = drm_vram_helper_mode_valid
>  };
>  
> -static int loongson_device_init(struct drm_device *dev, uint32_t flags)
> +static int loongson_device_init(struct drm_device *dev)
>  {
>  	struct loongson_device *ldev = dev->dev_private;
>  	struct pci_dev *gpu_pdev;
> @@ -131,7 +131,7 @@ int loongson_modeset_init(struct loongson_device *ldev)
>  	return 0;
>  }
>  
> -static int loongson_drm_load(struct drm_device *dev, unsigned long flags)
> +static int loongson_drm_load(struct drm_device *dev)
>  {
>  	struct loongson_device *ldev;
>  	int ret;
> @@ -143,7 +143,7 @@ static int loongson_drm_load(struct drm_device *dev, unsigned long flags)
>  	dev->dev_private = ldev;
>  	ldev->dev = dev;
>  
> -	ret = loongson_device_init(dev, flags);
> +	ret = loongson_device_init(dev);
>  	if (ret)
>  		goto err;
>  
> @@ -164,8 +164,16 @@ static int loongson_drm_load(struct drm_device *dev, unsigned long flags)
>  	pci_set_drvdata(dev->pdev, dev);
>  
>  	ret = loongson_modeset_init(ldev);
> -	if (ret)
> +	if (ret) {
>  		dev_err(dev->dev, "Fatal error during modeset init: %d\n", ret);
> +		goto err;
> +	}
> +
> +	ret = loongson_irq_init(ldev);
> +	if (ret) {
> +		dev_err(dev->dev, "Fatal error during irq init: %d\n", ret);
> +		goto err;
> +	}
>  
>  	drm_kms_helper_poll_init(dev);
>  	drm_mode_config_reset(dev);
> @@ -192,6 +200,10 @@ static struct drm_driver loongson_drm_driver = {
>  	.fops = &fops,
>  	DRM_GEM_VRAM_DRIVER,
>  
> +	.irq_handler = loongson_irq_handler,
> +	.irq_preinstall = loongson_irq_preinstall,
> +	.irq_uninstall = loongson_irq_uninstall,
> +
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
>  	.date = DRIVER_DATE,
> @@ -221,7 +233,7 @@ static int loongson_pci_probe(struct pci_dev *pdev,
>  		goto err_free;
>  	}
>  
> -	ret = loongson_drm_load(dev, 0x0);
> +	ret = loongson_drm_load(dev);
>  	if (ret) {
>  		drm_err(dev, "failed to load loongson: %d\n", ret);
>  		goto err_pdev;
> diff --git a/drivers/gpu/drm/loongson/loongson_drv.h b/drivers/gpu/drm/loongson/loongson_drv.h
> index 24a534c3c79c..60f5bd48f7f2 100644
> --- a/drivers/gpu/drm/loongson/loongson_drv.h
> +++ b/drivers/gpu/drm/loongson/loongson_drv.h
> @@ -4,9 +4,11 @@
>  #define __LOONGSON_DRV_H__
>  
>  #include <drm/drm_drv.h>
> +#include <drm/drm_fourcc.h>
> +#include <drm/drm_vblank.h>
>  #include <drm/drm_gem.h>
> +#include <drm/drm_irq.h>
>  #include <drm/drm_fb_helper.h>
> -#include <drm/drm_fourcc.h>
>  #include <drm/drm_probe_helper.h>
>  #include <drm/drm_atomic.h>
>  #include <drm/drm_atomic_helper.h>
> @@ -49,6 +51,7 @@
>  #define FB_HSYNC_REG (0x1420)
>  #define FB_VDISPLAY_REG (0x1480)
>  #define FB_VSYNC_REG (0x14a0)
> +#define FB_INT_REG (0x1570)
>  
>  #define CFG_FMT GENMASK(2, 0)
>  #define CFG_FBSWITCH BIT(7)
> @@ -60,6 +63,10 @@
>  #define FB_PANCFG_DEF 0x80001311
>  #define FB_HSYNC_PULSE (1 << 30)
>  #define FB_VSYNC_PULSE (1 << 30)
> +#define FB_VSYNC1_ENABLE (1 << 16)
> +#define FB_VSYNC0_ENABLE (1 << 18)
> +#define FB_VSYNC1_INT (1 << 0)
> +#define FB_VSYNC0_INT (1 << 2)
>  
>  /* PIX PLL */
>  #define LOOPC_MIN 24
> @@ -136,6 +143,14 @@ int loongson_encoder_init(struct loongson_device *ldev, int index);
>  /* plane */
>  int loongson_plane_init(struct loongson_crtc *lcrtc);
>  
> +/* irq */
> +int loongson_irq_init(struct loongson_device *ldev);
> +int loongson_crtc_enable_vblank(struct drm_crtc *crtc);
> +void loongson_crtc_disable_vblank(struct drm_crtc *crtc);
> +irqreturn_t loongson_irq_handler(int irq, void *arg);
> +void loongson_irq_preinstall(struct drm_device *dev);
> +void loongson_irq_uninstall(struct drm_device *dev);
> +
>  /* i2c */
>  int loongson_dc_gpio_init(struct loongson_device *ldev);
>  
> diff --git a/drivers/gpu/drm/loongson/loongson_irq.c b/drivers/gpu/drm/loongson/loongson_irq.c
> new file mode 100644
> index 000000000000..d212e16f3c00
> --- /dev/null
> +++ b/drivers/gpu/drm/loongson/loongson_irq.c
> @@ -0,0 +1,105 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +
> +#include "loongson_drv.h"
> +#include <linux/pci.h>
> +
> +int loongson_irq_init(struct loongson_device *ldev)
> +{
> +	struct drm_device *dev;
> +	int ret, irq;
> +
> +	dev = ldev->dev;
> +	irq = dev->pdev->irq;
> +
> +	ret = drm_vblank_init(dev, ldev->num_crtc);
> +	if (ret) {
> +		dev_err(dev->dev, "Fatal error during vblank init: %d\n", ret);
> +		return ret;
> +	}
> +	DRM_INFO("drm vblank init finished\n");
> +
> +	ret = drm_irq_install(dev, irq);
> +	if (ret) {
> +		dev_err(dev->dev, "Fatal error during irq install: %d\n", ret);
> +		return ret;
> +	}
> +	DRM_INFO("loongson irq initialized\n");
> +
> +	return 0;
> +}
> +
> +int loongson_crtc_enable_vblank(struct drm_crtc *crtc)
> +{
> +	struct loongson_crtc *lcrtc = to_loongson_crtc(crtc);
> +	struct loongson_device *ldev = lcrtc->ldev;
> +	u32 reg_val;
> +
> +	if (lcrtc->crtc_id) {
> +		reg_val = ls7a_mm_rreg(ldev, FB_INT_REG);
> +		reg_val |= FB_VSYNC1_ENABLE;
> +		ls7a_mm_wreg(ldev, FB_INT_REG, reg_val);
> +	} else {
> +		reg_val = ls7a_mm_rreg(ldev, FB_INT_REG);
> +		reg_val |= FB_VSYNC0_ENABLE;
> +		ls7a_mm_wreg(ldev, FB_INT_REG, reg_val);
> +	}
> +
> +	return 0;
> +}
> +
> +void loongson_crtc_disable_vblank(struct drm_crtc *crtc)
> +{
> +	struct loongson_crtc *lcrtc = to_loongson_crtc(crtc);
> +	struct loongson_device *ldev = lcrtc->ldev;
> +	u32 reg_val;
> +
> +	if (lcrtc->crtc_id) {
> +		reg_val = ls7a_mm_rreg(ldev, FB_INT_REG);
> +		reg_val &= ~FB_VSYNC1_ENABLE;
> +		ls7a_mm_wreg(ldev, FB_INT_REG, reg_val);
> +	} else {
> +		reg_val = ls7a_mm_rreg(ldev, FB_INT_REG);
> +		reg_val &= ~FB_VSYNC0_ENABLE;
> +		ls7a_mm_wreg(ldev, FB_INT_REG, reg_val);
> +	}

More readable to pull the common code in one place:

	reg_val = ls7a_mm_rreg(ldev, FB_INT_REG);

	if (lcrtc->crtc_id)
		reg_val &= ~FB_VSYNC1_ENABLE;
	else
		reg_val &= ~FB_VSYNC0_ENABLE;

	ls7a_mm_wreg(ldev, FB_INT_REG, reg_val);


> +}
> +

regards,
dan carpenter


  reply	other threads:[~2021-07-19  9:59 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-15  1:58 [PATCH v2 1/3] drm/loongson: Add DRM Driver for Loongson 7A1000 bridge chip lichenyang
2021-07-15  1:58 ` [PATCH v2 2/3] drm/loongson: Add GPIO and I2C driver for loongson drm lichenyang
2021-07-19  9:20   ` Dan Carpenter
2021-07-19  9:20     ` Dan Carpenter
2021-07-15  1:58 ` [PATCH v2 3/3] drm/loongson: Add interrupt driver for LS7A lichenyang
2021-07-19  9:58   ` Dan Carpenter [this message]
2021-07-19  9:58     ` Dan Carpenter
2021-07-19  9:53 ` [PATCH v2 1/3] drm/loongson: Add DRM Driver for Loongson 7A1000 bridge chip Dan Carpenter
2021-07-19  9:53   ` Dan Carpenter
2021-07-19 13:13 ` Dan Carpenter
2021-07-19 13:13   ` Dan Carpenter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210719095819.GS1931@kadam \
    --to=dan.carpenter@oracle.com \
    --cc=airlied@linux.ie \
    --cc=chenhuacai@kernel.org \
    --cc=devel@linuxdriverproject.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=lichenyang@loongson.cn \
    --cc=linux-kernel@vger.kernel.org \
    --cc=yangtiezhu@loongson.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.