drm/radeon/kms/atom: add support for AdjustDisplayPll
[safe/jmp/linux-2.6] / drivers / gpu / drm / radeon / atombios_crtc.c
index eac26cd..d5e6f3d 100644 (file)
 #include "atom.h"
 #include "atom-bits.h"
 
+/* evil but including atombios.h is much worse */
+bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
+                               SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing,
+                               int32_t *pixel_clock);
+static void atombios_overscan_setup(struct drm_crtc *crtc,
+                                   struct drm_display_mode *mode,
+                                   struct drm_display_mode *adjusted_mode)
+{
+       struct drm_device *dev = crtc->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+       SET_CRTC_OVERSCAN_PS_ALLOCATION args;
+       int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_OverScan);
+       int a1, a2;
+
+       memset(&args, 0, sizeof(args));
+
+       args.usOverscanRight = 0;
+       args.usOverscanLeft = 0;
+       args.usOverscanBottom = 0;
+       args.usOverscanTop = 0;
+       args.ucCRTC = radeon_crtc->crtc_id;
+
+       switch (radeon_crtc->rmx_type) {
+       case RMX_CENTER:
+               args.usOverscanTop = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2;
+               args.usOverscanBottom = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2;
+               args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2;
+               args.usOverscanRight = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2;
+               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+               break;
+       case RMX_ASPECT:
+               a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay;
+               a2 = adjusted_mode->crtc_vdisplay * mode->crtc_hdisplay;
+
+               if (a1 > a2) {
+                       args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2;
+                       args.usOverscanRight = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2;
+               } else if (a2 > a1) {
+                       args.usOverscanLeft = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2;
+                       args.usOverscanRight = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2;
+               }
+               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+               break;
+       case RMX_FULL:
+       default:
+               args.usOverscanRight = 0;
+               args.usOverscanLeft = 0;
+               args.usOverscanBottom = 0;
+               args.usOverscanTop = 0;
+               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+               break;
+       }
+}
+
+static void atombios_scaler_setup(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+       ENABLE_SCALER_PS_ALLOCATION args;
+       int index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
+
+       /* fixme - fill in enc_priv for atom dac */
+       enum radeon_tv_std tv_std = TV_STD_NTSC;
+       bool is_tv = false, is_cv = false;
+       struct drm_encoder *encoder;
+
+       if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id)
+               return;
+
+       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+               /* find tv std */
+               if (encoder->crtc == crtc) {
+                       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+                       if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
+                               struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
+                               tv_std = tv_dac->tv_std;
+                               is_tv = true;
+                       }
+               }
+       }
+
+       memset(&args, 0, sizeof(args));
+
+       args.ucScaler = radeon_crtc->crtc_id;
+
+       if (is_tv) {
+               switch (tv_std) {
+               case TV_STD_NTSC:
+               default:
+                       args.ucTVStandard = ATOM_TV_NTSC;
+                       break;
+               case TV_STD_PAL:
+                       args.ucTVStandard = ATOM_TV_PAL;
+                       break;
+               case TV_STD_PAL_M:
+                       args.ucTVStandard = ATOM_TV_PALM;
+                       break;
+               case TV_STD_PAL_60:
+                       args.ucTVStandard = ATOM_TV_PAL60;
+                       break;
+               case TV_STD_NTSC_J:
+                       args.ucTVStandard = ATOM_TV_NTSCJ;
+                       break;
+               case TV_STD_SCART_PAL:
+                       args.ucTVStandard = ATOM_TV_PAL; /* ??? */
+                       break;
+               case TV_STD_SECAM:
+                       args.ucTVStandard = ATOM_TV_SECAM;
+                       break;
+               case TV_STD_PAL_CN:
+                       args.ucTVStandard = ATOM_TV_PALCN;
+                       break;
+               }
+               args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
+       } else if (is_cv) {
+               args.ucTVStandard = ATOM_TV_CV;
+               args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
+       } else {
+               switch (radeon_crtc->rmx_type) {
+               case RMX_FULL:
+                       args.ucEnable = ATOM_SCALER_EXPANSION;
+                       break;
+               case RMX_CENTER:
+                       args.ucEnable = ATOM_SCALER_CENTER;
+                       break;
+               case RMX_ASPECT:
+                       args.ucEnable = ATOM_SCALER_EXPANSION;
+                       break;
+               default:
+                       if (ASIC_IS_AVIVO(rdev))
+                               args.ucEnable = ATOM_SCALER_DISABLE;
+                       else
+                               args.ucEnable = ATOM_SCALER_CENTER;
+                       break;
+               }
+       }
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+       if ((is_tv || is_cv)
+           && rdev->family >= CHIP_RV515 && rdev->family <= CHIP_R580) {
+               atom_rv515_force_tv_scaler(rdev, radeon_crtc);
+       }
+}
+
 static void atombios_lock_crtc(struct drm_crtc *crtc, int lock)
 {
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
@@ -103,18 +248,18 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
 
        switch (mode) {
        case DRM_MODE_DPMS_ON:
+               atombios_enable_crtc(crtc, 1);
                if (ASIC_IS_DCE3(rdev))
                        atombios_enable_crtc_memreq(crtc, 1);
-               atombios_enable_crtc(crtc, 1);
                atombios_blank_crtc(crtc, 0);
                break;
        case DRM_MODE_DPMS_STANDBY:
        case DRM_MODE_DPMS_SUSPEND:
        case DRM_MODE_DPMS_OFF:
                atombios_blank_crtc(crtc, 1);
-               atombios_enable_crtc(crtc, 0);
                if (ASIC_IS_DCE3(rdev))
                        atombios_enable_crtc_memreq(crtc, 0);
+               atombios_enable_crtc(crtc, 0);
                break;
        }
 
@@ -188,12 +333,13 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
        struct drm_encoder *encoder = NULL;
        struct radeon_encoder *radeon_encoder = NULL;
        uint8_t frev, crev;
-       int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
+       int index;
        SET_PIXEL_CLOCK_PS_ALLOCATION args;
        PIXEL_CLOCK_PARAMETERS *spc1_ptr;
        PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr;
        PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr;
-       uint32_t sclock = mode->clock;
+       uint32_t pll_clock = mode->clock;
+       uint32_t adjusted_clock;
        uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
        struct radeon_pll *pll;
        int pll_flags = 0;
@@ -244,15 +390,38 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
                                        pll_flags |= RADEON_PLL_USE_REF_DIV;
                        }
                        radeon_encoder = to_radeon_encoder(encoder);
