xref: /openbmc/linux/drivers/gpu/drm/ast/ast_mode.c (revision 747f7a29)
1 /*
2  * Copyright 2012 Red Hat Inc.
3  * Parts based on xf86-video-ast
4  * Copyright (c) 2005 ASPEED Technology Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20  * USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * The above copyright notice and this permission notice (including the
23  * next paragraph) shall be included in all copies or substantial portions
24  * of the Software.
25  *
26  */
27 /*
28  * Authors: Dave Airlie <airlied@redhat.com>
29  */
30 
31 #include <linux/export.h>
32 #include <linux/pci.h>
33 
34 #include <drm/drm_atomic.h>
35 #include <drm/drm_atomic_helper.h>
36 #include <drm/drm_atomic_state_helper.h>
37 #include <drm/drm_crtc.h>
38 #include <drm/drm_crtc_helper.h>
39 #include <drm/drm_edid.h>
40 #include <drm/drm_fourcc.h>
41 #include <drm/drm_gem_atomic_helper.h>
42 #include <drm/drm_gem_framebuffer_helper.h>
43 #include <drm/drm_gem_vram_helper.h>
44 #include <drm/drm_managed.h>
45 #include <drm/drm_plane_helper.h>
46 #include <drm/drm_probe_helper.h>
47 #include <drm/drm_simple_kms_helper.h>
48 
49 #include "ast_drv.h"
50 #include "ast_tables.h"
51 
52 static inline void ast_load_palette_index(struct ast_private *ast,
53 				     u8 index, u8 red, u8 green,
54 				     u8 blue)
55 {
56 	ast_io_write8(ast, AST_IO_DAC_INDEX_WRITE, index);
57 	ast_io_read8(ast, AST_IO_SEQ_PORT);
58 	ast_io_write8(ast, AST_IO_DAC_DATA, red);
59 	ast_io_read8(ast, AST_IO_SEQ_PORT);
60 	ast_io_write8(ast, AST_IO_DAC_DATA, green);
61 	ast_io_read8(ast, AST_IO_SEQ_PORT);
62 	ast_io_write8(ast, AST_IO_DAC_DATA, blue);
63 	ast_io_read8(ast, AST_IO_SEQ_PORT);
64 }
65 
66 static void ast_crtc_load_lut(struct ast_private *ast, struct drm_crtc *crtc)
67 {
68 	u16 *r, *g, *b;
69 	int i;
70 
71 	if (!crtc->enabled)
72 		return;
73 
74 	r = crtc->gamma_store;
75 	g = r + crtc->gamma_size;
76 	b = g + crtc->gamma_size;
77 
78 	for (i = 0; i < 256; i++)
79 		ast_load_palette_index(ast, i, *r++ >> 8, *g++ >> 8, *b++ >> 8);
80 }
81 
82 static bool ast_get_vbios_mode_info(const struct drm_format_info *format,
83 				    const struct drm_display_mode *mode,
84 				    struct drm_display_mode *adjusted_mode,
85 				    struct ast_vbios_mode_info *vbios_mode)
86 {
87 	u32 refresh_rate_index = 0, refresh_rate;
88 	const struct ast_vbios_enhtable *best = NULL;
89 	u32 hborder, vborder;
90 	bool check_sync;
91 
92 	switch (format->cpp[0] * 8) {
93 	case 8:
94 		vbios_mode->std_table = &vbios_stdtable[VGAModeIndex];
95 		break;
96 	case 16:
97 		vbios_mode->std_table = &vbios_stdtable[HiCModeIndex];
98 		break;
99 	case 24:
100 	case 32:
101 		vbios_mode->std_table = &vbios_stdtable[TrueCModeIndex];
102 		break;
103 	default:
104 		return false;
105 	}
106 
107 	switch (mode->crtc_hdisplay) {
108 	case 640:
109 		vbios_mode->enh_table = &res_640x480[refresh_rate_index];
110 		break;
111 	case 800:
112 		vbios_mode->enh_table = &res_800x600[refresh_rate_index];
113 		break;
114 	case 1024:
115 		vbios_mode->enh_table = &res_1024x768[refresh_rate_index];
116 		break;
117 	case 1280:
118 		if (mode->crtc_vdisplay == 800)
119 			vbios_mode->enh_table = &res_1280x800[refresh_rate_index];
120 		else
121 			vbios_mode->enh_table = &res_1280x1024[refresh_rate_index];
122 		break;
123 	case 1360:
124 		vbios_mode->enh_table = &res_1360x768[refresh_rate_index];
125 		break;
126 	case 1440:
127 		vbios_mode->enh_table = &res_1440x900[refresh_rate_index];
128 		break;
129 	case 1600:
130 		if (mode->crtc_vdisplay == 900)
131 			vbios_mode->enh_table = &res_1600x900[refresh_rate_index];
132 		else
133 			vbios_mode->enh_table = &res_1600x1200[refresh_rate_index];
134 		break;
135 	case 1680:
136 		vbios_mode->enh_table = &res_1680x1050[refresh_rate_index];
137 		break;
138 	case 1920:
139 		if (mode->crtc_vdisplay == 1080)
140 			vbios_mode->enh_table = &res_1920x1080[refresh_rate_index];
141 		else
142 			vbios_mode->enh_table = &res_1920x1200[refresh_rate_index];
143 		break;
144 	default:
145 		return false;
146 	}
147 
148 	refresh_rate = drm_mode_vrefresh(mode);
149 	check_sync = vbios_mode->enh_table->flags & WideScreenMode;
150 
151 	while (1) {
152 		const struct ast_vbios_enhtable *loop = vbios_mode->enh_table;
153 
154 		while (loop->refresh_rate != 0xff) {
155 			if ((check_sync) &&
156 			    (((mode->flags & DRM_MODE_FLAG_NVSYNC)  &&
157 			      (loop->flags & PVSync))  ||
158 			     ((mode->flags & DRM_MODE_FLAG_PVSYNC)  &&
159 			      (loop->flags & NVSync))  ||
160 			     ((mode->flags & DRM_MODE_FLAG_NHSYNC)  &&
161 			      (loop->flags & PHSync))  ||
162 			     ((mode->flags & DRM_MODE_FLAG_PHSYNC)  &&
163 			      (loop->flags & NHSync)))) {
164 				loop++;
165 				continue;
166 			}
167 			if (loop->refresh_rate <= refresh_rate
168 			    && (!best || loop->refresh_rate > best->refresh_rate))
169 				best = loop;
170 			loop++;
171 		}
172 		if (best || !check_sync)
173 			break;
174 		check_sync = 0;
175 	}
176 
177 	if (best)
178 		vbios_mode->enh_table = best;
179 
180 	hborder = (vbios_mode->enh_table->flags & HBorder) ? 8 : 0;
181 	vborder = (vbios_mode->enh_table->flags & VBorder) ? 8 : 0;
182 
183 	adjusted_mode->crtc_htotal = vbios_mode->enh_table->ht;
184 	adjusted_mode->crtc_hblank_start = vbios_mode->enh_table->hde + hborder;
185 	adjusted_mode->crtc_hblank_end = vbios_mode->enh_table->ht - hborder;
186 	adjusted_mode->crtc_hsync_start = vbios_mode->enh_table->hde + hborder +
187 		vbios_mode->enh_table->hfp;
188 	adjusted_mode->crtc_hsync_end = (vbios_mode->enh_table->hde + hborder +
189 					 vbios_mode->enh_table->hfp +
190 					 vbios_mode->enh_table->hsync);
191 
192 	adjusted_mode->crtc_vtotal = vbios_mode->enh_table->vt;
193 	adjusted_mode->crtc_vblank_start = vbios_mode->enh_table->vde + vborder;
194 	adjusted_mode->crtc_vblank_end = vbios_mode->enh_table->vt - vborder;
195 	adjusted_mode->crtc_vsync_start = vbios_mode->enh_table->vde + vborder +
196 		vbios_mode->enh_table->vfp;
197 	adjusted_mode->crtc_vsync_end = (vbios_mode->enh_table->vde + vborder +
198 					 vbios_mode->enh_table->vfp +
199 					 vbios_mode->enh_table->vsync);
200 
201 	return true;
202 }
203 
204 static void ast_set_vbios_color_reg(struct ast_private *ast,
205 				    const struct drm_format_info *format,
206 				    const struct ast_vbios_mode_info *vbios_mode)
207 {
208 	u32 color_index;
209 
210 	switch (format->cpp[0]) {
211 	case 1:
212 		color_index = VGAModeIndex - 1;
213 		break;
214 	case 2:
215 		color_index = HiCModeIndex;
216 		break;
217 	case 3:
218 	case 4:
219 		color_index = TrueCModeIndex;
220 		break;
221 	default:
222 		return;
223 	}
224 
225 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8c, (u8)((color_index & 0x0f) << 4));
226 
227 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
228 
229 	if (vbios_mode->enh_table->flags & NewModeInfo) {
230 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
231 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, format->cpp[0] * 8);
232 	}
233 }
234 
235 static void ast_set_vbios_mode_reg(struct ast_private *ast,
236 				   const struct drm_display_mode *adjusted_mode,
237 				   const struct ast_vbios_mode_info *vbios_mode)
238 {
239 	u32 refresh_rate_index, mode_id;
240 
241 	refresh_rate_index = vbios_mode->enh_table->refresh_rate_index;
242 	mode_id = vbios_mode->enh_table->mode_id;
243 
244 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff);
245 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff);
246 
247 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
248 
249 	if (vbios_mode->enh_table->flags & NewModeInfo) {
250 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
251 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000);
252 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay);
253 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8);
254 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay);
255 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8);
256 	}
257 }
258 
259 static void ast_set_std_reg(struct ast_private *ast,
260 			    struct drm_display_mode *mode,
261 			    struct ast_vbios_mode_info *vbios_mode)
262 {
263 	const struct ast_vbios_stdtable *stdtable;
264 	u32 i;
265 	u8 jreg;
266 
267 	stdtable = vbios_mode->std_table;
268 
269 	jreg = stdtable->misc;
270 	ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg);
271 
272 	/* Set SEQ; except Screen Disable field */
273 	ast_set_index_reg(ast, AST_IO_SEQ_PORT, 0x00, 0x03);
274 	ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, stdtable->seq[0]);
275 	for (i = 1; i < 4; i++) {
276 		jreg = stdtable->seq[i];
277 		ast_set_index_reg(ast, AST_IO_SEQ_PORT, (i + 1), jreg);
278 	}
279 
280 	/* Set CRTC; except base address and offset */
281 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00);
282 	for (i = 0; i < 12; i++)
283 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
284 	for (i = 14; i < 19; i++)
285 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
286 	for (i = 20; i < 25; i++)
287 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
288 
289 	/* set AR */
290 	jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ);
291 	for (i = 0; i < 20; i++) {
292 		jreg = stdtable->ar[i];
293 		ast_io_write8(ast, AST_IO_AR_PORT_WRITE, (u8)i);
294 		ast_io_write8(ast, AST_IO_AR_PORT_WRITE, jreg);
295 	}
296 	ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x14);
297 	ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x00);
298 
299 	jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ);
300 	ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x20);
301 
302 	/* Set GR */
303 	for (i = 0; i < 9; i++)
304 		ast_set_index_reg(ast, AST_IO_GR_PORT, i, stdtable->gr[i]);
305 }
306 
307 static void ast_set_crtc_reg(struct ast_private *ast,
308 			     struct drm_display_mode *mode,
309 			     struct ast_vbios_mode_info *vbios_mode)
310 {
311 	u8 jreg05 = 0, jreg07 = 0, jreg09 = 0, jregAC = 0, jregAD = 0, jregAE = 0;
312 	u16 temp, precache = 0;
313 
314 	if ((ast->chip == AST2500) &&
315 	    (vbios_mode->enh_table->flags & AST2500PreCatchCRT))
316 		precache = 40;
317 
318 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00);
319 
320 	temp = (mode->crtc_htotal >> 3) - 5;
321 	if (temp & 0x100)
322 		jregAC |= 0x01; /* HT D[8] */
323 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x00, 0x00, temp);
324 
325 	temp = (mode->crtc_hdisplay >> 3) - 1;
326 	if (temp & 0x100)
327 		jregAC |= 0x04; /* HDE D[8] */
328 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x01, 0x00, temp);
329 
330 	temp = (mode->crtc_hblank_start >> 3) - 1;
331 	if (temp & 0x100)
332 		jregAC |= 0x10; /* HBS D[8] */
333 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x02, 0x00, temp);
334 
335 	temp = ((mode->crtc_hblank_end >> 3) - 1) & 0x7f;
336 	if (temp & 0x20)
337 		jreg05 |= 0x80;  /* HBE D[5] */
338 	if (temp & 0x40)
339 		jregAD |= 0x01;  /* HBE D[5] */
340 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x03, 0xE0, (temp & 0x1f));
341 
342 	temp = ((mode->crtc_hsync_start-precache) >> 3) - 1;
343 	if (temp & 0x100)
344 		jregAC |= 0x40; /* HRS D[5] */
345 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x04, 0x00, temp);
346 
347 	temp = (((mode->crtc_hsync_end-precache) >> 3) - 1) & 0x3f;
348 	if (temp & 0x20)
349 		jregAD |= 0x04; /* HRE D[5] */
350 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05));
351 
352 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAC, 0x00, jregAC);
353 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAD, 0x00, jregAD);
354 
355 	/* vert timings */
356 	temp = (mode->crtc_vtotal) - 2;
357 	if (temp & 0x100)
358 		jreg07 |= 0x01;
359 	if (temp & 0x200)
360 		jreg07 |= 0x20;
361 	if (temp & 0x400)
362 		jregAE |= 0x01;
363 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x06, 0x00, temp);
364 
365 	temp = (mode->crtc_vsync_start) - 1;
366 	if (temp & 0x100)
367 		jreg07 |= 0x04;
368 	if (temp & 0x200)
369 		jreg07 |= 0x80;
370 	if (temp & 0x400)
371 		jregAE |= 0x08;
372 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x10, 0x00, temp);
373 
374 	temp = (mode->crtc_vsync_end - 1) & 0x3f;
375 	if (temp & 0x10)
376 		jregAE |= 0x20;
377 	if (temp & 0x20)
378 		jregAE |= 0x40;
379 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x70, temp & 0xf);
380 
381 	temp = mode->crtc_vdisplay - 1;
382 	if (temp & 0x100)
383 		jreg07 |= 0x02;
384 	if (temp & 0x200)
385 		jreg07 |= 0x40;
386 	if (temp & 0x400)
387 		jregAE |= 0x02;
388 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x12, 0x00, temp);
389 
390 	temp = mode->crtc_vblank_start - 1;
391 	if (temp & 0x100)
392 		jreg07 |= 0x08;
393 	if (temp & 0x200)
394 		jreg09 |= 0x20;
395 	if (temp & 0x400)
396 		jregAE |= 0x04;
397 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x15, 0x00, temp);
398 
399 	temp = mode->crtc_vblank_end - 1;
400 	if (temp & 0x100)
401 		jregAE |= 0x10;
402 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x16, 0x00, temp);
403 
404 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x07, 0x00, jreg07);
405 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x09, 0xdf, jreg09);
406 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAE, 0x00, (jregAE | 0x80));
407 
408 	if (precache)
409 		ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x80);
410 	else
411 		ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x00);
412 
413 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x80);
414 }
415 
416 static void ast_set_offset_reg(struct ast_private *ast,
417 			       struct drm_framebuffer *fb)
418 {
419 	u16 offset;
420 
421 	offset = fb->pitches[0] >> 3;
422 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x13, (offset & 0xff));
423 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xb0, (offset >> 8) & 0x3f);
424 }
425 
426 static void ast_set_dclk_reg(struct ast_private *ast,
427 			     struct drm_display_mode *mode,
428 			     struct ast_vbios_mode_info *vbios_mode)
429 {
430 	const struct ast_vbios_dclk_info *clk_info;
431 
432 	if (ast->chip == AST2500)
433 		clk_info = &dclk_table_ast2500[vbios_mode->enh_table->dclk_index];
434 	else
435 		clk_info = &dclk_table[vbios_mode->enh_table->dclk_index];
436 
437 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc0, 0x00, clk_info->param1);
438 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc1, 0x00, clk_info->param2);
439 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xbb, 0x0f,
440 			       (clk_info->param3 & 0xc0) |
441 			       ((clk_info->param3 & 0x3) << 4));
442 }
443 
444 static void ast_set_color_reg(struct ast_private *ast,
445 			      const struct drm_format_info *format)
446 {
447 	u8 jregA0 = 0, jregA3 = 0, jregA8 = 0;
448 
449 	switch (format->cpp[0] * 8) {
450 	case 8:
451 		jregA0 = 0x70;
452 		jregA3 = 0x01;
453 		jregA8 = 0x00;
454 		break;
455 	case 15:
456 	case 16:
457 		jregA0 = 0x70;
458 		jregA3 = 0x04;
459 		jregA8 = 0x02;
460 		break;
461 	case 32:
462 		jregA0 = 0x70;
463 		jregA3 = 0x08;
464 		jregA8 = 0x02;
465 		break;
466 	}
467 
468 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa0, 0x8f, jregA0);
469 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xf0, jregA3);
470 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa8, 0xfd, jregA8);
471 }
472 
473 static void ast_set_crtthd_reg(struct ast_private *ast)
474 {
475 	/* Set Threshold */
476 	if (ast->chip == AST2600) {
477 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0xe0);
478 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0xa0);
479 	} else if (ast->chip == AST2300 || ast->chip == AST2400 ||
480 	    ast->chip == AST2500) {
481 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78);
482 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60);
483 	} else if (ast->chip == AST2100 ||
484 		   ast->chip == AST1100 ||
485 		   ast->chip == AST2200 ||
486 		   ast->chip == AST2150) {
487 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x3f);
488 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x2f);
489 	} else {
490 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x2f);
491 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x1f);
492 	}
493 }
494 
495 static void ast_set_sync_reg(struct ast_private *ast,
496 			     struct drm_display_mode *mode,
497 			     struct ast_vbios_mode_info *vbios_mode)
498 {
499 	u8 jreg;
500 
501 	jreg  = ast_io_read8(ast, AST_IO_MISC_PORT_READ);
502 	jreg &= ~0xC0;
503 	if (vbios_mode->enh_table->flags & NVSync)
504 		jreg |= 0x80;
505 	if (vbios_mode->enh_table->flags & NHSync)
506 		jreg |= 0x40;
507 	ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg);
508 }
509 
510 static void ast_set_start_address_crt1(struct ast_private *ast,
511 				       unsigned int offset)
512 {
513 	u32 addr;
514 
515 	addr = offset >> 2;
516 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0d, (u8)(addr & 0xff));
517 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0c, (u8)((addr >> 8) & 0xff));
518 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xaf, (u8)((addr >> 16) & 0xff));
519 
520 }
521 
522 static void ast_wait_for_vretrace(struct ast_private *ast)
523 {
524 	unsigned long timeout = jiffies + HZ;
525 	u8 vgair1;
526 
527 	do {
528 		vgair1 = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ);
529 	} while (!(vgair1 & AST_IO_VGAIR1_VREFRESH) && time_before(jiffies, timeout));
530 }
531 
532 /*
533  * Primary plane
534  */
535 
536 static const uint32_t ast_primary_plane_formats[] = {
537 	DRM_FORMAT_XRGB8888,
538 	DRM_FORMAT_RGB565,
539 	DRM_FORMAT_C8,
540 };
541 
542 static int ast_primary_plane_helper_atomic_check(struct drm_plane *plane,
543 						 struct drm_atomic_state *state)
544 {
545 	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
546 										 plane);
547 	struct drm_crtc_state *crtc_state;
548 	struct ast_crtc_state *ast_crtc_state;
549 	int ret;
550 
551 	if (!new_plane_state->crtc)
552 		return 0;
553 
554 	crtc_state = drm_atomic_get_new_crtc_state(state,
555 						   new_plane_state->crtc);
556 
557 	ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
558 						  DRM_PLANE_HELPER_NO_SCALING,
559 						  DRM_PLANE_HELPER_NO_SCALING,
560 						  false, true);
561 	if (ret)
562 		return ret;
563 
564 	if (!new_plane_state->visible)
565 		return 0;
566 
567 	ast_crtc_state = to_ast_crtc_state(crtc_state);
568 
569 	ast_crtc_state->format = new_plane_state->fb->format;
570 
571 	return 0;
572 }
573 
574 static void
575 ast_primary_plane_helper_atomic_update(struct drm_plane *plane,
576 				       struct drm_atomic_state *state)
577 {
578 	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
579 									   plane);
580 	struct drm_device *dev = plane->dev;
581 	struct ast_private *ast = to_ast_private(dev);
582 	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
583 									   plane);
584 	struct drm_gem_vram_object *gbo;
585 	s64 gpu_addr;
586 	struct drm_framebuffer *fb = new_state->fb;
587 	struct drm_framebuffer *old_fb = old_state->fb;
588 
589 	if (!old_fb || (fb->format != old_fb->format)) {
590 		struct drm_crtc_state *crtc_state = new_state->crtc->state;
591 		struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
592 		struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info;
593 
594 		ast_set_color_reg(ast, fb->format);
595 		ast_set_vbios_color_reg(ast, fb->format, vbios_mode_info);
596 	}
597 
598 	gbo = drm_gem_vram_of_gem(fb->obj[0]);
599 	gpu_addr = drm_gem_vram_offset(gbo);
600 	if (drm_WARN_ON_ONCE(dev, gpu_addr < 0))
601 		return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */
602 
603 	ast_set_offset_reg(ast, fb);
604 	ast_set_start_address_crt1(ast, (u32)gpu_addr);
605 
606 	ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x00);
607 }
608 
609 static void
610 ast_primary_plane_helper_atomic_disable(struct drm_plane *plane,
611 					struct drm_atomic_state *state)
612 {
613 	struct ast_private *ast = to_ast_private(plane->dev);
614 
615 	ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20);
616 }
617 
618 static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs = {
619 	DRM_GEM_VRAM_PLANE_HELPER_FUNCS,
620 	.atomic_check = ast_primary_plane_helper_atomic_check,
621 	.atomic_update = ast_primary_plane_helper_atomic_update,
622 	.atomic_disable = ast_primary_plane_helper_atomic_disable,
623 };
624 
625 static const struct drm_plane_funcs ast_primary_plane_funcs = {
626 	.update_plane = drm_atomic_helper_update_plane,
627 	.disable_plane = drm_atomic_helper_disable_plane,
628 	.destroy = drm_plane_cleanup,
629 	.reset = drm_atomic_helper_plane_reset,
630 	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
631 	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
632 };
633 
634 static int ast_primary_plane_init(struct ast_private *ast)
635 {
636 	struct drm_device *dev = &ast->base;
637 	struct drm_plane *primary_plane = &ast->primary_plane;
638 	int ret;
639 
640 	ret = drm_universal_plane_init(dev, primary_plane, 0x01,
641 				       &ast_primary_plane_funcs,
642 				       ast_primary_plane_formats,
643 				       ARRAY_SIZE(ast_primary_plane_formats),
644 				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
645 	if (ret) {
646 		drm_err(dev, "drm_universal_plane_init() failed: %d\n", ret);
647 		return ret;
648 	}
649 	drm_plane_helper_add(primary_plane, &ast_primary_plane_helper_funcs);
650 
651 	return 0;
652 }
653 
654 /*
655  * Cursor plane
656  */
657 
658 static void ast_update_cursor_image(u8 __iomem *dst, const u8 *src, int width, int height)
659 {
660 	union {
661 		u32 ul;
662 		u8 b[4];
663 	} srcdata32[2], data32;
664 	union {
665 		u16 us;
666 		u8 b[2];
667 	} data16;
668 	u32 csum = 0;
669 	s32 alpha_dst_delta, last_alpha_dst_delta;
670 	u8 __iomem *dstxor;
671 	const u8 *srcxor;
672 	int i, j;
673 	u32 per_pixel_copy, two_pixel_copy;
674 
675 	alpha_dst_delta = AST_MAX_HWC_WIDTH << 1;
676 	last_alpha_dst_delta = alpha_dst_delta - (width << 1);
677 
678 	srcxor = src;
679 	dstxor = (u8 *)dst + last_alpha_dst_delta + (AST_MAX_HWC_HEIGHT - height) * alpha_dst_delta;
680 	per_pixel_copy = width & 1;
681 	two_pixel_copy = width >> 1;
682 
683 	for (j = 0; j < height; j++) {
684 		for (i = 0; i < two_pixel_copy; i++) {
685 			srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0;
686 			srcdata32[1].ul = *((u32 *)(srcxor + 4)) & 0xf0f0f0f0;
687 			data32.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4);
688 			data32.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4);
689 			data32.b[2] = srcdata32[1].b[1] | (srcdata32[1].b[0] >> 4);
690 			data32.b[3] = srcdata32[1].b[3] | (srcdata32[1].b[2] >> 4);
691 
692 			writel(data32.ul, dstxor);
693 			csum += data32.ul;
694 
695 			dstxor += 4;
696 			srcxor += 8;
697 
698 		}
699 
700 		for (i = 0; i < per_pixel_copy; i++) {
701 			srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0;
702 			data16.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4);
703 			data16.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4);
704 			writew(data16.us, dstxor);
705 			csum += (u32)data16.us;
706 
707 			dstxor += 2;
708 			srcxor += 4;
709 		}
710 		dstxor += last_alpha_dst_delta;
711 	}
712 
713 	/* write checksum + signature */
714 	dst += AST_HWC_SIZE;
715 	writel(csum, dst);
716 	writel(width, dst + AST_HWC_SIGNATURE_SizeX);
717 	writel(height, dst + AST_HWC_SIGNATURE_SizeY);
718 	writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTX);
719 	writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTY);
720 }
721 
722 static void ast_set_cursor_base(struct ast_private *ast, u64 address)
723 {
724 	u8 addr0 = (address >> 3) & 0xff;
725 	u8 addr1 = (address >> 11) & 0xff;
726 	u8 addr2 = (address >> 19) & 0xff;
727 
728 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc8, addr0);
729 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc9, addr1);
730 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, addr2);
731 }
732 
733 static void ast_set_cursor_location(struct ast_private *ast, u16 x, u16 y,
734 				    u8 x_offset, u8 y_offset)
735 {
736 	u8 x0 = (x & 0x00ff);
737 	u8 x1 = (x & 0x0f00) >> 8;
738 	u8 y0 = (y & 0x00ff);
739 	u8 y1 = (y & 0x0700) >> 8;
740 
741 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc2, x_offset);
742 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc3, y_offset);
743 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc4, x0);
744 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc5, x1);
745 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc6, y0);
746 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, y1);
747 }
748 
749 static void ast_set_cursor_enabled(struct ast_private *ast, bool enabled)
750 {
751 	static const u8 mask = (u8)~(AST_IO_VGACRCB_HWC_16BPP |
752 				     AST_IO_VGACRCB_HWC_ENABLED);
753 
754 	u8 vgacrcb = AST_IO_VGACRCB_HWC_16BPP;
755 
756 	if (enabled)
757 		vgacrcb |= AST_IO_VGACRCB_HWC_ENABLED;
758 
759 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, mask, vgacrcb);
760 }
761 
762 static const uint32_t ast_cursor_plane_formats[] = {
763 	DRM_FORMAT_ARGB8888,
764 };
765 
766 static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane,
767 						struct drm_atomic_state *state)
768 {
769 	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
770 										 plane);
771 	struct drm_framebuffer *fb = new_plane_state->fb;
772 	struct drm_crtc_state *crtc_state;
773 	int ret;
774 
775 	if (!new_plane_state->crtc)
776 		return 0;
777 
778 	crtc_state = drm_atomic_get_new_crtc_state(state,
779 						   new_plane_state->crtc);
780 
781 	ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
782 						  DRM_PLANE_HELPER_NO_SCALING,
783 						  DRM_PLANE_HELPER_NO_SCALING,
784 						  true, true);
785 	if (ret)
786 		return ret;
787 
788 	if (!new_plane_state->visible)
789 		return 0;
790 
791 	if (fb->width > AST_MAX_HWC_WIDTH || fb->height > AST_MAX_HWC_HEIGHT)
792 		return -EINVAL;
793 
794 	return 0;
795 }
796 
797 static void
798 ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
799 				      struct drm_atomic_state *state)
800 {
801 	struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane);
802 	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
803 									   plane);
804 	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
805 									   plane);
806 	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(new_state);
807 	struct drm_framebuffer *fb = new_state->fb;
808 	struct ast_private *ast = to_ast_private(plane->dev);
809 	struct iosys_map dst_map =
810 		ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].map;
811 	u64 dst_off =
812 		ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].off;
813 	struct iosys_map src_map = shadow_plane_state->data[0];
814 	unsigned int offset_x, offset_y;
815 	u16 x, y;
816 	u8 x_offset, y_offset;
817 	u8 __iomem *dst;
818 	u8 __iomem *sig;
819 	const u8 *src;
820 
821 	src = src_map.vaddr; /* TODO: Use mapping abstraction properly */
822 	dst = dst_map.vaddr_iomem; /* TODO: Use mapping abstraction properly */
823 	sig = dst + AST_HWC_SIZE; /* TODO: Use mapping abstraction properly */
824 
825 	/*
826 	 * Do data transfer to HW cursor BO. If a new cursor image was installed,
827 	 * point the scanout engine to dst_gbo's offset and page-flip the HWC buffers.
828 	 */
829 
830 	ast_update_cursor_image(dst, src, fb->width, fb->height);
831 
832 	if (new_state->fb != old_state->fb) {
833 		ast_set_cursor_base(ast, dst_off);
834 
835 		++ast_cursor_plane->next_hwc_index;
836 		ast_cursor_plane->next_hwc_index %= ARRAY_SIZE(ast_cursor_plane->hwc);
837 	}
838 
839 	/*
840 	 * Update location in HWC signature and registers.
841 	 */
842 
843 	writel(new_state->crtc_x, sig + AST_HWC_SIGNATURE_X);
844 	writel(new_state->crtc_y, sig + AST_HWC_SIGNATURE_Y);
845 
846 	offset_x = AST_MAX_HWC_WIDTH - fb->width;
847 	offset_y = AST_MAX_HWC_HEIGHT - fb->height;
848 
849 	if (new_state->crtc_x < 0) {
850 		x_offset = (-new_state->crtc_x) + offset_x;
851 		x = 0;
852 	} else {
853 		x_offset = offset_x;
854 		x = new_state->crtc_x;
855 	}
856 	if (new_state->crtc_y < 0) {
857 		y_offset = (-new_state->crtc_y) + offset_y;
858 		y = 0;
859 	} else {
860 		y_offset = offset_y;
861 		y = new_state->crtc_y;
862 	}
863 
864 	ast_set_cursor_location(ast, x, y, x_offset, y_offset);
865 
866 	/* Dummy write to enable HWC and make the HW pick-up the changes. */
867 	ast_set_cursor_enabled(ast, true);
868 }
869 
870 static void
871 ast_cursor_plane_helper_atomic_disable(struct drm_plane *plane,
872 				       struct drm_atomic_state *state)
873 {
874 	struct ast_private *ast = to_ast_private(plane->dev);
875 
876 	ast_set_cursor_enabled(ast, false);
877 }
878 
879 static const struct drm_plane_helper_funcs ast_cursor_plane_helper_funcs = {
880 	DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
881 	.atomic_check = ast_cursor_plane_helper_atomic_check,
882 	.atomic_update = ast_cursor_plane_helper_atomic_update,
883 	.atomic_disable = ast_cursor_plane_helper_atomic_disable,
884 };
885 
886 static void ast_cursor_plane_destroy(struct drm_plane *plane)
887 {
888 	struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane);
889 	size_t i;
890 	struct drm_gem_vram_object *gbo;
891 	struct iosys_map map;
892 
893 	for (i = 0; i < ARRAY_SIZE(ast_cursor_plane->hwc); ++i) {
894 		gbo = ast_cursor_plane->hwc[i].gbo;
895 		map = ast_cursor_plane->hwc[i].map;
896 		drm_gem_vram_vunmap(gbo, &map);
897 		drm_gem_vram_unpin(gbo);
898 		drm_gem_vram_put(gbo);
899 	}
900 
901 	drm_plane_cleanup(plane);
902 }
903 
904 static const struct drm_plane_funcs ast_cursor_plane_funcs = {
905 	.update_plane = drm_atomic_helper_update_plane,
906 	.disable_plane = drm_atomic_helper_disable_plane,
907 	.destroy = ast_cursor_plane_destroy,
908 	DRM_GEM_SHADOW_PLANE_FUNCS,
909 };
910 
911 static int ast_cursor_plane_init(struct ast_private *ast)
912 {
913 	struct drm_device *dev = &ast->base;
914 	struct ast_cursor_plane *ast_cursor_plane = &ast->cursor_plane;
915 	struct drm_plane *cursor_plane = &ast_cursor_plane->base;
916 	size_t size, i;
917 	struct drm_gem_vram_object *gbo;
918 	struct iosys_map map;
919 	int ret;
920 	s64 off;
921 
922 	/*
923 	 * Allocate backing storage for cursors. The BOs are permanently
924 	 * pinned to the top end of the VRAM.
925 	 */
926 
927 	size = roundup(AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE, PAGE_SIZE);
928 
929 	for (i = 0; i < ARRAY_SIZE(ast_cursor_plane->hwc); ++i) {
930 		gbo = drm_gem_vram_create(dev, size, 0);
931 		if (IS_ERR(gbo)) {
932 			ret = PTR_ERR(gbo);
933 			goto err_hwc;
934 		}
935 		ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM |
936 					    DRM_GEM_VRAM_PL_FLAG_TOPDOWN);
937 		if (ret)
938 			goto err_drm_gem_vram_put;
939 		ret = drm_gem_vram_vmap(gbo, &map);
940 		if (ret)
941 			goto err_drm_gem_vram_unpin;
942 		off = drm_gem_vram_offset(gbo);
943 		if (off < 0) {
944 			ret = off;
945 			goto err_drm_gem_vram_vunmap;
946 		}
947 		ast_cursor_plane->hwc[i].gbo = gbo;
948 		ast_cursor_plane->hwc[i].map = map;
949 		ast_cursor_plane->hwc[i].off = off;
950 	}
951 
952 	/*
953 	 * Create the cursor plane. The plane's destroy callback will release
954 	 * the backing storages' BO memory.
955 	 */
956 
957 	ret = drm_universal_plane_init(dev, cursor_plane, 0x01,
958 				       &ast_cursor_plane_funcs,
959 				       ast_cursor_plane_formats,
960 				       ARRAY_SIZE(ast_cursor_plane_formats),
961 				       NULL, DRM_PLANE_TYPE_CURSOR, NULL);
962 	if (ret) {
963 		drm_err(dev, "drm_universal_plane failed(): %d\n", ret);
964 		goto err_hwc;
965 	}
966 	drm_plane_helper_add(cursor_plane, &ast_cursor_plane_helper_funcs);
967 
968 	return 0;
969 
970 err_hwc:
971 	while (i) {
972 		--i;
973 		gbo = ast_cursor_plane->hwc[i].gbo;
974 		map = ast_cursor_plane->hwc[i].map;
975 err_drm_gem_vram_vunmap:
976 		drm_gem_vram_vunmap(gbo, &map);
977 err_drm_gem_vram_unpin:
978 		drm_gem_vram_unpin(gbo);
979 err_drm_gem_vram_put:
980 		drm_gem_vram_put(gbo);
981 	}
982 	return ret;
983 }
984 
985 /*
986  * CRTC
987  */
988 
989 static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
990 {
991 	struct ast_private *ast = to_ast_private(crtc->dev);
992 	u8 ch = AST_DPMS_VSYNC_OFF | AST_DPMS_HSYNC_OFF;
993 	struct ast_crtc_state *ast_state;
994 	const struct drm_format_info *format;
995 	struct ast_vbios_mode_info *vbios_mode_info;
996 
997 	/* TODO: Maybe control display signal generation with
998 	 *       Sync Enable (bit CR17.7).
999 	 */
1000 	switch (mode) {
1001 	case DRM_MODE_DPMS_ON:
1002 		ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT,  0x01, 0xdf, 0);
1003 		ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, 0);
1004 		if (ast->tx_chip_types & AST_TX_DP501_BIT)
1005 			ast_set_dp501_video_output(crtc->dev, 1);
1006 
1007 		if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
1008 			ast_dp_power_on_off(crtc->dev, AST_DP_POWER_ON);
1009 			ast_wait_for_vretrace(ast);
1010 			ast_dp_set_on_off(crtc->dev, 1);
1011 		}
1012 
1013 		ast_state = to_ast_crtc_state(crtc->state);
1014 		format = ast_state->format;
1015 
1016 		if (format) {
1017 			vbios_mode_info = &ast_state->vbios_mode_info;
1018 
1019 			ast_set_color_reg(ast, format);
1020 			ast_set_vbios_color_reg(ast, format, vbios_mode_info);
1021 		}
1022 
1023 		ast_crtc_load_lut(ast, crtc);
1024 		break;
1025 	case DRM_MODE_DPMS_STANDBY:
1026 	case DRM_MODE_DPMS_SUSPEND:
1027 	case DRM_MODE_DPMS_OFF:
1028 		ch = mode;
1029 		if (ast->tx_chip_types & AST_TX_DP501_BIT)
1030 			ast_set_dp501_video_output(crtc->dev, 0);
1031 
1032 		if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
1033 			ast_dp_set_on_off(crtc->dev, 0);
1034 			ast_dp_power_on_off(crtc->dev, AST_DP_POWER_OFF);
1035 		}
1036 
1037 		ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT,  0x01, 0xdf, 0x20);
1038 		ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, ch);
1039 		break;
1040 	}
1041 }
1042 
1043 static enum drm_mode_status
1044 ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
1045 {
1046 	struct ast_private *ast = to_ast_private(crtc->dev);
1047 	enum drm_mode_status status;
1048 	uint32_t jtemp;
1049 
1050 	if (ast->support_wide_screen) {
1051 		if ((mode->hdisplay == 1680) && (mode->vdisplay == 1050))
1052 			return MODE_OK;
1053 		if ((mode->hdisplay == 1280) && (mode->vdisplay == 800))
1054 			return MODE_OK;
1055 		if ((mode->hdisplay == 1440) && (mode->vdisplay == 900))
1056 			return MODE_OK;
1057 		if ((mode->hdisplay == 1360) && (mode->vdisplay == 768))
1058 			return MODE_OK;
1059 		if ((mode->hdisplay == 1600) && (mode->vdisplay == 900))
1060 			return MODE_OK;
1061 
1062 		if ((ast->chip == AST2100) || (ast->chip == AST2200) ||
1063 		    (ast->chip == AST2300) || (ast->chip == AST2400) ||
1064 		    (ast->chip == AST2500) || (ast->chip == AST2600)) {
1065 			if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080))
1066 				return MODE_OK;
1067 
1068 			if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) {
1069 				jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
1070 				if (jtemp & 0x01)
1071 					return MODE_NOMODE;
1072 				else
1073 					return MODE_OK;
1074 			}
1075 		}
1076 	}
1077 
1078 	status = MODE_NOMODE;
1079 
1080 	switch (mode->hdisplay) {
1081 	case 640:
1082 		if (mode->vdisplay == 480)
1083 			status = MODE_OK;
1084 		break;
1085 	case 800:
1086 		if (mode->vdisplay == 600)
1087 			status = MODE_OK;
1088 		break;
1089 	case 1024:
1090 		if (mode->vdisplay == 768)
1091 			status = MODE_OK;
1092 		break;
1093 	case 1280:
1094 		if (mode->vdisplay == 1024)
1095 			status = MODE_OK;
1096 		break;
1097 	case 1600:
1098 		if (mode->vdisplay == 1200)
1099 			status = MODE_OK;
1100 		break;
1101 	default:
1102 		break;
1103 	}
1104 
1105 	return status;
1106 }
1107 
1108 static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc,
1109 					struct drm_atomic_state *state)
1110 {
1111 	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1112 	struct drm_device *dev = crtc->dev;
1113 	struct ast_crtc_state *ast_state;
1114 	const struct drm_format_info *format;
1115 	bool succ;
1116 	int ret;
1117 
1118 	ret = drm_atomic_helper_check_crtc_state(crtc_state, false);
1119 	if (ret)
1120 		return ret;
1121 
1122 	if (!crtc_state->enable)
1123 		goto out;
1124 
1125 	ast_state = to_ast_crtc_state(crtc_state);
1126 
1127 	format = ast_state->format;
1128 	if (drm_WARN_ON_ONCE(dev, !format))
1129 		return -EINVAL; /* BUG: We didn't set format in primary check(). */
1130 
1131 	succ = ast_get_vbios_mode_info(format, &crtc_state->mode,
1132 				       &crtc_state->adjusted_mode,
1133 				       &ast_state->vbios_mode_info);
1134 	if (!succ)
1135 		return -EINVAL;
1136 
1137 out:
1138 	return drm_atomic_add_affected_planes(state, crtc);
1139 }
1140 
1141 static void ast_crtc_helper_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state)
1142 {
1143 	struct drm_device *dev = crtc->dev;
1144 	struct ast_private *ast = to_ast_private(dev);
1145 
1146 	/*
1147 	 * Concurrent operations could possibly trigger a call to
1148 	 * drm_connector_helper_funcs.get_modes by trying to read the
1149 	 * display modes. Protect access to I/O registers by acquiring
1150 	 * the I/O-register lock. Released in atomic_flush().
1151 	 */
1152 	mutex_lock(&ast->ioregs_lock);
1153 }
1154 
1155 static void
1156 ast_crtc_helper_atomic_flush(struct drm_crtc *crtc,
1157 			     struct drm_atomic_state *state)
1158 {
1159 	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
1160 									  crtc);
1161 	struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,
1162 									      crtc);
1163 	struct drm_device *dev = crtc->dev;
1164 	struct ast_private *ast = to_ast_private(dev);
1165 	struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
1166 	struct ast_crtc_state *old_ast_crtc_state = to_ast_crtc_state(old_crtc_state);
1167 	struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info;
1168 
1169 	/*
1170 	 * The gamma LUT has to be reloaded after changing the primary
1171 	 * plane's color format.
1172 	 */
1173 	if (old_ast_crtc_state->format != ast_crtc_state->format)
1174 		ast_crtc_load_lut(ast, crtc);
1175 
1176 	//Set Aspeed Display-Port
1177 	if (ast->tx_chip_types & AST_TX_ASTDP_BIT)
1178 		ast_dp_set_mode(crtc, vbios_mode_info);
1179 
1180 	mutex_unlock(&ast->ioregs_lock);
1181 }
1182 
1183 static void
1184 ast_crtc_helper_atomic_enable(struct drm_crtc *crtc,
1185 			      struct drm_atomic_state *state)
1186 {
1187 	struct drm_device *dev = crtc->dev;
1188 	struct ast_private *ast = to_ast_private(dev);
1189 	struct drm_crtc_state *crtc_state = crtc->state;
1190 	struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
1191 	struct ast_vbios_mode_info *vbios_mode_info =
1192 		&ast_crtc_state->vbios_mode_info;
1193 	struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
1194 
1195 	ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info);
1196 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06);
1197 	ast_set_std_reg(ast, adjusted_mode, vbios_mode_info);
1198 	ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info);
1199 	ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info);
1200 	ast_set_crtthd_reg(ast);
1201 	ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info);
1202 
1203 	ast_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
1204 }
1205 
1206 static void
1207 ast_crtc_helper_atomic_disable(struct drm_crtc *crtc,
1208 			       struct drm_atomic_state *state)
1209 {
1210 	struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,
1211 									      crtc);
1212 	struct drm_device *dev = crtc->dev;
1213 	struct ast_private *ast = to_ast_private(dev);
1214 
1215 	ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
1216 
1217 	/*
1218 	 * HW cursors require the underlying primary plane and CRTC to
1219 	 * display a valid mode and image. This is not the case during
1220 	 * full modeset operations. So we temporarily disable any active
1221 	 * plane, including the HW cursor. Each plane's atomic_update()
1222 	 * helper will re-enable it if necessary.
1223 	 *
1224 	 * We only do this during *full* modesets. It does not affect
1225 	 * simple pageflips on the planes.
1226 	 */
1227 	drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false);
1228 
1229 	/*
1230 	 * Ensure that no scanout takes place before reprogramming mode
1231 	 * and format registers.
1232 	 */
1233 	ast_wait_for_vretrace(ast);
1234 }
1235 
1236 static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
1237 	.mode_valid = ast_crtc_helper_mode_valid,
1238 	.atomic_check = ast_crtc_helper_atomic_check,
1239 	.atomic_begin = ast_crtc_helper_atomic_begin,
1240 	.atomic_flush = ast_crtc_helper_atomic_flush,
1241 	.atomic_enable = ast_crtc_helper_atomic_enable,
1242 	.atomic_disable = ast_crtc_helper_atomic_disable,
1243 };
1244 
1245 static void ast_crtc_reset(struct drm_crtc *crtc)
1246 {
1247 	struct ast_crtc_state *ast_state =
1248 		kzalloc(sizeof(*ast_state), GFP_KERNEL);
1249 
1250 	if (crtc->state)
1251 		crtc->funcs->atomic_destroy_state(crtc, crtc->state);
1252 
1253 	if (ast_state)
1254 		__drm_atomic_helper_crtc_reset(crtc, &ast_state->base);
1255 	else
1256 		__drm_atomic_helper_crtc_reset(crtc, NULL);
1257 }
1258 
1259 static struct drm_crtc_state *
1260 ast_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
1261 {
1262 	struct ast_crtc_state *new_ast_state, *ast_state;
1263 	struct drm_device *dev = crtc->dev;
1264 
1265 	if (drm_WARN_ON(dev, !crtc->state))
1266 		return NULL;
1267 
1268 	new_ast_state = kmalloc(sizeof(*new_ast_state), GFP_KERNEL);
1269 	if (!new_ast_state)
1270 		return NULL;
1271 	__drm_atomic_helper_crtc_duplicate_state(crtc, &new_ast_state->base);
1272 
1273 	ast_state = to_ast_crtc_state(crtc->state);
1274 
1275 	new_ast_state->format = ast_state->format;
1276 	memcpy(&new_ast_state->vbios_mode_info, &ast_state->vbios_mode_info,
1277 	       sizeof(new_ast_state->vbios_mode_info));
1278 
1279 	return &new_ast_state->base;
1280 }
1281 
1282 static void ast_crtc_atomic_destroy_state(struct drm_crtc *crtc,
1283 					  struct drm_crtc_state *state)
1284 {
1285 	struct ast_crtc_state *ast_state = to_ast_crtc_state(state);
1286 
1287 	__drm_atomic_helper_crtc_destroy_state(&ast_state->base);
1288 	kfree(ast_state);
1289 }
1290 
1291 static const struct drm_crtc_funcs ast_crtc_funcs = {
1292 	.reset = ast_crtc_reset,
1293 	.destroy = drm_crtc_cleanup,
1294 	.set_config = drm_atomic_helper_set_config,
1295 	.page_flip = drm_atomic_helper_page_flip,
1296 	.atomic_duplicate_state = ast_crtc_atomic_duplicate_state,
1297 	.atomic_destroy_state = ast_crtc_atomic_destroy_state,
1298 };
1299 
1300 static int ast_crtc_init(struct drm_device *dev)
1301 {
1302 	struct ast_private *ast = to_ast_private(dev);
1303 	struct drm_crtc *crtc = &ast->crtc;
1304 	int ret;
1305 
1306 	ret = drm_crtc_init_with_planes(dev, crtc, &ast->primary_plane,
1307 					&ast->cursor_plane.base, &ast_crtc_funcs,
1308 					NULL);
1309 	if (ret)
1310 		return ret;
1311 
1312 	drm_mode_crtc_set_gamma_size(crtc, 256);
1313 	drm_crtc_helper_add(crtc, &ast_crtc_helper_funcs);
1314 
1315 	return 0;
1316 }
1317 
1318 /*
1319  * VGA Connector
1320  */
1321 
1322 static int ast_vga_connector_helper_get_modes(struct drm_connector *connector)
1323 {
1324 	struct ast_vga_connector *ast_vga_connector = to_ast_vga_connector(connector);
1325 	struct drm_device *dev = connector->dev;
1326 	struct ast_private *ast = to_ast_private(dev);
1327 	struct edid *edid;
1328 	int count;
1329 
1330 	if (!ast_vga_connector->i2c)
1331 		goto err_drm_connector_update_edid_property;
1332 
1333 	/*
1334 	 * Protect access to I/O registers from concurrent modesetting
1335 	 * by acquiring the I/O-register lock.
1336 	 */
1337 	mutex_lock(&ast->ioregs_lock);
1338 
1339 	edid = drm_get_edid(connector, &ast_vga_connector->i2c->adapter);
1340 	if (!edid)
1341 		goto err_mutex_unlock;
1342 
1343 	mutex_unlock(&ast->ioregs_lock);
1344 
1345 	count = drm_add_edid_modes(connector, edid);
1346 	kfree(edid);
1347 
1348 	return count;
1349 
1350 err_mutex_unlock:
1351 	mutex_unlock(&ast->ioregs_lock);
1352 err_drm_connector_update_edid_property:
1353 	drm_connector_update_edid_property(connector, NULL);
1354 	return 0;
1355 }
1356 
1357 static const struct drm_connector_helper_funcs ast_vga_connector_helper_funcs = {
1358 	.get_modes = ast_vga_connector_helper_get_modes,
1359 };
1360 
1361 static const struct drm_connector_funcs ast_vga_connector_funcs = {
1362 	.reset = drm_atomic_helper_connector_reset,
1363 	.fill_modes = drm_helper_probe_single_connector_modes,
1364 	.destroy = drm_connector_cleanup,
1365 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1366 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1367 };
1368 
1369 static int ast_vga_connector_init(struct drm_device *dev,
1370 				  struct ast_vga_connector *ast_vga_connector)
1371 {
1372 	struct drm_connector *connector = &ast_vga_connector->base;
1373 	int ret;
1374 
1375 	ast_vga_connector->i2c = ast_i2c_create(dev);
1376 	if (!ast_vga_connector->i2c)
1377 		drm_err(dev, "failed to add ddc bus for connector\n");
1378 
1379 	if (ast_vga_connector->i2c)
1380 		ret = drm_connector_init_with_ddc(dev, connector, &ast_vga_connector_funcs,
1381 						  DRM_MODE_CONNECTOR_VGA,
1382 						  &ast_vga_connector->i2c->adapter);
1383 	else
1384 		ret = drm_connector_init(dev, connector, &ast_vga_connector_funcs,
1385 					 DRM_MODE_CONNECTOR_VGA);
1386 	if (ret)
1387 		return ret;
1388 
1389 	drm_connector_helper_add(connector, &ast_vga_connector_helper_funcs);
1390 
1391 	connector->interlace_allowed = 0;
1392 	connector->doublescan_allowed = 0;
1393 
1394 	connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1395 
1396 	return 0;
1397 }
1398 
1399 static int ast_vga_output_init(struct ast_private *ast)
1400 {
1401 	struct drm_device *dev = &ast->base;
1402 	struct drm_crtc *crtc = &ast->crtc;
1403 	struct drm_encoder *encoder = &ast->output.vga.encoder;
1404 	struct ast_vga_connector *ast_vga_connector = &ast->output.vga.vga_connector;
1405 	struct drm_connector *connector = &ast_vga_connector->base;
1406 	int ret;
1407 
1408 	ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC);
1409 	if (ret)
1410 		return ret;
1411 	encoder->possible_crtcs = drm_crtc_mask(crtc);
1412 
1413 	ret = ast_vga_connector_init(dev, ast_vga_connector);
1414 	if (ret)
1415 		return ret;
1416 
1417 	ret = drm_connector_attach_encoder(connector, encoder);
1418 	if (ret)
1419 		return ret;
1420 
1421 	return 0;
1422 }
1423 
1424 /*
1425  * SIL164 Connector
1426  */
1427 
1428 static int ast_sil164_connector_helper_get_modes(struct drm_connector *connector)
1429 {
1430 	struct ast_sil164_connector *ast_sil164_connector = to_ast_sil164_connector(connector);
1431 	struct drm_device *dev = connector->dev;
1432 	struct ast_private *ast = to_ast_private(dev);
1433 	struct edid *edid;
1434 	int count;
1435 
1436 	if (!ast_sil164_connector->i2c)
1437 		goto err_drm_connector_update_edid_property;
1438 
1439 	/*
1440 	 * Protect access to I/O registers from concurrent modesetting
1441 	 * by acquiring the I/O-register lock.
1442 	 */
1443 	mutex_lock(&ast->ioregs_lock);
1444 
1445 	edid = drm_get_edid(connector, &ast_sil164_connector->i2c->adapter);
1446 	if (!edid)
1447 		goto err_mutex_unlock;
1448 
1449 	mutex_unlock(&ast->ioregs_lock);
1450 
1451 	count = drm_add_edid_modes(connector, edid);
1452 	kfree(edid);
1453 
1454 	return count;
1455 
1456 err_mutex_unlock:
1457 	mutex_unlock(&ast->ioregs_lock);
1458 err_drm_connector_update_edid_property:
1459 	drm_connector_update_edid_property(connector, NULL);
1460 	return 0;
1461 }
1462 
1463 static const struct drm_connector_helper_funcs ast_sil164_connector_helper_funcs = {
1464 	.get_modes = ast_sil164_connector_helper_get_modes,
1465 };
1466 
1467 static const struct drm_connector_funcs ast_sil164_connector_funcs = {
1468 	.reset = drm_atomic_helper_connector_reset,
1469 	.fill_modes = drm_helper_probe_single_connector_modes,
1470 	.destroy = drm_connector_cleanup,
1471 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1472 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1473 };
1474 
1475 static int ast_sil164_connector_init(struct drm_device *dev,
1476 				     struct ast_sil164_connector *ast_sil164_connector)
1477 {
1478 	struct drm_connector *connector = &ast_sil164_connector->base;
1479 	int ret;
1480 
1481 	ast_sil164_connector->i2c = ast_i2c_create(dev);
1482 	if (!ast_sil164_connector->i2c)
1483 		drm_err(dev, "failed to add ddc bus for connector\n");
1484 
1485 	if (ast_sil164_connector->i2c)
1486 		ret = drm_connector_init_with_ddc(dev, connector, &ast_sil164_connector_funcs,
1487 						  DRM_MODE_CONNECTOR_DVII,
1488 						  &ast_sil164_connector->i2c->adapter);
1489 	else
1490 		ret = drm_connector_init(dev, connector, &ast_sil164_connector_funcs,
1491 					 DRM_MODE_CONNECTOR_DVII);
1492 	if (ret)
1493 		return ret;
1494 
1495 	drm_connector_helper_add(connector, &ast_sil164_connector_helper_funcs);
1496 
1497 	connector->interlace_allowed = 0;
1498 	connector->doublescan_allowed = 0;
1499 
1500 	connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1501 
1502 	return 0;
1503 }
1504 
1505 static int ast_sil164_output_init(struct ast_private *ast)
1506 {
1507 	struct drm_device *dev = &ast->base;
1508 	struct drm_crtc *crtc = &ast->crtc;
1509 	struct drm_encoder *encoder = &ast->output.sil164.encoder;
1510 	struct ast_sil164_connector *ast_sil164_connector = &ast->output.sil164.sil164_connector;
1511 	struct drm_connector *connector = &ast_sil164_connector->base;
1512 	int ret;
1513 
1514 	ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
1515 	if (ret)
1516 		return ret;
1517 	encoder->possible_crtcs = drm_crtc_mask(crtc);
1518 
1519 	ret = ast_sil164_connector_init(dev, ast_sil164_connector);
1520 	if (ret)
1521 		return ret;
1522 
1523 	ret = drm_connector_attach_encoder(connector, encoder);
1524 	if (ret)
1525 		return ret;
1526 
1527 	return 0;
1528 }
1529 
1530 /*
1531  * DP501 Connector
1532  */
1533 
1534 static int ast_dp501_connector_helper_get_modes(struct drm_connector *connector)
1535 {
1536 	void *edid;
1537 	bool succ;
1538 	int count;
1539 
1540 	edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
1541 	if (!edid)
1542 		goto err_drm_connector_update_edid_property;
1543 
1544 	succ = ast_dp501_read_edid(connector->dev, edid);
1545 	if (!succ)
1546 		goto err_kfree;
1547 
1548 	drm_connector_update_edid_property(connector, edid);
1549 	count = drm_add_edid_modes(connector, edid);
1550 	kfree(edid);
1551 
1552 	return count;
1553 
1554 err_kfree:
1555 	kfree(edid);
1556 err_drm_connector_update_edid_property:
1557 	drm_connector_update_edid_property(connector, NULL);
1558 	return 0;
1559 }
1560 
1561 static const struct drm_connector_helper_funcs ast_dp501_connector_helper_funcs = {
1562 	.get_modes = ast_dp501_connector_helper_get_modes,
1563 };
1564 
1565 static const struct drm_connector_funcs ast_dp501_connector_funcs = {
1566 	.reset = drm_atomic_helper_connector_reset,
1567 	.fill_modes = drm_helper_probe_single_connector_modes,
1568 	.destroy = drm_connector_cleanup,
1569 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1570 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1571 };
1572 
1573 static int ast_dp501_connector_init(struct drm_device *dev, struct drm_connector *connector)
1574 {
1575 	int ret;
1576 
1577 	ret = drm_connector_init(dev, connector, &ast_dp501_connector_funcs,
1578 				 DRM_MODE_CONNECTOR_DisplayPort);
1579 	if (ret)
1580 		return ret;
1581 
1582 	drm_connector_helper_add(connector, &ast_dp501_connector_helper_funcs);
1583 
1584 	connector->interlace_allowed = 0;
1585 	connector->doublescan_allowed = 0;
1586 
1587 	connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1588 
1589 	return 0;
1590 }
1591 
1592 static int ast_dp501_output_init(struct ast_private *ast)
1593 {
1594 	struct drm_device *dev = &ast->base;
1595 	struct drm_crtc *crtc = &ast->crtc;
1596 	struct drm_encoder *encoder = &ast->output.dp501.encoder;
1597 	struct drm_connector *connector = &ast->output.dp501.connector;
1598 	int ret;
1599 
1600 	ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
1601 	if (ret)
1602 		return ret;
1603 	encoder->possible_crtcs = drm_crtc_mask(crtc);
1604 
1605 	ret = ast_dp501_connector_init(dev, connector);
1606 	if (ret)
1607 		return ret;
1608 
1609 	ret = drm_connector_attach_encoder(connector, encoder);
1610 	if (ret)
1611 		return ret;
1612 
1613 	return 0;
1614 }
1615 
1616 /*
1617  * ASPEED Display-Port Connector
1618  */
1619 
1620 static int ast_astdp_connector_helper_get_modes(struct drm_connector *connector)
1621 {
1622 	void *edid;
1623 
1624 	int succ;
1625 	int count;
1626 
1627 	edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
1628 	if (!edid)
1629 		goto err_drm_connector_update_edid_property;
1630 
1631 	succ = ast_astdp_read_edid(connector->dev, edid);
1632 	if (succ < 0)
1633 		goto err_kfree;
1634 
1635 	drm_connector_update_edid_property(connector, edid);
1636 	count = drm_add_edid_modes(connector, edid);
1637 	kfree(edid);
1638 
1639 	return count;
1640 
1641 err_kfree:
1642 	kfree(edid);
1643 err_drm_connector_update_edid_property:
1644 	drm_connector_update_edid_property(connector, NULL);
1645 	return 0;
1646 }
1647 
1648 static const struct drm_connector_helper_funcs ast_astdp_connector_helper_funcs = {
1649 	.get_modes = ast_astdp_connector_helper_get_modes,
1650 };
1651 
1652 static const struct drm_connector_funcs ast_astdp_connector_funcs = {
1653 	.reset = drm_atomic_helper_connector_reset,
1654 	.fill_modes = drm_helper_probe_single_connector_modes,
1655 	.destroy = drm_connector_cleanup,
1656 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1657 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1658 };
1659 
1660 static int ast_astdp_connector_init(struct drm_device *dev, struct drm_connector *connector)
1661 {
1662 	int ret;
1663 
1664 	ret = drm_connector_init(dev, connector, &ast_astdp_connector_funcs,
1665 				 DRM_MODE_CONNECTOR_DisplayPort);
1666 	if (ret)
1667 		return ret;
1668 
1669 	drm_connector_helper_add(connector, &ast_astdp_connector_helper_funcs);
1670 
1671 	connector->interlace_allowed = 0;
1672 	connector->doublescan_allowed = 0;
1673 
1674 	connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1675 
1676 	return 0;
1677 }
1678 
1679 static int ast_astdp_output_init(struct ast_private *ast)
1680 {
1681 	struct drm_device *dev = &ast->base;
1682 	struct drm_crtc *crtc = &ast->crtc;
1683 	struct drm_encoder *encoder = &ast->output.astdp.encoder;
1684 	struct drm_connector *connector = &ast->output.astdp.connector;
1685 	int ret;
1686 
1687 	ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
1688 	if (ret)
1689 		return ret;
1690 	encoder->possible_crtcs = drm_crtc_mask(crtc);
1691 
1692 	ret = ast_astdp_connector_init(dev, connector);
1693 	if (ret)
1694 		return ret;
1695 
1696 	ret = drm_connector_attach_encoder(connector, encoder);
1697 	if (ret)
1698 		return ret;
1699 
1700 	return 0;
1701 }
1702 
1703 /*
1704  * Mode config
1705  */
1706 
1707 static const struct drm_mode_config_helper_funcs ast_mode_config_helper_funcs = {
1708 	.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
1709 };
1710 
1711 static const struct drm_mode_config_funcs ast_mode_config_funcs = {
1712 	.fb_create = drm_gem_fb_create,
1713 	.mode_valid = drm_vram_helper_mode_valid,
1714 	.atomic_check = drm_atomic_helper_check,
1715 	.atomic_commit = drm_atomic_helper_commit,
1716 };
1717 
1718 int ast_mode_config_init(struct ast_private *ast)
1719 {
1720 	struct drm_device *dev = &ast->base;
1721 	struct pci_dev *pdev = to_pci_dev(dev->dev);
1722 	int ret;
1723 
1724 	ret = drmm_mode_config_init(dev);
1725 	if (ret)
1726 		return ret;
1727 
1728 	dev->mode_config.funcs = &ast_mode_config_funcs;
1729 	dev->mode_config.min_width = 0;
1730 	dev->mode_config.min_height = 0;
1731 	dev->mode_config.preferred_depth = 24;
1732 	dev->mode_config.prefer_shadow = 1;
1733 	dev->mode_config.fb_base = pci_resource_start(pdev, 0);
1734 
1735 	if (ast->chip == AST2100 ||
1736 	    ast->chip == AST2200 ||
1737 	    ast->chip == AST2300 ||
1738 	    ast->chip == AST2400 ||
1739 	    ast->chip == AST2500 ||
1740 	    ast->chip == AST2600) {
1741 		dev->mode_config.max_width = 1920;
1742 		dev->mode_config.max_height = 2048;
1743 	} else {
1744 		dev->mode_config.max_width = 1600;
1745 		dev->mode_config.max_height = 1200;
1746 	}
1747 
1748 	dev->mode_config.helper_private = &ast_mode_config_helper_funcs;
1749 
1750 
1751 	ret = ast_primary_plane_init(ast);
1752 	if (ret)
1753 		return ret;
1754 
1755 	ret = ast_cursor_plane_init(ast);
1756 	if (ret)
1757 		return ret;
1758 
1759 	ast_crtc_init(dev);
1760 
1761 	if (ast->tx_chip_types & AST_TX_NONE_BIT) {
1762 		ret = ast_vga_output_init(ast);
1763 		if (ret)
1764 			return ret;
1765 	}
1766 	if (ast->tx_chip_types & AST_TX_SIL164_BIT) {
1767 		ret = ast_sil164_output_init(ast);
1768 		if (ret)
1769 			return ret;
1770 	}
1771 	if (ast->tx_chip_types & AST_TX_DP501_BIT) {
1772 		ret = ast_dp501_output_init(ast);
1773 		if (ret)
1774 			return ret;
1775 	}
1776 	if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
1777 		ret = ast_astdp_output_init(ast);
1778 		if (ret)
1779 			return ret;
1780 	}
1781 
1782 	drm_mode_config_reset(dev);
1783 
1784 	return 0;
1785 }
1786