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                        /* if (connector && connector->display_info.bpc)
 595                                bpc = connector->display_info.bpc; */
 596                        encoder_mode = atombios_get_encoder_mode(encoder);
 597                        is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock);
 598                        if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
 599                            (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) {
 600                                if (connector) {
 601                                        struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 602                                        struct radeon_connector_atom_dig *dig_connector =
 603                                                radeon_connector->con_priv;
 604
 605                                        dp_clock = dig_connector->dp_clock;
 606                                }
 607                        }
 608
 609                        /* use recommended ref_div for ss */
 610                        if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
 611                                if (ss_enabled) {
 612                                        if (ss->refdiv) {
 613                                                pll->flags |= RADEON_PLL_USE_REF_DIV;
 614                                                pll->reference_div = ss->refdiv;
 615                                                if (ASIC_IS_AVIVO(rdev))
 616                                                        pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV;
 617                                        }
 618                                }
 619                        }
 620
 621                        if (ASIC_IS_AVIVO(rdev)) {
 622                                /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
 623                                if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
 624                                        adjusted_clock = mode->clock * 2;
 625                                if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
 626                                        pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
 627                                if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
 628                                        pll->flags |= RADEON_PLL_IS_LCD;
 629                        } else {
 630                                if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
 631                                        pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
 632                                if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)
 633                                        pll->flags |= RADEON_PLL_USE_REF_DIV;
 634                        }
 635                        break;
 636                }
 637        }
 638
 639        /* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock
 640         * accordingly based on the encoder/transmitter to work around
 641         * special hw requirements.
 642         */
 643        if (ASIC_IS_DCE3(rdev)) {
 644                union adjust_pixel_clock args;
 645                u8 frev, crev;
 646                int index;
 647
 648                index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
 649                if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
 650                                           &crev))
 651                        return adjusted_clock;
 652
 653                memset(&args, 0, sizeof(args));
 654
 655                switch (frev) {
 656                case 1:
 657                        switch (crev) {
 658                        case 1:
 659                        case 2:
 660                                args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
 661                                args.v1.ucTransmitterID = radeon_encoder->encoder_id;
 662                                args.v1.ucEncodeMode = encoder_mode;
 663                                if (ss_enabled && ss->percentage)
 664                                        args.v1.ucConfig |=
 665                                                ADJUST_DISPLAY_CONFIG_SS_ENABLE;
 666
 667                                atom_execute_table(rdev->mode_info.atom_context,
 668                                                   index, (uint32_t *)&args);
 669                                adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10;
 670                                break;
 671                        case 3:
 672                                args.v3.sInput.usPixelClock = cpu_to_le16(mode->clock / 10);
 673                                args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id;
 674                                args.v3.sInput.ucEncodeMode = encoder_mode;
 675                                args.v3.sInput.ucDispPllConfig = 0;
 676                                if (ss_enabled && ss->percentage)
 677                                        args.v3.sInput.ucDispPllConfig |=
 678                                                DISPPLL_CONFIG_SS_ENABLE;
 679                                if (ENCODER_MODE_IS_DP(encoder_mode)) {
 680                                        args.v3.sInput.ucDispPllConfig |=
 681                                                DISPPLL_CONFIG_COHERENT_MODE;
 682                                        /* 16200 or 27000 */
 683                                        args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10);
 684                                } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
 685                                        struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 686                                        if (encoder_mode == ATOM_ENCODER_MODE_HDMI)
 687                                                /* deep color support */
 688                                                args.v3.sInput.usPixelClock =
 689                                                        cpu_to_le16((mode->clock * bpc / 8) / 10);
 690                                        if (dig->coherent_mode)
 691                                                args.v3.sInput.ucDispPllConfig |=
 692                                                        DISPPLL_CONFIG_COHERENT_MODE;
 693                                        if (is_duallink)
 694                                                args.v3.sInput.ucDispPllConfig |=
 695                                                        DISPPLL_CONFIG_DUAL_LINK;
 696                                }
 697                                if (radeon_encoder_get_dp_bridge_encoder_id(encoder) !=
 698                                    ENCODER_OBJECT_ID_NONE)
 699                                        args.v3.sInput.ucExtTransmitterID =
 700                                                radeon_encoder_get_dp_bridge_encoder_id(encoder);
 701                                else
 702                                        args.v3.sInput.ucExtTransmitterID = 0;
 703
 704                                atom_execute_table(rdev->mode_info.atom_context,
 705                                                   index, (uint32_t *)&args);
 706                                adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10;
 707                                if (args.v3.sOutput.ucRefDiv) {
 708                                        pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV;
 709                                        pll->flags |= RADEON_PLL_USE_REF_DIV;
 710                                        pll->reference_div = args.v3.sOutput.ucRefDiv;
 711                                }
 712                                if (args.v3.sOutput.ucPostDiv) {
 713                                        pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV;
 714                                        pll->flags |= RADEON_PLL_USE_POST_DIV;
 715                                        pll->post_div = args.v3.sOutput.ucPostDiv;
 716                                }
 717                                break;
 718                        default:
 719                                DRM_ERROR("Unknown table version %d %d\n", frev, crev);
 720                                return adjusted_clock;
 721                        }
 722                        break;
 723                default:
 724                        DRM_ERROR("Unknown table version %d %d\n", frev, crev);
 725                        return adjusted_clock;
 726                }
 727        }
 728        return adjusted_clock;
 729}
 730
 731union set_pixel_clock {
 732        SET_PIXEL_CLOCK_PS_ALLOCATION base;
 733        PIXEL_CLOCK_PARAMETERS v1;
 734        PIXEL_CLOCK_PARAMETERS_V2 v2;
 735        PIXEL_CLOCK_PARAMETERS_V3 v3;
 736        PIXEL_CLOCK_PARAMETERS_V5 v5;
 737        PIXEL_CLOCK_PARAMETERS_V6 v6;
 738};
 739
 740/* on DCE5, make sure the voltage is high enough to support the
 741 * required disp clk.
 742 */
 743static void atombios_crtc_set_disp_eng_pll(struct radeon_device *rdev,
 744                                    u32 dispclk)
 745{
 746        u8 frev, crev;
 747        int index;
 748        union set_pixel_clock args;
 749
 750        memset(&args, 0, sizeof(args));
 751
 752        index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
 753        if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
 754                                   &crev))
 755                return;
 756
 757        switch (frev) {
 758        case 1:
 759                switch (crev) {
 760                case 5:
 761                        /* if the default dcpll clock is specified,
 762                         * SetPixelClock provides the dividers
 763                         */
 764                        args.v5.ucCRTC = ATOM_CRTC_INVALID;
 765                        args.v5.usPixelClock = cpu_to_le16(dispclk);
 766                        args.v5.ucPpll = ATOM_DCPLL;
 767                        break;
 768                case 6:
 769                        /* if the default dcpll clock is specified,
 770                         * SetPixelClock provides the dividers
 771                         */
 772                        args.v6.ulDispEngClkFreq = cpu_to_le32(dispclk);
 773                        if (ASIC_IS_DCE61(rdev))
 774                                args.v6.ucPpll = ATOM_EXT_PLL1;
 775                        else if (ASIC_IS_DCE6(rdev))
 776                                args.v6.ucPpll = ATOM_PPLL0;
 777                        else
 778                                args.v6.ucPpll = ATOM_DCPLL;
 779                        break;
 780                default:
 781                        DRM_ERROR("Unknown table version %d %d\n", frev, crev);
 782                        return;
 783                }
 784                break;
 785        default:
 786                DRM_ERROR("Unknown table version %d %d\n", frev, crev);
 787                return;
 788        }
 789        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 790}
 791
 792static void atombios_crtc_program_pll(struct drm_crtc *crtc,
 793                                      u32 crtc_id,
 794                                      int pll_id,
 795                                      u32 encoder_mode,
 796                                      u32 encoder_id,
 797                                      u32 clock,
 798                                      u32 ref_div,
 799                                      u32 fb_div,
 800                                      u32 frac_fb_div,
 801                                      u32 post_div,
 802                                      int bpc,
 803                                      bool ss_enabled,
 804                                      struct radeon_atom_ss *ss)
 805{
 806        struct drm_device *dev = crtc->dev;
 807        struct radeon_device *rdev = dev->dev_private;
 808        u8 frev, crev;
 809        int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
 810        union set_pixel_clock args;
 811
 812        memset(&args, 0, sizeof(args));
 813
 814        if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
 815                                   &crev))
 816                return;
 817
 818        switch (frev) {
 819        case 1:
 820                switch (crev) {
 821                case 1:
 822                        if (clock == ATOM_DISABLE)
 823                                return;
 824                        args.v1.usPixelClock = cpu_to_le16(clock / 10);
 825                        args.v1.usRefDiv = cpu_to_le16(ref_div);
 826                        args.v1.usFbDiv = cpu_to_le16(fb_div);
 827                        args.v1.ucFracFbDiv = frac_fb_div;
 828                        args.v1.ucPostDiv = post_div;
 829                        args.v1.ucPpll = pll_id;
 830                        args.v1.ucCRTC = crtc_id;
 831                        args.v1.ucRefDivSrc = 1;
 832                        break;
 833                case 2:
 834                        args.v2.usPixelClock = cpu_to_le16(clock / 10);
 835                        args.v2.usRefDiv = cpu_to_le16(ref_div);
 836                        args.v2.usFbDiv = cpu_to_le16(fb_div);
 837                        args.v2.ucFracFbDiv = frac_fb_div;
 838                        args.v2.ucPostDiv = post_div;
 839                        args.v2.ucPpll = pll_id;
 840                        args.v2.ucCRTC = crtc_id;
 841                        args.v2.ucRefDivSrc = 1;
 842                        break;
 843                case 3:
 844                        args.v3.usPixelClock = cpu_to_le16(clock / 10);
 845                        args.v3.usRefDiv = cpu_to_le16(ref_div);
 846                        args.v3.usFbDiv = cpu_to_le16(fb_div);
 847                        args.v3.ucFracFbDiv = frac_fb_div;
 848                        args.v3.ucPostDiv = post_div;
 849                        args.v3.ucPpll = pll_id;
 850                        args.v3.ucMiscInfo = (pll_id << 2);
 851                        if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
 852                                args.v3.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
 853                        args.v3.ucTransmitterId = encoder_id;
 854                        args.v3.ucEncoderMode = encoder_mode;
 855                        break;
 856                case 5:
 857                        args.v5.ucCRTC = crtc_id;
 858                        args.v5.usPixelClock = cpu_to_le16(clock / 10);
 859                        args.v5.ucRefDiv = ref_div;
 860                        args.v5.usFbDiv = cpu_to_le16(fb_div);
 861                        args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
 862                        args.v5.ucPostDiv = post_div;
 863                        args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */
 864                        if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
 865                                args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_REF_DIV_SRC;
 866                        switch (bpc) {
 867                        case 8:
 868                        default:
 869                                args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_24BPP;
 870                                break;
 871                        case 10:
 872                                args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP;
 873                                break;
 874                        }
 875                        args.v5.ucTransmitterID = encoder_id;
 876                        args.v5.ucEncoderMode = encoder_mode;
 877                        args.v5.ucPpll = pll_id;
 878                        break;
 879                case 6:
 880                        args.v6.ulDispEngClkFreq = cpu_to_le32(crtc_id << 24 | clock / 10);
 881                        args.v6.ucRefDiv = ref_div;
 882                        args.v6.usFbDiv = cpu_to_le16(fb_div);
 883                        args.v6.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
 884                        args.v6.ucPostDiv = post_div;
 885                        args.v6.ucMiscInfo = 0; /* HDMI depth, etc. */
 886                        if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
 887                                args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
 888                        switch (bpc) {
 889                        case 8:
 890                        default:
 891                                args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_24BPP;
 892                                break;
 893                        case 10:
 894                                args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP;
 895                                break;
 896                        case 12:
 897                                args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP;
 898                                break;
 899                        case 16:
 900                                args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP;
 901                                break;
 902                        }
 903                        args.v6.ucTransmitterID = encoder_id;
 904                        args.v6.ucEncoderMode = encoder_mode;
 905                        args.v6.ucPpll = pll_id;
 906                        break;
 907                default:
 908                        DRM_ERROR("Unknown table version %d %d\n", frev, crev);
 909                        return;
 910                }
 911                break;
 912        default:
 913                DRM_ERROR("Unknown table version %d %d\n", frev, crev);
 914                return;
 915        }
 916
 917        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 918}
 919
 920static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
 921{
 922        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 923        struct drm_device *dev = crtc->dev;
 924        struct radeon_device *rdev = dev->dev_private;
 925        struct drm_encoder *encoder = NULL;
 926        struct radeon_encoder *radeon_encoder = NULL;
 927        u32 pll_clock = mode->clock;
 928        u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
 929        struct radeon_pll *pll;
 930        u32 adjusted_clock;
 931        int encoder_mode = 0;
 932        struct radeon_atom_ss ss;
 933        bool ss_enabled = false;
 934        int bpc = 8;
 935
 936        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 937                if (encoder->crtc == crtc) {
 938                        radeon_encoder = to_radeon_encoder(encoder);
 939                        encoder_mode = atombios_get_encoder_mode(encoder);
 940                        break;
 941                }
 942        }
 943
 944        if (!radeon_encoder)
 945                return;
 946
 947        switch (radeon_crtc->pll_id) {
 948        case ATOM_PPLL1:
 949                pll = &rdev->clock.p1pll;
 950                break;
 951        case ATOM_PPLL2:
 952                pll = &rdev->clock.p2pll;
 953                break;
 954        case ATOM_DCPLL:
 955        case ATOM_PPLL_INVALID:
 956        default:
 957                pll = &rdev->clock.dcpll;
 958                break;
 959        }
 960
 961        if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
 962            (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) {
 963                struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 964                struct drm_connector *connector =
 965                        radeon_get_connector_for_encoder(encoder);
 966                struct radeon_connector *radeon_connector =
 967                        to_radeon_connector(connector);
 968                struct radeon_connector_atom_dig *dig_connector =
 969                        radeon_connector->con_priv;
 970                int dp_clock;
 971
 972                /* if (connector->display_info.bpc)
 973                        bpc = connector->display_info.bpc; */
 974
 975                switch (encoder_mode) {
 976                case ATOM_ENCODER_MODE_DP_MST:
 977                case ATOM_ENCODER_MODE_DP:
 978                        /* DP/eDP */
 979                        dp_clock = dig_connector->dp_clock / 10;
 980                        if (ASIC_IS_DCE4(rdev))
 981                                ss_enabled =
 982                                        radeon_atombios_get_asic_ss_info(rdev, &ss,
 983                                                                         ASIC_INTERNAL_SS_ON_DP,
 984                                                                         dp_clock);
 985                        else {
 986                                if (dp_clock == 16200) {
 987                                        ss_enabled =
 988                                                radeon_atombios_get_ppll_ss_info(rdev, &ss,
 989                                                                                 ATOM_DP_SS_ID2);
 990                                        if (!ss_enabled)
 991                                                ss_enabled =
 992                                                        radeon_atombios_get_ppll_ss_info(rdev, &ss,
 993                                                                                         ATOM_DP_SS_ID1);
 994                                } else
 995                                        ss_enabled =
 996                                                radeon_atombios_get_ppll_ss_info(rdev, &ss,
 997                                                                                 ATOM_DP_SS_ID1);
 998                        }
 999                        break;
1000                case ATOM_ENCODER_MODE_LVDS:
1001                        if (ASIC_IS_DCE4(rdev))
1002                                ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss,
1003                                                                              dig->lcd_ss_id,
1004                                                                              mode->clock / 10);
1005                        else
1006                                ss_enabled = radeon_atombios_get_ppll_ss_info(rdev, &ss,
1007                                                                              dig->lcd_ss_id);
1008                        break;
1009                case ATOM_ENCODER_MODE_DVI:
1010                        if (ASIC_IS_DCE4(rdev))
1011                                ss_enabled =
1012                                        radeon_atombios_get_asic_ss_info(rdev, &ss,
1013                                                                         ASIC_INTERNAL_SS_ON_TMDS,
1014                                                                         mode->clock / 10);
1015                        break;
1016                case ATOM_ENCODER_MODE_HDMI:
1017                        if (ASIC_IS_DCE4(rdev))
1018                                ss_enabled =
1019                                        radeon_atombios_get_asic_ss_info(rdev, &ss,
1020                                                                         ASIC_INTERNAL_SS_ON_HDMI,
1021                                                                         mode->clock / 10);
1022                        break;
1023                default:
1024                        break;
1025                }
1026        }
1027
1028        /* adjust pixel clock as needed */
1029        adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss);
1030
1031        if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
1032                /* TV seems to prefer the legacy algo on some boards */
1033                radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
1034                                          &ref_div, &post_div);
1035        else if (ASIC_IS_AVIVO(rdev))
1036                radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
1037                                         &ref_div, &post_div);
1038        else
1039                radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
1040                                          &ref_div, &post_div);
1041
1042        atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, &ss);
1043
1044        atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
1045                                  encoder_mode, radeon_encoder->encoder_id, mode->clock,
1046                                  ref_div, fb_div, frac_fb_div, post_div, bpc, ss_enabled, &ss);
1047
1048        if (ss_enabled) {
1049                /* calculate ss amount and step size */
1050                if (ASIC_IS_DCE4(rdev)) {
1051                        u32 step_size;
1052                        u32 amount = (((fb_div * 10) + frac_fb_div) * ss.percentage) / 10000;
1053                        ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK;
1054                        ss.amount |= ((amount - (amount / 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
1055                                ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK;
1056                        if (ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD)
1057                                step_size = (4 * amount * ref_div * (ss.rate * 2048)) /
1058                                        (125 * 25 * pll->reference_freq / 100);
1059                        else
1060                                step_size = (2 * amount * ref_div * (ss.rate * 2048)) /
1061                                        (125 * 25 * pll->reference_freq / 100);
1062                        ss.step = step_size;
1063                }
1064
1065                atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, &ss);
1066        }
1067}
1068
1069static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
1070                                 struct drm_framebuffer *fb,
1071                                 int x, int y, int atomic)
1072{
1073        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1074        struct drm_device *dev = crtc->dev;
1075        struct radeon_device *rdev = dev->dev_private;
1076        struct radeon_framebuffer *radeon_fb;
1077        struct drm_framebuffer *target_fb;
1078        struct drm_gem_object *obj;
1079        struct radeon_bo *rbo;
1080        uint64_t fb_location;
1081        uint32_t fb_format, fb_pitch_pixels, tiling_flags;
1082        unsigned bankw, bankh, mtaspect, tile_split;
1083        u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE);
1084        u32 tmp, viewport_w, viewport_h;
1085        int r;
1086
1087        /* no fb bound */
1088        if (!atomic && !crtc->fb) {
1089                DRM_DEBUG_KMS("No FB bound\n");
1090                return 0;
1091        }
1092
1093        if (atomic) {
1094                radeon_fb = to_radeon_framebuffer(fb);
1095                target_fb = fb;
1096        }
1097        else {
1098                radeon_fb = to_radeon_framebuffer(crtc->fb);
1099                target_fb = crtc->fb;
1100        }
1101
1102        /* If atomic, assume fb object is pinned & idle & fenced and
1103         * just update base pointers
1104         */
1105        obj = radeon_fb->obj;
1106        rbo = gem_to_radeon_bo(obj);
1107        r = radeon_bo_reserve(rbo, false);
1108        if (unlikely(r != 0))
1109                return r;
1110
1111        if (atomic)
1112                fb_location = radeon_bo_gpu_offset(rbo);
1113        else {
1114                r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
1115                if (unlikely(r != 0)) {
1116                        radeon_bo_unreserve(rbo);
1117                        return -EINVAL;
1118                }
1119        }
1120
1121        radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
1122        radeon_bo_unreserve(rbo);
1123
1124        switch (target_fb->bits_per_pixel) {
1125        case 8:
1126                fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) |
1127                             EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED));
1128                break;
1129        case 15:
1130                fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
1131                             EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB1555));
1132                break;
1133        case 16:
1134                fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
1135                             EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565));
1136#ifdef __BIG_ENDIAN
1137                fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
1138#endif
1139                break;
1140        case 24:
1141        case 32:
1142                fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
1143                             EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888));
1144#ifdef __BIG_ENDIAN
1145                fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
1146#endif
1147                break;
1148        default:
1149                DRM_ERROR("Unsupported screen depth %d\n",
1150                          target_fb->bits_per_pixel);
1151                return -EINVAL;
1152        }
1153
1154        if (tiling_flags & RADEON_TILING_MACRO) {
1155                if (rdev->family >= CHIP_CAYMAN)
1156                        tmp = rdev->config.cayman.tile_config;
1157                else
1158                        tmp = rdev->config.evergreen.tile_config;
1159
1160                switch ((tmp & 0xf0) >> 4) {
1161                case 0: /* 4 banks */
1162                        fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_4_BANK);
1163                        break;
1164                case 1: /* 8 banks */
1165                default:
1166                        fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_8_BANK);
1167                        break;
1168                case 2: /* 16 banks */
1169                        fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_16_BANK);
1170                        break;
1171                }
1172
1173                fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1);
1174
1175                evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split);
1176                fb_format |= EVERGREEN_GRPH_TILE_SPLIT(tile_split);
1177                fb_format |= EVERGREEN_GRPH_BANK_WIDTH(bankw);
1178                fb_format |= EVERGREEN_GRPH_BANK_HEIGHT(bankh);
1179                fb_format |= EVERGREEN_GRPH_MACRO_TILE_ASPECT(mtaspect);
1180        } else if (tiling_flags & RADEON_TILING_MICRO)
1181                fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1);
1182
1183        switch (radeon_crtc->crtc_id) {
1184        case 0:
1185                WREG32(AVIVO_D1VGA_CONTROL, 0);
1186                break;
1187        case 1:
1188                WREG32(AVIVO_D2VGA_CONTROL, 0);
1189                break;
1190        case 2:
1191                WREG32(EVERGREEN_D3VGA_CONTROL, 0);
1192                break;
1193        case 3:
1194                WREG32(EVERGREEN_D4VGA_CONTROL, 0);
1195                break;
1196        case 4:
1197                WREG32(EVERGREEN_D5VGA_CONTROL, 0);
1198                break;
1199        case 5:
1200                WREG32(EVERGREEN_D6VGA_CONTROL, 0);
1201                break;
1202        default:
1203                break;
1204        }
1205
1206        WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
1207               upper_32_bits(fb_location));
1208        WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
1209               upper_32_bits(fb_location));
1210        WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
1211               (u32)fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
1212        WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
1213               (u32) fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
1214        WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
1215        WREG32(EVERGREEN_GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap);
1216
1217        WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
1218        WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
1219        WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0);
1220        WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0);
1221        WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width);
1222        WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height);
1223
1224        fb_pitch_pixels = target_fb->pitches[0] / (target_fb->bits_per_pixel / 8);
1225        WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
1226        WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
1227
1228        WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
1229               target_fb->height);
1230        x &= ~3;
1231        y &= ~1;
1232        WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset,
1233               (x << 16) | y);
1234        viewport_w = crtc->mode.hdisplay;
1235        viewport_h = (crtc->mode.vdisplay + 1) & ~1;
1236        WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
1237               (viewport_w << 16) | viewport_h);
1238
1239        /* pageflip setup */
1240        /* make sure flip is at vb rather than hb */
1241        tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset);
1242        tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN;
1243        WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp);
1244
1245        /* set pageflip to happen anywhere in vblank interval */
1246        WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
1247
1248        if (!atomic && fb && fb != crtc->fb) {
1249                radeon_fb = to_radeon_framebuffer(fb);
1250                rbo = gem_to_radeon_bo(radeon_fb->obj);
1251                r = radeon_bo_reserve(rbo, false);
1252                if (unlikely(r != 0))
1253                        return r;
1254                radeon_bo_unpin(rbo);
1255                radeon_bo_unreserve(rbo);
1256        }
1257
1258        /* Bytes per pixel may have changed */
1259        radeon_bandwidth_update(rdev);
1260
1261        return 0;
1262}
1263
1264static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
1265                                  struct drm_framebuffer *fb,
1266                                  int x, int y, int atomic)
1267{
1268        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1269        struct drm_device *dev = crtc->dev;
1270        struct radeon_device *rdev = dev->dev_private;
1271        struct radeon_framebuffer *radeon_fb;
1272        struct drm_gem_object *obj;
1273        struct radeon_bo *rbo;
1274        struct drm_framebuffer *target_fb;
1275        uint64_t fb_location;
1276        uint32_t fb_format, fb_pitch_pixels, tiling_flags;
1277        u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE;
1278        u32 tmp, viewport_w, viewport_h;
1279        int r;
1280
1281        /* no fb bound */
1282        if (!atomic && !crtc->fb) {
1283                DRM_DEBUG_KMS("No FB bound\n");
1284                return 0;
1285        }
1286
1287        if (atomic) {
1288                radeon_fb = to_radeon_framebuffer(fb);
1289                target_fb = fb;
1290        }
1291        else {
1292                radeon_fb = to_radeon_framebuffer(crtc->fb);
1293                target_fb = crtc->fb;
1294        }
1295
1296        obj = radeon_fb->obj;
1297        rbo = gem_to_radeon_bo(obj);
1298        r = radeon_bo_reserve(rbo, false);
1299        if (unlikely(r != 0))
1300                return r;
1301
1302        /* If atomic, assume fb object is pinned & idle & fenced and
1303         * just update base pointers
1304         */
1305        if (atomic)
1306                fb_location = radeon_bo_gpu_offset(rbo);
1307        else {
1308                r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
1309                if (unlikely(r != 0)) {
1310                        radeon_bo_unreserve(rbo);
1311                        return -EINVAL;
1312                }
1313        }
1314        radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
1315        radeon_bo_unreserve(rbo);
1316
1317        switch (target_fb->bits_per_pixel) {
1318        case 8:
1319                fb_format =
1320                    AVIVO_D1GRPH_CONTROL_DEPTH_8BPP |
1321                    AVIVO_D1GRPH_CONTROL_8BPP_INDEXED;
1322                break;
1323        case 15:
1324                fb_format =
1325                    AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
1326                    AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555;
1327                break;
1328        case 16:
1329                fb_format =
1330                    AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
1331                    AVIVO_D1GRPH_CONTROL_16BPP_RGB565;
1332#ifdef __BIG_ENDIAN
1333                fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
1334#endif
1335                break;
1336        case 24:
1337        case 32:
1338                fb_format =
1339                    AVIVO_D1GRPH_CONTROL_DEPTH_32BPP |
1340                    AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888;
1341#ifdef __BIG_ENDIAN
1342                fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT;
1343#endif
1344                break;
1345        default:
1346                DRM_ERROR("Unsupported screen depth %d\n",
1347                          target_fb->bits_per_pixel);
1348                return -EINVAL;
1349        }
1350
1351        if (rdev->family >= CHIP_R600) {
1352                if (tiling_flags & RADEON_TILING_MACRO)
1353                        fb_format |= R600_D1GRPH_ARRAY_MODE_2D_TILED_THIN1;
1354                else if (tiling_flags & RADEON_TILING_MICRO)
1355                        fb_format |= R600_D1GRPH_ARRAY_MODE_1D_TILED_THIN1;
1356        } else {
1357                if (tiling_flags & RADEON_TILING_MACRO)
1358                        fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
1359
1360                if (tiling_flags & RADEON_TILING_MICRO)
1361                        fb_format |= AVIVO_D1GRPH_TILED;
1362        }
1363
1364        if (radeon_crtc->crtc_id == 0)
1365                WREG32(AVIVO_D1VGA_CONTROL, 0);
1366        else
1367                WREG32(AVIVO_D2VGA_CONTROL, 0);
1368
1369        if (rdev->family >= CHIP_RV770) {
1370                if (radeon_crtc->crtc_id) {
1371                        WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
1372                        WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
1373                } else {
1374                        WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
1375                        WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
1376                }
1377        }
1378        WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
1379               (u32) fb_location);
1380        WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS +
1381               radeon_crtc->crtc_offset, (u32) fb_location);
1382        WREG32(AVIVO_D1GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
1383        if (rdev->family >= CHIP_R600)
1384                WREG32(R600_D1GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap);
1385
1386        WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
1387        WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
1388        WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0);
1389        WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0);
1390        WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width);
1391        WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height);
1392
1393        fb_pitch_pixels = target_fb->pitches[0] / (target_fb->bits_per_pixel / 8);
1394        WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
1395        WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
1396
1397        WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
1398               target_fb->height);
1399        x &= ~3;
1400        y &= ~1;
1401        WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset,
1402               (x << 16) | y);
1403        viewport_w = crtc->mode.hdisplay;
1404        viewport_h = (crtc->mode.vdisplay + 1) & ~1;
1405        WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
1406               (viewport_w << 16) | viewport_h);
1407
1408        /* pageflip setup */
1409        /* make sure flip is at vb rather than hb */
1410        tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset);
1411        tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN;
1412        WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp);
1413
1414        /* set pageflip to happen anywhere in vblank interval */
1415        WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
1416
1417        if (!atomic && fb && fb != crtc->fb) {
1418                radeon_fb = to_radeon_framebuffer(fb);
1419                rbo = gem_to_radeon_bo(radeon_fb->obj);
1420                r = radeon_bo_reserve(rbo, false);
1421                if (unlikely(r != 0))
1422                        return r;
1423                radeon_bo_unpin(rbo);
1424                radeon_bo_unreserve(rbo);
1425        }
1426
1427        /* Bytes per pixel may have changed */
1428        radeon_bandwidth_update(rdev);
1429
1430        return 0;
1431}
1432
1433int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
1434                           struct drm_framebuffer *old_fb)
1435{
1436        struct drm_device *dev = crtc->dev;
1437        struct radeon_device *rdev = dev->dev_private;
1438
1439        if (ASIC_IS_DCE4(rdev))
1440                return dce4_crtc_do_set_base(crtc, old_fb, x, y, 0);
1441        else if (ASIC_IS_AVIVO(rdev))
1442                return avivo_crtc_do_set_base(crtc, old_fb, x, y, 0);
1443        else
1444                return radeon_crtc_do_set_base(crtc, old_fb, x, y, 0);
1445}
1446
1447int atombios_crtc_set_base_atomic(struct drm_crtc *crtc,
1448                                  struct drm_framebuffer *fb,
1449                                  int x, int y, enum mode_set_atomic state)
1450{
1451       struct drm_device *dev = crtc->dev;
1452       struct radeon_device *rdev = dev->dev_private;
1453
1454        if (ASIC_IS_DCE4(rdev))
1455                return dce4_crtc_do_set_base(crtc, fb, x, y, 1);
1456        else if (ASIC_IS_AVIVO(rdev))
1457                return avivo_crtc_do_set_base(crtc, fb, x, y, 1);
1458        else
1459                return radeon_crtc_do_set_base(crtc, fb, x, y, 1);
1460}
1461
1462/* properly set additional regs when using atombios */
1463static void radeon_legacy_atom_fixup(struct drm_crtc *crtc)
1464{
1465        struct drm_device *dev = crtc->dev;
1466        struct radeon_device *rdev = dev->dev_private;
1467        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1468        u32 disp_merge_cntl;
1469
1470        switch (radeon_crtc->crtc_id) {
1471        case 0:
1472                disp_merge_cntl = RREG32(RADEON_DISP_MERGE_CNTL);
1473                disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
1474                WREG32(RADEON_DISP_MERGE_CNTL, disp_merge_cntl);
1475                break;
1476        case 1:
1477                disp_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL);
1478                disp_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN;
1479                WREG32(RADEON_DISP2_MERGE_CNTL, disp_merge_cntl);
1480                WREG32(RADEON_FP_H2_SYNC_STRT_WID,   RREG32(RADEON_CRTC2_H_SYNC_STRT_WID));
1481                WREG32(RADEON_FP_V2_SYNC_STRT_WID,   RREG32(RADEON_CRTC2_V_SYNC_STRT_WID));
1482                break;
1483        }
1484}
1485
1486static int radeon_atom_pick_pll(struct drm_crtc *crtc)
1487{
1488        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1489        struct drm_device *dev = crtc->dev;
1490        struct radeon_device *rdev = dev->dev_private;
1491        struct drm_encoder *test_encoder;
1492        struct drm_crtc *test_crtc;
1493        uint32_t pll_in_use = 0;
1494
1495        if (ASIC_IS_DCE61(rdev)) {
1496                list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
1497                        if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
1498                                struct radeon_encoder *test_radeon_encoder =
1499                                        to_radeon_encoder(test_encoder);
1500                                struct radeon_encoder_atom_dig *dig =
1501                                        test_radeon_encoder->enc_priv;
1502
1503                                if ((test_radeon_encoder->encoder_id ==
1504                                     ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
1505                                    (dig->linkb == false)) /* UNIPHY A uses PPLL2 */
1506                                        return ATOM_PPLL2;
1507                        }
1508                }
1509                /* UNIPHY B/C/D/E/F */
1510                list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
1511                        struct radeon_crtc *radeon_test_crtc;
1512
1513                        if (crtc == test_crtc)
1514                                continue;
1515
1516                        radeon_test_crtc = to_radeon_crtc(test_crtc);
1517                        if ((radeon_test_crtc->pll_id == ATOM_PPLL0) ||
1518                            (radeon_test_crtc->pll_id == ATOM_PPLL1))
1519                                pll_in_use |= (1 << radeon_test_crtc->pll_id);
1520                }
1521                if (!(pll_in_use & 4))
1522                        return ATOM_PPLL0;
1523                return ATOM_PPLL1;
1524        } else if (ASIC_IS_DCE4(rdev)) {
1525                list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
1526                        if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
1527                                /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,
1528                                 * depending on the asic:
1529                                 * DCE4: PPLL or ext clock
1530                                 * DCE5: DCPLL or ext clock
1531                                 *
1532                                 * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip
1533                                 * PPLL/DCPLL programming and only program the DP DTO for the
1534                                 * crtc virtual pixel clock.
1535                                 */
1536                                if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
1537                                        if (ASIC_IS_DCE5(rdev) || rdev->clock.dp_extclk)
1538                                                return ATOM_PPLL_INVALID;
1539                                }
1540                        }
1541                }
1542
1543                /* otherwise, pick one of the plls */
1544                list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
1545                        struct radeon_crtc *radeon_test_crtc;
1546
1547                        if (crtc == test_crtc)
1548                                continue;
1549
1550                        radeon_test_crtc = to_radeon_crtc(test_crtc);
1551                        if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) &&
1552                            (radeon_test_crtc->pll_id <= ATOM_PPLL2))
1553                                pll_in_use |= (1 << radeon_test_crtc->pll_id);
1554                }
1555                if (!(pll_in_use & 1))
1556                        return ATOM_PPLL1;
1557                return ATOM_PPLL2;
1558        } else
1559                return radeon_crtc->crtc_id;
1560
1561}
1562
1563void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev)
1564{
1565        /* always set DCPLL */
1566        if (ASIC_IS_DCE6(rdev))
1567                atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk);
1568        else if (ASIC_IS_DCE4(rdev)) {
1569                struct radeon_atom_ss ss;
1570                bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss,
1571                                                                   ASIC_INTERNAL_SS_ON_DCPLL,
1572                                                                   rdev->clock.default_dispclk);
1573                if (ss_enabled)
1574                        atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, &ss);
1575                /* XXX: DCE5, make sure voltage, dispclk is high enough */
1576                atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk);
1577                if (ss_enabled)
1578                        atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, &ss);
1579        }
1580
1581}
1582
1583int atombios_crtc_mode_set(struct drm_crtc *crtc,
1584                           struct drm_display_mode *mode,
1585                           struct drm_display_mode *adjusted_mode,
1586                           int x, int y, struct drm_framebuffer *old_fb)
1587{
1588        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1589        struct drm_device *dev = crtc->dev;
1590        struct radeon_device *rdev = dev->dev_private;
1591        struct drm_encoder *encoder;
1592        bool is_tvcv = false;
1593
1594        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
1595                /* find tv std */
1596                if (encoder->crtc == crtc) {
1597                        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1598                        if (radeon_encoder->active_device &
1599                            (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
1600                                is_tvcv = true;
1601                }
1602        }
1603
1604        atombios_crtc_set_pll(crtc, adjusted_mode);
1605
1606        if (ASIC_IS_DCE4(rdev))
1607                atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
1608        else if (ASIC_IS_AVIVO(rdev)) {
1609                if (is_tvcv)
1610                        atombios_crtc_set_timing(crtc, adjusted_mode);
1611                else
1612                        atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
1613        } else {
1614                atombios_crtc_set_timing(crtc, adjusted_mode);
1615                if (radeon_crtc->crtc_id == 0)
1616                        atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
1617                radeon_legacy_atom_fixup(crtc);
1618        }
1619        atombios_crtc_set_base(crtc, x, y, old_fb);
1620        atombios_overscan_setup(crtc, mode, adjusted_mode);
1621        atombios_scaler_setup(crtc);
1622        return 0;
1623}
1624
1625static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
1626                                     struct drm_display_mode *mode,
1627                                     struct drm_display_mode *adjusted_mode)
1628{
1629        if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
1630                return false;
1631        return true;
1632}
1633
1634static void atombios_crtc_prepare(struct drm_crtc *crtc)
1635{
1636        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1637
1638        /* pick pll */
1639        radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
1640
1641        atombios_lock_crtc(crtc, ATOM_ENABLE);
1642        atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
1643}
1644
1645static void atombios_crtc_commit(struct drm_crtc *crtc)
1646{
1647        atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
1648        atombios_lock_crtc(crtc, ATOM_DISABLE);
1649}
1650
1651static void atombios_crtc_disable(struct drm_crtc *crtc)
1652{
1653        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1654        struct drm_device *dev = crtc->dev;
1655        struct radeon_device *rdev = dev->dev_private;
1656        struct radeon_atom_ss ss;
1657
1658        atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
1659
1660        switch (radeon_crtc->pll_id) {
1661        case ATOM_PPLL1:
1662        case ATOM_PPLL2:
1663                /* disable the ppll */
1664                atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
1665                                          0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
1666                break;
1667        case ATOM_PPLL0:
1668                /* disable the ppll */
1669                if (ASIC_IS_DCE61(rdev))
1670                        atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
1671                                                  0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
1672                break;
1673        default:
1674                break;
1675        }
1676        radeon_crtc->pll_id = -1;
1677}
1678
1679static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
1680        .dpms = atombios_crtc_dpms,
1681        .mode_fixup = atombios_crtc_mode_fixup,
1682        .mode_set = atombios_crtc_mode_set,
1683        .mode_set_base = atombios_crtc_set_base,
1684        .mode_set_base_atomic = atombios_crtc_set_base_atomic,
1685        .prepare = atombios_crtc_prepare,
1686        .commit = atombios_crtc_commit,
1687        .load_lut = radeon_crtc_load_lut,
1688        .disable = atombios_crtc_disable,
1689};
1690
1691void radeon_atombios_init_crtc(struct drm_device *dev,
1692                               struct radeon_crtc *radeon_crtc)
1693{
1694        struct radeon_device *rdev = dev->dev_private;
1695
1696        if (ASIC_IS_DCE4(rdev)) {
1697                switch (radeon_crtc->crtc_id) {
1698                case 0:
1699                default:
1700                        radeon_crtc->crtc_offset = EVERGREEN_CRTC0_REGISTER_OFFSET;
1701                        break;
1702                case 1:
1703                        radeon_crtc->crtc_offset = EVERGREEN_CRTC1_REGISTER_OFFSET;
1704                        break;
1705                case 2:
1706                        radeon_crtc->crtc_offset = EVERGREEN_CRTC2_REGISTER_OFFSET;
1707                        break;
1708                case 3:
1709                        radeon_crtc->crtc_offset = EVERGREEN_CRTC3_REGISTER_OFFSET;
1710                        break;
1711                case 4:
1712                        radeon_crtc->crtc_offset = EVERGREEN_CRTC4_REGISTER_OFFSET;
1713                        break;
1714                case 5:
1715                        radeon_crtc->crtc_offset = EVERGREEN_CRTC5_REGISTER_OFFSET;
1716                        break;
1717                }
1718        } else {
1719                if (radeon_crtc->crtc_id == 1)
1720                        radeon_crtc->crtc_offset =
1721                                AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL;
1722                else
1723                        radeon_crtc->crtc_offset = 0;
1724        }
1725        radeon_crtc->pll_id = -1;
1726        drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
1727}
1728