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