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