summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/rcar-du
diff options
context:
space:
mode:
authorBiju Das <biju.das.jz@bp.renesas.com>2023-05-02 12:09:08 +0200
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2023-05-29 15:41:03 +0200
commit11696c5e89245a1d360f75be3dfc4960b25a265a (patch)
tree3b88479798b74644ee8d55d02e891df0c782683a /drivers/gpu/drm/rcar-du
parentdrm: rcar-du: remove R-Car H3 ES1.* workarounds (diff)
downloadlinux-11696c5e89245a1d360f75be3dfc4960b25a265a.tar.xz
linux-11696c5e89245a1d360f75be3dfc4960b25a265a.zip
drm: Place Renesas drivers in a separate dir
Create vendor specific renesas directory and move renesas drivers to that directory. Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com> Acked-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Diffstat (limited to 'drivers/gpu/drm/rcar-du')
-rw-r--r--drivers/gpu/drm/rcar-du/Kconfig82
-rw-r--r--drivers/gpu/drm/rcar-du/Makefile18
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_cmm.c217
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_cmm.h58
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.c1338
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.h103
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_drv.c744
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_drv.h152
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_encoder.c137
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_encoder.h29
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_group.c377
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_group.h65
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_kms.c1006
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_kms.h44
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.c831
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.h86
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_regs.h553
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_vsp.c513
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_vsp.h93
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_writeback.c246
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_writeback.h39
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c124
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_lvds.c1035
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_lvds.h41
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_lvds_regs.h111
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c1106
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_mipi_dsi.h31
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h176
-rw-r--r--drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c816
-rw-r--r--drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi_regs.h151
30 files changed, 0 insertions, 10322 deletions
diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig
deleted file mode 100644
index 53c356aed5d5..000000000000
--- a/drivers/gpu/drm/rcar-du/Kconfig
+++ /dev/null
@@ -1,82 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-config DRM_RCAR_DU
- tristate "DRM Support for R-Car Display Unit"
- depends on DRM && OF
- depends on ARM || ARM64
- depends on ARCH_RENESAS || COMPILE_TEST
- select DRM_KMS_HELPER
- select DRM_GEM_DMA_HELPER
- select VIDEOMODE_HELPERS
- help
- Choose this option if you have an R-Car chipset.
- If M is selected the module will be called rcar-du-drm.
-
-config DRM_RCAR_USE_CMM
- bool "R-Car DU Color Management Module (CMM) Support"
- depends on DRM_RCAR_DU
- default DRM_RCAR_DU
- help
- Enable support for R-Car Color Management Module (CMM).
-
-config DRM_RCAR_CMM
- def_tristate DRM_RCAR_DU
- depends on DRM_RCAR_USE_CMM
-
-config DRM_RCAR_DW_HDMI
- tristate "R-Car Gen3 and RZ/G2 DU HDMI Encoder Support"
- depends on DRM && OF
- depends on DRM_RCAR_DU || COMPILE_TEST
- select DRM_DW_HDMI
- help
- Enable support for R-Car Gen3 or RZ/G2 internal HDMI encoder.
-
-config DRM_RCAR_USE_LVDS
- bool "R-Car DU LVDS Encoder Support"
- depends on DRM_BRIDGE && OF
- depends on DRM_RCAR_DU || COMPILE_TEST
- default DRM_RCAR_DU
- help
- Enable support for the R-Car Display Unit embedded LVDS encoders.
-
-config DRM_RCAR_LVDS
- def_tristate DRM_RCAR_DU
- depends on DRM_RCAR_USE_LVDS
- depends on PM
- select DRM_KMS_HELPER
- select DRM_PANEL
- select RESET_CONTROLLER
-
-config DRM_RCAR_USE_MIPI_DSI
- bool "R-Car DU MIPI DSI Encoder Support"
- depends on DRM_BRIDGE && OF
- depends on DRM_RCAR_DU || COMPILE_TEST
- default DRM_RCAR_DU
- help
- Enable support for the R-Car Display Unit embedded MIPI DSI encoders.
-
-config DRM_RCAR_MIPI_DSI
- def_tristate DRM_RCAR_DU
- depends on DRM_RCAR_USE_MIPI_DSI
- select DRM_MIPI_DSI
- select RESET_CONTROLLER
-
-config DRM_RZG2L_MIPI_DSI
- tristate "RZ/G2L MIPI DSI Encoder Support"
- depends on DRM && DRM_BRIDGE && OF
- depends on ARCH_RENESAS || COMPILE_TEST
- select DRM_MIPI_DSI
- help
- Enable support for the RZ/G2L Display Unit embedded MIPI DSI encoders.
-
-config DRM_RCAR_VSP
- bool "R-Car DU VSP Compositor Support" if ARM
- default y if ARM64
- depends on DRM_RCAR_DU
- depends on VIDEO_RENESAS_VSP1=y || (VIDEO_RENESAS_VSP1 && DRM_RCAR_DU=m)
- help
- Enable support to expose the R-Car VSP Compositor as KMS planes.
-
-config DRM_RCAR_WRITEBACK
- bool
- default y if ARM64
- depends on DRM_RCAR_DU
diff --git a/drivers/gpu/drm/rcar-du/Makefile b/drivers/gpu/drm/rcar-du/Makefile
deleted file mode 100644
index b8f2c82651d9..000000000000
--- a/drivers/gpu/drm/rcar-du/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-rcar-du-drm-y := rcar_du_crtc.o \
- rcar_du_drv.o \
- rcar_du_encoder.o \
- rcar_du_group.o \
- rcar_du_kms.o \
- rcar_du_plane.o \
-
-rcar-du-drm-$(CONFIG_DRM_RCAR_VSP) += rcar_du_vsp.o
-rcar-du-drm-$(CONFIG_DRM_RCAR_WRITEBACK) += rcar_du_writeback.o
-
-obj-$(CONFIG_DRM_RCAR_CMM) += rcar_cmm.o
-obj-$(CONFIG_DRM_RCAR_DU) += rcar-du-drm.o
-obj-$(CONFIG_DRM_RCAR_DW_HDMI) += rcar_dw_hdmi.o
-obj-$(CONFIG_DRM_RCAR_LVDS) += rcar_lvds.o
-obj-$(CONFIG_DRM_RCAR_MIPI_DSI) += rcar_mipi_dsi.o
-
-obj-$(CONFIG_DRM_RZG2L_MIPI_DSI) += rzg2l_mipi_dsi.o
diff --git a/drivers/gpu/drm/rcar-du/rcar_cmm.c b/drivers/gpu/drm/rcar-du/rcar_cmm.c
deleted file mode 100644
index e2a67dda4658..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_cmm.c
+++ /dev/null
@@ -1,217 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * R-Car Display Unit Color Management Module
- *
- * Copyright (C) 2019 Jacopo Mondi <jacopo+renesas@jmondi.org>
- */
-
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-
-#include <drm/drm_color_mgmt.h>
-
-#include "rcar_cmm.h"
-
-#define CM2_LUT_CTRL 0x0000
-#define CM2_LUT_CTRL_LUT_EN BIT(0)
-#define CM2_LUT_TBL_BASE 0x0600
-#define CM2_LUT_TBL(__i) (CM2_LUT_TBL_BASE + (__i) * 4)
-
-struct rcar_cmm {
- void __iomem *base;
-
- /*
- * @lut: 1D-LUT state
- * @lut.enabled: 1D-LUT enabled flag
- */
- struct {
- bool enabled;
- } lut;
-};
-
-static inline int rcar_cmm_read(struct rcar_cmm *rcmm, u32 reg)
-{
- return ioread32(rcmm->base + reg);
-}
-
-static inline void rcar_cmm_write(struct rcar_cmm *rcmm, u32 reg, u32 data)
-{
- iowrite32(data, rcmm->base + reg);
-}
-
-/*
- * rcar_cmm_lut_write() - Scale the DRM LUT table entries to hardware precision
- * and write to the CMM registers
- * @rcmm: Pointer to the CMM device
- * @drm_lut: Pointer to the DRM LUT table
- */
-static void rcar_cmm_lut_write(struct rcar_cmm *rcmm,
- const struct drm_color_lut *drm_lut)
-{
- unsigned int i;
-
- for (i = 0; i < CM2_LUT_SIZE; ++i) {
- u32 entry = drm_color_lut_extract(drm_lut[i].red, 8) << 16
- | drm_color_lut_extract(drm_lut[i].green, 8) << 8
- | drm_color_lut_extract(drm_lut[i].blue, 8);
-
- rcar_cmm_write(rcmm, CM2_LUT_TBL(i), entry);
- }
-}
-
-/*
- * rcar_cmm_setup() - Configure the CMM unit
- * @pdev: The platform device associated with the CMM instance
- * @config: The CMM unit configuration
- *
- * Configure the CMM unit with the given configuration. Currently enabling,
- * disabling and programming of the 1-D LUT unit is supported.
- *
- * As rcar_cmm_setup() accesses the CMM registers the unit should be powered
- * and its functional clock enabled. To guarantee this, before any call to
- * this function is made, the CMM unit has to be enabled by calling
- * rcar_cmm_enable() first.
- *
- * TODO: Add support for LUT double buffer operations to avoid updating the
- * LUT table entries while a frame is being displayed.
- */
-int rcar_cmm_setup(struct platform_device *pdev,
- const struct rcar_cmm_config *config)
-{
- struct rcar_cmm *rcmm = platform_get_drvdata(pdev);
-
- /* Disable LUT if no table is provided. */
- if (!config->lut.table) {
- if (rcmm->lut.enabled) {
- rcar_cmm_write(rcmm, CM2_LUT_CTRL, 0);
- rcmm->lut.enabled = false;
- }
-
- return 0;
- }
-
- /* Enable LUT and program the new gamma table values. */
- if (!rcmm->lut.enabled) {
- rcar_cmm_write(rcmm, CM2_LUT_CTRL, CM2_LUT_CTRL_LUT_EN);
- rcmm->lut.enabled = true;
- }
-
- rcar_cmm_lut_write(rcmm, config->lut.table);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(rcar_cmm_setup);
-
-/*
- * rcar_cmm_enable() - Enable the CMM unit
- * @pdev: The platform device associated with the CMM instance
- *
- * When the output of the corresponding DU channel is routed to the CMM unit,
- * the unit shall be enabled before the DU channel is started, and remain
- * enabled until the channel is stopped. The CMM unit shall be disabled with
- * rcar_cmm_disable().
- *
- * Calls to rcar_cmm_enable() and rcar_cmm_disable() are not reference-counted.
- * It is an error to attempt to enable an already enabled CMM unit, or to
- * attempt to disable a disabled unit.
- */
-int rcar_cmm_enable(struct platform_device *pdev)
-{
- int ret;
-
- ret = pm_runtime_resume_and_get(&pdev->dev);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(rcar_cmm_enable);
-
-/*
- * rcar_cmm_disable() - Disable the CMM unit
- * @pdev: The platform device associated with the CMM instance
- *
- * See rcar_cmm_enable() for usage information.
- *
- * Disabling the CMM unit disable all the internal processing blocks. The CMM
- * state shall thus be restored with rcar_cmm_setup() when re-enabling the CMM
- * unit after the next rcar_cmm_enable() call.
- */
-void rcar_cmm_disable(struct platform_device *pdev)
-{
- struct rcar_cmm *rcmm = platform_get_drvdata(pdev);
-
- rcar_cmm_write(rcmm, CM2_LUT_CTRL, 0);
- rcmm->lut.enabled = false;
-
- pm_runtime_put(&pdev->dev);
-}
-EXPORT_SYMBOL_GPL(rcar_cmm_disable);
-
-/*
- * rcar_cmm_init() - Initialize the CMM unit
- * @pdev: The platform device associated with the CMM instance
- *
- * Return: 0 on success, -EPROBE_DEFER if the CMM is not available yet,
- * -ENODEV if the DRM_RCAR_CMM config option is disabled
- */
-int rcar_cmm_init(struct platform_device *pdev)
-{
- struct rcar_cmm *rcmm = platform_get_drvdata(pdev);
-
- if (!rcmm)
- return -EPROBE_DEFER;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(rcar_cmm_init);
-
-static int rcar_cmm_probe(struct platform_device *pdev)
-{
- struct rcar_cmm *rcmm;
-
- rcmm = devm_kzalloc(&pdev->dev, sizeof(*rcmm), GFP_KERNEL);
- if (!rcmm)
- return -ENOMEM;
- platform_set_drvdata(pdev, rcmm);
-
- rcmm->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(rcmm->base))
- return PTR_ERR(rcmm->base);
-
- pm_runtime_enable(&pdev->dev);
-
- return 0;
-}
-
-static int rcar_cmm_remove(struct platform_device *pdev)
-{
- pm_runtime_disable(&pdev->dev);
-
- return 0;
-}
-
-static const struct of_device_id rcar_cmm_of_table[] = {
- { .compatible = "renesas,rcar-gen3-cmm", },
- { .compatible = "renesas,rcar-gen2-cmm", },
- { },
-};
-MODULE_DEVICE_TABLE(of, rcar_cmm_of_table);
-
-static struct platform_driver rcar_cmm_platform_driver = {
- .probe = rcar_cmm_probe,
- .remove = rcar_cmm_remove,
- .driver = {
- .name = "rcar-cmm",
- .of_match_table = rcar_cmm_of_table,
- },
-};
-
-module_platform_driver(rcar_cmm_platform_driver);
-
-MODULE_AUTHOR("Jacopo Mondi <jacopo+renesas@jmondi.org>");
-MODULE_DESCRIPTION("Renesas R-Car CMM Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/rcar-du/rcar_cmm.h b/drivers/gpu/drm/rcar-du/rcar_cmm.h
deleted file mode 100644
index 628072acc98b..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_cmm.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * R-Car Display Unit Color Management Module
- *
- * Copyright (C) 2019 Jacopo Mondi <jacopo+renesas@jmondi.org>
- */
-
-#ifndef __RCAR_CMM_H__
-#define __RCAR_CMM_H__
-
-#define CM2_LUT_SIZE 256
-
-struct drm_color_lut;
-struct platform_device;
-
-/**
- * struct rcar_cmm_config - CMM configuration
- *
- * @lut: 1D-LUT configuration
- * @lut.table: 1D-LUT table entries. Disable LUT operations when NULL
- */
-struct rcar_cmm_config {
- struct {
- struct drm_color_lut *table;
- } lut;
-};
-
-#if IS_ENABLED(CONFIG_DRM_RCAR_CMM)
-int rcar_cmm_init(struct platform_device *pdev);
-
-int rcar_cmm_enable(struct platform_device *pdev);
-void rcar_cmm_disable(struct platform_device *pdev);
-
-int rcar_cmm_setup(struct platform_device *pdev,
- const struct rcar_cmm_config *config);
-#else
-static inline int rcar_cmm_init(struct platform_device *pdev)
-{
- return -ENODEV;
-}
-
-static inline int rcar_cmm_enable(struct platform_device *pdev)
-{
- return 0;
-}
-
-static inline void rcar_cmm_disable(struct platform_device *pdev)
-{
-}
-
-static inline int rcar_cmm_setup(struct platform_device *pdev,
- const struct rcar_cmm_config *config)
-{
- return 0;
-}
-#endif /* IS_ENABLED(CONFIG_DRM_RCAR_CMM) */
-
-#endif /* __RCAR_CMM_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
deleted file mode 100644
index 7e175dbfd892..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ /dev/null
@@ -1,1338 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * R-Car Display Unit CRTCs
- *
- * Copyright (C) 2013-2015 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-#include <linux/clk.h>
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-
-#include <drm/drm_atomic.h>
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_bridge.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_device.h>
-#include <drm/drm_gem_dma_helper.h>
-#include <drm/drm_vblank.h>
-
-#include "rcar_cmm.h"
-#include "rcar_du_crtc.h"
-#include "rcar_du_drv.h"
-#include "rcar_du_encoder.h"
-#include "rcar_du_kms.h"
-#include "rcar_du_plane.h"
-#include "rcar_du_regs.h"
-#include "rcar_du_vsp.h"
-#include "rcar_lvds.h"
-#include "rcar_mipi_dsi.h"
-
-static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg)
-{
- struct rcar_du_device *rcdu = rcrtc->dev;
-
- return rcar_du_read(rcdu, rcrtc->mmio_offset + reg);
-}
-
-static void rcar_du_crtc_write(struct rcar_du_crtc *rcrtc, u32 reg, u32 data)
-{
- struct rcar_du_device *rcdu = rcrtc->dev;
-
- rcar_du_write(rcdu, rcrtc->mmio_offset + reg, data);
-}
-
-static void rcar_du_crtc_clr(struct rcar_du_crtc *rcrtc, u32 reg, u32 clr)
-{
- struct rcar_du_device *rcdu = rcrtc->dev;
-
- rcar_du_write(rcdu, rcrtc->mmio_offset + reg,
- rcar_du_read(rcdu, rcrtc->mmio_offset + reg) & ~clr);
-}
-
-static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set)
-{
- struct rcar_du_device *rcdu = rcrtc->dev;
-
- rcar_du_write(rcdu, rcrtc->mmio_offset + reg,
- rcar_du_read(rcdu, rcrtc->mmio_offset + reg) | set);
-}
-
-void rcar_du_crtc_dsysr_clr_set(struct rcar_du_crtc *rcrtc, u32 clr, u32 set)
-{
- struct rcar_du_device *rcdu = rcrtc->dev;
-
- rcrtc->dsysr = (rcrtc->dsysr & ~clr) | set;
- rcar_du_write(rcdu, rcrtc->mmio_offset + DSYSR, rcrtc->dsysr);
-}
-
-/* -----------------------------------------------------------------------------
- * Hardware Setup
- */
-
-struct dpll_info {
- unsigned int output;
- unsigned int fdpll;
- unsigned int n;
- unsigned int m;
-};
-
-static void rcar_du_dpll_divider(struct rcar_du_crtc *rcrtc,
- struct dpll_info *dpll,
- unsigned long input,
- unsigned long target)
-{
- unsigned long best_diff = (unsigned long)-1;
- unsigned long diff;
- unsigned int fdpll;
- unsigned int m;
- unsigned int n;
-
- /*
- * fin fvco fout fclkout
- * in --> [1/M] --> |PD| -> [LPF] -> [VCO] -> [1/P] -+-> [1/FDPLL] -> out
- * +-> | | |
- * | |
- * +---------------- [1/N] <------------+
- *
- * fclkout = fvco / P / FDPLL -- (1)
- *
- * fin/M = fvco/P/N
- *
- * fvco = fin * P * N / M -- (2)
- *
- * (1) + (2) indicates
- *
- * fclkout = fin * N / M / FDPLL
- *
- * NOTES
- * N : (n + 1)
- * M : (m + 1)
- * FDPLL : (fdpll + 1)
- * P : 2
- * 2kHz < fvco < 4096MHz
- *
- * To minimize the jitter,
- * N : as large as possible
- * M : as small as possible
- */
- for (m = 0; m < 4; m++) {
- for (n = 119; n > 38; n--) {
- /*
- * This code only runs on 64-bit architectures, the
- * unsigned long type can thus be used for 64-bit
- * computation. It will still compile without any
- * warning on 32-bit architectures.
- *
- * To optimize calculations, use fout instead of fvco
- * to verify the VCO frequency constraint.
- */
- unsigned long fout = input * (n + 1) / (m + 1);
-
- if (fout < 1000 || fout > 2048 * 1000 * 1000U)
- continue;
-
- for (fdpll = 1; fdpll < 32; fdpll++) {
- unsigned long output;
-
- output = fout / (fdpll + 1);
- if (output >= 400 * 1000 * 1000)
- continue;
-
- diff = abs((long)output - (long)target);
- if (best_diff > diff) {
- best_diff = diff;
- dpll->n = n;
- dpll->m = m;
- dpll->fdpll = fdpll;
- dpll->output = output;
- }
-
- if (diff == 0)
- goto done;
- }
- }
- }
-
-done:
- dev_dbg(rcrtc->dev->dev,
- "output:%u, fdpll:%u, n:%u, m:%u, diff:%lu\n",
- dpll->output, dpll->fdpll, dpll->n, dpll->m, best_diff);
-}
-
-struct du_clk_params {
- struct clk *clk;
- unsigned long rate;
- unsigned long diff;
- u32 escr;
-};
-
-static void rcar_du_escr_divider(struct clk *clk, unsigned long target,
- u32 escr, struct du_clk_params *params)
-{
- unsigned long rate;
- unsigned long diff;
- u32 div;
-
- /*
- * If the target rate has already been achieved perfectly we can't do
- * better.
- */
- if (params->diff == 0)
- return;
-
- /*
- * Compute the input clock rate and internal divisor values to obtain
- * the clock rate closest to the target frequency.
- */
- rate = clk_round_rate(clk, target);
- div = clamp(DIV_ROUND_CLOSEST(rate, target), 1UL, 64UL) - 1;
- diff = abs(rate / (div + 1) - target);
-
- /*
- * Store the parameters if the resulting frequency is better than any
- * previously calculated value.
- */
- if (diff < params->diff) {
- params->clk = clk;
- params->rate = rate;
- params->diff = diff;
- params->escr = escr | div;
- }
-}
-
-static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
-{
- const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
- struct rcar_du_device *rcdu = rcrtc->dev;
- unsigned long mode_clock = mode->clock * 1000;
- unsigned int hdse_offset;
- u32 dsmr;
- u32 escr;
-
- if (rcdu->info->dpll_mask & (1 << rcrtc->index)) {
- unsigned long target = mode_clock;
- struct dpll_info dpll = { 0 };
- unsigned long extclk;
- u32 dpllcr;
- u32 div = 0;
-
- /*
- * DU channels that have a display PLL can't use the internal
- * system clock, and have no internal clock divider.
- */
- extclk = clk_get_rate(rcrtc->extclock);
- rcar_du_dpll_divider(rcrtc, &dpll, extclk, target);
-
- dpllcr = DPLLCR_CODE | DPLLCR_CLKE
- | DPLLCR_FDPLL(dpll.fdpll)
- | DPLLCR_N(dpll.n) | DPLLCR_M(dpll.m)
- | DPLLCR_STBY;
-
- if (rcrtc->index == 1)
- dpllcr |= DPLLCR_PLCS1
- | DPLLCR_INCS_DOTCLKIN1;
- else
- dpllcr |= DPLLCR_PLCS0
- | DPLLCR_INCS_DOTCLKIN0;
-
- rcar_du_group_write(rcrtc->group, DPLLCR, dpllcr);
-
- escr = ESCR_DCLKSEL_DCLKIN | div;
- } else if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index) ||
- rcdu->info->dsi_clk_mask & BIT(rcrtc->index)) {
- /*
- * Use the external LVDS or DSI PLL output as the dot clock when
- * outputting to the LVDS or DSI encoder on an SoC that supports
- * this clock routing option. We use the clock directly in that
- * case, without any additional divider.
- */
- escr = ESCR_DCLKSEL_DCLKIN;
- } else {
- struct du_clk_params params = { .diff = (unsigned long)-1 };
-
- rcar_du_escr_divider(rcrtc->clock, mode_clock,
- ESCR_DCLKSEL_CLKS, &params);
- if (rcrtc->extclock)
- rcar_du_escr_divider(rcrtc->extclock, mode_clock,
- ESCR_DCLKSEL_DCLKIN, &params);
-
- dev_dbg(rcrtc->dev->dev, "mode clock %lu %s rate %lu\n",
- mode_clock, params.clk == rcrtc->clock ? "cpg" : "ext",
- params.rate);
-
- clk_set_rate(params.clk, params.rate);
- escr = params.escr;
- }
-
- /*
- * The ESCR register only exists in DU channels that can output to an
- * LVDS or DPAT, and the OTAR register in DU channels that can output
- * to a DPAD.
- */
- if ((rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs |
- rcdu->info->routes[RCAR_DU_OUTPUT_DPAD1].possible_crtcs |
- rcdu->info->routes[RCAR_DU_OUTPUT_LVDS0].possible_crtcs |
- rcdu->info->routes[RCAR_DU_OUTPUT_LVDS1].possible_crtcs) &
- BIT(rcrtc->index)) {
- dev_dbg(rcrtc->dev->dev, "%s: ESCR 0x%08x\n", __func__, escr);
-
- rcar_du_crtc_write(rcrtc, rcrtc->index % 2 ? ESCR13 : ESCR02, escr);
- }
-
- if ((rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs |
- rcdu->info->routes[RCAR_DU_OUTPUT_DPAD1].possible_crtcs) &
- BIT(rcrtc->index))
- rcar_du_crtc_write(rcrtc, rcrtc->index % 2 ? OTAR13 : OTAR02, 0);
-
- /* Signal polarities */
- dsmr = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? DSMR_VSL : 0)
- | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? DSMR_HSL : 0)
- | ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? DSMR_ODEV : 0)
- | DSMR_DIPM_DISP | DSMR_CSPM;
- rcar_du_crtc_write(rcrtc, DSMR, dsmr);
-
- /*
- * When the CMM is enabled, an additional offset of 25 pixels must be
- * subtracted from the HDS (horizontal display start) and HDE
- * (horizontal display end) registers.
- */
- hdse_offset = 19;
- if (rcrtc->group->cmms_mask & BIT(rcrtc->index % 2))
- hdse_offset += 25;
-
- /* Display timings */
- rcar_du_crtc_write(rcrtc, HDSR, mode->htotal - mode->hsync_start -
- hdse_offset);
- rcar_du_crtc_write(rcrtc, HDER, mode->htotal - mode->hsync_start +
- mode->hdisplay - hdse_offset);
- rcar_du_crtc_write(rcrtc, HSWR, mode->hsync_end -
- mode->hsync_start - 1);
- rcar_du_crtc_write(rcrtc, HCR, mode->htotal - 1);
-
- rcar_du_crtc_write(rcrtc, VDSR, mode->crtc_vtotal -
- mode->crtc_vsync_end - 2);
- rcar_du_crtc_write(rcrtc, VDER, mode->crtc_vtotal -
- mode->crtc_vsync_end +
- mode->crtc_vdisplay - 2);
- rcar_du_crtc_write(rcrtc, VSPR, mode->crtc_vtotal -
- mode->crtc_vsync_end +
- mode->crtc_vsync_start - 1);
- rcar_du_crtc_write(rcrtc, VCR, mode->crtc_vtotal - 1);
-
- rcar_du_crtc_write(rcrtc, DESR, mode->htotal - mode->hsync_start - 1);
- rcar_du_crtc_write(rcrtc, DEWR, mode->hdisplay);
-}
-
-static unsigned int plane_zpos(struct rcar_du_plane *plane)
-{
- return plane->plane.state->normalized_zpos;
-}
-
-static const struct rcar_du_format_info *
-plane_format(struct rcar_du_plane *plane)
-{
- return to_rcar_plane_state(plane->plane.state)->format;
-}
-
-static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc)
-{
- struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES];
- struct rcar_du_device *rcdu = rcrtc->dev;
- unsigned int num_planes = 0;
- unsigned int dptsr_planes;
- unsigned int hwplanes = 0;
- unsigned int prio = 0;
- unsigned int i;
- u32 dspr = 0;
-
- for (i = 0; i < rcrtc->group->num_planes; ++i) {
- struct rcar_du_plane *plane = &rcrtc->group->planes[i];
- unsigned int j;
-
- if (plane->plane.state->crtc != &rcrtc->crtc ||
- !plane->plane.state->visible)
- continue;
-
- /* Insert the plane in the sorted planes array. */
- for (j = num_planes++; j > 0; --j) {
- if (plane_zpos(planes[j-1]) <= plane_zpos(plane))
- break;
- planes[j] = planes[j-1];
- }
-
- planes[j] = plane;
- prio += plane_format(plane)->planes * 4;
- }
-
- for (i = 0; i < num_planes; ++i) {
- struct rcar_du_plane *plane = planes[i];
- struct drm_plane_state *state = plane->plane.state;
- unsigned int index = to_rcar_plane_state(state)->hwindex;
-
- prio -= 4;
- dspr |= (index + 1) << prio;
- hwplanes |= 1 << index;
-
- if (plane_format(plane)->planes == 2) {
- index = (index + 1) % 8;
-
- prio -= 4;
- dspr |= (index + 1) << prio;
- hwplanes |= 1 << index;
- }
- }
-
- /* If VSP+DU integration is enabled the plane assignment is fixed. */
- if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE)) {
- if (rcdu->info->gen < 3) {
- dspr = (rcrtc->index % 2) + 1;
- hwplanes = 1 << (rcrtc->index % 2);
- } else {
- dspr = (rcrtc->index % 2) ? 3 : 1;
- hwplanes = 1 << ((rcrtc->index % 2) ? 2 : 0);
- }
- }
-
- /*
- * Update the planes to display timing and dot clock generator
- * associations.
- *
- * Updating the DPTSR register requires restarting the CRTC group,
- * resulting in visible flicker. To mitigate the issue only update the
- * association if needed by enabled planes. Planes being disabled will
- * keep their current association.
- */
- mutex_lock(&rcrtc->group->lock);
-
- dptsr_planes = rcrtc->index % 2 ? rcrtc->group->dptsr_planes | hwplanes
- : rcrtc->group->dptsr_planes & ~hwplanes;
-
- if (dptsr_planes != rcrtc->group->dptsr_planes) {
- rcar_du_group_write(rcrtc->group, DPTSR,
- (dptsr_planes << 16) | dptsr_planes);
- rcrtc->group->dptsr_planes = dptsr_planes;
-
- if (rcrtc->group->used_crtcs)
- rcar_du_group_restart(rcrtc->group);
- }
-
- /* Restart the group if plane sources have changed. */
- if (rcrtc->group->need_restart)
- rcar_du_group_restart(rcrtc->group);
-
- mutex_unlock(&rcrtc->group->lock);
-
- rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR,
- dspr);
-}
-
-/* -----------------------------------------------------------------------------
- * Page Flip
- */
-
-void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc)
-{
- struct drm_pending_vblank_event *event;
- struct drm_device *dev = rcrtc->crtc.dev;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->event_lock, flags);
- event = rcrtc->event;
- rcrtc->event = NULL;
- spin_unlock_irqrestore(&dev->event_lock, flags);
-
- if (event == NULL)
- return;
-
- spin_lock_irqsave(&dev->event_lock, flags);
- drm_crtc_send_vblank_event(&rcrtc->crtc, event);
- wake_up(&rcrtc->flip_wait);
- spin_unlock_irqrestore(&dev->event_lock, flags);
-
- drm_crtc_vblank_put(&rcrtc->crtc);
-}
-
-static bool rcar_du_crtc_page_flip_pending(struct rcar_du_crtc *rcrtc)
-{
- struct drm_device *dev = rcrtc->crtc.dev;
- unsigned long flags;
- bool pending;
-
- spin_lock_irqsave(&dev->event_lock, flags);
- pending = rcrtc->event != NULL;
- spin_unlock_irqrestore(&dev->event_lock, flags);
-
- return pending;
-}
-
-static void rcar_du_crtc_wait_page_flip(struct rcar_du_crtc *rcrtc)
-{
- struct rcar_du_device *rcdu = rcrtc->dev;
-
- if (wait_event_timeout(rcrtc->flip_wait,
- !rcar_du_crtc_page_flip_pending(rcrtc),
- msecs_to_jiffies(50)))
- return;
-
- dev_warn(rcdu->dev, "page flip timeout\n");
-
- rcar_du_crtc_finish_page_flip(rcrtc);
-}
-
-/* -----------------------------------------------------------------------------
- * Color Management Module (CMM)
- */
-
-static int rcar_du_cmm_check(struct drm_crtc *crtc,
- struct drm_crtc_state *state)
-{
- struct drm_property_blob *drm_lut = state->gamma_lut;
- struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
- struct device *dev = rcrtc->dev->dev;
-
- if (!drm_lut)
- return 0;
-
- /* We only accept fully populated LUT tables. */
- if (drm_color_lut_size(drm_lut) != CM2_LUT_SIZE) {
- dev_err(dev, "invalid gamma lut size: %zu bytes\n",
- drm_lut->length);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void rcar_du_cmm_setup(struct drm_crtc *crtc)
-{
- struct drm_property_blob *drm_lut = crtc->state->gamma_lut;
- struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
- struct rcar_cmm_config cmm_config = {};
-
- if (!rcrtc->cmm)
- return;
-
- if (drm_lut)
- cmm_config.lut.table = (struct drm_color_lut *)drm_lut->data;
-
- rcar_cmm_setup(rcrtc->cmm, &cmm_config);
-}
-
-/* -----------------------------------------------------------------------------
- * Start/Stop and Suspend/Resume
- */
-
-static void rcar_du_crtc_setup(struct rcar_du_crtc *rcrtc)
-{
- /* Set display off and background to black */
- rcar_du_crtc_write(rcrtc, DOOR, DOOR_RGB(0, 0, 0));
- rcar_du_crtc_write(rcrtc, BPOR, BPOR_RGB(0, 0, 0));
-
- /* Configure display timings and output routing */
- rcar_du_crtc_set_display_timing(rcrtc);
- rcar_du_group_set_routing(rcrtc->group);
-
- /* Start with all planes disabled. */
- rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
-
- /* Enable the VSP compositor. */
- if (rcar_du_has(rcrtc->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
- rcar_du_vsp_enable(rcrtc);
-
- /* Turn vertical blanking interrupt reporting on. */
- drm_crtc_vblank_on(&rcrtc->crtc);
-}
-
-static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
-{
- int ret;
-
- /*
- * Guard against double-get, as the function is called from both the
- * .atomic_enable() and .atomic_begin() handlers.
- */
- if (rcrtc->initialized)
- return 0;
-
- ret = clk_prepare_enable(rcrtc->clock);
- if (ret < 0)
- return ret;
-
- ret = clk_prepare_enable(rcrtc->extclock);
- if (ret < 0)
- goto error_clock;
-
- ret = rcar_du_group_get(rcrtc->group);
- if (ret < 0)
- goto error_group;
-
- rcar_du_crtc_setup(rcrtc);
- rcrtc->initialized = true;
-
- return 0;
-
-error_group:
- clk_disable_unprepare(rcrtc->extclock);
-error_clock:
- clk_disable_unprepare(rcrtc->clock);
- return ret;
-}
-
-static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
-{
- rcar_du_group_put(rcrtc->group);
-
- clk_disable_unprepare(rcrtc->extclock);
- clk_disable_unprepare(rcrtc->clock);
-
- rcrtc->initialized = false;
-}
-
-static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
-{
- bool interlaced;
-
- /*
- * Select master sync mode. This enables display operation in master
- * sync mode (with the HSYNC and VSYNC signals configured as outputs and
- * actively driven).
- */
- interlaced = rcrtc->crtc.mode.flags & DRM_MODE_FLAG_INTERLACE;
- rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK | DSYSR_SCM_MASK,
- (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
- DSYSR_TVM_MASTER);
-
- rcar_du_group_start_stop(rcrtc->group, true);
-}
-
-static void rcar_du_crtc_disable_planes(struct rcar_du_crtc *rcrtc)
-{
- struct rcar_du_device *rcdu = rcrtc->dev;
- struct drm_crtc *crtc = &rcrtc->crtc;
- u32 status;
-
- /* Make sure vblank interrupts are enabled. */
- drm_crtc_vblank_get(crtc);
-
- /*
- * Disable planes and calculate how many vertical blanking interrupts we
- * have to wait for. If a vertical blanking interrupt has been triggered
- * but not processed yet, we don't know whether it occurred before or
- * after the planes got disabled. We thus have to wait for two vblank
- * interrupts in that case.
- */
- spin_lock_irq(&rcrtc->vblank_lock);
- rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
- status = rcar_du_crtc_read(rcrtc, DSSR);
- rcrtc->vblank_count = status & DSSR_VBK ? 2 : 1;
- spin_unlock_irq(&rcrtc->vblank_lock);
-
- if (!wait_event_timeout(rcrtc->vblank_wait, rcrtc->vblank_count == 0,
- msecs_to_jiffies(100)))
- dev_warn(rcdu->dev, "vertical blanking timeout\n");
-
- drm_crtc_vblank_put(crtc);
-}
-
-static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
-{
- struct drm_crtc *crtc = &rcrtc->crtc;
-
- /*
- * Disable all planes and wait for the change to take effect. This is
- * required as the plane enable registers are updated on vblank, and no
- * vblank will occur once the CRTC is stopped. Disabling planes when
- * starting the CRTC thus wouldn't be enough as it would start scanning
- * out immediately from old frame buffers until the next vblank.
- *
- * This increases the CRTC stop delay, especially when multiple CRTCs
- * are stopped in one operation as we now wait for one vblank per CRTC.
- * Whether this can be improved needs to be researched.
- */
- rcar_du_crtc_disable_planes(rcrtc);
-
- /*
- * Disable vertical blanking interrupt reporting. We first need to wait
- * for page flip completion before stopping the CRTC as userspace
- * expects page flips to eventually complete.
- */
- rcar_du_crtc_wait_page_flip(rcrtc);
- drm_crtc_vblank_off(crtc);
-
- /* Disable the VSP compositor. */
- if (rcar_du_has(rcrtc->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
- rcar_du_vsp_disable(rcrtc);
-
- if (rcrtc->cmm)
- rcar_cmm_disable(rcrtc->cmm);
-
- /*
- * Select switch sync mode. This stops display operation and configures
- * the HSYNC and VSYNC signals as inputs.
- *
- * TODO: Find another way to stop the display for DUs that don't support
- * TVM sync.
- */
- if (rcar_du_has(rcrtc->dev, RCAR_DU_FEATURE_TVM_SYNC))
- rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK,
- DSYSR_TVM_SWITCH);
-
- rcar_du_group_start_stop(rcrtc->group, false);
-}
-
-/* -----------------------------------------------------------------------------
- * CRTC Functions
- */
-
-static int rcar_du_crtc_atomic_check(struct drm_crtc *crtc,
- struct drm_atomic_state *state)
-{
- struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
- crtc);
- struct rcar_du_crtc_state *rstate = to_rcar_crtc_state(crtc_state);
- struct drm_encoder *encoder;
- int ret;
-
- ret = rcar_du_cmm_check(crtc, crtc_state);
- if (ret)
- return ret;
-
- /* Store the routes from the CRTC output to the DU outputs. */
- rstate->outputs = 0;
-
- drm_for_each_encoder_mask(encoder, crtc->dev,
- crtc_state->encoder_mask) {
- struct rcar_du_encoder *renc;
-
- /* Skip the writeback encoder. */
- if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL)
- continue;
-
- renc = to_rcar_encoder(encoder);
- rstate->outputs |= BIT(renc->output);
- }
-
- return 0;
-}
-
-static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
- struct drm_atomic_state *state)
-{
- struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
- struct rcar_du_crtc_state *rstate = to_rcar_crtc_state(crtc->state);
- struct rcar_du_device *rcdu = rcrtc->dev;
-
- if (rcrtc->cmm)
- rcar_cmm_enable(rcrtc->cmm);
- rcar_du_crtc_get(rcrtc);
-
- /*
- * On D3/E3 the dot clock is provided by the LVDS encoder attached to
- * the DU channel. We need to enable its clock output explicitly before
- * starting the CRTC, as the bridge hasn't been enabled by the atomic
- * helpers yet.
- */
- if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index)) {
- bool dot_clk_only = rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0);
- struct drm_bridge *bridge = rcdu->lvds[rcrtc->index];
- const struct drm_display_mode *mode =
- &crtc->state->adjusted_mode;
-
- rcar_lvds_pclk_enable(bridge, mode->clock * 1000, dot_clk_only);
- }
-
- /*
- * Similarly to LVDS, on V3U the dot clock is provided by the DSI
- * encoder, and we need to enable the DSI clocks before enabling the CRTC.
- */
- if ((rcdu->info->dsi_clk_mask & BIT(rcrtc->index)) &&
- (rstate->outputs &
- (BIT(RCAR_DU_OUTPUT_DSI0) | BIT(RCAR_DU_OUTPUT_DSI1)))) {
- struct drm_bridge *bridge = rcdu->dsi[rcrtc->index];
-
- rcar_mipi_dsi_pclk_enable(bridge, state);
- }
-
- rcar_du_crtc_start(rcrtc);
-
- /*
- * TODO: The chip manual indicates that CMM tables should be written
- * after the DU channel has been activated. Investigate the impact
- * of this restriction on the first displayed frame.
- */
- rcar_du_cmm_setup(crtc);
-}
-
-static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
- struct drm_atomic_state *state)
-{
- struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state,
- crtc);
- struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
- struct rcar_du_crtc_state *rstate = to_rcar_crtc_state(old_state);
- struct rcar_du_device *rcdu = rcrtc->dev;
-
- rcar_du_crtc_stop(rcrtc);
- rcar_du_crtc_put(rcrtc);
-
- if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index)) {
- bool dot_clk_only = rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0);
- struct drm_bridge *bridge = rcdu->lvds[rcrtc->index];
-
- /*
- * Disable the LVDS clock output, see
- * rcar_du_crtc_atomic_enable(). When the LVDS output is used,
- * this also disables the LVDS encoder.
- */
- rcar_lvds_pclk_disable(bridge, dot_clk_only);
- }
-
- if ((rcdu->info->dsi_clk_mask & BIT(rcrtc->index)) &&
- (rstate->outputs &
- (BIT(RCAR_DU_OUTPUT_DSI0) | BIT(RCAR_DU_OUTPUT_DSI1)))) {
- struct drm_bridge *bridge = rcdu->dsi[rcrtc->index];
-
- /*
- * Disable the DSI clock output, see
- * rcar_du_crtc_atomic_enable().
- */
- rcar_mipi_dsi_pclk_disable(bridge);
- }
-
- spin_lock_irq(&crtc->dev->event_lock);
- if (crtc->state->event) {
- drm_crtc_send_vblank_event(crtc, crtc->state->event);
- crtc->state->event = NULL;
- }
- spin_unlock_irq(&crtc->dev->event_lock);
-}
-
-static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc,
- struct drm_atomic_state *state)
-{
- struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
-
- WARN_ON(!crtc->state->enable);
-
- /*
- * If a mode set is in progress we can be called with the CRTC disabled.
- * We thus need to first get and setup the CRTC in order to configure
- * planes. We must *not* put the CRTC in .atomic_flush(), as it must be
- * kept awake until the .atomic_enable() call that will follow. The get
- * operation in .atomic_enable() will in that case be a no-op, and the
- * CRTC will be put later in .atomic_disable().
- *
- * If a mode set is not in progress the CRTC is enabled, and the
- * following get call will be a no-op. There is thus no need to balance
- * it in .atomic_flush() either.
- */
- rcar_du_crtc_get(rcrtc);
-
- /* If the active state changed, we let .atomic_enable handle CMM. */
- if (crtc->state->color_mgmt_changed && !crtc->state->active_changed)
- rcar_du_cmm_setup(crtc);
-
- if (rcar_du_has(rcrtc->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
- rcar_du_vsp_atomic_begin(rcrtc);
-}
-
-static void rcar_du_crtc_atomic_flush(struct drm_crtc *crtc,
- struct drm_atomic_state *state)
-{
- struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
- struct drm_device *dev = rcrtc->crtc.dev;
- unsigned long flags;
-
- rcar_du_crtc_update_planes(rcrtc);
-
- if (crtc->state->event) {
- WARN_ON(drm_crtc_vblank_get(crtc) != 0);
-
- spin_lock_irqsave(&dev->event_lock, flags);
- rcrtc->event = crtc->state->event;
- crtc->state->event = NULL;
- spin_unlock_irqrestore(&dev->event_lock, flags);
- }
-
- if (rcar_du_has(rcrtc->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
- rcar_du_vsp_atomic_flush(rcrtc);
-}
-
-static enum drm_mode_status
-rcar_du_crtc_mode_valid(struct drm_crtc *crtc,
- const struct drm_display_mode *mode)
-{
- struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
- struct rcar_du_device *rcdu = rcrtc->dev;
- bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
- unsigned int min_sync_porch;
- unsigned int vbp;
-
- if (interlaced && !rcar_du_has(rcdu, RCAR_DU_FEATURE_INTERLACED))
- return MODE_NO_INTERLACE;
-
- /*
- * The hardware requires a minimum combined horizontal sync and back
- * porch of 20 pixels (when CMM isn't used) or 45 pixels (when CMM is
- * used), and a minimum vertical back porch of 3 lines.
- */
- min_sync_porch = 20;
- if (rcrtc->group->cmms_mask & BIT(rcrtc->index % 2))
- min_sync_porch += 25;
-
- if (mode->htotal - mode->hsync_start < min_sync_porch)
- return MODE_HBLANK_NARROW;
-
- vbp = (mode->vtotal - mode->vsync_end) / (interlaced ? 2 : 1);
- if (vbp < 3)
- return MODE_VBLANK_NARROW;
-
- return MODE_OK;
-}
-
-static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
- .atomic_check = rcar_du_crtc_atomic_check,
- .atomic_begin = rcar_du_crtc_atomic_begin,
- .atomic_flush = rcar_du_crtc_atomic_flush,
- .atomic_enable = rcar_du_crtc_atomic_enable,
- .atomic_disable = rcar_du_crtc_atomic_disable,
- .mode_valid = rcar_du_crtc_mode_valid,
-};
-
-static void rcar_du_crtc_crc_init(struct rcar_du_crtc *rcrtc)
-{
- struct rcar_du_device *rcdu = rcrtc->dev;
- const char **sources;
- unsigned int count;
- int i = -1;
-
- /* CRC available only on Gen3 HW. */
- if (rcdu->info->gen < 3)
- return;
-
- /* Reserve 1 for "auto" source. */
- count = rcrtc->vsp->num_planes + 1;
-
- sources = kmalloc_array(count, sizeof(*sources), GFP_KERNEL);
- if (!sources)
- return;
-
- sources[0] = kstrdup("auto", GFP_KERNEL);
- if (!sources[0])
- goto error;
-
- for (i = 0; i < rcrtc->vsp->num_planes; ++i) {
- struct drm_plane *plane = &rcrtc->vsp->planes[i].plane;
- char name[16];
-
- sprintf(name, "plane%u", plane->base.id);
- sources[i + 1] = kstrdup(name, GFP_KERNEL);
- if (!sources[i + 1])
- goto error;
- }
-
- rcrtc->sources = sources;
- rcrtc->sources_count = count;
- return;
-
-error:
- while (i >= 0) {
- kfree(sources[i]);
- i--;
- }
- kfree(sources);
-}
-
-static void rcar_du_crtc_crc_cleanup(struct rcar_du_crtc *rcrtc)
-{
- unsigned int i;
-
- if (!rcrtc->sources)
- return;
-
- for (i = 0; i < rcrtc->sources_count; i++)
- kfree(rcrtc->sources[i]);
- kfree(rcrtc->sources);
-
- rcrtc->sources = NULL;
- rcrtc->sources_count = 0;
-}
-
-static struct drm_crtc_state *
-rcar_du_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
-{
- struct rcar_du_crtc_state *state;
- struct rcar_du_crtc_state *copy;
-
- if (WARN_ON(!crtc->state))
- return NULL;
-
- state = to_rcar_crtc_state(crtc->state);
- copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
- if (copy == NULL)
- return NULL;
-
- __drm_atomic_helper_crtc_duplicate_state(crtc, &copy->state);
-
- return &copy->state;
-}
-
-static void rcar_du_crtc_atomic_destroy_state(struct drm_crtc *crtc,
- struct drm_crtc_state *state)
-{
- __drm_atomic_helper_crtc_destroy_state(state);
- kfree(to_rcar_crtc_state(state));
-}
-
-static void rcar_du_crtc_cleanup(struct drm_crtc *crtc)
-{
- struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
-
- rcar_du_crtc_crc_cleanup(rcrtc);
-
- return drm_crtc_cleanup(crtc);
-}
-
-static void rcar_du_crtc_reset(struct drm_crtc *crtc)
-{
- struct rcar_du_crtc_state *state;
-
- if (crtc->state) {
- rcar_du_crtc_atomic_destroy_state(crtc, crtc->state);
- crtc->state = NULL;
- }
-
- state = kzalloc(sizeof(*state), GFP_KERNEL);
- if (state == NULL)
- return;
-
- state->crc.source = VSP1_DU_CRC_NONE;
- state->crc.index = 0;
-
- __drm_atomic_helper_crtc_reset(crtc, &state->state);
-}
-
-static int rcar_du_crtc_enable_vblank(struct drm_crtc *crtc)
-{
- struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
-
- rcar_du_crtc_write(rcrtc, DSRCR, DSRCR_VBCL);
- rcar_du_crtc_set(rcrtc, DIER, DIER_VBE);
- rcrtc->vblank_enable = true;
-
- return 0;
-}
-
-static void rcar_du_crtc_disable_vblank(struct drm_crtc *crtc)
-{
- struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
-
- rcar_du_crtc_clr(rcrtc, DIER, DIER_VBE);
- rcrtc->vblank_enable = false;
-}
-
-static int rcar_du_crtc_parse_crc_source(struct rcar_du_crtc *rcrtc,
- const char *source_name,
- enum vsp1_du_crc_source *source)
-{
- unsigned int index;
- int ret;
-
- /*
- * Parse the source name. Supported values are "plane%u" to compute the
- * CRC on an input plane (%u is the plane ID), and "auto" to compute the
- * CRC on the composer (VSP) output.
- */
-
- if (!source_name) {
- *source = VSP1_DU_CRC_NONE;
- return 0;
- } else if (!strcmp(source_name, "auto")) {
- *source = VSP1_DU_CRC_OUTPUT;
- return 0;
- } else if (strstarts(source_name, "plane")) {
- unsigned int i;
-
- *source = VSP1_DU_CRC_PLANE;
-
- ret = kstrtouint(source_name + strlen("plane"), 10, &index);
- if (ret < 0)
- return ret;
-
- for (i = 0; i < rcrtc->vsp->num_planes; ++i) {
- if (index == rcrtc->vsp->planes[i].plane.base.id)
- return i;
- }
- }
-
- return -EINVAL;
-}
-
-static int rcar_du_crtc_verify_crc_source(struct drm_crtc *crtc,
- const char *source_name,
- size_t *values_cnt)
-{
- struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
- enum vsp1_du_crc_source source;
-
- if (rcar_du_crtc_parse_crc_source(rcrtc, source_name, &source) < 0) {
- DRM_DEBUG_DRIVER("unknown source %s\n", source_name);
- return -EINVAL;
- }
-
- *values_cnt = 1;
- return 0;
-}
-
-static const char *const *
-rcar_du_crtc_get_crc_sources(struct drm_crtc *crtc, size_t *count)
-{
- struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
-
- *count = rcrtc->sources_count;
- return rcrtc->sources;
-}
-
-static int rcar_du_crtc_set_crc_source(struct drm_crtc *crtc,
- const char *source_name)
-{
- struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
- struct drm_modeset_acquire_ctx ctx;
- struct drm_crtc_state *crtc_state;
- struct drm_atomic_state *state;
- enum vsp1_du_crc_source source;
- unsigned int index;
- int ret;
-
- ret = rcar_du_crtc_parse_crc_source(rcrtc, source_name, &source);
- if (ret < 0)
- return ret;
-
- index = ret;
-
- /* Perform an atomic commit to set the CRC source. */
- drm_modeset_acquire_init(&ctx, 0);
-
- state = drm_atomic_state_alloc(crtc->dev);
- if (!state) {
- ret = -ENOMEM;
- goto unlock;
- }
-
- state->acquire_ctx = &ctx;
-
-retry:
- crtc_state = drm_atomic_get_crtc_state(state, crtc);
- if (!IS_ERR(crtc_state)) {
- struct rcar_du_crtc_state *rcrtc_state;
-
- rcrtc_state = to_rcar_crtc_state(crtc_state);
- rcrtc_state->crc.source = source;
- rcrtc_state->crc.index = index;
-
- ret = drm_atomic_commit(state);
- } else {
- ret = PTR_ERR(crtc_state);
- }
-
- if (ret == -EDEADLK) {
- drm_atomic_state_clear(state);
- drm_modeset_backoff(&ctx);
- goto retry;
- }
-
- drm_atomic_state_put(state);
-
-unlock:
- drm_modeset_drop_locks(&ctx);
- drm_modeset_acquire_fini(&ctx);
-
- return ret;
-}
-
-static const struct drm_crtc_funcs crtc_funcs_gen2 = {
- .reset = rcar_du_crtc_reset,
- .destroy = drm_crtc_cleanup,
- .set_config = drm_atomic_helper_set_config,
- .page_flip = drm_atomic_helper_page_flip,
- .atomic_duplicate_state = rcar_du_crtc_atomic_duplicate_state,
- .atomic_destroy_state = rcar_du_crtc_atomic_destroy_state,
- .enable_vblank = rcar_du_crtc_enable_vblank,
- .disable_vblank = rcar_du_crtc_disable_vblank,
-};
-
-static const struct drm_crtc_funcs crtc_funcs_gen3 = {
- .reset = rcar_du_crtc_reset,
- .destroy = rcar_du_crtc_cleanup,
- .set_config = drm_atomic_helper_set_config,
- .page_flip = drm_atomic_helper_page_flip,
- .atomic_duplicate_state = rcar_du_crtc_atomic_duplicate_state,
- .atomic_destroy_state = rcar_du_crtc_atomic_destroy_state,
- .enable_vblank = rcar_du_crtc_enable_vblank,
- .disable_vblank = rcar_du_crtc_disable_vblank,
- .set_crc_source = rcar_du_crtc_set_crc_source,
- .verify_crc_source = rcar_du_crtc_verify_crc_source,
- .get_crc_sources = rcar_du_crtc_get_crc_sources,
-};
-
-/* -----------------------------------------------------------------------------
- * Interrupt Handling
- */
-
-static irqreturn_t rcar_du_crtc_irq(int irq, void *arg)
-{
- struct rcar_du_crtc *rcrtc = arg;
- struct rcar_du_device *rcdu = rcrtc->dev;
- irqreturn_t ret = IRQ_NONE;
- u32 status;
-
- spin_lock(&rcrtc->vblank_lock);
-
- status = rcar_du_crtc_read(rcrtc, DSSR);
- rcar_du_crtc_write(rcrtc, DSRCR, status & DSRCR_MASK);
-
- if (status & DSSR_VBK) {
- /*
- * Wake up the vblank wait if the counter reaches 0. This must
- * be protected by the vblank_lock to avoid races in
- * rcar_du_crtc_disable_planes().
- */
- if (rcrtc->vblank_count) {
- if (--rcrtc->vblank_count == 0)
- wake_up(&rcrtc->vblank_wait);
- }
- }
-
- spin_unlock(&rcrtc->vblank_lock);
-
- if (status & DSSR_VBK) {
- if (rcdu->info->gen < 3) {
- drm_crtc_handle_vblank(&rcrtc->crtc);
- rcar_du_crtc_finish_page_flip(rcrtc);
- }
-
- ret = IRQ_HANDLED;
- }
-
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * Initialization
- */
-
-int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex,
- unsigned int hwindex)
-{
- static const unsigned int mmio_offsets[] = {
- DU0_REG_OFFSET, DU1_REG_OFFSET, DU2_REG_OFFSET, DU3_REG_OFFSET
- };
-
- struct rcar_du_device *rcdu = rgrp->dev;
- struct platform_device *pdev = to_platform_device(rcdu->dev);
- struct rcar_du_crtc *rcrtc = &rcdu->crtcs[swindex];
- struct drm_crtc *crtc = &rcrtc->crtc;
- struct drm_plane *primary;
- unsigned int irqflags;
- struct clk *clk;
- char clk_name[9];
- char *name;
- int irq;
- int ret;
-
- /* Get the CRTC clock and the optional external clock. */
- if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_CLOCK)) {
- sprintf(clk_name, "du.%u", hwindex);
- name = clk_name;
- } else {
- name = NULL;
- }
-
- rcrtc->clock = devm_clk_get(rcdu->dev, name);
- if (IS_ERR(rcrtc->clock)) {
- dev_err(rcdu->dev, "no clock for DU channel %u\n", hwindex);
- return PTR_ERR(rcrtc->clock);
- }
-
- sprintf(clk_name, "dclkin.%u", hwindex);
- clk = devm_clk_get(rcdu->dev, clk_name);
- if (!IS_ERR(clk)) {
- rcrtc->extclock = clk;
- } else if (PTR_ERR(clk) == -EPROBE_DEFER) {
- return -EPROBE_DEFER;
- } else if (rcdu->info->dpll_mask & BIT(hwindex)) {
- /*
- * DU channels that have a display PLL can't use the internal
- * system clock and thus require an external clock.
- */
- ret = PTR_ERR(clk);
- dev_err(rcdu->dev, "can't get dclkin.%u: %d\n", hwindex, ret);
- return ret;
- }
-
- init_waitqueue_head(&rcrtc->flip_wait);
- init_waitqueue_head(&rcrtc->vblank_wait);
- spin_lock_init(&rcrtc->vblank_lock);
-
- rcrtc->dev = rcdu;
- rcrtc->group = rgrp;
- rcrtc->mmio_offset = mmio_offsets[hwindex];
- rcrtc->index = hwindex;
- rcrtc->dsysr = rcrtc->index % 2 ? 0 : DSYSR_DRES;
-
- if (rcar_du_has(rcdu, RCAR_DU_FEATURE_TVM_SYNC))
- rcrtc->dsysr |= DSYSR_TVM_TVSYNC;
-
- if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
- primary = &rcrtc->vsp->planes[rcrtc->vsp_pipe].plane;
- else
- primary = &rgrp->planes[swindex % 2].plane;
-
- ret = drm_crtc_init_with_planes(&rcdu->ddev, crtc, primary, NULL,
- rcdu->info->gen <= 2 ?
- &crtc_funcs_gen2 : &crtc_funcs_gen3,
- NULL);
- if (ret < 0)
- return ret;
-
- /* CMM might be disabled for this CRTC. */
- if (rcdu->cmms[swindex]) {
- rcrtc->cmm = rcdu->cmms[swindex];
- rgrp->cmms_mask |= BIT(hwindex % 2);
-
- drm_mode_crtc_set_gamma_size(crtc, CM2_LUT_SIZE);
- drm_crtc_enable_color_mgmt(crtc, 0, false, CM2_LUT_SIZE);
- }
-
- drm_crtc_helper_add(crtc, &crtc_helper_funcs);
-
- /* Register the interrupt handler. */
- if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ)) {
- /* The IRQ's are associated with the CRTC (sw)index. */
- irq = platform_get_irq(pdev, swindex);
- irqflags = 0;
- } else {
- irq = platform_get_irq(pdev, 0);
- irqflags = IRQF_SHARED;
- }
-
- if (irq < 0) {
- dev_err(rcdu->dev, "no IRQ for CRTC %u\n", swindex);
- return irq;
- }
-
- ret = devm_request_irq(rcdu->dev, irq, rcar_du_crtc_irq, irqflags,
- dev_name(rcdu->dev), rcrtc);
- if (ret < 0) {
- dev_err(rcdu->dev,
- "failed to register IRQ for CRTC %u\n", swindex);
- return ret;
- }
-
- rcar_du_crtc_crc_init(rcrtc);
-
- return 0;
-}
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
deleted file mode 100644
index d0f38a8b3561..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * R-Car Display Unit CRTCs
- *
- * Copyright (C) 2013-2015 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-#ifndef __RCAR_DU_CRTC_H__
-#define __RCAR_DU_CRTC_H__
-
-#include <linux/mutex.h>
-#include <linux/spinlock.h>
-#include <linux/wait.h>
-
-#include <drm/drm_crtc.h>
-#include <drm/drm_writeback.h>
-
-#include <media/vsp1.h>
-
-struct rcar_du_group;
-struct rcar_du_vsp;
-
-/**
- * struct rcar_du_crtc - the CRTC, representing a DU superposition processor
- * @crtc: base DRM CRTC
- * @dev: the DU device
- * @clock: the CRTC functional clock
- * @extclock: external pixel dot clock (optional)
- * @mmio_offset: offset of the CRTC registers in the DU MMIO block
- * @index: CRTC hardware index
- * @initialized: whether the CRTC has been initialized and clocks enabled
- * @dsysr: cached value of the DSYSR register
- * @vblank_enable: whether vblank events are enabled on this CRTC
- * @event: event to post when the pending page flip completes
- * @flip_wait: wait queue used to signal page flip completion
- * @vblank_lock: protects vblank_wait and vblank_count
- * @vblank_wait: wait queue used to signal vertical blanking
- * @vblank_count: number of vertical blanking interrupts to wait for
- * @group: CRTC group this CRTC belongs to
- * @cmm: CMM associated with this CRTC
- * @vsp: VSP feeding video to this CRTC
- * @vsp_pipe: index of the VSP pipeline feeding video to this CRTC
- * @writeback: the writeback connector
- */
-struct rcar_du_crtc {
- struct drm_crtc crtc;
-
- struct rcar_du_device *dev;
- struct clk *clock;
- struct clk *extclock;
- unsigned int mmio_offset;
- unsigned int index;
- bool initialized;
-
- u32 dsysr;
-
- bool vblank_enable;
- struct drm_pending_vblank_event *event;
- wait_queue_head_t flip_wait;
-
- spinlock_t vblank_lock;
- wait_queue_head_t vblank_wait;
- unsigned int vblank_count;
-
- struct rcar_du_group *group;
- struct platform_device *cmm;
- struct rcar_du_vsp *vsp;
- unsigned int vsp_pipe;
-
- const char *const *sources;
- unsigned int sources_count;
-
- struct drm_writeback_connector writeback;
-};
-
-#define to_rcar_crtc(c) container_of(c, struct rcar_du_crtc, crtc)
-#define wb_to_rcar_crtc(c) container_of(c, struct rcar_du_crtc, writeback)
-
-/**
- * struct rcar_du_crtc_state - Driver-specific CRTC state
- * @state: base DRM CRTC state
- * @crc: CRC computation configuration
- * @outputs: bitmask of the outputs (enum rcar_du_output) driven by this CRTC
- */
-struct rcar_du_crtc_state {
- struct drm_crtc_state state;
-
- struct vsp1_du_crc_config crc;
- unsigned int outputs;
-};
-
-#define to_rcar_crtc_state(s) container_of(s, struct rcar_du_crtc_state, state)
-
-int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex,
- unsigned int hwindex);
-
-void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc);
-
-void rcar_du_crtc_dsysr_clr_set(struct rcar_du_crtc *rcrtc, u32 clr, u32 set);
-
-#endif /* __RCAR_DU_CRTC_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
deleted file mode 100644
index 1ffde19cb87f..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ /dev/null
@@ -1,744 +0,0 @@
-// 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>
-#include <linux/dma-mapping.h>
-#include <linux/io.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/of_device.h>
-#include <linux/platform_device.h>
-#include <linux/pm.h>
-#include <linux/slab.h>
-#include <linux/wait.h>
-
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
-#include <drm/drm_gem_dma_helper.h>
-#include <drm/drm_managed.h>
-#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 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 },
- { }
-};
-
-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
- */
-
-DEFINE_DRM_GEM_DMA_FOPS(rcar_du_fops);
-
-static const struct drm_driver rcar_du_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
- .dumb_create = rcar_du_dumb_create,
- .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
- .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
- .gem_prime_import_sg_table = rcar_du_gem_prime_import_sg_table,
- .gem_prime_mmap = drm_gem_prime_mmap,
- .fops = &rcar_du_fops,
- .name = "rcar-du",
- .desc = "Renesas R-Car Display Unit",
- .date = "20130110",
- .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 int 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);
-
- return 0;
-}
-
-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;
- 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);
-
- /*
- * 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) {
- 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("Device %s probed\n", dev_name(&pdev->dev));
-
- drm_fbdev_generic_setup(&rcdu->ddev, 32);
-
- 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");
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
deleted file mode 100644
index 5cfa2bb7ad93..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/* 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)
- */
-
-#ifndef __RCAR_DU_DRV_H__
-#define __RCAR_DU_DRV_H__
-
-#include <linux/kernel.h>
-#include <linux/wait.h>
-
-#include <drm/drm_device.h>
-
-#include "rcar_cmm.h"
-#include "rcar_du_crtc.h"
-#include "rcar_du_group.h"
-#include "rcar_du_vsp.h"
-
-struct clk;
-struct device;
-struct drm_bridge;
-struct drm_property;
-struct rcar_du_device;
-
-#define RCAR_DU_FEATURE_CRTC_IRQ BIT(0) /* Per-CRTC IRQ */
-#define RCAR_DU_FEATURE_CRTC_CLOCK BIT(1) /* Per-CRTC clock */
-#define RCAR_DU_FEATURE_VSP1_SOURCE BIT(2) /* Has inputs from VSP1 */
-#define RCAR_DU_FEATURE_INTERLACED BIT(3) /* HW supports interlaced */
-#define RCAR_DU_FEATURE_TVM_SYNC BIT(4) /* Has TV switch/sync modes */
-#define RCAR_DU_FEATURE_NO_BLENDING BIT(5) /* PnMR.SPIM does not have ALP nor EOR bits */
-
-#define RCAR_DU_QUIRK_ALIGN_128B BIT(0) /* Align pitches to 128 bytes */
-
-enum rcar_du_output {
- RCAR_DU_OUTPUT_DPAD0,
- RCAR_DU_OUTPUT_DPAD1,
- RCAR_DU_OUTPUT_DSI0,
- RCAR_DU_OUTPUT_DSI1,
- RCAR_DU_OUTPUT_HDMI0,
- RCAR_DU_OUTPUT_HDMI1,
- RCAR_DU_OUTPUT_LVDS0,
- RCAR_DU_OUTPUT_LVDS1,
- RCAR_DU_OUTPUT_TCON,
- RCAR_DU_OUTPUT_MAX,
-};
-
-/*
- * struct rcar_du_output_routing - Output routing specification
- * @possible_crtcs: bitmask of possible CRTCs for the output
- * @port: device tree port number corresponding to this output route
- *
- * The DU has 5 possible outputs (DPAD0/1, LVDS0/1, TCON). Output routing data
- * specify the valid SoC outputs, which CRTCs can drive the output, and the type
- * of in-SoC encoder for the output.
- */
-struct rcar_du_output_routing {
- unsigned int possible_crtcs;
- unsigned int port;
-};
-
-/*
- * struct rcar_du_device_info - DU model-specific information
- * @gen: device generation (2 or 3)
- * @features: device features (RCAR_DU_FEATURE_*)
- * @quirks: device quirks (RCAR_DU_QUIRK_*)
- * @channels_mask: bit mask of available DU channels
- * @routes: array of CRTC to output routes, indexed by output (RCAR_DU_OUTPUT_*)
- * @num_lvds: number of internal LVDS encoders
- * @num_rpf: number of RPFs in VSP
- * @dpll_mask: bit mask of DU channels equipped with a DPLL
- * @dsi_clk_mask: bitmask of channels that can use the DSI clock as dot clock
- * @lvds_clk_mask: bitmask of channels that can use the LVDS clock as dot clock
- */
-struct rcar_du_device_info {
- unsigned int gen;
- unsigned int features;
- unsigned int quirks;
- unsigned int channels_mask;
- struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX];
- unsigned int num_lvds;
- unsigned int num_rpf;
- unsigned int dpll_mask;
- unsigned int dsi_clk_mask;
- unsigned int lvds_clk_mask;
-};
-
-#define RCAR_DU_MAX_CRTCS 4
-#define RCAR_DU_MAX_GROUPS DIV_ROUND_UP(RCAR_DU_MAX_CRTCS, 2)
-#define RCAR_DU_MAX_VSPS 4
-#define RCAR_DU_MAX_LVDS 2
-#define RCAR_DU_MAX_DSI 2
-
-struct rcar_du_device {
- struct device *dev;
- const struct rcar_du_device_info *info;
-
- void __iomem *mmio;
-
- struct drm_device ddev;
-
- struct rcar_du_crtc crtcs[RCAR_DU_MAX_CRTCS];
- unsigned int num_crtcs;
-
- struct rcar_du_group groups[RCAR_DU_MAX_GROUPS];
- struct platform_device *cmms[RCAR_DU_MAX_CRTCS];
- struct rcar_du_vsp vsps[RCAR_DU_MAX_VSPS];
- struct drm_bridge *lvds[RCAR_DU_MAX_LVDS];
- struct drm_bridge *dsi[RCAR_DU_MAX_DSI];
-
- struct {
- struct drm_property *colorkey;
- } props;
-
- unsigned int dpad0_source;
- unsigned int dpad1_source;
- unsigned int vspd1_sink;
-};
-
-static inline struct rcar_du_device *to_rcar_du_device(struct drm_device *dev)
-{
- return container_of(dev, struct rcar_du_device, ddev);
-}
-
-static inline bool rcar_du_has(struct rcar_du_device *rcdu,
- unsigned int feature)
-{
- return rcdu->info->features & feature;
-}
-
-static inline bool rcar_du_needs(struct rcar_du_device *rcdu,
- unsigned int quirk)
-{
- return rcdu->info->quirks & quirk;
-}
-
-static inline u32 rcar_du_read(struct rcar_du_device *rcdu, u32 reg)
-{
- return ioread32(rcdu->mmio + reg);
-}
-
-static inline void rcar_du_write(struct rcar_du_device *rcdu, u32 reg, u32 data)
-{
- iowrite32(data, rcdu->mmio + reg);
-}
-
-const char *rcar_du_output_name(enum rcar_du_output output);
-
-#endif /* __RCAR_DU_DRV_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
deleted file mode 100644
index 7ecec7b04a8d..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
+++ /dev/null
@@ -1,137 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * R-Car Display Unit Encoder
- *
- * Copyright (C) 2013-2014 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-#include <linux/export.h>
-#include <linux/of.h>
-
-#include <drm/drm_bridge.h>
-#include <drm/drm_bridge_connector.h>
-#include <drm/drm_panel.h>
-
-#include "rcar_du_drv.h"
-#include "rcar_du_encoder.h"
-#include "rcar_lvds.h"
-
-/* -----------------------------------------------------------------------------
- * Encoder
- */
-
-static unsigned int rcar_du_encoder_count_ports(struct device_node *node)
-{
- struct device_node *ports;
- struct device_node *port;
- unsigned int num_ports = 0;
-
- ports = of_get_child_by_name(node, "ports");
- if (!ports)
- ports = of_node_get(node);
-
- for_each_child_of_node(ports, port) {
- if (of_node_name_eq(port, "port"))
- num_ports++;
- }
-
- of_node_put(ports);
-
- return num_ports;
-}
-
-static const struct drm_encoder_funcs rcar_du_encoder_funcs = {
-};
-
-int rcar_du_encoder_init(struct rcar_du_device *rcdu,
- enum rcar_du_output output,
- struct device_node *enc_node)
-{
- struct rcar_du_encoder *renc;
- struct drm_connector *connector;
- struct drm_bridge *bridge;
- int ret;
-
- /*
- * Locate the DRM bridge from the DT node. For the DPAD outputs, if the
- * DT node has a single port, assume that it describes a panel and
- * create a panel bridge.
- */
- if ((output == RCAR_DU_OUTPUT_DPAD0 ||
- output == RCAR_DU_OUTPUT_DPAD1) &&
- rcar_du_encoder_count_ports(enc_node) == 1) {
- struct drm_panel *panel = of_drm_find_panel(enc_node);
-
- if (IS_ERR(panel))
- return PTR_ERR(panel);
-
- bridge = devm_drm_panel_bridge_add_typed(rcdu->dev, panel,
- DRM_MODE_CONNECTOR_DPI);
- if (IS_ERR(bridge))
- return PTR_ERR(bridge);
- } else {
- bridge = of_drm_find_bridge(enc_node);
- if (!bridge)
- return -EPROBE_DEFER;
-
- if (output == RCAR_DU_OUTPUT_LVDS0 ||
- output == RCAR_DU_OUTPUT_LVDS1)
- rcdu->lvds[output - RCAR_DU_OUTPUT_LVDS0] = bridge;
-
- if (output == RCAR_DU_OUTPUT_DSI0 ||
- output == RCAR_DU_OUTPUT_DSI1)
- rcdu->dsi[output - RCAR_DU_OUTPUT_DSI0] = bridge;
- }
-
- /*
- * Create and initialize the encoder. On Gen3, skip the LVDS1 output if
- * the LVDS1 encoder is used as a companion for LVDS0 in dual-link
- * mode, or any LVDS output if it isn't connected. The latter may happen
- * on D3 or E3 as the LVDS encoders are needed to provide the pixel
- * clock to the DU, even when the LVDS outputs are not used.
- */
- if (rcdu->info->gen >= 3) {
- if (output == RCAR_DU_OUTPUT_LVDS1 &&
- rcar_lvds_dual_link(bridge))
- return -ENOLINK;
-
- if ((output == RCAR_DU_OUTPUT_LVDS0 ||
- output == RCAR_DU_OUTPUT_LVDS1) &&
- !rcar_lvds_is_connected(bridge))
- return -ENOLINK;
- }
-
- dev_dbg(rcdu->dev, "initializing encoder %pOF for output %s\n",
- enc_node, rcar_du_output_name(output));
-
- renc = drmm_encoder_alloc(&rcdu->ddev, struct rcar_du_encoder, base,
- &rcar_du_encoder_funcs, DRM_MODE_ENCODER_NONE,
- NULL);
- if (IS_ERR(renc))
- return PTR_ERR(renc);
-
- renc->output = output;
-
- /* Attach the bridge to the encoder. */
- ret = drm_bridge_attach(&renc->base, bridge, NULL,
- DRM_BRIDGE_ATTACH_NO_CONNECTOR);
- if (ret) {
- dev_err(rcdu->dev,
- "failed to attach bridge %pOF for output %s (%d)\n",
- bridge->of_node, rcar_du_output_name(output), ret);
- return ret;
- }
-
- /* Create the connector for the chain of bridges. */
- connector = drm_bridge_connector_init(&rcdu->ddev, &renc->base);
- if (IS_ERR(connector)) {
- dev_err(rcdu->dev,
- "failed to created connector for output %s (%ld)\n",
- rcar_du_output_name(output), PTR_ERR(connector));
- return PTR_ERR(connector);
- }
-
- return drm_connector_attach_encoder(connector, &renc->base);
-}
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h
deleted file mode 100644
index e5ec8fbb3979..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * R-Car Display Unit Encoder
- *
- * Copyright (C) 2013-2014 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-#ifndef __RCAR_DU_ENCODER_H__
-#define __RCAR_DU_ENCODER_H__
-
-#include <drm/drm_encoder.h>
-
-struct rcar_du_device;
-
-struct rcar_du_encoder {
- struct drm_encoder base;
- enum rcar_du_output output;
-};
-
-#define to_rcar_encoder(e) \
- container_of(e, struct rcar_du_encoder, base)
-
-int rcar_du_encoder_init(struct rcar_du_device *rcdu,
- enum rcar_du_output output,
- struct device_node *enc_node);
-
-#endif /* __RCAR_DU_ENCODER_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
deleted file mode 100644
index 2ccd2581f544..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ /dev/null
@@ -1,377 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * R-Car Display Unit Channels Pair
- *
- * Copyright (C) 2013-2015 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-/*
- * The R8A7779 DU is split in per-CRTC resources (scan-out engine, blending
- * unit, timings generator, ...) and device-global resources (start/stop
- * control, planes, ...) shared between the two CRTCs.
- *
- * The R8A7790 introduced a third CRTC with its own set of global resources.
- * This would be modeled as two separate DU device instances if it wasn't for
- * a handful or resources that are shared between the three CRTCs (mostly
- * related to input and output routing). For this reason the R8A7790 DU must be
- * modeled as a single device with three CRTCs, two sets of "semi-global"
- * resources, and a few device-global resources.
- *
- * The rcar_du_group object is a driver specific object, without any real
- * counterpart in the DU documentation, that models those semi-global resources.
- */
-
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include "rcar_du_drv.h"
-#include "rcar_du_group.h"
-#include "rcar_du_regs.h"
-
-u32 rcar_du_group_read(struct rcar_du_group *rgrp, u32 reg)
-{
- return rcar_du_read(rgrp->dev, rgrp->mmio_offset + reg);
-}
-
-void rcar_du_group_write(struct rcar_du_group *rgrp, u32 reg, u32 data)
-{
- rcar_du_write(rgrp->dev, rgrp->mmio_offset + reg, data);
-}
-
-static void rcar_du_group_setup_pins(struct rcar_du_group *rgrp)
-{
- u32 defr6 = DEFR6_CODE;
-
- if (rgrp->channels_mask & BIT(0))
- defr6 |= DEFR6_ODPM02_DISP;
-
- if (rgrp->channels_mask & BIT(1))
- defr6 |= DEFR6_ODPM12_DISP;
-
- rcar_du_group_write(rgrp, DEFR6, defr6);
-}
-
-static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
-{
- struct rcar_du_device *rcdu = rgrp->dev;
- u32 defr8 = DEFR8_CODE;
-
- if (rcdu->info->gen < 3) {
- defr8 |= DEFR8_DEFE8;
-
- /*
- * On Gen2 the DEFR8 register for the first group also controls
- * RGB output routing to DPAD0 and VSPD1 routing to DU0/1/2 for
- * DU instances that support it.
- */
- if (rgrp->index == 0) {
- defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
- if (rgrp->dev->vspd1_sink == 2)
- defr8 |= DEFR8_VSCS;
- }
- } else {
- /*
- * On Gen3 VSPD routing can't be configured, and DPAD routing
- * is set in the group corresponding to the DPAD output (no Gen3
- * SoC has multiple DPAD sources belonging to separate groups).
- */
- if (rgrp->index == rcdu->dpad0_source / 2)
- defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
- }
-
- rcar_du_group_write(rgrp, DEFR8, defr8);
-}
-
-static void rcar_du_group_setup_didsr(struct rcar_du_group *rgrp)
-{
- struct rcar_du_device *rcdu = rgrp->dev;
- struct rcar_du_crtc *rcrtc;
- unsigned int num_crtcs = 0;
- unsigned int i;
- u32 didsr;
-
- /*
- * Configure input dot clock routing with a hardcoded configuration. If
- * the DU channel can use the LVDS encoder output clock as the dot
- * clock, do so. Otherwise route DU_DOTCLKINn signal to DUn.
- *
- * Each channel can then select between the dot clock configured here
- * and the clock provided by the CPG through the ESCR register.
- */
- if (rcdu->info->gen < 3 && rgrp->index == 0) {
- /*
- * On Gen2 a single register in the first group controls dot
- * clock selection for all channels.
- */
- rcrtc = rcdu->crtcs;
- num_crtcs = rcdu->num_crtcs;
- } else if (rcdu->info->gen >= 3 && rgrp->num_crtcs > 1) {
- /*
- * On Gen3 dot clocks are setup through per-group registers,
- * only available when the group has two channels.
- */
- rcrtc = &rcdu->crtcs[rgrp->index * 2];
- num_crtcs = rgrp->num_crtcs;
- }
-
- if (!num_crtcs)
- return;
-
- didsr = DIDSR_CODE;
- for (i = 0; i < num_crtcs; ++i, ++rcrtc) {
- if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index))
- didsr |= DIDSR_LDCS_LVDS0(i)
- | DIDSR_PDCS_CLK(i, 0);
- else if (rcdu->info->dsi_clk_mask & BIT(rcrtc->index))
- didsr |= DIDSR_LDCS_DSI(i);
- else
- didsr |= DIDSR_LDCS_DCLKIN(i)
- | DIDSR_PDCS_CLK(i, 0);
- }
-
- rcar_du_group_write(rgrp, DIDSR, didsr);
-}
-
-static void rcar_du_group_setup(struct rcar_du_group *rgrp)
-{
- struct rcar_du_device *rcdu = rgrp->dev;
- u32 defr7 = DEFR7_CODE;
- u32 dorcr;
-
- /* Enable extended features */
- rcar_du_group_write(rgrp, DEFR, DEFR_CODE | DEFR_DEFE);
- if (rcdu->info->gen < 3) {
- rcar_du_group_write(rgrp, DEFR2, DEFR2_CODE | DEFR2_DEFE2G);
- rcar_du_group_write(rgrp, DEFR3, DEFR3_CODE | DEFR3_DEFE3);
- rcar_du_group_write(rgrp, DEFR4, DEFR4_CODE);
- }
- rcar_du_group_write(rgrp, DEFR5, DEFR5_CODE | DEFR5_DEFE5);
-
- if (rcdu->info->gen < 4)
- rcar_du_group_setup_pins(rgrp);
-
- if (rcdu->info->gen < 4) {
- /*
- * TODO: Handle routing of the DU output to CMM dynamically, as
- * we should bypass CMM completely when no color management
- * feature is used.
- */
- defr7 |= (rgrp->cmms_mask & BIT(1) ? DEFR7_CMME1 : 0) |
- (rgrp->cmms_mask & BIT(0) ? DEFR7_CMME0 : 0);
- rcar_du_group_write(rgrp, DEFR7, defr7);
- }
-
- if (rcdu->info->gen >= 2) {
- if (rcdu->info->gen < 4)
- rcar_du_group_setup_defr8(rgrp);
- rcar_du_group_setup_didsr(rgrp);
- }
-
- if (rcdu->info->gen >= 3)
- rcar_du_group_write(rgrp, DEFR10, DEFR10_CODE | DEFR10_DEFE10);
-
- /*
- * Use DS1PR and DS2PR to configure planes priorities and connects the
- * superposition 0 to DU0 pins. DU1 pins will be configured dynamically.
- *
- * Groups that have a single channel have a hardcoded configuration. On
- * Gen3 and newer, the documentation requires PG1T, DK1S and PG1D_DS1 to
- * always be set in this case.
- */
- dorcr = DORCR_PG0D_DS0 | DORCR_DPRS;
- if (rcdu->info->gen >= 3 && rgrp->num_crtcs == 1)
- dorcr |= DORCR_PG1T | DORCR_DK1S | DORCR_PG1D_DS1;
- rcar_du_group_write(rgrp, DORCR, dorcr);
-
- /* Apply planes to CRTCs association. */
- mutex_lock(&rgrp->lock);
- rcar_du_group_write(rgrp, DPTSR, (rgrp->dptsr_planes << 16) |
- rgrp->dptsr_planes);
- mutex_unlock(&rgrp->lock);
-}
-
-/*
- * rcar_du_group_get - Acquire a reference to the DU channels group
- *
- * Acquiring the first reference setups core registers. A reference must be held
- * before accessing any hardware registers.
- *
- * This function must be called with the DRM mode_config lock held.
- *
- * Return 0 in case of success or a negative error code otherwise.
- */
-int rcar_du_group_get(struct rcar_du_group *rgrp)
-{
- if (rgrp->use_count)
- goto done;
-
- rcar_du_group_setup(rgrp);
-
-done:
- rgrp->use_count++;
- return 0;
-}
-
-/*
- * rcar_du_group_put - Release a reference to the DU
- *
- * This function must be called with the DRM mode_config lock held.
- */
-void rcar_du_group_put(struct rcar_du_group *rgrp)
-{
- --rgrp->use_count;
-}
-
-static void __rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
-{
- struct rcar_du_device *rcdu = rgrp->dev;
-
- /*
- * Group start/stop is controlled by the DRES and DEN bits of DSYSR0
- * for the first group and DSYSR2 for the second group. On most DU
- * instances, this maps to the first CRTC of the group, and we can just
- * use rcar_du_crtc_dsysr_clr_set() to access the correct DSYSR. On
- * M3-N, however, DU2 doesn't exist, but DSYSR2 does. We thus need to
- * access the register directly using group read/write.
- */
- if (rcdu->info->channels_mask & BIT(rgrp->index * 2)) {
- struct rcar_du_crtc *rcrtc = &rgrp->dev->crtcs[rgrp->index * 2];
-
- rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_DRES | DSYSR_DEN,
- start ? DSYSR_DEN : DSYSR_DRES);
- } else {
- rcar_du_group_write(rgrp, DSYSR,
- start ? DSYSR_DEN : DSYSR_DRES);
- }
-}
-
-void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
-{
- /*
- * Many of the configuration bits are only updated when the display
- * reset (DRES) bit in DSYSR is set to 1, disabling *both* CRTCs. Some
- * of those bits could be pre-configured, but others (especially the
- * bits related to plane assignment to display timing controllers) need
- * to be modified at runtime.
- *
- * Restart the display controller if a start is requested. Sorry for the
- * flicker. It should be possible to move most of the "DRES-update" bits
- * setup to driver initialization time and minimize the number of cases
- * when the display controller will have to be restarted.
- */
- if (start) {
- if (rgrp->used_crtcs++ != 0)
- __rcar_du_group_start_stop(rgrp, false);
- __rcar_du_group_start_stop(rgrp, true);
- } else {
- if (--rgrp->used_crtcs == 0)
- __rcar_du_group_start_stop(rgrp, false);
- }
-}
-
-void rcar_du_group_restart(struct rcar_du_group *rgrp)
-{
- rgrp->need_restart = false;
-
- __rcar_du_group_start_stop(rgrp, false);
- __rcar_du_group_start_stop(rgrp, true);
-}
-
-int rcar_du_set_dpad0_vsp1_routing(struct rcar_du_device *rcdu)
-{
- struct rcar_du_group *rgrp;
- struct rcar_du_crtc *crtc;
- unsigned int index;
- int ret;
-
- if (rcdu->info->gen < 2)
- return 0;
-
- /*
- * RGB output routing to DPAD0 and VSP1D routing to DU0/1/2 are
- * configured in the DEFR8 register of the first group on Gen2 and the
- * last group on Gen3. As this function can be called with the DU
- * channels of the corresponding CRTCs disabled, we need to enable the
- * group clock before accessing the register.
- */
- index = rcdu->info->gen < 3 ? 0 : DIV_ROUND_UP(rcdu->num_crtcs, 2) - 1;
- rgrp = &rcdu->groups[index];
- crtc = &rcdu->crtcs[index * 2];
-
- ret = clk_prepare_enable(crtc->clock);
- if (ret < 0)
- return ret;
-
- rcar_du_group_setup_defr8(rgrp);
-
- clk_disable_unprepare(crtc->clock);
-
- return 0;
-}
-
-static void rcar_du_group_set_dpad_levels(struct rcar_du_group *rgrp)
-{
- static const u32 doflr_values[2] = {
- DOFLR_HSYCFL0 | DOFLR_VSYCFL0 | DOFLR_ODDFL0 |
- DOFLR_DISPFL0 | DOFLR_CDEFL0 | DOFLR_RGBFL0,
- DOFLR_HSYCFL1 | DOFLR_VSYCFL1 | DOFLR_ODDFL1 |
- DOFLR_DISPFL1 | DOFLR_CDEFL1 | DOFLR_RGBFL1,
- };
- static const u32 dpad_mask = BIT(RCAR_DU_OUTPUT_DPAD1)
- | BIT(RCAR_DU_OUTPUT_DPAD0);
- struct rcar_du_device *rcdu = rgrp->dev;
- u32 doflr = DOFLR_CODE;
- unsigned int i;
-
- if (rcdu->info->gen < 2)
- return;
-
- /*
- * The DPAD outputs can't be controlled directly. However, the parallel
- * output of the DU channels routed to DPAD can be set to fixed levels
- * through the DOFLR group register. Use this to turn the DPAD on or off
- * by driving fixed low-level signals at the output of any DU channel
- * not routed to a DPAD output. This doesn't affect the DU output
- * signals going to other outputs, such as the internal LVDS and HDMI
- * encoders.
- */
-
- for (i = 0; i < rgrp->num_crtcs; ++i) {
- struct rcar_du_crtc_state *rstate;
- struct rcar_du_crtc *rcrtc;
-
- rcrtc = &rcdu->crtcs[rgrp->index * 2 + i];
- rstate = to_rcar_crtc_state(rcrtc->crtc.state);
-
- if (!(rstate->outputs & dpad_mask))
- doflr |= doflr_values[i];
- }
-
- rcar_du_group_write(rgrp, DOFLR, doflr);
-}
-
-int rcar_du_group_set_routing(struct rcar_du_group *rgrp)
-{
- struct rcar_du_device *rcdu = rgrp->dev;
- u32 dorcr = rcar_du_group_read(rgrp, DORCR);
-
- dorcr &= ~(DORCR_PG1T | DORCR_DK1S | DORCR_PG1D_MASK);
-
- /*
- * Set the DPAD1 pins sources. Select CRTC 0 if explicitly requested and
- * CRTC 1 in all other cases to avoid cloning CRTC 0 to DPAD0 and DPAD1
- * by default.
- */
- if (rcdu->dpad1_source == rgrp->index * 2)
- dorcr |= DORCR_PG1D_DS0;
- else
- dorcr |= DORCR_PG1T | DORCR_DK1S | DORCR_PG1D_DS1;
-
- rcar_du_group_write(rgrp, DORCR, dorcr);
-
- rcar_du_group_set_dpad_levels(rgrp);
-
- return rcar_du_set_dpad0_vsp1_routing(rgrp->dev);
-}
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.h b/drivers/gpu/drm/rcar-du/rcar_du_group.h
deleted file mode 100644
index 55649ad86a10..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * R-Car Display Unit Planes and CRTCs Group
- *
- * Copyright (C) 2013-2014 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-#ifndef __RCAR_DU_GROUP_H__
-#define __RCAR_DU_GROUP_H__
-
-#include <linux/mutex.h>
-
-#include "rcar_du_plane.h"
-
-struct rcar_du_device;
-
-/*
- * struct rcar_du_group - CRTCs and planes group
- * @dev: the DU device
- * @mmio_offset: registers offset in the device memory map
- * @index: group index
- * @channels_mask: bitmask of populated DU channels in this group
- * @cmms_mask: bitmask of available CMMs in this group
- * @num_crtcs: number of CRTCs in this group (1 or 2)
- * @use_count: number of users of the group (rcar_du_group_(get|put))
- * @used_crtcs: number of CRTCs currently in use
- * @lock: protects the dptsr_planes field and the DPTSR register
- * @dptsr_planes: bitmask of planes driven by dot-clock and timing generator 1
- * @num_planes: number of planes in the group
- * @planes: planes handled by the group
- * @need_restart: the group needs to be restarted due to a configuration change
- */
-struct rcar_du_group {
- struct rcar_du_device *dev;
- unsigned int mmio_offset;
- unsigned int index;
-
- unsigned int channels_mask;
- unsigned int cmms_mask;
- unsigned int num_crtcs;
- unsigned int use_count;
- unsigned int used_crtcs;
-
- struct mutex lock;
- unsigned int dptsr_planes;
-
- unsigned int num_planes;
- struct rcar_du_plane planes[RCAR_DU_NUM_KMS_PLANES];
- bool need_restart;
-};
-
-u32 rcar_du_group_read(struct rcar_du_group *rgrp, u32 reg);
-void rcar_du_group_write(struct rcar_du_group *rgrp, u32 reg, u32 data);
-
-int rcar_du_group_get(struct rcar_du_group *rgrp);
-void rcar_du_group_put(struct rcar_du_group *rgrp);
-void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start);
-void rcar_du_group_restart(struct rcar_du_group *rgrp);
-int rcar_du_group_set_routing(struct rcar_du_group *rgrp);
-
-int rcar_du_set_dpad0_vsp1_routing(struct rcar_du_device *rcdu);
-
-#endif /* __RCAR_DU_GROUP_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
deleted file mode 100644
index adfb36b0e815..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ /dev/null
@@ -1,1006 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * R-Car Display Unit Mode Setting
- *
- * Copyright (C) 2013-2015 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-#include <drm/drm_atomic.h>
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_device.h>
-#include <drm/drm_framebuffer.h>
-#include <drm/drm_gem_dma_helper.h>
-#include <drm/drm_gem_framebuffer_helper.h>
-#include <drm/drm_managed.h>
-#include <drm/drm_probe_helper.h>
-#include <drm/drm_vblank.h>
-
-#include <linux/device.h>
-#include <linux/dma-buf.h>
-#include <linux/of_graph.h>
-#include <linux/of_platform.h>
-#include <linux/wait.h>
-
-#include "rcar_du_crtc.h"
-#include "rcar_du_drv.h"
-#include "rcar_du_encoder.h"
-#include "rcar_du_kms.h"
-#include "rcar_du_regs.h"
-#include "rcar_du_vsp.h"
-#include "rcar_du_writeback.h"
-
-/* -----------------------------------------------------------------------------
- * Format helpers
- */
-
-static const struct rcar_du_format_info rcar_du_format_infos[] = {
- {
- .fourcc = DRM_FORMAT_RGB565,
- .v4l2 = V4L2_PIX_FMT_RGB565,
- .bpp = 16,
- .planes = 1,
- .hsub = 1,
- .pnmr = PnMR_SPIM_TP | PnMR_DDDF_16BPP,
- .edf = PnDDCR4_EDF_NONE,
- }, {
- .fourcc = DRM_FORMAT_ARGB1555,
- .v4l2 = V4L2_PIX_FMT_ARGB555,
- .bpp = 16,
- .planes = 1,
- .hsub = 1,
- .pnmr = PnMR_SPIM_ALP | PnMR_DDDF_ARGB,
- .edf = PnDDCR4_EDF_NONE,
- }, {
- .fourcc = DRM_FORMAT_XRGB1555,
- .v4l2 = V4L2_PIX_FMT_XRGB555,
- .bpp = 16,
- .planes = 1,
- .pnmr = PnMR_SPIM_ALP | PnMR_DDDF_ARGB,
- .edf = PnDDCR4_EDF_NONE,
- }, {
- .fourcc = DRM_FORMAT_XRGB8888,
- .v4l2 = V4L2_PIX_FMT_XBGR32,
- .bpp = 32,
- .planes = 1,
- .hsub = 1,
- .pnmr = PnMR_SPIM_TP | PnMR_DDDF_16BPP,
- .edf = PnDDCR4_EDF_RGB888,
- }, {
- .fourcc = DRM_FORMAT_ARGB8888,
- .v4l2 = V4L2_PIX_FMT_ABGR32,
- .bpp = 32,
- .planes = 1,
- .hsub = 1,
- .pnmr = PnMR_SPIM_ALP | PnMR_DDDF_16BPP,
- .edf = PnDDCR4_EDF_ARGB8888,
- }, {
- .fourcc = DRM_FORMAT_UYVY,
- .v4l2 = V4L2_PIX_FMT_UYVY,
- .bpp = 16,
- .planes = 1,
- .hsub = 2,
- .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
- .edf = PnDDCR4_EDF_NONE,
- }, {
- .fourcc = DRM_FORMAT_YUYV,
- .v4l2 = V4L2_PIX_FMT_YUYV,
- .bpp = 16,
- .planes = 1,
- .hsub = 2,
- .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
- .edf = PnDDCR4_EDF_NONE,
- }, {
- .fourcc = DRM_FORMAT_NV12,
- .v4l2 = V4L2_PIX_FMT_NV12M,
- .bpp = 12,
- .planes = 2,
- .hsub = 2,
- .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
- .edf = PnDDCR4_EDF_NONE,
- }, {
- .fourcc = DRM_FORMAT_NV21,
- .v4l2 = V4L2_PIX_FMT_NV21M,
- .bpp = 12,
- .planes = 2,
- .hsub = 2,
- .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
- .edf = PnDDCR4_EDF_NONE,
- }, {
- .fourcc = DRM_FORMAT_NV16,
- .v4l2 = V4L2_PIX_FMT_NV16M,
- .bpp = 16,
- .planes = 2,
- .hsub = 2,
- .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
- .edf = PnDDCR4_EDF_NONE,
- },
- /*
- * The following formats are not supported on Gen2 and thus have no
- * associated .pnmr or .edf settings.
- */
- {
- .fourcc = DRM_FORMAT_RGB332,
- .v4l2 = V4L2_PIX_FMT_RGB332,
- .bpp = 8,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_ARGB4444,
- .v4l2 = V4L2_PIX_FMT_ARGB444,
- .bpp = 16,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_XRGB4444,
- .v4l2 = V4L2_PIX_FMT_XRGB444,
- .bpp = 16,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_RGBA4444,
- .v4l2 = V4L2_PIX_FMT_RGBA444,
- .bpp = 16,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_RGBX4444,
- .v4l2 = V4L2_PIX_FMT_RGBX444,
- .bpp = 16,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_ABGR4444,
- .v4l2 = V4L2_PIX_FMT_ABGR444,
- .bpp = 16,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_XBGR4444,
- .v4l2 = V4L2_PIX_FMT_XBGR444,
- .bpp = 16,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_BGRA4444,
- .v4l2 = V4L2_PIX_FMT_BGRA444,
- .bpp = 16,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_BGRX4444,
- .v4l2 = V4L2_PIX_FMT_BGRX444,
- .bpp = 16,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_RGBA5551,
- .v4l2 = V4L2_PIX_FMT_RGBA555,
- .bpp = 16,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_RGBX5551,
- .v4l2 = V4L2_PIX_FMT_RGBX555,
- .bpp = 16,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_ABGR1555,
- .v4l2 = V4L2_PIX_FMT_ABGR555,
- .bpp = 16,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_XBGR1555,
- .v4l2 = V4L2_PIX_FMT_XBGR555,
- .bpp = 16,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_BGRA5551,
- .v4l2 = V4L2_PIX_FMT_BGRA555,
- .bpp = 16,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_BGRX5551,
- .v4l2 = V4L2_PIX_FMT_BGRX555,
- .bpp = 16,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_BGR888,
- .v4l2 = V4L2_PIX_FMT_RGB24,
- .bpp = 24,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_RGB888,
- .v4l2 = V4L2_PIX_FMT_BGR24,
- .bpp = 24,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_RGBA8888,
- .v4l2 = V4L2_PIX_FMT_BGRA32,
- .bpp = 32,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_RGBX8888,
- .v4l2 = V4L2_PIX_FMT_BGRX32,
- .bpp = 32,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_ABGR8888,
- .v4l2 = V4L2_PIX_FMT_RGBA32,
- .bpp = 32,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_XBGR8888,
- .v4l2 = V4L2_PIX_FMT_RGBX32,
- .bpp = 32,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_BGRA8888,
- .v4l2 = V4L2_PIX_FMT_ARGB32,
- .bpp = 32,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_BGRX8888,
- .v4l2 = V4L2_PIX_FMT_XRGB32,
- .bpp = 32,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_RGBX1010102,
- .v4l2 = V4L2_PIX_FMT_RGBX1010102,
- .bpp = 32,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_RGBA1010102,
- .v4l2 = V4L2_PIX_FMT_RGBA1010102,
- .bpp = 32,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_ARGB2101010,
- .v4l2 = V4L2_PIX_FMT_ARGB2101010,
- .bpp = 32,
- .planes = 1,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_YVYU,
- .v4l2 = V4L2_PIX_FMT_YVYU,
- .bpp = 16,
- .planes = 1,
- .hsub = 2,
- }, {
- .fourcc = DRM_FORMAT_NV61,
- .v4l2 = V4L2_PIX_FMT_NV61M,
- .bpp = 16,
- .planes = 2,
- .hsub = 2,
- }, {
- .fourcc = DRM_FORMAT_YUV420,
- .v4l2 = V4L2_PIX_FMT_YUV420M,
- .bpp = 12,
- .planes = 3,
- .hsub = 2,
- }, {
- .fourcc = DRM_FORMAT_YVU420,
- .v4l2 = V4L2_PIX_FMT_YVU420M,
- .bpp = 12,
- .planes = 3,
- .hsub = 2,
- }, {
- .fourcc = DRM_FORMAT_YUV422,
- .v4l2 = V4L2_PIX_FMT_YUV422M,
- .bpp = 16,
- .planes = 3,
- .hsub = 2,
- }, {
- .fourcc = DRM_FORMAT_YVU422,
- .v4l2 = V4L2_PIX_FMT_YVU422M,
- .bpp = 16,
- .planes = 3,
- .hsub = 2,
- }, {
- .fourcc = DRM_FORMAT_YUV444,
- .v4l2 = V4L2_PIX_FMT_YUV444M,
- .bpp = 24,
- .planes = 3,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_YVU444,
- .v4l2 = V4L2_PIX_FMT_YVU444M,
- .bpp = 24,
- .planes = 3,
- .hsub = 1,
- }, {
- .fourcc = DRM_FORMAT_Y210,
- .v4l2 = V4L2_PIX_FMT_Y210,
- .bpp = 32,
- .planes = 1,
- .hsub = 2,
- }, {
- .fourcc = DRM_FORMAT_Y212,
- .v4l2 = V4L2_PIX_FMT_Y212,
- .bpp = 32,
- .planes = 1,
- .hsub = 2,
- },
-};
-
-const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(rcar_du_format_infos); ++i) {
- if (rcar_du_format_infos[i].fourcc == fourcc)
- return &rcar_du_format_infos[i];
- }
-
- return NULL;
-}
-
-/* -----------------------------------------------------------------------------
- * Frame buffer
- */
-
-static const struct drm_gem_object_funcs rcar_du_gem_funcs = {
- .free = drm_gem_dma_object_free,
- .print_info = drm_gem_dma_object_print_info,
- .get_sg_table = drm_gem_dma_object_get_sg_table,
- .vmap = drm_gem_dma_object_vmap,
- .mmap = drm_gem_dma_object_mmap,
- .vm_ops = &drm_gem_dma_vm_ops,
-};
-
-struct drm_gem_object *rcar_du_gem_prime_import_sg_table(struct drm_device *dev,
- struct dma_buf_attachment *attach,
- struct sg_table *sgt)
-{
- struct rcar_du_device *rcdu = to_rcar_du_device(dev);
- struct drm_gem_dma_object *dma_obj;
- struct drm_gem_object *gem_obj;
- int ret;
-
- if (!rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
- return drm_gem_dma_prime_import_sg_table(dev, attach, sgt);
-
- /* Create a DMA GEM buffer. */
- dma_obj = kzalloc(sizeof(*dma_obj), GFP_KERNEL);
- if (!dma_obj)
- return ERR_PTR(-ENOMEM);
-
- gem_obj = &dma_obj->base;
- gem_obj->funcs = &rcar_du_gem_funcs;
-
- drm_gem_private_object_init(dev, gem_obj, attach->dmabuf->size);
- dma_obj->map_noncoherent = false;
-
- ret = drm_gem_create_mmap_offset(gem_obj);
- if (ret) {
- drm_gem_object_release(gem_obj);
- kfree(dma_obj);
- return ERR_PTR(ret);
- }
-
- dma_obj->dma_addr = 0;
- dma_obj->sgt = sgt;
-
- return gem_obj;
-}
-
-int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev,
- struct drm_mode_create_dumb *args)
-{
- struct rcar_du_device *rcdu = to_rcar_du_device(dev);
- unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
- unsigned int align;
-
- /*
- * The R8A7779 DU requires a 16 pixels pitch alignment as documented,
- * but the R8A7790 DU seems to require a 128 bytes pitch alignment.
- */
- if (rcar_du_needs(rcdu, RCAR_DU_QUIRK_ALIGN_128B))
- align = 128;
- else
- align = 16 * args->bpp / 8;
-
- args->pitch = roundup(min_pitch, align);
-
- return drm_gem_dma_dumb_create_internal(file, dev, args);
-}
-
-static struct drm_framebuffer *
-rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
- const struct drm_mode_fb_cmd2 *mode_cmd)
-{
- struct rcar_du_device *rcdu = to_rcar_du_device(dev);
- const struct rcar_du_format_info *format;
- unsigned int chroma_pitch;
- unsigned int max_pitch;
- unsigned int align;
- unsigned int i;
-
- format = rcar_du_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 (rcdu->info->gen < 3) {
- /*
- * On Gen2 the DU limits the pitch to 4095 pixels and requires
- * buffers to be aligned to a 16 pixels boundary (or 128 bytes
- * on some platforms).
- */
- unsigned int bpp = format->planes == 1 ? format->bpp / 8 : 1;
-
- max_pitch = 4095 * bpp;
-
- if (rcar_du_needs(rcdu, RCAR_DU_QUIRK_ALIGN_128B))
- align = 128;
- else
- align = 16 * bpp;
- } else {
- /*
- * On Gen3 the memory interface is handled by the VSP that
- * limits the pitch to 65535 bytes and has no alignment
- * constraint.
- */
- max_pitch = 65535;
- align = 1;
- }
-
- if (mode_cmd->pitches[0] & (align - 1) ||
- mode_cmd->pitches[0] > max_pitch) {
- dev_dbg(dev->dev, "invalid pitch value %u\n",
- mode_cmd->pitches[0]);
- return ERR_PTR(-EINVAL);
- }
-
- /*
- * Calculate the chroma plane(s) pitch using the horizontal subsampling
- * factor. For semi-planar formats, the U and V planes are combined, the
- * pitch must thus be doubled.
- */
- chroma_pitch = mode_cmd->pitches[0] / format->hsub;
- if (format->planes == 2)
- chroma_pitch *= 2;
-
- for (i = 1; i < format->planes; ++i) {
- if (mode_cmd->pitches[i] != chroma_pitch) {
- dev_dbg(dev->dev,
- "luma and chroma pitches are not compatible\n");
- return ERR_PTR(-EINVAL);
- }
- }
-
- return drm_gem_fb_create(dev, file_priv, mode_cmd);
-}
-
-/* -----------------------------------------------------------------------------
- * Atomic Check and Update
- */
-
-static int rcar_du_atomic_check(struct drm_device *dev,
- struct drm_atomic_state *state)
-{
- struct rcar_du_device *rcdu = to_rcar_du_device(dev);
- int ret;
-
- ret = drm_atomic_helper_check(dev, state);
- if (ret)
- return ret;
-
- if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
- return 0;
-
- return rcar_du_atomic_check_planes(dev, state);
-}
-
-static void rcar_du_atomic_commit_tail(struct drm_atomic_state *old_state)
-{
- struct drm_device *dev = old_state->dev;
- struct rcar_du_device *rcdu = to_rcar_du_device(dev);
- struct drm_crtc_state *crtc_state;
- struct drm_crtc *crtc;
- unsigned int i;
-
- /*
- * Store RGB routing to DPAD0 and DPAD1, the hardware will be configured
- * when starting the CRTCs.
- */
- rcdu->dpad1_source = -1;
-
- for_each_new_crtc_in_state(old_state, crtc, crtc_state, i) {
- struct rcar_du_crtc_state *rcrtc_state =
- to_rcar_crtc_state(crtc_state);
- struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
-
- if (rcrtc_state->outputs & BIT(RCAR_DU_OUTPUT_DPAD0))
- rcdu->dpad0_source = rcrtc->index;
-
- if (rcrtc_state->outputs & BIT(RCAR_DU_OUTPUT_DPAD1))
- rcdu->dpad1_source = rcrtc->index;
- }
-
- /* Apply the atomic update. */
- drm_atomic_helper_commit_modeset_disables(dev, old_state);
- drm_atomic_helper_commit_planes(dev, old_state,
- DRM_PLANE_COMMIT_ACTIVE_ONLY);
- drm_atomic_helper_commit_modeset_enables(dev, old_state);
-
- drm_atomic_helper_commit_hw_done(old_state);
- drm_atomic_helper_wait_for_flip_done(dev, old_state);
-
- drm_atomic_helper_cleanup_planes(dev, old_state);
-}
-
-/* -----------------------------------------------------------------------------
- * Initialization
- */
-
-static const struct drm_mode_config_helper_funcs rcar_du_mode_config_helper = {
- .atomic_commit_tail = rcar_du_atomic_commit_tail,
-};
-
-static const struct drm_mode_config_funcs rcar_du_mode_config_funcs = {
- .fb_create = rcar_du_fb_create,
- .atomic_check = rcar_du_atomic_check,
- .atomic_commit = drm_atomic_helper_commit,
-};
-
-static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu,
- enum rcar_du_output output,
- struct of_endpoint *ep)
-{
- struct device_node *entity;
- int ret;
-
- /* Locate the connected entity and initialize the encoder. */
- entity = of_graph_get_remote_port_parent(ep->local_node);
- if (!entity) {
- dev_dbg(rcdu->dev, "unconnected endpoint %pOF, skipping\n",
- ep->local_node);
- return -ENODEV;
- }
-
- if (!of_device_is_available(entity)) {
- dev_dbg(rcdu->dev,
- "connected entity %pOF is disabled, skipping\n",
- entity);
- of_node_put(entity);
- return -ENODEV;
- }
-
- ret = rcar_du_encoder_init(rcdu, output, entity);
- if (ret && ret != -EPROBE_DEFER && ret != -ENOLINK)
- dev_warn(rcdu->dev,
- "failed to initialize encoder %pOF on output %s (%d), skipping\n",
- entity, rcar_du_output_name(output), ret);
-
- of_node_put(entity);
-
- return ret;
-}
-
-static int rcar_du_encoders_init(struct rcar_du_device *rcdu)
-{
- struct device_node *np = rcdu->dev->of_node;
- struct device_node *ep_node;
- unsigned int num_encoders = 0;
-
- /*
- * Iterate over the endpoints and create one encoder for each output
- * pipeline.
- */
- for_each_endpoint_of_node(np, ep_node) {
- enum rcar_du_output output;
- struct of_endpoint ep;
- unsigned int i;
- int ret;
-
- ret = of_graph_parse_endpoint(ep_node, &ep);
- if (ret < 0) {
- of_node_put(ep_node);
- return ret;
- }
-
- /* Find the output route corresponding to the port number. */
- for (i = 0; i < RCAR_DU_OUTPUT_MAX; ++i) {
- if (rcdu->info->routes[i].possible_crtcs &&
- rcdu->info->routes[i].port == ep.port) {
- output = i;
- break;
- }
- }
-
- if (i == RCAR_DU_OUTPUT_MAX) {
- dev_warn(rcdu->dev,
- "port %u references unexisting output, skipping\n",
- ep.port);
- continue;
- }
-
- /* Process the output pipeline. */
- ret = rcar_du_encoders_init_one(rcdu, output, &ep);
- if (ret < 0) {
- if (ret == -EPROBE_DEFER) {
- of_node_put(ep_node);
- return ret;
- }
-
- continue;
- }
-
- num_encoders++;
- }
-
- return num_encoders;
-}
-
-static int rcar_du_properties_init(struct rcar_du_device *rcdu)
-{
- /*
- * The color key is expressed as an RGB888 triplet stored in a 32-bit
- * integer in XRGB8888 format. Bit 24 is used as a flag to disable (0)
- * or enable source color keying (1).
- */
- rcdu->props.colorkey =
- drm_property_create_range(&rcdu->ddev, 0, "colorkey",
- 0, 0x01ffffff);
- if (rcdu->props.colorkey == NULL)
- return -ENOMEM;
-
- return 0;
-}
-
-static int rcar_du_vsps_init(struct rcar_du_device *rcdu)
-{
- const struct device_node *np = rcdu->dev->of_node;
- const char *vsps_prop_name = "renesas,vsps";
- struct of_phandle_args args;
- struct {
- struct device_node *np;
- unsigned int crtcs_mask;
- } vsps[RCAR_DU_MAX_VSPS] = { { NULL, }, };
- unsigned int vsps_count = 0;
- unsigned int cells;
- unsigned int i;
- int ret;
-
- /*
- * First parse the DT vsps property to populate the list of VSPs. Each
- * entry contains a pointer to the VSP DT node and a bitmask of the
- * connected DU CRTCs.
- */
- ret = of_property_count_u32_elems(np, vsps_prop_name);
- if (ret < 0) {
- /* Backward compatibility with old DTBs. */
- vsps_prop_name = "vsps";
- ret = of_property_count_u32_elems(np, vsps_prop_name);
- }
- cells = ret / rcdu->num_crtcs - 1;
- if (cells > 1)
- return -EINVAL;
-
- for (i = 0; i < rcdu->num_crtcs; ++i) {
- unsigned int j;
-
- ret = of_parse_phandle_with_fixed_args(np, vsps_prop_name,
- cells, i, &args);
- if (ret < 0)
- goto error;
-
- /*
- * Add the VSP to the list or update the corresponding existing
- * entry if the VSP has already been added.
- */
- for (j = 0; j < vsps_count; ++j) {
- if (vsps[j].np == args.np)
- break;
- }
-
- if (j < vsps_count)
- of_node_put(args.np);
- else
- vsps[vsps_count++].np = args.np;
-
- vsps[j].crtcs_mask |= BIT(i);
-
- /*
- * Store the VSP pointer and pipe index in the CRTC. If the
- * second cell of the 'renesas,vsps' specifier isn't present,
- * default to 0 to remain compatible with older DT bindings.
- */
- rcdu->crtcs[i].vsp = &rcdu->vsps[j];
- rcdu->crtcs[i].vsp_pipe = cells >= 1 ? args.args[0] : 0;
- }
-
- /*
- * Then initialize all the VSPs from the node pointers and CRTCs bitmask
- * computed previously.
- */
- for (i = 0; i < vsps_count; ++i) {
- struct rcar_du_vsp *vsp = &rcdu->vsps[i];
-
- vsp->index = i;
- vsp->dev = rcdu;
-
- ret = rcar_du_vsp_init(vsp, vsps[i].np, vsps[i].crtcs_mask);
- if (ret < 0)
- goto error;
- }
-
- return 0;
-
-error:
- for (i = 0; i < ARRAY_SIZE(vsps); ++i)
- of_node_put(vsps[i].np);
-
- return ret;
-}
-
-static int rcar_du_cmm_init(struct rcar_du_device *rcdu)
-{
- const struct device_node *np = rcdu->dev->of_node;
- unsigned int i;
- int cells;
-
- cells = of_property_count_u32_elems(np, "renesas,cmms");
- if (cells == -EINVAL)
- return 0;
-
- if (cells > rcdu->num_crtcs) {
- dev_err(rcdu->dev,
- "Invalid number of entries in 'renesas,cmms'\n");
- return -EINVAL;
- }
-
- for (i = 0; i < cells; ++i) {
- struct platform_device *pdev;
- struct device_link *link;
- struct device_node *cmm;
- int ret;
-
- cmm = of_parse_phandle(np, "renesas,cmms", i);
- if (!cmm) {
- dev_err(rcdu->dev,
- "Failed to parse 'renesas,cmms' property\n");
- return -EINVAL;
- }
-
- if (!of_device_is_available(cmm)) {
- /* It's fine to have a phandle to a non-enabled CMM. */
- of_node_put(cmm);
- continue;
- }
-
- pdev = of_find_device_by_node(cmm);
- if (!pdev) {
- dev_err(rcdu->dev, "No device found for CMM%u\n", i);
- of_node_put(cmm);
- return -EINVAL;
- }
-
- of_node_put(cmm);
-
- /*
- * -ENODEV is used to report that the CMM config option is
- * disabled: return 0 and let the DU continue probing.
- */
- ret = rcar_cmm_init(pdev);
- if (ret) {
- platform_device_put(pdev);
- return ret == -ENODEV ? 0 : ret;
- }
-
- rcdu->cmms[i] = pdev;
-
- /*
- * Enforce suspend/resume ordering by making the CMM a provider
- * of the DU: CMM is suspended after and resumed before the DU.
- */
- link = device_link_add(rcdu->dev, &pdev->dev, DL_FLAG_STATELESS);
- if (!link) {
- dev_err(rcdu->dev,
- "Failed to create device link to CMM%u\n", i);
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static void rcar_du_modeset_cleanup(struct drm_device *dev, void *res)
-{
- struct rcar_du_device *rcdu = to_rcar_du_device(dev);
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(rcdu->cmms); ++i)
- platform_device_put(rcdu->cmms[i]);
-}
-
-int rcar_du_modeset_init(struct rcar_du_device *rcdu)
-{
- static const unsigned int mmio_offsets[] = {
- DU0_REG_OFFSET, DU2_REG_OFFSET
- };
-
- struct drm_device *dev = &rcdu->ddev;
- struct drm_encoder *encoder;
- unsigned int dpad0_sources;
- unsigned int num_encoders;
- unsigned int num_groups;
- unsigned int swindex;
- unsigned int hwindex;
- unsigned int i;
- int ret;
-
- ret = drmm_mode_config_init(dev);
- if (ret)
- return ret;
-
- ret = drmm_add_action(&rcdu->ddev, rcar_du_modeset_cleanup, NULL);
- if (ret)
- return ret;
-
- dev->mode_config.min_width = 0;
- dev->mode_config.min_height = 0;
- dev->mode_config.normalize_zpos = true;
- dev->mode_config.funcs = &rcar_du_mode_config_funcs;
- dev->mode_config.helper_private = &rcar_du_mode_config_helper;
-
- if (rcdu->info->gen < 3) {
- dev->mode_config.max_width = 4095;
- dev->mode_config.max_height = 2047;
- } else {
- /*
- * The Gen3 DU uses the VSP1 for memory access, and is limited
- * to frame sizes of 8190x8190.
- */
- dev->mode_config.max_width = 8190;
- dev->mode_config.max_height = 8190;
- }
-
- rcdu->num_crtcs = hweight8(rcdu->info->channels_mask);
-
- ret = rcar_du_properties_init(rcdu);
- if (ret < 0)
- return ret;
-
- /*
- * Initialize vertical blanking interrupts handling. Start with vblank
- * disabled for all CRTCs.
- */
- ret = drm_vblank_init(dev, rcdu->num_crtcs);
- if (ret < 0)
- return ret;
-
- /* Initialize the groups. */
- num_groups = DIV_ROUND_UP(rcdu->num_crtcs, 2);
-
- for (i = 0; i < num_groups; ++i) {
- struct rcar_du_group *rgrp = &rcdu->groups[i];
-
- mutex_init(&rgrp->lock);
-
- rgrp->dev = rcdu;
- rgrp->mmio_offset = mmio_offsets[i];
- rgrp->index = i;
- /* Extract the channel mask for this group only. */
- rgrp->channels_mask = (rcdu->info->channels_mask >> (2 * i))
- & GENMASK(1, 0);
- rgrp->num_crtcs = hweight8(rgrp->channels_mask);
-
- /*
- * If we have more than one CRTCs in this group pre-associate
- * the low-order planes with CRTC 0 and the high-order planes
- * with CRTC 1 to minimize flicker occurring when the
- * association is changed.
- */
- rgrp->dptsr_planes = rgrp->num_crtcs > 1
- ? (rcdu->info->gen >= 3 ? 0x04 : 0xf0)
- : 0;
-
- if (!rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE)) {
- ret = rcar_du_planes_init(rgrp);
- if (ret < 0)
- return ret;
- }
- }
-
- /* Initialize the compositors. */
- if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE)) {
- ret = rcar_du_vsps_init(rcdu);
- if (ret < 0)
- return ret;
- }
-
- /* Initialize the Color Management Modules. */
- ret = rcar_du_cmm_init(rcdu);
- if (ret)
- return ret;
-
- /* Create the CRTCs. */
- for (swindex = 0, hwindex = 0; swindex < rcdu->num_crtcs; ++hwindex) {
- struct rcar_du_group *rgrp;
-
- /* Skip unpopulated DU channels. */
- if (!(rcdu->info->channels_mask & BIT(hwindex)))
- continue;
-
- rgrp = &rcdu->groups[hwindex / 2];
-
- ret = rcar_du_crtc_create(rgrp, swindex++, hwindex);
- if (ret < 0)
- return ret;
- }
-
- /* Initialize the encoders. */
- ret = rcar_du_encoders_init(rcdu);
- if (ret < 0)
- return ret;
-
- if (ret == 0) {
- dev_err(rcdu->dev, "error: no encoder could be initialized\n");
- return -EINVAL;
- }
-
- num_encoders = ret;
-
- /*
- * Set the possible CRTCs and possible clones. There's always at least
- * one way for all encoders to clone each other, set all bits in the
- * possible clones field.
- */
- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- struct rcar_du_encoder *renc = to_rcar_encoder(encoder);
- const struct rcar_du_output_routing *route =
- &rcdu->info->routes[renc->output];
-
- encoder->possible_crtcs = route->possible_crtcs;
- encoder->possible_clones = (1 << num_encoders) - 1;
- }
-
- /* Create the writeback connectors. */
- if (rcdu->info->gen >= 3) {
- for (i = 0; i < rcdu->num_crtcs; ++i) {
- struct rcar_du_crtc *rcrtc = &rcdu->crtcs[i];
-
- ret = rcar_du_writeback_init(rcdu, rcrtc);
- if (ret < 0)
- return ret;
- }
- }
-
- /*
- * Initialize the default DPAD0 source to the index of the first DU
- * channel that can be connected to DPAD0. The exact value doesn't
- * matter as it should be overwritten by mode setting for the RGB
- * output, but it is nonetheless required to ensure a valid initial
- * hardware configuration on Gen3 where DU0 can't always be connected to
- * DPAD0.
- */
- dpad0_sources = rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs;
- rcdu->dpad0_source = ffs(dpad0_sources) - 1;
-
- drm_mode_config_reset(dev);
-
- drm_kms_helper_poll_init(dev);
-
- return 0;
-}
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.h b/drivers/gpu/drm/rcar-du/rcar_du_kms.h
deleted file mode 100644
index f31afeeee05a..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * R-Car Display Unit Mode Setting
- *
- * Copyright (C) 2013-2014 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-#ifndef __RCAR_DU_KMS_H__
-#define __RCAR_DU_KMS_H__
-
-#include <linux/types.h>
-
-struct dma_buf_attachment;
-struct drm_file;
-struct drm_device;
-struct drm_gem_object;
-struct drm_mode_create_dumb;
-struct rcar_du_device;
-struct sg_table;
-
-struct rcar_du_format_info {
- u32 fourcc;
- u32 v4l2;
- unsigned int bpp;
- unsigned int planes;
- unsigned int hsub;
- unsigned int pnmr;
- unsigned int edf;
-};
-
-const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc);
-
-int rcar_du_modeset_init(struct rcar_du_device *rcdu);
-
-int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev,
- struct drm_mode_create_dumb *args);
-
-struct drm_gem_object *rcar_du_gem_prime_import_sg_table(struct drm_device *dev,
- struct dma_buf_attachment *attach,
- struct sg_table *sgt);
-
-#endif /* __RCAR_DU_KMS_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
deleted file mode 100644
index d759e0192181..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ /dev/null
@@ -1,831 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * R-Car Display Unit Planes
- *
- * Copyright (C) 2013-2015 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-#include <drm/drm_atomic.h>
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_blend.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_device.h>
-#include <drm/drm_fb_dma_helper.h>
-#include <drm/drm_fourcc.h>
-#include <drm/drm_framebuffer.h>
-#include <drm/drm_gem_dma_helper.h>
-
-#include "rcar_du_drv.h"
-#include "rcar_du_group.h"
-#include "rcar_du_kms.h"
-#include "rcar_du_plane.h"
-#include "rcar_du_regs.h"
-
-/* -----------------------------------------------------------------------------
- * Atomic hardware plane allocator
- *
- * The hardware plane allocator is solely based on the atomic plane states
- * without keeping any external state to avoid races between .atomic_check()
- * and .atomic_commit().
- *
- * The core idea is to avoid using a free planes bitmask that would need to be
- * shared between check and commit handlers with a collective knowledge based on
- * the allocated hardware plane(s) for each KMS plane. The allocator then loops
- * over all plane states to compute the free planes bitmask, allocates hardware
- * planes based on that bitmask, and stores the result back in the plane states.
- *
- * For this to work we need to access the current state of planes not touched by
- * the atomic update. To ensure that it won't be modified, we need to lock all
- * planes using drm_atomic_get_plane_state(). This effectively serializes atomic
- * updates from .atomic_check() up to completion (when swapping the states if
- * the check step has succeeded) or rollback (when freeing the states if the
- * check step has failed).
- *
- * Allocation is performed in the .atomic_check() handler and applied
- * automatically when the core swaps the old and new states.
- */
-
-static bool rcar_du_plane_needs_realloc(
- const struct rcar_du_plane_state *old_state,
- const struct rcar_du_plane_state *new_state)
-{
- /*
- * Lowering the number of planes doesn't strictly require reallocation
- * as the extra hardware plane will be freed when committing, but doing
- * so could lead to more fragmentation.
- */
- if (!old_state->format ||
- old_state->format->planes != new_state->format->planes)
- return true;
-
- /* Reallocate hardware planes if the source has changed. */
- if (old_state->source != new_state->source)
- return true;
-
- return false;
-}
-
-static unsigned int rcar_du_plane_hwmask(struct rcar_du_plane_state *state)
-{
- unsigned int mask;
-
- if (state->hwindex == -1)
- return 0;
-
- mask = 1 << state->hwindex;
- if (state->format->planes == 2)
- mask |= 1 << ((state->hwindex + 1) % 8);
-
- return mask;
-}
-
-/*
- * The R8A7790 DU can source frames directly from the VSP1 devices VSPD0 and
- * VSPD1. VSPD0 feeds DU0/1 plane 0, and VSPD1 feeds either DU2 plane 0 or
- * DU0/1 plane 1.
- *
- * Allocate the correct fixed plane when sourcing frames from VSPD0 or VSPD1,
- * and allocate planes in reverse index order otherwise to ensure maximum
- * availability of planes 0 and 1.
- *
- * The caller is responsible for ensuring that the requested source is
- * compatible with the DU revision.
- */
-static int rcar_du_plane_hwalloc(struct rcar_du_plane *plane,
- struct rcar_du_plane_state *state,
- unsigned int free)
-{
- unsigned int num_planes = state->format->planes;
- int fixed = -1;
- int i;
-
- if (state->source == RCAR_DU_PLANE_VSPD0) {
- /* VSPD0 feeds plane 0 on DU0/1. */
- if (plane->group->index != 0)
- return -EINVAL;
-
- fixed = 0;
- } else if (state->source == RCAR_DU_PLANE_VSPD1) {
- /* VSPD1 feeds plane 1 on DU0/1 or plane 0 on DU2. */
- fixed = plane->group->index == 0 ? 1 : 0;
- }
-
- if (fixed >= 0)
- return free & (1 << fixed) ? fixed : -EBUSY;
-
- for (i = RCAR_DU_NUM_HW_PLANES - 1; i >= 0; --i) {
- if (!(free & (1 << i)))
- continue;
-
- if (num_planes == 1 || free & (1 << ((i + 1) % 8)))
- break;
- }
-
- return i < 0 ? -EBUSY : i;
-}
-
-int rcar_du_atomic_check_planes(struct drm_device *dev,
- struct drm_atomic_state *state)
-{
- struct rcar_du_device *rcdu = to_rcar_du_device(dev);
- unsigned int group_freed_planes[RCAR_DU_MAX_GROUPS] = { 0, };
- unsigned int group_free_planes[RCAR_DU_MAX_GROUPS] = { 0, };
- bool needs_realloc = false;
- unsigned int groups = 0;
- unsigned int i;
- struct drm_plane *drm_plane;
- struct drm_plane_state *old_drm_plane_state;
- struct drm_plane_state *new_drm_plane_state;
-
- /* Check if hardware planes need to be reallocated. */
- for_each_oldnew_plane_in_state(state, drm_plane, old_drm_plane_state,
- new_drm_plane_state, i) {
- struct rcar_du_plane_state *old_plane_state;
- struct rcar_du_plane_state *new_plane_state;
- struct rcar_du_plane *plane;
- unsigned int index;
-
- plane = to_rcar_plane(drm_plane);
- old_plane_state = to_rcar_plane_state(old_drm_plane_state);
- new_plane_state = to_rcar_plane_state(new_drm_plane_state);
-
- dev_dbg(rcdu->dev, "%s: checking plane (%u,%tu)\n", __func__,
- plane->group->index, plane - plane->group->planes);
-
- /*
- * If the plane is being disabled we don't need to go through
- * the full reallocation procedure. Just mark the hardware
- * plane(s) as freed.
- */
- if (!new_plane_state->format) {
- dev_dbg(rcdu->dev, "%s: plane is being disabled\n",
- __func__);
- index = plane - plane->group->planes;
- group_freed_planes[plane->group->index] |= 1 << index;
- new_plane_state->hwindex = -1;
- continue;
- }
-
- /*
- * If the plane needs to be reallocated mark it as such, and
- * mark the hardware plane(s) as free.
- */
- if (rcar_du_plane_needs_realloc(old_plane_state, new_plane_state)) {
- dev_dbg(rcdu->dev, "%s: plane needs reallocation\n",
- __func__);
- groups |= 1 << plane->group->index;
- needs_realloc = true;
-
- index = plane - plane->group->planes;
- group_freed_planes[plane->group->index] |= 1 << index;
- new_plane_state->hwindex = -1;
- }
- }
-
- if (!needs_realloc)
- return 0;
-
- /*
- * Grab all plane states for the groups that need reallocation to ensure
- * locking and avoid racy updates. This serializes the update operation,
- * but there's not much we can do about it as that's the hardware
- * design.
- *
- * Compute the used planes mask for each group at the same time to avoid
- * looping over the planes separately later.
- */
- while (groups) {
- unsigned int index = ffs(groups) - 1;
- struct rcar_du_group *group = &rcdu->groups[index];
- unsigned int used_planes = 0;
-
- dev_dbg(rcdu->dev, "%s: finding free planes for group %u\n",
- __func__, index);
-
- for (i = 0; i < group->num_planes; ++i) {
- struct rcar_du_plane *plane = &group->planes[i];
- struct rcar_du_plane_state *new_plane_state;
- struct drm_plane_state *s;
-
- s = drm_atomic_get_plane_state(state, &plane->plane);
- if (IS_ERR(s))
- return PTR_ERR(s);
-
- /*
- * If the plane has been freed in the above loop its
- * hardware planes must not be added to the used planes
- * bitmask. However, the current state doesn't reflect
- * the free state yet, as we've modified the new state
- * above. Use the local freed planes list to check for
- * that condition instead.
- */
- if (group_freed_planes[index] & (1 << i)) {
- dev_dbg(rcdu->dev,
- "%s: plane (%u,%tu) has been freed, skipping\n",
- __func__, plane->group->index,
- plane - plane->group->planes);
- continue;
- }
-
- new_plane_state = to_rcar_plane_state(s);
- used_planes |= rcar_du_plane_hwmask(new_plane_state);
-
- dev_dbg(rcdu->dev,
- "%s: plane (%u,%tu) uses %u hwplanes (index %d)\n",
- __func__, plane->group->index,
- plane - plane->group->planes,
- new_plane_state->format ?
- new_plane_state->format->planes : 0,
- new_plane_state->hwindex);
- }
-
- group_free_planes[index] = 0xff & ~used_planes;
- groups &= ~(1 << index);
-
- dev_dbg(rcdu->dev, "%s: group %u free planes mask 0x%02x\n",
- __func__, index, group_free_planes[index]);
- }
-
- /* Reallocate hardware planes for each plane that needs it. */
- for_each_oldnew_plane_in_state(state, drm_plane, old_drm_plane_state,
- new_drm_plane_state, i) {
- struct rcar_du_plane_state *old_plane_state;
- struct rcar_du_plane_state *new_plane_state;
- struct rcar_du_plane *plane;
- unsigned int crtc_planes;
- unsigned int free;
- int idx;
-
- plane = to_rcar_plane(drm_plane);
- old_plane_state = to_rcar_plane_state(old_drm_plane_state);
- new_plane_state = to_rcar_plane_state(new_drm_plane_state);
-
- dev_dbg(rcdu->dev, "%s: allocating plane (%u,%tu)\n", __func__,
- plane->group->index, plane - plane->group->planes);
-
- /*
- * Skip planes that are being disabled or don't need to be
- * reallocated.
- */
- if (!new_plane_state->format ||
- !rcar_du_plane_needs_realloc(old_plane_state, new_plane_state))
- continue;
-
- /*
- * Try to allocate the plane from the free planes currently
- * associated with the target CRTC to avoid restarting the CRTC
- * group and thus minimize flicker. If it fails fall back to
- * allocating from all free planes.
- */
- crtc_planes = to_rcar_crtc(new_plane_state->state.crtc)->index % 2
- ? plane->group->dptsr_planes
- : ~plane->group->dptsr_planes;
- free = group_free_planes[plane->group->index];
-
- idx = rcar_du_plane_hwalloc(plane, new_plane_state,
- free & crtc_planes);
- if (idx < 0)
- idx = rcar_du_plane_hwalloc(plane, new_plane_state,
- free);
- if (idx < 0) {
- dev_dbg(rcdu->dev, "%s: no available hardware plane\n",
- __func__);
- return idx;
- }
-
- dev_dbg(rcdu->dev, "%s: allocated %u hwplanes (index %u)\n",
- __func__, new_plane_state->format->planes, idx);
-
- new_plane_state->hwindex = idx;
-
- group_free_planes[plane->group->index] &=
- ~rcar_du_plane_hwmask(new_plane_state);
-
- dev_dbg(rcdu->dev, "%s: group %u free planes mask 0x%02x\n",
- __func__, plane->group->index,
- group_free_planes[plane->group->index]);
- }
-
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Plane Setup
- */
-
-#define RCAR_DU_COLORKEY_NONE (0 << 24)
-#define RCAR_DU_COLORKEY_SOURCE (1 << 24)
-#define RCAR_DU_COLORKEY_MASK (1 << 24)
-
-static void rcar_du_plane_write(struct rcar_du_group *rgrp,
- unsigned int index, u32 reg, u32 data)
-{
- rcar_du_write(rgrp->dev, rgrp->mmio_offset + index * PLANE_OFF + reg,
- data);
-}
-
-static void rcar_du_plane_setup_scanout(struct rcar_du_group *rgrp,
- const struct rcar_du_plane_state *state)
-{
- unsigned int src_x = state->state.src.x1 >> 16;
- unsigned int src_y = state->state.src.y1 >> 16;
- unsigned int index = state->hwindex;
- unsigned int pitch;
- bool interlaced;
- u32 dma[2];
-
- interlaced = state->state.crtc->state->adjusted_mode.flags
- & DRM_MODE_FLAG_INTERLACE;
-
- if (state->source == RCAR_DU_PLANE_MEMORY) {
- struct drm_framebuffer *fb = state->state.fb;
- struct drm_gem_dma_object *gem;
- unsigned int i;
-
- if (state->format->planes == 2)
- pitch = fb->pitches[0];
- else
- pitch = fb->pitches[0] * 8 / state->format->bpp;
-
- for (i = 0; i < state->format->planes; ++i) {
- gem = drm_fb_dma_get_gem_obj(fb, i);
- dma[i] = gem->dma_addr + fb->offsets[i];
- }
- } else {
- pitch = drm_rect_width(&state->state.src) >> 16;
- dma[0] = 0;
- dma[1] = 0;
- }
-
- /*
- * Memory pitch (expressed in pixels). Must be doubled for interlaced
- * operation with 32bpp formats.
- */
- rcar_du_plane_write(rgrp, index, PnMWR,
- (interlaced && state->format->bpp == 32) ?
- pitch * 2 : pitch);
-
- /*
- * The Y position is expressed in raster line units and must be doubled
- * for 32bpp formats, according to the R8A7790 datasheet. No mention of
- * doubling the Y position is found in the R8A7779 datasheet, but the
- * rule seems to apply there as well.
- *
- * Despite not being documented, doubling seem not to be needed when
- * operating in interlaced mode.
- *
- * Similarly, for the second plane, NV12 and NV21 formats seem to
- * require a halved Y position value, in both progressive and interlaced
- * modes.
- */
- rcar_du_plane_write(rgrp, index, PnSPXR, src_x);
- rcar_du_plane_write(rgrp, index, PnSPYR, src_y *
- (!interlaced && state->format->bpp == 32 ? 2 : 1));
-
- rcar_du_plane_write(rgrp, index, PnDSA0R, dma[0]);
-
- if (state->format->planes == 2) {
- index = (index + 1) % 8;
-
- rcar_du_plane_write(rgrp, index, PnMWR, pitch);
-
- rcar_du_plane_write(rgrp, index, PnSPXR, src_x);
- rcar_du_plane_write(rgrp, index, PnSPYR, src_y *
- (state->format->bpp == 16 ? 2 : 1) / 2);
-
- rcar_du_plane_write(rgrp, index, PnDSA0R, dma[1]);
- }
-}
-
-static void rcar_du_plane_setup_mode(struct rcar_du_group *rgrp,
- unsigned int index,
- const struct rcar_du_plane_state *state)
-{
- u32 colorkey;
- u32 pnmr;
-
- /*
- * The PnALPHAR register controls alpha-blending in 16bpp formats
- * (ARGB1555 and XRGB1555).
- *
- * For ARGB, set the alpha value to 0, and enable alpha-blending when
- * the A bit is 0. This maps A=0 to alpha=0 and A=1 to alpha=255.
- *
- * For XRGB, set the alpha value to the plane-wide alpha value and
- * enable alpha-blending regardless of the X bit value.
- */
- if (state->format->fourcc != DRM_FORMAT_XRGB1555)
- rcar_du_plane_write(rgrp, index, PnALPHAR, PnALPHAR_ABIT_0);
- else
- rcar_du_plane_write(rgrp, index, PnALPHAR,
- PnALPHAR_ABIT_X | state->state.alpha >> 8);
-
- pnmr = PnMR_BM_MD | state->format->pnmr;
-
- /*
- * Disable color keying when requested. YUV formats have the
- * PnMR_SPIM_TP_OFF bit set in their pnmr field, disabling color keying
- * automatically.
- */
- if ((state->colorkey & RCAR_DU_COLORKEY_MASK) == RCAR_DU_COLORKEY_NONE)
- pnmr |= PnMR_SPIM_TP_OFF;
-
- /* For packed YUV formats we need to select the U/V order. */
- if (state->format->fourcc == DRM_FORMAT_YUYV)
- pnmr |= PnMR_YCDF_YUYV;
-
- rcar_du_plane_write(rgrp, index, PnMR, pnmr);
-
- switch (state->format->fourcc) {
- case DRM_FORMAT_RGB565:
- colorkey = ((state->colorkey & 0xf80000) >> 8)
- | ((state->colorkey & 0x00fc00) >> 5)
- | ((state->colorkey & 0x0000f8) >> 3);
- rcar_du_plane_write(rgrp, index, PnTC2R, colorkey);
- break;
-
- case DRM_FORMAT_ARGB1555:
- case DRM_FORMAT_XRGB1555:
- colorkey = ((state->colorkey & 0xf80000) >> 9)
- | ((state->colorkey & 0x00f800) >> 6)
- | ((state->colorkey & 0x0000f8) >> 3);
- rcar_du_plane_write(rgrp, index, PnTC2R, colorkey);
- break;
-
- case DRM_FORMAT_XRGB8888:
- case DRM_FORMAT_ARGB8888:
- rcar_du_plane_write(rgrp, index, PnTC3R,
- PnTC3R_CODE | (state->colorkey & 0xffffff));
- break;
- }
-}
-
-static void rcar_du_plane_setup_format_gen2(struct rcar_du_group *rgrp,
- unsigned int index,
- const struct rcar_du_plane_state *state)
-{
- u32 ddcr2 = PnDDCR2_CODE;
- u32 ddcr4;
-
- /*
- * Data format
- *
- * The data format is selected by the DDDF field in PnMR and the EDF
- * field in DDCR4.
- */
-
- rcar_du_plane_setup_mode(rgrp, index, state);
-
- if (state->format->planes == 2) {
- if (state->hwindex != index) {
- if (state->format->fourcc == DRM_FORMAT_NV12 ||
- state->format->fourcc == DRM_FORMAT_NV21)
- ddcr2 |= PnDDCR2_Y420;
-
- if (state->format->fourcc == DRM_FORMAT_NV21)
- ddcr2 |= PnDDCR2_NV21;
-
- ddcr2 |= PnDDCR2_DIVU;
- } else {
- ddcr2 |= PnDDCR2_DIVY;
- }
- }
-
- rcar_du_plane_write(rgrp, index, PnDDCR2, ddcr2);
-
- ddcr4 = state->format->edf | PnDDCR4_CODE;
- if (state->source != RCAR_DU_PLANE_MEMORY)
- ddcr4 |= PnDDCR4_VSPS;
-
- rcar_du_plane_write(rgrp, index, PnDDCR4, ddcr4);
-}
-
-static void rcar_du_plane_setup_format_gen3(struct rcar_du_group *rgrp,
- unsigned int index,
- const struct rcar_du_plane_state *state)
-{
- struct rcar_du_device *rcdu = rgrp->dev;
- u32 pnmr = state->format->pnmr | PnMR_SPIM_TP_OFF;
-
- if (rcdu->info->features & RCAR_DU_FEATURE_NO_BLENDING) {
- /* No blending. ALP and EOR are not supported. */
- pnmr &= ~(PnMR_SPIM_ALP | PnMR_SPIM_EOR);
- }
-
- rcar_du_plane_write(rgrp, index, PnMR, pnmr);
-
- rcar_du_plane_write(rgrp, index, PnDDCR4,
- state->format->edf | PnDDCR4_CODE);
-
- /*
- * On Gen3, some DU channels have two planes, each being wired to a
- * separate VSPD instance. The DU can then blend two planes. While
- * this feature isn't used by the driver, issues related to alpha
- * blending (such as incorrect colors or planes being invisible) may
- * still occur if the PnALPHAR register has a stale value. Set the
- * register to 0 to avoid this.
- */
-
- rcar_du_plane_write(rgrp, index, PnALPHAR, 0);
-}
-
-static void rcar_du_plane_setup_format(struct rcar_du_group *rgrp,
- unsigned int index,
- const struct rcar_du_plane_state *state)
-{
- struct rcar_du_device *rcdu = rgrp->dev;
- const struct drm_rect *dst = &state->state.dst;
-
- if (rcdu->info->gen < 3)
- rcar_du_plane_setup_format_gen2(rgrp, index, state);
- else
- rcar_du_plane_setup_format_gen3(rgrp, index, state);
-
- /* Destination position and size */
- rcar_du_plane_write(rgrp, index, PnDSXR, drm_rect_width(dst));
- rcar_du_plane_write(rgrp, index, PnDSYR, drm_rect_height(dst));
- rcar_du_plane_write(rgrp, index, PnDPXR, dst->x1);
- rcar_du_plane_write(rgrp, index, PnDPYR, dst->y1);
-
- if (rcdu->info->gen < 3) {
- /* Wrap-around and blinking, disabled */
- rcar_du_plane_write(rgrp, index, PnWASPR, 0);
- rcar_du_plane_write(rgrp, index, PnWAMWR, 4095);
- rcar_du_plane_write(rgrp, index, PnBTR, 0);
- rcar_du_plane_write(rgrp, index, PnMLR, 0);
- }
-}
-
-void __rcar_du_plane_setup(struct rcar_du_group *rgrp,
- const struct rcar_du_plane_state *state)
-{
- struct rcar_du_device *rcdu = rgrp->dev;
-
- rcar_du_plane_setup_format(rgrp, state->hwindex, state);
- if (state->format->planes == 2)
- rcar_du_plane_setup_format(rgrp, (state->hwindex + 1) % 8,
- state);
-
- if (rcdu->info->gen >= 3)
- return;
-
- rcar_du_plane_setup_scanout(rgrp, state);
-
- if (state->source == RCAR_DU_PLANE_VSPD1) {
- unsigned int vspd1_sink = rgrp->index ? 2 : 0;
-
- if (rcdu->vspd1_sink != vspd1_sink) {
- rcdu->vspd1_sink = vspd1_sink;
- rcar_du_set_dpad0_vsp1_routing(rcdu);
-
- /*
- * Changes to the VSP1 sink take effect on DRES and thus
- * need a restart of the group.
- */
- rgrp->need_restart = true;
- }
- }
-}
-
-int __rcar_du_plane_atomic_check(struct drm_plane *plane,
- struct drm_plane_state *state,
- const struct rcar_du_format_info **format)
-{
- struct drm_device *dev = plane->dev;
- struct drm_crtc_state *crtc_state;
- int ret;
-
- 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;
- *format = NULL;
- 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,
- DRM_PLANE_NO_SCALING,
- DRM_PLANE_NO_SCALING,
- true, true);
- if (ret < 0)
- return ret;
-
- if (!state->visible) {
- *format = NULL;
- return 0;
- }
-
- *format = rcar_du_format_info(state->fb->format->format);
- if (*format == NULL) {
- dev_dbg(dev->dev, "%s: unsupported format %p4cc\n", __func__,
- &state->fb->format->format);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int rcar_du_plane_atomic_check(struct drm_plane *plane,
- struct drm_atomic_state *state)
-{
- struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
- plane);
- struct rcar_du_plane_state *rstate = to_rcar_plane_state(new_plane_state);
-
- return __rcar_du_plane_atomic_check(plane, new_plane_state,
- &rstate->format);
-}
-
-static void rcar_du_plane_atomic_update(struct drm_plane *plane,
- struct drm_atomic_state *state)
-{
- struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, plane);
- struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane);
- struct rcar_du_plane *rplane = to_rcar_plane(plane);
- struct rcar_du_plane_state *old_rstate;
- struct rcar_du_plane_state *new_rstate;
-
- if (!new_state->visible)
- return;
-
- rcar_du_plane_setup(rplane);
-
- /*
- * Check whether the source has changed from memory to live source or
- * from live source to memory. The source has been configured by the
- * VSPS bit in the PnDDCR4 register. Although the datasheet states that
- * the bit is updated during vertical blanking, it seems that updates
- * only occur when the DU group is held in reset through the DSYSR.DRES
- * bit. We thus need to restart the group if the source changes.
- */
- old_rstate = to_rcar_plane_state(old_state);
- new_rstate = to_rcar_plane_state(new_state);
-
- if ((old_rstate->source == RCAR_DU_PLANE_MEMORY) !=
- (new_rstate->source == RCAR_DU_PLANE_MEMORY))
- rplane->group->need_restart = true;
-}
-
-static const struct drm_plane_helper_funcs rcar_du_plane_helper_funcs = {
- .atomic_check = rcar_du_plane_atomic_check,
- .atomic_update = rcar_du_plane_atomic_update,
-};
-
-static struct drm_plane_state *
-rcar_du_plane_atomic_duplicate_state(struct drm_plane *plane)
-{
- struct rcar_du_plane_state *state;
- struct rcar_du_plane_state *copy;
-
- if (WARN_ON(!plane->state))
- return NULL;
-
- state = to_rcar_plane_state(plane->state);
- copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
- if (copy == NULL)
- return NULL;
-
- __drm_atomic_helper_plane_duplicate_state(plane, &copy->state);
-
- return &copy->state;
-}
-
-static void rcar_du_plane_atomic_destroy_state(struct drm_plane *plane,
- struct drm_plane_state *state)
-{
- __drm_atomic_helper_plane_destroy_state(state);
- kfree(to_rcar_plane_state(state));
-}
-
-static void rcar_du_plane_reset(struct drm_plane *plane)
-{
- struct rcar_du_plane_state *state;
-
- if (plane->state) {
- rcar_du_plane_atomic_destroy_state(plane, plane->state);
- plane->state = NULL;
- }
-
- state = kzalloc(sizeof(*state), GFP_KERNEL);
- if (state == NULL)
- return;
-
- __drm_atomic_helper_plane_reset(plane, &state->state);
-
- state->hwindex = -1;
- state->source = RCAR_DU_PLANE_MEMORY;
- state->colorkey = RCAR_DU_COLORKEY_NONE;
-}
-
-static int rcar_du_plane_atomic_set_property(struct drm_plane *plane,
- struct drm_plane_state *state,
- struct drm_property *property,
- uint64_t val)
-{
- struct rcar_du_plane_state *rstate = to_rcar_plane_state(state);
- struct rcar_du_device *rcdu = to_rcar_plane(plane)->group->dev;
-
- if (property == rcdu->props.colorkey)
- rstate->colorkey = val;
- else
- return -EINVAL;
-
- return 0;
-}
-
-static int rcar_du_plane_atomic_get_property(struct drm_plane *plane,
- const struct drm_plane_state *state, struct drm_property *property,
- uint64_t *val)
-{
- const struct rcar_du_plane_state *rstate =
- container_of(state, const struct rcar_du_plane_state, state);
- struct rcar_du_device *rcdu = to_rcar_plane(plane)->group->dev;
-
- if (property == rcdu->props.colorkey)
- *val = rstate->colorkey;
- else
- return -EINVAL;
-
- return 0;
-}
-
-static const struct drm_plane_funcs rcar_du_plane_funcs = {
- .update_plane = drm_atomic_helper_update_plane,
- .disable_plane = drm_atomic_helper_disable_plane,
- .reset = rcar_du_plane_reset,
- .destroy = drm_plane_cleanup,
- .atomic_duplicate_state = rcar_du_plane_atomic_duplicate_state,
- .atomic_destroy_state = rcar_du_plane_atomic_destroy_state,
- .atomic_set_property = rcar_du_plane_atomic_set_property,
- .atomic_get_property = rcar_du_plane_atomic_get_property,
-};
-
-static const uint32_t formats[] = {
- DRM_FORMAT_RGB565,
- DRM_FORMAT_ARGB1555,
- DRM_FORMAT_XRGB1555,
- DRM_FORMAT_XRGB8888,
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_UYVY,
- DRM_FORMAT_YUYV,
- DRM_FORMAT_NV12,
- DRM_FORMAT_NV21,
- DRM_FORMAT_NV16,
-};
-
-int rcar_du_planes_init(struct rcar_du_group *rgrp)
-{
- struct rcar_du_device *rcdu = rgrp->dev;
- unsigned int crtcs;
- unsigned int i;
- int ret;
-
- /*
- * Create one primary plane per CRTC in this group and seven overlay
- * planes.
- */
- rgrp->num_planes = rgrp->num_crtcs + 7;
-
- crtcs = ((1 << rcdu->num_crtcs) - 1) & (3 << (2 * rgrp->index));
-
- for (i = 0; i < rgrp->num_planes; ++i) {
- enum drm_plane_type type = i < rgrp->num_crtcs
- ? DRM_PLANE_TYPE_PRIMARY
- : DRM_PLANE_TYPE_OVERLAY;
- struct rcar_du_plane *plane = &rgrp->planes[i];
-
- plane->group = rgrp;
-
- ret = drm_universal_plane_init(&rcdu->ddev, &plane->plane,
- crtcs, &rcar_du_plane_funcs,
- formats, ARRAY_SIZE(formats),
- NULL, type, NULL);
- if (ret < 0)
- return ret;
-
- drm_plane_helper_add(&plane->plane,
- &rcar_du_plane_helper_funcs);
-
- drm_plane_create_alpha_property(&plane->plane);
-
- if (type == DRM_PLANE_TYPE_PRIMARY) {
- drm_plane_create_zpos_immutable_property(&plane->plane,
- 0);
- } else {
- drm_object_attach_property(&plane->plane.base,
- rcdu->props.colorkey,
- RCAR_DU_COLORKEY_NONE);
- drm_plane_create_zpos_property(&plane->plane, 1, 1, 7);
- }
- }
-
- return 0;
-}
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
deleted file mode 100644
index f9893d7d6dfc..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * R-Car Display Unit Planes
- *
- * Copyright (C) 2013-2014 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-#ifndef __RCAR_DU_PLANE_H__
-#define __RCAR_DU_PLANE_H__
-
-#include <drm/drm_plane.h>
-
-struct rcar_du_format_info;
-struct rcar_du_group;
-
-/*
- * The RCAR DU has 8 hardware planes, shared between primary and overlay planes.
- * As using overlay planes requires at least one of the CRTCs being enabled, no
- * more than 7 overlay planes can be available. We thus create 1 primary plane
- * per CRTC and 7 overlay planes, for a total of up to 9 KMS planes.
- */
-#define RCAR_DU_NUM_KMS_PLANES 9
-#define RCAR_DU_NUM_HW_PLANES 8
-
-enum rcar_du_plane_source {
- RCAR_DU_PLANE_MEMORY,
- RCAR_DU_PLANE_VSPD0,
- RCAR_DU_PLANE_VSPD1,
-};
-
-struct rcar_du_plane {
- struct drm_plane plane;
- struct rcar_du_group *group;
-};
-
-static inline struct rcar_du_plane *to_rcar_plane(struct drm_plane *plane)
-{
- return container_of(plane, struct rcar_du_plane, plane);
-}
-
-/**
- * struct rcar_du_plane_state - Driver-specific plane state
- * @state: base DRM plane state
- * @format: information about the pixel format used by the plane
- * @hwindex: 0-based hardware plane index, -1 means unused
- * @colorkey: value of the plane colorkey property
- */
-struct rcar_du_plane_state {
- struct drm_plane_state state;
-
- const struct rcar_du_format_info *format;
- int hwindex;
- enum rcar_du_plane_source source;
-
- unsigned int colorkey;
-};
-
-static inline struct rcar_du_plane_state *
-to_rcar_plane_state(struct drm_plane_state *state)
-{
- return container_of(state, struct rcar_du_plane_state, state);
-}
-
-int rcar_du_atomic_check_planes(struct drm_device *dev,
- struct drm_atomic_state *state);
-
-int __rcar_du_plane_atomic_check(struct drm_plane *plane,
- struct drm_plane_state *state,
- const struct rcar_du_format_info **format);
-
-int rcar_du_planes_init(struct rcar_du_group *rgrp);
-
-void __rcar_du_plane_setup(struct rcar_du_group *rgrp,
- const struct rcar_du_plane_state *state);
-
-static inline void rcar_du_plane_setup(struct rcar_du_plane *plane)
-{
- struct rcar_du_plane_state *state =
- to_rcar_plane_state(plane->plane.state);
-
- return __rcar_du_plane_setup(plane->group, state);
-}
-
-#endif /* __RCAR_DU_PLANE_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_regs.h b/drivers/gpu/drm/rcar-du/rcar_du_regs.h
deleted file mode 100644
index 391de6661d8b..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_regs.h
+++ /dev/null
@@ -1,553 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * R-Car Display Unit Registers Definitions
- *
- * Copyright (C) 2013-2015 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-#ifndef __RCAR_DU_REGS_H__
-#define __RCAR_DU_REGS_H__
-
-#define DU0_REG_OFFSET 0x00000
-#define DU1_REG_OFFSET 0x30000
-#define DU2_REG_OFFSET 0x40000
-#define DU3_REG_OFFSET 0x70000
-
-/* -----------------------------------------------------------------------------
- * Display Control Registers
- */
-
-#define DSYSR 0x00000 /* display 1 */
-#define DSYSR_ILTS (1 << 29)
-#define DSYSR_DSEC (1 << 20)
-#define DSYSR_IUPD (1 << 16)
-#define DSYSR_DRES (1 << 9)
-#define DSYSR_DEN (1 << 8)
-#define DSYSR_TVM_MASTER (0 << 6)
-#define DSYSR_TVM_SWITCH (1 << 6)
-#define DSYSR_TVM_TVSYNC (2 << 6)
-#define DSYSR_TVM_MASK (3 << 6)
-#define DSYSR_SCM_INT_NONE (0 << 4)
-#define DSYSR_SCM_INT_SYNC (2 << 4)
-#define DSYSR_SCM_INT_VIDEO (3 << 4)
-#define DSYSR_SCM_MASK (3 << 4)
-
-#define DSMR 0x00004
-#define DSMR_VSPM (1 << 28)
-#define DSMR_ODPM (1 << 27)
-#define DSMR_DIPM_DISP (0 << 25)
-#define DSMR_DIPM_CSYNC (1 << 25)
-#define DSMR_DIPM_DE (3 << 25)
-#define DSMR_DIPM_MASK (3 << 25)
-#define DSMR_CSPM (1 << 24)
-#define DSMR_DIL (1 << 19)
-#define DSMR_VSL (1 << 18)
-#define DSMR_HSL (1 << 17)
-#define DSMR_DDIS (1 << 16)
-#define DSMR_CDEL (1 << 15)
-#define DSMR_CDEM_CDE (0 << 13)
-#define DSMR_CDEM_LOW (2 << 13)
-#define DSMR_CDEM_HIGH (3 << 13)
-#define DSMR_CDEM_MASK (3 << 13)
-#define DSMR_CDED (1 << 12)
-#define DSMR_ODEV (1 << 8)
-#define DSMR_CSY_VH_OR (0 << 6)
-#define DSMR_CSY_333 (2 << 6)
-#define DSMR_CSY_222 (3 << 6)
-#define DSMR_CSY_MASK (3 << 6)
-
-#define DSSR 0x00008
-#define DSSR_VC1FB_DSA0 (0 << 30)
-#define DSSR_VC1FB_DSA1 (1 << 30)
-#define DSSR_VC1FB_DSA2 (2 << 30)
-#define DSSR_VC1FB_INIT (3 << 30)
-#define DSSR_VC1FB_MASK (3 << 30)
-#define DSSR_VC0FB_DSA0 (0 << 28)
-#define DSSR_VC0FB_DSA1 (1 << 28)
-#define DSSR_VC0FB_DSA2 (2 << 28)
-#define DSSR_VC0FB_INIT (3 << 28)
-#define DSSR_VC0FB_MASK (3 << 28)
-#define DSSR_DFB(n) (1 << ((n)+15))
-#define DSSR_TVR (1 << 15)
-#define DSSR_FRM (1 << 14)
-#define DSSR_VBK (1 << 11)
-#define DSSR_RINT (1 << 9)
-#define DSSR_HBK (1 << 8)
-#define DSSR_ADC(n) (1 << ((n)-1))
-
-#define DSRCR 0x0000c
-#define DSRCR_TVCL (1 << 15)
-#define DSRCR_FRCL (1 << 14)
-#define DSRCR_VBCL (1 << 11)
-#define DSRCR_RICL (1 << 9)
-#define DSRCR_HBCL (1 << 8)
-#define DSRCR_ADCL(n) (1 << ((n)-1))
-#define DSRCR_MASK 0x0000cbff
-
-#define DIER 0x00010
-#define DIER_TVE (1 << 15)
-#define DIER_FRE (1 << 14)
-#define DIER_VBE (1 << 11)
-#define DIER_RIE (1 << 9)
-#define DIER_HBE (1 << 8)
-#define DIER_ADCE(n) (1 << ((n)-1))
-
-#define CPCR 0x00014
-#define CPCR_CP4CE (1 << 19)
-#define CPCR_CP3CE (1 << 18)
-#define CPCR_CP2CE (1 << 17)
-#define CPCR_CP1CE (1 << 16)
-
-#define DPPR 0x00018
-#define DPPR_DPE(n) (1 << ((n)*4-1))
-#define DPPR_DPS(n, p) (((p)-1) << DPPR_DPS_SHIFT(n))
-#define DPPR_DPS_SHIFT(n) (((n)-1)*4)
-#define DPPR_BPP16 (DPPR_DPE(8) | DPPR_DPS(8, 1)) /* plane1 */
-#define DPPR_BPP32_P1 (DPPR_DPE(7) | DPPR_DPS(7, 1))
-#define DPPR_BPP32_P2 (DPPR_DPE(8) | DPPR_DPS(8, 2))
-#define DPPR_BPP32 (DPPR_BPP32_P1 | DPPR_BPP32_P2) /* plane1 & 2 */
-
-#define DEFR 0x00020
-#define DEFR_CODE (0x7773 << 16)
-#define DEFR_EXSL (1 << 12)
-#define DEFR_EXVL (1 << 11)
-#define DEFR_EXUP (1 << 5)
-#define DEFR_VCUP (1 << 4)
-#define DEFR_DEFE (1 << 0)
-
-#define DAPCR 0x00024
-#define DAPCR_CODE (0x7773 << 16)
-#define DAPCR_AP2E (1 << 4)
-#define DAPCR_AP1E (1 << 0)
-
-#define DCPCR 0x00028
-#define DCPCR_CODE (0x7773 << 16)
-#define DCPCR_CA2B (1 << 13)
-#define DCPCR_CD2F (1 << 12)
-#define DCPCR_DC2E (1 << 8)
-#define DCPCR_CAB (1 << 5)
-#define DCPCR_CDF (1 << 4)
-#define DCPCR_DCE (1 << 0)
-
-#define DEFR2 0x00034
-#define DEFR2_CODE (0x7775 << 16)
-#define DEFR2_DEFE2G (1 << 0)
-
-#define DEFR3 0x00038
-#define DEFR3_CODE (0x7776 << 16)
-#define DEFR3_EVDA (1 << 14)
-#define DEFR3_EVDM_1 (1 << 12)
-#define DEFR3_EVDM_2 (2 << 12)
-#define DEFR3_EVDM_3 (3 << 12)
-#define DEFR3_VMSM2_EMA (1 << 6)
-#define DEFR3_VMSM1_ENA (1 << 4)
-#define DEFR3_DEFE3 (1 << 0)
-
-#define DEFR4 0x0003c
-#define DEFR4_CODE (0x7777 << 16)
-#define DEFR4_LRUO (1 << 5)
-#define DEFR4_SPCE (1 << 4)
-
-#define DVCSR 0x000d0
-#define DVCSR_VCnFB2_DSA0(n) (0 << ((n)*2+16))
-#define DVCSR_VCnFB2_DSA1(n) (1 << ((n)*2+16))
-#define DVCSR_VCnFB2_DSA2(n) (2 << ((n)*2+16))
-#define DVCSR_VCnFB2_INIT(n) (3 << ((n)*2+16))
-#define DVCSR_VCnFB2_MASK(n) (3 << ((n)*2+16))
-#define DVCSR_VCnFB_DSA0(n) (0 << ((n)*2))
-#define DVCSR_VCnFB_DSA1(n) (1 << ((n)*2))
-#define DVCSR_VCnFB_DSA2(n) (2 << ((n)*2))
-#define DVCSR_VCnFB_INIT(n) (3 << ((n)*2))
-#define DVCSR_VCnFB_MASK(n) (3 << ((n)*2))
-
-#define DEFR5 0x000e0
-#define DEFR5_CODE (0x66 << 24)
-#define DEFR5_YCRGB2_DIS (0 << 14)
-#define DEFR5_YCRGB2_PRI1 (1 << 14)
-#define DEFR5_YCRGB2_PRI2 (2 << 14)
-#define DEFR5_YCRGB2_PRI3 (3 << 14)
-#define DEFR5_YCRGB2_MASK (3 << 14)
-#define DEFR5_YCRGB1_DIS (0 << 12)
-#define DEFR5_YCRGB1_PRI1 (1 << 12)
-#define DEFR5_YCRGB1_PRI2 (2 << 12)
-#define DEFR5_YCRGB1_PRI3 (3 << 12)
-#define DEFR5_YCRGB1_MASK (3 << 12)
-#define DEFR5_DEFE5 (1 << 0)
-
-#define DDLTR 0x000e4
-#define DDLTR_CODE (0x7766 << 16)
-#define DDLTR_DLAR2 (1 << 6)
-#define DDLTR_DLAY2 (1 << 5)
-#define DDLTR_DLAY1 (1 << 1)
-
-#define DEFR6 0x000e8
-#define DEFR6_CODE (0x7778 << 16)
-#define DEFR6_ODPM12_DSMR (0 << 10)
-#define DEFR6_ODPM12_DISP (2 << 10)
-#define DEFR6_ODPM12_CDE (3 << 10)
-#define DEFR6_ODPM12_MASK (3 << 10)
-#define DEFR6_ODPM02_DSMR (0 << 8)
-#define DEFR6_ODPM02_DISP (2 << 8)
-#define DEFR6_ODPM02_CDE (3 << 8)
-#define DEFR6_ODPM02_MASK (3 << 8)
-#define DEFR6_TCNE1 (1 << 6)
-#define DEFR6_TCNE0 (1 << 4)
-#define DEFR6_MLOS1 (1 << 2)
-#define DEFR6_DEFAULT (DEFR6_CODE | DEFR6_TCNE1)
-
-#define DEFR7 0x000ec
-#define DEFR7_CODE (0x7779 << 16)
-#define DEFR7_CMME1 BIT(6)
-#define DEFR7_CMME0 BIT(4)
-
-/* -----------------------------------------------------------------------------
- * R8A7790-only Control Registers
- */
-
-#define DD1SSR 0x20008
-#define DD1SSR_TVR (1 << 15)
-#define DD1SSR_FRM (1 << 14)
-#define DD1SSR_BUF (1 << 12)
-#define DD1SSR_VBK (1 << 11)
-#define DD1SSR_RINT (1 << 9)
-#define DD1SSR_HBK (1 << 8)
-#define DD1SSR_ADC(n) (1 << ((n)-1))
-
-#define DD1SRCR 0x2000c
-#define DD1SRCR_TVR (1 << 15)
-#define DD1SRCR_FRM (1 << 14)
-#define DD1SRCR_BUF (1 << 12)
-#define DD1SRCR_VBK (1 << 11)
-#define DD1SRCR_RINT (1 << 9)
-#define DD1SRCR_HBK (1 << 8)
-#define DD1SRCR_ADC(n) (1 << ((n)-1))
-
-#define DD1IER 0x20010
-#define DD1IER_TVR (1 << 15)
-#define DD1IER_FRM (1 << 14)
-#define DD1IER_BUF (1 << 12)
-#define DD1IER_VBK (1 << 11)
-#define DD1IER_RINT (1 << 9)
-#define DD1IER_HBK (1 << 8)
-#define DD1IER_ADC(n) (1 << ((n)-1))
-
-#define DEFR8 0x20020
-#define DEFR8_CODE (0x7790 << 16)
-#define DEFR8_VSCS (1 << 6)
-#define DEFR8_DRGBS_DU(n) ((n) << 4)
-#define DEFR8_DRGBS_MASK (3 << 4)
-#define DEFR8_DEFE8 (1 << 0)
-
-#define DOFLR 0x20024
-#define DOFLR_CODE (0x7790 << 16)
-#define DOFLR_HSYCFL1 (1 << 13)
-#define DOFLR_VSYCFL1 (1 << 12)
-#define DOFLR_ODDFL1 (1 << 11)
-#define DOFLR_DISPFL1 (1 << 10)
-#define DOFLR_CDEFL1 (1 << 9)
-#define DOFLR_RGBFL1 (1 << 8)
-#define DOFLR_HSYCFL0 (1 << 5)
-#define DOFLR_VSYCFL0 (1 << 4)
-#define DOFLR_ODDFL0 (1 << 3)
-#define DOFLR_DISPFL0 (1 << 2)
-#define DOFLR_CDEFL0 (1 << 1)
-#define DOFLR_RGBFL0 (1 << 0)
-
-#define DIDSR 0x20028
-#define DIDSR_CODE (0x7790 << 16)
-#define DIDSR_LDCS_DCLKIN(n) (0 << (8 + (n) * 2))
-#define DIDSR_LDCS_DSI(n) (2 << (8 + (n) * 2)) /* V3U only */
-#define DIDSR_LDCS_LVDS0(n) (2 << (8 + (n) * 2))
-#define DIDSR_LDCS_LVDS1(n) (3 << (8 + (n) * 2))
-#define DIDSR_LDCS_MASK(n) (3 << (8 + (n) * 2))
-#define DIDSR_PDCS_CLK(n, clk) (clk << ((n) * 2))
-#define DIDSR_PDCS_MASK(n) (3 << ((n) * 2))
-
-#define DEFR10 0x20038
-#define DEFR10_CODE (0x7795 << 16)
-#define DEFR10_VSPF1_RGB (0 << 14)
-#define DEFR10_VSPF1_YC (1 << 14)
-#define DEFR10_DOCF1_RGB (0 << 12)
-#define DEFR10_DOCF1_YC (1 << 12)
-#define DEFR10_YCDF0_YCBCR444 (0 << 11)
-#define DEFR10_YCDF0_YCBCR422 (1 << 11)
-#define DEFR10_VSPF0_RGB (0 << 10)
-#define DEFR10_VSPF0_YC (1 << 10)
-#define DEFR10_DOCF0_RGB (0 << 8)
-#define DEFR10_DOCF0_YC (1 << 8)
-#define DEFR10_TSEL_H3_TCON1 (0 << 1) /* DEFR102 register only (DU2/DU3) */
-#define DEFR10_DEFE10 (1 << 0)
-
-#define DPLLCR 0x20044
-#define DPLLCR_CODE (0x95 << 24)
-#define DPLLCR_PLCS1 (1 << 23)
-#define DPLLCR_PLCS0 (1 << 21)
-#define DPLLCR_CLKE (1 << 18)
-#define DPLLCR_FDPLL(n) ((n) << 12)
-#define DPLLCR_N(n) ((n) << 5)
-#define DPLLCR_M(n) ((n) << 3)
-#define DPLLCR_STBY (1 << 2)
-#define DPLLCR_INCS_DOTCLKIN0 (0 << 0)
-#define DPLLCR_INCS_DOTCLKIN1 (1 << 1)
-
-#define DPLLC2R 0x20048
-#define DPLLC2R_CODE (0x95 << 24)
-#define DPLLC2R_SELC (1 << 12)
-#define DPLLC2R_M(n) ((n) << 8)
-#define DPLLC2R_FDPLL(n) ((n) << 0)
-
-/* -----------------------------------------------------------------------------
- * Display Timing Generation Registers
- */
-
-#define HDSR 0x00040
-#define HDER 0x00044
-#define VDSR 0x00048
-#define VDER 0x0004c
-#define HCR 0x00050
-#define HSWR 0x00054
-#define VCR 0x00058
-#define VSPR 0x0005c
-#define EQWR 0x00060
-#define SPWR 0x00064
-#define CLAMPSR 0x00070
-#define CLAMPWR 0x00074
-#define DESR 0x00078
-#define DEWR 0x0007c
-
-/* -----------------------------------------------------------------------------
- * Display Attribute Registers
- */
-
-#define CP1TR 0x00080
-#define CP2TR 0x00084
-#define CP3TR 0x00088
-#define CP4TR 0x0008c
-
-#define DOOR 0x00090
-#define DOOR_RGB(r, g, b) (((r) << 18) | ((g) << 10) | ((b) << 2))
-#define CDER 0x00094
-#define CDER_RGB(r, g, b) (((r) << 18) | ((g) << 10) | ((b) << 2))
-#define BPOR 0x00098
-#define BPOR_RGB(r, g, b) (((r) << 18) | ((g) << 10) | ((b) << 2))
-
-#define RINTOFSR 0x0009c
-
-#define DSHPR 0x000c8
-#define DSHPR_CODE (0x7776 << 16)
-#define DSHPR_PRIH (0xa << 4)
-#define DSHPR_PRIL_BPP16 (0x8 << 0)
-#define DSHPR_PRIL_BPP32 (0x9 << 0)
-
-/* -----------------------------------------------------------------------------
- * Display Plane Registers
- */
-
-#define PLANE_OFF 0x00100
-
-#define PnMR 0x00100 /* plane 1 */
-#define PnMR_VISL_VIN0 (0 << 26) /* use Video Input 0 */
-#define PnMR_VISL_VIN1 (1 << 26) /* use Video Input 1 */
-#define PnMR_VISL_VIN2 (2 << 26) /* use Video Input 2 */
-#define PnMR_VISL_VIN3 (3 << 26) /* use Video Input 3 */
-#define PnMR_YCDF_YUYV (1 << 20) /* YUYV format */
-#define PnMR_TC_R (0 << 17) /* Tranparent color is PnTC1R */
-#define PnMR_TC_CP (1 << 17) /* Tranparent color is color palette */
-#define PnMR_WAE (1 << 16) /* Wrap around Enable */
-#define PnMR_SPIM_TP (0 << 12) /* Transparent Color */
-#define PnMR_SPIM_ALP (1 << 12) /* Alpha Blending */
-#define PnMR_SPIM_EOR (2 << 12) /* EOR */
-#define PnMR_SPIM_TP_OFF (1 << 14) /* No Transparent Color */
-#define PnMR_CPSL_CP1 (0 << 8) /* Color Palette selected 1 */
-#define PnMR_CPSL_CP2 (1 << 8) /* Color Palette selected 2 */
-#define PnMR_CPSL_CP3 (2 << 8) /* Color Palette selected 3 */
-#define PnMR_CPSL_CP4 (3 << 8) /* Color Palette selected 4 */
-#define PnMR_DC (1 << 7) /* Display Area Change */
-#define PnMR_BM_MD (0 << 4) /* Manual Display Change Mode */
-#define PnMR_BM_AR (1 << 4) /* Auto Rendering Mode */
-#define PnMR_BM_AD (2 << 4) /* Auto Display Change Mode */
-#define PnMR_BM_VC (3 << 4) /* Video Capture Mode */
-#define PnMR_DDDF_8BPP (0 << 0) /* 8bit */
-#define PnMR_DDDF_16BPP (1 << 0) /* 16bit or 32bit */
-#define PnMR_DDDF_ARGB (2 << 0) /* ARGB */
-#define PnMR_DDDF_YC (3 << 0) /* YC */
-#define PnMR_DDDF_MASK (3 << 0)
-
-#define PnMWR 0x00104
-
-#define PnALPHAR 0x00108
-#define PnALPHAR_ABIT_1 (0 << 12)
-#define PnALPHAR_ABIT_0 (1 << 12)
-#define PnALPHAR_ABIT_X (2 << 12)
-
-#define PnDSXR 0x00110
-#define PnDSYR 0x00114
-#define PnDPXR 0x00118
-#define PnDPYR 0x0011c
-
-#define PnDSA0R 0x00120
-#define PnDSA1R 0x00124
-#define PnDSA2R 0x00128
-#define PnDSA_MASK 0xfffffff0
-
-#define PnSPXR 0x00130
-#define PnSPYR 0x00134
-#define PnWASPR 0x00138
-#define PnWAMWR 0x0013c
-
-#define PnBTR 0x00140
-
-#define PnTC1R 0x00144
-#define PnTC2R 0x00148
-#define PnTC3R 0x0014c
-#define PnTC3R_CODE (0x66 << 24)
-
-#define PnMLR 0x00150
-
-#define PnSWAPR 0x00180
-#define PnSWAPR_DIGN (1 << 4)
-#define PnSWAPR_SPQW (1 << 3)
-#define PnSWAPR_SPLW (1 << 2)
-#define PnSWAPR_SPWD (1 << 1)
-#define PnSWAPR_SPBY (1 << 0)
-
-#define PnDDCR 0x00184
-#define PnDDCR_CODE (0x7775 << 16)
-#define PnDDCR_LRGB1 (1 << 11)
-#define PnDDCR_LRGB0 (1 << 10)
-
-#define PnDDCR2 0x00188
-#define PnDDCR2_CODE (0x7776 << 16)
-#define PnDDCR2_NV21 (1 << 5)
-#define PnDDCR2_Y420 (1 << 4)
-#define PnDDCR2_DIVU (1 << 1)
-#define PnDDCR2_DIVY (1 << 0)
-
-#define PnDDCR4 0x00190
-#define PnDDCR4_CODE (0x7766 << 16)
-#define PnDDCR4_VSPS (1 << 13)
-#define PnDDCR4_SDFS_RGB (0 << 4)
-#define PnDDCR4_SDFS_YC (5 << 4)
-#define PnDDCR4_SDFS_MASK (7 << 4)
-#define PnDDCR4_EDF_NONE (0 << 0)
-#define PnDDCR4_EDF_ARGB8888 (1 << 0)
-#define PnDDCR4_EDF_RGB888 (2 << 0)
-#define PnDDCR4_EDF_RGB666 (3 << 0)
-#define PnDDCR4_EDF_MASK (7 << 0)
-
-#define APnMR 0x0a100
-#define APnMR_WAE (1 << 16) /* Wrap around Enable */
-#define APnMR_DC (1 << 7) /* Display Area Change */
-#define APnMR_BM_MD (0 << 4) /* Manual Display Change Mode */
-#define APnMR_BM_AD (2 << 4) /* Auto Display Change Mode */
-
-#define APnMWR 0x0a104
-
-#define APnDSXR 0x0a110
-#define APnDSYR 0x0a114
-#define APnDPXR 0x0a118
-#define APnDPYR 0x0a11c
-
-#define APnDSA0R 0x0a120
-#define APnDSA1R 0x0a124
-#define APnDSA2R 0x0a128
-
-#define APnSPXR 0x0a130
-#define APnSPYR 0x0a134
-#define APnWASPR 0x0a138
-#define APnWAMWR 0x0a13c
-
-#define APnBTR 0x0a140
-
-#define APnMLR 0x0a150
-#define APnSWAPR 0x0a180
-
-/* -----------------------------------------------------------------------------
- * Display Capture Registers
- */
-
-#define DCMR 0x0c100
-#define DCMWR 0x0c104
-#define DCSAR 0x0c120
-#define DCMLR 0x0c150
-
-/* -----------------------------------------------------------------------------
- * Color Palette Registers
- */
-
-#define CP1_000R 0x01000
-#define CP1_255R 0x013fc
-#define CP2_000R 0x02000
-#define CP2_255R 0x023fc
-#define CP3_000R 0x03000
-#define CP3_255R 0x033fc
-#define CP4_000R 0x04000
-#define CP4_255R 0x043fc
-
-/* -----------------------------------------------------------------------------
- * External Synchronization Control Registers
- */
-
-#define ESCR02 0x10000
-#define ESCR13 0x01000
-#define ESCR_DCLKOINV (1 << 25)
-#define ESCR_DCLKSEL_DCLKIN (0 << 20)
-#define ESCR_DCLKSEL_CLKS (1 << 20)
-#define ESCR_DCLKSEL_MASK (1 << 20)
-#define ESCR_DCLKDIS (1 << 16)
-#define ESCR_SYNCSEL_OFF (0 << 8)
-#define ESCR_SYNCSEL_EXVSYNC (2 << 8)
-#define ESCR_SYNCSEL_EXHSYNC (3 << 8)
-#define ESCR_FRQSEL_MASK (0x3f << 0)
-
-#define OTAR02 0x10004
-#define OTAR13 0x01004
-
-/* -----------------------------------------------------------------------------
- * Dual Display Output Control Registers
- */
-
-#define DORCR 0x11000
-#define DORCR_PG1T (1 << 30)
-#define DORCR_DK1S (1 << 28)
-#define DORCR_PG1D_DS0 (0 << 24)
-#define DORCR_PG1D_DS1 (1 << 24)
-#define DORCR_PG1D_FIX0 (2 << 24)
-#define DORCR_PG1D_DOOR (3 << 24)
-#define DORCR_PG1D_MASK (3 << 24)
-#define DORCR_DR0D (1 << 21)
-#define DORCR_PG0D_DS0 (0 << 16)
-#define DORCR_PG0D_DS1 (1 << 16)
-#define DORCR_PG0D_FIX0 (2 << 16)
-#define DORCR_PG0D_DOOR (3 << 16)
-#define DORCR_PG0D_MASK (3 << 16)
-#define DORCR_RGPV (1 << 4)
-#define DORCR_DPRS (1 << 0)
-
-#define DPTSR 0x11004
-#define DPTSR_PnDK(n) (1 << ((n) + 16))
-#define DPTSR_PnTS(n) (1 << (n))
-
-#define DAPTSR 0x11008
-#define DAPTSR_APnDK(n) (1 << ((n) + 16))
-#define DAPTSR_APnTS(n) (1 << (n))
-
-#define DS1PR 0x11020
-#define DS2PR 0x11024
-
-/* -----------------------------------------------------------------------------
- * YC-RGB Conversion Coefficient Registers
- */
-
-#define YNCR 0x11080
-#define YNOR 0x11084
-#define CRNOR 0x11088
-#define CBNOR 0x1108c
-#define RCRCR 0x11090
-#define GCRCR 0x11094
-#define GCBCR 0x11098
-#define BCBCR 0x1109c
-
-#endif /* __RCAR_DU_REGS_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
deleted file mode 100644
index 45c05d0ffc70..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ /dev/null
@@ -1,513 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * R-Car Display Unit VSP-Based Compositor
- *
- * Copyright (C) 2015 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-#include <drm/drm_atomic.h>
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_blend.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_fb_dma_helper.h>
-#include <drm/drm_fourcc.h>
-#include <drm/drm_framebuffer.h>
-#include <drm/drm_gem_atomic_helper.h>
-#include <drm/drm_gem_dma_helper.h>
-#include <drm/drm_managed.h>
-#include <drm/drm_vblank.h>
-
-#include <linux/bitops.h>
-#include <linux/dma-mapping.h>
-#include <linux/of_platform.h>
-#include <linux/scatterlist.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-
-#include <media/vsp1.h>
-
-#include "rcar_du_drv.h"
-#include "rcar_du_kms.h"
-#include "rcar_du_vsp.h"
-#include "rcar_du_writeback.h"
-
-static void rcar_du_vsp_complete(void *private, unsigned int status, u32 crc)
-{
- struct rcar_du_crtc *crtc = private;
-
- if (crtc->vblank_enable)
- drm_crtc_handle_vblank(&crtc->crtc);
-
- if (status & VSP1_DU_STATUS_COMPLETE)
- rcar_du_crtc_finish_page_flip(crtc);
- if (status & VSP1_DU_STATUS_WRITEBACK)
- rcar_du_writeback_complete(crtc);
-
- drm_crtc_add_crc_entry(&crtc->crtc, false, 0, &crc);
-}
-
-void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
-{
- const struct drm_display_mode *mode = &crtc->crtc.state->adjusted_mode;
- struct rcar_du_device *rcdu = crtc->dev;
- struct vsp1_du_lif_config cfg = {
- .width = mode->hdisplay,
- .height = mode->vdisplay,
- .interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE,
- .callback = rcar_du_vsp_complete,
- .callback_data = crtc,
- };
- struct rcar_du_plane_state state = {
- .state = {
- .alpha = DRM_BLEND_ALPHA_OPAQUE,
- .crtc = &crtc->crtc,
- .dst.x1 = 0,
- .dst.y1 = 0,
- .dst.x2 = mode->hdisplay,
- .dst.y2 = mode->vdisplay,
- .src.x1 = 0,
- .src.y1 = 0,
- .src.x2 = mode->hdisplay << 16,
- .src.y2 = mode->vdisplay << 16,
- .zpos = 0,
- },
- .format = rcar_du_format_info(DRM_FORMAT_XRGB8888),
- .source = RCAR_DU_PLANE_VSPD1,
- .colorkey = 0,
- };
-
- if (rcdu->info->gen >= 3)
- state.hwindex = (crtc->index % 2) ? 2 : 0;
- else
- state.hwindex = crtc->index % 2;
-
- __rcar_du_plane_setup(crtc->group, &state);
-
- vsp1_du_setup_lif(crtc->vsp->vsp, crtc->vsp_pipe, &cfg);
-}
-
-void rcar_du_vsp_disable(struct rcar_du_crtc *crtc)
-{
- vsp1_du_setup_lif(crtc->vsp->vsp, crtc->vsp_pipe, NULL);
-}
-
-void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc)
-{
- vsp1_du_atomic_begin(crtc->vsp->vsp, crtc->vsp_pipe);
-}
-
-void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc)
-{
- struct vsp1_du_atomic_pipe_config cfg = { { 0, } };
- struct rcar_du_crtc_state *state;
-
- state = to_rcar_crtc_state(crtc->crtc.state);
- cfg.crc = state->crc;
-
- rcar_du_writeback_setup(crtc, &cfg.writeback);
-
- vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe, &cfg);
-}
-
-static const u32 rcar_du_vsp_formats[] = {
- DRM_FORMAT_RGB332,
- DRM_FORMAT_ARGB4444,
- DRM_FORMAT_XRGB4444,
- DRM_FORMAT_ARGB1555,
- DRM_FORMAT_XRGB1555,
- DRM_FORMAT_RGB565,
- DRM_FORMAT_BGR888,
- DRM_FORMAT_RGB888,
- DRM_FORMAT_BGRA8888,
- DRM_FORMAT_BGRX8888,
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_XRGB8888,
- DRM_FORMAT_UYVY,
- DRM_FORMAT_YUYV,
- DRM_FORMAT_YVYU,
- DRM_FORMAT_NV12,
- DRM_FORMAT_NV21,
- DRM_FORMAT_NV16,
- DRM_FORMAT_NV61,
- DRM_FORMAT_YUV420,
- DRM_FORMAT_YVU420,
- DRM_FORMAT_YUV422,
- DRM_FORMAT_YVU422,
- DRM_FORMAT_YUV444,
- DRM_FORMAT_YVU444,
-};
-
-/*
- * Gen4 supports the same formats as above, and additionally 2-10-10-10 RGB
- * formats and Y210 & Y212 formats.
- */
-static const u32 rcar_du_vsp_formats_gen4[] = {
- DRM_FORMAT_RGB332,
- DRM_FORMAT_ARGB4444,
- DRM_FORMAT_XRGB4444,
- DRM_FORMAT_ARGB1555,
- DRM_FORMAT_XRGB1555,
- DRM_FORMAT_RGB565,
- DRM_FORMAT_BGR888,
- DRM_FORMAT_RGB888,
- DRM_FORMAT_BGRA8888,
- DRM_FORMAT_BGRX8888,
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGBX1010102,
- DRM_FORMAT_RGBA1010102,
- DRM_FORMAT_ARGB2101010,
- DRM_FORMAT_UYVY,
- DRM_FORMAT_YUYV,
- DRM_FORMAT_YVYU,
- DRM_FORMAT_NV12,
- DRM_FORMAT_NV21,
- DRM_FORMAT_NV16,
- DRM_FORMAT_NV61,
- DRM_FORMAT_YUV420,
- DRM_FORMAT_YVU420,
- DRM_FORMAT_YUV422,
- DRM_FORMAT_YVU422,
- DRM_FORMAT_YUV444,
- DRM_FORMAT_YVU444,
- DRM_FORMAT_Y210,
- DRM_FORMAT_Y212,
-};
-
-static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
-{
- struct rcar_du_vsp_plane_state *state =
- to_rcar_vsp_plane_state(plane->plane.state);
- struct rcar_du_crtc *crtc = to_rcar_crtc(state->state.crtc);
- struct drm_framebuffer *fb = plane->plane.state->fb;
- const struct rcar_du_format_info *format;
- struct vsp1_du_atomic_config cfg = {
- .pixelformat = 0,
- .pitch = fb->pitches[0],
- .alpha = state->state.alpha >> 8,
- .zpos = state->state.zpos,
- };
- u32 fourcc = state->format->fourcc;
- unsigned int i;
-
- cfg.src.left = state->state.src.x1 >> 16;
- cfg.src.top = state->state.src.y1 >> 16;
- cfg.src.width = drm_rect_width(&state->state.src) >> 16;
- cfg.src.height = drm_rect_height(&state->state.src) >> 16;
-
- cfg.dst.left = state->state.dst.x1;
- cfg.dst.top = state->state.dst.y1;
- cfg.dst.width = drm_rect_width(&state->state.dst);
- cfg.dst.height = drm_rect_height(&state->state.dst);
-
- for (i = 0; i < state->format->planes; ++i)
- cfg.mem[i] = sg_dma_address(state->sg_tables[i].sgl)
- + fb->offsets[i];
-
- if (state->state.pixel_blend_mode == DRM_MODE_BLEND_PIXEL_NONE) {
- switch (fourcc) {
- case DRM_FORMAT_ARGB1555:
- fourcc = DRM_FORMAT_XRGB1555;
- break;
-
- case DRM_FORMAT_ARGB4444:
- fourcc = DRM_FORMAT_XRGB4444;
- break;
-
- case DRM_FORMAT_ARGB8888:
- fourcc = DRM_FORMAT_XRGB8888;
- break;
- }
- }
-
- format = rcar_du_format_info(fourcc);
- cfg.pixelformat = format->v4l2;
-
- cfg.premult = state->state.pixel_blend_mode == DRM_MODE_BLEND_PREMULTI;
-
- vsp1_du_atomic_update(plane->vsp->vsp, crtc->vsp_pipe,
- plane->index, &cfg);
-}
-
-int rcar_du_vsp_map_fb(struct rcar_du_vsp *vsp, struct drm_framebuffer *fb,
- struct sg_table sg_tables[3])
-{
- struct rcar_du_device *rcdu = vsp->dev;
- unsigned int i, j;
- int ret;
-
- for (i = 0; i < fb->format->num_planes; ++i) {
- struct drm_gem_dma_object *gem = drm_fb_dma_get_gem_obj(fb, i);
- struct sg_table *sgt = &sg_tables[i];
-
- if (gem->sgt) {
- struct scatterlist *src;
- struct scatterlist *dst;
-
- /*
- * If the GEM buffer has a scatter gather table, it has
- * been imported from a dma-buf and has no physical
- * address as it might not be physically contiguous.
- * Copy the original scatter gather table to map it to
- * the VSP.
- */
- ret = sg_alloc_table(sgt, gem->sgt->orig_nents,
- GFP_KERNEL);
- if (ret)
- goto fail;
-
- src = gem->sgt->sgl;
- dst = sgt->sgl;
- for (j = 0; j < gem->sgt->orig_nents; ++j) {
- sg_set_page(dst, sg_page(src), src->length,
- src->offset);
- src = sg_next(src);
- dst = sg_next(dst);
- }
- } else {
- ret = dma_get_sgtable(rcdu->dev, sgt, gem->vaddr,
- gem->dma_addr, gem->base.size);
- if (ret)
- goto fail;
- }
-
- ret = vsp1_du_map_sg(vsp->vsp, sgt);
- if (ret) {
- sg_free_table(sgt);
- goto fail;
- }
- }
-
- return 0;
-
-fail:
- while (i--) {
- struct sg_table *sgt = &sg_tables[i];
-
- vsp1_du_unmap_sg(vsp->vsp, sgt);
- sg_free_table(sgt);
- }
-
- return ret;
-}
-
-static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
- struct drm_plane_state *state)
-{
- struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state);
- struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp;
- int ret;
-
- /*
- * There's no need to prepare (and unprepare) the framebuffer when the
- * plane is not visible, as it will not be displayed.
- */
- if (!state->visible)
- return 0;
-
- ret = rcar_du_vsp_map_fb(vsp, state->fb, rstate->sg_tables);
- if (ret < 0)
- return ret;
-
- return drm_gem_plane_helper_prepare_fb(plane, state);
-}
-
-void rcar_du_vsp_unmap_fb(struct rcar_du_vsp *vsp, struct drm_framebuffer *fb,
- struct sg_table sg_tables[3])
-{
- unsigned int i;
-
- for (i = 0; i < fb->format->num_planes; ++i) {
- struct sg_table *sgt = &sg_tables[i];
-
- vsp1_du_unmap_sg(vsp->vsp, sgt);
- sg_free_table(sgt);
- }
-}
-
-static void rcar_du_vsp_plane_cleanup_fb(struct drm_plane *plane,
- struct drm_plane_state *state)
-{
- struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state);
- struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp;
-
- if (!state->visible)
- return;
-
- rcar_du_vsp_unmap_fb(vsp, state->fb, rstate->sg_tables);
-}
-
-static int rcar_du_vsp_plane_atomic_check(struct drm_plane *plane,
- struct drm_atomic_state *state)
-{
- struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
- plane);
- struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(new_plane_state);
-
- return __rcar_du_plane_atomic_check(plane, new_plane_state,
- &rstate->format);
-}
-
-static void rcar_du_vsp_plane_atomic_update(struct drm_plane *plane,
- struct drm_atomic_state *state)
-{
- struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, plane);
- struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane);
- struct rcar_du_vsp_plane *rplane = to_rcar_vsp_plane(plane);
- struct rcar_du_crtc *crtc = to_rcar_crtc(old_state->crtc);
-
- if (new_state->visible)
- rcar_du_vsp_plane_setup(rplane);
- else if (old_state->crtc)
- vsp1_du_atomic_update(rplane->vsp->vsp, crtc->vsp_pipe,
- rplane->index, NULL);
-}
-
-static const struct drm_plane_helper_funcs rcar_du_vsp_plane_helper_funcs = {
- .prepare_fb = rcar_du_vsp_plane_prepare_fb,
- .cleanup_fb = rcar_du_vsp_plane_cleanup_fb,
- .atomic_check = rcar_du_vsp_plane_atomic_check,
- .atomic_update = rcar_du_vsp_plane_atomic_update,
-};
-
-static struct drm_plane_state *
-rcar_du_vsp_plane_atomic_duplicate_state(struct drm_plane *plane)
-{
- struct rcar_du_vsp_plane_state *copy;
-
- if (WARN_ON(!plane->state))
- return NULL;
-
- copy = kzalloc(sizeof(*copy), GFP_KERNEL);
- if (copy == NULL)
- return NULL;
-
- __drm_atomic_helper_plane_duplicate_state(plane, &copy->state);
-
- return &copy->state;
-}
-
-static void rcar_du_vsp_plane_atomic_destroy_state(struct drm_plane *plane,
- struct drm_plane_state *state)
-{
- __drm_atomic_helper_plane_destroy_state(state);
- kfree(to_rcar_vsp_plane_state(state));
-}
-
-static void rcar_du_vsp_plane_reset(struct drm_plane *plane)
-{
- struct rcar_du_vsp_plane_state *state;
-
- if (plane->state) {
- rcar_du_vsp_plane_atomic_destroy_state(plane, plane->state);
- plane->state = NULL;
- }
-
- state = kzalloc(sizeof(*state), GFP_KERNEL);
- if (state == NULL)
- return;
-
- __drm_atomic_helper_plane_reset(plane, &state->state);
-}
-
-static const struct drm_plane_funcs rcar_du_vsp_plane_funcs = {
- .update_plane = drm_atomic_helper_update_plane,
- .disable_plane = drm_atomic_helper_disable_plane,
- .reset = rcar_du_vsp_plane_reset,
- .destroy = drm_plane_cleanup,
- .atomic_duplicate_state = rcar_du_vsp_plane_atomic_duplicate_state,
- .atomic_destroy_state = rcar_du_vsp_plane_atomic_destroy_state,
-};
-
-static void rcar_du_vsp_cleanup(struct drm_device *dev, void *res)
-{
- struct rcar_du_vsp *vsp = res;
- unsigned int i;
-
- for (i = 0; i < vsp->num_planes; ++i) {
- struct rcar_du_vsp_plane *plane = &vsp->planes[i];
-
- drm_plane_cleanup(&plane->plane);
- }
-
- kfree(vsp->planes);
-
- put_device(vsp->vsp);
-}
-
-int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
- unsigned int crtcs)
-{
- struct rcar_du_device *rcdu = vsp->dev;
- struct platform_device *pdev;
- unsigned int num_crtcs = hweight32(crtcs);
- unsigned int num_planes;
- unsigned int i;
- int ret;
-
- /* Find the VSP device and initialize it. */
- pdev = of_find_device_by_node(np);
- if (!pdev)
- return -ENXIO;
-
- vsp->vsp = &pdev->dev;
-
- ret = drmm_add_action_or_reset(&rcdu->ddev, rcar_du_vsp_cleanup, vsp);
- if (ret < 0)
- return ret;
-
- ret = vsp1_du_init(vsp->vsp);
- if (ret < 0)
- return ret;
-
- num_planes = rcdu->info->num_rpf;
-
- vsp->planes = kcalloc(num_planes, sizeof(*vsp->planes), GFP_KERNEL);
- if (!vsp->planes)
- return -ENOMEM;
-
- for (i = 0; i < num_planes; ++i) {
- enum drm_plane_type type = i < num_crtcs
- ? DRM_PLANE_TYPE_PRIMARY
- : DRM_PLANE_TYPE_OVERLAY;
- struct rcar_du_vsp_plane *plane = &vsp->planes[i];
- unsigned int num_formats;
- const u32 *formats;
-
- if (rcdu->info->gen < 4) {
- num_formats = ARRAY_SIZE(rcar_du_vsp_formats);
- formats = rcar_du_vsp_formats;
- } else {
- num_formats = ARRAY_SIZE(rcar_du_vsp_formats_gen4);
- formats = rcar_du_vsp_formats_gen4;
- }
-
- plane->vsp = vsp;
- plane->index = i;
-
- ret = drm_universal_plane_init(&rcdu->ddev, &plane->plane,
- crtcs, &rcar_du_vsp_plane_funcs,
- formats, num_formats,
- NULL, type, NULL);
- if (ret < 0)
- return ret;
-
- drm_plane_helper_add(&plane->plane,
- &rcar_du_vsp_plane_helper_funcs);
-
- drm_plane_create_alpha_property(&plane->plane);
- drm_plane_create_zpos_property(&plane->plane, i, 0,
- num_planes - 1);
-
- drm_plane_create_blend_mode_property(&plane->plane,
- BIT(DRM_MODE_BLEND_PIXEL_NONE) |
- BIT(DRM_MODE_BLEND_PREMULTI) |
- BIT(DRM_MODE_BLEND_COVERAGE));
-
- vsp->num_planes++;
- }
-
- return 0;
-}
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
deleted file mode 100644
index 67630f0b6599..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * R-Car Display Unit VSP-Based Compositor
- *
- * Copyright (C) 2015 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-#ifndef __RCAR_DU_VSP_H__
-#define __RCAR_DU_VSP_H__
-
-#include <drm/drm_plane.h>
-
-struct drm_framebuffer;
-struct rcar_du_format_info;
-struct rcar_du_vsp;
-struct sg_table;
-
-struct rcar_du_vsp_plane {
- struct drm_plane plane;
- struct rcar_du_vsp *vsp;
- unsigned int index;
-};
-
-struct rcar_du_vsp {
- unsigned int index;
- struct device *vsp;
- struct rcar_du_device *dev;
- struct rcar_du_vsp_plane *planes;
- unsigned int num_planes;
-};
-
-static inline struct rcar_du_vsp_plane *to_rcar_vsp_plane(struct drm_plane *p)
-{
- return container_of(p, struct rcar_du_vsp_plane, plane);
-}
-
-/**
- * struct rcar_du_vsp_plane_state - Driver-specific plane state
- * @state: base DRM plane state
- * @format: information about the pixel format used by the plane
- * @sg_tables: scatter-gather tables for the frame buffer memory
- */
-struct rcar_du_vsp_plane_state {
- struct drm_plane_state state;
-
- const struct rcar_du_format_info *format;
- struct sg_table sg_tables[3];
-};
-
-static inline struct rcar_du_vsp_plane_state *
-to_rcar_vsp_plane_state(struct drm_plane_state *state)
-{
- return container_of(state, struct rcar_du_vsp_plane_state, state);
-}
-
-#ifdef CONFIG_DRM_RCAR_VSP
-int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
- unsigned int crtcs);
-void rcar_du_vsp_enable(struct rcar_du_crtc *crtc);
-void rcar_du_vsp_disable(struct rcar_du_crtc *crtc);
-void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc);
-void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc);
-int rcar_du_vsp_map_fb(struct rcar_du_vsp *vsp, struct drm_framebuffer *fb,
- struct sg_table sg_tables[3]);
-void rcar_du_vsp_unmap_fb(struct rcar_du_vsp *vsp, struct drm_framebuffer *fb,
- struct sg_table sg_tables[3]);
-#else
-static inline int rcar_du_vsp_init(struct rcar_du_vsp *vsp,
- struct device_node *np,
- unsigned int crtcs)
-{
- return -ENXIO;
-}
-static inline void rcar_du_vsp_enable(struct rcar_du_crtc *crtc) { };
-static inline void rcar_du_vsp_disable(struct rcar_du_crtc *crtc) { };
-static inline void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc) { };
-static inline void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc) { };
-static inline int rcar_du_vsp_map_fb(struct rcar_du_vsp *vsp,
- struct drm_framebuffer *fb,
- struct sg_table sg_tables[3])
-{
- return -ENXIO;
-}
-static inline void rcar_du_vsp_unmap_fb(struct rcar_du_vsp *vsp,
- struct drm_framebuffer *fb,
- struct sg_table sg_tables[3])
-{
-}
-#endif
-
-#endif /* __RCAR_DU_VSP_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_writeback.c b/drivers/gpu/drm/rcar-du/rcar_du_writeback.c
deleted file mode 100644
index 8cd37d7b8ae2..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_writeback.c
+++ /dev/null
@@ -1,246 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * R-Car Display Unit Writeback Support
- *
- * Copyright (C) 2019 Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- */
-
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_device.h>
-#include <drm/drm_edid.h>
-#include <drm/drm_fourcc.h>
-#include <drm/drm_framebuffer.h>
-#include <drm/drm_probe_helper.h>
-#include <drm/drm_writeback.h>
-
-#include "rcar_du_crtc.h"
-#include "rcar_du_drv.h"
-#include "rcar_du_kms.h"
-#include "rcar_du_writeback.h"
-
-/**
- * struct rcar_du_wb_conn_state - Driver-specific writeback connector state
- * @state: base DRM connector state
- * @format: format of the writeback framebuffer
- */
-struct rcar_du_wb_conn_state {
- struct drm_connector_state state;
- const struct rcar_du_format_info *format;
-};
-
-#define to_rcar_wb_conn_state(s) \
- container_of(s, struct rcar_du_wb_conn_state, state)
-
-/**
- * struct rcar_du_wb_job - Driver-private data for writeback jobs
- * @sg_tables: scatter-gather tables for the framebuffer memory
- */
-struct rcar_du_wb_job {
- struct sg_table sg_tables[3];
-};
-
-static int rcar_du_wb_conn_get_modes(struct drm_connector *connector)
-{
- struct drm_device *dev = connector->dev;
-
- return drm_add_modes_noedid(connector, dev->mode_config.max_width,
- dev->mode_config.max_height);
-}
-
-static int rcar_du_wb_prepare_job(struct drm_writeback_connector *connector,
- struct drm_writeback_job *job)
-{
- struct rcar_du_crtc *rcrtc = wb_to_rcar_crtc(connector);
- struct rcar_du_wb_job *rjob;
- int ret;
-
- if (!job->fb)
- return 0;
-
- rjob = kzalloc(sizeof(*rjob), GFP_KERNEL);
- if (!rjob)
- return -ENOMEM;
-
- /* Map the framebuffer to the VSP. */
- ret = rcar_du_vsp_map_fb(rcrtc->vsp, job->fb, rjob->sg_tables);
- if (ret < 0) {
- kfree(rjob);
- return ret;
- }
-
- job->priv = rjob;
- return 0;
-}
-
-static void rcar_du_wb_cleanup_job(struct drm_writeback_connector *connector,
- struct drm_writeback_job *job)
-{
- struct rcar_du_crtc *rcrtc = wb_to_rcar_crtc(connector);
- struct rcar_du_wb_job *rjob = job->priv;
-
- if (!job->fb)
- return;
-
- rcar_du_vsp_unmap_fb(rcrtc->vsp, job->fb, rjob->sg_tables);
- kfree(rjob);
-}
-
-static const struct drm_connector_helper_funcs rcar_du_wb_conn_helper_funcs = {
- .get_modes = rcar_du_wb_conn_get_modes,
- .prepare_writeback_job = rcar_du_wb_prepare_job,
- .cleanup_writeback_job = rcar_du_wb_cleanup_job,
-};
-
-static struct drm_connector_state *
-rcar_du_wb_conn_duplicate_state(struct drm_connector *connector)
-{
- struct rcar_du_wb_conn_state *copy;
-
- if (WARN_ON(!connector->state))
- return NULL;
-
- copy = kzalloc(sizeof(*copy), GFP_KERNEL);
- if (!copy)
- return NULL;
-
- __drm_atomic_helper_connector_duplicate_state(connector, &copy->state);
-
- return &copy->state;
-}
-
-static void rcar_du_wb_conn_destroy_state(struct drm_connector *connector,
- struct drm_connector_state *state)
-{
- __drm_atomic_helper_connector_destroy_state(state);
- kfree(to_rcar_wb_conn_state(state));
-}
-
-static void rcar_du_wb_conn_reset(struct drm_connector *connector)
-{
- struct rcar_du_wb_conn_state *state;
-
- if (connector->state) {
- rcar_du_wb_conn_destroy_state(connector, connector->state);
- connector->state = NULL;
- }
-
- state = kzalloc(sizeof(*state), GFP_KERNEL);
- if (state == NULL)
- return;
-
- __drm_atomic_helper_connector_reset(connector, &state->state);
-}
-
-static const struct drm_connector_funcs rcar_du_wb_conn_funcs = {
- .reset = rcar_du_wb_conn_reset,
- .fill_modes = drm_helper_probe_single_connector_modes,
- .destroy = drm_connector_cleanup,
- .atomic_duplicate_state = rcar_du_wb_conn_duplicate_state,
- .atomic_destroy_state = rcar_du_wb_conn_destroy_state,
-};
-
-static int rcar_du_wb_enc_atomic_check(struct drm_encoder *encoder,
- struct drm_crtc_state *crtc_state,
- struct drm_connector_state *conn_state)
-{
- struct rcar_du_wb_conn_state *wb_state =
- to_rcar_wb_conn_state(conn_state);
- const struct drm_display_mode *mode = &crtc_state->mode;
- struct drm_device *dev = encoder->dev;
- struct drm_framebuffer *fb;
-
- if (!conn_state->writeback_job)
- return 0;
-
- fb = conn_state->writeback_job->fb;
-
- /*
- * Verify that the framebuffer format is supported and that its size
- * matches the current mode.
- */
- if (fb->width != mode->hdisplay || fb->height != mode->vdisplay) {
- dev_dbg(dev->dev, "%s: invalid framebuffer size %ux%u\n",
- __func__, fb->width, fb->height);
- return -EINVAL;
- }
-
- wb_state->format = rcar_du_format_info(fb->format->format);
- if (wb_state->format == NULL) {
- dev_dbg(dev->dev, "%s: unsupported format %p4cc\n", __func__,
- &fb->format->format);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static const struct drm_encoder_helper_funcs rcar_du_wb_enc_helper_funcs = {
- .atomic_check = rcar_du_wb_enc_atomic_check,
-};
-
-/*
- * Only RGB formats are currently supported as the VSP outputs RGB to the DU
- * and can't convert to YUV separately for writeback.
- */
-static const u32 writeback_formats[] = {
- DRM_FORMAT_RGB332,
- DRM_FORMAT_ARGB4444,
- DRM_FORMAT_XRGB4444,
- DRM_FORMAT_ARGB1555,
- DRM_FORMAT_XRGB1555,
- DRM_FORMAT_RGB565,
- DRM_FORMAT_BGR888,
- DRM_FORMAT_RGB888,
- DRM_FORMAT_BGRA8888,
- DRM_FORMAT_BGRX8888,
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_XRGB8888,
-};
-
-int rcar_du_writeback_init(struct rcar_du_device *rcdu,
- struct rcar_du_crtc *rcrtc)
-{
- struct drm_writeback_connector *wb_conn = &rcrtc->writeback;
-
- drm_connector_helper_add(&wb_conn->base,
- &rcar_du_wb_conn_helper_funcs);
-
- return drm_writeback_connector_init(&rcdu->ddev, wb_conn,
- &rcar_du_wb_conn_funcs,
- &rcar_du_wb_enc_helper_funcs,
- writeback_formats,
- ARRAY_SIZE(writeback_formats),
- 1 << drm_crtc_index(&rcrtc->crtc));
-}
-
-void rcar_du_writeback_setup(struct rcar_du_crtc *rcrtc,
- struct vsp1_du_writeback_config *cfg)
-{
- struct rcar_du_wb_conn_state *wb_state;
- struct drm_connector_state *state;
- struct rcar_du_wb_job *rjob;
- struct drm_framebuffer *fb;
- unsigned int i;
-
- state = rcrtc->writeback.base.state;
- if (!state || !state->writeback_job)
- return;
-
- fb = state->writeback_job->fb;
- rjob = state->writeback_job->priv;
- wb_state = to_rcar_wb_conn_state(state);
-
- cfg->pixelformat = wb_state->format->v4l2;
- cfg->pitch = fb->pitches[0];
-
- for (i = 0; i < wb_state->format->planes; ++i)
- cfg->mem[i] = sg_dma_address(rjob->sg_tables[i].sgl)
- + fb->offsets[i];
-
- drm_writeback_queue_job(&rcrtc->writeback, state);
-}
-
-void rcar_du_writeback_complete(struct rcar_du_crtc *rcrtc)
-{
- drm_writeback_signal_completion(&rcrtc->writeback, 0);
-}
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_writeback.h b/drivers/gpu/drm/rcar-du/rcar_du_writeback.h
deleted file mode 100644
index a71c9c08cafa..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_du_writeback.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * R-Car Display Unit Writeback Support
- *
- * Copyright (C) 2019 Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- */
-
-#ifndef __RCAR_DU_WRITEBACK_H__
-#define __RCAR_DU_WRITEBACK_H__
-
-#include <drm/drm_plane.h>
-
-struct rcar_du_crtc;
-struct rcar_du_device;
-struct vsp1_du_atomic_pipe_config;
-
-#ifdef CONFIG_DRM_RCAR_WRITEBACK
-int rcar_du_writeback_init(struct rcar_du_device *rcdu,
- struct rcar_du_crtc *rcrtc);
-void rcar_du_writeback_setup(struct rcar_du_crtc *rcrtc,
- struct vsp1_du_writeback_config *cfg);
-void rcar_du_writeback_complete(struct rcar_du_crtc *rcrtc);
-#else
-static inline int rcar_du_writeback_init(struct rcar_du_device *rcdu,
- struct rcar_du_crtc *rcrtc)
-{
- return -ENXIO;
-}
-static inline void
-rcar_du_writeback_setup(struct rcar_du_crtc *rcrtc,
- struct vsp1_du_writeback_config *cfg)
-{
-}
-static inline void rcar_du_writeback_complete(struct rcar_du_crtc *rcrtc)
-{
-}
-#endif
-
-#endif /* __RCAR_DU_WRITEBACK_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
deleted file mode 100644
index 18ed14911b98..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
+++ /dev/null
@@ -1,124 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * R-Car Gen3 HDMI PHY
- *
- * Copyright (C) 2016 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-#include <linux/mod_devicetable.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-
-#include <drm/bridge/dw_hdmi.h>
-#include <drm/drm_modes.h>
-
-#define RCAR_HDMI_PHY_OPMODE_PLLCFG 0x06 /* Mode of operation and PLL dividers */
-#define RCAR_HDMI_PHY_PLLCURRGMPCTRL 0x10 /* PLL current and Gmp (conductance) */
-#define RCAR_HDMI_PHY_PLLDIVCTRL 0x11 /* PLL dividers */
-
-struct rcar_hdmi_phy_params {
- unsigned long mpixelclock;
- u16 opmode_div; /* Mode of operation and PLL dividers */
- u16 curr_gmp; /* PLL current and Gmp (conductance) */
- u16 div; /* PLL dividers */
-};
-
-static const struct rcar_hdmi_phy_params rcar_hdmi_phy_params[] = {
- { 35500000, 0x0003, 0x0344, 0x0328 },
- { 44900000, 0x0003, 0x0285, 0x0128 },
- { 71000000, 0x0002, 0x1184, 0x0314 },
- { 90000000, 0x0002, 0x1144, 0x0114 },
- { 140250000, 0x0001, 0x20c4, 0x030a },
- { 182750000, 0x0001, 0x2084, 0x010a },
- { 281250000, 0x0000, 0x0084, 0x0305 },
- { 297000000, 0x0000, 0x0084, 0x0105 },
- { ~0UL, 0x0000, 0x0000, 0x0000 },
-};
-
-static enum drm_mode_status
-rcar_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
- const struct drm_display_info *info,
- const struct drm_display_mode *mode)
-{
- /*
- * The maximum supported clock frequency is 297 MHz, as shown in the PHY
- * parameters table.
- */
- if (mode->clock > 297000)
- return MODE_CLOCK_HIGH;
-
- return MODE_OK;
-}
-
-static int rcar_hdmi_phy_configure(struct dw_hdmi *hdmi, void *data,
- unsigned long mpixelclock)
-{
- const struct rcar_hdmi_phy_params *params = rcar_hdmi_phy_params;
-
- for (; params->mpixelclock != ~0UL; ++params) {
- if (mpixelclock <= params->mpixelclock)
- break;
- }
-
- if (params->mpixelclock == ~0UL)
- return -EINVAL;
-
- dw_hdmi_phy_i2c_write(hdmi, params->opmode_div,
- RCAR_HDMI_PHY_OPMODE_PLLCFG);
- dw_hdmi_phy_i2c_write(hdmi, params->curr_gmp,
- RCAR_HDMI_PHY_PLLCURRGMPCTRL);
- dw_hdmi_phy_i2c_write(hdmi, params->div, RCAR_HDMI_PHY_PLLDIVCTRL);
-
- return 0;
-}
-
-static const struct dw_hdmi_plat_data rcar_dw_hdmi_plat_data = {
- .output_port = 1,
- .mode_valid = rcar_hdmi_mode_valid,
- .configure_phy = rcar_hdmi_phy_configure,
-};
-
-static int rcar_dw_hdmi_probe(struct platform_device *pdev)
-{
- struct dw_hdmi *hdmi;
-
- hdmi = dw_hdmi_probe(pdev, &rcar_dw_hdmi_plat_data);
- if (IS_ERR(hdmi))
- return PTR_ERR(hdmi);
-
- platform_set_drvdata(pdev, hdmi);
-
- return 0;
-}
-
-static int rcar_dw_hdmi_remove(struct platform_device *pdev)
-{
- struct dw_hdmi *hdmi = platform_get_drvdata(pdev);
-
- dw_hdmi_remove(hdmi);
-
- return 0;
-}
-
-static const struct of_device_id rcar_dw_hdmi_of_table[] = {
- { .compatible = "renesas,rcar-gen3-hdmi" },
- { /* Sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, rcar_dw_hdmi_of_table);
-
-static struct platform_driver rcar_dw_hdmi_platform_driver = {
- .probe = rcar_dw_hdmi_probe,
- .remove = rcar_dw_hdmi_remove,
- .driver = {
- .name = "rcar-dw-hdmi",
- .of_match_table = rcar_dw_hdmi_of_table,
- },
-};
-
-module_platform_driver(rcar_dw_hdmi_platform_driver);
-
-MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
-MODULE_DESCRIPTION("Renesas R-Car Gen3 HDMI Encoder Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
deleted file mode 100644
index ca215b588fd7..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
+++ /dev/null
@@ -1,1035 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * R-Car LVDS Encoder
- *
- * Copyright (C) 2013-2018 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/media-bus-format.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/of_graph.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/reset.h>
-#include <linux/slab.h>
-#include <linux/sys_soc.h>
-
-#include <drm/drm_atomic.h>
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_bridge.h>
-#include <drm/drm_of.h>
-#include <drm/drm_panel.h>
-#include <drm/drm_print.h>
-#include <drm/drm_probe_helper.h>
-
-#include "rcar_lvds.h"
-#include "rcar_lvds_regs.h"
-
-struct rcar_lvds;
-
-/* Keep in sync with the LVDCR0.LVMD hardware register values. */
-enum rcar_lvds_mode {
- RCAR_LVDS_MODE_JEIDA = 0,
- RCAR_LVDS_MODE_MIRROR = 1,
- RCAR_LVDS_MODE_VESA = 4,
-};
-
-enum rcar_lvds_link_type {
- RCAR_LVDS_SINGLE_LINK = 0,
- RCAR_LVDS_DUAL_LINK_EVEN_ODD_PIXELS = 1,
- RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS = 2,
-};
-
-#define RCAR_LVDS_QUIRK_LANES BIT(0) /* LVDS lanes 1 and 3 inverted */
-#define RCAR_LVDS_QUIRK_GEN3_LVEN BIT(1) /* LVEN bit needs to be set on R8A77970/R8A7799x */
-#define RCAR_LVDS_QUIRK_PWD BIT(2) /* PWD bit available (all of Gen3 but E3) */
-#define RCAR_LVDS_QUIRK_EXT_PLL BIT(3) /* Has extended PLL */
-#define RCAR_LVDS_QUIRK_DUAL_LINK BIT(4) /* Supports dual-link operation */
-
-struct rcar_lvds_device_info {
- unsigned int gen;
- unsigned int quirks;
- void (*pll_setup)(struct rcar_lvds *lvds, unsigned int freq);
-};
-
-struct rcar_lvds {
- struct device *dev;
- const struct rcar_lvds_device_info *info;
- struct reset_control *rstc;
-
- struct drm_bridge bridge;
-
- struct drm_bridge *next_bridge;
- struct drm_panel *panel;
-
- void __iomem *mmio;
- struct {
- struct clk *mod; /* CPG module clock */
- struct clk *extal; /* External clock */
- struct clk *dotclkin[2]; /* External DU clocks */
- } clocks;
-
- struct drm_bridge *companion;
- enum rcar_lvds_link_type link_type;
-};
-
-#define bridge_to_rcar_lvds(b) \
- container_of(b, struct rcar_lvds, bridge)
-
-static u32 rcar_lvds_read(struct rcar_lvds *lvds, u32 reg)
-{
- return ioread32(lvds->mmio + reg);
-}
-
-static void rcar_lvds_write(struct rcar_lvds *lvds, u32 reg, u32 data)
-{
- iowrite32(data, lvds->mmio + reg);
-}
-
-/* -----------------------------------------------------------------------------
- * PLL Setup
- */
-
-static void rcar_lvds_pll_setup_gen2(struct rcar_lvds *lvds, unsigned int freq)
-{
- u32 val;
-
- if (freq < 39000000)
- val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_38M;
- else if (freq < 61000000)
- val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_60M;
- else if (freq < 121000000)
- val = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_121M;
- else
- val = LVDPLLCR_PLLDLYCNT_150M;
-
- rcar_lvds_write(lvds, LVDPLLCR, val);
-}
-
-static void rcar_lvds_pll_setup_gen3(struct rcar_lvds *lvds, unsigned int freq)
-{
- u32 val;
-
- if (freq < 42000000)
- val = LVDPLLCR_PLLDIVCNT_42M;
- else if (freq < 85000000)
- val = LVDPLLCR_PLLDIVCNT_85M;
- else if (freq < 128000000)
- val = LVDPLLCR_PLLDIVCNT_128M;
- else
- val = LVDPLLCR_PLLDIVCNT_148M;
-
- rcar_lvds_write(lvds, LVDPLLCR, val);
-}
-
-struct pll_info {
- unsigned long diff;
- unsigned int pll_m;
- unsigned int pll_n;
- unsigned int pll_e;
- unsigned int div;
- u32 clksel;
-};
-
-static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk,
- unsigned long target, struct pll_info *pll,
- u32 clksel, bool dot_clock_only)
-{
- unsigned int div7 = dot_clock_only ? 1 : 7;
- unsigned long output;
- unsigned long fin;
- unsigned int m_min;
- unsigned int m_max;
- unsigned int m;
- int error;
-
- if (!clk)
- return;
-
- /*
- * The LVDS PLL is made of a pre-divider and a multiplier (strangely
- * enough called M and N respectively), followed by a post-divider E.
- *
- * ,-----. ,-----. ,-----. ,-----.
- * Fin --> | 1/M | -Fpdf-> | PFD | --> | VCO | -Fvco-> | 1/E | --> Fout
- * `-----' ,-> | | `-----' | `-----'
- * | `-----' |
- * | ,-----. |
- * `-------- | 1/N | <-------'
- * `-----'
- *
- * The clock output by the PLL is then further divided by a programmable
- * divider DIV to achieve the desired target frequency. Finally, an
- * optional fixed /7 divider is used to convert the bit clock to a pixel
- * clock (as LVDS transmits 7 bits per lane per clock sample).
- *
- * ,-------. ,-----. |\
- * Fout --> | 1/DIV | --> | 1/7 | --> | |
- * `-------' | `-----' | | --> dot clock
- * `------------> | |
- * |/
- *
- * The /7 divider is optional, it is enabled when the LVDS PLL is used
- * to drive the LVDS encoder, and disabled when used to generate a dot
- * clock for the DU RGB output, without using the LVDS encoder.
- *
- * The PLL allowed input frequency range is 12 MHz to 192 MHz.
- */
-
- fin = clk_get_rate(clk);
- if (fin < 12000000 || fin > 192000000)
- return;
-
- /*
- * The comparison frequency range is 12 MHz to 24 MHz, which limits the
- * allowed values for the pre-divider M (normal range 1-8).
- *
- * Fpfd = Fin / M
- */
- m_min = max_t(unsigned int, 1, DIV_ROUND_UP(fin, 24000000));
- m_max = min_t(unsigned int, 8, fin / 12000000);
-
- for (m = m_min; m <= m_max; ++m) {
- unsigned long fpfd;
- unsigned int n_min;
- unsigned int n_max;
- unsigned int n;
-
- /*
- * The VCO operating range is 900 Mhz to 1800 MHz, which limits
- * the allowed values for the multiplier N (normal range
- * 60-120).
- *
- * Fvco = Fin * N / M
- */
- fpfd = fin / m;
- n_min = max_t(unsigned int, 60, DIV_ROUND_UP(900000000, fpfd));
- n_max = min_t(unsigned int, 120, 1800000000 / fpfd);
-
- for (n = n_min; n < n_max; ++n) {
- unsigned long fvco;
- unsigned int e_min;
- unsigned int e;
-
- /*
- * The output frequency is limited to 1039.5 MHz,
- * limiting again the allowed values for the
- * post-divider E (normal value 1, 2 or 4).
- *
- * Fout = Fvco / E
- */
- fvco = fpfd * n;
- e_min = fvco > 1039500000 ? 1 : 0;
-
- for (e = e_min; e < 3; ++e) {
- unsigned long fout;
- unsigned long diff;
- unsigned int div;
-
- /*
- * Finally we have a programable divider after
- * the PLL, followed by a an optional fixed /7
- * divider.
- */
- fout = fvco / (1 << e) / div7;
- div = max(1UL, DIV_ROUND_CLOSEST(fout, target));
- diff = abs(fout / div - target);
-
- if (diff < pll->diff) {
- pll->diff = diff;
- pll->pll_m = m;
- pll->pll_n = n;
- pll->pll_e = e;
- pll->div = div;
- pll->clksel = clksel;
-
- if (diff == 0)
- goto done;
- }
- }
- }
- }
-
-done:
- output = fin * pll->pll_n / pll->pll_m / (1 << pll->pll_e)
- / div7 / pll->div;
- error = (long)(output - target) * 10000 / (long)target;
-
- dev_dbg(lvds->dev,
- "%pC %lu Hz -> Fout %lu Hz (target %lu Hz, error %d.%02u%%), PLL M/N/E/DIV %u/%u/%u/%u\n",
- clk, fin, output, target, error / 100,
- error < 0 ? -error % 100 : error % 100,
- pll->pll_m, pll->pll_n, pll->pll_e, pll->div);
-}
-
-static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds,
- unsigned int freq, bool dot_clock_only)
-{
- struct pll_info pll = { .diff = (unsigned long)-1 };
- u32 lvdpllcr;
-
- rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[0], freq, &pll,
- LVDPLLCR_CKSEL_DU_DOTCLKIN(0), dot_clock_only);
- rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[1], freq, &pll,
- LVDPLLCR_CKSEL_DU_DOTCLKIN(1), dot_clock_only);
- rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.extal, freq, &pll,
- LVDPLLCR_CKSEL_EXTAL, dot_clock_only);
-
- lvdpllcr = LVDPLLCR_PLLON | pll.clksel | LVDPLLCR_CLKOUT
- | LVDPLLCR_PLLN(pll.pll_n - 1) | LVDPLLCR_PLLM(pll.pll_m - 1);
-
- if (pll.pll_e > 0)
- lvdpllcr |= LVDPLLCR_STP_CLKOUTE | LVDPLLCR_OUTCLKSEL
- | LVDPLLCR_PLLE(pll.pll_e - 1);
-
- if (dot_clock_only)
- lvdpllcr |= LVDPLLCR_OCKSEL;
-
- rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
-
- if (pll.div > 1)
- /*
- * The DIVRESET bit is a misnomer, setting it to 1 deasserts the
- * divisor reset.
- */
- rcar_lvds_write(lvds, LVDDIV, LVDDIV_DIVSEL |
- LVDDIV_DIVRESET | LVDDIV_DIV(pll.div - 1));
- else
- rcar_lvds_write(lvds, LVDDIV, 0);
-}
-
-/* -----------------------------------------------------------------------------
- * Enable/disable
- */
-
-static enum rcar_lvds_mode rcar_lvds_get_lvds_mode(struct rcar_lvds *lvds,
- const struct drm_connector *connector)
-{
- const struct drm_display_info *info;
- enum rcar_lvds_mode mode;
-
- /*
- * There is no API yet to retrieve LVDS mode from a bridge, only panels
- * are supported.
- */
- if (!lvds->panel)
- return RCAR_LVDS_MODE_JEIDA;
-
- info = &connector->display_info;
- if (!info->num_bus_formats || !info->bus_formats) {
- dev_warn(lvds->dev,
- "no LVDS bus format reported, using JEIDA\n");
- return RCAR_LVDS_MODE_JEIDA;
- }
-
- switch (info->bus_formats[0]) {
- case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
- case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
- mode = RCAR_LVDS_MODE_JEIDA;
- break;
- case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
- mode = RCAR_LVDS_MODE_VESA;
- break;
- default:
- dev_warn(lvds->dev,
- "unsupported LVDS bus format 0x%04x, using JEIDA\n",
- info->bus_formats[0]);
- return RCAR_LVDS_MODE_JEIDA;
- }
-
- if (info->bus_flags & DRM_BUS_FLAG_DATA_LSB_TO_MSB)
- mode |= RCAR_LVDS_MODE_MIRROR;
-
- return mode;
-}
-
-static void rcar_lvds_enable(struct drm_bridge *bridge,
- struct drm_atomic_state *state,
- struct drm_crtc *crtc,
- struct drm_connector *connector)
-{
- struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
- u32 lvdhcr;
- u32 lvdcr0;
- int ret;
-
- ret = pm_runtime_resume_and_get(lvds->dev);
- if (ret)
- return;
-
- /* Enable the companion LVDS encoder in dual-link mode. */
- if (lvds->link_type != RCAR_LVDS_SINGLE_LINK && lvds->companion)
- rcar_lvds_enable(lvds->companion, state, crtc, connector);
-
- /*
- * Hardcode the channels and control signals routing for now.
- *
- * HSYNC -> CTRL0
- * VSYNC -> CTRL1
- * DISP -> CTRL2
- * 0 -> CTRL3
- */
- rcar_lvds_write(lvds, LVDCTRCR, LVDCTRCR_CTR3SEL_ZERO |
- LVDCTRCR_CTR2SEL_DISP | LVDCTRCR_CTR1SEL_VSYNC |
- LVDCTRCR_CTR0SEL_HSYNC);
-
- if (lvds->info->quirks & RCAR_LVDS_QUIRK_LANES)
- lvdhcr = LVDCHCR_CHSEL_CH(0, 0) | LVDCHCR_CHSEL_CH(1, 3)
- | LVDCHCR_CHSEL_CH(2, 2) | LVDCHCR_CHSEL_CH(3, 1);
- else
- lvdhcr = LVDCHCR_CHSEL_CH(0, 0) | LVDCHCR_CHSEL_CH(1, 1)
- | LVDCHCR_CHSEL_CH(2, 2) | LVDCHCR_CHSEL_CH(3, 3);
-
- rcar_lvds_write(lvds, LVDCHCR, lvdhcr);
-
- if (lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK) {
- u32 lvdstripe = 0;
-
- if (lvds->link_type != RCAR_LVDS_SINGLE_LINK) {
- /*
- * By default we generate even pixels from the primary
- * encoder and odd pixels from the companion encoder.
- * Swap pixels around if the sink requires odd pixels
- * from the primary encoder and even pixels from the
- * companion encoder.
- */
- bool swap_pixels = lvds->link_type ==
- RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS;
-
- /*
- * Configure vertical stripe since we are dealing with
- * an LVDS dual-link connection.
- *
- * ST_SWAP is reserved for the companion encoder, only
- * set it in the primary encoder.
- */
- lvdstripe = LVDSTRIPE_ST_ON
- | (lvds->companion && swap_pixels ?
- LVDSTRIPE_ST_SWAP : 0);
- }
- rcar_lvds_write(lvds, LVDSTRIPE, lvdstripe);
- }
-
- /*
- * PLL clock configuration on all instances but the companion in
- * dual-link mode.
- *
- * The extended PLL has been turned on by an explicit call to
- * rcar_lvds_pclk_enable() from the DU driver.
- */
- if ((lvds->link_type == RCAR_LVDS_SINGLE_LINK || lvds->companion) &&
- !(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
- const struct drm_crtc_state *crtc_state =
- drm_atomic_get_new_crtc_state(state, crtc);
- const struct drm_display_mode *mode =
- &crtc_state->adjusted_mode;
-
- lvds->info->pll_setup(lvds, mode->clock * 1000);
- }
-
- /* Set the LVDS mode and select the input. */
- lvdcr0 = rcar_lvds_get_lvds_mode(lvds, connector) << LVDCR0_LVMD_SHIFT;
-
- if (lvds->bridge.encoder) {
- if (drm_crtc_index(crtc) == 2)
- lvdcr0 |= LVDCR0_DUSEL;
- }
-
- rcar_lvds_write(lvds, LVDCR0, lvdcr0);
-
- /* Turn all the channels on. */
- rcar_lvds_write(lvds, LVDCR1,
- LVDCR1_CHSTBY(3) | LVDCR1_CHSTBY(2) |
- LVDCR1_CHSTBY(1) | LVDCR1_CHSTBY(0) | LVDCR1_CLKSTBY);
-
- if (lvds->info->gen < 3) {
- /* Enable LVDS operation and turn the bias circuitry on. */
- lvdcr0 |= LVDCR0_BEN | LVDCR0_LVEN;
- rcar_lvds_write(lvds, LVDCR0, lvdcr0);
- }
-
- if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
- /*
- * Turn the PLL on (simple PLL only, extended PLL is fully
- * controlled through LVDPLLCR).
- */
- lvdcr0 |= LVDCR0_PLLON;
- rcar_lvds_write(lvds, LVDCR0, lvdcr0);
- }
-
- if (lvds->info->quirks & RCAR_LVDS_QUIRK_PWD) {
- /* Set LVDS normal mode. */
- lvdcr0 |= LVDCR0_PWD;
- rcar_lvds_write(lvds, LVDCR0, lvdcr0);
- }
-
- if (lvds->info->quirks & RCAR_LVDS_QUIRK_GEN3_LVEN) {
- /*
- * Turn on the LVDS PHY. On D3, the LVEN and LVRES bit must be
- * set at the same time, so don't write the register yet.
- */
- lvdcr0 |= LVDCR0_LVEN;
- if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_PWD))
- rcar_lvds_write(lvds, LVDCR0, lvdcr0);
- }
-
- if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
- /* Wait for the PLL startup delay (simple PLL only). */
- usleep_range(100, 150);
- }
-
- /* Turn the output on. */
- lvdcr0 |= LVDCR0_LVRES;
- rcar_lvds_write(lvds, LVDCR0, lvdcr0);
-}
-
-static void rcar_lvds_disable(struct drm_bridge *bridge)
-{
- struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
- u32 lvdcr0;
-
- /*
- * Clear the LVDCR0 bits in the order specified by the hardware
- * documentation, ending with a write of 0 to the full register to
- * clear all remaining bits.
- */
- lvdcr0 = rcar_lvds_read(lvds, LVDCR0);
-
- lvdcr0 &= ~LVDCR0_LVRES;
- rcar_lvds_write(lvds, LVDCR0, lvdcr0);
-
- if (lvds->info->quirks & RCAR_LVDS_QUIRK_GEN3_LVEN) {
- lvdcr0 &= ~LVDCR0_LVEN;
- rcar_lvds_write(lvds, LVDCR0, lvdcr0);
- }
-
- if (lvds->info->quirks & RCAR_LVDS_QUIRK_PWD) {
- lvdcr0 &= ~LVDCR0_PWD;
- rcar_lvds_write(lvds, LVDCR0, lvdcr0);
- }
-
- if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
- lvdcr0 &= ~LVDCR0_PLLON;
- rcar_lvds_write(lvds, LVDCR0, lvdcr0);
- }
-
- rcar_lvds_write(lvds, LVDCR0, 0);
- rcar_lvds_write(lvds, LVDCR1, 0);
-
- /* The extended PLL is turned off in rcar_lvds_pclk_disable(). */
- if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL))
- rcar_lvds_write(lvds, LVDPLLCR, 0);
-
- /* Disable the companion LVDS encoder in dual-link mode. */
- if (lvds->link_type != RCAR_LVDS_SINGLE_LINK && lvds->companion)
- rcar_lvds_disable(lvds->companion);
-
- pm_runtime_put_sync(lvds->dev);
-}
-
-/* -----------------------------------------------------------------------------
- * Clock - D3/E3 only
- */
-
-int rcar_lvds_pclk_enable(struct drm_bridge *bridge, unsigned long freq,
- bool dot_clk_only)
-{
- struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
- int ret;
-
- if (WARN_ON(!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)))
- return -ENODEV;
-
- dev_dbg(lvds->dev, "enabling LVDS PLL, freq=%luHz\n", freq);
-
- ret = pm_runtime_resume_and_get(lvds->dev);
- if (ret)
- return ret;
-
- rcar_lvds_pll_setup_d3_e3(lvds, freq, dot_clk_only);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(rcar_lvds_pclk_enable);
-
-void rcar_lvds_pclk_disable(struct drm_bridge *bridge, bool dot_clk_only)
-{
- struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
-
- if (WARN_ON(!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)))
- return;
-
- dev_dbg(lvds->dev, "disabling LVDS PLL\n");
-
- if (!dot_clk_only)
- rcar_lvds_disable(bridge);
-
- rcar_lvds_write(lvds, LVDPLLCR, 0);
-
- pm_runtime_put_sync(lvds->dev);
-}
-EXPORT_SYMBOL_GPL(rcar_lvds_pclk_disable);
-
-/* -----------------------------------------------------------------------------
- * Bridge
- */
-
-static void rcar_lvds_atomic_enable(struct drm_bridge *bridge,
- struct drm_bridge_state *old_bridge_state)
-{
- struct drm_atomic_state *state = old_bridge_state->base.state;
- struct drm_connector *connector;
- struct drm_crtc *crtc;
-
- connector = drm_atomic_get_new_connector_for_encoder(state,
- bridge->encoder);
- crtc = drm_atomic_get_new_connector_state(state, connector)->crtc;
-
- rcar_lvds_enable(bridge, state, crtc, connector);
-}
-
-static void rcar_lvds_atomic_disable(struct drm_bridge *bridge,
- struct drm_bridge_state *old_bridge_state)
-{
- struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
-
- /*
- * For D3 and E3, disabling the LVDS encoder before the DU would stall
- * the DU, causing a vblank wait timeout when stopping the DU. This has
- * been traced to clearing the LVEN bit, but the exact reason is
- * unknown. Keep the encoder enabled, it will be disabled by an explicit
- * call to rcar_lvds_pclk_disable() from the DU driver.
- *
- * We could clear the LVRES bit already to disable the LVDS output, but
- * that's likely pointless.
- */
- if (lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)
- return;
-
- rcar_lvds_disable(bridge);
-}
-
-static bool rcar_lvds_mode_fixup(struct drm_bridge *bridge,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
- int min_freq;
-
- /*
- * The internal LVDS encoder has a restricted clock frequency operating
- * range, from 5MHz to 148.5MHz on D3 and E3, and from 31MHz to
- * 148.5MHz on all other platforms. Clamp the clock accordingly.
- */
- min_freq = lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL ? 5000 : 31000;
- adjusted_mode->clock = clamp(adjusted_mode->clock, min_freq, 148500);
-
- return true;
-}
-
-static int rcar_lvds_attach(struct drm_bridge *bridge,
- enum drm_bridge_attach_flags flags)
-{
- struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
-
- if (!lvds->next_bridge)
- return 0;
-
- return drm_bridge_attach(bridge->encoder, lvds->next_bridge, bridge,
- flags);
-}
-
-static const struct drm_bridge_funcs rcar_lvds_bridge_ops = {
- .attach = rcar_lvds_attach,
- .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
- .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
- .atomic_reset = drm_atomic_helper_bridge_reset,
- .atomic_enable = rcar_lvds_atomic_enable,
- .atomic_disable = rcar_lvds_atomic_disable,
- .mode_fixup = rcar_lvds_mode_fixup,
-};
-
-bool rcar_lvds_dual_link(struct drm_bridge *bridge)
-{
- struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
-
- return lvds->link_type != RCAR_LVDS_SINGLE_LINK;
-}
-EXPORT_SYMBOL_GPL(rcar_lvds_dual_link);
-
-bool rcar_lvds_is_connected(struct drm_bridge *bridge)
-{
- struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
-
- return lvds->next_bridge != NULL;
-}
-EXPORT_SYMBOL_GPL(rcar_lvds_is_connected);
-
-/* -----------------------------------------------------------------------------
- * Probe & Remove
- */
-
-static int rcar_lvds_parse_dt_companion(struct rcar_lvds *lvds)
-{
- const struct of_device_id *match;
- struct device_node *companion;
- struct device_node *port0, *port1;
- struct rcar_lvds *companion_lvds;
- struct device *dev = lvds->dev;
- int dual_link;
- int ret = 0;
-
- /* Locate the companion LVDS encoder for dual-link operation, if any. */
- companion = of_parse_phandle(dev->of_node, "renesas,companion", 0);
- if (!companion)
- return 0;
-
- /*
- * Sanity check: the companion encoder must have the same compatible
- * string.
- */
- match = of_match_device(dev->driver->of_match_table, dev);
- if (!of_device_is_compatible(companion, match->compatible)) {
- dev_err(dev, "Companion LVDS encoder is invalid\n");
- ret = -ENXIO;
- goto done;
- }
-
- /*
- * We need to work out if the sink is expecting us to function in
- * dual-link mode. We do this by looking at the DT port nodes we are
- * connected to, if they are marked as expecting even pixels and
- * odd pixels than we need to enable vertical stripe output.
- */
- port0 = of_graph_get_port_by_id(dev->of_node, 1);
- port1 = of_graph_get_port_by_id(companion, 1);
- dual_link = drm_of_lvds_get_dual_link_pixel_order(port0, port1);
- of_node_put(port0);
- of_node_put(port1);
-
- switch (dual_link) {
- case DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS:
- lvds->link_type = RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS;
- break;
- case DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS:
- lvds->link_type = RCAR_LVDS_DUAL_LINK_EVEN_ODD_PIXELS;
- break;
- default:
- /*
- * Early dual-link bridge specific implementations populate the
- * timings field of drm_bridge. If the flag is set, we assume
- * that we are expected to generate even pixels from the primary
- * encoder, and odd pixels from the companion encoder.
- */
- if (lvds->next_bridge->timings &&
- lvds->next_bridge->timings->dual_link)
- lvds->link_type = RCAR_LVDS_DUAL_LINK_EVEN_ODD_PIXELS;
- else
- lvds->link_type = RCAR_LVDS_SINGLE_LINK;
- }
-
- if (lvds->link_type == RCAR_LVDS_SINGLE_LINK) {
- dev_dbg(dev, "Single-link configuration detected\n");
- goto done;
- }
-
- lvds->companion = of_drm_find_bridge(companion);
- if (!lvds->companion) {
- ret = -EPROBE_DEFER;
- goto done;
- }
-
- dev_dbg(dev,
- "Dual-link configuration detected (companion encoder %pOF)\n",
- companion);
-
- if (lvds->link_type == RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS)
- dev_dbg(dev, "Data swapping required\n");
-
- /*
- * FIXME: We should not be messing with the companion encoder private
- * data from the primary encoder, we should rather let the companion
- * encoder work things out on its own. However, the companion encoder
- * doesn't hold a reference to the primary encoder, and
- * drm_of_lvds_get_dual_link_pixel_order needs to be given references
- * to the output ports of both encoders, therefore leave it like this
- * for the time being.
- */
- companion_lvds = bridge_to_rcar_lvds(lvds->companion);
- companion_lvds->link_type = lvds->link_type;
-
-done:
- of_node_put(companion);
-
- return ret;
-}
-
-static int rcar_lvds_parse_dt(struct rcar_lvds *lvds)
-{
- int ret;
-
- ret = drm_of_find_panel_or_bridge(lvds->dev->of_node, 1, 0,
- &lvds->panel, &lvds->next_bridge);
- if (ret)
- goto done;
-
- if (lvds->panel) {
- lvds->next_bridge = devm_drm_panel_bridge_add(lvds->dev,
- lvds->panel);
- if (IS_ERR_OR_NULL(lvds->next_bridge)) {
- ret = -EINVAL;
- goto done;
- }
- }
-
- if (lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK)
- ret = rcar_lvds_parse_dt_companion(lvds);
-
-done:
- /*
- * On D3/E3 the LVDS encoder provides a clock to the DU, which can be
- * used for the DPAD output even when the LVDS output is not connected.
- * Don't fail probe in that case as the DU will need the bridge to
- * control the clock.
- */
- if (lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)
- return ret == -ENODEV ? 0 : ret;
-
- return ret;
-}
-
-static struct clk *rcar_lvds_get_clock(struct rcar_lvds *lvds, const char *name,
- bool optional)
-{
- struct clk *clk;
-
- clk = devm_clk_get(lvds->dev, name);
- if (!IS_ERR(clk))
- return clk;
-
- if (PTR_ERR(clk) == -ENOENT && optional)
- return NULL;
-
- dev_err_probe(lvds->dev, PTR_ERR(clk), "failed to get %s clock\n",
- name ? name : "module");
-
- return clk;
-}
-
-static int rcar_lvds_get_clocks(struct rcar_lvds *lvds)
-{
- lvds->clocks.mod = rcar_lvds_get_clock(lvds, NULL, false);
- if (IS_ERR(lvds->clocks.mod))
- return PTR_ERR(lvds->clocks.mod);
-
- /*
- * LVDS encoders without an extended PLL have no external clock inputs.
- */
- if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL))
- return 0;
-
- lvds->clocks.extal = rcar_lvds_get_clock(lvds, "extal", true);
- if (IS_ERR(lvds->clocks.extal))
- return PTR_ERR(lvds->clocks.extal);
-
- lvds->clocks.dotclkin[0] = rcar_lvds_get_clock(lvds, "dclkin.0", true);
- if (IS_ERR(lvds->clocks.dotclkin[0]))
- return PTR_ERR(lvds->clocks.dotclkin[0]);
-
- lvds->clocks.dotclkin[1] = rcar_lvds_get_clock(lvds, "dclkin.1", true);
- if (IS_ERR(lvds->clocks.dotclkin[1]))
- return PTR_ERR(lvds->clocks.dotclkin[1]);
-
- /* At least one input to the PLL must be available. */
- if (!lvds->clocks.extal && !lvds->clocks.dotclkin[0] &&
- !lvds->clocks.dotclkin[1]) {
- dev_err(lvds->dev,
- "no input clock (extal, dclkin.0 or dclkin.1)\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static const struct rcar_lvds_device_info rcar_lvds_r8a7790es1_info = {
- .gen = 2,
- .quirks = RCAR_LVDS_QUIRK_LANES,
- .pll_setup = rcar_lvds_pll_setup_gen2,
-};
-
-static const struct soc_device_attribute lvds_quirk_matches[] = {
- {
- .soc_id = "r8a7790", .revision = "ES1.*",
- .data = &rcar_lvds_r8a7790es1_info,
- },
- { /* sentinel */ }
-};
-
-static int rcar_lvds_probe(struct platform_device *pdev)
-{
- const struct soc_device_attribute *attr;
- struct rcar_lvds *lvds;
- int ret;
-
- lvds = devm_kzalloc(&pdev->dev, sizeof(*lvds), GFP_KERNEL);
- if (lvds == NULL)
- return -ENOMEM;
-
- platform_set_drvdata(pdev, lvds);
-
- lvds->dev = &pdev->dev;
- lvds->info = of_device_get_match_data(&pdev->dev);
-
- attr = soc_device_match(lvds_quirk_matches);
- if (attr)
- lvds->info = attr->data;
-
- ret = rcar_lvds_parse_dt(lvds);
- if (ret < 0)
- return ret;
-
- lvds->bridge.funcs = &rcar_lvds_bridge_ops;
- lvds->bridge.of_node = pdev->dev.of_node;
-
- lvds->mmio = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(lvds->mmio))
- return PTR_ERR(lvds->mmio);
-
- ret = rcar_lvds_get_clocks(lvds);
- if (ret < 0)
- return ret;
-
- lvds->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
- if (IS_ERR(lvds->rstc))
- return dev_err_probe(&pdev->dev, PTR_ERR(lvds->rstc),
- "failed to get cpg reset\n");
-
- pm_runtime_enable(&pdev->dev);
-
- drm_bridge_add(&lvds->bridge);
-
- return 0;
-}
-
-static int rcar_lvds_remove(struct platform_device *pdev)
-{
- struct rcar_lvds *lvds = platform_get_drvdata(pdev);
-
- drm_bridge_remove(&lvds->bridge);
-
- pm_runtime_disable(&pdev->dev);
-
- return 0;
-}
-
-static const struct rcar_lvds_device_info rcar_lvds_gen2_info = {
- .gen = 2,
- .pll_setup = rcar_lvds_pll_setup_gen2,
-};
-
-static const struct rcar_lvds_device_info rcar_lvds_gen3_info = {
- .gen = 3,
- .quirks = RCAR_LVDS_QUIRK_PWD,
- .pll_setup = rcar_lvds_pll_setup_gen3,
-};
-
-static const struct rcar_lvds_device_info rcar_lvds_r8a77970_info = {
- .gen = 3,
- .quirks = RCAR_LVDS_QUIRK_PWD | RCAR_LVDS_QUIRK_GEN3_LVEN,
- .pll_setup = rcar_lvds_pll_setup_gen2,
-};
-
-static const struct rcar_lvds_device_info rcar_lvds_r8a77990_info = {
- .gen = 3,
- .quirks = RCAR_LVDS_QUIRK_GEN3_LVEN | RCAR_LVDS_QUIRK_EXT_PLL
- | RCAR_LVDS_QUIRK_DUAL_LINK,
-};
-
-static const struct rcar_lvds_device_info rcar_lvds_r8a77995_info = {
- .gen = 3,
- .quirks = RCAR_LVDS_QUIRK_GEN3_LVEN | RCAR_LVDS_QUIRK_PWD
- | RCAR_LVDS_QUIRK_EXT_PLL | RCAR_LVDS_QUIRK_DUAL_LINK,
-};
-
-static const struct of_device_id rcar_lvds_of_table[] = {
- { .compatible = "renesas,r8a7742-lvds", .data = &rcar_lvds_gen2_info },
- { .compatible = "renesas,r8a7743-lvds", .data = &rcar_lvds_gen2_info },
- { .compatible = "renesas,r8a7744-lvds", .data = &rcar_lvds_gen2_info },
- { .compatible = "renesas,r8a774a1-lvds", .data = &rcar_lvds_gen3_info },
- { .compatible = "renesas,r8a774b1-lvds", .data = &rcar_lvds_gen3_info },
- { .compatible = "renesas,r8a774c0-lvds", .data = &rcar_lvds_r8a77990_info },
- { .compatible = "renesas,r8a774e1-lvds", .data = &rcar_lvds_gen3_info },
- { .compatible = "renesas,r8a7790-lvds", .data = &rcar_lvds_gen2_info },
- { .compatible = "renesas,r8a7791-lvds", .data = &rcar_lvds_gen2_info },
- { .compatible = "renesas,r8a7793-lvds", .data = &rcar_lvds_gen2_info },
- { .compatible = "renesas,r8a7795-lvds", .data = &rcar_lvds_gen3_info },
- { .compatible = "renesas,r8a7796-lvds", .data = &rcar_lvds_gen3_info },
- { .compatible = "renesas,r8a77961-lvds", .data = &rcar_lvds_gen3_info },
- { .compatible = "renesas,r8a77965-lvds", .data = &rcar_lvds_gen3_info },
- { .compatible = "renesas,r8a77970-lvds", .data = &rcar_lvds_r8a77970_info },
- { .compatible = "renesas,r8a77980-lvds", .data = &rcar_lvds_gen3_info },
- { .compatible = "renesas,r8a77990-lvds", .data = &rcar_lvds_r8a77990_info },
- { .compatible = "renesas,r8a77995-lvds", .data = &rcar_lvds_r8a77995_info },
- { }
-};
-
-MODULE_DEVICE_TABLE(of, rcar_lvds_of_table);
-
-static int rcar_lvds_runtime_suspend(struct device *dev)
-{
- struct rcar_lvds *lvds = dev_get_drvdata(dev);
-
- clk_disable_unprepare(lvds->clocks.mod);
-
- reset_control_assert(lvds->rstc);
-
- return 0;
-}
-
-static int rcar_lvds_runtime_resume(struct device *dev)
-{
- struct rcar_lvds *lvds = dev_get_drvdata(dev);
- int ret;
-
- ret = reset_control_deassert(lvds->rstc);
- if (ret)
- return ret;
-
- ret = clk_prepare_enable(lvds->clocks.mod);
- if (ret < 0)
- goto err_reset_assert;
-
- return 0;
-
-err_reset_assert:
- reset_control_assert(lvds->rstc);
-
- return ret;
-}
-
-static const struct dev_pm_ops rcar_lvds_pm_ops = {
- SET_RUNTIME_PM_OPS(rcar_lvds_runtime_suspend, rcar_lvds_runtime_resume, NULL)
-};
-
-static struct platform_driver rcar_lvds_platform_driver = {
- .probe = rcar_lvds_probe,
- .remove = rcar_lvds_remove,
- .driver = {
- .name = "rcar-lvds",
- .pm = &rcar_lvds_pm_ops,
- .of_match_table = rcar_lvds_of_table,
- },
-};
-
-module_platform_driver(rcar_lvds_platform_driver);
-
-MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
-MODULE_DESCRIPTION("Renesas R-Car LVDS Encoder Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.h b/drivers/gpu/drm/rcar-du/rcar_lvds.h
deleted file mode 100644
index 887c63500000..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_lvds.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * R-Car LVDS Encoder
- *
- * Copyright (C) 2013-2018 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-#ifndef __RCAR_LVDS_H__
-#define __RCAR_LVDS_H__
-
-struct drm_bridge;
-
-#if IS_ENABLED(CONFIG_DRM_RCAR_LVDS)
-int rcar_lvds_pclk_enable(struct drm_bridge *bridge, unsigned long freq,
- bool dot_clk_only);
-void rcar_lvds_pclk_disable(struct drm_bridge *bridge, bool dot_clk_only);
-bool rcar_lvds_dual_link(struct drm_bridge *bridge);
-bool rcar_lvds_is_connected(struct drm_bridge *bridge);
-#else
-static inline int rcar_lvds_pclk_enable(struct drm_bridge *bridge,
- unsigned long freq, bool dot_clk_only)
-{
- return -ENOSYS;
-}
-static inline void rcar_lvds_pclk_disable(struct drm_bridge *bridge,
- bool dot_clock_only)
-{
-}
-static inline bool rcar_lvds_dual_link(struct drm_bridge *bridge)
-{
- return false;
-}
-static inline bool rcar_lvds_is_connected(struct drm_bridge *bridge)
-{
- return false;
-}
-#endif /* CONFIG_DRM_RCAR_LVDS */
-
-#endif /* __RCAR_LVDS_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
deleted file mode 100644
index ab0406a27d33..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * R-Car LVDS Interface Registers Definitions
- *
- * Copyright (C) 2013-2015 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-#ifndef __RCAR_LVDS_REGS_H__
-#define __RCAR_LVDS_REGS_H__
-
-#define LVDCR0 0x0000
-#define LVDCR0_DUSEL (1 << 15)
-#define LVDCR0_DMD (1 << 12) /* Gen2 only */
-#define LVDCR0_LVMD_MASK (0xf << 8)
-#define LVDCR0_LVMD_SHIFT 8
-#define LVDCR0_PLLON (1 << 4)
-#define LVDCR0_PWD (1 << 2) /* Gen3 only */
-#define LVDCR0_BEN (1 << 2) /* Gen2 only */
-#define LVDCR0_LVEN (1 << 1)
-#define LVDCR0_LVRES (1 << 0)
-
-#define LVDCR1 0x0004
-#define LVDCR1_CKSEL (1 << 15) /* Gen2 only */
-#define LVDCR1_CHSTBY(n) (3 << (2 + (n) * 2))
-#define LVDCR1_CLKSTBY (3 << 0)
-
-#define LVDPLLCR 0x0008
-/* Gen2 & V3M */
-#define LVDPLLCR_CEEN (1 << 14)
-#define LVDPLLCR_FBEN (1 << 13)
-#define LVDPLLCR_COSEL (1 << 12)
-#define LVDPLLCR_PLLDLYCNT_150M (0x1bf << 0)
-#define LVDPLLCR_PLLDLYCNT_121M (0x22c << 0)
-#define LVDPLLCR_PLLDLYCNT_60M (0x77b << 0)
-#define LVDPLLCR_PLLDLYCNT_38M (0x69a << 0)
-#define LVDPLLCR_PLLDLYCNT_MASK (0x7ff << 0)
-/* Gen3 but V3M,D3 and E3 */
-#define LVDPLLCR_PLLDIVCNT_42M (0x014cb << 0)
-#define LVDPLLCR_PLLDIVCNT_85M (0x00a45 << 0)
-#define LVDPLLCR_PLLDIVCNT_128M (0x006c3 << 0)
-#define LVDPLLCR_PLLDIVCNT_148M (0x046c1 << 0)
-#define LVDPLLCR_PLLDIVCNT_MASK (0x7ffff << 0)
-/* D3 and E3 */
-#define LVDPLLCR_PLLON (1 << 22)
-#define LVDPLLCR_PLLSEL_PLL0 (0 << 20)
-#define LVDPLLCR_PLLSEL_LVX (1 << 20)
-#define LVDPLLCR_PLLSEL_PLL1 (2 << 20)
-#define LVDPLLCR_CKSEL_LVX (1 << 17)
-#define LVDPLLCR_CKSEL_EXTAL (3 << 17)
-#define LVDPLLCR_CKSEL_DU_DOTCLKIN(n) ((5 + (n) * 2) << 17)
-#define LVDPLLCR_OCKSEL (1 << 16)
-#define LVDPLLCR_STP_CLKOUTE (1 << 14)
-#define LVDPLLCR_OUTCLKSEL (1 << 12)
-#define LVDPLLCR_CLKOUT (1 << 11)
-#define LVDPLLCR_PLLE(n) ((n) << 10)
-#define LVDPLLCR_PLLN(n) ((n) << 3)
-#define LVDPLLCR_PLLM(n) ((n) << 0)
-
-#define LVDCTRCR 0x000c
-#define LVDCTRCR_CTR3SEL_ZERO (0 << 12)
-#define LVDCTRCR_CTR3SEL_ODD (1 << 12)
-#define LVDCTRCR_CTR3SEL_CDE (2 << 12)
-#define LVDCTRCR_CTR3SEL_MASK (7 << 12)
-#define LVDCTRCR_CTR2SEL_DISP (0 << 8)
-#define LVDCTRCR_CTR2SEL_ODD (1 << 8)
-#define LVDCTRCR_CTR2SEL_CDE (2 << 8)
-#define LVDCTRCR_CTR2SEL_HSYNC (3 << 8)
-#define LVDCTRCR_CTR2SEL_VSYNC (4 << 8)
-#define LVDCTRCR_CTR2SEL_MASK (7 << 8)
-#define LVDCTRCR_CTR1SEL_VSYNC (0 << 4)
-#define LVDCTRCR_CTR1SEL_DISP (1 << 4)
-#define LVDCTRCR_CTR1SEL_ODD (2 << 4)
-#define LVDCTRCR_CTR1SEL_CDE (3 << 4)
-#define LVDCTRCR_CTR1SEL_HSYNC (4 << 4)
-#define LVDCTRCR_CTR1SEL_MASK (7 << 4)
-#define LVDCTRCR_CTR0SEL_HSYNC (0 << 0)
-#define LVDCTRCR_CTR0SEL_VSYNC (1 << 0)
-#define LVDCTRCR_CTR0SEL_DISP (2 << 0)
-#define LVDCTRCR_CTR0SEL_ODD (3 << 0)
-#define LVDCTRCR_CTR0SEL_CDE (4 << 0)
-#define LVDCTRCR_CTR0SEL_MASK (7 << 0)
-
-#define LVDCHCR 0x0010
-#define LVDCHCR_CHSEL_CH(n, c) ((((c) - (n)) & 3) << ((n) * 4))
-#define LVDCHCR_CHSEL_MASK(n) (3 << ((n) * 4))
-
-/* All registers below are specific to D3 and E3 */
-#define LVDSTRIPE 0x0014
-#define LVDSTRIPE_ST_TRGSEL_DISP (0 << 2)
-#define LVDSTRIPE_ST_TRGSEL_HSYNC_R (1 << 2)
-#define LVDSTRIPE_ST_TRGSEL_HSYNC_F (2 << 2)
-#define LVDSTRIPE_ST_SWAP (1 << 1)
-#define LVDSTRIPE_ST_ON (1 << 0)
-
-#define LVDSCR 0x0018
-#define LVDSCR_DEPTH(n) (((n) - 1) << 29)
-#define LVDSCR_BANDSET (1 << 28)
-#define LVDSCR_TWGCNT(n) ((((n) - 256) / 16) << 24)
-#define LVDSCR_SDIV(n) ((n) << 22)
-#define LVDSCR_MODE (1 << 21)
-#define LVDSCR_RSTN (1 << 20)
-
-#define LVDDIV 0x001c
-#define LVDDIV_DIVSEL (1 << 8)
-#define LVDDIV_DIVRESET (1 << 7)
-#define LVDDIV_DIVSTP (1 << 6)
-#define LVDDIV_DIV(n) ((n) << 0)
-
-#endif /* __RCAR_LVDS_REGS_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
deleted file mode 100644
index e10e4d4b89a2..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
+++ /dev/null
@@ -1,1106 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * R-Car MIPI DSI Encoder
- *
- * Copyright (C) 2020 Renesas Electronics Corporation
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/iopoll.h>
-#include <linux/math64.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/of_graph.h>
-#include <linux/platform_device.h>
-#include <linux/reset.h>
-#include <linux/slab.h>
-
-#include <drm/drm_atomic.h>
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_bridge.h>
-#include <drm/drm_mipi_dsi.h>
-#include <drm/drm_of.h>
-#include <drm/drm_panel.h>
-#include <drm/drm_probe_helper.h>
-
-#include "rcar_mipi_dsi.h"
-#include "rcar_mipi_dsi_regs.h"
-
-#define MHZ(v) ((u32)((v) * 1000000U))
-
-enum rcar_mipi_dsi_hw_model {
- RCAR_DSI_V3U,
- RCAR_DSI_V4H,
-};
-
-struct rcar_mipi_dsi_device_info {
- enum rcar_mipi_dsi_hw_model model;
-
- const struct dsi_clk_config *clk_cfg;
-
- u8 clockset2_m_offset;
-
- u8 n_min;
- u8 n_max;
- u8 n_mul;
- unsigned long fpfd_min;
- unsigned long fpfd_max;
- u16 m_min;
- u16 m_max;
- unsigned long fout_min;
- unsigned long fout_max;
-};
-
-struct rcar_mipi_dsi {
- struct device *dev;
- const struct rcar_mipi_dsi_device_info *info;
- struct reset_control *rstc;
-
- struct mipi_dsi_host host;
- struct drm_bridge bridge;
- struct drm_bridge *next_bridge;
- struct drm_connector connector;
-
- void __iomem *mmio;
- struct {
- struct clk *mod;
- struct clk *pll;
- struct clk *dsi;
- } clocks;
-
- enum mipi_dsi_pixel_format format;
- unsigned int num_data_lanes;
- unsigned int lanes;
-};
-
-struct dsi_setup_info {
- unsigned long hsfreq;
- u16 hsfreqrange;
-
- unsigned long fout;
- u16 m;
- u16 n;
- u16 vclk_divider;
- const struct dsi_clk_config *clkset;
-};
-
-static inline struct rcar_mipi_dsi *
-bridge_to_rcar_mipi_dsi(struct drm_bridge *bridge)
-{
- return container_of(bridge, struct rcar_mipi_dsi, bridge);
-}
-
-static inline struct rcar_mipi_dsi *
-host_to_rcar_mipi_dsi(struct mipi_dsi_host *host)
-{
- return container_of(host, struct rcar_mipi_dsi, host);
-}
-
-static const u32 hsfreqrange_table[][2] = {
- { MHZ(80), 0x00 }, { MHZ(90), 0x10 }, { MHZ(100), 0x20 },
- { MHZ(110), 0x30 }, { MHZ(120), 0x01 }, { MHZ(130), 0x11 },
- { MHZ(140), 0x21 }, { MHZ(150), 0x31 }, { MHZ(160), 0x02 },
- { MHZ(170), 0x12 }, { MHZ(180), 0x22 }, { MHZ(190), 0x32 },
- { MHZ(205), 0x03 }, { MHZ(220), 0x13 }, { MHZ(235), 0x23 },
- { MHZ(250), 0x33 }, { MHZ(275), 0x04 }, { MHZ(300), 0x14 },
- { MHZ(325), 0x25 }, { MHZ(350), 0x35 }, { MHZ(400), 0x05 },
- { MHZ(450), 0x16 }, { MHZ(500), 0x26 }, { MHZ(550), 0x37 },
- { MHZ(600), 0x07 }, { MHZ(650), 0x18 }, { MHZ(700), 0x28 },
- { MHZ(750), 0x39 }, { MHZ(800), 0x09 }, { MHZ(850), 0x19 },
- { MHZ(900), 0x29 }, { MHZ(950), 0x3a }, { MHZ(1000), 0x0a },
- { MHZ(1050), 0x1a }, { MHZ(1100), 0x2a }, { MHZ(1150), 0x3b },
- { MHZ(1200), 0x0b }, { MHZ(1250), 0x1b }, { MHZ(1300), 0x2b },
- { MHZ(1350), 0x3c }, { MHZ(1400), 0x0c }, { MHZ(1450), 0x1c },
- { MHZ(1500), 0x2c }, { MHZ(1550), 0x3d }, { MHZ(1600), 0x0d },
- { MHZ(1650), 0x1d }, { MHZ(1700), 0x2e }, { MHZ(1750), 0x3e },
- { MHZ(1800), 0x0e }, { MHZ(1850), 0x1e }, { MHZ(1900), 0x2f },
- { MHZ(1950), 0x3f }, { MHZ(2000), 0x0f }, { MHZ(2050), 0x40 },
- { MHZ(2100), 0x41 }, { MHZ(2150), 0x42 }, { MHZ(2200), 0x43 },
- { MHZ(2250), 0x44 }, { MHZ(2300), 0x45 }, { MHZ(2350), 0x46 },
- { MHZ(2400), 0x47 }, { MHZ(2450), 0x48 }, { MHZ(2500), 0x49 },
- { /* sentinel */ },
-};
-
-struct dsi_clk_config {
- u32 min_freq;
- u32 max_freq;
- u8 vco_cntrl;
- u8 cpbias_cntrl;
- u8 gmp_cntrl;
- u8 int_cntrl;
- u8 prop_cntrl;
-};
-
-static const struct dsi_clk_config dsi_clk_cfg_v3u[] = {
- { MHZ(40), MHZ(55), 0x3f, 0x10, 0x01, 0x00, 0x0b },
- { MHZ(52.5), MHZ(80), 0x39, 0x10, 0x01, 0x00, 0x0b },
- { MHZ(80), MHZ(110), 0x2f, 0x10, 0x01, 0x00, 0x0b },
- { MHZ(105), MHZ(160), 0x29, 0x10, 0x01, 0x00, 0x0b },
- { MHZ(160), MHZ(220), 0x1f, 0x10, 0x01, 0x00, 0x0b },
- { MHZ(210), MHZ(320), 0x19, 0x10, 0x01, 0x00, 0x0b },
- { MHZ(320), MHZ(440), 0x0f, 0x10, 0x01, 0x00, 0x0b },
- { MHZ(420), MHZ(660), 0x09, 0x10, 0x01, 0x00, 0x0b },
- { MHZ(630), MHZ(1149), 0x03, 0x10, 0x01, 0x00, 0x0b },
- { MHZ(1100), MHZ(1152), 0x01, 0x10, 0x01, 0x00, 0x0b },
- { MHZ(1150), MHZ(1250), 0x01, 0x10, 0x01, 0x00, 0x0c },
- { /* sentinel */ },
-};
-
-static const struct dsi_clk_config dsi_clk_cfg_v4h[] = {
- { MHZ(40), MHZ(45.31), 0x2b, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(45.31), MHZ(54.66), 0x28, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(54.66), MHZ(62.5), 0x28, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(62.5), MHZ(75), 0x27, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(75), MHZ(90.63), 0x23, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(90.63), MHZ(109.37), 0x20, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(109.37), MHZ(125), 0x20, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(125), MHZ(150), 0x1f, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(150), MHZ(181.25), 0x1b, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(181.25), MHZ(218.75), 0x18, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(218.75), MHZ(250), 0x18, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(250), MHZ(300), 0x17, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(300), MHZ(362.5), 0x13, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(362.5), MHZ(455.48), 0x10, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(455.48), MHZ(500), 0x10, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(500), MHZ(600), 0x0f, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(600), MHZ(725), 0x0b, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(725), MHZ(875), 0x08, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(875), MHZ(1000), 0x08, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(1000), MHZ(1200), 0x07, 0x00, 0x00, 0x08, 0x0a },
- { MHZ(1200), MHZ(1250), 0x03, 0x00, 0x00, 0x08, 0x0a },
- { /* sentinel */ },
-};
-
-static void rcar_mipi_dsi_write(struct rcar_mipi_dsi *dsi, u32 reg, u32 data)
-{
- iowrite32(data, dsi->mmio + reg);
-}
-
-static u32 rcar_mipi_dsi_read(struct rcar_mipi_dsi *dsi, u32 reg)
-{
- return ioread32(dsi->mmio + reg);
-}
-
-static void rcar_mipi_dsi_clr(struct rcar_mipi_dsi *dsi, u32 reg, u32 clr)
-{
- rcar_mipi_dsi_write(dsi, reg, rcar_mipi_dsi_read(dsi, reg) & ~clr);
-}
-
-static void rcar_mipi_dsi_set(struct rcar_mipi_dsi *dsi, u32 reg, u32 set)
-{
- rcar_mipi_dsi_write(dsi, reg, rcar_mipi_dsi_read(dsi, reg) | set);
-}
-
-static int rcar_mipi_dsi_write_phtw(struct rcar_mipi_dsi *dsi, u32 phtw)
-{
- u32 status;
- int ret;
-
- rcar_mipi_dsi_write(dsi, PHTW, phtw);
-
- ret = read_poll_timeout(rcar_mipi_dsi_read, status,
- !(status & (PHTW_DWEN | PHTW_CWEN)),
- 2000, 10000, false, dsi, PHTW);
- if (ret < 0) {
- dev_err(dsi->dev, "PHY test interface write timeout (0x%08x)\n",
- phtw);
- return ret;
- }
-
- return ret;
-}
-
-static int rcar_mipi_dsi_write_phtw_arr(struct rcar_mipi_dsi *dsi,
- const u32 *phtw, unsigned int size)
-{
- for (unsigned int i = 0; i < size; i++) {
- int ret = rcar_mipi_dsi_write_phtw(dsi, phtw[i]);
-
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-
-#define WRITE_PHTW(...) \
- ({ \
- static const u32 phtw[] = { __VA_ARGS__ }; \
- int ret; \
- ret = rcar_mipi_dsi_write_phtw_arr(dsi, phtw, \
- ARRAY_SIZE(phtw)); \
- ret; \
- })
-
-static int rcar_mipi_dsi_init_phtw_v3u(struct rcar_mipi_dsi *dsi)
-{
- return WRITE_PHTW(0x01020114, 0x01600115, 0x01030116, 0x0102011d,
- 0x011101a4, 0x018601a4, 0x014201a0, 0x010001a3,
- 0x0101011f);
-}
-
-static int rcar_mipi_dsi_post_init_phtw_v3u(struct rcar_mipi_dsi *dsi)
-{
- return WRITE_PHTW(0x010c0130, 0x010c0140, 0x010c0150, 0x010c0180,
- 0x010c0190, 0x010a0160, 0x010a0170, 0x01800164,
- 0x01800174);
-}
-
-static int rcar_mipi_dsi_init_phtw_v4h(struct rcar_mipi_dsi *dsi,
- const struct dsi_setup_info *setup_info)
-{
- int ret;
-
- if (setup_info->hsfreq < MHZ(450)) {
- ret = WRITE_PHTW(0x01010100, 0x011b01ac);
- if (ret)
- return ret;
- }
-
- ret = WRITE_PHTW(0x01010100, 0x01030173, 0x01000174, 0x01500175,
- 0x01030176, 0x01040166, 0x010201ad);
- if (ret)
- return ret;
-
- if (setup_info->hsfreq <= MHZ(1000))
- ret = WRITE_PHTW(0x01020100, 0x01910170, 0x01020171,
- 0x01110172);
- else if (setup_info->hsfreq <= MHZ(1500))
- ret = WRITE_PHTW(0x01020100, 0x01980170, 0x01030171,
- 0x01100172);
- else if (setup_info->hsfreq <= MHZ(2500))
- ret = WRITE_PHTW(0x01020100, 0x0144016b, 0x01000172);
- else
- return -EINVAL;
-
- if (ret)
- return ret;
-
- if (dsi->lanes <= 1) {
- ret = WRITE_PHTW(0x01070100, 0x010e010b);
- if (ret)
- return ret;
- }
-
- if (dsi->lanes <= 2) {
- ret = WRITE_PHTW(0x01090100, 0x010e010b);
- if (ret)
- return ret;
- }
-
- if (dsi->lanes <= 3) {
- ret = WRITE_PHTW(0x010b0100, 0x010e010b);
- if (ret)
- return ret;
- }
-
- if (setup_info->hsfreq <= MHZ(1500)) {
- ret = WRITE_PHTW(0x01010100, 0x01c0016e);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static int
-rcar_mipi_dsi_post_init_phtw_v4h(struct rcar_mipi_dsi *dsi,
- const struct dsi_setup_info *setup_info)
-{
- u32 status;
- int ret;
-
- if (setup_info->hsfreq <= MHZ(1500)) {
- WRITE_PHTW(0x01020100, 0x00000180);
-
- ret = read_poll_timeout(rcar_mipi_dsi_read, status,
- status & PHTR_TEST, 2000, 10000, false,
- dsi, PHTR);
- if (ret < 0) {
- dev_err(dsi->dev, "failed to test PHTR\n");
- return ret;
- }
-
- WRITE_PHTW(0x01010100, 0x0100016e);
- }
-
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Hardware Setup
- */
-
-static void rcar_mipi_dsi_pll_calc(struct rcar_mipi_dsi *dsi,
- unsigned long fin_rate,
- unsigned long fout_target,
- struct dsi_setup_info *setup_info)
-{
- unsigned int best_err = -1;
- const struct rcar_mipi_dsi_device_info *info = dsi->info;
-
- for (unsigned int n = info->n_min; n <= info->n_max; n++) {
- unsigned long fpfd;
-
- fpfd = fin_rate / n;
-
- if (fpfd < info->fpfd_min || fpfd > info->fpfd_max)
- continue;
-
- for (unsigned int m = info->m_min; m <= info->m_max; m++) {
- unsigned int err;
- u64 fout;
-
- fout = div64_u64((u64)fpfd * m, dsi->info->n_mul);
-
- if (fout < info->fout_min || fout > info->fout_max)
- continue;
-
- fout = div64_u64(fout, setup_info->vclk_divider);
-
- if (fout < setup_info->clkset->min_freq ||
- fout > setup_info->clkset->max_freq)
- continue;
-
- err = abs((long)(fout - fout_target) * 10000 /
- (long)fout_target);
- if (err < best_err) {
- setup_info->m = m;
- setup_info->n = n;
- setup_info->fout = (unsigned long)fout;
- best_err = err;
-
- if (err == 0)
- return;
- }
- }
- }
-}
-
-static void rcar_mipi_dsi_parameters_calc(struct rcar_mipi_dsi *dsi,
- struct clk *clk, unsigned long target,
- struct dsi_setup_info *setup_info)
-{
-
- const struct dsi_clk_config *clk_cfg;
- unsigned long fout_target;
- unsigned long fin_rate;
- unsigned int i;
- unsigned int err;
-
- /*
- * Calculate Fout = dot clock * ColorDepth / (2 * Lane Count)
- * The range out Fout is [40 - 1250] Mhz
- */
- fout_target = target * mipi_dsi_pixel_format_to_bpp(dsi->format)
- / (2 * dsi->lanes);
- if (fout_target < MHZ(40) || fout_target > MHZ(1250))
- return;
-
- /* Find PLL settings */
- for (clk_cfg = dsi->info->clk_cfg; clk_cfg->min_freq != 0; clk_cfg++) {
- if (fout_target > clk_cfg->min_freq &&
- fout_target <= clk_cfg->max_freq) {
- setup_info->clkset = clk_cfg;
- break;
- }
- }
-
- fin_rate = clk_get_rate(clk);
-
- switch (dsi->info->model) {
- case RCAR_DSI_V3U:
- default:
- setup_info->vclk_divider = 1 << ((clk_cfg->vco_cntrl >> 4) & 0x3);
- break;
-
- case RCAR_DSI_V4H:
- setup_info->vclk_divider = 1 << (((clk_cfg->vco_cntrl >> 3) & 0x7) + 1);
- break;
- }
-
- rcar_mipi_dsi_pll_calc(dsi, fin_rate, fout_target, setup_info);
-
- /* Find hsfreqrange */
- setup_info->hsfreq = setup_info->fout * 2;
- for (i = 0; i < ARRAY_SIZE(hsfreqrange_table); i++) {
- if (hsfreqrange_table[i][0] >= setup_info->hsfreq) {
- setup_info->hsfreqrange = hsfreqrange_table[i][1];
- break;
- }
- }
-
- err = abs((long)(setup_info->fout - fout_target) * 10000 / (long)fout_target);
-
- dev_dbg(dsi->dev,
- "Fout = %u * %lu / (%u * %u * %u) = %lu (target %lu Hz, error %d.%02u%%)\n",
- setup_info->m, fin_rate, dsi->info->n_mul, setup_info->n,
- setup_info->vclk_divider, setup_info->fout, fout_target,
- err / 100, err % 100);
-
- dev_dbg(dsi->dev,
- "vco_cntrl = 0x%x\tprop_cntrl = 0x%x\thsfreqrange = 0x%x\n",
- clk_cfg->vco_cntrl, clk_cfg->prop_cntrl,
- setup_info->hsfreqrange);
-}
-
-static void rcar_mipi_dsi_set_display_timing(struct rcar_mipi_dsi *dsi,
- const struct drm_display_mode *mode)
-{
- u32 setr;
- u32 vprmset0r;
- u32 vprmset1r;
- u32 vprmset2r;
- u32 vprmset3r;
- u32 vprmset4r;
-
- /* Configuration for Pixel Stream and Packet Header */
- if (mipi_dsi_pixel_format_to_bpp(dsi->format) == 24)
- rcar_mipi_dsi_write(dsi, TXVMPSPHSETR, TXVMPSPHSETR_DT_RGB24);
- else if (mipi_dsi_pixel_format_to_bpp(dsi->format) == 18)
- rcar_mipi_dsi_write(dsi, TXVMPSPHSETR, TXVMPSPHSETR_DT_RGB18);
- else if (mipi_dsi_pixel_format_to_bpp(dsi->format) == 16)
- rcar_mipi_dsi_write(dsi, TXVMPSPHSETR, TXVMPSPHSETR_DT_RGB16);
- else {
- dev_warn(dsi->dev, "unsupported format");
- return;
- }
-
- /* Configuration for Blanking sequence and Input Pixel */
- setr = TXVMSETR_HSABPEN_EN | TXVMSETR_HBPBPEN_EN
- | TXVMSETR_HFPBPEN_EN | TXVMSETR_SYNSEQ_PULSES
- | TXVMSETR_PIXWDTH | TXVMSETR_VSTPM;
- rcar_mipi_dsi_write(dsi, TXVMSETR, setr);
-
- /* Configuration for Video Parameters */
- vprmset0r = (mode->flags & DRM_MODE_FLAG_PVSYNC ?
- TXVMVPRMSET0R_VSPOL_HIG : TXVMVPRMSET0R_VSPOL_LOW)
- | (mode->flags & DRM_MODE_FLAG_PHSYNC ?
- TXVMVPRMSET0R_HSPOL_HIG : TXVMVPRMSET0R_HSPOL_LOW)
- | TXVMVPRMSET0R_CSPC_RGB | TXVMVPRMSET0R_BPP_24;
-
- vprmset1r = TXVMVPRMSET1R_VACTIVE(mode->vdisplay)
- | TXVMVPRMSET1R_VSA(mode->vsync_end - mode->vsync_start);
-
- vprmset2r = TXVMVPRMSET2R_VFP(mode->vsync_start - mode->vdisplay)
- | TXVMVPRMSET2R_VBP(mode->vtotal - mode->vsync_end);
-
- vprmset3r = TXVMVPRMSET3R_HACTIVE(mode->hdisplay)
- | TXVMVPRMSET3R_HSA(mode->hsync_end - mode->hsync_start);
-
- vprmset4r = TXVMVPRMSET4R_HFP(mode->hsync_start - mode->hdisplay)
- | TXVMVPRMSET4R_HBP(mode->htotal - mode->hsync_end);
-
- rcar_mipi_dsi_write(dsi, TXVMVPRMSET0R, vprmset0r);
- rcar_mipi_dsi_write(dsi, TXVMVPRMSET1R, vprmset1r);
- rcar_mipi_dsi_write(dsi, TXVMVPRMSET2R, vprmset2r);
- rcar_mipi_dsi_write(dsi, TXVMVPRMSET3R, vprmset3r);
- rcar_mipi_dsi_write(dsi, TXVMVPRMSET4R, vprmset4r);
-}
-
-static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,
- const struct drm_display_mode *mode)
-{
- struct dsi_setup_info setup_info = {};
- unsigned int timeout;
- int ret;
- int dsi_format;
- u32 phy_setup;
- u32 clockset2, clockset3;
- u32 ppisetr;
- u32 vclkset;
-
- /* Checking valid format */
- dsi_format = mipi_dsi_pixel_format_to_bpp(dsi->format);
- if (dsi_format < 0) {
- dev_warn(dsi->dev, "invalid format");
- return -EINVAL;
- }
-
- /* Parameters Calculation */
- rcar_mipi_dsi_parameters_calc(dsi, dsi->clocks.pll,
- mode->clock * 1000, &setup_info);
-
- /* LPCLK enable */
- rcar_mipi_dsi_set(dsi, LPCLKSET, LPCLKSET_CKEN);
-
- /* CFGCLK enabled */
- rcar_mipi_dsi_set(dsi, CFGCLKSET, CFGCLKSET_CKEN);
-
- rcar_mipi_dsi_clr(dsi, PHYSETUP, PHYSETUP_RSTZ);
- rcar_mipi_dsi_clr(dsi, PHYSETUP, PHYSETUP_SHUTDOWNZ);
-
- rcar_mipi_dsi_set(dsi, PHTC, PHTC_TESTCLR);
- rcar_mipi_dsi_clr(dsi, PHTC, PHTC_TESTCLR);
-
- /* PHY setting */
- phy_setup = rcar_mipi_dsi_read(dsi, PHYSETUP);
- phy_setup &= ~PHYSETUP_HSFREQRANGE_MASK;
- phy_setup |= PHYSETUP_HSFREQRANGE(setup_info.hsfreqrange);
- rcar_mipi_dsi_write(dsi, PHYSETUP, phy_setup);
-
- switch (dsi->info->model) {
- case RCAR_DSI_V3U:
- default:
- ret = rcar_mipi_dsi_init_phtw_v3u(dsi);
- if (ret < 0)
- return ret;
- break;
-
- case RCAR_DSI_V4H:
- ret = rcar_mipi_dsi_init_phtw_v4h(dsi, &setup_info);
- if (ret < 0)
- return ret;
- break;
- }
-
- /* PLL Clock Setting */
- rcar_mipi_dsi_clr(dsi, CLOCKSET1, CLOCKSET1_SHADOW_CLEAR);
- rcar_mipi_dsi_set(dsi, CLOCKSET1, CLOCKSET1_SHADOW_CLEAR);
- rcar_mipi_dsi_clr(dsi, CLOCKSET1, CLOCKSET1_SHADOW_CLEAR);
-
- clockset2 = CLOCKSET2_M(setup_info.m - dsi->info->clockset2_m_offset)
- | CLOCKSET2_N(setup_info.n - 1)
- | CLOCKSET2_VCO_CNTRL(setup_info.clkset->vco_cntrl);
- clockset3 = CLOCKSET3_PROP_CNTRL(setup_info.clkset->prop_cntrl)
- | CLOCKSET3_INT_CNTRL(setup_info.clkset->int_cntrl)
- | CLOCKSET3_CPBIAS_CNTRL(setup_info.clkset->cpbias_cntrl)
- | CLOCKSET3_GMP_CNTRL(setup_info.clkset->gmp_cntrl);
- rcar_mipi_dsi_write(dsi, CLOCKSET2, clockset2);
- rcar_mipi_dsi_write(dsi, CLOCKSET3, clockset3);
-
- rcar_mipi_dsi_clr(dsi, CLOCKSET1, CLOCKSET1_UPDATEPLL);
- rcar_mipi_dsi_set(dsi, CLOCKSET1, CLOCKSET1_UPDATEPLL);
- udelay(10);
- rcar_mipi_dsi_clr(dsi, CLOCKSET1, CLOCKSET1_UPDATEPLL);
-
- ppisetr = PPISETR_DLEN_3 | PPISETR_CLEN;
- rcar_mipi_dsi_write(dsi, PPISETR, ppisetr);
-
- rcar_mipi_dsi_set(dsi, PHYSETUP, PHYSETUP_SHUTDOWNZ);
- rcar_mipi_dsi_set(dsi, PHYSETUP, PHYSETUP_RSTZ);
- usleep_range(400, 500);
-
- /* Checking PPI clock status register */
- for (timeout = 10; timeout > 0; --timeout) {
- if ((rcar_mipi_dsi_read(dsi, PPICLSR) & PPICLSR_STPST) &&
- (rcar_mipi_dsi_read(dsi, PPIDLSR) & PPIDLSR_STPST) &&
- (rcar_mipi_dsi_read(dsi, CLOCKSET1) & CLOCKSET1_LOCK))
- break;
-
- usleep_range(1000, 2000);
- }
-
- if (!timeout) {
- dev_err(dsi->dev, "failed to enable PPI clock\n");
- return -ETIMEDOUT;
- }
-
- switch (dsi->info->model) {
- case RCAR_DSI_V3U:
- default:
- ret = rcar_mipi_dsi_post_init_phtw_v3u(dsi);
- if (ret < 0)
- return ret;
- break;
-
- case RCAR_DSI_V4H:
- ret = rcar_mipi_dsi_post_init_phtw_v4h(dsi, &setup_info);
- if (ret < 0)
- return ret;
- break;
- }
-
- /* Enable DOT clock */
- vclkset = VCLKSET_CKEN;
- rcar_mipi_dsi_write(dsi, VCLKSET, vclkset);
-
- if (dsi_format == 24)
- vclkset |= VCLKSET_BPP_24;
- else if (dsi_format == 18)
- vclkset |= VCLKSET_BPP_18;
- else if (dsi_format == 16)
- vclkset |= VCLKSET_BPP_16;
- else {
- dev_warn(dsi->dev, "unsupported format");
- return -EINVAL;
- }
-
- vclkset |= VCLKSET_COLOR_RGB | VCLKSET_LANE(dsi->lanes - 1);
-
- switch (dsi->info->model) {
- case RCAR_DSI_V3U:
- default:
- vclkset |= VCLKSET_DIV_V3U(__ffs(setup_info.vclk_divider));
- break;
-
- case RCAR_DSI_V4H:
- vclkset |= VCLKSET_DIV_V4H(__ffs(setup_info.vclk_divider) - 1);
- break;
- }
-
- rcar_mipi_dsi_write(dsi, VCLKSET, vclkset);
-
- /* After setting VCLKSET register, enable VCLKEN */
- rcar_mipi_dsi_set(dsi, VCLKEN, VCLKEN_CKEN);
-
- dev_dbg(dsi->dev, "DSI device is started\n");
-
- return 0;
-}
-
-static void rcar_mipi_dsi_shutdown(struct rcar_mipi_dsi *dsi)
-{
- /* Disable VCLKEN */
- rcar_mipi_dsi_write(dsi, VCLKSET, 0);
-
- /* Disable DOT clock */
- rcar_mipi_dsi_write(dsi, VCLKSET, 0);
-
- rcar_mipi_dsi_clr(dsi, PHYSETUP, PHYSETUP_RSTZ);
- rcar_mipi_dsi_clr(dsi, PHYSETUP, PHYSETUP_SHUTDOWNZ);
-
- /* CFGCLK disable */
- rcar_mipi_dsi_clr(dsi, CFGCLKSET, CFGCLKSET_CKEN);
-
- /* LPCLK disable */
- rcar_mipi_dsi_clr(dsi, LPCLKSET, LPCLKSET_CKEN);
-
- dev_dbg(dsi->dev, "DSI device is shutdown\n");
-}
-
-static int rcar_mipi_dsi_clk_enable(struct rcar_mipi_dsi *dsi)
-{
- int ret;
-
- reset_control_deassert(dsi->rstc);
-
- ret = clk_prepare_enable(dsi->clocks.mod);
- if (ret < 0)
- goto err_reset;
-
- ret = clk_prepare_enable(dsi->clocks.dsi);
- if (ret < 0)
- goto err_clock;
-
- return 0;
-
-err_clock:
- clk_disable_unprepare(dsi->clocks.mod);
-err_reset:
- reset_control_assert(dsi->rstc);
- return ret;
-}
-
-static void rcar_mipi_dsi_clk_disable(struct rcar_mipi_dsi *dsi)
-{
- clk_disable_unprepare(dsi->clocks.dsi);
- clk_disable_unprepare(dsi->clocks.mod);
-
- reset_control_assert(dsi->rstc);
-}
-
-static int rcar_mipi_dsi_start_hs_clock(struct rcar_mipi_dsi *dsi)
-{
- /*
- * In HW manual, we need to check TxDDRClkHS-Q Stable? but it dont
- * write how to check. So we skip this check in this patch
- */
- u32 status;
- int ret;
-
- /* Start HS clock. */
- rcar_mipi_dsi_set(dsi, PPICLCR, PPICLCR_TXREQHS);
-
- ret = read_poll_timeout(rcar_mipi_dsi_read, status,
- status & PPICLSR_TOHS,
- 2000, 10000, false, dsi, PPICLSR);
- if (ret < 0) {
- dev_err(dsi->dev, "failed to enable HS clock\n");
- return ret;
- }
-
- rcar_mipi_dsi_set(dsi, PPICLSCR, PPICLSCR_TOHS);
-
- return 0;
-}
-
-static int rcar_mipi_dsi_start_video(struct rcar_mipi_dsi *dsi)
-{
- u32 status;
- int ret;
-
- /* Wait for the link to be ready. */
- ret = read_poll_timeout(rcar_mipi_dsi_read, status,
- !(status & (LINKSR_LPBUSY | LINKSR_HSBUSY)),
- 2000, 10000, false, dsi, LINKSR);
- if (ret < 0) {
- dev_err(dsi->dev, "Link failed to become ready\n");
- return ret;
- }
-
- /* De-assert video FIFO clear. */
- rcar_mipi_dsi_clr(dsi, TXVMCR, TXVMCR_VFCLR);
-
- ret = read_poll_timeout(rcar_mipi_dsi_read, status,
- status & TXVMSR_VFRDY,
- 2000, 10000, false, dsi, TXVMSR);
- if (ret < 0) {
- dev_err(dsi->dev, "Failed to de-assert video FIFO clear\n");
- return ret;
- }
-
- /* Enable transmission in video mode. */
- rcar_mipi_dsi_set(dsi, TXVMCR, TXVMCR_EN_VIDEO);
-
- ret = read_poll_timeout(rcar_mipi_dsi_read, status,
- status & TXVMSR_RDY,
- 2000, 10000, false, dsi, TXVMSR);
- if (ret < 0) {
- dev_err(dsi->dev, "Failed to enable video transmission\n");
- return ret;
- }
-
- return 0;
-}
-
-static void rcar_mipi_dsi_stop_video(struct rcar_mipi_dsi *dsi)
-{
- u32 status;
- int ret;
-
- /* Disable transmission in video mode. */
- rcar_mipi_dsi_clr(dsi, TXVMCR, TXVMCR_EN_VIDEO);
-
- ret = read_poll_timeout(rcar_mipi_dsi_read, status,
- !(status & TXVMSR_ACT),
- 2000, 100000, false, dsi, TXVMSR);
- if (ret < 0) {
- dev_err(dsi->dev, "Failed to disable video transmission\n");
- return;
- }
-
- /* Assert video FIFO clear. */
- rcar_mipi_dsi_set(dsi, TXVMCR, TXVMCR_VFCLR);
-
- ret = read_poll_timeout(rcar_mipi_dsi_read, status,
- !(status & TXVMSR_VFRDY),
- 2000, 100000, false, dsi, TXVMSR);
- if (ret < 0) {
- dev_err(dsi->dev, "Failed to assert video FIFO clear\n");
- return;
- }
-}
-
-/* -----------------------------------------------------------------------------
- * Bridge
- */
-
-static int rcar_mipi_dsi_attach(struct drm_bridge *bridge,
- enum drm_bridge_attach_flags flags)
-{
- struct rcar_mipi_dsi *dsi = bridge_to_rcar_mipi_dsi(bridge);
-
- return drm_bridge_attach(bridge->encoder, dsi->next_bridge, bridge,
- flags);
-}
-
-static void rcar_mipi_dsi_atomic_enable(struct drm_bridge *bridge,
- struct drm_bridge_state *old_bridge_state)
-{
- struct rcar_mipi_dsi *dsi = bridge_to_rcar_mipi_dsi(bridge);
-
- rcar_mipi_dsi_start_video(dsi);
-}
-
-static void rcar_mipi_dsi_atomic_disable(struct drm_bridge *bridge,
- struct drm_bridge_state *old_bridge_state)
-{
- struct rcar_mipi_dsi *dsi = bridge_to_rcar_mipi_dsi(bridge);
-
- rcar_mipi_dsi_stop_video(dsi);
-}
-
-void rcar_mipi_dsi_pclk_enable(struct drm_bridge *bridge,
- struct drm_atomic_state *state)
-{
- struct rcar_mipi_dsi *dsi = bridge_to_rcar_mipi_dsi(bridge);
- const struct drm_display_mode *mode;
- struct drm_connector *connector;
- struct drm_crtc *crtc;
- int ret;
-
- connector = drm_atomic_get_new_connector_for_encoder(state,
- bridge->encoder);
- crtc = drm_atomic_get_new_connector_state(state, connector)->crtc;
- mode = &drm_atomic_get_new_crtc_state(state, crtc)->adjusted_mode;
-
- ret = rcar_mipi_dsi_clk_enable(dsi);
- if (ret < 0) {
- dev_err(dsi->dev, "failed to enable DSI clocks\n");
- return;
- }
-
- ret = rcar_mipi_dsi_startup(dsi, mode);
- if (ret < 0)
- goto err_dsi_startup;
-
- rcar_mipi_dsi_set_display_timing(dsi, mode);
-
- ret = rcar_mipi_dsi_start_hs_clock(dsi);
- if (ret < 0)
- goto err_dsi_start_hs;
-
- return;
-
-err_dsi_start_hs:
- rcar_mipi_dsi_shutdown(dsi);
-err_dsi_startup:
- rcar_mipi_dsi_clk_disable(dsi);
-}
-EXPORT_SYMBOL_GPL(rcar_mipi_dsi_pclk_enable);
-
-void rcar_mipi_dsi_pclk_disable(struct drm_bridge *bridge)
-{
- struct rcar_mipi_dsi *dsi = bridge_to_rcar_mipi_dsi(bridge);
-
- rcar_mipi_dsi_shutdown(dsi);
- rcar_mipi_dsi_clk_disable(dsi);
-}
-EXPORT_SYMBOL_GPL(rcar_mipi_dsi_pclk_disable);
-
-static enum drm_mode_status
-rcar_mipi_dsi_bridge_mode_valid(struct drm_bridge *bridge,
- const struct drm_display_info *info,
- const struct drm_display_mode *mode)
-{
- if (mode->clock > 297000)
- return MODE_CLOCK_HIGH;
-
- return MODE_OK;
-}
-
-static const struct drm_bridge_funcs rcar_mipi_dsi_bridge_ops = {
- .attach = rcar_mipi_dsi_attach,
- .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
- .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
- .atomic_reset = drm_atomic_helper_bridge_reset,
- .atomic_enable = rcar_mipi_dsi_atomic_enable,
- .atomic_disable = rcar_mipi_dsi_atomic_disable,
- .mode_valid = rcar_mipi_dsi_bridge_mode_valid,
-};
-
-/* -----------------------------------------------------------------------------
- * Host setting
- */
-
-static int rcar_mipi_dsi_host_attach(struct mipi_dsi_host *host,
- struct mipi_dsi_device *device)
-{
- struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
- int ret;
-
- if (device->lanes > dsi->num_data_lanes)
- return -EINVAL;
-
- dsi->lanes = device->lanes;
- dsi->format = device->format;
-
- dsi->next_bridge = devm_drm_of_get_bridge(dsi->dev, dsi->dev->of_node,
- 1, 0);
- if (IS_ERR(dsi->next_bridge)) {
- ret = PTR_ERR(dsi->next_bridge);
- dev_err(dsi->dev, "failed to get next bridge: %d\n", ret);
- return ret;
- }
-
- /* Initialize the DRM bridge. */
- dsi->bridge.funcs = &rcar_mipi_dsi_bridge_ops;
- dsi->bridge.of_node = dsi->dev->of_node;
- drm_bridge_add(&dsi->bridge);
-
- return 0;
-}
-
-static int rcar_mipi_dsi_host_detach(struct mipi_dsi_host *host,
- struct mipi_dsi_device *device)
-{
- struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
-
- drm_bridge_remove(&dsi->bridge);
-
- return 0;
-}
-
-static const struct mipi_dsi_host_ops rcar_mipi_dsi_host_ops = {
- .attach = rcar_mipi_dsi_host_attach,
- .detach = rcar_mipi_dsi_host_detach,
-};
-
-/* -----------------------------------------------------------------------------
- * Probe & Remove
- */
-
-static int rcar_mipi_dsi_parse_dt(struct rcar_mipi_dsi *dsi)
-{
- int ret;
-
- ret = drm_of_get_data_lanes_count_ep(dsi->dev->of_node, 1, 0, 1, 4);
- if (ret < 0) {
- dev_err(dsi->dev, "missing or invalid data-lanes property\n");
- return ret;
- }
-
- dsi->num_data_lanes = ret;
- return 0;
-}
-
-static struct clk *rcar_mipi_dsi_get_clock(struct rcar_mipi_dsi *dsi,
- const char *name,
- bool optional)
-{
- struct clk *clk;
-
- clk = devm_clk_get(dsi->dev, name);
- if (!IS_ERR(clk))
- return clk;
-
- if (PTR_ERR(clk) == -ENOENT && optional)
- return NULL;
-
- dev_err_probe(dsi->dev, PTR_ERR(clk), "failed to get %s clock\n",
- name ? name : "module");
-
- return clk;
-}
-
-static int rcar_mipi_dsi_get_clocks(struct rcar_mipi_dsi *dsi)
-{
- dsi->clocks.mod = rcar_mipi_dsi_get_clock(dsi, NULL, false);
- if (IS_ERR(dsi->clocks.mod))
- return PTR_ERR(dsi->clocks.mod);
-
- dsi->clocks.pll = rcar_mipi_dsi_get_clock(dsi, "pll", true);
- if (IS_ERR(dsi->clocks.pll))
- return PTR_ERR(dsi->clocks.pll);
-
- dsi->clocks.dsi = rcar_mipi_dsi_get_clock(dsi, "dsi", true);
- if (IS_ERR(dsi->clocks.dsi))
- return PTR_ERR(dsi->clocks.dsi);
-
- if (!dsi->clocks.pll && !dsi->clocks.dsi) {
- dev_err(dsi->dev, "no input clock (pll, dsi)\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int rcar_mipi_dsi_probe(struct platform_device *pdev)
-{
- struct rcar_mipi_dsi *dsi;
- struct resource *mem;
- int ret;
-
- dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL);
- if (dsi == NULL)
- return -ENOMEM;
-
- platform_set_drvdata(pdev, dsi);
-
- dsi->dev = &pdev->dev;
- dsi->info = of_device_get_match_data(&pdev->dev);
-
- ret = rcar_mipi_dsi_parse_dt(dsi);
- if (ret < 0)
- return ret;
-
- /* Acquire resources. */
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- dsi->mmio = devm_ioremap_resource(dsi->dev, mem);
- if (IS_ERR(dsi->mmio))
- return PTR_ERR(dsi->mmio);
-
- ret = rcar_mipi_dsi_get_clocks(dsi);
- if (ret < 0)
- return ret;
-
- dsi->rstc = devm_reset_control_get(dsi->dev, NULL);
- if (IS_ERR(dsi->rstc)) {
- dev_err(dsi->dev, "failed to get cpg reset\n");
- return PTR_ERR(dsi->rstc);
- }
-
- /* Initialize the DSI host. */
- dsi->host.dev = dsi->dev;
- dsi->host.ops = &rcar_mipi_dsi_host_ops;
- ret = mipi_dsi_host_register(&dsi->host);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int rcar_mipi_dsi_remove(struct platform_device *pdev)
-{
- struct rcar_mipi_dsi *dsi = platform_get_drvdata(pdev);
-
- mipi_dsi_host_unregister(&dsi->host);
-
- return 0;
-}
-
-static const struct rcar_mipi_dsi_device_info v3u_data = {
- .model = RCAR_DSI_V3U,
- .clk_cfg = dsi_clk_cfg_v3u,
- .clockset2_m_offset = 2,
- .n_min = 3,
- .n_max = 8,
- .n_mul = 1,
- .fpfd_min = MHZ(2),
- .fpfd_max = MHZ(8),
- .m_min = 64,
- .m_max = 625,
- .fout_min = MHZ(320),
- .fout_max = MHZ(1250),
-};
-
-static const struct rcar_mipi_dsi_device_info v4h_data = {
- .model = RCAR_DSI_V4H,
- .clk_cfg = dsi_clk_cfg_v4h,
- .clockset2_m_offset = 0,
- .n_min = 1,
- .n_max = 8,
- .n_mul = 2,
- .fpfd_min = MHZ(8),
- .fpfd_max = MHZ(24),
- .m_min = 167,
- .m_max = 1000,
- .fout_min = MHZ(2000),
- .fout_max = MHZ(4000),
-};
-
-static const struct of_device_id rcar_mipi_dsi_of_table[] = {
- { .compatible = "renesas,r8a779a0-dsi-csi2-tx", .data = &v3u_data },
- { .compatible = "renesas,r8a779g0-dsi-csi2-tx", .data = &v4h_data },
- { }
-};
-
-MODULE_DEVICE_TABLE(of, rcar_mipi_dsi_of_table);
-
-static struct platform_driver rcar_mipi_dsi_platform_driver = {
- .probe = rcar_mipi_dsi_probe,
- .remove = rcar_mipi_dsi_remove,
- .driver = {
- .name = "rcar-mipi-dsi",
- .of_match_table = rcar_mipi_dsi_of_table,
- },
-};
-
-module_platform_driver(rcar_mipi_dsi_platform_driver);
-
-MODULE_DESCRIPTION("Renesas R-Car MIPI DSI Encoder Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.h b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.h
deleted file mode 100644
index 528a196e6edd..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * R-Car DSI Encoder
- *
- * Copyright (C) 2022 Renesas Electronics Corporation
- *
- * Contact: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
- */
-
-#ifndef __RCAR_MIPI_DSI_H__
-#define __RCAR_MIPI_DSI_H__
-
-struct drm_atomic_state;
-struct drm_bridge;
-
-#if IS_ENABLED(CONFIG_DRM_RCAR_MIPI_DSI)
-void rcar_mipi_dsi_pclk_enable(struct drm_bridge *bridge,
- struct drm_atomic_state *state);
-void rcar_mipi_dsi_pclk_disable(struct drm_bridge *bridge);
-#else
-static inline void rcar_mipi_dsi_pclk_enable(struct drm_bridge *bridge,
- struct drm_atomic_state *state)
-{
-}
-
-static inline void rcar_mipi_dsi_pclk_disable(struct drm_bridge *bridge)
-{
-}
-#endif /* CONFIG_DRM_RCAR_MIPI_DSI */
-
-#endif /* __RCAR_MIPI_DSI_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h
deleted file mode 100644
index f8114d11f2d1..000000000000
--- a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * R-Car MIPI DSI Interface Registers Definitions
- *
- * Copyright (C) 2020 Renesas Electronics Corporation
- */
-
-#ifndef __RCAR_MIPI_DSI_REGS_H__
-#define __RCAR_MIPI_DSI_REGS_H__
-
-#define LINKSR 0x010
-#define LINKSR_LPBUSY (1 << 1)
-#define LINKSR_HSBUSY (1 << 0)
-
-/*
- * Video Mode Register
- */
-#define TXVMSETR 0x180
-#define TXVMSETR_SYNSEQ_PULSES (0 << 16)
-#define TXVMSETR_SYNSEQ_EVENTS (1 << 16)
-#define TXVMSETR_VSTPM (1 << 15)
-#define TXVMSETR_PIXWDTH (1 << 8)
-#define TXVMSETR_VSEN_EN (1 << 4)
-#define TXVMSETR_VSEN_DIS (0 << 4)
-#define TXVMSETR_HFPBPEN_EN (1 << 2)
-#define TXVMSETR_HFPBPEN_DIS (0 << 2)
-#define TXVMSETR_HBPBPEN_EN (1 << 1)
-#define TXVMSETR_HBPBPEN_DIS (0 << 1)
-#define TXVMSETR_HSABPEN_EN (1 << 0)
-#define TXVMSETR_HSABPEN_DIS (0 << 0)
-
-#define TXVMCR 0x190
-#define TXVMCR_VFCLR (1 << 12)
-#define TXVMCR_EN_VIDEO (1 << 0)
-
-#define TXVMSR 0x1a0
-#define TXVMSR_STR (1 << 16)
-#define TXVMSR_VFRDY (1 << 12)
-#define TXVMSR_ACT (1 << 8)
-#define TXVMSR_RDY (1 << 0)
-
-#define TXVMSCR 0x1a4
-#define TXVMSCR_STR (1 << 16)
-
-#define TXVMPSPHSETR 0x1c0
-#define TXVMPSPHSETR_DT_RGB16 (0x0e << 16)
-#define TXVMPSPHSETR_DT_RGB18 (0x1e << 16)
-#define TXVMPSPHSETR_DT_RGB18_LS (0x2e << 16)
-#define TXVMPSPHSETR_DT_RGB24 (0x3e << 16)
-#define TXVMPSPHSETR_DT_YCBCR16 (0x2c << 16)
-
-#define TXVMVPRMSET0R 0x1d0
-#define TXVMVPRMSET0R_HSPOL_HIG (0 << 17)
-#define TXVMVPRMSET0R_HSPOL_LOW (1 << 17)
-#define TXVMVPRMSET0R_VSPOL_HIG (0 << 16)
-#define TXVMVPRMSET0R_VSPOL_LOW (1 << 16)
-#define TXVMVPRMSET0R_CSPC_RGB (0 << 4)
-#define TXVMVPRMSET0R_CSPC_YCbCr (1 << 4)
-#define TXVMVPRMSET0R_BPP_16 (0 << 0)
-#define TXVMVPRMSET0R_BPP_18 (1 << 0)
-#define TXVMVPRMSET0R_BPP_24 (2 << 0)
-
-#define TXVMVPRMSET1R 0x1d4
-#define TXVMVPRMSET1R_VACTIVE(x) (((x) & 0x7fff) << 16)
-#define TXVMVPRMSET1R_VSA(x) (((x) & 0xfff) << 0)
-
-#define TXVMVPRMSET2R 0x1d8
-#define TXVMVPRMSET2R_VFP(x) (((x) & 0x1fff) << 16)
-#define TXVMVPRMSET2R_VBP(x) (((x) & 0x1fff) << 0)
-
-#define TXVMVPRMSET3R 0x1dc
-#define TXVMVPRMSET3R_HACTIVE(x) (((x) & 0x7fff) << 16)
-#define TXVMVPRMSET3R_HSA(x) (((x) & 0xfff) << 0)
-
-#define TXVMVPRMSET4R 0x1e0
-#define TXVMVPRMSET4R_HFP(x) (((x) & 0x1fff) << 16)
-#define TXVMVPRMSET4R_HBP(x) (((x) & 0x1fff) << 0)
-
-/*
- * PHY-Protocol Interface (PPI) Registers
- */
-#define PPISETR 0x700
-#define PPISETR_DLEN_0 (0x1 << 0)
-#define PPISETR_DLEN_1 (0x3 << 0)
-#define PPISETR_DLEN_2 (0x7 << 0)
-#define PPISETR_DLEN_3 (0xf << 0)
-#define PPISETR_CLEN (1 << 8)
-
-#define PPICLCR 0x710
-#define PPICLCR_TXREQHS (1 << 8)
-#define PPICLCR_TXULPSEXT (1 << 1)
-#define PPICLCR_TXULPSCLK (1 << 0)
-
-#define PPICLSR 0x720
-#define PPICLSR_HSTOLP (1 << 27)
-#define PPICLSR_TOHS (1 << 26)
-#define PPICLSR_STPST (1 << 0)
-
-#define PPICLSCR 0x724
-#define PPICLSCR_HSTOLP (1 << 27)
-#define PPICLSCR_TOHS (1 << 26)
-
-#define PPIDLSR 0x760
-#define PPIDLSR_STPST (0xf << 0)
-
-/*
- * Clocks registers
- */
-#define LPCLKSET 0x1000
-#define LPCLKSET_CKEN (1 << 8)
-#define LPCLKSET_LPCLKDIV(x) (((x) & 0x3f) << 0)
-
-#define CFGCLKSET 0x1004
-#define CFGCLKSET_CKEN (1 << 8)
-#define CFGCLKSET_CFGCLKDIV(x) (((x) & 0x3f) << 0)
-
-#define DOTCLKDIV 0x1008
-#define DOTCLKDIV_CKEN (1 << 8)
-#define DOTCLKDIV_DOTCLKDIV(x) (((x) & 0x3f) << 0)
-
-#define VCLKSET 0x100c
-#define VCLKSET_CKEN (1 << 16)
-#define VCLKSET_COLOR_RGB (0 << 8)
-#define VCLKSET_COLOR_YCC (1 << 8)
-#define VCLKSET_DIV_V3U(x) (((x) & 0x3) << 4)
-#define VCLKSET_DIV_V4H(x) (((x) & 0x7) << 4)
-#define VCLKSET_BPP_16 (0 << 2)
-#define VCLKSET_BPP_18 (1 << 2)
-#define VCLKSET_BPP_18L (2 << 2)
-#define VCLKSET_BPP_24 (3 << 2)
-#define VCLKSET_LANE(x) (((x) & 0x3) << 0)
-
-#define VCLKEN 0x1010
-#define VCLKEN_CKEN (1 << 0)
-
-#define PHYSETUP 0x1014
-#define PHYSETUP_HSFREQRANGE(x) (((x) & 0x7f) << 16)
-#define PHYSETUP_HSFREQRANGE_MASK (0x7f << 16)
-#define PHYSETUP_CFGCLKFREQRANGE(x) (((x) & 0x3f) << 8)
-#define PHYSETUP_SHUTDOWNZ (1 << 1)
-#define PHYSETUP_RSTZ (1 << 0)
-
-#define CLOCKSET1 0x101c
-#define CLOCKSET1_LOCK_PHY (1 << 17)
-#define CLOCKSET1_LOCK (1 << 16)
-#define CLOCKSET1_CLKSEL (1 << 8)
-#define CLOCKSET1_CLKINSEL_EXTAL (0 << 2)
-#define CLOCKSET1_CLKINSEL_DIG (1 << 2)
-#define CLOCKSET1_CLKINSEL_DU (1 << 3)
-#define CLOCKSET1_SHADOW_CLEAR (1 << 1)
-#define CLOCKSET1_UPDATEPLL (1 << 0)
-
-#define CLOCKSET2 0x1020
-#define CLOCKSET2_M(x) (((x) & 0xfff) << 16)
-#define CLOCKSET2_VCO_CNTRL(x) (((x) & 0x3f) << 8)
-#define CLOCKSET2_N(x) (((x) & 0xf) << 0)
-
-#define CLOCKSET3 0x1024
-#define CLOCKSET3_PROP_CNTRL(x) (((x) & 0x3f) << 24)
-#define CLOCKSET3_INT_CNTRL(x) (((x) & 0x3f) << 16)
-#define CLOCKSET3_CPBIAS_CNTRL(x) (((x) & 0x7f) << 8)
-#define CLOCKSET3_GMP_CNTRL(x) (((x) & 0x3) << 0)
-
-#define PHTW 0x1034
-#define PHTW_DWEN (1 << 24)
-#define PHTW_TESTDIN_DATA(x) (((x) & 0xff) << 16)
-#define PHTW_CWEN (1 << 8)
-#define PHTW_TESTDIN_CODE(x) (((x) & 0xff) << 0)
-
-#define PHTR 0x1038
-#define PHTR_TEST (1 << 16)
-
-#define PHTC 0x103c
-#define PHTC_TESTCLR (1 << 0)
-
-#endif /* __RCAR_MIPI_DSI_REGS_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c b/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c
deleted file mode 100644
index aa95b85a2964..000000000000
--- a/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c
+++ /dev/null
@@ -1,816 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * RZ/G2L MIPI DSI Encoder Driver
- *
- * Copyright (C) 2022 Renesas Electronics Corporation
- */
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/iopoll.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/of_graph.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/reset.h>
-#include <linux/slab.h>
-
-#include <drm/drm_atomic.h>
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_bridge.h>
-#include <drm/drm_mipi_dsi.h>
-#include <drm/drm_of.h>
-#include <drm/drm_panel.h>
-#include <drm/drm_probe_helper.h>
-
-#include "rzg2l_mipi_dsi_regs.h"
-
-struct rzg2l_mipi_dsi {
- struct device *dev;
- void __iomem *mmio;
-
- struct reset_control *rstc;
- struct reset_control *arstc;
- struct reset_control *prstc;
-
- struct mipi_dsi_host host;
- struct drm_bridge bridge;
- struct drm_bridge *next_bridge;
-
- struct clk *vclk;
-
- enum mipi_dsi_pixel_format format;
- unsigned int num_data_lanes;
- unsigned int lanes;
- unsigned long mode_flags;
-};
-
-static inline struct rzg2l_mipi_dsi *
-bridge_to_rzg2l_mipi_dsi(struct drm_bridge *bridge)
-{
- return container_of(bridge, struct rzg2l_mipi_dsi, bridge);
-}
-
-static inline struct rzg2l_mipi_dsi *
-host_to_rzg2l_mipi_dsi(struct mipi_dsi_host *host)
-{
- return container_of(host, struct rzg2l_mipi_dsi, host);
-}
-
-struct rzg2l_mipi_dsi_timings {
- unsigned long hsfreq_max;
- u32 t_init;
- u32 tclk_prepare;
- u32 ths_prepare;
- u32 tclk_zero;
- u32 tclk_pre;
- u32 tclk_post;
- u32 tclk_trail;
- u32 ths_zero;
- u32 ths_trail;
- u32 ths_exit;
- u32 tlpx;
-};
-
-static const struct rzg2l_mipi_dsi_timings rzg2l_mipi_dsi_global_timings[] = {
- {
- .hsfreq_max = 80000,
- .t_init = 79801,
- .tclk_prepare = 8,
- .ths_prepare = 13,
- .tclk_zero = 33,
- .tclk_pre = 24,
- .tclk_post = 94,
- .tclk_trail = 10,
- .ths_zero = 23,
- .ths_trail = 17,
- .ths_exit = 13,
- .tlpx = 6,
- },
- {
- .hsfreq_max = 125000,
- .t_init = 79801,
- .tclk_prepare = 8,
- .ths_prepare = 12,
- .tclk_zero = 33,
- .tclk_pre = 15,
- .tclk_post = 94,
- .tclk_trail = 10,
- .ths_zero = 23,
- .ths_trail = 17,
- .ths_exit = 13,
- .tlpx = 6,
- },
- {
- .hsfreq_max = 250000,
- .t_init = 79801,
- .tclk_prepare = 8,
- .ths_prepare = 12,
- .tclk_zero = 33,
- .tclk_pre = 13,
- .tclk_post = 94,
- .tclk_trail = 10,
- .ths_zero = 23,
- .ths_trail = 16,
- .ths_exit = 13,
- .tlpx = 6,
- },
- {
- .hsfreq_max = 360000,
- .t_init = 79801,
- .tclk_prepare = 8,
- .ths_prepare = 10,
- .tclk_zero = 33,
- .tclk_pre = 4,
- .tclk_post = 35,
- .tclk_trail = 7,
- .ths_zero = 16,
- .ths_trail = 9,
- .ths_exit = 13,
- .tlpx = 6,
- },
- {
- .hsfreq_max = 720000,
- .t_init = 79801,
- .tclk_prepare = 8,
- .ths_prepare = 9,
- .tclk_zero = 33,
- .tclk_pre = 4,
- .tclk_post = 35,
- .tclk_trail = 7,
- .ths_zero = 16,
- .ths_trail = 9,
- .ths_exit = 13,
- .tlpx = 6,
- },
- {
- .hsfreq_max = 1500000,
- .t_init = 79801,
- .tclk_prepare = 8,
- .ths_prepare = 9,
- .tclk_zero = 33,
- .tclk_pre = 4,
- .tclk_post = 35,
- .tclk_trail = 7,
- .ths_zero = 16,
- .ths_trail = 9,
- .ths_exit = 13,
- .tlpx = 6,
- },
-};
-
-static void rzg2l_mipi_dsi_phy_write(struct rzg2l_mipi_dsi *dsi, u32 reg, u32 data)
-{
- iowrite32(data, dsi->mmio + reg);
-}
-
-static void rzg2l_mipi_dsi_link_write(struct rzg2l_mipi_dsi *dsi, u32 reg, u32 data)
-{
- iowrite32(data, dsi->mmio + LINK_REG_OFFSET + reg);
-}
-
-static u32 rzg2l_mipi_dsi_phy_read(struct rzg2l_mipi_dsi *dsi, u32 reg)
-{
- return ioread32(dsi->mmio + reg);
-}
-
-static u32 rzg2l_mipi_dsi_link_read(struct rzg2l_mipi_dsi *dsi, u32 reg)
-{
- return ioread32(dsi->mmio + LINK_REG_OFFSET + reg);
-}
-
-/* -----------------------------------------------------------------------------
- * Hardware Setup
- */
-
-static int rzg2l_mipi_dsi_dphy_init(struct rzg2l_mipi_dsi *dsi,
- unsigned long hsfreq)
-{
- const struct rzg2l_mipi_dsi_timings *dphy_timings;
- unsigned int i;
- u32 dphyctrl0;
- u32 dphytim0;
- u32 dphytim1;
- u32 dphytim2;
- u32 dphytim3;
- int ret;
-
- /* All DSI global operation timings are set with recommended setting */
- for (i = 0; i < ARRAY_SIZE(rzg2l_mipi_dsi_global_timings); ++i) {
- dphy_timings = &rzg2l_mipi_dsi_global_timings[i];
- if (hsfreq <= dphy_timings->hsfreq_max)
- break;
- }
-
- /* Initializing DPHY before accessing LINK */
- dphyctrl0 = DSIDPHYCTRL0_CAL_EN_HSRX_OFS | DSIDPHYCTRL0_CMN_MASTER_EN |
- DSIDPHYCTRL0_RE_VDD_DETVCCQLV18 | DSIDPHYCTRL0_EN_BGR;
-
- rzg2l_mipi_dsi_phy_write(dsi, DSIDPHYCTRL0, dphyctrl0);
- usleep_range(20, 30);
-
- dphyctrl0 |= DSIDPHYCTRL0_EN_LDO1200;
- rzg2l_mipi_dsi_phy_write(dsi, DSIDPHYCTRL0, dphyctrl0);
- usleep_range(10, 20);
-
- dphytim0 = DSIDPHYTIM0_TCLK_MISS(0) |
- DSIDPHYTIM0_T_INIT(dphy_timings->t_init);
- dphytim1 = DSIDPHYTIM1_THS_PREPARE(dphy_timings->ths_prepare) |
- DSIDPHYTIM1_TCLK_PREPARE(dphy_timings->tclk_prepare) |
- DSIDPHYTIM1_THS_SETTLE(0) |
- DSIDPHYTIM1_TCLK_SETTLE(0);
- dphytim2 = DSIDPHYTIM2_TCLK_TRAIL(dphy_timings->tclk_trail) |
- DSIDPHYTIM2_TCLK_POST(dphy_timings->tclk_post) |
- DSIDPHYTIM2_TCLK_PRE(dphy_timings->tclk_pre) |
- DSIDPHYTIM2_TCLK_ZERO(dphy_timings->tclk_zero);
- dphytim3 = DSIDPHYTIM3_TLPX(dphy_timings->tlpx) |
- DSIDPHYTIM3_THS_EXIT(dphy_timings->ths_exit) |
- DSIDPHYTIM3_THS_TRAIL(dphy_timings->ths_trail) |
- DSIDPHYTIM3_THS_ZERO(dphy_timings->ths_zero);
-
- rzg2l_mipi_dsi_phy_write(dsi, DSIDPHYTIM0, dphytim0);
- rzg2l_mipi_dsi_phy_write(dsi, DSIDPHYTIM1, dphytim1);
- rzg2l_mipi_dsi_phy_write(dsi, DSIDPHYTIM2, dphytim2);
- rzg2l_mipi_dsi_phy_write(dsi, DSIDPHYTIM3, dphytim3);
-
- ret = reset_control_deassert(dsi->rstc);
- if (ret < 0)
- return ret;
-
- udelay(1);
-
- return 0;
-}
-
-static void rzg2l_mipi_dsi_dphy_exit(struct rzg2l_mipi_dsi *dsi)
-{
- u32 dphyctrl0;
-
- dphyctrl0 = rzg2l_mipi_dsi_phy_read(dsi, DSIDPHYCTRL0);
-
- dphyctrl0 &= ~(DSIDPHYCTRL0_EN_LDO1200 | DSIDPHYCTRL0_EN_BGR);
- rzg2l_mipi_dsi_phy_write(dsi, DSIDPHYCTRL0, dphyctrl0);
-
- reset_control_assert(dsi->rstc);
-}
-
-static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi,
- const struct drm_display_mode *mode)
-{
- unsigned long hsfreq;
- unsigned int bpp;
- u32 txsetr;
- u32 clstptsetr;
- u32 lptrnstsetr;
- u32 clkkpt;
- u32 clkbfht;
- u32 clkstpt;
- u32 golpbkt;
- int ret;
-
- /*
- * Relationship between hsclk and vclk must follow
- * vclk * bpp = hsclk * 8 * lanes
- * where vclk: video clock (Hz)
- * bpp: video pixel bit depth
- * hsclk: DSI HS Byte clock frequency (Hz)
- * lanes: number of data lanes
- *
- * hsclk(bit) = hsclk(byte) * 8
- */
- bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
- hsfreq = (mode->clock * bpp * 8) / (8 * dsi->lanes);
-
- ret = pm_runtime_resume_and_get(dsi->dev);
- if (ret < 0)
- return ret;
-
- clk_set_rate(dsi->vclk, mode->clock * 1000);
-
- ret = rzg2l_mipi_dsi_dphy_init(dsi, hsfreq);
- if (ret < 0)
- goto err_phy;
-
- /* Enable Data lanes and Clock lanes */
- txsetr = TXSETR_DLEN | TXSETR_NUMLANEUSE(dsi->lanes - 1) | TXSETR_CLEN;
- rzg2l_mipi_dsi_link_write(dsi, TXSETR, txsetr);
-
- /*
- * Global timings characteristic depends on high speed Clock Frequency
- * Currently MIPI DSI-IF just supports maximum FHD@60 with:
- * - videoclock = 148.5 (MHz)
- * - bpp: maximum 24bpp
- * - data lanes: maximum 4 lanes
- * Therefore maximum hsclk will be 891 Mbps.
- */
- if (hsfreq > 445500) {
- clkkpt = 12;
- clkbfht = 15;
- clkstpt = 48;
- golpbkt = 75;
- } else if (hsfreq > 250000) {
- clkkpt = 7;
- clkbfht = 8;
- clkstpt = 27;
- golpbkt = 40;
- } else {
- clkkpt = 8;
- clkbfht = 6;
- clkstpt = 24;
- golpbkt = 29;
- }
-
- clstptsetr = CLSTPTSETR_CLKKPT(clkkpt) | CLSTPTSETR_CLKBFHT(clkbfht) |
- CLSTPTSETR_CLKSTPT(clkstpt);
- rzg2l_mipi_dsi_link_write(dsi, CLSTPTSETR, clstptsetr);
-
- lptrnstsetr = LPTRNSTSETR_GOLPBKT(golpbkt);
- rzg2l_mipi_dsi_link_write(dsi, LPTRNSTSETR, lptrnstsetr);
-
- return 0;
-
-err_phy:
- rzg2l_mipi_dsi_dphy_exit(dsi);
- pm_runtime_put(dsi->dev);
-
- return ret;
-}
-
-static void rzg2l_mipi_dsi_stop(struct rzg2l_mipi_dsi *dsi)
-{
- rzg2l_mipi_dsi_dphy_exit(dsi);
- pm_runtime_put(dsi->dev);
-}
-
-static void rzg2l_mipi_dsi_set_display_timing(struct rzg2l_mipi_dsi *dsi,
- const struct drm_display_mode *mode)
-{
- u32 vich1ppsetr;
- u32 vich1vssetr;
- u32 vich1vpsetr;
- u32 vich1hssetr;
- u32 vich1hpsetr;
- int dsi_format;
- u32 delay[2];
- u8 index;
-
- /* Configuration for Pixel Packet */
- dsi_format = mipi_dsi_pixel_format_to_bpp(dsi->format);
- switch (dsi_format) {
- case 24:
- vich1ppsetr = VICH1PPSETR_DT_RGB24;
- break;
- case 18:
- vich1ppsetr = VICH1PPSETR_DT_RGB18;
- break;
- }
-
- if ((dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) &&
- !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST))
- vich1ppsetr |= VICH1PPSETR_TXESYNC_PULSE;
-
- rzg2l_mipi_dsi_link_write(dsi, VICH1PPSETR, vich1ppsetr);
-
- /* Configuration for Video Parameters */
- vich1vssetr = VICH1VSSETR_VACTIVE(mode->vdisplay) |
- VICH1VSSETR_VSA(mode->vsync_end - mode->vsync_start);
- vich1vssetr |= (mode->flags & DRM_MODE_FLAG_PVSYNC) ?
- VICH1VSSETR_VSPOL_HIGH : VICH1VSSETR_VSPOL_LOW;
-
- vich1vpsetr = VICH1VPSETR_VFP(mode->vsync_start - mode->vdisplay) |
- VICH1VPSETR_VBP(mode->vtotal - mode->vsync_end);
-
- vich1hssetr = VICH1HSSETR_HACTIVE(mode->hdisplay) |
- VICH1HSSETR_HSA(mode->hsync_end - mode->hsync_start);
- vich1hssetr |= (mode->flags & DRM_MODE_FLAG_PHSYNC) ?
- VICH1HSSETR_HSPOL_HIGH : VICH1HSSETR_HSPOL_LOW;
-
- vich1hpsetr = VICH1HPSETR_HFP(mode->hsync_start - mode->hdisplay) |
- VICH1HPSETR_HBP(mode->htotal - mode->hsync_end);
-
- rzg2l_mipi_dsi_link_write(dsi, VICH1VSSETR, vich1vssetr);
- rzg2l_mipi_dsi_link_write(dsi, VICH1VPSETR, vich1vpsetr);
- rzg2l_mipi_dsi_link_write(dsi, VICH1HSSETR, vich1hssetr);
- rzg2l_mipi_dsi_link_write(dsi, VICH1HPSETR, vich1hpsetr);
-
- /*
- * Configuration for Delay Value
- * Delay value based on 2 ranges of video clock.
- * 74.25MHz is videoclock of HD@60p or FHD@30p
- */
- if (mode->clock > 74250) {
- delay[0] = 231;
- delay[1] = 216;
- } else {
- delay[0] = 220;
- delay[1] = 212;
- }
-
- if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
- index = 0;
- else
- index = 1;
-
- rzg2l_mipi_dsi_link_write(dsi, VICH1SET1R,
- VICH1SET1R_DLY(delay[index]));
-}
-
-static int rzg2l_mipi_dsi_start_hs_clock(struct rzg2l_mipi_dsi *dsi)
-{
- bool is_clk_cont;
- u32 hsclksetr;
- u32 status;
- int ret;
-
- is_clk_cont = !(dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS);
-
- /* Start HS clock */
- hsclksetr = HSCLKSETR_HSCLKRUN_HS | (is_clk_cont ?
- HSCLKSETR_HSCLKMODE_CONT :
- HSCLKSETR_HSCLKMODE_NON_CONT);
- rzg2l_mipi_dsi_link_write(dsi, HSCLKSETR, hsclksetr);
-
- if (is_clk_cont) {
- ret = read_poll_timeout(rzg2l_mipi_dsi_link_read, status,
- status & PLSR_CLLP2HS,
- 2000, 20000, false, dsi, PLSR);
- if (ret < 0) {
- dev_err(dsi->dev, "failed to start HS clock\n");
- return ret;
- }
- }
-
- dev_dbg(dsi->dev, "Start High Speed Clock with %s clock mode",
- is_clk_cont ? "continuous" : "non-continuous");
-
- return 0;
-}
-
-static int rzg2l_mipi_dsi_stop_hs_clock(struct rzg2l_mipi_dsi *dsi)
-{
- bool is_clk_cont;
- u32 status;
- int ret;
-
- is_clk_cont = !(dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS);
-
- /* Stop HS clock */
- rzg2l_mipi_dsi_link_write(dsi, HSCLKSETR,
- is_clk_cont ? HSCLKSETR_HSCLKMODE_CONT :
- HSCLKSETR_HSCLKMODE_NON_CONT);
-
- if (is_clk_cont) {
- ret = read_poll_timeout(rzg2l_mipi_dsi_link_read, status,
- status & PLSR_CLHS2LP,
- 2000, 20000, false, dsi, PLSR);
- if (ret < 0) {
- dev_err(dsi->dev, "failed to stop HS clock\n");
- return ret;
- }
- }
-
- return 0;
-}
-
-static int rzg2l_mipi_dsi_start_video(struct rzg2l_mipi_dsi *dsi)
-{
- u32 vich1set0r;
- u32 status;
- int ret;
-
- /* Configuration for Blanking sequence and start video input*/
- vich1set0r = VICH1SET0R_HFPNOLP | VICH1SET0R_HBPNOLP |
- VICH1SET0R_HSANOLP | VICH1SET0R_VSTART;
- rzg2l_mipi_dsi_link_write(dsi, VICH1SET0R, vich1set0r);
-
- ret = read_poll_timeout(rzg2l_mipi_dsi_link_read, status,
- status & VICH1SR_VIRDY,
- 2000, 20000, false, dsi, VICH1SR);
- if (ret < 0)
- dev_err(dsi->dev, "Failed to start video signal input\n");
-
- return ret;
-}
-
-static int rzg2l_mipi_dsi_stop_video(struct rzg2l_mipi_dsi *dsi)
-{
- u32 status;
- int ret;
-
- rzg2l_mipi_dsi_link_write(dsi, VICH1SET0R, VICH1SET0R_VSTPAFT);
- ret = read_poll_timeout(rzg2l_mipi_dsi_link_read, status,
- (status & VICH1SR_STOP) && (!(status & VICH1SR_RUNNING)),
- 2000, 20000, false, dsi, VICH1SR);
- if (ret < 0)
- goto err;
-
- ret = read_poll_timeout(rzg2l_mipi_dsi_link_read, status,
- !(status & LINKSR_HSBUSY),
- 2000, 20000, false, dsi, LINKSR);
- if (ret < 0)
- goto err;
-
- return 0;
-
-err:
- dev_err(dsi->dev, "Failed to stop video signal input\n");
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * Bridge
- */
-
-static int rzg2l_mipi_dsi_attach(struct drm_bridge *bridge,
- enum drm_bridge_attach_flags flags)
-{
- struct rzg2l_mipi_dsi *dsi = bridge_to_rzg2l_mipi_dsi(bridge);
-
- return drm_bridge_attach(bridge->encoder, dsi->next_bridge, bridge,
- flags);
-}
-
-static void rzg2l_mipi_dsi_atomic_enable(struct drm_bridge *bridge,
- struct drm_bridge_state *old_bridge_state)
-{
- struct drm_atomic_state *state = old_bridge_state->base.state;
- struct rzg2l_mipi_dsi *dsi = bridge_to_rzg2l_mipi_dsi(bridge);
- const struct drm_display_mode *mode;
- struct drm_connector *connector;
- struct drm_crtc *crtc;
- int ret;
-
- connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
- crtc = drm_atomic_get_new_connector_state(state, connector)->crtc;
- mode = &drm_atomic_get_new_crtc_state(state, crtc)->adjusted_mode;
-
- ret = rzg2l_mipi_dsi_startup(dsi, mode);
- if (ret < 0)
- return;
-
- rzg2l_mipi_dsi_set_display_timing(dsi, mode);
-
- ret = rzg2l_mipi_dsi_start_hs_clock(dsi);
- if (ret < 0)
- goto err_stop;
-
- ret = rzg2l_mipi_dsi_start_video(dsi);
- if (ret < 0)
- goto err_stop_clock;
-
- return;
-
-err_stop_clock:
- rzg2l_mipi_dsi_stop_hs_clock(dsi);
-err_stop:
- rzg2l_mipi_dsi_stop(dsi);
-}
-
-static void rzg2l_mipi_dsi_atomic_disable(struct drm_bridge *bridge,
- struct drm_bridge_state *old_bridge_state)
-{
- struct rzg2l_mipi_dsi *dsi = bridge_to_rzg2l_mipi_dsi(bridge);
-
- rzg2l_mipi_dsi_stop_video(dsi);
- rzg2l_mipi_dsi_stop_hs_clock(dsi);
- rzg2l_mipi_dsi_stop(dsi);
-}
-
-static enum drm_mode_status
-rzg2l_mipi_dsi_bridge_mode_valid(struct drm_bridge *bridge,
- const struct drm_display_info *info,
- const struct drm_display_mode *mode)
-{
- if (mode->clock > 148500)
- return MODE_CLOCK_HIGH;
-
- return MODE_OK;
-}
-
-static const struct drm_bridge_funcs rzg2l_mipi_dsi_bridge_ops = {
- .attach = rzg2l_mipi_dsi_attach,
- .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
- .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
- .atomic_reset = drm_atomic_helper_bridge_reset,
- .atomic_enable = rzg2l_mipi_dsi_atomic_enable,
- .atomic_disable = rzg2l_mipi_dsi_atomic_disable,
- .mode_valid = rzg2l_mipi_dsi_bridge_mode_valid,
-};
-
-/* -----------------------------------------------------------------------------
- * Host setting
- */
-
-static int rzg2l_mipi_dsi_host_attach(struct mipi_dsi_host *host,
- struct mipi_dsi_device *device)
-{
- struct rzg2l_mipi_dsi *dsi = host_to_rzg2l_mipi_dsi(host);
- int ret;
-
- if (device->lanes > dsi->num_data_lanes) {
- dev_err(dsi->dev,
- "Number of lines of device (%u) exceeds host (%u)\n",
- device->lanes, dsi->num_data_lanes);
- return -EINVAL;
- }
-
- switch (mipi_dsi_pixel_format_to_bpp(device->format)) {
- case 24:
- case 18:
- break;
- default:
- dev_err(dsi->dev, "Unsupported format 0x%04x\n", device->format);
- return -EINVAL;
- }
-
- dsi->lanes = device->lanes;
- dsi->format = device->format;
- dsi->mode_flags = device->mode_flags;
-
- dsi->next_bridge = devm_drm_of_get_bridge(dsi->dev, dsi->dev->of_node,
- 1, 0);
- if (IS_ERR(dsi->next_bridge)) {
- ret = PTR_ERR(dsi->next_bridge);
- dev_err(dsi->dev, "failed to get next bridge: %d\n", ret);
- return ret;
- }
-
- drm_bridge_add(&dsi->bridge);
-
- return 0;
-}
-
-static int rzg2l_mipi_dsi_host_detach(struct mipi_dsi_host *host,
- struct mipi_dsi_device *device)
-{
- struct rzg2l_mipi_dsi *dsi = host_to_rzg2l_mipi_dsi(host);
-
- drm_bridge_remove(&dsi->bridge);
-
- return 0;
-}
-
-static const struct mipi_dsi_host_ops rzg2l_mipi_dsi_host_ops = {
- .attach = rzg2l_mipi_dsi_host_attach,
- .detach = rzg2l_mipi_dsi_host_detach,
-};
-
-/* -----------------------------------------------------------------------------
- * Power Management
- */
-
-static int __maybe_unused rzg2l_mipi_pm_runtime_suspend(struct device *dev)
-{
- struct rzg2l_mipi_dsi *dsi = dev_get_drvdata(dev);
-
- reset_control_assert(dsi->prstc);
- reset_control_assert(dsi->arstc);
-
- return 0;
-}
-
-static int __maybe_unused rzg2l_mipi_pm_runtime_resume(struct device *dev)
-{
- struct rzg2l_mipi_dsi *dsi = dev_get_drvdata(dev);
- int ret;
-
- ret = reset_control_deassert(dsi->arstc);
- if (ret < 0)
- return ret;
-
- ret = reset_control_deassert(dsi->prstc);
- if (ret < 0)
- reset_control_assert(dsi->arstc);
-
- return ret;
-}
-
-static const struct dev_pm_ops rzg2l_mipi_pm_ops = {
- SET_RUNTIME_PM_OPS(rzg2l_mipi_pm_runtime_suspend, rzg2l_mipi_pm_runtime_resume, NULL)
-};
-
-/* -----------------------------------------------------------------------------
- * Probe & Remove
- */
-
-static int rzg2l_mipi_dsi_probe(struct platform_device *pdev)
-{
- unsigned int num_data_lanes;
- struct rzg2l_mipi_dsi *dsi;
- u32 txsetr;
- int ret;
-
- dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL);
- if (!dsi)
- return -ENOMEM;
-
- platform_set_drvdata(pdev, dsi);
- dsi->dev = &pdev->dev;
-
- ret = drm_of_get_data_lanes_count_ep(dsi->dev->of_node, 1, 0, 1, 4);
- if (ret < 0)
- return dev_err_probe(dsi->dev, ret,
- "missing or invalid data-lanes property\n");
-
- num_data_lanes = ret;
-
- dsi->mmio = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(dsi->mmio))
- return PTR_ERR(dsi->mmio);
-
- dsi->vclk = devm_clk_get(dsi->dev, "vclk");
- if (IS_ERR(dsi->vclk))
- return PTR_ERR(dsi->vclk);
-
- dsi->rstc = devm_reset_control_get_exclusive(dsi->dev, "rst");
- if (IS_ERR(dsi->rstc))
- return dev_err_probe(dsi->dev, PTR_ERR(dsi->rstc),
- "failed to get rst\n");
-
- dsi->arstc = devm_reset_control_get_exclusive(dsi->dev, "arst");
- if (IS_ERR(dsi->arstc))
- return dev_err_probe(&pdev->dev, PTR_ERR(dsi->arstc),
- "failed to get arst\n");
-
- dsi->prstc = devm_reset_control_get_exclusive(dsi->dev, "prst");
- if (IS_ERR(dsi->prstc))
- return dev_err_probe(dsi->dev, PTR_ERR(dsi->prstc),
- "failed to get prst\n");
-
- platform_set_drvdata(pdev, dsi);
-
- pm_runtime_enable(dsi->dev);
-
- ret = pm_runtime_resume_and_get(dsi->dev);
- if (ret < 0)
- goto err_pm_disable;
-
- /*
- * TXSETR register can be read only after DPHY init. But during probe
- * mode->clock and format are not available. So initialize DPHY with
- * timing parameters for 80Mbps.
- */
- ret = rzg2l_mipi_dsi_dphy_init(dsi, 80000);
- if (ret < 0)
- goto err_phy;
-
- txsetr = rzg2l_mipi_dsi_link_read(dsi, TXSETR);
- dsi->num_data_lanes = min(((txsetr >> 16) & 3) + 1, num_data_lanes);
- rzg2l_mipi_dsi_dphy_exit(dsi);
- pm_runtime_put(dsi->dev);
-
- /* Initialize the DRM bridge. */
- dsi->bridge.funcs = &rzg2l_mipi_dsi_bridge_ops;
- dsi->bridge.of_node = dsi->dev->of_node;
-
- /* Init host device */
- dsi->host.dev = dsi->dev;
- dsi->host.ops = &rzg2l_mipi_dsi_host_ops;
- ret = mipi_dsi_host_register(&dsi->host);
- if (ret < 0)
- goto err_pm_disable;
-
- return 0;
-
-err_phy:
- rzg2l_mipi_dsi_dphy_exit(dsi);
- pm_runtime_put(dsi->dev);
-err_pm_disable:
- pm_runtime_disable(dsi->dev);
- return ret;
-}
-
-static int rzg2l_mipi_dsi_remove(struct platform_device *pdev)
-{
- struct rzg2l_mipi_dsi *dsi = platform_get_drvdata(pdev);
-
- mipi_dsi_host_unregister(&dsi->host);
- pm_runtime_disable(&pdev->dev);
-
- return 0;
-}
-
-static const struct of_device_id rzg2l_mipi_dsi_of_table[] = {
- { .compatible = "renesas,rzg2l-mipi-dsi" },
- { /* sentinel */ }
-};
-
-MODULE_DEVICE_TABLE(of, rzg2l_mipi_dsi_of_table);
-
-static struct platform_driver rzg2l_mipi_dsi_platform_driver = {
- .probe = rzg2l_mipi_dsi_probe,
- .remove = rzg2l_mipi_dsi_remove,
- .driver = {
- .name = "rzg2l-mipi-dsi",
- .pm = &rzg2l_mipi_pm_ops,
- .of_match_table = rzg2l_mipi_dsi_of_table,
- },
-};
-
-module_platform_driver(rzg2l_mipi_dsi_platform_driver);
-
-MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
-MODULE_DESCRIPTION("Renesas RZ/G2L MIPI DSI Encoder Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi_regs.h b/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi_regs.h
deleted file mode 100644
index 1dbc16ec64a4..000000000000
--- a/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi_regs.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * RZ/G2L MIPI DSI Interface Registers Definitions
- *
- * Copyright (C) 2022 Renesas Electronics Corporation
- */
-
-#ifndef __RZG2L_MIPI_DSI_REGS_H__
-#define __RZG2L_MIPI_DSI_REGS_H__
-
-#include <linux/bits.h>
-
-/* DPHY Registers */
-#define DSIDPHYCTRL0 0x00
-#define DSIDPHYCTRL0_CAL_EN_HSRX_OFS BIT(16)
-#define DSIDPHYCTRL0_CMN_MASTER_EN BIT(8)
-#define DSIDPHYCTRL0_RE_VDD_DETVCCQLV18 BIT(2)
-#define DSIDPHYCTRL0_EN_LDO1200 BIT(1)
-#define DSIDPHYCTRL0_EN_BGR BIT(0)
-
-#define DSIDPHYTIM0 0x04
-#define DSIDPHYTIM0_TCLK_MISS(x) ((x) << 24)
-#define DSIDPHYTIM0_T_INIT(x) ((x) << 0)
-
-#define DSIDPHYTIM1 0x08
-#define DSIDPHYTIM1_THS_PREPARE(x) ((x) << 24)
-#define DSIDPHYTIM1_TCLK_PREPARE(x) ((x) << 16)
-#define DSIDPHYTIM1_THS_SETTLE(x) ((x) << 8)
-#define DSIDPHYTIM1_TCLK_SETTLE(x) ((x) << 0)
-
-#define DSIDPHYTIM2 0x0c
-#define DSIDPHYTIM2_TCLK_TRAIL(x) ((x) << 24)
-#define DSIDPHYTIM2_TCLK_POST(x) ((x) << 16)
-#define DSIDPHYTIM2_TCLK_PRE(x) ((x) << 8)
-#define DSIDPHYTIM2_TCLK_ZERO(x) ((x) << 0)
-
-#define DSIDPHYTIM3 0x10
-#define DSIDPHYTIM3_TLPX(x) ((x) << 24)
-#define DSIDPHYTIM3_THS_EXIT(x) ((x) << 16)
-#define DSIDPHYTIM3_THS_TRAIL(x) ((x) << 8)
-#define DSIDPHYTIM3_THS_ZERO(x) ((x) << 0)
-
-/* --------------------------------------------------------*/
-/* Link Registers */
-#define LINK_REG_OFFSET 0x10000
-
-/* Link Status Register */
-#define LINKSR 0x10
-#define LINKSR_LPBUSY BIT(13)
-#define LINKSR_HSBUSY BIT(12)
-#define LINKSR_VICHRUN1 BIT(8)
-#define LINKSR_SQCHRUN1 BIT(4)
-#define LINKSR_SQCHRUN0 BIT(0)
-
-/* Tx Set Register */
-#define TXSETR 0x100
-#define TXSETR_NUMLANECAP (0x3 << 16)
-#define TXSETR_DLEN (1 << 9)
-#define TXSETR_CLEN (1 << 8)
-#define TXSETR_NUMLANEUSE(x) (((x) & 0x3) << 0)
-
-/* HS Clock Set Register */
-#define HSCLKSETR 0x104
-#define HSCLKSETR_HSCLKMODE_CONT (1 << 1)
-#define HSCLKSETR_HSCLKMODE_NON_CONT (0 << 1)
-#define HSCLKSETR_HSCLKRUN_HS (1 << 0)
-#define HSCLKSETR_HSCLKRUN_LP (0 << 0)
-
-/* Reset Control Register */
-#define RSTCR 0x110
-#define RSTCR_SWRST BIT(0)
-#define RSTCR_FCETXSTP BIT(16)
-
-/* Reset Status Register */
-#define RSTSR 0x114
-#define RSTSR_DL0DIR (1 << 15)
-#define RSTSR_DLSTPST (0xf << 8)
-#define RSTSR_SWRSTV1 (1 << 4)
-#define RSTSR_SWRSTIB (1 << 3)
-#define RSTSR_SWRSTAPB (1 << 2)
-#define RSTSR_SWRSTLP (1 << 1)
-#define RSTSR_SWRSTHS (1 << 0)
-
-/* Clock Lane Stop Time Set Register */
-#define CLSTPTSETR 0x314
-#define CLSTPTSETR_CLKKPT(x) ((x) << 24)
-#define CLSTPTSETR_CLKBFHT(x) ((x) << 16)
-#define CLSTPTSETR_CLKSTPT(x) ((x) << 2)
-
-/* LP Transition Time Set Register */
-#define LPTRNSTSETR 0x318
-#define LPTRNSTSETR_GOLPBKT(x) ((x) << 0)
-
-/* Physical Lane Status Register */
-#define PLSR 0x320
-#define PLSR_CLHS2LP BIT(27)
-#define PLSR_CLLP2HS BIT(26)
-
-/* Video-Input Channel 1 Set 0 Register */
-#define VICH1SET0R 0x400
-#define VICH1SET0R_VSEN BIT(12)
-#define VICH1SET0R_HFPNOLP BIT(10)
-#define VICH1SET0R_HBPNOLP BIT(9)
-#define VICH1SET0R_HSANOLP BIT(8)
-#define VICH1SET0R_VSTPAFT BIT(1)
-#define VICH1SET0R_VSTART BIT(0)
-
-/* Video-Input Channel 1 Set 1 Register */
-#define VICH1SET1R 0x404
-#define VICH1SET1R_DLY(x) (((x) & 0xfff) << 2)
-
-/* Video-Input Channel 1 Status Register */
-#define VICH1SR 0x410
-#define VICH1SR_VIRDY BIT(3)
-#define VICH1SR_RUNNING BIT(2)
-#define VICH1SR_STOP BIT(1)
-#define VICH1SR_START BIT(0)
-
-/* Video-Input Channel 1 Pixel Packet Set Register */
-#define VICH1PPSETR 0x420
-#define VICH1PPSETR_DT_RGB18 (0x1e << 16)
-#define VICH1PPSETR_DT_RGB18_LS (0x2e << 16)
-#define VICH1PPSETR_DT_RGB24 (0x3e << 16)
-#define VICH1PPSETR_TXESYNC_PULSE (1 << 15)
-#define VICH1PPSETR_VC(x) ((x) << 22)
-
-/* Video-Input Channel 1 Vertical Size Set Register */
-#define VICH1VSSETR 0x428
-#define VICH1VSSETR_VACTIVE(x) (((x) & 0x7fff) << 16)
-#define VICH1VSSETR_VSPOL_LOW (1 << 15)
-#define VICH1VSSETR_VSPOL_HIGH (0 << 15)
-#define VICH1VSSETR_VSA(x) (((x) & 0xfff) << 0)
-
-/* Video-Input Channel 1 Vertical Porch Set Register */
-#define VICH1VPSETR 0x42c
-#define VICH1VPSETR_VFP(x) (((x) & 0x1fff) << 16)
-#define VICH1VPSETR_VBP(x) (((x) & 0x1fff) << 0)
-
-/* Video-Input Channel 1 Horizontal Size Set Register */
-#define VICH1HSSETR 0x430
-#define VICH1HSSETR_HACTIVE(x) (((x) & 0x7fff) << 16)
-#define VICH1HSSETR_HSPOL_LOW (1 << 15)
-#define VICH1HSSETR_HSPOL_HIGH (0 << 15)
-#define VICH1HSSETR_HSA(x) (((x) & 0xfff) << 0)
-
-/* Video-Input Channel 1 Horizontal Porch Set Register */
-#define VICH1HPSETR 0x434
-#define VICH1HPSETR_HFP(x) (((x) & 0x1fff) << 16)
-#define VICH1HPSETR_HBP(x) (((x) & 0x1fff) << 0)
-
-#endif /* __RZG2L_MIPI_DSI_REGS_H__ */