|
52 | 52 | #include "intel_fb.h" |
53 | 53 | #include "intel_fb_pin.h" |
54 | 54 | #include "skl_scaler.h" |
| 55 | +#include "skl_universal_plane.h" |
55 | 56 | #include "skl_watermark.h" |
56 | 57 |
|
57 | 58 | static void intel_plane_state_reset(struct intel_plane_state *plane_state, |
@@ -1223,3 +1224,298 @@ void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_sta |
1223 | 1224 | drm_vblank_work_init(&old_plane_state->unpin_work, old_plane_state->uapi.crtc, |
1224 | 1225 | intel_cursor_unpin_work); |
1225 | 1226 | } |
| 1227 | + |
| 1228 | +static void link_nv12_planes(struct intel_crtc_state *crtc_state, |
| 1229 | + struct intel_plane_state *uv_plane_state, |
| 1230 | + struct intel_plane_state *y_plane_state) |
| 1231 | +{ |
| 1232 | + struct intel_display *display = to_intel_display(uv_plane_state); |
| 1233 | + struct intel_plane *uv_plane = to_intel_plane(uv_plane_state->uapi.plane); |
| 1234 | + struct intel_plane *y_plane = to_intel_plane(y_plane_state->uapi.plane); |
| 1235 | + |
| 1236 | + drm_dbg_kms(display->drm, "UV plane [PLANE:%d:%s] using Y plane [PLANE:%d:%s]\n", |
| 1237 | + uv_plane->base.base.id, uv_plane->base.name, |
| 1238 | + y_plane->base.base.id, y_plane->base.name); |
| 1239 | + |
| 1240 | + uv_plane_state->planar_linked_plane = y_plane; |
| 1241 | + |
| 1242 | + y_plane_state->is_y_plane = true; |
| 1243 | + y_plane_state->planar_linked_plane = uv_plane; |
| 1244 | + |
| 1245 | + crtc_state->enabled_planes |= BIT(y_plane->id); |
| 1246 | + crtc_state->active_planes |= BIT(y_plane->id); |
| 1247 | + crtc_state->update_planes |= BIT(y_plane->id); |
| 1248 | + |
| 1249 | + crtc_state->data_rate[y_plane->id] = crtc_state->data_rate_y[uv_plane->id]; |
| 1250 | + crtc_state->rel_data_rate[y_plane->id] = crtc_state->rel_data_rate_y[uv_plane->id]; |
| 1251 | + |
| 1252 | + /* Copy parameters to Y plane */ |
| 1253 | + intel_plane_copy_hw_state(y_plane_state, uv_plane_state); |
| 1254 | + y_plane_state->uapi.src = uv_plane_state->uapi.src; |
| 1255 | + y_plane_state->uapi.dst = uv_plane_state->uapi.dst; |
| 1256 | + |
| 1257 | + y_plane_state->ctl = uv_plane_state->ctl; |
| 1258 | + y_plane_state->color_ctl = uv_plane_state->color_ctl; |
| 1259 | + y_plane_state->view = uv_plane_state->view; |
| 1260 | + y_plane_state->decrypt = uv_plane_state->decrypt; |
| 1261 | + |
| 1262 | + icl_link_nv12_planes(uv_plane_state, y_plane_state); |
| 1263 | +} |
| 1264 | + |
| 1265 | +static void unlink_nv12_plane(struct intel_crtc_state *crtc_state, |
| 1266 | + struct intel_plane_state *plane_state) |
| 1267 | +{ |
| 1268 | + struct intel_display *display = to_intel_display(plane_state); |
| 1269 | + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); |
| 1270 | + |
| 1271 | + plane_state->planar_linked_plane = NULL; |
| 1272 | + |
| 1273 | + if (!plane_state->is_y_plane) |
| 1274 | + return; |
| 1275 | + |
| 1276 | + drm_WARN_ON(display->drm, plane_state->uapi.visible); |
| 1277 | + |
| 1278 | + plane_state->is_y_plane = false; |
| 1279 | + |
| 1280 | + crtc_state->enabled_planes &= ~BIT(plane->id); |
| 1281 | + crtc_state->active_planes &= ~BIT(plane->id); |
| 1282 | + crtc_state->update_planes |= BIT(plane->id); |
| 1283 | + crtc_state->data_rate[plane->id] = 0; |
| 1284 | + crtc_state->rel_data_rate[plane->id] = 0; |
| 1285 | +} |
| 1286 | + |
| 1287 | +static int icl_check_nv12_planes(struct intel_atomic_state *state, |
| 1288 | + struct intel_crtc *crtc) |
| 1289 | +{ |
| 1290 | + struct intel_display *display = to_intel_display(state); |
| 1291 | + struct drm_i915_private *dev_priv = to_i915(state->base.dev); |
| 1292 | + struct intel_crtc_state *crtc_state = |
| 1293 | + intel_atomic_get_new_crtc_state(state, crtc); |
| 1294 | + struct intel_plane_state *plane_state; |
| 1295 | + struct intel_plane *plane; |
| 1296 | + int i; |
| 1297 | + |
| 1298 | + if (DISPLAY_VER(dev_priv) < 11) |
| 1299 | + return 0; |
| 1300 | + |
| 1301 | + /* |
| 1302 | + * Destroy all old plane links and make the Y plane invisible |
| 1303 | + * in the crtc_state->active_planes mask. |
| 1304 | + */ |
| 1305 | + for_each_new_intel_plane_in_state(state, plane, plane_state, i) { |
| 1306 | + if (plane->pipe != crtc->pipe) |
| 1307 | + continue; |
| 1308 | + |
| 1309 | + if (plane_state->planar_linked_plane) |
| 1310 | + unlink_nv12_plane(crtc_state, plane_state); |
| 1311 | + } |
| 1312 | + |
| 1313 | + if (!crtc_state->nv12_planes) |
| 1314 | + return 0; |
| 1315 | + |
| 1316 | + for_each_new_intel_plane_in_state(state, plane, plane_state, i) { |
| 1317 | + struct intel_plane_state *y_plane_state = NULL; |
| 1318 | + struct intel_plane *y_plane; |
| 1319 | + |
| 1320 | + if (plane->pipe != crtc->pipe) |
| 1321 | + continue; |
| 1322 | + |
| 1323 | + if ((crtc_state->nv12_planes & BIT(plane->id)) == 0) |
| 1324 | + continue; |
| 1325 | + |
| 1326 | + for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, y_plane) { |
| 1327 | + if (!icl_is_nv12_y_plane(display, y_plane->id)) |
| 1328 | + continue; |
| 1329 | + |
| 1330 | + if (crtc_state->active_planes & BIT(y_plane->id)) |
| 1331 | + continue; |
| 1332 | + |
| 1333 | + y_plane_state = intel_atomic_get_plane_state(state, y_plane); |
| 1334 | + if (IS_ERR(y_plane_state)) |
| 1335 | + return PTR_ERR(y_plane_state); |
| 1336 | + |
| 1337 | + break; |
| 1338 | + } |
| 1339 | + |
| 1340 | + if (!y_plane_state) { |
| 1341 | + drm_dbg_kms(&dev_priv->drm, |
| 1342 | + "[CRTC:%d:%s] need %d free Y planes for planar YUV\n", |
| 1343 | + crtc->base.base.id, crtc->base.name, |
| 1344 | + hweight8(crtc_state->nv12_planes)); |
| 1345 | + return -EINVAL; |
| 1346 | + } |
| 1347 | + |
| 1348 | + link_nv12_planes(crtc_state, plane_state, y_plane_state); |
| 1349 | + } |
| 1350 | + |
| 1351 | + return 0; |
| 1352 | +} |
| 1353 | + |
| 1354 | +static int intel_crtc_add_planes_to_state(struct intel_atomic_state *state, |
| 1355 | + struct intel_crtc *crtc, |
| 1356 | + u8 plane_ids_mask) |
| 1357 | +{ |
| 1358 | + struct drm_i915_private *dev_priv = to_i915(state->base.dev); |
| 1359 | + struct intel_plane *plane; |
| 1360 | + |
| 1361 | + for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) { |
| 1362 | + struct intel_plane_state *plane_state; |
| 1363 | + |
| 1364 | + if ((plane_ids_mask & BIT(plane->id)) == 0) |
| 1365 | + continue; |
| 1366 | + |
| 1367 | + plane_state = intel_atomic_get_plane_state(state, plane); |
| 1368 | + if (IS_ERR(plane_state)) |
| 1369 | + return PTR_ERR(plane_state); |
| 1370 | + } |
| 1371 | + |
| 1372 | + return 0; |
| 1373 | +} |
| 1374 | + |
| 1375 | +int intel_atomic_add_affected_planes(struct intel_atomic_state *state, |
| 1376 | + struct intel_crtc *crtc) |
| 1377 | +{ |
| 1378 | + const struct intel_crtc_state *old_crtc_state = |
| 1379 | + intel_atomic_get_old_crtc_state(state, crtc); |
| 1380 | + const struct intel_crtc_state *new_crtc_state = |
| 1381 | + intel_atomic_get_new_crtc_state(state, crtc); |
| 1382 | + |
| 1383 | + return intel_crtc_add_planes_to_state(state, crtc, |
| 1384 | + old_crtc_state->enabled_planes | |
| 1385 | + new_crtc_state->enabled_planes); |
| 1386 | +} |
| 1387 | + |
| 1388 | +static bool active_planes_affects_min_cdclk(struct drm_i915_private *dev_priv) |
| 1389 | +{ |
| 1390 | + /* See {hsw,vlv,ivb}_plane_ratio() */ |
| 1391 | + return IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv) || |
| 1392 | + IS_CHERRYVIEW(dev_priv) || IS_VALLEYVIEW(dev_priv) || |
| 1393 | + IS_IVYBRIDGE(dev_priv); |
| 1394 | +} |
| 1395 | + |
| 1396 | +static u8 intel_joiner_affected_planes(struct intel_atomic_state *state, |
| 1397 | + u8 joined_pipes) |
| 1398 | +{ |
| 1399 | + const struct intel_plane_state *plane_state; |
| 1400 | + struct intel_plane *plane; |
| 1401 | + u8 affected_planes = 0; |
| 1402 | + int i; |
| 1403 | + |
| 1404 | + for_each_new_intel_plane_in_state(state, plane, plane_state, i) { |
| 1405 | + struct intel_plane *linked = plane_state->planar_linked_plane; |
| 1406 | + |
| 1407 | + if ((joined_pipes & BIT(plane->pipe)) == 0) |
| 1408 | + continue; |
| 1409 | + |
| 1410 | + affected_planes |= BIT(plane->id); |
| 1411 | + if (linked) |
| 1412 | + affected_planes |= BIT(linked->id); |
| 1413 | + } |
| 1414 | + |
| 1415 | + return affected_planes; |
| 1416 | +} |
| 1417 | + |
| 1418 | +static int intel_joiner_add_affected_planes(struct intel_atomic_state *state, |
| 1419 | + u8 joined_pipes) |
| 1420 | +{ |
| 1421 | + u8 prev_affected_planes, affected_planes = 0; |
| 1422 | + |
| 1423 | + /* |
| 1424 | + * We want all the joined pipes to have the same |
| 1425 | + * set of planes in the atomic state, to make sure |
| 1426 | + * state copying always works correctly, and the |
| 1427 | + * UV<->Y plane linkage is always up to date. |
| 1428 | + * Keep pulling planes in until we've determined |
| 1429 | + * the full set of affected planes. A bit complicated |
| 1430 | + * on account of each pipe being capable of selecting |
| 1431 | + * their own Y planes independently of the other pipes, |
| 1432 | + * and the selection being done from the set of |
| 1433 | + * inactive planes. |
| 1434 | + */ |
| 1435 | + do { |
| 1436 | + struct intel_crtc *crtc; |
| 1437 | + |
| 1438 | + for_each_intel_crtc_in_pipe_mask(state->base.dev, crtc, joined_pipes) { |
| 1439 | + int ret; |
| 1440 | + |
| 1441 | + ret = intel_crtc_add_planes_to_state(state, crtc, affected_planes); |
| 1442 | + if (ret) |
| 1443 | + return ret; |
| 1444 | + } |
| 1445 | + |
| 1446 | + prev_affected_planes = affected_planes; |
| 1447 | + affected_planes = intel_joiner_affected_planes(state, joined_pipes); |
| 1448 | + } while (affected_planes != prev_affected_planes); |
| 1449 | + |
| 1450 | + return 0; |
| 1451 | +} |
| 1452 | + |
| 1453 | +static int intel_add_affected_planes(struct intel_atomic_state *state) |
| 1454 | +{ |
| 1455 | + const struct intel_crtc_state *crtc_state; |
| 1456 | + struct intel_crtc *crtc; |
| 1457 | + int i; |
| 1458 | + |
| 1459 | + for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { |
| 1460 | + int ret; |
| 1461 | + |
| 1462 | + ret = intel_joiner_add_affected_planes(state, intel_crtc_joined_pipe_mask(crtc_state)); |
| 1463 | + if (ret) |
| 1464 | + return ret; |
| 1465 | + } |
| 1466 | + |
| 1467 | + return 0; |
| 1468 | +} |
| 1469 | + |
| 1470 | +int intel_atomic_check_planes(struct intel_atomic_state *state) |
| 1471 | +{ |
| 1472 | + struct drm_i915_private *dev_priv = to_i915(state->base.dev); |
| 1473 | + struct intel_crtc_state *old_crtc_state, *new_crtc_state; |
| 1474 | + struct intel_plane_state __maybe_unused *plane_state; |
| 1475 | + struct intel_plane *plane; |
| 1476 | + struct intel_crtc *crtc; |
| 1477 | + int i, ret; |
| 1478 | + |
| 1479 | + ret = intel_add_affected_planes(state); |
| 1480 | + if (ret) |
| 1481 | + return ret; |
| 1482 | + |
| 1483 | + for_each_new_intel_plane_in_state(state, plane, plane_state, i) { |
| 1484 | + ret = intel_plane_atomic_check(state, plane); |
| 1485 | + if (ret) { |
| 1486 | + drm_dbg_atomic(&dev_priv->drm, |
| 1487 | + "[PLANE:%d:%s] atomic driver check failed\n", |
| 1488 | + plane->base.base.id, plane->base.name); |
| 1489 | + return ret; |
| 1490 | + } |
| 1491 | + } |
| 1492 | + |
| 1493 | + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, |
| 1494 | + new_crtc_state, i) { |
| 1495 | + u8 old_active_planes, new_active_planes; |
| 1496 | + |
| 1497 | + ret = icl_check_nv12_planes(state, crtc); |
| 1498 | + if (ret) |
| 1499 | + return ret; |
| 1500 | + |
| 1501 | + /* |
| 1502 | + * On some platforms the number of active planes affects |
| 1503 | + * the planes' minimum cdclk calculation. Add such planes |
| 1504 | + * to the state before we compute the minimum cdclk. |
| 1505 | + */ |
| 1506 | + if (!active_planes_affects_min_cdclk(dev_priv)) |
| 1507 | + continue; |
| 1508 | + |
| 1509 | + old_active_planes = old_crtc_state->active_planes & ~BIT(PLANE_CURSOR); |
| 1510 | + new_active_planes = new_crtc_state->active_planes & ~BIT(PLANE_CURSOR); |
| 1511 | + |
| 1512 | + if (hweight8(old_active_planes) == hweight8(new_active_planes)) |
| 1513 | + continue; |
| 1514 | + |
| 1515 | + ret = intel_crtc_add_planes_to_state(state, crtc, new_active_planes); |
| 1516 | + if (ret) |
| 1517 | + return ret; |
| 1518 | + } |
| 1519 | + |
| 1520 | + return 0; |
| 1521 | +} |
0 commit comments