0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #include <drm/drm_atomic.h>
0033 #include <drm/drm_atomic_helper.h>
0034 #include <drm/drm_fourcc.h>
0035 #include <drm/drm_plane_helper.h>
0036
0037 #include "i915_drv.h"
0038 #include "i915_reg.h"
0039 #include "intel_atomic.h"
0040 #include "intel_cdclk.h"
0041 #include "intel_display_types.h"
0042 #include "intel_global_state.h"
0043 #include "intel_hdcp.h"
0044 #include "intel_psr.h"
0045 #include "skl_universal_plane.h"
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 int intel_digital_connector_atomic_get_property(struct drm_connector *connector,
0057 const struct drm_connector_state *state,
0058 struct drm_property *property,
0059 u64 *val)
0060 {
0061 struct drm_device *dev = connector->dev;
0062 struct drm_i915_private *dev_priv = to_i915(dev);
0063 struct intel_digital_connector_state *intel_conn_state =
0064 to_intel_digital_connector_state(state);
0065
0066 if (property == dev_priv->force_audio_property)
0067 *val = intel_conn_state->force_audio;
0068 else if (property == dev_priv->broadcast_rgb_property)
0069 *val = intel_conn_state->broadcast_rgb;
0070 else {
0071 drm_dbg_atomic(&dev_priv->drm,
0072 "Unknown property [PROP:%d:%s]\n",
0073 property->base.id, property->name);
0074 return -EINVAL;
0075 }
0076
0077 return 0;
0078 }
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089 int intel_digital_connector_atomic_set_property(struct drm_connector *connector,
0090 struct drm_connector_state *state,
0091 struct drm_property *property,
0092 u64 val)
0093 {
0094 struct drm_device *dev = connector->dev;
0095 struct drm_i915_private *dev_priv = to_i915(dev);
0096 struct intel_digital_connector_state *intel_conn_state =
0097 to_intel_digital_connector_state(state);
0098
0099 if (property == dev_priv->force_audio_property) {
0100 intel_conn_state->force_audio = val;
0101 return 0;
0102 }
0103
0104 if (property == dev_priv->broadcast_rgb_property) {
0105 intel_conn_state->broadcast_rgb = val;
0106 return 0;
0107 }
0108
0109 drm_dbg_atomic(&dev_priv->drm, "Unknown property [PROP:%d:%s]\n",
0110 property->base.id, property->name);
0111 return -EINVAL;
0112 }
0113
0114 int intel_digital_connector_atomic_check(struct drm_connector *conn,
0115 struct drm_atomic_state *state)
0116 {
0117 struct drm_connector_state *new_state =
0118 drm_atomic_get_new_connector_state(state, conn);
0119 struct intel_digital_connector_state *new_conn_state =
0120 to_intel_digital_connector_state(new_state);
0121 struct drm_connector_state *old_state =
0122 drm_atomic_get_old_connector_state(state, conn);
0123 struct intel_digital_connector_state *old_conn_state =
0124 to_intel_digital_connector_state(old_state);
0125 struct drm_crtc_state *crtc_state;
0126
0127 intel_hdcp_atomic_check(conn, old_state, new_state);
0128
0129 if (!new_state->crtc)
0130 return 0;
0131
0132 crtc_state = drm_atomic_get_new_crtc_state(state, new_state->crtc);
0133
0134
0135
0136
0137
0138 if (new_conn_state->force_audio != old_conn_state->force_audio ||
0139 new_conn_state->broadcast_rgb != old_conn_state->broadcast_rgb ||
0140 new_conn_state->base.colorspace != old_conn_state->base.colorspace ||
0141 new_conn_state->base.picture_aspect_ratio != old_conn_state->base.picture_aspect_ratio ||
0142 new_conn_state->base.content_type != old_conn_state->base.content_type ||
0143 new_conn_state->base.scaling_mode != old_conn_state->base.scaling_mode ||
0144 new_conn_state->base.privacy_screen_sw_state != old_conn_state->base.privacy_screen_sw_state ||
0145 !drm_connector_atomic_hdr_metadata_equal(old_state, new_state))
0146 crtc_state->mode_changed = true;
0147
0148 return 0;
0149 }
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160 struct drm_connector_state *
0161 intel_digital_connector_duplicate_state(struct drm_connector *connector)
0162 {
0163 struct intel_digital_connector_state *state;
0164
0165 state = kmemdup(connector->state, sizeof(*state), GFP_KERNEL);
0166 if (!state)
0167 return NULL;
0168
0169 __drm_atomic_helper_connector_duplicate_state(connector, &state->base);
0170 return &state->base;
0171 }
0172
0173
0174
0175
0176
0177
0178 bool
0179 intel_connector_needs_modeset(struct intel_atomic_state *state,
0180 struct drm_connector *connector)
0181 {
0182 const struct drm_connector_state *old_conn_state, *new_conn_state;
0183
0184 old_conn_state = drm_atomic_get_old_connector_state(&state->base, connector);
0185 new_conn_state = drm_atomic_get_new_connector_state(&state->base, connector);
0186
0187 return old_conn_state->crtc != new_conn_state->crtc ||
0188 (new_conn_state->crtc &&
0189 drm_atomic_crtc_needs_modeset(drm_atomic_get_new_crtc_state(&state->base,
0190 new_conn_state->crtc)));
0191 }
0192
0193
0194
0195
0196
0197
0198
0199 bool intel_any_crtc_needs_modeset(struct intel_atomic_state *state)
0200 {
0201 struct intel_crtc *crtc;
0202 struct intel_crtc_state *crtc_state;
0203 int i;
0204
0205 for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
0206 if (intel_crtc_needs_modeset(crtc_state))
0207 return true;
0208 }
0209
0210 return false;
0211 }
0212
0213 struct intel_digital_connector_state *
0214 intel_atomic_get_digital_connector_state(struct intel_atomic_state *state,
0215 struct intel_connector *connector)
0216 {
0217 struct drm_connector_state *conn_state;
0218
0219 conn_state = drm_atomic_get_connector_state(&state->base,
0220 &connector->base);
0221 if (IS_ERR(conn_state))
0222 return ERR_CAST(conn_state);
0223
0224 return to_intel_digital_connector_state(conn_state);
0225 }
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236 struct drm_crtc_state *
0237 intel_crtc_duplicate_state(struct drm_crtc *crtc)
0238 {
0239 const struct intel_crtc_state *old_crtc_state = to_intel_crtc_state(crtc->state);
0240 struct intel_crtc_state *crtc_state;
0241
0242 crtc_state = kmemdup(old_crtc_state, sizeof(*crtc_state), GFP_KERNEL);
0243 if (!crtc_state)
0244 return NULL;
0245
0246 __drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->uapi);
0247
0248
0249 if (crtc_state->hw.degamma_lut)
0250 drm_property_blob_get(crtc_state->hw.degamma_lut);
0251 if (crtc_state->hw.ctm)
0252 drm_property_blob_get(crtc_state->hw.ctm);
0253 if (crtc_state->hw.gamma_lut)
0254 drm_property_blob_get(crtc_state->hw.gamma_lut);
0255
0256 crtc_state->update_pipe = false;
0257 crtc_state->disable_lp_wm = false;
0258 crtc_state->disable_cxsr = false;
0259 crtc_state->update_wm_pre = false;
0260 crtc_state->update_wm_post = false;
0261 crtc_state->fifo_changed = false;
0262 crtc_state->preload_luts = false;
0263 crtc_state->inherited = false;
0264 crtc_state->wm.need_postvbl_update = false;
0265 crtc_state->do_async_flip = false;
0266 crtc_state->fb_bits = 0;
0267 crtc_state->update_planes = 0;
0268 crtc_state->dsb = NULL;
0269
0270 return &crtc_state->uapi;
0271 }
0272
0273 static void intel_crtc_put_color_blobs(struct intel_crtc_state *crtc_state)
0274 {
0275 drm_property_blob_put(crtc_state->hw.degamma_lut);
0276 drm_property_blob_put(crtc_state->hw.gamma_lut);
0277 drm_property_blob_put(crtc_state->hw.ctm);
0278 }
0279
0280 void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state)
0281 {
0282 intel_crtc_put_color_blobs(crtc_state);
0283 }
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293 void
0294 intel_crtc_destroy_state(struct drm_crtc *crtc,
0295 struct drm_crtc_state *state)
0296 {
0297 struct intel_crtc_state *crtc_state = to_intel_crtc_state(state);
0298
0299 drm_WARN_ON(crtc->dev, crtc_state->dsb);
0300
0301 __drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
0302 intel_crtc_free_hw_state(crtc_state);
0303 kfree(crtc_state);
0304 }
0305
0306 static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_state,
0307 int num_scalers_need, struct intel_crtc *intel_crtc,
0308 const char *name, int idx,
0309 struct intel_plane_state *plane_state,
0310 int *scaler_id)
0311 {
0312 struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
0313 int j;
0314 u32 mode;
0315
0316 if (*scaler_id < 0) {
0317
0318 for (j = 0; j < intel_crtc->num_scalers; j++) {
0319 if (scaler_state->scalers[j].in_use)
0320 continue;
0321
0322 *scaler_id = j;
0323 scaler_state->scalers[*scaler_id].in_use = 1;
0324 break;
0325 }
0326 }
0327
0328 if (drm_WARN(&dev_priv->drm, *scaler_id < 0,
0329 "Cannot find scaler for %s:%d\n", name, idx))
0330 return;
0331
0332
0333 if (plane_state && plane_state->hw.fb &&
0334 plane_state->hw.fb->format->is_yuv &&
0335 plane_state->hw.fb->format->num_planes > 1) {
0336 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
0337 if (DISPLAY_VER(dev_priv) == 9) {
0338 mode = SKL_PS_SCALER_MODE_NV12;
0339 } else if (icl_is_hdr_plane(dev_priv, plane->id)) {
0340
0341
0342
0343
0344
0345 mode = PS_SCALER_MODE_NORMAL;
0346 } else {
0347 struct intel_plane *linked =
0348 plane_state->planar_linked_plane;
0349
0350 mode = PS_SCALER_MODE_PLANAR;
0351
0352 if (linked)
0353 mode |= PS_PLANE_Y_SEL(linked->id);
0354 }
0355 } else if (DISPLAY_VER(dev_priv) >= 10) {
0356 mode = PS_SCALER_MODE_NORMAL;
0357 } else if (num_scalers_need == 1 && intel_crtc->num_scalers > 1) {
0358
0359
0360
0361
0362
0363 scaler_state->scalers[*scaler_id].in_use = 0;
0364 *scaler_id = 0;
0365 scaler_state->scalers[0].in_use = 1;
0366 mode = SKL_PS_SCALER_MODE_HQ;
0367 } else {
0368 mode = SKL_PS_SCALER_MODE_DYN;
0369 }
0370
0371 drm_dbg_kms(&dev_priv->drm, "Attached scaler id %u.%u to %s:%d\n",
0372 intel_crtc->pipe, *scaler_id, name, idx);
0373 scaler_state->scalers[*scaler_id].mode = mode;
0374 }
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393 int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
0394 struct intel_crtc *intel_crtc,
0395 struct intel_crtc_state *crtc_state)
0396 {
0397 struct drm_plane *plane = NULL;
0398 struct intel_plane *intel_plane;
0399 struct intel_plane_state *plane_state = NULL;
0400 struct intel_crtc_scaler_state *scaler_state =
0401 &crtc_state->scaler_state;
0402 struct drm_atomic_state *drm_state = crtc_state->uapi.state;
0403 struct intel_atomic_state *intel_state = to_intel_atomic_state(drm_state);
0404 int num_scalers_need;
0405 int i;
0406
0407 num_scalers_need = hweight32(scaler_state->scaler_users);
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422 if (num_scalers_need > intel_crtc->num_scalers){
0423 drm_dbg_kms(&dev_priv->drm,
0424 "Too many scaling requests %d > %d\n",
0425 num_scalers_need, intel_crtc->num_scalers);
0426 return -EINVAL;
0427 }
0428
0429
0430 for (i = 0; i < sizeof(scaler_state->scaler_users) * 8; i++) {
0431 int *scaler_id;
0432 const char *name;
0433 int idx;
0434
0435
0436 if (!(scaler_state->scaler_users & (1 << i)))
0437 continue;
0438
0439 if (i == SKL_CRTC_INDEX) {
0440 name = "CRTC";
0441 idx = intel_crtc->base.base.id;
0442
0443
0444 scaler_id = &scaler_state->scaler_id;
0445 } else {
0446 name = "PLANE";
0447
0448
0449
0450 plane = drm_state->planes[i].ptr;
0451
0452
0453
0454
0455
0456 if (!plane) {
0457 struct drm_plane_state *state;
0458
0459
0460
0461
0462
0463
0464 if (DISPLAY_VER(dev_priv) >= 10)
0465 continue;
0466
0467 plane = drm_plane_from_index(&dev_priv->drm, i);
0468 state = drm_atomic_get_plane_state(drm_state, plane);
0469 if (IS_ERR(state)) {
0470 drm_dbg_kms(&dev_priv->drm,
0471 "Failed to add [PLANE:%d] to drm_state\n",
0472 plane->base.id);
0473 return PTR_ERR(state);
0474 }
0475 }
0476
0477 intel_plane = to_intel_plane(plane);
0478 idx = plane->base.id;
0479
0480
0481 if (drm_WARN_ON(&dev_priv->drm,
0482 intel_plane->pipe != intel_crtc->pipe))
0483 continue;
0484
0485 plane_state = intel_atomic_get_new_plane_state(intel_state,
0486 intel_plane);
0487 scaler_id = &plane_state->scaler_id;
0488 }
0489
0490 intel_atomic_setup_scaler(scaler_state, num_scalers_need,
0491 intel_crtc, name, idx,
0492 plane_state, scaler_id);
0493 }
0494
0495 return 0;
0496 }
0497
0498 struct drm_atomic_state *
0499 intel_atomic_state_alloc(struct drm_device *dev)
0500 {
0501 struct intel_atomic_state *state = kzalloc(sizeof(*state), GFP_KERNEL);
0502
0503 if (!state || drm_atomic_state_init(dev, &state->base) < 0) {
0504 kfree(state);
0505 return NULL;
0506 }
0507
0508 return &state->base;
0509 }
0510
0511 void intel_atomic_state_free(struct drm_atomic_state *_state)
0512 {
0513 struct intel_atomic_state *state = to_intel_atomic_state(_state);
0514
0515 drm_atomic_state_default_release(&state->base);
0516 kfree(state->global_objs);
0517
0518 i915_sw_fence_fini(&state->commit_ready);
0519
0520 kfree(state);
0521 }
0522
0523 void intel_atomic_state_clear(struct drm_atomic_state *s)
0524 {
0525 struct intel_atomic_state *state = to_intel_atomic_state(s);
0526
0527 drm_atomic_state_default_clear(&state->base);
0528 intel_atomic_clear_global_state(state);
0529
0530 state->dpll_set = state->modeset = false;
0531 }
0532
0533 struct intel_crtc_state *
0534 intel_atomic_get_crtc_state(struct drm_atomic_state *state,
0535 struct intel_crtc *crtc)
0536 {
0537 struct drm_crtc_state *crtc_state;
0538 crtc_state = drm_atomic_get_crtc_state(state, &crtc->base);
0539 if (IS_ERR(crtc_state))
0540 return ERR_CAST(crtc_state);
0541
0542 return to_intel_crtc_state(crtc_state);
0543 }