diff options
author | Dave Airlie <airlied@redhat.com> | 2014-01-16 19:56:09 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-05-18 21:13:55 -0400 |
commit | f1f62f2ccba0967c493ac9ad31c9b04d29688aaa (patch) | |
tree | 18549684b758fdfca521cc95ff3c289c6f54149f | |
parent | bf21d605bf7d18d2b3cdb1c19fc1b2a1549c1f11 (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.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_main.c | 28 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_mode.c | 76 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_tables.h | 67 |
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 | ||
107 | int ast_driver_load(struct drm_device *dev, unsigned long flags); | 108 | int 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, | |||
66 | static int ast_detect_chip(struct drm_device *dev) | 66 | static 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) | |||
746 | static int ast_mode_valid(struct drm_connector *connector, | 755 | static 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 | ||
752 | static void ast_connector_destroy(struct drm_connector *connector) | 810 | static 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 | ||
71 | static struct ast_vbios_dclk_info dclk_table[] = { | 76 | static 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 | ||
95 | static struct ast_vbios_stdtable vbios_stdtable[] = { | 104 | static 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 | ||
228 | static struct ast_vbios_enhtable res_1920x1200[] = { | 237 | /* 16:9 */ |
229 | {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz */ | 238 | static 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 | |||
245 | static 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 | ||
252 | static 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 */ |
236 | static struct ast_vbios_enhtable res_1280x800[] = { | 261 | static 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 | ||
244 | static struct ast_vbios_enhtable res_1440x900[] = { | 271 | static 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 | ||
251 | static struct ast_vbios_enhtable res_1680x1050[] = { | 280 | static 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 */ | 289 | static struct ast_vbios_enhtable res_1920x1200[] = { |
259 | static 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 |