summaryrefslogtreecommitdiffstats
path: root/drivers/video/tegra/dc/dp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/tegra/dc/dp.c')
-rw-r--r--drivers/video/tegra/dc/dp.c176
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
1167static void tegra_dp_set_max_link_bw(struct tegra_dc_sor_data *sor, 1167void 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
1179static int tegra_dp_init_max_link_cfg(struct tegra_dc_dp_data *dp, 1179static 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)); 1262static 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
1298static int tegra_dp_set_link_bandwidth(struct tegra_dc_dp_data *dp, u8 link_bw) 1311static 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)
1867static void tegra_dp_dpcd_init(struct tegra_dc_dp_data *dp) 1880static 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,