linux/drivers/gpu/drm/tegra/fb.c

184 lines
4.1 KiB
C
Raw Permalink Normal View History

// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2012-2013 Avionic Design GmbH
* Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
*
drm/fb: rename FB CMA helpers to FB DMA helpers Rename "FB CMA" helpers to "FB DMA" helpers - considering the hierarchy of APIs (mm/cma -> dma -> fb dma) calling them "FB DMA" seems to be more applicable. Besides that, commit e57924d4ae80 ("drm/doc: Task to rename CMA helpers") requests to rename the CMA helpers and implies that people seem to be confused about the naming. In order to do this renaming the following script was used: ``` #!/bin/bash DIRS="drivers/gpu include/drm Documentation/gpu" REGEX_SYM_UPPER="[0-9A-Z_\-]" REGEX_SYM_LOWER="[0-9a-z_\-]" REGEX_GREP_UPPER="(${REGEX_SYM_UPPER}*)(FB)_CMA_(${REGEX_SYM_UPPER}*)" REGEX_GREP_LOWER="(${REGEX_SYM_LOWER}*)(fb)_cma_(${REGEX_SYM_LOWER}*)" REGEX_SED_UPPER="s/${REGEX_GREP_UPPER}/\1\2_DMA_\3/g" REGEX_SED_LOWER="s/${REGEX_GREP_LOWER}/\1\2_dma_\3/g" # Find all upper case 'CMA' symbols and replace them with 'DMA'. for ff in $(grep -REHl "${REGEX_GREP_UPPER}" $DIRS) do sed -i -E "$REGEX_SED_UPPER" $ff done # Find all lower case 'cma' symbols and replace them with 'dma'. for ff in $(grep -REHl "${REGEX_GREP_LOWER}" $DIRS) do sed -i -E "$REGEX_SED_LOWER" $ff done # Replace all occurrences of 'CMA' / 'cma' in comments and # documentation files with 'DMA' / 'dma'. for ff in $(grep -RiHl " cma " $DIRS) do sed -i -E "s/ cma / dma /g" $ff sed -i -E "s/ CMA / DMA /g" $ff done ``` Only a few more manual modifications were needed, e.g. reverting the following modifications in some DRM Kconfig files - select CMA if HAVE_DMA_CONTIGUOUS + select DMA if HAVE_DMA_CONTIGUOUS as well as manually picking the occurrences of 'CMA'/'cma' in comments and documentation which relate to "FB CMA", but not "GEM CMA". This patch is compile-time tested building a x86_64 kernel with `make allyesconfig && make drivers/gpu/drm`. Acked-by: Sam Ravnborg <sam@ravnborg.org> Acked-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Danilo Krummrich <dakr@redhat.com> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com> #drivers/gpu/drm/arm Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Link: https://patchwork.freedesktop.org/patch/msgid/20220802000405.949236-3-dakr@redhat.com
2022-08-02 02:04:02 +02:00
* Based on the KMS/FB DMA helpers
* Copyright (C) 2012 Analog Devices Inc.
*/
#include <linux/console.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_framebuffer_helper.h>
drm: Split out drm_probe_helper.h Having the probe helper stuff (which pretty much everyone needs) in the drm_crtc_helper.h file (which atomic drivers should never need) is confusing. Split them out. To make sure I actually achieved the goal here I went through all drivers. And indeed, all atomic drivers are now free of drm_crtc_helper.h includes. v2: Make it compile. There was so much compile fail on arm drivers that I figured I'll better not include any of the acks on v1. v3: Massive rebase because i915 has lost a lot of drmP.h includes, but not all: Through drm_crtc_helper.h > drm_modeset_helper.h -> drmP.h there was still one, which this patch largely removes. Which means rolling out lots more includes all over. This will also conflict with ongoing drmP.h cleanup by others I expect. v3: Rebase on top of atomic bochs. v4: Review from Laurent for bridge/rcar/omap/shmob/core bits: - (re)move some of the added includes, use the better include files in other places (all suggested from Laurent adopted unchanged). - sort alphabetically v5: Actually try to sort them, and while at it, sort all the ones I touch. v6: Rebase onto i915 changes. v7: Rebase once more. Acked-by: Harry Wentland <harry.wentland@amd.com> Acked-by: Sam Ravnborg <sam@ravnborg.org> Cc: Sam Ravnborg <sam@ravnborg.org> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Acked-by: Benjamin Gaignard <benjamin.gaignard@linaro.org> Acked-by: Jani Nikula <jani.nikula@intel.com> Acked-by: Neil Armstrong <narmstrong@baylibre.com> Acked-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> Acked-by: CK Hu <ck.hu@mediatek.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Acked-by: Sam Ravnborg <sam@ravnborg.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Liviu Dudau <liviu.dudau@arm.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Cc: linux-arm-kernel@lists.infradead.org Cc: virtualization@lists.linux-foundation.org Cc: etnaviv@lists.freedesktop.org Cc: linux-samsung-soc@vger.kernel.org Cc: intel-gfx@lists.freedesktop.org Cc: linux-mediatek@lists.infradead.org Cc: linux-amlogic@lists.infradead.org Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: nouveau@lists.freedesktop.org Cc: spice-devel@lists.freedesktop.org Cc: amd-gfx@lists.freedesktop.org Cc: linux-renesas-soc@vger.kernel.org Cc: linux-rockchip@lists.infradead.org Cc: linux-stm32@st-md-mailman.stormreply.com Cc: linux-tegra@vger.kernel.org Cc: xen-devel@lists.xen.org Link: https://patchwork.freedesktop.org/patch/msgid/20190117210334.13234-1-daniel.vetter@ffwll.ch
2019-01-17 22:03:34 +01:00
#include <drm/drm_modeset_helper.h>
#include "drm.h"
#include "gem.h"
struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer,
unsigned int index)
{
return to_tegra_bo(drm_gem_fb_get_obj(framebuffer, index));
}
bool tegra_fb_is_bottom_up(struct drm_framebuffer *framebuffer)
{
struct tegra_bo *bo = tegra_fb_get_plane(framebuffer, 0);
if (bo->flags & TEGRA_BO_BOTTOM_UP)
return true;
return false;
}
int tegra_fb_get_tiling(struct drm_framebuffer *framebuffer,
struct tegra_bo_tiling *tiling)
{
uint64_t modifier = framebuffer->modifier;
if (fourcc_mod_is_vendor(modifier, NVIDIA)) {
if ((modifier & DRM_FORMAT_MOD_NVIDIA_SECTOR_LAYOUT) == 0)
tiling->sector_layout = TEGRA_BO_SECTOR_LAYOUT_TEGRA;
else
tiling->sector_layout = TEGRA_BO_SECTOR_LAYOUT_GPU;
modifier &= ~DRM_FORMAT_MOD_NVIDIA_SECTOR_LAYOUT;
}
switch (modifier) {
case DRM_FORMAT_MOD_LINEAR:
tiling->mode = TEGRA_BO_TILING_MODE_PITCH;
tiling->value = 0;
break;
case DRM_FORMAT_MOD_NVIDIA_TEGRA_TILED:
tiling->mode = TEGRA_BO_TILING_MODE_TILED;
tiling->value = 0;
break;
case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(0):
tiling->mode = TEGRA_BO_TILING_MODE_BLOCK;
tiling->value = 0;
break;
case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(1):
tiling->mode = TEGRA_BO_TILING_MODE_BLOCK;
tiling->value = 1;
break;
case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(2):
tiling->mode = TEGRA_BO_TILING_MODE_BLOCK;
tiling->value = 2;
break;
case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(3):
tiling->mode = TEGRA_BO_TILING_MODE_BLOCK;
tiling->value = 3;
break;
case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(4):
tiling->mode = TEGRA_BO_TILING_MODE_BLOCK;
tiling->value = 4;
break;
case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(5):
tiling->mode = TEGRA_BO_TILING_MODE_BLOCK;
tiling->value = 5;
break;
default:
DRM_DEBUG_KMS("unknown format modifier: %llx\n", modifier);
return -EINVAL;
}
return 0;
}
static const struct drm_framebuffer_funcs tegra_fb_funcs = {
.destroy = drm_gem_fb_destroy,
.create_handle = drm_gem_fb_create_handle,
};
struct drm_framebuffer *tegra_fb_alloc(struct drm_device *drm,
const struct drm_format_info *info,
const struct drm_mode_fb_cmd2 *mode_cmd,
struct tegra_bo **planes,
unsigned int num_planes)
{
struct drm_framebuffer *fb;
unsigned int i;
int err;
fb = kzalloc(sizeof(*fb), GFP_KERNEL);
if (!fb)
return ERR_PTR(-ENOMEM);
drm_helper_mode_fill_fb_struct(drm, fb, info, mode_cmd);
for (i = 0; i < fb->format->num_planes; i++)
fb->obj[i] = &planes[i]->gem;
err = drm_framebuffer_init(drm, fb, &tegra_fb_funcs);
if (err < 0) {
dev_err(drm->dev, "failed to initialize framebuffer: %d\n",
err);
kfree(fb);
return ERR_PTR(err);
}
return fb;
}
struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
struct drm_file *file,
drm: Pass the format info to .fb_create() Pass along the format information from the top to .fb_create() so that we can avoid redundant (and somewhat expensive) lookups in the drivers. Done with cocci (with some manual fixups): @@ identifier func =~ ".*create.*"; identifier dev, file, mode_cmd; @@ struct drm_framebuffer *func( struct drm_device *dev, struct drm_file *file, + const struct drm_format_info *info, const struct drm_mode_fb_cmd2 *mode_cmd) { ... ( - const struct drm_format_info *info = drm_get_format_info(...); | - const struct drm_format_info *info; ... - info = drm_get_format_info(...); ) <... - if (!info) - return ...; ...> } @@ identifier func =~ ".*create.*"; identifier dev, file, mode_cmd; @@ struct drm_framebuffer *func( struct drm_device *dev, struct drm_file *file, + const struct drm_format_info *info, const struct drm_mode_fb_cmd2 *mode_cmd) { ... } @find@ identifier fb_create_func =~ ".*create.*"; identifier dev, file, mode_cmd; @@ struct drm_framebuffer *fb_create_func( struct drm_device *dev, struct drm_file *file, + const struct drm_format_info *info, const struct drm_mode_fb_cmd2 *mode_cmd); @@ identifier find.fb_create_func; expression dev, file, mode_cmd; @@ fb_create_func(dev, file + ,info ,mode_cmd) @@ expression dev, file, mode_cmd; @@ drm_gem_fb_create(dev, file + ,info ,mode_cmd) @@ expression dev, file, mode_cmd; @@ drm_gem_fb_create_with_dirty(dev, file + ,info ,mode_cmd) @@ expression dev, file_priv, mode_cmd; identifier info, fb; @@ info = drm_get_format_info(...); ... fb = dev->mode_config.funcs->fb_create(dev, file_priv + ,info ,mode_cmd); @@ identifier dev, file_priv, mode_cmd; @@ struct drm_mode_config_funcs { ... struct drm_framebuffer *(*fb_create)(struct drm_device *dev, struct drm_file *file_priv, + const struct drm_format_info *info, const struct drm_mode_fb_cmd2 *mode_cmd); ... }; v2: Fix kernel docs (Laurent) Fix commit msg (Geert) Cc: Alex Deucher <alexander.deucher@amd.com> Cc: Liviu Dudau <liviu.dudau@arm.com> Cc: Maxime Ripard <mripard@kernel.org> Cc: Russell King <linux@armlinux.org.uk> Cc: Inki Dae <inki.dae@samsung.com> Cc: Seung-Woo Kim <sw0312.kim@samsung.com> Cc: Kyungmin Park <kyungmin.park@samsung.com> Cc: Patrik Jakobsson <patrik.r.jakobsson@gmail.com> Cc: Chun-Kuang Hu <chunkuang.hu@kernel.org> Cc: Philipp Zabel <p.zabel@pengutronix.de> Cc: Rob Clark <robdclark@gmail.com> Cc: Abhinav Kumar <quic_abhinavk@quicinc.com> Cc: Dmitry Baryshkov <lumag@kernel.org> Cc: Sean Paul <sean@poorly.run> Cc: Marijn Suijten <marijn.suijten@somainline.org> Cc: Marek Vasut <marex@denx.de> Cc: Stefan Agner <stefan@agner.ch> Cc: Lyude Paul <lyude@redhat.com> Cc: Danilo Krummrich <dakr@kernel.org> Cc: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Cc: Dave Airlie <airlied@redhat.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com> Cc: Biju Das <biju.das.jz@bp.renesas.com> Cc: Sandy Huang <hjc@rock-chips.com> Cc: "Heiko Stübner" <heiko@sntech.de> Cc: Andy Yan <andy.yan@rock-chips.com> Cc: Thierry Reding <thierry.reding@gmail.com> Cc: Mikko Perttunen <mperttunen@nvidia.com> Cc: Dave Stevenson <dave.stevenson@raspberrypi.com> Cc: "Maíra Canal" <mcanal@igalia.com> Cc: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com> Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com> Cc: Gurchetan Singh <gurchetansingh@chromium.org> Cc: Chia-I Wu <olvaffe@gmail.com> Cc: Zack Rusin <zack.rusin@broadcom.com> Cc: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> Cc: amd-gfx@lists.freedesktop.org Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: nouveau@lists.freedesktop.org Cc: virtualization@lists.linux.dev Cc: spice-devel@lists.freedesktop.org Cc: linux-renesas-soc@vger.kernel.org Cc: linux-tegra@vger.kernel.org Cc: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Acked-by: Liviu Dudau <liviu.dudau@arm.com> Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20250701090722.13645-5-ville.syrjala@linux.intel.com
2025-07-01 12:07:07 +03:00
const struct drm_format_info *info,
const struct drm_mode_fb_cmd2 *cmd)
{
struct tegra_bo *planes[4];
struct drm_gem_object *gem;
struct drm_framebuffer *fb;
unsigned int i;
int err;
for (i = 0; i < info->num_planes; i++) {
unsigned int width = cmd->width / (i ? info->hsub : 1);
unsigned int height = cmd->height / (i ? info->vsub : 1);
unsigned int size, bpp;
gem = drm_gem_object_lookup(file, cmd->handles[i]);
if (!gem) {
err = -ENXIO;
goto unreference;
}
bpp = info->cpp[i];
size = (height - 1) * cmd->pitches[i] +
width * bpp + cmd->offsets[i];
if (gem->size < size) {
err = -EINVAL;
drm_gem_object_put(gem);
goto unreference;
}
planes[i] = to_tegra_bo(gem);
}
fb = tegra_fb_alloc(drm, info, cmd, planes, i);
if (IS_ERR(fb)) {
err = PTR_ERR(fb);
goto unreference;
}
return fb;
unreference:
while (i--)
drm_gem_object_put(&planes[i]->gem);
return ERR_PTR(err);
}