0001
0002
0003
0004
0005 #include <linux/firmware.h>
0006 #include <linux/delay.h>
0007 #include <drm/drm_print.h>
0008 #include "ast_drv.h"
0009
0010 int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
0011 {
0012 struct ast_private *ast = to_ast_private(dev);
0013 u8 i = 0, j = 0;
0014
0015
0016
0017
0018
0019
0020
0021 if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING) &&
0022 ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS) &&
0023 ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD) &&
0024 ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5,
0025 ASTDP_HOST_EDID_READ_DONE_MASK))) {
0026 goto err_astdp_edid_not_ready;
0027 }
0028
0029 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
0030 0x00);
0031
0032 for (i = 0; i < 32; i++) {
0033
0034
0035
0036 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE4,
0037 ASTDP_AND_CLEAR_MASK, (u8)i);
0038 j = 0;
0039
0040
0041
0042
0043
0044 while ((ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD7,
0045 ASTDP_EDID_VALID_FLAG_MASK) != 0x01) ||
0046 (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD6,
0047 ASTDP_EDID_READ_POINTER_MASK) != i)) {
0048
0049
0050
0051
0052
0053
0054 mdelay(j+1);
0055
0056 if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1,
0057 ASTDP_MCU_FW_EXECUTING) &&
0058 ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC,
0059 ASTDP_LINK_SUCCESS) &&
0060 ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD))) {
0061 goto err_astdp_jump_out_loop_of_edid;
0062 }
0063
0064 j++;
0065 if (j > 200)
0066 goto err_astdp_jump_out_loop_of_edid;
0067 }
0068
0069 *(ediddata) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT,
0070 0xD8, ASTDP_EDID_READ_DATA_MASK);
0071 *(ediddata + 1) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD9,
0072 ASTDP_EDID_READ_DATA_MASK);
0073 *(ediddata + 2) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDA,
0074 ASTDP_EDID_READ_DATA_MASK);
0075 *(ediddata + 3) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDB,
0076 ASTDP_EDID_READ_DATA_MASK);
0077
0078 if (i == 31) {
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 *(ediddata + 3) = *(ediddata + 3) + *(ediddata + 2);
0089 *(ediddata + 2) = 0;
0090 }
0091
0092 ediddata += 4;
0093 }
0094
0095 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
0096 ASTDP_HOST_EDID_READ_DONE);
0097
0098 return 0;
0099
0100 err_astdp_jump_out_loop_of_edid:
0101 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5,
0102 (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
0103 ASTDP_HOST_EDID_READ_DONE);
0104 return (~(j+256) + 1);
0105
0106 err_astdp_edid_not_ready:
0107 if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING)))
0108 return (~0xD1 + 1);
0109 if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS)))
0110 return (~0xDC + 1);
0111 if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD)))
0112 return (~0xDF + 1);
0113 if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, ASTDP_HOST_EDID_READ_DONE_MASK)))
0114 return (~0xE5 + 1);
0115
0116 return 0;
0117 }
0118
0119
0120
0121
0122 void ast_dp_launch(struct drm_device *dev, u8 bPower)
0123 {
0124 u32 i = 0, j = 0, WaitCount = 1;
0125 u8 bDPTX = 0;
0126 u8 bDPExecute = 1;
0127
0128 struct ast_private *ast = to_ast_private(dev);
0129
0130 if (bPower)
0131 WaitCount = 300;
0132
0133
0134
0135 for (j = 0; j < WaitCount; j++) {
0136 bDPTX = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, TX_TYPE_MASK);
0137
0138 if (bDPTX)
0139 break;
0140
0141 msleep(100);
0142 }
0143
0144
0145 if (bDPTX == ASTDP_DPMCU_TX) {
0146
0147 i = 0;
0148
0149 while (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, COPROCESSOR_LAUNCH) !=
0150 COPROCESSOR_LAUNCH) {
0151 i++;
0152
0153 msleep(100);
0154
0155 if (i >= 10) {
0156
0157 bDPExecute = 0;
0158 break;
0159 }
0160 }
0161
0162 if (bDPExecute)
0163 ast->tx_chip_types |= BIT(AST_TX_ASTDP);
0164
0165 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5,
0166 (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
0167 ASTDP_HOST_EDID_READ_DONE);
0168 }
0169 }
0170
0171
0172
0173 void ast_dp_power_on_off(struct drm_device *dev, bool on)
0174 {
0175 struct ast_private *ast = to_ast_private(dev);
0176
0177 u8 bE3 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, AST_DP_VIDEO_ENABLE);
0178
0179
0180 if (!on)
0181 bE3 |= AST_DP_PHY_SLEEP;
0182
0183
0184 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, (u8) ~AST_DP_PHY_SLEEP, bE3);
0185 }
0186
0187
0188
0189 void ast_dp_set_on_off(struct drm_device *dev, bool on)
0190 {
0191 struct ast_private *ast = to_ast_private(dev);
0192 u8 video_on_off = on;
0193
0194
0195 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, (u8) ~AST_DP_VIDEO_ENABLE, on);
0196
0197
0198 if (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS) &&
0199 ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD)) {
0200 video_on_off <<= 4;
0201 while (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF,
0202 ASTDP_MIRROR_VIDEO_ENABLE) != video_on_off) {
0203
0204 mdelay(1);
0205 }
0206 }
0207 }
0208
0209 void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mode)
0210 {
0211 struct ast_private *ast = to_ast_private(crtc->dev);
0212
0213 u32 ulRefreshRateIndex;
0214 u8 ModeIdx;
0215
0216 ulRefreshRateIndex = vbios_mode->enh_table->refresh_rate_index - 1;
0217
0218 switch (crtc->mode.crtc_hdisplay) {
0219 case 320:
0220 ModeIdx = ASTDP_320x240_60;
0221 break;
0222 case 400:
0223 ModeIdx = ASTDP_400x300_60;
0224 break;
0225 case 512:
0226 ModeIdx = ASTDP_512x384_60;
0227 break;
0228 case 640:
0229 ModeIdx = (ASTDP_640x480_60 + (u8) ulRefreshRateIndex);
0230 break;
0231 case 800:
0232 ModeIdx = (ASTDP_800x600_56 + (u8) ulRefreshRateIndex);
0233 break;
0234 case 1024:
0235 ModeIdx = (ASTDP_1024x768_60 + (u8) ulRefreshRateIndex);
0236 break;
0237 case 1152:
0238 ModeIdx = ASTDP_1152x864_75;
0239 break;
0240 case 1280:
0241 if (crtc->mode.crtc_vdisplay == 800)
0242 ModeIdx = (ASTDP_1280x800_60_RB - (u8) ulRefreshRateIndex);
0243 else
0244 ModeIdx = (ASTDP_1280x1024_60 + (u8) ulRefreshRateIndex);
0245 break;
0246 case 1360:
0247 case 1366:
0248 ModeIdx = ASTDP_1366x768_60;
0249 break;
0250 case 1440:
0251 ModeIdx = (ASTDP_1440x900_60_RB - (u8) ulRefreshRateIndex);
0252 break;
0253 case 1600:
0254 if (crtc->mode.crtc_vdisplay == 900)
0255 ModeIdx = (ASTDP_1600x900_60_RB - (u8) ulRefreshRateIndex);
0256 else
0257 ModeIdx = ASTDP_1600x1200_60;
0258 break;
0259 case 1680:
0260 ModeIdx = (ASTDP_1680x1050_60_RB - (u8) ulRefreshRateIndex);
0261 break;
0262 case 1920:
0263 if (crtc->mode.crtc_vdisplay == 1080)
0264 ModeIdx = ASTDP_1920x1080_60;
0265 else
0266 ModeIdx = ASTDP_1920x1200_60;
0267 break;
0268 default:
0269 return;
0270 }
0271
0272
0273
0274
0275
0276
0277 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE0, ASTDP_AND_CLEAR_MASK,
0278 ASTDP_MISC0_24bpp);
0279 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE1, ASTDP_AND_CLEAR_MASK, ASTDP_MISC1);
0280 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE2, ASTDP_AND_CLEAR_MASK, ModeIdx);
0281 }