2 * Copyright 2014 Advanced Micro Devices, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
25 #include "amdgpu_pm.h"
26 #include "amdgpu_i2c.h"
28 #include "amdgpu_pll.h"
29 #include "amdgpu_connectors.h"
30 #ifdef CONFIG_DRM_AMDGPU_CIK
33 #include "dce_v10_0.h"
34 #include "dce_v11_0.h"
35 #include "dce_virtual.h"
37 static void dce_virtual_set_display_funcs(struct amdgpu_device
*adev
);
38 static void dce_virtual_set_irq_funcs(struct amdgpu_device
*adev
);
39 static int dce_virtual_pageflip_irq(struct amdgpu_device
*adev
,
40 struct amdgpu_irq_src
*source
,
41 struct amdgpu_iv_entry
*entry
);
44 * dce_virtual_vblank_wait - vblank wait asic callback.
46 * @adev: amdgpu_device pointer
47 * @crtc: crtc to wait for vblank on
49 * Wait for vblank on the requested crtc (evergreen+).
51 static void dce_virtual_vblank_wait(struct amdgpu_device
*adev
, int crtc
)
56 static u32
dce_virtual_vblank_get_counter(struct amdgpu_device
*adev
, int crtc
)
61 static void dce_virtual_page_flip(struct amdgpu_device
*adev
,
62 int crtc_id
, u64 crtc_base
, bool async
)
67 static int dce_virtual_crtc_get_scanoutpos(struct amdgpu_device
*adev
, int crtc
,
68 u32
*vbl
, u32
*position
)
76 static bool dce_virtual_hpd_sense(struct amdgpu_device
*adev
,
77 enum amdgpu_hpd_id hpd
)
82 static void dce_virtual_hpd_set_polarity(struct amdgpu_device
*adev
,
83 enum amdgpu_hpd_id hpd
)
88 static u32
dce_virtual_hpd_get_gpio_reg(struct amdgpu_device
*adev
)
93 static bool dce_virtual_is_display_hung(struct amdgpu_device
*adev
)
98 void dce_virtual_stop_mc_access(struct amdgpu_device
*adev
,
99 struct amdgpu_mode_mc_save
*save
)
101 switch (adev
->asic_type
) {
107 #ifdef CONFIG_DRM_AMDGPU_CIK
108 dce_v8_0_disable_dce(adev
);
113 dce_v10_0_disable_dce(adev
);
119 dce_v11_0_disable_dce(adev
);
125 DRM_ERROR("Virtual display unsupported ASIC type: 0x%X\n", adev
->asic_type
);
130 void dce_virtual_resume_mc_access(struct amdgpu_device
*adev
,
131 struct amdgpu_mode_mc_save
*save
)
136 void dce_virtual_set_vga_render_state(struct amdgpu_device
*adev
,
143 * dce_virtual_bandwidth_update - program display watermarks
145 * @adev: amdgpu_device pointer
147 * Calculate and program the display watermarks and line
148 * buffer allocation (CIK).
150 static void dce_virtual_bandwidth_update(struct amdgpu_device
*adev
)
155 static int dce_virtual_crtc_gamma_set(struct drm_crtc
*crtc
, u16
*red
,
156 u16
*green
, u16
*blue
, uint32_t size
)
158 struct amdgpu_crtc
*amdgpu_crtc
= to_amdgpu_crtc(crtc
);
161 /* userspace palettes are always correct as is */
162 for (i
= 0; i
< size
; i
++) {
163 amdgpu_crtc
->lut_r
[i
] = red
[i
] >> 6;
164 amdgpu_crtc
->lut_g
[i
] = green
[i
] >> 6;
165 amdgpu_crtc
->lut_b
[i
] = blue
[i
] >> 6;
171 static void dce_virtual_crtc_destroy(struct drm_crtc
*crtc
)
173 struct amdgpu_crtc
*amdgpu_crtc
= to_amdgpu_crtc(crtc
);
175 drm_crtc_cleanup(crtc
);
179 static const struct drm_crtc_funcs dce_virtual_crtc_funcs
= {
182 .gamma_set
= dce_virtual_crtc_gamma_set
,
183 .set_config
= amdgpu_crtc_set_config
,
184 .destroy
= dce_virtual_crtc_destroy
,
185 .page_flip_target
= amdgpu_crtc_page_flip_target
,
188 static void dce_virtual_crtc_dpms(struct drm_crtc
*crtc
, int mode
)
190 struct drm_device
*dev
= crtc
->dev
;
191 struct amdgpu_device
*adev
= dev
->dev_private
;
192 struct amdgpu_crtc
*amdgpu_crtc
= to_amdgpu_crtc(crtc
);
196 case DRM_MODE_DPMS_ON
:
197 amdgpu_crtc
->enabled
= true;
198 /* Make sure VBLANK and PFLIP interrupts are still enabled */
199 type
= amdgpu_crtc_idx_to_irq_type(adev
, amdgpu_crtc
->crtc_id
);
200 amdgpu_irq_update(adev
, &adev
->crtc_irq
, type
);
201 amdgpu_irq_update(adev
, &adev
->pageflip_irq
, type
);
202 drm_vblank_on(dev
, amdgpu_crtc
->crtc_id
);
204 case DRM_MODE_DPMS_STANDBY
:
205 case DRM_MODE_DPMS_SUSPEND
:
206 case DRM_MODE_DPMS_OFF
:
207 drm_vblank_off(dev
, amdgpu_crtc
->crtc_id
);
208 amdgpu_crtc
->enabled
= false;
214 static void dce_virtual_crtc_prepare(struct drm_crtc
*crtc
)
216 dce_virtual_crtc_dpms(crtc
, DRM_MODE_DPMS_OFF
);
219 static void dce_virtual_crtc_commit(struct drm_crtc
*crtc
)
221 dce_virtual_crtc_dpms(crtc
, DRM_MODE_DPMS_ON
);
224 static void dce_virtual_crtc_disable(struct drm_crtc
*crtc
)
226 struct amdgpu_crtc
*amdgpu_crtc
= to_amdgpu_crtc(crtc
);
228 dce_virtual_crtc_dpms(crtc
, DRM_MODE_DPMS_OFF
);
229 if (crtc
->primary
->fb
) {
231 struct amdgpu_framebuffer
*amdgpu_fb
;
232 struct amdgpu_bo
*rbo
;
234 amdgpu_fb
= to_amdgpu_framebuffer(crtc
->primary
->fb
);
235 rbo
= gem_to_amdgpu_bo(amdgpu_fb
->obj
);
236 r
= amdgpu_bo_reserve(rbo
, false);
238 DRM_ERROR("failed to reserve rbo before unpin\n");
240 amdgpu_bo_unpin(rbo
);
241 amdgpu_bo_unreserve(rbo
);
245 amdgpu_crtc
->pll_id
= ATOM_PPLL_INVALID
;
246 amdgpu_crtc
->encoder
= NULL
;
247 amdgpu_crtc
->connector
= NULL
;
250 static int dce_virtual_crtc_mode_set(struct drm_crtc
*crtc
,
251 struct drm_display_mode
*mode
,
252 struct drm_display_mode
*adjusted_mode
,
253 int x
, int y
, struct drm_framebuffer
*old_fb
)
255 struct amdgpu_crtc
*amdgpu_crtc
= to_amdgpu_crtc(crtc
);
257 /* update the hw version fpr dpm */
258 amdgpu_crtc
->hw_mode
= *adjusted_mode
;
263 static bool dce_virtual_crtc_mode_fixup(struct drm_crtc
*crtc
,
264 const struct drm_display_mode
*mode
,
265 struct drm_display_mode
*adjusted_mode
)
267 struct amdgpu_crtc
*amdgpu_crtc
= to_amdgpu_crtc(crtc
);
268 struct drm_device
*dev
= crtc
->dev
;
269 struct drm_encoder
*encoder
;
271 /* assign the encoder to the amdgpu crtc to avoid repeated lookups later */
272 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
) {
273 if (encoder
->crtc
== crtc
) {
274 amdgpu_crtc
->encoder
= encoder
;
275 amdgpu_crtc
->connector
= amdgpu_get_connector_for_encoder(encoder
);
279 if ((amdgpu_crtc
->encoder
== NULL
) || (amdgpu_crtc
->connector
== NULL
)) {
280 amdgpu_crtc
->encoder
= NULL
;
281 amdgpu_crtc
->connector
= NULL
;
289 static int dce_virtual_crtc_set_base(struct drm_crtc
*crtc
, int x
, int y
,
290 struct drm_framebuffer
*old_fb
)
295 static void dce_virtual_crtc_load_lut(struct drm_crtc
*crtc
)
300 static int dce_virtual_crtc_set_base_atomic(struct drm_crtc
*crtc
,
301 struct drm_framebuffer
*fb
,
302 int x
, int y
, enum mode_set_atomic state
)
307 static const struct drm_crtc_helper_funcs dce_virtual_crtc_helper_funcs
= {
308 .dpms
= dce_virtual_crtc_dpms
,
309 .mode_fixup
= dce_virtual_crtc_mode_fixup
,
310 .mode_set
= dce_virtual_crtc_mode_set
,
311 .mode_set_base
= dce_virtual_crtc_set_base
,
312 .mode_set_base_atomic
= dce_virtual_crtc_set_base_atomic
,
313 .prepare
= dce_virtual_crtc_prepare
,
314 .commit
= dce_virtual_crtc_commit
,
315 .load_lut
= dce_virtual_crtc_load_lut
,
316 .disable
= dce_virtual_crtc_disable
,
319 static int dce_virtual_crtc_init(struct amdgpu_device
*adev
, int index
)
321 struct amdgpu_crtc
*amdgpu_crtc
;
324 amdgpu_crtc
= kzalloc(sizeof(struct amdgpu_crtc
) +
325 (AMDGPUFB_CONN_LIMIT
* sizeof(struct drm_connector
*)), GFP_KERNEL
);
326 if (amdgpu_crtc
== NULL
)
329 drm_crtc_init(adev
->ddev
, &amdgpu_crtc
->base
, &dce_virtual_crtc_funcs
);
331 drm_mode_crtc_set_gamma_size(&amdgpu_crtc
->base
, 256);
332 amdgpu_crtc
->crtc_id
= index
;
333 adev
->mode_info
.crtcs
[index
] = amdgpu_crtc
;
335 for (i
= 0; i
< 256; i
++) {
336 amdgpu_crtc
->lut_r
[i
] = i
<< 2;
337 amdgpu_crtc
->lut_g
[i
] = i
<< 2;
338 amdgpu_crtc
->lut_b
[i
] = i
<< 2;
341 amdgpu_crtc
->pll_id
= ATOM_PPLL_INVALID
;
342 amdgpu_crtc
->encoder
= NULL
;
343 amdgpu_crtc
->connector
= NULL
;
344 drm_crtc_helper_add(&amdgpu_crtc
->base
, &dce_virtual_crtc_helper_funcs
);
349 static int dce_virtual_early_init(void *handle
)
351 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
353 adev
->mode_info
.vsync_timer_enabled
= AMDGPU_IRQ_STATE_DISABLE
;
354 dce_virtual_set_display_funcs(adev
);
355 dce_virtual_set_irq_funcs(adev
);
357 adev
->mode_info
.num_crtc
= 1;
358 adev
->mode_info
.num_hpd
= 1;
359 adev
->mode_info
.num_dig
= 1;
363 static bool dce_virtual_get_connector_info(struct amdgpu_device
*adev
)
365 struct amdgpu_i2c_bus_rec ddc_bus
;
366 struct amdgpu_router router
;
367 struct amdgpu_hpd hpd
;
369 /* look up gpio for ddc, hpd */
370 ddc_bus
.valid
= false;
371 hpd
.hpd
= AMDGPU_HPD_NONE
;
372 /* needed for aux chan transactions */
373 ddc_bus
.hpd
= hpd
.hpd
;
375 memset(&router
, 0, sizeof(router
));
376 router
.ddc_valid
= false;
377 router
.cd_valid
= false;
378 amdgpu_display_add_connector(adev
,
380 ATOM_DEVICE_CRT1_SUPPORT
,
381 DRM_MODE_CONNECTOR_VIRTUAL
, &ddc_bus
,
382 CONNECTOR_OBJECT_ID_VIRTUAL
,
386 amdgpu_display_add_encoder(adev
, ENCODER_VIRTUAL_ENUM_VIRTUAL
,
387 ATOM_DEVICE_CRT1_SUPPORT
,
390 amdgpu_link_encoder_connector(adev
->ddev
);
395 static int dce_virtual_sw_init(void *handle
)
398 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
400 r
= amdgpu_irq_add_id(adev
, 229, &adev
->crtc_irq
);
404 adev
->ddev
->max_vblank_count
= 0;
406 adev
->ddev
->mode_config
.funcs
= &amdgpu_mode_funcs
;
408 adev
->ddev
->mode_config
.max_width
= 16384;
409 adev
->ddev
->mode_config
.max_height
= 16384;
411 adev
->ddev
->mode_config
.preferred_depth
= 24;
412 adev
->ddev
->mode_config
.prefer_shadow
= 1;
414 adev
->ddev
->mode_config
.fb_base
= adev
->mc
.aper_base
;
416 r
= amdgpu_modeset_create_props(adev
);
420 adev
->ddev
->mode_config
.max_width
= 16384;
421 adev
->ddev
->mode_config
.max_height
= 16384;
424 for (i
= 0; i
< adev
->mode_info
.num_crtc
; i
++) {
425 r
= dce_virtual_crtc_init(adev
, i
);
430 dce_virtual_get_connector_info(adev
);
431 amdgpu_print_display_setup(adev
->ddev
);
433 drm_kms_helper_poll_init(adev
->ddev
);
435 adev
->mode_info
.mode_config_initialized
= true;
439 static int dce_virtual_sw_fini(void *handle
)
441 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
443 kfree(adev
->mode_info
.bios_hardcoded_edid
);
445 drm_kms_helper_poll_fini(adev
->ddev
);
447 drm_mode_config_cleanup(adev
->ddev
);
448 adev
->mode_info
.mode_config_initialized
= false;
452 static int dce_virtual_hw_init(void *handle
)
457 static int dce_virtual_hw_fini(void *handle
)
462 static int dce_virtual_suspend(void *handle
)
464 return dce_virtual_hw_fini(handle
);
467 static int dce_virtual_resume(void *handle
)
471 ret
= dce_virtual_hw_init(handle
);
476 static bool dce_virtual_is_idle(void *handle
)
481 static int dce_virtual_wait_for_idle(void *handle
)
486 static int dce_virtual_soft_reset(void *handle
)
491 static int dce_virtual_set_clockgating_state(void *handle
,
492 enum amd_clockgating_state state
)
497 static int dce_virtual_set_powergating_state(void *handle
,
498 enum amd_powergating_state state
)
503 const struct amd_ip_funcs dce_virtual_ip_funcs
= {
504 .name
= "dce_virtual",
505 .early_init
= dce_virtual_early_init
,
507 .sw_init
= dce_virtual_sw_init
,
508 .sw_fini
= dce_virtual_sw_fini
,
509 .hw_init
= dce_virtual_hw_init
,
510 .hw_fini
= dce_virtual_hw_fini
,
511 .suspend
= dce_virtual_suspend
,
512 .resume
= dce_virtual_resume
,
513 .is_idle
= dce_virtual_is_idle
,
514 .wait_for_idle
= dce_virtual_wait_for_idle
,
515 .soft_reset
= dce_virtual_soft_reset
,
516 .set_clockgating_state
= dce_virtual_set_clockgating_state
,
517 .set_powergating_state
= dce_virtual_set_powergating_state
,
520 /* these are handled by the primary encoders */
521 static void dce_virtual_encoder_prepare(struct drm_encoder
*encoder
)
526 static void dce_virtual_encoder_commit(struct drm_encoder
*encoder
)
532 dce_virtual_encoder_mode_set(struct drm_encoder
*encoder
,
533 struct drm_display_mode
*mode
,
534 struct drm_display_mode
*adjusted_mode
)
539 static void dce_virtual_encoder_disable(struct drm_encoder
*encoder
)
545 dce_virtual_encoder_dpms(struct drm_encoder
*encoder
, int mode
)
550 static bool dce_virtual_encoder_mode_fixup(struct drm_encoder
*encoder
,
551 const struct drm_display_mode
*mode
,
552 struct drm_display_mode
*adjusted_mode
)
555 /* set the active encoder to connector routing */
556 amdgpu_encoder_set_active_device(encoder
);
561 static const struct drm_encoder_helper_funcs dce_virtual_encoder_helper_funcs
= {
562 .dpms
= dce_virtual_encoder_dpms
,
563 .mode_fixup
= dce_virtual_encoder_mode_fixup
,
564 .prepare
= dce_virtual_encoder_prepare
,
565 .mode_set
= dce_virtual_encoder_mode_set
,
566 .commit
= dce_virtual_encoder_commit
,
567 .disable
= dce_virtual_encoder_disable
,
570 static void dce_virtual_encoder_destroy(struct drm_encoder
*encoder
)
572 struct amdgpu_encoder
*amdgpu_encoder
= to_amdgpu_encoder(encoder
);
574 kfree(amdgpu_encoder
->enc_priv
);
575 drm_encoder_cleanup(encoder
);
576 kfree(amdgpu_encoder
);
579 static const struct drm_encoder_funcs dce_virtual_encoder_funcs
= {
580 .destroy
= dce_virtual_encoder_destroy
,
583 static void dce_virtual_encoder_add(struct amdgpu_device
*adev
,
584 uint32_t encoder_enum
,
585 uint32_t supported_device
,
588 struct drm_device
*dev
= adev
->ddev
;
589 struct drm_encoder
*encoder
;
590 struct amdgpu_encoder
*amdgpu_encoder
;
592 /* see if we already added it */
593 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
) {
594 amdgpu_encoder
= to_amdgpu_encoder(encoder
);
595 if (amdgpu_encoder
->encoder_enum
== encoder_enum
) {
596 amdgpu_encoder
->devices
|= supported_device
;
603 amdgpu_encoder
= kzalloc(sizeof(struct amdgpu_encoder
), GFP_KERNEL
);
607 encoder
= &amdgpu_encoder
->base
;
608 encoder
->possible_crtcs
= 0x1;
609 amdgpu_encoder
->enc_priv
= NULL
;
610 amdgpu_encoder
->encoder_enum
= encoder_enum
;
611 amdgpu_encoder
->encoder_id
= (encoder_enum
& OBJECT_ID_MASK
) >> OBJECT_ID_SHIFT
;
612 amdgpu_encoder
->devices
= supported_device
;
613 amdgpu_encoder
->rmx_type
= RMX_OFF
;
614 amdgpu_encoder
->underscan_type
= UNDERSCAN_OFF
;
615 amdgpu_encoder
->is_ext_encoder
= false;
616 amdgpu_encoder
->caps
= caps
;
618 drm_encoder_init(dev
, encoder
, &dce_virtual_encoder_funcs
,
619 DRM_MODE_ENCODER_VIRTUAL
, NULL
);
620 drm_encoder_helper_add(encoder
, &dce_virtual_encoder_helper_funcs
);
621 DRM_INFO("[FM]encoder: %d is VIRTUAL\n", amdgpu_encoder
->encoder_id
);
624 static const struct amdgpu_display_funcs dce_virtual_display_funcs
= {
625 .set_vga_render_state
= &dce_virtual_set_vga_render_state
,
626 .bandwidth_update
= &dce_virtual_bandwidth_update
,
627 .vblank_get_counter
= &dce_virtual_vblank_get_counter
,
628 .vblank_wait
= &dce_virtual_vblank_wait
,
629 .is_display_hung
= &dce_virtual_is_display_hung
,
630 .backlight_set_level
= NULL
,
631 .backlight_get_level
= NULL
,
632 .hpd_sense
= &dce_virtual_hpd_sense
,
633 .hpd_set_polarity
= &dce_virtual_hpd_set_polarity
,
634 .hpd_get_gpio_reg
= &dce_virtual_hpd_get_gpio_reg
,
635 .page_flip
= &dce_virtual_page_flip
,
636 .page_flip_get_scanoutpos
= &dce_virtual_crtc_get_scanoutpos
,
637 .add_encoder
= &dce_virtual_encoder_add
,
638 .add_connector
= &amdgpu_connector_add
,
639 .stop_mc_access
= &dce_virtual_stop_mc_access
,
640 .resume_mc_access
= &dce_virtual_resume_mc_access
,
643 static void dce_virtual_set_display_funcs(struct amdgpu_device
*adev
)
645 if (adev
->mode_info
.funcs
== NULL
)
646 adev
->mode_info
.funcs
= &dce_virtual_display_funcs
;
649 static enum hrtimer_restart
dce_virtual_vblank_timer_handle(struct hrtimer
*vblank_timer
)
651 struct amdgpu_mode_info
*mode_info
= container_of(vblank_timer
, struct amdgpu_mode_info
,vblank_timer
);
652 struct amdgpu_device
*adev
= container_of(mode_info
, struct amdgpu_device
,mode_info
);
654 drm_handle_vblank(adev
->ddev
, crtc
);
655 dce_virtual_pageflip_irq(adev
, NULL
, NULL
);
656 hrtimer_start(vblank_timer
, ktime_set(0, DCE_VIRTUAL_VBLANK_PERIOD
), HRTIMER_MODE_REL
);
657 return HRTIMER_NORESTART
;
660 static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device
*adev
,
662 enum amdgpu_interrupt_state state
)
664 if (crtc
>= adev
->mode_info
.num_crtc
) {
665 DRM_DEBUG("invalid crtc %d\n", crtc
);
669 if (state
&& !adev
->mode_info
.vsync_timer_enabled
) {
670 DRM_DEBUG("Enable software vsync timer\n");
671 hrtimer_init(&adev
->mode_info
.vblank_timer
, CLOCK_MONOTONIC
, HRTIMER_MODE_REL
);
672 hrtimer_set_expires(&adev
->mode_info
.vblank_timer
, ktime_set(0, DCE_VIRTUAL_VBLANK_PERIOD
));
673 adev
->mode_info
.vblank_timer
.function
= dce_virtual_vblank_timer_handle
;
674 hrtimer_start(&adev
->mode_info
.vblank_timer
, ktime_set(0, DCE_VIRTUAL_VBLANK_PERIOD
), HRTIMER_MODE_REL
);
675 } else if (!state
&& adev
->mode_info
.vsync_timer_enabled
) {
676 DRM_DEBUG("Disable software vsync timer\n");
677 hrtimer_cancel(&adev
->mode_info
.vblank_timer
);
680 adev
->mode_info
.vsync_timer_enabled
= state
;
681 DRM_DEBUG("[FM]set crtc %d vblank interrupt state %d\n", crtc
, state
);
685 static int dce_virtual_set_crtc_irq_state(struct amdgpu_device
*adev
,
686 struct amdgpu_irq_src
*source
,
688 enum amdgpu_interrupt_state state
)
691 case AMDGPU_CRTC_IRQ_VBLANK1
:
692 dce_virtual_set_crtc_vblank_interrupt_state(adev
, 0, state
);
700 static void dce_virtual_crtc_vblank_int_ack(struct amdgpu_device
*adev
,
703 if (crtc
>= adev
->mode_info
.num_crtc
) {
704 DRM_DEBUG("invalid crtc %d\n", crtc
);
709 static int dce_virtual_crtc_irq(struct amdgpu_device
*adev
,
710 struct amdgpu_irq_src
*source
,
711 struct amdgpu_iv_entry
*entry
)
714 unsigned irq_type
= AMDGPU_CRTC_IRQ_VBLANK1
;
716 dce_virtual_crtc_vblank_int_ack(adev
, crtc
);
718 if (amdgpu_irq_enabled(adev
, source
, irq_type
)) {
719 drm_handle_vblank(adev
->ddev
, crtc
);
721 dce_virtual_pageflip_irq(adev
, NULL
, NULL
);
722 DRM_DEBUG("IH: D%d vblank\n", crtc
+ 1);
726 static int dce_virtual_set_pageflip_irq_state(struct amdgpu_device
*adev
,
727 struct amdgpu_irq_src
*src
,
729 enum amdgpu_interrupt_state state
)
731 if (type
>= adev
->mode_info
.num_crtc
) {
732 DRM_ERROR("invalid pageflip crtc %d\n", type
);
735 DRM_DEBUG("[FM]set pageflip irq type %d state %d\n", type
, state
);
740 static int dce_virtual_pageflip_irq(struct amdgpu_device
*adev
,
741 struct amdgpu_irq_src
*source
,
742 struct amdgpu_iv_entry
*entry
)
745 unsigned crtc_id
= 0;
746 struct amdgpu_crtc
*amdgpu_crtc
;
747 struct amdgpu_flip_work
*works
;
750 amdgpu_crtc
= adev
->mode_info
.crtcs
[crtc_id
];
752 if (crtc_id
>= adev
->mode_info
.num_crtc
) {
753 DRM_ERROR("invalid pageflip crtc %d\n", crtc_id
);
757 /* IRQ could occur when in initial stage */
758 if (amdgpu_crtc
== NULL
)
761 spin_lock_irqsave(&adev
->ddev
->event_lock
, flags
);
762 works
= amdgpu_crtc
->pflip_works
;
763 if (amdgpu_crtc
->pflip_status
!= AMDGPU_FLIP_SUBMITTED
) {
764 DRM_DEBUG_DRIVER("amdgpu_crtc->pflip_status = %d != "
765 "AMDGPU_FLIP_SUBMITTED(%d)\n",
766 amdgpu_crtc
->pflip_status
,
767 AMDGPU_FLIP_SUBMITTED
);
768 spin_unlock_irqrestore(&adev
->ddev
->event_lock
, flags
);
772 /* page flip completed. clean up */
773 amdgpu_crtc
->pflip_status
= AMDGPU_FLIP_NONE
;
774 amdgpu_crtc
->pflip_works
= NULL
;
776 /* wakeup usersapce */
778 drm_crtc_send_vblank_event(&amdgpu_crtc
->base
, works
->event
);
780 spin_unlock_irqrestore(&adev
->ddev
->event_lock
, flags
);
782 drm_crtc_vblank_put(&amdgpu_crtc
->base
);
783 schedule_work(&works
->unpin_work
);
788 static const struct amdgpu_irq_src_funcs dce_virtual_crtc_irq_funcs
= {
789 .set
= dce_virtual_set_crtc_irq_state
,
790 .process
= dce_virtual_crtc_irq
,
793 static const struct amdgpu_irq_src_funcs dce_virtual_pageflip_irq_funcs
= {
794 .set
= dce_virtual_set_pageflip_irq_state
,
795 .process
= dce_virtual_pageflip_irq
,
798 static void dce_virtual_set_irq_funcs(struct amdgpu_device
*adev
)
800 adev
->crtc_irq
.num_types
= AMDGPU_CRTC_IRQ_LAST
;
801 adev
->crtc_irq
.funcs
= &dce_virtual_crtc_irq_funcs
;
803 adev
->pageflip_irq
.num_types
= AMDGPU_PAGEFLIP_IRQ_LAST
;
804 adev
->pageflip_irq
.funcs
= &dce_virtual_pageflip_irq_funcs
;