Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.9-rc6 770 lines 20 kB view raw
1/* 2 * Copyright 2014 Advanced Micro Devices, Inc. 3 * 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: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 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. 21 * 22 */ 23 24#include <drm/drm_vblank.h> 25 26#include "amdgpu.h" 27#include "amdgpu_pm.h" 28#include "amdgpu_i2c.h" 29#include "atom.h" 30#include "amdgpu_pll.h" 31#include "amdgpu_connectors.h" 32#ifdef CONFIG_DRM_AMDGPU_SI 33#include "dce_v6_0.h" 34#endif 35#ifdef CONFIG_DRM_AMDGPU_CIK 36#include "dce_v8_0.h" 37#endif 38#include "dce_v10_0.h" 39#include "dce_v11_0.h" 40#include "dce_virtual.h" 41#include "ivsrcid/ivsrcid_vislands30.h" 42 43#define DCE_VIRTUAL_VBLANK_PERIOD 16666666 44 45 46static void dce_virtual_set_display_funcs(struct amdgpu_device *adev); 47static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev); 48static int dce_virtual_connector_encoder_init(struct amdgpu_device *adev, 49 int index); 50static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *adev, 51 int crtc, 52 enum amdgpu_interrupt_state state); 53 54static u32 dce_virtual_vblank_get_counter(struct amdgpu_device *adev, int crtc) 55{ 56 return 0; 57} 58 59static void dce_virtual_page_flip(struct amdgpu_device *adev, 60 int crtc_id, u64 crtc_base, bool async) 61{ 62 return; 63} 64 65static int dce_virtual_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc, 66 u32 *vbl, u32 *position) 67{ 68 *vbl = 0; 69 *position = 0; 70 71 return -EINVAL; 72} 73 74static bool dce_virtual_hpd_sense(struct amdgpu_device *adev, 75 enum amdgpu_hpd_id hpd) 76{ 77 return true; 78} 79 80static void dce_virtual_hpd_set_polarity(struct amdgpu_device *adev, 81 enum amdgpu_hpd_id hpd) 82{ 83 return; 84} 85 86static u32 dce_virtual_hpd_get_gpio_reg(struct amdgpu_device *adev) 87{ 88 return 0; 89} 90 91/** 92 * dce_virtual_bandwidth_update - program display watermarks 93 * 94 * @adev: amdgpu_device pointer 95 * 96 * Calculate and program the display watermarks and line 97 * buffer allocation (CIK). 98 */ 99static void dce_virtual_bandwidth_update(struct amdgpu_device *adev) 100{ 101 return; 102} 103 104static int dce_virtual_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, 105 u16 *green, u16 *blue, uint32_t size, 106 struct drm_modeset_acquire_ctx *ctx) 107{ 108 return 0; 109} 110 111static void dce_virtual_crtc_destroy(struct drm_crtc *crtc) 112{ 113 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 114 115 drm_crtc_cleanup(crtc); 116 kfree(amdgpu_crtc); 117} 118 119static const struct drm_crtc_funcs dce_virtual_crtc_funcs = { 120 .cursor_set2 = NULL, 121 .cursor_move = NULL, 122 .gamma_set = dce_virtual_crtc_gamma_set, 123 .set_config = amdgpu_display_crtc_set_config, 124 .destroy = dce_virtual_crtc_destroy, 125 .page_flip_target = amdgpu_display_crtc_page_flip_target, 126 .get_vblank_counter = amdgpu_get_vblank_counter_kms, 127 .enable_vblank = amdgpu_enable_vblank_kms, 128 .disable_vblank = amdgpu_disable_vblank_kms, 129 .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp, 130}; 131 132static void dce_virtual_crtc_dpms(struct drm_crtc *crtc, int mode) 133{ 134 struct drm_device *dev = crtc->dev; 135 struct amdgpu_device *adev = dev->dev_private; 136 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 137 unsigned type; 138 139 if (amdgpu_sriov_vf(adev)) 140 return; 141 142 switch (mode) { 143 case DRM_MODE_DPMS_ON: 144 amdgpu_crtc->enabled = true; 145 /* Make sure VBLANK interrupts are still enabled */ 146 type = amdgpu_display_crtc_idx_to_irq_type(adev, 147 amdgpu_crtc->crtc_id); 148 amdgpu_irq_update(adev, &adev->crtc_irq, type); 149 drm_crtc_vblank_on(crtc); 150 break; 151 case DRM_MODE_DPMS_STANDBY: 152 case DRM_MODE_DPMS_SUSPEND: 153 case DRM_MODE_DPMS_OFF: 154 drm_crtc_vblank_off(crtc); 155 amdgpu_crtc->enabled = false; 156 break; 157 } 158} 159 160 161static void dce_virtual_crtc_prepare(struct drm_crtc *crtc) 162{ 163 dce_virtual_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 164} 165 166static void dce_virtual_crtc_commit(struct drm_crtc *crtc) 167{ 168 dce_virtual_crtc_dpms(crtc, DRM_MODE_DPMS_ON); 169} 170 171static void dce_virtual_crtc_disable(struct drm_crtc *crtc) 172{ 173 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 174 175 drm_crtc_vblank_off(crtc); 176 177 amdgpu_crtc->enabled = false; 178 amdgpu_crtc->pll_id = ATOM_PPLL_INVALID; 179 amdgpu_crtc->encoder = NULL; 180 amdgpu_crtc->connector = NULL; 181} 182 183static int dce_virtual_crtc_mode_set(struct drm_crtc *crtc, 184 struct drm_display_mode *mode, 185 struct drm_display_mode *adjusted_mode, 186 int x, int y, struct drm_framebuffer *old_fb) 187{ 188 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 189 190 /* update the hw version fpr dpm */ 191 amdgpu_crtc->hw_mode = *adjusted_mode; 192 193 return 0; 194} 195 196static bool dce_virtual_crtc_mode_fixup(struct drm_crtc *crtc, 197 const struct drm_display_mode *mode, 198 struct drm_display_mode *adjusted_mode) 199{ 200 return true; 201} 202 203 204static int dce_virtual_crtc_set_base(struct drm_crtc *crtc, int x, int y, 205 struct drm_framebuffer *old_fb) 206{ 207 return 0; 208} 209 210static int dce_virtual_crtc_set_base_atomic(struct drm_crtc *crtc, 211 struct drm_framebuffer *fb, 212 int x, int y, enum mode_set_atomic state) 213{ 214 return 0; 215} 216 217static const struct drm_crtc_helper_funcs dce_virtual_crtc_helper_funcs = { 218 .dpms = dce_virtual_crtc_dpms, 219 .mode_fixup = dce_virtual_crtc_mode_fixup, 220 .mode_set = dce_virtual_crtc_mode_set, 221 .mode_set_base = dce_virtual_crtc_set_base, 222 .mode_set_base_atomic = dce_virtual_crtc_set_base_atomic, 223 .prepare = dce_virtual_crtc_prepare, 224 .commit = dce_virtual_crtc_commit, 225 .disable = dce_virtual_crtc_disable, 226 .get_scanout_position = amdgpu_crtc_get_scanout_position, 227}; 228 229static int dce_virtual_crtc_init(struct amdgpu_device *adev, int index) 230{ 231 struct amdgpu_crtc *amdgpu_crtc; 232 233 amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) + 234 (AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); 235 if (amdgpu_crtc == NULL) 236 return -ENOMEM; 237 238 drm_crtc_init(adev->ddev, &amdgpu_crtc->base, &dce_virtual_crtc_funcs); 239 240 drm_mode_crtc_set_gamma_size(&amdgpu_crtc->base, 256); 241 amdgpu_crtc->crtc_id = index; 242 adev->mode_info.crtcs[index] = amdgpu_crtc; 243 244 amdgpu_crtc->pll_id = ATOM_PPLL_INVALID; 245 amdgpu_crtc->encoder = NULL; 246 amdgpu_crtc->connector = NULL; 247 amdgpu_crtc->vsync_timer_enabled = AMDGPU_IRQ_STATE_DISABLE; 248 drm_crtc_helper_add(&amdgpu_crtc->base, &dce_virtual_crtc_helper_funcs); 249 250 return 0; 251} 252 253static int dce_virtual_early_init(void *handle) 254{ 255 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 256 257 dce_virtual_set_display_funcs(adev); 258 dce_virtual_set_irq_funcs(adev); 259 260 adev->mode_info.num_hpd = 1; 261 adev->mode_info.num_dig = 1; 262 return 0; 263} 264 265static struct drm_encoder * 266dce_virtual_encoder(struct drm_connector *connector) 267{ 268 struct drm_encoder *encoder; 269 270 drm_connector_for_each_possible_encoder(connector, encoder) { 271 if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL) 272 return encoder; 273 } 274 275 /* pick the first one */ 276 drm_connector_for_each_possible_encoder(connector, encoder) 277 return encoder; 278 279 return NULL; 280} 281 282static int dce_virtual_get_modes(struct drm_connector *connector) 283{ 284 struct drm_device *dev = connector->dev; 285 struct drm_display_mode *mode = NULL; 286 unsigned i; 287 static const struct mode_size { 288 int w; 289 int h; 290 } common_modes[21] = { 291 { 640, 480}, 292 { 720, 480}, 293 { 800, 600}, 294 { 848, 480}, 295 {1024, 768}, 296 {1152, 768}, 297 {1280, 720}, 298 {1280, 800}, 299 {1280, 854}, 300 {1280, 960}, 301 {1280, 1024}, 302 {1440, 900}, 303 {1400, 1050}, 304 {1680, 1050}, 305 {1600, 1200}, 306 {1920, 1080}, 307 {1920, 1200}, 308 {4096, 3112}, 309 {3656, 2664}, 310 {3840, 2160}, 311 {4096, 2160}, 312 }; 313 314 for (i = 0; i < 21; i++) { 315 mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false); 316 drm_mode_probed_add(connector, mode); 317 } 318 319 return 0; 320} 321 322static enum drm_mode_status dce_virtual_mode_valid(struct drm_connector *connector, 323 struct drm_display_mode *mode) 324{ 325 return MODE_OK; 326} 327 328static int 329dce_virtual_dpms(struct drm_connector *connector, int mode) 330{ 331 return 0; 332} 333 334static int 335dce_virtual_set_property(struct drm_connector *connector, 336 struct drm_property *property, 337 uint64_t val) 338{ 339 return 0; 340} 341 342static void dce_virtual_destroy(struct drm_connector *connector) 343{ 344 drm_connector_unregister(connector); 345 drm_connector_cleanup(connector); 346 kfree(connector); 347} 348 349static void dce_virtual_force(struct drm_connector *connector) 350{ 351 return; 352} 353 354static const struct drm_connector_helper_funcs dce_virtual_connector_helper_funcs = { 355 .get_modes = dce_virtual_get_modes, 356 .mode_valid = dce_virtual_mode_valid, 357 .best_encoder = dce_virtual_encoder, 358}; 359 360static const struct drm_connector_funcs dce_virtual_connector_funcs = { 361 .dpms = dce_virtual_dpms, 362 .fill_modes = drm_helper_probe_single_connector_modes, 363 .set_property = dce_virtual_set_property, 364 .destroy = dce_virtual_destroy, 365 .force = dce_virtual_force, 366}; 367 368static int dce_virtual_sw_init(void *handle) 369{ 370 int r, i; 371 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 372 373 r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SMU_DISP_TIMER2_TRIGGER, &adev->crtc_irq); 374 if (r) 375 return r; 376 377 adev->ddev->max_vblank_count = 0; 378 379 adev->ddev->mode_config.funcs = &amdgpu_mode_funcs; 380 381 adev->ddev->mode_config.max_width = 16384; 382 adev->ddev->mode_config.max_height = 16384; 383 384 adev->ddev->mode_config.preferred_depth = 24; 385 adev->ddev->mode_config.prefer_shadow = 1; 386 387 adev->ddev->mode_config.fb_base = adev->gmc.aper_base; 388 389 r = amdgpu_display_modeset_create_props(adev); 390 if (r) 391 return r; 392 393 adev->ddev->mode_config.max_width = 16384; 394 adev->ddev->mode_config.max_height = 16384; 395 396 /* allocate crtcs, encoders, connectors */ 397 for (i = 0; i < adev->mode_info.num_crtc; i++) { 398 r = dce_virtual_crtc_init(adev, i); 399 if (r) 400 return r; 401 r = dce_virtual_connector_encoder_init(adev, i); 402 if (r) 403 return r; 404 } 405 406 drm_kms_helper_poll_init(adev->ddev); 407 408 adev->mode_info.mode_config_initialized = true; 409 return 0; 410} 411 412static int dce_virtual_sw_fini(void *handle) 413{ 414 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 415 416 kfree(adev->mode_info.bios_hardcoded_edid); 417 418 drm_kms_helper_poll_fini(adev->ddev); 419 420 drm_mode_config_cleanup(adev->ddev); 421 /* clear crtcs pointer to avoid dce irq finish routine access freed data */ 422 memset(adev->mode_info.crtcs, 0, sizeof(adev->mode_info.crtcs[0]) * AMDGPU_MAX_CRTCS); 423 adev->mode_info.mode_config_initialized = false; 424 return 0; 425} 426 427static int dce_virtual_hw_init(void *handle) 428{ 429 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 430 431 switch (adev->asic_type) { 432#ifdef CONFIG_DRM_AMDGPU_SI 433 case CHIP_TAHITI: 434 case CHIP_PITCAIRN: 435 case CHIP_VERDE: 436 case CHIP_OLAND: 437 dce_v6_0_disable_dce(adev); 438 break; 439#endif 440#ifdef CONFIG_DRM_AMDGPU_CIK 441 case CHIP_BONAIRE: 442 case CHIP_HAWAII: 443 case CHIP_KAVERI: 444 case CHIP_KABINI: 445 case CHIP_MULLINS: 446 dce_v8_0_disable_dce(adev); 447 break; 448#endif 449 case CHIP_FIJI: 450 case CHIP_TONGA: 451 dce_v10_0_disable_dce(adev); 452 break; 453 case CHIP_CARRIZO: 454 case CHIP_STONEY: 455 case CHIP_POLARIS10: 456 case CHIP_POLARIS11: 457 case CHIP_VEGAM: 458 dce_v11_0_disable_dce(adev); 459 break; 460 case CHIP_TOPAZ: 461#ifdef CONFIG_DRM_AMDGPU_SI 462 case CHIP_HAINAN: 463#endif 464 /* no DCE */ 465 break; 466 default: 467 break; 468 } 469 return 0; 470} 471 472static int dce_virtual_hw_fini(void *handle) 473{ 474 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 475 int i = 0; 476 477 for (i = 0; i<adev->mode_info.num_crtc; i++) 478 if (adev->mode_info.crtcs[i]) 479 dce_virtual_set_crtc_vblank_interrupt_state(adev, i, AMDGPU_IRQ_STATE_DISABLE); 480 481 return 0; 482} 483 484static int dce_virtual_suspend(void *handle) 485{ 486 return dce_virtual_hw_fini(handle); 487} 488 489static int dce_virtual_resume(void *handle) 490{ 491 return dce_virtual_hw_init(handle); 492} 493 494static bool dce_virtual_is_idle(void *handle) 495{ 496 return true; 497} 498 499static int dce_virtual_wait_for_idle(void *handle) 500{ 501 return 0; 502} 503 504static int dce_virtual_soft_reset(void *handle) 505{ 506 return 0; 507} 508 509static int dce_virtual_set_clockgating_state(void *handle, 510 enum amd_clockgating_state state) 511{ 512 return 0; 513} 514 515static int dce_virtual_set_powergating_state(void *handle, 516 enum amd_powergating_state state) 517{ 518 return 0; 519} 520 521static const struct amd_ip_funcs dce_virtual_ip_funcs = { 522 .name = "dce_virtual", 523 .early_init = dce_virtual_early_init, 524 .late_init = NULL, 525 .sw_init = dce_virtual_sw_init, 526 .sw_fini = dce_virtual_sw_fini, 527 .hw_init = dce_virtual_hw_init, 528 .hw_fini = dce_virtual_hw_fini, 529 .suspend = dce_virtual_suspend, 530 .resume = dce_virtual_resume, 531 .is_idle = dce_virtual_is_idle, 532 .wait_for_idle = dce_virtual_wait_for_idle, 533 .soft_reset = dce_virtual_soft_reset, 534 .set_clockgating_state = dce_virtual_set_clockgating_state, 535 .set_powergating_state = dce_virtual_set_powergating_state, 536}; 537 538/* these are handled by the primary encoders */ 539static void dce_virtual_encoder_prepare(struct drm_encoder *encoder) 540{ 541 return; 542} 543 544static void dce_virtual_encoder_commit(struct drm_encoder *encoder) 545{ 546 return; 547} 548 549static void 550dce_virtual_encoder_mode_set(struct drm_encoder *encoder, 551 struct drm_display_mode *mode, 552 struct drm_display_mode *adjusted_mode) 553{ 554 return; 555} 556 557static void dce_virtual_encoder_disable(struct drm_encoder *encoder) 558{ 559 return; 560} 561 562static void 563dce_virtual_encoder_dpms(struct drm_encoder *encoder, int mode) 564{ 565 return; 566} 567 568static bool dce_virtual_encoder_mode_fixup(struct drm_encoder *encoder, 569 const struct drm_display_mode *mode, 570 struct drm_display_mode *adjusted_mode) 571{ 572 return true; 573} 574 575static const struct drm_encoder_helper_funcs dce_virtual_encoder_helper_funcs = { 576 .dpms = dce_virtual_encoder_dpms, 577 .mode_fixup = dce_virtual_encoder_mode_fixup, 578 .prepare = dce_virtual_encoder_prepare, 579 .mode_set = dce_virtual_encoder_mode_set, 580 .commit = dce_virtual_encoder_commit, 581 .disable = dce_virtual_encoder_disable, 582}; 583 584static void dce_virtual_encoder_destroy(struct drm_encoder *encoder) 585{ 586 drm_encoder_cleanup(encoder); 587 kfree(encoder); 588} 589 590static const struct drm_encoder_funcs dce_virtual_encoder_funcs = { 591 .destroy = dce_virtual_encoder_destroy, 592}; 593 594static int dce_virtual_connector_encoder_init(struct amdgpu_device *adev, 595 int index) 596{ 597 struct drm_encoder *encoder; 598 struct drm_connector *connector; 599 600 /* add a new encoder */ 601 encoder = kzalloc(sizeof(struct drm_encoder), GFP_KERNEL); 602 if (!encoder) 603 return -ENOMEM; 604 encoder->possible_crtcs = 1 << index; 605 drm_encoder_init(adev->ddev, encoder, &dce_virtual_encoder_funcs, 606 DRM_MODE_ENCODER_VIRTUAL, NULL); 607 drm_encoder_helper_add(encoder, &dce_virtual_encoder_helper_funcs); 608 609 connector = kzalloc(sizeof(struct drm_connector), GFP_KERNEL); 610 if (!connector) { 611 kfree(encoder); 612 return -ENOMEM; 613 } 614 615 /* add a new connector */ 616 drm_connector_init(adev->ddev, connector, &dce_virtual_connector_funcs, 617 DRM_MODE_CONNECTOR_VIRTUAL); 618 drm_connector_helper_add(connector, &dce_virtual_connector_helper_funcs); 619 connector->display_info.subpixel_order = SubPixelHorizontalRGB; 620 connector->interlace_allowed = false; 621 connector->doublescan_allowed = false; 622 623 /* link them */ 624 drm_connector_attach_encoder(connector, encoder); 625 626 return 0; 627} 628 629static const struct amdgpu_display_funcs dce_virtual_display_funcs = { 630 .bandwidth_update = &dce_virtual_bandwidth_update, 631 .vblank_get_counter = &dce_virtual_vblank_get_counter, 632 .backlight_set_level = NULL, 633 .backlight_get_level = NULL, 634 .hpd_sense = &dce_virtual_hpd_sense, 635 .hpd_set_polarity = &dce_virtual_hpd_set_polarity, 636 .hpd_get_gpio_reg = &dce_virtual_hpd_get_gpio_reg, 637 .page_flip = &dce_virtual_page_flip, 638 .page_flip_get_scanoutpos = &dce_virtual_crtc_get_scanoutpos, 639 .add_encoder = NULL, 640 .add_connector = NULL, 641}; 642 643static void dce_virtual_set_display_funcs(struct amdgpu_device *adev) 644{ 645 adev->mode_info.funcs = &dce_virtual_display_funcs; 646} 647 648static int dce_virtual_pageflip(struct amdgpu_device *adev, 649 unsigned crtc_id) 650{ 651 unsigned long flags; 652 struct amdgpu_crtc *amdgpu_crtc; 653 struct amdgpu_flip_work *works; 654 655 amdgpu_crtc = adev->mode_info.crtcs[crtc_id]; 656 657 if (crtc_id >= adev->mode_info.num_crtc) { 658 DRM_ERROR("invalid pageflip crtc %d\n", crtc_id); 659 return -EINVAL; 660 } 661 662 /* IRQ could occur when in initial stage */ 663 if (amdgpu_crtc == NULL) 664 return 0; 665 666 spin_lock_irqsave(&adev->ddev->event_lock, flags); 667 works = amdgpu_crtc->pflip_works; 668 if (amdgpu_crtc->pflip_status != AMDGPU_FLIP_SUBMITTED) { 669 DRM_DEBUG_DRIVER("amdgpu_crtc->pflip_status = %d != " 670 "AMDGPU_FLIP_SUBMITTED(%d)\n", 671 amdgpu_crtc->pflip_status, 672 AMDGPU_FLIP_SUBMITTED); 673 spin_unlock_irqrestore(&adev->ddev->event_lock, flags); 674 return 0; 675 } 676 677 /* page flip completed. clean up */ 678 amdgpu_crtc->pflip_status = AMDGPU_FLIP_NONE; 679 amdgpu_crtc->pflip_works = NULL; 680 681 /* wakeup usersapce */ 682 if (works->event) 683 drm_crtc_send_vblank_event(&amdgpu_crtc->base, works->event); 684 685 spin_unlock_irqrestore(&adev->ddev->event_lock, flags); 686 687 drm_crtc_vblank_put(&amdgpu_crtc->base); 688 amdgpu_bo_unref(&works->old_abo); 689 kfree(works->shared); 690 kfree(works); 691 692 return 0; 693} 694 695static enum hrtimer_restart dce_virtual_vblank_timer_handle(struct hrtimer *vblank_timer) 696{ 697 struct amdgpu_crtc *amdgpu_crtc = container_of(vblank_timer, 698 struct amdgpu_crtc, vblank_timer); 699 struct drm_device *ddev = amdgpu_crtc->base.dev; 700 struct amdgpu_device *adev = ddev->dev_private; 701 702 drm_handle_vblank(ddev, amdgpu_crtc->crtc_id); 703 dce_virtual_pageflip(adev, amdgpu_crtc->crtc_id); 704 hrtimer_start(vblank_timer, DCE_VIRTUAL_VBLANK_PERIOD, 705 HRTIMER_MODE_REL); 706 707 return HRTIMER_NORESTART; 708} 709 710static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *adev, 711 int crtc, 712 enum amdgpu_interrupt_state state) 713{ 714 if (crtc >= adev->mode_info.num_crtc || !adev->mode_info.crtcs[crtc]) { 715 DRM_DEBUG("invalid crtc %d\n", crtc); 716 return; 717 } 718 719 if (state && !adev->mode_info.crtcs[crtc]->vsync_timer_enabled) { 720 DRM_DEBUG("Enable software vsync timer\n"); 721 hrtimer_init(&adev->mode_info.crtcs[crtc]->vblank_timer, 722 CLOCK_MONOTONIC, HRTIMER_MODE_REL); 723 hrtimer_set_expires(&adev->mode_info.crtcs[crtc]->vblank_timer, 724 DCE_VIRTUAL_VBLANK_PERIOD); 725 adev->mode_info.crtcs[crtc]->vblank_timer.function = 726 dce_virtual_vblank_timer_handle; 727 hrtimer_start(&adev->mode_info.crtcs[crtc]->vblank_timer, 728 DCE_VIRTUAL_VBLANK_PERIOD, HRTIMER_MODE_REL); 729 } else if (!state && adev->mode_info.crtcs[crtc]->vsync_timer_enabled) { 730 DRM_DEBUG("Disable software vsync timer\n"); 731 hrtimer_cancel(&adev->mode_info.crtcs[crtc]->vblank_timer); 732 } 733 734 adev->mode_info.crtcs[crtc]->vsync_timer_enabled = state; 735 DRM_DEBUG("[FM]set crtc %d vblank interrupt state %d\n", crtc, state); 736} 737 738 739static int dce_virtual_set_crtc_irq_state(struct amdgpu_device *adev, 740 struct amdgpu_irq_src *source, 741 unsigned type, 742 enum amdgpu_interrupt_state state) 743{ 744 if (type > AMDGPU_CRTC_IRQ_VBLANK6) 745 return -EINVAL; 746 747 dce_virtual_set_crtc_vblank_interrupt_state(adev, type, state); 748 749 return 0; 750} 751 752static const struct amdgpu_irq_src_funcs dce_virtual_crtc_irq_funcs = { 753 .set = dce_virtual_set_crtc_irq_state, 754 .process = NULL, 755}; 756 757static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev) 758{ 759 adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_VBLANK6 + 1; 760 adev->crtc_irq.funcs = &dce_virtual_crtc_irq_funcs; 761} 762 763const struct amdgpu_ip_block_version dce_virtual_ip_block = 764{ 765 .type = AMD_IP_BLOCK_TYPE_DCE, 766 .major = 1, 767 .minor = 0, 768 .rev = 0, 769 .funcs = &dce_virtual_ip_funcs, 770};