linux/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c

763 lines
18 KiB
C
Raw Permalink Normal View History

// SPDX-License-Identifier: GPL-2.0+
/*
* R-Car Display Unit DRM driver
*
* Copyright (C) 2013-2015 Renesas Electronics Corporation
*
* Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
*/
#include <linux/clk.h>
2017-11-12 14:12:10 +02:00
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <drm/clients/drm_client_setup.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_fbdev_dma.h>
drm/gem: rename GEM CMA helpers to GEM DMA helpers Rename "GEM CMA" helpers to "GEM DMA" helpers - considering the hierarchy of APIs (mm/cma -> dma -> gem dma) calling them "GEM 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}*)(GEM)_CMA_(${REGEX_SYM_UPPER}*)" REGEX_GREP_LOWER="(${REGEX_SYM_LOWER}*)(gem)_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 # Rename all 'cma_obj's to 'dma_obj'. for ff in $(grep -RiHl "cma_obj" $DIRS) do sed -i -E "s/cma_obj/dma_obj/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 "GEM CMA", but not "FB CMA". Also drivers/gpu/drm/Makefile was fixed up manually after renaming drm_gem_cma_helper.c to drm_gem_dma_helper.c. 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-4-dakr@redhat.com
2022-08-02 02:04:03 +02:00
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_managed.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_probe_helper.h>
#include "rcar_du_drv.h"
#include "rcar_du_kms.h"
/* -----------------------------------------------------------------------------
* Device Information
*/
static const struct rcar_du_device_info rzg1_du_r8a7743_info = {
.gen = 2,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_CRTC_CLOCK
| RCAR_DU_FEATURE_INTERLACED
| RCAR_DU_FEATURE_TVM_SYNC,
.channels_mask = BIT(1) | BIT(0),
.routes = {
/*
* R8A774[34] has one RGB output and one LVDS output
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(1) | BIT(0),
.port = 0,
},
[RCAR_DU_OUTPUT_LVDS0] = {
.possible_crtcs = BIT(0),
.port = 1,
},
},
.num_lvds = 1,
.num_rpf = 4,
};
static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
.gen = 2,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_CRTC_CLOCK
| RCAR_DU_FEATURE_INTERLACED
| RCAR_DU_FEATURE_TVM_SYNC,
.channels_mask = BIT(1) | BIT(0),
.routes = {
/*
* R8A7745 has two RGB outputs
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(0),
.port = 0,
},
[RCAR_DU_OUTPUT_DPAD1] = {
.possible_crtcs = BIT(1),
.port = 1,
},
},
.num_rpf = 4,
};
static const struct rcar_du_device_info rzg1_du_r8a77470_info = {
.gen = 2,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_CRTC_CLOCK
| RCAR_DU_FEATURE_INTERLACED
| RCAR_DU_FEATURE_TVM_SYNC,
.channels_mask = BIT(1) | BIT(0),
.routes = {
/*
* R8A77470 has two RGB outputs, one LVDS output, and
* one (currently unsupported) analog video output
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(0),
.port = 0,
},
[RCAR_DU_OUTPUT_DPAD1] = {
.possible_crtcs = BIT(1),
.port = 1,
},
[RCAR_DU_OUTPUT_LVDS0] = {
.possible_crtcs = BIT(0) | BIT(1),
.port = 2,
},
},
.num_rpf = 4,
};
static const struct rcar_du_device_info rcar_du_r8a774a1_info = {
.gen = 3,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_CRTC_CLOCK
| RCAR_DU_FEATURE_VSP1_SOURCE
| RCAR_DU_FEATURE_INTERLACED
| RCAR_DU_FEATURE_TVM_SYNC,
.channels_mask = BIT(2) | BIT(1) | BIT(0),
.routes = {
/*
* R8A774A1 has one RGB output, one LVDS output and one HDMI
* output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(2),
.port = 0,
},
[RCAR_DU_OUTPUT_HDMI0] = {
.possible_crtcs = BIT(1),
.port = 1,
},
[RCAR_DU_OUTPUT_LVDS0] = {
.possible_crtcs = BIT(0),
.port = 2,
},
},
.num_lvds = 1,
.num_rpf = 5,
.dpll_mask = BIT(1),
};
static const struct rcar_du_device_info rcar_du_r8a774b1_info = {
.gen = 3,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_CRTC_CLOCK
| RCAR_DU_FEATURE_VSP1_SOURCE
| RCAR_DU_FEATURE_INTERLACED
| RCAR_DU_FEATURE_TVM_SYNC,
.channels_mask = BIT(3) | BIT(1) | BIT(0),
.routes = {
/*
* R8A774B1 has one RGB output, one LVDS output and one HDMI
* output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(2),
.port = 0,
},
[RCAR_DU_OUTPUT_HDMI0] = {
.possible_crtcs = BIT(1),
.port = 1,
},
[RCAR_DU_OUTPUT_LVDS0] = {
.possible_crtcs = BIT(0),
.port = 2,
},
},
.num_lvds = 1,
.num_rpf = 5,
.dpll_mask = BIT(1),
};
static const struct rcar_du_device_info rcar_du_r8a774c0_info = {
.gen = 3,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_CRTC_CLOCK
| RCAR_DU_FEATURE_VSP1_SOURCE,
.channels_mask = BIT(1) | BIT(0),
.routes = {
/*
* R8A774C0 has one RGB output and two LVDS outputs
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(0) | BIT(1),
.port = 0,
},
[RCAR_DU_OUTPUT_LVDS0] = {
.possible_crtcs = BIT(0),
.port = 1,
},
[RCAR_DU_OUTPUT_LVDS1] = {
.possible_crtcs = BIT(1),
.port = 2,
},
},
.num_lvds = 2,
.num_rpf = 4,
.lvds_clk_mask = BIT(1) | BIT(0),
};
static const struct rcar_du_device_info rcar_du_r8a774e1_info = {
.gen = 3,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_CRTC_CLOCK
| RCAR_DU_FEATURE_VSP1_SOURCE
| RCAR_DU_FEATURE_INTERLACED
| RCAR_DU_FEATURE_TVM_SYNC,
.channels_mask = BIT(3) | BIT(1) | BIT(0),
.routes = {
/*
* R8A774E1 has one RGB output, one LVDS output and one HDMI
* output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(2),
.port = 0,
},
[RCAR_DU_OUTPUT_HDMI0] = {
.possible_crtcs = BIT(1),
.port = 1,
},
[RCAR_DU_OUTPUT_LVDS0] = {
.possible_crtcs = BIT(0),
.port = 2,
},
},
.num_lvds = 1,
.num_rpf = 5,
.dpll_mask = BIT(1),
};
static const struct rcar_du_device_info rcar_du_r8a7779_info = {
.gen = 1,
.features = RCAR_DU_FEATURE_INTERLACED
| RCAR_DU_FEATURE_TVM_SYNC,
.channels_mask = BIT(1) | BIT(0),
.routes = {
/*
* R8A7779 has two RGB outputs and one (currently unsupported)
* TCON output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(0),
.port = 0,
},
[RCAR_DU_OUTPUT_DPAD1] = {
.possible_crtcs = BIT(1) | BIT(0),
.port = 1,
},
},
};
static const struct rcar_du_device_info rcar_du_r8a7790_info = {
.gen = 2,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_CRTC_CLOCK
| RCAR_DU_FEATURE_INTERLACED
| RCAR_DU_FEATURE_TVM_SYNC,
.quirks = RCAR_DU_QUIRK_ALIGN_128B,
.channels_mask = BIT(2) | BIT(1) | BIT(0),
.routes = {
/*
* R8A7742 and R8A7790 each have one RGB output and two LVDS
* outputs. Additionally R8A7790 supports one TCON output
* (currently unsupported by the driver).
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(2) | BIT(1) | BIT(0),
.port = 0,
},
[RCAR_DU_OUTPUT_LVDS0] = {
.possible_crtcs = BIT(0),
.port = 1,
},
[RCAR_DU_OUTPUT_LVDS1] = {
.possible_crtcs = BIT(2) | BIT(1),
.port = 2,
},
},
.num_lvds = 2,
.num_rpf = 4,
};
/* M2-W (r8a7791) and M2-N (r8a7793) are identical */
static const struct rcar_du_device_info rcar_du_r8a7791_info = {
.gen = 2,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_CRTC_CLOCK
| RCAR_DU_FEATURE_INTERLACED
| RCAR_DU_FEATURE_TVM_SYNC,
.channels_mask = BIT(1) | BIT(0),
.routes = {
/*
* R8A779[13] has one RGB output, one LVDS output and one
* (currently unsupported) TCON output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(1) | BIT(0),
.port = 0,
},
[RCAR_DU_OUTPUT_LVDS0] = {
.possible_crtcs = BIT(0),
.port = 1,
},
},
.num_lvds = 1,
.num_rpf = 4,
};
static const struct rcar_du_device_info rcar_du_r8a7792_info = {
.gen = 2,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_CRTC_CLOCK
| RCAR_DU_FEATURE_INTERLACED
| RCAR_DU_FEATURE_TVM_SYNC,
.channels_mask = BIT(1) | BIT(0),
.routes = {
/* R8A7792 has two RGB outputs. */
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(0),
.port = 0,
},
[RCAR_DU_OUTPUT_DPAD1] = {
.possible_crtcs = BIT(1),
.port = 1,
},
},
.num_rpf = 4,
};
static const struct rcar_du_device_info rcar_du_r8a7794_info = {
.gen = 2,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_CRTC_CLOCK
| RCAR_DU_FEATURE_INTERLACED
| RCAR_DU_FEATURE_TVM_SYNC,
.channels_mask = BIT(1) | BIT(0),
.routes = {
/*
* R8A7794 has two RGB outputs and one (currently unsupported)
* TCON output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(0),
.port = 0,
},
[RCAR_DU_OUTPUT_DPAD1] = {
.possible_crtcs = BIT(1),
.port = 1,
},
},
.num_rpf = 4,
};
static const struct rcar_du_device_info rcar_du_r8a7795_info = {
.gen = 3,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_CRTC_CLOCK
| RCAR_DU_FEATURE_VSP1_SOURCE
| RCAR_DU_FEATURE_INTERLACED
| RCAR_DU_FEATURE_TVM_SYNC,
.channels_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0),
.routes = {
/*
* R8A7795 has one RGB output, two HDMI outputs and one
* LVDS output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(3),
.port = 0,
},
[RCAR_DU_OUTPUT_HDMI0] = {
.possible_crtcs = BIT(1),
.port = 1,
},
[RCAR_DU_OUTPUT_HDMI1] = {
.possible_crtcs = BIT(2),
.port = 2,
},
[RCAR_DU_OUTPUT_LVDS0] = {
.possible_crtcs = BIT(0),
.port = 3,
},
},
.num_lvds = 1,
.num_rpf = 5,
.dpll_mask = BIT(2) | BIT(1),
};
static const struct rcar_du_device_info rcar_du_r8a7796_info = {
.gen = 3,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_CRTC_CLOCK
| RCAR_DU_FEATURE_VSP1_SOURCE
| RCAR_DU_FEATURE_INTERLACED
| RCAR_DU_FEATURE_TVM_SYNC,
.channels_mask = BIT(2) | BIT(1) | BIT(0),
.routes = {
/*
* R8A7796 has one RGB output, one LVDS output and one HDMI
* output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(2),
.port = 0,
},
[RCAR_DU_OUTPUT_HDMI0] = {
.possible_crtcs = BIT(1),
.port = 1,
},
[RCAR_DU_OUTPUT_LVDS0] = {
.possible_crtcs = BIT(0),
.port = 2,
},
},
.num_lvds = 1,
.num_rpf = 5,
.dpll_mask = BIT(1),
};
static const struct rcar_du_device_info rcar_du_r8a77965_info = {
.gen = 3,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_CRTC_CLOCK
| RCAR_DU_FEATURE_VSP1_SOURCE
| RCAR_DU_FEATURE_INTERLACED
| RCAR_DU_FEATURE_TVM_SYNC,
.channels_mask = BIT(3) | BIT(1) | BIT(0),
.routes = {
/*
* R8A77965 has one RGB output, one LVDS output and one HDMI
* output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(2),
.port = 0,
},
[RCAR_DU_OUTPUT_HDMI0] = {
.possible_crtcs = BIT(1),
.port = 1,
},
[RCAR_DU_OUTPUT_LVDS0] = {
.possible_crtcs = BIT(0),
.port = 2,
},
},
.num_lvds = 1,
.num_rpf = 5,
.dpll_mask = BIT(1),
};
static const struct rcar_du_device_info rcar_du_r8a77970_info = {
.gen = 3,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_CRTC_CLOCK
| RCAR_DU_FEATURE_VSP1_SOURCE
| RCAR_DU_FEATURE_INTERLACED
| RCAR_DU_FEATURE_TVM_SYNC,
.channels_mask = BIT(0),
.routes = {
/*
* R8A77970 and R8A77980 have one RGB output and one LVDS
* output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(0),
.port = 0,
},
[RCAR_DU_OUTPUT_LVDS0] = {
.possible_crtcs = BIT(0),
.port = 1,
},
},
.num_lvds = 1,
.num_rpf = 5,
};
static const struct rcar_du_device_info rcar_du_r8a7799x_info = {
.gen = 3,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_CRTC_CLOCK
| RCAR_DU_FEATURE_VSP1_SOURCE,
.channels_mask = BIT(1) | BIT(0),
.routes = {
/*
* R8A77990 and R8A77995 have one RGB output and two LVDS
* outputs.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(0) | BIT(1),
.port = 0,
},
[RCAR_DU_OUTPUT_LVDS0] = {
.possible_crtcs = BIT(0),
.port = 1,
},
[RCAR_DU_OUTPUT_LVDS1] = {
.possible_crtcs = BIT(1),
.port = 2,
},
},
.num_lvds = 2,
.num_rpf = 5,
.lvds_clk_mask = BIT(1) | BIT(0),
};
static const struct rcar_du_device_info rcar_du_r8a779a0_info = {
.gen = 4,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_VSP1_SOURCE
| RCAR_DU_FEATURE_NO_BLENDING,
.channels_mask = BIT(1) | BIT(0),
.routes = {
/* R8A779A0 has two MIPI DSI outputs. */
[RCAR_DU_OUTPUT_DSI0] = {
.possible_crtcs = BIT(0),
.port = 0,
},
[RCAR_DU_OUTPUT_DSI1] = {
.possible_crtcs = BIT(1),
.port = 1,
},
},
.num_rpf = 5,
.dsi_clk_mask = BIT(1) | BIT(0),
};
static const struct rcar_du_device_info rcar_du_r8a779g0_info = {
.gen = 4,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_VSP1_SOURCE
| RCAR_DU_FEATURE_NO_BLENDING,
.channels_mask = BIT(1) | BIT(0),
.routes = {
/* R8A779G0 has two MIPI DSI outputs. */
[RCAR_DU_OUTPUT_DSI0] = {
.possible_crtcs = BIT(0),
.port = 0,
},
[RCAR_DU_OUTPUT_DSI1] = {
.possible_crtcs = BIT(1),
.port = 1,
},
},
.num_rpf = 5,
.dsi_clk_mask = BIT(1) | BIT(0),
};
static const struct rcar_du_device_info rcar_du_r8a779h0_info = {
.gen = 4,
.features = RCAR_DU_FEATURE_CRTC_IRQ
| RCAR_DU_FEATURE_VSP1_SOURCE
| RCAR_DU_FEATURE_NO_BLENDING,
.channels_mask = BIT(0),
.routes = {
/* R8A779H0 has one MIPI DSI output. */
[RCAR_DU_OUTPUT_DSI0] = {
.possible_crtcs = BIT(0),
.port = 0,
},
},
.num_rpf = 5,
.dsi_clk_mask = BIT(0),
};
static const struct of_device_id rcar_du_of_table[] = {
{ .compatible = "renesas,du-r8a7742", .data = &rcar_du_r8a7790_info },
{ .compatible = "renesas,du-r8a7743", .data = &rzg1_du_r8a7743_info },
{ .compatible = "renesas,du-r8a7744", .data = &rzg1_du_r8a7743_info },
{ .compatible = "renesas,du-r8a7745", .data = &rzg1_du_r8a7745_info },
{ .compatible = "renesas,du-r8a77470", .data = &rzg1_du_r8a77470_info },
{ .compatible = "renesas,du-r8a774a1", .data = &rcar_du_r8a774a1_info },
{ .compatible = "renesas,du-r8a774b1", .data = &rcar_du_r8a774b1_info },
{ .compatible = "renesas,du-r8a774c0", .data = &rcar_du_r8a774c0_info },
{ .compatible = "renesas,du-r8a774e1", .data = &rcar_du_r8a774e1_info },
{ .compatible = "renesas,du-r8a7779", .data = &rcar_du_r8a7779_info },
{ .compatible = "renesas,du-r8a7790", .data = &rcar_du_r8a7790_info },
{ .compatible = "renesas,du-r8a7791", .data = &rcar_du_r8a7791_info },
{ .compatible = "renesas,du-r8a7792", .data = &rcar_du_r8a7792_info },
{ .compatible = "renesas,du-r8a7793", .data = &rcar_du_r8a7791_info },
{ .compatible = "renesas,du-r8a7794", .data = &rcar_du_r8a7794_info },
{ .compatible = "renesas,du-r8a7795", .data = &rcar_du_r8a7795_info },
{ .compatible = "renesas,du-r8a7796", .data = &rcar_du_r8a7796_info },
{ .compatible = "renesas,du-r8a77961", .data = &rcar_du_r8a7796_info },
{ .compatible = "renesas,du-r8a77965", .data = &rcar_du_r8a77965_info },
{ .compatible = "renesas,du-r8a77970", .data = &rcar_du_r8a77970_info },
{ .compatible = "renesas,du-r8a77980", .data = &rcar_du_r8a77970_info },
{ .compatible = "renesas,du-r8a77990", .data = &rcar_du_r8a7799x_info },
{ .compatible = "renesas,du-r8a77995", .data = &rcar_du_r8a7799x_info },
{ .compatible = "renesas,du-r8a779a0", .data = &rcar_du_r8a779a0_info },
{ .compatible = "renesas,du-r8a779g0", .data = &rcar_du_r8a779g0_info },
{ .compatible = "renesas,du-r8a779h0", .data = &rcar_du_r8a779h0_info },
{ }
};
MODULE_DEVICE_TABLE(of, rcar_du_of_table);
const char *rcar_du_output_name(enum rcar_du_output output)
{
static const char * const names[] = {
[RCAR_DU_OUTPUT_DPAD0] = "DPAD0",
[RCAR_DU_OUTPUT_DPAD1] = "DPAD1",
[RCAR_DU_OUTPUT_DSI0] = "DSI0",
[RCAR_DU_OUTPUT_DSI1] = "DSI1",
[RCAR_DU_OUTPUT_HDMI0] = "HDMI0",
[RCAR_DU_OUTPUT_HDMI1] = "HDMI1",
[RCAR_DU_OUTPUT_LVDS0] = "LVDS0",
[RCAR_DU_OUTPUT_LVDS1] = "LVDS1",
[RCAR_DU_OUTPUT_TCON] = "TCON",
};
if (output >= ARRAY_SIZE(names) || !names[output])
return "UNKNOWN";
return names[output];
}
/* -----------------------------------------------------------------------------
* DRM operations
*/
drm/gem: rename GEM CMA helpers to GEM DMA helpers Rename "GEM CMA" helpers to "GEM DMA" helpers - considering the hierarchy of APIs (mm/cma -> dma -> gem dma) calling them "GEM 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}*)(GEM)_CMA_(${REGEX_SYM_UPPER}*)" REGEX_GREP_LOWER="(${REGEX_SYM_LOWER}*)(gem)_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 # Rename all 'cma_obj's to 'dma_obj'. for ff in $(grep -RiHl "cma_obj" $DIRS) do sed -i -E "s/cma_obj/dma_obj/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 "GEM CMA", but not "FB CMA". Also drivers/gpu/drm/Makefile was fixed up manually after renaming drm_gem_cma_helper.c to drm_gem_dma_helper.c. 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-4-dakr@redhat.com
2022-08-02 02:04:03 +02:00
DEFINE_DRM_GEM_DMA_FOPS(rcar_du_fops);
drm/<drivers>: Constify struct drm_driver Only the following drivers aren't converted: - amdgpu, because of the driver_feature mangling due to virt support. Subsequent patch will address this. - nouveau, because DRIVER_ATOMIC uapi is still not the default on the platforms where it's supported (i.e. again driver_feature mangling) - vc4, again because of driver_feature mangling - qxl, because the ioctl table is somewhere else and moving that is maybe a bit too much, hence the num_ioctls assignment prevents a const driver structure. - arcpgu, because that is stuck behind a pending tiny-fication series from me. - legacy drivers, because legacy requires non-const drm_driver. Note that for armada I also went ahead and made the ioctl array const. Only cc'ing the driver people who've not been converted (everyone else is way too much). v2: Fix one misplaced const static, should be static const (0day) v3: - Improve commit message (Sam) Acked-by: Sam Ravnborg <sam@ravnborg.org> Cc: kernel test robot <lkp@intel.com> Acked-by: Maxime Ripard <mripard@kernel.org> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Sam Ravnborg <sam@ravnborg.org> Cc: Dave Airlie <airlied@redhat.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: virtualization@lists.linux-foundation.org Cc: Harry Wentland <harry.wentland@amd.com> Cc: Leo Li <sunpeng.li@amd.com> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: Christian König <christian.koenig@amd.com> Cc: Eric Anholt <eric@anholt.net> Cc: Maxime Ripard <mripard@kernel.org> Cc: Ben Skeggs <bskeggs@redhat.com> Cc: nouveau@lists.freedesktop.org Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20201104100425.1922351-5-daniel.vetter@ffwll.ch
2020-11-04 11:04:24 +01:00
static const struct drm_driver rcar_du_driver = {
drm/prime: Actually remove DRIVER_PRIME everywhere Split out to make the functional changes stick out more. All places where DRIVER_PRIME was used have been removed in previous patches already. v2: amdgpu gained DRIVER_SYNCOBJ_TIMELINE. v3: amdgpu lost DRIVER_SYNCOBJ_TIMELINE. v4: Don't add a space in i915_drv.c (Sam) v5: Add note that previous patches removed all the DRIVER_PRIME users already (Emil). v6: Fixupe ingenic (new driver) while applying. Cc: Sam Ravnborg <sam@ravnborg.org> Reviewed-by: Emil Velikov <emil.velikov@collabora.com> Reviewed-by: Eric Anholt <eric@anholt.net> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Cc: amd-gfx@lists.freedesktop.org Cc: etnaviv@lists.freedesktop.org Cc: freedreno@lists.freedesktop.org Cc: intel-gfx@lists.freedesktop.org Cc: lima@lists.freedesktop.org Cc: linux-amlogic@lists.infradead.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-arm-msm@vger.kernel.org Cc: linux-aspeed@lists.ozlabs.org Cc: linux-renesas-soc@vger.kernel.org Cc: linux-rockchip@lists.infradead.org Cc: linux-samsung-soc@vger.kernel.org Cc: linux-stm32@st-md-mailman.stormreply.com Cc: linux-tegra@vger.kernel.org Cc: nouveau@lists.freedesktop.org Cc: NXP Linux Team <linux-imx@nxp.com> Cc: spice-devel@lists.freedesktop.org Cc: virtualization@lists.linux-foundation.org Cc: VMware Graphics <linux-graphics-maintainer@vmware.com> Cc: xen-devel@lists.xenproject.org Link: https://patchwork.freedesktop.org/patch/msgid/20190617153924.414-1-daniel.vetter@ffwll.ch
2019-06-17 17:39:24 +02:00
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
drm: rcar-du: Allow importing non-contiguous dma-buf with VSP On R-Car Gen3, the DU uses a separate IP core named VSP to perform DMA from memory and composition of planes. The DU hardware then only handles the video timings and the interface with the encoders. This differs from Gen2, where the DU included a composer with DMA engines. When sourcing from the VSP, the DU hardware performs no memory access, and thus has no requirements on imported dma-buf memory types. The GEM CMA helpers however still create a DMA mapping to the DU device, which isn't used. The mapping to the VSP is done when processing the atomic commits, in the plane .prepare_fb() handler. When the system uses an IOMMU, the VSP device is attached to it, which enables the VSP to use non physically contiguous memory. The DU, as it performs no memory access, isn't connected to the IOMMU. The GEM CMA drm_gem_cma_prime_import_sg_table() helper will in that case fail to map non-contiguous imported dma-bufs, as the DMA mapping to the DU device will have multiple entries in its sgtable. The prevents using non physically contiguous memory for display. The DRM PRIME and GEM CMA helpers are designed to create the sgtable when the dma-buf is imported. By default, the device referenced by the drm_device is used to create the dma-buf attachment. Drivers can use a different device by using the drm_gem_prime_import_dev() function. While the DU has access to the VSP device, this won't help here, as different CRTCs use different VSP instances, connected to different IOMMU channels. The driver doesn't know at import time which CRTC a GEM object will be used, and thus can't select the right VSP device to pass to drm_gem_prime_import_dev(). To support non-contiguous memory, implement a custom .gem_prime_import_sg_table() operation that accepts all imported dma-buf regardless of the number of scatterlist entries. The sgtable will be mapped to the VSP at .prepare_fb() time, which will reject the framebuffer if the VSP isn't connected to an IOMMU. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
2017-11-13 04:40:30 +02:00
.dumb_create = rcar_du_dumb_create,
.gem_prime_import_sg_table = rcar_du_gem_prime_import_sg_table,
DRM_FBDEV_DMA_DRIVER_OPS,
.fops = &rcar_du_fops,
.name = "rcar-du",
.desc = "Renesas R-Car Display Unit",
.major = 1,
.minor = 0,
};
/* -----------------------------------------------------------------------------
* Power management
*/
static int rcar_du_pm_suspend(struct device *dev)
{
struct rcar_du_device *rcdu = dev_get_drvdata(dev);
return drm_mode_config_helper_suspend(&rcdu->ddev);
}
static int rcar_du_pm_resume(struct device *dev)
{
struct rcar_du_device *rcdu = dev_get_drvdata(dev);
return drm_mode_config_helper_resume(&rcdu->ddev);
}
static DEFINE_SIMPLE_DEV_PM_OPS(rcar_du_pm_ops,
rcar_du_pm_suspend, rcar_du_pm_resume);
/* -----------------------------------------------------------------------------
* Platform driver
*/
static void rcar_du_remove(struct platform_device *pdev)
{
struct rcar_du_device *rcdu = platform_get_drvdata(pdev);
struct drm_device *ddev = &rcdu->ddev;
drm_dev_unregister(ddev);
drm_atomic_helper_shutdown(ddev);
drm_kms_helper_poll_fini(ddev);
}
static void rcar_du_shutdown(struct platform_device *pdev)
{
struct rcar_du_device *rcdu = platform_get_drvdata(pdev);
drm_atomic_helper_shutdown(&rcdu->ddev);
}
static int rcar_du_probe(struct platform_device *pdev)
{
struct rcar_du_device *rcdu;
2017-11-12 14:12:10 +02:00
unsigned int mask;
int ret;
if (drm_firmware_drivers_only())
return -ENODEV;
/* Allocate and initialize the R-Car device structure. */
rcdu = devm_drm_dev_alloc(&pdev->dev, &rcar_du_driver,
struct rcar_du_device, ddev);
if (IS_ERR(rcdu))
return PTR_ERR(rcdu);
rcdu->dev = &pdev->dev;
rcdu->info = of_device_get_match_data(rcdu->dev);
platform_set_drvdata(pdev, rcdu);
/* I/O resources */
rcdu->mmio = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rcdu->mmio))
return PTR_ERR(rcdu->mmio);
2017-11-12 14:12:10 +02:00
/*
* Set the DMA coherent mask to reflect the DU 32-bit DMA address space
* limitations. When sourcing frames from a VSP the DU doesn't perform
* any memory access so set the mask to 40 bits to accept all buffers.
*/
mask = rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE) ? 40 : 32;
ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(mask));
if (ret)
return ret;
/* DRM/KMS objects */
ret = rcar_du_modeset_init(rcdu);
if (ret < 0) {
/*
* Don't use dev_err_probe(), as it would overwrite the probe
* deferral reason recorded in rcar_du_modeset_init().
*/
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev,
"failed to initialize DRM/KMS (%d)\n", ret);
goto error;
}
/*
* Register the DRM device with the core and the connectors with
* sysfs.
*/
ret = drm_dev_register(&rcdu->ddev, 0);
if (ret)
goto error;
drm_info(&rcdu->ddev, "Device %s probed\n", dev_name(&pdev->dev));
drm_client_setup(&rcdu->ddev, NULL);
return 0;
error:
drm_kms_helper_poll_fini(&rcdu->ddev);
return ret;
}
static struct platform_driver rcar_du_platform_driver = {
.probe = rcar_du_probe,
.remove = rcar_du_remove,
.shutdown = rcar_du_shutdown,
.driver = {
.name = "rcar-du",
.pm = pm_sleep_ptr(&rcar_du_pm_ops),
.of_match_table = rcar_du_of_table,
},
};
module_platform_driver(rcar_du_platform_driver);
MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
MODULE_DESCRIPTION("Renesas R-Car Display Unit DRM Driver");
MODULE_LICENSE("GPL");