mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00

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
189 lines
5 KiB
C
189 lines
5 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* shmob_drm_kms.c -- SH Mobile DRM Mode Setting
|
|
*
|
|
* Copyright (C) 2012 Renesas Electronics Corporation
|
|
*
|
|
* Laurent Pinchart (laurent.pinchart@ideasonboard.com)
|
|
*/
|
|
|
|
#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_gem_dma_helper.h>
|
|
#include <drm/drm_gem_framebuffer_helper.h>
|
|
#include <drm/drm_probe_helper.h>
|
|
|
|
#include "shmob_drm_crtc.h"
|
|
#include "shmob_drm_drv.h"
|
|
#include "shmob_drm_kms.h"
|
|
#include "shmob_drm_plane.h"
|
|
#include "shmob_drm_regs.h"
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Format helpers
|
|
*/
|
|
|
|
static const struct shmob_drm_format_info shmob_drm_format_infos[] = {
|
|
{
|
|
.fourcc = DRM_FORMAT_RGB565,
|
|
.bpp = 16,
|
|
.lddfr = LDDFR_PKF_RGB16,
|
|
.ldddsr = LDDDSR_LS | LDDDSR_WS,
|
|
.ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
|
|
LDBBSIFR_RY | LDBBSIFR_RPKF_RGB16,
|
|
}, {
|
|
.fourcc = DRM_FORMAT_RGB888,
|
|
.bpp = 24,
|
|
.lddfr = LDDFR_PKF_RGB24,
|
|
.ldddsr = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS,
|
|
.ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
|
|
LDBBSIFR_SWPB | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB24,
|
|
}, {
|
|
.fourcc = DRM_FORMAT_ARGB8888,
|
|
.bpp = 32,
|
|
.lddfr = LDDFR_PKF_ARGB32,
|
|
.ldddsr = LDDDSR_LS,
|
|
.ldbbsifr = LDBBSIFR_AL_PK | LDBBSIFR_SWPL | LDBBSIFR_RY |
|
|
LDBBSIFR_RPKF_ARGB32,
|
|
}, {
|
|
.fourcc = DRM_FORMAT_XRGB8888,
|
|
.bpp = 32,
|
|
.lddfr = LDDFR_PKF_ARGB32,
|
|
.ldddsr = LDDDSR_LS,
|
|
.ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_RY |
|
|
LDBBSIFR_RPKF_ARGB32,
|
|
}, {
|
|
.fourcc = DRM_FORMAT_NV12,
|
|
.bpp = 12,
|
|
.lddfr = LDDFR_CC | LDDFR_YF_420,
|
|
.ldddsr = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS,
|
|
.ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
|
|
LDBBSIFR_SWPB | LDBBSIFR_CHRR_420,
|
|
}, {
|
|
.fourcc = DRM_FORMAT_NV21,
|
|
.bpp = 12,
|
|
.lddfr = LDDFR_CC | LDDFR_YF_420,
|
|
.ldddsr = LDDDSR_LS | LDDDSR_WS,
|
|
.ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
|
|
LDBBSIFR_CHRR_420,
|
|
}, {
|
|
.fourcc = DRM_FORMAT_NV16,
|
|
.bpp = 16,
|
|
.lddfr = LDDFR_CC | LDDFR_YF_422,
|
|
.ldddsr = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS,
|
|
.ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
|
|
LDBBSIFR_SWPB | LDBBSIFR_CHRR_422,
|
|
}, {
|
|
.fourcc = DRM_FORMAT_NV61,
|
|
.bpp = 16,
|
|
.lddfr = LDDFR_CC | LDDFR_YF_422,
|
|
.ldddsr = LDDDSR_LS | LDDDSR_WS,
|
|
.ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
|
|
LDBBSIFR_CHRR_422,
|
|
}, {
|
|
.fourcc = DRM_FORMAT_NV24,
|
|
.bpp = 24,
|
|
.lddfr = LDDFR_CC | LDDFR_YF_444,
|
|
.ldddsr = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS,
|
|
.ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
|
|
LDBBSIFR_SWPB | LDBBSIFR_CHRR_444,
|
|
}, {
|
|
.fourcc = DRM_FORMAT_NV42,
|
|
.bpp = 24,
|
|
.lddfr = LDDFR_CC | LDDFR_YF_444,
|
|
.ldddsr = LDDDSR_LS | LDDDSR_WS,
|
|
.ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
|
|
LDBBSIFR_CHRR_444,
|
|
},
|
|
};
|
|
|
|
const struct shmob_drm_format_info *shmob_drm_format_info(u32 fourcc)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(shmob_drm_format_infos); ++i) {
|
|
if (shmob_drm_format_infos[i].fourcc == fourcc)
|
|
return &shmob_drm_format_infos[i];
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Frame buffer
|
|
*/
|
|
|
|
static struct drm_framebuffer *
|
|
shmob_drm_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)
|
|
{
|
|
const struct shmob_drm_format_info *format;
|
|
|
|
format = shmob_drm_format_info(mode_cmd->pixel_format);
|
|
if (format == NULL) {
|
|
dev_dbg(dev->dev, "unsupported pixel format %p4cc\n",
|
|
&mode_cmd->pixel_format);
|
|
return ERR_PTR(-EINVAL);
|
|
}
|
|
|
|
if (mode_cmd->pitches[0] & 7 || mode_cmd->pitches[0] >= 65536) {
|
|
dev_dbg(dev->dev, "invalid pitch value %u\n",
|
|
mode_cmd->pitches[0]);
|
|
return ERR_PTR(-EINVAL);
|
|
}
|
|
|
|
if (shmob_drm_format_is_yuv(format)) {
|
|
unsigned int chroma_cpp = format->bpp == 24 ? 2 : 1;
|
|
|
|
if (mode_cmd->pitches[1] != mode_cmd->pitches[0] * chroma_cpp) {
|
|
dev_dbg(dev->dev,
|
|
"luma and chroma pitches do not match\n");
|
|
return ERR_PTR(-EINVAL);
|
|
}
|
|
}
|
|
|
|
return drm_gem_fb_create(dev, file_priv, info, mode_cmd);
|
|
}
|
|
|
|
static const struct drm_mode_config_funcs shmob_drm_mode_config_funcs = {
|
|
.fb_create = shmob_drm_fb_create,
|
|
.atomic_check = drm_atomic_helper_check,
|
|
.atomic_commit = drm_atomic_helper_commit,
|
|
};
|
|
|
|
int shmob_drm_modeset_init(struct shmob_drm_device *sdev)
|
|
{
|
|
struct drm_device *dev = &sdev->ddev;
|
|
int ret;
|
|
|
|
ret = drmm_mode_config_init(dev);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ret = shmob_drm_crtc_create(sdev);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
ret = shmob_drm_encoder_create(sdev);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
ret = shmob_drm_connector_create(sdev, &sdev->encoder);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
drm_mode_config_reset(dev);
|
|
|
|
drm_kms_helper_poll_init(dev);
|
|
|
|
sdev->ddev.mode_config.min_width = 0;
|
|
sdev->ddev.mode_config.min_height = 0;
|
|
sdev->ddev.mode_config.max_width = 4095;
|
|
sdev->ddev.mode_config.max_height = 4095;
|
|
sdev->ddev.mode_config.funcs = &shmob_drm_mode_config_funcs;
|
|
|
|
return 0;
|
|
}
|