+                       break;
                }
        }
 
+       /* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock
+        * accordingly based on the encoder/transmitter to work around
+        * special hw requirements.
+        */
+       if (ASIC_IS_DCE3(rdev)) {
+               ADJUST_DISPLAY_PLL_PS_ALLOCATION adjust_pll_args;
+
+               if (!encoder)
+                       return;
+
+               memset(&adjust_pll_args, 0, sizeof(adjust_pll_args));
+               adjust_pll_args.usPixelClock = cpu_to_le16(mode->clock / 10);
+               adjust_pll_args.ucTransmitterID = radeon_encoder->encoder_id;
+               adjust_pll_args.ucEncodeMode = atombios_get_encoder_mode(encoder);
+
+               index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
+               atom_execute_table(rdev->mode_info.atom_context,
+                                  index, (uint32_t *)&adjust_pll_args);
+               adjusted_clock = le16_to_cpu(adjust_pll_args.usPixelClock) * 10;
+       } else
+               adjusted_clock = mode->clock;
+
        if (radeon_crtc->crtc_id == 0)
                pll = &rdev->clock.p1pll;
        else
                pll = &rdev->clock.p2pll;
 
-       radeon_compute_pll(pll, mode->clock, &sclock, &fb_div, &frac_fb_div,
+       radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
                           &ref_div, &post_div, pll_flags);
 
        atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
