aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-01-16 19:56:09 -0500
committerDave Airlie <airlied@redhat.com>2014-05-18 21:13:55 -0400
commitf1f62f2ccba0967c493ac9ad31c9b04d29688aaa (patch)
tree18549684b758fdfca521cc95ff3c289c6f54149f
parentbf21d605bf7d18d2b3cdb1c19fc1b2a1549c1f11 (diff)
drm/ast: add widescreen + rb modes from X.org driver (v2)
This syncs up the mode code from the X.org driver upstream, and adds the mode validation step for hw that doesn't have widescreen. v2: (from Egbert Eich <eich@suse.de) squash drm/ast: Use correct structure member for mode validation to avoid bisect regression. In struct drm_display_mode crtc_hdisplay and crtc_vdisplay are holding the crtc parameters after mode fixup. For validation we need hdisplay and vdisplay. Signed-off-by: Egbert Eich <eich@suse.de> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/ast/ast_drv.h1
-rw-r--r--drivers/gpu/drm/ast/ast_main.c28
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c76
-rw-r--r--drivers/gpu/drm/ast/ast_tables.h67
4 files changed, 145 insertions, 27 deletions
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 9833a1b1acc1..fab4b173dc49 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -102,6 +102,7 @@ struct ast_private {
102 * we have. */ 102 * we have. */
103 struct ttm_bo_kmap_obj cache_kmap; 103 struct ttm_bo_kmap_obj cache_kmap;
104 int next_cursor; 104 int next_cursor;
105 bool support_wide_screen;
105}; 106};
106 107
107int ast_driver_load(struct drm_device *dev, unsigned long flags); 108int ast_driver_load(struct drm_device *dev, unsigned long flags);
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
index 50535fd5a88d..cd0a791e76c5 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -66,6 +66,7 @@ uint8_t ast_get_index_reg_mask(struct ast_private *ast,
66static int ast_detect_chip(struct drm_device *dev) 66static int ast_detect_chip(struct drm_device *dev)
67{ 67{
68 struct ast_private *ast = dev->dev_private; 68 struct ast_private *ast = dev->dev_private;
69 uint32_t data, jreg;
69 70
70 if (dev->pdev->device == PCI_CHIP_AST1180) { 71 if (dev->pdev->device == PCI_CHIP_AST1180) {
71 ast->chip = AST1100; 72 ast->chip = AST1100;
@@ -104,6 +105,33 @@ static int ast_detect_chip(struct drm_device *dev)
104 DRM_INFO("AST 2000 detected\n"); 105 DRM_INFO("AST 2000 detected\n");
105 } 106 }
106 } 107 }
108
109 switch (ast->chip) {
110 case AST1180:
111 ast->support_wide_screen = true;
112 break;
113 case AST2000:
114 ast->support_wide_screen = false;
115 break;
116 default:
117 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
118 if (!(jreg & 0x80))
119 ast->support_wide_screen = true;
120 else if (jreg & 0x01)
121 ast->support_wide_screen = true;
122 else {
123 ast->support_wide_screen = false;
124 if (ast->chip == AST2300) {
125 ast_write32(ast, 0xf004, 0x1e6e0000);
126 ast_write32(ast, 0xf000, 0x1);
127 data = ast_read32(ast, 0x1207c);
128 if ((data & 0x300) == 0) /* ast1300 */
129 ast->support_wide_screen = true;
130 }
131 }
132 break;
133 }
134
107 return 0; 135 return 0;
108} 136}
109 137
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index cca063b11083..72bec23b66f4 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -115,11 +115,17 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
115 else 115 else
116 vbios_mode->enh_table = &res_1280x1024[refresh_rate_index]; 116 vbios_mode->enh_table = &res_1280x1024[refresh_rate_index];
117 break; 117 break;
118 case 1360:
119 vbios_mode->enh_table = &res_1360x768[refresh_rate_index];
120 break;
118 case 1440: 121 case 1440:
119 vbios_mode->enh_table = &res_1440x900[refresh_rate_index]; 122 vbios_mode->enh_table = &res_1440x900[refresh_rate_index];
120 break; 123 break;
121 case 1600: 124 case 1600:
122 vbios_mode->enh_table = &res_1600x1200[refresh_rate_index]; 125 if (crtc->mode.crtc_vdisplay == 900)
126 vbios_mode->enh_table = &res_1600x900[refresh_rate_index];
127 else
128 vbios_mode->enh_table = &res_1600x1200[refresh_rate_index];
123 break; 129 break;
124 case 1680: 130 case 1680:
125 vbios_mode->enh_table = &res_1680x1050[refresh_rate_index]; 131 vbios_mode->enh_table = &res_1680x1050[refresh_rate_index];
@@ -175,14 +181,17 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
175 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff); 181 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff);
176 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff); 182 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff);
177 183
178 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8); 184 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
179 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, crtc->fb->bits_per_pixel); 185 if (vbios_mode->enh_table->flags & NewModeInfo) {
180 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000); 186 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
181 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay); 187 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, crtc->fb->bits_per_pixel);
182 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8); 188 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000);
189 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay);
190 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8);
183 191
184 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay); 192 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay);
185 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8); 193 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8);
194 }
186 } 195 }
187 196
188 return true; 197 return true;
@@ -746,7 +755,56 @@ static int ast_get_modes(struct drm_connector *connector)
746static int ast_mode_valid(struct drm_connector *connector, 755static int ast_mode_valid(struct drm_connector *connector,
747 struct drm_display_mode *mode) 756 struct drm_display_mode *mode)
748{ 757{
749 return MODE_OK; 758 struct ast_private *ast = connector->dev->dev_private;
759 int flags = MODE_NOMODE;
760 uint32_t jtemp;
761
762 if (ast->support_wide_screen) {
763 if ((mode->hdisplay == 1680) && (mode->vdisplay == 1050))
764 return MODE_OK;
765 if ((mode->hdisplay == 1280) && (mode->vdisplay == 800))
766 return MODE_OK;
767 if ((mode->hdisplay == 1440) && (mode->vdisplay == 900))
768 return MODE_OK;
769 if ((mode->hdisplay == 1360) && (mode->vdisplay == 768))
770 return MODE_OK;
771 if ((mode->hdisplay == 1600) && (mode->vdisplay == 900))
772 return MODE_OK;
773
774 if ((ast->chip == AST2100) || (ast->chip == AST2200) || (ast->chip == AST2300) || (ast->chip == AST1180)) {
775 if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080))
776 return MODE_OK;
777
778 if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) {
779 jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
780 if (jtemp & 0x01)
781 return MODE_NOMODE;
782 else
783 return MODE_OK;
784 }
785 }
786 }
787 switch (mode->hdisplay) {
788 case 640:
789 if (mode->vdisplay == 480) flags = MODE_OK;
790 break;
791 case 800:
792 if (mode->vdisplay == 600) flags = MODE_OK;
793 break;
794 case 1024:
795 if (mode->vdisplay == 768) flags = MODE_OK;
796 break;
797 case 1280:
798 if (mode->vdisplay == 1024) flags = MODE_OK;
799 break;
800 case 1600:
801 if (mode->vdisplay == 1200) flags = MODE_OK;
802 break;
803 default:
804 return flags;
805 }
806
807 return flags;
750} 808}
751 809
752static void ast_connector_destroy(struct drm_connector *connector) 810static void ast_connector_destroy(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/ast/ast_tables.h b/drivers/gpu/drm/ast/ast_tables.h
index 95fa6aba26bc..4c761dcea972 100644
--- a/drivers/gpu/drm/ast/ast_tables.h
+++ b/drivers/gpu/drm/ast/ast_tables.h
@@ -42,7 +42,7 @@
42#define HBorder 0x00000020 42#define HBorder 0x00000020
43#define VBorder 0x00000010 43#define VBorder 0x00000010
44#define WideScreenMode 0x00000100 44#define WideScreenMode 0x00000100
45 45#define NewModeInfo 0x00000200
46 46
47/* DCLK Index */ 47/* DCLK Index */
48#define VCLK25_175 0x00 48#define VCLK25_175 0x00
@@ -67,6 +67,11 @@
67#define VCLK106_5 0x12 67#define VCLK106_5 0x12
68#define VCLK146_25 0x13 68#define VCLK146_25 0x13
69#define VCLK148_5 0x14 69#define VCLK148_5 0x14
70#define VCLK71 0x15
71#define VCLK88_75 0x16
72#define VCLK119 0x17
73#define VCLK85_5 0x18
74#define VCLK97_75 0x19
70 75
71static struct ast_vbios_dclk_info dclk_table[] = { 76static struct ast_vbios_dclk_info dclk_table[] = {
72 {0x2C, 0xE7, 0x03}, /* 00: VCLK25_175 */ 77 {0x2C, 0xE7, 0x03}, /* 00: VCLK25_175 */
@@ -90,6 +95,10 @@ static struct ast_vbios_dclk_info dclk_table[] = {
90 {0x28, 0x49, 0x80}, /* 12: VCLK106.5 */ 95 {0x28, 0x49, 0x80}, /* 12: VCLK106.5 */
91 {0x37, 0x49, 0x80}, /* 13: VCLK146.25 */ 96 {0x37, 0x49, 0x80}, /* 13: VCLK146.25 */
92 {0x1f, 0x45, 0x80}, /* 14: VCLK148.5 */ 97 {0x1f, 0x45, 0x80}, /* 14: VCLK148.5 */
98 {0x47, 0x6c, 0x80}, /* 15: VCLK71 */
99 {0x25, 0x65, 0x80}, /* 16: VCLK88.75 */
100 {0x77, 0x58, 0x80}, /* 17: VCLK119 */
101 {0x32, 0x67, 0x80}, /* 18: VCLK85_5 */
93}; 102};
94 103
95static struct ast_vbios_stdtable vbios_stdtable[] = { 104static struct ast_vbios_stdtable vbios_stdtable[] = {
@@ -225,41 +234,63 @@ static struct ast_vbios_enhtable res_1600x1200[] = {
225 (SyncPP | Charx8Dot), 0xFF, 1, 0x33 }, 234 (SyncPP | Charx8Dot), 0xFF, 1, 0x33 },
226}; 235};
227 236
228static struct ast_vbios_enhtable res_1920x1200[] = { 237/* 16:9 */
229 {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz */ 238static struct ast_vbios_enhtable res_1360x768[] = {
230 (SyncNP | Charx8Dot), 60, 1, 0x34 }, 239 {1792, 1360, 64,112, 795, 768, 3, 6, VCLK85_5, /* 60Hz */
231 {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz */ 240 (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x39 },
232 (SyncNP | Charx8Dot), 0xFF, 1, 0x34 }, 241 {1792, 1360, 64,112, 795, 768, 3, 6, VCLK85_5, /* end */
242 (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x39 },
243};
244
245static struct ast_vbios_enhtable res_1600x900[] = {
246 {1760, 1600, 48, 32, 926, 900, 3, 5, VCLK97_75, /* 60Hz CVT RB */
247 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x3A },
248 {1760, 1600, 48, 32, 926, 900, 3, 5, VCLK97_75, /* end */
249 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x3A }
233}; 250};
234 251
252static struct ast_vbios_enhtable res_1920x1080[] = {
253 {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */
254 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x38 },
255 {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */
256 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x38 },
257};
258
259
235/* 16:10 */ 260/* 16:10 */
236static struct ast_vbios_enhtable res_1280x800[] = { 261static struct ast_vbios_enhtable res_1280x800[] = {
262 {1440, 1280, 48, 32, 823, 800, 3, 6, VCLK71, /* 60Hz RB */
263 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 35 },
237 {1680, 1280, 72,128, 831, 800, 3, 6, VCLK83_5, /* 60Hz */ 264 {1680, 1280, 72,128, 831, 800, 3, 6, VCLK83_5, /* 60Hz */
238 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 60, 1, 0x35 }, 265 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x35 },
239 {1680, 1280, 72,128, 831, 800, 3, 6, VCLK83_5, /* 60Hz */ 266 {1680, 1280, 72,128, 831, 800, 3, 6, VCLK83_5, /* 60Hz */
240 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 0xFF, 1, 0x35 }, 267 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x35 },
241 268
242}; 269};
243 270
244static struct ast_vbios_enhtable res_1440x900[] = { 271static struct ast_vbios_enhtable res_1440x900[] = {
272 {1600, 1440, 48, 32, 926, 900, 3, 6, VCLK88_75, /* 60Hz RB */
273 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x36 },
245 {1904, 1440, 80,152, 934, 900, 3, 6, VCLK106_5, /* 60Hz */ 274 {1904, 1440, 80,152, 934, 900, 3, 6, VCLK106_5, /* 60Hz */
246 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 60, 1, 0x36 }, 275 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x36 },
247 {1904, 1440, 80,152, 934, 900, 3, 6, VCLK106_5, /* 60Hz */ 276 {1904, 1440, 80,152, 934, 900, 3, 6, VCLK106_5, /* 60Hz */
248 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 0xFF, 1, 0x36 }, 277 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x36 },
249}; 278};
250 279
251static struct ast_vbios_enhtable res_1680x1050[] = { 280static struct ast_vbios_enhtable res_1680x1050[] = {
281 {1840, 1680, 48, 32, 1080, 1050, 3, 6, VCLK119, /* 60Hz RB */
282 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x37 },
252 {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25, /* 60Hz */ 283 {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25, /* 60Hz */
253 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 60, 1, 0x37 }, 284 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x37 },
254 {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25, /* 60Hz */ 285 {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25, /* 60Hz */
255 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 0xFF, 1, 0x37 }, 286 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x37 },
256}; 287};
257 288
258/* HDTV */ 289static struct ast_vbios_enhtable res_1920x1200[] = {
259static struct ast_vbios_enhtable res_1920x1080[] = { 290 {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz */
260 {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */ 291 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x34 },
261 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode), 60, 1, 0x38 }, 292 {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz */
262 {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */ 293 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x34 },
263 (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode), 0xFF, 1, 0x38 },
264}; 294};
295
265#endif 296#endif