[PATCH 7/7] drm/amd/amdgpu: For virtual display, enable multi crtcs. (v3)
Deng, Emily
Emily.Deng at amd.com
Sat Oct 8 08:22:39 UTC 2016
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
More information about the amd-gfx
mailing list