Commit 55bf1496 authored by Daniel Vetter's avatar Daniel Vetter

Merge tag 'mediatek-drm-next-6.4' of...

Merge tag 'mediatek-drm-next-6.4' of https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux into drm-next

Mediatek DRM Next for Linux 6.4

1. Add support for 10-bit overlays
2. Add MediaTek SoC DRM (vdosys1) support for mt8195
3. Change mmsys compatible for mt8195 mediatek-drm
4. Only trigger DRM HPD events if bridge is attached
5. Change the aux retries times when receiving AUX_DEFER
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
From: Chun-Kuang Hu <chunkuang.hu@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20230410233005.2572-1-chunkuang.hu@kernel.org
parents b8d85bb5 9243d70e
......@@ -27,13 +27,10 @@ properties:
- const: mediatek,mt8192-disp-ccorr
- items:
- enum:
- mediatek,mt8186-disp-ccorr
- mediatek,mt8188-disp-ccorr
- mediatek,mt8195-disp-ccorr
- const: mediatek,mt8192-disp-ccorr
- items:
- enum:
- mediatek,mt8186-disp-ccorr
- const: mediatek,mt8192-disp-ccorr
reg:
maxItems: 1
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/mediatek/mediatek,ethdr.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MediaTek Ethdr Device
maintainers:
- Chun-Kuang Hu <chunkuang.hu@kernel.org>
- Philipp Zabel <p.zabel@pengutronix.de>
description:
ETHDR (ET High Dynamic Range) is a MediaTek internal HDR engine and is
designed for HDR video and graphics conversion in the external display path.
It handles multiple HDR input types and performs tone mapping, color
space/color format conversion, and then combine different layers,
output the required HDR or SDR signal to the subsequent display path.
This engine is composed of two video frontends, two graphic frontends,
one video backend and a mixer. ETHDR has two DMA function blocks, DS and ADL.
These two function blocks read the pre-programmed registers from DRAM and
set them to HW in the v-blanking period.
properties:
compatible:
const: mediatek,mt8195-disp-ethdr
reg:
maxItems: 7
reg-names:
items:
- const: mixer
- const: vdo_fe0
- const: vdo_fe1
- const: gfx_fe0
- const: gfx_fe1
- const: vdo_be
- const: adl_ds
interrupts:
maxItems: 1
iommus:
minItems: 1
maxItems: 2
clocks:
items:
- description: mixer clock
- description: video frontend 0 clock
- description: video frontend 1 clock
- description: graphic frontend 0 clock
- description: graphic frontend 1 clock
- description: video backend clock
- description: autodownload and menuload clock
- description: video frontend 0 async clock
- description: video frontend 1 async clock
- description: graphic frontend 0 async clock
- description: graphic frontend 1 async clock
- description: video backend async clock
- description: ethdr top clock
clock-names:
items:
- const: mixer
- const: vdo_fe0
- const: vdo_fe1
- const: gfx_fe0
- const: gfx_fe1
- const: vdo_be
- const: adl_ds
- const: vdo_fe0_async
- const: vdo_fe1_async
- const: gfx_fe0_async
- const: gfx_fe1_async
- const: vdo_be_async
- const: ethdr_top
power-domains:
maxItems: 1
resets:
items:
- description: video frontend 0 async reset
- description: video frontend 1 async reset
- description: graphic frontend 0 async reset
- description: graphic frontend 1 async reset
- description: video backend async reset
reset-names:
items:
- const: vdo_fe0_async
- const: vdo_fe1_async
- const: gfx_fe0_async
- const: gfx_fe1_async
- const: vdo_be_async
mediatek,gce-client-reg:
$ref: /schemas/types.yaml#/definitions/phandle-array
minItems: 1
maxItems: 7
description: The register of display function block to be set by gce.
There are 4 arguments in this property, gce node, subsys id, offset and
register size. The subsys id is defined in the gce header of each chips
include/dt-bindings/gce/<chip>-gce.h, mapping to the register of display
function block.
required:
- compatible
- reg
- clocks
- clock-names
- interrupts
- power-domains
- resets
- mediatek,gce-client-reg
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/mt8195-clk.h>
#include <dt-bindings/gce/mt8195-gce.h>
#include <dt-bindings/memory/mt8195-memory-port.h>
#include <dt-bindings/power/mt8195-power.h>
#include <dt-bindings/reset/mt8195-resets.h>
soc {
#address-cells = <2>;
#size-cells = <2>;
hdr-engine@1c114000 {
compatible = "mediatek,mt8195-disp-ethdr";
reg = <0 0x1c114000 0 0x1000>,
<0 0x1c115000 0 0x1000>,
<0 0x1c117000 0 0x1000>,
<0 0x1c119000 0 0x1000>,
<0 0x1c11a000 0 0x1000>,
<0 0x1c11b000 0 0x1000>,
<0 0x1c11c000 0 0x1000>;
reg-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
"vdo_be", "adl_ds";
mediatek,gce-client-reg = <&gce0 SUBSYS_1c11XXXX 0x4000 0x1000>,
<&gce0 SUBSYS_1c11XXXX 0x5000 0x1000>,
<&gce0 SUBSYS_1c11XXXX 0x7000 0x1000>,
<&gce0 SUBSYS_1c11XXXX 0x9000 0x1000>,
<&gce0 SUBSYS_1c11XXXX 0xa000 0x1000>,
<&gce0 SUBSYS_1c11XXXX 0xb000 0x1000>,
<&gce0 SUBSYS_1c11XXXX 0xc000 0x1000>;
clocks = <&vdosys1 CLK_VDO1_DISP_MIXER>,
<&vdosys1 CLK_VDO1_HDR_VDO_FE0>,
<&vdosys1 CLK_VDO1_HDR_VDO_FE1>,
<&vdosys1 CLK_VDO1_HDR_GFX_FE0>,
<&vdosys1 CLK_VDO1_HDR_GFX_FE1>,
<&vdosys1 CLK_VDO1_HDR_VDO_BE>,
<&vdosys1 CLK_VDO1_26M_SLOW>,
<&vdosys1 CLK_VDO1_HDR_VDO_FE0_DL_ASYNC>,
<&vdosys1 CLK_VDO1_HDR_VDO_FE1_DL_ASYNC>,
<&vdosys1 CLK_VDO1_HDR_GFX_FE0_DL_ASYNC>,
<&vdosys1 CLK_VDO1_HDR_GFX_FE1_DL_ASYNC>,
<&vdosys1 CLK_VDO1_HDR_VDO_BE_DL_ASYNC>,
<&topckgen CLK_TOP_ETHDR>;
clock-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
"vdo_be", "adl_ds", "vdo_fe0_async", "vdo_fe1_async",
"gfx_fe0_async", "gfx_fe1_async","vdo_be_async",
"ethdr_top";
power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
iommus = <&iommu_vpp M4U_PORT_L3_HDR_DS>,
<&iommu_vpp M4U_PORT_L3_HDR_ADL>;
interrupts = <GIC_SPI 517 IRQ_TYPE_LEVEL_HIGH 0>; /* disp mixer */
resets = <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE0_DL_ASYNC>,
<&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE1_DL_ASYNC>,
<&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE0_DL_ASYNC>,
<&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE1_DL_ASYNC>,
<&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_BE_DL_ASYNC>;
reset-names = "vdo_fe0_async", "vdo_fe1_async", "gfx_fe0_async",
"gfx_fe1_async", "vdo_be_async";
};
};
...
......@@ -6,6 +6,7 @@ mediatek-drm-y := mtk_disp_aal.o \
mtk_disp_gamma.o \
mtk_disp_merge.o \
mtk_disp_ovl.o \
mtk_disp_ovl_adaptor.o \
mtk_disp_rdma.o \
mtk_drm_crtc.o \
mtk_drm_ddp_comp.o \
......@@ -14,6 +15,7 @@ mediatek-drm-y := mtk_disp_aal.o \
mtk_drm_plane.o \
mtk_dsi.o \
mtk_dpi.o \
mtk_ethdr.o \
mtk_mdp_rdma.o
obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
......
......@@ -7,6 +7,8 @@
#define _MTK_DISP_DRV_H_
#include <linux/soc/mediatek/mtk-cmdq.h>
#include <linux/soc/mediatek/mtk-mmsys.h>
#include <linux/soc/mediatek/mtk-mutex.h>
#include "mtk_drm_plane.h"
#include "mtk_mdp_rdma.h"
......@@ -96,6 +98,34 @@ void mtk_ovl_register_vblank_cb(struct device *dev,
void mtk_ovl_unregister_vblank_cb(struct device *dev);
void mtk_ovl_enable_vblank(struct device *dev);
void mtk_ovl_disable_vblank(struct device *dev);
const u32 *mtk_ovl_get_formats(struct device *dev);
size_t mtk_ovl_get_num_formats(struct device *dev);
void mtk_ovl_adaptor_add_comp(struct device *dev, struct mtk_mutex *mutex);
void mtk_ovl_adaptor_remove_comp(struct device *dev, struct mtk_mutex *mutex);
void mtk_ovl_adaptor_connect(struct device *dev, struct device *mmsys_dev,
unsigned int next);
void mtk_ovl_adaptor_disconnect(struct device *dev, struct device *mmsys_dev,
unsigned int next);
int mtk_ovl_adaptor_clk_enable(struct device *dev);
void mtk_ovl_adaptor_clk_disable(struct device *dev);
void mtk_ovl_adaptor_config(struct device *dev, unsigned int w,
unsigned int h, unsigned int vrefresh,
unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
struct mtk_plane_state *state,
struct cmdq_pkt *cmdq_pkt);
void mtk_ovl_adaptor_register_vblank_cb(struct device *dev, void (*vblank_cb)(void *),
void *vblank_cb_data);
void mtk_ovl_adaptor_unregister_vblank_cb(struct device *dev);
void mtk_ovl_adaptor_enable_vblank(struct device *dev);
void mtk_ovl_adaptor_disable_vblank(struct device *dev);
void mtk_ovl_adaptor_start(struct device *dev);
void mtk_ovl_adaptor_stop(struct device *dev);
unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev);
struct device *mtk_ovl_adaptor_dma_dev_get(struct device *dev);
const u32 *mtk_ovl_adaptor_get_formats(struct device *dev);
size_t mtk_ovl_adaptor_get_num_formats(struct device *dev);
void mtk_rdma_bypass_shadow(struct device *dev);
int mtk_rdma_clk_enable(struct device *dev);
......@@ -115,6 +145,8 @@ void mtk_rdma_register_vblank_cb(struct device *dev,
void mtk_rdma_unregister_vblank_cb(struct device *dev);
void mtk_rdma_enable_vblank(struct device *dev);
void mtk_rdma_disable_vblank(struct device *dev);
const u32 *mtk_rdma_get_formats(struct device *dev);
size_t mtk_rdma_get_num_formats(struct device *dev);
int mtk_mdp_rdma_clk_enable(struct device *dev);
void mtk_mdp_rdma_clk_disable(struct device *dev);
......@@ -122,4 +154,7 @@ void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt);
void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt);
void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg,
struct cmdq_pkt *cmdq_pkt);
const u32 *mtk_mdp_rdma_get_formats(struct device *dev);
size_t mtk_mdp_rdma_get_num_formats(struct device *dev);
#endif
......@@ -42,6 +42,7 @@
#define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n))
#define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n))
#define DISP_REG_OVL_ADDR_MT2701 0x0040
#define DISP_REG_OVL_CLRFMT_EXT 0x02D0
#define DISP_REG_OVL_ADDR_MT8173 0x0f40
#define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n))
#define DISP_REG_OVL_HDR_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n) + 0x04)
......@@ -62,11 +63,45 @@
0 : OVL_CON_CLRFMT_RGB)
#define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
OVL_CON_CLRFMT_RGB : 0)
#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl))
#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl) (depth << 4 * (ovl))
#define OVL_CON_CLRFMT_8_BIT 0x00
#define OVL_CON_CLRFMT_10_BIT 0x01
#define OVL_CON_AEN BIT(8)
#define OVL_CON_ALPHA 0xff
#define OVL_CON_VIRT_FLIP BIT(9)
#define OVL_CON_HORZ_FLIP BIT(10)
static const u32 mt8173_formats[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_BGRX8888,
DRM_FORMAT_BGRA8888,
DRM_FORMAT_ABGR8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_RGB888,
DRM_FORMAT_BGR888,
DRM_FORMAT_RGB565,
DRM_FORMAT_UYVY,
DRM_FORMAT_YUYV,
};
static const u32 mt8195_formats[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_ARGB2101010,
DRM_FORMAT_BGRX8888,
DRM_FORMAT_BGRA8888,
DRM_FORMAT_BGRA1010102,
DRM_FORMAT_ABGR8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_RGB888,
DRM_FORMAT_BGR888,
DRM_FORMAT_RGB565,
DRM_FORMAT_UYVY,
DRM_FORMAT_YUYV,
};
struct mtk_disp_ovl_data {
unsigned int addr;
unsigned int gmc_bits;
......@@ -74,6 +109,9 @@ struct mtk_disp_ovl_data {
bool fmt_rgb565_is_0;
bool smi_id_en;
bool supports_afbc;
const u32 *formats;
size_t num_formats;
bool supports_clrfmt_ext;
};
/*
......@@ -139,6 +177,20 @@ void mtk_ovl_disable_vblank(struct device *dev)
writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN);
}
const u32 *mtk_ovl_get_formats(struct device *dev)
{
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
return ovl->data->formats;
}
size_t mtk_ovl_get_num_formats(struct device *dev)
{
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
return ovl->data->num_formats;
}
int mtk_ovl_clk_enable(struct device *dev)
{
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
......@@ -189,6 +241,30 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, struct cmdq_pkt *cmdq_pkt
DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx));
}
static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format,
struct cmdq_pkt *cmdq_pkt)
{
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
unsigned int reg;
unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT;
if (!ovl->data->supports_clrfmt_ext)
return;
reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT);
reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx);
if (format == DRM_FORMAT_RGBA1010102 ||
format == DRM_FORMAT_BGRA1010102 ||
format == DRM_FORMAT_ARGB2101010)
bit_depth = OVL_CON_CLRFMT_10_BIT;
reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx);
mtk_ddp_write(cmdq_pkt, reg, &ovl->cmdq_reg,
ovl->regs, DISP_REG_OVL_CLRFMT_EXT);
}
void mtk_ovl_config(struct device *dev, unsigned int w,
unsigned int h, unsigned int vrefresh,
unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
......@@ -303,9 +379,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
return OVL_CON_CLRFMT_ARGB8888;
case DRM_FORMAT_BGRX8888:
case DRM_FORMAT_BGRA8888:
case DRM_FORMAT_BGRA1010102:
return OVL_CON_CLRFMT_ARGB8888 | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_ARGB8888:
case DRM_FORMAT_ARGB2101010:
return OVL_CON_CLRFMT_RGBA8888;
case DRM_FORMAT_XBGR8888:
case DRM_FORMAT_ABGR8888:
......@@ -389,6 +467,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
&ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
}
mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt);
mtk_ovl_layer_on(dev, idx, cmdq_pkt);
}
......@@ -496,6 +575,8 @@ static const struct mtk_disp_ovl_data mt2701_ovl_driver_data = {
.gmc_bits = 8,
.layer_nr = 4,
.fmt_rgb565_is_0 = false,
.formats = mt8173_formats,
.num_formats = ARRAY_SIZE(mt8173_formats),
};
static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {
......@@ -503,6 +584,8 @@ static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {
.gmc_bits = 8,
.layer_nr = 4,
.fmt_rgb565_is_0 = true,
.formats = mt8173_formats,
.num_formats = ARRAY_SIZE(mt8173_formats),
};
static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = {
......@@ -510,6 +593,8 @@ static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = {
.gmc_bits = 10,
.layer_nr = 4,
.fmt_rgb565_is_0 = true,
.formats = mt8173_formats,
.num_formats = ARRAY_SIZE(mt8173_formats),
};
static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = {
......@@ -517,6 +602,8 @@ static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = {
.gmc_bits = 10,
.layer_nr = 2,
.fmt_rgb565_is_0 = true,
.formats = mt8173_formats,
.num_formats = ARRAY_SIZE(mt8173_formats),
};
static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = {
......@@ -525,6 +612,8 @@ static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = {
.layer_nr = 4,
.fmt_rgb565_is_0 = true,
.smi_id_en = true,
.formats = mt8173_formats,
.num_formats = ARRAY_SIZE(mt8173_formats),
};
static const struct mtk_disp_ovl_data mt8192_ovl_2l_driver_data = {
......@@ -533,6 +622,8 @@ static const struct mtk_disp_ovl_data mt8192_ovl_2l_driver_data = {
.layer_nr = 2,
.fmt_rgb565_is_0 = true,
.smi_id_en = true,
.formats = mt8173_formats,
.num_formats = ARRAY_SIZE(mt8173_formats),
};
static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = {
......@@ -542,6 +633,9 @@ static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = {
.fmt_rgb565_is_0 = true,
.smi_id_en = true,
.supports_afbc = true,
.formats = mt8195_formats,
.num_formats = ARRAY_SIZE(mt8195_formats),
.supports_clrfmt_ext = true,
};
static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
......
This diff is collapsed.
......@@ -55,8 +55,24 @@
#define RDMA_MEM_GMC 0x40402020
static const u32 mt8173_formats[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_BGRX8888,
DRM_FORMAT_BGRA8888,
DRM_FORMAT_ABGR8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_RGB888,
DRM_FORMAT_BGR888,
DRM_FORMAT_RGB565,
DRM_FORMAT_UYVY,
DRM_FORMAT_YUYV,
};
struct mtk_disp_rdma_data {
unsigned int fifo_size;
const u32 *formats;
size_t num_formats;
};
/*
......@@ -127,6 +143,20 @@ void mtk_rdma_disable_vblank(struct device *dev)
rdma_update_bits(dev, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, 0);
}
const u32 *mtk_rdma_get_formats(struct device *dev)
{
struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
return rdma->data->formats;
}
size_t mtk_rdma_get_num_formats(struct device *dev)
{
struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
return rdma->data->num_formats;
}
int mtk_rdma_clk_enable(struct device *dev)
{
struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
......@@ -361,18 +391,26 @@ static int mtk_disp_rdma_remove(struct platform_device *pdev)
static const struct mtk_disp_rdma_data mt2701_rdma_driver_data = {
.fifo_size = SZ_4K,
.formats = mt8173_formats,
.num_formats = ARRAY_SIZE(mt8173_formats),
};
static const struct mtk_disp_rdma_data mt8173_rdma_driver_data = {
.fifo_size = SZ_8K,
.formats = mt8173_formats,
.num_formats = ARRAY_SIZE(mt8173_formats),
};
static const struct mtk_disp_rdma_data mt8183_rdma_driver_data = {
.fifo_size = 5 * SZ_1K,
.formats = mt8173_formats,
.num_formats = ARRAY_SIZE(mt8173_formats),
};
static const struct mtk_disp_rdma_data mt8195_rdma_driver_data = {
.fifo_size = 1920,
.formats = mt8173_formats,
.num_formats = ARRAY_SIZE(mt8173_formats),
};
static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
......
......@@ -806,10 +806,9 @@ static int mtk_dp_aux_wait_for_completion(struct mtk_dp *mtk_dp, bool is_read)
}
static int mtk_dp_aux_do_transfer(struct mtk_dp *mtk_dp, bool is_read, u8 cmd,
u32 addr, u8 *buf, size_t length)
u32 addr, u8 *buf, size_t length, u8 *reply_cmd)
{
int ret;
u32 reply_cmd;
if (is_read && (length > DP_AUX_MAX_PAYLOAD_BYTES ||
(cmd == DP_AUX_NATIVE_READ && !length)))
......@@ -841,10 +840,10 @@ static int mtk_dp_aux_do_transfer(struct mtk_dp *mtk_dp, bool is_read, u8 cmd,
/* Wait for feedback from sink device. */
ret = mtk_dp_aux_wait_for_completion(mtk_dp, is_read);
reply_cmd = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3624) &
AUX_RX_REPLY_COMMAND_AUX_TX_P0_MASK;
*reply_cmd = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3624) &
AUX_RX_REPLY_COMMAND_AUX_TX_P0_MASK;
if (ret || reply_cmd) {
if (ret) {
u32 phy_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3628) &
AUX_RX_PHY_STATE_AUX_TX_P0_MASK;
if (phy_status != AUX_RX_PHY_STATE_AUX_TX_P0_RX_IDLE) {
......@@ -1823,7 +1822,8 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
spin_unlock_irqrestore(&mtk_dp->irq_thread_lock, flags);
if (status & MTK_DP_THREAD_CABLE_STATE_CHG) {
drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
if (mtk_dp->bridge.dev)
drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
if (!mtk_dp->train_info.cable_plugged_in) {
mtk_dp_disable_sdp_aui(mtk_dp);
......@@ -2070,7 +2070,7 @@ static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
ret = mtk_dp_aux_do_transfer(mtk_dp, is_read, request,
msg->address + accessed_bytes,
msg->buffer + accessed_bytes,
to_access);
to_access, &msg->reply);
if (ret) {
drm_info(mtk_dp->drm_dev,
......@@ -2080,7 +2080,6 @@ static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
accessed_bytes += to_access;
} while (accessed_bytes < msg->size);
msg->reply = DP_AUX_NATIVE_REPLY_ACK | DP_AUX_I2C_REPLY_ACK;
return msg->size;
err:
msg->reply = DP_AUX_NATIVE_REPLY_NACK | DP_AUX_I2C_REPLY_NACK;
......
......@@ -58,6 +58,7 @@ struct mtk_drm_crtc {
#endif
struct device *mmsys_dev;
struct device *dma_dev;
struct mtk_mutex *mutex;
unsigned int ddp_comp_nr;
struct mtk_ddp_comp **ddp_comp;
......@@ -378,13 +379,17 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
}
for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {
mtk_mmsys_ddp_connect(mtk_crtc->mmsys_dev,
mtk_crtc->ddp_comp[i]->id,
mtk_crtc->ddp_comp[i + 1]->id);
mtk_mutex_add_comp(mtk_crtc->mutex,
mtk_crtc->ddp_comp[i]->id);
if (!mtk_ddp_comp_connect(mtk_crtc->ddp_comp[i], mtk_crtc->mmsys_dev,
mtk_crtc->ddp_comp[i + 1]->id))
mtk_mmsys_ddp_connect(mtk_crtc->mmsys_dev,
mtk_crtc->ddp_comp[i]->id,
mtk_crtc->ddp_comp[i + 1]->id);
if (!mtk_ddp_comp_add(mtk_crtc->ddp_comp[i], mtk_crtc->mutex))
mtk_mutex_add_comp(mtk_crtc->mutex,
mtk_crtc->ddp_comp[i]->id);
}
mtk_mutex_add_comp(mtk_crtc->mutex, mtk_crtc->ddp_comp[i]->id);
if (!mtk_ddp_comp_add(mtk_crtc->ddp_comp[i], mtk_crtc->mutex))
mtk_mutex_add_comp(mtk_crtc->mutex, mtk_crtc->ddp_comp[i]->id);
mtk_mutex_enable(mtk_crtc->mutex);
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
......@@ -433,17 +438,22 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
}
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
mtk_mutex_remove_comp(mtk_crtc->mutex,
mtk_crtc->ddp_comp[i]->id);
if (!mtk_ddp_comp_remove(mtk_crtc->ddp_comp[i], mtk_crtc->mutex))
mtk_mutex_remove_comp(mtk_crtc->mutex,
mtk_crtc->ddp_comp[i]->id);
mtk_mutex_disable(mtk_crtc->mutex);
for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {
mtk_mmsys_ddp_disconnect(mtk_crtc->mmsys_dev,
mtk_crtc->ddp_comp[i]->id,
mtk_crtc->ddp_comp[i + 1]->id);
mtk_mutex_remove_comp(mtk_crtc->mutex,
mtk_crtc->ddp_comp[i]->id);
if (!mtk_ddp_comp_disconnect(mtk_crtc->ddp_comp[i], mtk_crtc->mmsys_dev,
mtk_crtc->ddp_comp[i + 1]->id))
mtk_mmsys_ddp_disconnect(mtk_crtc->mmsys_dev,
mtk_crtc->ddp_comp[i]->id,
mtk_crtc->ddp_comp[i + 1]->id);
if (!mtk_ddp_comp_remove(mtk_crtc->ddp_comp[i], mtk_crtc->mutex))
mtk_mutex_remove_comp(mtk_crtc->mutex,
mtk_crtc->ddp_comp[i]->id);
}
mtk_mutex_remove_comp(mtk_crtc->mutex, mtk_crtc->ddp_comp[i]->id);
if (!mtk_ddp_comp_remove(mtk_crtc->ddp_comp[i], mtk_crtc->mutex))
mtk_mutex_remove_comp(mtk_crtc->mutex, mtk_crtc->ddp_comp[i]->id);
mtk_crtc_ddp_clk_disable(mtk_crtc);
mtk_mutex_unprepare(mtk_crtc->mutex);
......@@ -856,7 +866,9 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
BIT(pipe),
mtk_drm_crtc_plane_type(mtk_crtc->layer_nr,
num_planes),
mtk_ddp_comp_supported_rotations(comp));
mtk_ddp_comp_supported_rotations(comp),
mtk_ddp_comp_get_formats(comp),
mtk_ddp_comp_get_num_formats(comp));
if (ret)
return ret;
......@@ -865,22 +877,36 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
return 0;
}
struct device *mtk_drm_crtc_dma_dev_get(struct drm_crtc *crtc)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
return mtk_crtc->dma_dev;
}
int mtk_drm_crtc_create(struct drm_device *drm_dev,
const enum mtk_ddp_comp_id *path, unsigned int path_len)
const unsigned int *path, unsigned int path_len,
int priv_data_index)
{
struct mtk_drm_private *priv = drm_dev->dev_private;
struct device *dev = drm_dev->dev;
struct mtk_drm_crtc *mtk_crtc;
unsigned int num_comp_planes = 0;
int pipe = priv->num_pipes;
int ret;
int i;
bool has_ctm = false;
uint gamma_lut_size = 0;
struct drm_crtc *tmp;
int crtc_i = 0;
if (!path)
return 0;
priv = priv->all_drm_private[priv_data_index];
drm_for_each_crtc(tmp, drm_dev)
crtc_i++;
for (i = 0; i < path_len; i++) {
enum mtk_ddp_comp_id comp_id = path[i];
struct device_node *node;
......@@ -889,10 +915,13 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
node = priv->comp_node[comp_id];
comp = &priv->ddp_comp[comp_id];
if (!node) {
/* Not all drm components have a DTS device node, such as ovl_adaptor,
* which is the drm bring up sub driver
*/
if (!node && comp_id != DDP_COMPONENT_DRM_OVL_ADAPTOR) {
dev_info(dev,
"Not creating crtc %d because component %d is disabled or missing\n",
pipe, comp_id);
"Not creating crtc %d because component %d is disabled or missing\n",
crtc_i, comp_id);
return 0;
}
......@@ -922,7 +951,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
}
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
enum mtk_ddp_comp_id comp_id = path[i];
unsigned int comp_id = path[i];
struct mtk_ddp_comp *comp;
comp = &priv->ddp_comp[comp_id];
......@@ -950,29 +979,35 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc, i,
pipe);
crtc_i);
if (ret)
return ret;
}
ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, pipe);
/*
* Default to use the first component as the dma dev.
* In the case of ovl_adaptor sub driver, it needs to use the
* dma_dev_get function to get representative dma dev.
*/
mtk_crtc->dma_dev = mtk_ddp_comp_dma_dev_get(&priv->ddp_comp[path[0]]);
ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, crtc_i);
if (ret < 0)
return ret;
if (gamma_lut_size)
drm_mode_crtc_set_gamma_size(&mtk_crtc->base, gamma_lut_size);
drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm, gamma_lut_size);
priv->num_pipes++;
mutex_init(&mtk_crtc->hw_lock);
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
i = priv->mbox_index++;
mtk_crtc->cmdq_client.client.dev = mtk_crtc->mmsys_dev;
mtk_crtc->cmdq_client.client.tx_block = false;
mtk_crtc->cmdq_client.client.knows_txdone = true;
mtk_crtc->cmdq_client.client.rx_callback = ddp_cmdq_cb;
mtk_crtc->cmdq_client.chan =
mbox_request_channel(&mtk_crtc->cmdq_client.client,
drm_crtc_index(&mtk_crtc->base));
mbox_request_channel(&mtk_crtc->cmdq_client.client, i);
if (IS_ERR(mtk_crtc->cmdq_client.chan)) {
dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n",
drm_crtc_index(&mtk_crtc->base));
......@@ -982,7 +1017,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
if (mtk_crtc->cmdq_client.chan) {
ret = of_property_read_u32_index(priv->mutex_node,
"mediatek,gce-events",
drm_crtc_index(&mtk_crtc->base),
i,
&mtk_crtc->cmdq_event);
if (ret) {
dev_dbg(dev, "mtk_crtc %d failed to get mediatek,gce-events property\n",
......
......@@ -16,11 +16,13 @@
void mtk_drm_crtc_commit(struct drm_crtc *crtc);
int mtk_drm_crtc_create(struct drm_device *drm_dev,
const enum mtk_ddp_comp_id *path,
unsigned int path_len);
const unsigned int *path,
unsigned int path_len,
int priv_data_index);
int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
struct mtk_plane_state *state);
void mtk_drm_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
struct drm_atomic_state *plane_state);
struct device *mtk_drm_crtc_dma_dev_get(struct drm_crtc *crtc);
#endif /* MTK_DRM_CRTC_H */
......@@ -359,6 +359,8 @@ static const struct mtk_ddp_comp_funcs ddp_ovl = {
.layer_config = mtk_ovl_layer_config,
.bgclr_in_on = mtk_ovl_bgclr_in_on,
.bgclr_in_off = mtk_ovl_bgclr_in_off,
.get_formats = mtk_ovl_get_formats,
.get_num_formats = mtk_ovl_get_num_formats,
};
static const struct mtk_ddp_comp_funcs ddp_postmask = {
......@@ -381,6 +383,8 @@ static const struct mtk_ddp_comp_funcs ddp_rdma = {
.disable_vblank = mtk_rdma_disable_vblank,
.layer_nr = mtk_rdma_layer_nr,
.layer_config = mtk_rdma_layer_config,
.get_formats = mtk_rdma_get_formats,
.get_num_formats = mtk_rdma_get_num_formats,
};
static const struct mtk_ddp_comp_funcs ddp_ufoe = {
......@@ -389,6 +393,27 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe = {
.start = mtk_ufoe_start,
};
static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
.clk_enable = mtk_ovl_adaptor_clk_enable,
.clk_disable = mtk_ovl_adaptor_clk_disable,
.config = mtk_ovl_adaptor_config,
.start = mtk_ovl_adaptor_start,
.stop = mtk_ovl_adaptor_stop,
.layer_nr = mtk_ovl_adaptor_layer_nr,
.layer_config = mtk_ovl_adaptor_layer_config,
.register_vblank_cb = mtk_ovl_adaptor_register_vblank_cb,
.unregister_vblank_cb = mtk_ovl_adaptor_unregister_vblank_cb,
.enable_vblank = mtk_ovl_adaptor_enable_vblank,
.disable_vblank = mtk_ovl_adaptor_disable_vblank,
.dma_dev_get = mtk_ovl_adaptor_dma_dev_get,
.connect = mtk_ovl_adaptor_connect,
.disconnect = mtk_ovl_adaptor_disconnect,
.add = mtk_ovl_adaptor_add_comp,
.remove = mtk_ovl_adaptor_remove_comp,
.get_formats = mtk_ovl_adaptor_get_formats,
.get_num_formats = mtk_ovl_adaptor_get_num_formats,
};
static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
[MTK_DISP_AAL] = "aal",
[MTK_DISP_BLS] = "bls",
......@@ -402,6 +427,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
[MTK_DISP_OD] = "od",
[MTK_DISP_OVL] = "ovl",
[MTK_DISP_OVL_2L] = "ovl-2l",
[MTK_DISP_OVL_ADAPTOR] = "ovl_adaptor",
[MTK_DISP_POSTMASK] = "postmask",
[MTK_DISP_PWM] = "pwm",
[MTK_DISP_RDMA] = "rdma",
......@@ -418,53 +444,54 @@ struct mtk_ddp_comp_match {
const struct mtk_ddp_comp_funcs *funcs;
};
static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_AAL0] = { MTK_DISP_AAL, 0, &ddp_aal },
[DDP_COMPONENT_AAL1] = { MTK_DISP_AAL, 1, &ddp_aal },
[DDP_COMPONENT_BLS] = { MTK_DISP_BLS, 0, NULL },
[DDP_COMPONENT_CCORR] = { MTK_DISP_CCORR, 0, &ddp_ccorr },
[DDP_COMPONENT_COLOR0] = { MTK_DISP_COLOR, 0, &ddp_color },
[DDP_COMPONENT_COLOR1] = { MTK_DISP_COLOR, 1, &ddp_color },
[DDP_COMPONENT_DITHER0] = { MTK_DISP_DITHER, 0, &ddp_dither },
[DDP_COMPONENT_DP_INTF0] = { MTK_DP_INTF, 0, &ddp_dpi },
[DDP_COMPONENT_DP_INTF1] = { MTK_DP_INTF, 1, &ddp_dpi },
[DDP_COMPONENT_DPI0] = { MTK_DPI, 0, &ddp_dpi },
[DDP_COMPONENT_DPI1] = { MTK_DPI, 1, &ddp_dpi },
[DDP_COMPONENT_DSC0] = { MTK_DISP_DSC, 0, &ddp_dsc },
[DDP_COMPONENT_DSC1] = { MTK_DISP_DSC, 1, &ddp_dsc },
[DDP_COMPONENT_DSI0] = { MTK_DSI, 0, &ddp_dsi },
[DDP_COMPONENT_DSI1] = { MTK_DSI, 1, &ddp_dsi },
[DDP_COMPONENT_DSI2] = { MTK_DSI, 2, &ddp_dsi },
[DDP_COMPONENT_DSI3] = { MTK_DSI, 3, &ddp_dsi },
[DDP_COMPONENT_GAMMA] = { MTK_DISP_GAMMA, 0, &ddp_gamma },
[DDP_COMPONENT_MERGE0] = { MTK_DISP_MERGE, 0, &ddp_merge },
[DDP_COMPONENT_MERGE1] = { MTK_DISP_MERGE, 1, &ddp_merge },
[DDP_COMPONENT_MERGE2] = { MTK_DISP_MERGE, 2, &ddp_merge },
[DDP_COMPONENT_MERGE3] = { MTK_DISP_MERGE, 3, &ddp_merge },
[DDP_COMPONENT_MERGE4] = { MTK_DISP_MERGE, 4, &ddp_merge },
[DDP_COMPONENT_MERGE5] = { MTK_DISP_MERGE, 5, &ddp_merge },
[DDP_COMPONENT_OD0] = { MTK_DISP_OD, 0, &ddp_od },
[DDP_COMPONENT_OD1] = { MTK_DISP_OD, 1, &ddp_od },
[DDP_COMPONENT_OVL0] = { MTK_DISP_OVL, 0, &ddp_ovl },
[DDP_COMPONENT_OVL1] = { MTK_DISP_OVL, 1, &ddp_ovl },
[DDP_COMPONENT_OVL_2L0] = { MTK_DISP_OVL_2L, 0, &ddp_ovl },
[DDP_COMPONENT_OVL_2L1] = { MTK_DISP_OVL_2L, 1, &ddp_ovl },
[DDP_COMPONENT_OVL_2L2] = { MTK_DISP_OVL_2L, 2, &ddp_ovl },
[DDP_COMPONENT_POSTMASK0] = { MTK_DISP_POSTMASK, 0, &ddp_postmask },
[DDP_COMPONENT_PWM0] = { MTK_DISP_PWM, 0, NULL },
[DDP_COMPONENT_PWM1] = { MTK_DISP_PWM, 1, NULL },
[DDP_COMPONENT_PWM2] = { MTK_DISP_PWM, 2, NULL },
[DDP_COMPONENT_RDMA0] = { MTK_DISP_RDMA, 0, &ddp_rdma },
[DDP_COMPONENT_RDMA1] = { MTK_DISP_RDMA, 1, &ddp_rdma },
[DDP_COMPONENT_RDMA2] = { MTK_DISP_RDMA, 2, &ddp_rdma },
[DDP_COMPONENT_RDMA4] = { MTK_DISP_RDMA, 4, &ddp_rdma },
[DDP_COMPONENT_UFOE] = { MTK_DISP_UFOE, 0, &ddp_ufoe },
[DDP_COMPONENT_WDMA0] = { MTK_DISP_WDMA, 0, NULL },
[DDP_COMPONENT_WDMA1] = { MTK_DISP_WDMA, 1, NULL },
static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_DRM_ID_MAX] = {
[DDP_COMPONENT_AAL0] = { MTK_DISP_AAL, 0, &ddp_aal },
[DDP_COMPONENT_AAL1] = { MTK_DISP_AAL, 1, &ddp_aal },
[DDP_COMPONENT_BLS] = { MTK_DISP_BLS, 0, NULL },
[DDP_COMPONENT_CCORR] = { MTK_DISP_CCORR, 0, &ddp_ccorr },
[DDP_COMPONENT_COLOR0] = { MTK_DISP_COLOR, 0, &ddp_color },
[DDP_COMPONENT_COLOR1] = { MTK_DISP_COLOR, 1, &ddp_color },
[DDP_COMPONENT_DITHER0] = { MTK_DISP_DITHER, 0, &ddp_dither },
[DDP_COMPONENT_DP_INTF0] = { MTK_DP_INTF, 0, &ddp_dpi },
[DDP_COMPONENT_DP_INTF1] = { MTK_DP_INTF, 1, &ddp_dpi },
[DDP_COMPONENT_DPI0] = { MTK_DPI, 0, &ddp_dpi },
[DDP_COMPONENT_DPI1] = { MTK_DPI, 1, &ddp_dpi },
[DDP_COMPONENT_DRM_OVL_ADAPTOR] = { MTK_DISP_OVL_ADAPTOR, 0, &ddp_ovl_adaptor },
[DDP_COMPONENT_DSC0] = { MTK_DISP_DSC, 0, &ddp_dsc },
[DDP_COMPONENT_DSC1] = { MTK_DISP_DSC, 1, &ddp_dsc },
[DDP_COMPONENT_DSI0] = { MTK_DSI, 0, &ddp_dsi },
[DDP_COMPONENT_DSI1] = { MTK_DSI, 1, &ddp_dsi },
[DDP_COMPONENT_DSI2] = { MTK_DSI, 2, &ddp_dsi },
[DDP_COMPONENT_DSI3] = { MTK_DSI, 3, &ddp_dsi },
[DDP_COMPONENT_GAMMA] = { MTK_DISP_GAMMA, 0, &ddp_gamma },
[DDP_COMPONENT_MERGE0] = { MTK_DISP_MERGE, 0, &ddp_merge },
[DDP_COMPONENT_MERGE1] = { MTK_DISP_MERGE, 1, &ddp_merge },
[DDP_COMPONENT_MERGE2] = { MTK_DISP_MERGE, 2, &ddp_merge },
[DDP_COMPONENT_MERGE3] = { MTK_DISP_MERGE, 3, &ddp_merge },
[DDP_COMPONENT_MERGE4] = { MTK_DISP_MERGE, 4, &ddp_merge },
[DDP_COMPONENT_MERGE5] = { MTK_DISP_MERGE, 5, &ddp_merge },
[DDP_COMPONENT_OD0] = { MTK_DISP_OD, 0, &ddp_od },
[DDP_COMPONENT_OD1] = { MTK_DISP_OD, 1, &ddp_od },
[DDP_COMPONENT_OVL0] = { MTK_DISP_OVL, 0, &ddp_ovl },
[DDP_COMPONENT_OVL1] = { MTK_DISP_OVL, 1, &ddp_ovl },
[DDP_COMPONENT_OVL_2L0] = { MTK_DISP_OVL_2L, 0, &ddp_ovl },
[DDP_COMPONENT_OVL_2L1] = { MTK_DISP_OVL_2L, 1, &ddp_ovl },
[DDP_COMPONENT_OVL_2L2] = { MTK_DISP_OVL_2L, 2, &ddp_ovl },
[DDP_COMPONENT_POSTMASK0] = { MTK_DISP_POSTMASK, 0, &ddp_postmask },
[DDP_COMPONENT_PWM0] = { MTK_DISP_PWM, 0, NULL },
[DDP_COMPONENT_PWM1] = { MTK_DISP_PWM, 1, NULL },
[DDP_COMPONENT_PWM2] = { MTK_DISP_PWM, 2, NULL },
[DDP_COMPONENT_RDMA0] = { MTK_DISP_RDMA, 0, &ddp_rdma },
[DDP_COMPONENT_RDMA1] = { MTK_DISP_RDMA, 1, &ddp_rdma },
[DDP_COMPONENT_RDMA2] = { MTK_DISP_RDMA, 2, &ddp_rdma },
[DDP_COMPONENT_RDMA4] = { MTK_DISP_RDMA, 4, &ddp_rdma },
[DDP_COMPONENT_UFOE] = { MTK_DISP_UFOE, 0, &ddp_ufoe },
[DDP_COMPONENT_WDMA0] = { MTK_DISP_WDMA, 0, NULL },
[DDP_COMPONENT_WDMA1] = { MTK_DISP_WDMA, 1, NULL },
};
static bool mtk_drm_find_comp_in_ddp(struct device *dev,
const enum mtk_ddp_comp_id *path,
const unsigned int *path,
unsigned int path_len,
struct mtk_ddp_comp *ddp_comp)
{
......@@ -517,7 +544,7 @@ unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm,
}
int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
enum mtk_ddp_comp_id comp_id)
unsigned int comp_id)
{
struct platform_device *comp_pdev;
enum mtk_ddp_comp_type type;
......@@ -526,19 +553,24 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
int ret;
#endif
if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX)
if (comp_id < 0 || comp_id >= DDP_COMPONENT_DRM_ID_MAX)
return -EINVAL;
type = mtk_ddp_matches[comp_id].type;
comp->id = comp_id;
comp->funcs = mtk_ddp_matches[comp_id].funcs;
comp_pdev = of_find_device_by_node(node);
if (!comp_pdev) {
DRM_INFO("Waiting for device %s\n", node->full_name);
return -EPROBE_DEFER;
/* Not all drm components have a DTS device node, such as ovl_adaptor,
* which is the drm bring up sub driver
*/
if (node) {
comp_pdev = of_find_device_by_node(node);
if (!comp_pdev) {
DRM_INFO("Waiting for device %s\n", node->full_name);
return -EPROBE_DEFER;
}
comp->dev = &comp_pdev->dev;
}
comp->dev = &comp_pdev->dev;
if (type == MTK_DISP_AAL ||
type == MTK_DISP_BLS ||
......@@ -548,6 +580,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
type == MTK_DISP_MERGE ||
type == MTK_DISP_OVL ||
type == MTK_DISP_OVL_2L ||
type == MTK_DISP_OVL_ADAPTOR ||
type == MTK_DISP_PWM ||
type == MTK_DISP_RDMA ||
type == MTK_DPI ||
......
......@@ -9,6 +9,7 @@
#include <linux/io.h>
#include <linux/soc/mediatek/mtk-cmdq.h>
#include <linux/soc/mediatek/mtk-mmsys.h>
#include <linux/soc/mediatek/mtk-mutex.h>
struct device;
struct device_node;
......@@ -30,6 +31,7 @@ enum mtk_ddp_comp_type {
MTK_DISP_OD,
MTK_DISP_OVL,
MTK_DISP_OVL_2L,
MTK_DISP_OVL_ADAPTOR,
MTK_DISP_POSTMASK,
MTK_DISP_PWM,
MTK_DISP_RDMA,
......@@ -71,12 +73,19 @@ struct mtk_ddp_comp_funcs {
void (*bgclr_in_off)(struct device *dev);
void (*ctm_set)(struct device *dev,
struct drm_crtc_state *state);
struct device * (*dma_dev_get)(struct device *dev);
const u32 *(*get_formats)(struct device *dev);
size_t (*get_num_formats)(struct device *dev);
void (*connect)(struct device *dev, struct device *mmsys_dev, unsigned int next);
void (*disconnect)(struct device *dev, struct device *mmsys_dev, unsigned int next);
void (*add)(struct device *dev, struct mtk_mutex *mutex);
void (*remove)(struct device *dev, struct mtk_mutex *mutex);
};
struct mtk_ddp_comp {
struct device *dev;
int irq;
enum mtk_ddp_comp_id id;
unsigned int id;
const struct mtk_ddp_comp_funcs *funcs;
};
......@@ -203,13 +212,76 @@ static inline void mtk_ddp_ctm_set(struct mtk_ddp_comp *comp,
comp->funcs->ctm_set(comp->dev, state);
}
static inline struct device *mtk_ddp_comp_dma_dev_get(struct mtk_ddp_comp *comp)
{
if (comp->funcs && comp->funcs->dma_dev_get)
return comp->funcs->dma_dev_get(comp->dev);
return comp->dev;
}
static inline
const u32 *mtk_ddp_comp_get_formats(struct mtk_ddp_comp *comp)
{
if (comp->funcs && comp->funcs->get_formats)
return comp->funcs->get_formats(comp->dev);
return NULL;
}
static inline
size_t mtk_ddp_comp_get_num_formats(struct mtk_ddp_comp *comp)
{
if (comp->funcs && comp->funcs->get_num_formats)
return comp->funcs->get_num_formats(comp->dev);
return 0;
}
static inline bool mtk_ddp_comp_add(struct mtk_ddp_comp *comp, struct mtk_mutex *mutex)
{
if (comp->funcs && comp->funcs->add) {
comp->funcs->add(comp->dev, mutex);
return true;
}
return false;
}
static inline bool mtk_ddp_comp_remove(struct mtk_ddp_comp *comp, struct mtk_mutex *mutex)
{
if (comp->funcs && comp->funcs->remove) {
comp->funcs->remove(comp->dev, mutex);
return true;
}
return false;
}
static inline bool mtk_ddp_comp_connect(struct mtk_ddp_comp *comp, struct device *mmsys_dev,
unsigned int next)
{
if (comp->funcs && comp->funcs->connect) {
comp->funcs->connect(comp->dev, mmsys_dev, next);
return true;
}
return false;
}
static inline bool mtk_ddp_comp_disconnect(struct mtk_ddp_comp *comp, struct device *mmsys_dev,
unsigned int next)
{
if (comp->funcs && comp->funcs->disconnect) {
comp->funcs->disconnect(comp->dev, mmsys_dev, next);
return true;
}
return false;
}
int mtk_ddp_comp_get_id(struct device_node *node,
enum mtk_ddp_comp_type comp_type);
unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm,
struct device *dev);
int mtk_ddp_comp_init(struct device_node *comp_node, struct mtk_ddp_comp *comp,
enum mtk_ddp_comp_id comp_id);
enum mtk_ddp_comp_type mtk_ddp_comp_get_type(enum mtk_ddp_comp_id comp_id);
unsigned int comp_id);
enum mtk_ddp_comp_type mtk_ddp_comp_get_type(unsigned int comp_id);
void mtk_ddp_write(struct cmdq_pkt *cmdq_pkt, unsigned int value,
struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
unsigned int offset);
......
This diff is collapsed.
......@@ -11,6 +11,8 @@
#define MAX_CRTC 3
#define MAX_CONNECTOR 2
#define DDP_COMPONENT_DRM_OVL_ADAPTOR (DDP_COMPONENT_ID_MAX + 1)
#define DDP_COMPONENT_DRM_ID_MAX (DDP_COMPONENT_DRM_OVL_ADAPTOR + 1)
struct device;
struct device_node;
......@@ -21,35 +23,33 @@ struct drm_property;
struct regmap;
struct mtk_mmsys_driver_data {
const resource_size_t io_start;
const enum mtk_ddp_comp_id *main_path;
const unsigned int *main_path;
unsigned int main_len;
const enum mtk_ddp_comp_id *ext_path;
const unsigned int *ext_path;
unsigned int ext_len;
const enum mtk_ddp_comp_id *third_path;
const unsigned int *third_path;
unsigned int third_len;
bool shadow_register;
};
struct mtk_mmsys_match_data {
unsigned short num_drv_data;
const struct mtk_mmsys_driver_data *drv_data[];
unsigned int mmsys_id;
unsigned int mmsys_dev_num;
};
struct mtk_drm_private {
struct drm_device *drm;
struct device *dma_dev;
unsigned int num_pipes;
bool mtk_drm_bound;
bool drm_master;
struct device *dev;
struct device_node *mutex_node;
struct device *mutex_dev;
struct device *mmsys_dev;
struct device_node *comp_node[DDP_COMPONENT_ID_MAX];
struct mtk_ddp_comp ddp_comp[DDP_COMPONENT_ID_MAX];
struct device_node *comp_node[DDP_COMPONENT_DRM_ID_MAX];
struct mtk_ddp_comp ddp_comp[DDP_COMPONENT_DRM_ID_MAX];
const struct mtk_mmsys_driver_data *data;
struct drm_atomic_state *suspend_state;
unsigned int mbox_index;
struct mtk_drm_private **all_drm_private;
};
extern struct platform_driver mtk_disp_aal_driver;
......@@ -57,10 +57,12 @@ extern struct platform_driver mtk_disp_ccorr_driver;
extern struct platform_driver mtk_disp_color_driver;
extern struct platform_driver mtk_disp_gamma_driver;
extern struct platform_driver mtk_disp_merge_driver;
extern struct platform_driver mtk_disp_ovl_adaptor_driver;
extern struct platform_driver mtk_disp_ovl_driver;
extern struct platform_driver mtk_disp_rdma_driver;
extern struct platform_driver mtk_dpi_driver;
extern struct platform_driver mtk_dsi_driver;
extern struct platform_driver mtk_ethdr_driver;
extern struct platform_driver mtk_mdp_rdma_driver;
#endif /* MTK_DRM_DRV_H */
......@@ -19,20 +19,6 @@
#include "mtk_drm_gem.h"
#include "mtk_drm_plane.h"
static const u32 formats[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_BGRX8888,
DRM_FORMAT_BGRA8888,
DRM_FORMAT_ABGR8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_RGB888,
DRM_FORMAT_BGR888,
DRM_FORMAT_RGB565,
DRM_FORMAT_UYVY,
DRM_FORMAT_YUYV,
};
static const u64 modifiers[] = {
DRM_FORMAT_MOD_LINEAR,
DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
......@@ -315,13 +301,19 @@ static const struct drm_plane_helper_funcs mtk_plane_helper_funcs = {
int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
unsigned long possible_crtcs, enum drm_plane_type type,
unsigned int supported_rotations)
unsigned int supported_rotations, const u32 *formats,
size_t num_formats)
{
int err;
if (!formats || !num_formats) {
DRM_ERROR("no formats for plane\n");
return -EINVAL;
}
err = drm_universal_plane_init(dev, plane, possible_crtcs,
&mtk_plane_funcs, formats,
ARRAY_SIZE(formats), modifiers, type, NULL);
num_formats, modifiers, type, NULL);
if (err) {
DRM_ERROR("failed to initialize plane\n");
return err;
......
......@@ -48,6 +48,7 @@ to_mtk_plane_state(struct drm_plane_state *state)
int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
unsigned long possible_crtcs, enum drm_plane_type type,
unsigned int supported_rotations);
unsigned int supported_rotations, const u32 *formats,
size_t num_formats);
#endif
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021 MediaTek Inc.
*/
#ifndef __MTK_ETHDR_H__
#define __MTK_ETHDR_H__
void mtk_ethdr_start(struct device *dev);
void mtk_ethdr_stop(struct device *dev);
int mtk_ethdr_clk_enable(struct device *dev);
void mtk_ethdr_clk_disable(struct device *dev);
void mtk_ethdr_config(struct device *dev, unsigned int w,
unsigned int h, unsigned int vrefresh,
unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
struct mtk_plane_state *state,
struct cmdq_pkt *cmdq_pkt);
void mtk_ethdr_register_vblank_cb(struct device *dev,
void (*vblank_cb)(void *),
void *vblank_cb_data);
void mtk_ethdr_unregister_vblank_cb(struct device *dev);
void mtk_ethdr_enable_vblank(struct device *dev);
void mtk_ethdr_disable_vblank(struct device *dev);
#endif
......@@ -62,6 +62,20 @@
#define RDMA_CSC_FULL709_TO_RGB 5
#define RDMA_CSC_BT601_TO_RGB 6
static const u32 formats[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_BGRX8888,
DRM_FORMAT_BGRA8888,
DRM_FORMAT_ABGR8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_RGB888,
DRM_FORMAT_BGR888,
DRM_FORMAT_RGB565,
DRM_FORMAT_UYVY,
DRM_FORMAT_YUYV,
};
enum rdma_format {
RDMA_INPUT_FORMAT_RGB565 = 0,
RDMA_INPUT_FORMAT_RGB888 = 1,
......@@ -219,6 +233,16 @@ void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg,
MDP_RDMA_MF_CLIP_SIZE, FLD_MF_CLIP_H);
}
const u32 *mtk_mdp_rdma_get_formats(struct device *dev)
{
return formats;
}
size_t mtk_mdp_rdma_get_num_formats(struct device *dev)
{
return ARRAY_SIZE(formats);
}
int mtk_mdp_rdma_clk_enable(struct device *dev)
{
struct mtk_mdp_rdma *rdma = dev_get_drvdata(dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment