soc/intel/alderlake: Add ADL-P 4+4 with 28W TDP
[coreboot.git] / src / drivers / aspeed / common / ast_dp501.c
blobba0833ca1ad86d98b5033fa161c973834f374922
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 /*
4 * File taken from the Linux ast driver (v3.18.5)
5 * coreboot-specific includes added at top and/or contents modified
6 * as needed to function within the coreboot environment.
7 */
9 #include <delay.h>
11 #include "ast_drv.h"
13 static void send_ack(struct ast_private *ast)
15 u8 sendack;
16 sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff);
17 sendack |= 0x80;
18 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack);
21 static void send_nack(struct ast_private *ast)
23 u8 sendack;
24 sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff);
25 sendack &= ~0x80;
26 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack);
29 static bool wait_ack(struct ast_private *ast)
31 u8 waitack;
32 u32 retry = 0;
33 do {
34 waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff);
35 waitack &= 0x80;
36 udelay(100);
37 } while ((!waitack) && (retry++ < 1000));
39 if (retry < 1000)
40 return true;
41 else
42 return false;
45 static bool wait_nack(struct ast_private *ast)
47 u8 waitack;
48 u32 retry = 0;
49 do {
50 waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff);
51 waitack &= 0x80;
52 udelay(100);
53 } while ((waitack) && (retry++ < 1000));
55 if (retry < 1000)
56 return true;
57 else
58 return false;
61 static void set_cmd_trigger(struct ast_private *ast)
63 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x40);
66 static void clear_cmd_trigger(struct ast_private *ast)
68 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x00);
71 static bool ast_write_cmd(struct drm_device *dev, u8 data)
73 struct ast_private *ast = dev->dev_private;
74 int retry = 0;
75 if (wait_nack(ast)) {
76 send_nack(ast);
77 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data);
78 send_ack(ast);
79 set_cmd_trigger(ast);
80 do {
81 if (wait_ack(ast)) {
82 clear_cmd_trigger(ast);
83 send_nack(ast);
84 return true;
86 } while (retry++ < 100);
88 clear_cmd_trigger(ast);
89 send_nack(ast);
90 return false;
93 static bool ast_write_data(struct drm_device *dev, u8 data)
95 struct ast_private *ast = dev->dev_private;
97 if (wait_nack(ast)) {
98 send_nack(ast);
99 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data);
100 send_ack(ast);
101 if (wait_ack(ast)) {
102 send_nack(ast);
103 return true;
106 send_nack(ast);
107 return false;
110 void ast_set_dp501_video_output(struct drm_device *dev, u8 mode)
112 ast_write_cmd(dev, 0x40);
113 ast_write_data(dev, mode);
115 msleep(10);
118 static u32 get_fw_base(struct ast_private *ast)
120 return ast_mindwm(ast, 0x1e6e2104) & 0x7fffffff;
123 bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size)
125 struct ast_private *ast = dev->dev_private;
126 u32 i, data;
127 u32 boot_address;
129 data = ast_mindwm(ast, 0x1e6e2100) & 0x01;
130 if (data) {
131 boot_address = get_fw_base(ast);
132 for (i = 0; i < size; i += 4)
133 *(u32 *)(addr + i) = ast_mindwm(ast, boot_address + i);
134 return true;
136 return false;
139 static bool ast_launch_m68k(struct drm_device *dev)
141 struct ast_private *ast = dev->dev_private;
142 u32 i, data, len = 0;
143 u32 boot_address;
144 u8 *fw_addr = NULL;
145 u8 jreg;
147 data = ast_mindwm(ast, 0x1e6e2100) & 0x01;
148 if (!data) {
149 if (ast->dp501_fw_addr) {
150 fw_addr = ast->dp501_fw_addr;
151 len = 32*1024;
152 } else {
153 if (!ast->dp501_fw)
154 return false;
156 fw_addr = (u8 *)ast->dp501_fw->data;
157 len = ast->dp501_fw->size;
159 /* Get BootAddress */
160 ast_moutdwm(ast, 0x1e6e2000, 0x1688a8a8);
161 data = ast_mindwm(ast, 0x1e6e0004);
162 switch (data & 0x03) {
163 case 0:
164 boot_address = 0x44000000;
165 break;
166 default:
167 case 1:
168 boot_address = 0x48000000;
169 break;
170 case 2:
171 boot_address = 0x50000000;
172 break;
173 case 3:
174 boot_address = 0x60000000;
175 break;
177 boot_address -= 0x200000; /* -2MB */
179 /* copy image to buffer */
180 for (i = 0; i < len; i += 4) {
181 data = *(u32 *)(fw_addr + i);
182 ast_moutdwm(ast, boot_address + i, data);
185 /* Init SCU */
186 ast_moutdwm(ast, 0x1e6e2000, 0x1688a8a8);
188 /* Launch FW */
189 ast_moutdwm(ast, 0x1e6e2104, 0x80000000 + boot_address);
190 ast_moutdwm(ast, 0x1e6e2100, 1);
192 /* Update Scratch */
193 data = ast_mindwm(ast, 0x1e6e2040) & 0xfffff1ff; /* D[11:9] = 100b: UEFI handling */
194 data |= 0x800;
195 ast_moutdwm(ast, 0x1e6e2040, data);
197 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xfc); /* D[1:0]: Reserved Video Buffer */
198 jreg |= 0x02;
199 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x99, jreg);
201 return true;
204 u8 ast_get_dp501_max_clk(struct drm_device *dev)
206 struct ast_private *ast = dev->dev_private;
207 u32 boot_address, offset, data;
208 u8 linkcap[4], linkrate, linklanes, maxclk = 0xff;
210 boot_address = get_fw_base(ast);
212 /* validate FW version */
213 offset = 0xf000;
214 data = ast_mindwm(ast, boot_address + offset);
215 if ((data & 0xf0) != 0x10) /* version: 1x */
216 return maxclk;
218 /* Read Link Capability */
219 offset = 0xf014;
220 *(u32 *)linkcap = ast_mindwm(ast, boot_address + offset);
221 if (linkcap[2] == 0) {
222 linkrate = linkcap[0];
223 linklanes = linkcap[1];
224 data = (linkrate == 0x0a) ? (90 * linklanes) : (54 * linklanes);
225 if (data > 0xff)
226 data = 0xff;
227 maxclk = (u8)data;
229 return maxclk;
232 bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata)
234 struct ast_private *ast = dev->dev_private;
235 u32 i, boot_address, offset, data;
237 boot_address = get_fw_base(ast);
239 /* validate FW version */
240 offset = 0xf000;
241 data = ast_mindwm(ast, boot_address + offset);
242 if ((data & 0xf0) != 0x10)
243 return false;
245 /* validate PnP Monitor */
246 offset = 0xf010;
247 data = ast_mindwm(ast, boot_address + offset);
248 if (!(data & 0x01))
249 return false;
251 /* Read EDID */
252 offset = 0xf020;
253 for (i = 0; i < 128; i += 4) {
254 data = ast_mindwm(ast, boot_address + offset + i);
255 *(u32 *)(ediddata + i) = data;
258 return true;
261 static bool ast_init_dvo(struct drm_device *dev)
263 struct ast_private *ast = dev->dev_private;
264 u8 jreg;
265 u32 data;
266 ast_write32(ast, 0xf004, 0x1e6e0000);
267 ast_write32(ast, 0xf000, 0x1);
268 ast_write32(ast, 0x12000, 0x1688a8a8);
270 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
271 if (!(jreg & 0x80)) {
272 /* Init SCU DVO Settings */
273 data = ast_read32(ast, 0x12008);
274 /* delay phase */
275 data &= 0xfffff8ff;
276 data |= 0x00000500;
277 ast_write32(ast, 0x12008, data);
279 if (ast->chip == AST2300) {
280 data = ast_read32(ast, 0x12084);
281 /* multi-pins for DVO single-edge */
282 data |= 0xfffe0000;
283 ast_write32(ast, 0x12084, data);
285 data = ast_read32(ast, 0x12088);
286 /* multi-pins for DVO single-edge */
287 data |= 0x000fffff;
288 ast_write32(ast, 0x12088, data);
290 data = ast_read32(ast, 0x12090);
291 /* multi-pins for DVO single-edge */
292 data &= 0xffffffcf;
293 data |= 0x00000020;
294 ast_write32(ast, 0x12090, data);
295 } else { /* AST2400 */
296 data = ast_read32(ast, 0x12088);
297 /* multi-pins for DVO single-edge */
298 data |= 0x30000000;
299 ast_write32(ast, 0x12088, data);
301 data = ast_read32(ast, 0x1208c);
302 /* multi-pins for DVO single-edge */
303 data |= 0x000000cf;
304 ast_write32(ast, 0x1208c, data);
306 data = ast_read32(ast, 0x120a4);
307 /* multi-pins for DVO single-edge */
308 data |= 0xffff0000;
309 ast_write32(ast, 0x120a4, data);
311 data = ast_read32(ast, 0x120a8);
312 /* multi-pins for DVO single-edge */
313 data |= 0x0000000f;
314 ast_write32(ast, 0x120a8, data);
316 data = ast_read32(ast, 0x12094);
317 /* multi-pins for DVO single-edge */
318 data |= 0x00000002;
319 ast_write32(ast, 0x12094, data);
323 /* Force to DVO */
324 data = ast_read32(ast, 0x1202c);
325 data &= 0xfffbffff;
326 ast_write32(ast, 0x1202c, data);
328 /* Init VGA DVO Settings */
329 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80);
330 return true;
333 static void ast_init_analog(struct drm_device *dev)
335 struct ast_private *ast = dev->dev_private;
336 u32 data;
339 * Set DAC source to VGA mode in SCU2C via the P2A
340 * bridge. First configure the P2U to target the SCU
341 * in case it isn't at this stage.
343 ast_write32(ast, 0xf004, 0x1e6e0000);
344 ast_write32(ast, 0xf000, 0x1);
346 /* Then unlock the SCU with the magic password */
347 ast_write32(ast, 0x12000, 0x1688a8a8);
348 ast_write32(ast, 0x12000, 0x1688a8a8);
349 ast_write32(ast, 0x12000, 0x1688a8a8);
351 /* Finally, clear bits [17:16] of SCU2c */
352 data = ast_read32(ast, 0x1202c);
353 data &= 0xfffcffff;
354 ast_write32(ast, 0, data);
356 /* Disable DVO */
357 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x00);
360 void ast_init_3rdtx(struct drm_device *dev)
362 struct ast_private *ast = dev->dev_private;
363 u8 jreg;
365 if (ast->chip == AST2300 || ast->chip == AST2400) {
366 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
367 switch (jreg & 0x0e) {
368 case 0x04:
369 ast_init_dvo(dev);
370 break;
371 case 0x08:
372 ast_launch_m68k(dev);
373 break;
374 case 0x0c:
375 ast_init_dvo(dev);
376 break;
377 default:
378 if (ast->tx_chip_type == AST_TX_SIL164)
379 ast_init_dvo(dev);
380 else
381 ast_init_analog(dev);