@@ -263,7 +432,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
                switch (crev) {
                case 1:
                        spc1_ptr = (PIXEL_CLOCK_PARAMETERS *) & args.sPCLKInput;
-                       spc1_ptr->usPixelClock = cpu_to_le16(sclock);
+                       spc1_ptr->usPixelClock = cpu_to_le16(mode->clock / 10);
                        spc1_ptr->usRefDiv = cpu_to_le16(ref_div);
                        spc1_ptr->usFbDiv = cpu_to_le16(fb_div);
                        spc1_ptr->ucFracFbDiv = frac_fb_div;
@@ -276,7 +445,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
                case 2:
                        spc2_ptr =
                            (PIXEL_CLOCK_PARAMETERS_V2 *) & args.sPCLKInput;
-                       spc2_ptr->usPixelClock = cpu_to_le16(sclock);
+                       spc2_ptr->usPixelClock = cpu_to_le16(mode->clock / 10);
                        spc2_ptr->usRefDiv = cpu_to_le16(ref_div);
                        spc2_ptr->usFbDiv = cpu_to_le16(fb_div);
                        spc2_ptr->ucFracFbDiv = frac_fb_div;
@@ -291,7 +460,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
                                return;
                        spc3_ptr =
                            (PIXEL_CLOCK_PARAMETERS_V3 *) & args.sPCLKInput;
-                       spc3_ptr->usPixelClock = cpu_to_le16(sclock);
+                       spc3_ptr->usPixelClock = cpu_to_le16(mode->clock / 10);
                        spc3_ptr->usRefDiv = cpu_to_le16(ref_div);
                        spc3_ptr->usFbDiv = cpu_to_le16(fb_div);
                        spc3_ptr->ucFracFbDiv = frac_fb_div;
@@ -314,6 +483,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
        }
 
        printk("executing set pll\n");
+       index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
@@ -342,6 +512,11 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
        }
 
        switch (crtc->fb->bits_per_pixel) {
+       case 8:
+               fb_format =
+                   AVIVO_D1GRPH_CONTROL_DEPTH_8BPP |
+                   AVIVO_D1GRPH_CONTROL_8BPP_INDEXED;
+               break;
        case 15:
                fb_format =
                    AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
@@ -412,6 +587,10 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
                radeon_fb = to_radeon_framebuffer(old_fb);
                radeon_gem_object_unpin(radeon_fb->obj);
        }
+
+       /* Bytes per pixel may have changed */
+       radeon_bandwidth_update(rdev);
+
        return 0;
 }
 
@@ -425,42 +604,68 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
        struct radeon_device *rdev = dev->dev_private;
        struct drm_encoder *encoder;
        SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing;
+       int need_tv_timings = 0;
+       bool ret;
 
        /* TODO color tiling */
        memset(&crtc_timing, 0, sizeof(crtc_timing));
 
-       /* TODO tv */
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-
+               /* find tv std */
+               if (encoder->crtc == crtc) {
+                       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+
+                       if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
+                               struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
+                               if (tv_dac) {
+                                       if (tv_dac->tv_std == TV_STD_NTSC ||
+                                           tv_dac->tv_std == TV_STD_NTSC_J ||
+                                           tv_dac->tv_std == TV_STD_PAL_M)
+                                               need_tv_timings = 1;
+                                       else
+                                               need_tv_timings = 2;
+                                       break;
+                               }
+                       }
+               }
        }
 
        crtc_timing.ucCRTC = radeon_crtc->crtc_id;
-       crtc_timing.usH_Total = adjusted_mode->crtc_htotal;
-       crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay;
-       crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start;
-       crtc_timing.usH_SyncWidth =
-           adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
+       if (need_tv_timings) {
+               ret = radeon_atom_get_tv_timings(rdev, need_tv_timings - 1,
+                                                &crtc_timing, &adjusted_mode->clock);
+               if (ret == false)
+                       need_tv_timings = 0;
+       }
+
+       if (!need_tv_timings) {
+               crtc_timing.usH_Total = adjusted_mode->crtc_htotal;
+               crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay;
+               crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start;
+               crtc_timing.usH_SyncWidth =
+                       adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
 
-       crtc_timing.usV_Total = adjusted_mode->crtc_vtotal;
-       crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay;
-       crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start;
-       crtc_timing.usV_SyncWidth =
-           adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
+               crtc_timing.usV_Total = adjusted_mode->crtc_vtotal;
+               crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay;
+               crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start;
+               crtc_timing.usV_SyncWidth =
+                       adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
 
-       if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
-               crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY;
+               if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
+                       crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY;
 
-       if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
-               crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY;
+               if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
+                       crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY;
 
-       if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC)
-               crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC;
+               if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC)
+                       crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC;
 
