blob: 34fb54a4acaebd5e16a996f1ab7e8fed464391fb [file] [log] [blame]
Joel Stanleye50183f2017-02-28 12:17:46 +10301From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2From: "Y.C. Chen" <yc_chen@aspeedtech.com>
3Date: Fri, 17 Feb 2017 14:36:46 +1100
Joel Stanley8d5acef2017-03-15 16:24:09 +10304Subject: [PATCH 06/12] drm/ast: Base support for AST2500
Joel Stanleye50183f2017-02-28 12:17:46 +10305
6Add detection and mode setting updates for AST2500 generation chip,
7code originally from Aspeed and slightly reworked for coding style
8mostly by Ben. This doesn't contain the BMC DRAM POST code which
9is in a separate patch.
10
11Signed-off-by: Y.C. Chen <yc_chen@aspeedtech.com>
12Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
13---
14
15v2. Add 800Mhz default mclk for AST2500
16
17Signed-off-by: Joel Stanley <joel@jms.id.au>
18---
19 drivers/gpu/drm/ast/ast_drv.h | 2 ++
20 drivers/gpu/drm/ast/ast_main.c | 32 +++++++++++++++++++---
21 drivers/gpu/drm/ast/ast_mode.c | 30 ++++++++++++++++-----
22 drivers/gpu/drm/ast/ast_tables.h | 58 +++++++++++++++++++++++++++++++++-------
23 4 files changed, 103 insertions(+), 19 deletions(-)
24
25diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
26index 3fd9d6e96bce..d1c1d530abaa 100644
27--- a/drivers/gpu/drm/ast/ast_drv.h
28+++ b/drivers/gpu/drm/ast/ast_drv.h
29@@ -64,6 +64,7 @@ enum ast_chip {
30 AST2150,
31 AST2300,
32 AST2400,
33+ AST2500,
34 AST1180,
35 };
36
37@@ -80,6 +81,7 @@ enum ast_tx_chip {
38 #define AST_DRAM_1Gx32 3
39 #define AST_DRAM_2Gx16 6
40 #define AST_DRAM_4Gx16 7
41+#define AST_DRAM_8Gx16 8
42
43 struct ast_fbdev;
44
45diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
46index 8d87d3ca439b..5a83d3793000 100644
47--- a/drivers/gpu/drm/ast/ast_main.c
48+++ b/drivers/gpu/drm/ast/ast_main.c
49@@ -142,7 +142,10 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
50 ast->chip = AST1100;
51 DRM_INFO("AST 1180 detected\n");
52 } else {
53- if (dev->pdev->revision >= 0x30) {
54+ if (dev->pdev->revision >= 0x40) {
55+ ast->chip = AST2500;
56+ DRM_INFO("AST 2500 detected\n");
57+ } else if (dev->pdev->revision >= 0x30) {
58 ast->chip = AST2400;
59 DRM_INFO("AST 2400 detected\n");
60 } else if (dev->pdev->revision >= 0x20) {
61@@ -196,6 +199,9 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
62 if (ast->chip == AST2400 &&
63 (scu_rev & 0x300) == 0x100) /* ast1400 */
64 ast->support_wide_screen = true;
65+ if (ast->chip == AST2500 &&
66+ scu_rev == 0x100) /* ast2510 */
67+ ast->support_wide_screen = true;
68 }
69 break;
70 }
71@@ -291,7 +297,10 @@ static int ast_get_dram_info(struct drm_device *dev)
72 default:
73 ast->dram_bus_width = 16;
74 ast->dram_type = AST_DRAM_1Gx16;
75- ast->mclk = 396;
76+ if (ast->chip == AST2500)
77+ ast->mclk = 800;
78+ else
79+ ast->mclk = 396;
80 return 0;
81 }
82
83@@ -300,7 +309,23 @@ static int ast_get_dram_info(struct drm_device *dev)
84 else
85 ast->dram_bus_width = 32;
86
87- if (ast->chip == AST2300 || ast->chip == AST2400) {
88+ if (ast->chip == AST2500) {
89+ switch (mcr_cfg & 0x03) {
90+ case 0:
91+ ast->dram_type = AST_DRAM_1Gx16;
92+ break;
93+ default:
94+ case 1:
95+ ast->dram_type = AST_DRAM_2Gx16;
96+ break;
97+ case 2:
98+ ast->dram_type = AST_DRAM_4Gx16;
99+ break;
100+ case 3:
101+ ast->dram_type = AST_DRAM_8Gx16;
102+ break;
103+ }
104+ } else if (ast->chip == AST2300 || ast->chip == AST2400) {
105 switch (mcr_cfg & 0x03) {
106 case 0:
107 ast->dram_type = AST_DRAM_512Mx16;
108@@ -523,6 +548,7 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags)
109 ast->chip == AST2200 ||
110 ast->chip == AST2300 ||
111 ast->chip == AST2400 ||
112+ ast->chip == AST2500 ||
113 ast->chip == AST1180) {
114 dev->mode_config.max_width = 1920;
115 dev->mode_config.max_height = 2048;
116diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
117index 1ff596e90225..e4db1c72940c 100644
118--- a/drivers/gpu/drm/ast/ast_mode.c
119+++ b/drivers/gpu/drm/ast/ast_mode.c
120@@ -271,7 +271,11 @@ static void ast_set_crtc_reg(struct drm_crtc *crtc, struct drm_display_mode *mod
121 {
122 struct ast_private *ast = crtc->dev->dev_private;
123 u8 jreg05 = 0, jreg07 = 0, jreg09 = 0, jregAC = 0, jregAD = 0, jregAE = 0;
124- u16 temp;
125+ u16 temp, precache = 0;
126+
127+ if ((ast->chip == AST2500) &&
128+ (vbios_mode->enh_table->flags & AST2500PreCatchCRT))
129+ precache = 40;
130
131 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00);
132
133@@ -297,12 +301,12 @@ static void ast_set_crtc_reg(struct drm_crtc *crtc, struct drm_display_mode *mod
134 jregAD |= 0x01; /* HBE D[5] */
135 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x03, 0xE0, (temp & 0x1f));
136
137- temp = (mode->crtc_hsync_start >> 3) - 1;
138+ temp = ((mode->crtc_hsync_start-precache) >> 3) - 1;
139 if (temp & 0x100)
140 jregAC |= 0x40; /* HRS D[5] */
141 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x04, 0x00, temp);
142
143- temp = ((mode->crtc_hsync_end >> 3) - 1) & 0x3f;
144+ temp = (((mode->crtc_hsync_end-precache) >> 3) - 1) & 0x3f;
145 if (temp & 0x20)
146 jregAD |= 0x04; /* HRE D[5] */
147 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05));
148@@ -363,6 +367,11 @@ static void ast_set_crtc_reg(struct drm_crtc *crtc, struct drm_display_mode *mod
149 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x09, 0xdf, jreg09);
150 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAE, 0x00, (jregAE | 0x80));
151
152+ if (precache)
153+ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x80);
154+ else
155+ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x00);
156+
157 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x80);
158 }
159
160@@ -383,12 +392,16 @@ static void ast_set_dclk_reg(struct drm_device *dev, struct drm_display_mode *mo
161 struct ast_private *ast = dev->dev_private;
162 const struct ast_vbios_dclk_info *clk_info;
163
164- clk_info = &dclk_table[vbios_mode->enh_table->dclk_index];
165+ if (ast->chip == AST2500)
166+ clk_info = &dclk_table_ast2500[vbios_mode->enh_table->dclk_index];
167+ else
168+ clk_info = &dclk_table[vbios_mode->enh_table->dclk_index];
169
170 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc0, 0x00, clk_info->param1);
171 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc1, 0x00, clk_info->param2);
172 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xbb, 0x0f,
173- (clk_info->param3 & 0x80) | ((clk_info->param3 & 0x3) << 4));
174+ (clk_info->param3 & 0xc0) |
175+ ((clk_info->param3 & 0x3) << 4));
176 }
177
178 static void ast_set_ext_reg(struct drm_crtc *crtc, struct drm_display_mode *mode,
179@@ -421,7 +434,8 @@ static void ast_set_ext_reg(struct drm_crtc *crtc, struct drm_display_mode *mode
180 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa8, 0xfd, jregA8);
181
182 /* Set Threshold */
183- if (ast->chip == AST2300 || ast->chip == AST2400) {
184+ if (ast->chip == AST2300 || ast->chip == AST2400 ||
185+ ast->chip == AST2500) {
186 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78);
187 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60);
188 } else if (ast->chip == AST2100 ||
189@@ -794,7 +808,9 @@ static int ast_mode_valid(struct drm_connector *connector,
190 if ((mode->hdisplay == 1600) && (mode->vdisplay == 900))
191 return MODE_OK;
192
193- if ((ast->chip == AST2100) || (ast->chip == AST2200) || (ast->chip == AST2300) || (ast->chip == AST2400) || (ast->chip == AST1180)) {
194+ if ((ast->chip == AST2100) || (ast->chip == AST2200) ||
195+ (ast->chip == AST2300) || (ast->chip == AST2400) ||
196+ (ast->chip == AST2500) || (ast->chip == AST1180)) {
197 if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080))
198 return MODE_OK;
199
200diff --git a/drivers/gpu/drm/ast/ast_tables.h b/drivers/gpu/drm/ast/ast_tables.h
201index a4ddf901a54f..5f4c2e833a65 100644
202--- a/drivers/gpu/drm/ast/ast_tables.h
203+++ b/drivers/gpu/drm/ast/ast_tables.h
204@@ -47,6 +47,7 @@
205 #define SyncPN (PVSync | NHSync)
206 #define SyncNP (NVSync | PHSync)
207 #define SyncNN (NVSync | NHSync)
208+#define AST2500PreCatchCRT 0x00004000
209
210 /* DCLK Index */
211 #define VCLK25_175 0x00
212@@ -108,6 +109,36 @@ static const struct ast_vbios_dclk_info dclk_table[] = {
213 {0x3b, 0x2c, 0x81}, /* 1A: VCLK118_25 */
214 };
215
216+static const struct ast_vbios_dclk_info dclk_table_ast2500[] = {
217+ {0x2C, 0xE7, 0x03}, /* 00: VCLK25_175 */
218+ {0x95, 0x62, 0x03}, /* 01: VCLK28_322 */
219+ {0x67, 0x63, 0x01}, /* 02: VCLK31_5 */
220+ {0x76, 0x63, 0x01}, /* 03: VCLK36 */
221+ {0xEE, 0x67, 0x01}, /* 04: VCLK40 */
222+ {0x82, 0x62, 0x01}, /* 05: VCLK49_5 */
223+ {0xC6, 0x64, 0x01}, /* 06: VCLK50 */
224+ {0x94, 0x62, 0x01}, /* 07: VCLK56_25 */
225+ {0x80, 0x64, 0x00}, /* 08: VCLK65 */
226+ {0x7B, 0x63, 0x00}, /* 09: VCLK75 */
227+ {0x67, 0x62, 0x00}, /* 0A: VCLK78_75 */
228+ {0x7C, 0x62, 0x00}, /* 0B: VCLK94_5 */
229+ {0x8E, 0x62, 0x00}, /* 0C: VCLK108 */
230+ {0x85, 0x24, 0x00}, /* 0D: VCLK135 */
231+ {0x67, 0x22, 0x00}, /* 0E: VCLK157_5 */
232+ {0x6A, 0x22, 0x00}, /* 0F: VCLK162 */
233+ {0x4d, 0x4c, 0x80}, /* 10: VCLK154 */
234+ {0xa7, 0x78, 0x80}, /* 11: VCLK83.5 */
235+ {0x28, 0x49, 0x80}, /* 12: VCLK106.5 */
236+ {0x37, 0x49, 0x80}, /* 13: VCLK146.25 */
237+ {0x1f, 0x45, 0x80}, /* 14: VCLK148.5 */
238+ {0x47, 0x6c, 0x80}, /* 15: VCLK71 */
239+ {0x25, 0x65, 0x80}, /* 16: VCLK88.75 */
240+ {0x58, 0x01, 0x42}, /* 17: VCLK119 */
241+ {0x32, 0x67, 0x80}, /* 18: VCLK85_5 */
242+ {0x6a, 0x6d, 0x80}, /* 19: VCLK97_75 */
243+ {0x44, 0x20, 0x43}, /* 1A: VCLK118_25 */
244+};
245+
246 static const struct ast_vbios_stdtable vbios_stdtable[] = {
247 /* MD_2_3_400 */
248 {
249@@ -246,12 +277,14 @@ static const struct ast_vbios_enhtable res_1360x768[] = {
250 {1792, 1360, 64, 112, 795, 768, 3, 6, VCLK85_5, /* 60Hz */
251 (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x39 },
252 {1792, 1360, 64, 112, 795, 768, 3, 6, VCLK85_5, /* end */
253- (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x39 },
254+ (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
255+ AST2500PreCatchCRT), 0xFF, 1, 0x39 },
256 };
257
258 static const struct ast_vbios_enhtable res_1600x900[] = {
259 {1760, 1600, 48, 32, 926, 900, 3, 5, VCLK97_75, /* 60Hz CVT RB */
260- (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x3A },
261+ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
262+ AST2500PreCatchCRT), 60, 1, 0x3A },
263 {2112, 1600, 88, 168, 934, 900, 3, 5, VCLK118_25, /* 60Hz CVT */
264 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x3A },
265 {2112, 1600, 88, 168, 934, 900, 3, 5, VCLK118_25, /* 60Hz CVT */
266@@ -260,16 +293,19 @@ static const struct ast_vbios_enhtable res_1600x900[] = {
267
268 static const struct ast_vbios_enhtable res_1920x1080[] = {
269 {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */
270- (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x38 },
271+ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
272+ AST2500PreCatchCRT), 60, 1, 0x38 },
273 {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */
274- (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x38 },
275+ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
276+ AST2500PreCatchCRT), 0xFF, 1, 0x38 },
277 };
278
279
280 /* 16:10 */
281 static const struct ast_vbios_enhtable res_1280x800[] = {
282 {1440, 1280, 48, 32, 823, 800, 3, 6, VCLK71, /* 60Hz RB */
283- (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x35 },
284+ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
285+ AST2500PreCatchCRT), 60, 1, 0x35 },
286 {1680, 1280, 72,128, 831, 800, 3, 6, VCLK83_5, /* 60Hz */
287 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x35 },
288 {1680, 1280, 72,128, 831, 800, 3, 6, VCLK83_5, /* 60Hz */
289@@ -279,7 +315,8 @@ static const struct ast_vbios_enhtable res_1280x800[] = {
290
291 static const struct ast_vbios_enhtable res_1440x900[] = {
292 {1600, 1440, 48, 32, 926, 900, 3, 6, VCLK88_75, /* 60Hz RB */
293- (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x36 },
294+ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
295+ AST2500PreCatchCRT), 60, 1, 0x36 },
296 {1904, 1440, 80,152, 934, 900, 3, 6, VCLK106_5, /* 60Hz */
297 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x36 },
298 {1904, 1440, 80,152, 934, 900, 3, 6, VCLK106_5, /* 60Hz */
299@@ -288,7 +325,8 @@ static const struct ast_vbios_enhtable res_1440x900[] = {
300
301 static const struct ast_vbios_enhtable res_1680x1050[] = {
302 {1840, 1680, 48, 32, 1080, 1050, 3, 6, VCLK119, /* 60Hz RB */
303- (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x37 },
304+ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
305+ AST2500PreCatchCRT), 60, 1, 0x37 },
306 {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25, /* 60Hz */
307 (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x37 },
308 {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25, /* 60Hz */
309@@ -297,9 +335,11 @@ static const struct ast_vbios_enhtable res_1680x1050[] = {
310
311 static const struct ast_vbios_enhtable res_1920x1200[] = {
312 {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz RB*/
313- (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x34 },
314+ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
315+ AST2500PreCatchCRT), 60, 1, 0x34 },
316 {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz RB */
317- (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x34 },
318+ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo |
319+ AST2500PreCatchCRT), 0xFF, 1, 0x34 },
320 };
321
322 #endif
323--
3242.11.0
325