The Patch is PASSED by Lenovo side. 
Tested-by: Steven You2 Liang <liangyou2 at lenovo.com>

-----Original Message-----
From: YC Chen [mailto:yc_c...@aspeedtech.com] 
Sent: Thursday, August 28, 2014 5:11 PM
To: dri-devel at lists.freedesktop.org
Cc: Kuo-Hsiang Chou; airlied at redhat.com; eich at suse.com; YC Chen
Subject: [PATCH v3] drm/ast: Add reduced blanking modes for wide screen mode

From: "Y.C. Chen" <yc_c...@aspeedtech.com>

Signed-off-by: Egbert Eich <eich at suse.com>
Signed-off-by: Y.C. Chen <yc_chen at aspeedtech.com>

v3: based on [PATCH 1/2] drm/ast: Add missing entry to dclk_table[].
    Add reduced blanking modes, improve mode matching to
    identify these modes by thier sync polarities.
---
 drivers/gpu/drm/ast/ast_mode.c   | 42 +++++++++++++++++++++++++++++++---------
 drivers/gpu/drm/ast/ast_tables.h | 42 ++++++++++++++++++++++++----------------
 2 files changed, 58 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c 
index 5389350..19ada0b 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -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);  }

diff --git a/drivers/gpu/drm/ast/ast_tables.h b/drivers/gpu/drm/ast/ast_tables.h
index 05c01ea..28ce659 100644
--- a/drivers/gpu/drm/ast/ast_tables.h
+++ b/drivers/gpu/drm/ast/ast_tables.h
@@ -35,14 +35,18 @@
 #define HalfDCLK                0x00000002
 #define DoubleScanMode          0x00000004
 #define LineCompareOff          0x00000008
-#define SyncPP                  0x00000000
-#define SyncPN                  0x00000040
-#define SyncNP                  0x00000080
-#define SyncNN                  0x000000C0
 #define HBorder                 0x00000020
 #define VBorder                 0x00000010
-#define WideScreenMode         0x00000100
-#define NewModeInfo            0x00000200
+#define WideScreenMode                 0x00000100
+#define NewModeInfo                            0x00000200
+#define NHSync                                 0x00000400
+#define PHSync                                 0x00000800
+#define NVSync                                 0x00001000
+#define PVSync                                 0x00002000
+#define        SyncPP                                  (PVSync | PHSync)
+#define        SyncPN                                  (PVSync | NHSync)
+#define        SyncNP                                  (NVSync | PHSync)
+#define        SyncNN                                  (NVSync | NHSync)

 /* DCLK Index */
 #define VCLK25_175                     0x00
@@ -72,6 +76,7 @@
 #define VCLK119                0x17
 #define VCLK85_5               0x18
 #define VCLK97_75              0x19
+#define VCLK118_25                     0x1A

 static struct ast_vbios_dclk_info dclk_table[] = {
        {0x2C, 0xE7, 0x03},                                     /* 00: 
VCLK25_175       */
@@ -100,6 +105,7 @@ static struct ast_vbios_dclk_info dclk_table[] = {
        {0x77, 0x58, 0x80},                                     /* 17: VCLK119  
    */
        {0x32, 0x67, 0x80},                                 /* 18: VCLK85_5     
*/
        {0x6a, 0x6d, 0x80},                                     /* 19: 
VCLK97_75        */
+       {0x3b, 0x2c, 0x81},                                     /* 1A: 
VCLK118_25       */
 };

 static struct ast_vbios_stdtable vbios_stdtable[] = { @@ -246,8 +252,10 @@ 
static struct ast_vbios_enhtable res_1360x768[] = {  static struct 
ast_vbios_enhtable res_1600x900[] = {
        {1760, 1600, 48, 32, 926,  900, 3, 5, VCLK97_75,        /* 60Hz CVT RB 
*/
         (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
60, 1, 0x3A },
-       {1760, 1600, 48, 32, 926,  900, 3, 5, VCLK97_75,        /* end */
-        (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
0xFF, 1, 0x3A }
+    {2112, 1600, 88,168, 934,  900, 3, 5, VCLK118_25,  /* 60Hz CVT */
+     (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 
2, 0x3A },
+    {2112, 1600, 88,168, 934,  900, 3, 5, VCLK118_25,  /* 60Hz CVT */
+     (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | 
+ NewModeInfo), 0xFF, 2, 0x3A },
 };

 static struct ast_vbios_enhtable res_1920x1080[] = { @@ -261,11 +269,11 @@ 
static struct ast_vbios_enhtable res_1920x1080[] = {
 /* 16:10 */
 static struct ast_vbios_enhtable res_1280x800[] = {
        {1440, 1280, 48, 32,  823,  800, 3, 6, VCLK71,  /* 60Hz RB */
-        (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
60, 1, 35 },
+        (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
+60, 1, 0x35 },
        {1680, 1280, 72,128,  831,  800, 3, 6, VCLK83_5,        /* 60Hz */
-        (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
60, 1, 0x35 },
+        (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
+60, 2, 0x35 },
        {1680, 1280, 72,128,  831,  800, 3, 6, VCLK83_5,        /* 60Hz */
-        (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
0xFF, 1, 0x35 },
+        (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
+0xFF, 2, 0x35 },

 };

@@ -273,24 +281,24 @@ static struct ast_vbios_enhtable res_1440x900[] = {
        {1600, 1440, 48, 32,  926,  900, 3, 6, VCLK88_75,       /* 60Hz RB */
         (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
60, 1, 0x36 },
        {1904, 1440, 80,152,  934,  900, 3, 6, VCLK106_5,       /* 60Hz */
-        (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
60, 1, 0x36 },
+        (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
+60, 2, 0x36 },
        {1904, 1440, 80,152,  934,  900, 3, 6, VCLK106_5,       /* 60Hz */
-        (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
0xFF, 1, 0x36 },
+        (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
+0xFF, 2, 0x36 },
 };

 static struct ast_vbios_enhtable res_1680x1050[] = {
        {1840, 1680, 48, 32, 1080, 1050, 3, 6, VCLK119, /* 60Hz RB */
         (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
60, 1, 0x37 },
        {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25,      /* 60Hz */
-        (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
60, 1, 0x37 },
+        (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
+60, 2, 0x37 },
        {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25,      /* 60Hz */
-        (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
0xFF, 1, 0x37 },
+        (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
+0xFF, 2, 0x37 },
 };

 static struct ast_vbios_enhtable res_1920x1200[] = {
-       {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz */
+       {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz RB*/
         (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
60, 1, 0x34 },
-       {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz */
+       {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz RB */
         (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 
0xFF, 1, 0x34 },  };

--
1.8.3.1

Reply via email to