linux/drivers/gpu/drm/radeon/atombios_crtc.c
<<
>>
Prefs
   1/*
   2 * Copyright 2007-8 Advanced Micro Devices, Inc.
   3 * Copyright 2008 Red Hat Inc.
   4 *
   5 * Permission is hereby granted, free of charge, to any person obtaining a
   6 * copy of this software and associated documentation files (the "Software"),
   7 * to deal in the Software without restriction, including without limitation
   8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   9 * and/or sell copies of the Software, and to permit persons to whom the
  10 * Software is furnished to do so, subject to the following conditions:
  11 *
  12 * The above copyright notice and this permission notice shall be included in
  13 * all copies or substantial portions of the Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  21 * OTHER DEALINGS IN THE SOFTWARE.
  22 *
  23 * Authors: Dave Airlie
  24 *          Alex Deucher
  25 */
  26#include <drm/drmP.h>
  27#include <drm/drm_crtc_helper.h>
  28#include <drm/radeon_drm.h>
  29#include <drm/drm_fixed.h>
  30#include "radeon.h"
  31#include "atom.h"
  32#include "atom-bits.h"
  33
  34static void atombios_overscan_setup(struct drm_crtc *crtc,
  35                                    struct drm_display_mode *mode,
  36                                    struct drm_display_mode *adjusted_mode)
  37{
  38        struct drm_device *dev = crtc->dev;
  39        struct radeon_device *rdev = dev->dev_private;
  40        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
  41        SET_CRTC_OVERSCAN_PS_ALLOCATION args;
  42        int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_OverScan);
  43        int a1, a2;
  44
  45        memset(&args, 0, sizeof(args));
  46
  47        args.ucCRTC = radeon_crtc->crtc_id;
  48
  49        switch (radeon_crtc->rmx_type) {
  50        case RMX_CENTER:
  51                args.usOverscanTop = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2);
  52                args.usOverscanBottom = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2);
  53                args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2);
  54                args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2);
  55                break;
  56        case RMX_ASPECT:
  57                a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay;
  58                a2 = adjusted_mode->crtc_vdisplay * mode->crtc_hdisplay;
  59
  60                if (a1 > a2) {
  61                        args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2);
  62                        args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2);
  63                } else if (a2 > a1) {
  64                        args.usOverscanTop = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2);
  65                        args.usOverscanBottom = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2);
  66                }
  67                break;
  68        case RMX_FULL:
  69        default:
  70                args.usOverscanRight = cpu_to_le16(radeon_crtc->h_border);
  71                args.usOverscanLeft = cpu_to_le16(radeon_crtc->h_border);
  72                args.usOverscanBottom = cpu_to_le16(radeon_crtc->v_border);
  73                args.usOverscanTop = cpu_to_le16(radeon_crtc->v_border);
  74                break;
  75        }
  76        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
  77}
  78
  79static void atombios_scaler_setup(struct drm_crtc *crtc)
  80{
  81        struct drm_device *dev = crtc->dev;
  82        struct radeon_device *rdev = dev->dev_private;
  83        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
  84        ENABLE_SCALER_PS_ALLOCATION args;
  85        int index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
  86
  87        /* fixme - fill in enc_priv for atom dac */
  88        enum radeon_tv_std tv_std = TV_STD_NTSC;
  89        bool is_tv = false, is_cv = false;
  90        struct drm_encoder *encoder;
  91
  92        if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id)
  93                return;
  94
  95        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
  96                /* find tv std */
  97                if (encoder->crtc == crtc) {
  98                        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  99                        if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
 100                                struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
 101                                tv_std = tv_dac->tv_std;
 102                                is_tv = true;
 103                        }
 104                }
 105        }
 106
 107        memset(&args, 0, sizeof(args));
 108
 109        args.ucScaler = radeon_crtc->crtc_id;
 110
 111        if (is_tv) {
 112                switch (tv_std) {
 113                case TV_STD_NTSC:
 114                default:
 115                        args.ucTVStandard = ATOM_TV_NTSC;
 116                        break;
 117                case TV_STD_PAL:
 118                        args.ucTVStandard = ATOM_TV_PAL;
 119                        break;
 120                case TV_STD_PAL_M:
 121                        args.ucTVStandard = ATOM_TV_PALM;
 122                        break;
 123                case TV_STD_PAL_60:
 124                        args.ucTVStandard = ATOM_TV_PAL60;
 125                        break;
 126                case TV_STD_NTSC_J:
 127                        args.ucTVStandard = ATOM_TV_NTSCJ;
 128                        break;
 129                case TV_STD_SCART_PAL:
 130                        args.ucTVStandard = ATOM_TV_PAL; /* ??? */
 131                        break;
 132                case TV_STD_SECAM:
 133                        args.ucTVStandard = ATOM_TV_SECAM;
 134                        break;
 135                case TV_STD_PAL_CN:
 136                        args.ucTVStandard = ATOM_TV_PALCN;
 137                        break;
 138                }
 139                args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
 140        } else if (is_cv) {
 141                args.ucTVStandard = ATOM_TV_CV;
 142                args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
 143        } else {
 144                switch (radeon_crtc->rmx_type) {
 145                case RMX_FULL:
 146                        args.ucEnable = ATOM_SCALER_EXPANSION;
 147                        break;
 148                case RMX_CENTER:
 149                        args.ucEnable = ATOM_SCALER_CENTER;
 150                        break;
 151                case RMX_ASPECT:
 152                        args.ucEnable = ATOM_SCALER_EXPANSION;
 153                        break;
 154                default:
 155                        if (ASIC_IS_AVIVO(rdev))
 156                                args.ucEnable = ATOM_SCALER_DISABLE;
 157                        else
 158                                args.ucEnable = ATOM_SCALER_CENTER;
 159                        break;
 160                }
 161        }
 162        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 163        if ((is_tv || is_cv)
 164            && rdev->family >= CHIP_RV515 && rdev->family <= CHIP_R580) {
 165                atom_rv515_force_tv_scaler(rdev, radeon_crtc);
 166        }
 167}
 168
 169static void atombios_lock_crtc(struct drm_crtc *crtc, int lock)
 170{
 171        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 172        struct drm_device *dev = crtc->dev;
 173        struct radeon_device *rdev = dev->dev_private;
 174        int index =
 175            GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters);
 176        ENABLE_CRTC_PS_ALLOCATION args;
 177
 178        memset(&args, 0, sizeof(args));
 179
 180        args.ucCRTC = radeon_crtc->crtc_id;
 181        args.ucEnable = lock;
 182
 183        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 184}
 185
 186static void atombios_enable_crtc(struct drm_crtc *crtc, int state)
 187{
 188        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 189        struct drm_device *dev = crtc->dev;
 190        struct radeon_device *rdev = dev->dev_private;
 191        int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC);
 192        ENABLE_CRTC_PS_ALLOCATION args;
 193
 194        memset(&args, 0, sizeof(args));
 195
 196        args.ucCRTC = radeon_crtc->crtc_id;
 197        args.ucEnable = state;
 198
 199        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 200}
 201
 202static void atombios_enable_crtc_memreq(struct drm_crtc *crtc, int state)
 203{
 204        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 205        struct drm_device *dev = crtc->dev;
 206        struct radeon_device *rdev = dev->dev_private;
 207        int index = GetIndexIntoMasterTable(COMMAND, EnableCRTCMemReq);
 208        ENABLE_CRTC_PS_ALLOCATION args;
 209
 210        memset(&args, 0, sizeof(args));
 211
 212        args.ucCRTC = radeon_crtc->crtc_id;
 213        args.ucEnable = state;
 214
 215        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 216}
 217
 218static void atombios_blank_crtc(struct drm_crtc *crtc, int state)
 219{
 220        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 221        struct drm_device *dev = crtc->dev;
 222        struct radeon_device *rdev = dev->dev_private;
 223        int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC);
 224        BLANK_CRTC_PS_ALLOCATION args;
 225
 226        memset(&args, 0, sizeof(args));
 227
 228        args.ucCRTC = radeon_crtc->crtc_id;
 229        args.ucBlanking = state;
 230
 231        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 232}
 233
 234static void atombios_powergate_crtc(struct drm_crtc *crtc, int state)
 235{
 236        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 237        struct drm_device *dev = crtc->dev;
 238        struct radeon_device *rdev = dev->dev_private;
 239        int index = GetIndexIntoMasterTable(COMMAND, EnableDispPowerGating);
 240        ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1 args;
 241
 242        memset(&args, 0, sizeof(args));
 243
 244        args.ucDispPipeId = radeon_crtc->crtc_id;
 245        args.ucEnable = state;
 246
 247        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 248}
 249
 250void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
 251{
 252        struct drm_device *dev = crtc->dev;
 253        struct radeon_device *rdev = dev->dev_private;
 254        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 255
 256        switch (mode) {
 257        case DRM_MODE_DPMS_ON:
 258                radeon_crtc->enabled = true;
 259                /* adjust pm to dpms changes BEFORE enabling crtcs */
 260                radeon_pm_compute_clocks(rdev);
 261                /* disable crtc pair power gating before programming */
 262                if (ASIC_IS_DCE6(rdev))
 263                        atombios_powergate_crtc(crtc, ATOM_DISABLE);
 264                atombios_enable_crtc(crtc, ATOM_ENABLE);
 265                if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
 266                        atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
 267                atombios_blank_crtc(crtc, ATOM_DISABLE);
 268                drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
 269                radeon_crtc_load_lut(crtc);
 270                break;
 271        case DRM_MODE_DPMS_STANDBY:
 272        case DRM_MODE_DPMS_SUSPEND:
 273        case DRM_MODE_DPMS_OFF:
 274                drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
 275                if (radeon_crtc->enabled)
 276                        atombios_blank_crtc(crtc, ATOM_ENABLE);
 277                if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
 278                        atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);
 279                atombios_enable_crtc(crtc, ATOM_DISABLE);
 280                radeon_crtc->enabled = false;
 281                /* power gating is per-pair */
 282                if (ASIC_IS_DCE6(rdev)) {
 283                        struct drm_crtc *other_crtc;
 284                        struct radeon_crtc *other_radeon_crtc;
 285                        list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) {
 286                                other_radeon_crtc = to_radeon_crtc(other_crtc);
 287                                if (((radeon_crtc->crtc_id == 0) && (other_radeon_crtc->crtc_id == 1)) ||
 288                                    ((radeon_crtc->crtc_id == 1) && (other_radeon_crtc->crtc_id == 0)) ||
 289                                    ((radeon_crtc->crtc_id == 2) && (other_radeon_crtc->crtc_id == 3)) ||
 290                                    ((radeon_crtc->crtc_id == 3) && (other_radeon_crtc->crtc_id == 2)) ||
 291                                    ((radeon_crtc->crtc_id == 4) && (other_radeon_crtc->crtc_id == 5)) ||
 292                                    ((radeon_crtc->crtc_id == 5) && (other_radeon_crtc->crtc_id == 4))) {
 293                                        /* if both crtcs in the pair are off, enable power gating */
 294                                        if (other_radeon_crtc->enabled == false)
 295                                                atombios_powergate_crtc(crtc, ATOM_ENABLE);
 296                                        break;
 297                                }
 298                        }
 299                }
 300                /* adjust pm to dpms changes AFTER disabling crtcs */
 301                radeon_pm_compute_clocks(rdev);
 302                break;
 303        }
 304}
 305
 306static void
 307atombios_set_crtc_dtd_timing(struct drm_crtc *crtc,
 308                             struct drm_display_mode *mode)
 309{
 310        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 311        struct drm_device *dev = crtc->dev;
 312        struct radeon_device *rdev = dev->dev_private;
 313        SET_CRTC_USING_DTD_TIMING_PARAMETERS args;
 314        int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming);
 315        u16 misc = 0;
 316
 317        memset(&args, 0, sizeof(args));
 318        args.usH_Size = cpu_to_le16(mode->crtc_hdisplay - (radeon_crtc->h_border * 2));
 319        args.usH_Blanking_Time =
 320                cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay + (radeon_crtc->h_border * 2));
 321        args.usV_Size = cpu_to_le16(mode->crtc_vdisplay - (radeon_crtc->v_border * 2));
 322        args.usV_Blanking_Time =
 323                cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay + (radeon_crtc->v_border * 2));
 324        args.usH_SyncOffset =
 325                cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay + radeon_crtc->h_border);
 326        args.usH_SyncWidth =
 327                cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start);
 328        args.usV_SyncOffset =
 329                cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay + radeon_crtc->v_border);
 330        args.usV_SyncWidth =
 331                cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start);
 332        args.ucH_Border = radeon_crtc->h_border;
 333        args.ucV_Border = radeon_crtc->v_border;
 334
 335        if (mode->flags & DRM_MODE_FLAG_NVSYNC)
 336                misc |= ATOM_VSYNC_POLARITY;
 337        if (mode->flags & DRM_MODE_FLAG_NHSYNC)
 338                misc |= ATOM_HSYNC_POLARITY;
 339        if (mode->flags & DRM_MODE_FLAG_CSYNC)
 340                misc |= ATOM_COMPOSITESYNC;
 341        if (mode->flags & DRM_MODE_FLAG_INTERLACE)
 342                misc |= ATOM_INTERLACE;
 343        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 344                misc |= ATOM_DOUBLE_CLOCK_MODE;
 345
 346        args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
 347        args.ucCRTC = radeon_crtc->crtc_id;
 348
 349        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 350}
 351
 352static void atombios_crtc_set_timing(struct drm_crtc *crtc,
 353                                     struct drm_display_mode *mode)
 354{
 355        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 356        struct drm_device *dev = crtc->dev;
 357        struct radeon_device *rdev = dev->dev_private;
 358        SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION args;
 359        int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing);
 360        u16 misc = 0;
 361
 362        memset(&args, 0, sizeof(args));
 363        args.usH_Total = cpu_to_le16(mode->crtc_htotal);
 364        args.usH_Disp = cpu_to_le16(mode->crtc_hdisplay);
 365        args.usH_SyncStart = cpu_to_le16(mode->crtc_hsync_start);
 366        args.usH_SyncWidth =
 367                cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start);
 368        args.usV_Total = cpu_to_le16(mode->crtc_vtotal);
 369        args.usV_Disp = cpu_to_le16(mode->crtc_vdisplay);
 370        args.usV_SyncStart = cpu_to_le16(mode->crtc_vsync_start);
 371        args.usV_SyncWidth =
 372                cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start);
 373
 374        args.ucOverscanRight = radeon_crtc->h_border;
 375        args.ucOverscanLeft = radeon_crtc->h_border;
 376        args.ucOverscanBottom = radeon_crtc->v_border;
 377        args.ucOverscanTop = radeon_crtc->v_border;
 378
 379        if (mode->flags & DRM_MODE_FLAG_NVSYNC)
 380                misc |= ATOM_VSYNC_POLARITY;
 381        if (mode->flags & DRM_MODE_FLAG_NHSYNC)
 382                misc |= ATOM_HSYNC_POLARITY;
 383        if (mode->flags & DRM_MODE_FLAG_CSYNC)
 384                misc |= ATOM_COMPOSITESYNC;
 385        if (mode->flags & DRM_MODE_FLAG_INTERLACE)
 386                misc |= ATOM_INTERLACE;
 387        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 388                misc |= ATOM_DOUBLE_CLOCK_MODE;
 389
 390        args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
 391        args.ucCRTC = radeon_crtc->crtc_id;
 392
 393        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 394}
 395
 396static void atombios_disable_ss(struct radeon_device *rdev, int pll_id)
 397{
 398        u32 ss_cntl;
 399
 400        if (ASIC_IS_DCE4(rdev)) {
 401                switch (pll_id) {
 402                case ATOM_PPLL1:
 403                        ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL);
 404                        ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
 405                        WREG32(EVERGREEN_P1PLL_SS_CNTL, ss_cntl);
 406                        break;
 407                case ATOM_PPLL2:
 408                        ss_cntl = RREG32(EVERGREEN_P2PLL_SS_CNTL);
 409                        ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
 410                        WREG32(EVERGREEN_P2PLL_SS_CNTL, ss_cntl);
 411                        break;
 412                case ATOM_DCPLL:
 413                case ATOM_PPLL_INVALID:
 414                        return;
 415                }
 416        } else if (ASIC_IS_AVIVO(rdev)) {
 417                switch (pll_id) {
 418                case ATOM_PPLL1:
 419                        ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL);
 420                        ss_cntl &= ~1;
 421                        WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl);
 422                        break;
 423                case ATOM_PPLL2:
 424                        ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL);
 425                        ss_cntl &= ~1;
 426                        WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl);
 427                        break;
 428                case ATOM_DCPLL:
 429                case ATOM_PPLL_INVALID:
 430                        return;
 431                }
 432        }
 433}
 434
 435
 436union atom_enable_ss {
 437        ENABLE_LVDS_SS_PARAMETERS lvds_ss;
 438        ENABLE_LVDS_SS_PARAMETERS_V2 lvds_ss_2;
 439        ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1;
 440        ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 v2;
 441        ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3;
 442};
 443
 444static void atombios_crtc_program_ss(struct radeon_device *rdev,
 445                                     int enable,
 446                                     int pll_id,
 447                                     struct radeon_atom_ss *ss)
 448{
 449        int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL);
 450        union atom_enable_ss args;
 451
 452        memset(&args, 0, sizeof(args));
 453
 454        if (ASIC_IS_DCE5(rdev)) {
 455                args.v3.usSpreadSpectrumAmountFrac = cpu_to_le16(0);
 456                args.v3.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
 457                switch (pll_id) {
 458                case ATOM_PPLL1:
 459                        args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL;
 460                        args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount);
 461                        args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step);
 462                        break;
 463                case ATOM_PPLL2:
 464                        args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL;
 465                        args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount);
 466                        args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step);
 467                        break;
 468                case ATOM_DCPLL:
 469                        args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL;
 470                        args.v3.usSpreadSpectrumAmount = cpu_to_le16(0);
 471                        args.v3.usSpreadSpectrumStep = cpu_to_le16(0);
 472                        break;
 473                case ATOM_PPLL_INVALID:
 474                        return;
 475                }
 476                args.v3.ucEnable = enable;
 477                if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK) || ASIC_IS_DCE61(rdev))
 478                        args.v3.ucEnable = ATOM_DISABLE;
 479        } else if (ASIC_IS_DCE4(rdev)) {
 480                args.v2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
 481                args.v2.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
 482                switch (pll_id) {
 483                case ATOM_PPLL1:
 484                        args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P1PLL;
 485                        args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount);
 486                        args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step);
 487                        break;
 488                case ATOM_PPLL2:
 489                        args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P2PLL;
 490                        args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount);
 491                        args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step);
 492                        break;
 493                case ATOM_DCPLL:
 494                        args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_DCPLL;
 495                        args.v2.usSpreadSpectrumAmount = cpu_to_le16(0);
 496                        args.v2.usSpreadSpectrumStep = cpu_to_le16(0);
 497                        break;
 498                case ATOM_PPLL_INVALID:
 499                        return;
 500                }
 501                args.v2.ucEnable = enable;
 502                if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK) || ASIC_IS_DCE41(rdev))
 503                        args.v2.ucEnable = ATOM_DISABLE;
 504        } else if (ASIC_IS_DCE3(rdev)) {
 505                args.v1.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
 506                args.v1.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
 507                args.v1.ucSpreadSpectrumStep = ss->step;
 508                args.v1.ucSpreadSpectrumDelay = ss->delay;
 509                args.v1.ucSpreadSpectrumRange = ss->range;
 510                args.v1.ucPpll = pll_id;
 511                args.v1.ucEnable = enable;
 512        } else if (ASIC_IS_AVIVO(rdev)) {
 513                if ((enable == ATOM_DISABLE) || (ss->percentage == 0) ||
 514                    (ss->type & ATOM_EXTERNAL_SS_MASK)) {
 515                        atombios_disable_ss(rdev, pll_id);
 516                        return;
 517                }
 518                args.lvds_ss_2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
 519                args.lvds_ss_2.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
 520                args.lvds_ss_2.ucSpreadSpectrumStep = ss->step;
 521                args.lvds_ss_2.ucSpreadSpectrumDelay = ss->delay;
 522                args.lvds_ss_2.ucSpreadSpectrumRange = ss->range;
 523                args.lvds_ss_2.ucEnable = enable;
 524        } else {
 525                if ((enable == ATOM_DISABLE) || (ss->percentage == 0) ||
 526                    (ss->type & ATOM_EXTERNAL_SS_MASK)) {
 527                        atombios_disable_ss(rdev, pll_id);
 528                        return;
 529                }
 530                args.lvds_ss.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
 531                args.lvds_ss.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
 532                args.lvds_ss.ucSpreadSpectrumStepSize_Delay = (ss->step & 3) << 2;
 533                args.lvds_ss.ucSpreadSpectrumStepSize_Delay |= (ss->delay & 7) << 4;
 534                args.lvds_ss.ucEnable = enable;
 535        }
 536        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 537}
 538
 539union adjust_pixel_clock {
 540        ADJUST_DISPLAY_PLL_PS_ALLOCATION v1;
 541        ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 v3;
 542};
 543
 544static u32 atombios_adjust_pll(struct drm_crtc *crtc,
 545                               struct drm_display_mode *mode,
 546                               struct radeon_pll *pll,
 547                               bool ss_enabled,
 548                               struct radeon_atom_ss *ss)
 549{
 550        struct drm_device *dev = crtc->dev;
 551        struct radeon_device *rdev = dev->dev_private;
 552        struct drm_encoder *encoder = NULL;
 553        struct radeon_encoder *radeon_encoder = NULL;
 554        struct drm_connector *connector = NULL;
 555        u32 adjusted_clock = mode->clock;
 556        int encoder_mode = 0;
 557        u32 dp_clock = mode->clock;
 558        int bpc = 8;
 559        bool is_duallink = false;
 560
 561        /* reset the pll flags */
 562        pll->flags = 0;
 563
 564        if (ASIC_IS_AVIVO(rdev)) {
 565                if ((rdev->family == CHIP_RS600) ||
 566                    (rdev->family == CHIP_RS690) ||
 567                    (rdev->family == CHIP_RS740))
 568                        pll->flags |= (/*RADEON_PLL_USE_FRAC_FB_DIV |*/
 569                                       RADEON_PLL_PREFER_CLOSEST_LOWER);
 570
 571                if (ASIC_IS_DCE32(rdev) && mode->clock > 200000)        /* range limits??? */
 572                        pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
 573                else
 574                        pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
 575
 576                if (rdev->family < CHIP_RV770)
 577                        pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP;
 578                /* use frac fb div on APUs */
 579                if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))
 580                        pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV;
 581        } else {
 582                pll->flags |= RADEON_PLL_LEGACY;
 583
 584                if (mode->clock > 200000)       /* range limits??? */
 585                        pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
 586                else
 587                        pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
 588        }
 589
 590        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 591                if (encoder->crtc == crtc) {
 592                        radeon_encoder = to_radeon_encoder(encoder);
 593                        connector = radeon_get_connector_for_encoder(encoder);
 594                        bpc = radeon_get_monitor_bpc(connector);
 595                        encoder_mode = atombios_get_encoder_mode(encoder);
 596                        is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock);
 597                        if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
 598                            (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) {
 599                                if (connector) {
 600                                        struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 601                                        struct radeon_connector_atom_dig *dig_connector =
 602                                                radeon_connector->con_priv;
 603
 604                                        dp_clock = dig_connector->dp_clock;
 605                                }
 606                        }
 607
 608                        /* use recommended ref_div for ss */
 609                        if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
 610                                if (ss_enabled) {
 611                                        if (ss->refdiv) {
 612                                                pll->flags |= RADEON_PLL_USE_REF_DIV;
 613                                                pll->reference_div = ss->refdiv;
 614                                                if (ASIC_IS_AVIVO(rdev))
 615                                                        pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV;
 616                                        }
 617                                }
 618                        }
 619
 620                        if (ASIC_IS_AVIVO(rdev)) {
 621                                /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
 622                                if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
 623                                        adjusted_clock = mode->clock * 2;
 624                                if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
 625                                        pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
 626                                if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
 627                                        pll->flags |= RADEON_PLL_IS_LCD;
 628                        } else {
 629                                if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
 630                                        pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
 631                                if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)
 632                                        pll->flags |= RADEON_PLL_USE_REF_DIV;
 633                        }
 634                        break;
 635                }
 636        }
 637
 638        /* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock
 639         * accordingly based on the encoder/transmitter to work around
 640         * special hw requirements.
 641         */
 642        if (ASIC_IS_DCE3(rdev)) {
 643                union adjust_pixel_clock args;
 644                u8 frev, crev;
 645                int index;
 646
 647                index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
 648                if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
 649                                           &crev))
 650                        return adjusted_clock;
 651
 652                memset(&args, 0, sizeof(args));
 653
 654                switch (frev) {
 655                case 1:
 656                        switch (crev) {
 657                        case 1:
 658                        case 2:
 659                                args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
 660                                args.v1.ucTransmitterID = radeon_encoder->encoder_id;
 661                                args.v1.ucEncodeMode = encoder_mode;
 662                                if (ss_enabled && ss->percentage)
 663                                        args.v1.ucConfig |=
 664                                                ADJUST_DISPLAY_CONFIG_SS_ENABLE;
 665
 666                                atom_execute_table(rdev->mode_info.atom_context,
 667                                                   index, (uint32_t *)&args);
 668                                adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10;
 669                                break;
 670                        case 3:
 671                                args.v3.sInput.usPixelClock = cpu_to_le16(mode->clock / 10);
 672                                args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id;
 673                                args.v3.sInput.ucEncodeMode = encoder_mode;
 674                                args.v3.sInput.ucDispPllConfig = 0;
 675                                if (ss_enabled && ss->percentage)
 676                                        args.v3.sInput.ucDispPllConfig |=
 677                                                DISPPLL_CONFIG_SS_ENABLE;
 678                                if (ENCODER_MODE_IS_DP(encoder_mode)) {
 679                                        args.v3.sInput.ucDispPllConfig |=
 680                                                DISPPLL_CONFIG_COHERENT_MODE;
 681                                        /* 16200 or 27000 */
 682                                        args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10);
 683                                } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
 684                                        struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 685                                        if (encoder_mode == ATOM_ENCODER_MODE_HDMI)
 686                                                /* deep color support */
 687                                                args.v3.sInput.usPixelClock =
 688                                                        cpu_to_le16((mode->clock * bpc / 8) / 10);
 689                                        if (dig->coherent_mode)
 690                                                args.v3.sInput.ucDispPllConfig |=
 691                                                        DISPPLL_CONFIG_COHERENT_MODE;
 692                                        if (is_duallink)
 693                                                args.v3.sInput.ucDispPllConfig |=
 694                                                        DISPPLL_CONFIG_DUAL_LINK;
 695                                }
 696                                if (radeon_encoder_get_dp_bridge_encoder_id(encoder) !=
 697                                    ENCODER_OBJECT_ID_NONE)
 698                                        args.v3.sInput.ucExtTransmitterID =
 699                                                radeon_encoder_get_dp_bridge_encoder_id(encoder);
 700                                else
 701                                        args.v3.sInput.ucExtTransmitterID = 0;
 702
 703                                atom_execute_table(rdev->mode_info.atom_context,
 704                                                   index, (uint32_t *)&args);
 705                                adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10;
 706                                if (args.v3.sOutput.ucRefDiv) {
 707                                        pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV;
 708                                        pll->flags |= RADEON_PLL_USE_REF_DIV;
 709                                        pll->reference_div = args.v3.sOutput.ucRefDiv;
 710                                }
 711                                if (args.v3.sOutput.ucPostDiv) {
 712                                        pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV;
 713                                        pll->flags |= RADEON_PLL_USE_POST_DIV;
 714                                        pll->post_div = args.v3.sOutput.ucPostDiv;
 715                                }
 716                                break;
 717                        default:
 718                                DRM_ERROR("Unknown table version %d %d\n", frev, crev);
 719                                return adjusted_clock;
 720                        }
 721                        break;
 722                default:
 723                        DRM_ERROR("Unknown table version %d %d\n", frev, crev);
 724                        return adjusted_clock;
 725                }
 726        }
 727        return adjusted_clock;
 728}
 729
 730union set_pixel_clock {
 731        SET_PIXEL_CLOCK_PS_ALLOCATION base;
 732        PIXEL_CLOCK_PARAMETERS v1;
 733        PIXEL_CLOCK_PARAMETERS_V2 v2;
 734        PIXEL_CLOCK_PARAMETERS_V3 v3;
 735        PIXEL_CLOCK_PARAMETERS_V5 v5;
 736        PIXEL_CLOCK_PARAMETERS_V6 v6;
 737};
 738
 739/* on DCE5, make sure the voltage is high enough to support the
 740 * required disp clk.
 741 */
 742static void atombios_crtc_set_disp_eng_pll(struct radeon_device *rdev,
 743                                    u32 dispclk)
 744{
 745        u8 frev, crev;
 746        int index;
 747        union set_pixel_clock args;
 748
 749        memset(&args, 0, sizeof(args));
 750
 751        index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
 752        if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
 753                                   &crev))
 754                return;
 755
 756        switch (frev) {
 757        case 1:
 758                switch (crev) {
 759                case 5:
 760                        /* if the default dcpll clock is specified,
 761                         * SetPixelClock provides the dividers
 762                         */
 763                        args.v5.ucCRTC = ATOM_CRTC_INVALID;
 764                        args.v5.usPixelClock = cpu_to_le16(dispclk);
 765                        args.v5.ucPpll = ATOM_DCPLL;
 766                        break;
 767                case 6:
 768                        /* if the default dcpll clock is specified,
 769                         * SetPixelClock provides the dividers
 770                         */
 771                        args.v6.ulDispEngClkFreq = cpu_to_le32(dispclk);
 772                        if (ASIC_IS_DCE61(rdev))
 773                                args.v6.ucPpll = ATOM_EXT_PLL1;
 774                        else if (ASIC_IS_DCE6(rdev))
 775                                args.v6.ucPpll = ATOM_PPLL0;
 776                        else
 777                                args.v6.ucPpll = ATOM_DCPLL;
 778                        break;
 779                default:
 780                        DRM_ERROR("Unknown table version %d %d\n", frev, crev);
 781                        return;
 782                }
 783                break;
 784        default:
 785                DRM_ERROR("Unknown table version %d %d\n", frev, crev);
 786                return;
 787        }
 788        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 789}
 790
 791static void atombios_crtc_program_pll(struct drm_crtc *crtc,
 792                                      u32 crtc_id,
 793                                      int pll_id,
 794                                      u32 encoder_mode,
 795                                      u32 encoder_id,
 796                                      u32 clock,
 797                                      u32 ref_div,
 798                                      u32 fb_div,
 799                                      u32 frac_fb_div,
 800                                      u32 post_div,
 801                                      int bpc,
 802                                      bool ss_enabled,
 803                                      struct radeon_atom_ss *ss)
 804{
 805        struct drm_device *dev = crtc->dev;
 806        struct radeon_device *rdev = dev->dev_private;
 807        u8 frev, crev;
 808        int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
 809        union set_pixel_clock args;
 810
 811        memset(&args, 0, sizeof(args));
 812
 813        if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
 814                                   &crev))
 815                return;
 816
 817        switch (frev) {
 818        case 1:
 819                switch (crev) {
 820                case 1:
 821                        if (clock == ATOM_DISABLE)
 822                                return;
 823                        args.v1.usPixelClock = cpu_to_le16(clock / 10);
 824                        args.v1.usRefDiv = cpu_to_le16(ref_div);
 825                        args.v1.usFbDiv = cpu_to_le16(fb_div);
 826                        args.v1.ucFracFbDiv = frac_fb_div;
 827                        args.v1.ucPostDiv = post_div;
 828                        args.v1.ucPpll = pll_id;
 829                        args.v1.ucCRTC = crtc_id;
 830                        args.v1.ucRefDivSrc = 1;
 831                        break;
 832                case 2:
 833                        args.v2.usPixelClock = cpu_to_le16(clock / 10);
 834                        args.v2.usRefDiv = cpu_to_le16(ref_div);
 835                        args.v2.usFbDiv = cpu_to_le16(fb_div);
 836                        args.v2.ucFracFbDiv = frac_fb_div;
 837                        args.v2.ucPostDiv = post_div;
 838                        args.v2.ucPpll = pll_id;
 839                        args.v2.ucCRTC = crtc_id;
 840                        args.v2.ucRefDivSrc = 1;
 841                        break;
 842                case 3:
 843                        args.v3.usPixelClock = cpu_to_le16(clock / 10);
 844                        args.v3.usRefDiv = cpu_to_le16(ref_div);
 845                        args.v3.usFbDiv = cpu_to_le16(fb_div);
 846                        args.v3.ucFracFbDiv = frac_fb_div;
 847                        args.v3.ucPostDiv = post_div;
 848                        args.v3.ucPpll = pll_id;
 849                        args.v3.ucMiscInfo = (pll_id << 2);
 850                        if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
 851                                args.v3.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
 852                        args.v3.ucTransmitterId = encoder_id;
 853                        args.v3.ucEncoderMode = encoder_mode;
 854                        break;
 855                case 5:
 856                        args.v5.ucCRTC = crtc_id;
 857                        args.v5.usPixelClock = cpu_to_le16(clock / 10);
 858                        args.v5.ucRefDiv = ref_div;
 859                        args.v5.usFbDiv = cpu_to_le16(fb_div);
 860                        args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
 861                        args.v5.ucPostDiv = post_div;
 862                        args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */
 863                        if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
 864                                args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_REF_DIV_SRC;
 865                        switch (bpc) {
 866                        case 8:
 867                        default:
 868                                args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_24BPP;
 869                                break;
 870                        case 10:
 871                                args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP;
 872                                break;
 873                        }
 874                        args.v5.ucTransmitterID = encoder_id;
 875                        args.v5.ucEncoderMode = encoder_mode;
 876                        args.v5.ucPpll = pll_id;
 877                        break;
 878                case 6:
 879                        args.v6.ulDispEngClkFreq = cpu_to_le32(crtc_id << 24 | clock / 10);
 880                        args.v6.ucRefDiv = ref_div;
 881                        args.v6.usFbDiv = cpu_to_le16(fb_div);
 882                        args.v6.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
 883                        args.v6.ucPostDiv = post_div;
 884                        args.v6.ucMiscInfo = 0; /* HDMI depth, etc. */
 885                        if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
 886                                args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
 887                        switch (bpc) {
 888                        case 8:
 889                        default:
 890                                args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_24BPP;
 891                                break;
 892                        case 10:
 893                                args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP;
 894                                break;
 895                        case 12:
 896                                args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP;
 897                                break;
 898                        case 16:
 899                                args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP;
 900                                break;
 901                        }
 902                        args.v6.ucTransmitterID = encoder_id;
 903                        args.v6.ucEncoderMode = encoder_mode;
 904                        args.v6.ucPpll = pll_id;
 905                        break;
 906                default:
 907                        DRM_ERROR("Unknown table version %d %d\n", frev, crev);
 908                        return;
 909                }
 910                break;
 911        default:
 912                DRM_ERROR("Unknown table version %d %d\n", frev, crev);
 913                return;
 914        }
 915
 916        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 917}
 918
 919static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
 920{
 921        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 922        struct drm_device *dev = crtc->dev;
 923        struct radeon_device *rdev = dev->dev_private;
 924        struct drm_encoder *encoder = NULL;
 925        struct radeon_encoder *radeon_encoder = NULL;
 926        u32 pll_clock = mode->clock;
 927        u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
 928        struct radeon_pll *pll;
 929        u32 adjusted_clock;
 930        int encoder_mode = 0;
 931        struct radeon_atom_ss ss;
 932        bool ss_enabled = false;
 933        int bpc = 8;
 934
 935        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 936                if (encoder->crtc == crtc) {
 937                        radeon_encoder = to_radeon_encoder(encoder);
 938                        encoder_mode = atombios_get_encoder_mode(encoder);
 939                        break;
 940                }
 941        }
 942
 943        if (!radeon_encoder)
 944                return;
 945
 946        switch (radeon_crtc->pll_id) {
 947        case ATOM_PPLL1:
 948                pll = &rdev->clock.p1pll;
 949                break;
 950        case ATOM_PPLL2:
 951                pll = &rdev->clock.p2pll;
 952                break;
 953        case ATOM_DCPLL:
 954        case ATOM_PPLL_INVALID:
 955        default:
 956                pll = &rdev->clock.dcpll;
 957                break;
 958        }
 959
 960        if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
 961            (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) {
 962                struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 963                struct drm_connector *connector =
 964                        radeon_get_connector_for_encoder(encoder);
 965                struct radeon_connector *radeon_connector =
 966                        to_radeon_connector(connector);
 967                struct radeon_connector_atom_dig *dig_connector =
 968                        radeon_connector->con_priv;
 969                int dp_clock;
 970                bpc = radeon_get_monitor_bpc(connector);
 971
 972                switch (encoder_mode) {
 973                case ATOM_ENCODER_MODE_DP_MST:
 974                case ATOM_ENCODER_MODE_DP:
 975                        /* DP/eDP */
 976                        dp_clock = dig_connector->dp_clock / 10;
 977                        if (ASIC_IS_DCE4(rdev))
 978                                ss_enabled =
 979                                        radeon_atombios_get_asic_ss_info(rdev, &ss,
 980                                                                         ASIC_INTERNAL_SS_ON_DP,
 981                                                                         dp_clock);
 982                        else {
 983                                if (dp_clock == 16200) {
 984                                        ss_enabled =
 985                                                radeon_atombios_get_ppll_ss_info(rdev, &ss,
 986                                                                                 ATOM_DP_SS_ID2);
 987                                        if (!ss_enabled)
 988                                                ss_enabled =
 989                                                        radeon_atombios_get_ppll_ss_info(rdev, &ss,
 990                                                                                         ATOM_DP_SS_ID1);
 991                                } else
 992                                        ss_enabled =
 993                                                radeon_atombios_get_ppll_ss_info(rdev, &ss,
 994                                                                                 ATOM_DP_SS_ID1);
 995                        }
 996                        break;
 997                case ATOM_ENCODER_MODE_LVDS:
 998                        if (ASIC_IS_DCE4(rdev))
 999                                ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss,
1000                                                                              dig->lcd_ss_id,
1001                                                                              mode->clock / 10);
1002                        else
1003                                ss_enabled = radeon_atombios_get_ppll_ss_info(rdev, &ss,
1004                                                                              dig->lcd_ss_id);
1005                        break;
1006                case ATOM_ENCODER_MODE_DVI:
1007                        if (ASIC_IS_DCE4(rdev))
1008                                ss_enabled =
1009                                        radeon_atombios_get_asic_ss_info(rdev, &ss,
1010                                                                         ASIC_INTERNAL_SS_ON_TMDS,
1011                                                                         mode->clock / 10);
1012                        break;
1013                case ATOM_ENCODER_MODE_HDMI:
1014                        if (ASIC_IS_DCE4(rdev))
1015                                ss_enabled =
1016                                        radeon_atombios_get_asic_ss_info(rdev, &ss,
1017                                                                         ASIC_INTERNAL_SS_ON_HDMI,
1018                                                                         mode->clock / 10);
1019                        break;
1020                default:
1021                        break;
1022                }
1023        }
1024
1025        /* adjust pixel clock as needed */
1026        adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss);
1027
1028        if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
1029                /* TV seems to prefer the legacy algo on some boards */
1030                radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
1031                                          &ref_div, &post_div);
1032        else if (ASIC_IS_AVIVO(rdev))
1033                radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
1034                                         &ref_div, &post_div);
1035        else
1036                radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
1037                                          &ref_div, &post_div);
1038
1039        atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, &ss);
1040
1041        atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
1042                                  encoder_mode, radeon_encoder->encoder_id, mode->clock,
1043                                  ref_div, fb_div, frac_fb_div, post_div, bpc, ss_enabled, &ss);
1044
1045        if (ss_enabled) {
1046                /* calculate ss amount and step size */
1047                if (ASIC_IS_DCE4(rdev)) {
1048                        u32 step_size;
1049                        u32 amount = (((fb_div * 10) + frac_fb_div) * ss.percentage) / 10000;
1050                        ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK;
1051                        ss.amount |= ((amount - (amount / 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
1052                                ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK;
1053                        if (ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD)
1054                                step_size = (4 * amount * ref_div * (ss.rate * 2048)) /
1055                                        (125 * 25 * pll->reference_freq / 100);
1056                        else
1057                                step_size = (2 * amount * ref_div * (ss.rate * 2048)) /
1058                                        (125 * 25 * pll->reference_freq / 100);
1059                        ss.step = step_size;
1060                }
1061
1062                atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, &ss);
1063        }
1064}
1065
1066static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
1067                                 struct drm_framebuffer *fb,
1068                                 int x, int y, int atomic)
1069{
1070        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1071        struct drm_device *dev = crtc->dev;
1072        struct radeon_device *rdev = dev->dev_private;
1073        struct radeon_framebuffer *radeon_fb;
1074        struct drm_framebuffer *target_fb;
1075        struct drm_gem_object *obj;
1076        struct radeon_bo *rbo;
1077        uint64_t fb_location;
1078        uint32_t fb_format, fb_pitch_pixels, tiling_flags;
1079        unsigned bankw, bankh, mtaspect, tile_split;
1080        u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE);
1081        u32 tmp, viewport_w, viewport_h;
1082        int r;
1083
1084        /* no fb bound */
1085        if (!atomic && !crtc->fb) {
1086                DRM_DEBUG_KMS("No FB bound\n");
1087                return 0;
1088        }
1089
1090        if (atomic) {
1091                radeon_fb = to_radeon_framebuffer(fb);
1092                target_fb = fb;
1093        }
1094        else {
1095                radeon_fb = to_radeon_framebuffer(crtc->fb);
1096                target_fb = crtc->fb;
1097        }
1098
1099        /* If atomic, assume fb object is pinned & idle & fenced and
1100         * just update base pointers
1101         */
1102        obj = radeon_fb->obj;
1103        rbo = gem_to_radeon_bo(obj);
1104        r = radeon_bo_reserve(rbo, false);
1105        if (unlikely(r != 0))
1106                return r;
1107
1108        if (atomic)
1109                fb_location = radeon_bo_gpu_offset(rbo);
1110        else {
1111                r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
1112                if (unlikely(r != 0)) {
1113                        radeon_bo_unreserve(rbo);
1114                        return -EINVAL;
1115                }
1116        }
1117
1118        radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
1119        radeon_bo_unreserve(rbo);
1120
1121        switch (target_fb->bits_per_pixel) {
1122        case 8:
1123                fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) |
1124                             EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED));
1125                break;
1126        case 15:
1127                fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
1128                             EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB1555));
1129                break;
1130        case 16:
1131                fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
1132                             EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565));
1133#ifdef __BIG_ENDIAN
1134                fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
1135#endif
1136                break;
1137        case 24:
1138        case 32:
1139                fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
1140                             EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888));
1141#ifdef __BIG_ENDIAN
1142                fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
1143#endif
1144                break;
1145        default:
1146                DRM_ERROR("Unsupported screen depth %d\n",
1147                          target_fb->bits_per_pixel);
1148                return -EINVAL;
1149        }
1150
1151        if (tiling_flags & RADEON_TILING_MACRO) {
1152                if (rdev->family >= CHIP_TAHITI)
1153                        tmp = rdev->config.si.tile_config;
1154                else if (rdev->family >= CHIP_CAYMAN)
1155                        tmp = rdev->config.cayman.tile_config;
1156                else
1157                        tmp = rdev->config.evergreen.tile_config;
1158
1159                switch ((tmp & 0xf0) >> 4) {
1160                case 0: /* 4 banks */
1161                        fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_4_BANK);
1162                        break;
1163                case 1: /* 8 banks */
1164                default:
1165                        fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_8_BANK);
1166                        break;
1167                case 2: /* 16 banks */
1168                        fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_16_BANK);
1169                        break;
1170                }
1171
1172                fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1);
1173
1174                evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split);
1175                fb_format |= EVERGREEN_GRPH_TILE_SPLIT(tile_split);
1176                fb_format |= EVERGREEN_GRPH_BANK_WIDTH(bankw);
1177                fb_format |= EVERGREEN_GRPH_BANK_HEIGHT(bankh);
1178                fb_format |= EVERGREEN_GRPH_MACRO_TILE_ASPECT(mtaspect);
1179        } else if (tiling_flags & RADEON_TILING_MICRO)
1180                fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1);
1181
1182        if ((rdev->family == CHIP_TAHITI) ||
1183            (rdev->family == CHIP_PITCAIRN))
1184                fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16);
1185        else if (rdev->family == CHIP_VERDE)
1186                fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16);
1187
1188        switch (radeon_crtc->crtc_id) {
1189        case 0:
1190                WREG32(AVIVO_D1VGA_CONTROL, 0);
1191                break;
1192        case 1:
1193                WREG32(AVIVO_D2VGA_CONTROL, 0);
1194                break;
1195        case 2:
1196                WREG32(EVERGREEN_D3VGA_CONTROL, 0);
1197                break;
1198        case 3:
1199                WREG32(EVERGREEN_D4VGA_CONTROL, 0);
1200                break;
1201        case 4:
1202                WREG32(EVERGREEN_D5VGA_CONTROL, 0);
1203                break;
1204        case 5:
1205                WREG32(EVERGREEN_D6VGA_CONTROL, 0);
1206                break;
1207        default:
1208                break;
1209        }
1210
1211        WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
1212               upper_32_bits(fb_location));
1213        WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
1214               upper_32_bits(fb_location));
1215        WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
1216               (u32)fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
1217        WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
1218               (u32) fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
1219        WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
1220        WREG32(EVERGREEN_GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap);
1221
1222        WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
1223        WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
1224        WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0);
1225        WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0);
1226        WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width);
1227        WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height);
1228
1229        fb_pitch_pixels = target_fb->pitches[0] / (target_fb->bits_per_pixel / 8);
1230        WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
1231        WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
1232
1233        WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
1234               target_fb->height);
1235        x &= ~3;
1236        y &= ~1;
1237        WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset,
1238               (x << 16) | y);
1239        viewport_w = crtc->mode.hdisplay;
1240        viewport_h = (crtc->mode.vdisplay + 1) & ~1;
1241        WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
1242               (viewport_w << 16) | viewport_h);
1243
1244        /* pageflip setup */
1245        /* make sure flip is at vb rather than hb */
1246        tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset);
1247        tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN;
1248        WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp);
1249
1250        /* set pageflip to happen anywhere in vblank interval */
1251        WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
1252
1253        if (!atomic && fb && fb != crtc->fb) {
1254                radeon_fb = to_radeon_framebuffer(fb);
1255                rbo = gem_to_radeon_bo(radeon_fb->obj);
1256                r = radeon_bo_reserve(rbo, false);
1257                if (unlikely(r != 0))
1258                        return r;
1259                radeon_bo_unpin(rbo);
1260                radeon_bo_unreserve(rbo);
1261        }
1262
1263        /* Bytes per pixel may have changed */
1264        radeon_bandwidth_update(rdev);
1265
1266        return 0;
1267}
1268
1269static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
1270                                  struct drm_framebuffer *fb,
1271                                  int x, int y, int atomic)
1272{
1273        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1274        struct drm_device *dev = crtc->dev;
1275        struct radeon_device *rdev = dev->dev_private;
1276        struct radeon_framebuffer *radeon_fb;
1277        struct drm_gem_object *obj;
1278        struct radeon_bo *rbo;
1279        struct drm_framebuffer *target_fb;
1280        uint64_t fb_location;
1281        uint32_t fb_format, fb_pitch_pixels, tiling_flags;
1282        u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE;
1283        u32 tmp, viewport_w, viewport_h;
1284        int r;
1285
1286        /* no fb bound */
1287        if (!atomic && !crtc->fb) {
1288                DRM_DEBUG_KMS("No FB bound\n");
1289                return 0;
1290        }
1291
1292        if (atomic) {
1293                radeon_fb = to_radeon_framebuffer(fb);
1294                target_fb = fb;
1295        }
1296        else {
1297                radeon_fb = to_radeon_framebuffer(crtc->fb);
1298                target_fb = crtc->fb;
1299        }
1300
1301        obj = radeon_fb->obj;
1302        rbo = gem_to_radeon_bo(obj);
1303        r = radeon_bo_reserve(rbo, false);
1304        if (unlikely(r != 0))
1305                return r;
1306
1307        /* If atomic, assume fb object is pinned & idle & fenced and
1308         * just update base pointers
1309         */
1310        if (atomic)
1311                fb_location = radeon_bo_gpu_offset(rbo);
1312        else {
1313                r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
1314                if (unlikely(r != 0)) {
1315                        radeon_bo_unreserve(rbo);
1316                        return -EINVAL;
1317                }
1318        }
1319        radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
1320        radeon_bo_unreserve(rbo);
1321
1322        switch (target_fb->bits_per_pixel) {
1323        case 8:
1324                fb_format =
1325                    AVIVO_D1GRPH_CONTROL_DEPTH_8BPP |
1326                    AVIVO_D1GRPH_CONTROL_8BPP_INDEXED;
1327                break;
1328        case 15:
1329                fb_format =
1330                    AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
1331                    AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555;
1332                break;
1333        case 16:
1334                fb_format =
1335                    AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
1336                    AVIVO_D1GRPH_CONTROL_16BPP_RGB565;
1337#ifdef __BIG_ENDIAN
1338                fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
1339#endif
1340                break;
1341        case 24:
1342        case 32:
1343                fb_format =
1344                    AVIVO_D1GRPH_CONTROL_DEPTH_32BPP |
1345                    AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888;
1346#ifdef __BIG_ENDIAN
1347                fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT;
1348#endif
1349                break;
1350        default:
1351                DRM_ERROR("Unsupported screen depth %d\n",
1352                          target_fb->bits_per_pixel);
1353                return -EINVAL;
1354        }
1355
1356        if (rdev->family >= CHIP_R600) {
1357                if (tiling_flags & RADEON_TILING_MACRO)
1358                        fb_format |= R600_D1GRPH_ARRAY_MODE_2D_TILED_THIN1;
1359                else if (tiling_flags & RADEON_TILING_MICRO)
1360                        fb_format |= R600_D1GRPH_ARRAY_MODE_1D_TILED_THIN1;
1361        } else {
1362                if (tiling_flags & RADEON_TILING_MACRO)
1363                        fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
1364
1365                if (tiling_flags & RADEON_TILING_MICRO)
1366                        fb_format |= AVIVO_D1GRPH_TILED;
1367        }
1368
1369        if (radeon_crtc->crtc_id == 0)
1370                WREG32(AVIVO_D1VGA_CONTROL, 0);
1371        else
1372                WREG32(AVIVO_D2VGA_CONTROL, 0);
1373
1374        if (rdev->family >= CHIP_RV770) {
1375                if (radeon_crtc->crtc_id) {
1376                        WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
1377                        WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
1378                } else {
1379                        WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
1380                        WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
1381                }
1382        }
1383        WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
1384               (u32) fb_location);
1385        WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS +
1386               radeon_crtc->crtc_offset, (u32) fb_location);
1387        WREG32(AVIVO_D1GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
1388        if (rdev->family >= CHIP_R600)
1389                WREG32(R600_D1GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap);
1390
1391        WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
1392        WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
1393        WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0);
1394        WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0);
1395        WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width);
1396        WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height);
1397
1398        fb_pitch_pixels = target_fb->pitches[0] / (target_fb->bits_per_pixel / 8);
1399        WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
1400        WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
1401
1402        WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
1403               target_fb->height);
1404        x &= ~3;
1405        y &= ~1;
1406        WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset,
1407               (x << 16) | y);
1408        viewport_w = crtc->mode.hdisplay;
1409        viewport_h = (crtc->mode.vdisplay + 1) & ~1;
1410        WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
1411               (viewport_w << 16) | viewport_h);
1412
1413        /* pageflip setup */
1414        /* make sure flip is at vb rather than hb */
1415        tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset);
1416        tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN;
1417        WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp);
1418
1419        /* set pageflip to happen anywhere in vblank interval */
1420        WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
1421
1422        if (!atomic && fb && fb != crtc->fb) {
1423                radeon_fb = to_radeon_framebuffer(fb);
1424                rbo = gem_to_radeon_bo(radeon_fb->obj);
1425                r = radeon_bo_reserve(rbo, false);
1426                if (unlikely(r != 0))
1427                        return r;
1428                radeon_bo_unpin(rbo);
1429                radeon_bo_unreserve(rbo);
1430        }
1431
1432        /* Bytes per pixel may have changed */
1433        radeon_bandwidth_update(rdev);
1434
1435        return 0;
1436}
1437
1438int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
1439                           struct drm_framebuffer *old_fb)
1440{
1441        struct drm_device *dev = crtc->dev;
1442        struct radeon_device *rdev = dev->dev_private;
1443
1444        if (ASIC_IS_DCE4(rdev))
1445                return dce4_crtc_do_set_base(crtc, old_fb, x, y, 0);
1446        else if (ASIC_IS_AVIVO(rdev))
1447                return avivo_crtc_do_set_base(crtc, old_fb, x, y, 0);
1448        else
1449                return radeon_crtc_do_set_base(crtc, old_fb, x, y, 0);
1450}
1451
1452int atombios_crtc_set_base_atomic(struct drm_crtc *crtc,
1453                                  struct drm_framebuffer *fb,
1454                                  int x, int y, enum mode_set_atomic state)
1455{
1456       struct drm_device *dev = crtc->dev;
1457       struct radeon_device *rdev = dev->dev_private;
1458
1459        if (ASIC_IS_DCE4(rdev))
1460                return dce4_crtc_do_set_base(crtc, fb, x, y, 1);
1461        else if (ASIC_IS_AVIVO(rdev))
1462                return avivo_crtc_do_set_base(crtc, fb, x, y, 1);
1463        else
1464                return radeon_crtc_do_set_base(crtc, fb, x, y, 1);
1465}
1466
1467/* properly set additional regs when using atombios */
1468static void radeon_legacy_atom_fixup(struct drm_crtc *crtc)
1469{
1470        struct drm_device *dev = crtc->dev;
1471        struct radeon_device *rdev = dev->dev_private;
1472        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1473        u32 disp_merge_cntl;
1474
1475        switch (radeon_crtc->crtc_id) {
1476        case 0:
1477                disp_merge_cntl = RREG32(RADEON_DISP_MERGE_CNTL);
1478                disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
1479                WREG32(RADEON_DISP_MERGE_CNTL, disp_merge_cntl);
1480                break;
1481        case 1:
1482                disp_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL);
1483                disp_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN;
1484                WREG32(RADEON_DISP2_MERGE_CNTL, disp_merge_cntl);
1485                WREG32(RADEON_FP_H2_SYNC_STRT_WID,   RREG32(RADEON_CRTC2_H_SYNC_STRT_WID));
1486                WREG32(RADEON_FP_V2_SYNC_STRT_WID,   RREG32(RADEON_CRTC2_V_SYNC_STRT_WID));
1487                break;
1488        }
1489}
1490
1491static int radeon_atom_pick_pll(struct drm_crtc *crtc)
1492{
1493        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1494        struct drm_device *dev = crtc->dev;
1495        struct radeon_device *rdev = dev->dev_private;
1496        struct drm_encoder *test_encoder;
1497        struct drm_crtc *test_crtc;
1498        uint32_t pll_in_use = 0;
1499
1500        if (ASIC_IS_DCE61(rdev)) {
1501                list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
1502                        if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
1503                                struct radeon_encoder *test_radeon_encoder =
1504                                        to_radeon_encoder(test_encoder);
1505                                struct radeon_encoder_atom_dig *dig =
1506                                        test_radeon_encoder->enc_priv;
1507
1508                                if ((test_radeon_encoder->encoder_id ==
1509                                     ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
1510                                    (dig->linkb == false)) /* UNIPHY A uses PPLL2 */
1511                                        return ATOM_PPLL2;
1512                        }
1513                }
1514                /* UNIPHY B/C/D/E/F */
1515                list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
1516                        struct radeon_crtc *radeon_test_crtc;
1517
1518                        if (crtc == test_crtc)
1519                                continue;
1520
1521                        radeon_test_crtc = to_radeon_crtc(test_crtc);
1522                        if ((radeon_test_crtc->pll_id == ATOM_PPLL0) ||
1523                            (radeon_test_crtc->pll_id == ATOM_PPLL1))
1524                                pll_in_use |= (1 << radeon_test_crtc->pll_id);
1525                }
1526                if (!(pll_in_use & 4))
1527                        return ATOM_PPLL0;
1528                return ATOM_PPLL1;
1529        } else if (ASIC_IS_DCE4(rdev)) {
1530                list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
1531                        if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
1532                                /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,
1533                                 * depending on the asic:
1534                                 * DCE4: PPLL or ext clock
1535                                 * DCE5: DCPLL or ext clock
1536                                 *
1537                                 * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip
1538                                 * PPLL/DCPLL programming and only program the DP DTO for the
1539                                 * crtc virtual pixel clock.
1540                                 */
1541                                if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
1542                                        if (ASIC_IS_DCE5(rdev) || rdev->clock.dp_extclk)
1543                                                return ATOM_PPLL_INVALID;
1544                                }
1545                        }
1546                }
1547
1548                /* otherwise, pick one of the plls */
1549                list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
1550                        struct radeon_crtc *radeon_test_crtc;
1551
1552                        if (crtc == test_crtc)
1553                                continue;
1554
1555                        radeon_test_crtc = to_radeon_crtc(test_crtc);
1556                        if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) &&
1557                            (radeon_test_crtc->pll_id <= ATOM_PPLL2))
1558                                pll_in_use |= (1 << radeon_test_crtc->pll_id);
1559                }
1560                if (!(pll_in_use & 1))
1561                        return ATOM_PPLL1;
1562                return ATOM_PPLL2;
1563        } else
1564                return radeon_crtc->crtc_id;
1565
1566}
1567
1568void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev)
1569{
1570        /* always set DCPLL */
1571        if (ASIC_IS_DCE6(rdev))
1572                atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk);
1573        else if (ASIC_IS_DCE4(rdev)) {
1574                struct radeon_atom_ss ss;
1575                bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss,
1576                                                                   ASIC_INTERNAL_SS_ON_DCPLL,
1577                                                                   rdev->clock.default_dispclk);
1578                if (ss_enabled)
1579                        atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, &ss);
1580                /* XXX: DCE5, make sure voltage, dispclk is high enough */
1581                atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk);
1582                if (ss_enabled)
1583                        atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, &ss);
1584        }
1585
1586}
1587
1588int atombios_crtc_mode_set(struct drm_crtc *crtc,
1589                           struct drm_display_mode *mode,
1590                           struct drm_display_mode *adjusted_mode,
1591                           int x, int y, struct drm_framebuffer *old_fb)
1592{
1593        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1594        struct drm_device *dev = crtc->dev;
1595        struct radeon_device *rdev = dev->dev_private;
1596        struct drm_encoder *encoder;
1597        bool is_tvcv = false;
1598
1599        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
1600                /* find tv std */
1601                if (encoder->crtc == crtc) {
1602                        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1603                        if (radeon_encoder->active_device &
1604                            (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
1605                                is_tvcv = true;
1606                }
1607        }
1608
1609        atombios_crtc_set_pll(crtc, adjusted_mode);
1610
1611        if (ASIC_IS_DCE4(rdev))
1612                atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
1613        else if (ASIC_IS_AVIVO(rdev)) {
1614                if (is_tvcv)
1615                        atombios_crtc_set_timing(crtc, adjusted_mode);
1616                else
1617                        atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
1618        } else {
1619                atombios_crtc_set_timing(crtc, adjusted_mode);
1620                if (radeon_crtc->crtc_id == 0)
1621                        atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
1622                radeon_legacy_atom_fixup(crtc);
1623        }
1624        atombios_crtc_set_base(crtc, x, y, old_fb);
1625        atombios_overscan_setup(crtc, mode, adjusted_mode);
1626        atombios_scaler_setup(crtc);
1627        return 0;
1628}
1629
1630static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
1631                                     struct drm_display_mode *mode,
1632                                     struct drm_display_mode *adjusted_mode)
1633{
1634        if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
1635                return false;
1636        return true;
1637}
1638
1639static void atombios_crtc_prepare(struct drm_crtc *crtc)
1640{
1641        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1642
1643        /* pick pll */
1644        radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
1645
1646        atombios_lock_crtc(crtc, ATOM_ENABLE);
1647        atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
1648}
1649
1650static void atombios_crtc_commit(struct drm_crtc *crtc)
1651{
1652        atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
1653        atombios_lock_crtc(crtc, ATOM_DISABLE);
1654}
1655
1656static void atombios_crtc_disable(struct drm_crtc *crtc)
1657{
1658        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1659        struct drm_device *dev = crtc->dev;
1660        struct radeon_device *rdev = dev->dev_private;
1661        struct radeon_atom_ss ss;
1662
1663        atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
1664
1665        switch (radeon_crtc->pll_id) {
1666        case ATOM_PPLL1:
1667        case ATOM_PPLL2:
1668                /* disable the ppll */
1669                atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
1670                                          0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
1671                break;
1672        case ATOM_PPLL0:
1673                /* disable the ppll */
1674                if (ASIC_IS_DCE61(rdev))
1675                        atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
1676                                                  0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
1677                break;
1678        default:
1679                break;
1680        }
1681        radeon_crtc->pll_id = -1;
1682}
1683
1684static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
1685        .dpms = atombios_crtc_dpms,
1686        .mode_fixup = atombios_crtc_mode_fixup,
1687        .mode_set = atombios_crtc_mode_set,
1688        .mode_set_base = atombios_crtc_set_base,
1689        .mode_set_base_atomic = atombios_crtc_set_base_atomic,
1690        .prepare = atombios_crtc_prepare,
1691        .commit = atombios_crtc_commit,
1692        .load_lut = radeon_crtc_load_lut,
1693        .disable = atombios_crtc_disable,
1694};
1695
1696void radeon_atombios_init_crtc(struct drm_device *dev,
1697                               struct radeon_crtc *radeon_crtc)
1698{
1699        struct radeon_device *rdev = dev->dev_private;
1700
1701        if (ASIC_IS_DCE4(rdev)) {
1702                switch (radeon_crtc->crtc_id) {
1703                case 0:
1704                default:
1705                        radeon_crtc->crtc_offset = EVERGREEN_CRTC0_REGISTER_OFFSET;
1706                        break;
1707                case 1:
1708                        radeon_crtc->crtc_offset = EVERGREEN_CRTC1_REGISTER_OFFSET;
1709                        break;
1710                case 2:
1711                        radeon_crtc->crtc_offset = EVERGREEN_CRTC2_REGISTER_OFFSET;
1712                        break;
1713                case 3:
1714                        radeon_crtc->crtc_offset = EVERGREEN_CRTC3_REGISTER_OFFSET;
1715                        break;
1716                case 4:
1717                        radeon_crtc->crtc_offset = EVERGREEN_CRTC4_REGISTER_OFFSET;
1718                        break;
1719                case 5:
1720                        radeon_crtc->crtc_offset = EVERGREEN_CRTC5_REGISTER_OFFSET;
1721                        break;
1722                }
1723        } else {
1724                if (radeon_crtc->crtc_id == 1)
1725                        radeon_crtc->crtc_offset =
1726                                AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL;
1727                else
1728                        radeon_crtc->crtc_offset = 0;
1729        }
1730        radeon_crtc->pll_id = -1;
1731        drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
1732}
1733