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