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 #include <drm/drm_print.h>
8 #include "ast_drv.h"
9
ast_astdp_read_edid(struct drm_device * dev,u8 * ediddata)10 int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
11 {
12 struct ast_private *ast = to_ast_private(dev);
13 u8 i = 0, j = 0;
14
15 /*
16 * CRD1[b5]: DP MCU FW is executing
17 * CRDC[b0]: DP link success
18 * CRDF[b0]: DP HPD
19 * CRE5[b0]: Host reading EDID process is done
20 */
21 if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING) &&
22 ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS) &&
23 ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD) &&
24 ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5,
25 ASTDP_HOST_EDID_READ_DONE_MASK))) {
26 goto err_astdp_edid_not_ready;
27 }
28
29 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
30 0x00);
31
32 for (i = 0; i < 32; i++) {
33 /*
34 * CRE4[7:0]: Read-Pointer for EDID (Unit: 4bytes); valid range: 0~64
35 */
36 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE4,
37 ASTDP_AND_CLEAR_MASK, (u8)i);
38 j = 0;
39
40 /*
41 * CRD7[b0]: valid flag for EDID
42 * CRD6[b0]: mirror read pointer for EDID
43 */
44 while ((ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD7,
45 ASTDP_EDID_VALID_FLAG_MASK) != 0x01) ||
46 (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD6,
47 ASTDP_EDID_READ_POINTER_MASK) != i)) {
48 /*
49 * Delay are getting longer with each retry.
50 * 1. The Delays are often 2 loops when users request "Display Settings"
51 * of right-click of mouse.
52 * 2. The Delays are often longer a lot when system resume from S3/S4.
53 */
54 mdelay(j+1);
55
56 if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1,
57 ASTDP_MCU_FW_EXECUTING) &&
58 ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC,
59 ASTDP_LINK_SUCCESS) &&
60 ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD))) {
61 goto err_astdp_jump_out_loop_of_edid;
62 }
63
64 j++;
65 if (j > 200)
66 goto err_astdp_jump_out_loop_of_edid;
67 }
68
69 *(ediddata) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT,
70 0xD8, ASTDP_EDID_READ_DATA_MASK);
71 *(ediddata + 1) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD9,
72 ASTDP_EDID_READ_DATA_MASK);
73 *(ediddata + 2) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDA,
74 ASTDP_EDID_READ_DATA_MASK);
75 *(ediddata + 3) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDB,
76 ASTDP_EDID_READ_DATA_MASK);
77
78 if (i == 31) {
79 /*
80 * For 128-bytes EDID_1.3,
81 * 1. Add the value of Bytes-126 to Bytes-127.
82 * The Bytes-127 is Checksum. Sum of all 128bytes should
83 * equal 0 (mod 256).
84 * 2. Modify Bytes-126 to be 0.
85 * The Bytes-126 indicates the Number of extensions to
86 * follow. 0 represents noextensions.
87 */
88 *(ediddata + 3) = *(ediddata + 3) + *(ediddata + 2);
89 *(ediddata + 2) = 0;
90 }
91
92 ediddata += 4;
93 }
94
95 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
96 ASTDP_HOST_EDID_READ_DONE);
97
98 return 0;
99
100 err_astdp_jump_out_loop_of_edid:
101 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5,
102 (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
103 ASTDP_HOST_EDID_READ_DONE);
104 return (~(j+256) + 1);
105
106 err_astdp_edid_not_ready:
107 if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING)))
108 return (~0xD1 + 1);
109 if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS)))
110 return (~0xDC + 1);
111 if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD)))
112 return (~0xDF + 1);
113 if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, ASTDP_HOST_EDID_READ_DONE_MASK)))
114 return (~0xE5 + 1);
115
116 return 0;
117 }
118
119 /*
120 * Launch Aspeed DP
121 */
ast_dp_launch(struct drm_device * dev,u8 bPower)122 void ast_dp_launch(struct drm_device *dev, u8 bPower)
123 {
124 u32 i = 0, j = 0, WaitCount = 1;
125 u8 bDPTX = 0;
126 u8 bDPExecute = 1;
127
128 struct ast_private *ast = to_ast_private(dev);
129 // S3 come back, need more time to wait BMC ready.
130 if (bPower)
131 WaitCount = 300;
132
133
134 // Wait total count by different condition.
135 for (j = 0; j < WaitCount; j++) {
136 bDPTX = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, TX_TYPE_MASK);
137
138 if (bDPTX)
139 break;
140
141 msleep(100);
142 }
143
144 // 0xE : ASTDP with DPMCU FW handling
145 if (bDPTX == ASTDP_DPMCU_TX) {
146 // Wait one second then timeout.
147 i = 0;
148
149 while (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, COPROCESSOR_LAUNCH) !=
150 COPROCESSOR_LAUNCH) {
151 i++;
152 // wait 100 ms
153 msleep(100);
154
155 if (i >= 10) {
156 // DP would not be ready.
157 bDPExecute = 0;
158 break;
159 }
160 }
161
162 if (bDPExecute)
163 ast->tx_chip_types |= BIT(AST_TX_ASTDP);
164
165 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5,
166 (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
167 ASTDP_HOST_EDID_READ_DONE);
168 }
169 }
170
171
172
ast_dp_power_on_off(struct drm_device * dev,bool on)173 void ast_dp_power_on_off(struct drm_device *dev, bool on)
174 {
175 struct ast_private *ast = to_ast_private(dev);
176 // Read and Turn off DP PHY sleep
177 u8 bE3 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, AST_DP_VIDEO_ENABLE);
178
179 // Turn on DP PHY sleep
180 if (!on)
181 bE3 |= AST_DP_PHY_SLEEP;
182
183 // DP Power on/off
184 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, (u8) ~AST_DP_PHY_SLEEP, bE3);
185 }
186
187
188
ast_dp_set_on_off(struct drm_device * dev,bool on)189 void ast_dp_set_on_off(struct drm_device *dev, bool on)
190 {
191 struct ast_private *ast = to_ast_private(dev);
192 u8 video_on_off = on;
193
194 // Video On/Off
195 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, (u8) ~AST_DP_VIDEO_ENABLE, on);
196
197 // If DP plug in and link successful then check video on / off status
198 if (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS) &&
199 ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD)) {
200 video_on_off <<= 4;
201 while (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF,
202 ASTDP_MIRROR_VIDEO_ENABLE) != video_on_off) {
203 // wait 1 ms
204 mdelay(1);
205 }
206 }
207 }
208
ast_dp_set_mode(struct drm_crtc * crtc,struct ast_vbios_mode_info * vbios_mode)209 void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mode)
210 {
211 struct ast_private *ast = to_ast_private(crtc->dev);
212
213 u32 ulRefreshRateIndex;
214 u8 ModeIdx;
215
216 ulRefreshRateIndex = vbios_mode->enh_table->refresh_rate_index - 1;
217
218 switch (crtc->mode.crtc_hdisplay) {
219 case 320:
220 ModeIdx = ASTDP_320x240_60;
221 break;
222 case 400:
223 ModeIdx = ASTDP_400x300_60;
224 break;
225 case 512:
226 ModeIdx = ASTDP_512x384_60;
227 break;
228 case 640:
229 ModeIdx = (ASTDP_640x480_60 + (u8) ulRefreshRateIndex);
230 break;
231 case 800:
232 ModeIdx = (ASTDP_800x600_56 + (u8) ulRefreshRateIndex);
233 break;
234 case 1024:
235 ModeIdx = (ASTDP_1024x768_60 + (u8) ulRefreshRateIndex);
236 break;
237 case 1152:
238 ModeIdx = ASTDP_1152x864_75;
239 break;
240 case 1280:
241 if (crtc->mode.crtc_vdisplay == 800)
242 ModeIdx = (ASTDP_1280x800_60_RB - (u8) ulRefreshRateIndex);
243 else // 1024
244 ModeIdx = (ASTDP_1280x1024_60 + (u8) ulRefreshRateIndex);
245 break;
246 case 1360:
247 case 1366:
248 ModeIdx = ASTDP_1366x768_60;
249 break;
250 case 1440:
251 ModeIdx = (ASTDP_1440x900_60_RB - (u8) ulRefreshRateIndex);
252 break;
253 case 1600:
254 if (crtc->mode.crtc_vdisplay == 900)
255 ModeIdx = (ASTDP_1600x900_60_RB - (u8) ulRefreshRateIndex);
256 else //1200
257 ModeIdx = ASTDP_1600x1200_60;
258 break;
259 case 1680:
260 ModeIdx = (ASTDP_1680x1050_60_RB - (u8) ulRefreshRateIndex);
261 break;
262 case 1920:
263 if (crtc->mode.crtc_vdisplay == 1080)
264 ModeIdx = ASTDP_1920x1080_60;
265 else //1200
266 ModeIdx = ASTDP_1920x1200_60;
267 break;
268 default:
269 return;
270 }
271
272 /*
273 * CRE0[7:0]: MISC0 ((0x00: 18-bpp) or (0x20: 24-bpp)
274 * CRE1[7:0]: MISC1 (default: 0x00)
275 * CRE2[7:0]: video format index (0x00 ~ 0x20 or 0x40 ~ 0x50)
276 */
277 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE0, ASTDP_AND_CLEAR_MASK,
278 ASTDP_MISC0_24bpp);
279 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE1, ASTDP_AND_CLEAR_MASK, ASTDP_MISC1);
280 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE2, ASTDP_AND_CLEAR_MASK, ModeIdx);
281 }
282