Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[sfrench/cifs-2.6.git] / drivers / gpu / drm / ast / ast_mode.c
index 5389350244f216fac07c5d98723ee2632c627e89..9dc0fd5c1ea4ef7741eaad8e85a65ea280096caf 100644 (file)
@@ -80,6 +80,8 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
        struct ast_private *ast = crtc->dev->dev_private;
        u32 refresh_rate_index = 0, mode_id, color_index, refresh_rate;
        u32 hborder, vborder;
+       bool check_sync;
+       struct ast_vbios_enhtable *best = NULL;
 
        switch (crtc->primary->fb->bits_per_pixel) {
        case 8:
@@ -141,14 +143,34 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
        }
 
        refresh_rate = drm_mode_vrefresh(mode);
-       while (vbios_mode->enh_table->refresh_rate < refresh_rate) {
-               vbios_mode->enh_table++;
-               if ((vbios_mode->enh_table->refresh_rate > refresh_rate) ||
-                   (vbios_mode->enh_table->refresh_rate == 0xff)) {
-                       vbios_mode->enh_table--;
-                       break;
+       check_sync = vbios_mode->enh_table->flags & WideScreenMode;
+       do {
+               struct ast_vbios_enhtable *loop = vbios_mode->enh_table;
+
+               while (loop->refresh_rate != 0xff) {
+                       if ((check_sync) &&
+                           (((mode->flags & DRM_MODE_FLAG_NVSYNC)  &&
+                             (loop->flags & PVSync))  ||
+                            ((mode->flags & DRM_MODE_FLAG_PVSYNC)  &&
+                             (loop->flags & NVSync))  ||
+                            ((mode->flags & DRM_MODE_FLAG_NHSYNC)  &&
+                             (loop->flags & PHSync))  ||
+                            ((mode->flags & DRM_MODE_FLAG_PHSYNC)  &&
+                             (loop->flags & NHSync)))) {
+                               loop++;
+                               continue;
+                       }
+                       if (loop->refresh_rate <= refresh_rate
+                           && (!best || loop->refresh_rate > best->refresh_rate))
+                               best = loop;
+                       loop++;
                }
-       }
+               if (best || !check_sync)
+                       break;
+               check_sync = 0;
+       } while (1);
+       if (best)
+               vbios_mode->enh_table = best;
 
        hborder = (vbios_mode->enh_table->flags & HBorder) ? 8 : 0;
        vborder = (vbios_mode->enh_table->flags & VBorder) ? 8 : 0;
@@ -419,8 +441,10 @@ static void ast_set_sync_reg(struct drm_device *dev, struct drm_display_mode *mo
        struct ast_private *ast = dev->dev_private;
        u8 jreg;
 
-       jreg = ast_io_read8(ast, AST_IO_MISC_PORT_READ);
-       jreg |= (vbios_mode->enh_table->flags & SyncNN);
+       jreg  = ast_io_read8(ast, AST_IO_MISC_PORT_READ);
+       jreg &= ~0xC0;
+       if (vbios_mode->enh_table->flags & NVSync) jreg |= 0x80;
+       if (vbios_mode->enh_table->flags & NHSync) jreg |= 0x40;
        ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg);
 }
 
@@ -1080,8 +1104,8 @@ static u32 copy_cursor_image(u8 *src, u8 *dst, int width, int height)
                        srcdata32[1].ul = *((u32 *)(srcxor + 4)) & 0xf0f0f0f0;
                        data32.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4);
                        data32.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4);
-                       data32.b[2] = srcdata32[0].b[1] | (srcdata32[1].b[0] >> 4);
-                       data32.b[3] = srcdata32[0].b[3] | (srcdata32[1].b[2] >> 4);
+                       data32.b[2] = srcdata32[1].b[1] | (srcdata32[1].b[0] >> 4);
+                       data32.b[3] = srcdata32[1].b[3] | (srcdata32[1].b[2] >> 4);
 
                        writel(data32.ul, dstxor);
                        csum += data32.ul;