Commit e13273d4 authored by Emily Deng's avatar Emily Deng Committed by Alex Deucher

drm/amdgpu: Initialize crtc, pageflip irq funcs (v2)

For virtual display feature, initialize dce_virtual_crtc_irq_funcs,
dce_virtual_pageflip_irq_funcs. As it has no dce engine, so the
pageflip interrupt won't be generated, and the vsync interrupt will
be generated by smu's periodic timer or software timer which will
be implemented later.

v2: agd: rebase on upstream
Signed-off-by: default avatarEmily Deng <Emily.Deng@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 8e6de75b
...@@ -473,19 +473,128 @@ static void dce_virtual_set_display_funcs(struct amdgpu_device *adev) ...@@ -473,19 +473,128 @@ static void dce_virtual_set_display_funcs(struct amdgpu_device *adev)
adev->mode_info.funcs = &dce_virtual_display_funcs; adev->mode_info.funcs = &dce_virtual_display_funcs;
} }
static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *adev,
int crtc,
enum amdgpu_interrupt_state state)
{
if (crtc >= adev->mode_info.num_crtc) {
DRM_DEBUG("invalid crtc %d\n", crtc);
return;
}
}
static int dce_virtual_set_crtc_irq_state(struct amdgpu_device *adev,
struct amdgpu_irq_src *source,
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;
}
return 0;
}
static void dce_virtual_crtc_vblank_int_ack(struct amdgpu_device *adev,
int crtc)
{
if (crtc >= adev->mode_info.num_crtc) {
DRM_DEBUG("invalid crtc %d\n", crtc);
return;
}
}
static int dce_virtual_crtc_irq(struct amdgpu_device *adev,
struct amdgpu_irq_src *source,
struct amdgpu_iv_entry *entry)
{
unsigned crtc = 0;
unsigned irq_type = AMDGPU_CRTC_IRQ_VBLANK1;
adev->ddev->vblank[crtc].count++;
dce_virtual_crtc_vblank_int_ack(adev, crtc);
if (amdgpu_irq_enabled(adev, source, irq_type)) {
drm_handle_vblank(adev->ddev, crtc);
}
DRM_DEBUG("IH: D%d vblank\n", crtc + 1);
return 0;
}
static int dce_virtual_set_pageflip_irq_state(struct amdgpu_device *adev,
struct amdgpu_irq_src *src,
unsigned type,
enum amdgpu_interrupt_state state)
{
if (type >= adev->mode_info.num_crtc) {
DRM_ERROR("invalid pageflip crtc %d\n", type);
return -EINVAL;
}
DRM_DEBUG("[FM]set pageflip irq type %d state %d\n", type, state);
return 0;
}
static int dce_virtual_pageflip_irq(struct amdgpu_device *adev,
struct amdgpu_irq_src *source,
struct amdgpu_iv_entry *entry)
{
unsigned long flags;
unsigned crtc_id = 0;
struct amdgpu_crtc *amdgpu_crtc;
struct amdgpu_flip_work *works;
crtc_id = 0;
amdgpu_crtc = adev->mode_info.crtcs[crtc_id];
if (crtc_id >= adev->mode_info.num_crtc) {
DRM_ERROR("invalid pageflip crtc %d\n", crtc_id);
return -EINVAL;
}
/* IRQ could occur when in initial stage */
if (amdgpu_crtc == NULL)
return 0;
spin_lock_irqsave(&adev->ddev->event_lock, flags);
works = amdgpu_crtc->pflip_works;
if (amdgpu_crtc->pflip_status != AMDGPU_FLIP_SUBMITTED) {
DRM_DEBUG_DRIVER("amdgpu_crtc->pflip_status = %d != "
"AMDGPU_FLIP_SUBMITTED(%d)\n",
amdgpu_crtc->pflip_status,
AMDGPU_FLIP_SUBMITTED);
spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
return 0;
}
/* page flip completed. clean up */
amdgpu_crtc->pflip_status = AMDGPU_FLIP_NONE;
amdgpu_crtc->pflip_works = NULL;
/* wakeup usersapce */
if (works->event)
drm_crtc_send_vblank_event(&amdgpu_crtc->base, works->event);
spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
drm_crtc_vblank_put(&amdgpu_crtc->base);
schedule_work(&works->unpin_work);
return 0;
}
static const struct amdgpu_irq_src_funcs dce_virtual_crtc_irq_funcs = { static const struct amdgpu_irq_src_funcs dce_virtual_crtc_irq_funcs = {
.set = NULL, .set = dce_virtual_set_crtc_irq_state,
.process = NULL, .process = dce_virtual_crtc_irq,
}; };
static const struct amdgpu_irq_src_funcs dce_virtual_pageflip_irq_funcs = { static const struct amdgpu_irq_src_funcs dce_virtual_pageflip_irq_funcs = {
.set = NULL, .set = dce_virtual_set_pageflip_irq_state,
.process = NULL, .process = dce_virtual_pageflip_irq,
};
static const struct amdgpu_irq_src_funcs dce_virtual_hpd_irq_funcs = {
.set = NULL,
.process = NULL,
}; };
static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev) static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev)
...@@ -495,8 +604,5 @@ static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev) ...@@ -495,8 +604,5 @@ static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev)
adev->pageflip_irq.num_types = AMDGPU_PAGEFLIP_IRQ_LAST; adev->pageflip_irq.num_types = AMDGPU_PAGEFLIP_IRQ_LAST;
adev->pageflip_irq.funcs = &dce_virtual_pageflip_irq_funcs; adev->pageflip_irq.funcs = &dce_virtual_pageflip_irq_funcs;
adev->hpd_irq.num_types = AMDGPU_HPD_LAST;
adev->hpd_irq.funcs = &dce_virtual_hpd_irq_funcs;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment