| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * (C) COPYRIGHT 2016 ARM Limited. All rights reserved. |
|---|
| 3 | 4 | * Author: Liviu Dudau <Liviu.Dudau@arm.com> |
|---|
| 4 | 5 | * |
|---|
| 5 | | - * This program is free software and is provided to you under the terms of the |
|---|
| 6 | | - * GNU General Public License version 2 as published by the Free Software |
|---|
| 7 | | - * Foundation, and any use by you of this program is subject to the terms |
|---|
| 8 | | - * of such GNU licence. |
|---|
| 9 | | - * |
|---|
| 10 | 6 | * ARM Mali DP500/DP550/DP650 driver (crtc operations) |
|---|
| 11 | 7 | */ |
|---|
| 12 | 8 | |
|---|
| 13 | | -#include <drm/drmP.h> |
|---|
| 9 | +#include <linux/clk.h> |
|---|
| 10 | +#include <linux/pm_runtime.h> |
|---|
| 11 | + |
|---|
| 12 | +#include <video/videomode.h> |
|---|
| 13 | + |
|---|
| 14 | 14 | #include <drm/drm_atomic.h> |
|---|
| 15 | 15 | #include <drm/drm_atomic_helper.h> |
|---|
| 16 | 16 | #include <drm/drm_crtc.h> |
|---|
| 17 | | -#include <drm/drm_crtc_helper.h> |
|---|
| 18 | | -#include <linux/clk.h> |
|---|
| 19 | | -#include <linux/pm_runtime.h> |
|---|
| 20 | | -#include <video/videomode.h> |
|---|
| 17 | +#include <drm/drm_print.h> |
|---|
| 18 | +#include <drm/drm_probe_helper.h> |
|---|
| 19 | +#include <drm/drm_vblank.h> |
|---|
| 21 | 20 | |
|---|
| 22 | 21 | #include "malidp_drv.h" |
|---|
| 23 | 22 | #include "malidp_hw.h" |
|---|
| .. | .. |
|---|
| 348 | 347 | |
|---|
| 349 | 348 | /* |
|---|
| 350 | 349 | * check if there is enough rotation memory available for planes |
|---|
| 351 | | - * that need 90° and 270° rotation. Each plane has set its required |
|---|
| 352 | | - * memory size in the ->plane_check() callback, here we only make |
|---|
| 353 | | - * sure that the sums are less that the total usable memory. |
|---|
| 350 | + * that need 90° and 270° rotion or planes that are compressed. |
|---|
| 351 | + * Each plane has set its required memory size in the ->plane_check() |
|---|
| 352 | + * callback, here we only make sure that the sums are less that the |
|---|
| 353 | + * total usable memory. |
|---|
| 354 | 354 | * |
|---|
| 355 | 355 | * The rotation memory allocation algorithm (for each plane): |
|---|
| 356 | | - * a. If no more rotated planes exist, all remaining rotate |
|---|
| 357 | | - * memory in the bank is available for use by the plane. |
|---|
| 358 | | - * b. If other rotated planes exist, and plane's layer ID is |
|---|
| 359 | | - * DE_VIDEO1, it can use all the memory from first bank if |
|---|
| 360 | | - * secondary rotation memory bank is available, otherwise it can |
|---|
| 356 | + * a. If no more rotated or compressed planes exist, all remaining |
|---|
| 357 | + * rotate memory in the bank is available for use by the plane. |
|---|
| 358 | + * b. If other rotated or compressed planes exist, and plane's |
|---|
| 359 | + * layer ID is DE_VIDEO1, it can use all the memory from first bank |
|---|
| 360 | + * if secondary rotation memory bank is available, otherwise it can |
|---|
| 361 | 361 | * use up to half the bank's memory. |
|---|
| 362 | | - * c. If other rotated planes exist, and plane's layer ID is not |
|---|
| 363 | | - * DE_VIDEO1, it can use half of the available memory |
|---|
| 362 | + * c. If other rotated or compressed planes exist, and plane's layer ID |
|---|
| 363 | + * is not DE_VIDEO1, it can use half of the available memory. |
|---|
| 364 | 364 | * |
|---|
| 365 | 365 | * Note: this algorithm assumes that the order in which the planes are |
|---|
| 366 | 366 | * checked always has DE_VIDEO1 plane first in the list if it is |
|---|
| .. | .. |
|---|
| 372 | 372 | |
|---|
| 373 | 373 | /* first count the number of rotated planes */ |
|---|
| 374 | 374 | drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) { |
|---|
| 375 | | - if (pstate->rotation & MALIDP_ROTATED_MASK) |
|---|
| 375 | + struct drm_framebuffer *fb = pstate->fb; |
|---|
| 376 | + |
|---|
| 377 | + if ((pstate->rotation & MALIDP_ROTATED_MASK) || fb->modifier) |
|---|
| 376 | 378 | rotated_planes++; |
|---|
| 377 | 379 | } |
|---|
| 378 | 380 | |
|---|
| .. | .. |
|---|
| 388 | 390 | drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) { |
|---|
| 389 | 391 | struct malidp_plane *mp = to_malidp_plane(plane); |
|---|
| 390 | 392 | struct malidp_plane_state *ms = to_malidp_plane_state(pstate); |
|---|
| 393 | + struct drm_framebuffer *fb = pstate->fb; |
|---|
| 391 | 394 | |
|---|
| 392 | | - if (pstate->rotation & MALIDP_ROTATED_MASK) { |
|---|
| 395 | + if ((pstate->rotation & MALIDP_ROTATED_MASK) || fb->modifier) { |
|---|
| 393 | 396 | /* process current plane */ |
|---|
| 394 | 397 | rotated_planes--; |
|---|
| 395 | 398 | |
|---|
| .. | .. |
|---|
| 459 | 462 | return &state->base; |
|---|
| 460 | 463 | } |
|---|
| 461 | 464 | |
|---|
| 462 | | -static void malidp_crtc_reset(struct drm_crtc *crtc) |
|---|
| 463 | | -{ |
|---|
| 464 | | - struct malidp_crtc_state *state = NULL; |
|---|
| 465 | | - |
|---|
| 466 | | - if (crtc->state) { |
|---|
| 467 | | - state = to_malidp_crtc_state(crtc->state); |
|---|
| 468 | | - __drm_atomic_helper_crtc_destroy_state(crtc->state); |
|---|
| 469 | | - } |
|---|
| 470 | | - |
|---|
| 471 | | - kfree(state); |
|---|
| 472 | | - state = kzalloc(sizeof(*state), GFP_KERNEL); |
|---|
| 473 | | - if (state) { |
|---|
| 474 | | - crtc->state = &state->base; |
|---|
| 475 | | - crtc->state->crtc = crtc; |
|---|
| 476 | | - } |
|---|
| 477 | | -} |
|---|
| 478 | | - |
|---|
| 479 | 465 | static void malidp_crtc_destroy_state(struct drm_crtc *crtc, |
|---|
| 480 | 466 | struct drm_crtc_state *state) |
|---|
| 481 | 467 | { |
|---|
| .. | .. |
|---|
| 489 | 475 | kfree(mali_state); |
|---|
| 490 | 476 | } |
|---|
| 491 | 477 | |
|---|
| 478 | +static void malidp_crtc_reset(struct drm_crtc *crtc) |
|---|
| 479 | +{ |
|---|
| 480 | + struct malidp_crtc_state *state = |
|---|
| 481 | + kzalloc(sizeof(*state), GFP_KERNEL); |
|---|
| 482 | + |
|---|
| 483 | + if (crtc->state) |
|---|
| 484 | + malidp_crtc_destroy_state(crtc, crtc->state); |
|---|
| 485 | + |
|---|
| 486 | + if (state) |
|---|
| 487 | + __drm_atomic_helper_crtc_reset(crtc, &state->base); |
|---|
| 488 | + else |
|---|
| 489 | + __drm_atomic_helper_crtc_reset(crtc, NULL); |
|---|
| 490 | +} |
|---|
| 491 | + |
|---|
| 492 | 492 | static int malidp_crtc_enable_vblank(struct drm_crtc *crtc) |
|---|
| 493 | 493 | { |
|---|
| 494 | 494 | struct malidp_drm *malidp = crtc_to_malidp_device(crtc); |
|---|