[PATCH 7/7] drm/amd/amdgpu: For virtual display, enable multi crtcs. (v3)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Reviewed-By: Emily Deng <Emily.Deng at amd.com>

> -----Original Message-----
> From: Alex Deucher [mailto:alexdeucher at gmail.com]
> Sent: Saturday, October 01, 2016 1:09 AM
> To: amd-gfx at lists.freedesktop.org
> Cc: Deng, Emily <Emily.Deng at amd.com>; Deucher, Alexander
> <Alexander.Deucher at amd.com>
> Subject: [PATCH 7/7] drm/amd/amdgpu: For virtual display, enable multi
> crtcs. (v3)
> 
> From: Emily Deng <Emily.Deng at amd.com>
> 
> Enable multi crtcs for virtual display, user can set the number of crtcs by
> amdgpu module parameter  virtual_display.
> 
> v2: make timers per crtc
> v3: agd: simplify implementation
> 
> Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 28 +++++++++++++----
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c    |  3 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h   |  5 ++--
>  drivers/gpu/drm/amd/amdgpu/dce_virtual.c   | 48 +++++++++++++++--------
> -------
>  4 files changed, 52 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 13caa52..91dc851 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -1238,20 +1238,38 @@ static void
> amdgpu_device_enable_virtual_display(struct amdgpu_device *adev)
>  	if (amdgpu_virtual_display) {
>  		struct drm_device *ddev = adev->ddev;
>  		const char *pci_address_name = pci_name(ddev->pdev);
> -		char *pciaddstr, *pciaddstr_tmp, *pciaddname;
> +		char *pciaddstr, *pciaddstr_tmp, *pciaddname_tmp,
> *pciaddname;
> 
>  		pciaddstr = kstrdup(amdgpu_virtual_display, GFP_KERNEL);
>  		pciaddstr_tmp = pciaddstr;
> -		while ((pciaddname = strsep(&pciaddstr_tmp, ";"))) {
> +		while ((pciaddname_tmp = strsep(&pciaddstr_tmp, ";"))) {
> +			pciaddname = strsep(&pciaddname_tmp, ",");
>  			if (!strcmp(pci_address_name, pciaddname)) {
> +				long num_crtc;
> +				int res = -1;
> +
>  				adev->enable_virtual_display = true;
> +
> +				if (pciaddname_tmp)
> +					res = kstrtol(pciaddname_tmp, 10,
> +						      &num_crtc);
> +
> +				if (!res) {
> +					if (num_crtc < 1)
> +						num_crtc = 1;
> +					if (num_crtc > 6)
> +						num_crtc = 6;
> +					adev->mode_info.num_crtc =
> num_crtc;
> +				} else {
> +					adev->mode_info.num_crtc = 1;
> +				}
>  				break;
>  			}
>  		}
> 
> -		DRM_INFO("virtual display
> string:%s, %s:virtual_display:%d\n",
> -				 amdgpu_virtual_display, pci_address_name,
> -				 adev->enable_virtual_display);
> +		DRM_INFO("virtual display string:%s, %s:virtual_display:%d,
> num_crtc:%d\n",
> +			 amdgpu_virtual_display, pci_address_name,
> +			 adev->enable_virtual_display, adev-
> >mode_info.num_crtc);
> 
>  		kfree(pciaddstr);
>  	}
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index 728e8ca..721ef24 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -201,7 +201,8 @@ module_param_named(pg_mask, amdgpu_pg_mask,
> uint, 0444);  MODULE_PARM_DESC(disable_cu, "Disable CUs (se.sh.cu,...)");
> module_param_named(disable_cu, amdgpu_disable_cu, charp, 0444);
> 
> -MODULE_PARM_DESC(virtual_display, "Enable virtual display feature (the
> virtual_display will be set like xxxx:xx:xx.x;xxxx:xx:xx.x)");
> +MODULE_PARM_DESC(virtual_display,
> +		 "Enable virtual display feature (the virtual_display will be set
> +like xxxx:xx:xx.x,x;xxxx:xx:xx.x,x)");
>  module_param_named(virtual_display, amdgpu_virtual_display, charp,
> 0444);
> 
>  static const struct pci_device_id pciidlist[] = { diff --git
> a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> index 7b0eff7..1e23334 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> @@ -341,8 +341,6 @@ struct amdgpu_mode_info {
>  	int			num_dig; /* number of dig blocks */
>  	int			disp_priority;
>  	const struct amdgpu_display_funcs *funcs;
> -	struct hrtimer vblank_timer;
> -	enum amdgpu_interrupt_state vsync_timer_enabled;
>  };
> 
>  #define AMDGPU_MAX_BL_LEVEL 0xFF
> @@ -413,6 +411,9 @@ struct amdgpu_crtc {
>  	u32 wm_high;
>  	u32 lb_vblank_lead_lines;
>  	struct drm_display_mode hw_mode;
> +	/* for virtual dce */
> +	struct hrtimer vblank_timer;
> +	enum amdgpu_interrupt_state vsync_timer_enabled;
>  };
> 
>  struct amdgpu_encoder_atom_dig {
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> index 0c8b21e..682e066 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> @@ -335,6 +335,7 @@ static int dce_virtual_crtc_init(struct amdgpu_device
> *adev, int index)
>  	amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
>  	amdgpu_crtc->encoder = NULL;
>  	amdgpu_crtc->connector = NULL;
> +	amdgpu_crtc->vsync_timer_enabled =
> AMDGPU_IRQ_STATE_DISABLE;
>  	drm_crtc_helper_add(&amdgpu_crtc->base,
> &dce_virtual_crtc_helper_funcs);
> 
>  	return 0;
> @@ -344,11 +345,9 @@ static int dce_virtual_early_init(void *handle)  {
>  	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> 
> -	adev->mode_info.vsync_timer_enabled =
> AMDGPU_IRQ_STATE_DISABLE;
>  	dce_virtual_set_display_funcs(adev);
>  	dce_virtual_set_irq_funcs(adev);
> 
> -	adev->mode_info.num_crtc = 1;
>  	adev->mode_info.num_hpd = 1;
>  	adev->mode_info.num_dig = 1;
>  	return 0;
> @@ -760,14 +759,13 @@ static int dce_virtual_pageflip(struct
> amdgpu_device *adev,
> 
>  static enum hrtimer_restart dce_virtual_vblank_timer_handle(struct hrtimer
> *vblank_timer)  {
> -	struct amdgpu_mode_info *mode_info =
> -		container_of(vblank_timer, struct amdgpu_mode_info ,
> vblank_timer);
> -	struct amdgpu_device *adev =
> -		container_of(mode_info, struct amdgpu_device ,
> mode_info);
> -	unsigned crtc = 0;
> +	struct amdgpu_crtc *amdgpu_crtc = container_of(vblank_timer,
> +						       struct amdgpu_crtc,
> vblank_timer);
> +	struct drm_device *ddev = amdgpu_crtc->base.dev;
> +	struct amdgpu_device *adev = ddev->dev_private;
> 
> -	drm_handle_vblank(adev->ddev, crtc);
> -	dce_virtual_pageflip(adev, crtc);
> +	drm_handle_vblank(ddev, amdgpu_crtc->crtc_id);
> +	dce_virtual_pageflip(adev, amdgpu_crtc->crtc_id);
>  	hrtimer_start(vblank_timer, ktime_set(0,
> DCE_VIRTUAL_VBLANK_PERIOD),
>  		      HRTIMER_MODE_REL);
> 
> @@ -783,18 +781,22 @@ static void
> dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *ad
>  		return;
>  	}
> 
> -	if (state && !adev->mode_info.vsync_timer_enabled) {
> +	if (state && !adev->mode_info.crtcs[crtc]->vsync_timer_enabled) {
>  		DRM_DEBUG("Enable software vsync timer\n");
> -		hrtimer_init(&adev->mode_info.vblank_timer,
> CLOCK_MONOTONIC, HRTIMER_MODE_REL);
> -		hrtimer_set_expires(&adev->mode_info.vblank_timer,
> ktime_set(0, DCE_VIRTUAL_VBLANK_PERIOD));
> -		adev->mode_info.vblank_timer.function =
> dce_virtual_vblank_timer_handle;
> -		hrtimer_start(&adev->mode_info.vblank_timer, ktime_set(0,
> DCE_VIRTUAL_VBLANK_PERIOD), HRTIMER_MODE_REL);
> -	} else if (!state && adev->mode_info.vsync_timer_enabled) {
> +		hrtimer_init(&adev->mode_info.crtcs[crtc]->vblank_timer,
> +			     CLOCK_MONOTONIC, HRTIMER_MODE_REL);
> +		hrtimer_set_expires(&adev->mode_info.crtcs[crtc]-
> >vblank_timer,
> +				    ktime_set(0,
> DCE_VIRTUAL_VBLANK_PERIOD));
> +		adev->mode_info.crtcs[crtc]->vblank_timer.function =
> +			dce_virtual_vblank_timer_handle;
> +		hrtimer_start(&adev->mode_info.crtcs[crtc]->vblank_timer,
> +			      ktime_set(0, DCE_VIRTUAL_VBLANK_PERIOD),
> HRTIMER_MODE_REL);
> +	} else if (!state && adev->mode_info.crtcs[crtc]-
> >vsync_timer_enabled)
> +{
>  		DRM_DEBUG("Disable software vsync timer\n");
> -		hrtimer_cancel(&adev->mode_info.vblank_timer);
> +		hrtimer_cancel(&adev->mode_info.crtcs[crtc]-
> >vblank_timer);
>  	}
> 
> -	adev->mode_info.vsync_timer_enabled = state;
> +	adev->mode_info.crtcs[crtc]->vsync_timer_enabled = state;
>  	DRM_DEBUG("[FM]set crtc %d vblank interrupt state %d\n", crtc,
> state);  }
> 
> @@ -804,13 +806,11 @@ static int dce_virtual_set_crtc_irq_state(struct
> amdgpu_device *adev,
>  					  unsigned type,
>  					  enum amdgpu_interrupt_state state)
> {
> -	switch (type) {
> -	case AMDGPU_CRTC_IRQ_VBLANK1:
> -		dce_virtual_set_crtc_vblank_interrupt_state(adev, 0, state);
> -		break;
> -	default:
> -		break;
> -	}
> +	if (type > AMDGPU_CRTC_IRQ_VBLANK6)
> +		return -EINVAL;
> +
> +	dce_virtual_set_crtc_vblank_interrupt_state(adev, type, state);
> +
>  	return 0;
>  }
> 
> --
> 2.5.5



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux