diff options
Diffstat (limited to 'drivers/video/tegra/dc/dp.c')
-rw-r--r-- | drivers/video/tegra/dc/dp.c | 176 |
1 files changed, 95 insertions, 81 deletions
diff --git a/drivers/video/tegra/dc/dp.c b/drivers/video/tegra/dc/dp.c index 4ac21c384..cad1be38e 100644 --- a/drivers/video/tegra/dc/dp.c +++ b/drivers/video/tegra/dc/dp.c | |||
@@ -1149,7 +1149,7 @@ static int tegra_dc_init_default_panel_link_cfg(struct tegra_dc_dp_link_config * | |||
1149 | */ | 1149 | */ |
1150 | if (!cfg->is_valid) { | 1150 | if (!cfg->is_valid) { |
1151 | cfg->max_lane_count = 4; | 1151 | cfg->max_lane_count = 4; |
1152 | cfg->tps3_supported = false; | 1152 | cfg->tps = TEGRA_DC_DP_TRAINING_PATTERN_2; |
1153 | cfg->support_enhanced_framing = true; | 1153 | cfg->support_enhanced_framing = true; |
1154 | cfg->downspread = true; | 1154 | cfg->downspread = true; |
1155 | cfg->support_fast_lt = true; | 1155 | cfg->support_fast_lt = true; |
@@ -1164,8 +1164,8 @@ static int tegra_dc_init_default_panel_link_cfg(struct tegra_dc_dp_link_config * | |||
1164 | return 0; | 1164 | return 0; |
1165 | } | 1165 | } |
1166 | 1166 | ||
1167 | static void tegra_dp_set_max_link_bw(struct tegra_dc_sor_data *sor, | 1167 | void tegra_dp_set_max_link_bw(struct tegra_dc_sor_data *sor, |
1168 | struct tegra_dc_dp_link_config *cfg) | 1168 | struct tegra_dc_dp_link_config *cfg) |
1169 | { | 1169 | { |
1170 | unsigned int key; /* Index into the link speed table */ | 1170 | unsigned int key; /* Index into the link speed table */ |
1171 | 1171 | ||
@@ -1176,90 +1176,103 @@ static void tegra_dp_set_max_link_bw(struct tegra_dc_sor_data *sor, | |||
1176 | cfg->max_link_bw = sor->link_speeds[key].link_rate; | 1176 | cfg->max_link_bw = sor->link_speeds[key].link_rate; |
1177 | } | 1177 | } |
1178 | 1178 | ||
1179 | static int tegra_dp_init_max_link_cfg(struct tegra_dc_dp_data *dp, | 1179 | static int __tegra_dp_init_max_link_cfg(struct tegra_dc_dp_data *dp, |
1180 | struct tegra_dc_dp_link_config *cfg) | 1180 | struct tegra_dc_dp_link_config *cfg) |
1181 | { | 1181 | { |
1182 | if (dp->dc->out->type == TEGRA_DC_OUT_FAKE_DP) | 1182 | u8 dpcd_data; |
1183 | tegra_dc_init_default_panel_link_cfg(cfg); | 1183 | int ret; |
1184 | else { | ||
1185 | u8 dpcd_data; | ||
1186 | int ret; | ||
1187 | 1184 | ||
1188 | if (dp->sink_cap_valid) | 1185 | if (dp->sink_cap_valid) |
1189 | dpcd_data = dp->sink_cap[NV_DPCD_MAX_LANE_COUNT]; | 1186 | dpcd_data = dp->sink_cap[NV_DPCD_MAX_LANE_COUNT]; |
1190 | else | 1187 | else |
1191 | CHECK_RET(tegra_dc_dp_dpcd_read(dp, | 1188 | CHECK_RET(tegra_dc_dp_dpcd_read(dp, |
1192 | NV_DPCD_MAX_LANE_COUNT, &dpcd_data)); | 1189 | NV_DPCD_MAX_LANE_COUNT, &dpcd_data)); |
1193 | 1190 | ||
1194 | cfg->max_lane_count = dpcd_data & NV_DPCD_MAX_LANE_COUNT_MASK; | 1191 | cfg->max_lane_count = dpcd_data & NV_DPCD_MAX_LANE_COUNT_MASK; |
1195 | 1192 | ||
1196 | if (cfg->max_lane_count >= 4) | 1193 | if (cfg->max_lane_count >= 4) |
1197 | cfg->max_lane_count = 4; | 1194 | cfg->max_lane_count = 4; |
1198 | else if (cfg->max_lane_count >= 2) | 1195 | else if (cfg->max_lane_count >= 2) |
1199 | cfg->max_lane_count = 2; | 1196 | cfg->max_lane_count = 2; |
1200 | else | 1197 | else |
1201 | cfg->max_lane_count = 1; | 1198 | cfg->max_lane_count = 1; |
1202 | 1199 | ||
1203 | if (dp->pdata && dp->pdata->lanes && | 1200 | if (dp->pdata && dp->pdata->lanes && |
1204 | dp->pdata->lanes < cfg->max_lane_count) | 1201 | dp->pdata->lanes < cfg->max_lane_count) |
1205 | cfg->max_lane_count = dp->pdata->lanes; | 1202 | cfg->max_lane_count = dp->pdata->lanes; |
1206 | 1203 | ||
1207 | cfg->tps3_supported = | 1204 | if (dpcd_data & NV_DPCD_MAX_LANE_COUNT_TPS3_SUPPORTED_YES) |
1208 | (dpcd_data & | 1205 | cfg->tps = TEGRA_DC_DP_TRAINING_PATTERN_3; |
1209 | NV_DPCD_MAX_LANE_COUNT_TPS3_SUPPORTED_YES) ? | 1206 | |
1210 | true : false; | 1207 | cfg->support_enhanced_framing = |
1211 | cfg->support_enhanced_framing = | 1208 | (dpcd_data & NV_DPCD_MAX_LANE_COUNT_ENHANCED_FRAMING_YES) ? |
1212 | (dpcd_data & NV_DPCD_MAX_LANE_COUNT_ENHANCED_FRAMING_YES) ? | 1209 | true : false; |
1210 | |||
1211 | if (dp->sink_cap_valid) | ||
1212 | dpcd_data = dp->sink_cap[NV_DPCD_MAX_DOWNSPREAD]; | ||
1213 | else | ||
1214 | CHECK_RET(tegra_dc_dp_dpcd_read(dp, | ||
1215 | NV_DPCD_MAX_DOWNSPREAD, &dpcd_data)); | ||
1216 | cfg->downspread = | ||
1217 | (dpcd_data & NV_DPCD_MAX_DOWNSPREAD_VAL_0_5_PCT) ? | ||
1218 | true : false; | ||
1219 | cfg->support_fast_lt = (dpcd_data & | ||
1220 | NV_DPCD_MAX_DOWNSPREAD_NO_AUX_HANDSHAKE_LT_T) ? | ||
1213 | true : false; | 1221 | true : false; |
1214 | 1222 | ||
1215 | if (dp->sink_cap_valid) | 1223 | CHECK_RET(tegra_dc_dp_dpcd_read(dp, |
1216 | dpcd_data = dp->sink_cap[NV_DPCD_MAX_DOWNSPREAD]; | 1224 | NV_DPCD_TRAINING_AUX_RD_INTERVAL, &dpcd_data)); |
1217 | else | 1225 | cfg->aux_rd_interval = dpcd_data; |
1218 | CHECK_RET(tegra_dc_dp_dpcd_read(dp, | ||
1219 | NV_DPCD_MAX_DOWNSPREAD, &dpcd_data)); | ||
1220 | cfg->downspread = | ||
1221 | (dpcd_data & NV_DPCD_MAX_DOWNSPREAD_VAL_0_5_PCT) ? | ||
1222 | true : false; | ||
1223 | cfg->support_fast_lt = (dpcd_data & | ||
1224 | NV_DPCD_MAX_DOWNSPREAD_NO_AUX_HANDSHAKE_LT_T) ? | ||
1225 | true : false; | ||
1226 | 1226 | ||
1227 | if (dp->sink_cap_valid) | ||
1228 | cfg->max_link_bw = | ||
1229 | dp->sink_cap[NV_DPCD_MAX_LINK_BANDWIDTH]; | ||
1230 | else | ||
1227 | CHECK_RET(tegra_dc_dp_dpcd_read(dp, | 1231 | CHECK_RET(tegra_dc_dp_dpcd_read(dp, |
1228 | NV_DPCD_TRAINING_AUX_RD_INTERVAL, &dpcd_data)); | 1232 | NV_DPCD_MAX_LINK_BANDWIDTH, |
1229 | cfg->aux_rd_interval = dpcd_data; | 1233 | &cfg->max_link_bw)); |
1230 | 1234 | ||
1231 | if (dp->sink_cap_valid) | 1235 | tegra_dp_set_max_link_bw(dp->sor, cfg); |
1232 | cfg->max_link_bw = | 1236 | |
1233 | dp->sink_cap[NV_DPCD_MAX_LINK_BANDWIDTH]; | 1237 | if (dp->pdata && dp->pdata->link_bw && |
1234 | else | 1238 | dp->pdata->link_bw < cfg->max_link_bw) |
1235 | CHECK_RET(tegra_dc_dp_dpcd_read(dp, | 1239 | cfg->max_link_bw = dp->pdata->link_bw; |
1236 | NV_DPCD_MAX_LINK_BANDWIDTH, | 1240 | |
1237 | &cfg->max_link_bw)); | 1241 | CHECK_RET(tegra_dc_dp_dpcd_read(dp, NV_DPCD_EDP_CONFIG_CAP, |
1238 | 1242 | &dpcd_data)); | |
1239 | tegra_dp_set_max_link_bw(dp->sor, cfg); | 1243 | cfg->alt_scramber_reset_cap = |
1240 | 1244 | (dpcd_data & NV_DPCD_EDP_CONFIG_CAP_ASC_RESET_YES) ? | |
1241 | if (dp->pdata && dp->pdata->link_bw && | 1245 | true : false; |
1242 | dp->pdata->link_bw < cfg->max_link_bw) | 1246 | cfg->only_enhanced_framing = (dpcd_data & |
1243 | cfg->max_link_bw = dp->pdata->link_bw; | 1247 | NV_DPCD_EDP_CONFIG_CAP_FRAMING_CHANGE_YES) ? |
1244 | 1248 | true : false; | |
1245 | CHECK_RET(tegra_dc_dp_dpcd_read(dp, NV_DPCD_EDP_CONFIG_CAP, | 1249 | cfg->edp_cap = (dpcd_data & |
1246 | &dpcd_data)); | 1250 | NV_DPCD_EDP_CONFIG_CAP_DISPLAY_CONTROL_CAP_YES) ? |
1247 | cfg->alt_scramber_reset_cap = | 1251 | true : false; |
1248 | (dpcd_data & NV_DPCD_EDP_CONFIG_CAP_ASC_RESET_YES) ? | 1252 | |
1249 | true : false; | 1253 | CHECK_RET(tegra_dc_dp_dpcd_read(dp, NV_DPCD_FEATURE_ENUM_LIST, |
1250 | cfg->only_enhanced_framing = (dpcd_data & | 1254 | &dpcd_data)); |
1251 | NV_DPCD_EDP_CONFIG_CAP_FRAMING_CHANGE_YES) ? | 1255 | cfg->support_vsc_ext_colorimetry = (dpcd_data & |
1252 | true : false; | 1256 | NV_DPCD_FEATURE_ENUM_LIST_VSC_EXT_COLORIMETRY) ? |
1253 | cfg->edp_cap = (dpcd_data & | 1257 | true : false; |
1254 | NV_DPCD_EDP_CONFIG_CAP_DISPLAY_CONTROL_CAP_YES) ? | 1258 | |
1255 | true : false; | 1259 | return 0; |
1256 | 1260 | } | |
1257 | CHECK_RET(tegra_dc_dp_dpcd_read(dp, NV_DPCD_FEATURE_ENUM_LIST, | 1261 | |
1258 | &dpcd_data)); | 1262 | static int tegra_dp_init_max_link_cfg(struct tegra_dc_dp_data *dp, |
1259 | cfg->support_vsc_ext_colorimetry = (dpcd_data & | 1263 | struct tegra_dc_dp_link_config *cfg) |
1260 | NV_DPCD_FEATURE_ENUM_LIST_VSC_EXT_COLORIMETRY) ? | 1264 | { |
1261 | true : false; | 1265 | int ret = 0; |
1262 | } | 1266 | |
1267 | if (dp->dc->out->type == TEGRA_DC_OUT_FAKE_DP) | ||
1268 | tegra_dc_init_default_panel_link_cfg(cfg); | ||
1269 | else if (tegra_dc_is_t19x()) | ||
1270 | ret = tegra_dp_init_max_link_cfg_t19x(dp, cfg); | ||
1271 | else | ||
1272 | ret = __tegra_dp_init_max_link_cfg(dp, cfg); | ||
1273 | |||
1274 | if (ret) | ||
1275 | return ret; | ||
1263 | 1276 | ||
1264 | cfg->bits_per_pixel = dp->dc->out->depth ? : 24; | 1277 | cfg->bits_per_pixel = dp->dc->out->depth ? : 24; |
1265 | 1278 | ||
@@ -1275,6 +1288,7 @@ static int tegra_dp_init_max_link_cfg(struct tegra_dc_dp_data *dp, | |||
1275 | tegra_dc_dp_calc_config(dp, dp->mode, cfg); | 1288 | tegra_dc_dp_calc_config(dp, dp->mode, cfg); |
1276 | 1289 | ||
1277 | dp->max_link_cfg = *cfg; | 1290 | dp->max_link_cfg = *cfg; |
1291 | |||
1278 | return 0; | 1292 | return 0; |
1279 | } | 1293 | } |
1280 | 1294 | ||
@@ -1294,7 +1308,6 @@ static int tegra_dc_dp_set_assr(struct tegra_dc_dp_data *dp, bool ena) | |||
1294 | return 0; | 1308 | return 0; |
1295 | } | 1309 | } |
1296 | 1310 | ||
1297 | |||
1298 | static int tegra_dp_set_link_bandwidth(struct tegra_dc_dp_data *dp, u8 link_bw) | 1311 | static int tegra_dp_set_link_bandwidth(struct tegra_dc_dp_data *dp, u8 link_bw) |
1299 | { | 1312 | { |
1300 | tegra_dc_sor_set_link_bandwidth(dp->sor, link_bw); | 1313 | tegra_dc_sor_set_link_bandwidth(dp->sor, link_bw); |
@@ -1867,6 +1880,7 @@ static void tegra_dp_hpd_config(struct tegra_dc_dp_data *dp) | |||
1867 | static void tegra_dp_dpcd_init(struct tegra_dc_dp_data *dp) | 1880 | static void tegra_dp_dpcd_init(struct tegra_dc_dp_data *dp) |
1868 | { | 1881 | { |
1869 | struct tegra_dc_dp_link_config *cfg = &dp->link_cfg; | 1882 | struct tegra_dc_dp_link_config *cfg = &dp->link_cfg; |
1883 | int ret; | ||
1870 | u32 size_ieee_oui = 3, auxstat; | 1884 | u32 size_ieee_oui = 3, auxstat; |
1871 | u8 data_ieee_oui_be[3] = {(NV_IEEE_OUI >> 16) & 0xff, | 1885 | u8 data_ieee_oui_be[3] = {(NV_IEEE_OUI >> 16) & 0xff, |
1872 | (NV_IEEE_OUI >> 8) & 0xff, | 1886 | (NV_IEEE_OUI >> 8) & 0xff, |
@@ -1877,9 +1891,9 @@ static void tegra_dp_dpcd_init(struct tegra_dc_dp_data *dp) | |||
1877 | dev_err(&dp->dc->ndev->dev, | 1891 | dev_err(&dp->dc->ndev->dev, |
1878 | "dp: failed to read the revision number from sink\n"); | 1892 | "dp: failed to read the revision number from sink\n"); |
1879 | 1893 | ||
1880 | if (tegra_dp_init_max_link_cfg(dp, cfg)) | 1894 | ret = tegra_dp_init_max_link_cfg(dp, cfg); |
1881 | dev_err(&dp->dc->ndev->dev, | 1895 | if (ret) |
1882 | "dp: failed to init link configuration\n"); | 1896 | dev_err(&dp->dc->ndev->dev, "dp: failed to init link cfg\n"); |
1883 | 1897 | ||
1884 | tegra_dc_dpaux_write(dp->dpaux, DPAUX_DP_AUXCTL_CMD_AUXWR, | 1898 | tegra_dc_dpaux_write(dp->dpaux, DPAUX_DP_AUXCTL_CMD_AUXWR, |
1885 | NV_DPCD_SOURCE_IEEE_OUI, data_ieee_oui_be, &size_ieee_oui, | 1899 | NV_DPCD_SOURCE_IEEE_OUI, data_ieee_oui_be, &size_ieee_oui, |