hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
....@@ -20,7 +20,9 @@
2020 * OTHER DEALINGS IN THE SOFTWARE.
2121 *
2222 */
23
-#include <drm/drmP.h>
23
+
24
+#include <drm/drm_vblank.h>
25
+
2426 #include "amdgpu.h"
2527 #include "amdgpu_pm.h"
2628 #include "amdgpu_i2c.h"
....@@ -45,6 +47,9 @@
4547 static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev);
4648 static int dce_virtual_connector_encoder_init(struct amdgpu_device *adev,
4749 int index);
50
+static int dce_virtual_pageflip(struct amdgpu_device *adev,
51
+ unsigned crtc_id);
52
+static enum hrtimer_restart dce_virtual_vblank_timer_handle(struct hrtimer *vblank_timer);
4853 static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *adev,
4954 int crtc,
5055 enum amdgpu_interrupt_state state);
....@@ -121,12 +126,16 @@
121126 .set_config = amdgpu_display_crtc_set_config,
122127 .destroy = dce_virtual_crtc_destroy,
123128 .page_flip_target = amdgpu_display_crtc_page_flip_target,
129
+ .get_vblank_counter = amdgpu_get_vblank_counter_kms,
130
+ .enable_vblank = amdgpu_enable_vblank_kms,
131
+ .disable_vblank = amdgpu_disable_vblank_kms,
132
+ .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
124133 };
125134
126135 static void dce_virtual_crtc_dpms(struct drm_crtc *crtc, int mode)
127136 {
128137 struct drm_device *dev = crtc->dev;
129
- struct amdgpu_device *adev = dev->dev_private;
138
+ struct amdgpu_device *adev = drm_to_adev(dev);
130139 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
131140 unsigned type;
132141
....@@ -165,22 +174,12 @@
165174 static void dce_virtual_crtc_disable(struct drm_crtc *crtc)
166175 {
167176 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
177
+ struct drm_device *dev = crtc->dev;
168178
169
- dce_virtual_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
170
- if (crtc->primary->fb) {
171
- int r;
172
- struct amdgpu_bo *abo;
179
+ if (dev->num_crtcs)
180
+ drm_crtc_vblank_off(crtc);
173181
174
- abo = gem_to_amdgpu_bo(crtc->primary->fb->obj[0]);
175
- r = amdgpu_bo_reserve(abo, true);
176
- if (unlikely(r))
177
- DRM_ERROR("failed to reserve abo before unpin\n");
178
- else {
179
- amdgpu_bo_unpin(abo);
180
- amdgpu_bo_unreserve(abo);
181
- }
182
- }
183
-
182
+ amdgpu_crtc->enabled = false;
184183 amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
185184 amdgpu_crtc->encoder = NULL;
186185 amdgpu_crtc->connector = NULL;
....@@ -229,6 +228,7 @@
229228 .prepare = dce_virtual_crtc_prepare,
230229 .commit = dce_virtual_crtc_commit,
231230 .disable = dce_virtual_crtc_disable,
231
+ .get_scanout_position = amdgpu_crtc_get_scanout_position,
232232 };
233233
234234 static int dce_virtual_crtc_init(struct amdgpu_device *adev, int index)
....@@ -240,7 +240,7 @@
240240 if (amdgpu_crtc == NULL)
241241 return -ENOMEM;
242242
243
- drm_crtc_init(adev->ddev, &amdgpu_crtc->base, &dce_virtual_crtc_funcs);
243
+ drm_crtc_init(adev_to_drm(adev), &amdgpu_crtc->base, &dce_virtual_crtc_funcs);
244244
245245 drm_mode_crtc_set_gamma_size(&amdgpu_crtc->base, 256);
246246 amdgpu_crtc->crtc_id = index;
....@@ -252,6 +252,11 @@
252252 amdgpu_crtc->vsync_timer_enabled = AMDGPU_IRQ_STATE_DISABLE;
253253 drm_crtc_helper_add(&amdgpu_crtc->base, &dce_virtual_crtc_helper_funcs);
254254
255
+ hrtimer_init(&amdgpu_crtc->vblank_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
256
+ hrtimer_set_expires(&amdgpu_crtc->vblank_timer, DCE_VIRTUAL_VBLANK_PERIOD);
257
+ amdgpu_crtc->vblank_timer.function = dce_virtual_vblank_timer_handle;
258
+ hrtimer_start(&amdgpu_crtc->vblank_timer,
259
+ DCE_VIRTUAL_VBLANK_PERIOD, HRTIMER_MODE_REL);
255260 return 0;
256261 }
257262
....@@ -271,15 +276,14 @@
271276 dce_virtual_encoder(struct drm_connector *connector)
272277 {
273278 struct drm_encoder *encoder;
274
- int i;
275279
276
- drm_connector_for_each_possible_encoder(connector, encoder, i) {
280
+ drm_connector_for_each_possible_encoder(connector, encoder) {
277281 if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL)
278282 return encoder;
279283 }
280284
281285 /* pick the first one */
282
- drm_connector_for_each_possible_encoder(connector, encoder, i)
286
+ drm_connector_for_each_possible_encoder(connector, encoder)
283287 return encoder;
284288
285289 return NULL;
....@@ -293,7 +297,7 @@
293297 static const struct mode_size {
294298 int w;
295299 int h;
296
- } common_modes[17] = {
300
+ } common_modes[21] = {
297301 { 640, 480},
298302 { 720, 480},
299303 { 800, 600},
....@@ -310,10 +314,14 @@
310314 {1680, 1050},
311315 {1600, 1200},
312316 {1920, 1080},
313
- {1920, 1200}
317
+ {1920, 1200},
318
+ {4096, 3112},
319
+ {3656, 2664},
320
+ {3840, 2160},
321
+ {4096, 2160},
314322 };
315323
316
- for (i = 0; i < 17; i++) {
324
+ for (i = 0; i < 21; i++) {
317325 mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false);
318326 drm_mode_probed_add(connector, mode);
319327 }
....@@ -372,28 +380,28 @@
372380 int r, i;
373381 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
374382
375
- r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SMU_DISP_TIMER2_TRIGGER, &adev->crtc_irq);
383
+ r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SMU_DISP_TIMER2_TRIGGER, &adev->crtc_irq);
376384 if (r)
377385 return r;
378386
379
- adev->ddev->max_vblank_count = 0;
387
+ adev_to_drm(adev)->max_vblank_count = 0;
380388
381
- adev->ddev->mode_config.funcs = &amdgpu_mode_funcs;
389
+ adev_to_drm(adev)->mode_config.funcs = &amdgpu_mode_funcs;
382390
383
- adev->ddev->mode_config.max_width = 16384;
384
- adev->ddev->mode_config.max_height = 16384;
391
+ adev_to_drm(adev)->mode_config.max_width = 16384;
392
+ adev_to_drm(adev)->mode_config.max_height = 16384;
385393
386
- adev->ddev->mode_config.preferred_depth = 24;
387
- adev->ddev->mode_config.prefer_shadow = 1;
394
+ adev_to_drm(adev)->mode_config.preferred_depth = 24;
395
+ adev_to_drm(adev)->mode_config.prefer_shadow = 1;
388396
389
- adev->ddev->mode_config.fb_base = adev->gmc.aper_base;
397
+ adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
390398
391399 r = amdgpu_display_modeset_create_props(adev);
392400 if (r)
393401 return r;
394402
395
- adev->ddev->mode_config.max_width = 16384;
396
- adev->ddev->mode_config.max_height = 16384;
403
+ adev_to_drm(adev)->mode_config.max_width = 16384;
404
+ adev_to_drm(adev)->mode_config.max_height = 16384;
397405
398406 /* allocate crtcs, encoders, connectors */
399407 for (i = 0; i < adev->mode_info.num_crtc; i++) {
....@@ -405,7 +413,7 @@
405413 return r;
406414 }
407415
408
- drm_kms_helper_poll_init(adev->ddev);
416
+ drm_kms_helper_poll_init(adev_to_drm(adev));
409417
410418 adev->mode_info.mode_config_initialized = true;
411419 return 0;
....@@ -417,9 +425,9 @@
417425
418426 kfree(adev->mode_info.bios_hardcoded_edid);
419427
420
- drm_kms_helper_poll_fini(adev->ddev);
428
+ drm_kms_helper_poll_fini(adev_to_drm(adev));
421429
422
- drm_mode_config_cleanup(adev->ddev);
430
+ drm_mode_config_cleanup(adev_to_drm(adev));
423431 /* clear crtcs pointer to avoid dce irq finish routine access freed data */
424432 memset(adev->mode_info.crtcs, 0, sizeof(adev->mode_info.crtcs[0]) * AMDGPU_MAX_CRTCS);
425433 adev->mode_info.mode_config_initialized = false;
....@@ -465,12 +473,8 @@
465473 #endif
466474 /* no DCE */
467475 break;
468
- case CHIP_VEGA10:
469
- case CHIP_VEGA12:
470
- case CHIP_VEGA20:
471
- break;
472476 default:
473
- DRM_ERROR("Virtual display unsupported ASIC type: 0x%X\n", adev->asic_type);
477
+ break;
474478 }
475479 return 0;
476480 }
....@@ -482,7 +486,7 @@
482486
483487 for (i = 0; i<adev->mode_info.num_crtc; i++)
484488 if (adev->mode_info.crtcs[i])
485
- dce_virtual_set_crtc_vblank_interrupt_state(adev, i, AMDGPU_IRQ_STATE_DISABLE);
489
+ hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
486490
487491 return 0;
488492 }
....@@ -608,7 +612,7 @@
608612 if (!encoder)
609613 return -ENOMEM;
610614 encoder->possible_crtcs = 1 << index;
611
- drm_encoder_init(adev->ddev, encoder, &dce_virtual_encoder_funcs,
615
+ drm_encoder_init(adev_to_drm(adev), encoder, &dce_virtual_encoder_funcs,
612616 DRM_MODE_ENCODER_VIRTUAL, NULL);
613617 drm_encoder_helper_add(encoder, &dce_virtual_encoder_helper_funcs);
614618
....@@ -619,13 +623,12 @@
619623 }
620624
621625 /* add a new connector */
622
- drm_connector_init(adev->ddev, connector, &dce_virtual_connector_funcs,
626
+ drm_connector_init(adev_to_drm(adev), connector, &dce_virtual_connector_funcs,
623627 DRM_MODE_CONNECTOR_VIRTUAL);
624628 drm_connector_helper_add(connector, &dce_virtual_connector_helper_funcs);
625629 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
626630 connector->interlace_allowed = false;
627631 connector->doublescan_allowed = false;
628
- drm_connector_register(connector);
629632
630633 /* link them */
631634 drm_connector_attach_encoder(connector, encoder);
....@@ -649,8 +652,7 @@
649652
650653 static void dce_virtual_set_display_funcs(struct amdgpu_device *adev)
651654 {
652
- if (adev->mode_info.funcs == NULL)
653
- adev->mode_info.funcs = &dce_virtual_display_funcs;
655
+ adev->mode_info.funcs = &dce_virtual_display_funcs;
654656 }
655657
656658 static int dce_virtual_pageflip(struct amdgpu_device *adev,
....@@ -671,14 +673,14 @@
671673 if (amdgpu_crtc == NULL)
672674 return 0;
673675
674
- spin_lock_irqsave(&adev->ddev->event_lock, flags);
676
+ spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags);
675677 works = amdgpu_crtc->pflip_works;
676678 if (amdgpu_crtc->pflip_status != AMDGPU_FLIP_SUBMITTED) {
677679 DRM_DEBUG_DRIVER("amdgpu_crtc->pflip_status = %d != "
678680 "AMDGPU_FLIP_SUBMITTED(%d)\n",
679681 amdgpu_crtc->pflip_status,
680682 AMDGPU_FLIP_SUBMITTED);
681
- spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
683
+ spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
682684 return 0;
683685 }
684686
....@@ -690,10 +692,12 @@
690692 if (works->event)
691693 drm_crtc_send_vblank_event(&amdgpu_crtc->base, works->event);
692694
693
- spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
695
+ spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
694696
695697 drm_crtc_vblank_put(&amdgpu_crtc->base);
696
- schedule_work(&works->unpin_work);
698
+ amdgpu_bo_unref(&works->old_abo);
699
+ kfree(works->shared);
700
+ kfree(works);
697701
698702 return 0;
699703 }
....@@ -703,10 +707,16 @@
703707 struct amdgpu_crtc *amdgpu_crtc = container_of(vblank_timer,
704708 struct amdgpu_crtc, vblank_timer);
705709 struct drm_device *ddev = amdgpu_crtc->base.dev;
706
- struct amdgpu_device *adev = ddev->dev_private;
710
+ struct amdgpu_device *adev = drm_to_adev(ddev);
711
+ struct amdgpu_irq_src *source = adev->irq.client[AMDGPU_IRQ_CLIENTID_LEGACY].sources
712
+ [VISLANDS30_IV_SRCID_SMU_DISP_TIMER2_TRIGGER];
713
+ int irq_type = amdgpu_display_crtc_idx_to_irq_type(adev,
714
+ amdgpu_crtc->crtc_id);
707715
708
- drm_handle_vblank(ddev, amdgpu_crtc->crtc_id);
709
- dce_virtual_pageflip(adev, amdgpu_crtc->crtc_id);
716
+ if (amdgpu_irq_enabled(adev, source, irq_type)) {
717
+ drm_handle_vblank(ddev, amdgpu_crtc->crtc_id);
718
+ dce_virtual_pageflip(adev, amdgpu_crtc->crtc_id);
719
+ }
710720 hrtimer_start(vblank_timer, DCE_VIRTUAL_VBLANK_PERIOD,
711721 HRTIMER_MODE_REL);
712722
....@@ -720,21 +730,6 @@
720730 if (crtc >= adev->mode_info.num_crtc || !adev->mode_info.crtcs[crtc]) {
721731 DRM_DEBUG("invalid crtc %d\n", crtc);
722732 return;
723
- }
724
-
725
- if (state && !adev->mode_info.crtcs[crtc]->vsync_timer_enabled) {
726
- DRM_DEBUG("Enable software vsync timer\n");
727
- hrtimer_init(&adev->mode_info.crtcs[crtc]->vblank_timer,
728
- CLOCK_MONOTONIC, HRTIMER_MODE_REL);
729
- hrtimer_set_expires(&adev->mode_info.crtcs[crtc]->vblank_timer,
730
- DCE_VIRTUAL_VBLANK_PERIOD);
731
- adev->mode_info.crtcs[crtc]->vblank_timer.function =
732
- dce_virtual_vblank_timer_handle;
733
- hrtimer_start(&adev->mode_info.crtcs[crtc]->vblank_timer,
734
- DCE_VIRTUAL_VBLANK_PERIOD, HRTIMER_MODE_REL);
735
- } else if (!state && adev->mode_info.crtcs[crtc]->vsync_timer_enabled) {
736
- DRM_DEBUG("Disable software vsync timer\n");
737
- hrtimer_cancel(&adev->mode_info.crtcs[crtc]->vblank_timer);
738733 }
739734
740735 adev->mode_info.crtcs[crtc]->vsync_timer_enabled = state;