aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/ast
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-03-27 21:05:12 -0400
committerDave Airlie <airlied@redhat.com>2014-05-18 21:13:57 -0400
commit83c6620bae3f14adb2430fdcc367980fe3b7bee2 (patch)
treeb7d9d9d1d70c2ae5fb5479bdd16b7f04d9282892 /drivers/gpu/drm/ast
parent0e5ce92438146655d60447802d2c11bdbc089329 (diff)
drm/ast: initial DP501 support (v0.2)
This is the initial attempt at porting the DP501 code from the userspace driver, the firmware file is in http://people.freedesktop.org/~airlied/ast_dp501_fw.bin this should really be exposed as another encoder/connector that is cloneable v0.2: init 3rd tx properly, add scratch reduction of VRAM size backup firmware properly. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/ast')
-rw-r--r--drivers/gpu/drm/ast/Makefile4
-rw-r--r--drivers/gpu/drm/ast/ast_dp501.c410
-rw-r--r--drivers/gpu/drm/ast/ast_drv.h22
-rw-r--r--drivers/gpu/drm/ast/ast_main.c53
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c22
-rw-r--r--drivers/gpu/drm/ast/ast_post.c6
6 files changed, 505 insertions, 12 deletions
diff --git a/drivers/gpu/drm/ast/Makefile b/drivers/gpu/drm/ast/Makefile
index 8df4f284ee24..171aa0622b66 100644
--- a/drivers/gpu/drm/ast/Makefile
+++ b/drivers/gpu/drm/ast/Makefile
@@ -4,6 +4,6 @@
4 4
5ccflags-y := -Iinclude/drm 5ccflags-y := -Iinclude/drm
6 6
7ast-y := ast_drv.o ast_main.o ast_mode.o ast_fb.o ast_ttm.o ast_post.o 7ast-y := ast_drv.o ast_main.o ast_mode.o ast_fb.o ast_ttm.o ast_post.o ast_dp501.o
8 8
9obj-$(CONFIG_DRM_AST) := ast.o \ No newline at end of file 9obj-$(CONFIG_DRM_AST) := ast.o
diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c
new file mode 100644
index 000000000000..5da4b62285fa
--- /dev/null
+++ b/drivers/gpu/drm/ast/ast_dp501.c
@@ -0,0 +1,410 @@
1
2#include <linux/firmware.h>
3#include <drm/drmP.h>
4#include "ast_drv.h"
5MODULE_FIRMWARE("ast_dp501_fw.bin");
6
7int ast_load_dp501_microcode(struct drm_device *dev)
8{
9 struct ast_private *ast = dev->dev_private;
10 static char *fw_name = "ast_dp501_fw.bin";
11 int err;
12 err = request_firmware(&ast->dp501_fw, fw_name, dev->dev);
13 if (err)
14 return err;
15
16 return 0;
17}
18
19static void send_ack(struct ast_private *ast)
20{
21 u8 sendack;
22 sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff);
23 sendack |= 0x80;
24 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack);
25}
26
27static void send_nack(struct ast_private *ast)
28{
29 u8 sendack;
30 sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff);
31 sendack &= ~0x80;
32 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack);
33}
34
35static bool wait_ack(struct ast_private *ast)
36{
37 u8 waitack;
38 u32 retry = 0;
39 do {
40 waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff);
41 waitack &= 0x80;
42 udelay(100);
43 } while ((!waitack) && (retry++ < 1000));
44
45 if (retry < 1000)
46 return true;
47 else
48 return false;
49}
50
51static bool wait_nack(struct ast_private *ast)
52{
53 u8 waitack;
54 u32 retry = 0;
55 do {
56 waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff);
57 waitack &= 0x80;
58 udelay(100);
59 } while ((waitack) && (retry++ < 1000));
60
61 if (retry < 1000)
62 return true;
63 else
64 return false;
65}
66
67static void set_cmd_trigger(struct ast_private *ast)
68{
69 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x40);
70}
71
72static void clear_cmd_trigger(struct ast_private *ast)
73{
74 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x00);
75}
76
77#if 0
78static bool wait_fw_ready(struct ast_private *ast)
79{
80 u8 waitready;
81 u32 retry = 0;
82 do {
83 waitready = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff);
84 waitready &= 0x40;
85 udelay(100);
86 } while ((!waitready) && (retry++ < 1000));
87
88 if (retry < 1000)
89 return true;
90 else
91 return false;
92}
93#endif
94
95static bool ast_write_cmd(struct drm_device *dev, u8 data)
96{
97 struct ast_private *ast = dev->dev_private;
98 int retry = 0;
99 if (wait_nack(ast)) {
100 send_nack(ast);
101 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data);
102 send_ack(ast);
103 set_cmd_trigger(ast);
104 do {
105 if (wait_ack(ast)) {
106 clear_cmd_trigger(ast);
107 send_nack(ast);
108 return true;
109 }
110 } while (retry++ < 100);
111 }
112 clear_cmd_trigger(ast);
113 send_nack(ast);
114 return false;
115}
116
117static bool ast_write_data(struct drm_device *dev, u8 data)
118{
119 struct ast_private *ast = dev->dev_private;
120
121 if (wait_nack(ast)) {
122 send_nack(ast);
123 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data);
124 send_ack(ast);
125 if (wait_ack(ast)) {
126 send_nack(ast);
127 return true;
128 }
129 }
130 send_nack(ast);
131 return false;
132}
133
134#if 0
135static bool ast_read_data(struct drm_device *dev, u8 *data)
136{
137 struct ast_private *ast = dev->dev_private;
138 u8 tmp;
139
140 *data = 0;
141
142 if (wait_ack(ast) == false)
143 return false;
144 tmp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd3, 0xff);
145 *data = tmp;
146 if (wait_nack(ast) == false) {
147 send_nack(ast);
148 return false;
149 }
150 send_nack(ast);
151 return true;
152}
153
154static void clear_cmd(struct ast_private *ast)
155{
156 send_nack(ast);
157 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, 0x00);
158}
159#endif
160
161void ast_set_dp501_video_output(struct drm_device *dev, u8 mode)
162{
163 ast_write_cmd(dev, 0x40);
164 ast_write_data(dev, mode);
165
166 msleep(10);
167}
168
169static u32 get_fw_base(struct ast_private *ast)
170{
171 return ast_mindwm(ast, 0x1e6e2104) & 0x7fffffff;
172}
173
174bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size)
175{
176 struct ast_private *ast = dev->dev_private;
177 u32 i, data;
178 u32 boot_address;
179
180 data = ast_mindwm(ast, 0x1e6e2100) & 0x01;
181 if (data) {
182 boot_address = get_fw_base(ast);
183 for (i = 0; i < size; i += 4)
184 *(u32 *)(addr + i) = ast_mindwm(ast, boot_address + i);
185 return true;
186 }
187 return false;
188}
189
190bool ast_launch_m68k(struct drm_device *dev)
191{
192 struct ast_private *ast = dev->dev_private;
193 u32 i, data, len = 0;
194 u32 boot_address;
195 u8 *fw_addr = NULL;
196 u8 jreg;
197
198 data = ast_mindwm(ast, 0x1e6e2100) & 0x01;
199 if (!data) {
200
201 if (ast->dp501_fw_addr) {
202 fw_addr = ast->dp501_fw_addr;
203 len = 32*1024;
204 } else if (ast->dp501_fw) {
205 fw_addr = (u8 *)ast->dp501_fw->data;
206 len = ast->dp501_fw->size;
207 }
208 /* Get BootAddress */
209 ast_moutdwm(ast, 0x1e6e2000, 0x1688a8a8);
210 data = ast_mindwm(ast, 0x1e6e0004);
211 switch (data & 0x03) {
212 case 0:
213 boot_address = 0x44000000;
214 break;
215 default:
216 case 1:
217 boot_address = 0x48000000;
218 break;
219 case 2:
220 boot_address = 0x50000000;
221 break;
222 case 3:
223 boot_address = 0x60000000;
224 break;
225 }
226 boot_address -= 0x200000; /* -2MB */
227
228 /* copy image to buffer */
229 for (i = 0; i < len; i += 4) {
230 data = *(u32 *)(fw_addr + i);
231 ast_moutdwm(ast, boot_address + i, data);
232 }
233
234 /* Init SCU */
235 ast_moutdwm(ast, 0x1e6e2000, 0x1688a8a8);
236
237 /* Launch FW */
238 ast_moutdwm(ast, 0x1e6e2104, 0x80000000 + boot_address);
239 ast_moutdwm(ast, 0x1e6e2100, 1);
240
241 /* Update Scratch */
242 data = ast_mindwm(ast, 0x1e6e2040) & 0xfffff1ff; /* D[11:9] = 100b: UEFI handling */
243 data |= 0x800;
244 ast_moutdwm(ast, 0x1e6e2040, data);
245
246 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xfc); /* D[1:0]: Reserved Video Buffer */
247 jreg |= 0x02;
248 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x99, jreg);
249 }
250 return true;
251}
252
253u8 ast_get_dp501_max_clk(struct drm_device *dev)
254{
255 struct ast_private *ast = dev->dev_private;
256 u32 boot_address, offset, data;
257 u8 linkcap[4], linkrate, linklanes, maxclk = 0xff;
258
259 boot_address = get_fw_base(ast);
260
261 /* validate FW version */
262 offset = 0xf000;
263 data = ast_mindwm(ast, boot_address + offset);
264 if ((data & 0xf0) != 0x10) /* version: 1x */
265 return maxclk;
266
267 /* Read Link Capability */
268 offset = 0xf014;
269 *(u32 *)linkcap = ast_mindwm(ast, boot_address + offset);
270 if (linkcap[2] == 0) {
271 linkrate = linkcap[0];
272 linklanes = linkcap[1];
273 data = (linkrate == 0x0a) ? (90 * linklanes) : (54 * linklanes);
274 if (data > 0xff)
275 data = 0xff;
276 maxclk = (u8)data;
277 }
278 return maxclk;
279}
280
281bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata)
282{
283 struct ast_private *ast = dev->dev_private;
284 u32 i, boot_address, offset, data;
285
286 boot_address = get_fw_base(ast);
287
288 /* validate FW version */
289 offset = 0xf000;
290 data = ast_mindwm(ast, boot_address + offset);
291 if ((data & 0xf0) != 0x10)
292 return false;
293
294 /* validate PnP Monitor */
295 offset = 0xf010;
296 data = ast_mindwm(ast, boot_address + offset);
297 if (!(data & 0x01))
298 return false;
299
300 /* Read EDID */
301 offset = 0xf020;
302 for (i = 0; i < 128; i += 4) {
303 data = ast_mindwm(ast, boot_address + offset + i);
304 *(u32 *)(ediddata + i) = data;
305 }
306
307 return true;
308}
309
310static bool ast_init_dvo(struct drm_device *dev)
311{
312 struct ast_private *ast = dev->dev_private;
313 u8 jreg;
314 u32 data;
315 ast_write32(ast, 0xf004, 0x1e6e0000);
316 ast_write32(ast, 0xf000, 0x1);
317 ast_write32(ast, 0x12000, 0x1688a8a8);
318
319 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
320 if (!(jreg & 0x80)) {
321 /* Init SCU DVO Settings */
322 data = ast_read32(ast, 0x12008);
323 /* delay phase */
324 data &= 0xfffff8ff;
325 data |= 0x00000500;
326 ast_write32(ast, 0x12008, data);
327
328 if (ast->chip == AST2300) {
329 data = ast_read32(ast, 0x12084);
330 /* multi-pins for DVO single-edge */
331 data |= 0xfffe0000;
332 ast_write32(ast, 0x12084, data);
333
334 data = ast_read32(ast, 0x12088);
335 /* multi-pins for DVO single-edge */
336 data |= 0x000fffff;
337 ast_write32(ast, 0x12088, data);
338
339 data = ast_read32(ast, 0x12090);
340 /* multi-pins for DVO single-edge */
341 data &= 0xffffffcf;
342 data |= 0x00000020;
343 ast_write32(ast, 0x12090, data);
344 } else { /* AST2400 */
345 data = ast_read32(ast, 0x12088);
346 /* multi-pins for DVO single-edge */
347 data |= 0x30000000;
348 ast_write32(ast, 0x12088, data);
349
350 data = ast_read32(ast, 0x1208c);
351 /* multi-pins for DVO single-edge */
352 data |= 0x000000cf;
353 ast_write32(ast, 0x1208c, data);
354
355 data = ast_read32(ast, 0x120a4);
356 /* multi-pins for DVO single-edge */
357 data |= 0xffff0000;
358 ast_write32(ast, 0x120a4, data);
359
360 data = ast_read32(ast, 0x120a8);
361 /* multi-pins for DVO single-edge */
362 data |= 0x0000000f;
363 ast_write32(ast, 0x120a8, data);
364
365 data = ast_read32(ast, 0x12094);
366 /* multi-pins for DVO single-edge */
367 data |= 0x00000002;
368 ast_write32(ast, 0x12094, data);
369 }
370 }
371
372 /* Force to DVO */
373 data = ast_read32(ast, 0x1202c);
374 data &= 0xfffbffff;
375 ast_write32(ast, 0x1202c, data);
376
377 /* Init VGA DVO Settings */
378 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80);
379 return true;
380}
381
382void ast_init_3rdtx(struct drm_device *dev)
383{
384 struct ast_private *ast = dev->dev_private;
385 u8 jreg;
386 u32 data;
387 if (ast->chip == AST2300 || ast->chip == AST2400) {
388 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
389 switch (jreg & 0x0e) {
390 case 0x04:
391 ast_init_dvo(dev);
392 break;
393 case 0x08:
394 ast_launch_m68k(dev);
395 break;
396 case 0x0c:
397 ast_init_dvo(dev);
398 break;
399 default:
400 if (ast->tx_chip_type == AST_TX_SIL164)
401 ast_init_dvo(dev);
402 else {
403 ast_write32(ast, 0x12000, 0x1688a8a8);
404 data = ast_read32(ast, 0x1202c);
405 data &= 0xfffcffff;
406 ast_write32(ast, 0, data);
407 }
408 }
409 }
410}
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 561742793947..5d6a87573c33 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -65,6 +65,13 @@ enum ast_chip {
65 AST1180, 65 AST1180,
66}; 66};
67 67
68enum ast_tx_chip {
69 AST_TX_NONE,
70 AST_TX_SIL164,
71 AST_TX_ITE66121,
72 AST_TX_DP501,
73};
74
68#define AST_DRAM_512Mx16 0 75#define AST_DRAM_512Mx16 0
69#define AST_DRAM_1Gx16 1 76#define AST_DRAM_1Gx16 1
70#define AST_DRAM_512Mx32 2 77#define AST_DRAM_512Mx32 2
@@ -104,6 +111,11 @@ struct ast_private {
104 struct ttm_bo_kmap_obj cache_kmap; 111 struct ttm_bo_kmap_obj cache_kmap;
105 int next_cursor; 112 int next_cursor;
106 bool support_wide_screen; 113 bool support_wide_screen;
114
115 enum ast_tx_chip tx_chip_type;
116 u8 dp501_maxclk;
117 u8 *dp501_fw_addr;
118 const struct firmware *dp501_fw; /* dp501 fw */
107}; 119};
108 120
109int ast_driver_load(struct drm_device *dev, unsigned long flags); 121int ast_driver_load(struct drm_device *dev, unsigned long flags);
@@ -370,4 +382,14 @@ int ast_mmap(struct file *filp, struct vm_area_struct *vma);
370 382
371/* ast post */ 383/* ast post */
372void ast_post_gpu(struct drm_device *dev); 384void ast_post_gpu(struct drm_device *dev);
385u32 ast_mindwm(struct ast_private *ast, u32 r);
386void ast_moutdwm(struct ast_private *ast, u32 r, u32 v);
387/* ast dp501 */
388int ast_load_dp501_microcode(struct drm_device *dev);
389void ast_set_dp501_video_output(struct drm_device *dev, u8 mode);
390bool ast_launch_m68k(struct drm_device *dev);
391bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size);
392bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata);
393u8 ast_get_dp501_max_clk(struct drm_device *dev);
394void ast_init_3rdtx(struct drm_device *dev);
373#endif 395#endif
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
index 01ea4b6d4bf3..1124fb40758e 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -136,6 +136,31 @@ static int ast_detect_chip(struct drm_device *dev)
136 break; 136 break;
137 } 137 }
138 138
139 ast->tx_chip_type = AST_TX_NONE;
140 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xff);
141 if (jreg & 0x80)
142 ast->tx_chip_type = AST_TX_SIL164;
143 if ((ast->chip == AST2300) || (ast->chip == AST2400)) {
144 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
145 switch (jreg) {
146 case 0x04:
147 ast->tx_chip_type = AST_TX_SIL164;
148 break;
149 case 0x08:
150 ast->dp501_fw_addr = kzalloc(32*1024, GFP_KERNEL);
151 if (ast->dp501_fw_addr) {
152 /* backup firmware */
153 if (ast_backup_fw(dev, ast->dp501_fw_addr, 32*1024)) {
154 kfree(ast->dp501_fw_addr);
155 ast->dp501_fw_addr = NULL;
156 }
157 }
158 /* fallthrough */
159 case 0x0c:
160 ast->tx_chip_type = AST_TX_DP501;
161 }
162 }
163
139 return 0; 164 return 0;
140} 165}
141 166
@@ -289,17 +314,32 @@ static u32 ast_get_vram_info(struct drm_device *dev)
289{ 314{
290 struct ast_private *ast = dev->dev_private; 315 struct ast_private *ast = dev->dev_private;
291 u8 jreg; 316 u8 jreg;
292 317 u32 vram_size;
293 ast_open_key(ast); 318 ast_open_key(ast);
294 319
320 vram_size = AST_VIDMEM_DEFAULT_SIZE;
295 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff); 321 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff);
296 switch (jreg & 3) { 322 switch (jreg & 3) {
297 case 0: return AST_VIDMEM_SIZE_8M; 323 case 0: vram_size = AST_VIDMEM_SIZE_8M; break;
298 case 1: return AST_VIDMEM_SIZE_16M; 324 case 1: vram_size = AST_VIDMEM_SIZE_16M; break;
299 case 2: return AST_VIDMEM_SIZE_32M; 325 case 2: vram_size = AST_VIDMEM_SIZE_32M; break;
300 case 3: return AST_VIDMEM_SIZE_64M; 326 case 3: vram_size = AST_VIDMEM_SIZE_64M; break;
301 } 327 }
302 return AST_VIDMEM_DEFAULT_SIZE; 328
329 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xff);
330 switch (jreg & 0x03) {
331 case 1:
332 vram_size -= 0x100000;
333 break;
334 case 2:
335 vram_size -= 0x200000;
336 break;
337 case 3:
338 vram_size -= 0x400000;
339 break;
340 }
341
342 return vram_size;
303} 343}
304 344
305int ast_driver_load(struct drm_device *dev, unsigned long flags) 345int ast_driver_load(struct drm_device *dev, unsigned long flags)
@@ -376,6 +416,7 @@ int ast_driver_unload(struct drm_device *dev)
376{ 416{
377 struct ast_private *ast = dev->dev_private; 417 struct ast_private *ast = dev->dev_private;
378 418
419 kfree(ast->dp501_fw_addr);
379 ast_mode_fini(dev); 420 ast_mode_fini(dev);
380 ast_fbdev_fini(dev); 421 ast_fbdev_fini(dev);
381 drm_mode_config_cleanup(dev); 422 drm_mode_config_cleanup(dev);
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index e9a14a14a029..208dc45d0513 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -460,9 +460,13 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
460 case DRM_MODE_DPMS_STANDBY: 460 case DRM_MODE_DPMS_STANDBY:
461 case DRM_MODE_DPMS_SUSPEND: 461 case DRM_MODE_DPMS_SUSPEND:
462 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0); 462 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0);
463 if (ast->tx_chip_type == AST_TX_DP501)
464 ast_set_dp501_video_output(crtc->dev, 1);
463 ast_crtc_load_lut(crtc); 465 ast_crtc_load_lut(crtc);
464 break; 466 break;
465 case DRM_MODE_DPMS_OFF: 467 case DRM_MODE_DPMS_OFF:
468 if (ast->tx_chip_type == AST_TX_DP501)
469 ast_set_dp501_video_output(crtc->dev, 0);
466 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20); 470 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20);
467 break; 471 break;
468 } 472 }
@@ -738,10 +742,24 @@ static int ast_encoder_init(struct drm_device *dev)
738static int ast_get_modes(struct drm_connector *connector) 742static int ast_get_modes(struct drm_connector *connector)
739{ 743{
740 struct ast_connector *ast_connector = to_ast_connector(connector); 744 struct ast_connector *ast_connector = to_ast_connector(connector);
745 struct ast_private *ast = connector->dev->dev_private;
741 struct edid *edid; 746 struct edid *edid;
742 int ret; 747 int ret;
743 748 bool flags = false;
744 edid = drm_get_edid(connector, &ast_connector->i2c->adapter); 749 if (ast->tx_chip_type == AST_TX_DP501) {
750 ast->dp501_maxclk = 0xff;
751 edid = kmalloc(128, GFP_KERNEL);
752 if (!edid)
753 return -ENOMEM;
754
755 flags = ast_dp501_read_edid(connector->dev, (u8 *)edid);
756 if (flags)
757 ast->dp501_maxclk = ast_get_dp501_max_clk(connector->dev);
758 else
759 kfree(edid);
760 }
761 if (!flags)
762 edid = drm_get_edid(connector, &ast_connector->i2c->adapter);
745 if (edid) { 763 if (edid) {
746 drm_mode_connector_update_edid_property(&ast_connector->base, edid); 764 drm_mode_connector_update_edid_property(&ast_connector->base, edid);
747 ret = drm_add_edid_modes(connector, edid); 765 ret = drm_add_edid_modes(connector, edid);
diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c
index e8a64383256e..116c8301dfd4 100644
--- a/drivers/gpu/drm/ast/ast_post.c
+++ b/drivers/gpu/drm/ast/ast_post.c
@@ -107,7 +107,7 @@ ast_set_def_ext_reg(struct drm_device *dev)
107 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff, reg); 107 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff, reg);
108} 108}
109 109
110static u32 ast_mindwm(struct ast_private *ast, u32 r) 110u32 ast_mindwm(struct ast_private *ast, u32 r)
111{ 111{
112 uint32_t data; 112 uint32_t data;
113 113
@@ -120,7 +120,7 @@ static u32 ast_mindwm(struct ast_private *ast, u32 r)
120 return ast_read32(ast, 0x10000 + (r & 0x0000ffff)); 120 return ast_read32(ast, 0x10000 + (r & 0x0000ffff));
121} 121}
122 122
123static void ast_moutdwm(struct ast_private *ast, u32 r, u32 v) 123void ast_moutdwm(struct ast_private *ast, u32 r, u32 v)
124{ 124{
125 uint32_t data; 125 uint32_t data;
126 ast_write32(ast, 0xf004, r & 0xffff0000); 126 ast_write32(ast, 0xf004, r & 0xffff0000);
@@ -378,6 +378,8 @@ void ast_post_gpu(struct drm_device *dev)
378 ast_init_dram_2300(dev); 378 ast_init_dram_2300(dev);
379 else 379 else
380 ast_init_dram_reg(dev); 380 ast_init_dram_reg(dev);
381
382 ast_init_3rdtx(dev);
381} 383}
382 384
383/* AST 2300 DRAM settings */ 385/* AST 2300 DRAM settings */