Rev 6937 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6937 | Rev 7144 | ||
---|---|---|---|
Line 26... | Line 26... | ||
26 | */ |
26 | */ |
Line 27... | Line 27... | ||
27 | 27 | ||
28 | 28 | ||
- | 29 | #include |
|
29 | #include |
30 | #include |
Line 30... | Line 31... | ||
30 | #include |
31 | #include |
31 | #include |
32 | #include |
32 | 33 | ||
Line 351... | Line 352... | ||
351 | return 0; |
352 | return 0; |
Line 352... | Line 353... | ||
352 | 353 | ||
353 | drm_property_unreference_blob(state->mode_blob); |
354 | drm_property_unreference_blob(state->mode_blob); |
Line -... | Line 355... | ||
- | 355 | state->mode_blob = NULL; |
|
- | 356 | ||
354 | state->mode_blob = NULL; |
357 | memset(&state->mode, 0, sizeof(state->mode)); |
355 | 358 | ||
356 | if (blob) { |
359 | if (blob) { |
357 | if (blob->length != sizeof(struct drm_mode_modeinfo) || |
360 | if (blob->length != sizeof(struct drm_mode_modeinfo) || |
358 | drm_mode_convert_umode(&state->mode, |
361 | drm_mode_convert_umode(&state->mode, |
Line 363... | Line 366... | ||
363 | state->mode_blob = drm_property_reference_blob(blob); |
366 | state->mode_blob = drm_property_reference_blob(blob); |
364 | state->enable = true; |
367 | state->enable = true; |
365 | DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n", |
368 | DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n", |
366 | state->mode.name, state); |
369 | state->mode.name, state); |
367 | } else { |
370 | } else { |
368 | memset(&state->mode, 0, sizeof(state->mode)); |
- | |
369 | state->enable = false; |
371 | state->enable = false; |
370 | DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n", |
372 | DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n", |
371 | state); |
373 | state); |
372 | } |
374 | } |
Line 373... | Line 375... | ||
373 | 375 | ||
374 | return 0; |
376 | return 0; |
375 | } |
377 | } |
Line 376... | Line 378... | ||
376 | EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc); |
378 | EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc); |
- | 379 | ||
- | 380 | /** |
|
- | 381 | * drm_atomic_replace_property_blob - replace a blob property |
|
- | 382 | * @blob: a pointer to the member blob to be replaced |
|
- | 383 | * @new_blob: the new blob to replace with |
|
- | 384 | * @replaced: whether the blob has been replaced |
|
- | 385 | * |
|
- | 386 | * RETURNS: |
|
- | 387 | * Zero on success, error code on failure |
|
- | 388 | */ |
|
- | 389 | static void |
|
- | 390 | drm_atomic_replace_property_blob(struct drm_property_blob **blob, |
|
- | 391 | struct drm_property_blob *new_blob, |
|
- | 392 | bool *replaced) |
|
- | 393 | { |
|
- | 394 | struct drm_property_blob *old_blob = *blob; |
|
- | 395 | ||
- | 396 | if (old_blob == new_blob) |
|
- | 397 | return; |
|
- | 398 | ||
- | 399 | if (old_blob) |
|
- | 400 | drm_property_unreference_blob(old_blob); |
|
- | 401 | if (new_blob) |
|
- | 402 | drm_property_reference_blob(new_blob); |
|
- | 403 | *blob = new_blob; |
|
- | 404 | *replaced = true; |
|
- | 405 | ||
- | 406 | return; |
|
- | 407 | } |
|
- | 408 | ||
- | 409 | static int |
|
- | 410 | drm_atomic_replace_property_blob_from_id(struct drm_crtc *crtc, |
|
- | 411 | struct drm_property_blob **blob, |
|
- | 412 | uint64_t blob_id, |
|
- | 413 | ssize_t expected_size, |
|
- | 414 | bool *replaced) |
|
- | 415 | { |
|
- | 416 | struct drm_device *dev = crtc->dev; |
|
- | 417 | struct drm_property_blob *new_blob = NULL; |
|
- | 418 | ||
- | 419 | if (blob_id != 0) { |
|
- | 420 | new_blob = drm_property_lookup_blob(dev, blob_id); |
|
- | 421 | if (new_blob == NULL) |
|
- | 422 | return -EINVAL; |
|
- | 423 | if (expected_size > 0 && expected_size != new_blob->length) |
|
- | 424 | return -EINVAL; |
|
- | 425 | } |
|
- | 426 | ||
- | 427 | drm_atomic_replace_property_blob(blob, new_blob, replaced); |
|
- | 428 | ||
- | 429 | return 0; |
|
- | 430 | } |
|
377 | 431 | ||
378 | /** |
432 | /** |
379 | * drm_atomic_crtc_set_property - set property on CRTC |
433 | * drm_atomic_crtc_set_property - set property on CRTC |
380 | * @crtc: the drm CRTC to set a property on |
434 | * @crtc: the drm CRTC to set a property on |
381 | * @state: the state object to update with the new property value |
435 | * @state: the state object to update with the new property value |
Line 395... | Line 449... | ||
395 | struct drm_crtc_state *state, struct drm_property *property, |
449 | struct drm_crtc_state *state, struct drm_property *property, |
396 | uint64_t val) |
450 | uint64_t val) |
397 | { |
451 | { |
398 | struct drm_device *dev = crtc->dev; |
452 | struct drm_device *dev = crtc->dev; |
399 | struct drm_mode_config *config = &dev->mode_config; |
453 | struct drm_mode_config *config = &dev->mode_config; |
- | 454 | bool replaced = false; |
|
400 | int ret; |
455 | int ret; |
Line 401... | Line 456... | ||
401 | 456 | ||
402 | if (property == config->prop_active) |
457 | if (property == config->prop_active) |
403 | state->active = val; |
458 | state->active = val; |
404 | else if (property == config->prop_mode_id) { |
459 | else if (property == config->prop_mode_id) { |
405 | struct drm_property_blob *mode = |
460 | struct drm_property_blob *mode = |
406 | drm_property_lookup_blob(dev, val); |
461 | drm_property_lookup_blob(dev, val); |
407 | ret = drm_atomic_set_mode_prop_for_crtc(state, mode); |
462 | ret = drm_atomic_set_mode_prop_for_crtc(state, mode); |
408 | drm_property_unreference_blob(mode); |
463 | drm_property_unreference_blob(mode); |
- | 464 | return ret; |
|
- | 465 | } else if (property == config->degamma_lut_property) { |
|
- | 466 | ret = drm_atomic_replace_property_blob_from_id(crtc, |
|
- | 467 | &state->degamma_lut, |
|
409 | return ret; |
468 | val, |
- | 469 | -1, |
|
- | 470 | &replaced); |
|
- | 471 | state->color_mgmt_changed = replaced; |
|
- | 472 | return ret; |
|
- | 473 | } else if (property == config->ctm_property) { |
|
- | 474 | ret = drm_atomic_replace_property_blob_from_id(crtc, |
|
- | 475 | &state->ctm, |
|
- | 476 | val, |
|
- | 477 | sizeof(struct drm_color_ctm), |
|
- | 478 | &replaced); |
|
- | 479 | state->color_mgmt_changed = replaced; |
|
- | 480 | return ret; |
|
- | 481 | } else if (property == config->gamma_lut_property) { |
|
- | 482 | ret = drm_atomic_replace_property_blob_from_id(crtc, |
|
- | 483 | &state->gamma_lut, |
|
- | 484 | val, |
|
- | 485 | -1, |
|
- | 486 | &replaced); |
|
- | 487 | state->color_mgmt_changed = replaced; |
|
410 | } |
488 | return ret; |
411 | else if (crtc->funcs->atomic_set_property) |
489 | } else if (crtc->funcs->atomic_set_property) |
412 | return crtc->funcs->atomic_set_property(crtc, state, property, val); |
490 | return crtc->funcs->atomic_set_property(crtc, state, property, val); |
413 | else |
491 | else |
Line 414... | Line 492... | ||
414 | return -EINVAL; |
492 | return -EINVAL; |
Line 442... | Line 520... | ||
442 | 520 | ||
443 | if (property == config->prop_active) |
521 | if (property == config->prop_active) |
444 | *val = state->active; |
522 | *val = state->active; |
445 | else if (property == config->prop_mode_id) |
523 | else if (property == config->prop_mode_id) |
- | 524 | *val = (state->mode_blob) ? state->mode_blob->base.id : 0; |
|
- | 525 | else if (property == config->degamma_lut_property) |
|
- | 526 | *val = (state->degamma_lut) ? state->degamma_lut->base.id : 0; |
|
- | 527 | else if (property == config->ctm_property) |
|
- | 528 | *val = (state->ctm) ? state->ctm->base.id : 0; |
|
- | 529 | else if (property == config->gamma_lut_property) |
|
446 | *val = (state->mode_blob) ? state->mode_blob->base.id : 0; |
530 | *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0; |
447 | else if (crtc->funcs->atomic_get_property) |
531 | else if (crtc->funcs->atomic_get_property) |
448 | return crtc->funcs->atomic_get_property(crtc, state, property, val); |
532 | return crtc->funcs->atomic_get_property(crtc, state, property, val); |
449 | else |
533 | else |
Line 1202... | Line 1286... | ||
1202 | * -EDEADLK semantics. For simplicity this one will grab all modeset locks after |
1286 | * -EDEADLK semantics. For simplicity this one will grab all modeset locks after |
1203 | * the slowpath completed. |
1287 | * the slowpath completed. |
1204 | */ |
1288 | */ |
1205 | void drm_atomic_legacy_backoff(struct drm_atomic_state *state) |
1289 | void drm_atomic_legacy_backoff(struct drm_atomic_state *state) |
1206 | { |
1290 | { |
- | 1291 | struct drm_device *dev = state->dev; |
|
- | 1292 | unsigned crtc_mask = 0; |
|
- | 1293 | struct drm_crtc *crtc; |
|
1207 | int ret; |
1294 | int ret; |
- | 1295 | bool global = false; |
|
- | 1296 | ||
- | 1297 | drm_for_each_crtc(crtc, dev) { |
|
- | 1298 | if (crtc->acquire_ctx != state->acquire_ctx) |
|
- | 1299 | continue; |
|
- | 1300 | ||
- | 1301 | crtc_mask |= drm_crtc_mask(crtc); |
|
- | 1302 | crtc->acquire_ctx = NULL; |
|
- | 1303 | } |
|
- | 1304 | ||
- | 1305 | if (WARN_ON(dev->mode_config.acquire_ctx == state->acquire_ctx)) { |
|
- | 1306 | global = true; |
|
- | 1307 | ||
- | 1308 | dev->mode_config.acquire_ctx = NULL; |
|
- | 1309 | } |
|
Line 1208... | Line 1310... | ||
1208 | 1310 | ||
1209 | retry: |
1311 | retry: |
Line 1210... | Line 1312... | ||
1210 | drm_modeset_backoff(state->acquire_ctx); |
1312 | drm_modeset_backoff(state->acquire_ctx); |
1211 | 1313 | ||
1212 | ret = drm_modeset_lock_all_ctx(state->dev, state->acquire_ctx); |
1314 | ret = drm_modeset_lock_all_ctx(dev, state->acquire_ctx); |
- | 1315 | if (ret) |
|
- | 1316 | goto retry; |
|
- | 1317 | ||
- | 1318 | drm_for_each_crtc(crtc, dev) |
|
- | 1319 | if (drm_crtc_mask(crtc) & crtc_mask) |
|
- | 1320 | crtc->acquire_ctx = state->acquire_ctx; |
|
- | 1321 | ||
1213 | if (ret) |
1322 | if (global) |
1214 | goto retry; |
1323 | dev->mode_config.acquire_ctx = state->acquire_ctx; |
Line 1215... | Line 1324... | ||
1215 | } |
1324 | } |
1216 | EXPORT_SYMBOL(drm_atomic_legacy_backoff); |
1325 | EXPORT_SYMBOL(drm_atomic_legacy_backoff); |
Line 1341... | Line 1450... | ||
1341 | 1450 | ||
1342 | static struct drm_pending_vblank_event *create_vblank_event( |
1451 | static struct drm_pending_vblank_event *create_vblank_event( |
1343 | struct drm_device *dev, struct drm_file *file_priv, uint64_t user_data) |
1452 | struct drm_device *dev, struct drm_file *file_priv, uint64_t user_data) |
1344 | { |
1453 | { |
1345 | struct drm_pending_vblank_event *e = NULL; |
- | |
1346 | unsigned long flags; |
- | |
1347 | - | ||
1348 | spin_lock_irqsave(&dev->event_lock, flags); |
- | |
1349 | if (file_priv->event_space < sizeof e->event) { |
- | |
1350 | spin_unlock_irqrestore(&dev->event_lock, flags); |
1454 | struct drm_pending_vblank_event *e = NULL; |
1351 | goto out; |
- | |
1352 | } |
- | |
1353 | file_priv->event_space -= sizeof e->event; |
- | |
Line 1354... | Line 1455... | ||
1354 | spin_unlock_irqrestore(&dev->event_lock, flags); |
1455 | int ret; |
1355 | 1456 | ||
1356 | e = kzalloc(sizeof *e, GFP_KERNEL); |
- | |
1357 | if (e == NULL) { |
- | |
1358 | spin_lock_irqsave(&dev->event_lock, flags); |
- | |
1359 | file_priv->event_space += sizeof e->event; |
1457 | e = kzalloc(sizeof *e, GFP_KERNEL); |
1360 | spin_unlock_irqrestore(&dev->event_lock, flags); |
- | |
Line 1361... | Line 1458... | ||
1361 | goto out; |
1458 | if (!e) |
1362 | } |
1459 | return NULL; |
1363 | 1460 | ||
1364 | e->event.base.type = DRM_EVENT_FLIP_COMPLETE; |
- | |
1365 | e->event.base.length = sizeof e->event; |
- | |
1366 | e->event.user_data = user_data; |
- | |
Line -... | Line 1461... | ||
- | 1461 | e->event.base.type = DRM_EVENT_FLIP_COMPLETE; |
|
1367 | e->base.event = &e->event.base; |
1462 | e->event.base.length = sizeof(e->event); |
- | 1463 | e->event.user_data = user_data; |
|
1368 | e->base.file_priv = file_priv; |
1464 | |
1369 | e->base.destroy = (void (*) (struct drm_pending_event *)) kfree; |
1465 | ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base); |
Line 1370... | Line -... | ||
1370 | - | ||
1371 | out: |
- | |
1372 | return e; |
- | |
1373 | } |
- | |
1374 | - | ||
1375 | static void destroy_vblank_event(struct drm_device *dev, |
- | |
1376 | struct drm_file *file_priv, struct drm_pending_vblank_event *e) |
- | |
1377 | { |
- | |
1378 | unsigned long flags; |
1466 | if (ret) { |
1379 | 1467 | kfree(e); |
|
Line 1380... | Line 1468... | ||
1380 | spin_lock_irqsave(&dev->event_lock, flags); |
1468 | return NULL; |
1381 | file_priv->event_space += sizeof e->event; |
1469 | } |
1382 | spin_unlock_irqrestore(&dev->event_lock, flags); |
1470 |