Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/fb-helper: Move out commit code

Move the modeset commit code to drm_client_modeset.
No changes except exporting API.

v7: Export drm_client_panel_rotation() (Gerd Hoffmann)
v2: Move to drm_client_modeset.c instead of drm_client.c

Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20190531140117.37751-5-noralf@tronnes.org

+292 -282
+288
drivers/gpu/drm/drm_client_modeset.c
··· 11 11 #include <linux/mutex.h> 12 12 #include <linux/slab.h> 13 13 14 + #include <drm/drm_atomic.h> 14 15 #include <drm/drm_client.h> 15 16 #include <drm/drm_crtc.h> 16 17 #include <drm/drm_device.h> 18 + #include <drm/drm_drv.h> 19 + 20 + #include "drm_crtc_internal.h" 21 + #include "drm_internal.h" 17 22 18 23 int drm_client_modeset_create(struct drm_client_dev *client) 19 24 { ··· 107 102 } 108 103 /* TODO: Remove export when modeset code has been moved over */ 109 104 EXPORT_SYMBOL(drm_client_find_modeset); 105 + 106 + /** 107 + * drm_client_panel_rotation() - Check panel orientation 108 + * @modeset: DRM modeset 109 + * @rotation: Returned rotation value 110 + * 111 + * This function checks if the primary plane in @modeset can hw rotate to match 112 + * the panel orientation on its connector. 113 + * 114 + * Note: Currently only 0 and 180 degrees are supported. 115 + * 116 + * Return: 117 + * True if the plane can do the rotation, false otherwise. 118 + */ 119 + bool drm_client_panel_rotation(struct drm_mode_set *modeset, unsigned int *rotation) 120 + { 121 + struct drm_connector *connector = modeset->connectors[0]; 122 + struct drm_plane *plane = modeset->crtc->primary; 123 + u64 valid_mask = 0; 124 + unsigned int i; 125 + 126 + if (!modeset->num_connectors) 127 + return false; 128 + 129 + switch (connector->display_info.panel_orientation) { 130 + case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP: 131 + *rotation = DRM_MODE_ROTATE_180; 132 + break; 133 + case DRM_MODE_PANEL_ORIENTATION_LEFT_UP: 134 + *rotation = DRM_MODE_ROTATE_90; 135 + break; 136 + case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP: 137 + *rotation = DRM_MODE_ROTATE_270; 138 + break; 139 + default: 140 + *rotation = DRM_MODE_ROTATE_0; 141 + } 142 + 143 + /* 144 + * TODO: support 90 / 270 degree hardware rotation, 145 + * depending on the hardware this may require the framebuffer 146 + * to be in a specific tiling format. 147 + */ 148 + if (*rotation != DRM_MODE_ROTATE_180 || !plane->rotation_property) 149 + return false; 150 + 151 + for (i = 0; i < plane->rotation_property->num_values; i++) 152 + valid_mask |= (1ULL << plane->rotation_property->values[i]); 153 + 154 + if (!(*rotation & valid_mask)) 155 + return false; 156 + 157 + return true; 158 + } 159 + EXPORT_SYMBOL(drm_client_panel_rotation); 160 + 161 + static int drm_client_modeset_commit_atomic(struct drm_client_dev *client, bool active) 162 + { 163 + struct drm_device *dev = client->dev; 164 + struct drm_plane_state *plane_state; 165 + struct drm_plane *plane; 166 + struct drm_atomic_state *state; 167 + struct drm_modeset_acquire_ctx ctx; 168 + struct drm_mode_set *mode_set; 169 + int ret; 170 + 171 + drm_modeset_acquire_init(&ctx, 0); 172 + 173 + state = drm_atomic_state_alloc(dev); 174 + if (!state) { 175 + ret = -ENOMEM; 176 + goto out_ctx; 177 + } 178 + 179 + state->acquire_ctx = &ctx; 180 + retry: 181 + drm_for_each_plane(plane, dev) { 182 + plane_state = drm_atomic_get_plane_state(state, plane); 183 + if (IS_ERR(plane_state)) { 184 + ret = PTR_ERR(plane_state); 185 + goto out_state; 186 + } 187 + 188 + plane_state->rotation = DRM_MODE_ROTATE_0; 189 + 190 + /* disable non-primary: */ 191 + if (plane->type == DRM_PLANE_TYPE_PRIMARY) 192 + continue; 193 + 194 + ret = __drm_atomic_helper_disable_plane(plane, plane_state); 195 + if (ret != 0) 196 + goto out_state; 197 + } 198 + 199 + drm_client_for_each_modeset(mode_set, client) { 200 + struct drm_plane *primary = mode_set->crtc->primary; 201 + unsigned int rotation; 202 + 203 + if (drm_client_panel_rotation(mode_set, &rotation)) { 204 + /* Cannot fail as we've already gotten the plane state above */ 205 + plane_state = drm_atomic_get_new_plane_state(state, primary); 206 + plane_state->rotation = rotation; 207 + } 208 + 209 + ret = __drm_atomic_helper_set_config(mode_set, state); 210 + if (ret != 0) 211 + goto out_state; 212 + 213 + /* 214 + * __drm_atomic_helper_set_config() sets active when a 215 + * mode is set, unconditionally clear it if we force DPMS off 216 + */ 217 + if (!active) { 218 + struct drm_crtc *crtc = mode_set->crtc; 219 + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 220 + 221 + crtc_state->active = false; 222 + } 223 + } 224 + 225 + ret = drm_atomic_commit(state); 226 + 227 + out_state: 228 + if (ret == -EDEADLK) 229 + goto backoff; 230 + 231 + drm_atomic_state_put(state); 232 + out_ctx: 233 + drm_modeset_drop_locks(&ctx); 234 + drm_modeset_acquire_fini(&ctx); 235 + 236 + return ret; 237 + 238 + backoff: 239 + drm_atomic_state_clear(state); 240 + drm_modeset_backoff(&ctx); 241 + 242 + goto retry; 243 + } 244 + 245 + static int drm_client_modeset_commit_legacy(struct drm_client_dev *client) 246 + { 247 + struct drm_device *dev = client->dev; 248 + struct drm_mode_set *mode_set; 249 + struct drm_plane *plane; 250 + int ret = 0; 251 + 252 + drm_modeset_lock_all(dev); 253 + drm_for_each_plane(plane, dev) { 254 + if (plane->type != DRM_PLANE_TYPE_PRIMARY) 255 + drm_plane_force_disable(plane); 256 + 257 + if (plane->rotation_property) 258 + drm_mode_plane_set_obj_prop(plane, 259 + plane->rotation_property, 260 + DRM_MODE_ROTATE_0); 261 + } 262 + 263 + drm_client_for_each_modeset(mode_set, client) { 264 + struct drm_crtc *crtc = mode_set->crtc; 265 + 266 + if (crtc->funcs->cursor_set2) { 267 + ret = crtc->funcs->cursor_set2(crtc, NULL, 0, 0, 0, 0, 0); 268 + if (ret) 269 + goto out; 270 + } else if (crtc->funcs->cursor_set) { 271 + ret = crtc->funcs->cursor_set(crtc, NULL, 0, 0, 0); 272 + if (ret) 273 + goto out; 274 + } 275 + 276 + ret = drm_mode_set_config_internal(mode_set); 277 + if (ret) 278 + goto out; 279 + } 280 + out: 281 + drm_modeset_unlock_all(dev); 282 + 283 + return ret; 284 + } 285 + 286 + /** 287 + * drm_client_modeset_commit_force() - Force commit CRTC configuration 288 + * @client: DRM client 289 + * 290 + * Commit modeset configuration to crtcs without checking if there is a DRM master. 291 + * 292 + * Returns: 293 + * Zero on success or negative error code on failure. 294 + */ 295 + int drm_client_modeset_commit_force(struct drm_client_dev *client) 296 + { 297 + struct drm_device *dev = client->dev; 298 + int ret; 299 + 300 + mutex_lock(&client->modeset_mutex); 301 + if (drm_drv_uses_atomic_modeset(dev)) 302 + ret = drm_client_modeset_commit_atomic(client, true); 303 + else 304 + ret = drm_client_modeset_commit_legacy(client); 305 + mutex_unlock(&client->modeset_mutex); 306 + 307 + return ret; 308 + } 309 + EXPORT_SYMBOL(drm_client_modeset_commit_force); 310 + 311 + /** 312 + * drm_client_modeset_commit() - Commit CRTC configuration 313 + * @client: DRM client 314 + * 315 + * Commit modeset configuration to crtcs. 316 + * 317 + * Returns: 318 + * Zero on success or negative error code on failure. 319 + */ 320 + int drm_client_modeset_commit(struct drm_client_dev *client) 321 + { 322 + struct drm_device *dev = client->dev; 323 + int ret; 324 + 325 + if (!drm_master_internal_acquire(dev)) 326 + return -EBUSY; 327 + 328 + ret = drm_client_modeset_commit_force(client); 329 + 330 + drm_master_internal_release(dev); 331 + 332 + return ret; 333 + } 334 + EXPORT_SYMBOL(drm_client_modeset_commit); 335 + 336 + static void drm_client_modeset_dpms_legacy(struct drm_client_dev *client, int dpms_mode) 337 + { 338 + struct drm_device *dev = client->dev; 339 + struct drm_connector *connector; 340 + struct drm_mode_set *modeset; 341 + int j; 342 + 343 + drm_modeset_lock_all(dev); 344 + drm_client_for_each_modeset(modeset, client) { 345 + if (!modeset->crtc->enabled) 346 + continue; 347 + 348 + for (j = 0; j < modeset->num_connectors; j++) { 349 + connector = modeset->connectors[j]; 350 + connector->funcs->dpms(connector, dpms_mode); 351 + drm_object_property_set_value(&connector->base, 352 + dev->mode_config.dpms_property, dpms_mode); 353 + } 354 + } 355 + drm_modeset_unlock_all(dev); 356 + } 357 + 358 + /** 359 + * drm_client_modeset_dpms() - Set DPMS mode 360 + * @client: DRM client 361 + * @mode: DPMS mode 362 + * 363 + * Note: For atomic drivers @mode is reduced to on/off. 364 + * 365 + * Returns: 366 + * Zero on success or negative error code on failure. 367 + */ 368 + int drm_client_modeset_dpms(struct drm_client_dev *client, int mode) 369 + { 370 + struct drm_device *dev = client->dev; 371 + int ret = 0; 372 + 373 + if (!drm_master_internal_acquire(dev)) 374 + return -EBUSY; 375 + 376 + mutex_lock(&client->modeset_mutex); 377 + if (drm_drv_uses_atomic_modeset(dev)) 378 + ret = drm_client_modeset_commit_atomic(client, mode == DRM_MODE_DPMS_ON); 379 + else 380 + drm_client_modeset_dpms_legacy(client, mode); 381 + mutex_unlock(&client->modeset_mutex); 382 + 383 + drm_master_internal_release(dev); 384 + 385 + return ret; 386 + } 387 + EXPORT_SYMBOL(drm_client_modeset_dpms);
-282
drivers/gpu/drm/drm_fb_helper.c
··· 38 38 #include <linux/vmalloc.h> 39 39 40 40 #include <drm/drm_atomic.h> 41 - #include <drm/drm_atomic_helper.h> 42 41 #include <drm/drm_crtc.h> 43 42 #include <drm/drm_crtc_helper.h> 44 43 #include <drm/drm_drv.h> ··· 46 47 #include <drm/drm_print.h> 47 48 #include <drm/drm_vblank.h> 48 49 49 - #include "drm_crtc_helper_internal.h" 50 - #include "drm_crtc_internal.h" 51 50 #include "drm_internal.h" 52 51 53 52 static bool drm_fbdev_emulation = true; ··· 391 394 EXPORT_SYMBOL(drm_fb_helper_debug_leave); 392 395 393 396 /** 394 - * drm_client_panel_rotation() - Check panel orientation 395 - * @modeset: DRM modeset 396 - * @rotation: Returned rotation value 397 - * 398 - * This function checks if the primary plane in @modeset can hw rotate to match 399 - * the panel orientation on its connector. 400 - * 401 - * Note: Currently only 0 and 180 degrees are supported. 402 - * 403 - * Return: 404 - * True if the plane can do the rotation, false otherwise. 405 - */ 406 - bool drm_client_panel_rotation(struct drm_mode_set *modeset, unsigned int *rotation) 407 - { 408 - struct drm_connector *connector = modeset->connectors[0]; 409 - struct drm_plane *plane = modeset->crtc->primary; 410 - u64 valid_mask = 0; 411 - unsigned int i; 412 - 413 - if (!modeset->num_connectors) 414 - return false; 415 - 416 - switch (connector->display_info.panel_orientation) { 417 - case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP: 418 - *rotation = DRM_MODE_ROTATE_180; 419 - break; 420 - case DRM_MODE_PANEL_ORIENTATION_LEFT_UP: 421 - *rotation = DRM_MODE_ROTATE_90; 422 - break; 423 - case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP: 424 - *rotation = DRM_MODE_ROTATE_270; 425 - break; 426 - default: 427 - *rotation = DRM_MODE_ROTATE_0; 428 - } 429 - 430 - /* 431 - * TODO: support 90 / 270 degree hardware rotation, 432 - * depending on the hardware this may require the framebuffer 433 - * to be in a specific tiling format. 434 - */ 435 - if (*rotation != DRM_MODE_ROTATE_180 || !plane->rotation_property) 436 - return false; 437 - 438 - for (i = 0; i < plane->rotation_property->num_values; i++) 439 - valid_mask |= (1ULL << plane->rotation_property->values[i]); 440 - 441 - if (!(*rotation & valid_mask)) 442 - return false; 443 - 444 - return true; 445 - } 446 - 447 - static int drm_client_modeset_commit_atomic(struct drm_client_dev *client, bool active) 448 - { 449 - struct drm_device *dev = client->dev; 450 - struct drm_plane_state *plane_state; 451 - struct drm_plane *plane; 452 - struct drm_atomic_state *state; 453 - struct drm_modeset_acquire_ctx ctx; 454 - struct drm_mode_set *mode_set; 455 - int ret; 456 - 457 - drm_modeset_acquire_init(&ctx, 0); 458 - 459 - state = drm_atomic_state_alloc(dev); 460 - if (!state) { 461 - ret = -ENOMEM; 462 - goto out_ctx; 463 - } 464 - 465 - state->acquire_ctx = &ctx; 466 - retry: 467 - drm_for_each_plane(plane, dev) { 468 - plane_state = drm_atomic_get_plane_state(state, plane); 469 - if (IS_ERR(plane_state)) { 470 - ret = PTR_ERR(plane_state); 471 - goto out_state; 472 - } 473 - 474 - plane_state->rotation = DRM_MODE_ROTATE_0; 475 - 476 - /* disable non-primary: */ 477 - if (plane->type == DRM_PLANE_TYPE_PRIMARY) 478 - continue; 479 - 480 - ret = __drm_atomic_helper_disable_plane(plane, plane_state); 481 - if (ret != 0) 482 - goto out_state; 483 - } 484 - 485 - drm_client_for_each_modeset(mode_set, client) { 486 - struct drm_plane *primary = mode_set->crtc->primary; 487 - unsigned int rotation; 488 - 489 - if (drm_client_panel_rotation(mode_set, &rotation)) { 490 - /* Cannot fail as we've already gotten the plane state above */ 491 - plane_state = drm_atomic_get_new_plane_state(state, primary); 492 - plane_state->rotation = rotation; 493 - } 494 - 495 - ret = __drm_atomic_helper_set_config(mode_set, state); 496 - if (ret != 0) 497 - goto out_state; 498 - 499 - /* 500 - * __drm_atomic_helper_set_config() sets active when a 501 - * mode is set, unconditionally clear it if we force DPMS off 502 - */ 503 - if (!active) { 504 - struct drm_crtc *crtc = mode_set->crtc; 505 - struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 506 - 507 - crtc_state->active = false; 508 - } 509 - } 510 - 511 - ret = drm_atomic_commit(state); 512 - 513 - out_state: 514 - if (ret == -EDEADLK) 515 - goto backoff; 516 - 517 - drm_atomic_state_put(state); 518 - out_ctx: 519 - drm_modeset_drop_locks(&ctx); 520 - drm_modeset_acquire_fini(&ctx); 521 - 522 - return ret; 523 - 524 - backoff: 525 - drm_atomic_state_clear(state); 526 - drm_modeset_backoff(&ctx); 527 - 528 - goto retry; 529 - } 530 - 531 - static int drm_client_modeset_commit_legacy(struct drm_client_dev *client) 532 - { 533 - struct drm_device *dev = client->dev; 534 - struct drm_mode_set *mode_set; 535 - struct drm_plane *plane; 536 - int ret = 0; 537 - 538 - drm_modeset_lock_all(dev); 539 - drm_for_each_plane(plane, dev) { 540 - if (plane->type != DRM_PLANE_TYPE_PRIMARY) 541 - drm_plane_force_disable(plane); 542 - 543 - if (plane->rotation_property) 544 - drm_mode_plane_set_obj_prop(plane, 545 - plane->rotation_property, 546 - DRM_MODE_ROTATE_0); 547 - } 548 - 549 - drm_client_for_each_modeset(mode_set, client) { 550 - struct drm_crtc *crtc = mode_set->crtc; 551 - 552 - if (crtc->funcs->cursor_set2) { 553 - ret = crtc->funcs->cursor_set2(crtc, NULL, 0, 0, 0, 0, 0); 554 - if (ret) 555 - goto out; 556 - } else if (crtc->funcs->cursor_set) { 557 - ret = crtc->funcs->cursor_set(crtc, NULL, 0, 0, 0); 558 - if (ret) 559 - goto out; 560 - } 561 - 562 - ret = drm_mode_set_config_internal(mode_set); 563 - if (ret) 564 - goto out; 565 - } 566 - out: 567 - drm_modeset_unlock_all(dev); 568 - 569 - return ret; 570 - } 571 - 572 - /** 573 - * drm_client_modeset_commit_force() - Force commit CRTC configuration 574 - * @client: DRM client 575 - * 576 - * Commit modeset configuration to crtcs without checking if there is a DRM master. 577 - * 578 - * Returns: 579 - * Zero on success or negative error code on failure. 580 - */ 581 - int drm_client_modeset_commit_force(struct drm_client_dev *client) 582 - { 583 - struct drm_device *dev = client->dev; 584 - int ret; 585 - 586 - mutex_lock(&client->modeset_mutex); 587 - if (drm_drv_uses_atomic_modeset(dev)) 588 - ret = drm_client_modeset_commit_atomic(client, true); 589 - else 590 - ret = drm_client_modeset_commit_legacy(client); 591 - mutex_unlock(&client->modeset_mutex); 592 - 593 - return ret; 594 - } 595 - 596 - /** 597 - * drm_client_modeset_commit() - Commit CRTC configuration 598 - * @client: DRM client 599 - * 600 - * Commit modeset configuration to crtcs. 601 - * 602 - * Returns: 603 - * Zero on success or negative error code on failure. 604 - */ 605 - int drm_client_modeset_commit(struct drm_client_dev *client) 606 - { 607 - struct drm_device *dev = client->dev; 608 - int ret; 609 - 610 - if (!drm_master_internal_acquire(dev)) 611 - return -EBUSY; 612 - 613 - ret = drm_client_modeset_commit_force(client); 614 - 615 - drm_master_internal_release(dev); 616 - 617 - return ret; 618 - } 619 - 620 - /** 621 397 * drm_fb_helper_restore_fbdev_mode_unlocked - restore fbdev configuration 622 398 * @fb_helper: driver-allocated fbdev helper, can be NULL 623 399 * ··· 488 718 #else 489 719 static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { }; 490 720 #endif 491 - 492 - static void drm_client_modeset_dpms_legacy(struct drm_client_dev *client, int dpms_mode) 493 - { 494 - struct drm_device *dev = client->dev; 495 - struct drm_connector *connector; 496 - struct drm_mode_set *modeset; 497 - int j; 498 - 499 - drm_modeset_lock_all(dev); 500 - drm_client_for_each_modeset(modeset, client) { 501 - if (!modeset->crtc->enabled) 502 - continue; 503 - 504 - for (j = 0; j < modeset->num_connectors; j++) { 505 - connector = modeset->connectors[j]; 506 - connector->funcs->dpms(connector, dpms_mode); 507 - drm_object_property_set_value(&connector->base, 508 - dev->mode_config.dpms_property, dpms_mode); 509 - } 510 - } 511 - drm_modeset_unlock_all(dev); 512 - } 513 - 514 - /** 515 - * drm_client_modeset_dpms() - Set DPMS mode 516 - * @client: DRM client 517 - * @mode: DPMS mode 518 - * 519 - * Note: For atomic drivers @mode is reduced to on/off. 520 - * 521 - * Returns: 522 - * Zero on success or negative error code on failure. 523 - */ 524 - int drm_client_modeset_dpms(struct drm_client_dev *client, int mode) 525 - { 526 - struct drm_device *dev = client->dev; 527 - int ret = 0; 528 - 529 - if (!drm_master_internal_acquire(dev)) 530 - return -EBUSY; 531 - 532 - mutex_lock(&client->modeset_mutex); 533 - if (drm_drv_uses_atomic_modeset(dev)) 534 - ret = drm_client_modeset_commit_atomic(client, mode == DRM_MODE_DPMS_ON); 535 - else 536 - drm_client_modeset_dpms_legacy(client, mode); 537 - mutex_unlock(&client->modeset_mutex); 538 - 539 - drm_master_internal_release(dev); 540 - 541 - return ret; 542 - } 543 721 544 722 static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode) 545 723 {
+4
include/drm/drm_client.h
··· 155 155 void drm_client_modeset_free(struct drm_client_dev *client); 156 156 void drm_client_modeset_release(struct drm_client_dev *client); 157 157 struct drm_mode_set *drm_client_find_modeset(struct drm_client_dev *client, struct drm_crtc *crtc); 158 + bool drm_client_panel_rotation(struct drm_mode_set *modeset, unsigned int *rotation); 159 + int drm_client_modeset_commit_force(struct drm_client_dev *client); 160 + int drm_client_modeset_commit(struct drm_client_dev *client); 161 + int drm_client_modeset_dpms(struct drm_client_dev *client, int mode); 158 162 159 163 /** 160 164 * drm_client_for_each_modeset() - Iterate over client modesets