-       if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
-               crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE;
+               if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
+                       crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE;
 
-       if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
-               crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE;
+               if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
+                       crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE;
+       }
 
        atombios_crtc_set_pll(crtc, adjusted_mode);
        atombios_crtc_set_timing(crtc, &crtc_timing);
@@ -522,6 +727,8 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
                radeon_crtc_set_base(crtc, x, y, old_fb);
                radeon_legacy_atom_set_surface(crtc);
        }
+       atombios_overscan_setup(crtc, mode, adjusted_mode);
+       atombios_scaler_setup(crtc);
        return 0;
 }
 
@@ -529,6 +736,8 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
                                     struct drm_display_mode *mode,
                                     struct drm_display_mode *adjusted_mode)
 {
+       if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
+               return false;
        return true;
 }
 
@@ -551,6 +760,7 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
        .mode_set_base = atombios_crtc_set_base,
        .prepare = atombios_crtc_prepare,
        .commit = atombios_crtc_commit,
+       .load_lut = radeon_crtc_load_lut,
 };
 
 void radeon_atombios_init_crtc(struct drm_device *dev,
@@ -561,148 +771,3 @@ void radeon_atombios_init_crtc(struct drm_device *dev,
                    AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL;
        drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
 }
-
-void radeon_init_disp_bw_avivo(struct drm_device *dev,
-                              struct drm_display_mode *mode1,
-                              uint32_t pixel_bytes1,
-                              struct drm_display_mode *mode2,
-                              uint32_t pixel_bytes2)
-{
-       struct radeon_device *rdev = dev->dev_private;
-       fixed20_12 min_mem_eff;
-       fixed20_12 peak_disp_bw, mem_bw, pix_clk, pix_clk2, temp_ff;
-       fixed20_12 sclk_ff, mclk_ff;
-       uint32_t dc_lb_memory_split, temp;
-
-       min_mem_eff.full = rfixed_const_8(0);
-       if (rdev->disp_priority == 2) {
-               uint32_t mc_init_misc_lat_timer = 0;
-               if (rdev->family == CHIP_RV515)
-                       mc_init_misc_lat_timer =
-                           RREG32_MC(RV515_MC_INIT_MISC_LAT_TIMER);
-               else if (rdev->family == CHIP_RS690)
-                       mc_init_misc_lat_timer =
-                           RREG32_MC(RS690_MC_INIT_MISC_LAT_TIMER);
-
-               mc_init_misc_lat_timer &=
-                   ~(R300_MC_DISP1R_INIT_LAT_MASK <<
-                     R300_MC_DISP1R_INIT_LAT_SHIFT);
-               mc_init_misc_lat_timer &=
-                   ~(R300_MC_DISP0R_INIT_LAT_MASK <<
-                     R300_MC_DISP0R_INIT_LAT_SHIFT);
-
-               if (mode2)
-                       mc_init_misc_lat_timer |=
-                           (1 << R300_MC_DISP1R_INIT_LAT_SHIFT);
-               if (mode1)
-                       mc_init_misc_lat_timer |=
-                           (1 << R300_MC_DISP0R_INIT_LAT_SHIFT);
-
-               if (rdev->family == CHIP_RV515)
-                       WREG32_MC(RV515_MC_INIT_MISC_LAT_TIMER,
-                                 mc_init_misc_lat_timer);
-               else if (rdev->family == CHIP_RS690)
-                       WREG32_MC(RS690_MC_INIT_MISC_LAT_TIMER,
-                                 mc_init_misc_lat_timer);
-       }
-
-       /*
-        * determine is there is enough bw for current mode
-        */
-       temp_ff.full = rfixed_const(100);
-       mclk_ff.full = rfixed_const(rdev->clock.default_mclk);
-       mclk_ff.full = rfixed_div(mclk_ff, temp_ff);
-       sclk_ff.full = rfixed_const(rdev->clock.default_sclk);
-       sclk_ff.full = rfixed_div(sclk_ff, temp_ff);
-
-       temp = (rdev->mc.vram_width / 8) * (rdev->mc.vram_is_ddr ? 2 : 1);
-       temp_ff.full = rfixed_const(temp);
-       mem_bw.full = rfixed_mul(mclk_ff, temp_ff);
-       mem_bw.full = rfixed_mul(mem_bw, min_mem_eff);
-
-       pix_clk.full = 0;
-       pix_clk2.full = 0;
-       peak_disp_bw.full = 0;
-       if (mode1) {
-               temp_ff.full = rfixed_const(1000);
-               pix_clk.full = rfixed_const(mode1->clock);      /* convert to fixed point */
-               pix_clk.full = rfixed_div(pix_clk, temp_ff);
-               temp_ff.full = rfixed_const(pixel_bytes1);
-               peak_disp_bw.full += rfixed_mul(pix_clk, temp_ff);
-       }
-       if (mode2) {
-               temp_ff.full = rfixed_const(1000);
-               pix_clk2.full = rfixed_const(mode2->clock);     /* convert to fixed point */
-               pix_clk2.full = rfixed_div(pix_clk2, temp_ff);
-               temp_ff.full = rfixed_const(pixel_bytes2);
-               peak_disp_bw.full += rfixed_mul(pix_clk2, temp_ff);
-       }
-
-       if (peak_disp_bw.full >= mem_bw.full) {
-               DRM_ERROR
-                   ("You may not have enough display bandwidth for current mode\n"
-                    "If you have flickering problem, try to lower resolution, refresh rate, or color depth\n");
-               printk("peak disp bw %d, mem_bw %d\n",
-                      rfixed_trunc(peak_disp_bw), rfixed_trunc(mem_bw));
-       }
-
-       /*
-        * Line Buffer Setup
-        * There is a single line buffer shared by both display controllers.
-        * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between the display
-        * controllers.  The paritioning can either be done manually or via one of four
-        * preset allocations specified in bits 1:0:
-        * 0 - line buffer is divided in half and shared between each display controller
-        * 1 - D1 gets 3/4 of the line buffer, D2 gets 1/4
-        * 2 - D1 gets the whole buffer
-        * 3 - D1 gets 1/4 of the line buffer, D2 gets 3/4
-        * Setting bit 2 of DC_LB_MEMORY_SPLIT controls switches to manual allocation mode.
-        * In manual allocation mode, D1 always starts at 0, D1 end/2 is specified in bits
-        * 14:4; D2 allocation follows D1.
-        */
-
-       /* is auto or manual better ? */
-       dc_lb_memory_split =
-           RREG32(AVIVO_DC_LB_MEMORY_SPLIT) & ~AVIVO_DC_LB_MEMORY_SPLIT_MASK;
-       dc_lb_memory_split &= ~AVIVO_DC_LB_MEMORY_SPLIT_SHIFT_MODE;
-#if 1
-       /* auto */
-       if (mode1 && mode2) {
-               if (mode1->hdisplay > mode2->hdisplay) {
-                       if (mode1->hdisplay > 2560)
-                               dc_lb_memory_split |=
-                                   AVIVO_DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q;
-                       else
-                               dc_lb_memory_split |=
-                                   AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
-               } else if (mode2->hdisplay > mode1->hdisplay) {
-                       if (mode2->hdisplay > 2560)
-                               dc_lb_memory_split |=
-                                   AVIVO_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q;
-                       else
-                               dc_lb_memory_split |=
-                                   AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
-               } else
-                       dc_lb_memory_split |=
-                           AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
-       } else if (mode1) {
-               dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_D1_ONLY;
-       } else if (mode2) {
-               dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q;
-       }
-#else
-       /* manual */
-       dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_SHIFT_MODE;
-       dc_lb_memory_split &=
-           ~(AVIVO_DC_LB_DISP1_END_ADR_MASK <<
-             AVIVO_DC_LB_DISP1_END_ADR_SHIFT);
-       if (mode1) {
-               dc_lb_memory_split |=
-                   ((((mode1->hdisplay / 2) + 64) & AVIVO_DC_LB_DISP1_END_ADR_MASK)
-                    << AVIVO_DC_LB_DISP1_END_ADR_SHIFT);
-       } else if (mode2) {
-               dc_lb_memory_split |= (0 << AVIVO_DC_LB_DISP1_END_ADR_SHIFT);
-       }
-#endif
-       WREG32(AVIVO_DC_LB_MEMORY_SPLIT, dc_lb_memory_split);
-}