ast_dp501.c revision 1.2
1/*	$NetBSD: ast_dp501.c,v 1.2 2018/08/27 04:58:23 riastradh Exp $	*/
2
3
4#include <sys/cdefs.h>
5__KERNEL_RCSID(0, "$NetBSD: ast_dp501.c,v 1.2 2018/08/27 04:58:23 riastradh Exp $");
6
7#include <linux/firmware.h>
8#include <drm/drmP.h>
9#include "ast_drv.h"
10MODULE_FIRMWARE("ast_dp501_fw.bin");
11
12int ast_load_dp501_microcode(struct drm_device *dev)
13{
14	struct ast_private *ast = dev->dev_private;
15	static char *fw_name = "ast_dp501_fw.bin";
16	int err;
17	err = request_firmware(&ast->dp501_fw, fw_name, dev->dev);
18	if (err)
19		return err;
20
21	return 0;
22}
23
24static void send_ack(struct ast_private *ast)
25{
26	u8 sendack;
27	sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff);
28	sendack |= 0x80;
29	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack);
30}
31
32static void send_nack(struct ast_private *ast)
33{
34	u8 sendack;
35	sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff);
36	sendack &= ~0x80;
37	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack);
38}
39
40static bool wait_ack(struct ast_private *ast)
41{
42	u8 waitack;
43	u32 retry = 0;
44	do {
45		waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff);
46		waitack &= 0x80;
47		udelay(100);
48	} while ((!waitack) && (retry++ < 1000));
49
50	if (retry < 1000)
51		return true;
52	else
53		return false;
54}
55
56static bool wait_nack(struct ast_private *ast)
57{
58	u8 waitack;
59	u32 retry = 0;
60	do {
61		waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff);
62		waitack &= 0x80;
63		udelay(100);
64	} while ((waitack) && (retry++ < 1000));
65
66	if (retry < 1000)
67		return true;
68	else
69		return false;
70}
71
72static void set_cmd_trigger(struct ast_private *ast)
73{
74	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x40);
75}
76
77static void clear_cmd_trigger(struct ast_private *ast)
78{
79	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x00);
80}
81
82#if 0
83static bool wait_fw_ready(struct ast_private *ast)
84{
85	u8 waitready;
86	u32 retry = 0;
87	do {
88		waitready = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff);
89		waitready &= 0x40;
90		udelay(100);
91	} while ((!waitready) && (retry++ < 1000));
92
93	if (retry < 1000)
94		return true;
95	else
96		return false;
97}
98#endif
99
100static bool ast_write_cmd(struct drm_device *dev, u8 data)
101{
102	struct ast_private *ast = dev->dev_private;
103	int retry = 0;
104	if (wait_nack(ast)) {
105		send_nack(ast);
106		ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data);
107		send_ack(ast);
108		set_cmd_trigger(ast);
109		do {
110			if (wait_ack(ast)) {
111				clear_cmd_trigger(ast);
112				send_nack(ast);
113				return true;
114			}
115		} while (retry++ < 100);
116	}
117	clear_cmd_trigger(ast);
118	send_nack(ast);
119	return false;
120}
121
122static bool ast_write_data(struct drm_device *dev, u8 data)
123{
124	struct ast_private *ast = dev->dev_private;
125
126	if (wait_nack(ast)) {
127		send_nack(ast);
128		ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data);
129		send_ack(ast);
130		if (wait_ack(ast)) {
131			send_nack(ast);
132			return true;
133		}
134	}
135	send_nack(ast);
136	return false;
137}
138
139#if 0
140static bool ast_read_data(struct drm_device *dev, u8 *data)
141{
142	struct ast_private *ast = dev->dev_private;
143	u8 tmp;
144
145	*data = 0;
146
147	if (wait_ack(ast) == false)
148		return false;
149	tmp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd3, 0xff);
150	*data = tmp;
151	if (wait_nack(ast) == false) {
152		send_nack(ast);
153		return false;
154	}
155	send_nack(ast);
156	return true;
157}
158
159static void clear_cmd(struct ast_private *ast)
160{
161	send_nack(ast);
162	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, 0x00);
163}
164#endif
165
166void ast_set_dp501_video_output(struct drm_device *dev, u8 mode)
167{
168	ast_write_cmd(dev, 0x40);
169	ast_write_data(dev, mode);
170
171	msleep(10);
172}
173
174static u32 get_fw_base(struct ast_private *ast)
175{
176	return ast_mindwm(ast, 0x1e6e2104) & 0x7fffffff;
177}
178
179bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size)
180{
181	struct ast_private *ast = dev->dev_private;
182	u32 i, data;
183	u32 boot_address;
184
185	data = ast_mindwm(ast, 0x1e6e2100) & 0x01;
186	if (data) {
187		boot_address = get_fw_base(ast);
188		for (i = 0; i < size; i += 4)
189			*(u32 *)(addr + i) = ast_mindwm(ast, boot_address + i);
190		return true;
191	}
192	return false;
193}
194
195bool ast_launch_m68k(struct drm_device *dev)
196{
197	struct ast_private *ast = dev->dev_private;
198	u32 i, data, len = 0;
199	u32 boot_address;
200	u8 *fw_addr = NULL;
201	u8 jreg;
202
203	data = ast_mindwm(ast, 0x1e6e2100) & 0x01;
204	if (!data) {
205
206		if (ast->dp501_fw_addr) {
207			fw_addr = ast->dp501_fw_addr;
208			len = 32*1024;
209		} else if (ast->dp501_fw) {
210			fw_addr = (u8 *)ast->dp501_fw->data;
211			len = ast->dp501_fw->size;
212		}
213		/* Get BootAddress */
214		ast_moutdwm(ast, 0x1e6e2000, 0x1688a8a8);
215		data = ast_mindwm(ast, 0x1e6e0004);
216		switch (data & 0x03) {
217		case 0:
218			boot_address = 0x44000000;
219			break;
220		default:
221		case 1:
222			boot_address = 0x48000000;
223			break;
224		case 2:
225			boot_address = 0x50000000;
226			break;
227		case 3:
228			boot_address = 0x60000000;
229			break;
230		}
231		boot_address -= 0x200000; /* -2MB */
232
233		/* copy image to buffer */
234		for (i = 0; i < len; i += 4) {
235			data = *(u32 *)(fw_addr + i);
236			ast_moutdwm(ast, boot_address + i, data);
237		}
238
239		/* Init SCU */
240		ast_moutdwm(ast, 0x1e6e2000, 0x1688a8a8);
241
242		/* Launch FW */
243		ast_moutdwm(ast, 0x1e6e2104, 0x80000000 + boot_address);
244		ast_moutdwm(ast, 0x1e6e2100, 1);
245
246		/* Update Scratch */
247		data = ast_mindwm(ast, 0x1e6e2040) & 0xfffff1ff;		/* D[11:9] = 100b: UEFI handling */
248		data |= 0x800;
249		ast_moutdwm(ast, 0x1e6e2040, data);
250
251		jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xfc); /* D[1:0]: Reserved Video Buffer */
252		jreg |= 0x02;
253		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x99, jreg);
254	}
255	return true;
256}
257
258u8 ast_get_dp501_max_clk(struct drm_device *dev)
259{
260	struct ast_private *ast = dev->dev_private;
261	u32 boot_address, offset, data;
262	u8 linkcap[4], linkrate, linklanes, maxclk = 0xff;
263
264	boot_address = get_fw_base(ast);
265
266	/* validate FW version */
267	offset = 0xf000;
268	data = ast_mindwm(ast, boot_address + offset);
269	if ((data & 0xf0) != 0x10) /* version: 1x */
270		return maxclk;
271
272	/* Read Link Capability */
273	offset  = 0xf014;
274	*(u32 *)linkcap = ast_mindwm(ast, boot_address + offset);
275	if (linkcap[2] == 0) {
276		linkrate = linkcap[0];
277		linklanes = linkcap[1];
278		data = (linkrate == 0x0a) ? (90 * linklanes) : (54 * linklanes);
279		if (data > 0xff)
280			data = 0xff;
281		maxclk = (u8)data;
282	}
283	return maxclk;
284}
285
286bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata)
287{
288	struct ast_private *ast = dev->dev_private;
289	u32 i, boot_address, offset, data;
290
291	boot_address = get_fw_base(ast);
292
293	/* validate FW version */
294	offset = 0xf000;
295	data = ast_mindwm(ast, boot_address + offset);
296	if ((data & 0xf0) != 0x10)
297		return false;
298
299	/* validate PnP Monitor */
300	offset = 0xf010;
301	data = ast_mindwm(ast, boot_address + offset);
302	if (!(data & 0x01))
303		return false;
304
305	/* Read EDID */
306	offset = 0xf020;
307	for (i = 0; i < 128; i += 4) {
308		data = ast_mindwm(ast, boot_address + offset + i);
309		*(u32 *)(ediddata + i) = data;
310	}
311
312	return true;
313}
314
315static bool ast_init_dvo(struct drm_device *dev)
316{
317	struct ast_private *ast = dev->dev_private;
318	u8 jreg;
319	u32 data;
320	ast_write32(ast, 0xf004, 0x1e6e0000);
321	ast_write32(ast, 0xf000, 0x1);
322	ast_write32(ast, 0x12000, 0x1688a8a8);
323
324	jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
325	if (!(jreg & 0x80)) {
326		/* Init SCU DVO Settings */
327		data = ast_read32(ast, 0x12008);
328		/* delay phase */
329		data &= 0xfffff8ff;
330		data |= 0x00000500;
331		ast_write32(ast, 0x12008, data);
332
333		if (ast->chip == AST2300) {
334			data = ast_read32(ast, 0x12084);
335			/* multi-pins for DVO single-edge */
336			data |= 0xfffe0000;
337			ast_write32(ast, 0x12084, data);
338
339			data = ast_read32(ast, 0x12088);
340			/* multi-pins for DVO single-edge */
341			data |= 0x000fffff;
342			ast_write32(ast, 0x12088, data);
343
344			data = ast_read32(ast, 0x12090);
345			/* multi-pins for DVO single-edge */
346			data &= 0xffffffcf;
347			data |= 0x00000020;
348			ast_write32(ast, 0x12090, data);
349		} else { /* AST2400 */
350			data = ast_read32(ast, 0x12088);
351			/* multi-pins for DVO single-edge */
352			data |= 0x30000000;
353			ast_write32(ast, 0x12088, data);
354
355			data = ast_read32(ast, 0x1208c);
356			/* multi-pins for DVO single-edge */
357			data |= 0x000000cf;
358			ast_write32(ast, 0x1208c, data);
359
360			data = ast_read32(ast, 0x120a4);
361			/* multi-pins for DVO single-edge */
362			data |= 0xffff0000;
363			ast_write32(ast, 0x120a4, data);
364
365			data = ast_read32(ast, 0x120a8);
366			/* multi-pins for DVO single-edge */
367			data |= 0x0000000f;
368			ast_write32(ast, 0x120a8, data);
369
370			data = ast_read32(ast, 0x12094);
371			/* multi-pins for DVO single-edge */
372			data |= 0x00000002;
373			ast_write32(ast, 0x12094, data);
374		}
375	}
376
377	/* Force to DVO */
378	data = ast_read32(ast, 0x1202c);
379	data &= 0xfffbffff;
380	ast_write32(ast, 0x1202c, data);
381
382	/* Init VGA DVO Settings */
383	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80);
384	return true;
385}
386
387
388static void ast_init_analog(struct drm_device *dev)
389{
390	struct ast_private *ast = dev->dev_private;
391	u32 data;
392
393	/*
394	 * Set DAC source to VGA mode in SCU2C via the P2A
395	 * bridge. First configure the P2U to target the SCU
396	 * in case it isn't at this stage.
397	 */
398	ast_write32(ast, 0xf004, 0x1e6e0000);
399	ast_write32(ast, 0xf000, 0x1);
400
401	/* Then unlock the SCU with the magic password */
402	ast_write32(ast, 0x12000, 0x1688a8a8);
403	ast_write32(ast, 0x12000, 0x1688a8a8);
404	ast_write32(ast, 0x12000, 0x1688a8a8);
405
406	/* Finally, clear bits [17:16] of SCU2c */
407	data = ast_read32(ast, 0x1202c);
408	data &= 0xfffcffff;
409	ast_write32(ast, 0, data);
410
411	/* Disable DVO */
412	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x00);
413}
414
415void ast_init_3rdtx(struct drm_device *dev)
416{
417	struct ast_private *ast = dev->dev_private;
418	u8 jreg;
419
420	if (ast->chip == AST2300 || ast->chip == AST2400) {
421		jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
422		switch (jreg & 0x0e) {
423		case 0x04:
424			ast_init_dvo(dev);
425			break;
426		case 0x08:
427			ast_launch_m68k(dev);
428			break;
429		case 0x0c:
430			ast_init_dvo(dev);
431			break;
432		default:
433			if (ast->tx_chip_type == AST_TX_SIL164)
434				ast_init_dvo(dev);
435			else
436				ast_init_analog(dev);
437		}
438	}
439}
440