core: - uapi: error out EBUSY when existing master - uapi: rework SET/DROP MASTER permission handling - remove drm_pci.h - drm_pci* are now legacy - introduced managed DRM resources - subclassing support for drm_framebuffer - simple encoder helper - edid improvements - vblank + writeback documentation improved - drm/mm - optimise tree searches - port drivers to use devm_drm_dev_alloc dma-buf: - add flag for p2p buffer support mst: - ACT timeout improvements - remove drm_dp_mst_has_audio - don't use 2nd TX slot - spec recommends against it bridge: - dw-hdmi various improvements - chrontel ch7033 support - fix stack issues with old gcc hdmi: - add unpack function for drm infoframe fbdev: - misc fbdev driver fixes i915: - uapi: global sseu pinning - uapi: OA buffer polling - uapi: remove generated perf code - uapi: per-engine default property values in sysfs - Tigerlake GEN12 enabled. - Lots of gem refactoring - Tigerlake enablement patches - move to drm_device logging - Icelake gamma HW readout - push MST link retrain to hotplug work - bandwidth atomic helpers - ICL fixes - RPS/GT refactoring - Cherryview full-ppgtt support - i915 locking guidelines documented - require linear fb stride to be 512 multiple on gen9 - Tigerlake SAGV support amdgpu: - uapi: encrypted GPU memory handling - uapi: add MEM_SYNC IB flag - p2p dma-buf support - export VRAM dma-bufs - FRU chip access support - RAS/SR-IOV updates - Powerplay locking fixes - VCN DPG (powergating) enablement - GFX10 clockgating fixes - DC fixes - GPU reset fixes - navi SDMA fix - expose FP16 for modesetting - DP 1.4 compliance fixes - gfx10 soft recovery - Improved Critical Thermal Faults handling - resizable BAR on gmc10 amdkfd: - uapi: GWS resource management - track GPU memory per process - report PCI domain in topology radeon: - safe reg list generator fixes nouveau: - HD audio fixes on recent systems - vGPU detection (fail probe if we're on one, for now) - Interlaced mode fixes (mostly avoidance on Turing, which doesn't support it) - SVM improvements/fixes - NVIDIA format modifier support - Misc other fixes. adv7511: - HDMI SPDIF support ast: - allocate crtc state size - fix double assignment - fix suspend bochs: - drop connector register cirrus: - move to tiny drivers. exynos: - fix imported dma-buf mapping - enable runtime PM - fixes and cleanups mediatek: - DPI pin mode swap - config mipi_tx current/impedance lima: - devfreq + cooling device support - task handling improvements - runtime PM support pl111: - vexpress init improvements - fix module auto-load rcar-du: - DT bindings conversion to YAML - Planes zpos sanity check and fix - MAINTAINERS entry for LVDS panel driver mcde: - fix return value mgag200: - use managed config init stm: - read endpoints from DT vboxvideo: - use PCI managed functions - drop WC mtrr vkms: - enable cursor by default rockchip: - afbc support virtio: - various cleanups qxl: - fix cursor notify port hisilicon: - 128-byte stride alignment fix sun4i: - improved format handling -----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJe1edsAAoJEAx081l5xIa+bKEQAJAZv/8OMM2rx+p+GyKgrNpl ihTX/oyToy8dw97s1kWF7V5kKU+qjF8aWlKoPS0xovzaMAzYSFz9FRNEUgqtTXMI zIAzSXioqP21oL9/ZTHcXDULtz8Gk3uiPomgXMWLlNBdt3X5qvCwsmPRIYSwG0GJ 00VCvxDbVxGSM3wzcvbfyRwHCq3SrFvIusXv5jHnnxEFGH0C7Mj2/FLYMKLNjvli Q8VEI2wQPZj1QdA8fLFVneIQsR6YUSko9OfFMANP8VJGpPMnUkvVxTJ5ACGJspvn U/h6NYqJeUU2Y3BSKqtjIC3a1LY51tp5tL9q4H9TD1hqMckt6F2V7T2IeFU8i6+V YzUsSiT4q1xB+uiFVcgopx2hyIp8INOEyWrVdYgw2JviROeRD+pDHvJd13ZNMnTe GvLWQ/PfBFrcz8eligjiYjOf66ZTU+j/rivaOBFyrs9gdlsaEW2QRurFrcNX+0lZ kDbLsIFjhYnPXsvHP87x4BuQCKQIEh8wWuxXuJjunBPdqVrJyltZWbBiKO571b5/ BtX6xj6ztUOffR2RdiVanzY546I2hEi7SHMUuWnMqXsOV46GBN0QvlpZad/47n9x ZUy8HDDD0/qWuGwvPOJGIeAnUteWge9AhWXTeN5+1h5m+QEOzYkPKqC3Hp8TW1pM gToTWgAhnu731fhzLWyt =H7IS -----END PGP SIGNATURE----- Merge tag 'drm-next-2020-06-02' of git://anongit.freedesktop.org/drm/drm Pull drm updates from Dave Airlie: "Highlights: - Core DRM had a lot of refactoring around managed drm resources to make drivers simpler. - Intel Tigerlake support is on by default - amdgpu now support p2p PCI buffer sharing and encrypted GPU memory Details: core: - uapi: error out EBUSY when existing master - uapi: rework SET/DROP MASTER permission handling - remove drm_pci.h - drm_pci* are now legacy - introduced managed DRM resources - subclassing support for drm_framebuffer - simple encoder helper - edid improvements - vblank + writeback documentation improved - drm/mm - optimise tree searches - port drivers to use devm_drm_dev_alloc dma-buf: - add flag for p2p buffer support mst: - ACT timeout improvements - remove drm_dp_mst_has_audio - don't use 2nd TX slot - spec recommends against it bridge: - dw-hdmi various improvements - chrontel ch7033 support - fix stack issues with old gcc hdmi: - add unpack function for drm infoframe fbdev: - misc fbdev driver fixes i915: - uapi: global sseu pinning - uapi: OA buffer polling - uapi: remove generated perf code - uapi: per-engine default property values in sysfs - Tigerlake GEN12 enabled. - Lots of gem refactoring - Tigerlake enablement patches - move to drm_device logging - Icelake gamma HW readout - push MST link retrain to hotplug work - bandwidth atomic helpers - ICL fixes - RPS/GT refactoring - Cherryview full-ppgtt support - i915 locking guidelines documented - require linear fb stride to be 512 multiple on gen9 - Tigerlake SAGV support amdgpu: - uapi: encrypted GPU memory handling - uapi: add MEM_SYNC IB flag - p2p dma-buf support - export VRAM dma-bufs - FRU chip access support - RAS/SR-IOV updates - Powerplay locking fixes - VCN DPG (powergating) enablement - GFX10 clockgating fixes - DC fixes - GPU reset fixes - navi SDMA fix - expose FP16 for modesetting - DP 1.4 compliance fixes - gfx10 soft recovery - Improved Critical Thermal Faults handling - resizable BAR on gmc10 amdkfd: - uapi: GWS resource management - track GPU memory per process - report PCI domain in topology radeon: - safe reg list generator fixes nouveau: - HD audio fixes on recent systems - vGPU detection (fail probe if we're on one, for now) - Interlaced mode fixes (mostly avoidance on Turing, which doesn't support it) - SVM improvements/fixes - NVIDIA format modifier support - Misc other fixes. adv7511: - HDMI SPDIF support ast: - allocate crtc state size - fix double assignment - fix suspend bochs: - drop connector register cirrus: - move to tiny drivers. exynos: - fix imported dma-buf mapping - enable runtime PM - fixes and cleanups mediatek: - DPI pin mode swap - config mipi_tx current/impedance lima: - devfreq + cooling device support - task handling improvements - runtime PM support pl111: - vexpress init improvements - fix module auto-load rcar-du: - DT bindings conversion to YAML - Planes zpos sanity check and fix - MAINTAINERS entry for LVDS panel driver mcde: - fix return value mgag200: - use managed config init stm: - read endpoints from DT vboxvideo: - use PCI managed functions - drop WC mtrr vkms: - enable cursor by default rockchip: - afbc support virtio: - various cleanups qxl: - fix cursor notify port hisilicon: - 128-byte stride alignment fix sun4i: - improved format handling" * tag 'drm-next-2020-06-02' of git://anongit.freedesktop.org/drm/drm: (1401 commits) drm/amd/display: Fix potential integer wraparound resulting in a hang drm/amd/display: drop cursor position check in atomic test drm/amdgpu: fix device attribute node create failed with multi gpu drm/nouveau: use correct conflicting framebuffer API drm/vblank: Fix -Wformat compile warnings on some arches drm/amdgpu: Sync with VM root BO when switching VM to CPU update mode drm/amd/display: Handle GPU reset for DC block drm/amdgpu: add apu flags (v2) drm/amd/powerpay: Disable gfxoff when setting manual mode on picasso and raven drm/amdgpu: fix pm sysfs node handling (v2) drm/amdgpu: move gpu_info parsing after common early init drm/amdgpu: move discovery gfx config fetching drm/nouveau/dispnv50: fix runtime pm imbalance on error drm/nouveau: fix runtime pm imbalance on error drm/nouveau: fix runtime pm imbalance on error drm/nouveau/debugfs: fix runtime pm imbalance on error drm/nouveau/nouveau/hmm: fix migrate zero page to GPU drm/nouveau/nouveau/hmm: fix nouveau_dmem_chunk allocations drm/nouveau/kms/nv50-: Share DP SST mode_valid() handling with MST drm/nouveau/kms/nv50-: Move 8BPC limit for MST into nv50_mstc_get_modes() ...
230 lines
6.2 KiB
C
230 lines
6.2 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
|
|
* Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
|
|
*/
|
|
|
|
#include <drm/drm_atomic.h>
|
|
#include <drm/drm_atomic_helper.h>
|
|
#include <drm/drm_crtc.h>
|
|
#include <drm/drm_crtc_helper.h>
|
|
#include <drm/drm_fourcc.h>
|
|
#include <drm/drm_fb_cma_helper.h>
|
|
|
|
#include "tidss_crtc.h"
|
|
#include "tidss_dispc.h"
|
|
#include "tidss_drv.h"
|
|
#include "tidss_plane.h"
|
|
|
|
/* drm_plane_helper_funcs */
|
|
|
|
static int tidss_plane_atomic_check(struct drm_plane *plane,
|
|
struct drm_plane_state *state)
|
|
{
|
|
struct drm_device *ddev = plane->dev;
|
|
struct tidss_device *tidss = to_tidss(ddev);
|
|
struct tidss_plane *tplane = to_tidss_plane(plane);
|
|
const struct drm_format_info *finfo;
|
|
struct drm_crtc_state *crtc_state;
|
|
u32 hw_plane = tplane->hw_plane_id;
|
|
u32 hw_videoport;
|
|
int ret;
|
|
|
|
dev_dbg(ddev->dev, "%s\n", __func__);
|
|
|
|
if (!state->crtc) {
|
|
/*
|
|
* The visible field is not reset by the DRM core but only
|
|
* updated by drm_plane_helper_check_state(), set it manually.
|
|
*/
|
|
state->visible = false;
|
|
return 0;
|
|
}
|
|
|
|
crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
|
|
if (IS_ERR(crtc_state))
|
|
return PTR_ERR(crtc_state);
|
|
|
|
ret = drm_atomic_helper_check_plane_state(state, crtc_state, 0,
|
|
INT_MAX, true, true);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
/*
|
|
* The HW is only able to start drawing at subpixel boundary
|
|
* (the two first checks bellow). At the end of a row the HW
|
|
* can only jump integer number of subpixels forward to the
|
|
* beginning of the next row. So we can only show picture with
|
|
* integer subpixel width (the third check). However, after
|
|
* reaching the end of the drawn picture the drawing starts
|
|
* again at the absolute memory address where top left corner
|
|
* position of the drawn picture is (so there is no need to
|
|
* check for odd height).
|
|
*/
|
|
|
|
finfo = drm_format_info(state->fb->format->format);
|
|
|
|
if ((state->src_x >> 16) % finfo->hsub != 0) {
|
|
dev_dbg(ddev->dev,
|
|
"%s: x-position %u not divisible subpixel size %u\n",
|
|
__func__, (state->src_x >> 16), finfo->hsub);
|
|
return -EINVAL;
|
|
}
|
|
|
|
if ((state->src_y >> 16) % finfo->vsub != 0) {
|
|
dev_dbg(ddev->dev,
|
|
"%s: y-position %u not divisible subpixel size %u\n",
|
|
__func__, (state->src_y >> 16), finfo->vsub);
|
|
return -EINVAL;
|
|
}
|
|
|
|
if ((state->src_w >> 16) % finfo->hsub != 0) {
|
|
dev_dbg(ddev->dev,
|
|
"%s: src width %u not divisible by subpixel size %u\n",
|
|
__func__, (state->src_w >> 16), finfo->hsub);
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (!state->visible)
|
|
return 0;
|
|
|
|
hw_videoport = to_tidss_crtc(state->crtc)->hw_videoport;
|
|
|
|
ret = dispc_plane_check(tidss->dispc, hw_plane, state, hw_videoport);
|
|
if (ret)
|
|
return ret;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void tidss_plane_atomic_update(struct drm_plane *plane,
|
|
struct drm_plane_state *old_state)
|
|
{
|
|
struct drm_device *ddev = plane->dev;
|
|
struct tidss_device *tidss = to_tidss(ddev);
|
|
struct tidss_plane *tplane = to_tidss_plane(plane);
|
|
struct drm_plane_state *state = plane->state;
|
|
u32 hw_videoport;
|
|
int ret;
|
|
|
|
dev_dbg(ddev->dev, "%s\n", __func__);
|
|
|
|
if (!state->visible) {
|
|
dispc_plane_enable(tidss->dispc, tplane->hw_plane_id, false);
|
|
return;
|
|
}
|
|
|
|
hw_videoport = to_tidss_crtc(state->crtc)->hw_videoport;
|
|
|
|
ret = dispc_plane_setup(tidss->dispc, tplane->hw_plane_id,
|
|
state, hw_videoport);
|
|
|
|
if (ret) {
|
|
dev_err(plane->dev->dev, "%s: Failed to setup plane %d\n",
|
|
__func__, tplane->hw_plane_id);
|
|
dispc_plane_enable(tidss->dispc, tplane->hw_plane_id, false);
|
|
return;
|
|
}
|
|
|
|
dispc_plane_enable(tidss->dispc, tplane->hw_plane_id, true);
|
|
}
|
|
|
|
static void tidss_plane_atomic_disable(struct drm_plane *plane,
|
|
struct drm_plane_state *old_state)
|
|
{
|
|
struct drm_device *ddev = plane->dev;
|
|
struct tidss_device *tidss = to_tidss(ddev);
|
|
struct tidss_plane *tplane = to_tidss_plane(plane);
|
|
|
|
dev_dbg(ddev->dev, "%s\n", __func__);
|
|
|
|
dispc_plane_enable(tidss->dispc, tplane->hw_plane_id, false);
|
|
}
|
|
|
|
static void drm_plane_destroy(struct drm_plane *plane)
|
|
{
|
|
struct tidss_plane *tplane = to_tidss_plane(plane);
|
|
|
|
drm_plane_cleanup(plane);
|
|
kfree(tplane);
|
|
}
|
|
|
|
static const struct drm_plane_helper_funcs tidss_plane_helper_funcs = {
|
|
.atomic_check = tidss_plane_atomic_check,
|
|
.atomic_update = tidss_plane_atomic_update,
|
|
.atomic_disable = tidss_plane_atomic_disable,
|
|
};
|
|
|
|
static const struct drm_plane_funcs tidss_plane_funcs = {
|
|
.update_plane = drm_atomic_helper_update_plane,
|
|
.disable_plane = drm_atomic_helper_disable_plane,
|
|
.reset = drm_atomic_helper_plane_reset,
|
|
.destroy = drm_plane_destroy,
|
|
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
|
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
|
|
};
|
|
|
|
struct tidss_plane *tidss_plane_create(struct tidss_device *tidss,
|
|
u32 hw_plane_id, u32 plane_type,
|
|
u32 crtc_mask, const u32 *formats,
|
|
u32 num_formats)
|
|
{
|
|
struct tidss_plane *tplane;
|
|
enum drm_plane_type type;
|
|
u32 possible_crtcs;
|
|
u32 num_planes = tidss->feat->num_planes;
|
|
u32 color_encodings = (BIT(DRM_COLOR_YCBCR_BT601) |
|
|
BIT(DRM_COLOR_YCBCR_BT709));
|
|
u32 color_ranges = (BIT(DRM_COLOR_YCBCR_FULL_RANGE) |
|
|
BIT(DRM_COLOR_YCBCR_LIMITED_RANGE));
|
|
u32 default_encoding = DRM_COLOR_YCBCR_BT601;
|
|
u32 default_range = DRM_COLOR_YCBCR_FULL_RANGE;
|
|
u32 blend_modes = (BIT(DRM_MODE_BLEND_PREMULTI) |
|
|
BIT(DRM_MODE_BLEND_COVERAGE));
|
|
int ret;
|
|
|
|
tplane = kzalloc(sizeof(*tplane), GFP_KERNEL);
|
|
if (!tplane)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
tplane->hw_plane_id = hw_plane_id;
|
|
|
|
possible_crtcs = crtc_mask;
|
|
type = plane_type;
|
|
|
|
ret = drm_universal_plane_init(&tidss->ddev, &tplane->plane,
|
|
possible_crtcs,
|
|
&tidss_plane_funcs,
|
|
formats, num_formats,
|
|
NULL, type, NULL);
|
|
if (ret < 0)
|
|
goto err;
|
|
|
|
drm_plane_helper_add(&tplane->plane, &tidss_plane_helper_funcs);
|
|
|
|
drm_plane_create_zpos_property(&tplane->plane, hw_plane_id, 0,
|
|
num_planes - 1);
|
|
|
|
ret = drm_plane_create_color_properties(&tplane->plane,
|
|
color_encodings,
|
|
color_ranges,
|
|
default_encoding,
|
|
default_range);
|
|
if (ret)
|
|
goto err;
|
|
|
|
ret = drm_plane_create_alpha_property(&tplane->plane);
|
|
if (ret)
|
|
goto err;
|
|
|
|
ret = drm_plane_create_blend_mode_property(&tplane->plane, blend_modes);
|
|
if (ret)
|
|
goto err;
|
|
|
|
return tplane;
|
|
|
|
err:
|
|
kfree(tplane);
|
|
return ERR_PTR(ret);
|
|
}
|