xref: /linux/drivers/gpu/drm/ast/ast_dp.c (revision 3fd6c59042dbba50391e30862beac979491145fe)
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2021, ASPEED Technology Inc.
3 // Authors: KuoHsiang Chou <kuohsiang_chou@aspeedtech.com>
4 
5 #include <linux/firmware.h>
6 #include <linux/delay.h>
7 
8 #include <drm/drm_atomic_state_helper.h>
9 #include <drm/drm_edid.h>
10 #include <drm/drm_modeset_helper_vtables.h>
11 #include <drm/drm_print.h>
12 #include <drm/drm_probe_helper.h>
13 
14 #include "ast_drv.h"
15 
ast_astdp_is_connected(struct ast_device * ast)16 static bool ast_astdp_is_connected(struct ast_device *ast)
17 {
18 	if (!ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, AST_IO_VGACRDF_HPD))
19 		return false;
20 	return true;
21 }
22 
ast_astdp_read_edid_block(void * data,u8 * buf,unsigned int block,size_t len)23 static int ast_astdp_read_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
24 {
25 	struct ast_device *ast = data;
26 	size_t rdlen = round_up(len, 4);
27 	int ret = 0;
28 	unsigned int i;
29 
30 	if (block > 0)
31 		return -EIO; /* extension headers not supported */
32 
33 	/*
34 	 * Protect access to I/O registers from concurrent modesetting
35 	 * by acquiring the I/O-register lock.
36 	 */
37 	mutex_lock(&ast->modeset_lock);
38 
39 	/* Start reading EDID data */
40 	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xe5, (u8)~AST_IO_VGACRE5_EDID_READ_DONE, 0x00);
41 
42 	for (i = 0; i < rdlen; i += 4) {
43 		unsigned int offset;
44 		unsigned int j;
45 		u8 ediddata[4];
46 		u8 vgacre4;
47 
48 		offset = (i + block * EDID_LENGTH) / 4;
49 		if (offset >= 64) {
50 			ret = -EIO;
51 			goto out;
52 		}
53 		vgacre4 = offset;
54 
55 		/*
56 		 * CRE4[7:0]: Read-Pointer for EDID (Unit: 4bytes); valid range: 0~64
57 		 */
58 		ast_set_index_reg(ast, AST_IO_VGACRI, 0xe4, vgacre4);
59 
60 		/*
61 		 * CRD7[b0]: valid flag for EDID
62 		 * CRD6[b0]: mirror read pointer for EDID
63 		 */
64 		for (j = 0; j < 200; ++j) {
65 			u8 vgacrd7, vgacrd6;
66 
67 			/*
68 			 * Delay are getting longer with each retry.
69 			 *
70 			 * 1. No delay on first try
71 			 * 2. The Delays are often 2 loops when users request "Display Settings"
72 			 *	  of right-click of mouse.
73 			 * 3. The Delays are often longer a lot when system resume from S3/S4.
74 			 */
75 			if (j)
76 				mdelay(j + 1);
77 
78 			/* Wait for EDID offset to show up in mirror register */
79 			vgacrd7 = ast_get_index_reg(ast, AST_IO_VGACRI, 0xd7);
80 			if (vgacrd7 & AST_IO_VGACRD7_EDID_VALID_FLAG) {
81 				vgacrd6 = ast_get_index_reg(ast, AST_IO_VGACRI, 0xd6);
82 				if (vgacrd6 == offset)
83 					break;
84 			}
85 		}
86 		if (j == 200) {
87 			ret = -EBUSY;
88 			goto out;
89 		}
90 
91 		ediddata[0] = ast_get_index_reg(ast, AST_IO_VGACRI, 0xd8);
92 		ediddata[1] = ast_get_index_reg(ast, AST_IO_VGACRI, 0xd9);
93 		ediddata[2] = ast_get_index_reg(ast, AST_IO_VGACRI, 0xda);
94 		ediddata[3] = ast_get_index_reg(ast, AST_IO_VGACRI, 0xdb);
95 
96 		if (i == 31) {
97 			/*
98 			 * For 128-bytes EDID_1.3,
99 			 * 1. Add the value of Bytes-126 to Bytes-127.
100 			 *		The Bytes-127 is Checksum. Sum of all 128bytes should
101 			 *		equal 0	(mod 256).
102 			 * 2. Modify Bytes-126 to be 0.
103 			 *		The Bytes-126 indicates the Number of extensions to
104 			 *		follow. 0 represents noextensions.
105 			 */
106 			ediddata[3] = ediddata[3] + ediddata[2];
107 			ediddata[2] = 0;
108 		}
109 
110 		memcpy(buf, ediddata, min((len - i), 4));
111 		buf += 4;
112 	}
113 
114 out:
115 	/* Signal end of reading */
116 	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xe5, (u8)~AST_IO_VGACRE5_EDID_READ_DONE,
117 			       AST_IO_VGACRE5_EDID_READ_DONE);
118 
119 	mutex_unlock(&ast->modeset_lock);
120 
121 	return ret;
122 }
123 
124 /*
125  * Launch Aspeed DP
126  */
ast_dp_launch(struct ast_device * ast)127 int ast_dp_launch(struct ast_device *ast)
128 {
129 	struct drm_device *dev = &ast->base;
130 	unsigned int i = 10;
131 
132 	while (i) {
133 		u8 vgacrd1 = ast_get_index_reg(ast, AST_IO_VGACRI, 0xd1);
134 
135 		if (vgacrd1 & AST_IO_VGACRD1_MCU_FW_EXECUTING)
136 			break;
137 		--i;
138 		msleep(100);
139 	}
140 	if (!i) {
141 		drm_err(dev, "Wait DPMCU executing timeout\n");
142 		return -ENODEV;
143 	}
144 
145 	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xe5,
146 			       (u8) ~AST_IO_VGACRE5_EDID_READ_DONE,
147 			       AST_IO_VGACRE5_EDID_READ_DONE);
148 
149 	return 0;
150 }
151 
ast_dp_get_phy_sleep(struct ast_device * ast)152 static bool ast_dp_get_phy_sleep(struct ast_device *ast)
153 {
154 	u8 vgacre3 = ast_get_index_reg(ast, AST_IO_VGACRI, 0xe3);
155 
156 	return (vgacre3 & AST_IO_VGACRE3_DP_PHY_SLEEP);
157 }
158 
ast_dp_set_phy_sleep(struct ast_device * ast,bool sleep)159 static void ast_dp_set_phy_sleep(struct ast_device *ast, bool sleep)
160 {
161 	u8 vgacre3 = 0x00;
162 
163 	if (sleep)
164 		vgacre3 |= AST_IO_VGACRE3_DP_PHY_SLEEP;
165 
166 	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xe3, (u8)~AST_IO_VGACRE3_DP_PHY_SLEEP,
167 			       vgacre3);
168 	msleep(50);
169 }
170 
ast_dp_link_training(struct ast_device * ast)171 static void ast_dp_link_training(struct ast_device *ast)
172 {
173 	struct drm_device *dev = &ast->base;
174 	int i;
175 
176 	for (i = 0; i < 10; i++) {
177 		u8 vgacrdc;
178 
179 		if (i)
180 			msleep(100);
181 
182 		vgacrdc = ast_get_index_reg(ast, AST_IO_VGACRI, 0xdc);
183 		if (vgacrdc & AST_IO_VGACRDC_LINK_SUCCESS)
184 			return;
185 	}
186 	drm_err(dev, "Link training failed\n");
187 }
188 
__ast_dp_wait_enable(struct ast_device * ast,bool enabled)189 static bool __ast_dp_wait_enable(struct ast_device *ast, bool enabled)
190 {
191 	u8 vgacrdf_test = 0x00;
192 	u8 vgacrdf;
193 	unsigned int i;
194 
195 	if (enabled)
196 		vgacrdf_test |= AST_IO_VGACRDF_DP_VIDEO_ENABLE;
197 
198 	for (i = 0; i < 200; ++i) {
199 		if (i)
200 			mdelay(1);
201 		vgacrdf = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xdf,
202 						 AST_IO_VGACRDF_DP_VIDEO_ENABLE);
203 		if (vgacrdf == vgacrdf_test)
204 			return true;
205 	}
206 
207 	return false;
208 }
209 
ast_dp_set_enable(struct ast_device * ast,bool enabled)210 static void ast_dp_set_enable(struct ast_device *ast, bool enabled)
211 {
212 	struct drm_device *dev = &ast->base;
213 	u8 vgacre3 = 0x00;
214 
215 	if (enabled)
216 		vgacre3 |= AST_IO_VGACRE3_DP_VIDEO_ENABLE;
217 
218 	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xe3, (u8)~AST_IO_VGACRE3_DP_VIDEO_ENABLE,
219 			       vgacre3);
220 
221 	drm_WARN_ON(dev, !__ast_dp_wait_enable(ast, enabled));
222 }
223 
ast_dp_set_mode(struct drm_crtc * crtc,struct ast_vbios_mode_info * vbios_mode)224 static void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mode)
225 {
226 	struct ast_device *ast = to_ast_device(crtc->dev);
227 
228 	u32 ulRefreshRateIndex;
229 	u8 ModeIdx;
230 
231 	ulRefreshRateIndex = vbios_mode->enh_table->refresh_rate_index - 1;
232 
233 	switch (crtc->mode.crtc_hdisplay) {
234 	case 320:
235 		ModeIdx = ASTDP_320x240_60;
236 		break;
237 	case 400:
238 		ModeIdx = ASTDP_400x300_60;
239 		break;
240 	case 512:
241 		ModeIdx = ASTDP_512x384_60;
242 		break;
243 	case 640:
244 		ModeIdx = (ASTDP_640x480_60 + (u8) ulRefreshRateIndex);
245 		break;
246 	case 800:
247 		ModeIdx = (ASTDP_800x600_56 + (u8) ulRefreshRateIndex);
248 		break;
249 	case 1024:
250 		ModeIdx = (ASTDP_1024x768_60 + (u8) ulRefreshRateIndex);
251 		break;
252 	case 1152:
253 		ModeIdx = ASTDP_1152x864_75;
254 		break;
255 	case 1280:
256 		if (crtc->mode.crtc_vdisplay == 800)
257 			ModeIdx = (ASTDP_1280x800_60_RB - (u8) ulRefreshRateIndex);
258 		else		// 1024
259 			ModeIdx = (ASTDP_1280x1024_60 + (u8) ulRefreshRateIndex);
260 		break;
261 	case 1360:
262 	case 1366:
263 		ModeIdx = ASTDP_1366x768_60;
264 		break;
265 	case 1440:
266 		ModeIdx = (ASTDP_1440x900_60_RB - (u8) ulRefreshRateIndex);
267 		break;
268 	case 1600:
269 		if (crtc->mode.crtc_vdisplay == 900)
270 			ModeIdx = (ASTDP_1600x900_60_RB - (u8) ulRefreshRateIndex);
271 		else		//1200
272 			ModeIdx = ASTDP_1600x1200_60;
273 		break;
274 	case 1680:
275 		ModeIdx = (ASTDP_1680x1050_60_RB - (u8) ulRefreshRateIndex);
276 		break;
277 	case 1920:
278 		if (crtc->mode.crtc_vdisplay == 1080)
279 			ModeIdx = ASTDP_1920x1080_60;
280 		else		//1200
281 			ModeIdx = ASTDP_1920x1200_60;
282 		break;
283 	default:
284 		return;
285 	}
286 
287 	/*
288 	 * CRE0[7:0]: MISC0 ((0x00: 18-bpp) or (0x20: 24-bpp)
289 	 * CRE1[7:0]: MISC1 (default: 0x00)
290 	 * CRE2[7:0]: video format index (0x00 ~ 0x20 or 0x40 ~ 0x50)
291 	 */
292 	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE0, ASTDP_AND_CLEAR_MASK,
293 			       ASTDP_MISC0_24bpp);
294 	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE1, ASTDP_AND_CLEAR_MASK, ASTDP_MISC1);
295 	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE2, ASTDP_AND_CLEAR_MASK, ModeIdx);
296 }
297 
ast_wait_for_vretrace(struct ast_device * ast)298 static void ast_wait_for_vretrace(struct ast_device *ast)
299 {
300 	unsigned long timeout = jiffies + HZ;
301 	u8 vgair1;
302 
303 	do {
304 		vgair1 = ast_io_read8(ast, AST_IO_VGAIR1_R);
305 	} while (!(vgair1 & AST_IO_VGAIR1_VREFRESH) && time_before(jiffies, timeout));
306 }
307 
308 /*
309  * Encoder
310  */
311 
312 static const struct drm_encoder_funcs ast_astdp_encoder_funcs = {
313 	.destroy = drm_encoder_cleanup,
314 };
315 
ast_astdp_encoder_helper_atomic_mode_set(struct drm_encoder * encoder,struct drm_crtc_state * crtc_state,struct drm_connector_state * conn_state)316 static void ast_astdp_encoder_helper_atomic_mode_set(struct drm_encoder *encoder,
317 						     struct drm_crtc_state *crtc_state,
318 						     struct drm_connector_state *conn_state)
319 {
320 	struct drm_crtc *crtc = crtc_state->crtc;
321 	struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
322 	struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info;
323 
324 	ast_dp_set_mode(crtc, vbios_mode_info);
325 }
326 
ast_astdp_encoder_helper_atomic_enable(struct drm_encoder * encoder,struct drm_atomic_state * state)327 static void ast_astdp_encoder_helper_atomic_enable(struct drm_encoder *encoder,
328 						   struct drm_atomic_state *state)
329 {
330 	struct ast_device *ast = to_ast_device(encoder->dev);
331 	struct ast_connector *ast_connector = &ast->output.astdp.connector;
332 
333 	if (ast_connector->physical_status == connector_status_connected) {
334 		ast_dp_set_phy_sleep(ast, false);
335 		ast_dp_link_training(ast);
336 
337 		ast_wait_for_vretrace(ast);
338 		ast_dp_set_enable(ast, true);
339 	}
340 }
341 
ast_astdp_encoder_helper_atomic_disable(struct drm_encoder * encoder,struct drm_atomic_state * state)342 static void ast_astdp_encoder_helper_atomic_disable(struct drm_encoder *encoder,
343 						    struct drm_atomic_state *state)
344 {
345 	struct ast_device *ast = to_ast_device(encoder->dev);
346 
347 	ast_dp_set_enable(ast, false);
348 	ast_dp_set_phy_sleep(ast, true);
349 }
350 
351 static const struct drm_encoder_helper_funcs ast_astdp_encoder_helper_funcs = {
352 	.atomic_mode_set = ast_astdp_encoder_helper_atomic_mode_set,
353 	.atomic_enable = ast_astdp_encoder_helper_atomic_enable,
354 	.atomic_disable = ast_astdp_encoder_helper_atomic_disable,
355 };
356 
357 /*
358  * Connector
359  */
360 
ast_astdp_connector_helper_get_modes(struct drm_connector * connector)361 static int ast_astdp_connector_helper_get_modes(struct drm_connector *connector)
362 {
363 	struct ast_connector *ast_connector = to_ast_connector(connector);
364 	int count;
365 
366 	if (ast_connector->physical_status == connector_status_connected) {
367 		struct ast_device *ast = to_ast_device(connector->dev);
368 		const struct drm_edid *drm_edid;
369 
370 		drm_edid = drm_edid_read_custom(connector, ast_astdp_read_edid_block, ast);
371 		drm_edid_connector_update(connector, drm_edid);
372 		count = drm_edid_connector_add_modes(connector);
373 		drm_edid_free(drm_edid);
374 	} else {
375 		drm_edid_connector_update(connector, NULL);
376 
377 		/*
378 		 * There's no EDID data without a connected monitor. Set BMC-
379 		 * compatible modes in this case. The XGA default resolution
380 		 * should work well for all BMCs.
381 		 */
382 		count = drm_add_modes_noedid(connector, 4096, 4096);
383 		if (count)
384 			drm_set_preferred_mode(connector, 1024, 768);
385 	}
386 
387 	return count;
388 }
389 
ast_astdp_connector_helper_detect_ctx(struct drm_connector * connector,struct drm_modeset_acquire_ctx * ctx,bool force)390 static int ast_astdp_connector_helper_detect_ctx(struct drm_connector *connector,
391 						 struct drm_modeset_acquire_ctx *ctx,
392 						 bool force)
393 {
394 	struct ast_connector *ast_connector = to_ast_connector(connector);
395 	struct ast_device *ast = to_ast_device(connector->dev);
396 	enum drm_connector_status status = connector_status_disconnected;
397 	bool phy_sleep;
398 
399 	mutex_lock(&ast->modeset_lock);
400 
401 	phy_sleep = ast_dp_get_phy_sleep(ast);
402 	if (phy_sleep)
403 		ast_dp_set_phy_sleep(ast, false);
404 
405 	if (ast_astdp_is_connected(ast))
406 		status = connector_status_connected;
407 
408 	if (phy_sleep && status == connector_status_disconnected)
409 		ast_dp_set_phy_sleep(ast, true);
410 
411 	mutex_unlock(&ast->modeset_lock);
412 
413 	if (status != ast_connector->physical_status)
414 		++connector->epoch_counter;
415 	ast_connector->physical_status = status;
416 
417 	return connector_status_connected;
418 }
419 
420 static const struct drm_connector_helper_funcs ast_astdp_connector_helper_funcs = {
421 	.get_modes = ast_astdp_connector_helper_get_modes,
422 	.detect_ctx = ast_astdp_connector_helper_detect_ctx,
423 };
424 
425 /*
426  * Output
427  */
428 
429 static const struct drm_connector_funcs ast_astdp_connector_funcs = {
430 	.reset = drm_atomic_helper_connector_reset,
431 	.fill_modes = drm_helper_probe_single_connector_modes,
432 	.destroy = drm_connector_cleanup,
433 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
434 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
435 };
436 
ast_astdp_output_init(struct ast_device * ast)437 int ast_astdp_output_init(struct ast_device *ast)
438 {
439 	struct drm_device *dev = &ast->base;
440 	struct drm_crtc *crtc = &ast->crtc;
441 	struct drm_encoder *encoder;
442 	struct ast_connector *ast_connector;
443 	struct drm_connector *connector;
444 	int ret;
445 
446 	/* encoder */
447 
448 	encoder = &ast->output.astdp.encoder;
449 	ret = drm_encoder_init(dev, encoder, &ast_astdp_encoder_funcs,
450 			       DRM_MODE_ENCODER_TMDS, NULL);
451 	if (ret)
452 		return ret;
453 	drm_encoder_helper_add(encoder, &ast_astdp_encoder_helper_funcs);
454 
455 	encoder->possible_crtcs = drm_crtc_mask(crtc);
456 
457 	/* connector */
458 
459 	ast_connector = &ast->output.astdp.connector;
460 	connector = &ast_connector->base;
461 	ret = drm_connector_init(dev, connector, &ast_astdp_connector_funcs,
462 				 DRM_MODE_CONNECTOR_DisplayPort);
463 	if (ret)
464 		return ret;
465 	drm_connector_helper_add(connector, &ast_astdp_connector_helper_funcs);
466 
467 	connector->interlace_allowed = 0;
468 	connector->doublescan_allowed = 0;
469 	connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
470 
471 	ast_connector->physical_status = connector->status;
472 
473 	ret = drm_connector_attach_encoder(connector, encoder);
474 	if (ret)
475 		return ret;
476 
477 	return 0;
478 }
479